summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/activeqt/testcon/changeproperties.cpp8
-rw-r--r--tools/activeqt/testcon/testcon.pro2
-rw-r--r--tools/assistant/assistant.pro4
-rw-r--r--tools/assistant/compat/Info_mac.plist18
-rw-r--r--tools/assistant/compat/assistant.icnsbin162568 -> 0 bytes
-rw-r--r--tools/assistant/compat/assistant.icobin355574 -> 0 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/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/images/assistant-128.pngbin6448 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/assistant.pngbin2034 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/close.pngbin406 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/designer.pngbin1282 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/linguist.pngbin1382 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/addtab.pngbin469 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/book.pngbin1477 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/closetab.pngbin516 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/editcopy.pngbin1468 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/find.pngbin1836 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/home.pngbin1807 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/next.pngbin1310 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/prev.pngbin1080 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/print.pngbin2087 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/synctoc.pngbin1838 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/whatsthis.pngbin1586 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/zoomin.pngbin1696 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/mac/zoomout.pngbin1662 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/qt.pngbin1422 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/addtab.pngbin314 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/book.pngbin1109 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/closetab.pngbin375 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/editcopy.pngbin1325 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/find.pngbin1944 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/home.pngbin1414 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/next.pngbin1038 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/previous.pngbin898 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/print.pngbin1456 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/synctoc.pngbin1235 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/whatsthis.pngbin1040 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/zoomin.pngbin1208 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/win/zoomout.pngbin1226 -> 0 bytes
-rw-r--r--tools/assistant/compat/images/wrap.pngbin500 -> 0 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.cpp446
-rw-r--r--tools/assistant/compat/main.cpp465
-rw-r--r--tools/assistant/compat/mainwindow.cpp885
-rw-r--r--tools/assistant/compat/mainwindow.h137
-rw-r--r--tools/assistant/compat/mainwindow.ui457
-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.ui162
-rw-r--r--tools/assistant/lib/fulltextsearch/fulltextsearch.pro4
-rw-r--r--tools/assistant/lib/fulltextsearch/qclucene-config_p.h14
-rw-r--r--tools/assistant/lib/fulltextsearch/qclucene_global_p.h2
-rw-r--r--tools/assistant/lib/fulltextsearch/qsort_p.h8
-rw-r--r--tools/assistant/lib/lib.pro5
-rw-r--r--tools/assistant/lib/qclucenefieldnames.cpp57
-rw-r--r--tools/assistant/lib/qclucenefieldnames_p.h (renamed from tools/assistant/compat/fontsettingsdialog.h)46
-rw-r--r--tools/assistant/lib/qhelp_global.cpp22
-rw-r--r--tools/assistant/lib/qhelpcollectionhandler.cpp12
-rw-r--r--tools/assistant/lib/qhelpcollectionhandler_p.h3
-rw-r--r--tools/assistant/lib/qhelpcontentwidget.cpp3
-rw-r--r--tools/assistant/lib/qhelpdbreader.cpp2
-rw-r--r--tools/assistant/lib/qhelpengine.cpp17
-rw-r--r--tools/assistant/lib/qhelpengine.h2
-rw-r--r--tools/assistant/lib/qhelpenginecore.cpp9
-rw-r--r--tools/assistant/lib/qhelpenginecore.h2
-rw-r--r--tools/assistant/lib/qhelpgenerator.cpp108
-rw-r--r--tools/assistant/lib/qhelpgenerator_p.h3
-rw-r--r--tools/assistant/lib/qhelpindexwidget.cpp3
-rw-r--r--tools/assistant/lib/qhelpprojectdata.cpp69
-rw-r--r--tools/assistant/lib/qhelpsearchengine.cpp10
-rw-r--r--tools/assistant/lib/qhelpsearchengine.h3
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene.cpp421
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_clucene_p.h37
-rw-r--r--tools/assistant/lib/qhelpsearchindexreader_default_p.h3
-rw-r--r--tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp20
-rw-r--r--tools/assistant/lib/qhelpsearchquerywidget.cpp90
-rw-r--r--tools/assistant/lib/qhelpsearchresultwidget.cpp2
-rw-r--r--tools/assistant/tools/assistant/aboutdialog.cpp44
-rw-r--r--tools/assistant/tools/assistant/assistant.pro135
-rw-r--r--tools/assistant/tools/assistant/assistant.qchbin364544 -> 364544 bytes
-rw-r--r--tools/assistant/tools/assistant/assistant_images.qrc1
-rw-r--r--tools/assistant/tools/assistant/bookmarkdialog.cpp237
-rw-r--r--tools/assistant/tools/assistant/bookmarkdialog.h89
-rw-r--r--tools/assistant/tools/assistant/bookmarkdialog.ui82
-rw-r--r--tools/assistant/tools/assistant/bookmarkfiltermodel.cpp322
-rw-r--r--tools/assistant/tools/assistant/bookmarkfiltermodel.h118
-rw-r--r--tools/assistant/tools/assistant/bookmarkitem.cpp184
-rw-r--r--tools/assistant/tools/assistant/bookmarkitem.h91
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanager.cpp1019
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanager.h202
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp321
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanagerwidget.h103
-rw-r--r--tools/assistant/tools/assistant/bookmarkmanagerwidget.ui137
-rw-r--r--tools/assistant/tools/assistant/bookmarkmodel.cpp452
-rw-r--r--tools/assistant/tools/assistant/bookmarkmodel.h117
-rw-r--r--tools/assistant/tools/assistant/bookmarkwidget.ui85
-rw-r--r--tools/assistant/tools/assistant/centralwidget.cpp573
-rw-r--r--tools/assistant/tools/assistant/centralwidget.h85
-rw-r--r--tools/assistant/tools/assistant/cmdlineparser.cpp357
-rw-r--r--tools/assistant/tools/assistant/cmdlineparser.h28
-rw-r--r--tools/assistant/tools/assistant/contentwindow.cpp54
-rw-r--r--tools/assistant/tools/assistant/contentwindow.h5
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qdoc26
-rw-r--r--tools/assistant/tools/assistant/doc/assistant.qdocconf2
-rw-r--r--tools/assistant/tools/assistant/doc/images/assistant-assistant.pngbin105954 -> 205326 bytes
-rw-r--r--tools/assistant/tools/assistant/filternamedialog.cpp4
-rw-r--r--tools/assistant/tools/assistant/findwidget.cpp234
-rw-r--r--tools/assistant/tools/assistant/findwidget.h (renamed from tools/assistant/compat/helpwindow.h)77
-rw-r--r--tools/assistant/tools/assistant/helpenginewrapper.cpp835
-rw-r--r--tools/assistant/tools/assistant/helpenginewrapper.h216
-rw-r--r--tools/assistant/tools/assistant/helpviewer.cpp645
-rw-r--r--tools/assistant/tools/assistant/helpviewer.h139
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qtb.cpp307
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qtb.h113
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qwv.cpp427
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qwv.h123
-rw-r--r--tools/assistant/tools/assistant/images/bookmark.pngbin0 -> 1266 bytes
-rw-r--r--tools/assistant/tools/assistant/indexwindow.cpp29
-rw-r--r--tools/assistant/tools/assistant/indexwindow.h4
-rw-r--r--tools/assistant/tools/assistant/installdialog.cpp15
-rw-r--r--tools/assistant/tools/assistant/installdialog.h2
-rw-r--r--tools/assistant/tools/assistant/main.cpp539
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp593
-rw-r--r--tools/assistant/tools/assistant/mainwindow.h52
-rw-r--r--tools/assistant/tools/assistant/preferencesdialog.cpp172
-rw-r--r--tools/assistant/tools/assistant/preferencesdialog.h13
-rw-r--r--tools/assistant/tools/assistant/qtdocinstaller.cpp87
-rw-r--r--tools/assistant/tools/assistant/qtdocinstaller.h21
-rw-r--r--tools/assistant/tools/assistant/remotecontrol.cpp287
-rw-r--r--tools/assistant/tools/assistant/remotecontrol.h18
-rw-r--r--tools/assistant/tools/assistant/searchwidget.cpp14
-rw-r--r--tools/assistant/tools/assistant/searchwidget.h2
-rw-r--r--tools/assistant/tools/assistant/topicchooser.cpp29
-rw-r--r--tools/assistant/tools/assistant/topicchooser.h9
-rw-r--r--tools/assistant/tools/assistant/tracer.h (renamed from tools/assistant/compat/lib/qassistantclient_global.h)40
-rw-r--r--tools/assistant/tools/assistant/xbelsupport.cpp233
-rw-r--r--tools/assistant/tools/assistant/xbelsupport.h (renamed from tools/assistant/compat/topicchooser.h)52
-rw-r--r--tools/assistant/tools/qcollectiongenerator/main.cpp159
-rw-r--r--tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro19
-rw-r--r--tools/assistant/tools/qhelpconverter/filespage.cpp4
-rw-r--r--tools/assistant/tools/qhelpconverter/filterpage.cpp4
-rw-r--r--tools/assistant/tools/qhelpconverter/finishpage.cpp3
-rw-r--r--tools/assistant/tools/qhelpconverter/helpwindow.cpp2
-rw-r--r--tools/assistant/tools/qhelpconverter/inputpage.h2
-rw-r--r--tools/assistant/tools/qhelpconverter/main.cpp15
-rw-r--r--tools/assistant/tools/qhelpgenerator/main.cpp60
-rw-r--r--tools/assistant/tools/shared/collectionconfiguration.cpp313
-rw-r--r--tools/assistant/tools/shared/collectionconfiguration.h145
-rw-r--r--tools/assistant/tools/shared/helpgenerator.cpp9
-rw-r--r--tools/assistant/tools/shared/helpgenerator.h1
-rw-r--r--tools/assistant/translations/qt_help.pro52
-rw-r--r--tools/assistant/translations/translations.pro53
-rw-r--r--tools/assistant/translations/translations_adp.pro41
-rw-r--r--tools/configure/configure.pro13
-rw-r--r--tools/configure/configureapp.cpp1678
-rw-r--r--tools/configure/configureapp.h6
-rw-r--r--tools/configure/environment.cpp20
-rw-r--r--tools/configure/environment.h3
-rw-r--r--tools/designer/src/components/buddyeditor/buddyeditor.cpp1
-rw-r--r--tools/designer/src/components/formeditor/formeditor.pri2
-rw-r--r--tools/designer/src/components/formeditor/formeditor.qrc2
-rw-r--r--tools/designer/src/components/formeditor/formeditor_optionspage.cpp6
-rw-r--r--tools/designer/src/components/formeditor/formwindow.cpp244
-rw-r--r--tools/designer/src/components/formeditor/formwindow.h15
-rw-r--r--tools/designer/src/components/formeditor/formwindowmanager.cpp4
-rw-r--r--tools/designer/src/components/formeditor/images/cleartext.pngbin0 -> 760 bytes
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.cpp61
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.h4
-rw-r--r--tools/designer/src/components/formeditor/qdesignerundostack.cpp112
-rw-r--r--tools/designer/src/components/formeditor/qdesignerundostack.h (renamed from tools/assistant/compat/lib/qassistantclient.h)70
-rw-r--r--tools/designer/src/components/formeditor/qmdiarea_container.cpp1
-rw-r--r--tools/designer/src/components/lib/lib.pro10
-rw-r--r--tools/designer/src/components/objectinspector/objectinspector.pri2
-rw-r--r--tools/designer/src/components/propertyeditor/brushpropertymanager.cpp18
-rw-r--r--tools/designer/src/components/propertyeditor/defs.cpp107
-rw-r--r--tools/designer/src/components/propertyeditor/propertyeditor.cpp71
-rw-r--r--tools/designer/src/components/propertyeditor/propertyeditor.h5
-rw-r--r--tools/designer/src/components/propertyeditor/propertyeditor.pri8
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp12
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditorwindow.h2
-rw-r--r--tools/designer/src/components/taskmenu/itemlisteditor.cpp22
-rw-r--r--tools/designer/src/components/widgetbox/widgetbox.cpp5
-rw-r--r--tools/designer/src/components/widgetbox/widgetboxcategorylistview.cpp26
-rw-r--r--tools/designer/src/designer/assistantclient.cpp2
-rw-r--r--tools/designer/src/designer/designer.pro11
-rw-r--r--tools/designer/src/designer/mainwindow.cpp20
-rw-r--r--tools/designer/src/designer/qdesigner_actions.cpp30
-rw-r--r--tools/designer/src/designer/qdesigner_actions.h4
-rw-r--r--tools/designer/src/designer/qdesigner_workbench.cpp1
-rw-r--r--tools/designer/src/lib/sdk/abstractdnditem.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/abstractformeditor.cpp3
-rw-r--r--tools/designer/src/lib/sdk/abstracticoncache.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/dynamicpropertysheet.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/layoutdecoration.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/membersheet.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/propertysheet.qdoc26
-rw-r--r--tools/designer/src/lib/sdk/taskmenu.qdoc26
-rw-r--r--tools/designer/src/lib/shared/actionrepository.cpp6
-rw-r--r--tools/designer/src/lib/shared/filterwidget.cpp167
-rw-r--r--tools/designer/src/lib/shared/filterwidget_p.h53
-rw-r--r--tools/designer/src/lib/shared/formwindowbase.cpp13
-rw-r--r--tools/designer/src/lib/shared/plugindialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/previewconfigurationwidget.cpp2
-rw-r--r--tools/designer/src/lib/shared/qdesigner_formwindowcommand.cpp6
-rw-r--r--tools/designer/src/lib/shared/qdesigner_formwindowcommand_p.h4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_menu.cpp8
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertycommand.cpp54
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertycommand_p.h28
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp16
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertyeditor_p.h8
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertysheet.cpp38
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertysheet_p.h3
-rw-r--r--tools/designer/src/lib/shared/qdesigner_toolbar.cpp1
-rw-r--r--tools/designer/src/lib/shared/qtresourcemodel.cpp6
-rw-r--r--tools/designer/src/lib/shared/qtresourceview.cpp7
-rw-r--r--tools/designer/src/lib/shared/shared.pri10
-rw-r--r--tools/designer/src/lib/shared/stylesheeteditor.cpp1
-rw-r--r--tools/designer/src/lib/uilib/abstractformbuilder.cpp17
-rw-r--r--tools/designer/src/lib/uilib/container.qdoc26
-rw-r--r--tools/designer/src/lib/uilib/customwidget.qdoc26
-rw-r--r--tools/designer/src/lib/uilib/properties.cpp11
-rw-r--r--tools/designer/src/plugins/phononwidgets/seeksliderplugin.cpp4
-rw-r--r--tools/designer/src/plugins/phononwidgets/videoplayerplugin.cpp4
-rw-r--r--tools/designer/src/plugins/phononwidgets/volumesliderplugin.cpp4
-rw-r--r--tools/designer/src/plugins/plugins.pro3
-rw-r--r--tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro13
-rw-r--r--tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp132
-rw-r--r--tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h74
-rw-r--r--tools/designer/src/plugins/qwebview/qwebview_plugin.cpp4
-rw-r--r--tools/designer/translations/translations.pro140
-rw-r--r--tools/linguist/lconvert/main.cpp33
-rw-r--r--tools/linguist/linguist.pro2
-rw-r--r--tools/linguist/linguist/linguist.pro17
-rw-r--r--tools/linguist/linguist/mainwindow.cpp63
-rw-r--r--tools/linguist/linguist/mainwindow.ui2
-rw-r--r--tools/linguist/linguist/messagemodel.cpp2
-rw-r--r--tools/linguist/linguist/phrase.cpp7
-rw-r--r--tools/linguist/linguist/printout.cpp2
-rw-r--r--tools/linguist/linguist/sourcecodeview.cpp2
-rw-r--r--tools/linguist/lrelease/lrelease.pro1
-rw-r--r--tools/linguist/lrelease/main.cpp57
-rw-r--r--tools/linguist/lupdate/cpp.cpp163
-rw-r--r--tools/linguist/lupdate/java.cpp49
-rw-r--r--tools/linguist/lupdate/lupdate.h1
-rw-r--r--tools/linguist/lupdate/lupdate.pro4
-rw-r--r--tools/linguist/lupdate/main.cpp256
-rw-r--r--tools/linguist/lupdate/merge.cpp18
-rw-r--r--tools/linguist/lupdate/qdeclarative.cpp432
-rw-r--r--tools/linguist/lupdate/qscript.cpp309
-rw-r--r--tools/linguist/lupdate/qscript.g282
-rw-r--r--tools/linguist/lupdate/ui.cpp19
-rw-r--r--tools/linguist/phrasebooks/french.qph62
-rw-r--r--tools/linguist/phrasebooks/hungarian.qph752
-rw-r--r--tools/linguist/phrasebooks/russian.qph18
-rw-r--r--tools/linguist/shared/numerus.cpp65
-rw-r--r--tools/linguist/shared/po.cpp573
-rw-r--r--tools/linguist/shared/profileevaluator.cpp6
-rw-r--r--tools/linguist/shared/qm.cpp8
-rw-r--r--tools/linguist/shared/translator.cpp42
-rw-r--r--tools/linguist/shared/translator.h8
-rw-r--r--tools/linguist/shared/ts.dtd23
-rw-r--r--tools/linguist/shared/xliff.cpp19
-rw-r--r--tools/macdeployqt/shared/shared.cpp2
-rw-r--r--tools/makeqpf/qpf2.cpp2
-rw-r--r--tools/pixeltool/qpixeltool.cpp2
-rw-r--r--tools/porting/src/codemodel.h2
-rw-r--r--tools/porting/src/errors.cpp6
-rw-r--r--tools/porting/src/errors.h6
-rw-r--r--tools/porting/src/preprocessorcontrol.cpp2
-rw-r--r--tools/porting/src/q3porting.xml4
-rw-r--r--tools/porting/src/rpp.cpp4
-rw-r--r--tools/porting/src/semantic.cpp10
-rw-r--r--tools/porting/src/textreplacement.h4
-rw-r--r--tools/porting/src/tokenengine.h2
-rw-r--r--tools/porting/src/tokenreplacements.cpp8
-rw-r--r--tools/qconfig/qconfig.pro1
-rw-r--r--tools/qdbus/qdbus.pro3
-rw-r--r--tools/qdbus/qdbus/qdbus.cpp191
-rw-r--r--tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp2
-rw-r--r--tools/qdbus/qdbusviewer/qdbusmodel.cpp14
-rw-r--r--tools/qdbus/qdbusviewer/qdbusmodel.h1
-rw-r--r--tools/qdbus/qdbusviewer/qdbusviewer.cpp97
-rw-r--r--tools/qdbus/qdbusviewer/qdbusviewer.h7
-rw-r--r--tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp9
-rw-r--r--tools/qdoc3/codechunk.h2
-rw-r--r--tools/qdoc3/codemarker.cpp28
-rw-r--r--tools/qdoc3/codemarker.h36
-rw-r--r--tools/qdoc3/codeparser.cpp18
-rw-r--r--tools/qdoc3/codeparser.h2
-rw-r--r--tools/qdoc3/command.cpp9
-rw-r--r--tools/qdoc3/config.cpp17
-rw-r--r--tools/qdoc3/config.h9
-rw-r--r--tools/qdoc3/cppcodemarker.cpp152
-rw-r--r--tools/qdoc3/cppcodemarker.h10
-rw-r--r--tools/qdoc3/cppcodeparser.cpp148
-rw-r--r--tools/qdoc3/cppcodeparser.h1
-rw-r--r--tools/qdoc3/ditaxmlgenerator.cpp5163
-rw-r--r--tools/qdoc3/ditaxmlgenerator.h338
-rw-r--r--tools/qdoc3/doc.cpp26
-rw-r--r--tools/qdoc3/doc.h1
-rw-r--r--tools/qdoc3/doc/classic.css284
-rw-r--r--tools/qdoc3/doc/examples/layoutmanagement.qdocinc13
-rw-r--r--tools/qdoc3/doc/examples/main.cpp54
-rw-r--r--tools/qdoc3/doc/examples/minimum.qdocconf42
-rw-r--r--tools/qdoc3/doc/examples/objectmodel.qdocinc11
-rw-r--r--tools/qdoc3/doc/examples/signalandslots.qdocinc9
-rw-r--r--tools/qdoc3/doc/files/compat.qdocconf31
-rw-r--r--tools/qdoc3/doc/files/qt.qdocconf115
-rw-r--r--tools/qdoc3/doc/images/happy.gifbin0 -> 11526 bytes
-rw-r--r--tools/qdoc3/doc/images/happyguy.jpgbin0 -> 53442 bytes
-rw-r--r--tools/qdoc3/doc/images/qt-logo.pngbin0 -> 5149 bytes
-rw-r--r--tools/qdoc3/doc/images/training.jpgbin0 -> 8368 bytes
-rw-r--r--tools/qdoc3/doc/qdoc-manual.qdoc8774
-rw-r--r--tools/qdoc3/doc/qdoc-manual.qdocconf234
-rw-r--r--tools/qdoc3/generator.cpp169
-rw-r--r--tools/qdoc3/generator.h12
-rw-r--r--tools/qdoc3/helpprojectwriter.cpp198
-rw-r--r--tools/qdoc3/helpprojectwriter.h1
-rw-r--r--tools/qdoc3/htmlgenerator.cpp2055
-rw-r--r--tools/qdoc3/htmlgenerator.h95
-rw-r--r--tools/qdoc3/jambiapiparser.cpp2
-rw-r--r--tools/qdoc3/javacodemarker.cpp6
-rw-r--r--tools/qdoc3/javacodemarker.h5
-rw-r--r--tools/qdoc3/javadocgenerator.cpp2
-rw-r--r--tools/qdoc3/javadocgenerator.h2
-rw-r--r--tools/qdoc3/linguistgenerator.cpp6
-rw-r--r--tools/qdoc3/linguistgenerator.h2
-rw-r--r--tools/qdoc3/location.cpp2
-rw-r--r--tools/qdoc3/main.cpp60
-rw-r--r--tools/qdoc3/mangenerator.cpp2
-rw-r--r--tools/qdoc3/mangenerator.h2
-rw-r--r--tools/qdoc3/node.cpp587
-rw-r--r--tools/qdoc3/node.h239
-rw-r--r--tools/qdoc3/pagegenerator.cpp131
-rw-r--r--tools/qdoc3/pagegenerator.h21
-rw-r--r--tools/qdoc3/plaincodemarker.cpp7
-rw-r--r--tools/qdoc3/plaincodemarker.h1
-rw-r--r--tools/qdoc3/qdoc3.pro27
-rw-r--r--tools/qdoc3/qsakernelparser.cpp6
-rw-r--r--tools/qdoc3/qscodemarker.cpp25
-rw-r--r--tools/qdoc3/qscodemarker.h1
-rw-r--r--tools/qdoc3/qscodeparser.cpp6
-rw-r--r--tools/qdoc3/test/assistant.qdocconf44
-rw-r--r--tools/qdoc3/test/designer.qdocconf44
-rw-r--r--tools/qdoc3/test/images/bg_l.pngbin0 -> 100 bytes
-rw-r--r--tools/qdoc3/test/images/bg_l_blank.pngbin0 -> 84 bytes
-rw-r--r--tools/qdoc3/test/images/bg_r.pngbin0 -> 96 bytes
-rw-r--r--tools/qdoc3/test/images/box_bg.pngbin0 -> 89 bytes
-rw-r--r--tools/qdoc3/test/images/breadcrumb.pngbin0 -> 134 bytes
-rw-r--r--tools/qdoc3/test/images/bullet_dn.pngbin0 -> 230 bytes
-rw-r--r--tools/qdoc3/test/images/bullet_gt.pngbin0 -> 124 bytes
-rw-r--r--tools/qdoc3/test/images/bullet_sq.pngbin0 -> 74 bytes
-rw-r--r--tools/qdoc3/test/images/bullet_up.pngbin0 -> 253 bytes
-rw-r--r--tools/qdoc3/test/images/feedbackground.pngbin0 -> 263 bytes
-rw-r--r--tools/qdoc3/test/images/horBar.pngbin0 -> 2807 bytes
-rw-r--r--tools/qdoc3/test/images/page.pngbin0 -> 3102 bytes
-rw-r--r--tools/qdoc3/test/images/page_bg.pngbin0 -> 84 bytes
-rw-r--r--tools/qdoc3/test/images/sprites-combined.pngbin0 -> 62534 bytes
-rw-r--r--tools/qdoc3/test/jambi.qdocconf3
-rw-r--r--tools/qdoc3/test/linguist.qdocconf44
-rw-r--r--tools/qdoc3/test/macros.qdocconf1
-rw-r--r--tools/qdoc3/test/qdeclarative.qdocconf96
-rw-r--r--tools/qdoc3/test/qmake.qdocconf44
-rw-r--r--tools/qdoc3/test/qt-api-only.qdocconf4
-rw-r--r--tools/qdoc3/test/qt-api-only_ja_JP.qdocconf37
-rw-r--r--tools/qdoc3/test/qt-api-only_zh_CN.qdocconf37
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf77
-rw-r--r--tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf118
-rw-r--r--tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf116
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf11
-rw-r--r--tools/qdoc3/test/qt-defines.qdocconf42
-rw-r--r--tools/qdoc3/test/qt-ditaxml.qdocconf11
-rw-r--r--tools/qdoc3/test/qt-html-templates.qdocconf209
-rw-r--r--tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf177
-rw-r--r--tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf177
-rw-r--r--tools/qdoc3/test/qt-webxml.qdocconf3
-rw-r--r--tools/qdoc3/test/qt.qdocconf78
-rw-r--r--tools/qdoc3/test/qt_ja_JP.qdocconf118
-rw-r--r--tools/qdoc3/test/qt_zh_CN.qdocconf116
-rw-r--r--tools/qdoc3/test/scripts/functions.js60
-rw-r--r--tools/qdoc3/test/scripts/jquery.js152
-rw-r--r--tools/qdoc3/test/style/style.css1051
-rw-r--r--tools/qdoc3/test/style/style_ie6.css54
-rw-r--r--tools/qdoc3/test/style/style_ie7.css19
-rw-r--r--tools/qdoc3/test/style/style_ie8.css0
-rw-r--r--tools/qdoc3/text.h2
-rw-r--r--tools/qdoc3/tokenizer.cpp31
-rw-r--r--tools/qdoc3/tokenizer.h13
-rw-r--r--tools/qdoc3/tree.cpp133
-rw-r--r--tools/qdoc3/tree.h20
-rw-r--r--tools/qdoc3/webxmlgenerator.cpp6
-rw-r--r--tools/qdoc3/webxmlgenerator.h7
-rw-r--r--tools/qev/qev.pro2
-rw-r--r--tools/qmeegographicssystemhelper/qmeegofencesync.cpp79
-rw-r--r--tools/qmeegographicssystemhelper/qmeegofencesync.h101
-rw-r--r--tools/qmeegographicssystemhelper/qmeegofencesync_p.h (renamed from tools/designer/src/components/propertyeditor/defs.h)28
-rw-r--r--tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp138
-rw-r--r--tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h182
-rw-r--r--tools/qmeegographicssystemhelper/qmeegographicssystemhelper.pro10
-rw-r--r--tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp117
-rw-r--r--tools/qmeegographicssystemhelper/qmeegolivepixmap.h112
-rw-r--r--tools/qmeegographicssystemhelper/qmeegolivepixmap_p.h57
-rw-r--r--tools/qmeegographicssystemhelper/qmeegooverlaywidget.cpp102
-rw-r--r--tools/qmeegographicssystemhelper/qmeegooverlaywidget.h86
-rw-r--r--tools/qmeegographicssystemhelper/qmeegoruntime.cpp234
-rw-r--r--tools/qmeegographicssystemhelper/qmeegoruntime.h68
-rw-r--r--tools/qml/Info_mac.plist49
-rw-r--r--tools/qml/browser/Browser.qml318
-rw-r--r--tools/qml/browser/browser.qrc9
-rw-r--r--tools/qml/browser/images/folder.pngbin0 -> 1841 bytes
-rw-r--r--tools/qml/browser/images/titlebar.pngbin0 -> 1436 bytes
-rw-r--r--tools/qml/browser/images/titlebar.sci5
-rw-r--r--tools/qml/browser/images/up.pngbin0 -> 662 bytes
-rw-r--r--tools/qml/deviceorientation.cpp80
-rw-r--r--tools/qml/deviceorientation.h84
-rw-r--r--tools/qml/deviceorientation_harmattan.cpp161
-rw-r--r--tools/qml/deviceorientation_maemo5.cpp148
-rw-r--r--tools/qml/deviceorientation_symbian.cpp192
-rw-r--r--tools/qml/loggerwidget.cpp201
-rw-r--r--tools/qml/loggerwidget.h99
-rw-r--r--tools/qml/main.cpp594
-rw-r--r--tools/qml/proxysettings.cpp113
-rw-r--r--tools/qml/proxysettings.h75
-rw-r--r--tools/qml/proxysettings.ui115
-rw-r--r--tools/qml/proxysettings_maemo5.ui177
-rw-r--r--tools/qml/qdeclarativetester.cpp439
-rw-r--r--tools/qml/qdeclarativetester.h290
-rw-r--r--tools/qml/qml.icnsbin0 -> 196156 bytes
-rw-r--r--tools/qml/qml.pri41
-rw-r--r--tools/qml/qml.pro53
-rw-r--r--tools/qml/qmlruntime.cpp1545
-rw-r--r--tools/qml/qmlruntime.h206
-rw-r--r--tools/qml/recopts.ui513
-rw-r--r--tools/qml/recopts_maemo5.ui254
-rw-r--r--tools/qml/startup/Logo.qml179
-rw-r--r--tools/qml/startup/qt-back.pngbin0 -> 3549 bytes
-rw-r--r--tools/qml/startup/qt-blue.jpgbin0 -> 20900 bytes
-rw-r--r--tools/qml/startup/qt-front.pngbin0 -> 3318 bytes
-rw-r--r--tools/qml/startup/qt-sketch.jpgbin0 -> 17048 bytes
-rw-r--r--tools/qml/startup/qt-text.pngbin0 -> 14565 bytes
-rw-r--r--tools/qml/startup/quick-blur.pngbin0 -> 2826 bytes
-rw-r--r--tools/qml/startup/quick-regular.pngbin0 -> 1399 bytes
-rw-r--r--tools/qml/startup/shadow.pngbin0 -> 1592 bytes
-rw-r--r--tools/qml/startup/startup.qml173
-rw-r--r--tools/qml/startup/startup.qrc16
-rw-r--r--tools/qml/startup/white-star.pngbin0 -> 2651 bytes
-rw-r--r--tools/qml/texteditautoresizer_maemo5.h113
-rw-r--r--tools/qtconfig/main.cpp14
-rw-r--r--tools/qtconfig/mainwindow.cpp28
-rw-r--r--tools/qtconfig/paletteeditoradvanced.cpp1
-rw-r--r--tools/qtconfig/qtconfig.pro5
-rw-r--r--tools/qtconfig/translations/translations.pro15
-rw-r--r--tools/qtestlib/wince/cetest/activesyncconnection.cpp2
-rw-r--r--tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp21
-rw-r--r--tools/qtestlib/wince/cetest/cetcpsyncconnection.h3
-rw-r--r--tools/qtestlib/wince/cetest/cetest.pro2
-rw-r--r--tools/qtestlib/wince/cetest/main.cpp10
-rw-r--r--tools/qtestlib/wince/cetest/qmake_include.pri2
-rw-r--r--tools/qttracereplay/main.cpp175
-rw-r--r--tools/qvfb/main.cpp13
-rw-r--r--tools/qvfb/qvfb.cpp56
-rw-r--r--tools/qvfb/qvfb.pro2
-rw-r--r--tools/qvfb/qvfbratedlg.cpp10
-rw-r--r--tools/qvfb/translations/translations.pro34
-rw-r--r--tools/runonphone/main.cpp162
-rw-r--r--tools/runonphone/ossignalconverter.cpp121
-rw-r--r--tools/runonphone/ossignalconverter.h63
-rw-r--r--tools/runonphone/ossignalconverter_p.h71
-rw-r--r--tools/runonphone/runonphone.pro11
-rw-r--r--tools/runonphone/serenum.h2
-rw-r--r--tools/runonphone/serenum_unix.cpp162
-rw-r--r--tools/runonphone/serenum_win.cpp2
-rw-r--r--tools/runonphone/symbianutils/json.cpp490
-rw-r--r--tools/runonphone/symbianutils/json.h149
-rw-r--r--tools/runonphone/symbianutils/launcher.cpp440
-rw-r--r--tools/runonphone/symbianutils/launcher.h35
-rw-r--r--tools/runonphone/symbianutils/symbiandevicemanager.cpp194
-rw-r--r--tools/runonphone/symbianutils/symbiandevicemanager.h47
-rw-r--r--tools/runonphone/symbianutils/symbianutils.pri12
-rw-r--r--tools/runonphone/symbianutils/tcftrkdevice.cpp929
-rw-r--r--tools/runonphone/symbianutils/tcftrkdevice.h295
-rw-r--r--tools/runonphone/symbianutils/tcftrkmessage.cpp562
-rw-r--r--tools/runonphone/symbianutils/tcftrkmessage.h296
-rw-r--r--tools/runonphone/symbianutils/trkdevice.cpp116
-rw-r--r--tools/runonphone/symbianutils/trkdevice.h11
-rw-r--r--tools/runonphone/symbianutils/trkutils.cpp163
-rw-r--r--tools/runonphone/symbianutils/trkutils.h92
-rw-r--r--tools/runonphone/symbianutils/trkutils_p.h2
-rw-r--r--tools/runonphone/trksignalhandler.cpp189
-rw-r--r--tools/runonphone/trksignalhandler.h8
-rw-r--r--tools/shared/deviceskin/deviceskin.pri3
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.pngbin115575 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.pngbin104711 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin29
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf78
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.qrc5
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin18
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf36
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/finger.pngbin40343 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.pngbin52037 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.pngbin100615 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.qrc5
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.pngbin69447 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.pngbin242107 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.pngbin230638 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin35
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf142
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc5
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.pngbin133117 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.pngbin133180 -> 0 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin17
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf53
-rw-r--r--tools/shared/fontpanel/fontpanel.cpp8
-rw-r--r--tools/shared/qtpropertybrowser/qtpropertymanager.cpp44
-rw-r--r--tools/shared/symbian/epocroot.cpp120
-rw-r--r--tools/shared/symbian/epocroot.pri11
-rw-r--r--tools/shared/symbian/epocroot_p.h (renamed from tools/shared/symbian/epocroot.h)24
-rw-r--r--tools/shared/windows/registry.cpp17
-rw-r--r--tools/shared/windows/registry_p.h (renamed from tools/shared/windows/registry.h)24
-rw-r--r--tools/tools.pro49
538 files changed, 46476 insertions, 16951 deletions
diff --git a/tools/activeqt/testcon/changeproperties.cpp b/tools/activeqt/testcon/changeproperties.cpp
index e2ad601..00a2cab 100644
--- a/tools/activeqt/testcon/changeproperties.cpp
+++ b/tools/activeqt/testcon/changeproperties.cpp
@@ -111,10 +111,10 @@ void ChangeProperties::on_buttonSet_clicked()
value = qVariantFromValue(col);
} else {
QMessageBox::warning(this, tr("Can't parse input"),
- QString(tr("Failed to create a color from %1\n"
+ tr("Failed to create a color from %1\n"
"The string has to be a valid color name (e.g. 'red')\n"
"or a RGB triple of format '#rrggbb'."
- ).arg(editValue->text())));
+ ).arg(editValue->text()));
}
}
break;
@@ -125,10 +125,10 @@ void ChangeProperties::on_buttonSet_clicked()
value = qVariantFromValue(fnt);
} else {
QMessageBox::warning(this, tr("Can't parse input"),
- (tr("Failed to create a font from %1\n"
+ tr("Failed to create a font from %1\n"
"The string has to have a format family,<point size> or\n"
"family,pointsize,stylehint,weight,italic,underline,strikeout,fixedpitch,rawmode."
- ).arg(editValue->text())));
+ ).arg(editValue->text()));
}
}
break;
diff --git a/tools/activeqt/testcon/testcon.pro b/tools/activeqt/testcon/testcon.pro
index dc98218..89f8067 100644
--- a/tools/activeqt/testcon/testcon.pro
+++ b/tools/activeqt/testcon/testcon.pro
@@ -16,6 +16,6 @@ RC_FILE = testcon.rc
win32-borland {
QMAKE_POST_LINK = -midl $$QT_SOURCE_TREE/tools/activeqt/testcon/testcon.idl
} else {
- !win32-g++:QMAKE_POST_LINK = midl $$QT_SOURCE_TREE/tools/activeqt/testcon/testcon.idl && move testcon.tlb $(TARGETDIR)
+ !win32-g++*:QMAKE_POST_LINK = midl $$QT_SOURCE_TREE/tools/activeqt/testcon/testcon.idl && move testcon.tlb $(TARGETDIR)
}
diff --git a/tools/assistant/assistant.pro b/tools/assistant/assistant.pro
index 08d0d4b..97196b2 100644
--- a/tools/assistant/assistant.pro
+++ b/tools/assistant/assistant.pro
@@ -3,6 +3,4 @@ CONFIG += ordered
SUBDIRS += lib/fulltextsearch \
lib \
- tools \
- compat \
- compat/lib \ \ No newline at end of file
+ tools
diff --git a/tools/assistant/compat/Info_mac.plist b/tools/assistant/compat/Info_mac.plist
deleted file mode 100644
index b1e6336..0000000
--- a/tools/assistant/compat/Info_mac.plist
+++ /dev/null
@@ -1,18 +0,0 @@
-<?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/assistant.icns b/tools/assistant/compat/assistant.icns
deleted file mode 100644
index 6291dd3..0000000
--- a/tools/assistant/compat/assistant.icns
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/assistant.ico b/tools/assistant/compat/assistant.ico
deleted file mode 100644
index 9e1b83f..0000000
--- a/tools/assistant/compat/assistant.ico
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/assistant.pro b/tools/assistant/compat/assistant.pro
deleted file mode 100644
index e865d6b..0000000
--- a/tools/assistant/compat/assistant.pro
+++ /dev/null
@@ -1,84 +0,0 @@
-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
deleted file mode 100644
index dae1f48..0000000
--- a/tools/assistant/compat/assistant.qrc
+++ /dev/null
@@ -1,37 +0,0 @@
-<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
deleted file mode 100644
index b4786ce..0000000
--- a/tools/assistant/compat/assistant.rc
+++ /dev/null
@@ -1 +0,0 @@
-IDI_ICON1 ICON DISCARDABLE "assistant.ico"
diff --git a/tools/assistant/compat/compat.pro b/tools/assistant/compat/compat.pro
deleted file mode 100644
index 1086f4c..0000000
--- a/tools/assistant/compat/compat.pro
+++ /dev/null
@@ -1,84 +0,0 @@
-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
deleted file mode 100644
index 1faef42..0000000
--- a/tools/assistant/compat/config.cpp
+++ /dev/null
@@ -1,438 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 498e6bb..0000000
--- a/tools/assistant/compat/config.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index db2f824..0000000
--- a/tools/assistant/compat/docuparser.cpp
+++ /dev/null
@@ -1,433 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 7c7692e..0000000
--- a/tools/assistant/compat/docuparser.h
+++ /dev/null
@@ -1,166 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 31a3241..0000000
--- a/tools/assistant/compat/fontsettingsdialog.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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/helpdialog.cpp b/tools/assistant/compat/helpdialog.cpp
deleted file mode 100644
index 23c1bfc..0000000
--- a/tools/assistant/compat/helpdialog.cpp
+++ /dev/null
@@ -1,1331 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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(QString)), this, SLOT(updateSearchButton(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
deleted file mode 100644
index 4e1bac2..0000000
--- a/tools/assistant/compat/helpdialog.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 0fc8817..0000000
--- a/tools/assistant/compat/helpdialog.ui
+++ /dev/null
@@ -1,404 +0,0 @@
-<ui version="4.0" >
- <author></author>
- <comment>*********************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 6674342..0000000
--- a/tools/assistant/compat/helpwindow.cpp
+++ /dev/null
@@ -1,247 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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/images/assistant-128.png b/tools/assistant/compat/images/assistant-128.png
deleted file mode 100644
index f05949f..0000000
--- a/tools/assistant/compat/images/assistant-128.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/assistant.png b/tools/assistant/compat/images/assistant.png
deleted file mode 100644
index ea4d1e7..0000000
--- a/tools/assistant/compat/images/assistant.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/close.png b/tools/assistant/compat/images/close.png
deleted file mode 100644
index 540694e..0000000
--- a/tools/assistant/compat/images/close.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/designer.png b/tools/assistant/compat/images/designer.png
deleted file mode 100644
index 72c42e7..0000000
--- a/tools/assistant/compat/images/designer.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/linguist.png b/tools/assistant/compat/images/linguist.png
deleted file mode 100644
index d388cbd..0000000
--- a/tools/assistant/compat/images/linguist.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/addtab.png b/tools/assistant/compat/images/mac/addtab.png
deleted file mode 100644
index 20928fb..0000000
--- a/tools/assistant/compat/images/mac/addtab.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/book.png b/tools/assistant/compat/images/mac/book.png
deleted file mode 100644
index 7a3204c..0000000
--- a/tools/assistant/compat/images/mac/book.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/closetab.png b/tools/assistant/compat/images/mac/closetab.png
deleted file mode 100644
index ab9d669..0000000
--- a/tools/assistant/compat/images/mac/closetab.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/editcopy.png b/tools/assistant/compat/images/mac/editcopy.png
deleted file mode 100644
index f551364..0000000
--- a/tools/assistant/compat/images/mac/editcopy.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/find.png b/tools/assistant/compat/images/mac/find.png
deleted file mode 100644
index 3561745..0000000
--- a/tools/assistant/compat/images/mac/find.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/home.png b/tools/assistant/compat/images/mac/home.png
deleted file mode 100644
index 78d94da..0000000
--- a/tools/assistant/compat/images/mac/home.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/next.png b/tools/assistant/compat/images/mac/next.png
deleted file mode 100644
index a585cab..0000000
--- a/tools/assistant/compat/images/mac/next.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/prev.png b/tools/assistant/compat/images/mac/prev.png
deleted file mode 100644
index 612fb34..0000000
--- a/tools/assistant/compat/images/mac/prev.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/print.png b/tools/assistant/compat/images/mac/print.png
deleted file mode 100644
index 10ca56c..0000000
--- a/tools/assistant/compat/images/mac/print.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/synctoc.png b/tools/assistant/compat/images/mac/synctoc.png
deleted file mode 100644
index 067fa94..0000000
--- a/tools/assistant/compat/images/mac/synctoc.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/whatsthis.png b/tools/assistant/compat/images/mac/whatsthis.png
deleted file mode 100644
index 5b7078f..0000000
--- a/tools/assistant/compat/images/mac/whatsthis.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/zoomin.png b/tools/assistant/compat/images/mac/zoomin.png
deleted file mode 100644
index d46f5af..0000000
--- a/tools/assistant/compat/images/mac/zoomin.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/mac/zoomout.png b/tools/assistant/compat/images/mac/zoomout.png
deleted file mode 100644
index 4632656..0000000
--- a/tools/assistant/compat/images/mac/zoomout.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/qt.png b/tools/assistant/compat/images/qt.png
deleted file mode 100644
index 2dc6716..0000000
--- a/tools/assistant/compat/images/qt.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/addtab.png b/tools/assistant/compat/images/win/addtab.png
deleted file mode 100644
index 4bb0feb..0000000
--- a/tools/assistant/compat/images/win/addtab.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/book.png b/tools/assistant/compat/images/win/book.png
deleted file mode 100644
index 09ec4d3..0000000
--- a/tools/assistant/compat/images/win/book.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/closetab.png b/tools/assistant/compat/images/win/closetab.png
deleted file mode 100644
index ef9e020..0000000
--- a/tools/assistant/compat/images/win/closetab.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/editcopy.png b/tools/assistant/compat/images/win/editcopy.png
deleted file mode 100644
index 1121b47..0000000
--- a/tools/assistant/compat/images/win/editcopy.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/find.png b/tools/assistant/compat/images/win/find.png
deleted file mode 100644
index 6ea35e9..0000000
--- a/tools/assistant/compat/images/win/find.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/home.png b/tools/assistant/compat/images/win/home.png
deleted file mode 100644
index b1c6ae1..0000000
--- a/tools/assistant/compat/images/win/home.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/next.png b/tools/assistant/compat/images/win/next.png
deleted file mode 100644
index 8df4127..0000000
--- a/tools/assistant/compat/images/win/next.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/previous.png b/tools/assistant/compat/images/win/previous.png
deleted file mode 100644
index 0780bc2..0000000
--- a/tools/assistant/compat/images/win/previous.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/print.png b/tools/assistant/compat/images/win/print.png
deleted file mode 100644
index ba7c02d..0000000
--- a/tools/assistant/compat/images/win/print.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/synctoc.png b/tools/assistant/compat/images/win/synctoc.png
deleted file mode 100644
index da301bc..0000000
--- a/tools/assistant/compat/images/win/synctoc.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/whatsthis.png b/tools/assistant/compat/images/win/whatsthis.png
deleted file mode 100644
index 623cad6..0000000
--- a/tools/assistant/compat/images/win/whatsthis.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/zoomin.png b/tools/assistant/compat/images/win/zoomin.png
deleted file mode 100644
index 2e586fc..0000000
--- a/tools/assistant/compat/images/win/zoomin.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/win/zoomout.png b/tools/assistant/compat/images/win/zoomout.png
deleted file mode 100644
index a736d39..0000000
--- a/tools/assistant/compat/images/win/zoomout.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/images/wrap.png b/tools/assistant/compat/images/wrap.png
deleted file mode 100644
index 90f18d9..0000000
--- a/tools/assistant/compat/images/wrap.png
+++ /dev/null
Binary files differ
diff --git a/tools/assistant/compat/index.cpp b/tools/assistant/compat/index.cpp
deleted file mode 100644
index ff54626..0000000
--- a/tools/assistant/compat/index.cpp
+++ /dev/null
@@ -1,581 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 9dd6d54..0000000
--- a/tools/assistant/compat/index.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index e50d470..0000000
--- a/tools/assistant/compat/lib/lib.pro
+++ /dev/null
@@ -1,78 +0,0 @@
-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, "", true)|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
deleted file mode 100644
index 72d0a92..0000000
--- a/tools/assistant/compat/lib/qassistantclient.cpp
+++ /dev/null
@@ -1,446 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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.
-
- \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/main.cpp b/tools/assistant/compat/main.cpp
deleted file mode 100644
index c16c52e..0000000
--- a/tools/assistant/compat/main.cpp
+++ /dev/null
@@ -1,465 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 76143a5..0000000
--- a/tools/assistant/compat/mainwindow.cpp
+++ /dev/null
@@ -1,885 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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")));
-#elif defined(Q_WS_X11)
- ui.actionGoNext->setIcon(QIcon::fromTheme("go-next" , ui.actionGoNext->icon()));
- ui.actionGoPrevious->setIcon(QIcon::fromTheme("go-previous" , ui.actionGoPrevious->icon()));
- ui.actionGoHome->setIcon(QIcon::fromTheme("user-home" , ui.actionGoHome->icon()));
- ui.actionEditCopy->setIcon(QIcon::fromTheme("edit-copy" , ui.actionEditCopy->icon()));
- ui.actionEditFind->setIcon(QIcon::fromTheme("edit-find" , ui.actionEditFind->icon()));
- ui.actionFilePrint->setIcon(QIcon::fromTheme("document-print" , ui.actionFilePrint->icon()));
- ui.actionZoomOut->setIcon(QIcon::fromTheme("zoom-out" , ui.actionZoomOut->icon()));
- ui.actionZoomIn->setIcon(QIcon::fromTheme("zoom-in" , ui.actionZoomIn->icon()));
- ui.actionSyncToc->setIcon(QIcon::fromTheme("view-refresh" , ui.actionSyncToc->icon()));
-#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);
-
- box.setText(QString::fromLatin1("<center><img src=\":/trolltech/assistant/images/assistant-128.png\">"
- "<h3>%1</h3>"
- "<p>Version %2</p></center>"
- "<p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p>")
- .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)));
- 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;
-}
-
-#ifndef QT_NO_PRINTER
-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;
- }
-};
-#endif //QT_NO_PRINTER
-
-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
deleted file mode 100644
index a08064d..0000000
--- a/tools/assistant/compat/mainwindow.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 535e27e..0000000
--- a/tools/assistant/compat/mainwindow.ui
+++ /dev/null
@@ -1,457 +0,0 @@
-<ui version="4.0" >
- <comment>*********************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-*********************************************************************</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
deleted file mode 100644
index 2878a20..0000000
--- a/tools/assistant/compat/profile.cpp
+++ /dev/null
@@ -1,196 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 1aa9719..0000000
--- a/tools/assistant/compat/profile.h
+++ /dev/null
@@ -1,95 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index c3c1572..0000000
--- a/tools/assistant/compat/tabbedbrowser.cpp
+++ /dev/null
@@ -1,530 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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(QPoint)), SLOT(openTabMenu(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(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
deleted file mode 100644
index 0e32505..0000000
--- a/tools/assistant/compat/tabbedbrowser.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index 411f145..0000000
--- a/tools/assistant/compat/tabbedbrowser.ui
+++ /dev/null
@@ -1,233 +0,0 @@
-<ui version="4.0" >
- <author></author>
- <comment>*********************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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
deleted file mode 100644
index b2e7e98..0000000
--- a/tools/assistant/compat/topicchooser.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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.ui b/tools/assistant/compat/topicchooser.ui
deleted file mode 100644
index 18ff61b..0000000
--- a/tools/assistant/compat/topicchooser.ui
+++ /dev/null
@@ -1,162 +0,0 @@
-<ui version="4.0" >
- <comment>*********************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@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/lib/fulltextsearch/fulltextsearch.pro b/tools/assistant/lib/fulltextsearch/fulltextsearch.pro
index e0cd13a..4d2fddb 100644
--- a/tools/assistant/lib/fulltextsearch/fulltextsearch.pro
+++ b/tools/assistant/lib/fulltextsearch/fulltextsearch.pro
@@ -29,7 +29,7 @@ unix:QMAKE_PKGCONFIG_REQUIRES = QtCore
CONFIG(exceptions_off) {
CONFIG -= exceptions_off
CONFIG += exceptions
- !win32|win32-g++ {
+ !win32|win32-g++* {
QMAKE_CFLAGS -= -fno-exceptions
QMAKE_CXXFLAGS -= -fno-exceptions
QMAKE_LFLAGS -= -fno-exceptions
@@ -46,5 +46,5 @@ win32-msvc.net | win32-msvc2* {
# 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\.//')
+ DEFINES += Q_SOLARIS_VERSION=$$system(uname -r | sed -e 's/5\\.//')
}
diff --git a/tools/assistant/lib/fulltextsearch/qclucene-config_p.h b/tools/assistant/lib/fulltextsearch/qclucene-config_p.h
index 0c70718..387d64d 100644
--- a/tools/assistant/lib/fulltextsearch/qclucene-config_p.h
+++ b/tools/assistant/lib/fulltextsearch/qclucene-config_p.h
@@ -314,14 +314,12 @@ configure.
#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__)
+ /* 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. */
diff --git a/tools/assistant/lib/fulltextsearch/qclucene_global_p.h b/tools/assistant/lib/fulltextsearch/qclucene_global_p.h
index f4b744d..206725b 100644
--- a/tools/assistant/lib/fulltextsearch/qclucene_global_p.h
+++ b/tools/assistant/lib/fulltextsearch/qclucene_global_p.h
@@ -36,7 +36,7 @@
#include <QtCore/QChar>
#include <QtCore/QString>
-#if !defined(_MSC_VER) && defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
+#if !defined(_MSC_VER) && !defined(__MINGW32__) && defined(_CL_HAVE_WCHAR_H) && defined(_CL_HAVE_WCHAR_T)
# if !defined(TCHAR)
# define TCHAR wchar_t
# endif
diff --git a/tools/assistant/lib/fulltextsearch/qsort_p.h b/tools/assistant/lib/fulltextsearch/qsort_p.h
index e6f024b..5c75c58 100644
--- a/tools/assistant/lib/fulltextsearch/qsort_p.h
+++ b/tools/assistant/lib/fulltextsearch/qsort_p.h
@@ -64,15 +64,15 @@ private:
class QHELP_EXPORT QCLuceneSort
{
public:
- QCLuceneSort();
- QCLuceneSort(const QStringList &fieldNames);
- QCLuceneSort(const QString &field, bool reverse = false);
+ QCLuceneSort();
+ explicit QCLuceneSort(const QStringList &fieldNames);
+ explicit 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);
+ void setSort(const QString &field, bool reverse = false);
protected:
friend class QCLuceneHits;
diff --git a/tools/assistant/lib/lib.pro b/tools/assistant/lib/lib.pro
index 51933de..26d3456 100644
--- a/tools/assistant/lib/lib.pro
+++ b/tools/assistant/lib/lib.pro
@@ -23,7 +23,6 @@ unix:QMAKE_PKGCONFIG_REQUIRES += QtNetwork \
QtSql \
QtXml
LIBS_PRIVATE += -l$$qclucene
-
RESOURCES += helpsystem.qrc
SOURCES += qhelpenginecore.cpp \
qhelpengine.cpp \
@@ -41,6 +40,7 @@ SOURCES += qhelpenginecore.cpp \
qhelpsearchindexwriter_default.cpp \
qhelpsearchindexreader_default.cpp \
qhelpsearchindexreader.cpp \
+ qclucenefieldnames.cpp \
qhelp_global.cpp
# access to clucene
@@ -63,7 +63,8 @@ HEADERS += qhelpenginecore.h \
qhelpsearchindex_default_p.h \
qhelpsearchindexwriter_default_p.h \
qhelpsearchindexreader_default_p.h \
- qhelpsearchindexreader_p.h
+ qhelpsearchindexreader_p.h \
+ qclucenefieldnames_p.h
# access to clucene
HEADERS += qhelpsearchindexwriter_clucene_p.h \
diff --git a/tools/assistant/lib/qclucenefieldnames.cpp b/tools/assistant/lib/qclucenefieldnames.cpp
new file mode 100644
index 0000000..5c3a474
--- /dev/null
+++ b/tools/assistant/lib/qclucenefieldnames.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qclucenefieldnames_p.h"
+
+QT_BEGIN_NAMESPACE
+
+namespace fulltextsearch {
+namespace clucene {
+const QString AttributeField(QLatin1String("attribute"));
+const QString ContentField(QLatin1String("content"));
+const QString NamespaceField(QLatin1String("namespace"));
+const QString PathField(QLatin1String("path"));
+const QString TitleField(QLatin1String("title"));
+const QString TitleTokenizedField(QLatin1String("titleTokenized"));
+} // namespace clucene
+} // namespace fulltextsearch
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/fontsettingsdialog.h b/tools/assistant/lib/qclucenefieldnames_p.h
index 6599d2a..a611382 100644
--- a/tools/assistant/compat/fontsettingsdialog.h
+++ b/tools/assistant/lib/qclucenefieldnames_p.h
@@ -39,39 +39,25 @@
**
****************************************************************************/
-#ifndef _FONT_SETTINGS_DIALOG_H_
-#define _FONT_SETTINGS_DIALOG_H_
+#ifndef QCLUCENEFIELDNAMES_P_H
+#define QCLUCENEFIELDNAMES_P_H
-#include <QtCore/QObject>
-#include <QtGui/QDialog>
+#include <QtCore/QtGlobal>
+#include <QtCore/QString>
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_
-
+namespace fulltextsearch {
+namespace clucene {
+ extern const QString AttributeField;
+ extern const QString ContentField;
+ extern const QString NamespaceField;
+ extern const QString PathField;
+ extern const QString TitleField;
+ extern const QString TitleTokenizedField;
+} // namespace clucene
+} // namespace fulltextsearch
QT_END_NAMESPACE
+
+#endif // QCLUCENEFIELDNAMES_P_H
diff --git a/tools/assistant/lib/qhelp_global.cpp b/tools/assistant/lib/qhelp_global.cpp
index 539b504..c2c916b 100644
--- a/tools/assistant/lib/qhelp_global.cpp
+++ b/tools/assistant/lib/qhelp_global.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include <QtCore/QCoreApplication>
#include <QtCore/QRegExp>
#include <QtCore/QMutexLocker>
#include <QtGui/QTextDocument>
@@ -55,12 +56,12 @@ QString QHelpGlobal::uniquifyConnectionName(const QString &name, void *pointer)
counter = 0;
return QString::fromLatin1("%1-%2-%3").
- arg(name).arg(long(pointer)).arg(counter);
+ arg(name).arg(quintptr(pointer)).arg(counter);
}
QString QHelpGlobal::documentTitle(const QString &content)
{
- QString title = QObject::tr("Untitled");
+ QString title = QCoreApplication::translate("QHelp", "Untitled");
if (!content.isEmpty()) {
int start = content.indexOf(QLatin1String("<title>"), 0, Qt::CaseInsensitive) + 7;
int end = content.indexOf(QLatin1String("</title>"), 0, Qt::CaseInsensitive);
@@ -86,17 +87,18 @@ QString QHelpGlobal::codecFromData(const QByteArray &data)
QString QHelpGlobal::codecFromHtmlData(const QByteArray &data)
{
- QString content = QString::fromUtf8(data.constData(), data.size());
- int start = content.indexOf(QLatin1String("<meta"), 0, Qt::CaseInsensitive);
+ QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size()));
+ int start = head.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();
+ const int end = head.indexOf(QLatin1Char('>'), start) + 1;
+ if (end <= start)
+ break;
+ const QString &meta = head.mid(start, end - start).toLower();
if (r.indexIn(meta) != -1)
return r.cap(1);
- start = content.indexOf(QLatin1String("<meta"), end,
+ start = head.indexOf(QLatin1String("<meta"), end,
Qt::CaseInsensitive);
}
}
@@ -105,8 +107,8 @@ QString QHelpGlobal::codecFromHtmlData(const QByteArray &data)
QString QHelpGlobal::codecFromXmlData(const QByteArray &data)
{
- QString content = QString::fromUtf8(data.constData(), data.size());
+ QString head = QString::fromUtf8(data.constData(), qMin(1000, data.size()));
const QRegExp encodingExp(QLatin1String("^\\s*<\\?xml version="
"\"\\d\\.\\d\" encoding=\"([^\"]+)\"\\?>.*"));
- return encodingExp.exactMatch(content) ? encodingExp.cap(1) : QString();
+ return encodingExp.exactMatch(head) ? encodingExp.cap(1) : QString();
}
diff --git a/tools/assistant/lib/qhelpcollectionhandler.cpp b/tools/assistant/lib/qhelpcollectionhandler.cpp
index cb7e457..bd8dc20 100644
--- a/tools/assistant/lib/qhelpcollectionhandler.cpp
+++ b/tools/assistant/lib/qhelpcollectionhandler.cpp
@@ -114,6 +114,9 @@ bool QHelpCollectionHandler::openCollectionFile()
return false;
}
+ m_query.exec(QLatin1String("PRAGMA synchronous=OFF"));
+ m_query.exec(QLatin1String("PRAGMA cache_size=3000"));
+
m_query.exec(QLatin1String("SELECT COUNT(*) FROM sqlite_master WHERE TYPE=\'table\'"
"AND Name=\'NamespaceTable\'"));
m_query.next();
@@ -163,6 +166,9 @@ bool QHelpCollectionHandler::copyCollectionFile(const QString &fileName)
return false;
}
+ copyQuery->exec(QLatin1String("PRAGMA synchronous=OFF"));
+ copyQuery->exec(QLatin1String("PRAGMA cache_size=3000"));
+
if (!createTables(copyQuery)) {
emit error(tr("Cannot copy collection file: %1").arg(colFile));
return false;
@@ -308,10 +314,8 @@ bool QHelpCollectionHandler::addCustomFilter(const QString &filterName,
m_query.prepare(QLatin1String("SELECT Id FROM FilterNameTable WHERE Name=?"));
m_query.bindValue(0, filterName);
m_query.exec();
- while (m_query.next()) {
+ if (m_query.next())
nameId = m_query.value(0).toInt();
- break;
- }
m_query.exec(QLatin1String("SELECT Id, Name FROM FilterAttributeTable"));
QStringList idsToInsert = attributes;
@@ -584,6 +588,8 @@ void QHelpCollectionHandler::optimizeDatabase(const QString &fileName)
}
QSqlQuery query(db);
+ db.exec(QLatin1String("PRAGMA synchronous=OFF"));
+ db.exec(QLatin1String("PRAGMA cache_size=3000"));
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)"));
diff --git a/tools/assistant/lib/qhelpcollectionhandler_p.h b/tools/assistant/lib/qhelpcollectionhandler_p.h
index 8efe507..8901b06 100644
--- a/tools/assistant/lib/qhelpcollectionhandler_p.h
+++ b/tools/assistant/lib/qhelpcollectionhandler_p.h
@@ -76,7 +76,8 @@ public:
};
typedef QList<DocInfo> DocInfoList;
- QHelpCollectionHandler(const QString &collectionFile, QObject *parent = 0);
+ explicit QHelpCollectionHandler(const QString &collectionFile,
+ QObject *parent = 0);
~QHelpCollectionHandler();
QString collectionFile() const;
diff --git a/tools/assistant/lib/qhelpcontentwidget.cpp b/tools/assistant/lib/qhelpcontentwidget.cpp
index a80dc39..6f3f942 100644
--- a/tools/assistant/lib/qhelpcontentwidget.cpp
+++ b/tools/assistant/lib/qhelpcontentwidget.cpp
@@ -370,7 +370,8 @@ void QHelpContentModel::invalidateContents(bool onShutDown)
delete d->rootItem;
d->rootItem = 0;
}
- reset();
+ if (!onShutDown)
+ reset();
}
/*!
diff --git a/tools/assistant/lib/qhelpdbreader.cpp b/tools/assistant/lib/qhelpdbreader.cpp
index 6dd949a..5c0f595 100644
--- a/tools/assistant/lib/qhelpdbreader.cpp
+++ b/tools/assistant/lib/qhelpdbreader.cpp
@@ -205,7 +205,7 @@ QByteArray QHelpDBReader::fileData(const QString &virtualFolder,
"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(1, QString(QLatin1String("./") + filePath));
m_query->bindValue(2, virtualFolder);
m_query->bindValue(3, m_namespace);
m_query->exec();
diff --git a/tools/assistant/lib/qhelpengine.cpp b/tools/assistant/lib/qhelpengine.cpp
index 96cf0fd..e8ae31b 100644
--- a/tools/assistant/lib/qhelpengine.cpp
+++ b/tools/assistant/lib/qhelpengine.cpp
@@ -75,14 +75,15 @@ void QHelpEnginePrivate::init(const QString &collectionFile,
{
QHelpEngineCorePrivate::init(collectionFile, helpEngineCore);
- contentModel = new QHelpContentModel(this);
- indexModel = new QHelpIndexModel(this);
-
- connect(helpEngineCore, SIGNAL(setupFinished()),
- this, SLOT(applyCurrentFilter()));
- connect(helpEngineCore, SIGNAL(currentFilterChanged(QString)),
- this, SLOT(applyCurrentFilter()));
-
+ if (!contentModel)
+ contentModel = new QHelpContentModel(this);
+ if (!indexModel)
+ indexModel = new QHelpIndexModel(this);
+
+ connect(helpEngineCore, SIGNAL(setupFinished()), this,
+ SLOT(applyCurrentFilter()));
+ connect(helpEngineCore, SIGNAL(currentFilterChanged(QString)), this,
+ SLOT(applyCurrentFilter()));
}
void QHelpEnginePrivate::applyCurrentFilter()
diff --git a/tools/assistant/lib/qhelpengine.h b/tools/assistant/lib/qhelpengine.h
index 2bdb983..3577f4b 100644
--- a/tools/assistant/lib/qhelpengine.h
+++ b/tools/assistant/lib/qhelpengine.h
@@ -62,7 +62,7 @@ class QHELP_EXPORT QHelpEngine : public QHelpEngineCore
Q_OBJECT
public:
- QHelpEngine(const QString &collectionFile, QObject *parent = 0);
+ explicit QHelpEngine(const QString &collectionFile, QObject *parent = 0);
~QHelpEngine();
QHelpContentModel *contentModel() const;
diff --git a/tools/assistant/lib/qhelpenginecore.cpp b/tools/assistant/lib/qhelpenginecore.cpp
index 066e4d5..d72dfe4 100644
--- a/tools/assistant/lib/qhelpenginecore.cpp
+++ b/tools/assistant/lib/qhelpenginecore.cpp
@@ -119,7 +119,7 @@ bool QHelpEngineCorePrivate::setup()
QHelpDBReader *reader = new QHelpDBReader(absFileName,
QHelpGlobal::uniquifyConnectionName(info.fileName, this), this);
if (!reader->init()) {
- emit q->warning(tr("Cannot open documentation file %1: %2!")
+ emit q->warning(QHelpEngineCore::tr("Cannot open documentation file %1: %2!")
.arg(absFileName, reader->errorMessage()));
continue;
}
@@ -406,8 +406,9 @@ QStringList QHelpEngineCore::customFilters() const
/*!
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.
+ are specified by \a attributes. If the filter already exists,
+ its attribute set is replaced. The function returns true if
+ the operation succeeded, otherwise it returns false.
\sa customFilters(), removeCustomFilter()
*/
@@ -705,7 +706,7 @@ QVariant QHelpEngineCore::metaData(const QString &documentationFileName,
}
/*!
- Returns a description of the last error that occured.
+ Returns a description of the last error that occurred.
*/
QString QHelpEngineCore::error() const
{
diff --git a/tools/assistant/lib/qhelpenginecore.h b/tools/assistant/lib/qhelpenginecore.h
index 118c310..db25c0b 100644
--- a/tools/assistant/lib/qhelpenginecore.h
+++ b/tools/assistant/lib/qhelpenginecore.h
@@ -65,7 +65,7 @@ class QHELP_EXPORT QHelpEngineCore : public QObject
Q_PROPERTY(QString currentFilter READ currentFilter WRITE setCurrentFilter)
public:
- QHelpEngineCore(const QString &collectionFile, QObject *parent = 0);
+ explicit QHelpEngineCore(const QString &collectionFile, QObject *parent = 0);
virtual ~QHelpEngineCore();
bool setupData();
diff --git a/tools/assistant/lib/qhelpgenerator.cpp b/tools/assistant/lib/qhelpgenerator.cpp
index 4b94ebf..f94031b 100644
--- a/tools/assistant/lib/qhelpgenerator.cpp
+++ b/tools/assistant/lib/qhelpgenerator.cpp
@@ -47,6 +47,7 @@
#include <QtCore/QFileInfo>
#include <QtCore/QDir>
#include <QtCore/QDebug>
+#include <QtCore/QSet>
#include <QtCore/QVariant>
#include <QtCore/QDateTime>
#include <QtCore/QTextCodec>
@@ -190,6 +191,9 @@ bool QHelpGenerator::generate(QHelpDataInterface *helpData,
return false;
}
+ d->query->exec(QLatin1String("PRAGMA synchronous=OFF"));
+ d->query->exec(QLatin1String("PRAGMA cache_size=3000"));
+
addProgress(1.0);
createTables();
insertFileNotFoundFile();
@@ -537,7 +541,8 @@ bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPa
}
int fileId = -1;
- if (!d->fileMap.contains(fileName)) {
+ QMap<QString, int>::Iterator fileMapIt = d->fileMap.find(fileName);
+ if (fileMapIt == d->fileMap.end()) {
fileDataList.append(qCompress(data));
fileNameData.name = fileName;
@@ -551,18 +556,20 @@ bool QHelpGenerator::insertFiles(const QStringList &files, const QString &rootPa
++tableFileId;
} else {
- fileId = d->fileMap.value(fileName);
+ fileId = fileMapIt.value();
+ QSet<int> &fileFilterSet = d->fileFilterMap[fileId];
+ QSet<int> &tmpFileFilterSet = tmpFileFilterMap[fileId];
foreach (const 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 (!fileFilterSet.contains(filter)
+ && !tmpFileFilterSet.contains(filter)) {
+ fileFilterSet.insert(filter);
+ tmpFileFilterSet.insert(filter);
}
}
}
}
- if (tmpFileFilterMap.count()) {
+ if (!tmpFileFilterMap.isEmpty()) {
d->query->exec(QLatin1String("BEGIN"));
QMap<int, QSet<int> >::const_iterator it = tmpFileFilterMap.constBegin();
while (it != tmpFileFilterMap.constEnd()) {
@@ -625,8 +632,7 @@ bool QHelpGenerator::registerCustomFilter(const QString &filterName,
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());
+ idsToInsert.removeAll(d->query->value(1).toString());
}
foreach (const QString &id, idsToInsert) {
@@ -674,7 +680,7 @@ bool QHelpGenerator::registerCustomFilter(const QString &filterName,
return true;
}
-bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> keywords,
+bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> &keywords,
const QStringList &filterAttributes)
{
if (!d->query)
@@ -704,7 +710,18 @@ bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> keywords,
int i = 0;
d->query->exec(QLatin1String("BEGIN"));
+ QSet<QString> indices;
foreach (const QHelpDataIndexItem &itm, keywords) {
+ // Identical ids make no sense and just confuse the Assistant user,
+ // so we ignore all repetitions.
+ if (indices.contains(itm.identifier))
+ continue;
+
+ // Still empty ids should be ignored, as otherwise we will include only
+ // the first keyword with an empty id.
+ if (!itm.identifier.isEmpty())
+ indices.insert(itm.identifier);
+
pos = itm.reference.indexOf(QLatin1Char('#'));
fileName = itm.reference.left(pos);
if (pos > -1)
@@ -716,8 +733,9 @@ bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> keywords,
if (fName.startsWith(QLatin1String("./")))
fName = fName.mid(2);
- if (d->fileMap.contains(fName))
- fileId = d->fileMap.value(fName);
+ QMap<QString, int>::ConstIterator it = d->fileMap.find(fName);
+ if (it != d->fileMap.end())
+ fileId = it.value();
else
fileId = 1;
@@ -749,7 +767,7 @@ bool QHelpGenerator::insertKeywords(const QList<QHelpDataIndexItem> keywords,
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())
+ if (d->query->next() && d->query->value(0).toInt() >= indices.count())
return true;
return false;
}
@@ -824,4 +842,68 @@ bool QHelpGenerator::insertMetaData(const QMap<QString, QVariant> &metaData)
return true;
}
+bool QHelpGenerator::checkLinks(const QHelpDataInterface &helpData)
+{
+ /*
+ * Step 1: Gather the canoncal file paths of all files in the project.
+ * We use a set, because there will be a lot of look-ups.
+ */
+ QSet<QString> files;
+ foreach (const QHelpDataFilterSection &filterSection, helpData.filterSections()) {
+ foreach (const QString &file, filterSection.files()) {
+ QFileInfo fileInfo(helpData.rootPath() + QDir::separator() + file);
+ const QString &canonicalFileName = fileInfo.canonicalFilePath();
+ if (!fileInfo.exists())
+ emit warning(tr("File '%1' does not exist.").arg(file));
+ else
+ files.insert(canonicalFileName);
+ }
+ }
+
+ /*
+ * Step 2: Check the hypertext and image references of all HTML files.
+ * Note that we don't parse the files, but simply grep for the
+ * respective HTML elements. Therefore. contents that are e.g.
+ * commented out can cause false warning.
+ */
+ bool allLinksOk = true;
+ foreach (const QString &fileName, files) {
+ if (!fileName.endsWith(QLatin1String("html"))
+ && !fileName.endsWith(QLatin1String("htm")))
+ continue;
+ QFile htmlFile(fileName);
+ if (!htmlFile.open(QIODevice::ReadOnly)) {
+ emit warning(tr("File '%1' cannot be opened.").arg(fileName));
+ continue;
+ }
+ const QRegExp linkPattern(QLatin1String("<(?:a href|img src)=\"?([^#\">]+)[#\">]"));
+ QTextStream stream(&htmlFile);
+ const QString codec = QHelpGlobal::codecFromData(htmlFile.read(1000));
+ stream.setCodec(QTextCodec::codecForName(codec.toLatin1().constData()));
+ const QString &content = stream.readAll();
+ QStringList invalidLinks;
+ for (int pos = linkPattern.indexIn(content); pos != -1;
+ pos = linkPattern.indexIn(content, pos + 1)) {
+ const QString& linkedFileName = linkPattern.cap(1);
+ if (linkedFileName.contains(QLatin1String("://")))
+ continue;
+ const QString curDir = QFileInfo(fileName).dir().path();
+ const QString &canonicalLinkedFileName =
+ QFileInfo(curDir + QDir::separator() + linkedFileName).canonicalFilePath();
+ if (!files.contains(canonicalLinkedFileName)
+ && !invalidLinks.contains(canonicalLinkedFileName)) {
+ emit warning(tr("File '%1' contains an invalid link to file '%2'").
+ arg(fileName).arg(linkedFileName));
+ allLinksOk = false;
+ invalidLinks.append(canonicalLinkedFileName);
+ }
+ }
+ }
+
+ if (!allLinksOk)
+ d->error = tr("Invalid links in HTML files.");
+ return allLinksOk;
+}
+
QT_END_NAMESPACE
+
diff --git a/tools/assistant/lib/qhelpgenerator_p.h b/tools/assistant/lib/qhelpgenerator_p.h
index c589e25..823a07a 100644
--- a/tools/assistant/lib/qhelpgenerator_p.h
+++ b/tools/assistant/lib/qhelpgenerator_p.h
@@ -74,6 +74,7 @@ public:
bool generate(QHelpDataInterface *helpData,
const QString &outputFileName);
+ bool checkLinks(const QHelpDataInterface &helpData);
QString error() const;
Q_SIGNALS:
@@ -96,7 +97,7 @@ private:
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,
+ bool insertKeywords(const QList<QHelpDataIndexItem> &keywords,
const QStringList &filterAttributes);
bool insertFiles(const QStringList &files, const QString &rootPath,
const QStringList &filterAttributes);
diff --git a/tools/assistant/lib/qhelpindexwidget.cpp b/tools/assistant/lib/qhelpindexwidget.cpp
index 270bcdd..11b9966 100644
--- a/tools/assistant/lib/qhelpindexwidget.cpp
+++ b/tools/assistant/lib/qhelpindexwidget.cpp
@@ -244,7 +244,8 @@ void QHelpIndexModel::invalidateIndex(bool onShutDown)
disconnect(this, SLOT(insertIndices()));
d->indexProvider->stopCollecting();
d->indices.clear();
- filter(QString());
+ if (!onShutDown)
+ filter(QString());
}
/*!
diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp
index 869a446..5247847 100644
--- a/tools/assistant/lib/qhelpprojectdata.cpp
+++ b/tools/assistant/lib/qhelpprojectdata.cpp
@@ -41,11 +41,13 @@
#include "qhelpprojectdata_p.h"
+#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QStack>
#include <QtCore/QMap>
#include <QtCore/QRegExp>
+#include <QtCore/QUrl>
#include <QtCore/QVariant>
#include <QtXml/QXmlStreamReader>
@@ -76,13 +78,14 @@ private:
void readFiles();
void raiseUnknownTokenError();
void addMatchingFiles(const QString &pattern);
+ bool hasValidSyntax(const QString &nameSpace, const QString &vFolder) const;
QMap<QString, QStringList> dirEntriesCache;
};
void QHelpProjectDataPrivate::raiseUnknownTokenError()
{
- raiseError(QObject::tr("Unknown token."));
+ raiseError(QCoreApplication::translate("QHelpProject", "Unknown token."));
}
void QHelpProjectDataPrivate::readData(const QByteArray &contents)
@@ -95,12 +98,14 @@ void QHelpProjectDataPrivate::readData(const QByteArray &contents)
&& attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
readProject();
else
- raiseError(QObject::tr("Unknown token. Expected \"QtHelpProject\"!"));
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Unknown token. Expected \"QtHelpProject\"!"));
}
}
if (hasError()) {
- raiseError(QObject::tr("Error in line %1: %2").arg(lineNumber())
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Error in line %1: %2").arg(lineNumber())
.arg(errorString()));
}
}
@@ -112,12 +117,14 @@ void QHelpProjectDataPrivate::readProject()
if (isStartElement()) {
if (name() == QLatin1String("virtualFolder")) {
virtualFolder = readElementText();
- if (virtualFolder.contains(QLatin1String("/")))
- raiseError(QObject::tr("A virtual folder must not contain a \'/\' character!"));
+ if (!hasValidSyntax(QLatin1String("test"), virtualFolder))
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Virtual folder has invalid syntax."));
} else if (name() == QLatin1String("namespace")) {
namespaceName = readElementText();
- if (namespaceName.contains(QLatin1String("/")))
- raiseError(QObject::tr("A namespace must not contain a \'/\' character!"));
+ if (!hasValidSyntax(namespaceName, QLatin1String("test")))
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Namespace has invalid syntax."));
} else if (name() == QLatin1String("customFilter")) {
readCustomFilter();
} else if (name() == QLatin1String("filterSection")) {
@@ -125,17 +132,21 @@ void QHelpProjectDataPrivate::readProject()
} else if (name() == QLatin1String("metaData")) {
QString n = attributes().value(QLatin1String("name")).toString();
if (!metaData.contains(n))
- metaData[n] = attributes().value(QLatin1String("value")).toString();
+ metaData[n]
+ = attributes().value(QLatin1String("value")).toString();
else
- metaData.insert(n, attributes().value(QLatin1String("value")).toString());
+ 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."));
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Missing namespace in QtHelpProject."));
else if (virtualFolder.isEmpty())
- raiseError(QObject::tr("Missing virtual folder in QtHelpProject"));
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "Missing virtual folder in QtHelpProject"));
break;
}
}
@@ -223,12 +234,14 @@ void QHelpProjectDataPrivate::readKeywords()
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()));
+ raiseError(QCoreApplication::translate("QHelpProject",
+ "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();
}
@@ -305,6 +318,24 @@ void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
filterSectionList.last().addFile(pattern);
}
+bool QHelpProjectDataPrivate::hasValidSyntax(const QString &nameSpace,
+ const QString &vFolder) const
+{
+ const QLatin1Char slash('/');
+ if (nameSpace.contains(slash) || vFolder.contains(slash))
+ return false;
+ QUrl url;
+ const QLatin1String scheme("qthelp");
+ url.setScheme(scheme);
+ const QString canonicalNamespace = nameSpace.toLower();
+ url.setHost(canonicalNamespace);
+ url.setPath(vFolder);
+
+ const QString expectedUrl(scheme + QLatin1String("://")
+ + canonicalNamespace + slash + vFolder);
+ return url.isValid() && url.toString() == expectedUrl;
+}
+
/*!
\internal
\class QHelpProjectData
@@ -346,8 +377,8 @@ 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);
+ d->errorMsg = QCoreApplication::translate("QHelpProject",
+ "The input file %1 could not be opened!").arg(fileName);
return false;
}
diff --git a/tools/assistant/lib/qhelpsearchengine.cpp b/tools/assistant/lib/qhelpsearchengine.cpp
index 9914efa..164163a 100644
--- a/tools/assistant/lib/qhelpsearchengine.cpp
+++ b/tools/assistant/lib/qhelpsearchengine.cpp
@@ -263,17 +263,17 @@ private:
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
+ on the end of the indexing process the indexingFinished() is emitted. 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
+ functionality to set up a proper search queries 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
+ is emitted and after the search has finished the searchingFinished() signal is emitted. The
search process can be stopped by calling cancelSearching().
If the search succeeds, the searchingFinished() will be called with the search hits count,
@@ -318,7 +318,7 @@ private:
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.
+ after the signal is emitted.
*/
QHelpSearchEngine::QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent)
: QObject(parent)
@@ -434,7 +434,7 @@ void QHelpSearchEngine::cancelSearching()
}
/*!
- Starts the search process using the given list of querys \a queryList
+ Starts the search process using the given list of queries \a queryList
build by the search field name and the values to search for.
*/
void QHelpSearchEngine::search(const QList<QHelpSearchQuery> &queryList)
diff --git a/tools/assistant/lib/qhelpsearchengine.h b/tools/assistant/lib/qhelpsearchengine.h
index 545360c..0b07920 100644
--- a/tools/assistant/lib/qhelpsearchengine.h
+++ b/tools/assistant/lib/qhelpsearchengine.h
@@ -80,7 +80,8 @@ class QHELP_EXPORT QHelpSearchEngine : public QObject
Q_OBJECT
public:
- QHelpSearchEngine(QHelpEngineCore *helpEngine, QObject *parent = 0);
+ explicit QHelpSearchEngine(QHelpEngineCore *helpEngine,
+ QObject *parent = 0);
~QHelpSearchEngine();
QHelpSearchQueryWidget* queryWidget();
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
index b050361..75cc2b9 100644
--- a/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene.cpp
@@ -39,16 +39,19 @@
**
****************************************************************************/
-#include "qhelpenginecore.h"
-#include "fulltextsearch/qsearchable_p.h"
-#include "fulltextsearch/qqueryparser_p.h"
#include "fulltextsearch/qindexreader_p.h"
+#include "fulltextsearch/qqueryparser_p.h"
+#include "fulltextsearch/qsearchable_p.h"
+#include "qclucenefieldnames_p.h"
+#include "qhelpenginecore.h"
+
#include "qhelpsearchindexreader_clucene_p.h"
#include <QtCore/QDir>
#include <QtCore/QSet>
#include <QtCore/QString>
#include <QtCore/QFileInfo>
+#include <QtCore/QSharedPointer>
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
#include <QtCore/QMutexLocker>
@@ -107,64 +110,88 @@ void QHelpSearchIndexReaderClucene::run()
#if !defined(QT_NO_EXCEPTIONS)
try {
#endif
- QCLuceneBooleanQuery booleanQuery;
+ QCLuceneBooleanQuery booleanQueryTitle;
+ QCLuceneBooleanQuery booleanQueryContent;
QCLuceneStandardAnalyzer analyzer;
- if (!buildQuery(booleanQuery, queryList, analyzer)) {
+ const QStringList& attribList =
+ engine.filterAttributes(engine.currentFilter());
+ bool titleQueryIsValid = buildQuery(queryList, TitleTokenizedField,
+ attribList, booleanQueryTitle, analyzer);
+ bool contentQueryIsValid = buildQuery(queryList, ContentField,
+ attribList, booleanQueryContent, analyzer);
+ if (!titleQueryIsValid && !contentQueryIsValid) {
emit searchingFinished(0);
return;
}
- const QStringList attribList = engine.filterAttributes(engine.currentFilter());
- if (!attribList.isEmpty()) {
- QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+")
- + attribList.join(QLatin1String(" +")), QLatin1String("attribute"), analyzer);
+ QCLuceneIndexSearcher indexSearcher(indexPath);
- if (!query) {
+ // QCLuceneHits object must be allocated on the heap, because
+ // there is no default constructor.
+ QSharedPointer<QCLuceneHits> titleHits;
+ QSharedPointer<QCLuceneHits> contentHits;
+ if (titleQueryIsValid) {
+ titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryTitle)));
+ }
+ if (contentQueryIsValid) {
+ contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryContent)));
+ }
+ bool boost = true;
+ if ((titleHits.isNull() || titleHits->length() == 0)
+ && (contentHits.isNull() || contentHits->length() == 0)) {
+ booleanQueryTitle = QCLuceneBooleanQuery();
+ booleanQueryContent = QCLuceneBooleanQuery();
+ titleQueryIsValid =
+ buildTryHarderQuery(queryList, TitleTokenizedField,
+ attribList, booleanQueryTitle, analyzer);
+ contentQueryIsValid =
+ buildTryHarderQuery(queryList, ContentField, attribList,
+ booleanQueryContent, analyzer);
+ if (!titleQueryIsValid && !contentQueryIsValid) {
emit searchingFinished(0);
return;
}
- booleanQuery.add(query, true, true, false);
- }
-
- QCLuceneIndexSearcher indexSearcher(indexPath);
- QCLuceneHits hits = indexSearcher.search(booleanQuery);
-
- bool boost = true;
- QCLuceneBooleanQuery tryHarderQuery;
- if (hits.length() == 0) {
- if (buildTryHarderQuery(tryHarderQuery, queryList, analyzer)) {
- if (!attribList.isEmpty()) {
- QCLuceneQuery* query = QCLuceneQueryParser::parse(QLatin1String("+")
- + attribList.join(QLatin1String(" +")), QLatin1String("attribute"),
- analyzer);
- tryHarderQuery.add(query, true, true, false);
- }
- hits = indexSearcher.search(tryHarderQuery);
- boost = (hits.length() == 0);
+ if (titleQueryIsValid) {
+ titleHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryTitle)));
}
+ if (contentQueryIsValid) {
+ contentHits = QSharedPointer<QCLuceneHits>(new QCLuceneHits(
+ indexSearcher.search(booleanQueryContent)));
+ }
+ boost = false;
}
+ QList<QSharedPointer<QCLuceneHits> > cluceneHitsList;
+ if (!titleHits.isNull())
+ cluceneHitsList.append(titleHits);
+ if (!contentHits.isNull())
+ cluceneHitsList.append(contentHits);
QSet<QString> pathSet;
QCLuceneDocument document;
const QStringList namespaceList = engine.registeredDocumentations();
- 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();
+ foreach (const QSharedPointer<QCLuceneHits> &hits, cluceneHitsList) {
+ for (qint32 i = 0; i < hits->length(); i++) {
+ document = hits->document(i);
+ const QString path = document.get(PathField);
+ if (!pathSet.contains(path) && namespaceList.contains(
+ document.get(NamespaceField), Qt::CaseInsensitive)) {
+ pathSet.insert(path);
+ hitList.append(qMakePair(path, document.get(TitleField)));
+ }
+ document.clear();
- mutex.lock();
- if (m_cancel) {
+ mutex.lock();
+ if (m_cancel) {
+ mutex.unlock();
+ emit searchingFinished(0);
+ return;
+ }
mutex.unlock();
- emit searchingFinished(0);
- return;
}
- mutex.unlock();
}
indexSearcher.close();
@@ -184,150 +211,211 @@ void QHelpSearchIndexReaderClucene::run()
}
}
-bool QHelpSearchIndexReaderClucene::defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery,
- QCLuceneStandardAnalyzer &analyzer)
+bool QHelpSearchIndexReaderClucene::buildQuery(
+ const QList<QHelpSearchQuery> &queries, const QString &fieldName,
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &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;
+ bool queryIsValid = false;
+ foreach (const QHelpSearchQuery &query, queries) {
+ if (fieldName != ContentField && isNegativeQuery(query)) {
+ queryIsValid = false;
+ break;
+ }
+ switch (query.fieldName) {
+ case QHelpSearchQuery::FUZZY:
+ if (addFuzzyQuery(query, fieldName, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::WITHOUT:
+ if (fieldName != ContentField)
+ return false;
+ if (addWithoutQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::PHRASE:
+ if (addPhraseQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::ALL:
+ if (addAllQuery(query, fieldName, booleanQuery))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::DEFAULT:
+ if (addDefaultQuery(query, fieldName, true, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ case QHelpSearchQuery::ATLEAST:
+ if (addAtLeastQuery(query, fieldName, booleanQuery, analyzer))
+ queryIsValid = true;
+ break;
+ default:
+ Q_ASSERT(!"Invalid field name");
+ }
+ }
+
+ if (queryIsValid && !filterAttributes.isEmpty()) {
+ queryIsValid =
+ addAttributesQuery(filterAttributes, booleanQuery, analyzer);
}
- return false;
+ return queryIsValid;
}
-bool QHelpSearchIndexReaderClucene::buildQuery(QCLuceneBooleanQuery &booleanQuery,
- const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer)
+bool QHelpSearchIndexReaderClucene::buildTryHarderQuery(
+ const QList<QHelpSearchQuery> &queries, const QString &fieldName,
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
{
- 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, analyzer)) {
- 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 &term, termList) {
- if (!stopWords.contains(term, Qt::CaseInsensitive))
- q->addTerm(QCLuceneTerm(QLatin1String("content"), term.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;
+ if (queries.isEmpty())
+ return false;
+ const QHelpSearchQuery &query = queries.front();
+ if (query.fieldName != QHelpSearchQuery::DEFAULT)
+ return false;
+ if (isNegativeQuery(query))
+ return false;
+ if (!addDefaultQuery(query, fieldName, false, booleanQuery, analyzer))
+ return false;
+ if (filterAttributes.isEmpty())
+ return true;
+ return addAttributesQuery(filterAttributes, booleanQuery, analyzer);
+}
- case QHelpSearchQuery::ALL: {
- QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
- foreach (const QString &term, query.wordList) {
- if (stopWords.contains(term, Qt::CaseInsensitive))
- continue;
+bool QHelpSearchIndexReaderClucene::isNegativeQuery(const QHelpSearchQuery &query) const
+{
+ const QString &search = query.wordList.join(" ");
+ return search.contains('!') || search.contains('-')
+ || search.contains(QLatin1String(" NOT "));
+}
- QCLuceneQuery *query = new QCLuceneTermQuery(QCLuceneTerm(
- QLatin1String("content"), term.toLower()));
+bool QHelpSearchIndexReaderClucene::addFuzzyQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ const QLatin1String fuzzy("~");
+ foreach (const QString &term, query.wordList) {
+ if (!term.isEmpty()) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term + fuzzy, fieldName, analyzer);
+ if (lQuery != 0) {
+ booleanQuery.add(lQuery, true, false, false);
+ queryIsValid = true;
+ }
+ }
+ }
+ return queryIsValid;
+}
- if (query) {
- booleanQuery.add(query, true, true, false);
- } else {
- return false;
- }
- }
- } break;
+bool QHelpSearchIndexReaderClucene::addWithoutQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, false, true);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
- case QHelpSearchQuery::DEFAULT: {
- foreach (const QString &term, query.wordList) {
- QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(),
- QLatin1String("content"), analyzer);
+bool QHelpSearchIndexReaderClucene::addPhraseQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QString &term = query.wordList.at(0).toLower();
+ if (term.contains(QLatin1Char(' '))) {
+ const QStringList termList = term.split(QLatin1String(" "));
+ QCLucenePhraseQuery *q = new QCLucenePhraseQuery();
+ const QStringList stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, termList) {
+ if (!stopWords.contains(term, Qt::CaseInsensitive))
+ q->addTerm(QCLuceneTerm(fieldName, term.toLower()));
+ }
+ if (!q->getTerms().isEmpty()) {
+ booleanQuery.add(q, true, true, false);
+ queryIsValid = true;
+ }
+ } else {
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, true, false);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
- if (query)
- booleanQuery.add(query, true, true, false);
- }
- } break;
+bool QHelpSearchIndexReaderClucene::addAllQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, QCLuceneBooleanQuery &booleanQuery)
+{
+ bool queryIsValid = false;
+ const QStringList &stopWords = QCLuceneStopAnalyzer().englishStopWords();
+ foreach (const QString &term, query.wordList) {
+ if (stopWords.contains(term, Qt::CaseInsensitive))
+ continue;
+ QCLuceneQuery *lQuery = new QCLuceneTermQuery(QCLuceneTerm(
+ fieldName, term.toLower()));
+ booleanQuery.add(lQuery, true, true, false);
+ queryIsValid = true;
+ }
+ return queryIsValid;
+}
- case QHelpSearchQuery::ATLEAST: {
- foreach (const QString &term, query.wordList) {
- if (term.isEmpty() || !defaultQuery(term.toLower(), booleanQuery, analyzer))
- return false;
- }
- }
+bool QHelpSearchIndexReaderClucene::addDefaultQuery(const QHelpSearchQuery &query,
+ const QString &fieldName, bool allTermsRequired,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ bool queryIsValid = false;
+ foreach (const QString &term, query.wordList) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term.toLower(), fieldName, analyzer);
+ if (lQuery) {
+ booleanQuery.add(lQuery, true, allTermsRequired, false);
+ queryIsValid = true;
}
}
-
- return true;
+ return queryIsValid;
}
-bool QHelpSearchIndexReaderClucene::buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery,
- const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer)
+bool QHelpSearchIndexReaderClucene::addAtLeastQuery(
+ const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer)
{
- bool retVal = false;
- foreach (const QHelpSearchQuery query, queryList) {
- switch (query.fieldName) {
- default: break;
- case QHelpSearchQuery::DEFAULT: {
- foreach (const QString &term, query.wordList) {
- QCLuceneQuery *query = QCLuceneQueryParser::parse(term.toLower(),
- QLatin1String("content"), analyzer);
-
- if (query) {
- retVal = true;
- booleanQuery.add(query, true, false, false);
- }
- }
- } break;
+ bool queryIsValid = false;
+ foreach (const QString &term, query.wordList) {
+ if (!term.isEmpty()) {
+ QCLuceneQuery *lQuery =
+ QCLuceneQueryParser::parse(term, fieldName, analyzer);
+ if (lQuery) {
+ booleanQuery.add(lQuery, true, false, false);
+ queryIsValid = true;
+ }
}
}
- return retVal;
+ return queryIsValid;
+}
+
+bool QHelpSearchIndexReaderClucene::addAttributesQuery(
+ const QStringList &filterAttributes, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer)
+{
+ QCLuceneQuery* lQuery = QCLuceneQueryParser::parse(QLatin1String("+")
+ + filterAttributes.join(QLatin1String(" +")), AttributeField, analyzer);
+ if (!lQuery)
+ return false;
+ booleanQuery.add(lQuery, true, true, false);
+ return true;
}
void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engine,
QList<QHelpSearchEngine::SearchHit> &hitList, const QList<QHelpSearchQuery> &queryList)
{
- foreach (const QHelpSearchQuery query, queryList) {
+ foreach (const QHelpSearchQuery &query, queryList) {
if (query.fieldName != QHelpSearchQuery::DEFAULT)
continue;
@@ -335,21 +423,22 @@ void QHelpSearchIndexReaderClucene::boostSearchHits(const QHelpEngineCore &engin
QCLuceneStandardAnalyzer analyzer;
QCLuceneQuery *parsedQuery = QCLuceneQueryParser::parse(
- joinedQuery, QLatin1String("content"), analyzer);
+ joinedQuery, ContentField, analyzer);
if (parsedQuery) {
joinedQuery = parsedQuery->toString();
delete parsedQuery;
}
- int length = QString(QLatin1String("content:")).length();
- int index = joinedQuery.indexOf(QLatin1String("content:"));
+ const QString contentString(ContentField + QLatin1String(":"));
+ int length = contentString.length();
+ int index = joinedQuery.indexOf(contentString);
QString term;
int nextIndex = 0;
QStringList searchTerms;
while (index != -1) {
- nextIndex = joinedQuery.indexOf(QLatin1String("content:"), index + 1);
+ nextIndex = joinedQuery.indexOf(contentString, index + 1);
term = joinedQuery.mid(index + length, nextIndex - (length + index)).simplified();
if (term.startsWith(QLatin1String("\""))
&& term.endsWith(QLatin1String("\""))) {
diff --git a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
index 8f51cb1..7f53733 100644
--- a/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
+++ b/tools/assistant/lib/qhelpsearchindexreader_clucene_p.h
@@ -53,10 +53,13 @@
// We mean it.
//
-#include "qhelpsearchindexreader_p.h"
+#include <QtCore/QList>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
#include "fulltextsearch/qanalyzer_p.h"
#include "fulltextsearch/qquery_p.h"
+#include "qhelpsearchindexreader_p.h"
QT_BEGIN_NAMESPACE
@@ -73,14 +76,34 @@ public:
private:
void run();
- bool defaultQuery(const QString &term, QCLuceneBooleanQuery &booleanQuery,
- QCLuceneStandardAnalyzer &analyzer);
- bool buildQuery(QCLuceneBooleanQuery &booleanQuery, const QList<QHelpSearchQuery> &queryList,
- QCLuceneStandardAnalyzer &analyzer);
- bool buildTryHarderQuery(QCLuceneBooleanQuery &booleanQuery,
- const QList<QHelpSearchQuery> &queryList, QCLuceneStandardAnalyzer &analyzer);
void boostSearchHits(const QHelpEngineCore &engine, QList<QHelpSearchEngine::SearchHit> &hitList,
const QList<QHelpSearchQuery> &queryList);
+ bool buildQuery(const QList<QHelpSearchQuery> &queries,
+ const QString &fieldName,
+ const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool buildTryHarderQuery(const QList<QHelpSearchQuery> &queries,
+ const QString &fieldName,
+ const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool addFuzzyQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool addWithoutQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addPhraseQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addAllQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery);
+ bool addDefaultQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ bool allTermsRequired, QCLuceneBooleanQuery &booleanQuery,
+ QCLuceneAnalyzer &analyzer);
+ bool addAtLeastQuery(const QHelpSearchQuery &query, const QString &fieldName,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool addAttributesQuery(const QStringList &filterAttributes,
+ QCLuceneBooleanQuery &booleanQuery, QCLuceneAnalyzer &analyzer);
+ bool isNegativeQuery(const QHelpSearchQuery &query) const;
};
} // namespace clucene
diff --git a/tools/assistant/lib/qhelpsearchindexreader_default_p.h b/tools/assistant/lib/qhelpsearchindexreader_default_p.h
index b30fa4b..27764db 100644
--- a/tools/assistant/lib/qhelpsearchindexreader_default_p.h
+++ b/tools/assistant/lib/qhelpsearchindexreader_default_p.h
@@ -61,9 +61,6 @@
QT_BEGIN_NAMESPACE
-struct Entry;
-struct PosEntry;
-
namespace fulltextsearch {
namespace std {
diff --git a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
index 4f9fa3f..4baa376 100644
--- a/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
+++ b/tools/assistant/lib/qhelpsearchindexwriter_clucene.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "qclucenefieldnames_p.h"
#include "qhelpenginecore.h"
#include "qhelp_global.h"
#include "fulltextsearch/qhits_p.h"
@@ -406,17 +407,17 @@ public:
QString parsedTitle = QHelpGlobal::documentTitle(data);
if(!parsedData.isEmpty()) {
- document->add(new QCLuceneField(QLatin1String("content"),
+ document->add(new QCLuceneField(ContentField,
parsedData,QCLuceneField::INDEX_TOKENIZED));
- document->add(new QCLuceneField(QLatin1String("path"), fileName,
+ document->add(new QCLuceneField(PathField, fileName,
QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
- document->add(new QCLuceneField(QLatin1String("title"), parsedTitle,
+ document->add(new QCLuceneField(TitleField, parsedTitle,
QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
- document->add(new QCLuceneField(QLatin1String("titleTokenized"), parsedTitle,
+ document->add(new QCLuceneField(TitleTokenizedField, parsedTitle,
QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
- document->add(new QCLuceneField(QLatin1String("namespace"), namespaceName,
+ document->add(new QCLuceneField(NamespaceField, namespaceName,
QCLuceneField::STORE_YES | QCLuceneField::INDEX_UNTOKENIZED));
- document->add(new QCLuceneField(QLatin1String("attribute"), attributes,
+ document->add(new QCLuceneField(AttributeField, attributes,
QCLuceneField::STORE_YES | QCLuceneField::INDEX_TOKENIZED));
return true;
}
@@ -715,9 +716,7 @@ void QHelpSearchIndexWriter::run()
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));
+ QCLuceneTermQuery query(QCLuceneTerm(NamespaceField, namespaceName));
QCLuceneIndexSearcher indexSearcher(indexPath);
QCLuceneHits hits = indexSearcher.search(query);
if (hits.length() <= 0)
@@ -851,8 +850,7 @@ void QHelpSearchIndexWriter::removeDocuments(const QString &indexPath,
return;
QCLuceneIndexReader reader = QCLuceneIndexReader::open(indexPath);
- reader.deleteDocuments(QCLuceneTerm(QLatin1String("namespace"),
- namespaceName));
+ reader.deleteDocuments(QCLuceneTerm(NamespaceField, namespaceName));
reader.close();
}
diff --git a/tools/assistant/lib/qhelpsearchquerywidget.cpp b/tools/assistant/lib/qhelpsearchquerywidget.cpp
index 3c3919e..1634a0d 100644
--- a/tools/assistant/lib/qhelpsearchquerywidget.cpp
+++ b/tools/assistant/lib/qhelpsearchquerywidget.cpp
@@ -41,8 +41,6 @@
#include "qhelpsearchquerywidget.h"
-#include <QtCore/QDebug>
-
#include <QtCore/QAbstractListModel>
#include <QtCore/QObject>
#include <QtCore/QStringList>
@@ -101,8 +99,9 @@ private:
};
QHelpSearchQueryWidgetPrivate()
- : QObject(), simpleSearch(true),
- searchCompleter(new CompleterModel(this), this)
+ : QObject()
+ , simpleSearch(true)
+ , searchCompleter(new CompleterModel(this), this)
{
searchButton = 0;
advancedSearchWidget = 0;
@@ -136,33 +135,6 @@ private:
#endif
}
- 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 really 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;
@@ -222,8 +194,8 @@ private:
}
}
- void nextOrPrevQuery(int maxOrMinIndex, int addend,
- QToolButton *thisButton, QToolButton *otherButton)
+ void nextOrPrevQuery(int maxOrMinIndex, int addend, QToolButton *thisButton,
+ QToolButton *otherButton)
{
QueryHistory *queryHist;
QList<QLineEdit *> lineEdits;
@@ -233,7 +205,7 @@ private:
} else {
queryHist = &complexQueries;
lineEdits << allQuery << atLeastQuery << similarQuery
- << withoutQuery << exactQuery;
+ << withoutQuery << exactQuery;
}
foreach (QLineEdit *lineEdit, lineEdits)
lineEdit->clear();
@@ -278,11 +250,11 @@ private:
void enableOrDisableToolButtons()
{
- const QueryHistory &queryHist =
- simpleSearch ? simpleQueries : complexQueries;
+ const QueryHistory &queryHist = simpleSearch ? simpleQueries
+ : complexQueries;
prevQueryButton->setEnabled(queryHist.curQuery > 0);
- nextQueryButton->setEnabled(queryHist.curQuery <
- queryHist.queries.size() - 1);
+ nextQueryButton->setEnabled(queryHist.curQuery
+ < queryHist.queries.size() - 1);
}
private slots:
@@ -306,41 +278,45 @@ private slots:
QList<QHelpSearchQuery> queryList;
#if !defined(QT_CLUCENE_SUPPORT)
queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
- QStringList(defaultQuery->text())));
+ QStringList(defaultQuery->text())));
#else
if (defaultQuery->isEnabled()) {
queryList.append(QHelpSearchQuery(QHelpSearchQuery::DEFAULT,
- buildTermList(escapeString(defaultQuery->text()))));
+ buildTermList(defaultQuery->text())));
} else {
const QRegExp exp(QLatin1String("\\s+"));
- QStringList lst = similarQuery->text().split(exp, QString::SkipEmptyParts);
+ QStringList lst = similarQuery->text().split(exp,
+ QString::SkipEmptyParts);
if (!lst.isEmpty()) {
QStringList fuzzy;
foreach (const QString &term, lst)
- fuzzy += buildTermList(escapeString(term));
- queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY, fuzzy));
+ fuzzy += buildTermList(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::FUZZY,
+ fuzzy));
}
lst = withoutQuery->text().split(exp, QString::SkipEmptyParts);
if (!lst.isEmpty()) {
QStringList without;
foreach (const QString &term, lst)
- without.append(escapeString(term));
- queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT, without));
+ without.append(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::WITHOUT,
+ without));
}
if (!exactQuery->text().isEmpty()) {
QString phrase = exactQuery->text().remove(QLatin1Char('\"'));
- phrase = escapeString(phrase.simplified());
- queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE, QStringList(phrase)));
+ phrase = phrase.simplified();
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::PHRASE,
+ QStringList(phrase)));
}
lst = allQuery->text().split(exp, QString::SkipEmptyParts);
if (!lst.isEmpty()) {
QStringList all;
foreach (const QString &term, lst)
- all.append(escapeString(term));
+ all.append(term);
queryList.append(QHelpSearchQuery(QHelpSearchQuery::ALL, all));
}
@@ -348,8 +324,9 @@ private slots:
if (!lst.isEmpty()) {
QStringList atLeast;
foreach (const QString &term, lst)
- atLeast += buildTermList(escapeString(term));
- queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST, atLeast));
+ atLeast += buildTermList(term);
+ queryList.append(QHelpSearchQuery(QHelpSearchQuery::ATLEAST,
+ atLeast));
}
}
#endif
@@ -363,8 +340,9 @@ private slots:
void nextQuery()
{
- nextOrPrevQuery((simpleSearch ? simpleQueries : complexQueries).queries.size() - 1,
- 1, nextQueryButton, prevQueryButton);
+ nextOrPrevQuery((simpleSearch ? simpleQueries
+ : complexQueries).queries.size() - 1, 1, nextQueryButton,
+ prevQueryButton);
}
void prevQuery()
@@ -415,8 +393,9 @@ private:
\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.
+ 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.
*/
/*!
@@ -544,7 +523,8 @@ QList<QHelpSearchQuery> QHelpSearchQueryWidget::query() const
QList<QHelpSearchQuery>() : queryHist.queries.last();
}
-/*! \reimp
+/*!
+ \reimp
*/
void QHelpSearchQueryWidget::focusInEvent(QFocusEvent *focusEvent)
{
diff --git a/tools/assistant/lib/qhelpsearchresultwidget.cpp b/tools/assistant/lib/qhelpsearchresultwidget.cpp
index ad540c6..2f5489b 100644
--- a/tools/assistant/lib/qhelpsearchresultwidget.cpp
+++ b/tools/assistant/lib/qhelpsearchresultwidget.cpp
@@ -304,7 +304,7 @@ private:
last = resultLastToShow > count ? count : resultLastToShow;
}
}
- hitsLabel->setText(tr("%1 - %2 of %3 Hits").arg(first).arg(last).arg(count));
+ hitsLabel->setText(QHelpSearchResultWidget::tr("%1 - %2 of %n Hits", 0, count).arg(first).arg(last));
}
private:
diff --git a/tools/assistant/tools/assistant/aboutdialog.cpp b/tools/assistant/tools/assistant/aboutdialog.cpp
index 0ab8659..a9bc352 100644
--- a/tools/assistant/tools/assistant/aboutdialog.cpp
+++ b/tools/assistant/tools/assistant/aboutdialog.cpp
@@ -38,6 +38,8 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "helpviewer.h"
+#include "tracer.h"
#include <QtCore/QBuffer>
@@ -56,6 +58,7 @@ QT_BEGIN_NAMESPACE
AboutLabel::AboutLabel(QWidget *parent)
: QTextBrowser(parent)
{
+ TRACE_OBJ
setFrameStyle(QFrame::NoFrame);
QPalette p;
p.setColor(QPalette::Base, p.color(QPalette::Background));
@@ -64,14 +67,16 @@ AboutLabel::AboutLabel(QWidget *parent)
void AboutLabel::setText(const QString &text, const QByteArray &resources)
{
+ TRACE_OBJ
QDataStream in(resources);
in >> m_resourceMap;
-
+
QTextBrowser::setText(text);
}
QSize AboutLabel::minimumSizeHint() const
{
+ TRACE_OBJ
QTextDocument *doc = document();
doc->adjustSize();
return QSize(int(doc->size().width()), int(doc->size().height()));
@@ -79,6 +84,7 @@ QSize AboutLabel::minimumSizeHint() const
QVariant AboutLabel::loadResource(int type, const QUrl &name)
{
+ TRACE_OBJ
if (type == 2 || type == 3) {
if (m_resourceMap.contains(name.toString())) {
return m_resourceMap.value(name.toString());
@@ -89,44 +95,47 @@ QVariant AboutLabel::loadResource(int type, const QUrl &name)
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")))) {
+ TRACE_OBJ
+ if (url.isValid() && (!AbstractHelpViewer::isLocalUrl(url)
+ || !AbstractHelpViewer::canOpenPage(url.path()))) {
if (!QDesktopServices::openUrl(url)) {
QMessageBox::warning(this, tr("Warning"),
- tr("Unable to launch external application.\n"),
- tr("OK"));
+ tr("Unable to launch external application.\n"), tr("OK"));
}
}
}
AboutDialog::AboutDialog(QWidget *parent)
- : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint|Qt::WindowTitleHint|Qt::WindowSystemMenuHint)
+ : QDialog(parent, Qt::MSWindowsFixedSizeDialogHint |
+ Qt::WindowTitleHint|Qt::WindowSystemMenuHint)
{
+ TRACE_OBJ
m_pixmapLabel = 0;
m_aboutLabel = new AboutLabel();
-
+
m_closeButton = new QPushButton();
m_closeButton->setText(tr("&Close"));
- connect(m_closeButton, SIGNAL(clicked()),
- this, SLOT(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, 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);
+ m_layout->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding), 3, 2, 1, 1);
}
void AboutDialog::setText(const QString &text, const QByteArray &resources)
{
+ TRACE_OBJ
m_aboutLabel->setText(text, resources);
updateSize();
}
void AboutDialog::setPixmap(const QPixmap &pixmap)
{
+ TRACE_OBJ
if (!m_pixmapLabel) {
m_pixmapLabel = new QLabel();
m_layout->addWidget(m_pixmapLabel, 0, 0, 1, -1, Qt::AlignCenter);
@@ -137,12 +146,15 @@ void AboutDialog::setPixmap(const QPixmap &pixmap)
QString AboutDialog::documentTitle() const
{
+ TRACE_OBJ
return m_aboutLabel->documentTitle();
}
void AboutDialog::updateSize()
{
- QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos()).size();
+ TRACE_OBJ
+ QSize screenSize = QApplication::desktop()->availableGeometry(QCursor::pos())
+ .size();
int limit = qMin(screenSize.width()/2, 500);
#ifdef Q_WS_MAC
@@ -154,7 +166,7 @@ void AboutDialog::updateSize()
if (width > limit)
width = limit;
-
+
QFontMetrics fm(qApp->font("QWorkspaceTitleBar"));
int windowTitleWidth = qMin(fm.width(windowTitle()) + 50, limit);
if (windowTitleWidth > width)
@@ -162,8 +174,8 @@ void AboutDialog::updateSize()
layout()->activate();
int height = (layout()->hasHeightForWidth())
- ? layout()->totalHeightForWidth(width)
- : layout()->totalMinimumSize().height();
+ ? layout()->totalHeightForWidth(width)
+ : layout()->totalMinimumSize().height();
setFixedSize(width, height);
QCoreApplication::removePostedEvents(this, QEvent::LayoutRequest);
}
diff --git a/tools/assistant/tools/assistant/assistant.pro b/tools/assistant/tools/assistant/assistant.pro
index 1a7e874..d9aff7a 100644
--- a/tools/assistant/tools/assistant/assistant.pro
+++ b/tools/assistant/tools/assistant/assistant.pro
@@ -1,71 +1,94 @@
-include($$QT_SOURCE_TREE/tools/shared/fontpanel/fontpanel.pri)
-
+include(../../../shared/fontpanel/fontpanel.pri)
TEMPLATE = app
LANGUAGE = C++
TARGET = assistant
-
-contains(QT_CONFIG, webkit) {
- QT += webkit
-}
-
-CONFIG += qt warn_on help
-
+contains(QT_CONFIG, webkit):QT += webkit
+CONFIG += qt \
+ warn_on \
+ help
QT += network
-
PROJECTNAME = Assistant
DESTDIR = ../../../../bin
-
-target.path=$$[QT_INSTALL_BINS]
+target.path = $$[QT_INSTALL_BINS]
INSTALLS += target
+DEPENDPATH += ../shared
-### 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
+# ## Work around a qmake issue when statically linking to
+# ## not-yet-installed plugins
+QMAKE_LIBDIR += $$QT_BUILD_TREE/plugins/sqldrivers
+HEADERS += aboutdialog.h \
+ bookmarkdialog.h \
+ bookmarkfiltermodel.h \
+ bookmarkitem.h \
+ bookmarkmanager.h \
+ bookmarkmanagerwidget.h \
+ bookmarkmodel.h \
+ centralwidget.h \
+ cmdlineparser.h \
+ contentwindow.h \
+ findwidget.h \
+ filternamedialog.h \
+ helpenginewrapper.h \
+ helpviewer.h \
+ indexwindow.h \
+ installdialog.h \
+ mainwindow.h \
+ preferencesdialog.h \
+ qtdocinstaller.h \
+ remotecontrol.h \
+ searchwidget.h \
+ topicchooser.h \
+ tracer.h \
+ xbelsupport.h \
+ ../shared/collectionconfiguration.h
+contains(QT_CONFIG, webkit) {
+ HEADERS += helpviewer_qwv.h
+} else {
+ HEADERS += helpviewer_qtb.h
+ }
+win32:HEADERS += remotecontrol_win.h
-win32 {
- HEADERS += remotecontrol_win.h
+SOURCES += aboutdialog.cpp \
+ bookmarkdialog.cpp \
+ bookmarkfiltermodel.cpp \
+ bookmarkitem.cpp \
+ bookmarkmanager.cpp \
+ bookmarkmanagerwidget.cpp \
+ bookmarkmodel.cpp \
+ centralwidget.cpp \
+ cmdlineparser.cpp \
+ contentwindow.cpp \
+ findwidget.cpp \
+ filternamedialog.cpp \
+ helpenginewrapper.cpp \
+ helpviewer.cpp \
+ indexwindow.cpp \
+ installdialog.cpp \
+ main.cpp \
+ mainwindow.cpp \
+ preferencesdialog.cpp \
+ qtdocinstaller.cpp \
+ remotecontrol.cpp \
+ searchwidget.cpp \
+ topicchooser.cpp \
+ xbelsupport.cpp \
+ ../shared/collectionconfiguration.cpp
+ contains(QT_CONFIG, webkit) {
+ SOURCES += helpviewer_qwv.cpp
+} else {
+ SOURCES += helpviewer_qtb.cpp
}
-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
+FORMS += bookmarkdialog.ui \
+ bookmarkmanagerwidget.ui \
+ bookmarkwidget.ui \
+ filternamedialog.ui \
+ installdialog.ui \
+ preferencesdialog.ui \
+ topicchooser.ui
-RESOURCES += assistant.qrc assistant_images.qrc
+RESOURCES += assistant.qrc \
+ assistant_images.qrc
win32 {
!wince*:LIBS += -lshell32
diff --git a/tools/assistant/tools/assistant/assistant.qch b/tools/assistant/tools/assistant/assistant.qch
index 78fe9f3..e6d5299 100644
--- a/tools/assistant/tools/assistant/assistant.qch
+++ b/tools/assistant/tools/assistant/assistant.qch
Binary files differ
diff --git a/tools/assistant/tools/assistant/assistant_images.qrc b/tools/assistant/tools/assistant/assistant_images.qrc
index 58e03b5..34918c0 100644
--- a/tools/assistant/tools/assistant/assistant_images.qrc
+++ b/tools/assistant/tools/assistant/assistant_images.qrc
@@ -4,6 +4,7 @@
<file>images/assistant-128.png</file>
<file>images/assistant.png</file>
<file>images/wrap.png</file>
+ <file>images/bookmark.png</file>
#mac
<file>images/mac/addtab.png</file>
<file>images/mac/book.png</file>
diff --git a/tools/assistant/tools/assistant/bookmarkdialog.cpp b/tools/assistant/tools/assistant/bookmarkdialog.cpp
new file mode 100644
index 0000000..d9e9a53
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkdialog.cpp
@@ -0,0 +1,237 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkdialog.h"
+#include "bookmarkfiltermodel.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+#include "helpenginewrapper.h"
+#include "tracer.h"
+
+#include <QtGui/QKeyEvent>
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+BookmarkDialog::BookmarkDialog(BookmarkModel *sourceModel, const QString &title,
+ const QString &url, QWidget *parent)
+ : QDialog(parent)
+ , m_url(url)
+ , m_title(title)
+ , bookmarkModel(sourceModel)
+{
+ TRACE_OBJ
+ ui.setupUi(this);
+
+ ui.bookmarkEdit->setText(m_title);
+ ui.newFolderButton->setVisible(false);
+ ui.buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
+
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(accepted()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(rejected()));
+ connect(ui.newFolderButton, SIGNAL(clicked()), this, SLOT(addFolder()));
+ connect(ui.toolButton, SIGNAL(clicked()), this, SLOT(toolButtonClicked()));
+ connect(ui.bookmarkEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+
+ bookmarkProxyModel = new BookmarkFilterModel(this);
+ bookmarkProxyModel->setSourceModel(bookmarkModel);
+ ui.bookmarkFolders->setModel(bookmarkProxyModel);
+ connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(int)), this,
+ SLOT(currentIndexChanged(int)));
+
+ bookmarkTreeModel = new BookmarkTreeModel(this);
+ bookmarkTreeModel->setSourceModel(bookmarkModel);
+ ui.treeView->setModel(bookmarkTreeModel);
+
+ ui.treeView->expandAll();
+ ui.treeView->setVisible(false);
+ ui.treeView->installEventFilter(this);
+ ui.treeView->viewport()->installEventFilter(this);
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
+ connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,
+ QModelIndex)), this, SLOT(currentIndexChanged(QModelIndex)));
+
+ ui.bookmarkFolders->setCurrentIndex(0);
+ ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2)));
+
+ const HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.usesAppFont())
+ setFont(helpEngine.appFont());
+}
+
+BookmarkDialog::~BookmarkDialog()
+{
+ TRACE_OBJ
+}
+
+bool BookmarkDialog::isRootItem(const QModelIndex &index) const
+{
+ return !bookmarkTreeModel->parent(index).isValid();
+}
+
+bool BookmarkDialog::eventFilter(QObject *object, QEvent *event)
+{
+ TRACE_OBJ
+ if (object != ui.treeView && object != ui.treeView->viewport())
+ return QWidget::eventFilter(object, event);
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ const QModelIndex &index = ui.treeView->currentIndex();
+ if (!isRootItem(index)) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+ } break;
+ default: break;
+ }
+ }
+
+ return QObject::eventFilter(object, event);
+}
+
+void BookmarkDialog::currentIndexChanged(int row)
+{
+ TRACE_OBJ
+ QModelIndex next = bookmarkProxyModel->index(row, 0, QModelIndex());
+ if (next.isValid()) {
+ next = bookmarkProxyModel->mapToSource(next);
+ ui.treeView->setCurrentIndex(bookmarkTreeModel->mapFromSource(next));
+ }
+}
+
+void BookmarkDialog::currentIndexChanged(const QModelIndex &index)
+{
+ TRACE_OBJ
+ const QModelIndex current = bookmarkTreeModel->mapToSource(index);
+ if (current.isValid()) {
+ const int row = bookmarkProxyModel->mapFromSource(current).row();
+ ui.bookmarkFolders->setCurrentIndex(row);
+ }
+}
+
+void BookmarkDialog::accepted()
+{
+ TRACE_OBJ
+ QModelIndex index = ui.treeView->currentIndex();
+ if (index.isValid()) {
+ index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index));
+ bookmarkModel->setData(index, DataVector() << m_title << m_url << false);
+ } else
+ rejected();
+
+ accept();
+}
+
+void BookmarkDialog::rejected()
+{
+ TRACE_OBJ
+ foreach (const QPersistentModelIndex &index, cache)
+ bookmarkModel->removeItem(index);
+ reject();
+}
+
+void BookmarkDialog::addFolder()
+{
+ TRACE_OBJ
+ QModelIndex index = ui.treeView->currentIndex();
+ if (index.isValid()) {
+ index = bookmarkModel->addItem(bookmarkTreeModel->mapToSource(index),
+ true);
+ cache.append(index);
+
+ index = bookmarkTreeModel->mapFromSource(index);
+ if (index.isValid()) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ ui.treeView->expand(index);
+ ui.treeView->setCurrentIndex(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+ }
+}
+
+void BookmarkDialog::toolButtonClicked()
+{
+ TRACE_OBJ
+ const 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::textChanged(const QString& text)
+{
+ m_title = text;
+}
+
+void BookmarkDialog::customContextMenuRequested(const QPoint &point)
+{
+ TRACE_OBJ
+ const QModelIndex &index = ui.treeView->currentIndex();
+ if (isRootItem(index))
+ return; // check if we go to rename the "Bookmarks Menu", bail
+
+ QMenu menu(QLatin1String(""), this);
+ QAction *renameItem = menu.addAction(tr("Rename Folder"));
+
+ QAction *picked = menu.exec(ui.treeView->mapToGlobal(point));
+ if (picked == renameItem) {
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/bookmarkdialog.h b/tools/assistant/tools/assistant/bookmarkdialog.h
new file mode 100644
index 0000000..e177af6
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkdialog.h
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKDIALOG_H
+#define BOOKMARKDIALOG_H
+
+#include "ui_bookmarkdialog.h"
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkModel;
+class BookmarkFilterModel;
+class BookmarkTreeModel;
+
+class BookmarkDialog : public QDialog
+{
+ Q_OBJECT
+public:
+ BookmarkDialog(BookmarkModel *bookmarkModel, const QString &title,
+ const QString &url, QWidget *parent = 0);
+ ~BookmarkDialog();
+
+private:
+ bool isRootItem(const QModelIndex &index) const;
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void currentIndexChanged(int index);
+ void currentIndexChanged(const QModelIndex &index);
+
+ void accepted();
+ void rejected();
+
+ void addFolder();
+ void toolButtonClicked();
+ void textChanged(const QString& text);
+ void customContextMenuRequested(const QPoint &point);
+
+private:
+ QString m_url;
+ QString m_title;
+ Ui::BookmarkDialog ui;
+ QList<QPersistentModelIndex> cache;
+
+ BookmarkModel *bookmarkModel;
+ BookmarkTreeModel *bookmarkTreeModel;
+ BookmarkFilterModel *bookmarkProxyModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKDIALOG_H
diff --git a/tools/assistant/tools/assistant/bookmarkdialog.ui b/tools/assistant/tools/assistant/bookmarkdialog.ui
index 7a878f9..5131531 100644
--- a/tools/assistant/tools/assistant/bookmarkdialog.ui
+++ b/tools/assistant/tools/assistant/bookmarkdialog.ui
@@ -1,38 +1,39 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<class>BookmarkDialog</class>
- <widget class="QDialog" name="BookmarkDialog" >
- <property name="geometry" >
+ <widget class="QDialog" name="BookmarkDialog">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>450</width>
- <height>135</height>
+ <height>133</height>
</rect>
</property>
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Add Bookmark</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_3" >
+ <layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout" >
+ <layout class="QHBoxLayout" name="horizontalLayout">
<item>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
+ <layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QLabel" name="label" >
- <property name="text" >
+ <widget class="QLabel" name="label">
+ <property name="text">
<string>Bookmark:</string>
</property>
</widget>
</item>
<item>
- <widget class="QLabel" name="label_2" >
- <property name="text" >
+ <widget class="QLabel" name="label_2">
+ <property name="text">
<string>Add in Folder:</string>
</property>
</widget>
@@ -40,35 +41,35 @@
</layout>
</item>
<item>
- <layout class="QVBoxLayout" name="verticalLayout" >
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QLineEdit" name="bookmarkEdit" />
+ <widget class="QLineEdit" name="bookmarkEdit"/>
</item>
<item>
- <widget class="QComboBox" name="bookmarkFolders" />
+ <widget class="QComboBox" name="bookmarkFolders"/>
</item>
</layout>
</item>
</layout>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_3" >
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
- <widget class="QToolButton" name="toolButton" >
- <property name="minimumSize" >
+ <widget class="QToolButton" name="toolButton">
+ <property name="minimumSize">
<size>
<width>25</width>
<height>20</height>
</size>
</property>
- <property name="text" >
+ <property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
- <widget class="Line" name="line" >
- <property name="orientation" >
+ <widget class="Line" name="line">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
@@ -76,30 +77,39 @@
</layout>
</item>
<item>
- <widget class="QTreeView" name="treeView" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Ignored" hsizetype="Expanding" >
+ <widget class="QTreeView" name="treeView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="headerHidden">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_4" >
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
- <widget class="QPushButton" name="newFolderButton" >
- <property name="text" >
+ <widget class="QPushButton" name="newFolderButton">
+ <property name="text">
<string>New Folder</string>
</property>
</widget>
</item>
<item>
- <widget class="QDialogButtonBox" name="buttonBox" >
- <property name="orientation" >
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="standardButtons" >
+ <property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
@@ -116,11 +126,11 @@
<receiver>BookmarkDialog</receiver>
<slot>accept()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
@@ -132,11 +142,11 @@
<receiver>BookmarkDialog</receiver>
<slot>reject()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
diff --git a/tools/assistant/tools/assistant/bookmarkfiltermodel.cpp b/tools/assistant/tools/assistant/bookmarkfiltermodel.cpp
new file mode 100644
index 0000000..7a7c2e3
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkfiltermodel.cpp
@@ -0,0 +1,322 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkfiltermodel.h"
+
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+
+BookmarkFilterModel::BookmarkFilterModel(QObject *parent)
+ : QAbstractProxyModel(parent)
+ , hideBookmarks(true)
+ , sourceModel(0)
+{
+}
+
+void
+BookmarkFilterModel::setSourceModel(QAbstractItemModel *_sourceModel)
+{
+ beginResetModel();
+
+ QAbstractProxyModel::setSourceModel(sourceModel);
+ sourceModel = qobject_cast<BookmarkModel*> (_sourceModel);
+
+ connect(sourceModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(changed(QModelIndex, QModelIndex)));
+
+ connect(sourceModel, SIGNAL(rowsInserted(QModelIndex, int, int)),
+ this, SLOT(rowsInserted(QModelIndex, int, int)));
+
+ connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)),
+ this, SLOT(rowsAboutToBeRemoved(QModelIndex, int, int)));
+ connect(sourceModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(rowsRemoved(QModelIndex, int, int)));
+
+ connect(sourceModel, SIGNAL(layoutAboutToBeChanged()), this,
+ SLOT(layoutAboutToBeChanged()));
+ connect(sourceModel, SIGNAL(layoutChanged()), this,
+ SLOT(layoutChanged()));
+
+ connect(sourceModel, SIGNAL(modelAboutToBeReset()), this,
+ SLOT(modelAboutToBeReset()));
+ connect(sourceModel, SIGNAL(modelReset()), this, SLOT(modelReset()));
+
+ if (sourceModel)
+ setupCache(sourceModel->index(0, 0, QModelIndex()));
+
+ endResetModel();
+}
+
+int
+BookmarkFilterModel::rowCount(const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ return cache.count();
+}
+
+int
+BookmarkFilterModel::columnCount(const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ if (sourceModel)
+ return sourceModel->columnCount();
+ return 0;
+}
+
+QModelIndex
+BookmarkFilterModel::mapToSource(const QModelIndex &proxyIndex) const
+{
+ const int row = proxyIndex.row();
+ if (proxyIndex.isValid() && row >= 0 && row < cache.count())
+ return cache[row];
+ return QModelIndex();
+}
+
+QModelIndex
+BookmarkFilterModel::mapFromSource(const QModelIndex &sourceIndex) const
+{
+ return index(cache.indexOf(sourceIndex), 0, QModelIndex());
+}
+
+QModelIndex
+BookmarkFilterModel::parent(const QModelIndex &child) const
+{
+ Q_UNUSED(child)
+ return QModelIndex();
+}
+
+QModelIndex
+BookmarkFilterModel::index(int row, int column, const QModelIndex &index) const
+{
+ Q_UNUSED(index)
+ if (row < 0 || column < 0 || cache.count() <= row
+ || !sourceModel || sourceModel->columnCount() <= column) {
+ return QModelIndex();
+ }
+ return createIndex(row, 0);
+}
+
+Qt::DropActions
+BookmarkFilterModel::supportedDropActions () const
+{
+ if (sourceModel)
+ return sourceModel->supportedDropActions();
+ return Qt::IgnoreAction;
+}
+
+Qt::ItemFlags
+BookmarkFilterModel::flags(const QModelIndex &index) const
+{
+ if (sourceModel)
+ return sourceModel->flags(index);
+ return Qt::NoItemFlags;
+}
+
+QVariant
+BookmarkFilterModel::data(const QModelIndex &index, int role) const
+{
+ if (sourceModel)
+ return sourceModel->data(mapToSource(index), role);
+ return QVariant();
+}
+
+bool
+BookmarkFilterModel::setData(const QModelIndex &index, const QVariant &value,
+ int role)
+{
+ if (sourceModel)
+ return sourceModel->setData(mapToSource(index), value, role);
+ return false;
+}
+
+void
+BookmarkFilterModel::filterBookmarks()
+{
+ if (sourceModel) {
+ beginResetModel();
+ hideBookmarks = true;
+ setupCache(sourceModel->index(0, 0, QModelIndex()));
+ endResetModel();
+ }
+}
+
+void
+BookmarkFilterModel::filterBookmarkFolders()
+{
+ if (sourceModel) {
+ beginResetModel();
+ hideBookmarks = false;
+ setupCache(sourceModel->index(0, 0, QModelIndex()));
+ endResetModel();
+ }
+}
+
+void
+BookmarkFilterModel::changed(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight)
+{
+ emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight));
+}
+
+void
+BookmarkFilterModel::rowsInserted(const QModelIndex &parent, int start, int end)
+{
+ if (!sourceModel)
+ return;
+
+ QModelIndex cachePrevious = parent;
+ if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) {
+ BookmarkItem *newItem = parentItem->child(start);
+
+ // iterate over tree hirarchie to find the previous folder
+ for (int i = 0; i < parentItem->childCount(); ++i) {
+ if (BookmarkItem *child = parentItem->child(i)) {
+ const QModelIndex &tmp = sourceModel->indexFromItem(child);
+ if (tmp.data(UserRoleFolder).toBool() && child != newItem)
+ cachePrevious = tmp;
+ }
+ }
+
+ const QModelIndex &newIndex = sourceModel->indexFromItem(newItem);
+ const bool isFolder = newIndex.data(UserRoleFolder).toBool();
+ if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks)) {
+ beginInsertRows(mapFromSource(parent), start, end);
+ cache.insert(cache.indexOf(cachePrevious) + 1, newIndex);
+ endInsertRows();
+ }
+ }
+}
+
+void
+BookmarkFilterModel::rowsAboutToBeRemoved(const QModelIndex &parent, int start,
+ int end)
+{
+ if (!sourceModel)
+ return;
+
+ if (BookmarkItem *parentItem = sourceModel->itemFromIndex(parent)) {
+ if (BookmarkItem *child = parentItem->child(start)) {
+ indexToRemove = sourceModel->indexFromItem(child);
+ if (cache.contains(indexToRemove))
+ beginRemoveRows(mapFromSource(parent), start, end);
+ }
+ }
+}
+
+void
+BookmarkFilterModel::rowsRemoved(const QModelIndex &/*parent*/, int, int)
+{
+ if (cache.contains(indexToRemove)) {
+ cache.removeAll(indexToRemove);
+ endRemoveRows();
+ }
+}
+
+void
+BookmarkFilterModel::layoutAboutToBeChanged()
+{
+ // TODO: ???
+}
+
+void
+BookmarkFilterModel::layoutChanged()
+{
+ // TODO: ???
+}
+
+void
+BookmarkFilterModel::modelAboutToBeReset()
+{
+ beginResetModel();
+}
+
+void
+BookmarkFilterModel::modelReset()
+{
+ if (sourceModel)
+ setupCache(sourceModel->index(0, 0, QModelIndex()));
+ endResetModel();
+}
+
+void
+BookmarkFilterModel::setupCache(const QModelIndex &parent)
+{
+ cache.clear();
+ collectItems(parent);
+}
+
+void
+BookmarkFilterModel::collectItems(const QModelIndex &parent)
+{
+ if (parent.isValid()) {
+ bool isFolder = sourceModel->data(parent, UserRoleFolder).toBool();
+ if ((isFolder && hideBookmarks) || (!isFolder && !hideBookmarks))
+ cache.append(parent);
+
+ if (sourceModel->hasChildren(parent)) {
+ for (int i = 0; i < sourceModel->rowCount(parent); ++i)
+ collectItems(sourceModel->index(i, 0, parent));
+ }
+ }
+}
+
+// -- BookmarkTreeModel
+
+BookmarkTreeModel::BookmarkTreeModel(QObject *parent)
+ : QSortFilterProxyModel(parent)
+{
+}
+
+int
+BookmarkTreeModel::columnCount(const QModelIndex &parent) const
+{
+ return qMin(1, QSortFilterProxyModel::columnCount(parent));
+}
+
+bool
+BookmarkTreeModel::filterAcceptsRow(int row, const QModelIndex &parent) const
+{
+ Q_UNUSED(row)
+ BookmarkModel *model = qobject_cast<BookmarkModel*> (sourceModel());
+ if (model->rowCount(parent) > 0
+ && model->data(model->index(row, 0, parent), UserRoleFolder).toBool())
+ return true;
+ return false;
+}
diff --git a/tools/assistant/tools/assistant/bookmarkfiltermodel.h b/tools/assistant/tools/assistant/bookmarkfiltermodel.h
new file mode 100644
index 0000000..4ea7ab9
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkfiltermodel.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKFILTERMODEL_H
+#define BOOKMARKFILTERMODEL_H
+
+#include <QtCore/QPersistentModelIndex>
+
+#include <QtGui/QAbstractProxyModel>
+#include <QtGui/QSortFilterProxyModel>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkItem;
+class BookmarkModel;
+
+typedef QList<QPersistentModelIndex> PersistentModelIndexCache;
+
+class BookmarkFilterModel : public QAbstractProxyModel
+{
+ Q_OBJECT
+public:
+ explicit BookmarkFilterModel(QObject *parent = 0);
+
+ void setSourceModel(QAbstractItemModel *sourceModel);
+
+ int rowCount(const QModelIndex &index) const;
+ int columnCount(const QModelIndex &index) const;
+
+ QModelIndex mapToSource(const QModelIndex &proxyIndex) const;
+ QModelIndex mapFromSource(const QModelIndex &sourceIndex) const;
+
+ QModelIndex parent(const QModelIndex &child) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
+
+ Qt::DropActions supportedDropActions () const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+
+ void filterBookmarks();
+ void filterBookmarkFolders();
+
+private slots:
+ void changed(const QModelIndex &topLeft, const QModelIndex &bottomRight);
+ void rowsInserted(const QModelIndex &parent, int start, int end);
+ void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end);
+ void rowsRemoved(const QModelIndex &parent, int start, int end);
+ void layoutAboutToBeChanged();
+ void layoutChanged();
+ void modelAboutToBeReset();
+ void modelReset();
+
+private:
+ void setupCache(const QModelIndex &parent);
+ void collectItems(const QModelIndex &parent);
+
+private:
+ bool hideBookmarks;
+ BookmarkModel *sourceModel;
+ PersistentModelIndexCache cache;
+ QPersistentModelIndex indexToRemove;
+};
+
+// -- BookmarkTreeModel
+
+class BookmarkTreeModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ BookmarkTreeModel(QObject *parent = 0);
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+
+protected:
+ bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKFILTERMODEL_H
diff --git a/tools/assistant/tools/assistant/bookmarkitem.cpp b/tools/assistant/tools/assistant/bookmarkitem.cpp
new file mode 100644
index 0000000..2c92113
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkitem.cpp
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "bookmarkitem.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDebug>
+
+QT_BEGIN_NAMESPACE
+
+BookmarkItem::BookmarkItem(const DataVector &data, BookmarkItem *parent)
+ : m_data(data)
+ , m_parent(parent)
+{
+}
+
+BookmarkItem::~BookmarkItem()
+{
+ qDeleteAll(m_children);
+}
+
+BookmarkItem*
+BookmarkItem::parent() const
+{
+ return m_parent;
+}
+
+void
+BookmarkItem::setParent(BookmarkItem *parent)
+{
+ m_parent = parent;
+}
+
+void
+BookmarkItem::addChild(BookmarkItem *child)
+{
+ child->setParent(this);
+ m_children.append(child);
+}
+
+BookmarkItem*
+BookmarkItem::child(int number) const
+{
+ if (number >= 0 && number < m_children.count())
+ return m_children[number];
+ return 0;
+}
+
+int BookmarkItem::childCount() const
+{
+ return m_children.count();
+}
+
+int BookmarkItem::childNumber() const
+{
+ if (m_parent)
+ return m_parent->m_children.indexOf(const_cast<BookmarkItem*>(this));
+ return 0;
+}
+
+QVariant
+BookmarkItem::data(int column) const
+{
+ if (column == 0)
+ return m_data[0];
+
+ if (column == 1 || column == UserRoleUrl)
+ return m_data[1];
+
+ if (column == UserRoleFolder)
+ return m_data[1].toString() == QLatin1String("Folder");
+
+ if (column == UserRoleExpanded)
+ return m_data[2];
+
+ return QVariant();
+}
+
+void
+BookmarkItem::setData(const DataVector &data)
+{
+ m_data = data;
+}
+
+bool
+BookmarkItem::setData(int column, const QVariant &newValue)
+{
+ int index = -1;
+ if (column == 0 || column == 1)
+ index = column;
+
+ if (column == UserRoleUrl || column == UserRoleFolder)
+ index = 1;
+
+ if (column == UserRoleExpanded)
+ index = 2;
+
+ if (index < 0)
+ return false;
+
+ m_data[index] = newValue;
+ return true;
+}
+
+bool
+BookmarkItem::insertChildren(bool isFolder, int position, int count)
+{
+ if (position < 0 || position > m_children.size())
+ return false;
+
+ for (int row = 0; row < count; ++row) {
+ m_children.insert(position, new BookmarkItem(DataVector()
+ << (isFolder
+ ? QCoreApplication::translate("BookmarkItem", "New Folder")
+ : QCoreApplication::translate("BookmarkItem", "Untitled"))
+ << (isFolder ? "Folder" : "about:blank") << false, this));
+ }
+
+ return true;
+}
+
+bool
+BookmarkItem::removeChildren(int position, int count)
+{
+ if (position < 0 || position > m_children.size())
+ return false;
+
+ for (int row = 0; row < count; ++row)
+ delete m_children.takeAt(position);
+
+ return true;
+}
+
+void
+BookmarkItem::dumpTree(int indent) const
+{
+ const QString tree(indent, ' ');
+ qDebug() << tree + (data(UserRoleFolder).toBool() ? "Folder" : "Bookmark")
+ << "Label:" << data(0).toString() << "parent:" << m_parent << "this:"
+ << this;
+
+ foreach (BookmarkItem *item, m_children)
+ item->dumpTree(indent + 4);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/bookmarkitem.h b/tools/assistant/tools/assistant/bookmarkitem.h
new file mode 100644
index 0000000..7c5b8d0
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkitem.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef BOOKMARKITEM_H
+#define BOOKMARKITEM_H
+
+#include <QtCore/QVariant>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+
+enum {
+ UserRoleUrl = Qt::UserRole + 50,
+ UserRoleFolder = Qt::UserRole + 100,
+ UserRoleExpanded = Qt::UserRole + 150
+};
+
+typedef QVector<QVariant> DataVector;
+
+class BookmarkItem
+{
+public:
+ explicit BookmarkItem(const DataVector &data, BookmarkItem *parent = 0);
+ ~BookmarkItem();
+
+ BookmarkItem *parent() const;
+ void setParent(BookmarkItem *parent);
+
+ void addChild(BookmarkItem *child);
+ BookmarkItem *child(int number) const;
+
+ int childCount() const;
+ int childNumber() const;
+
+ QVariant data(int column) const;
+ void setData(const DataVector &data);
+ bool setData(int column, const QVariant &value);
+
+ bool insertChildren(bool isFolder, int position, int count);
+ bool removeChildren(int position, int count);
+
+ void dumpTree(int indent) const;
+
+private:
+ DataVector m_data;
+
+ BookmarkItem *m_parent;
+ QList<BookmarkItem*> m_children;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKITEM_H
diff --git a/tools/assistant/tools/assistant/bookmarkmanager.cpp b/tools/assistant/tools/assistant/bookmarkmanager.cpp
index 0ce1b9d..23632b1 100644
--- a/tools/assistant/tools/assistant/bookmarkmanager.cpp
+++ b/tools/assistant/tools/assistant/bookmarkmanager.cpp
@@ -38,549 +38,215 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "bookmarkmanager.h"
+#include "bookmarkmanagerwidget.h"
+#include "bookmarkdialog.h"
+#include "bookmarkfiltermodel.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
#include "centralwidget.h"
+#include "helpenginewrapper.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)
-{
- ui.setupUi(this);
-
- installEventFilter(this);
- ui.treeView->installEventFilter(this);
- ui.treeView->viewport()->installEventFilter(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(QString)), this,
- SLOT(textChanged(QString)));
-
- connect(bookmarkManager->treeBookmarkModel(),
- SIGNAL(itemChanged(QStandardItem*)),
- this, SLOT(itemChanged(QStandardItem*)));
-
- connect(ui.bookmarkFolders, SIGNAL(currentIndexChanged(QString)), this,
- SLOT(selectBookmarkFolder(QString)));
-
- connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this,
- SLOT(customContextMenuRequested(QPoint)));
-
- connect(ui.treeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,
- QModelIndex)), this, SLOT(currentChanged(QModelIndex)));
-}
-
-BookmarkDialog::~BookmarkDialog()
-{
-}
+// -- BookmarkManager::BookmarkWidget
-void BookmarkDialog::addAccepted()
+void BookmarkManager::BookmarkWidget::focusInEvent(QFocusEvent *event)
{
- QItemSelectionModel *model = ui.treeView->selectionModel();
- const QModelIndexList &list = model->selection().indexes();
+ TRACE_OBJ
+ if (event->reason() != Qt::MouseFocusReason) {
+ ui.lineEdit->selectAll();
+ ui.lineEdit->setFocus();
- QModelIndex index;
- if (!list.isEmpty())
- index = proxyModel->mapToSource(list.at(0));
-
- bookmarkManager->addNewBookmark(index, ui.bookmarkEdit->text(), m_url);
- accept();
-}
-
-void BookmarkDialog::addNewFolder()
-{
- QItemSelectionModel *model = ui.treeView->selectionModel();
- const QModelIndexList &list = model->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);
- model->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));
+ // force the focus in event on bookmark manager
+ emit focusInEvent();
}
- ui.treeView->setFocus();
}
-void BookmarkDialog::toolButtonClicked()
-{
- bool visible = !ui.treeView->isVisible();
- ui.treeView->setVisible(visible);
- ui.newFolderButton->setVisible(visible);
+// -- BookmarkManager::BookmarkTreeView
- if (visible) {
- resize(QSize(width(), 400));
- ui.toolButton->setText(QLatin1String("-"));
- } else {
- resize(width(), minimumHeight());
- ui.toolButton->setText(QLatin1String("+"));
- }
-}
-
-void BookmarkDialog::itemChanged(QStandardItem *item)
+BookmarkManager::BookmarkTreeView::BookmarkTreeView(QWidget *parent)
+ : QTreeView(parent)
{
- if (renameItem != item) {
- renameItem = item;
- oldText = item->text();
- return;
- }
+ TRACE_OBJ
+ setAcceptDrops(true);
+ setDragEnabled(true);
+ setAutoExpandDelay(1000);
+ setUniformRowHeights(true);
+ setDropIndicatorShown(true);
+ setExpandsOnDoubleClick(true);
- if (item->text() != oldText) {
- ui.bookmarkFolders->clear();
- ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
+ connect(this, SIGNAL(expanded(QModelIndex)), this,
+ SLOT(setExpandedData(QModelIndex)));
+ connect(this, SIGNAL(collapsed(QModelIndex)), this,
+ SLOT(setExpandedData(QModelIndex)));
- 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)
+void BookmarkManager::BookmarkTreeView::subclassKeyPressEvent(QKeyEvent *event)
{
- ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(!string.isEmpty());
+ TRACE_OBJ
+ QTreeView::keyPressEvent(event);
}
-void BookmarkDialog::selectBookmarkFolder(const QString &folderName)
+void BookmarkManager::BookmarkTreeView::setExpandedData(const QModelIndex &index)
{
- 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()) {
- const QModelIndex &index = model->indexFromItem(list.at(0));
- QItemSelectionModel *model = ui.treeView->selectionModel();
- if (model) {
- model->setCurrentIndex(proxyModel->mapFromSource(index),
- QItemSelectionModel::ClearAndSelect);
- }
- }
+ TRACE_OBJ
+ if (BookmarkModel *treeModel = qobject_cast<BookmarkModel*> (model()))
+ treeModel->setData(index, isExpanded(index), UserRoleExpanded);
}
-void BookmarkDialog::customContextMenuRequested(const QPoint &point)
-{
- QModelIndex index = ui.treeView->indexAt(point);
- if (!index.isValid())
- return;
-
- QMenu menu(QLatin1String(""), this);
+// -- BookmarkManager
- QAction *removeItem = menu.addAction(tr("Delete Folder"));
- QAction *renameItem = menu.addAction(tr("Rename Folder"));
-
- QAction *picked = menu.exec(ui.treeView->mapToGlobal(point));
- if (!picked)
- return;
-
- const QModelIndex &proxyIndex = proxyModel->mapToSource(index);
- if (picked == removeItem) {
- bookmarkManager->removeBookmarkItem(ui.treeView, proxyIndex);
- 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 == renameItem) {
- BookmarkModel *model = bookmarkManager->treeBookmarkModel();
- if (QStandardItem *item = model->itemFromIndex(proxyIndex)) {
- item->setEditable(true);
- ui.treeView->edit(index);
- item->setEditable(false);
- }
- }
-}
+QMutex BookmarkManager::mutex;
+BookmarkManager* BookmarkManager::bookmarkManager = 0;
-void BookmarkDialog::currentChanged(const QModelIndex &current)
-{
- QString text = tr("Bookmarks");
- if (current.isValid())
- text = current.data().toString();
- ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(text));
-}
+// -- public
-bool BookmarkDialog::eventFilter(QObject *object, QEvent *e)
+BookmarkManager* BookmarkManager::instance()
{
- if (object != ui.treeView && object != ui.treeView->viewport())
- return QWidget::eventFilter(object, e);
-
- if (e->type() == QEvent::KeyPress) {
- QKeyEvent *ke = static_cast<QKeyEvent*>(e);
- switch (ke->key()) {
- case Qt::Key_F2: {
- const QModelIndex &index = ui.treeView->currentIndex();
- 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: {
- const QModelIndex &index = ui.treeView->currentIndex();
- bookmarkManager->removeBookmarkItem(ui.treeView,
- proxyModel->mapToSource(index));
- ui.bookmarkFolders->clear();
- ui.bookmarkFolders->addItems(bookmarkManager->bookmarkFolders());
-
- QString name = tr("Bookmarks");
- if (index.isValid())
- name = index.data().toString();
- ui.bookmarkFolders->setCurrentIndex(ui.bookmarkFolders->findText(name));
- } break;
-
- default:
- break;
- }
+ TRACE_OBJ
+ if (!bookmarkManager) {
+ QMutexLocker _(&mutex);
+ if (!bookmarkManager)
+ bookmarkManager = new BookmarkManager();
}
-
- return QObject::eventFilter(object, e);
+ return bookmarkManager;
}
-
-// #pragma mark -- BookmarkWidget
-
-
-BookmarkWidget::BookmarkWidget(BookmarkManager *manager, QWidget *parent,
- bool showButtons)
- : QWidget(parent)
- , addButton(0)
- , removeButton(0)
- , bookmarkManager(manager)
+void BookmarkManager::destroy()
{
- setup(showButtons);
-
- installEventFilter(this);
- treeView->installEventFilter(this);
- treeView->viewport()->installEventFilter(this);
+ TRACE_OBJ
+ delete bookmarkManager;
+ bookmarkManager = 0;
}
-BookmarkWidget::~BookmarkWidget()
+QWidget* BookmarkManager::bookmarkDockWidget() const
{
+ TRACE_OBJ
+ if (bookmarkWidget)
+ return bookmarkWidget;
+ return 0;
}
-void BookmarkWidget::removeClicked()
+void BookmarkManager::takeBookmarksMenu(QMenu* menu)
{
- const QModelIndex &index = treeView->currentIndex();
- if (searchField->text().isEmpty()) {
- bookmarkManager->removeBookmarkItem(treeView,
- filterBookmarkModel->mapToSource(index));
- }
+ TRACE_OBJ
+ bookmarkMenu = menu;
+ refeshBookmarkMenu();
}
-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());
- }
+// -- public slots
- if (addButton)
- addButton->setEnabled(searchBookmarks);
-
- if (removeButton)
- removeButton->setEnabled(searchBookmarks);
-
- filterBookmarkModel->setFilterRegExp(regExp);
-
- const QModelIndex &index = treeView->indexAt(QPoint(1, 1));
- if (index.isValid())
- treeView->setCurrentIndex(index);
-
- if (searchBookmarks)
- expandItems();
-}
-
-void BookmarkWidget::expand(const QModelIndex &index)
+void BookmarkManager::addBookmark(const QString &title, const QString &url)
{
- const QModelIndex &source = filterBookmarkModel->mapToSource(index);
- QStandardItem *item =
- bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
- if (item)
- item->setData(treeView->isExpanded(index), Qt::UserRole + 11);
+ TRACE_OBJ
+ showBookmarkDialog(title.isEmpty() ? tr("Untitled") : title,
+ url.isEmpty() ? QLatin1String("about:blank") : url);
}
-void BookmarkWidget::activated(const QModelIndex &index)
-{
- if (!index.isValid())
- return;
+// -- private
- QString data = index.data(Qt::UserRole + 10).toString();
- if (data != QLatin1String("Folder"))
- emit requestShowLink(data);
-}
-
-void BookmarkWidget::customContextMenuRequested(const QPoint &point)
+BookmarkManager::BookmarkManager()
+ : typeAndSearch(false)
+ , bookmarkMenu(0)
+ , bookmarkModel(new BookmarkModel)
+ , bookmarkWidget(new BookmarkWidget)
+ , bookmarkTreeView(new BookmarkTreeView)
+ , bookmarkManagerWidget(0)
{
- QModelIndex index = treeView->indexAt(point);
- if (!index.isValid())
- return;
+ TRACE_OBJ
+ bookmarkWidget->installEventFilter(this);
+ connect(bookmarkWidget->ui.add, SIGNAL(clicked()), this,
+ SLOT(addBookmark()));
+ connect(bookmarkWidget->ui.remove, SIGNAL(clicked()), this,
+ SLOT(removeBookmark()));
+ connect(bookmarkWidget->ui.lineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ connect(bookmarkWidget, SIGNAL(focusInEvent()), this, SLOT(focusInEvent()));
- 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"));
- }
- }
+ bookmarkTreeView->setModel(bookmarkModel);
+ bookmarkTreeView->installEventFilter(this);
+ bookmarkTreeView->viewport()->installEventFilter(this);
+ bookmarkTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
+ bookmarkWidget->ui.stackedWidget->addWidget(bookmarkTreeView);
- QAction *pickedAction = menu.exec(treeView->mapToGlobal(point));
- if (!pickedAction)
- return;
+ connect(bookmarkTreeView, SIGNAL(activated(QModelIndex)), this,
+ SLOT(setSourceFromIndex(QModelIndex)));
+ connect(bookmarkTreeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
- if (pickedAction == showItem) {
- emit requestShowLink(data);
- }
- else if (pickedAction == showItemNewTab) {
- CentralWidget::instance()->setSourceInNewTab(data);
- }
- else if (pickedAction == removeItem) {
- bookmarkManager->removeBookmarkItem(treeView,
- filterBookmarkModel->mapToSource(index));
- }
- else if (pickedAction == renameItem) {
- const QModelIndex &source = filterBookmarkModel->mapToSource(index);
- QStandardItem *item =
- bookmarkManager->treeBookmarkModel()->itemFromIndex(source);
- if (item) {
- item->setEditable(true);
- treeView->edit(index);
- item->setEditable(false);
- }
- }
+ connect(&HelpEngineWrapper::instance(), SIGNAL(setupFinished()), this,
+ SLOT(setupFinished()));
+ connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkMenu()));
+ connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkMenu()));
+ connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(refeshBookmarkMenu()));
}
-void BookmarkWidget::setup(bool showButtons)
+BookmarkManager::~BookmarkManager()
{
- 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(QString)), this,
- SLOT(filterChanged()));
-
- treeView = new TreeView(this);
- vlayout->addWidget(treeView);
-
-#ifdef Q_OS_MAC
-# define SYSTEM "mac"
-#else
-# define SYSTEM "win"
-#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(QLatin1String(":/trolltech/assistant/images/"
- SYSTEM "/addtab.png")));
- 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(QLatin1String(":/trolltech/assistant/images/"
- SYSTEM "/closetab.png")));
- 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->setContextMenuPolicy(Qt::CustomContextMenu);
-
- connect(treeView, SIGNAL(expanded(QModelIndex)), this,
- SLOT(expand(QModelIndex)));
- connect(treeView, SIGNAL(collapsed(QModelIndex)), this,
- SLOT(expand(QModelIndex)));
- connect(treeView, SIGNAL(activated(QModelIndex)), this,
- SLOT(activated(QModelIndex)));
- connect(treeView, SIGNAL(customContextMenuRequested(QPoint)),
- this, SLOT(customContextMenuRequested(QPoint)));
-
- filterBookmarkModel->setFilterKeyColumn(0);
- filterBookmarkModel->setDynamicSortFilter(true);
- filterBookmarkModel->setSourceModel(bookmarkManager->treeBookmarkModel());
-
- expandItems();
+ TRACE_OBJ
+ delete bookmarkManagerWidget;
+ HelpEngineWrapper::instance().setBookmarks(bookmarkModel->bookmarks());
+ delete bookmarkModel;
}
-void BookmarkWidget::expandItems()
+void BookmarkManager::removeItem(const QModelIndex &index)
{
- 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());
+ TRACE_OBJ
+ QModelIndex current = index;
+ if (typeAndSearch) { // need to map because of proxy
+ current = typeAndSearchModel->mapToSource(current);
+ current = bookmarkFilterModel->mapToSource(current);
+ } else if (!bookmarkModel->parent(index).isValid()) {
+ return; // check if we should delete the "Bookmarks Menu", bail
}
-}
-
-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);
+ if (bookmarkModel->hasChildren(current)) {
+ int value = QMessageBox::question(bookmarkTreeView, 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;
}
+ bookmarkModel->removeItem(current);
}
-bool BookmarkWidget::eventFilter(QObject *object, QEvent *e)
+bool BookmarkManager::eventFilter(QObject *object, QEvent *event)
{
- if (object != this && object != treeView
- && object != treeView->viewport()) {
- return QWidget::eventFilter(object, e);
- }
+ if (object != bookmarkTreeView && object != bookmarkTreeView->viewport()
+ && object != bookmarkWidget)
+ return QObject::eventFilter(object, event);
- if (e->type() == QEvent::KeyPress) {
- QKeyEvent *ke = static_cast<QKeyEvent*>(e);
- const bool tree = object == treeView || object == treeView->viewport();
+ TRACE_OBJ
+ const bool isWidget = object == bookmarkWidget;
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
switch (ke->key()) {
case Qt::Key_F2: {
- const QModelIndex &index = treeView->currentIndex();
- const QModelIndex &src = filterBookmarkModel->mapToSource(index);
- if (tree && searchField->text().isEmpty()) {
- if (QStandardItem *item = bookmarkManager->treeBookmarkModel()
- ->itemFromIndex(src)) {
- item->setEditable(true);
- treeView->edit(index);
- item->setEditable(false);
- }
- }
- } break;
-
- case Qt::Key_Enter: {
- case Qt::Key_Return:
- if (tree) {
- const QString &data = treeView->selectionModel()->currentIndex()
- .data(Qt::UserRole + 10).toString();
- if (!data.isEmpty() && data != QLatin1String("Folder"))
- emit requestShowLink(data);
- }
+ renameBookmark(bookmarkTreeView->currentIndex());
} break;
case Qt::Key_Delete: {
- const QModelIndex &index = treeView->currentIndex();
- const QModelIndex &src = filterBookmarkModel->mapToSource(index);
- if (tree && searchField->text().isEmpty())
- bookmarkManager->removeBookmarkItem(treeView, src);
+ removeItem(bookmarkTreeView->currentIndex());
+ return true;
} break;
- case Qt::Key_Up: {
+ case Qt::Key_Up: { // needs event filter on widget
case Qt::Key_Down:
- if (!tree)
- treeView->subclassKeyPressEvent(ke);
+ if (isWidget)
+ bookmarkTreeView->subclassKeyPressEvent(ke);
} break;
case Qt::Key_Escape: {
@@ -591,324 +257,233 @@ bool BookmarkWidget::eventFilter(QObject *object, QEvent *e)
}
}
- if (e->type() == QEvent::MouseButtonRelease) {
- QMouseEvent *me = static_cast<QMouseEvent*>(e);
- bool controlPressed = me->modifiers() & Qt::ControlModifier;
- if(((me->button() == Qt::LeftButton) && controlPressed)
- || (me->button() == Qt::MidButton)) {
- const QModelIndex &index = treeView->currentIndex();
- const QString &data = index.data(Qt::UserRole + 10).toString();
- if (!data.isEmpty() && data != QLatin1String("Folder"))
- CentralWidget::instance()->setSourceInNewTab(data);
+ if (event->type() == QEvent::MouseButtonRelease && !isWidget) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ switch (me->button()) {
+ case Qt::LeftButton: {
+ if (me->modifiers() & Qt::ControlModifier)
+ setSourceFromIndex(bookmarkTreeView->currentIndex(), true);
+ } break;
+
+ case Qt::MidButton: {
+ setSourceFromIndex(bookmarkTreeView->currentIndex(), true);
+ } break;
+
+ default: break;
}
}
- return QWidget::eventFilter(object, e);
+ return QObject::eventFilter(object, event);
}
-
-// #pragma mark -- BookmarkModel
-
-
-BookmarkModel::BookmarkModel(int rows, int columns, QObject *parent)
- : QStandardItemModel(rows, columns, parent)
+void BookmarkManager::buildBookmarksMenu(const QModelIndex &index, QMenu* menu)
{
-}
+ TRACE_OBJ
+ if (!index.isValid())
+ return;
-BookmarkModel::~BookmarkModel()
-{
+ const QString &text = index.data().toString();
+ const QIcon &icon = qVariantValue<QIcon>(index.data(Qt::DecorationRole));
+ if (index.data(UserRoleFolder).toBool()) {
+ if (QMenu* subMenu = menu->addMenu(icon, text)) {
+ for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
+ buildBookmarksMenu(bookmarkModel->index(i, 0, index), subMenu);
+ }
+ } else {
+ QAction *action = menu->addAction(icon, text);
+ action->setData(index.data(UserRoleUrl).toString());
+ }
}
-Qt::DropActions BookmarkModel::supportedDropActions() const
+void BookmarkManager::showBookmarkDialog(const QString &name, const QString &url)
{
- return Qt::MoveAction;
+ TRACE_OBJ
+ BookmarkDialog dialog(bookmarkModel, name, url, bookmarkTreeView);
+ dialog.exec();
}
-Qt::ItemFlags BookmarkModel::flags(const QModelIndex &index) const
-{
- Qt::ItemFlags defaultFlags = QStandardItemModel::flags(index);
- if ((!index.isValid()) // can only happen for the invisible root item
- || index.data(Qt::UserRole + 10).toString() == QLatin1String("Folder"))
- return (Qt::ItemIsDropEnabled | defaultFlags) &~ Qt::ItemIsDragEnabled;
+// -- private slots
- return (Qt::ItemIsDragEnabled | defaultFlags) &~ Qt::ItemIsDropEnabled;
-}
+void BookmarkManager::setupFinished()
+{
+ TRACE_OBJ
+ bookmarkModel->setBookmarks(HelpEngineWrapper::instance().bookmarks());
+ bookmarkModel->expandFoldersIfNeeeded(bookmarkTreeView);
+ refeshBookmarkMenu();
-// #pragma mark -- BookmarkManager
+ bookmarkTreeView->hideColumn(1);
+ bookmarkTreeView->header()->setVisible(false);
+ bookmarkTreeView->header()->setStretchLastSection(true);
+ bookmarkFilterModel = new BookmarkFilterModel(this);
+ bookmarkFilterModel->setSourceModel(bookmarkModel);
+ bookmarkFilterModel->filterBookmarkFolders();
-BookmarkManager::BookmarkManager(QHelpEngineCore *_helpEngine)
- : treeModel(new BookmarkModel(0, 1, this))
- , listModel(new BookmarkModel(0, 1, this))
- , renameItem(0)
- , helpEngine(_helpEngine)
-{
- folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
-
- connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this,
- SLOT(itemChanged(QStandardItem*)));
- connect(treeModel, SIGNAL(itemChanged(QStandardItem*)), this,
- SIGNAL(bookmarksChanged()));
- connect(treeModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SIGNAL(bookmarksChanged()));
+ typeAndSearchModel = new QSortFilterProxyModel(this);
+ typeAndSearchModel->setDynamicSortFilter(true);
+ typeAndSearchModel->setSourceModel(bookmarkFilterModel);
}
-BookmarkManager::~BookmarkManager()
+void BookmarkManager::addBookmark()
{
- treeModel->clear();
- listModel->clear();
+ TRACE_OBJ
+ if (CentralWidget *widget = CentralWidget::instance())
+ addBookmark(widget->currentTitle(), widget->currentSource().toString());
}
-BookmarkModel* BookmarkManager::treeBookmarkModel()
+void BookmarkManager::removeBookmark()
{
- return treeModel;
+ TRACE_OBJ
+ removeItem(bookmarkTreeView->currentIndex());
}
-BookmarkModel* BookmarkManager::listBookmarkModel()
+void BookmarkManager::manageBookmarks()
{
- return listModel;
+ TRACE_OBJ
+ if (bookmarkManagerWidget == 0) {
+ bookmarkManagerWidget = new BookmarkManagerWidget(bookmarkModel);
+ connect(bookmarkManagerWidget, SIGNAL(setSource(QUrl)), this,
+ SIGNAL(setSource(QUrl)));
+ connect(bookmarkManagerWidget, SIGNAL(setSourceInNewTab(QUrl))
+ , this, SIGNAL(setSourceInNewTab(QUrl)));
+ connect(bookmarkManagerWidget, SIGNAL(managerWidgetAboutToClose())
+ , this, SLOT(managerWidgetAboutToClose()));
+ }
+ bookmarkManagerWidget->show();
+ bookmarkManagerWidget->raise();
}
-void BookmarkManager::saveBookmarks()
+void BookmarkManager::refeshBookmarkMenu()
{
- QByteArray bookmarks;
- QDataStream stream(&bookmarks, QIODevice::WriteOnly);
+ TRACE_OBJ
+ if (!bookmarkMenu)
+ return;
- readBookmarksRecursive(treeModel->invisibleRootItem(), stream, 0);
- helpEngine->setCustomValue(QLatin1String("Bookmarks"), bookmarks);
-}
+ bookmarkMenu->clear();
-QStringList BookmarkManager::bookmarkFolders() const
-{
- QStringList folders(tr("Bookmarks"));
+ bookmarkMenu->addAction(tr("Manage Bookmarks..."), this,
+ SLOT(manageBookmarks()));
+ bookmarkMenu->addAction(QIcon::fromTheme("bookmark-new"),
+ tr("Add Bookmark..."), this, SLOT(addBookmark()),
+ QKeySequence(tr("Ctrl+D")));
+ bookmarkMenu->addSeparator();
- 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;
-}
+ const QModelIndex &root = bookmarkModel->index(0, 0, QModelIndex());
+ for (int i = 0; i < bookmarkModel->rowCount(root); ++i)
+ buildBookmarksMenu(bookmarkModel->index(i, 0, root), bookmarkMenu);
-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);
+ connect(bookmarkMenu, SIGNAL(triggered(QAction*)), this,
+ SLOT(setSourceFromAction(QAction*)));
}
-void BookmarkManager::removeBookmarkItem(QTreeView *treeView,
- const QModelIndex &index)
+void BookmarkManager::renameBookmark(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());
- }
-}
+ // check if we should rename the "Bookmarks Menu", bail
+ if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
+ return;
-void BookmarkManager::showBookmarkDialog(QWidget *parent, const QString &name,
- const QString &url)
-{
- BookmarkDialog dialog(this, name, url, parent);
- dialog.exec();
+ bookmarkModel->setItemsEditable(true);
+ bookmarkTreeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
}
-void BookmarkManager::addNewBookmark(const QModelIndex &index,
- const QString &name, const QString &url)
+void BookmarkManager::setSourceFromAction(QAction *action)
{
- QStandardItem *item = new QStandardItem(name);
- item->setEditable(false);
- item->setData(false, Qt::UserRole + 11);
- item->setData(url, Qt::UserRole + 10);
+ TRACE_OBJ
+ const QVariant &data = action->data();
- if (index.isValid())
- treeModel->itemFromIndex(index)->appendRow(item);
- else
- treeModel->appendRow(item);
- listModel->appendRow(item->clone());
- emit bookmarksChanged();
+ if (data.canConvert<QUrl>())
+ emit setSource(data.toUrl());
}
-void BookmarkManager::fillBookmarkMenu(QMenu *menu)
+void BookmarkManager::setSourceFromIndex(const QModelIndex &index, bool newTab)
{
- if (!menu || !treeModel)
- return;
+ TRACE_OBJ
+ QAbstractItemModel *base = bookmarkModel;
+ if (typeAndSearch)
+ base = typeAndSearchModel;
- map.clear();
- fillBookmarkMenu(menu, treeModel->invisibleRootItem());
-}
-
-void BookmarkManager::fillBookmarkMenu(QMenu *menu, QStandardItem *root)
-{
- for (int i = 0; i < root->rowCount(); ++i) {
- QStandardItem *item = root->child(i);
- if (item && item->data(Qt::UserRole + 10)
- .toString() == QLatin1String("Folder")) {
- QMenu* newMenu = menu->addMenu(folderIcon, item->text());
- if (item->rowCount() > 0)
- fillBookmarkMenu(newMenu, item);
- } else {
- map.insert(menu->addAction(item->text()), item->index());
- }
- }
-}
+ if (base->data(index, UserRoleFolder).toBool())
+ return;
-QUrl BookmarkManager::urlForAction(QAction* action) const
-{
- if (map.contains(action)) {
- const QModelIndex &index = map.value(action);
- if (QStandardItem* item = treeModel->itemFromIndex(index))
- return QUrl(item->data(Qt::UserRole + 10).toString());
+ const QVariant &data = base->data(index, UserRoleUrl);
+ if (data.canConvert<QUrl>()) {
+ if (newTab)
+ emit setSourceInNewTab(data.toUrl());
+ else
+ emit setSource(data.toUrl());
}
- return QUrl();
}
-void BookmarkManager::itemChanged(QStandardItem *item)
+void BookmarkManager::customContextMenuRequested(const QPoint &point)
{
- if (renameItem != item) {
- renameItem = item;
- oldText = item->text();
+ TRACE_OBJ
+ QModelIndex index = bookmarkTreeView->indexAt(point);
+ if (!index.isValid())
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());
- }
- }
-}
+ // check if we should open the menu on "Bookmarks Menu", bail
+ if (!typeAndSearch && !bookmarkModel->parent(index).isValid())
+ return;
-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;
- }
- }
+ QAction *remove = 0;
+ QAction *rename = 0;
+ QAction *showItem = 0;
+ QAction *showItemInNewTab = 0;
- if (type == QLatin1String("Folder"))
- item->setIcon(folderIcon);
- else
- listModel->appendRow(item->clone());
+ QMenu menu(QLatin1String(""));
+ if (!typeAndSearch && bookmarkModel->data(index, UserRoleFolder).toBool()) {
+ remove = menu.addAction(tr("Delete Folder"));
+ rename = menu.addAction(tr("Rename Folder"));
+ } else {
+ showItem = menu.addAction(tr("Show Bookmark"));
+ showItemInNewTab = menu.addAction(tr("Show Bookmark in New Tab"));
+ menu.addSeparator();
+ remove = menu.addAction(tr("Delete Bookmark"));
+ rename = menu.addAction(tr("Rename Bookmark"));
}
+
+ QAction *pickedAction = menu.exec(bookmarkTreeView->mapToGlobal(point));
+ if (pickedAction == rename)
+ renameBookmark(index);
+ else if (pickedAction == remove)
+ removeItem(index);
+ else if (pickedAction == showItem || pickedAction == showItemInNewTab)
+ setSourceFromIndex(index, pickedAction == showItemInNewTab);
}
-QString BookmarkManager::uniqueFolderName() const
+void BookmarkManager::focusInEvent()
{
- 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;
+ TRACE_OBJ
+ const QModelIndex &index = bookmarkTreeView->indexAt(QPoint(2, 2));
+ if (index.isValid())
+ bookmarkTreeView->setCurrentIndex(index);
}
-void BookmarkManager::removeBookmarkFolderItems(QStandardItem *item)
+void BookmarkManager::managerWidgetAboutToClose()
{
- 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;
- }
- }
- }
+ delete bookmarkManagerWidget;
+ bookmarkManagerWidget = 0;
}
-void BookmarkManager::readBookmarksRecursive(const QStandardItem *item,
- QDataStream &stream, const qint32 depth) const
+void BookmarkManager::textChanged(const QString &text)
{
- 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));
+ TRACE_OBJ
+ if (!bookmarkWidget->ui.lineEdit->text().isEmpty()) {
+ if (!typeAndSearch) {
+ typeAndSearch = true;
+ bookmarkTreeView->setItemsExpandable(false);
+ bookmarkTreeView->setRootIsDecorated(false);
+ bookmarkTreeView->setModel(typeAndSearchModel);
+ }
+ typeAndSearchModel->setFilterRegExp(QRegExp(text));
+ } else {
+ typeAndSearch = false;
+ bookmarkTreeView->setModel(bookmarkModel);
+ bookmarkTreeView->setItemsExpandable(true);
+ bookmarkTreeView->setRootIsDecorated(true);
+ bookmarkModel->expandFoldersIfNeeeded(bookmarkTreeView);
}
}
diff --git a/tools/assistant/tools/assistant/bookmarkmanager.h b/tools/assistant/tools/assistant/bookmarkmanager.h
index da36833..c26dad8 100644
--- a/tools/assistant/tools/assistant/bookmarkmanager.h
+++ b/tools/assistant/tools/assistant/bookmarkmanager.h
@@ -38,178 +38,118 @@
** $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 <QtCore/QMutex>
#include <QtGui/QTreeView>
-#include <QtGui/QStandardItemModel>
+
+#include "ui_bookmarkwidget.h"
QT_BEGIN_NAMESPACE
-class QEvent;
-class QLineEdit;
-class QTreeView;
-class QToolButton;
-class QStandardItem;
-class QHelpEngineCore;
-class QAbstractItemModel;
+class BookmarkManagerWidget;
+class BookmarkModel;
+class BookmarkFilterModel;
+class QKeyEvent;
class QSortFilterProxyModel;
-class BookmarkManager;
-
-class BookmarkDialog : public QDialog
+class BookmarkManager : public QObject
{
Q_OBJECT
+ class BookmarkWidget;
+ class BookmarkTreeView;
+ class BookmarkListView;
+ Q_DISABLE_COPY(BookmarkManager);
public:
- BookmarkDialog(BookmarkManager *manager, const QString &title,
- const QString &url, QWidget *parent = 0);
- ~BookmarkDialog();
+ static BookmarkManager* instance();
+ static void destroy();
-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);
-
-private:
- bool eventFilter(QObject *object, QEvent *e);
+ QWidget* bookmarkDockWidget() const;
+ void takeBookmarksMenu(QMenu* menu);
-private:
- QString m_url;
- QString m_title;
-
- QString oldText;
- QStandardItem *renameItem;
+public slots:
+ void addBookmark(const QString &title, const QString &url);
- Ui::BookmarkDialog ui;
- BookmarkManager *bookmarkManager;
- QSortFilterProxyModel *proxyModel;
-};
+signals:
+ void escapePressed();
+ void setSource(const QUrl &url);
+ void setSourceInNewTab(const QUrl &url);
-class TreeView : public QTreeView {
- Q_OBJECT
-public:
- TreeView(QWidget* parent = 0) : QTreeView(parent) {}
- void subclassKeyPressEvent(QKeyEvent* event)
- {
- QTreeView::keyPressEvent(event);
- }
-};
+private:
+ BookmarkManager();
+ ~BookmarkManager();
-class BookmarkWidget : public QWidget
-{
- Q_OBJECT
+ void removeItem(const QModelIndex &index);
+ bool eventFilter(QObject *object, QEvent *event);
+ void buildBookmarksMenu(const QModelIndex &index, QMenu *menu);
+ void showBookmarkDialog(const QString &name, const QString &url);
-public:
- BookmarkWidget(BookmarkManager *manager, QWidget *parent = 0,
- bool showButtons = true);
- ~BookmarkWidget();
+private slots:
+ void setupFinished();
-signals:
void addBookmark();
- void requestShowLink(const QUrl &url);
- void escapePressed();
+ void removeBookmark();
+ void manageBookmarks();
+ void refeshBookmarkMenu();
+ void renameBookmark(const QModelIndex &index);
-private slots:
- void removeClicked();
- void filterChanged();
- void expand(const QModelIndex& index);
- void activated(const QModelIndex &index);
+ void setSourceFromAction(QAction *action);
+ void setSourceFromIndex(const QModelIndex &index, bool newTab = false);
+
+ void focusInEvent();
+ void managerWidgetAboutToClose();
+ void textChanged(const QString &text);
void customContextMenuRequested(const QPoint &point);
private:
- void setup(bool showButtons);
- void expandItems();
- void focusInEvent(QFocusEvent *e);
- bool eventFilter(QObject *object, QEvent *event);
+ bool typeAndSearch;
-private:
- QRegExp regExp;
- TreeView *treeView;
- QLineEdit *searchField;
- QToolButton *addButton;
- QToolButton *removeButton;
- BookmarkManager *bookmarkManager;
- QSortFilterProxyModel* filterBookmarkModel;
-};
+ static QMutex mutex;
+ static BookmarkManager *bookmarkManager;
-class BookmarkModel : public QStandardItemModel
-{
- Q_OBJECT
+ QMenu *bookmarkMenu;
-public:
- BookmarkModel(int rows, int columns, QObject *parent = 0);
- ~BookmarkModel();
+ BookmarkModel *bookmarkModel;
+ BookmarkFilterModel *bookmarkFilterModel;
+ QSortFilterProxyModel *typeAndSearchModel;
- Qt::DropActions supportedDropActions() const;
- Qt::ItemFlags flags(const QModelIndex &index) const;
+ BookmarkWidget *bookmarkWidget;
+ BookmarkTreeView *bookmarkTreeView;
+ BookmarkManagerWidget *bookmarkManagerWidget;
};
-class BookmarkManager : public QObject
+class BookmarkManager::BookmarkWidget : public QWidget
{
Q_OBJECT
-
public:
- BookmarkManager(QHelpEngineCore* helpEngine);
- ~BookmarkManager();
+ BookmarkWidget(QWidget *parent = 0)
+ : QWidget(parent) { ui.setupUi(this); }
+ virtual ~BookmarkWidget() {}
- 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();
-
- void fillBookmarkMenu(QMenu *menu);
- QUrl urlForAction(QAction* action) const;
+ Ui::BookmarkWidget ui;
signals:
- void bookmarksChanged();
-
-private slots:
- void itemChanged(QStandardItem *item);
+ void focusInEvent();
private:
- QString uniqueFolderName() const;
- void removeBookmarkFolderItems(QStandardItem *item);
- void readBookmarksRecursive(const QStandardItem *item, QDataStream &stream,
- const qint32 depth) const;
- void fillBookmarkMenu(QMenu *menu, QStandardItem *root);
+ void focusInEvent(QFocusEvent *event);
+};
-private:
- QString oldText;
- QIcon folderIcon;
-
- BookmarkModel *treeModel;
- BookmarkModel *listModel;
- QStandardItem *renameItem;
- QHelpEngineCore *helpEngine;
- QMap<QAction*, QModelIndex> map;
+class BookmarkManager::BookmarkTreeView : public QTreeView
+{
+ Q_OBJECT
+public:
+ BookmarkTreeView(QWidget *parent = 0);
+ ~BookmarkTreeView() {}
+
+ void subclassKeyPressEvent(QKeyEvent *event);
+
+private slots:
+ void setExpandedData(const QModelIndex &index);
};
QT_END_NAMESPACE
-#endif
+#endif // BOOKMARKMANAGER_H
diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp b/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp
new file mode 100644
index 0000000..65df6be
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkmanagerwidget.h"
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+#include "tracer.h"
+#include "xbelsupport.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFile>
+#include <QtCore/QUrl>
+
+#include <QtGui/QCloseEvent>
+#include <QtGui/QFileDialog>
+#include <QtGui/QKeySequence>
+#include <QtGui/QMessageBox>
+#include <QtGui/QShortcut>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ #define TR(x) QCoreApplication::translate("BookmarkManager", x)
+}
+
+BookmarkManagerWidget::BookmarkManagerWidget(BookmarkModel *sourceModel,
+ QWidget *parent)
+ : QWidget(parent)
+ , bookmarkModel(sourceModel)
+{
+ TRACE_OBJ
+ ui.setupUi(this);
+
+ ui.treeView->setModel(bookmarkModel);
+
+ ui.treeView->expandAll();
+ ui.treeView->installEventFilter(this);
+ ui.treeView->viewport()->installEventFilter(this);
+ ui.treeView->setContextMenuPolicy(Qt::CustomContextMenu);
+
+ connect(ui.treeView, SIGNAL(customContextMenuRequested(QPoint)), this,
+ SLOT(customContextMenuRequested(QPoint)));
+
+ connect(ui.remove, SIGNAL(clicked()), this, SLOT(removeItem()));
+ connect(ui.lineEdit, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ new QShortcut(QKeySequence::Find, ui.lineEdit, SLOT(setFocus()));
+
+ importExportMenu.addAction(tr("Import..."), this, SLOT(importBookmarks()));
+ importExportMenu.addAction(tr("Export..."), this, SLOT(exportBookmarks()));
+ ui.importExport->setMenu(&importExportMenu);
+
+ new QShortcut(QKeySequence::FindNext, this, SLOT(findNext()));
+ new QShortcut(QKeySequence::FindPrevious, this, SLOT(findPrevious()));
+
+ connect(bookmarkModel, SIGNAL(rowsRemoved(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkCache()));
+ connect(bookmarkModel, SIGNAL(rowsInserted(QModelIndex, int, int)), this,
+ SLOT(refeshBookmarkCache()));
+ connect(bookmarkModel, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this,
+ SLOT(refeshBookmarkCache()));
+
+ ui.treeView->setCurrentIndex(ui.treeView->indexAt(QPoint(2, 2)));
+}
+
+BookmarkManagerWidget::~BookmarkManagerWidget()
+{
+ TRACE_OBJ
+}
+
+void BookmarkManagerWidget::closeEvent(QCloseEvent *event)
+{
+ TRACE_OBJ
+ event->accept();
+ emit managerWidgetAboutToClose();
+}
+
+void BookmarkManagerWidget::renameItem(const QModelIndex &index)
+{
+ TRACE_OBJ
+ // check if we should rename the "Bookmarks Menu", bail
+ if (!bookmarkModel->parent(index).isValid())
+ return;
+
+ bookmarkModel->setItemsEditable(true);
+ ui.treeView->edit(index);
+ bookmarkModel->setItemsEditable(false);
+}
+
+static int nextIndex(int current, int count, bool forward)
+{
+ TRACE_OBJ
+ if (current >= 0)
+ return (forward ? (current + 1) : ((current - 1) + count)) % count;
+ return 0;
+}
+
+void BookmarkManagerWidget::selectNextIndex(bool direction) const
+{
+ QModelIndex current = ui.treeView->currentIndex();
+ if (current.isValid() && !cache.isEmpty()) {
+ current = cache.at(nextIndex(cache.indexOf(current), cache.count(),
+ direction));
+ }
+ ui.treeView->setCurrentIndex(current);
+}
+
+bool BookmarkManagerWidget::eventFilter(QObject *object, QEvent *event)
+{
+ TRACE_OBJ
+ if (object != ui.treeView && object != ui.treeView->viewport())
+ return QWidget::eventFilter(object, event);
+
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent*>(event);
+ switch (ke->key()) {
+ case Qt::Key_F2: {
+ renameItem(ui.treeView->currentIndex());
+ } break;
+
+ case Qt::Key_Delete: {
+ removeItem(ui.treeView->currentIndex());
+ } break;
+
+ default: break;
+ }
+ }
+
+ if (event->type() == QEvent::MouseButtonRelease) {
+ QMouseEvent *me = static_cast<QMouseEvent*>(event);
+ switch (me->button()) {
+ case Qt::LeftButton: {
+ if (me->modifiers() & Qt::ControlModifier)
+ setSourceFromIndex(ui.treeView->currentIndex(), true);
+ } break;
+
+ case Qt::MidButton: {
+ setSourceFromIndex(ui.treeView->currentIndex(), true);
+ } break;
+
+ default: break;
+ }
+ }
+ return QObject::eventFilter(object, event);
+}
+
+void BookmarkManagerWidget::findNext()
+{
+ TRACE_OBJ
+ selectNextIndex(true);
+}
+
+void BookmarkManagerWidget::findPrevious()
+{
+ TRACE_OBJ
+ selectNextIndex(false);
+}
+
+void BookmarkManagerWidget::importBookmarks()
+{
+ TRACE_OBJ
+ const QString &fileName = QFileDialog::getOpenFileName(0, TR("Open File"),
+ QDir::currentPath(), TR("Files (*.xbel)"));
+
+ if (fileName.isEmpty())
+ return;
+
+ QFile file(fileName);
+ if (file.open(QIODevice::ReadOnly)) {
+ XbelReader reader(bookmarkModel);
+ reader.readFromFile(&file);
+ }
+}
+
+void BookmarkManagerWidget::exportBookmarks()
+{
+ TRACE_OBJ
+ QString fileName = QFileDialog::getSaveFileName(0, TR("Save File"),
+ QLatin1String("untitled.xbel"), TR("Files (*.xbel)"));
+
+ const QLatin1String suffix(".xbel");
+ if (!fileName.endsWith(suffix))
+ fileName.append(suffix);
+
+ QFile file(fileName);
+ if (file.open(QIODevice::WriteOnly)) {
+ XbelWriter writer(bookmarkModel);
+ writer.writeToFile(&file);
+ } else {
+ QMessageBox::information(this, TR("Qt Assistant"),
+ TR("Unable to save bookmarks."), TR("OK"));
+ }
+}
+
+void BookmarkManagerWidget::refeshBookmarkCache()
+{
+ TRACE_OBJ
+ cache.clear();
+
+ const QString &text = ui.lineEdit->text();
+ if (!text.isEmpty())
+ cache = bookmarkModel->indexListFor(text);
+}
+
+void BookmarkManagerWidget::textChanged(const QString &/*text*/)
+{
+ TRACE_OBJ
+ refeshBookmarkCache();
+ if (!cache.isEmpty())
+ ui.treeView->setCurrentIndex(cache.at(0));
+}
+
+void BookmarkManagerWidget::removeItem(const QModelIndex &index)
+{
+ TRACE_OBJ
+ QModelIndex current = index.isValid() ? index : ui.treeView->currentIndex();
+ if (!bookmarkModel->parent(current).isValid())
+ return; // check if we should delete the "Bookmarks Menu", bail
+
+ if (bookmarkModel->hasChildren(current)) {
+ int value = QMessageBox::question(this, 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;
+ }
+ bookmarkModel->removeItem(current);
+}
+
+void BookmarkManagerWidget::customContextMenuRequested(const QPoint &point)
+{
+ TRACE_OBJ
+ const QModelIndex &index = ui.treeView->indexAt(point);
+ if (!index.isValid())
+ return;
+
+ // check if we should open the menu on "Bookmarks Menu", bail
+ if (!bookmarkModel->parent(index).isValid())
+ return;
+
+ QAction *remove = 0;
+ QAction *rename = 0;
+ QAction *showItem = 0;
+ QAction *showItemInNewTab = 0;
+
+ QMenu menu(QLatin1String(""));
+ if (bookmarkModel->data(index, UserRoleFolder).toBool()) {
+ remove = menu.addAction(TR("Delete Folder"));
+ rename = menu.addAction(TR("Rename Folder"));
+ } else {
+ showItem = menu.addAction(TR("Show Bookmark"));
+ showItemInNewTab = menu.addAction(TR("Show Bookmark in New Tab"));
+ menu.addSeparator();
+ remove = menu.addAction(TR("Delete Bookmark"));
+ rename = menu.addAction(TR("Rename Bookmark"));
+ }
+
+ QAction *pickedAction = menu.exec(ui.treeView->mapToGlobal(point));
+ if (pickedAction == rename)
+ renameItem(index);
+ else if (pickedAction == remove)
+ removeItem(index);
+ else if (pickedAction == showItem || pickedAction == showItemInNewTab)
+ setSourceFromIndex(index, pickedAction == showItemInNewTab);
+}
+
+void
+BookmarkManagerWidget::setSourceFromIndex(const QModelIndex &index, bool newTab)
+{
+ TRACE_OBJ
+ if (bookmarkModel->data(index, UserRoleFolder).toBool())
+ return;
+
+ const QVariant &data = bookmarkModel->data(index, UserRoleUrl);
+ if (data.canConvert<QUrl>()) {
+ if (newTab)
+ emit setSourceInNewTab(data.toUrl());
+ else
+ emit setSource(data.toUrl());
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.h b/tools/assistant/tools/assistant/bookmarkmanagerwidget.h
new file mode 100644
index 0000000..56433cb
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKMANAGERWIDGET_H
+#define BOOKMARKMANAGERWIDGET_H
+
+#include "ui_bookmarkmanagerwidget.h"
+
+#include <QtCore/QPersistentModelIndex>
+
+#include <QtGui/QMenu>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkModel;
+class QCloseEvent;
+class QString;
+
+class BookmarkManagerWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ explicit BookmarkManagerWidget(BookmarkModel *bookmarkModel,
+ QWidget *parent = 0);
+ ~BookmarkManagerWidget();
+
+protected:
+ void closeEvent(QCloseEvent *event);
+
+signals:
+ void setSource(const QUrl &url);
+ void setSourceInNewTab(const QUrl &url);
+
+ void managerWidgetAboutToClose();
+
+private:
+ void renameItem(const QModelIndex &index);
+ void selectNextIndex(bool direction) const;
+ bool eventFilter(QObject *object, QEvent *event);
+
+private slots:
+ void findNext();
+ void findPrevious();
+
+ void importBookmarks();
+ void exportBookmarks();
+
+ void refeshBookmarkCache();
+ void textChanged(const QString &text);
+
+ void removeItem(const QModelIndex &index = QModelIndex());
+
+ void customContextMenuRequested(const QPoint &point);
+ void setSourceFromIndex(const QModelIndex &index, bool newTab = false);
+
+private:
+ QMenu importExportMenu;
+ Ui::BookmarkManagerWidget ui;
+ QList<QPersistentModelIndex> cache;
+
+ BookmarkModel *bookmarkModel;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKMANAGERWIDGET_H
diff --git a/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui b/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui
new file mode 100644
index 0000000..dc965d9
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmanagerwidget.ui
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BookmarkManagerWidget</class>
+ <widget class="QWidget" name="BookmarkManagerWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>517</width>
+ <height>348</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Manage Bookmarks</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <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>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QTreeView" name="treeView">
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="showDropIndicator" stdset="0">
+ <bool>true</bool>
+ </property>
+ <property name="dragEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="autoExpandDelay">
+ <number>1000</number>
+ </property>
+ <property name="uniformRowHeights">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerDefaultSectionSize">
+ <number>225</number>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>50</number>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>225</number>
+ </attribute>
+ <attribute name="headerMinimumSectionSize">
+ <number>50</number>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QPushButton" name="remove">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="importExport">
+ <property name="text">
+ <string>Import and Backup</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <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="QPushButton" name="pushButton_5">
+ <property name="text">
+ <string>OK</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>pushButton_5</sender>
+ <signal>clicked()</signal>
+ <receiver>BookmarkManagerWidget</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>445</x>
+ <y>328</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>340</x>
+ <y>313</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/assistant/tools/assistant/bookmarkmodel.cpp b/tools/assistant/tools/assistant/bookmarkmodel.cpp
new file mode 100644
index 0000000..4c30b42
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmodel.cpp
@@ -0,0 +1,452 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "bookmarkmodel.h"
+#include "bookmarkitem.h"
+
+#include <QtCore/QMimeData>
+#include <QtCore/QStack>
+
+#include <QtGui/QApplication>
+#include <QtGui/QStyle>
+#include <QtGui/QTreeView>
+
+const QLatin1String MIMETYPE("application/bookmarks.assistant");
+
+BookmarkModel::BookmarkModel()
+ : QAbstractItemModel()
+ , m_folder(false)
+ , m_editable(false)
+ , rootItem(0)
+{
+}
+
+BookmarkModel::~BookmarkModel()
+{
+ delete rootItem;
+}
+
+QByteArray
+BookmarkModel::bookmarks() const
+{
+ QByteArray ba;
+ QDataStream stream(&ba, QIODevice::WriteOnly);
+
+ const QModelIndex &root = index(0,0, QModelIndex());
+ for (int i = 0; i < rowCount(root); ++i)
+ collectItems(index(i, 0, root), 0, &stream);
+
+ return ba;
+}
+
+void
+BookmarkModel::setBookmarks(const QByteArray &bookmarks)
+{
+ beginResetModel();
+
+ delete rootItem;
+ folderIcon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
+ bookmarkIcon = QIcon(QLatin1String(":/trolltech/assistant/images/bookmark.png"));
+
+ rootItem = new BookmarkItem(DataVector() << tr("Name") << tr("Address")
+ << true);
+ BookmarkItem* item = new BookmarkItem(DataVector() << tr("Bookmarks Menu")
+ << QLatin1String("Folder") << true);
+ rootItem->addChild(item);
+
+ QStack<BookmarkItem*> parents;
+ parents.push(item);
+
+ qint32 depth;
+ bool expanded;
+ QString name, url;
+ QDataStream stream(bookmarks);
+ while (!stream.atEnd()) {
+ stream >> depth >> name >> url >> expanded;
+
+ while ((parents.count() - 1) != depth)
+ parents.pop();
+
+ item = new BookmarkItem(DataVector() << name << url << expanded);
+ if (url == QLatin1String("Folder")) {
+ parents.top()->addChild(item);
+ parents.push(item);
+ } else {
+ parents.top()->addChild(item);
+ }
+ }
+
+ cache.clear();
+ const QModelIndex &root = index(0,0, QModelIndex());
+
+ setupCache(root);
+ cache.insert(static_cast<BookmarkItem*> (root.internalPointer()), root);
+
+ endResetModel();
+}
+
+void
+BookmarkModel::setItemsEditable(bool editable)
+{
+ m_editable = editable;
+}
+
+void
+BookmarkModel::expandFoldersIfNeeeded(QTreeView *treeView)
+{
+ foreach (const QModelIndex &index, cache)
+ treeView->setExpanded(index, index.data(UserRoleExpanded).toBool());
+}
+
+QModelIndex
+BookmarkModel::addItem(const QModelIndex &parent, bool isFolder)
+{
+ m_folder = isFolder;
+ QModelIndex next;
+ if (insertRow(rowCount(parent), parent))
+ next = index(rowCount(parent) - 1, 0, parent);
+ m_folder = false;
+
+ return next;
+}
+
+bool
+BookmarkModel::removeItem(const QModelIndex &index)
+{
+ if (!index.isValid())
+ return false;
+
+ QModelIndexList indexes;
+ if (rowCount(index) > 0)
+ indexes = collectItems(index);
+ indexes.append(index);
+
+ foreach (const QModelIndex &itemToRemove, indexes) {
+ if (!removeRow(itemToRemove.row(), itemToRemove.parent()))
+ return false;
+ cache.remove(itemFromIndex(itemToRemove));
+ }
+ return true;
+}
+
+int
+BookmarkModel::rowCount(const QModelIndex &index) const
+{
+ if (BookmarkItem *item = itemFromIndex(index))
+ return item->childCount();
+ return 0;
+}
+
+int
+BookmarkModel::columnCount(const QModelIndex &/*index*/) const
+{
+ return 2;
+}
+
+QModelIndex
+BookmarkModel::parent(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return QModelIndex();
+
+ if (BookmarkItem *childItem = itemFromIndex(index)) {
+ if (BookmarkItem *parent = childItem->parent()) {
+ if (parent != rootItem)
+ return createIndex(parent->childNumber(), 0, parent);
+ }
+ }
+ return QModelIndex();
+}
+
+QModelIndex
+BookmarkModel::index(int row, int column, const QModelIndex &index) const
+{
+ if (index.isValid() && (index.column() != 0 && index.column() != 1))
+ return QModelIndex();
+
+ if (BookmarkItem *parent = itemFromIndex(index)) {
+ if (BookmarkItem *childItem = parent->child(row))
+ return createIndex(row, column, childItem);
+ }
+ return QModelIndex();
+}
+
+Qt::DropActions
+BookmarkModel::supportedDropActions () const
+{
+ return /* Qt::CopyAction | */Qt::MoveAction;
+}
+
+Qt::ItemFlags
+BookmarkModel::flags(const QModelIndex &index) const
+{
+ if (!index.isValid())
+ return Qt::NoItemFlags;
+
+ Qt::ItemFlags defaultFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+
+ if (m_editable)
+ defaultFlags |= Qt::ItemIsEditable;
+
+ if (itemFromIndex(index) && index.data(UserRoleFolder).toBool()) {
+ if (index.column() > 0)
+ return defaultFlags &~ Qt::ItemIsEditable;
+ return defaultFlags | Qt::ItemIsDropEnabled;
+ }
+
+ return defaultFlags | Qt::ItemIsDragEnabled;
+}
+
+QVariant
+BookmarkModel::data(const QModelIndex &index, int role) const
+{
+ if (index.isValid()) {
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ switch (role) {
+ case Qt::EditRole: {
+ case Qt::DisplayRole:
+ if (index.data(UserRoleFolder).toBool() && index.column() == 1)
+ return QLatin1String("");
+ return item->data(index.column());
+ } break;
+
+ case Qt::DecorationRole: {
+ if (index.column() == 0)
+ return index.data(UserRoleFolder).toBool()
+ ? folderIcon : bookmarkIcon;
+ } break;
+
+ default:;
+ return item->data(role);
+ }
+ }
+ }
+ return QVariant();
+}
+
+void BookmarkModel::setData(const QModelIndex &index, const DataVector &data)
+{
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ item->setData(data);
+ emit dataChanged(index, index);
+ }
+}
+
+bool
+BookmarkModel::setData(const QModelIndex &index, const QVariant &value, int role)
+{
+ bool result = false;
+ if (role != Qt::EditRole && role != UserRoleExpanded)
+ return result;
+
+ if (BookmarkItem *item = itemFromIndex(index)) {
+ if (role == Qt::EditRole) {
+ const bool isFolder = index.data(UserRoleFolder).toBool();
+ if (!isFolder || (isFolder && index.column() == 0))
+ result = item->setData(index.column(), value);
+ } else if (role == UserRoleExpanded) {
+ result = item->setData(UserRoleExpanded, value);
+ }
+ }
+
+ if (result)
+ emit dataChanged(index, index);
+ return result;
+}
+
+QVariant
+BookmarkModel::headerData(int section, Qt::Orientation orientation,
+ int role) const
+{
+ if (rootItem && orientation == Qt::Horizontal && role == Qt::DisplayRole)
+ return rootItem->data(section);
+ return QVariant();
+}
+
+QModelIndex
+BookmarkModel::indexFromItem(BookmarkItem *item) const
+{
+ return cache.value(item, QModelIndex());
+}
+
+BookmarkItem*
+BookmarkModel::itemFromIndex(const QModelIndex &index) const
+{
+ if (index.isValid())
+ return static_cast<BookmarkItem*>(index.internalPointer());
+ return rootItem;
+}
+
+QList<QPersistentModelIndex>
+BookmarkModel::indexListFor(const QString &label) const
+{
+ QList<QPersistentModelIndex> hits;
+ const QModelIndexList &list = collectItems(QModelIndex());
+ foreach(const QModelIndex &index, list) {
+ if (index.data().toString().contains(label, Qt::CaseInsensitive))
+ hits.prepend(index); // list is reverse sorted
+ }
+ return hits;
+}
+
+bool
+BookmarkModel::insertRows(int position, int rows, const QModelIndex &parent)
+{
+ if (!parent.data(UserRoleFolder).toBool())
+ return false;
+
+ bool success = false;
+ if (BookmarkItem *parentItem = itemFromIndex(parent)) {
+ beginInsertRows(parent, position, position + rows - 1);
+ success = parentItem->insertChildren(m_folder, position, rows);
+ if (success) {
+ const QModelIndex &current = index(position, 0, parent);
+ cache.insert(itemFromIndex(current), current);
+ }
+ endInsertRows();
+ }
+ return success;
+}
+
+bool
+BookmarkModel::removeRows(int position, int rows, const QModelIndex &index)
+{
+ bool success = false;
+ if (BookmarkItem *parent = itemFromIndex(index)) {
+ beginRemoveRows(index, position, position + rows - 1);
+ success = parent->removeChildren(position, rows);
+ endRemoveRows();
+ }
+ return success;
+}
+
+QStringList
+BookmarkModel::mimeTypes() const
+{
+ return QStringList() << MIMETYPE;
+}
+
+QMimeData*
+BookmarkModel::mimeData(const QModelIndexList &indexes) const
+{
+ if (indexes.isEmpty())
+ return 0;
+
+ QByteArray data;
+ QDataStream stream(&data, QIODevice::WriteOnly);
+
+ foreach (const QModelIndex &index, indexes) {
+ if (index.column() == 0)
+ collectItems(index, 0, &stream);
+ }
+
+ QMimeData *mimeData = new QMimeData();
+ mimeData->setData(MIMETYPE, data);
+ return mimeData;
+}
+
+bool
+BookmarkModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
+ int row, int column, const QModelIndex &parent)
+{
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ if (!data->hasFormat(MIMETYPE) || column > 0)
+ return false;
+
+ QByteArray ba = data->data(MIMETYPE);
+ QDataStream stream(&ba, QIODevice::ReadOnly);
+ while (stream.atEnd())
+ return false;
+
+ qint32 depth;
+ bool expanded;
+ QString name, url;
+ while (!stream.atEnd()) {
+ stream >> depth >> name >> url >> expanded;
+ if (insertRow(qMax(0, row), parent)) {
+ const QModelIndex &current = index(qMax(0, row), 0, parent);
+ if (current.isValid()) {
+ BookmarkItem* item = itemFromIndex(current);
+ item->setData(DataVector() << name << url << expanded);
+ }
+ }
+ }
+ return true;
+}
+
+void
+BookmarkModel::setupCache(const QModelIndex &parent)
+{
+ const QModelIndexList &list = collectItems(parent);
+ foreach (const QModelIndex &index, list)
+ cache.insert(itemFromIndex(index), index);
+}
+
+QModelIndexList
+BookmarkModel::collectItems(const QModelIndex &parent) const
+{
+ QModelIndexList list;
+ for (int i = rowCount(parent) - 1; i >= 0 ; --i) {
+ const QModelIndex &next = index(i, 0, parent);
+ if (data(next, UserRoleFolder).toBool())
+ list += collectItems(next);
+ list.append(next);
+ }
+ return list;
+}
+
+void
+BookmarkModel::collectItems(const QModelIndex &parent, qint32 depth,
+ QDataStream *stream) const
+{
+ if (parent.isValid()) {
+ *stream << depth;
+ *stream << parent.data().toString();
+ *stream << parent.data(UserRoleUrl).toString();
+ *stream << parent.data(UserRoleExpanded).toBool();
+
+ for (int i = 0; i < rowCount(parent); ++i) {
+ if (parent.data(UserRoleFolder).toBool())
+ collectItems(index(i, 0 , parent), depth + 1, stream);
+ }
+ }
+}
diff --git a/tools/assistant/tools/assistant/bookmarkmodel.h b/tools/assistant/tools/assistant/bookmarkmodel.h
new file mode 100644
index 0000000..f74baea
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkmodel.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef BOOKMARKMODEL_H
+#define BOOKMARKMODEL_H
+
+#include <QtCore/QAbstractItemModel>
+
+#include <QtGui/QIcon>
+
+QT_BEGIN_NAMESPACE
+
+class BookmarkItem;
+class QMimeData;
+class QTreeView;
+
+typedef QMap<BookmarkItem*, QPersistentModelIndex> ItemModelIndexCache;
+
+class BookmarkModel : public QAbstractItemModel
+{
+ Q_OBJECT
+public:
+ BookmarkModel();
+ ~BookmarkModel();
+
+ QByteArray bookmarks() const;
+ void setBookmarks(const QByteArray &bookmarks);
+
+ void setItemsEditable(bool editable);
+ void expandFoldersIfNeeeded(QTreeView *treeView);
+
+ QModelIndex addItem(const QModelIndex &parent, bool isFolder = false);
+ bool removeItem(const QModelIndex &index);
+
+ int rowCount(const QModelIndex &index = QModelIndex()) const;
+ int columnCount(const QModelIndex &index = QModelIndex()) const;
+
+ QModelIndex parent(const QModelIndex &index) const;
+ QModelIndex index(int row, int column, const QModelIndex &index) const;
+
+ Qt::DropActions supportedDropActions () const;
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+
+ QVariant data(const QModelIndex &index, int role) const;
+ void setData(const QModelIndex &index, const QVector<QVariant> &data);
+ bool setData(const QModelIndex &index, const QVariant &value, int role);
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+
+ QModelIndex indexFromItem(BookmarkItem *item) const;
+ BookmarkItem *itemFromIndex(const QModelIndex &index) const;
+ QList<QPersistentModelIndex> indexListFor(const QString &label) const;
+
+ bool insertRows(int position, int rows, const QModelIndex &parent);
+ bool removeRows(int position, int rows, const QModelIndex &parent);
+
+ QStringList mimeTypes() const;
+ QMimeData* mimeData(const QModelIndexList &indexes) const;
+ bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row,
+ int column, const QModelIndex &parent);
+
+private:
+ void setupCache(const QModelIndex &parent);
+ QModelIndexList collectItems(const QModelIndex &parent) const;
+ void collectItems(const QModelIndex &parent, qint32 depth,
+ QDataStream *stream) const;
+
+private:
+ int columns;
+ bool m_folder;
+ bool m_editable;
+ QIcon folderIcon;
+ QIcon bookmarkIcon;
+ QTreeView *treeView;
+ BookmarkItem *rootItem;
+ ItemModelIndexCache cache;
+};
+
+QT_END_NAMESPACE
+
+#endif // BOOKMARKMODEL_H
diff --git a/tools/assistant/tools/assistant/bookmarkwidget.ui b/tools/assistant/tools/assistant/bookmarkwidget.ui
new file mode 100644
index 0000000..a31a277
--- /dev/null
+++ b/tools/assistant/tools/assistant/bookmarkwidget.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>BookmarkWidget</class>
+ <widget class="QWidget" name="BookmarkWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>235</width>
+ <height>606</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Bookmarks</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <property name="margin">
+ <number>4</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Filter:</string>
+ </property>
+ </widget>
+ </item>
+ <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>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="lineEdit"/>
+ </item>
+ <item>
+ <widget class="QStackedWidget" name="stackedWidget"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <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="QPushButton" name="add">
+ <property name="text">
+ <string>Add</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="remove">
+ <property name="text">
+ <string>Remove</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/tools/assistant/tools/assistant/centralwidget.cpp b/tools/assistant/tools/assistant/centralwidget.cpp
index 0e4096b..f42dfdf 100644
--- a/tools/assistant/tools/assistant/centralwidget.cpp
+++ b/tools/assistant/tools/assistant/centralwidget.cpp
@@ -38,36 +38,36 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "centralwidget.h"
-#include "helpviewer.h"
+#include "findwidget.h"
+#include "helpenginewrapper.h"
#include "searchwidget.h"
#include "mainwindow.h"
-#include "preferencesdialog.h"
+#include "../shared/collectionconfiguration.h"
+
+#if defined(QT_NO_WEBKIT)
+#include "helpviewer_qtb.h"
+#else
+#include "helpviewer_qwv.h"
+#endif // QT_NO_WEBKIT
-#include <QtCore/QDir>
-#include <QtCore/QEvent>
#include <QtCore/QTimer>
-#include <QtGui/QMenu>
-#include <QtGui/QLabel>
+#include <QtGui/QApplication>
+#include <QtGui/QKeyEvent>
#include <QtGui/QLayout>
+#include <QtGui/QMenu>
#include <QtGui/QPrinter>
-#include <QtGui/QLineEdit>
-#include <QtGui/QCheckBox>
#include <QtGui/QTabBar>
#include <QtGui/QTabWidget>
+#include <QtGui/QTextBrowser>
#include <QtGui/QToolButton>
-#include <QtGui/QMouseEvent>
-#include <QtGui/QSpacerItem>
-#include <QtGui/QTextCursor>
+#include <QtGui/QPageSetupDialog>
#include <QtGui/QPrintDialog>
-#include <QtGui/QApplication>
-#include <QtGui/QTextDocumentFragment>
#include <QtGui/QPrintPreviewDialog>
-#include <QtGui/QPageSetupDialog>
-#include <QtHelp/QHelpEngine>
#include <QtHelp/QHelpSearchEngine>
QT_BEGIN_NAMESPACE
@@ -76,6 +76,7 @@ namespace {
HelpViewer* helpViewerFromTabPosition(const QTabWidget *widget,
const QPoint &point)
{
+ TRACE_OBJ
QTabBar *tabBar = qFindChild<QTabBar*>(widget);
for (int i = 0; i < tabBar->count(); ++i) {
if (tabBar->tabRect(i).contains(point))
@@ -86,137 +87,18 @@ namespace {
CentralWidget *staticCentralWidget = 0;
}
-FindWidget::FindWidget(QWidget *parent)
- : QWidget(parent)
- , appPalette(qApp->palette())
-{
- QHBoxLayout *hboxLayout = new QHBoxLayout(this);
- QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
-
-#ifndef Q_OS_MAC
- hboxLayout->setMargin(0);
- hboxLayout->setSpacing(6);
- resourcePath.append(QLatin1String("win"));
-#else
- resourcePath.append(QLatin1String("mac"));
-#endif
-
- toolClose = setupToolButton(QLatin1String(""),
- resourcePath + QLatin1String("/closetab.png"));
- hboxLayout->addWidget(toolClose);
-
- editFind = new QLineEdit(this);
- hboxLayout->addWidget(editFind);
- editFind->setMinimumSize(QSize(150, 0));
- connect(editFind, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
-
- toolPrevious = setupToolButton(tr("Previous"),
- resourcePath + QLatin1String("/previous.png"));
- hboxLayout->addWidget(toolPrevious);
-
- toolNext = setupToolButton(tr("Next"),
- resourcePath + QLatin1String("/next.png"));
- 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->setScaledContents(true);
- labelWrapped->setTextFormat(Qt::RichText);
- labelWrapped->setMinimumSize(QSize(0, 20));
- labelWrapped->setMaximumSize(QSize(105, 20));
- 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()
-{
-}
+// -- CentralWidget
-void FindWidget::hideEvent(QHideEvent* event)
-{
-#if !defined(QT_NO_WEBKIT)
- // TODO: remove this once webkit supports setting the palette
- if (!event->spontaneous())
- qApp->setPalette(appPalette);
-#else
- Q_UNUSED(event);
-#endif
-}
-
-void FindWidget::showEvent(QShowEvent* event)
-{
-#if !defined(QT_NO_WEBKIT)
- // TODO: remove this once webkit supports setting the palette
- if (!event->spontaneous()) {
- QPalette p = appPalette;
- 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);
- }
-#else
- Q_UNUSED(event);
-#endif
-}
-
-void FindWidget::updateButtons()
-{
- if (editFind->text().isEmpty()) {
- toolPrevious->setEnabled(false);
- toolNext->setEnabled(false);
- } else {
- toolPrevious->setEnabled(true);
- toolNext->setEnabled(true);
- }
-}
-
-QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon)
-{
- QToolButton *toolButton = new QToolButton(this);
-
- toolButton->setText(text);
- toolButton->setAutoRaise(true);
- toolButton->setIcon(QIcon(icon));
- toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
-
- return toolButton;
-}
-
-
-// --
-
-
-CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent)
+CentralWidget::CentralWidget(MainWindow *parent)
: QWidget(parent)
, lastTabPage(0)
- , collectionFile(engine->collectionFile())
- , findBar(0)
, tabWidget(0)
, findWidget(0)
- , helpEngine(engine)
, printer(0)
, usesDefaultCollection(parent->usesDefaultCollection())
, m_searchWidget(0)
{
+ TRACE_OBJ
globalActionList.clear();
staticCentralWidget = this;
QVBoxLayout *vboxLayout = new QVBoxLayout(this);
@@ -253,20 +135,15 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent)
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(QString)), this,
- SLOT(findCurrentText(QString)));
- connect(findWidget->toolPrevious, SIGNAL(clicked()), this, SLOT(findPrevious()));
+ findWidget = new FindWidget(this);
+ vboxLayout->addWidget(findWidget);
+ findWidget->hide();
+
+ connect(findWidget, SIGNAL(findNext()), this, SLOT(findNext()));
+ connect(findWidget, SIGNAL(findPrevious()), this, SLOT(findPrevious()));
+ connect(findWidget, SIGNAL(find(QString, bool)), this,
+ SLOT(find(QString, bool)));
+ connect(findWidget, SIGNAL(escapePressed()), this, SLOT(activateTab()));
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
if (tabBar) {
@@ -288,45 +165,40 @@ CentralWidget::CentralWidget(QHelpEngine *engine, MainWindow *parent)
CentralWidget::~CentralWidget()
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
delete printer;
#endif
- QHelpEngineCore engine(collectionFile, 0);
- if (!engine.setupData())
- return;
-
- QString zoomCount;
- QString currentPages;
- QLatin1Char separator('|');
+ QStringList zoomFactors;
+ QStringList currentPages;
bool searchAttached = m_searchWidget->isAttached();
int i = searchAttached ? 1 : 0;
for (; i < tabWidget->count(); ++i) {
HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
if (viewer && viewer->source().isValid()) {
- currentPages += viewer->source().toString() + separator;
- zoomCount += QString::number(viewer->zoom()) + separator;
+ currentPages << viewer->source().toString();
+ zoomFactors << QString::number(viewer->scale());
}
}
- engine.setCustomValue(QLatin1String("LastTabPage"), lastTabPage);
- engine.setCustomValue(QLatin1String("LastShownPages"), currentPages);
- engine.setCustomValue(QLatin1String("SearchWasAttached"), searchAttached);
-#if !defined(QT_NO_WEBKIT)
- engine.setCustomValue(QLatin1String("LastPagesZoomWebView"), zoomCount);
-#else
- engine.setCustomValue(QLatin1String("LastPagesZoomTextBrowser"), zoomCount);
-#endif
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ helpEngine.setLastTabPage(tabWidget->currentIndex());
+ helpEngine.setLastShownPages(currentPages);
+ helpEngine.setSearchWasAttached(searchAttached);
+ helpEngine.setLastZoomFactors(zoomFactors);
}
CentralWidget *CentralWidget::instance()
{
+ TRACE_OBJ
return staticCentralWidget;
}
void CentralWidget::newTab()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
#if !defined(QT_NO_WEBKIT)
if (viewer && viewer->hasLoadFinished())
@@ -338,9 +210,10 @@ void CentralWidget::newTab()
void CentralWidget::zoomIn()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
- viewer->zoomIn();
+ viewer->scaleUp();
if (tabWidget->currentWidget() == m_searchWidget)
m_searchWidget->zoomIn();
@@ -348,21 +221,18 @@ void CentralWidget::zoomIn()
void CentralWidget::zoomOut()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
- viewer->zoomOut();
+ viewer->scaleDown();
if (tabWidget->currentWidget() == m_searchWidget)
m_searchWidget->zoomOut();
}
-void CentralWidget::findNext()
-{
- find(findWidget->editFind->text(), true);
-}
-
void CentralWidget::nextPage()
{
+ TRACE_OBJ
int index = tabWidget->currentIndex() + 1;
if (index >= tabWidget->count())
index = 0;
@@ -371,9 +241,9 @@ void CentralWidget::nextPage()
void CentralWidget::resetZoom()
{
- HelpViewer *viewer = currentHelpViewer();
- if (viewer)
- viewer->resetZoom();
+ TRACE_OBJ
+ if (HelpViewer *viewer = currentHelpViewer())
+ viewer->resetScale();
if (tabWidget->currentWidget() == m_searchWidget)
m_searchWidget->resetZoom();
@@ -381,19 +251,16 @@ void CentralWidget::resetZoom()
void CentralWidget::previousPage()
{
+ TRACE_OBJ
int index = tabWidget->currentIndex() -1;
if (index < 0)
index = tabWidget->count() -1;
tabWidget->setCurrentIndex(index);
}
-void CentralWidget::findPrevious()
-{
- find(findWidget->editFind->text(), false);
-}
-
void CentralWidget::closeTab()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (!viewer|| tabWidget->count() == 1)
return;
@@ -404,12 +271,13 @@ void CentralWidget::closeTab()
void CentralWidget::setSource(const QUrl &url)
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
HelpViewer *lastViewer =
qobject_cast<HelpViewer*>(tabWidget->widget(lastTabPage));
if (!viewer && !lastViewer) {
- viewer = new HelpViewer(helpEngine, this);
+ viewer = new HelpViewer(this);
viewer->installEventFilter(this);
lastTabPage = tabWidget->addTab(viewer, QString());
tabWidget->setCurrentIndex(lastTabPage);
@@ -427,18 +295,14 @@ void CentralWidget::setSource(const QUrl &url)
void CentralWidget::setupWidget()
{
- int option = helpEngine->customValue(QLatin1String("StartOption"),
- ShowLastPages).toInt();
-
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ int option = helpEngine.startOption();
if (option != ShowLastPages) {
QString homePage;
- if (option == ShowHomePage) {
- homePage = helpEngine->customValue(QLatin1String("defaultHomepage"),
- QLatin1String("help")).toString();
- homePage = helpEngine->customValue(QLatin1String("homepage"),
- homePage).toString();
- }
- if (option == ShowBlankPage)
+ if (option == ShowHomePage)
+ homePage = helpEngine.homePage();
+ else if (option == ShowBlankPage)
homePage = QLatin1String("about:blank");
setSource(homePage);
} else {
@@ -448,11 +312,9 @@ void CentralWidget::setupWidget()
void CentralWidget::setLastShownPages()
{
- const QLatin1String key("LastShownPages");
- QString value = helpEngine->customValue(key, QString()).toString();
- const QStringList lastShownPageList = value.split(QLatin1Char('|'),
- QString::SkipEmptyParts);
-
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ const QStringList &lastShownPageList = helpEngine.lastShownPages();
const int pageCount = lastShownPageList.count();
if (pageCount == 0) {
if (usesDefaultCollection)
@@ -461,48 +323,40 @@ void CentralWidget::setLastShownPages()
setSource(QUrl(QLatin1String("about:blank")));
return;
}
+ QStringList zoomFactors = helpEngine.lastZoomFactors();
+ while (zoomFactors.count() < pageCount)
+ zoomFactors.append(CollectionConfiguration::DefaultZoomFactor);
-#if !defined(QT_NO_WEBKIT)
- const QLatin1String zoom("LastPagesZoomWebView");
-#else
- const QLatin1String zoom("LastPagesZoomTextBrowser");
-#endif
-
- value = helpEngine->customValue(zoom, QString()).toString();
- QVector<QString> zoomVector = value.split(QLatin1Char('|'),
- QString::SkipEmptyParts).toVector();
-
- const int zoomCount = zoomVector.count();
- zoomVector.insert(zoomCount, pageCount - zoomCount, QLatin1String("0.0"));
-
- QVector<QString>::const_iterator zIt = zoomVector.constBegin();
- QStringList::const_iterator it = lastShownPageList.constBegin();
- for (; it != lastShownPageList.constEnd(); ++it, ++zIt)
- setSourceInNewTab((*it), (*zIt).toFloat());
-
- const QLatin1String lastTab("LastTabPage");
- int tab = helpEngine->customValue(lastTab, 1).toInt();
-
- const QLatin1String searchKey("SearchWasAttached");
const bool searchIsAttached = m_searchWidget->isAttached();
- const bool searchWasAttached = helpEngine->customValue(searchKey).toBool();
-
- if (searchWasAttached && !searchIsAttached)
- tabWidget->setCurrentIndex(--tab);
+ const bool searchWasAttached = helpEngine.searchWasAttached();
+ int tabToShow = helpEngine.lastTabPage();
+ if (searchWasAttached && !searchIsAttached && tabToShow != 0)
+ --tabToShow;
else if (!searchWasAttached && searchIsAttached)
- tabWidget->setCurrentIndex(++tab);
- else
- tabWidget->setCurrentIndex(tab);
+ ++tabToShow;
+
+ for (int curTab = 0; curTab < pageCount; ++curTab) {
+ const QString &curFile = lastShownPageList.at(curTab);
+ if (helpEngine.findFile(curFile).isValid()
+ || curFile == QLatin1String("about:blank")) {
+ setSourceInNewTab(curFile, zoomFactors.at(curTab).toFloat());
+ } else if (curTab + searchIsAttached <= tabToShow)
+ --tabToShow;
+ }
+
+ tabWidget->setCurrentIndex(tabToShow);
}
bool CentralWidget::hasSelection() const
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
return viewer ? viewer->hasSelection() : false;
}
QUrl CentralWidget::currentSource() const
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer)
return viewer->source();
@@ -512,6 +366,7 @@ QUrl CentralWidget::currentSource() const
QString CentralWidget::currentTitle() const
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer)
return viewer->documentTitle();
@@ -521,6 +376,7 @@ QString CentralWidget::currentTitle() const
void CentralWidget::copySelection()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
viewer->copy();
@@ -528,13 +384,13 @@ void CentralWidget::copySelection()
void CentralWidget::showTextSearch()
{
- findBar->show();
- findWidget->editFind->selectAll();
- findWidget->editFind->setFocus(Qt::ShortcutFocusReason);
+ TRACE_OBJ
+ findWidget->show();
}
void CentralWidget::initPrinter()
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
if (!printer)
printer = new QPrinter(QPrinter::HighResolution);
@@ -543,6 +399,7 @@ void CentralWidget::initPrinter()
void CentralWidget::print()
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
HelpViewer *viewer = currentHelpViewer();
if (!viewer)
@@ -550,23 +407,23 @@ void CentralWidget::print()
initPrinter();
- QPrintDialog *dlg = new QPrintDialog(printer, this);
+ QPrintDialog dlg(printer, this);
#if defined(QT_NO_WEBKIT)
if (viewer->textCursor().hasSelection())
- dlg->addEnabledOption(QAbstractPrintDialog::PrintSelection);
+ dlg.addEnabledOption(QAbstractPrintDialog::PrintSelection);
#endif
- dlg->addEnabledOption(QAbstractPrintDialog::PrintPageRange);
- dlg->addEnabledOption(QAbstractPrintDialog::PrintCollateCopies);
- dlg->setWindowTitle(tr("Print Document"));
- if (dlg->exec() == QDialog::Accepted) {
+ 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()
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
initPrinter();
QPrintPreviewDialog preview(printer, this);
@@ -578,6 +435,7 @@ void CentralWidget::printPreview()
void CentralWidget::printPreview(QPrinter *p)
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
HelpViewer *viewer = currentHelpViewer();
if (viewer)
@@ -587,6 +445,7 @@ void CentralWidget::printPreview(QPrinter *p)
void CentralWidget::pageSetup()
{
+ TRACE_OBJ
#ifndef QT_NO_PRINTER
initPrinter();
QPageSetupDialog dlg(printer);
@@ -596,11 +455,13 @@ void CentralWidget::pageSetup()
bool CentralWidget::isHomeAvailable() const
{
+ TRACE_OBJ
return currentHelpViewer() ? true : false;
}
void CentralWidget::home()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
viewer->home();
@@ -608,6 +469,7 @@ void CentralWidget::home()
bool CentralWidget::isForwardAvailable() const
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer)
return viewer->isForwardAvailable();
@@ -617,6 +479,7 @@ bool CentralWidget::isForwardAvailable() const
void CentralWidget::forward()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
viewer->forward();
@@ -624,6 +487,7 @@ void CentralWidget::forward()
bool CentralWidget::isBackwardAvailable() const
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer)
return viewer->isBackwardAvailable();
@@ -633,6 +497,7 @@ bool CentralWidget::isBackwardAvailable() const
void CentralWidget::backward()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (viewer)
viewer->backward();
@@ -641,49 +506,37 @@ void CentralWidget::backward()
QList<QAction*> CentralWidget::globalActions() const
{
+ TRACE_OBJ
return globalActionList;
}
void CentralWidget::setGlobalActions(const QList<QAction*> &actions)
{
+ TRACE_OBJ
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
+ TRACE_OBJ
+ if (HelpViewer *viewer = currentHelpViewer()) {
+ if (viewer->launchWithExternalApp(url))
+ return;
+ }
- viewer = new HelpViewer(helpEngine, this);
+ HelpViewer *viewer = new HelpViewer(this, zoom);
viewer->installEventFilter(this);
viewer->setSource(url);
viewer->setFocus(Qt::OtherFocusReason);
tabWidget->setCurrentIndex(tabWidget->addTab(viewer,
quoteTabTitle(viewer->documentTitle())));
-
- QFont font;
- getBrowserFontFor(viewer, &font);
-
-#if defined(QT_NO_WEBKIT)
- font.setPointSize((int)(font.pointSize() + zoom));
- setBrowserFontFor(viewer, font);
- viewer->setZoom((int)zoom);
-#else
- setBrowserFontFor(viewer, font);
- viewer->setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom);
-#endif
-
connectSignals();
}
HelpViewer *CentralWidget::newEmptyTab()
{
- HelpViewer *viewer = new HelpViewer(helpEngine, this);
+ TRACE_OBJ
+ HelpViewer *viewer = new HelpViewer(this);
viewer->installEventFilter(this);
viewer->setFocus(Qt::OtherFocusReason);
#if defined(QT_NO_WEBKIT)
@@ -695,13 +548,9 @@ HelpViewer *CentralWidget::newEmptyTab()
return viewer;
}
-void CentralWidget::findCurrentText(const QString &text)
-{
- find(text, true);
-}
-
void CentralWidget::connectSignals()
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer) {
connect(viewer, SIGNAL(copyAvailable(bool)), this,
@@ -716,16 +565,25 @@ void CentralWidget::connectSignals()
SIGNAL(highlighted(QString)));
connect(viewer, SIGNAL(sourceChanged(QUrl)), this,
SLOT(setTabTitle(QUrl)));
+ connect(viewer, SIGNAL(printRequested()), this, SLOT(print()));
}
}
-HelpViewer *CentralWidget::currentHelpViewer() const
+HelpViewer* CentralWidget::viewerAt(int index) const
+{
+ TRACE_OBJ
+ return qobject_cast<HelpViewer*>(tabWidget->widget(index));
+}
+
+HelpViewer* CentralWidget::currentHelpViewer() const
{
+ TRACE_OBJ
return qobject_cast<HelpViewer*>(tabWidget->currentWidget());
}
void CentralWidget::activateTab(bool onlyHelpViewer)
{
+ TRACE_OBJ
if (currentHelpViewer()) {
currentHelpViewer()->setFocus();
} else {
@@ -739,6 +597,7 @@ void CentralWidget::activateTab(bool onlyHelpViewer)
void CentralWidget::setTabTitle(const QUrl &url)
{
+ TRACE_OBJ
Q_UNUSED(url)
#if !defined(QT_NO_WEBKIT)
QTabBar *tabBar = qFindChild<QTabBar*>(tabWidget);
@@ -760,6 +619,7 @@ void CentralWidget::setTabTitle(const QUrl &url)
void CentralWidget::currentPageChanged(int index)
{
+ TRACE_OBJ
const HelpViewer *viewer = currentHelpViewer();
if (viewer)
lastTabPage = index;
@@ -775,6 +635,7 @@ void CentralWidget::currentPageChanged(int index)
void CentralWidget::showTabBarContextMenu(const QPoint &point)
{
+ TRACE_OBJ
HelpViewer *viewer = helpViewerFromTabPosition(tabWidget, point);
if (!viewer)
return;
@@ -822,11 +683,12 @@ void CentralWidget::showTabBarContextMenu(const QPoint &point)
}
if (pickedAction == newBookmark)
- emit addNewBookmark(viewer->documentTitle(), viewer->source().toString());
+ emit addBookmark(viewer->documentTitle(), viewer->source().toString());
}
bool CentralWidget::eventFilter(QObject *object, QEvent *e)
{
+ TRACE_OBJ
if (e->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
switch (ke->key()) {
@@ -834,14 +696,6 @@ bool CentralWidget::eventFilter(QObject *object, QEvent *e)
return QWidget::eventFilter(object, e);
} break;
- case Qt::Key_Escape: {
- if (findWidget->editFind == object) {
- findBar->hide();
- if (HelpViewer *viewer = currentHelpViewer())
- viewer->setFocus();
- }
- } break;
-
case Qt::Key_Backspace: {
HelpViewer *viewer = currentHelpViewer();
if (viewer == object) {
@@ -882,43 +736,52 @@ bool CentralWidget::eventFilter(QObject *object, QEvent *e)
void CentralWidget::keyPressEvent(QKeyEvent *e)
{
+ TRACE_OBJ
const QString &text = e->text();
if (text.startsWith(QLatin1Char('/'))) {
- if (!findBar->isVisible()) {
- findBar->show();
- findWidget->editFind->clear();
+ if (!findWidget->isVisible()) {
+ findWidget->showAndClear();
} else {
- findWidget->editFind->selectAll();
+ findWidget->show();
}
- findWidget->editFind->setFocus();
- return;
+ } else {
+ QWidget::keyPressEvent(e);
}
- QWidget::keyPressEvent(e);
}
-void CentralWidget::find(const QString &ttf, bool forward)
+void CentralWidget::findNext()
{
- QPalette p = findWidget->editFind->palette();
- p.setColor(QPalette::Active, QPalette::Base, Qt::white);
+ TRACE_OBJ
+ find(findWidget->text(), true);
+}
- bool found = false;
+void CentralWidget::findPrevious()
+{
+ TRACE_OBJ
+ find(findWidget->text(), false);
+}
+void CentralWidget::find(const QString &ttf, bool forward)
+{
+ TRACE_OBJ
+ bool found = false;
#if defined(QT_NO_WEBKIT)
found = findInTextBrowser(ttf, forward);
#else
found = findInWebPage(ttf, forward);
#endif
- if (!found && !ttf.isEmpty())
- p.setColor(QPalette::Active, QPalette::Base, QColor(255, 102, 102));
+ if (!found && ttf.isEmpty())
+ found = true; // the line edit is empty, no need to mark it red...
if (!findWidget->isVisible())
findWidget->show();
- findWidget->editFind->setPalette(p);
+ findWidget->setPalette(found);
}
bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
{
+ TRACE_OBJ
#if !defined(QT_NO_WEBKIT)
if (HelpViewer *viewer = currentHelpViewer()) {
bool found = false;
@@ -927,21 +790,23 @@ bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
if (!forward)
options |= QWebPage::FindBackward;
- if (findWidget->checkCase->isChecked())
+ if (findWidget->caseSensitive())
options |= QWebPage::FindCaseSensitively;
found = viewer->findText(ttf, options);
- findWidget->labelWrapped->hide();
+ findWidget->setTextWrappedVisible(false);
if (!found) {
options |= QWebPage::FindWrapsAroundDocument;
found = viewer->findText(ttf, options);
if (found)
- findWidget->labelWrapped->show();
+ findWidget->setTextWrappedVisible(true);
}
}
// force highlighting of all other matches, also when empty (clear)
options = QWebPage::HighlightAllOccurrences;
+ if (findWidget->caseSensitive())
+ options |= QWebPage::FindCaseSensitively;
viewer->findText(QLatin1String(""), options);
viewer->findText(ttf, options);
return found;
@@ -949,12 +814,16 @@ bool CentralWidget::findInWebPage(const QString &ttf, bool forward)
// this needs to stay, case for active search results page
return findInTextBrowser(ttf, forward);
+#else
+ Q_UNUSED(ttf);
+ Q_UNUSED(forward);
#endif
return false;
}
bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
{
+ TRACE_OBJ
QTextBrowser *browser = qobject_cast<QTextBrowser*>(currentHelpViewer());
if (tabWidget->currentWidget() == m_searchWidget)
browser = qFindChild<QTextBrowser*>(m_searchWidget);
@@ -978,13 +847,10 @@ bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
if (!forward)
options |= QTextDocument::FindBackward;
- if (findWidget->checkCase->isChecked())
+ if (findWidget->caseSensitive())
options |= QTextDocument::FindCaseSensitively;
- if (findWidget->checkWholeWords->isChecked())
- options |= QTextDocument::FindWholeWords;
-
- findWidget->labelWrapped->hide();
+ findWidget->setTextWrappedVisible(false);
bool found = true;
QTextCursor newCursor = doc->find(ttf, cursor, options);
@@ -997,7 +863,7 @@ bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
found = false;
newCursor = cursor;
} else {
- findWidget->labelWrapped->show();
+ findWidget->setTextWrappedVisible(true);
}
}
browser->setTextCursor(newCursor);
@@ -1006,21 +872,31 @@ bool CentralWidget::findInTextBrowser(const QString &ttf, bool forward)
void CentralWidget::updateBrowserFont()
{
- QFont font;
- bool searchAttached = searchWidgetAttached();
+ TRACE_OBJ
+ const bool searchAttached = searchWidgetAttached();
if (searchAttached) {
- getBrowserFontFor(m_searchWidget, &font);
- setBrowserFontFor(m_searchWidget, font);
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ m_searchWidget->setFont(helpEngine.usesBrowserFont()
+ ? helpEngine.browserFont() : qApp->font());
}
- int i = searchAttached ? 1 : 0;
- getBrowserFontFor(tabWidget->widget(i), &font);
- for ( ; i < tabWidget->count(); ++i)
- setBrowserFontFor(tabWidget->widget(i), font);
+ const int count = tabWidget->count();
+ if (HelpViewer* viewer = viewerAt(count - 1)) {
+ const QFont &font = viewer->viewerFont();
+ for (int i = searchAttached ? 1 : 0; i < count; ++i)
+ viewerAt(i)->setViewerFont(font);
+ }
+}
+
+bool CentralWidget::searchWidgetAttached() const
+{
+ TRACE_OBJ
+ return m_searchWidget && m_searchWidget->isAttached();
}
void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine)
{
+ TRACE_OBJ
if (m_searchWidget)
return;
@@ -1030,15 +906,16 @@ void CentralWidget::createSearchWidget(QHelpSearchEngine *searchEngine)
connect(m_searchWidget, SIGNAL(requestShowLinkInNewTab(QUrl)), this,
SLOT(setSourceFromSearchInNewTab(QUrl)));
- QFont font;
- getBrowserFontFor(m_searchWidget, &font);
- setBrowserFontFor(m_searchWidget, font);
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ m_searchWidget->setFont(!helpEngine.usesBrowserFont() ? qApp->font()
+ : helpEngine.browserFont());
}
void CentralWidget::activateSearchWidget(bool updateLastTabPage)
{
+ TRACE_OBJ
if (!m_searchWidget)
- createSearchWidget(helpEngine->searchEngine());
+ createSearchWidget(HelpEngineWrapper::instance().searchEngine());
if (!m_searchWidget->isAttached()) {
tabWidget->insertTab(0, m_searchWidget, tr("Search"));
@@ -1054,6 +931,7 @@ void CentralWidget::activateSearchWidget(bool updateLastTabPage)
void CentralWidget::removeSearchWidget()
{
+ TRACE_OBJ
if (searchWidgetAttached()) {
tabWidget->removeTab(0);
m_searchWidget->setAttached(false);
@@ -1062,6 +940,7 @@ void CentralWidget::removeSearchWidget()
int CentralWidget::availableHelpViewer() const
{
+ TRACE_OBJ
int count = tabWidget->count();
if (searchWidgetAttached())
count--;
@@ -1070,6 +949,7 @@ int CentralWidget::availableHelpViewer() const
bool CentralWidget::enableTabCloseAction() const
{
+ TRACE_OBJ
int minTabCount = 1;
if (searchWidgetAttached())
minTabCount = 2;
@@ -1079,6 +959,7 @@ bool CentralWidget::enableTabCloseAction() const
QString CentralWidget::quoteTabTitle(const QString &title) const
{
+ TRACE_OBJ
QString s = title;
return s.replace(QLatin1Char('&'), QLatin1String("&&"));
}
@@ -1086,6 +967,7 @@ QString CentralWidget::quoteTabTitle(const QString &title) const
void
CentralWidget::setSourceFromSearch(const QUrl &url)
{
+ TRACE_OBJ
setSource(url);
#if defined(QT_NO_WEBKIT)
highlightSearchTerms();
@@ -1098,6 +980,7 @@ CentralWidget::setSourceFromSearch(const QUrl &url)
void
CentralWidget::setSourceFromSearchInNewTab(const QUrl &url)
{
+ TRACE_OBJ
setSourceInNewTab(url);
#if defined(QT_NO_WEBKIT)
highlightSearchTerms();
@@ -1110,11 +993,13 @@ CentralWidget::setSourceFromSearchInNewTab(const QUrl &url)
void
CentralWidget::highlightSearchTerms()
{
+ TRACE_OBJ
HelpViewer *viewer = currentHelpViewer();
if (!viewer)
return;
- QHelpSearchEngine *searchEngine = helpEngine->searchEngine();
+ QHelpSearchEngine *searchEngine =
+ HelpEngineWrapper::instance().searchEngine();
QList<QHelpSearchQuery> queryList = searchEngine->query();
QStringList terms;
@@ -1126,7 +1011,7 @@ CentralWidget::highlightSearchTerms()
case QHelpSearchQuery::DEFAULT:
case QHelpSearchQuery::ATLEAST:
foreach (QString term, query.wordList)
- terms.append(term.remove(QLatin1String("\"")));
+ terms.append(term.remove(QLatin1Char('"')));
}
}
}
@@ -1174,8 +1059,33 @@ CentralWidget::highlightSearchTerms()
#endif
}
+
+void CentralWidget::closeOrReloadTabs(const QList<int> &indices, bool tryReload)
+{
+ TRACE_OBJ
+ QList<int> sortedIndices = indices;
+ qSort(sortedIndices);
+ for (int i = sortedIndices.count(); --i >= 0;) {
+ const int tab = sortedIndices.at(i);
+ bool close = true;
+ if (tryReload) {
+ HelpViewer *viewer =
+ qobject_cast<HelpViewer*>(tabWidget->widget(tab));
+ if (HelpEngineWrapper::instance().findFile(viewer->source()).isValid()) {
+ viewer->reload();
+ close = false;
+ }
+ }
+ if (close)
+ closeTabAt(tab);
+ }
+ if (availableHelpViewer() == 0)
+ setSource(QUrl(QLatin1String("about:blank")));
+}
+
void CentralWidget::closeTabAt(int index)
{
+ TRACE_OBJ
HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(index));
tabWidget->removeTab(index);
QTimer::singleShot(0, viewer, SLOT(deleteLater()));
@@ -1183,8 +1093,9 @@ void CentralWidget::closeTabAt(int index)
QMap<int, QString> CentralWidget::currentSourceFileList() const
{
+ TRACE_OBJ
QMap<int, QString> sourceList;
- for (int i = 1; i < tabWidget->count(); ++i) {
+ for (int i = 0; i < tabWidget->count(); ++i) {
HelpViewer *viewer = qobject_cast<HelpViewer*>(tabWidget->widget(i));
if (viewer && viewer->source().isValid())
sourceList.insert(i, viewer->source().host());
@@ -1192,40 +1103,4 @@ QMap<int, QString> CentralWidget::currentSourceFileList() const
return sourceList;
}
-void CentralWidget::getBrowserFontFor(QWidget *viewer, QFont *font)
-{
- const QLatin1String key("useBrowserFont");
- if (!helpEngine->customValue(key, false).toBool()) {
- *font = qApp->font(); // case for QTextBrowser and SearchWidget
-#if !defined(QT_NO_WEBKIT)
- QWebView *view = qobject_cast<QWebView*> (viewer);
- if (view) {
- QWebSettings *settings = QWebSettings::globalSettings();
- *font = QFont(settings->fontFamily(QWebSettings::StandardFont),
- settings->fontSize(QWebSettings::DefaultFontSize));
- }
-#endif
- } else {
- *font = qVariantValue<QFont>(helpEngine->customValue(
- QLatin1String("browserFont")));
- }
-}
-
-void CentralWidget::setBrowserFontFor(QWidget *widget, const QFont &font)
-{
-#if !defined(QT_NO_WEBKIT)
- QWebView *view = qobject_cast<QWebView*> (widget);
- if (view) {
- QWebSettings *settings = view->settings();
- settings->setFontFamily(QWebSettings::StandardFont, font.family());
- settings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
- } else if (widget && widget->font() != font) {
- widget->setFont(font);
- }
-#else
- if (widget && widget->font() != font)
- widget->setFont(font);
-#endif
-}
-
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/centralwidget.h b/tools/assistant/tools/assistant/centralwidget.h
index 9e32985..f286ff7 100644
--- a/tools/assistant/tools/assistant/centralwidget.h
+++ b/tools/assistant/tools/assistant/centralwidget.h
@@ -38,78 +38,27 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#ifndef CENTRALWIDGET_H
#define CENTRALWIDGET_H
#include <QtCore/QUrl>
-#include <QtCore/QPoint>
-#include <QtCore/QObject>
-
#include <QtGui/QWidget>
-#include "searchwidget.h"
-
QT_BEGIN_NAMESPACE
-class QEvent;
-class QLabel;
-class QAction;
-class QCheckBox;
-class QLineEdit;
-class QTextBrowser;
-class QToolButton;
-
+class FindWidget;
class HelpViewer;
-class QTabWidget;
-class QHelpEngine;
-class CentralWidget;
-class PrintHelper;
class MainWindow;
-
class QHelpSearchEngine;
-
-class FindWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- FindWidget(QWidget *parent = 0);
- ~FindWidget();
-
-signals:
- void findNext();
- void findPrevious();
-
-protected:
- void hideEvent(QHideEvent* event);
- void showEvent(QShowEvent * event);
-
-private slots:
- void updateButtons();
-
-private:
- QToolButton* setupToolButton(const QString &text, const QString &icon);
-
-private:
- QLineEdit *editFind;
- QCheckBox *checkCase;
- QLabel *labelWrapped;
- QToolButton *toolNext;
- QToolButton *toolClose;
- QToolButton *toolPrevious;
- QCheckBox *checkWholeWords;
-
- QPalette appPalette;
- friend class CentralWidget;
-};
+class QTabWidget;
+class SearchWidget;
class CentralWidget : public QWidget
{
Q_OBJECT
public:
- CentralWidget(QHelpEngine *engine, MainWindow *parent);
+ CentralWidget(MainWindow *parent);
~CentralWidget();
void setupWidget();
@@ -121,12 +70,11 @@ public:
bool isBackwardAvailable() const;
QList<QAction*> globalActions() const;
void setGlobalActions(const QList<QAction*> &actions);
+
+ HelpViewer *viewerAt(int index) const;
HelpViewer *currentHelpViewer() const;
- void activateTab(bool onlyHelpViewer = false);
- bool searchWidgetAttached() const {
- return m_searchWidget && m_searchWidget->isAttached();
- }
+ bool searchWidgetAttached() const;
void createSearchWidget(QHelpSearchEngine *searchEngine);
void activateSearchWidget(bool updateLastTabPage = false);
void removeSearchWidget();
@@ -134,6 +82,7 @@ public:
int availableHelpViewer() const;
bool enableTabCloseAction() const;
+ void closeOrReloadTabs(const QList<int> &indices, bool tryReload);
void closeTabAt(int index);
QMap<int, QString> currentSourceFileList() const;
@@ -142,11 +91,9 @@ public:
public slots:
void zoomIn();
void zoomOut();
- void findNext();
void nextPage();
void resetZoom();
void previousPage();
- void findPrevious();
void copySelection();
void showTextSearch();
void print();
@@ -155,12 +102,17 @@ public slots:
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();
+ void activateTab(bool onlyHelpViewer = false);
+
+ void findNext();
+ void findPrevious();
+ void find(const QString &text, bool forward);
+
signals:
void currentViewerChanged();
void copyAvailable(bool yes);
@@ -168,7 +120,7 @@ signals:
void highlighted(const QString &link);
void forwardAvailable(bool available);
void backwardAvailable(bool available);
- void addNewBookmark(const QString &title, const QString &url);
+ void addBookmark(const QString &title, const QString &url);
protected:
void keyPressEvent(QKeyEvent *);
@@ -187,25 +139,18 @@ private slots:
private:
void connectSignals();
bool eventFilter(QObject *object, QEvent *e);
- void find(const QString &ttf, bool forward);
bool findInWebPage(const QString &ttf, bool forward);
bool findInTextBrowser(const QString &ttf, bool forward);
void initPrinter();
QString quoteTabTitle(const QString &title) const;
void setLastShownPages();
- void getBrowserFontFor(QWidget* viewer, QFont *font);
- void setBrowserFontFor(QWidget *widget, const QFont &font);
-
private:
int lastTabPage;
- QString collectionFile;
QList<QAction*> globalActionList;
- QWidget *findBar;
QTabWidget *tabWidget;
FindWidget *findWidget;
- QHelpEngine *helpEngine;
QPrinter *printer;
bool usesDefaultCollection;
diff --git a/tools/assistant/tools/assistant/cmdlineparser.cpp b/tools/assistant/tools/assistant/cmdlineparser.cpp
index 38814a5..181abe2 100644
--- a/tools/assistant/tools/assistant/cmdlineparser.cpp
+++ b/tools/assistant/tools/assistant/cmdlineparser.cpp
@@ -38,29 +38,17 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include <QtCore/QFileInfo>
+#include <QtCore/QStringBuilder>
#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_removeSearchIndex(false),
- m_copy(false),
- m_quiet(false)
-{
- m_helpMessage = QLatin1String(
+static const char helpMessage[] = QT_TRANSLATE_NOOP("CmdLineParser",
"Usage: assistant [Options]\n\n"
"-collectionFile file Uses the specified collection\n"
" file instead of the default one\n"
@@ -85,166 +73,199 @@ CmdLineParser::CmdLineParser()
" file.\n"
"-setCurrentFilter filter Set the filter as the active filter.\n"
"-remove-search-index Removes the full text search index.\n"
+ "-rebuild-search-index Re-builds the full text search index (potentially slow).\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")) {
+CmdLineParser::CmdLineParser(const QStringList &arguments)
+ : m_pos(0),
+ m_enableRemoteControl(false),
+ m_contents(Untouched),
+ m_index(Untouched),
+ m_bookmarks(Untouched),
+ m_search(Untouched),
+ m_register(None),
+ m_removeSearchIndex(false),
+ m_rebuildSearchIndex(false),
+ m_quiet(false)
+{
+ TRACE_OBJ
+ for (int i = 1; i < arguments.count(); ++i) {
+ const QString &arg = arguments.at(i);
+ if (arg.toLower() == "-quiet")
m_quiet = true;
- break;
- }
+ else
+ m_arguments.append(arg);
}
+}
- 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")) {
+CmdLineParser::Result CmdLineParser::parse()
+{
+ TRACE_OBJ
+ bool showHelp = false;
+
+ while (m_error.isEmpty() && hasMoreArgs()) {
+ const QString &arg = nextArg().toLower();
+ if (arg == QLatin1String("-collectionfile"))
+ handleCollectionFileOption();
+ else if (arg == QLatin1String("-showurl"))
+ handleShowUrlOption();
+ 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("-remove-search-index")) {
+ else if (arg == QLatin1String("-show"))
+ handleShowOption();
+ else if (arg == QLatin1String("-hide"))
+ handleHideOption();
+ else if (arg == QLatin1String("-activate"))
+ handleActivateOption();
+ else if (arg == QLatin1String("-register"))
+ handleRegisterOption();
+ else if (arg == QLatin1String("-unregister"))
+ handleUnregisterOption();
+ else if (arg == QLatin1String("-setcurrentfilter"))
+ handleSetCurrentFilterOption();
+ else if (arg == QLatin1String("-remove-search-index"))
m_removeSearchIndex = true;
- } else if (arg == QLatin1String("-quiet")) {
- continue;
- } else if (arg == QLatin1String("-help")) {
+ else if (arg == QLatin1String("-rebuild-search-index"))
+ m_rebuildSearchIndex = true;
+ 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;
- }
+ else
+ m_error = tr("Unknown option: %1").arg(arg);
}
- if (!error.isEmpty()) {
- showMessage(error + QLatin1String("\n\n\n") + m_helpMessage, true);
+ if (!m_error.isEmpty()) {
+ showMessage(m_error + QLatin1String("\n\n\n") + tr(helpMessage), true);
return Error;
} else if (showHelp) {
- showMessage(m_helpMessage, false);
+ showMessage(tr(helpMessage), false);
return Help;
}
return Ok;
}
+bool CmdLineParser::hasMoreArgs() const
+{
+ TRACE_OBJ
+ return m_pos < m_arguments.count();
+}
+
+const QString &CmdLineParser::nextArg()
+{
+ TRACE_OBJ
+ Q_ASSERT(hasMoreArgs());
+ return m_arguments.at(m_pos++);
+}
+
+void CmdLineParser::handleCollectionFileOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &fileName = nextArg();
+ m_collectionFile = getFileName(fileName);
+ if (m_collectionFile.isEmpty())
+ m_error = tr("The collection file '%1' does not exist.").
+ arg(fileName);
+ } else {
+ m_error = tr("Missing collection file.");
+ }
+}
+
+void CmdLineParser::handleShowUrlOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &urlString = nextArg();
+ QUrl url(urlString);
+ if (url.isValid()) {
+ m_url = url;
+ } else
+ m_error = tr("Invalid URL '%1'.").arg(urlString);
+ } else {
+ m_error = tr("Missing URL.");
+ }
+}
+
+void CmdLineParser::handleShowOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Show);
+}
+
+void CmdLineParser::handleHideOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Hide);
+}
+
+void CmdLineParser::handleActivateOption()
+{
+ TRACE_OBJ
+ handleShowOrHideOrActivateOption(Activate);
+}
+
+void CmdLineParser::handleShowOrHideOrActivateOption(ShowState state)
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &widget = nextArg().toLower();
+ if (widget == QLatin1String("contents"))
+ m_contents = state;
+ else if (widget == QLatin1String("index"))
+ m_index = state;
+ else if (widget == QLatin1String("bookmarks"))
+ m_bookmarks = state;
+ else if (widget == QLatin1String("search"))
+ m_search = state;
+ else
+ m_error = tr("Unknown widget: %1").arg(widget);
+ } else {
+ m_error = tr("Missing widget.");
+ }
+}
+
+void CmdLineParser::handleRegisterOption()
+{
+ TRACE_OBJ
+ handleRegisterOrUnregisterOption(Register);
+}
+
+void CmdLineParser::handleUnregisterOption()
+{
+ TRACE_OBJ
+ handleRegisterOrUnregisterOption(Unregister);
+}
+
+void CmdLineParser::handleRegisterOrUnregisterOption(RegisterState state)
+{
+ TRACE_OBJ
+ if (hasMoreArgs()) {
+ const QString &fileName = nextArg();
+ m_helpFile = getFileName(fileName);
+ if (m_helpFile.isEmpty())
+ m_error = tr("The Qt help file '%1' does not exist.").arg(fileName);
+ else
+ m_register = state;
+ } else {
+ m_error = tr("Missing help file.");
+ }
+}
+
+void CmdLineParser::handleSetCurrentFilterOption()
+{
+ TRACE_OBJ
+ if (hasMoreArgs())
+ m_currentFilter = nextArg();
+ else
+ m_error = tr("Missing filter argument.");
+}
+
QString CmdLineParser::getFileName(const QString &fileName)
{
+ TRACE_OBJ
QFileInfo fi(fileName);
if (!fi.exists())
return QString();
@@ -253,14 +274,15 @@ QString CmdLineParser::getFileName(const QString &fileName)
void CmdLineParser::showMessage(const QString &msg, bool error)
{
+ TRACE_OBJ
if (m_quiet)
return;
#ifdef Q_OS_WIN
- QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");
+ QString message = QLatin1String("<pre>") % msg % QLatin1String("</pre>");
if (error)
- QMessageBox::critical(0, QObject::tr("Qt Assistant"), s);
+ QMessageBox::critical(0, tr("Error"), message);
else
- QMessageBox::information(0, QObject::tr("Qt Assistant"), s);
+ QMessageBox::information(0, tr("Notice"), message);
#else
fprintf(error ? stderr : stdout, "%s\n", qPrintable(msg));
#endif
@@ -268,61 +290,86 @@ void CmdLineParser::showMessage(const QString &msg, bool error)
void CmdLineParser::setCollectionFile(const QString &file)
{
+ TRACE_OBJ
m_collectionFile = file;
}
QString CmdLineParser::collectionFile() const
{
+ TRACE_OBJ
return m_collectionFile;
}
+bool CmdLineParser::collectionFileGiven() const
+{
+ TRACE_OBJ
+ return m_arguments.contains(QLatin1String("-collectionfile"),
+ Qt::CaseInsensitive);
+}
+
QUrl CmdLineParser::url() const
{
+ TRACE_OBJ
return m_url;
}
bool CmdLineParser::enableRemoteControl() const
{
+ TRACE_OBJ
return m_enableRemoteControl;
}
CmdLineParser::ShowState CmdLineParser::contents() const
{
+ TRACE_OBJ
return m_contents;
}
CmdLineParser::ShowState CmdLineParser::index() const
{
+ TRACE_OBJ
return m_index;
}
CmdLineParser::ShowState CmdLineParser::bookmarks() const
{
+ TRACE_OBJ
return m_bookmarks;
}
CmdLineParser::ShowState CmdLineParser::search() const
{
+ TRACE_OBJ
return m_search;
}
QString CmdLineParser::currentFilter() const
{
+ TRACE_OBJ
return m_currentFilter;
}
bool CmdLineParser::removeSearchIndex() const
{
+ TRACE_OBJ
return m_removeSearchIndex;
}
+bool CmdLineParser::rebuildSearchIndex() const
+{
+ TRACE_OBJ
+ return m_rebuildSearchIndex;
+}
+
CmdLineParser::RegisterState CmdLineParser::registerRequest() const
{
+ TRACE_OBJ
return m_register;
}
QString CmdLineParser::helpFile() const
{
+ TRACE_OBJ
return m_helpFile;
}
diff --git a/tools/assistant/tools/assistant/cmdlineparser.h b/tools/assistant/tools/assistant/cmdlineparser.h
index 17707cb..9fc36b3 100644
--- a/tools/assistant/tools/assistant/cmdlineparser.h
+++ b/tools/assistant/tools/assistant/cmdlineparser.h
@@ -42,6 +42,7 @@
#ifndef CMDLINEPARSER_H
#define CMDLINEPARSER_H
+#include <QtCore/QCoreApplication>
#include <QtCore/QStringList>
#include <QtCore/QUrl>
@@ -49,16 +50,18 @@ QT_BEGIN_NAMESPACE
class CmdLineParser
{
+ Q_DECLARE_TR_FUNCTIONS(CmdLineParser)
public:
enum Result {Ok, Help, Error};
enum ShowState {Untouched, Show, Hide, Activate};
enum RegisterState {None, Register, Unregister};
- CmdLineParser();
- Result parse(const QStringList &arguments);
+ CmdLineParser(const QStringList &arguments);
+ Result parse();
void setCollectionFile(const QString &file);
QString collectionFile() const;
+ bool collectionFileGiven() const;
QString cloneFile() const;
QUrl url() const;
bool enableRemoteControl() const;
@@ -68,17 +71,29 @@ public:
ShowState search() const;
QString currentFilter() const;
bool removeSearchIndex() const;
+ bool rebuildSearchIndex() 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);
+ bool hasMoreArgs() const;
+ const QString &nextArg();
+ void handleCollectionFileOption();
+ void handleShowUrlOption();
+ void handleShowOption();
+ void handleHideOption();
+ void handleActivateOption();
+ void handleShowOrHideOrActivateOption(ShowState state);
+ void handleRegisterOption();
+ void handleUnregisterOption();
+ void handleRegisterOrUnregisterOption(RegisterState state);
+ void handleSetCurrentFilterOption();
- QString m_helpMessage;
+ QStringList m_arguments;
+ int m_pos;
QString m_collectionFile;
QString m_cloneFile;
QString m_helpFile;
@@ -92,8 +107,9 @@ private:
RegisterState m_register;
QString m_currentFilter;
bool m_removeSearchIndex;
- bool m_copy;
+ bool m_rebuildSearchIndex;
bool m_quiet;
+ QString m_error;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/contentwindow.cpp b/tools/assistant/tools/assistant/contentwindow.cpp
index 4640673..8afa1df 100644
--- a/tools/assistant/tools/assistant/contentwindow.cpp
+++ b/tools/assistant/tools/assistant/contentwindow.cpp
@@ -38,25 +38,26 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "contentwindow.h"
#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.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)
+ContentWindow::ContentWindow()
+ : m_contentWidget(HelpEngineWrapper::instance().contentWidget())
, m_expandDepth(-2)
{
- m_contentWidget = m_helpEngine->contentWidget();
+ TRACE_OBJ
m_contentWidget->viewport()->installEventFilter(this);
m_contentWidget->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -76,10 +77,12 @@ ContentWindow::ContentWindow(QHelpEngine *helpEngine)
ContentWindow::~ContentWindow()
{
+ TRACE_OBJ
}
bool ContentWindow::syncToContent(const QUrl& url)
{
+ TRACE_OBJ
QModelIndex idx = m_contentWidget->indexOf(url);
if (!idx.isValid())
return false;
@@ -89,6 +92,8 @@ bool ContentWindow::syncToContent(const QUrl& url)
void ContentWindow::expandTOC()
{
+ TRACE_OBJ
+ Q_ASSERT(m_expandDepth >= -2);
if (m_expandDepth > -2) {
expandToDepth(m_expandDepth);
m_expandDepth = -2;
@@ -97,42 +102,51 @@ void ContentWindow::expandTOC()
void ContentWindow::expandToDepth(int depth)
{
+ TRACE_OBJ
+ Q_ASSERT(depth >= -2);
m_expandDepth = depth;
if (depth == -1)
m_contentWidget->expandAll();
+ else if (depth == 0)
+ m_contentWidget->collapseAll();
else
- m_contentWidget->expandToDepth(depth);
+ m_contentWidget->expandToDepth(depth - 1);
}
void ContentWindow::focusInEvent(QFocusEvent *e)
{
+ TRACE_OBJ
if (e->reason() != Qt::MouseFocusReason)
m_contentWidget->setFocus();
}
void ContentWindow::keyPressEvent(QKeyEvent *e)
{
+ TRACE_OBJ
if (e->key() == Qt::Key_Escape)
emit escapePressed();
}
bool ContentWindow::eventFilter(QObject *o, QEvent *e)
{
+ TRACE_OBJ
if (m_contentWidget && o == m_contentWidget->viewport()
&& e->type() == QEvent::MouseButtonRelease) {
QMouseEvent *me = static_cast<QMouseEvent*>(e);
- QModelIndex index = m_contentWidget->indexAt(me->pos());
- QItemSelectionModel *sm = m_contentWidget->selectionModel();
+ const QModelIndex &index = m_contentWidget->indexAt(me->pos());
+ if (!index.isValid())
+ return QWidget::eventFilter(o, e);
- Qt::MouseButtons button = me->button();
- if (index.isValid() && (sm && sm->isSelected(index))) {
+ const Qt::MouseButtons button = me->button();
+ QItemSelectionModel *sm = m_contentWidget->selectionModel();
+ if (sm->isSelected(index)) {
if ((button == Qt::LeftButton && (me->modifiers() & Qt::ControlModifier))
|| (button == Qt::MidButton)) {
QHelpContentModel *contentModel =
qobject_cast<QHelpContentModel*>(m_contentWidget->model());
if (contentModel) {
QHelpContentItem *itm = contentModel->contentItemAt(index);
- if (itm && !isPdfFile(itm))
+ if (itm && AbstractHelpViewer::canOpenPage(itm->url().path()))
CentralWidget::instance()->setSourceInNewTab(itm->url());
}
} else if (button == Qt::LeftButton) {
@@ -146,6 +160,7 @@ bool ContentWindow::eventFilter(QObject *o, QEvent *e)
void ContentWindow::showContextMenu(const QPoint &pos)
{
+ TRACE_OBJ
if (!m_contentWidget->indexAt(pos).isValid())
return;
@@ -157,7 +172,7 @@ void ContentWindow::showContextMenu(const QPoint &pos)
QMenu menu;
QAction *curTab = menu.addAction(tr("Open Link"));
QAction *newTab = menu.addAction(tr("Open Link in New Tab"));
- if (isPdfFile(itm))
+ if (!AbstractHelpViewer::canOpenPage(itm->url().path()))
newTab->setEnabled(false);
menu.move(m_contentWidget->mapToGlobal(pos));
@@ -171,20 +186,17 @@ void ContentWindow::showContextMenu(const QPoint &pos)
void ContentWindow::itemClicked(const QModelIndex &index)
{
+ TRACE_OBJ
QHelpContentModel *contentModel =
qobject_cast<QHelpContentModel*>(m_contentWidget->model());
if (contentModel) {
- QHelpContentItem *itm = contentModel->contentItemAt(index);
- if (itm)
- emit linkActivated(itm->url());
+ if (QHelpContentItem *itm = contentModel->contentItemAt(index)) {
+ const QUrl &url = itm->url();
+ if (url != CentralWidget::instance()->currentSource())
+ emit linkActivated(url);
+ }
}
}
-bool ContentWindow::isPdfFile(QHelpContentItem *item) const
-{
- const QString &path = item->url().path();
- return path.endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive);
-}
-
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/contentwindow.h b/tools/assistant/tools/assistant/contentwindow.h
index f3bf060..62855dd 100644
--- a/tools/assistant/tools/assistant/contentwindow.h
+++ b/tools/assistant/tools/assistant/contentwindow.h
@@ -57,7 +57,7 @@ class ContentWindow : public QWidget
Q_OBJECT
public:
- ContentWindow(QHelpEngine *helpEngine);
+ ContentWindow();
~ContentWindow();
bool syncToContent(const QUrl &url);
@@ -78,8 +78,7 @@ private:
bool eventFilter(QObject *o, QEvent *e);
bool isPdfFile(QHelpContentItem *item) const;
- QHelpEngine *m_helpEngine;
- QHelpContentWidget *m_contentWidget;
+ QHelpContentWidget * const m_contentWidget;
int m_expandDepth;
};
diff --git a/tools/assistant/tools/assistant/doc/assistant.qdoc b/tools/assistant/tools/assistant/doc/assistant.qdoc
index 284d680..eda2063 100644
--- a/tools/assistant/tools/assistant/doc/assistant.qdoc
+++ b/tools/assistant/tools/assistant/doc/assistant.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/assistant/tools/assistant/doc/assistant.qdocconf b/tools/assistant/tools/assistant/doc/assistant.qdocconf
index 3f192c0..57abeae 100644
--- a/tools/assistant/tools/assistant/doc/assistant.qdocconf
+++ b/tools/assistant/tools/assistant/doc/assistant.qdocconf
@@ -12,5 +12,5 @@ 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; 2010 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.6.4</div></td>\n" \
+ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt 4.7.2</div></td>\n" \
"</tr></table></div></address>"
diff --git a/tools/assistant/tools/assistant/doc/images/assistant-assistant.png b/tools/assistant/tools/assistant/doc/images/assistant-assistant.png
index b825de0..1ff5cc9 100644
--- a/tools/assistant/tools/assistant/doc/images/assistant-assistant.png
+++ b/tools/assistant/tools/assistant/doc/images/assistant-assistant.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/filternamedialog.cpp b/tools/assistant/tools/assistant/filternamedialog.cpp
index 1560e04..f75f999 100644
--- a/tools/assistant/tools/assistant/filternamedialog.cpp
+++ b/tools/assistant/tools/assistant/filternamedialog.cpp
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include <QtGui/QPushButton>
@@ -48,6 +49,7 @@ QT_BEGIN_NAMESPACE
FilterNameDialog::FilterNameDialog(QWidget *parent)
: QDialog(parent)
{
+ TRACE_OBJ
m_ui.setupUi(this);
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok),
SIGNAL(clicked()), this, SLOT(accept()));
@@ -61,11 +63,13 @@ FilterNameDialog::FilterNameDialog(QWidget *parent)
QString FilterNameDialog::filterName() const
{
+ TRACE_OBJ
return m_ui.lineEdit->text();
}
void FilterNameDialog::updateOkButton()
{
+ TRACE_OBJ
m_ui.buttonBox->button(QDialogButtonBox::Ok)
->setDisabled(m_ui.lineEdit->text().isEmpty());
}
diff --git a/tools/assistant/tools/assistant/findwidget.cpp b/tools/assistant/tools/assistant/findwidget.cpp
new file mode 100644
index 0000000..60318d4
--- /dev/null
+++ b/tools/assistant/tools/assistant/findwidget.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+#include "findwidget.h"
+
+#include <QtGui/QApplication>
+#include <QtGui/QCheckBox>
+#include <QtGui/QHideEvent>
+#include <QtGui/QKeyEvent>
+#include <QtGui/QLabel>
+#include <QtGui/QLayout>
+#include <QtGui/QLineEdit>
+#include <QtGui/QToolButton>
+
+QT_BEGIN_NAMESPACE
+
+FindWidget::FindWidget(QWidget *parent)
+ : QWidget(parent)
+ , appPalette(qApp->palette())
+{
+ TRACE_OBJ
+ installEventFilter(this);
+ QHBoxLayout *hboxLayout = new QHBoxLayout(this);
+ QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
+
+#ifndef Q_OS_MAC
+ hboxLayout->setMargin(0);
+ hboxLayout->setSpacing(6);
+ resourcePath.append(QLatin1String("win"));
+#else
+ resourcePath.append(QLatin1String("mac"));
+#endif
+
+ toolClose = setupToolButton(QLatin1String(""),
+ resourcePath + QLatin1String("/closetab.png"));
+ hboxLayout->addWidget(toolClose);
+ connect(toolClose, SIGNAL(clicked()), SLOT(hide()));
+
+ editFind = new QLineEdit(this);
+ hboxLayout->addWidget(editFind);
+ editFind->setMinimumSize(QSize(150, 0));
+ connect(editFind, SIGNAL(textChanged(QString)), this,
+ SLOT(textChanged(QString)));
+ connect(editFind, SIGNAL(returnPressed()), this, SIGNAL(findNext()));
+ connect(editFind, SIGNAL(textChanged(QString)), this, SLOT(updateButtons()));
+
+ toolPrevious = setupToolButton(tr("Previous"),
+ resourcePath + QLatin1String("/previous.png"));
+ connect(toolPrevious, SIGNAL(clicked()), this, SIGNAL(findPrevious()));
+
+ hboxLayout->addWidget(toolPrevious);
+
+ toolNext = setupToolButton(tr("Next"),
+ resourcePath + QLatin1String("/next.png"));
+ hboxLayout->addWidget(toolNext);
+ connect(toolNext, SIGNAL(clicked()), this, SIGNAL(findNext()));
+
+ checkCase = new QCheckBox(tr("Case Sensitive"), this);
+ hboxLayout->addWidget(checkCase);
+
+ labelWrapped = new QLabel(this);
+ labelWrapped->setScaledContents(true);
+ labelWrapped->setTextFormat(Qt::RichText);
+ labelWrapped->setMinimumSize(QSize(0, 20));
+ labelWrapped->setMaximumSize(QSize(105, 20));
+ 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()
+{
+ TRACE_OBJ
+}
+
+void FindWidget::show()
+{
+ TRACE_OBJ
+ QWidget::show();
+ editFind->selectAll();
+ editFind->setFocus(Qt::ShortcutFocusReason);
+}
+
+void FindWidget::showAndClear()
+{
+ TRACE_OBJ
+ show();
+ editFind->clear();
+}
+
+QString FindWidget::text() const
+{
+ TRACE_OBJ
+ return editFind->text();
+}
+
+bool FindWidget::caseSensitive() const
+{
+ TRACE_OBJ
+ return checkCase->isChecked();
+}
+
+void FindWidget::setPalette(bool found)
+{
+ TRACE_OBJ
+ QPalette palette = editFind->palette();
+ palette.setColor(QPalette::Active, QPalette::Base, found ? Qt::white
+ : QColor(255, 102, 102));
+ editFind->setPalette(palette);
+}
+
+void FindWidget::setTextWrappedVisible(bool visible)
+{
+ TRACE_OBJ
+ labelWrapped->setVisible(visible);
+}
+
+void FindWidget::hideEvent(QHideEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous())
+ qApp->setPalette(appPalette);
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::showEvent(QShowEvent* event)
+{
+ TRACE_OBJ
+#if !defined(QT_NO_WEBKIT)
+ // TODO: remove this once webkit supports setting the palette
+ if (!event->spontaneous()) {
+ QPalette p = appPalette;
+ 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);
+ }
+#else
+ Q_UNUSED(event);
+#endif
+}
+
+void FindWidget::updateButtons()
+{
+ TRACE_OBJ
+ const bool enable = !editFind->text().isEmpty();
+ toolNext->setEnabled(enable);
+ toolPrevious->setEnabled(enable);
+}
+
+void FindWidget::textChanged(const QString &text)
+{
+ TRACE_OBJ
+ emit find(text, true);
+}
+
+bool FindWidget::eventFilter(QObject *object, QEvent *e)
+{
+ TRACE_OBJ
+ if (e->type() == QEvent::KeyPress) {
+ if ((static_cast<QKeyEvent*>(e))->key() == Qt::Key_Escape) {
+ hide();
+ emit escapePressed();
+ }
+ }
+ return QWidget::eventFilter(object, e);
+}
+
+QToolButton* FindWidget::setupToolButton(const QString &text, const QString &icon)
+{
+ TRACE_OBJ
+ QToolButton *toolButton = new QToolButton(this);
+
+ toolButton->setText(text);
+ toolButton->setAutoRaise(true);
+ toolButton->setIcon(QIcon(icon));
+ toolButton->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+
+ return toolButton;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/helpwindow.h b/tools/assistant/tools/assistant/findwidget.h
index c20a21f..cf78003 100644
--- a/tools/assistant/compat/helpwindow.h
+++ b/tools/assistant/tools/assistant/findwidget.h
@@ -38,63 +38,64 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#ifndef FINDWIDGET_H
+#define FINDWIDGET_H
-#ifndef HELPWINDOW_H
-#define HELPWINDOW_H
-
-#include <QTextBrowser>
+#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
-class MainWindow;
-class QKeyEvent;
-class QMime;
-class QMouseEvent;
-class QMenu;
+class QCheckBox;
+class QLabel;
+class QLineEdit;
+class QToolButton;
-class HelpWindow : public QTextBrowser
+class FindWidget : public QWidget
{
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 );
+ FindWidget(QWidget *parent = 0);
+ ~FindWidget();
+
+ void show();
+ void showAndClear();
- void mousePressEvent(QMouseEvent *e);
- void keyPressEvent(QKeyEvent *);
+ QString text() const;
+ bool caseSensitive() const;
+
+ void setPalette(bool found);
+ void setTextWrappedVisible(bool visible);
signals:
- void chooseWebBrowser();
- void choosePDFReader();
+ void escapePressed();
-protected:
- virtual void contextMenuEvent(QContextMenuEvent *e);
- virtual void mouseReleaseEvent(QMouseEvent *e);
+ void findNext();
+ void findPrevious();
+ void find(const QString &text, bool forward);
-protected slots:
- void ensureCursorVisible();
+protected:
+ void hideEvent(QHideEvent* event);
+ void showEvent(QShowEvent * event);
private slots:
- void openLinkInNewWindow();
- void openLinkInNewPage();
+ void updateButtons();
+ void textChanged(const QString &text);
- bool isKDERunning() const;
+private:
+ bool eventFilter(QObject *object, QEvent *e);
+ QToolButton* setupToolButton(const QString &text, const QString &icon);
private:
- bool hasAnchorAt(const QPoint& pos);
-
- MainWindow *mw;
- QString lastAnchor;
- bool blockScroll;
- bool shiftPressed;
- bool newWindow;
- bool fwdAvail;
- bool backAvail;
+ QPalette appPalette;
+
+ QLineEdit *editFind;
+ QCheckBox *checkCase;
+ QLabel *labelWrapped;
+ QToolButton *toolNext;
+ QToolButton *toolClose;
+ QToolButton *toolPrevious;
};
QT_END_NAMESPACE
-#endif // HELPWINDOW_H
+#endif // FINDWIDGET_H
diff --git a/tools/assistant/tools/assistant/helpenginewrapper.cpp b/tools/assistant/tools/assistant/helpenginewrapper.cpp
new file mode 100644
index 0000000..a53a9ee
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpenginewrapper.cpp
@@ -0,0 +1,835 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "helpenginewrapper.h"
+#include "../shared/collectionconfiguration.h"
+
+#include <QtCore/QDateTime>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFileSystemWatcher>
+#include <QtCore/QPair>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QTimer>
+#include <QtHelp/QHelpContentModel>
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpIndexModel>
+#include <QtHelp/QHelpSearchEngine>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const QString Unfiltered;
+ const QString AppFontKey(QLatin1String("appFont"));
+ const QString AppWritingSystemKey(QLatin1String("appWritingSystem"));
+ const QString BookmarksKey(QLatin1String("Bookmarks"));
+ const QString BrowserFontKey(QLatin1String("browserFont"));
+ const QString BrowserWritingSystemKey(QLatin1String("browserWritingSystem"));
+ const QString HomePageKey(QLatin1String("homepage"));
+ const QString MainWindowKey(QLatin1String("MainWindow"));
+ const QString MainWindowGeometryKey(QLatin1String("MainWindowGeometry"));
+ const QString SearchWasAttachedKey(QLatin1String("SearchWasAttached"));
+ const QString StartOptionKey(QLatin1String("StartOption"));
+ const QString UseAppFontKey(QLatin1String("useAppFont"));
+ const QString UseBrowserFontKey(QLatin1String("useBrowserFont"));
+ const QString VersionKey(QString(QLatin1String("qtVersion%1$$$%2")).
+ arg(QLatin1String(QT_VERSION_STR)));
+} // anonymous namespace
+
+class TimeoutForwarder : public QObject
+{
+ Q_OBJECT
+public:
+ TimeoutForwarder(const QString &fileName);
+private slots:
+ void forward();
+private:
+ friend class HelpEngineWrapperPrivate;
+
+ const QString m_fileName;
+};
+
+class HelpEngineWrapperPrivate : public QObject
+{
+ Q_OBJECT
+ friend class HelpEngineWrapper;
+ friend class TimeoutForwarder;
+private slots:
+ void qchFileChanged(const QString &fileName);
+
+signals:
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
+
+private:
+ HelpEngineWrapperPrivate(const QString &collectionFile);
+
+ void initFileSystemWatchers();
+ void checkDocFilesWatched();
+ void qchFileChanged(const QString &fileName, bool fromTimeout);
+
+ static const int UpdateGracePeriod = 2000;
+
+ QHelpEngine * const m_helpEngine;
+ QFileSystemWatcher * const m_qchWatcher;
+ typedef QPair<QDateTime, QSharedPointer<TimeoutForwarder> > RecentSignal;
+ QMap<QString, RecentSignal> m_recentQchUpdates;
+};
+
+const QString HelpEngineWrapper::TrUnfiltered = HelpEngineWrapper::tr("Unfiltered");
+
+HelpEngineWrapper *HelpEngineWrapper::helpEngineWrapper = 0;
+
+HelpEngineWrapper &HelpEngineWrapper::instance(const QString &collectionFile)
+{
+ TRACE_OBJ
+ /*
+ * Note that this Singleton cannot be static, because it has to be
+ * deleted before the QApplication.
+ */
+ if (helpEngineWrapper == 0)
+ helpEngineWrapper = new HelpEngineWrapper(collectionFile);
+ return *helpEngineWrapper;
+}
+
+void HelpEngineWrapper::removeInstance()
+{
+ TRACE_OBJ
+ delete helpEngineWrapper;
+ helpEngineWrapper = 0;
+}
+
+HelpEngineWrapper::HelpEngineWrapper(const QString &collectionFile)
+ : d(new HelpEngineWrapperPrivate(collectionFile))
+{
+ TRACE_OBJ
+
+ /*
+ * Otherwise we will waste time if several new docs are found,
+ * because we will start to index them, only to be interupted
+ * by the next request. Also, there is a nasty SQLITE bug that will
+ * cause the application to hang for minutes in that case.
+ * This call is reverted by initalDocSetupDone(), which must be
+ * called after the new docs have been installed.
+ */
+ disconnect(d->m_helpEngine, SIGNAL(setupFinished()),
+ searchEngine(), SLOT(indexDocumentation()));
+
+ connect(d, SIGNAL(documentationRemoved(QString)),
+ this, SIGNAL(documentationRemoved(QString)));
+ connect(d, SIGNAL(documentationUpdated(QString)),
+ this, SIGNAL(documentationUpdated(QString)));
+ connect(d->m_helpEngine, SIGNAL(currentFilterChanged(QString)),
+ this, SLOT(handleCurrentFilterChanged(QString)));
+ connect(d->m_helpEngine, SIGNAL(setupFinished()),
+ this, SIGNAL(setupFinished()));
+}
+
+HelpEngineWrapper::~HelpEngineWrapper()
+{
+ TRACE_OBJ
+ const QStringList &namespaces = d->m_helpEngine->registeredDocumentations();
+ foreach (const QString &nameSpace, namespaces) {
+ const QString &docFile
+ = d->m_helpEngine->documentationFileName(nameSpace);
+ d->m_qchWatcher->removePath(docFile);
+ }
+
+ delete d;
+}
+
+void HelpEngineWrapper::initialDocSetupDone()
+{
+ TRACE_OBJ
+ connect(d->m_helpEngine, SIGNAL(setupFinished()),
+ searchEngine(), SLOT(indexDocumentation()));
+ setupData();
+}
+
+QHelpSearchEngine *HelpEngineWrapper::searchEngine() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->searchEngine();
+}
+
+QHelpContentModel *HelpEngineWrapper::contentModel() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->contentModel();
+}
+
+QHelpIndexModel *HelpEngineWrapper::indexModel() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->indexModel();
+}
+
+QHelpContentWidget *HelpEngineWrapper::contentWidget()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->contentWidget();
+}
+
+QHelpIndexWidget *HelpEngineWrapper::indexWidget()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->indexWidget();
+}
+
+const QStringList HelpEngineWrapper::registeredDocumentations() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->registeredDocumentations();
+}
+
+const QString HelpEngineWrapper::collectionFile() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->collectionFile();
+}
+
+bool HelpEngineWrapper::registerDocumentation(const QString &docFile)
+{
+ TRACE_OBJ
+ d->checkDocFilesWatched();
+ if (!d->m_helpEngine->registerDocumentation(docFile))
+ return false;
+ d->m_qchWatcher->addPath(docFile);
+ d->checkDocFilesWatched();
+ return true;
+}
+
+bool HelpEngineWrapper::unregisterDocumentation(const QString &namespaceName)
+{
+ TRACE_OBJ
+ d->checkDocFilesWatched();
+ const QString &file = d->m_helpEngine->documentationFileName(namespaceName);
+ if (!d->m_helpEngine->unregisterDocumentation(namespaceName))
+ return false;
+ d->m_qchWatcher->removePath(file);
+ d->checkDocFilesWatched();
+ return true;
+}
+
+bool HelpEngineWrapper::setupData()
+{
+ TRACE_OBJ
+ return d->m_helpEngine->setupData();
+}
+
+bool HelpEngineWrapper::addCustomFilter(const QString &filterName,
+ const QStringList &attributes)
+{
+ TRACE_OBJ
+ return d->m_helpEngine->addCustomFilter(filterName, attributes);
+}
+
+bool HelpEngineWrapper::removeCustomFilter(const QString &filterName)
+{
+ TRACE_OBJ
+ return d->m_helpEngine->removeCustomFilter(filterName);
+}
+
+void HelpEngineWrapper::setCurrentFilter(const QString &currentFilter)
+{
+ TRACE_OBJ
+ const QString &filter
+ = currentFilter == TrUnfiltered ? Unfiltered : currentFilter;
+ d->m_helpEngine->setCurrentFilter(filter);
+}
+
+const QString HelpEngineWrapper::currentFilter() const
+{
+ TRACE_OBJ
+ const QString &filter = d->m_helpEngine->currentFilter();
+ return filter == Unfiltered ? TrUnfiltered : filter;
+}
+
+const QStringList HelpEngineWrapper::customFilters() const
+{
+ TRACE_OBJ
+ QStringList filters = d->m_helpEngine->customFilters();
+ filters.removeOne(Unfiltered);
+ filters.prepend(TrUnfiltered);
+ return filters;
+}
+
+QUrl HelpEngineWrapper::findFile(const QUrl &url) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->findFile(url);
+}
+
+QByteArray HelpEngineWrapper::fileData(const QUrl &url) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->fileData(url);
+}
+
+QMap<QString, QUrl> HelpEngineWrapper::linksForIdentifier(const QString &id) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->linksForIdentifier(id);
+}
+
+const QStringList HelpEngineWrapper::filterAttributes() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->filterAttributes();
+}
+
+const QStringList HelpEngineWrapper::filterAttributes(const QString &filterName) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->filterAttributes(filterName);
+}
+
+QString HelpEngineWrapper::error() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->error();
+}
+
+const QStringList HelpEngineWrapper::qtDocInfo(const QString &component) const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(VersionKey.arg(component)).toString().
+ split(CollectionConfiguration::ListSeparator);
+}
+
+void HelpEngineWrapper::setQtDocInfo(const QString &component,
+ const QStringList &doc)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(VersionKey.arg(component),
+ doc.join(CollectionConfiguration::ListSeparator));
+}
+
+const QStringList HelpEngineWrapper::lastShownPages() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastShownPages(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastShownPages(const QStringList &lastShownPages)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastShownPages(*d->m_helpEngine, lastShownPages);
+}
+
+const QStringList HelpEngineWrapper::lastZoomFactors() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastZoomFactors(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastZoomFactors(const QStringList &lastZoomFactors)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastZoomFactors(*d->m_helpEngine, lastZoomFactors);
+}
+
+const QString HelpEngineWrapper::cacheDir() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::cacheDir(*d->m_helpEngine);
+}
+
+bool HelpEngineWrapper::cacheDirIsRelativeToCollection() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::cacheDirIsRelativeToCollection(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setCacheDir(const QString &cacheDir,
+ bool relativeToCollection)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setCacheDir(*d->m_helpEngine, cacheDir,
+ relativeToCollection);
+}
+
+bool HelpEngineWrapper::filterFunctionalityEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::filterFunctionalityEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setFilterFunctionalityEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setFilterFunctionalityEnabled(*d->m_helpEngine,
+ enabled);
+}
+
+bool HelpEngineWrapper::filterToolbarVisible() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::filterToolbarVisible(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setFilterToolbarVisible(bool visible)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setFilterToolbarVisible(*d->m_helpEngine, visible);
+}
+
+bool HelpEngineWrapper::addressBarEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::addressBarEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAddressBarEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAddressBarEnabled(*d->m_helpEngine, enabled);
+}
+
+bool HelpEngineWrapper::addressBarVisible() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::addressBarVisible(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAddressBarVisible(bool visible)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAddressBarVisible(*d->m_helpEngine, visible);
+}
+
+bool HelpEngineWrapper::documentationManagerEnabled() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::documentationManagerEnabled(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setDocumentationManagerEnabled(bool enabled)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setDocumentationManagerEnabled(*d->m_helpEngine,
+ enabled);
+}
+
+const QByteArray HelpEngineWrapper::aboutMenuTexts() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutMenuTexts(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutMenuTexts(const QByteArray &texts)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutMenuTexts(*d->m_helpEngine, texts);
+}
+
+const QByteArray HelpEngineWrapper::aboutIcon() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutIcon(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutIcon(const QByteArray &icon)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutIcon(*d->m_helpEngine, icon);
+}
+
+const QByteArray HelpEngineWrapper::aboutImages() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutImages(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutImages(const QByteArray &images)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutImages(*d->m_helpEngine, images);
+}
+
+const QByteArray HelpEngineWrapper::aboutTexts() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::aboutTexts(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setAboutTexts(const QByteArray &texts)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setAboutTexts(*d->m_helpEngine, texts);
+}
+
+const QString HelpEngineWrapper::windowTitle() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::windowTitle(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setWindowTitle(const QString &windowTitle)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setWindowTitle(*d->m_helpEngine, windowTitle);
+}
+
+const QByteArray HelpEngineWrapper::applicationIcon() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::applicationIcon(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setApplicationIcon(const QByteArray &icon)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setApplicationIcon(*d->m_helpEngine, icon);
+}
+
+const QByteArray HelpEngineWrapper::mainWindow() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(MainWindowKey).toByteArray();
+}
+
+void HelpEngineWrapper::setMainWindow(const QByteArray &mainWindow)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(MainWindowKey, mainWindow);
+}
+
+const QByteArray HelpEngineWrapper::mainWindowGeometry() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(MainWindowGeometryKey).toByteArray();
+}
+
+void HelpEngineWrapper::setMainWindowGeometry(const QByteArray &geometry)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(MainWindowGeometryKey, geometry);
+}
+
+const QByteArray HelpEngineWrapper::bookmarks() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(BookmarksKey).toByteArray();
+}
+
+void HelpEngineWrapper::setBookmarks(const QByteArray &bookmarks)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BookmarksKey, bookmarks);
+}
+
+int HelpEngineWrapper::lastTabPage() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::lastTabPage(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setLastTabPage(int lastPage)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setLastTabPage(*d->m_helpEngine, lastPage);
+}
+
+bool HelpEngineWrapper::searchWasAttached() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(SearchWasAttachedKey).toBool();
+}
+
+void HelpEngineWrapper::setSearchWasAttached(bool attached)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(SearchWasAttachedKey, attached);
+}
+
+int HelpEngineWrapper::startOption() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(StartOptionKey, ShowLastPages).toInt();
+}
+
+void HelpEngineWrapper::setStartOption(int option)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(StartOptionKey, option);
+}
+
+const QString HelpEngineWrapper::homePage() const
+{
+ TRACE_OBJ
+ const QString &homePage
+ = d->m_helpEngine->customValue(HomePageKey).toString();
+ if (!homePage.isEmpty())
+ return homePage;
+ return defaultHomePage();
+}
+
+void HelpEngineWrapper::setHomePage(const QString &page)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(HomePageKey, page);
+
+}
+
+const QString HelpEngineWrapper::defaultHomePage() const
+{
+ TRACE_OBJ
+ return CollectionConfiguration::defaultHomePage(*d->m_helpEngine);
+}
+
+void HelpEngineWrapper::setDefaultHomePage(const QString &page)
+{
+ TRACE_OBJ
+ CollectionConfiguration::setDefaultHomePage(*d->m_helpEngine, page);
+}
+
+bool HelpEngineWrapper::hasFontSettings() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseAppFontKey).isValid();
+}
+
+bool HelpEngineWrapper::usesAppFont() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseAppFontKey).toBool();
+}
+
+void HelpEngineWrapper::setUseAppFont(bool useAppFont)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(UseAppFontKey, useAppFont);
+}
+
+bool HelpEngineWrapper::usesBrowserFont() const
+{
+ TRACE_OBJ
+ return d->m_helpEngine->customValue(UseBrowserFontKey, false).toBool();
+}
+
+void HelpEngineWrapper::setUseBrowserFont(bool useBrowserFont)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(UseBrowserFontKey, useBrowserFont);
+}
+
+const QFont HelpEngineWrapper::appFont() const
+{
+ TRACE_OBJ
+ return qVariantValue<QFont>(d->m_helpEngine->customValue(AppFontKey));
+}
+
+void HelpEngineWrapper::setAppFont(const QFont &font)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(AppFontKey, font);
+}
+
+QFontDatabase::WritingSystem HelpEngineWrapper::appWritingSystem() const
+{
+ TRACE_OBJ
+ return static_cast<QFontDatabase::WritingSystem>(
+ d->m_helpEngine->customValue(AppWritingSystemKey).toInt());
+}
+
+void HelpEngineWrapper::setAppWritingSystem(QFontDatabase::WritingSystem system)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(AppWritingSystemKey, system);
+}
+
+const QFont HelpEngineWrapper::browserFont() const
+{
+ TRACE_OBJ
+ return qVariantValue<QFont>(d->m_helpEngine->customValue(BrowserFontKey));
+}
+
+void HelpEngineWrapper::setBrowserFont(const QFont &font)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BrowserFontKey, font);
+}
+
+QFontDatabase::WritingSystem HelpEngineWrapper::browserWritingSystem() const
+{
+ TRACE_OBJ
+ return static_cast<QFontDatabase::WritingSystem>(
+ d->m_helpEngine->customValue(BrowserWritingSystemKey).toInt());
+}
+
+void HelpEngineWrapper::setBrowserWritingSystem(QFontDatabase::WritingSystem system)
+{
+ TRACE_OBJ
+ d->m_helpEngine->setCustomValue(BrowserWritingSystemKey, system);
+}
+
+void HelpEngineWrapper::handleCurrentFilterChanged(const QString &filter)
+{
+ const QString &filterToReport
+ = filter == Unfiltered ? TrUnfiltered : filter;
+ emit currentFilterChanged(filterToReport);
+}
+
+
+TimeoutForwarder::TimeoutForwarder(const QString &fileName)
+ : m_fileName(fileName)
+{
+ TRACE_OBJ
+}
+
+void TimeoutForwarder::forward()
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().d->qchFileChanged(m_fileName, true);
+}
+
+
+HelpEngineWrapperPrivate::HelpEngineWrapperPrivate(const QString &collectionFile)
+ : m_helpEngine(new QHelpEngine(collectionFile, this)),
+ m_qchWatcher(new QFileSystemWatcher(this))
+{
+ TRACE_OBJ
+ if (!m_helpEngine->customFilters().contains(Unfiltered))
+ m_helpEngine->addCustomFilter(Unfiltered, QStringList());
+ initFileSystemWatchers();
+}
+
+void HelpEngineWrapperPrivate::initFileSystemWatchers()
+{
+ TRACE_OBJ
+ foreach(const QString &ns, m_helpEngine->registeredDocumentations()) {
+ const QString &docFile = m_helpEngine->documentationFileName(ns);
+ m_qchWatcher->addPath(docFile);
+ connect(m_qchWatcher, SIGNAL(fileChanged(QString)),
+ this, SLOT(qchFileChanged(QString)));
+ }
+ checkDocFilesWatched();
+}
+
+void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName)
+{
+ TRACE_OBJ
+ qchFileChanged(fileName, false);
+}
+
+void HelpEngineWrapperPrivate::checkDocFilesWatched()
+{
+ TRACE_OBJ
+ const int watchedFilesCount = m_qchWatcher->files().count();
+ const int docFilesCount = m_helpEngine->registeredDocumentations().count();
+ if (watchedFilesCount != docFilesCount) {
+ qWarning("Strange: Have %d docs, but %d are being watched",
+ watchedFilesCount, docFilesCount);
+ }
+}
+
+void HelpEngineWrapperPrivate::qchFileChanged(const QString &fileName,
+ bool fromTimeout)
+{
+ TRACE_OBJ
+
+ /*
+ * We don't use QHelpEngineCore::namespaceName(fileName), because the file
+ * may not exist anymore or contain a different namespace.
+ */
+ QString ns;
+ foreach (const QString &curNs, m_helpEngine->registeredDocumentations()) {
+ if (m_helpEngine->documentationFileName(curNs) == fileName) {
+ ns = curNs;
+ break;
+ }
+ }
+
+ /*
+ * We can't do an assertion here, because QFileSystemWatcher may send the
+ * signal more than once.
+ */
+ if (ns.isEmpty()) {
+ m_recentQchUpdates.remove(fileName);
+ return;
+ }
+
+ /*
+ * Since the QFileSystemWatcher typically sends the signal more than once,
+ * we repeatedly delay our reaction a bit until we think the last signal
+ * was sent.
+ */
+
+ QMap<QString, RecentSignal>::Iterator it = m_recentQchUpdates.find(fileName);
+ const QDateTime &now = QDateTime::currentDateTime();
+
+ // Case 1: This is the first recent signal for the file.
+ if (it == m_recentQchUpdates.end()) {
+ QSharedPointer<TimeoutForwarder> forwarder(new TimeoutForwarder(fileName));
+ m_recentQchUpdates.insert(fileName, RecentSignal(now, forwarder));
+ QTimer::singleShot(UpdateGracePeriod, forwarder.data(), SLOT(forward()));
+ return;
+ }
+
+ // Case 2: The last signal for this file has not expired yet.
+ if (it.value().first > now.addMSecs(-UpdateGracePeriod)) {
+ if (!fromTimeout)
+ it.value().first = now;
+ else
+ QTimer::singleShot(UpdateGracePeriod, it.value().second.data(),
+ SLOT(forward()));
+ return;
+ }
+
+ // Case 3: The last signal for this file has expired.
+ if (m_helpEngine->unregisterDocumentation(ns)) {
+ if (!QFileInfo(fileName).exists()
+ || !m_helpEngine->registerDocumentation(fileName)) {
+ m_qchWatcher->removePath(fileName);
+ emit documentationRemoved(ns);
+ } else {
+ emit documentationUpdated(ns);
+ }
+ m_helpEngine->setupData();
+ }
+ m_recentQchUpdates.erase(it);
+}
+
+
+QT_END_NAMESPACE
+
+#include "helpenginewrapper.moc"
diff --git a/tools/assistant/tools/assistant/helpenginewrapper.h b/tools/assistant/tools/assistant/helpenginewrapper.h
new file mode 100644
index 0000000..c1041b6
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpenginewrapper.h
@@ -0,0 +1,216 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPENGINEWRAPPER_H
+#define HELPENGINEWRAPPER_H
+
+#include <QtCore/QMap>
+#include <QtCore/QObject>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+#include <QtCore/QUrl>
+#include <QtGui/QFont>
+#include <QtGui/QFontDatabase>
+
+QT_BEGIN_NAMESPACE
+
+class QFileSystemWatcher;
+class QHelpContentModel;
+class QHelpContentWidget;
+class QHelpIndexModel;
+class QHelpIndexWidget;
+class QHelpSearchEngine;
+
+enum {
+ ShowHomePage = 0,
+ ShowBlankPage = 1,
+ ShowLastPages = 2
+};
+
+class HelpEngineWrapperPrivate;
+class TimeoutForwarder;
+
+class HelpEngineWrapper : public QObject
+{
+ Q_OBJECT
+ Q_DISABLE_COPY(HelpEngineWrapper)
+ friend class TimeoutForwarder;
+public:
+ static HelpEngineWrapper &instance(const QString &collectionFile = QString());
+ static void removeInstance();
+
+ // Forwarded help engine member functions, possibly enriched.
+ QHelpSearchEngine *searchEngine() const;
+ QHelpContentModel *contentModel() const;
+ QHelpIndexModel *indexModel() const;
+ QHelpContentWidget *contentWidget();
+ QHelpIndexWidget *indexWidget();
+ bool setupData();
+ const QStringList registeredDocumentations() const;
+ const QString collectionFile() const;
+ bool registerDocumentation(const QString &docFile);
+ bool unregisterDocumentation(const QString &namespaceName);
+ bool addCustomFilter(const QString &filterName,
+ const QStringList &attributes);
+ bool removeCustomFilter(const QString &filterName);
+ void setCurrentFilter(const QString &filterName);
+ const QString currentFilter() const;
+ const QStringList customFilters() const;
+ QUrl findFile(const QUrl &url) const;
+ QByteArray fileData(const QUrl &url) const;
+ QMap<QString, QUrl> linksForIdentifier(const QString &id) const;
+ const QStringList filterAttributes() const;
+ const QStringList filterAttributes(const QString &filterName) const;
+ QString error() const;
+
+ /*
+ * To be called after assistant has finished looking for new documentation.
+ * This will mainly cause the search index to be updated, if necessary.
+ */
+ void initialDocSetupDone();
+
+ const QStringList qtDocInfo(const QString &component) const;
+ void setQtDocInfo(const QString &component, const QStringList &doc);
+
+ const QString homePage() const;
+ void setHomePage(const QString &page);
+ const QString defaultHomePage() const;
+ void setDefaultHomePage(const QString &page);
+
+ int lastTabPage() const;
+ void setLastTabPage(int lastPage);
+
+ // TODO: Don't allow last pages and zoom factors to be set in isolation
+ // Perhaps also fill up missing elements automatically or assert.
+ const QStringList lastShownPages() const;
+ void setLastShownPages(const QStringList &lastShownPages);
+ const QStringList lastZoomFactors() const;
+ void setLastZoomFactors(const QStringList &lastZoomFactors);
+
+ const QString cacheDir() const;
+ bool cacheDirIsRelativeToCollection() const;
+ void setCacheDir(const QString &cacheDir, bool relativeToCollection);
+
+ bool filterFunctionalityEnabled() const;
+ void setFilterFunctionalityEnabled(bool enabled);
+
+ bool filterToolbarVisible() const;
+ void setFilterToolbarVisible(bool visible);
+
+ bool addressBarEnabled() const;
+ void setAddressBarEnabled(bool enabled);
+
+ bool addressBarVisible() const;
+ void setAddressBarVisible(bool visible);
+
+ bool documentationManagerEnabled() const;
+ void setDocumentationManagerEnabled(bool enabled);
+
+ const QByteArray aboutMenuTexts() const;
+ void setAboutMenuTexts(const QByteArray &texts);
+ const QByteArray aboutTexts() const;
+ void setAboutTexts(const QByteArray &texts);
+ const QByteArray aboutIcon() const;
+ void setAboutIcon(const QByteArray &icon);
+ const QByteArray aboutImages() const;
+ void setAboutImages(const QByteArray &images);
+
+ const QString windowTitle() const;
+ void setWindowTitle(const QString &windowTitle);
+
+ const QByteArray applicationIcon() const;
+ void setApplicationIcon(const QByteArray &icon);
+
+ const QByteArray mainWindow() const;
+ void setMainWindow(const QByteArray &mainWindow);
+ const QByteArray mainWindowGeometry() const;
+ void setMainWindowGeometry(const QByteArray &geometry);
+
+ const QByteArray bookmarks() const;
+ void setBookmarks(const QByteArray &bookmarks);
+
+ int startOption() const;
+ void setStartOption(int option);
+
+ bool searchWasAttached() const;
+ void setSearchWasAttached(bool attached);
+
+ bool hasFontSettings() const;
+ bool usesAppFont() const;
+ void setUseAppFont(bool useAppFont);
+ bool usesBrowserFont() const;
+ void setUseBrowserFont(bool useBrowserFont);
+ const QFont appFont() const;
+ void setAppFont(const QFont &font);
+ QFontDatabase::WritingSystem appWritingSystem() const;
+ void setAppWritingSystem(QFontDatabase::WritingSystem system);
+ const QFont browserFont() const;
+ void setBrowserFont(const QFont &font);
+ QFontDatabase::WritingSystem browserWritingSystem() const;
+ void setBrowserWritingSystem(QFontDatabase::WritingSystem system);
+
+ static const QString TrUnfiltered;
+
+signals:
+
+ // For asynchronous doc updates triggered by external actions.
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
+
+ // Forwarded from QHelpEngineCore.
+ void currentFilterChanged(const QString &currentFilter);
+ void setupFinished();
+
+private slots:
+ void handleCurrentFilterChanged(const QString &filter);
+
+private:
+ HelpEngineWrapper(const QString &collectionFile);
+ ~HelpEngineWrapper();
+
+ static HelpEngineWrapper *helpEngineWrapper;
+
+ HelpEngineWrapperPrivate *d;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPENGINEWRAPPER_H
diff --git a/tools/assistant/tools/assistant/helpviewer.cpp b/tools/assistant/tools/assistant/helpviewer.cpp
index f22ab8a..6499139 100644
--- a/tools/assistant/tools/assistant/helpviewer.cpp
+++ b/tools/assistant/tools/assistant/helpviewer.cpp
@@ -38,590 +38,143 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "helpviewer.h"
-#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "tracer.h"
-#include <QtCore/QDir>
-#include <QtCore/QEvent>
-#include <QtCore/QVariant>
-#include <QtCore/QByteArray>
-#include <QtCore/QTimer>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStringBuilder>
+#include <QtCore/QTemporaryFile>
+#include <QtCore/QUrl>
-#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;
+const QLatin1String AbstractHelpViewer::DocPath("qthelp://com.trolltech.");
+
+const QString AbstractHelpViewer::AboutBlank =
+ QCoreApplication::translate("HelpViewer", "<title>about:blank</title>");
+
+const QString AbstractHelpViewer::LocalHelpFile = QLatin1String("qthelp://"
+ "com.trolltech.com.assistantinternal-1.0.0/assistant/assistant.html");
+
+const QString AbstractHelpViewer::PageNotFoundMessage =
+ QCoreApplication::translate("HelpViewer", "<title>Error 404...</title><div "
+ "align=\"center\"><br><br><h1>The page could not be found</h1><br><h3>'%1'"
+ "</h3></div>");
+
+struct ExtensionMap {
+ const char *extension;
+ const char *mimeType;
+} extensionMap[] = {
+ { ".bmp", "image/bmp" },
+ { ".css", "text/css" },
+ { ".gif", "image/gif" },
+ { ".html", "text/html" },
+ { ".htm", "text/html" },
+ { ".ico", "image/x-icon" },
+ { ".jpeg", "image/jpeg" },
+ { ".jpg", "image/jpeg" },
+ { ".js", "application/x-javascript" },
+ { ".mng", "video/x-mng" },
+ { ".pbm", "image/x-portable-bitmap" },
+ { ".pgm", "image/x-portable-graymap" },
+ { ".pdf", "application/pdf" },
+ { ".png", "image/png" },
+ { ".ppm", "image/x-portable-pixmap" },
+ { ".rss", "application/rss+xml" },
+ { ".svg", "image/svg+xml" },
+ { ".svgz", "image/svg+xml" },
+ { ".text", "text/plain" },
+ { ".tif", "image/tiff" },
+ { ".tiff", "image/tiff" },
+ { ".txt", "text/plain" },
+ { ".xbm", "image/x-xbitmap" },
+ { ".xml", "text/xml" },
+ { ".xpm", "image/x-xpm" },
+ { ".xsl", "text/xsl" },
+ { ".xhtml", "application/xhtml+xml" },
+ { ".wml", "text/vnd.wap.wml" },
+ { ".wmlc", "application/vnd.wap.wmlc" },
+ { "about:blank", 0 },
+ { 0, 0 }
};
-HelpNetworkAccessManager::HelpNetworkAccessManager(QHelpEngine *engine,
- QObject *parent)
- : QNetworkAccessManager(parent), helpEngine(engine)
-{
-}
-
-QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/,
- const QNetworkRequest &request, QIODevice* /*outgoingData*/)
-{
- 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 if (mimeType.endsWith(QLatin1String(".txt"))) {
- mimeType = QLatin1String("text/plain");
- } else {
- mimeType = QLatin1String("text/html");
- }
-
- const QByteArray &data = helpEngine->findFile(url).isValid()
- ? helpEngine->fileData(url) : QByteArray("File not found!");
- return new HelpNetworkReply(request, data, mimeType);
-}
-
-class HelpPage : public QWebPage
-{
-public:
- HelpPage(CentralWidget *central, QHelpEngine *engine, QObject *parent);
-
-protected:
- virtual QWebPage *createWindow(QWebPage::WebWindowType);
- virtual void triggerAction(WebAction action, bool checked = false);
-
- virtual bool acceptNavigationRequest(QWebFrame *frame,
- const QNetworkRequest &request, NavigationType type);
-
-private:
- CentralWidget *centralWidget;
- QHelpEngine *helpEngine;
- bool closeNewTabIfNeeded;
-
- friend class HelpViewer;
- Qt::MouseButtons m_pressedButtons;
- Qt::KeyboardModifiers m_keyboardModifiers;
-};
+// -- AbstractHelpViewer
-HelpPage::HelpPage(CentralWidget *central, QHelpEngine *engine, QObject *parent)
- : QWebPage(parent)
- , centralWidget(central)
- , helpEngine(engine)
- , closeNewTabIfNeeded(false)
- , m_pressedButtons(Qt::NoButton)
- , m_keyboardModifiers(Qt::NoModifier)
+AbstractHelpViewer::AbstractHelpViewer()
{
}
-QWebPage *HelpPage::createWindow(QWebPage::WebWindowType)
+AbstractHelpViewer::~AbstractHelpViewer()
{
- HelpPage* newPage = static_cast<HelpPage*>(centralWidget->newEmptyTab()->page());
- if (newPage)
- newPage->closeNewTabIfNeeded = closeNewTabIfNeeded;
- closeNewTabIfNeeded = false;
- return newPage;
}
-static bool isLocalUrl(const QUrl &url)
+bool AbstractHelpViewer::isLocalUrl(const QUrl &url)
{
- const QString scheme = url.scheme();
- if (scheme.isEmpty()
+ TRACE_OBJ
+ const QString &scheme = url.scheme();
+ return scheme.isEmpty()
|| scheme == QLatin1String("file")
|| scheme == QLatin1String("qrc")
|| scheme == QLatin1String("data")
|| scheme == QLatin1String("qthelp")
- || scheme == QLatin1String("about"))
- return true;
- return false;
-}
-
-void HelpPage::triggerAction(WebAction action, bool checked)
-{
- switch (action) {
- case OpenLinkInNewWindow:
- closeNewTabIfNeeded = true;
- default: // fall through
- QWebPage::triggerAction(action, checked);
- break;
- }
+ || scheme == QLatin1String("about");
}
-bool HelpPage::acceptNavigationRequest(QWebFrame *,
- const QNetworkRequest &request, QWebPage::NavigationType type)
+bool AbstractHelpViewer::canOpenPage(const QString &url)
{
- const QUrl &url = request.url();
- const bool closeNewTab = closeNewTabIfNeeded;
- closeNewTabIfNeeded = false;
-
- if (isLocalUrl(url)) {
- const QString& path = url.path();
- if (path.endsWith(QLatin1String(".pdf"))) {
- const int lastDash = path.lastIndexOf(QChar('/'));
- QString fileName = QDir::tempPath() + QDir::separator();
- if (lastDash < 0)
- fileName += path;
- else
- fileName += path.mid(lastDash + 1, path.length());
-
- QFile tmpFile(QDir::cleanPath(fileName));
- if (tmpFile.open(QIODevice::ReadWrite)) {
- tmpFile.write(helpEngine->fileData(url));
- tmpFile.close();
- }
- QDesktopServices::openUrl(QUrl(tmpFile.fileName()));
-
- if (closeNewTab)
- QMetaObject::invokeMethod(CentralWidget::instance(), "closeTab");
- return false;
- }
-
- if (type == QWebPage::NavigationTypeLinkClicked
- && (m_keyboardModifiers & Qt::ControlModifier
- || m_pressedButtons == Qt::MidButton)) {
- HelpViewer* viewer = centralWidget->newEmptyTab();
- if (viewer)
- CentralWidget::instance()->setSource(url);
- m_pressedButtons = Qt::NoButton;
- m_keyboardModifiers = Qt::NoModifier;
- return false;
- }
- return true;
- }
-
- QDesktopServices::openUrl(url);
- return false;
-}
-
-HelpViewer::HelpViewer(QHelpEngine *engine, CentralWidget *parent)
- : QWebView(parent)
- , helpEngine(engine)
- , parentWidget(parent)
- , loadFinished(false)
-{
- 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)));
- connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
-}
-
-void HelpViewer::setSource(const QUrl &url)
-{
- loadFinished = false;
- 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));
+ TRACE_OBJ
+ return !mimeFromUrl(url).isEmpty();
}
-void HelpViewer::home()
+QString AbstractHelpViewer::mimeFromUrl(const QUrl &url)
{
- QString homepage = helpEngine->customValue(QLatin1String("homepage"),
- QLatin1String("")).toString();
+ TRACE_OBJ
+ const QString &path = url.path();
+ const int index = path.lastIndexOf(QLatin1Char('.'));
+ const QByteArray &ext = path.mid(index).toUtf8().toLower();
- if (homepage.isEmpty()) {
- homepage = helpEngine->customValue(QLatin1String("defaultHomepage"),
- QLatin1String("help")).toString();
+ const ExtensionMap *e = extensionMap;
+ while (e->extension) {
+ if (ext == e->extension)
+ return QLatin1String(e->mimeType);
+ ++e;
}
-
- 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);
+ return QLatin1String("");
}
-void HelpViewer::mouseReleaseEvent(QMouseEvent *e)
+bool AbstractHelpViewer::launchWithExternalApp(const QUrl &url)
{
- 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());
-}
-
-void HelpViewer::mousePressEvent(QMouseEvent *event)
-{
- HelpPage *currentPage = static_cast<HelpPage*>(page());
- if (currentPage) {
- currentPage->m_pressedButtons = event->buttons();
- currentPage->m_keyboardModifiers = event->modifiers();
- }
- QWebView::mousePressEvent(event);
-}
-
-void HelpViewer::setLoadFinished(bool ok)
-{
- loadFinished = ok;
- emit sourceChanged(url());
-}
-
-#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--;
-}
+ TRACE_OBJ
+ if (isLocalUrl(url)) {
+ const HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ const QUrl &resolvedUrl = helpEngine.findFile(url);
+ if (!resolvedUrl.isValid())
+ return false;
-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")) {
- const QString& path = url.path();
- const int lastDash = path.lastIndexOf(QChar('/'));
- QString fileName = QDir::tempPath() + QDir::separator();
- if (lastDash < 0)
- fileName += path;
- else
- fileName += path.mid(lastDash + 1, path.length());
+ const QString& path = resolvedUrl.path();
+ if (!canOpenPage(path)) {
+ QTemporaryFile tmpTmpFile;
+ if (!tmpTmpFile.open())
+ return false;
- 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);
- }
+ const QString &extension = QFileInfo(path).completeSuffix();
+ QFile actualTmpFile(tmpTmpFile.fileName() % QLatin1String(".")
+ % extension);
+ if (!actualTmpFile.open(QIODevice::ReadWrite | QIODevice::Truncate))
+ return false;
- if (!launched) {
- QMessageBox::information(this, tr("Help"),
- tr("Unable to launch external application.\n"), tr("OK"));
+ actualTmpFile.write(helpEngine.fileData(resolvedUrl));
+ actualTmpFile.close();
+ return QDesktopServices::openUrl(QUrl(actualTmpFile.fileName()));
}
- return true;
+ } else if (url.scheme() == QLatin1String("http")) {
+ return QDesktopServices::openUrl(url);
}
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
index 3618a73..def9418 100644
--- a/tools/assistant/tools/assistant/helpviewer.h
+++ b/tools/assistant/tools/assistant/helpviewer.h
@@ -38,139 +38,46 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#ifndef HELPVIEWER_H
#define HELPVIEWER_H
-#include <QtCore/QUrl>
-#include <QtCore/QVariant>
-#include <QtGui/QTextBrowser>
-#include <QtGui/QAction>
+#include <QtCore/QString>
-#if !defined(QT_NO_WEBKIT)
-#include <QWebView>
-#endif
+#include <QtGui/QFont>
QT_BEGIN_NAMESPACE
-class QHelpEngine;
-class CentralWidget;
-
-class QPoint;
-class QString;
-class QKeyEvent;
class QMouseEvent;
-class QContextMenuEvent;
+class QUrl;
-#if !defined(QT_NO_WEBKIT)
-
-class HelpViewer : public QWebView
+class AbstractHelpViewer
{
- 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
+ AbstractHelpViewer();
+ virtual ~AbstractHelpViewer();
- void resetZoom();
- void zoomIn(qreal range = 1);
- void zoomOut(qreal range = 1);
+ virtual QFont viewerFont() const = 0;
+ virtual void setViewerFont(const QFont &font) = 0;
- inline void copy()
- { return triggerPageAction(QWebPage::Copy); }
+ virtual void scaleUp() = 0;
+ virtual void scaleDown() = 0;
+
+ virtual void resetScale() = 0;
+ virtual qreal scale() const = 0;
- inline bool isForwardAvailable() const
- { return pageAction(QWebPage::Forward)->isEnabled(); }
- inline bool isBackwardAvailable() const
- { return pageAction(QWebPage::Back)->isEnabled(); }
- inline bool hasLoadFinished() const
- { return loadFinished; }
- inline qreal zoom() const
- { return textSizeMultiplier(); }
+ virtual bool handleForwardBackwardMouseButtons(QMouseEvent *e) = 0;
-public Q_SLOTS:
- void home();
- void backward() { back(); }
+ static const QLatin1String DocPath;
+ static const QString AboutBlank;
+ static const QString LocalHelpFile;
+ static const QString PageNotFoundMessage;
-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);
- void mousePressEvent(QMouseEvent *event);
-
-private Q_SLOTS:
- void actionChanged();
- void setLoadFinished(bool ok);
-
-private:
- QHelpEngine *helpEngine;
- CentralWidget* parentWidget;
- bool loadFinished;
+ static bool isLocalUrl(const QUrl &url);
+ static bool canOpenPage(const QString &url);
+ static QString mimeFromUrl(const QUrl &url);
+ static bool launchWithExternalApp(const QUrl &url);
};
-#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
+#endif // HELPVIEWER_H
diff --git a/tools/assistant/tools/assistant/helpviewer_qtb.cpp b/tools/assistant/tools/assistant/helpviewer_qtb.cpp
new file mode 100644
index 0000000..7f82b56
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer_qtb.cpp
@@ -0,0 +1,307 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "helpviewer_qtb.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "tracer.h"
+
+#include <QtCore/QStringBuilder>
+
+#include <QtGui/QContextMenuEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QClipboard>
+#include <QtGui/QApplication>
+
+QT_BEGIN_NAMESPACE
+
+HelpViewer::HelpViewer(CentralWidget *parent, qreal zoom)
+ : QTextBrowser(parent)
+ , zoomCount(zoom)
+ , controlPressed(false)
+ , lastAnchor(QString())
+ , parentWidget(parent)
+ , helpEngine(HelpEngineWrapper::instance())
+ , forceFont(false)
+{
+ TRACE_OBJ
+ installEventFilter(this);
+ document()->setDocumentMargin(8);
+
+ QFont font = viewerFont();
+ font.setPointSize(int(font.pointSize() + zoom));
+ setViewerFont(font);
+}
+
+HelpViewer::~HelpViewer()
+{
+ TRACE_OBJ
+}
+
+QFont HelpViewer::viewerFont() const
+{
+ TRACE_OBJ
+ if (HelpEngineWrapper::instance().usesBrowserFont())
+ return helpEngine.browserFont();
+ return qApp->font();
+}
+
+void HelpViewer::setViewerFont(const QFont &newFont)
+{
+ TRACE_OBJ
+ if (font() != newFont) {
+ forceFont = true;
+ setFont(newFont);
+ forceFont = false;
+ }
+}
+
+void HelpViewer::scaleUp()
+{
+ TRACE_OBJ
+ if (zoomCount < 10) {
+ ++zoomCount;
+ forceFont = true;
+ zoomIn();
+ forceFont = false;
+ }
+}
+
+void HelpViewer::scaleDown()
+{
+ TRACE_OBJ
+ if (zoomCount > -5) {
+ --zoomCount;
+ forceFont = true;
+ zoomOut();
+ forceFont = false;
+ }
+}
+
+void HelpViewer::resetScale()
+{
+ TRACE_OBJ
+ if (zoomCount != 0) {
+ forceFont = true;
+ zoomOut(zoomCount);
+ forceFont = false;
+ }
+ zoomCount = 0;
+}
+
+bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *e)
+{
+ if (e->button() == Qt::XButton1) {
+ QTextBrowser::backward();
+ return true;
+ }
+
+ if (e->button() == Qt::XButton2) {
+ QTextBrowser::forward();
+ return true;
+ }
+ return false;
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ const QString &string = url.toString();
+ if (url.isValid() && string != QLatin1String("help")) {
+ if (launchWithExternalApp(url))
+ return;
+
+ const QUrl &resolvedUrl = helpEngine.findFile(url);
+ if (resolvedUrl.isValid()) {
+ QTextBrowser::setSource(resolvedUrl);
+ return;
+ }
+ }
+
+ if (string != QLatin1String("help")) {
+ QTextBrowser::setSource(url);
+ setHtml(string == QLatin1String("about:blank") ? AboutBlank
+ : PageNotFoundMessage.arg(url.toString()));
+ emit sourceChanged(url);
+ } else {
+ QTextBrowser::setSource(LocalHelpFile);
+ }
+}
+
+QVariant HelpViewer::loadResource(int type, const QUrl &name)
+{
+ TRACE_OBJ
+ 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()
+{
+ TRACE_OBJ
+ if(lastAnchor.isEmpty())
+ return;
+
+ parentWidget->setSourceInNewTab(QUrl(lastAnchor));
+ lastAnchor.clear();
+}
+
+void HelpViewer::openLinkInNewTab(const QString &link)
+{
+ TRACE_OBJ
+ lastAnchor = link;
+ openLinkInNewTab();
+}
+
+bool HelpViewer::hasAnchorAt(const QPoint& pos)
+{
+ TRACE_OBJ
+ 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)
+{
+ TRACE_OBJ
+ 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)
+{
+ TRACE_OBJ
+#ifndef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(e))
+ return;
+#endif
+
+ controlPressed = e->modifiers() & Qt::ControlModifier;
+ if ((controlPressed && hasAnchorAt(e->pos())) ||
+ (e->button() == Qt::MidButton && hasAnchorAt(e->pos()))) {
+ openLinkInNewTab();
+ return;
+ }
+
+ QTextBrowser::mouseReleaseEvent(e);
+}
+
+void HelpViewer::mousePressEvent(QMouseEvent *e)
+{
+#ifdef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(e))
+ return;
+#endif
+ QTextBrowser::mousePressEvent(e);
+}
+
+void HelpViewer::keyPressEvent(QKeyEvent *e)
+{
+ TRACE_OBJ
+ 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()
+{
+ TRACE_OBJ
+ setSource(helpEngine.homePage());
+}
+
+void HelpViewer::wheelEvent(QWheelEvent *e)
+{
+ TRACE_OBJ
+ if (e->modifiers() == Qt::ControlModifier) {
+ e->accept();
+ e->delta() > 0 ? scaleUp() : scaleDown();
+ } else {
+ QTextBrowser::wheelEvent(e);
+ }
+}
+
+bool HelpViewer::eventFilter(QObject *obj, QEvent *event)
+{
+ TRACE_OBJ
+ if (event->type() == QEvent::FontChange && !forceFont)
+ return true;
+ return QTextBrowser::eventFilter(obj, event);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/helpviewer_qtb.h b/tools/assistant/tools/assistant/helpviewer_qtb.h
new file mode 100644
index 0000000..58aacd7
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer_qtb.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef HELPVIEWERQTB_H
+#define HELPVIEWERQTB_H
+
+#include "helpviewer.h"
+
+#include <QtCore/QUrl>
+#include <QtCore/QVariant>
+
+#include <QtGui/QTextBrowser>
+
+QT_BEGIN_NAMESPACE
+
+class CentralWidget;
+class HelpEngineWrapper;
+class QContextMenuEvent;
+class QKeyEvent;
+class QMouseEvent;
+
+class HelpViewer : public QTextBrowser, public AbstractHelpViewer
+{
+ Q_OBJECT
+
+public:
+ explicit HelpViewer(CentralWidget *parent, qreal zoom = 0.0);
+ ~HelpViewer();
+
+ QFont viewerFont() const;
+ void setViewerFont(const QFont &font);
+
+ void scaleUp();
+ void scaleDown();
+ void resetScale();
+ qreal scale() const { return zoomCount; }
+
+ bool handleForwardBackwardMouseButtons(QMouseEvent *e);
+
+ void setSource(const QUrl &url);
+
+ inline bool hasSelection() const
+ { return textCursor().hasSelection(); }
+
+public Q_SLOTS:
+ void home();
+
+protected:
+ void wheelEvent(QWheelEvent *e);
+ bool eventFilter(QObject *obj, QEvent *event);
+
+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);
+ void mousePressEvent(QMouseEvent *e);
+
+private slots:
+ void openLinkInNewTab();
+
+private:
+ int zoomCount;
+ bool controlPressed;
+ QString lastAnchor;
+ CentralWidget* parentWidget;
+ HelpEngineWrapper &helpEngine;
+
+ bool forceFont;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPVIEWERQTB_H
diff --git a/tools/assistant/tools/assistant/helpviewer_qwv.cpp b/tools/assistant/tools/assistant/helpviewer_qwv.cpp
new file mode 100644
index 0000000..221e1b8
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer_qwv.cpp
@@ -0,0 +1,427 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "helpviewer_qwv.h"
+
+#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "tracer.h"
+
+#include <QtCore/QFileInfo>
+#include <QtCore/QString>
+#include <QtCore/QStringBuilder>
+#include <QtCore/QTimer>
+
+#include <QtGui/QWheelEvent>
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkRequest>
+
+QT_BEGIN_NAMESPACE
+
+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())
+{
+ TRACE_OBJ
+ 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()
+{
+ TRACE_OBJ
+}
+
+qint64 HelpNetworkReply::readData(char *buffer, qint64 maxlen)
+{
+ TRACE_OBJ
+ qint64 len = qMin(qint64(data.length()), maxlen);
+ if (len) {
+ memcpy(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(QObject *parent);
+
+protected:
+ virtual QNetworkReply *createRequest(Operation op,
+ const QNetworkRequest &request, QIODevice *outgoingData = 0);
+};
+
+HelpNetworkAccessManager::HelpNetworkAccessManager(QObject *parent)
+ : QNetworkAccessManager(parent)
+{
+ TRACE_OBJ
+}
+
+QNetworkReply *HelpNetworkAccessManager::createRequest(Operation /*op*/,
+ const QNetworkRequest &request, QIODevice* /*outgoingData*/)
+{
+ TRACE_OBJ
+ QString url = request.url().toString();
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+
+ // TODO: For some reason the url to load is already wrong (passed from webkit)
+ // though the css file and the references inside should work that way. One
+ // possible problem might be that the css is loaded at the same level as the
+ // html, thus a path inside the css like (../images/foo.png) might cd out of
+ // the virtual folder
+ if (!helpEngine.findFile(url).isValid()) {
+ if (url.startsWith(AbstractHelpViewer::DocPath)) {
+ QUrl newUrl = request.url();
+ if (!newUrl.path().startsWith(QLatin1String("/qdoc/"))) {
+ newUrl.setPath(QLatin1String("qdoc") + newUrl.path());
+ url = newUrl.toString();
+ }
+ }
+ }
+
+ const QString &mimeType = AbstractHelpViewer::mimeFromUrl(url);
+ const QByteArray &data = helpEngine.findFile(url).isValid()
+ ? helpEngine.fileData(url)
+ : AbstractHelpViewer::PageNotFoundMessage.arg(url).toUtf8();
+ return new HelpNetworkReply(request, data, mimeType.isEmpty()
+ ? QLatin1String("application/octet-stream") : mimeType);
+}
+
+class HelpPage : public QWebPage
+{
+public:
+ HelpPage(CentralWidget *central, QObject *parent);
+
+protected:
+ virtual QWebPage *createWindow(QWebPage::WebWindowType);
+ virtual void triggerAction(WebAction action, bool checked = false);
+
+ virtual bool acceptNavigationRequest(QWebFrame *frame,
+ const QNetworkRequest &request, NavigationType type);
+
+private:
+ CentralWidget *centralWidget;
+ bool closeNewTabIfNeeded;
+
+ friend class HelpViewer;
+ QUrl m_loadingUrl;
+ Qt::MouseButtons m_pressedButtons;
+ Qt::KeyboardModifiers m_keyboardModifiers;
+};
+
+HelpPage::HelpPage(CentralWidget *central, QObject *parent)
+ : QWebPage(parent)
+ , centralWidget(central)
+ , closeNewTabIfNeeded(false)
+ , m_pressedButtons(Qt::NoButton)
+ , m_keyboardModifiers(Qt::NoModifier)
+{
+ TRACE_OBJ
+}
+
+QWebPage *HelpPage::createWindow(QWebPage::WebWindowType)
+{
+ TRACE_OBJ
+ HelpPage* newPage = static_cast<HelpPage*>(centralWidget->newEmptyTab()->page());
+ if (newPage)
+ newPage->closeNewTabIfNeeded = closeNewTabIfNeeded;
+ closeNewTabIfNeeded = false;
+ return newPage;
+}
+
+void HelpPage::triggerAction(WebAction action, bool checked)
+{
+ TRACE_OBJ
+ switch (action) {
+ case OpenLinkInNewWindow:
+ closeNewTabIfNeeded = true;
+ default: // fall through
+ QWebPage::triggerAction(action, checked);
+ break;
+ }
+}
+
+bool HelpPage::acceptNavigationRequest(QWebFrame *,
+ const QNetworkRequest &request, QWebPage::NavigationType type)
+{
+ TRACE_OBJ
+ const bool closeNewTab = closeNewTabIfNeeded;
+ closeNewTabIfNeeded = false;
+
+ const QUrl &url = request.url();
+ if (AbstractHelpViewer::launchWithExternalApp(url)) {
+ if (closeNewTab)
+ QMetaObject::invokeMethod(centralWidget, "closeTab");
+ return false;
+ }
+
+ if (type == QWebPage::NavigationTypeLinkClicked
+ && (m_keyboardModifiers & Qt::ControlModifier
+ || m_pressedButtons == Qt::MidButton)) {
+ if (centralWidget->newEmptyTab())
+ centralWidget->setSource(url);
+ m_pressedButtons = Qt::NoButton;
+ m_keyboardModifiers = Qt::NoModifier;
+ return false;
+ }
+
+ m_loadingUrl = url; // because of async page loading, we will hit some kind
+ // of race condition while using a remote command, like a combination of
+ // SetSource; SyncContent. SetSource would be called and SyncContents shortly
+ // afterwards, but the page might not have finished loading and the old url
+ // would be returned.
+ return true;
+}
+
+// -- HelpViewer
+
+HelpViewer::HelpViewer(CentralWidget *parent, qreal zoom)
+ : QWebView(parent)
+ , parentWidget(parent)
+ , loadFinished(false)
+ , helpEngine(HelpEngineWrapper::instance())
+{
+ TRACE_OBJ
+ setAcceptDrops(false);
+
+ setPage(new HelpPage(parent, this));
+
+ page()->setNetworkAccessManager(new HelpNetworkAccessManager(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)));
+ connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted()));
+ connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
+ connect(page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested()));
+
+ setFont(viewerFont());
+ setTextSizeMultiplier(zoom == 0.0 ? 1.0 : zoom);
+}
+
+HelpViewer::~HelpViewer()
+{
+ TRACE_OBJ
+}
+
+QFont HelpViewer::viewerFont() const
+{
+ TRACE_OBJ
+ if (helpEngine.usesBrowserFont())
+ return helpEngine.browserFont();
+
+ QWebSettings *webSettings = QWebSettings::globalSettings();
+ return QFont(webSettings->fontFamily(QWebSettings::StandardFont),
+ webSettings->fontSize(QWebSettings::DefaultFontSize));
+}
+
+void HelpViewer::setViewerFont(const QFont &font)
+{
+ TRACE_OBJ
+ QWebSettings *webSettings = settings();
+ webSettings->setFontFamily(QWebSettings::StandardFont, font.family());
+ webSettings->setFontSize(QWebSettings::DefaultFontSize, font.pointSize());
+}
+
+void HelpViewer::scaleUp()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(textSizeMultiplier() + 0.1);
+}
+
+void HelpViewer::scaleDown()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(qMax(0.0, textSizeMultiplier() - 0.1));
+}
+
+void HelpViewer::resetScale()
+{
+ TRACE_OBJ
+ setTextSizeMultiplier(1.0);
+}
+
+bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *e)
+{
+ TRACE_OBJ
+ if (e->button() == Qt::XButton1) {
+ triggerPageAction(QWebPage::Back);
+ return true;
+ }
+
+ if (e->button() == Qt::XButton2) {
+ triggerPageAction(QWebPage::Forward);
+ return true;
+ }
+
+ return false;
+}
+
+QUrl HelpViewer::source() const
+{
+ HelpPage *currentPage = static_cast<HelpPage*> (page());
+ if (currentPage && !hasLoadFinished()) {
+ // see HelpPage::acceptNavigationRequest(...)
+ return currentPage->m_loadingUrl;
+ }
+ return url();
+}
+
+void HelpViewer::setSource(const QUrl &url)
+{
+ TRACE_OBJ
+ load(url.toString() == QLatin1String("help") ? LocalHelpFile : url);
+}
+
+void HelpViewer::home()
+{
+ TRACE_OBJ
+ setSource(helpEngine.homePage());
+}
+
+void HelpViewer::wheelEvent(QWheelEvent *e)
+{
+ TRACE_OBJ
+ if (e->modifiers()& Qt::ControlModifier) {
+ e->accept();
+ e->delta() > 0 ? scaleUp() : scaleDown();
+ } else {
+ QWebView::wheelEvent(e);
+ }
+}
+
+void HelpViewer::mouseReleaseEvent(QMouseEvent *e)
+{
+ TRACE_OBJ
+#ifndef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(e))
+ return;
+#endif
+
+ QWebView::mouseReleaseEvent(e);
+}
+
+void HelpViewer::actionChanged()
+{
+ TRACE_OBJ
+ 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());
+}
+
+void HelpViewer::mousePressEvent(QMouseEvent *event)
+{
+ TRACE_OBJ
+#ifdef Q_OS_LINUX
+ if (handleForwardBackwardMouseButtons(event))
+ return;
+#endif
+
+ HelpPage *currentPage = static_cast<HelpPage*>(page());
+ if (currentPage) {
+ currentPage->m_pressedButtons = event->buttons();
+ currentPage->m_keyboardModifiers = event->modifiers();
+ }
+ QWebView::mousePressEvent(event);
+}
+
+void HelpViewer::setLoadStarted()
+{
+ loadFinished = false;
+}
+
+void HelpViewer::setLoadFinished(bool ok)
+{
+ TRACE_OBJ
+ loadFinished = ok;
+ emit sourceChanged(url());
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/helpviewer_qwv.h b/tools/assistant/tools/assistant/helpviewer_qwv.h
new file mode 100644
index 0000000..d4a27a2
--- /dev/null
+++ b/tools/assistant/tools/assistant/helpviewer_qwv.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef HELPVIEWERQWV_H
+#define HELPVIEWERQWV_H
+
+#include "helpviewer.h"
+
+#include <QtGui/QAction>
+#include <QtWebKit/QWebView>
+
+QT_BEGIN_NAMESPACE
+
+class CentralWidget;
+class HelpEngineWrapper;
+class QMouseEvent;
+
+class HelpViewer : public QWebView, public AbstractHelpViewer
+{
+ Q_OBJECT
+
+public:
+ explicit HelpViewer(CentralWidget *parent, qreal zoom = 0.0);
+ ~HelpViewer();
+
+ QFont viewerFont() const;
+ void setViewerFont(const QFont &font);
+
+ void scaleUp();
+ void scaleDown();
+ void resetScale();
+ qreal scale() const { return textSizeMultiplier(); }
+
+ bool handleForwardBackwardMouseButtons(QMouseEvent *e);
+
+ QUrl source() const;
+ void setSource(const QUrl &url);
+
+ inline QString documentTitle() const
+ { return title(); }
+
+ inline bool hasSelection() const
+ { return !selectedText().isEmpty(); } // ### this is suboptimal
+
+ 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(); }
+ inline bool hasLoadFinished() const
+ { return loadFinished; }
+
+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 &);
+ void printRequested();
+
+protected:
+ virtual void wheelEvent(QWheelEvent *);
+ void mouseReleaseEvent(QMouseEvent *e);
+ void mousePressEvent(QMouseEvent *event);
+
+private Q_SLOTS:
+ void actionChanged();
+ void setLoadStarted();
+ void setLoadFinished(bool ok);
+
+private:
+ CentralWidget* parentWidget;
+ bool loadFinished;
+ HelpEngineWrapper &helpEngine;
+};
+
+QT_END_NAMESPACE
+
+#endif // HELPVIEWERQWV_H
diff --git a/tools/assistant/tools/assistant/images/bookmark.png b/tools/assistant/tools/assistant/images/bookmark.png
new file mode 100644
index 0000000..57e57e3
--- /dev/null
+++ b/tools/assistant/tools/assistant/images/bookmark.png
Binary files differ
diff --git a/tools/assistant/tools/assistant/indexwindow.cpp b/tools/assistant/tools/assistant/indexwindow.cpp
index 24a212e..63ddbe4 100644
--- a/tools/assistant/tools/assistant/indexwindow.cpp
+++ b/tools/assistant/tools/assistant/indexwindow.cpp
@@ -38,9 +38,12 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "indexwindow.h"
#include "centralwidget.h"
+#include "helpenginewrapper.h"
+#include "helpviewer.h"
#include "topicchooser.h"
#include <QtGui/QLayout>
@@ -51,22 +54,20 @@
#include <QtGui/QContextMenuEvent>
#include <QtGui/QListWidgetItem>
-#include <QtHelp/QHelpEngine>
#include <QtHelp/QHelpIndexWidget>
QT_BEGIN_NAMESPACE
-IndexWindow::IndexWindow(QHelpEngine *helpEngine, QWidget *parent)
+IndexWindow::IndexWindow(QWidget *parent)
: QWidget(parent)
- , m_searchLineEdit(0)
- , m_indexWidget(0)
- , m_helpEngine(helpEngine)
+ , m_searchLineEdit(new QLineEdit)
+ , m_indexWidget(HelpEngineWrapper::instance().indexWidget())
{
+ TRACE_OBJ
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)));
@@ -74,11 +75,11 @@ IndexWindow::IndexWindow(QHelpEngine *helpEngine, QWidget *parent)
layout->setMargin(4);
layout->addWidget(m_searchLineEdit);
- m_indexWidget = m_helpEngine->indexWidget();
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
m_indexWidget->installEventFilter(this);
- connect(m_helpEngine->indexModel(), SIGNAL(indexCreationStarted()), this,
+ connect(helpEngine.indexModel(), SIGNAL(indexCreationStarted()), this,
SLOT(disableSearchLineEdit()));
- connect(m_helpEngine->indexModel(), SIGNAL(indexCreated()), this,
+ connect(helpEngine.indexModel(), SIGNAL(indexCreated()), this,
SLOT(enableSearchLineEdit()));
connect(m_indexWidget, SIGNAL(linkActivated(QUrl,QString)), this,
SIGNAL(linkActivated(QUrl)));
@@ -93,10 +94,12 @@ IndexWindow::IndexWindow(QHelpEngine *helpEngine, QWidget *parent)
IndexWindow::~IndexWindow()
{
+ TRACE_OBJ
}
void IndexWindow::filterIndices(const QString &filter)
{
+ TRACE_OBJ
if (filter.contains(QLatin1Char('*')))
m_indexWidget->filterIndices(filter, filter);
else
@@ -105,6 +108,7 @@ void IndexWindow::filterIndices(const QString &filter)
bool IndexWindow::eventFilter(QObject *obj, QEvent *e)
{
+ TRACE_OBJ
if (obj == m_searchLineEdit && e->type() == QEvent::KeyPress) {
QKeyEvent *ke = static_cast<QKeyEvent*>(e);
QModelIndex idx = m_indexWidget->currentIndex();
@@ -170,22 +174,26 @@ bool IndexWindow::eventFilter(QObject *obj, QEvent *e)
void IndexWindow::enableSearchLineEdit()
{
+ TRACE_OBJ
m_searchLineEdit->setDisabled(false);
filterIndices(m_searchLineEdit->text());
}
void IndexWindow::disableSearchLineEdit()
{
+ TRACE_OBJ
m_searchLineEdit->setDisabled(true);
}
void IndexWindow::setSearchLineEditText(const QString &text)
{
+ TRACE_OBJ
m_searchLineEdit->setText(text);
}
void IndexWindow::focusInEvent(QFocusEvent *e)
{
+ TRACE_OBJ
if (e->reason() != Qt::MouseFocusReason) {
m_searchLineEdit->selectAll();
m_searchLineEdit->setFocus();
@@ -194,6 +202,7 @@ void IndexWindow::focusInEvent(QFocusEvent *e)
void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index)
{
+ TRACE_OBJ
QHelpIndexModel *model = qobject_cast<QHelpIndexModel*>(indexWidget->model());
if (model) {
QString keyword = model->data(index, Qt::DisplayRole).toString();
@@ -210,7 +219,7 @@ void IndexWindow::open(QHelpIndexWidget* indexWidget, const QModelIndex &index)
return;
}
- if (url.path().endsWith(QLatin1String(".pdf"), Qt::CaseInsensitive))
+ if (!AbstractHelpViewer::canOpenPage(url.path()))
CentralWidget::instance()->setSource(url);
else
CentralWidget::instance()->setSourceInNewTab(url);
diff --git a/tools/assistant/tools/assistant/indexwindow.h b/tools/assistant/tools/assistant/indexwindow.h
index 4343d0e..eb587b1 100644
--- a/tools/assistant/tools/assistant/indexwindow.h
+++ b/tools/assistant/tools/assistant/indexwindow.h
@@ -49,7 +49,6 @@
QT_BEGIN_NAMESPACE
class QHelpIndexWidget;
-class QHelpEngine;
class QModelIndex;
class IndexWindow : public QWidget
@@ -57,7 +56,7 @@ class IndexWindow : public QWidget
Q_OBJECT
public:
- IndexWindow(QHelpEngine *helpEngine, QWidget *parent = 0);
+ IndexWindow(QWidget *parent = 0);
~IndexWindow();
void setSearchLineEditText(const QString &text);
@@ -84,7 +83,6 @@ private:
QLineEdit *m_searchLineEdit;
QHelpIndexWidget *m_indexWidget;
- QHelpEngine *m_helpEngine;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/installdialog.cpp b/tools/assistant/tools/assistant/installdialog.cpp
index 95a1226..f3bf6f6 100644
--- a/tools/assistant/tools/assistant/installdialog.cpp
+++ b/tools/assistant/tools/assistant/installdialog.cpp
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "installdialog.h"
@@ -66,6 +67,7 @@ InstallDialog::InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent,
const QString &host, int port)
: QDialog(parent), m_helpEngine(helpEngine), m_host(host), m_port(port)
{
+ TRACE_OBJ
m_ui.setupUi(this);
m_ui.installButton->setEnabled(false);
@@ -94,15 +96,18 @@ InstallDialog::InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent,
InstallDialog::~InstallDialog()
{
+ TRACE_OBJ
}
QStringList InstallDialog::installedDocumentations() const
{
+ TRACE_OBJ
return m_installedDocumentations;
}
void InstallDialog::init()
{
+ TRACE_OBJ
m_ui.statusLabel->setText(tr("Downloading documentation info..."));
m_ui.progressBar->show();
@@ -122,6 +127,7 @@ void InstallDialog::init()
void InstallDialog::updateInstallButton()
{
+ TRACE_OBJ
QListWidgetItem *item = 0;
for (int i=0; i<m_ui.listWidget->count(); ++i) {
item = m_ui.listWidget->item(i);
@@ -136,6 +142,7 @@ void InstallDialog::updateInstallButton()
void InstallDialog::updateDocItemList()
{
+ TRACE_OBJ
QStringList registeredDocs = m_helpEngine->registeredDocumentations();
QListWidgetItem *item = 0;
for (int i=0; i<m_ui.listWidget->count(); ++i) {
@@ -151,6 +158,7 @@ void InstallDialog::updateDocItemList()
void InstallDialog::cancelDownload()
{
+ TRACE_OBJ
m_ui.statusLabel->setText(tr("Download canceled."));
m_httpAborted = true;
m_itemsToInstall.clear();
@@ -162,6 +170,7 @@ void InstallDialog::cancelDownload()
void InstallDialog::install()
{
+ TRACE_OBJ
QListWidgetItem *item = 0;
for (int i=0; i<m_ui.listWidget->count(); ++i) {
item = m_ui.listWidget->item(i);
@@ -174,6 +183,7 @@ void InstallDialog::install()
void InstallDialog::downloadNextFile()
{
+ TRACE_OBJ
if (!m_itemsToInstall.count()) {
m_ui.cancelButton->setEnabled(false);
m_ui.closeButton->setEnabled(true);
@@ -226,6 +236,7 @@ void InstallDialog::downloadNextFile()
void InstallDialog::httpRequestFinished(int requestId, bool error)
{
+ TRACE_OBJ
if (requestId == m_docInfoId && m_buffer) {
m_ui.progressBar->hide();
if (error) {
@@ -296,6 +307,7 @@ void InstallDialog::httpRequestFinished(int requestId, bool error)
void InstallDialog::installFile(const QString &fileName)
{
+ TRACE_OBJ
if (m_helpEngine->registerDocumentation(fileName)) {
m_installedDocumentations
.append(QHelpEngineCore::namespaceName(fileName));
@@ -308,6 +320,7 @@ void InstallDialog::installFile(const QString &fileName)
void InstallDialog::readResponseHeader(const QHttpResponseHeader &responseHeader)
{
+ TRACE_OBJ
if (responseHeader.statusCode() != 200) {
QMessageBox::information(this, m_windowTitle,
tr("Download failed: %1.")
@@ -321,6 +334,7 @@ void InstallDialog::readResponseHeader(const QHttpResponseHeader &responseHeader
void InstallDialog::updateDataReadProgress(int bytesRead, int totalBytes)
{
+ TRACE_OBJ
if (m_httpAborted)
return;
@@ -330,6 +344,7 @@ void InstallDialog::updateDataReadProgress(int bytesRead, int totalBytes)
void InstallDialog::browseDirectories()
{
+ TRACE_OBJ
QString dir = QFileDialog::getExistingDirectory(this, m_windowTitle,
m_ui.pathLineEdit->text());
if (!dir.isEmpty())
diff --git a/tools/assistant/tools/assistant/installdialog.h b/tools/assistant/tools/assistant/installdialog.h
index 2f19519..afafc63 100644
--- a/tools/assistant/tools/assistant/installdialog.h
+++ b/tools/assistant/tools/assistant/installdialog.h
@@ -61,7 +61,7 @@ class InstallDialog : public QDialog
Q_OBJECT
public:
- InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0,
+ explicit InstallDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0,
const QString &host = QString(), int port = -1);
~InstallDialog();
diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp
index 7a957e2..e3eef34 100644
--- a/tools/assistant/tools/assistant/main.cpp
+++ b/tools/assistant/tools/assistant/main.cpp
@@ -38,27 +38,34 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
+#include <QtCore/QLibraryInfo>
#include <QtCore/QLocale>
+#include <QtCore/QScopedPointer>
+#include <QtCore/QStringList>
#include <QtCore/QTranslator>
-#include <QtCore/QLibraryInfo>
#include <QtCore/QUrl>
-#include <QtCore/QStringList>
#include <QtGui/QApplication>
#include <QtGui/QDesktopServices>
-#include <QtHelp/QHelpEngineCore>
+#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpSearchEngine>
#include <QtNetwork/QLocalSocket>
#include <QtSql/QSqlDatabase>
+#include "../shared/collectionconfiguration.h"
+#include "helpenginewrapper.h"
#include "mainwindow.h"
#include "cmdlineparser.h"
+// #define TRACING_REQUESTED
+
QT_USE_NAMESPACE
#if defined(USE_STATIC_SQLITE_PLUGIN)
@@ -66,118 +73,57 @@ QT_USE_NAMESPACE
Q_IMPORT_PLUGIN(qsqlite)
#endif
+namespace {
+
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);
-
+ TRACE_OBJ
+ int lastPage = CollectionConfiguration::lastTabPage(helpEngine);
+ QStringList currentPages = CollectionConfiguration::lastShownPages(helpEngine);
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"));
- }
+ QStringList zoomList = CollectionConfiguration::lastZoomFactors(helpEngine);
+ while (zoomList.count() < currentPages.count())
+ zoomList.append(CollectionConfiguration::DefaultZoomFactor);
for (int i = currentPages.count(); --i >= 0;) {
if (QUrl(currentPages.at(i)).host() == nsName) {
- zoomList.remove(i);
+ zoomList.removeAt(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));
+ CollectionConfiguration::setLastShownPages(helpEngine, currentPages);
+ CollectionConfiguration::setLastTabPage(helpEngine, lastPage);
+ CollectionConfiguration::setLastZoomFactors(helpEngine, zoomList);
}
}
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)
+ TRACE_OBJ
+ if (!CollectionConfiguration::isNewer(caller, user))
return false;
-
- user.setCustomValue(QLatin1String("CreationTime"),
- callerCollectionCreationTime);
- user.setCustomValue(QLatin1String("WindowTitle"),
- caller.customValue(QLatin1String("WindowTitle")));
- user.setCustomValue(QLatin1String("LastShownPages"),
- caller.customValue(QLatin1String("LastShownPages")));
-#if !defined(QT_NO_WEBKIT)
- const QLatin1String zoomKey("LastPagesZoomWebView");
-#else
- const QLatin1String zoomKey("LastPagesZoomTextBrowser");
-#endif
- user.setCustomValue(zoomKey, caller.customValue(zoomKey));
- 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")));
- user.setCustomValue(QLatin1String("defaultHomepage"),
- caller.customValue(QLatin1String("defaultHomepage")));
-
+ CollectionConfiguration::copyConfiguration(caller, user);
return true;
}
-bool
-referencedHelpFilesExistAll(QHelpEngineCore& user, QStringList& nameSpaces)
+void stripNonexistingDocs(QHelpEngineCore& collection)
{
- 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);
- }
+ TRACE_OBJ
+ const QStringList &namespaces = collection.registeredDocumentations();
+ foreach (const QString &ns, namespaces) {
+ QFileInfo fi(collection.documentationFileName(ns));
+ if (!fi.exists() || !fi.isFile())
+ collection.unregisterDocumentation(ns);
}
- return (counter != nameSpaces.count()) ? false : true;
}
QString indexFilesFolder(const QString &collectionFile)
{
+ TRACE_OBJ
QString indexFilesFolder = QLatin1String(".fulltextsearch");
if (!collectionFile.isEmpty()) {
QFileInfo fi(collectionFile);
@@ -187,192 +133,307 @@ QString indexFilesFolder(const QString &collectionFile)
return indexFilesFolder;
}
-int main(int argc, char *argv[])
+/*
+ * Returns the expected absolute file path of the cached collection file
+ * correspondinging to the given collection's file.
+ * It may or may not exist yet.
+ */
+QString constructCachedCollectionFilePath(const QHelpEngineCore &collection)
+{
+ TRACE_OBJ
+ const QString &filePath = collection.collectionFile();
+ const QString &fileName = QFileInfo(filePath).fileName();
+ const QString &cacheDir = CollectionConfiguration::cacheDir(collection);
+ const QString &dir = !cacheDir.isEmpty()
+ && CollectionConfiguration::cacheDirIsRelativeToCollection(collection)
+ ? QFileInfo(filePath).dir().absolutePath()
+ + QDir::separator() + cacheDir
+ : MainWindow::collectionFileDirectory(false, cacheDir);
+ return dir + QDir::separator() + fileName;
+}
+
+bool synchronizeDocs(QHelpEngineCore &collection,
+ QHelpEngineCore &cachedCollection,
+ CmdLineParser &cmd)
{
-#ifndef Q_OS_WIN
- // First do a quick search for arguments that imply command-line mode.
+ TRACE_OBJ
+ const QDateTime &lastCollectionRegisterTime =
+ CollectionConfiguration::lastRegisterTime(collection);
+ if (!lastCollectionRegisterTime.isValid() || lastCollectionRegisterTime
+ < CollectionConfiguration::lastRegisterTime(cachedCollection))
+ return true;
+
+ const QStringList &docs = collection.registeredDocumentations();
+ const QStringList &cachedDocs = cachedCollection.registeredDocumentations();
+
+ /*
+ * Ensure that the cached collection contains all docs that
+ * the collection contains.
+ */
+ foreach (const QString &doc, docs) {
+ if (!cachedDocs.contains(doc)) {
+ const QString &docFile = collection.documentationFileName(doc);
+ if (!cachedCollection.registerDocumentation(docFile)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error registering documentation file '%1': %2").
+ arg(docFile).arg(cachedCollection.error()), true);
+ return false;
+ }
+ }
+ }
+
+ CollectionConfiguration::updateLastRegisterTime(cachedCollection);
+
+ return true;
+}
+
+bool removeSearchIndex(const QString &collectionFile)
+{
+ TRACE_OBJ
+ QString path = QFileInfo(collectionFile).path();
+ path += QLatin1Char('/') + indexFilesFolder(collectionFile);
+
+ QLocalSocket localSocket;
+ localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
+ .arg(QLatin1String(QT_VERSION_STR)));
+
+ QDir dir(path); // check if there is no other instance ruinning
+ if (!dir.exists() || localSocket.waitForConnected())
+ return false;
+
+ QStringList lst = dir.entryList(QDir::Files | QDir::Hidden);
+ foreach (const QString &item, lst)
+ dir.remove(item);
+ return true;
+}
+
+bool rebuildSearchIndex(QCoreApplication &app, const QString &collectionFile,
+ CmdLineParser &cmd)
+{
+ TRACE_OBJ
+ QHelpEngine engine(collectionFile);
+ if (!engine.setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant", "Error: %1")
+ .arg(engine.error()), true);
+ return false;
+ }
+
+ QHelpSearchEngine * const searchEngine = engine.searchEngine();
+ QObject::connect(searchEngine, SIGNAL(indexingFinished()), &app,
+ SLOT(quit()));
+ searchEngine->reindexDocumentation();
+ return app.exec() == 0;
+}
+
+bool useGui(int argc, char *argv[])
+{
+ TRACE_OBJ
+ bool gui = true;
+#ifndef Q_OS_WIN
+ // Look for arguments that imply command-line mode.
const char * cmdModeArgs[] = {
- "-help", "-register", "-unregister", "-remove-search-index"
+ "-help", "-register", "-unregister", "-remove-search-index",
+ "-rebuild-search-index"
};
- bool useGui = true;
for (int i = 1; i < argc; ++i) {
for (size_t j = 0; j < sizeof cmdModeArgs/sizeof *cmdModeArgs; ++j) {
if(strcmp(argv[i], cmdModeArgs[j]) == 0) {
- useGui = false;
+ gui = false;
break;
}
}
}
- QApplication a(argc, argv, useGui);
#else
- QApplication a(argc, argv);
+ Q_UNUSED(argc)
+ Q_UNUSED(argv)
#endif
+ return gui;
+}
+
+bool registerDocumentation(QHelpEngineCore &collection, CmdLineParser &cmd,
+ bool printSuccess)
+{
+ TRACE_OBJ
+ if (!collection.registerDocumentation(cmd.helpFile())) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Could not register documentation file\n%1\n\nReason:\n%2")
+ .arg(cmd.helpFile()).arg(collection.error()), true);
+ return false;
+ }
+ if (printSuccess)
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Documentation successfully registered."),
+ false);
+ CollectionConfiguration::updateLastRegisterTime(collection);
+ return true;
+}
+
+bool unregisterDocumentation(QHelpEngineCore &collection,
+ const QString &namespaceName, CmdLineParser &cmd, bool printSuccess)
+{
+ TRACE_OBJ
+ if (!collection.unregisterDocumentation(namespaceName)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Could not unregister documentation"
+ " file\n%1\n\nReason:\n%2").
+ arg(cmd.helpFile()).arg(collection.error()), true);
+ return false;
+ }
+ updateLastPagesOnUnregister(collection, namespaceName);
+ if (printSuccess)
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Documentation successfully unregistered."),
+ false);
+ return true;
+}
+
+void setupTranslation(const QString &fileName, const QString &dir)
+{
+ QTranslator *translator = new QTranslator(QCoreApplication::instance());
+ if (translator->load(fileName, dir)) {
+ QCoreApplication::installTranslator(translator);
+ } else if (!fileName.endsWith(QLatin1String("en_US"))) {
+ qWarning("Could not load translation file %s in directory %s.",
+ qPrintable(fileName), qPrintable(dir));
+ }
+}
+
+void setupTranslations()
+{
+ TRACE_OBJ
+ const QString& locale = QLocale::system().name();
+ const QString &resourceDir
+ = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ setupTranslation(QLatin1String("assistant_") + locale, resourceDir);
+ setupTranslation(QLatin1String("qt_") + locale, resourceDir);
+ setupTranslation(QLatin1String("qt_help_") + locale, resourceDir);
+}
+
+} // Anonymous namespace.
+
+int main(int argc, char *argv[])
+{
+ TRACE_OBJ
+ QApplication a(argc, argv, useGui(argc, argv));
a.addLibraryPath(a.applicationDirPath() + QLatin1String("/plugins"));
+ setupTranslations();
- CmdLineParser cmd;
- CmdLineParser::Result res = cmd.parse(a.arguments());
+ // Parse arguments.
+ CmdLineParser cmd(a.arguments());
+ CmdLineParser::Result res = cmd.parse();
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;
- }
+ /*
+ * Create the collection objects that we need. We always have the
+ * cached collection file. Depending on whether the user specified
+ * one, we also may have an input collection file.
+ */
+ const QString collectionFile = cmd.collectionFile();
+ const bool collectionFileGiven = !collectionFile.isEmpty();
+ QScopedPointer<QHelpEngineCore> collection;
+ if (collectionFileGiven) {
+ collection.reset(new QHelpEngineCore(collectionFile));
+ if (!collection->setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.").
+ arg(collectionFile).arg(collection->error()), true);
+ return EXIT_FAILURE;
}
- help.setCustomValue(QLatin1String("DocUpdate"), true);
- return 0;
}
-
- if (cmd.removeSearchIndex()) {
- QString file = cmdCollectionFile;
- if (file.isEmpty())
- file = MainWindow::defaultHelpCollectionFileName();
- QString path = QFileInfo(file).path();
- path += QLatin1Char('/') + indexFilesFolder(file);
-
- QLocalSocket localSocket;
- localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
- .arg(QLatin1String(QT_VERSION_STR)));
-
- QDir dir(path); // check if there is no other instance ruinning
- if (!localSocket.waitForConnected() && dir.exists()) {
- QStringList lst = dir.entryList(QDir::Files | QDir::Hidden);
- foreach (const QString &item, lst)
- dir.remove(item);
- return 0;
- } else {
- return -1;
- }
+ const QString &cachedCollectionFile = collectionFileGiven
+ ? constructCachedCollectionFilePath(*collection)
+ : MainWindow::defaultHelpCollectionFileName();
+ if (collectionFileGiven && !QFileInfo(cachedCollectionFile).exists()
+ && !collection->copyCollectionFile(cachedCollectionFile)) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error creating collection file '%1': %2.").
+ arg(cachedCollectionFile).arg(collection->error()), true);
+ return EXIT_FAILURE;
}
-
- {
- 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;
- }
+ QHelpEngineCore cachedCollection(cachedCollectionFile);
+ if (!cachedCollection.setupData()) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Error reading collection file '%1': %2.").
+ arg(cachedCollectionFile).
+ arg(cachedCollection.error()), true);
+ return EXIT_FAILURE;
}
- if (!cmdCollectionFile.isEmpty()) {
- QHelpEngineCore caller(cmdCollectionFile);
- if (!caller.setupData()) {
- cmd.showMessage(QObject::tr("The specified collection file could "
- "not be read!"), true);
- return -1;
- }
+ stripNonexistingDocs(cachedCollection);
+ if (collectionFileGiven) {
+ if (CollectionConfiguration::isNewer(*collection, cachedCollection))
+ CollectionConfiguration::copyConfiguration(*collection,
+ cachedCollection);
+ if (!synchronizeDocs(*collection, cachedCollection, cmd))
+ return EXIT_FAILURE;
+ }
- 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 (cmd.registerRequest() != CmdLineParser::None) {
+ const QStringList &cachedDocs =
+ cachedCollection.registeredDocumentations();
+ const QString &namespaceName =
+ QHelpEngineCore::namespaceName(cmd.helpFile());
+ if (cmd.registerRequest() == CmdLineParser::Register) {
+ if (collectionFileGiven
+ && !registerDocumentation(*collection, cmd, true))
+ return EXIT_FAILURE;
+ if (!cachedDocs.contains(namespaceName)
+ && !registerDocumentation(cachedCollection, cmd, !collectionFileGiven))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
-
- 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);
- }
- }
+ if (cmd.registerRequest() == CmdLineParser::Unregister) {
+ if (collectionFileGiven
+ && !unregisterDocumentation(*collection, namespaceName, cmd, true))
+ return EXIT_FAILURE;
+ if (cachedDocs.contains(namespaceName)
+ && !unregisterDocumentation(cachedCollection, namespaceName,
+ cmd, !collectionFileGiven))
+ return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
- 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());
+ if (cmd.removeSearchIndex()) {
+ return removeSearchIndex(cachedCollectionFile)
+ ? EXIT_SUCCESS : EXIT_FAILURE;
}
- const QString& locale = QLocale::system().name();
- QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (cmd.rebuildSearchIndex()) {
+ return rebuildSearchIndex(a, cachedCollectionFile, cmd)
+ ? EXIT_SUCCESS : EXIT_FAILURE;
+ }
- QTranslator translator(0);
- translator.load(QLatin1String("assistant_") + locale, resourceDir);
- a.installTranslator(&translator);
+ if (!QSqlDatabase::isDriverAvailable(QLatin1String("QSQLITE"))) {
+ cmd.showMessage(QCoreApplication::translate("Assistant",
+ "Cannot load sqlite database driver!"),
+ true);
+ return EXIT_FAILURE;
+ }
- QTranslator qtTranslator(0);
- qtTranslator.load(QLatin1String("qt_") + locale, resourceDir);
- a.installTranslator(&qtTranslator);
+ if (!cmd.currentFilter().isEmpty()) {
+ if (collectionFileGiven)
+ collection->setCurrentFilter(cmd.currentFilter());
+ cachedCollection.setCurrentFilter(cmd.currentFilter());
+ }
- QTranslator qtHelpTranslator(0);
- qtHelpTranslator.load(QLatin1String("qt_help_") + locale, resourceDir);
- a.installTranslator(&qtHelpTranslator);
+ if (collectionFileGiven)
+ cmd.setCollectionFile(cachedCollectionFile);
- MainWindow w(&cmd);
- w.show();
+ MainWindow *w = new MainWindow(&cmd);
+ w->show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
- return a.exec();
+
+ /*
+ * We need to be careful here: The main window has to be deleted before
+ * the help engine wrapper, which has to be deleted before the
+ * QApplication.
+ */
+ const int retval = a.exec();
+ delete w;
+ HelpEngineWrapper::removeInstance();
+ return retval;
}
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
index 0dbf813..68343a4 100644
--- a/tools/assistant/tools/assistant/mainwindow.cpp
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -38,24 +38,31 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "mainwindow.h"
+
+#include "bookmarkmanager.h"
#include "centralwidget.h"
-#include "helpviewer.h"
#include "indexwindow.h"
#include "topicchooser.h"
#include "contentwindow.h"
#include "preferencesdialog.h"
-#include "bookmarkmanager.h"
+#include "helpenginewrapper.h"
#include "remotecontrol.h"
#include "cmdlineparser.h"
#include "aboutdialog.h"
#include "searchwidget.h"
#include "qtdocinstaller.h"
+// #define TRACING_REQUESTED
+
#include <QtCore/QDir>
#include <QtCore/QTimer>
+#include <QtCore/QDateTime>
#include <QtCore/QDebug>
+#include <QtCore/QFileSystemWatcher>
+#include <QtCore/QPair>
#include <QtCore/QResource>
#include <QtCore/QByteArray>
#include <QtCore/QTextStream>
@@ -76,8 +83,9 @@
#include <QtGui/QProgressBar>
#include <QtGui/QDesktopServices>
#include <QtGui/QToolButton>
+#include <QtGui/QFileDialog>
-#include <QtHelp/QHelpEngine>
+#include <QtHelp/QHelpEngineCore>
#include <QtHelp/QHelpSearchEngine>
#include <QtHelp/QHelpContentModel>
#include <QtHelp/QHelpIndexModel>
@@ -86,6 +94,7 @@ QT_BEGIN_NAMESPACE
MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
: QMainWindow(parent)
+ , m_bookmarkWidget(0)
, m_filterCombo(0)
, m_toolBarMenu(0)
, m_cmdLine(cmdLine)
@@ -93,37 +102,53 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
, m_qtDocInstaller(0)
, m_connectedInitSignals(false)
{
+ TRACE_OBJ
+
setToolButtonStyle(Qt::ToolButtonFollowStyle);
+ QString collectionFile;
if (usesDefaultCollection()) {
MainWindow::collectionFileDirectory(true);
- m_helpEngine = new QHelpEngine(MainWindow::defaultHelpCollectionFileName(),
- this);
+ collectionFile = MainWindow::defaultHelpCollectionFileName();
} else {
- m_helpEngine = new QHelpEngine(cmdLine->collectionFile(), this);
+ collectionFile = cmdLine->collectionFile();
}
+ HelpEngineWrapper &helpEngineWrapper =
+ HelpEngineWrapper::instance(collectionFile);
- m_centralWidget = new CentralWidget(m_helpEngine, this);
+ m_centralWidget = new CentralWidget(this);
setCentralWidget(m_centralWidget);
- m_indexWindow = new IndexWindow(m_helpEngine);
+ m_indexWindow = new IndexWindow(this);
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);
+ m_contentWindow = new ContentWindow;
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);
+ QDockWidget *bookmarkDock = 0;
+ if (BookmarkManager *manager = BookmarkManager::instance()) {
+ bookmarkDock = new QDockWidget(tr("Bookmarks"), this);
+ bookmarkDock->setObjectName(QLatin1String("BookmarkWindow"));
+ bookmarkDock->setWidget(m_bookmarkWidget = manager->bookmarkDockWidget());
+ addDockWidget(Qt::LeftDockWidgetArea, bookmarkDock);
+
+ connect(manager, SIGNAL(escapePressed()), this,
+ SLOT(activateCurrentCentralWidgetTab()));
+ connect(manager, SIGNAL(setSource(QUrl)), m_centralWidget,
+ SLOT(setSource(QUrl)));
+ connect(manager, SIGNAL(setSourceInNewTab(QUrl)), m_centralWidget,
+ SLOT(setSourceInNewTab(QUrl)));
+ connect(m_centralWidget, SIGNAL(addBookmark(QString, QString)), manager,
+ SLOT(addBookmark(QString, QString)));
+ }
- QHelpSearchEngine *searchEngine = m_helpEngine->searchEngine();
+ QHelpSearchEngine *searchEngine = helpEngineWrapper.searchEngine();
connect(searchEngine, SIGNAL(indexingStarted()), this, SLOT(indexingStarted()));
connect(searchEngine, SIGNAL(indexingFinished()), this, SLOT(indexingFinished()));
@@ -136,22 +161,13 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
setupActions();
statusBar()->show();
- if (initHelpDB()) {
+ if (initHelpDB(!cmdLine->collectionFileGiven())) {
setupFilterToolbar();
setupAddressToolbar();
- m_bookmarkManager->setupBookmarkModels();
- m_bookmarkMenu->addSeparator();
- m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu);
- connect(m_bookmarkMenu, SIGNAL(triggered(QAction*)), this,
- SLOT(showBookmark(QAction*)));
- connect(m_bookmarkManager, SIGNAL(bookmarksChanged()), this,
- SLOT(updateBookmarkMenu()));
-
- setWindowTitle(m_helpEngine->customValue(QLatin1String("WindowTitle"),
- defWindowTitle).toString());
- QByteArray iconArray = m_helpEngine->customValue(QLatin1String("ApplicationIcon"),
- QByteArray()).toByteArray();
+ const QString windowTitle = helpEngineWrapper.windowTitle();
+ setWindowTitle(windowTitle.isEmpty() ? defWindowTitle : windowTitle);
+ QByteArray iconArray = helpEngineWrapper.applicationIcon();
if (iconArray.size() > 0) {
QPixmap pix;
pix.loadFromData(iconArray);
@@ -165,29 +181,28 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
// Show the widget here, otherwise the restore geometry and state won't work
// on x11.
show();
- QByteArray ba(m_helpEngine->customValue(QLatin1String("MainWindow")).toByteArray());
+ QByteArray ba(helpEngineWrapper.mainWindow());
if (!ba.isEmpty())
restoreState(ba);
- ba = m_helpEngine->customValue(QLatin1String("MainWindowGeometry")).toByteArray();
+ ba = helpEngineWrapper.mainWindowGeometry();
if (!ba.isEmpty()) {
restoreGeometry(ba);
} else {
tabifyDockWidget(contentDock, indexDock);
- tabifyDockWidget(indexDock, bookmarkDock);
+ if (bookmarkDock)
+ 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);
+ if (!helpEngineWrapper.hasFontSettings()) {
+ helpEngineWrapper.setUseAppFont(false);
+ helpEngineWrapper.setUseBrowserFont(false);
+ helpEngineWrapper.setAppFont(qApp->font());
+ helpEngineWrapper.setAppWritingSystem(QFontDatabase::Latin);
+ helpEngineWrapper.setBrowserFont(qApp->font());
+ helpEngineWrapper.setBrowserWritingSystem(QFontDatabase::Latin);
} else {
updateApplicationFont();
}
@@ -196,7 +211,7 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
QTimer::singleShot(0, this, SLOT(insertLastPages()));
if (m_cmdLine->enableRemoteControl())
- (void)new RemoteControl(this, m_helpEngine);
+ (void)new RemoteControl(this);
if (m_cmdLine->contents() == CmdLineParser::Show)
showContents();
@@ -209,9 +224,9 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
hideIndex();
if (m_cmdLine->bookmarks() == CmdLineParser::Show)
- showBookmarks();
+ showBookmarksDockWidget();
else if (m_cmdLine->bookmarks() == CmdLineParser::Hide)
- hideBookmarks();
+ hideBookmarksDockWidget();
if (m_cmdLine->search() == CmdLineParser::Show)
showSearch();
@@ -223,51 +238,64 @@ MainWindow::MainWindow(CmdLineParser *cmdLine, QWidget *parent)
else if (m_cmdLine->index() == CmdLineParser::Activate)
showIndex();
else if (m_cmdLine->bookmarks() == CmdLineParser::Activate)
- showBookmarks();
+ showBookmarksDockWidget();
if (!m_cmdLine->currentFilter().isEmpty()) {
const QString &curFilter = m_cmdLine->currentFilter();
- if (m_helpEngine->customFilters().contains(curFilter))
- m_helpEngine->setCurrentFilter(curFilter);
+ if (helpEngineWrapper.customFilters().contains(curFilter))
+ helpEngineWrapper.setCurrentFilter(curFilter);
}
if (usesDefaultCollection())
QTimer::singleShot(0, this, SLOT(lookForNewQtDocumentation()));
else
checkInitState();
+
+ connect(&helpEngineWrapper, SIGNAL(documentationRemoved(QString)),
+ this, SLOT(documentationRemoved(QString)));
+ connect(&helpEngineWrapper, SIGNAL(documentationUpdated(QString)),
+ this, SLOT(documentationUpdated(QString)));
}
setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
}
MainWindow::~MainWindow()
{
+ TRACE_OBJ
if (m_qtDocInstaller)
delete m_qtDocInstaller;
}
bool MainWindow::usesDefaultCollection() const
{
+ TRACE_OBJ
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());
-
+ TRACE_OBJ
+ BookmarkManager::destroy();
+ HelpEngineWrapper::instance().setMainWindow(saveState());
+ HelpEngineWrapper::instance().setMainWindowGeometry(saveGeometry());
QMainWindow::closeEvent(e);
}
-bool MainWindow::initHelpDB()
+bool MainWindow::initHelpDB(bool registerInternalDoc)
{
- if (!m_helpEngine->setupData())
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngineWrapper = HelpEngineWrapper::instance();
+ if (!helpEngineWrapper.setupData())
return false;
+ if (!registerInternalDoc) {
+ if (helpEngineWrapper.defaultHomePage() == QLatin1String("help"))
+ helpEngineWrapper.setDefaultHomePage(QLatin1String("about:blank"));
+ return true;
+ }
bool assistantInternalDocRegistered = false;
QString intern(QLatin1String("com.trolltech.com.assistantinternal-"));
- foreach (const QString &ns, m_helpEngine->registeredDocumentations()) {
+ foreach (const QString &ns, helpEngineWrapper.registeredDocumentations()) {
if (ns.startsWith(intern)) {
intern = ns;
assistantInternalDocRegistered = true;
@@ -275,8 +303,7 @@ bool MainWindow::initHelpDB()
}
}
- const QString &collectionFile = m_helpEngine->collectionFile();
-
+ const QString &collectionFile = helpEngineWrapper.collectionFile();
QFileInfo fi(collectionFile);
QString helpFile;
QTextStream(&helpFile) << fi.absolutePath() << QDir::separator()
@@ -293,109 +320,78 @@ bool MainWindow::initHelpDB()
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);
+ helpEngineWrapper.unregisterDocumentation(intern);
+ helpEngineWrapper.registerDocumentation(helpFile);
needsSetup = true;
}
if (needsSetup)
- m_helpEngine->setupData();
+ helpEngineWrapper.setupData();
return true;
}
void MainWindow::lookForNewQtDocumentation()
{
- m_qtDocInstaller = new QtDocInstaller(m_helpEngine->collectionFile());
- connect(m_qtDocInstaller, SIGNAL(errorMessage(QString)), this,
- SLOT(displayInstallationError(QString)));
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ QStringList docs;
+ docs << QLatin1String("assistant")
+ << QLatin1String("designer")
+ << QLatin1String("linguist")
+ << QLatin1String("qmake")
+ << QLatin1String("qt");
+ QList<QtDocInstaller::DocInfo> qtDocInfos;
+ foreach (const QString &doc, docs)
+ qtDocInfos.append(QtDocInstaller::DocInfo(doc, helpEngine.qtDocInfo(doc)));
+
+ m_qtDocInstaller = new QtDocInstaller(qtDocInfos);
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)
+ SLOT(qtDocumentationInstalled()));
+ connect(m_qtDocInstaller, SIGNAL(qchFileNotFound(QString)), this,
+ SLOT(resetQtDocInfo(QString)));
+ connect(m_qtDocInstaller, SIGNAL(registerDocumentation(QString, QString)),
+ this, SLOT(registerDocumentation(QString, QString)));
+ if (helpEngine.qtDocInfo(QLatin1String("qt")).count() != 2)
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)
+void MainWindow::qtDocumentationInstalled()
{
- if (newDocsInstalled)
- m_helpEngine->setupData();
+ TRACE_OBJ
statusBar()->clearMessage();
checkInitState();
}
void MainWindow::checkInitState()
{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().initialDocSetupDone();
if (!m_cmdLine->enableRemoteControl())
return;
- if (m_helpEngine->contentModel()->isCreatingContents()
- || m_helpEngine->indexModel()->isCreatingIndex()) {
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.contentModel()->isCreatingContents()
+ || helpEngine.indexModel()->isCreatingIndex()) {
if (!m_connectedInitSignals) {
- connect(m_helpEngine->contentModel(), SIGNAL(contentsCreated()),
+ connect(helpEngine.contentModel(), SIGNAL(contentsCreated()),
this, SLOT(checkInitState()));
- connect(m_helpEngine->indexModel(), SIGNAL(indexCreated()), this,
+ connect(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);
+ disconnect(helpEngine.contentModel(), 0, this, 0);
+ disconnect(helpEngine.indexModel(), 0, this, 0);
}
emit initDone();
}
}
-void MainWindow::updateBookmarkMenu()
-{
- if (m_bookmarkManager) {
- m_bookmarkMenu->removeAction(m_bookmarkMenuAction);
-
- m_bookmarkMenu->clear();
-
- m_bookmarkMenu->addAction(m_bookmarkMenuAction);
- m_bookmarkMenu->addSeparator();
-
- m_bookmarkManager->fillBookmarkMenu(m_bookmarkMenu);
- }
-}
-
-void MainWindow::showBookmark(QAction *action)
-{
- if (m_bookmarkManager) {
- const QUrl &url = m_bookmarkManager->urlForAction(action);
- if (url.isValid())
- m_centralWidget->setSource(url);
- }
-}
-
void MainWindow::insertLastPages()
{
+ TRACE_OBJ
if (m_cmdLine->url().isValid())
m_centralWidget->setSource(m_cmdLine->url());
else
@@ -407,6 +403,7 @@ void MainWindow::insertLastPages()
void MainWindow::setupActions()
{
+ TRACE_OBJ
QString resourcePath = QLatin1String(":/trolltech/assistant/images/");
#ifdef Q_OS_MAC
setUnifiedTitleAndToolBarOnMac(true);
@@ -417,6 +414,11 @@ void MainWindow::setupActions()
QMenu *menu = menuBar()->addMenu(tr("&File"));
+ m_newTabAction = menu->addAction(tr("New &Tab"), m_centralWidget, SLOT(newTab()));
+ m_newTabAction->setShortcut(QKeySequence::AddTab);
+
+ menu->addSeparator();
+
m_pageSetupAction = menu->addAction(tr("Page Set&up..."), m_centralWidget,
SLOT(pageSetup()));
m_printPreviewAction = menu->addAction(tr("Print Preview..."), m_centralWidget,
@@ -429,16 +431,18 @@ void MainWindow::setupActions()
menu->addSeparator();
- m_newTabAction = menu->addAction(tr("New &Tab"), m_centralWidget, SLOT(newTab()));
- m_newTabAction->setShortcut(QKeySequence::AddTab);
-
m_closeTabAction = menu->addAction(tr("&Close Tab"), m_centralWidget,
SLOT(closeTab()));
m_closeTabAction->setShortcuts(QKeySequence::Close);
- QAction *tmp = menu->addAction(tr("&Quit"), this, SLOT(close()));
- tmp->setShortcut(QKeySequence::Quit);
+ QAction *tmp = menu->addAction(QIcon::fromTheme("application-exit"),
+ tr("&Quit"), this, SLOT(close()));
tmp->setMenuRole(QAction::QuitRole);
+#ifdef Q_OS_WIN
+ tmp->setShortcut(QKeySequence(tr("CTRL+Q")));
+#else
+ tmp->setShortcut(QKeySequence::Quit);
+#endif
menu = menuBar()->addMenu(tr("&Edit"));
m_copyAction = menu->addAction(tr("&Copy selected Text"), m_centralWidget,
@@ -492,7 +496,7 @@ void MainWindow::setupActions()
QKeySequence(tr("ALT+C")));
m_viewMenu->addAction(tr("Index"), this, SLOT(showIndex()),
QKeySequence(tr("ALT+I")));
- m_viewMenu->addAction(tr("Bookmarks"), this, SLOT(showBookmarks()),
+ m_viewMenu->addAction(tr("Bookmarks"), this, SLOT(showBookmarksDockWidget()),
QKeySequence(tr("ALT+O")));
m_viewMenu->addAction(tr("Search"), this, SLOT(showSearchWidget()),
QKeySequence(tr("ALT+S")));
@@ -528,16 +532,16 @@ void MainWindow::setupActions()
tmp->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Alt+Left"))
<< QKeySequence(Qt::CTRL + Qt::Key_PageUp));
- m_bookmarkMenu = menuBar()->addMenu(tr("&Bookmarks"));
- m_bookmarkMenuAction = m_bookmarkMenu->addAction(tr("Add Bookmark..."),
- this, SLOT(addBookmark()));
- m_bookmarkMenuAction->setShortcut(tr("CTRL+D"));
+ if (BookmarkManager *manager = BookmarkManager::instance())
+ manager->takeBookmarksMenu(menuBar()->addMenu(tr("&Bookmarks")));
menu = menuBar()->addMenu(tr("&Help"));
m_aboutAction = menu->addAction(tr("About..."), this, SLOT(showAboutDialog()));
m_aboutAction->setMenuRole(QAction::AboutRole);
#ifdef Q_WS_X11
+ m_newTabAction->setIcon(QIcon::fromTheme("tab-new", m_newTabAction->icon()));
+ m_closeTabAction->setIcon(QIcon::fromTheme("window-close", m_closeTabAction->icon()));
m_backAction->setIcon(QIcon::fromTheme("go-previous" , m_backAction->icon()));
m_nextAction->setIcon(QIcon::fromTheme("go-next" , m_nextAction->icon()));
m_zoomInAction->setIcon(QIcon::fromTheme("zoom-in" , m_zoomInAction->icon()));
@@ -547,7 +551,10 @@ void MainWindow::setupActions()
m_copyAction->setIcon(QIcon::fromTheme("edit-copy" , m_copyAction->icon()));
m_findAction->setIcon(QIcon::fromTheme("edit-find" , m_findAction->icon()));
m_homeAction->setIcon(QIcon::fromTheme("go-home" , m_homeAction->icon()));
+ m_pageSetupAction->setIcon(QIcon::fromTheme("document-page-setup", m_pageSetupAction->icon()));
+ m_printPreviewAction->setIcon(QIcon::fromTheme("document-print-preview", m_printPreviewAction->icon()));
m_printAction->setIcon(QIcon::fromTheme("document-print" , m_printAction->icon()));
+ m_aboutAction->setIcon(QIcon::fromTheme("help-about", m_aboutAction->icon()));
#endif
QToolBar *navigationBar = addToolBar(tr("Navigation Toolbar"));
@@ -592,14 +599,6 @@ void MainWindow::setupActions()
SLOT(updateNavigationItems()));
connect(m_centralWidget, SIGNAL(highlighted(QString)), statusBar(),
SLOT(showMessage(QString)));
- connect(m_centralWidget, SIGNAL(addNewBookmark(QString,QString)), this,
- SLOT(addNewBookmark(QString,QString)));
-
- // bookmarks
- connect(m_bookmarkWidget, SIGNAL(requestShowLink(QUrl)), m_centralWidget,
- SLOT(setSource(QUrl)));
- connect(m_bookmarkWidget, SIGNAL(escapePressed()), this,
- SLOT(activateCurrentCentralWidgetTab()));
// index window
connect(m_indexWindow, SIGNAL(linkActivated(QUrl)), m_centralWidget,
@@ -624,6 +623,7 @@ void MainWindow::setupActions()
QMenu *MainWindow::toolBarMenu()
{
+ TRACE_OBJ
if (!m_toolBarMenu) {
m_viewMenu->addSeparator();
m_toolBarMenu = m_viewMenu->addMenu(tr("Toolbars"));
@@ -633,8 +633,9 @@ QMenu *MainWindow::toolBarMenu()
void MainWindow::setupFilterToolbar()
{
- if (!m_helpEngine->
- customValue(QLatin1String("EnableFilterFunctionality"), true).toBool())
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (!helpEngine.filterFunctionalityEnabled())
return;
m_filterCombo = new QComboBox(this);
@@ -647,16 +648,15 @@ void MainWindow::setupFilterToolbar()
this));
filterToolBar->addWidget(m_filterCombo);
- const QLatin1String hideFilter("HideFilterFunctionality");
- if (m_helpEngine->customValue(hideFilter, true).toBool())
+ if (!helpEngine.filterToolbarVisible())
filterToolBar->hide();
toolBarMenu()->addAction(filterToolBar->toggleViewAction());
- connect(m_helpEngine, SIGNAL(setupFinished()), this,
- SLOT(setupFilterCombo()));
+ connect(&helpEngine, SIGNAL(setupFinished()), this,
+ SLOT(setupFilterCombo()), Qt::QueuedConnection);
connect(m_filterCombo, SIGNAL(activated(QString)), this,
SLOT(filterDocumentation(QString)));
- connect(m_helpEngine, SIGNAL(currentFilterChanged(QString)), this,
+ connect(&helpEngine, SIGNAL(currentFilterChanged(QString)), this,
SLOT(currentFilterChanged(QString)));
setupFilterCombo();
@@ -664,7 +664,9 @@ void MainWindow::setupFilterToolbar()
void MainWindow::setupAddressToolbar()
{
- if (!m_helpEngine->customValue(QLatin1String("EnableAddressBar"), true).toBool())
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (!helpEngine.addressBarEnabled())
return;
m_addressLineEdit = new QLineEdit(this);
@@ -676,7 +678,7 @@ void MainWindow::setupAddressToolbar()
this));
addressToolBar->addWidget(m_addressLineEdit);
- if (m_helpEngine->customValue(QLatin1String("HideAddressBar"), true).toBool())
+ if (!helpEngine.addressBarVisible())
addressToolBar->hide();
toolBarMenu()->addAction(addressToolBar->toggleViewAction());
@@ -691,57 +693,53 @@ void MainWindow::setupAddressToolbar()
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;
- }
+ TRACE_OBJ
+ QByteArray ba = HelpEngineWrapper::instance().aboutMenuTexts();
+ 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);
}
+ if (!trStr.isEmpty())
+ m_aboutAction->setText(trStr);
}
}
void MainWindow::showNewAddress()
{
+ TRACE_OBJ
showNewAddress(m_centralWidget->currentSource());
}
void MainWindow::showNewAddress(const QUrl &url)
{
+ TRACE_OBJ
m_addressLineEdit->setText(url.toString());
}
-void MainWindow::addBookmark()
-{
- addNewBookmark(m_centralWidget->currentTitle(),
- m_centralWidget->currentSource().toString());
-}
-
void MainWindow::gotoAddress()
{
+ TRACE_OBJ
m_centralWidget->setSource(m_addressLineEdit->text());
}
void MainWindow::updateNavigationItems()
{
+ TRACE_OBJ
bool hasCurrentViewer = m_centralWidget->isHomeAvailable();
m_copyAction->setEnabled(m_centralWidget->hasSelection());
m_homeAction->setEnabled(hasCurrentViewer);
@@ -755,12 +753,14 @@ void MainWindow::updateNavigationItems()
void MainWindow::updateTabCloseAction()
{
+ TRACE_OBJ
m_closeTabAction->setEnabled(m_centralWidget->enableTabCloseAction());
}
void MainWindow::showTopicChooser(const QMap<QString, QUrl> &links,
const QString &keyword)
{
+ TRACE_OBJ
TopicChooser tc(this, keyword, links);
if (tc.exec() == QDialog::Accepted) {
m_centralWidget->setSource(tc.link());
@@ -769,18 +769,18 @@ void MainWindow::showTopicChooser(const QMap<QString, QUrl> &links,
void MainWindow::showPreferences()
{
- PreferencesDialog dia(m_helpEngine, this);
-
+ TRACE_OBJ
+ PreferencesDialog dia(this);
connect(&dia, SIGNAL(updateApplicationFont()), this,
SLOT(updateApplicationFont()));
connect(&dia, SIGNAL(updateBrowserFont()), m_centralWidget,
SLOT(updateBrowserFont()));
-
dia.showDialog();
}
void MainWindow::syncContents()
{
+ TRACE_OBJ
qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
const QUrl url = m_centralWidget->currentSource();
showContents();
@@ -792,40 +792,32 @@ void MainWindow::syncContents()
void MainWindow::copyAvailable(bool yes)
{
+ TRACE_OBJ
m_copyAction->setEnabled(yes);
}
-void MainWindow::addNewBookmark(const QString &title, const QString &url)
-{
- if (url.isEmpty() || url == QLatin1String("about:blank"))
- return;
-
- m_bookmarkManager->showBookmarkDialog(this, title, url);
-}
-
void MainWindow::showAboutDialog()
{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
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;
- }
+ QByteArray ba = helpEngine.aboutTexts();
+ 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;
}
}
}
@@ -834,11 +826,8 @@ void MainWindow::showAboutDialog()
QByteArray iconArray;
if (!contents.isEmpty()) {
- iconArray = m_helpEngine->customValue(QLatin1String("AboutIcon"),
- QByteArray()).toByteArray();
- QByteArray resources =
- m_helpEngine->customValue(QLatin1String("AboutImages"),
- QByteArray()).toByteArray();
+ iconArray = helpEngine.aboutIcon();
+ QByteArray resources = helpEngine.aboutImages();
QPixmap pix;
pix.loadFromData(iconArray);
aboutDia.setText(QString::fromUtf8(contents), resources);
@@ -847,7 +836,7 @@ void MainWindow::showAboutDialog()
aboutDia.setWindowTitle(aboutDia.documentTitle());
} else {
QByteArray resources;
- aboutDia.setText(QString::fromLatin1("<center>"
+ aboutDia.setText(tr("<center>"
"<h3>%1</h3>"
"<p>Version %2</p></center>"
"<p>Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).</p>")
@@ -861,50 +850,109 @@ void MainWindow::showAboutDialog()
aboutDia.exec();
}
+void MainWindow::setContentsVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showContents();
+ else
+ hideContents();
+}
+
void MainWindow::showContents()
{
+ TRACE_OBJ
activateDockWidget(m_contentWindow);
}
+void MainWindow::hideContents()
+{
+ TRACE_OBJ
+ m_contentWindow->parentWidget()->hide();
+}
+
+void MainWindow::setIndexVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showIndex();
+ else
+ hideIndex();
+}
+
void MainWindow::showIndex()
{
+ TRACE_OBJ
activateDockWidget(m_indexWindow);
}
-void MainWindow::showBookmarks()
+void MainWindow::hideIndex()
{
- activateDockWidget(m_bookmarkWidget);
+ TRACE_OBJ
+ m_indexWindow->parentWidget()->hide();
}
-void MainWindow::activateDockWidget(QWidget *w)
+void MainWindow::setBookmarksVisible(bool visible)
{
- w->parentWidget()->show();
- w->parentWidget()->raise();
- w->setFocus();
+ TRACE_OBJ
+ if (visible)
+ showBookmarksDockWidget();
+ else
+ hideBookmarksDockWidget();
}
-void MainWindow::hideContents()
+void MainWindow::showBookmarksDockWidget()
{
- m_contentWindow->parentWidget()->hide();
+ TRACE_OBJ
+ if (m_bookmarkWidget)
+ activateDockWidget(m_bookmarkWidget);
}
-void MainWindow::hideIndex()
+void MainWindow::hideBookmarksDockWidget()
{
- m_indexWindow->parentWidget()->hide();
+ TRACE_OBJ
+ if (m_bookmarkWidget)
+ m_bookmarkWidget->parentWidget()->hide();
+}
+
+void MainWindow::setSearchVisible(bool visible)
+{
+ TRACE_OBJ
+ if (visible)
+ showSearch();
+ else
+ hideSearch();
+}
+
+void MainWindow::showSearch()
+{
+ TRACE_OBJ
+ m_centralWidget->activateSearchWidget();
}
-void MainWindow::hideBookmarks()
+void MainWindow::hideSearch()
{
- m_bookmarkWidget->parentWidget()->hide();
+ TRACE_OBJ
+ m_centralWidget->removeSearchWidget();
+}
+
+void MainWindow::activateDockWidget(QWidget *w)
+{
+ TRACE_OBJ
+ w->parentWidget()->show();
+ w->parentWidget()->raise();
+ w->setFocus();
}
void MainWindow::setIndexString(const QString &str)
{
+ TRACE_OBJ
m_indexWindow->setSearchLineEditText(str);
}
void MainWindow::activateCurrentBrowser()
{
+ TRACE_OBJ
CentralWidget *cw = CentralWidget::instance();
if (cw) {
cw->activateTab(true);
@@ -913,40 +961,38 @@ void MainWindow::activateCurrentBrowser()
void MainWindow::activateCurrentCentralWidgetTab()
{
+ TRACE_OBJ
m_centralWidget->activateTab();
}
-void MainWindow::showSearch()
-{
- m_centralWidget->activateSearchWidget();
-}
-
void MainWindow::showSearchWidget()
{
+ TRACE_OBJ
m_centralWidget->activateSearchWidget(true);
}
-void MainWindow::hideSearch()
-{
- m_centralWidget->removeSearchWidget();
-}
-
void MainWindow::updateApplicationFont()
{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
QFont font = qApp->font();
- if (m_helpEngine->customValue(QLatin1String("useAppFont")).toBool())
- font = qVariantValue<QFont>(m_helpEngine->customValue(QLatin1String("appFont")));
+ if (helpEngine.usesAppFont())
+ font = helpEngine.appFont();
- qApp->setFont(font, "QWidget");
+ const QWidgetList &widgets = qApp->allWidgets();
+ foreach (QWidget* widget, widgets)
+ widget->setFont(font);
}
void MainWindow::setupFilterCombo()
{
+ TRACE_OBJ
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
QString curFilter = m_filterCombo->currentText();
if (curFilter.isEmpty())
- curFilter = m_helpEngine->currentFilter();
+ curFilter = helpEngine.currentFilter();
m_filterCombo->clear();
- m_filterCombo->addItems(m_helpEngine->customFilters());
+ m_filterCombo->addItems(helpEngine.customFilters());
int idx = m_filterCombo->findText(curFilter);
if (idx < 0)
idx = 0;
@@ -955,16 +1001,20 @@ void MainWindow::setupFilterCombo()
void MainWindow::filterDocumentation(const QString &customFilter)
{
- m_helpEngine->setCurrentFilter(customFilter);
+ TRACE_OBJ
+ HelpEngineWrapper::instance().setCurrentFilter(customFilter);
}
void MainWindow::expandTOC(int depth)
{
+ TRACE_OBJ
+ Q_ASSERT(depth >= -1);
m_contentWindow->expandToDepth(depth);
}
void MainWindow::indexingStarted()
{
+ TRACE_OBJ
if (!m_progressWidget) {
m_progressWidget = new QWidget();
QLayout* hlayout = new QHBoxLayout(m_progressWidget);
@@ -990,21 +1040,15 @@ void MainWindow::indexingStarted()
void MainWindow::indexingFinished()
{
+ TRACE_OBJ
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)
{
+ TRACE_OBJ
QString collectionPath =
QDesktopServices::storageLocation(QDesktopServices::DataLocation);
if (collectionPath.isEmpty()) {
@@ -1030,16 +1074,65 @@ QString MainWindow::collectionFileDirectory(bool createDir, const QString &cache
QString MainWindow::defaultHelpCollectionFileName()
{
- return collectionFileDirectory() + QDir::separator() +
+ TRACE_OBJ
+ // forces creation of the default collection file path
+ return collectionFileDirectory(true) + QDir::separator() +
QString(QLatin1String("qthelpcollection_%1.qhc")).
arg(QLatin1String(QT_VERSION_STR));
}
void MainWindow::currentFilterChanged(const QString &filter)
{
+ TRACE_OBJ
const int index = m_filterCombo->findText(filter);
Q_ASSERT(index != -1);
m_filterCombo->setCurrentIndex(index);
}
+void MainWindow::documentationRemoved(const QString &namespaceName)
+{
+ TRACE_OBJ
+ CentralWidget* widget = CentralWidget::instance();
+ widget->closeOrReloadTabs(widget->currentSourceFileList().
+ keys(namespaceName), false);
+}
+
+void MainWindow::documentationUpdated(const QString &namespaceName)
+{
+ TRACE_OBJ
+ CentralWidget* widget = CentralWidget::instance();
+ widget->closeOrReloadTabs(widget->currentSourceFileList().
+ keys(namespaceName), true);
+}
+
+void MainWindow::resetQtDocInfo(const QString &component)
+{
+ TRACE_OBJ
+ HelpEngineWrapper::instance().setQtDocInfo(component,
+ QStringList(QDateTime().toString(Qt::ISODate)));
+}
+
+void MainWindow::registerDocumentation(const QString &component,
+ const QString &absFileName)
+{
+ TRACE_OBJ
+ QString ns = QHelpEngineCore::namespaceName(absFileName);
+ if (ns.isEmpty())
+ return;
+
+ HelpEngineWrapper &helpEngine = HelpEngineWrapper::instance();
+ if (helpEngine.registeredDocumentations().contains(ns))
+ helpEngine.unregisterDocumentation(ns);
+ if (!helpEngine.registerDocumentation(absFileName)) {
+ QMessageBox::warning(this, tr("Qt Assistant"),
+ tr("Could not register file '%1': %2").
+ arg(absFileName).arg(helpEngine.error()));
+ } else {
+ QStringList docInfo;
+ docInfo << QFileInfo(absFileName).lastModified().toString(Qt::ISODate)
+ << absFileName;
+ helpEngine.setQtDocInfo(component, docInfo);
+ }
+}
+
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/mainwindow.h b/tools/assistant/tools/assistant/mainwindow.h
index 8a9b572..26726ee 100644
--- a/tools/assistant/tools/assistant/mainwindow.h
+++ b/tools/assistant/tools/assistant/mainwindow.h
@@ -48,6 +48,7 @@
QT_BEGIN_NAMESPACE
class QAction;
+class QFileSystemWatcher;
class QLineEdit;
class QComboBox;
class QMenu;
@@ -57,8 +58,6 @@ class QHelpEngineCore;
class QHelpEngine;
class CentralWidget;
class ContentWindow;
-class BookmarkManager;
-class BookmarkWidget;
class CmdLineParser;
class QtDocInstaller;
@@ -67,7 +66,7 @@ class MainWindow : public QMainWindow
Q_OBJECT
public:
- MainWindow(CmdLineParser *cmdLine, QWidget *parent = 0);
+ explicit MainWindow(CmdLineParser *cmdLine, QWidget *parent = 0);
~MainWindow();
static void activateCurrentBrowser();
@@ -76,10 +75,6 @@ public:
static QString defaultHelpCollectionFileName();
public:
- void hideContents();
- void hideIndex();
- void hideBookmarks();
- void hideSearch();
void setIndexString(const QString &str);
void expandTOC(int depth);
bool usesDefaultCollection() const;
@@ -88,18 +83,20 @@ signals:
void initDone();
public slots:
- void showContents();
- void showIndex();
- void showBookmarks();
- void showSearch();
+ void setContentsVisible(bool visible);
+ void setIndexVisible(bool visible);
+ void setBookmarksVisible(bool visible);
+ void setSearchVisible(bool visible);
void showSearchWidget();
void syncContents();
void activateCurrentCentralWidgetTab();
void currentFilterChanged(const QString &filter);
private slots:
+ void showContents();
+ void showIndex();
+ void showSearch();
void insertLastPages();
- void addBookmark();
void gotoAddress();
void showPreferences();
void showNewAddress();
@@ -108,7 +105,6 @@ private slots:
void updateNavigationItems();
void updateTabCloseAction();
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);
@@ -116,15 +112,16 @@ private slots:
void lookForNewQtDocumentation();
void indexingStarted();
void indexingFinished();
- void displayInstallationError(const QString &errorMessage);
- void qtDocumentationInstalled(bool newDocsInstalled);
+ void qtDocumentationInstalled();
+ void registerDocumentation(const QString &component,
+ const QString &absFileName);
+ void resetQtDocInfo(const QString &component);
void checkInitState();
-
- void updateBookmarkMenu();
- void showBookmark(QAction *action);
+ void documentationRemoved(const QString &namespaceName);
+ void documentationUpdated(const QString &namespaceName);
private:
- bool initHelpDB();
+ bool initHelpDB(bool registerInternalDoc);
void setupActions();
void closeEvent(QCloseEvent *e);
void activateDockWidget(QWidget *w);
@@ -132,14 +129,21 @@ private:
void setupFilterToolbar();
void setupAddressToolbar();
QMenu *toolBarMenu();
- QWidget *setupBookmarkWidget();
+ void hideContents();
+ void hideIndex();
+ void hideSearch();
- QHelpEngine *m_helpEngine;
+private slots:
+ void showBookmarksDockWidget();
+ void hideBookmarksDockWidget();
+
+private:
+ QWidget *m_bookmarkWidget;
+
+private:
CentralWidget *m_centralWidget;
IndexWindow *m_indexWindow;
ContentWindow *m_contentWindow;
- BookmarkWidget *m_bookmarkWidget;
- BookmarkManager *m_bookmarkManager;
QLineEdit *m_addressLineEdit;
QComboBox *m_filterCombo;
@@ -161,8 +165,6 @@ private:
QMenu *m_viewMenu;
QMenu *m_toolBarMenu;
- QMenu *m_bookmarkMenu;
- QAction *m_bookmarkMenuAction;
CmdLineParser *m_cmdLine;
diff --git a/tools/assistant/tools/assistant/preferencesdialog.cpp b/tools/assistant/tools/assistant/preferencesdialog.cpp
index ca12d8f..0e1d719 100644
--- a/tools/assistant/tools/assistant/preferencesdialog.cpp
+++ b/tools/assistant/tools/assistant/preferencesdialog.cpp
@@ -38,34 +38,36 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "preferencesdialog.h"
+
+#include "centralwidget.h"
#include "filternamedialog.h"
-#include "installdialog.h"
#include "fontpanel.h"
-#include "centralwidget.h"
-#include "aboutdialog.h"
+#include "helpenginewrapper.h"
+#include "installdialog.h"
+#include "tracer.h"
-#include <QtAlgorithms>
+#include <QtCore/QtAlgorithms>
+#include <QtCore/QFileSystemWatcher>
-#include <QtGui/QHeaderView>
+#include <QtGui/QDesktopWidget>
#include <QtGui/QFileDialog>
-#include <QtGui/QMessageBox>
-#include <QtGui/QMenu>
#include <QtGui/QFontDatabase>
-#include <QtGui/QApplication>
-#include <QtGui/QDesktopWidget>
+#include <QtGui/QHeaderView>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
#include <QtHelp/QHelpEngineCore>
QT_BEGIN_NAMESPACE
-PreferencesDialog::PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *parent)
+PreferencesDialog::PreferencesDialog(QWidget *parent)
: QDialog(parent)
- , m_helpEngine(helpEngine)
, m_appFontChanged(false)
, m_browserFontChanged(false)
+ , helpEngine(HelpEngineWrapper::instance())
{
+ TRACE_OBJ
m_ui.setupUi(this);
connect(m_ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()),
@@ -73,11 +75,8 @@ PreferencesDialog::PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *paren
connect(m_ui.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()),
this, SLOT(reject()));
- QLatin1String key("EnableFilterFunctionality");
- m_hideFiltersTab = !m_helpEngine->customValue(key, true).toBool();
-
- key = QLatin1String("EnableDocumentationManager");
- m_hideDocsTab = !m_helpEngine->customValue(key, true).toBool();
+ m_hideFiltersTab = !helpEngine.filterFunctionalityEnabled();
+ m_hideDocsTab = !helpEngine.documentationManagerEnabled();
if (!m_hideFiltersTab) {
m_ui.attributeWidget->header()->hide();
@@ -106,7 +105,7 @@ PreferencesDialog::PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *paren
connect(m_ui.docRemoveButton, SIGNAL(clicked()), this,
SLOT(removeDocumentation()));
- m_docsBackup = m_helpEngine->registeredDocumentations();
+ m_docsBackup = helpEngine.registeredDocumentations();
m_ui.registeredDocsListWidget->addItems(m_docsBackup);
} else {
m_ui.tabWidget->removeTab(m_ui.tabWidget->indexOf(m_ui.docsTab));
@@ -114,67 +113,56 @@ PreferencesDialog::PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *paren
updateFontSettingsPage();
updateOptionsPage();
+
+ if (helpEngine.usesAppFont())
+ setFont(helpEngine.appFont());
}
PreferencesDialog::~PreferencesDialog()
{
- QLatin1String key("");
+ TRACE_OBJ
if (m_appFontChanged) {
- key = QLatin1String("appFont");
- m_helpEngine->setCustomValue(key, m_appFontPanel->selectedFont());
-
- key = QLatin1String("useAppFont");
- m_helpEngine->setCustomValue(key, m_appFontPanel->isChecked());
-
- key = QLatin1String("appWritingSystem");
- m_helpEngine->setCustomValue(key, m_appFontPanel->writingSystem());
+ helpEngine.setAppFont(m_appFontPanel->selectedFont());
+ helpEngine.setUseAppFont(m_appFontPanel->isChecked());
+ helpEngine.setAppWritingSystem(m_appFontPanel->writingSystem());
+ emit updateApplicationFont();
}
if (m_browserFontChanged) {
- key = QLatin1String("browserFont");
- m_helpEngine->setCustomValue(key, m_browserFontPanel->selectedFont());
-
- key = QLatin1String("useBrowserFont");
- m_helpEngine->setCustomValue(key, m_browserFontPanel->isChecked());
-
- key = QLatin1String("browserWritingSystem");
- m_helpEngine->setCustomValue(key, m_browserFontPanel->writingSystem());
- }
-
- if (m_appFontChanged || m_browserFontChanged) {
- emit updateApplicationFont();
+ helpEngine.setBrowserFont(m_browserFontPanel->selectedFont());
+ helpEngine.setUseBrowserFont(m_browserFontPanel->isChecked());
+ helpEngine.setBrowserWritingSystem(m_browserFontPanel->writingSystem());
emit updateBrowserFont();
}
QString homePage = m_ui.homePageLineEdit->text();
if (homePage.isEmpty())
homePage = QLatin1String("help");
- m_helpEngine->setCustomValue(QLatin1String("homepage"), homePage);
+ helpEngine.setHomePage(homePage);
int option = m_ui.helpStartComboBox->currentIndex();
- m_helpEngine->setCustomValue(QLatin1String("StartOption"), option);
+ helpEngine.setStartOption(option);
}
void PreferencesDialog::showDialog()
{
+ TRACE_OBJ
if (exec() != Accepted)
m_appFontChanged = m_browserFontChanged = false;
}
void PreferencesDialog::updateFilterPage()
{
- if (!m_helpEngine)
- return;
-
+ TRACE_OBJ
m_ui.filterWidget->clear();
m_ui.attributeWidget->clear();
- QHelpEngineCore help(m_helpEngine->collectionFile(), 0);
- help.setupData();
m_filterMapBackup.clear();
- const QStringList filters = help.customFilters();
+ const QStringList &filters = helpEngine.customFilters();
foreach (const QString &filter, filters) {
- QStringList atts = help.filterAttributes(filter);
+ if (filter == HelpEngineWrapper::TrUnfiltered)
+ continue;
+ QStringList atts = helpEngine.filterAttributes(filter);
m_filterMapBackup.insert(filter, atts);
if (!m_filterMap.contains(filter))
m_filterMap.insert(filter, atts);
@@ -182,15 +170,16 @@ void PreferencesDialog::updateFilterPage()
m_ui.filterWidget->addItems(m_filterMap.keys());
- foreach (const QString &a, help.filterAttributes())
+ foreach (const QString &a, helpEngine.filterAttributes())
new QTreeWidgetItem(m_ui.attributeWidget, QStringList() << a);
- if (m_filterMap.keys().count())
+ if (!m_filterMap.keys().isEmpty())
m_ui.filterWidget->setCurrentRow(0);
}
void PreferencesDialog::updateAttributes(QListWidgetItem *item)
{
+ TRACE_OBJ
QStringList checkedList;
if (item)
checkedList = m_filterMap.value(item->text());
@@ -206,6 +195,7 @@ void PreferencesDialog::updateAttributes(QListWidgetItem *item)
void PreferencesDialog::updateFilterMap()
{
+ TRACE_OBJ
if (!m_ui.filterWidget->currentItem())
return;
QString filter = m_ui.filterWidget->currentItem()->text();
@@ -224,6 +214,7 @@ void PreferencesDialog::updateFilterMap()
void PreferencesDialog::addFilter()
{
+ TRACE_OBJ
FilterNameDialog dia(this);
if (dia.exec() == QDialog::Rejected)
return;
@@ -241,6 +232,7 @@ void PreferencesDialog::addFilter()
void PreferencesDialog::removeFilter()
{
+ TRACE_OBJ
QListWidgetItem *item =
m_ui.filterWidget ->takeItem(m_ui.filterWidget->currentRow());
if (!item)
@@ -255,6 +247,7 @@ void PreferencesDialog::removeFilter()
void PreferencesDialog::addDocumentationLocal()
{
+ TRACE_OBJ
const QStringList fileNames = QFileDialog::getOpenFileNames(this,
tr("Add Documentation"), QString(), tr("Qt Compressed Help Files (*.qch)"));
if (fileNames.isEmpty())
@@ -275,10 +268,11 @@ void PreferencesDialog::addDocumentationLocal()
continue;
}
- m_helpEngine->registerDocumentation(fileName);
- m_ui.registeredDocsListWidget->addItem(nameSpace);
- m_regDocs.append(nameSpace);
- m_unregDocs.removeAll(nameSpace);
+ if (helpEngine.registerDocumentation(fileName)) {
+ m_ui.registeredDocsListWidget->addItem(nameSpace);
+ m_regDocs.append(nameSpace);
+ m_unregDocs.removeAll(nameSpace);
+ }
}
if (!invalidFiles.isEmpty() || !alreadyRegistered.isEmpty()) {
@@ -307,6 +301,7 @@ void PreferencesDialog::addDocumentationLocal()
void PreferencesDialog::removeDocumentation()
{
+ TRACE_OBJ
bool foundBefore = false;
CentralWidget* widget = CentralWidget::instance();
QMap<int, QString> openedDocList = widget->currentSourceFileList();
@@ -338,6 +333,7 @@ void PreferencesDialog::removeDocumentation()
void PreferencesDialog::applyChanges()
{
+ TRACE_OBJ
bool filtersWereChanged = false;
if (!m_hideFiltersTab) {
if (m_filterMap.count() != m_filterMapBackup.count()) {
@@ -370,34 +366,28 @@ void PreferencesDialog::applyChanges()
if (filtersWereChanged) {
foreach (const QString &filter, m_removedFilters)
- m_helpEngine->removeCustomFilter(filter);
+ helpEngine.removeCustomFilter(filter);
QMapIterator<QString, QStringList> it(m_filterMap);
while (it.hasNext()) {
it.next();
- m_helpEngine->addCustomFilter(it.key(), it.value());
+ 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 (widget->availableHelpViewer()== 0)
- widget->setSource(QUrl(QLatin1String("about:blank")));
-
- if (m_unregDocs.count()) {
- foreach (const QString &doc, m_unregDocs)
- m_helpEngine->unregisterDocumentation(doc);
- }
+ CentralWidget::instance()->closeOrReloadTabs(m_TabsToClose, false);
+
+ foreach (const QString &doc, m_unregDocs)
+ helpEngine.unregisterDocumentation(doc);
- if (filtersWereChanged || m_regDocs.count() || m_unregDocs.count())
- m_helpEngine->setupData();
+ if (filtersWereChanged || !m_regDocs.isEmpty() || !m_unregDocs.isEmpty())
+ helpEngine.setupData();
accept();
}
void PreferencesDialog::updateFontSettingsPage()
{
+ TRACE_OBJ
m_browserFontPanel = new FontPanel(this);
m_browserFontPanel->setCheckable(true);
m_ui.stackedWidget_2->insertWidget(0, m_browserFontPanel);
@@ -411,31 +401,23 @@ void PreferencesDialog::updateFontSettingsPage()
const QString customSettings(tr("Use custom settings"));
m_appFontPanel->setTitle(customSettings);
- QLatin1String key = QLatin1String("appFont");
- QFont font = qVariantValue<QFont>(m_helpEngine->customValue(key));
+ QFont font = helpEngine.appFont();
m_appFontPanel->setSelectedFont(font);
- key = QLatin1String("appWritingSystem");
- QFontDatabase::WritingSystem system = static_cast<QFontDatabase::WritingSystem>
- (m_helpEngine->customValue(key).toInt());
+ QFontDatabase::WritingSystem system = helpEngine.appWritingSystem();
m_appFontPanel->setWritingSystem(system);
- key = QLatin1String("useAppFont");
- m_appFontPanel->setChecked(m_helpEngine->customValue(key).toBool());
+ m_appFontPanel->setChecked(helpEngine.usesAppFont());
m_browserFontPanel->setTitle(customSettings);
- key = QLatin1String("browserFont");
- font = qVariantValue<QFont>(m_helpEngine->customValue(key));
+ font = helpEngine.browserFont();
m_browserFontPanel->setSelectedFont(font);
- key = QLatin1String("browserWritingSystem");
- system = static_cast<QFontDatabase::WritingSystem>
- (m_helpEngine->customValue(key).toInt());
+ system = helpEngine.browserWritingSystem();
m_browserFontPanel->setWritingSystem(system);
- key = QLatin1String("useBrowserFont");
- m_browserFontPanel->setChecked(m_helpEngine->customValue(key).toBool());
+ m_browserFontPanel->setChecked(helpEngine.usesBrowserFont());
connect(m_appFontPanel, SIGNAL(toggled(bool)), this,
SLOT(appFontSettingToggled(bool)));
@@ -457,41 +439,38 @@ void PreferencesDialog::updateFontSettingsPage()
void PreferencesDialog::appFontSettingToggled(bool on)
{
+ TRACE_OBJ
Q_UNUSED(on)
m_appFontChanged = true;
}
void PreferencesDialog::appFontSettingChanged(int index)
{
+ TRACE_OBJ
Q_UNUSED(index)
m_appFontChanged = true;
}
void PreferencesDialog::browserFontSettingToggled(bool on)
{
+ TRACE_OBJ
Q_UNUSED(on)
m_browserFontChanged = true;
}
void PreferencesDialog::browserFontSettingChanged(int index)
{
+ TRACE_OBJ
Q_UNUSED(index)
m_browserFontChanged = true;
}
void PreferencesDialog::updateOptionsPage()
{
- QString homepage = m_helpEngine->customValue(QLatin1String("homepage"),
- QLatin1String("")).toString();
+ TRACE_OBJ
+ m_ui.homePageLineEdit->setText(helpEngine.homePage());
- if (homepage.isEmpty()) {
- homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"),
- QLatin1String("help")).toString();
- }
- m_ui.homePageLineEdit->setText(homepage);
-
- int option = m_helpEngine->customValue(QLatin1String("StartOption"),
- ShowLastPages).toInt();
+ int option = helpEngine.startOption();
m_ui.helpStartComboBox->setCurrentIndex(option);
connect(m_ui.blankPageButton, SIGNAL(clicked()), this, SLOT(setBlankPage()));
@@ -501,11 +480,13 @@ void PreferencesDialog::updateOptionsPage()
void PreferencesDialog::setBlankPage()
{
+ TRACE_OBJ
m_ui.homePageLineEdit->setText(QLatin1String("about:blank"));
}
void PreferencesDialog::setCurrentPage()
{
+ TRACE_OBJ
QString homepage = CentralWidget::instance()->currentSource().toString();
if (homepage.isEmpty())
homepage = QLatin1String("help");
@@ -515,9 +496,8 @@ void PreferencesDialog::setCurrentPage()
void PreferencesDialog::setDefaultPage()
{
- QString homepage = m_helpEngine->customValue(QLatin1String("defaultHomepage"),
- QLatin1String("help")).toString();
- m_ui.homePageLineEdit->setText(homepage);
+ TRACE_OBJ
+ m_ui.homePageLineEdit->setText(helpEngine.defaultHomePage());
}
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/preferencesdialog.h b/tools/assistant/tools/assistant/preferencesdialog.h
index 9ad6b6a..2894494 100644
--- a/tools/assistant/tools/assistant/preferencesdialog.h
+++ b/tools/assistant/tools/assistant/preferencesdialog.h
@@ -48,20 +48,15 @@
QT_BEGIN_NAMESPACE
class FontPanel;
-class QHelpEngineCore;
-
-enum {
- ShowHomePage = 0,
- ShowBlankPage = 1,
- ShowLastPages = 2
-};
+class HelpEngineWrapper;
+class QFileSystemWatcher;
class PreferencesDialog : public QDialog
{
Q_OBJECT
public:
- PreferencesDialog(QHelpEngineCore *helpEngine, QWidget *parent = 0);
+ PreferencesDialog(QWidget *parent = 0);
~PreferencesDialog();
void showDialog();
@@ -93,7 +88,6 @@ private:
void updateOptionsPage();
Ui::PreferencesDialogClass m_ui;
- QHelpEngineCore *m_helpEngine;
bool m_hideFiltersTab;
bool m_hideDocsTab;
QMap<QString, QStringList> m_filterMapBackup;
@@ -107,6 +101,7 @@ private:
FontPanel *m_browserFontPanel;
bool m_appFontChanged;
bool m_browserFontChanged;
+ HelpEngineWrapper &helpEngine;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/qtdocinstaller.cpp b/tools/assistant/tools/assistant/qtdocinstaller.cpp
index 652f630..5a501bf 100644
--- a/tools/assistant/tools/assistant/qtdocinstaller.cpp
+++ b/tools/assistant/tools/assistant/qtdocinstaller.cpp
@@ -38,23 +38,27 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include <QtCore/QDir>
#include <QtCore/QLibraryInfo>
#include <QtCore/QDateTime>
+#include <QtCore/QFileSystemWatcher>
#include <QtHelp/QHelpEngineCore>
+#include "helpenginewrapper.h"
#include "qtdocinstaller.h"
QT_BEGIN_NAMESPACE
-QtDocInstaller::QtDocInstaller(const QString &collectionFile)
+QtDocInstaller::QtDocInstaller(const QList<DocInfo> &docInfos)
+ : m_abort(false), m_docInfos(docInfos)
{
- m_abort = false;
- m_collectionFile = collectionFile;
+ TRACE_OBJ
}
QtDocInstaller::~QtDocInstaller()
{
+ TRACE_OBJ
if (!isRunning())
return;
m_mutex.lock();
@@ -65,86 +69,59 @@ QtDocInstaller::~QtDocInstaller()
void QtDocInstaller::installDocs()
{
+ TRACE_OBJ
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");
+ TRACE_OBJ
+ m_qchDir = QLibraryInfo::location(QLibraryInfo::DocumentationPath)
+ + QDir::separator() + QLatin1String("qch");
+ m_qchFiles = m_qchDir.entryList(QStringList() << QLatin1String("*.qch"));
- foreach (const QString &doc, docs) {
- changes |= installDoc(doc, helpEngine);
+ bool changes = false;
+ foreach (const DocInfo &docInfo, m_docInfos) {
+ changes |= installDoc(docInfo);
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)
+bool QtDocInstaller::installDoc(const DocInfo &docInfo)
{
- 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("|"));
-
+ TRACE_OBJ
+ const QString &component = docInfo.first;
+ const QStringList &info = docInfo.second;
QDateTime dt;
- if (lst.count() && !lst.first().isEmpty())
- dt = QDateTime::fromString(lst.first(), Qt::ISODate);
+ if (!info.isEmpty() && !info.first().isEmpty())
+ dt = QDateTime::fromString(info.first(), Qt::ISODate);
QString qchFile;
- if (lst.count() == 2)
- qchFile = lst.last();
-
- QDir dir(QLibraryInfo::location(QLibraryInfo::DocumentationPath)
- + QDir::separator() + QLatin1String("qch"));
+ if (info.count() == 2)
+ qchFile = info.last();
- const QStringList files = dir.entryList(QStringList() << QLatin1String("*.qch"));
- if (files.isEmpty()) {
- helpEngine->setCustomValue(versionKey, QDateTime().toString(Qt::ISODate)
- + QLatin1String("|"));
+ if (m_qchFiles.isEmpty()) {
+ emit qchFileNotFound(component);
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)
+ foreach (const QString &f, m_qchFiles) {
+ if (f.startsWith(component)) {
+ QFileInfo fi(m_qchDir.absolutePath() + QDir::separator() + f);
+ if (dt.isValid() && fi.lastModified().toTime_t() == dt.toTime_t()
&& 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());
+ emit registerDocumentation(component, fi.absoluteFilePath());
return true;
}
}
+
+ emit qchFileNotFound(component);
return false;
}
diff --git a/tools/assistant/tools/assistant/qtdocinstaller.h b/tools/assistant/tools/assistant/qtdocinstaller.h
index 05606f9..92a707b 100644
--- a/tools/assistant/tools/assistant/qtdocinstaller.h
+++ b/tools/assistant/tools/assistant/qtdocinstaller.h
@@ -42,34 +42,41 @@
#ifndef QTDOCINSTALLER
#define QTDOCINSTALLER
-#include <QtCore/QThread>
+#include <QtCore/QDir>
#include <QtCore/QMutex>
+#include <QtCore/QPair>
+#include <QtCore/QStringList>
+#include <QtCore/QThread>
QT_BEGIN_NAMESPACE
-class QHelpEngineCore;
+class HelpEngineWrapper;
class QtDocInstaller : public QThread
{
Q_OBJECT
public:
- QtDocInstaller(const QString &collectionFile);
+ typedef QPair<QString, QStringList> DocInfo;
+ QtDocInstaller(const QList<DocInfo> &docInfos);
~QtDocInstaller();
void installDocs();
signals:
- void errorMessage(const QString &msg);
+ void qchFileNotFound(const QString &component);
+ void registerDocumentation(const QString &component,
+ const QString &absFileName);
void docsInstalled(bool newDocsInstalled);
private:
void run();
- bool installDoc(const QString &name,
- QHelpEngineCore *helpEngine);
+ bool installDoc(const DocInfo &docInfo);
bool m_abort;
- QString m_collectionFile;
QMutex m_mutex;
+ QStringList m_qchFiles;
+ QDir m_qchDir;
+ QList<DocInfo> m_docInfos;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/remotecontrol.cpp b/tools/assistant/tools/assistant/remotecontrol.cpp
index 5fa7432..5ecdd69 100644
--- a/tools/assistant/tools/assistant/remotecontrol.cpp
+++ b/tools/assistant/tools/assistant/remotecontrol.cpp
@@ -38,12 +38,16 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "remotecontrol.h"
#include "mainwindow.h"
#include "centralwidget.h"
+#include "helpenginewrapper.h"
#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QFileSystemWatcher>
#include <QtCore/QThread>
#include <QtCore/QTextStream>
#include <QtCore/QSocketNotifier>
@@ -65,16 +69,19 @@ QT_BEGIN_NAMESPACE
StdInListenerWin::StdInListenerWin(QObject *parent)
: QThread(parent)
{
+ TRACE_OBJ
}
StdInListenerWin::~StdInListenerWin()
{
+ TRACE_OBJ
terminate();
wait();
}
void StdInListenerWin::run()
{
+ TRACE_OBJ
bool ok = true;
char chBuf[4096];
DWORD dwRead;
@@ -97,23 +104,24 @@ void StdInListenerWin::run()
#endif
while (ok) {
- ok = ReadFile(hStdinDup, chBuf, 4096, &dwRead, NULL);
+ ok = ReadFile(hStdinDup, chBuf, sizeof(chBuf), &dwRead, NULL);
if (ok && dwRead != 0)
- emit receivedCommand(QString::fromLocal8Bit(chBuf));
+ emit receivedCommand(QString::fromLocal8Bit(chBuf, dwRead));
}
}
#endif
-RemoteControl::RemoteControl(MainWindow *mainWindow, QHelpEngine *helpEngine)
+RemoteControl::RemoteControl(MainWindow *mainWindow)
: QObject(mainWindow)
, m_mainWindow(mainWindow)
- , m_helpEngine(helpEngine)
, m_debug(false)
, m_caching(true)
, m_syncContents(false)
- , m_expandTOC(-3)
+ , m_expandTOC(-2)
+ , helpEngine(HelpEngineWrapper::instance())
{
+ TRACE_OBJ
connect(m_mainWindow, SIGNAL(initDone()), this, SLOT(applyCache()));
#ifdef Q_OS_WIN
StdInListenerWin *l = new StdInListenerWin(this);
@@ -130,6 +138,7 @@ RemoteControl::RemoteControl(MainWindow *mainWindow, QHelpEngine *helpEngine)
void RemoteControl::receivedData()
{
+ TRACE_OBJ
QByteArray ba;
while (true) {
char c = getc(stdin);
@@ -145,135 +154,204 @@ void RemoteControl::receivedData()
void RemoteControl::handleCommandString(const QString &cmdString)
{
+ TRACE_OBJ
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();
+ QString cmd, arg;
+ splitInputString(*it, cmd, arg);
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_helpEngine->customFilters().contains(arg))
- return;
- if (m_caching) {
- clearCache();
- m_currentFilter = arg;
- } else {
- m_helpEngine->setCurrentFilter(arg);
- }
- } else {
+ if (cmd == QLatin1String("debug"))
+ handleDebugCommand(arg);
+ else if (cmd == QLatin1String("show"))
+ handleShowOrHideCommand(arg, true);
+ else if (cmd == QLatin1String("hide"))
+ handleShowOrHideCommand(arg, false);
+ else if (cmd == QLatin1String("setsource"))
+ handleSetSourceCommand(arg);
+ else if (cmd == QLatin1String("synccontents"))
+ handleSyncContentsCommand();
+ else if (cmd == QLatin1String("activatekeyword"))
+ handleActivateKeywordCommand(arg);
+ else if (cmd == QLatin1String("activateidentifier"))
+ handleActivateIdentifierCommand(arg);
+ else if (cmd == QLatin1String("expandtoc"))
+ handleExpandTocCommand(arg);
+ else if (cmd == QLatin1String("setcurrentfilter"))
+ handleSetCurrentFilterCommand(arg);
+ else if (cmd == QLatin1String("register"))
+ handleRegisterCommand(arg);
+ else if (cmd == QLatin1String("unregister"))
+ handleUnregisterCommand(arg);
+ else
return;
- }
+
++it;
}
m_mainWindow->raise();
m_mainWindow->activateWindow();
}
+void RemoteControl::splitInputString(const QString &input, QString &cmd,
+ QString &arg)
+{
+ TRACE_OBJ
+ QString cmdLine = input.trimmed();
+ int i = cmdLine.indexOf(QLatin1Char(' '));
+ cmd = cmdLine.left(i);
+ arg = cmdLine.mid(i+1);
+ cmd = cmd.toLower();
+}
+
+void RemoteControl::handleDebugCommand(const QString &arg)
+{
+ TRACE_OBJ
+ m_debug = arg == QLatin1String("on");
+}
+
+void RemoteControl::handleShowOrHideCommand(const QString &arg, bool show)
+{
+ TRACE_OBJ
+ if (arg.toLower() == QLatin1String("contents"))
+ m_mainWindow->setContentsVisible(show);
+ else if (arg.toLower() == QLatin1String("index"))
+ m_mainWindow->setIndexVisible(show);
+ else if (arg.toLower() == QLatin1String("bookmarks"))
+ m_mainWindow->setBookmarksVisible(show);
+ else if (arg.toLower() == QLatin1String("search"))
+ m_mainWindow->setSearchVisible(show);
+}
+
+void RemoteControl::handleSetSourceCommand(const QString &arg)
+{
+ TRACE_OBJ
+ 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);
+ }
+ }
+}
+
+void RemoteControl::handleSyncContentsCommand()
+{
+ TRACE_OBJ
+ if (m_caching)
+ m_syncContents = true;
+ else
+ m_mainWindow->syncContents();
+}
+
+void RemoteControl::handleActivateKeywordCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (m_caching) {
+ clearCache();
+ m_activateKeyword = arg;
+ } else {
+ m_mainWindow->setIndexString(arg);
+ if (!arg.isEmpty())
+ helpEngine.indexWidget()->activateCurrentItem();
+ }
+}
+
+void RemoteControl::handleActivateIdentifierCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (m_caching) {
+ clearCache();
+ m_activateIdentifier = arg;
+ } else {
+ const QMap<QString, QUrl> &links = helpEngine.linksForIdentifier(arg);
+ if (!links.isEmpty())
+ CentralWidget::instance()->setSource(links.constBegin().value());
+ }
+}
+
+void RemoteControl::handleExpandTocCommand(const QString &arg)
+{
+ TRACE_OBJ
+ bool ok = false;
+ int depth = -2;
+ if (!arg.isEmpty())
+ depth = arg.toInt(&ok);
+ if (!ok || depth < -2)
+ depth = -2;
+
+ if (m_caching)
+ m_expandTOC = depth;
+ else if (depth != -2)
+ m_mainWindow->expandTOC(depth);
+}
+
+void RemoteControl::handleSetCurrentFilterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ if (helpEngine.customFilters().contains(arg)) {
+ if (m_caching) {
+ clearCache();
+ m_currentFilter = arg;
+ } else {
+ helpEngine.setCurrentFilter(arg);
+ }
+ }
+}
+
+void RemoteControl::handleRegisterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ const QString &absFileName = QFileInfo(arg).absoluteFilePath();
+ if (helpEngine.registeredDocumentations().
+ contains(QHelpEngineCore::namespaceName(absFileName)))
+ return;
+ if (helpEngine.registerDocumentation(absFileName))
+ helpEngine.setupData();
+}
+
+void RemoteControl::handleUnregisterCommand(const QString &arg)
+{
+ TRACE_OBJ
+ const QString &absFileName = QFileInfo(arg).absoluteFilePath();
+ const QString &ns = QHelpEngineCore::namespaceName(absFileName);
+ if (helpEngine.registeredDocumentations().contains(ns)) {
+ CentralWidget* widget = CentralWidget::instance();
+ widget->closeOrReloadTabs(widget->currentSourceFileList().keys(ns), false);
+ if (helpEngine.unregisterDocumentation(ns))
+ helpEngine.setupData();
+ }
+}
+
void RemoteControl::applyCache()
{
+ TRACE_OBJ
if (m_setSource.isValid()) {
CentralWidget::instance()->setSource(m_setSource);
} else if (!m_activateKeyword.isEmpty()) {
m_mainWindow->setIndexString(m_activateKeyword);
- m_helpEngine->indexWidget()->activateCurrentItem();
+ helpEngine.indexWidget()->activateCurrentItem();
} else if (!m_activateIdentifier.isEmpty()) {
QMap<QString, QUrl> links =
- m_helpEngine->linksForIdentifier(m_activateIdentifier);
- if (links.count())
+ helpEngine.linksForIdentifier(m_activateIdentifier);
+ if (!links.isEmpty())
CentralWidget::instance()->setSource(links.constBegin().value());
} else if (!m_currentFilter.isEmpty()) {
- m_helpEngine->setCurrentFilter(m_currentFilter);
+ helpEngine.setCurrentFilter(m_currentFilter);
}
if (m_syncContents)
m_mainWindow->syncContents();
- if (m_expandTOC != -3)
+ Q_ASSERT(m_expandTOC >= -2);
+ if (m_expandTOC != -2)
m_mainWindow->expandTOC(m_expandTOC);
m_caching = false;
@@ -281,6 +359,7 @@ void RemoteControl::applyCache()
void RemoteControl::clearCache()
{
+ TRACE_OBJ
m_currentFilter.clear();
m_setSource.clear();
m_syncContents = false;
diff --git a/tools/assistant/tools/assistant/remotecontrol.h b/tools/assistant/tools/assistant/remotecontrol.h
index b888b40..0777878 100644
--- a/tools/assistant/tools/assistant/remotecontrol.h
+++ b/tools/assistant/tools/assistant/remotecontrol.h
@@ -43,19 +43,20 @@
#define REMOTECONTROL_H
#include <QtCore/QObject>
+#include <QtCore/QString>
#include <QtCore/QUrl>
QT_BEGIN_NAMESPACE
+class HelpEngineWrapper;
class MainWindow;
-class QHelpEngine;
class RemoteControl : public QObject
{
Q_OBJECT
public:
- RemoteControl(MainWindow *mainWindow, QHelpEngine *helpEngine);
+ RemoteControl(MainWindow *mainWindow);
private slots:
void receivedData();
@@ -64,10 +65,20 @@ private slots:
private:
void clearCache();
+ void splitInputString(const QString &input, QString &cmd, QString &arg);
+ void handleDebugCommand(const QString &arg);
+ void handleShowOrHideCommand(const QString &arg, bool show);
+ void handleSetSourceCommand(const QString &arg);
+ void handleSyncContentsCommand();
+ void handleActivateKeywordCommand(const QString &arg);
+ void handleActivateIdentifierCommand(const QString &arg);
+ void handleExpandTocCommand(const QString &arg);
+ void handleSetCurrentFilterCommand(const QString &arg);
+ void handleRegisterCommand(const QString &arg);
+ void handleUnregisterCommand(const QString &arg);
private:
MainWindow *m_mainWindow;
- QHelpEngine *m_helpEngine;
bool m_debug;
bool m_caching;
@@ -77,6 +88,7 @@ private:
QString m_activateIdentifier;
int m_expandTOC;
QString m_currentFilter;
+ HelpEngineWrapper &helpEngine;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/searchwidget.cpp b/tools/assistant/tools/assistant/searchwidget.cpp
index ad24231..d83790d 100644
--- a/tools/assistant/tools/assistant/searchwidget.cpp
+++ b/tools/assistant/tools/assistant/searchwidget.cpp
@@ -38,6 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
+#include "tracer.h"
#include "mainwindow.h"
#include "searchwidget.h"
@@ -65,6 +66,7 @@ SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
, attached(false)
, searchEngine(engine)
{
+ TRACE_OBJ
QVBoxLayout *vLayout = new QVBoxLayout(this);
resultWidget = searchEngine->resultWidget();
@@ -91,11 +93,13 @@ SearchWidget::SearchWidget(QHelpSearchEngine *engine, QWidget *parent)
SearchWidget::~SearchWidget()
{
+ TRACE_OBJ
// nothing todo
}
void SearchWidget::zoomIn()
{
+ TRACE_OBJ
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser && zoomCount != 10) {
zoomCount++;
@@ -105,6 +109,7 @@ void SearchWidget::zoomIn()
void SearchWidget::zoomOut()
{
+ TRACE_OBJ
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser && zoomCount != -5) {
zoomCount--;
@@ -114,6 +119,7 @@ void SearchWidget::zoomOut()
void SearchWidget::resetZoom()
{
+ TRACE_OBJ
if (zoomCount == 0)
return;
@@ -126,33 +132,39 @@ void SearchWidget::resetZoom()
bool SearchWidget::isAttached() const
{
+ TRACE_OBJ
return attached;
}
void SearchWidget::setAttached(bool state)
{
+ TRACE_OBJ
attached = state;
}
void SearchWidget::search() const
{
+ TRACE_OBJ
QList<QHelpSearchQuery> query = searchEngine->queryWidget()->query();
searchEngine->search(query);
}
void SearchWidget::searchingStarted()
{
+ TRACE_OBJ
qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
}
void SearchWidget::searchingFinished(int hits)
{
+ TRACE_OBJ
Q_UNUSED(hits)
qApp->restoreOverrideCursor();
}
bool SearchWidget::eventFilter(QObject* o, QEvent *e)
{
+ TRACE_OBJ
QTextBrowser* browser = qFindChild<QTextBrowser*>(resultWidget);
if (browser && o == browser->viewport()
&& e->type() == QEvent::MouseButtonRelease){
@@ -171,6 +183,7 @@ bool SearchWidget::eventFilter(QObject* o, QEvent *e)
void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
{
+ TRACE_OBJ
if (keyEvent->key() == Qt::Key_Escape)
MainWindow::activateCurrentBrowser();
else
@@ -179,6 +192,7 @@ void SearchWidget::keyPressEvent(QKeyEvent *keyEvent)
void SearchWidget::contextMenuEvent(QContextMenuEvent *contextMenuEvent)
{
+ TRACE_OBJ
QMenu menu;
QPoint point = contextMenuEvent->globalPos();
diff --git a/tools/assistant/tools/assistant/searchwidget.h b/tools/assistant/tools/assistant/searchwidget.h
index 465e8f6..750497b 100644
--- a/tools/assistant/tools/assistant/searchwidget.h
+++ b/tools/assistant/tools/assistant/searchwidget.h
@@ -58,7 +58,7 @@ class SearchWidget : public QWidget
Q_OBJECT
public:
- SearchWidget(QHelpSearchEngine *engine, QWidget *parent = 0);
+ explicit SearchWidget(QHelpSearchEngine *engine, QWidget *parent = 0);
~SearchWidget();
void zoomIn();
diff --git a/tools/assistant/tools/assistant/topicchooser.cpp b/tools/assistant/tools/assistant/topicchooser.cpp
index 5c04244..262fea8 100644
--- a/tools/assistant/tools/assistant/topicchooser.cpp
+++ b/tools/assistant/tools/assistant/topicchooser.cpp
@@ -38,9 +38,7 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
-#include <QtCore/QMap>
-#include <QtCore/QUrl>
+#include "tracer.h"
#include "topicchooser.h"
@@ -50,37 +48,40 @@ TopicChooser::TopicChooser(QWidget *parent, const QString &keyword,
const QMap<QString, QUrl> &links)
: QDialog(parent)
{
+ TRACE_OBJ
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)
+ QMap<QString, QUrl>::const_iterator it = links.constBegin();
+ for (; it != links.constEnd(); ++it) {
ui.listWidget->addItem(it.key());
+ m_links.append(it.value());
+ }
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()));
+ 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
{
+ TRACE_OBJ
QListWidgetItem *item = ui.listWidget->currentItem();
if (!item)
return QUrl();
QString title = item->text();
- if (title.isEmpty() || !m_links.contains(title))
+ if (title.isEmpty())
return QUrl();
- return m_links.value(title);
+ const int row = ui.listWidget->row(item);
+ Q_ASSERT(row < m_links.count());
+ return m_links.at(row);
}
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/assistant/topicchooser.h b/tools/assistant/tools/assistant/topicchooser.h
index 4dba726..4113cee 100644
--- a/tools/assistant/tools/assistant/topicchooser.h
+++ b/tools/assistant/tools/assistant/topicchooser.h
@@ -44,9 +44,10 @@
#include "ui_topicchooser.h"
-#include <QUrl>
-#include <QMap>
-#include <QString>
+#include <QtCore/QList>
+#include <QtCore/QMap>
+#include <QtCore/QString>
+#include <QtCore/QUrl>
#include <QtGui/QDialog>
@@ -64,7 +65,7 @@ public:
private:
Ui::TopicChooser ui;
- QMap<QString, QUrl> m_links;
+ QList<QUrl> m_links;
};
QT_END_NAMESPACE
diff --git a/tools/assistant/compat/lib/qassistantclient_global.h b/tools/assistant/tools/assistant/tracer.h
index 6b58736..66d450a 100644
--- a/tools/assistant/compat/lib/qassistantclient_global.h
+++ b/tools/assistant/tools/assistant/tracer.h
@@ -39,25 +39,37 @@
**
****************************************************************************/
-#ifndef QASSISTANTCLIENT_GLOBAL_H
-#define QASSISTANTCLIENT_GLOBAL_H
+#ifndef TRACER_H
+#define TRACER_H
-#include <QtCore/qglobal.h>
-
-QT_BEGIN_HEADER
+#include <QtCore/QtGlobal>
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
+class Tracer
+{
+public:
+ Tracer(const char *func) : m_func(func)
+ {
+ qDebug("Entering function %s.", m_func);
+ }
-QT_END_NAMESPACE
+ ~Tracer()
+ {
+ qDebug("Leaving function %s.", m_func);
+ }
-QT_END_HEADER
+private:
+ const char * const m_func;
+};
+QT_END_NAMESPACE
+
+// #define TRACING_REQUESTED
+#ifdef TRACING_REQUESTED
+#define TRACE_OBJ Tracer traceObj__(Q_FUNC_INFO);
+#else
+#define TRACE_OBJ
#endif
+
+#endif // TRACER_H
diff --git a/tools/assistant/tools/assistant/xbelsupport.cpp b/tools/assistant/tools/assistant/xbelsupport.cpp
new file mode 100644
index 0000000..ce49230
--- /dev/null
+++ b/tools/assistant/tools/assistant/xbelsupport.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "tracer.h"
+
+#include "xbelsupport.h"
+
+#include "bookmarkitem.h"
+#include "bookmarkmodel.h"
+
+#include <QtCore/QDate>
+#include <QtCore/QModelIndex>
+
+QT_BEGIN_NAMESPACE
+
+struct Bookmark {
+ QString title;
+ QString url;
+ bool folded;
+};
+
+XbelWriter::XbelWriter(BookmarkModel *model)
+ : QXmlStreamWriter()
+ , bookmarkModel(model)
+{
+ TRACE_OBJ
+ setAutoFormatting(true);
+}
+
+void XbelWriter::writeToFile(QIODevice *device)
+{
+ TRACE_OBJ
+ setDevice(device);
+
+ writeStartDocument();
+ writeDTD(QLatin1String("<!DOCTYPE xbel>"));
+ writeStartElement(QLatin1String("xbel"));
+ writeAttribute(QLatin1String("version"), QLatin1String("1.0"));
+
+ const QModelIndex &root = bookmarkModel->index(0,0, QModelIndex());
+ for (int i = 0; i < bookmarkModel->rowCount(root); ++i)
+ writeData(bookmarkModel->index(i, 0, root));
+ writeEndDocument();
+}
+
+void XbelWriter::writeData(const QModelIndex &index)
+{
+ TRACE_OBJ
+ if (index.isValid()) {
+ Bookmark entry;
+ entry.title = index.data().toString();
+ entry.url = index.data(UserRoleUrl).toString();
+
+ if (index.data(UserRoleFolder).toBool()) {
+ writeStartElement(QLatin1String("folder"));
+ entry.folded = !index.data(UserRoleExpanded).toBool();
+ writeAttribute(QLatin1String("folded"), entry.folded
+ ? QLatin1String("yes") : QLatin1String("no"));
+ writeTextElement(QLatin1String("title"), entry.title);
+
+ for (int i = 0; i < bookmarkModel->rowCount(index); ++i)
+ writeData(bookmarkModel->index(i, 0 , index));
+ writeEndElement();
+ } else {
+ writeStartElement(QLatin1String("bookmark"));
+ writeAttribute(QLatin1String("href"), entry.url);
+ writeTextElement(QLatin1String("title"), entry.title);
+ writeEndElement();
+ }
+ }
+}
+
+// -- XbelReader
+
+XbelReader::XbelReader(BookmarkModel *model)
+ : QXmlStreamReader()
+ , bookmarkModel(model)
+{
+ TRACE_OBJ
+}
+
+bool XbelReader::readFromFile(QIODevice *device)
+{
+ TRACE_OBJ
+ setDevice(device);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("xbel")
+ && attributes().value(QLatin1String("version"))
+ == QLatin1String("1.0")) {
+ const QModelIndex &root = bookmarkModel->index(0,0, QModelIndex());
+ parents.append(bookmarkModel->addItem(root, true));
+ readXBEL();
+ bookmarkModel->setData(parents.first(),
+ QDate::currentDate().toString(Qt::ISODate), Qt::EditRole);
+ } else {
+ raiseError(QLatin1String("The file is not an XBEL version 1.0 file."));
+ }
+ }
+ }
+
+ return !error();
+}
+
+void XbelReader::readXBEL()
+{
+ TRACE_OBJ
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("folder"))
+ readFolder();
+ else if (name() == QLatin1String("bookmark"))
+ readBookmark();
+ else
+ readUnknownElement();
+ }
+ }
+}
+
+void XbelReader::readFolder()
+{
+ TRACE_OBJ
+ parents.append(bookmarkModel->addItem(parents.last(), true));
+ bookmarkModel->setData(parents.last(),
+ attributes().value(QLatin1String("folded")) == QLatin1String("no"),
+ UserRoleExpanded);
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("title")) {
+ bookmarkModel->setData(parents.last(), readElementText(),
+ Qt::EditRole);
+ } else if (name() == QLatin1String("folder"))
+ readFolder();
+ else if (name() == QLatin1String("bookmark"))
+ readBookmark();
+ else
+ readUnknownElement();
+ }
+ }
+
+ parents.removeLast();
+}
+
+void XbelReader::readBookmark()
+{
+ TRACE_OBJ
+ const QModelIndex &index = bookmarkModel->addItem(parents.last(), false);
+ if (BookmarkItem* item = bookmarkModel->itemFromIndex(index)) {
+ item->setData(UserRoleUrl, attributes().value(QLatin1String("href"))
+ .toString());
+ }
+
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement()) {
+ if (name() == QLatin1String("title"))
+ bookmarkModel->setData(index, readElementText(), Qt::EditRole);
+ else
+ readUnknownElement();
+ }
+ }
+}
+
+void XbelReader::readUnknownElement()
+{
+ TRACE_OBJ
+ while (!atEnd()) {
+ readNext();
+
+ if (isEndElement())
+ break;
+
+ if (isStartElement())
+ readUnknownElement();
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/topicchooser.h b/tools/assistant/tools/assistant/xbelsupport.h
index fef57df..037415f 100644
--- a/tools/assistant/compat/topicchooser.h
+++ b/tools/assistant/tools/assistant/xbelsupport.h
@@ -39,39 +39,49 @@
**
****************************************************************************/
-#ifndef TOPICCHOOSER_H
-#define TOPICCHOOSER_H
+#ifndef XBELSUPPORT_H
+#define XBELSUPPORT_H
-#include "ui_topicchooser.h"
+#include <QtXml/QXmlStreamReader>
+#include <QtCore/QPersistentModelIndex>
-#include <QDialog>
-#include <QStringList>
+QT_FORWARD_DECLARE_CLASS(QIODevice)
+QT_FORWARD_DECLARE_CLASS(QModelIndex)
QT_BEGIN_NAMESPACE
-class TopicChooser : public QDialog
+class BookmarkModel;
+
+class XbelWriter : public QXmlStreamWriter
{
- Q_OBJECT
public:
- TopicChooser(QWidget *parent, const QStringList &lnkNames,
- const QStringList &lnks, const QString &title);
+ XbelWriter(BookmarkModel *model);
+ void writeToFile(QIODevice *device);
+
+private:
+ void writeData(const QModelIndex &index);
- QString link() const;
+private:
+ BookmarkModel *bookmarkModel;
+};
- static QString getLink(QWidget *parent, const QStringList &lnkNames,
- const QStringList &lnks, const QString &title);
+class XbelReader : public QXmlStreamReader
+{
+public:
+ XbelReader(BookmarkModel *model);
+ bool readFromFile(QIODevice *device);
-private slots:
- void on_buttonDisplay_clicked();
- void on_buttonCancel_clicked();
- void on_listbox_itemActivated(QListWidgetItem *item);
+private:
+ void readXBEL();
+ void readFolder();
+ void readBookmark();
+ void readUnknownElement();
private:
- Ui::TopicChooser ui;
- QString theLink;
- QStringList links, linkNames;
+ BookmarkModel *bookmarkModel;
+ QList<QPersistentModelIndex> parents;
};
-#endif // TOPICCHOOSER_H
-
QT_END_NAMESPACE
+
+#endif // XBELSUPPORT_H
diff --git a/tools/assistant/tools/qcollectiongenerator/main.cpp b/tools/assistant/tools/qcollectiongenerator/main.cpp
index 2339c50..fc9dc67 100644
--- a/tools/assistant/tools/qcollectiongenerator/main.cpp
+++ b/tools/assistant/tools/qcollectiongenerator/main.cpp
@@ -39,23 +39,31 @@
**
****************************************************************************/
+#include "../shared/collectionconfiguration.h"
#include "../shared/helpgenerator.h"
+#include <private/qhelpgenerator_p.h>
+#include <private/qhelpprojectdata_p.h>
+
+#include <QtCore/QCoreApplication>
#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 <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
#include <QtHelp/QHelpEngineCore>
-
#include <QtXml/QXmlStreamReader>
+
QT_USE_NAMESPACE
+class QCG {
+ Q_DECLARE_TR_FUNCTIONS(QCollectionGenerator)
+};
+
class CollectionConfigReader : public QXmlStreamReader
{
public:
@@ -87,6 +95,7 @@ public:
QStringList filesToRegister() const { return m_filesToRegister; }
QString cacheDirectory() const { return m_cacheDirectory; }
+ bool cacheDirRelativeToCollection() const { return m_cacheDirRelativeToCollection; }
private:
void raiseErrorWithLine();
@@ -115,12 +124,12 @@ private:
QMap<QString, QString> m_filesToGenerate;
QStringList m_filesToRegister;
QString m_cacheDirectory;
+ bool m_cacheDirRelativeToCollection;
};
void CollectionConfigReader::raiseErrorWithLine()
{
- raiseError(QObject::tr("Unknown token at line %1.")
- .arg(lineNumber()));
+ raiseError(QCG::tr("Unknown token at line %1.").arg(lineNumber()));
}
void CollectionConfigReader::readData(const QByteArray &contents)
@@ -139,8 +148,9 @@ void CollectionConfigReader::readData(const QByteArray &contents)
&& attributes().value(QLatin1String("version")) == QLatin1String("1.0"))
readConfig();
else
- raiseError(QObject::tr("Unknown token at line %1. Expected \"QtHelpCollectionProject\"!")
- .arg(lineNumber()));
+ raiseError(QCG::tr("Unknown token at line %1. "
+ "Expected \"QtHelpCollectionProject\".")
+ .arg(lineNumber()));
}
}
}
@@ -162,7 +172,7 @@ void CollectionConfigReader::readConfig()
}
}
if (!ok && !hasError())
- raiseError(QLatin1String("Missing end tags."));
+ raiseError(QCG::tr("Missing end tags."));
}
void CollectionConfigReader::readAssistantSettings()
@@ -198,6 +208,9 @@ void CollectionConfigReader::readAssistantSettings()
} else if (name() == QLatin1String("aboutDialog")) {
readAboutDialog();
} else if (name() == "cacheDirectory") {
+ m_cacheDirRelativeToCollection =
+ attributes().value(QLatin1String("base"))
+ == QLatin1String("collection");
m_cacheDirectory = readElementText();
} else {
raiseErrorWithLine();
@@ -301,7 +314,7 @@ void CollectionConfigReader::readFiles()
}
}
if (input.isEmpty() || output.isEmpty()) {
- raiseError(QLatin1String("Missing input or output file for help file generation!"));
+ raiseError(QCG::tr("Missing input or output file for help file generation."));
return;
}
m_filesToGenerate.insert(input, output);
@@ -322,6 +335,14 @@ void CollectionConfigReader::readRegister()
}
}
+namespace {
+ QString absoluteFileName(const QString &basePath, const QString &fileName)
+ {
+ return QFileInfo(fileName).isAbsolute() ?
+ fileName : basePath + QDir::separator() + fileName;
+ }
+}
+
int main(int argc, char *argv[])
{
QString error;
@@ -332,6 +353,22 @@ int main(int argc, char *argv[])
bool showHelp = false;
bool showVersion = false;
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
+#endif // Q_OS_WIN32
+
for (int i=1; i<argc; ++i) {
arg = QString::fromLocal8Bit(argv[i]);
if (arg == QLatin1String("-o")) {
@@ -339,7 +376,7 @@ int main(int argc, char *argv[])
QFileInfo fi(QString::fromLocal8Bit(argv[i]));
collectionFile = fi.absoluteFilePath();
} else {
- error = QObject::tr("Missing output file name!");
+ error = QCG::tr("Missing output file name.");
}
} else if (arg == QLatin1String("-h")) {
showHelp = true;
@@ -353,14 +390,15 @@ int main(int argc, char *argv[])
}
if (showVersion) {
- fprintf(stdout, "Qt Collection Generator version 1.0 (Qt %s)\n", QT_VERSION_STR);
+ fputs(qPrintable(QCG::tr("Qt Collection Generator version 1.0 (Qt %1)\n")
+ .arg(QT_VERSION_STR)), stdout);
return 0;
}
if (configFile.isEmpty() && !showHelp)
- error = QObject::tr("Missing collection config file!");
+ error = QCG::tr("Missing collection config file.");
- QString help = QObject::tr("\nUsage:\n\n"
+ QString help = QCG::tr("\nUsage:\n\n"
"qcollectiongenerator <collection-config-file> [options]\n\n"
" -o <collection-file> Generates a collection file\n"
" called <collection-file>. If\n"
@@ -370,7 +408,7 @@ int main(int argc, char *argv[])
" qcollectiongenerator.\n\n");
if (showHelp) {
- fprintf(stdout, "%s", qPrintable(help));
+ fputs(qPrintable(help), stdout);
return 0;
}else if (!error.isEmpty()) {
fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
@@ -379,7 +417,7 @@ int main(int argc, char *argv[])
QFile file(configFile);
if (!file.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Could not open %s!\n", qPrintable(configFile));
+ fputs(qPrintable(QCG::tr("Could not open %1.\n").arg(configFile)), stderr);
return -1;
}
@@ -389,39 +427,39 @@ int main(int argc, char *argv[])
+ fi.baseName() + QLatin1String(".qhc");
}
- QCoreApplication app(argc, argv);
-
- fprintf(stdout, "Reading collection config file...\n");
+ fputs(qPrintable(QCG::tr("Reading collection config file...\n")), stdout);
CollectionConfigReader config;
config.readData(file.readAll());
if (config.hasError()) {
- fprintf(stderr, "Collection config file error: %s\n", qPrintable(config.errorString()));
+ fputs(qPrintable(QCG::tr("Collection config file error: %1\n")
+ .arg(config.errorString())), stderr);
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()));
+ fputs(qPrintable(QCG::tr("Generating help for %1...\n").arg(it.key())), stdout);
QHelpProjectData helpData;
- if (!helpData.readData(basePath + QDir::separator() + it.key())) {
+ if (!helpData.readData(absoluteFileName(basePath, it.key()))) {
fprintf(stderr, "%s\n", qPrintable(helpData.errorMessage()));
return -1;
}
HelpGenerator helpGenerator;
- if (!helpGenerator.generate(&helpData, basePath + QDir::separator() + it.value())) {
+ if (!helpGenerator.generate(&helpData, absoluteFileName(basePath, it.value()))) {
fprintf(stderr, "%s\n", qPrintable(helpGenerator.error()));
return -1;
}
++it;
}
- fprintf(stdout, "Creating collection file...\n");
+ fputs(qPrintable(QCG::tr("Creating collection file...\n")), stdout);
QFileInfo colFi(collectionFile);
if (colFi.exists()) {
if (!colFi.dir().remove(colFi.fileName())) {
- fprintf(stderr, "The file %s cannot be overwritten!\n", qPrintable(collectionFile));
+ fputs(qPrintable(QCG::tr("The file %1 cannot be overwritten.\n")
+ .arg(collectionFile)), stderr);
return -1;
}
}
@@ -433,49 +471,56 @@ int main(int argc, char *argv[])
}
foreach (const QString &file, config.filesToRegister()) {
- if (!helpEngine.registerDocumentation(basePath + QDir::separator() + file)) {
+ if (!helpEngine.registerDocumentation(absoluteFileName(basePath, file))) {
fprintf(stderr, "%s\n", qPrintable(helpEngine.error()));
return -1;
}
}
+ if (!config.filesToRegister().isEmpty())
+ CollectionConfiguration::updateLastRegisterTime(helpEngine);
if (!config.title().isEmpty())
- helpEngine.setCustomValue(QLatin1String("WindowTitle"), config.title());
+ CollectionConfiguration::setWindowTitle(helpEngine, config.title());
if (!config.homePage().isEmpty()) {
- helpEngine.setCustomValue(QLatin1String("defaultHomepage"),
- config.homePage());
+ CollectionConfiguration::setDefaultHomePage(helpEngine,
+ config.homePage());
}
- if (!config.startPage().isEmpty())
- helpEngine.setCustomValue(QLatin1String("LastShownPages"), config.startPage());
+ if (!config.startPage().isEmpty()) {
+ CollectionConfiguration::setLastShownPages(helpEngine,
+ QStringList(config.startPage()));
+ }
- if (!config.currentFilter().isEmpty())
- helpEngine.setCustomValue(QLatin1String("CurrentFilter"), config.currentFilter());
+ if (!config.currentFilter().isEmpty()) {
+ helpEngine.setCurrentFilter(config.currentFilter());
+ }
- if (!config.cacheDirectory().isEmpty())
- helpEngine.setCustomValue(QLatin1String("CacheDirectory"), config.cacheDirectory());
+ if (!config.cacheDirectory().isEmpty()) {
+ CollectionConfiguration::setCacheDir(helpEngine, config.cacheDirectory(),
+ config.cacheDirRelativeToCollection());
+ }
- helpEngine.setCustomValue(QLatin1String("EnableFilterFunctionality"),
+ CollectionConfiguration::setFilterFunctionalityEnabled(helpEngine,
config.enableFilterFunctionality());
- helpEngine.setCustomValue(QLatin1String("HideFilterFunctionality"),
- config.hideFilterFunctionality());
- helpEngine.setCustomValue(QLatin1String("EnableDocumentationManager"),
+ CollectionConfiguration::setFilterToolbarVisible(helpEngine,
+ !config.hideFilterFunctionality());
+ CollectionConfiguration::setDocumentationManagerEnabled(helpEngine,
config.enableDocumentationManager());
- helpEngine.setCustomValue(QLatin1String("EnableAddressBar"),
+ CollectionConfiguration::setAddressBarEnabled(helpEngine,
config.enableAddressBar());
- helpEngine.setCustomValue(QLatin1String("HideAddressBar"),
- config.hideAddressBar());
- helpEngine.setCustomValue(QLatin1String("CreationTime"),
+ CollectionConfiguration::setAddressBarVisible(helpEngine,
+ !config.hideAddressBar());
+ CollectionConfiguration::setCreationTime(helpEngine,
QDateTime::currentDateTime().toTime_t());
if (!config.applicationIcon().isEmpty()) {
- QFile icon(basePath + QDir::separator() + config.applicationIcon());
+ QFile icon(absoluteFileName(basePath, config.applicationIcon()));
if (!icon.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName()));
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
return -1;
}
- helpEngine.setCustomValue(QLatin1String("ApplicationIcon"), icon.readAll());
+ CollectionConfiguration::setApplicationIcon(helpEngine, icon.readAll());
}
if (config.aboutMenuTexts().count()) {
@@ -487,16 +532,16 @@ int main(int argc, char *argv[])
s << it.value();
++it;
}
- helpEngine.setCustomValue(QLatin1String("AboutMenuTexts"), ba);
+ CollectionConfiguration::setAboutMenuTexts(helpEngine, ba);
}
if (!config.aboutIcon().isEmpty()) {
- QFile icon(basePath + QDir::separator() + config.aboutIcon());
+ QFile icon(absoluteFileName(basePath, config.aboutIcon()));
if (!icon.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Cannot open %s!\n", qPrintable(icon.fileName()));
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(icon.fileName())), stderr);
return -1;
}
- helpEngine.setCustomValue(QLatin1String("AboutIcon"), icon.readAll());
+ CollectionConfiguration::setAboutIcon(helpEngine, icon.readAll());
}
if (config.aboutTextFiles().count()) {
@@ -512,10 +557,10 @@ int main(int argc, char *argv[])
while (it != config.aboutTextFiles().constEnd()) {
s << it.key();
- QFileInfo fi(basePath + QDir::separator() + it.value());
+ QFileInfo fi(absoluteFileName(basePath, it.value()));
QFile f(fi.absoluteFilePath());
if (!f.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Cannot open %s!\n", qPrintable(f.fileName()));
+ fputs(qPrintable(QCG::tr("Cannot open %1.\n").arg(f.fileName())), stderr);
return -1;
}
QByteArray data = f.readAll();
@@ -537,21 +582,21 @@ int main(int argc, char *argv[])
if (!imgData.contains(src))
imgData.insert(src, img.readAll());
} else {
- fprintf(stderr, "Cannot open referenced image file %s!\n",
- qPrintable(img.fileName()));
+ fputs(qPrintable(QCG::tr("Cannot open referenced image file %1.\n")
+ .arg(img.fileName())), stderr);
}
}
}
++it;
}
- helpEngine.setCustomValue(QLatin1String("AboutTexts"), ba);
+ CollectionConfiguration::setAboutTexts(helpEngine, ba);
if (imgData.count()) {
QByteArray imageData;
QBuffer buffer(&imageData);
buffer.open(QIODevice::WriteOnly);
QDataStream out(&buffer);
out << imgData;
- helpEngine.setCustomValue(QLatin1String("AboutImages"), imageData);
+ CollectionConfiguration::setAboutImages(helpEngine, imageData);
}
}
diff --git a/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro b/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
index cf70e48..98e6a31 100644
--- a/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
+++ b/tools/assistant/tools/qcollectiongenerator/qcollectiongenerator.pro
@@ -1,14 +1,17 @@
-QT += xml network
+QT += xml \
+ network
TEMPLATE = app
DESTDIR = ../../../../bin
TARGET = qcollectiongenerator
-CONFIG += qt warn_on help console
+CONFIG += qt \
+ warn_on \
+ help \
+ console
CONFIG -= app_bundle
-
-target.path=$$[QT_INSTALL_BINS]
+target.path = $$[QT_INSTALL_BINS]
INSTALLS += target
-
SOURCES += ../shared/helpgenerator.cpp \
- main.cpp
-
-HEADERS += ../shared/helpgenerator.h
+ main.cpp \
+ ../shared/collectionconfiguration.cpp
+HEADERS += ../shared/helpgenerator.h \
+ ../shared/collectionconfiguration.h
diff --git a/tools/assistant/tools/qhelpconverter/filespage.cpp b/tools/assistant/tools/qhelpconverter/filespage.cpp
index 4ebf391..fd4a40e 100644
--- a/tools/assistant/tools/qhelpconverter/filespage.cpp
+++ b/tools/assistant/tools/qhelpconverter/filespage.cpp
@@ -59,8 +59,8 @@ FilesPage::FilesPage(QWidget *parent)
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 "
+ m_ui.fileLabel->setText(tr("<p><b>Warning:</b> "
+ "When removing images or stylesheets, be aware that those files "
"are not directly referenced by the .adp or .dcf "
"file.</p>"));
}
diff --git a/tools/assistant/tools/qhelpconverter/filterpage.cpp b/tools/assistant/tools/qhelpconverter/filterpage.cpp
index 7f86980..c15a580 100644
--- a/tools/assistant/tools/qhelpconverter/filterpage.cpp
+++ b/tools/assistant/tools/qhelpconverter/filterpage.cpp
@@ -50,7 +50,7 @@ FilterPage::FilterPage(QWidget *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 "
+ "also define a custom filter for it. Both the "
"filter attributes and the custom filters are "
"optional."));
@@ -127,7 +127,7 @@ 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(0, tr("unfiltered", "list of available documentation"));
item->setText(1, QLatin1String(""));
m_ui.customFilterWidget->editItem(item, 0);
m_ui.removeButton->setDisabled(false);
diff --git a/tools/assistant/tools/qhelpconverter/finishpage.cpp b/tools/assistant/tools/qhelpconverter/finishpage.cpp
index 0be3a1b..f0228e3 100644
--- a/tools/assistant/tools/qhelpconverter/finishpage.cpp
+++ b/tools/assistant/tools/qhelpconverter/finishpage.cpp
@@ -52,8 +52,7 @@ FinishPage::FinishPage(QWidget *parent)
: QWizardPage(parent)
{
setTitle(tr("Converting File"));
- setSubTitle(QLatin1String("Creating the new Qt help files from the "
- "old .adp file."));
+ setSubTitle(tr("Creating the new Qt help files from the old ADP file."));
setFinalPage(true);
QVBoxLayout *layout = new QVBoxLayout(this);
diff --git a/tools/assistant/tools/qhelpconverter/helpwindow.cpp b/tools/assistant/tools/qhelpconverter/helpwindow.cpp
index 9cc1a85..2c7e030 100644
--- a/tools/assistant/tools/qhelpconverter/helpwindow.cpp
+++ b/tools/assistant/tools/qhelpconverter/helpwindow.cpp
@@ -64,7 +64,7 @@ HelpWindow::HelpWindow(QWidget *parent)
layout = new QVBoxLayout(frame);
layout->setMargin(2);
- QLabel *l = new QLabel(QLatin1String("<center><b>Wizard Assistant</b></center>"));
+ QLabel *l = new QLabel(tr("<center><b>Wizard Assistant</b></center>"));
layout->addWidget(l);
m_textEdit = new QTextEdit();
m_textEdit->setFrameStyle(QFrame::NoFrame);
diff --git a/tools/assistant/tools/qhelpconverter/inputpage.h b/tools/assistant/tools/qhelpconverter/inputpage.h
index e9276c6..28a7075 100644
--- a/tools/assistant/tools/qhelpconverter/inputpage.h
+++ b/tools/assistant/tools/qhelpconverter/inputpage.h
@@ -54,7 +54,7 @@ class InputPage : public QWizardPage
Q_OBJECT
public:
- InputPage(AdpReader *reader, QWidget *parent = 0);
+ explicit InputPage(AdpReader *reader, QWidget *parent = 0);
private slots:
void getFileName();
diff --git a/tools/assistant/tools/qhelpconverter/main.cpp b/tools/assistant/tools/qhelpconverter/main.cpp
index 4b1d815..5ee624d 100644
--- a/tools/assistant/tools/qhelpconverter/main.cpp
+++ b/tools/assistant/tools/qhelpconverter/main.cpp
@@ -40,6 +40,9 @@
****************************************************************************/
#include <QtCore/QFileInfo>
+#include <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
#include <QtGui/QApplication>
#include "conversionwizard.h"
@@ -49,6 +52,18 @@ QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
ConversionWizard w;
if (argc == 2) {
diff --git a/tools/assistant/tools/qhelpgenerator/main.cpp b/tools/assistant/tools/qhelpgenerator/main.cpp
index 6245e33..5e20b4e 100644
--- a/tools/assistant/tools/qhelpgenerator/main.cpp
+++ b/tools/assistant/tools/qhelpgenerator/main.cpp
@@ -44,11 +44,18 @@
#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QCoreApplication>
+#include <QtCore/QTranslator>
+#include <QtCore/QLocale>
+#include <QtCore/QLibraryInfo>
#include <private/qhelpprojectdata_p.h>
QT_USE_NAMESPACE
+class QHG {
+ Q_DECLARE_TR_FUNCTIONS(QHelpGenerator)
+};
+
int main(int argc, char *argv[])
{
QString error;
@@ -58,6 +65,23 @@ int main(int argc, char *argv[])
QString basePath;
bool showHelp = false;
bool showVersion = false;
+ bool checkLinks = false;
+
+ QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QTranslator qt_helpTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("assistant_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)
+ && qt_helpTranslator.load(QLatin1String("qt_help_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ app.installTranslator(&qt_helpTranslator);
+ }
+#endif // Q_OS_WIN32
for (int i = 1; i < argc; ++i) {
arg = QString::fromLocal8Bit(argv[i]);
@@ -66,12 +90,14 @@ int main(int argc, char *argv[])
QFileInfo fi(QString::fromLocal8Bit(argv[i]));
compressedFile = fi.absoluteFilePath();
} else {
- error = QObject::tr("Missing output file name!");
+ error = QHG::tr("Missing output file name.");
}
} else if (arg == QLatin1String("-v")) {
showVersion = true;
} else if (arg == QLatin1String("-h")) {
showHelp = true;
+ } else if (arg == QLatin1String("-c")) {
+ checkLinks = true;
} else {
QFileInfo fi(arg);
projectFile = fi.absoluteFilePath();
@@ -80,24 +106,27 @@ int main(int argc, char *argv[])
}
if (showVersion) {
- fprintf(stdout, "Qt Help Generator version 1.0 (Qt %s)\n", QT_VERSION_STR);
+ fputs(qPrintable(QHG::tr("Qt Help Generator version 1.0 (Qt %1)\n")
+ .arg(QT_VERSION_STR)), stdout);
return 0;
}
if (projectFile.isEmpty() && !showHelp)
- error = QObject::tr("Missing Qt help project file!");
+ error = QHG::tr("Missing Qt help project file.");
- QString help = QObject::tr("\nUsage:\n\n"
+ QString help = QHG::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"
+ " -c Checks whether all links in HTML files\n"
+ " point to files in this help project.\n"
" -v Displays the version of \n"
" qhelpgenerator.\n\n");
if (showHelp) {
- fprintf(stdout, "%s", qPrintable(help));
+ fputs(qPrintable(help), stdout);
return 0;
}else if (!error.isEmpty()) {
fprintf(stderr, "%s\n\n%s", qPrintable(error), qPrintable(help));
@@ -106,22 +135,24 @@ int main(int argc, char *argv[])
QFile file(projectFile);
if (!file.open(QIODevice::ReadOnly)) {
- fprintf(stderr, "Could not open %s!\n", qPrintable(projectFile));
+ fputs(qPrintable(QHG::tr("Could not open %1.\n").arg(projectFile)), stderr);
return -1;
}
if (compressedFile.isEmpty()) {
- QFileInfo fi(projectFile);
- compressedFile = basePath + QDir::separator()
- + fi.baseName() + QLatin1String(".qch");
+ if (!checkLinks) {
+ 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()));
+ fputs(qPrintable(QHG::tr("Could not create output directory: %1\n")
+ .arg(parentDir.path())), stderr);
}
}
}
@@ -132,9 +163,12 @@ int main(int argc, char *argv[])
return -1;
}
- QCoreApplication app(argc, argv);
HelpGenerator generator;
- bool success = generator.generate(helpData, compressedFile);
+ bool success = true;
+ if (checkLinks)
+ success = generator.checkLinks(*helpData);
+ if (success && !compressedFile.isEmpty())
+ success = generator.generate(helpData, compressedFile);
delete helpData;
if (!success) {
fprintf(stderr, "%s\n", qPrintable(generator.error()));
diff --git a/tools/assistant/tools/shared/collectionconfiguration.cpp b/tools/assistant/tools/shared/collectionconfiguration.cpp
new file mode 100644
index 0000000..e3944b6
--- /dev/null
+++ b/tools/assistant/tools/shared/collectionconfiguration.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "collectionconfiguration.h"
+
+#include <QtHelp/QHelpEngineCore>
+
+QT_BEGIN_NAMESPACE
+
+namespace {
+ const QString AboutIconKey(QLatin1String("AboutIcon"));
+ const QString AboutImagesKey(QLatin1String("AboutImages"));
+ const QString AboutMenuTextsKey(QLatin1String("AboutMenuTexts"));
+ const QString AboutTextsKey(QLatin1String("AboutTexts"));
+ const QString ApplicationIconKey(QLatin1String("ApplicationIcon"));
+ const QString CacheDirKey(QLatin1String("CacheDirectory"));
+ const QString CacheDirRelativeToCollectionKey(QLatin1String("CacheDirRelativeToCollection"));
+ const QString CreationTimeKey(QLatin1String("CreationTime"));
+ const QString DefaultHomePageKey(QLatin1String("defaultHomepage"));
+ const QString EnableAddressBarKey(QLatin1String("EnableAddressBar"));
+ const QString EnableDocManagerKey(QLatin1String("EnableDocumentationManager"));
+ const QString EnableFilterKey(QLatin1String("EnableFilterFunctionality"));
+ const QString HideAddressBarKey(QLatin1String("HideAddressBar"));
+ const QString FilterToolbarHiddenKey(QLatin1String("HideFilterFunctionality"));
+ const QString LastPageKey(QLatin1String("LastTabPage"));
+ const QString LastRegisterTime(QLatin1String("LastRegisterTime"));
+ const QString LastShownPagesKey(QLatin1String("LastShownPages"));
+ const QString LastZoomFactorsKey(QLatin1String(
+#if !defined(QT_NO_WEBKIT)
+ "LastPagesZoomWebView"
+#else
+ "LastPagesZoomTextBrowser"
+#endif
+ ));
+ const QString WindowTitleKey(QLatin1String("WindowTitle"));
+} // anonymous namespace
+
+const QString CollectionConfiguration::DefaultZoomFactor(QLatin1String("0.0"));
+const QString CollectionConfiguration::ListSeparator(QLatin1String("|"));
+
+uint CollectionConfiguration::creationTime(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CreationTimeKey, 0).toUInt();
+}
+
+void CollectionConfiguration::setCreationTime(QHelpEngineCore &helpEngine, uint time)
+{
+ helpEngine.setCustomValue(CreationTimeKey, time);
+}
+
+const QString CollectionConfiguration::windowTitle(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(WindowTitleKey).toString();
+}
+
+void CollectionConfiguration::setWindowTitle(QHelpEngineCore &helpEngine,
+ const QString &windowTitle)
+{
+ helpEngine.setCustomValue(WindowTitleKey, windowTitle);
+}
+
+bool CollectionConfiguration::filterFunctionalityEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableFilterKey, true).toBool();
+}
+
+void CollectionConfiguration::setFilterFunctionalityEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableFilterKey, enabled);
+}
+
+bool CollectionConfiguration::filterToolbarVisible(const QHelpEngineCore &helpEngine)
+{
+ return !helpEngine.customValue(FilterToolbarHiddenKey, true).toBool();
+}
+
+void CollectionConfiguration::setFilterToolbarVisible(QHelpEngineCore &helpEngine,
+ bool visible)
+{
+ helpEngine.setCustomValue(FilterToolbarHiddenKey, !visible);
+}
+
+bool CollectionConfiguration::addressBarEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableAddressBarKey, true).toBool();
+}
+
+void CollectionConfiguration::setAddressBarEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableAddressBarKey, enabled);
+}
+
+bool CollectionConfiguration::addressBarVisible(const QHelpEngineCore &helpEngine)
+{
+ return !helpEngine.customValue(HideAddressBarKey, true).toBool();
+}
+
+void CollectionConfiguration::setAddressBarVisible(QHelpEngineCore &helpEngine,
+ bool visible)
+{
+ helpEngine.setCustomValue(HideAddressBarKey, !visible);
+}
+
+const QString CollectionConfiguration::cacheDir(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CacheDirKey).toString();
+}
+
+bool CollectionConfiguration::cacheDirIsRelativeToCollection(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(CacheDirRelativeToCollectionKey).toBool();
+}
+
+void CollectionConfiguration::setCacheDir(QHelpEngineCore &helpEngine,
+ const QString &cacheDir, bool relativeToCollection)
+{
+ helpEngine.setCustomValue(CacheDirKey, cacheDir);
+ helpEngine.setCustomValue(CacheDirRelativeToCollectionKey,
+ relativeToCollection);
+}
+
+bool CollectionConfiguration::documentationManagerEnabled(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(EnableDocManagerKey, true).toBool();
+}
+
+void CollectionConfiguration::setDocumentationManagerEnabled(QHelpEngineCore &helpEngine,
+ bool enabled)
+{
+ helpEngine.setCustomValue(EnableDocManagerKey, enabled);
+}
+
+const QByteArray CollectionConfiguration::applicationIcon(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(ApplicationIconKey).toByteArray();
+}
+
+void CollectionConfiguration::setApplicationIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon)
+{
+ helpEngine.setCustomValue(ApplicationIconKey, icon);
+}
+
+const QByteArray CollectionConfiguration::aboutMenuTexts(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutMenuTextsKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutMenuTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts)
+{
+ helpEngine.setCustomValue(AboutMenuTextsKey, texts);
+}
+
+const QByteArray CollectionConfiguration::aboutIcon(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutIconKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon)
+{
+ helpEngine.setCustomValue(AboutIconKey, icon);
+}
+
+const QByteArray CollectionConfiguration::aboutTexts(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutTextsKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts)
+{
+ helpEngine.setCustomValue(AboutTextsKey, texts);
+}
+
+const QByteArray CollectionConfiguration::aboutImages(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(AboutImagesKey).toByteArray();
+}
+
+void CollectionConfiguration::setAboutImages(QHelpEngineCore &helpEngine,
+ const QByteArray &images)
+{
+ helpEngine.setCustomValue(AboutImagesKey, images);
+}
+
+const QString CollectionConfiguration::defaultHomePage(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(DefaultHomePageKey, QLatin1String("help")).
+ toString();
+}
+
+void CollectionConfiguration::setDefaultHomePage(QHelpEngineCore &helpEngine,
+ const QString &page)
+{
+ helpEngine.setCustomValue(DefaultHomePageKey, page);
+}
+
+const QStringList CollectionConfiguration::lastShownPages(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastShownPagesKey).toString().
+ split(ListSeparator, QString::SkipEmptyParts);
+}
+
+void CollectionConfiguration::setLastShownPages(QHelpEngineCore &helpEngine,
+ const QStringList &lastShownPages)
+{
+ helpEngine.setCustomValue(LastShownPagesKey,
+ lastShownPages.join(ListSeparator));
+}
+
+const QStringList CollectionConfiguration::lastZoomFactors(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastZoomFactorsKey).toString().
+ split(ListSeparator, QString::SkipEmptyParts);
+}
+
+void CollectionConfiguration::setLastZoomFactors(QHelpEngineCore &helpEngine,
+ const QStringList &lastZoomFactors)
+{
+ helpEngine.setCustomValue(LastZoomFactorsKey,
+ lastZoomFactors.join(ListSeparator));
+}
+
+int CollectionConfiguration::lastTabPage(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastPageKey, 1).toInt();
+}
+
+void CollectionConfiguration::setLastTabPage(QHelpEngineCore &helpEngine,
+ int lastPage)
+{
+ helpEngine.setCustomValue(LastPageKey, lastPage);
+}
+
+const QDateTime CollectionConfiguration::lastRegisterTime(const QHelpEngineCore &helpEngine)
+{
+ return helpEngine.customValue(LastRegisterTime, QDateTime()).toDateTime();
+}
+
+void CollectionConfiguration::updateLastRegisterTime(QHelpEngineCore &helpEngine)
+{
+ helpEngine.setCustomValue(LastRegisterTime, QDateTime::currentDateTime());
+}
+
+bool CollectionConfiguration::isNewer(const QHelpEngineCore &newer,
+ const QHelpEngineCore &older)
+{
+ return creationTime(newer) > creationTime(older);
+}
+
+void CollectionConfiguration::copyConfiguration(const QHelpEngineCore &source,
+ QHelpEngineCore &target)
+{
+ setCreationTime(target, creationTime(source));
+ setWindowTitle(target, windowTitle(source));
+ target.setCurrentFilter(source.currentFilter());
+ setCacheDir(target, cacheDir(source), cacheDirIsRelativeToCollection(source));
+ setFilterFunctionalityEnabled(target, filterFunctionalityEnabled(source));
+ setFilterToolbarVisible(target, filterToolbarVisible(source));
+ setAddressBarEnabled(target, addressBarEnabled(source));
+ setAddressBarVisible(target, addressBarVisible(source));
+ setDocumentationManagerEnabled(target, documentationManagerEnabled(source));
+ setApplicationIcon(target, applicationIcon(source));
+ setAboutMenuTexts(target, aboutMenuTexts(source));
+ setAboutIcon(target, aboutIcon(source));
+ setAboutTexts(target, aboutTexts(source));
+ setAboutImages(target, aboutImages(source));
+ setDefaultHomePage(target, defaultHomePage(source));
+}
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/tools/shared/collectionconfiguration.h b/tools/assistant/tools/shared/collectionconfiguration.h
new file mode 100644
index 0000000..b7bf247
--- /dev/null
+++ b/tools/assistant/tools/shared/collectionconfiguration.h
@@ -0,0 +1,145 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef COLLECTIONCONFIGURATION_H
+#define COLLECTIONCONFIGURATION_H
+
+#include <QtCore/QByteArray>
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
+#include <QtCore/QString>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+
+class QHelpEngineCore;
+
+class CollectionConfiguration
+{
+public:
+ static const QString windowTitle(const QHelpEngineCore &helpEngine);
+ static void setWindowTitle(QHelpEngineCore &helpEngine,
+ const QString &windowTitle);
+
+ static const QString cacheDir(const QHelpEngineCore &helpEngine);
+ static bool cacheDirIsRelativeToCollection(const QHelpEngineCore &helpEngine);
+ static void setCacheDir(QHelpEngineCore &helpEngine,
+ const QString &cacheDir, bool relativeToCollection);
+
+ static uint creationTime(const QHelpEngineCore &helpEngine);
+ static void setCreationTime(QHelpEngineCore &helpEngine, uint time);
+
+ static bool filterFunctionalityEnabled(const QHelpEngineCore &helpEngine);
+ static void setFilterFunctionalityEnabled(QHelpEngineCore &helpEngine,
+ bool enabled);
+
+ static bool filterToolbarVisible(const QHelpEngineCore &helpEngine);
+ static void setFilterToolbarVisible(QHelpEngineCore &helpEngine,
+ bool visible);
+
+ static bool addressBarEnabled(const QHelpEngineCore &helpEngine);
+ static void setAddressBarEnabled(QHelpEngineCore &helpEngine, bool enabled);
+
+ static bool addressBarVisible(const QHelpEngineCore &helpEngine);
+ static void setAddressBarVisible(QHelpEngineCore &helpEngine, bool visible);
+
+
+ static bool documentationManagerEnabled(const QHelpEngineCore &helpEngine);
+ static void setDocumentationManagerEnabled(QHelpEngineCore &helpEngine,
+ bool enabled);
+
+ static const QByteArray applicationIcon(const QHelpEngineCore &helpEngine);
+ static void setApplicationIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon);
+
+ // TODO: Encapsulate encoding from/to QByteArray here
+ static const QByteArray aboutMenuTexts(const QHelpEngineCore &helpEngine);
+ static void setAboutMenuTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts);
+
+ static const QByteArray aboutIcon(const QHelpEngineCore &helpEngine);
+ static void setAboutIcon(QHelpEngineCore &helpEngine,
+ const QByteArray &icon);
+
+ // TODO: Encapsulate encoding from/to QByteArray here
+ static const QByteArray aboutTexts(const QHelpEngineCore &helpEngine);
+ static void setAboutTexts(QHelpEngineCore &helpEngine,
+ const QByteArray &texts);
+
+ static const QByteArray aboutImages(const QHelpEngineCore &helpEngine);
+ static void setAboutImages(QHelpEngineCore &helpEngine,
+ const QByteArray &images);
+
+ static const QString defaultHomePage(const QHelpEngineCore &helpEngine);
+ static void setDefaultHomePage(QHelpEngineCore &helpEngine,
+ const QString &page);
+
+ // TODO: Don't allow last pages and zoom factors to be set in isolation
+ // Perhaps also fill up missing elements automatically or assert.
+ static const QStringList lastShownPages(const QHelpEngineCore &helpEngine);
+ static void setLastShownPages(QHelpEngineCore &helpEngine,
+ const QStringList &lastShownPages);
+ static const QStringList lastZoomFactors(const QHelpEngineCore &helpEngine);
+ static void setLastZoomFactors(QHelpEngineCore &helPEngine,
+ const QStringList &lastZoomFactors);
+
+ static int lastTabPage(const QHelpEngineCore &helpEngine);
+ static void setLastTabPage(QHelpEngineCore &helpEngine, int lastPage);
+
+ static bool isNewer(const QHelpEngineCore &newer,
+ const QHelpEngineCore &older);
+ static void copyConfiguration(const QHelpEngineCore &source,
+ QHelpEngineCore &target);
+
+ /*
+ * Note that this only reflects register actions caused by the
+ * "-register" command line switch, not GUI or remote control actions.
+ */
+ static const QDateTime lastRegisterTime(const QHelpEngineCore &helpEngine);
+ static void updateLastRegisterTime(QHelpEngineCore &helpEngine);
+
+ static const QString DefaultZoomFactor;
+ static const QString ListSeparator;
+};
+
+QT_END_NAMESPACE
+
+#endif // COLLECTIONCONFIGURATION_H
diff --git a/tools/assistant/tools/shared/helpgenerator.cpp b/tools/assistant/tools/shared/helpgenerator.cpp
index fa183cd..4812bc5 100644
--- a/tools/assistant/tools/shared/helpgenerator.cpp
+++ b/tools/assistant/tools/shared/helpgenerator.cpp
@@ -61,6 +61,11 @@ bool HelpGenerator::generate(QHelpDataInterface *helpData,
return generator->generate(helpData, outputFileName);
}
+bool HelpGenerator::checkLinks(const QHelpDataInterface &helpData)
+{
+ return generator->checkLinks(helpData);
+}
+
QString HelpGenerator::error() const
{
return generator->error();
@@ -68,12 +73,12 @@ QString HelpGenerator::error() const
void HelpGenerator::printStatus(const QString &msg)
{
- fprintf(stdout, "%s\n", qPrintable(msg));
+ puts(qPrintable(msg));
}
void HelpGenerator::printWarning(const QString &msg)
{
- fprintf(stdout, "Warning: %s\n", qPrintable(msg));
+ puts(qPrintable(tr("Warning: %1").arg(msg)));
}
QT_END_NAMESPACE
diff --git a/tools/assistant/tools/shared/helpgenerator.h b/tools/assistant/tools/shared/helpgenerator.h
index 903d588..6da1c2b 100644
--- a/tools/assistant/tools/shared/helpgenerator.h
+++ b/tools/assistant/tools/shared/helpgenerator.h
@@ -57,6 +57,7 @@ public:
HelpGenerator();
bool generate(QHelpDataInterface *helpData,
const QString &outputFileName);
+ bool checkLinks(const QHelpDataInterface &helpData);
QString error() const;
private slots:
diff --git a/tools/assistant/translations/qt_help.pro b/tools/assistant/translations/qt_help.pro
deleted file mode 100644
index 1012f3f..0000000
--- a/tools/assistant/translations/qt_help.pro
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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
-
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/qt_help_cs.ts \
- $$TR_DIR/qt_help_da.ts \
- $$TR_DIR/qt_help_de.ts \
- $$TR_DIR/qt_help_ja.ts \
- $$TR_DIR/qt_help_pl.ts \
- $$TR_DIR/qt_help_ru.ts \
- $$TR_DIR/qt_help_zh_CN.ts \
- $$TR_DIR/qt_help_zh_TW.ts \
- $$TR_DIR/qt_help_fr.ts
diff --git a/tools/assistant/translations/translations.pro b/tools/assistant/translations/translations.pro
deleted file mode 100644
index d29ffc3..0000000
--- a/tools/assistant/translations/translations.pro
+++ /dev/null
@@ -1,53 +0,0 @@
-# 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 \
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/assistant_cs.ts \
- $$TR_DIR/assistant_da.ts \
- $$TR_DIR/assistant_de.ts \
- $$TR_DIR/assistant_fr.ts \
- $$TR_DIR/assistant_ja.ts \
- $$TR_DIR/assistant_pl.ts \
- $$TR_DIR/assistant_ru.ts \
- $$TR_DIR/assistant_zh_CN.ts \
- $$TR_DIR/assistant_zh_TW.ts
diff --git a/tools/assistant/translations/translations_adp.pro b/tools/assistant/translations/translations_adp.pro
deleted file mode 100644
index f8da2e3..0000000
--- a/tools/assistant/translations/translations_adp.pro
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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
-
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/assistant_adp_de.ts \
- $$TR_DIR/assistant_adp_ja.ts \
- $$TR_DIR/assistant_adp_pl.ts \
- $$TR_DIR/assistant_adp_ru.ts \
- $$TR_DIR/assistant_adp_zh_CN.ts \
- $$TR_DIR/assistant_adp_zh_TW.ts
diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro
index ab4b155..0a49fbe 100644
--- a/tools/configure/configure.pro
+++ b/tools/configure/configure.pro
@@ -1,5 +1,5 @@
TARGET = configure
-DESTDIR = ../..
+DESTDIR = $$PWD/../.. # build directly in source dir
CONFIG += console flat
CONFIG -= moc qt
@@ -8,7 +8,7 @@ DEFINES += QT_BOOTSTRAPPED
win32 : LIBS += -lole32 -ladvapi32
win32-msvc.net | win32-msvc2* : QMAKE_CXXFLAGS += /EHsc
-win32-g++ : LIBS += -luuid
+win32-g++* : LIBS += -luuid
win32-msvc* {
QMAKE_CFLAGS_RELEASE -= -MD
@@ -23,7 +23,8 @@ win32-msvc* {
PRECOMPILED_HEADER = configure_pch.h
-INCPATH += $$QT_SOURCE_TREE/src/corelib/arch/generic \
+INCLUDEPATH += \
+ $$QT_SOURCE_TREE/src/corelib/arch/generic \
$$QT_SOURCE_TREE/src/corelib/global \
$$QT_BUILD_TREE/include \
$$QT_BUILD_TREE/include/QtCore \
@@ -62,8 +63,8 @@ HEADERS = configureapp.h environment.h tools.h\
$$QT_SOURCE_TREE/src/corelib/tools/qunicodetables_p.h \
$$QT_SOURCE_TREE/src/corelib/xml/qxmlstream.h \
$$QT_SOURCE_TREE/src/corelib/xml/qxmlutils_p.h \
- $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.h \
- $$QT_SOURCE_TREE/tools/shared/windows/registry.h
+ $$QT_SOURCE_TREE/tools/shared/symbian/epocroot_p.h \
+ $$QT_SOURCE_TREE/tools/shared/windows/registry_p.h
SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \
@@ -91,6 +92,7 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \
$$QT_SOURCE_TREE/src/corelib/io/qiodevice.cpp \
$$QT_SOURCE_TREE/src/corelib/io/qtextstream.cpp \
$$QT_SOURCE_TREE/src/corelib/io/qtemporaryfile.cpp \
+ $$QT_SOURCE_TREE/src/corelib/plugin/qsystemlibrary.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qbitarray.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qdatetime.cpp \
$$QT_SOURCE_TREE/src/corelib/tools/qmap.cpp \
@@ -119,3 +121,4 @@ DEFINES += COMMERCIAL_VERSION
INCLUDEPATH += $$QT_SOURCE_TREE/src/corelib/arch/generic \
$$QT_SOURCE_TREE/include/QtCore \
+ $$QT_SOURCE_TREE/tools/shared
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 5de4f27..3c12eb9 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -61,7 +61,7 @@
QT_BEGIN_NAMESPACE
-std::ostream &operator<<( std::ostream &s, const QString &val ) {
+std::ostream &operator<<(std::ostream &s, const QString &val) {
s << val.toLocal8Bit().data();
return s;
}
@@ -89,7 +89,7 @@ bool writeToFile(const char* text, const QString &filename)
return true;
}
-Configure::Configure( int& argc, char** argv )
+Configure::Configure(int& argc, char** argv)
{
useUnixSeparators = false;
// Default values for indentation
@@ -111,7 +111,7 @@ Configure::Configure( int& argc, char** argv )
*/
dictionary[ "CONFIGCMD" ] = argv[ 0 ];
- for ( i = 1; i < argc; i++ )
+ for (i = 1; i < argc; i++)
configCmdLine += argv[ i ];
@@ -127,7 +127,7 @@ Configure::Configure( int& argc, char** argv )
#else
const QString installPath = buildPath;
#endif
- if(sourceDir != buildDir) { //shadow builds!
+ if (sourceDir != buildDir) { //shadow builds!
if (!findFile("perl") && !findFile("perl.exe")) {
cout << "Error: Creating a shadow build of Qt requires" << endl
<< "perl to be in the PATH environment";
@@ -140,37 +140,37 @@ Configure::Configure( int& argc, char** argv )
{ //duplicate qmake
QStack<QString> qmake_dirs;
qmake_dirs.push("qmake");
- while(!qmake_dirs.isEmpty()) {
+ while (!qmake_dirs.isEmpty()) {
QString dir = qmake_dirs.pop();
QString od(buildPath + "/" + dir);
QString id(sourcePath + "/" + dir);
QFileInfoList entries = QDir(id).entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries);
- for(int i = 0; i < entries.size(); ++i) {
+ for (int i = 0; i < entries.size(); ++i) {
QFileInfo fi(entries.at(i));
- if(fi.isDir()) {
+ if (fi.isDir()) {
qmake_dirs.push(dir + "/" + fi.fileName());
QDir().mkpath(od + "/" + fi.fileName());
} else {
- QDir().mkpath(od );
+ QDir().mkpath(od);
bool justCopy = true;
const QString fname = fi.fileName();
const QString outFile(od + "/" + fname), inFile(id + "/" + fname);
- if(fi.fileName() == "Makefile") { //ignore
- } else if(fi.suffix() == "h" || fi.suffix() == "cpp") {
+ if (fi.fileName() == "Makefile") { //ignore
+ } else if (fi.suffix() == "h" || fi.suffix() == "cpp") {
QTemporaryFile tmpFile;
- if(tmpFile.open()) {
+ if (tmpFile.open()) {
QTextStream stream(&tmpFile);
stream << "#include \"" << inFile << "\"" << endl;
justCopy = false;
stream.flush();
tmpFile.flush();
- if(filesDiffer(tmpFile.fileName(), outFile)) {
+ if (filesDiffer(tmpFile.fileName(), outFile)) {
QFile::remove(outFile);
tmpFile.copy(outFile);
}
}
}
- if(justCopy && filesDiffer(inFile, outFile))
+ if (justCopy && filesDiffer(inFile, outFile))
QFile::copy(inFile, outFile);
}
}
@@ -179,13 +179,13 @@ Configure::Configure( int& argc, char** argv )
{ //make a syncqt script(s) that can be used in the shadow
QFile syncqt(buildPath + "/bin/syncqt");
- if(syncqt.open(QFile::WriteOnly)) {
+ if (syncqt.open(QFile::WriteOnly)) {
QTextStream stream(&syncqt);
stream << "#!/usr/bin/perl -w" << endl
<< "require \"" << sourcePath + "/bin/syncqt\";" << endl;
}
QFile syncqt_bat(buildPath + "/bin/syncqt.bat");
- if(syncqt_bat.open(QFile::WriteOnly)) {
+ if (syncqt_bat.open(QFile::WriteOnly)) {
QTextStream stream(&syncqt_bat);
stream << "@echo off" << endl
<< "set QTDIR=" << QDir::toNativeSeparators(sourcePath) << endl
@@ -195,13 +195,40 @@ Configure::Configure( int& argc, char** argv )
}
}
+ // make patch_capabilities and createpackage scripts for Symbian that can be used from the shadow build
+ QFile patch_capabilities(buildPath + "/bin/patch_capabilities");
+ if (patch_capabilities.open(QFile::WriteOnly)) {
+ QTextStream stream(&patch_capabilities);
+ stream << "#!/usr/bin/perl -w" << endl
+ << "require \"" << sourcePath + "/bin/patch_capabilities\";" << endl;
+ }
+ QFile patch_capabilities_bat(buildPath + "/bin/patch_capabilities.bat");
+ if (patch_capabilities_bat.open(QFile::WriteOnly)) {
+ QTextStream stream(&patch_capabilities_bat);
+ stream << "@echo off" << endl
+ << "call " << fixSeparators(sourcePath) << fixSeparators("/bin/patch_capabilities.bat %*") << endl;
+ patch_capabilities_bat.close();
+ }
+ QFile createpackage(buildPath + "/bin/createpackage");
+ if (createpackage.open(QFile::WriteOnly)) {
+ QTextStream stream(&createpackage);
+ stream << "#!/usr/bin/perl -w" << endl
+ << "require \"" << sourcePath + "/bin/createpackage\";" << endl;
+ }
+ QFile createpackage_bat(buildPath + "/bin/createpackage.bat");
+ if (createpackage_bat.open(QFile::WriteOnly)) {
+ QTextStream stream(&createpackage_bat);
+ stream << "@echo off" << endl
+ << "call " << fixSeparators(sourcePath) << fixSeparators("/bin/createpackage.bat %*") << endl;
+ createpackage_bat.close();
+ }
+
// For Windows CE and shadow builds we need to copy these to the
// build directory.
QFile::copy(sourcePath + "/bin/setcepaths.bat" , buildPath + "/bin/setcepaths.bat");
-
//copy the mkspecs
buildDir.mkpath("mkspecs");
- if(!Environment::cpdir(sourcePath + "/mkspecs", buildPath + "/mkspecs")){
+ if (!Environment::cpdir(sourcePath + "/mkspecs", buildPath + "/mkspecs")){
cout << "Couldn't copy mkspecs!" << sourcePath << " " << buildPath << endl;
dictionary["DONE"] = "error";
return;
@@ -248,9 +275,11 @@ Configure::Configure( int& argc, char** argv )
dictionary[ "PHONON_BACKEND" ] = "yes";
dictionary[ "MULTIMEDIA" ] = "yes";
dictionary[ "AUDIO_BACKEND" ] = "auto";
+ dictionary[ "WMSDK" ] = "auto";
dictionary[ "DIRECTSHOW" ] = "no";
dictionary[ "WEBKIT" ] = "auto";
dictionary[ "DECLARATIVE" ] = "auto";
+ dictionary[ "DECLARATIVE_DEBUG" ]= "yes";
dictionary[ "PLUGIN_MANIFESTS" ] = "yes";
QString version;
@@ -276,7 +305,7 @@ Configure::Configure( int& argc, char** argv )
dictionary[ "VERSION" ] = version;
{
QRegExp version_re("([0-9]*)\\.([0-9]*)\\.([0-9]*)(|-.*)");
- if(version_re.exactMatch(version)) {
+ if (version_re.exactMatch(version)) {
dictionary[ "VERSION_MAJOR" ] = version_re.cap(1);
dictionary[ "VERSION_MINOR" ] = version_re.cap(2);
dictionary[ "VERSION_PATCH" ] = version_re.cap(3);
@@ -344,15 +373,16 @@ Configure::Configure( int& argc, char** argv )
QString tmp = dictionary[ "QMAKESPEC" ];
if (tmp.contains("\\")) {
- tmp = tmp.mid( tmp.lastIndexOf( "\\" ) + 1 );
+ tmp = tmp.mid(tmp.lastIndexOf("\\") + 1);
} else {
- tmp = tmp.mid( tmp.lastIndexOf("/") + 1 );
+ tmp = tmp.mid(tmp.lastIndexOf("/") + 1);
}
dictionary[ "QMAKESPEC" ] = tmp;
dictionary[ "INCREDIBUILD_XGE" ] = "auto";
dictionary[ "LTCG" ] = "no";
dictionary[ "NATIVE_GESTURES" ] = "yes";
+ dictionary[ "MSVC_MP" ] = "no";
}
Configure::~Configure()
@@ -364,11 +394,19 @@ Configure::~Configure()
}
}
-QString Configure::fixSeparators(QString somePath)
+QString Configure::fixSeparators(const QString &somePath, bool escape)
+{
+ if (useUnixSeparators)
+ return QDir::fromNativeSeparators(somePath);
+ QString ret = QDir::toNativeSeparators(somePath);
+ return escape ? escapeSeparators(ret) : ret;
+}
+
+QString Configure::escapeSeparators(const QString &somePath)
{
- return useUnixSeparators ?
- QDir::fromNativeSeparators(somePath) :
- QDir::toNativeSeparators(somePath);
+ QString out = somePath;
+ out.replace(QLatin1Char('\\'), QLatin1String("\\\\"));
+ return out;
}
// We could use QDir::homePath() + "/.qt-license", but
@@ -403,12 +441,12 @@ void Configure::parseCmdLine()
#if !defined(EVAL)
if (argCount < 1) // skip rest if no arguments
;
- else if( configCmdLine.at(i) == "-redo" ) {
+ else if (configCmdLine.at(i) == "-redo") {
dictionary[ "REDO" ] = "yes";
configCmdLine.clear();
reloadCmdLine();
}
- else if( configCmdLine.at(i) == "-loadconfig" ) {
+ else if (configCmdLine.at(i) == "-loadconfig") {
++i;
if (i != argCount) {
dictionary[ "REDO" ] = "yes";
@@ -424,9 +462,9 @@ void Configure::parseCmdLine()
#endif
// Look first for XQMAKESPEC
- for(int j = 0 ; j < argCount; ++j)
+ for (int j = 0 ; j < argCount; ++j)
{
- if( configCmdLine.at(j) == "-xplatform") {
+ if (configCmdLine.at(j) == "-xplatform") {
++j;
if (j == argCount)
break;
@@ -436,46 +474,46 @@ void Configure::parseCmdLine()
}
}
- for( ; i<configCmdLine.size(); ++i ) {
+ for (; i<configCmdLine.size(); ++i) {
bool continueElse[] = {false, false};
- if( configCmdLine.at(i) == "-help"
+ if (configCmdLine.at(i) == "-help"
|| configCmdLine.at(i) == "-h"
- || configCmdLine.at(i) == "-?" )
+ || configCmdLine.at(i) == "-?")
dictionary[ "HELP" ] = "yes";
#if !defined(EVAL)
- else if( configCmdLine.at(i) == "-qconfig" ) {
+ else if (configCmdLine.at(i) == "-qconfig") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "QCONFIG" ] = configCmdLine.at(i);
}
- else if ( configCmdLine.at(i) == "-buildkey" ) {
+ else if (configCmdLine.at(i) == "-buildkey") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "USER_BUILD_KEY" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-release" ) {
+ else if (configCmdLine.at(i) == "-release") {
dictionary[ "BUILD" ] = "release";
if (dictionary[ "BUILDALL" ] == "auto")
dictionary[ "BUILDALL" ] = "no";
- } else if( configCmdLine.at(i) == "-debug" ) {
+ } else if (configCmdLine.at(i) == "-debug") {
dictionary[ "BUILD" ] = "debug";
if (dictionary[ "BUILDALL" ] == "auto")
dictionary[ "BUILDALL" ] = "no";
- } else if( configCmdLine.at(i) == "-debug-and-release" )
+ } else if (configCmdLine.at(i) == "-debug-and-release")
dictionary[ "BUILDALL" ] = "yes";
- else if( configCmdLine.at(i) == "-shared" )
+ else if (configCmdLine.at(i) == "-shared")
dictionary[ "SHARED" ] = "yes";
- else if( configCmdLine.at(i) == "-static" )
+ else if (configCmdLine.at(i) == "-static")
dictionary[ "SHARED" ] = "no";
- else if( configCmdLine.at(i) == "-developer-build" )
+ else if (configCmdLine.at(i) == "-developer-build")
dictionary[ "BUILDDEV" ] = "yes";
- else if( configCmdLine.at(i) == "-nokia-developer" ) {
+ else if (configCmdLine.at(i) == "-nokia-developer") {
cout << "Detected -nokia-developer option" << endl;
cout << "Nokia employees and agents are allowed to use this software under" << endl;
cout << "the authority of Nokia Corporation and/or its subsidiary(-ies)" << endl;
@@ -486,45 +524,52 @@ void Configure::parseCmdLine()
dictionary[ "SYMBIAN_DEFFILES" ] = "no";
}
}
- else if( configCmdLine.at(i) == "-opensource" ) {
+ else if (configCmdLine.at(i) == "-opensource") {
dictionary[ "BUILDTYPE" ] = "opensource";
}
- else if( configCmdLine.at(i) == "-commercial" ) {
+ else if (configCmdLine.at(i) == "-commercial") {
dictionary[ "BUILDTYPE" ] = "commercial";
}
- else if( configCmdLine.at(i) == "-ltcg" ) {
+ else if (configCmdLine.at(i) == "-ltcg") {
dictionary[ "LTCG" ] = "yes";
}
- else if( configCmdLine.at(i) == "-no-ltcg" ) {
+ else if (configCmdLine.at(i) == "-no-ltcg") {
dictionary[ "LTCG" ] = "no";
}
+ else if (configCmdLine.at(i) == "-mp") {
+ dictionary[ "MSVC_MP" ] = "yes";
+ }
+ else if (configCmdLine.at(i) == "-no-mp") {
+ dictionary[ "MSVC_MP" ] = "no";
+ }
+
#endif
- else if( configCmdLine.at(i) == "-platform" ) {
+ else if (configCmdLine.at(i) == "-platform") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "QMAKESPEC" ] = configCmdLine.at(i);
dictionary[ "QMAKESPEC_FROM" ] = "commandline";
- } else if( configCmdLine.at(i) == "-arch" ) {
+ } else if (configCmdLine.at(i) == "-arch") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "ARCHITECTURE" ] = configCmdLine.at(i);
if (configCmdLine.at(i) == "boundschecker") {
dictionary[ "ARCHITECTURE" ] = "generic"; // Boundschecker uses the generic arch,
qtConfig += "boundschecker"; // but also needs this CONFIG option
}
- } else if( configCmdLine.at(i) == "-embedded" ) {
+ } else if (configCmdLine.at(i) == "-embedded") {
dictionary[ "EMBEDDED" ] = "yes";
- } else if( configCmdLine.at(i) == "-xplatform") {
+ } else if (configCmdLine.at(i) == "-xplatform") {
++i;
// do nothing
}
#if !defined(EVAL)
- else if( configCmdLine.at(i) == "-no-zlib" ) {
+ else if (configCmdLine.at(i) == "-no-zlib") {
// No longer supported since Qt 4.4.0
// But save the information for later so that we can print a warning
//
@@ -536,72 +581,64 @@ void Configure::parseCmdLine()
// There's no guarantee that Qt will build under those conditions
dictionary[ "ZLIB_FORCED" ] = "yes";
- } else if( configCmdLine.at(i) == "-qt-zlib" ) {
+ } else if (configCmdLine.at(i) == "-qt-zlib") {
dictionary[ "ZLIB" ] = "qt";
- } else if( configCmdLine.at(i) == "-system-zlib" ) {
+ } else if (configCmdLine.at(i) == "-system-zlib") {
dictionary[ "ZLIB" ] = "system";
}
// Image formats --------------------------------------------
- else if( configCmdLine.at(i) == "-no-gif" )
+ else if (configCmdLine.at(i) == "-no-gif")
dictionary[ "GIF" ] = "no";
- else if( configCmdLine.at(i) == "-qt-gif" )
- dictionary[ "GIF" ] = "auto";
-
- else if( configCmdLine.at(i) == "-no-libtiff" ) {
- dictionary[ "TIFF"] = "no";
- dictionary[ "LIBTIFF" ] = "no";
- } else if( configCmdLine.at(i) == "-qt-libtiff" ) {
- dictionary[ "TIFF" ] = "plugin";
+ else if (configCmdLine.at(i) == "-qt-gif")
+ dictionary[ "GIF" ] = "plugin";
+
+ else if (configCmdLine.at(i) == "-no-libtiff") {
+ dictionary[ "TIFF"] = "no";
+ dictionary[ "LIBTIFF" ] = "no";
+ } else if (configCmdLine.at(i) == "-qt-libtiff") {
dictionary[ "LIBTIFF" ] = "qt";
- } else if( configCmdLine.at(i) == "-system-libtiff" ) {
- dictionary[ "TIFF" ] = "plugin";
- dictionary[ "LIBTIFF" ] = "system";
+ } else if (configCmdLine.at(i) == "-system-libtiff") {
+ dictionary[ "LIBTIFF" ] = "system";
}
- else if( configCmdLine.at(i) == "-no-libjpeg" ) {
+ else if (configCmdLine.at(i) == "-no-libjpeg") {
dictionary[ "JPEG" ] = "no";
dictionary[ "LIBJPEG" ] = "no";
- } else if( configCmdLine.at(i) == "-qt-libjpeg" ) {
- dictionary[ "JPEG" ] = "plugin";
+ } else if (configCmdLine.at(i) == "-qt-libjpeg") {
dictionary[ "LIBJPEG" ] = "qt";
- } else if( configCmdLine.at(i) == "-system-libjpeg" ) {
- dictionary[ "JPEG" ] = "plugin";
+ } else if (configCmdLine.at(i) == "-system-libjpeg") {
dictionary[ "LIBJPEG" ] = "system";
}
- else if( configCmdLine.at(i) == "-no-libpng" ) {
+ else if (configCmdLine.at(i) == "-no-libpng") {
dictionary[ "PNG" ] = "no";
dictionary[ "LIBPNG" ] = "no";
- } else if( configCmdLine.at(i) == "-qt-libpng" ) {
- dictionary[ "PNG" ] = "qt";
+ } else if (configCmdLine.at(i) == "-qt-libpng") {
dictionary[ "LIBPNG" ] = "qt";
- } else if( configCmdLine.at(i) == "-system-libpng" ) {
- dictionary[ "PNG" ] = "qt";
+ } else if (configCmdLine.at(i) == "-system-libpng") {
dictionary[ "LIBPNG" ] = "system";
}
- else if( configCmdLine.at(i) == "-no-libmng" ) {
+ else if (configCmdLine.at(i) == "-no-libmng") {
dictionary[ "MNG" ] = "no";
dictionary[ "LIBMNG" ] = "no";
- } else if( configCmdLine.at(i) == "-qt-libmng" ) {
- dictionary[ "MNG" ] = "qt";
+ } else if (configCmdLine.at(i) == "-qt-libmng") {
dictionary[ "LIBMNG" ] = "qt";
- } else if( configCmdLine.at(i) == "-system-libmng" ) {
- dictionary[ "MNG" ] = "qt";
+ } else if (configCmdLine.at(i) == "-system-libmng") {
dictionary[ "LIBMNG" ] = "system";
}
// Text Rendering --------------------------------------------
- else if( configCmdLine.at(i) == "-no-freetype" )
+ else if (configCmdLine.at(i) == "-no-freetype")
dictionary[ "FREETYPE" ] = "no";
- else if( configCmdLine.at(i) == "-qt-freetype" )
+ else if (configCmdLine.at(i) == "-qt-freetype")
dictionary[ "FREETYPE" ] = "yes";
// CE- C runtime --------------------------------------------
- else if( configCmdLine.at(i) == "-crt" ) {
+ else if (configCmdLine.at(i) == "-crt") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
QDir cDir(configCmdLine.at(i));
if (!cDir.exists())
@@ -625,9 +662,9 @@ void Configure::parseCmdLine()
dictionary[ "CETEST_REQUESTED" ] = "yes";
}
// Qt/CE - signing tool -------------------------------------
- else if( configCmdLine.at(i) == "-signature") {
+ else if (configCmdLine.at(i) == "-signature") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
QFileInfo info(configCmdLine.at(i));
if (!info.exists())
@@ -636,57 +673,57 @@ void Configure::parseCmdLine()
dictionary[ "CE_SIGNATURE" ] = QDir::toNativeSeparators(info.absoluteFilePath());
}
// Styles ---------------------------------------------------
- else if( configCmdLine.at(i) == "-qt-style-windows" )
+ else if (configCmdLine.at(i) == "-qt-style-windows")
dictionary[ "STYLE_WINDOWS" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-windows" )
+ else if (configCmdLine.at(i) == "-no-style-windows")
dictionary[ "STYLE_WINDOWS" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-windowsce" )
+ else if (configCmdLine.at(i) == "-qt-style-windowsce")
dictionary[ "STYLE_WINDOWSCE" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-windowsce" )
+ else if (configCmdLine.at(i) == "-no-style-windowsce")
dictionary[ "STYLE_WINDOWSCE" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-windowsmobile" )
+ else if (configCmdLine.at(i) == "-qt-style-windowsmobile")
dictionary[ "STYLE_WINDOWSMOBILE" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-windowsmobile" )
+ else if (configCmdLine.at(i) == "-no-style-windowsmobile")
dictionary[ "STYLE_WINDOWSMOBILE" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-windowsxp" )
+ else if (configCmdLine.at(i) == "-qt-style-windowsxp")
dictionary[ "STYLE_WINDOWSXP" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-windowsxp" )
+ else if (configCmdLine.at(i) == "-no-style-windowsxp")
dictionary[ "STYLE_WINDOWSXP" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-windowsvista" )
+ else if (configCmdLine.at(i) == "-qt-style-windowsvista")
dictionary[ "STYLE_WINDOWSVISTA" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-windowsvista" )
+ else if (configCmdLine.at(i) == "-no-style-windowsvista")
dictionary[ "STYLE_WINDOWSVISTA" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-plastique" )
+ else if (configCmdLine.at(i) == "-qt-style-plastique")
dictionary[ "STYLE_PLASTIQUE" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-plastique" )
+ else if (configCmdLine.at(i) == "-no-style-plastique")
dictionary[ "STYLE_PLASTIQUE" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-cleanlooks" )
+ else if (configCmdLine.at(i) == "-qt-style-cleanlooks")
dictionary[ "STYLE_CLEANLOOKS" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-cleanlooks" )
+ else if (configCmdLine.at(i) == "-no-style-cleanlooks")
dictionary[ "STYLE_CLEANLOOKS" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-motif" )
+ else if (configCmdLine.at(i) == "-qt-style-motif")
dictionary[ "STYLE_MOTIF" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-motif" )
+ else if (configCmdLine.at(i) == "-no-style-motif")
dictionary[ "STYLE_MOTIF" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-cde" )
+ else if (configCmdLine.at(i) == "-qt-style-cde")
dictionary[ "STYLE_CDE" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-cde" )
+ else if (configCmdLine.at(i) == "-no-style-cde")
dictionary[ "STYLE_CDE" ] = "no";
- else if( configCmdLine.at(i) == "-qt-style-s60" )
+ else if (configCmdLine.at(i) == "-qt-style-s60")
dictionary[ "STYLE_S60" ] = "yes";
- else if( configCmdLine.at(i) == "-no-style-s60" )
+ else if (configCmdLine.at(i) == "-no-style-s60")
dictionary[ "STYLE_S60" ] = "no";
// Qt 3 Support ---------------------------------------------
- else if( configCmdLine.at(i) == "-no-qt3support" )
+ else if (configCmdLine.at(i) == "-no-qt3support")
dictionary[ "QT3SUPPORT" ] = "no";
// Work around compiler nesting limitation
@@ -696,159 +733,156 @@ void Configure::parseCmdLine()
}
// OpenGL Support -------------------------------------------
- else if( configCmdLine.at(i) == "-no-opengl" ) {
+ else if (configCmdLine.at(i) == "-no-opengl") {
dictionary[ "OPENGL" ] = "no";
- } else if ( configCmdLine.at(i) == "-opengl-es-cm" ) {
+ } else if (configCmdLine.at(i) == "-opengl-es-cm") {
dictionary[ "OPENGL" ] = "yes";
dictionary[ "OPENGL_ES_CM" ] = "yes";
- } else if ( configCmdLine.at(i) == "-opengl-es-cl" ) {
- dictionary[ "OPENGL" ] = "yes";
- dictionary[ "OPENGL_ES_CL" ] = "yes";
- } else if ( configCmdLine.at(i) == "-opengl-es-2" ) {
+ } else if (configCmdLine.at(i) == "-opengl-es-2") {
dictionary[ "OPENGL" ] = "yes";
dictionary[ "OPENGL_ES_2" ] = "yes";
}
// OpenVG Support -------------------------------------------
- else if( configCmdLine.at(i) == "-openvg" ) {
+ else if (configCmdLine.at(i) == "-openvg") {
dictionary[ "OPENVG" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-openvg" ) {
+ } else if (configCmdLine.at(i) == "-no-openvg") {
dictionary[ "OPENVG" ] = "no";
}
// Databases ------------------------------------------------
- else if( configCmdLine.at(i) == "-qt-sql-mysql" )
+ else if (configCmdLine.at(i) == "-qt-sql-mysql")
dictionary[ "SQL_MYSQL" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-mysql" )
+ else if (configCmdLine.at(i) == "-plugin-sql-mysql")
dictionary[ "SQL_MYSQL" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-mysql" )
+ else if (configCmdLine.at(i) == "-no-sql-mysql")
dictionary[ "SQL_MYSQL" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-odbc" )
+ else if (configCmdLine.at(i) == "-qt-sql-odbc")
dictionary[ "SQL_ODBC" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-odbc" )
+ else if (configCmdLine.at(i) == "-plugin-sql-odbc")
dictionary[ "SQL_ODBC" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-odbc" )
+ else if (configCmdLine.at(i) == "-no-sql-odbc")
dictionary[ "SQL_ODBC" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-oci" )
+ else if (configCmdLine.at(i) == "-qt-sql-oci")
dictionary[ "SQL_OCI" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-oci" )
+ else if (configCmdLine.at(i) == "-plugin-sql-oci")
dictionary[ "SQL_OCI" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-oci" )
+ else if (configCmdLine.at(i) == "-no-sql-oci")
dictionary[ "SQL_OCI" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-psql" )
+ else if (configCmdLine.at(i) == "-qt-sql-psql")
dictionary[ "SQL_PSQL" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-psql" )
+ else if (configCmdLine.at(i) == "-plugin-sql-psql")
dictionary[ "SQL_PSQL" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-psql" )
+ else if (configCmdLine.at(i) == "-no-sql-psql")
dictionary[ "SQL_PSQL" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-tds" )
+ else if (configCmdLine.at(i) == "-qt-sql-tds")
dictionary[ "SQL_TDS" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-tds" )
+ else if (configCmdLine.at(i) == "-plugin-sql-tds")
dictionary[ "SQL_TDS" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-tds" )
+ else if (configCmdLine.at(i) == "-no-sql-tds")
dictionary[ "SQL_TDS" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-db2" )
+ else if (configCmdLine.at(i) == "-qt-sql-db2")
dictionary[ "SQL_DB2" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-db2" )
+ else if (configCmdLine.at(i) == "-plugin-sql-db2")
dictionary[ "SQL_DB2" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-db2" )
+ else if (configCmdLine.at(i) == "-no-sql-db2")
dictionary[ "SQL_DB2" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-sqlite" )
+ else if (configCmdLine.at(i) == "-qt-sql-sqlite")
dictionary[ "SQL_SQLITE" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-sqlite" )
+ else if (configCmdLine.at(i) == "-plugin-sql-sqlite")
dictionary[ "SQL_SQLITE" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-sqlite" )
+ else if (configCmdLine.at(i) == "-no-sql-sqlite")
dictionary[ "SQL_SQLITE" ] = "no";
- else if( configCmdLine.at(i) == "-system-sqlite" )
+ else if (configCmdLine.at(i) == "-system-sqlite")
dictionary[ "SQL_SQLITE_LIB" ] = "system";
- else if( configCmdLine.at(i) == "-qt-sql-sqlite2" )
+ else if (configCmdLine.at(i) == "-qt-sql-sqlite2")
dictionary[ "SQL_SQLITE2" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-sqlite2" )
+ else if (configCmdLine.at(i) == "-plugin-sql-sqlite2")
dictionary[ "SQL_SQLITE2" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-sqlite2" )
+ else if (configCmdLine.at(i) == "-no-sql-sqlite2")
dictionary[ "SQL_SQLITE2" ] = "no";
- else if( configCmdLine.at(i) == "-qt-sql-ibase" )
+ else if (configCmdLine.at(i) == "-qt-sql-ibase")
dictionary[ "SQL_IBASE" ] = "yes";
- else if( configCmdLine.at(i) == "-plugin-sql-ibase" )
+ else if (configCmdLine.at(i) == "-plugin-sql-ibase")
dictionary[ "SQL_IBASE" ] = "plugin";
- else if( configCmdLine.at(i) == "-no-sql-ibase" )
+ else if (configCmdLine.at(i) == "-no-sql-ibase")
dictionary[ "SQL_IBASE" ] = "no";
#endif
// IDE project generation -----------------------------------
- else if( configCmdLine.at(i) == "-no-dsp" )
+ else if (configCmdLine.at(i) == "-no-dsp")
dictionary[ "DSPFILES" ] = "no";
- else if( configCmdLine.at(i) == "-dsp" )
+ else if (configCmdLine.at(i) == "-dsp")
dictionary[ "DSPFILES" ] = "yes";
- else if( configCmdLine.at(i) == "-no-vcp" )
+ else if (configCmdLine.at(i) == "-no-vcp")
dictionary[ "VCPFILES" ] = "no";
- else if( configCmdLine.at(i) == "-vcp" )
+ else if (configCmdLine.at(i) == "-vcp")
dictionary[ "VCPFILES" ] = "yes";
- else if( configCmdLine.at(i) == "-no-vcproj" )
+ else if (configCmdLine.at(i) == "-no-vcproj")
dictionary[ "VCPROJFILES" ] = "no";
- else if( configCmdLine.at(i) == "-vcproj" )
+ else if (configCmdLine.at(i) == "-vcproj")
dictionary[ "VCPROJFILES" ] = "yes";
- else if( configCmdLine.at(i) == "-no-incredibuild-xge" )
+ else if (configCmdLine.at(i) == "-no-incredibuild-xge")
dictionary[ "INCREDIBUILD_XGE" ] = "no";
- else if( configCmdLine.at(i) == "-incredibuild-xge" )
+ else if (configCmdLine.at(i) == "-incredibuild-xge")
dictionary[ "INCREDIBUILD_XGE" ] = "yes";
- else if( configCmdLine.at(i) == "-native-gestures" )
+ else if (configCmdLine.at(i) == "-native-gestures")
dictionary[ "NATIVE_GESTURES" ] = "yes";
- else if( configCmdLine.at(i) == "-no-native-gestures" )
+ else if (configCmdLine.at(i) == "-no-native-gestures")
dictionary[ "NATIVE_GESTURES" ] = "no";
#if !defined(EVAL)
// Symbian Support -------------------------------------------
- else if (configCmdLine.at(i) == "-fpu" )
+ else if (configCmdLine.at(i) == "-fpu")
{
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "ARM_FPU_TYPE" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-s60" )
+ else if (configCmdLine.at(i) == "-s60")
dictionary[ "S60" ] = "yes";
- else if( configCmdLine.at(i) == "-no-s60" )
+ else if (configCmdLine.at(i) == "-no-s60")
dictionary[ "S60" ] = "no";
- else if( configCmdLine.at(i) == "-usedeffiles" )
+ else if (configCmdLine.at(i) == "-usedeffiles")
dictionary[ "SYMBIAN_DEFFILES" ] = "yes";
- else if( configCmdLine.at(i) == "-no-usedeffiles" )
+ else if (configCmdLine.at(i) == "-no-usedeffiles")
dictionary[ "SYMBIAN_DEFFILES" ] = "no";
// Others ---------------------------------------------------
- else if (configCmdLine.at(i) == "-fast" )
+ else if (configCmdLine.at(i) == "-fast")
dictionary[ "FAST" ] = "yes";
- else if (configCmdLine.at(i) == "-no-fast" )
+ else if (configCmdLine.at(i) == "-no-fast")
dictionary[ "FAST" ] = "no";
- else if( configCmdLine.at(i) == "-stl" )
+ else if (configCmdLine.at(i) == "-stl")
dictionary[ "STL" ] = "yes";
- else if( configCmdLine.at(i) == "-no-stl" )
+ else if (configCmdLine.at(i) == "-no-stl")
dictionary[ "STL" ] = "no";
- else if ( configCmdLine.at(i) == "-exceptions" )
+ else if (configCmdLine.at(i) == "-exceptions")
dictionary[ "EXCEPTIONS" ] = "yes";
- else if ( configCmdLine.at(i) == "-no-exceptions" )
+ else if (configCmdLine.at(i) == "-no-exceptions")
dictionary[ "EXCEPTIONS" ] = "no";
- else if ( configCmdLine.at(i) == "-rtti" )
+ else if (configCmdLine.at(i) == "-rtti")
dictionary[ "RTTI" ] = "yes";
- else if ( configCmdLine.at(i) == "-no-rtti" )
+ else if (configCmdLine.at(i) == "-no-rtti")
dictionary[ "RTTI" ] = "no";
- else if( configCmdLine.at(i) == "-accessibility" )
+ else if (configCmdLine.at(i) == "-accessibility")
dictionary[ "ACCESSIBILITY" ] = "yes";
- else if( configCmdLine.at(i) == "-no-accessibility" ) {
+ else if (configCmdLine.at(i) == "-no-accessibility") {
dictionary[ "ACCESSIBILITY" ] = "no";
cout << "Setting accessibility to NO" << endl;
}
@@ -874,63 +908,69 @@ void Configure::parseCmdLine()
else if (configCmdLine.at(i) == "-iwmmxt")
dictionary[ "IWMMXT" ] = "yes";
- else if( configCmdLine.at(i) == "-no-openssl" ) {
+ else if (configCmdLine.at(i) == "-no-openssl") {
dictionary[ "OPENSSL"] = "no";
- } else if( configCmdLine.at(i) == "-openssl" ) {
+ } else if (configCmdLine.at(i) == "-openssl") {
dictionary[ "OPENSSL" ] = "yes";
- } else if( configCmdLine.at(i) == "-openssl-linked" ) {
+ } else if (configCmdLine.at(i) == "-openssl-linked") {
dictionary[ "OPENSSL" ] = "linked";
- } else if( configCmdLine.at(i) == "-no-qdbus" ) {
+ } else if (configCmdLine.at(i) == "-no-qdbus") {
dictionary[ "DBUS" ] = "no";
- } else if( configCmdLine.at(i) == "-qdbus" ) {
+ } else if (configCmdLine.at(i) == "-qdbus") {
dictionary[ "DBUS" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-dbus" ) {
+ } else if (configCmdLine.at(i) == "-no-dbus") {
dictionary[ "DBUS" ] = "no";
- } else if( configCmdLine.at(i) == "-dbus" ) {
+ } else if (configCmdLine.at(i) == "-dbus") {
dictionary[ "DBUS" ] = "yes";
- } else if( configCmdLine.at(i) == "-dbus-linked" ) {
+ } else if (configCmdLine.at(i) == "-dbus-linked") {
dictionary[ "DBUS" ] = "linked";
- } else if( configCmdLine.at(i) == "-no-script" ) {
+ } else if (configCmdLine.at(i) == "-no-script") {
dictionary[ "SCRIPT" ] = "no";
- } else if( configCmdLine.at(i) == "-script" ) {
+ } else if (configCmdLine.at(i) == "-script") {
dictionary[ "SCRIPT" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-scripttools" ) {
+ } else if (configCmdLine.at(i) == "-no-scripttools") {
dictionary[ "SCRIPTTOOLS" ] = "no";
- } else if( configCmdLine.at(i) == "-scripttools" ) {
+ } else if (configCmdLine.at(i) == "-scripttools") {
dictionary[ "SCRIPTTOOLS" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-xmlpatterns" ) {
+ } else if (configCmdLine.at(i) == "-no-xmlpatterns") {
dictionary[ "XMLPATTERNS" ] = "no";
- } else if( configCmdLine.at(i) == "-xmlpatterns" ) {
+ } else if (configCmdLine.at(i) == "-xmlpatterns") {
dictionary[ "XMLPATTERNS" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-multimedia" ) {
+ } else if (configCmdLine.at(i) == "-no-multimedia") {
dictionary[ "MULTIMEDIA" ] = "no";
- } else if( configCmdLine.at(i) == "-multimedia" ) {
+ } else if (configCmdLine.at(i) == "-multimedia") {
dictionary[ "MULTIMEDIA" ] = "yes";
- } else if( configCmdLine.at(i) == "-audio-backend" ) {
+ } else if (configCmdLine.at(i) == "-audio-backend") {
dictionary[ "AUDIO_BACKEND" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-audio-backend" ) {
+ } else if (configCmdLine.at(i) == "-no-audio-backend") {
dictionary[ "AUDIO_BACKEND" ] = "no";
- } else if( configCmdLine.at(i) == "-no-phonon" ) {
+ } else if (configCmdLine.at(i) == "-no-phonon") {
dictionary[ "PHONON" ] = "no";
- } else if( configCmdLine.at(i) == "-phonon" ) {
+ } else if (configCmdLine.at(i) == "-phonon") {
dictionary[ "PHONON" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-phonon-backend" ) {
+ } else if (configCmdLine.at(i) == "-no-phonon-backend") {
dictionary[ "PHONON_BACKEND" ] = "no";
- } else if( configCmdLine.at(i) == "-phonon-backend" ) {
+ } else if (configCmdLine.at(i) == "-phonon-backend") {
dictionary[ "PHONON_BACKEND" ] = "yes";
- } else if( configCmdLine.at(i) == "-phonon-wince-ds9" ) {
+ } else if (configCmdLine.at(i) == "-phonon-wince-ds9") {
dictionary[ "DIRECTSHOW" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-webkit" ) {
+ } else if (configCmdLine.at(i) == "-no-webkit") {
dictionary[ "WEBKIT" ] = "no";
- } else if( configCmdLine.at(i) == "-webkit" ) {
+ } else if (configCmdLine.at(i) == "-webkit") {
dictionary[ "WEBKIT" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-declarative" ) {
+ } else if (configCmdLine.at(i) == "-webkit-debug") {
+ dictionary[ "WEBKIT" ] = "debug";
+ } else if (configCmdLine.at(i) == "-no-declarative") {
dictionary[ "DECLARATIVE" ] = "no";
- } else if( configCmdLine.at(i) == "-declarative" ) {
+ } else if (configCmdLine.at(i) == "-declarative") {
dictionary[ "DECLARATIVE" ] = "yes";
- } else if( configCmdLine.at(i) == "-no-plugin-manifests" ) {
+ } else if (configCmdLine.at(i) == "-no-declarative-debug") {
+ dictionary[ "DECLARATIVE_DEBUG" ] = "no";
+ } else if (configCmdLine.at(i) == "-declarative-debug") {
+ dictionary[ "DECLARATIVE_DEBUG" ] = "yes";
+ } else if (configCmdLine.at(i) == "-no-plugin-manifests") {
dictionary[ "PLUGIN_MANIFESTS" ] = "no";
- } else if( configCmdLine.at(i) == "-plugin-manifests" ) {
+ } else if (configCmdLine.at(i) == "-plugin-manifests") {
dictionary[ "PLUGIN_MANIFESTS" ] = "yes";
}
@@ -940,52 +980,52 @@ void Configure::parseCmdLine()
if (!continueElse[0]) {
}
- else if( configCmdLine.at(i) == "-internal" )
+ else if (configCmdLine.at(i) == "-internal")
dictionary[ "QMAKE_INTERNAL" ] = "yes";
- else if( configCmdLine.at(i) == "-no-qmake" )
+ else if (configCmdLine.at(i) == "-no-qmake")
dictionary[ "BUILD_QMAKE" ] = "no";
- else if( configCmdLine.at(i) == "-qmake" )
+ else if (configCmdLine.at(i) == "-qmake")
dictionary[ "BUILD_QMAKE" ] = "yes";
- else if( configCmdLine.at(i) == "-dont-process" )
+ else if (configCmdLine.at(i) == "-dont-process")
dictionary[ "NOPROCESS" ] = "yes";
- else if( configCmdLine.at(i) == "-process" )
+ else if (configCmdLine.at(i) == "-process")
dictionary[ "NOPROCESS" ] = "no";
- else if( configCmdLine.at(i) == "-no-qmake-deps" )
+ else if (configCmdLine.at(i) == "-no-qmake-deps")
dictionary[ "DEPENDENCIES" ] = "no";
- else if( configCmdLine.at(i) == "-qmake-deps" )
+ else if (configCmdLine.at(i) == "-qmake-deps")
dictionary[ "DEPENDENCIES" ] = "yes";
- else if( configCmdLine.at(i) == "-qtnamespace" ) {
+ else if (configCmdLine.at(i) == "-qtnamespace") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
- qmakeDefines += "QT_NAMESPACE="+configCmdLine.at(i);
- } else if( configCmdLine.at(i) == "-qtlibinfix" ) {
+ dictionary[ "QT_NAMESPACE" ] = configCmdLine.at(i);
+ } else if (configCmdLine.at(i) == "-qtlibinfix") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_LIBINFIX" ] = configCmdLine.at(i);
if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) {
dictionary[ "QT_INSTALL_PLUGINS" ] =
QString("\\resource\\qt%1\\plugins").arg(dictionary[ "QT_LIBINFIX" ]);
}
- } else if( configCmdLine.at(i) == "-D" ) {
+ } else if (configCmdLine.at(i) == "-D") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
qmakeDefines += configCmdLine.at(i);
- } else if( configCmdLine.at(i) == "-I" ) {
+ } else if (configCmdLine.at(i) == "-I") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
qmakeIncludes += configCmdLine.at(i);
- } else if( configCmdLine.at(i) == "-L" ) {
+ } else if (configCmdLine.at(i) == "-L") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
QFileInfo check(configCmdLine.at(i));
if (!check.isDir()) {
@@ -994,25 +1034,31 @@ void Configure::parseCmdLine()
break;
}
qmakeLibs += QString("-L" + configCmdLine.at(i));
- } else if( configCmdLine.at(i) == "-l" ) {
+ } else if (configCmdLine.at(i) == "-l") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
qmakeLibs += QString("-l" + configCmdLine.at(i));
} else if (configCmdLine.at(i).startsWith("OPENSSL_LIBS=")) {
opensslLibs = configCmdLine.at(i);
+ } else if (configCmdLine.at(i).startsWith("PSQL_LIBS=")) {
+ psqlLibs = configCmdLine.at(i);
+ } else if (configCmdLine.at(i).startsWith("SYBASE=")) {
+ sybase = configCmdLine.at(i);
+ } else if (configCmdLine.at(i).startsWith("SYBASE_LIBS=")) {
+ sybaseLibs = configCmdLine.at(i);
}
- else if( ( configCmdLine.at(i) == "-override-version" ) || ( configCmdLine.at(i) == "-version-override" ) ){
+ else if ((configCmdLine.at(i) == "-override-version") || (configCmdLine.at(i) == "-version-override")){
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "VERSION" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-saveconfig" ) {
+ else if (configCmdLine.at(i) == "-saveconfig") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
dictionary[ "CUSTOMCONFIG" ] = "_" + configCmdLine.at(i);
}
@@ -1023,92 +1069,98 @@ void Configure::parseCmdLine()
else if (configCmdLine.at(i) == "-nomake") {
++i;
- if (i==argCount)
+ if (i == argCount)
break;
disabledBuildParts += configCmdLine.at(i);
}
// Directories ----------------------------------------------
- else if( configCmdLine.at(i) == "-prefix" ) {
+ else if (configCmdLine.at(i) == "-prefix") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_PREFIX" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-bindir" ) {
+ else if (configCmdLine.at(i) == "-bindir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_BINS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-libdir" ) {
+ else if (configCmdLine.at(i) == "-libdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_LIBS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-docdir" ) {
+ else if (configCmdLine.at(i) == "-docdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_DOCS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-headerdir" ) {
+ else if (configCmdLine.at(i) == "-headerdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_HEADERS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-plugindir" ) {
+ else if (configCmdLine.at(i) == "-plugindir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_PLUGINS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-datadir" ) {
+ else if (configCmdLine.at(i) == "-importdir") {
+ ++i;
+ if (i == argCount)
+ break;
+ dictionary[ "QT_INSTALL_IMPORTS" ] = configCmdLine.at(i);
+ }
+ else if (configCmdLine.at(i) == "-datadir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_DATA" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-translationdir" ) {
+ else if (configCmdLine.at(i) == "-translationdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_TRANSLATIONS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-examplesdir" ) {
+ else if (configCmdLine.at(i) == "-examplesdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_EXAMPLES" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-demosdir" ) {
+ else if (configCmdLine.at(i) == "-demosdir") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_INSTALL_DEMOS" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-hostprefix" ) {
+ else if (configCmdLine.at(i) == "-hostprefix") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "QT_HOST_PREFIX" ] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i) == "-make" ) {
+ else if (configCmdLine.at(i) == "-make") {
++i;
- if(i==argCount)
+ if (i == argCount)
break;
dictionary[ "MAKE" ] = configCmdLine.at(i);
}
@@ -1120,18 +1172,26 @@ void Configure::parseCmdLine()
QString system = configCmdLine.at(i);
if (system == QLatin1String("raster")
|| system == QLatin1String("opengl")
- || system == QLatin1String("openvg"))
+ || system == QLatin1String("openvg")
+ || system == QLatin1String("runtime"))
dictionary["GRAPHICS_SYSTEM"] = configCmdLine.at(i);
}
- else if( configCmdLine.at(i).indexOf( QRegExp( "^-(en|dis)able-" ) ) != -1 ) {
+ else if (configCmdLine.at(i) == "-runtimegraphicssystem") {
+ ++i;
+ if (i == argCount)
+ break;
+ dictionary["RUNTIME_SYSTEM"] = configCmdLine.at(i);
+ }
+
+ else if (configCmdLine.at(i).indexOf(QRegExp("^-(en|dis)able-")) != -1) {
// Scan to see if any specific modules and drivers are enabled or disabled
- for( QStringList::Iterator module = modules.begin(); module != modules.end(); ++module ) {
- if( configCmdLine.at(i) == QString( "-enable-" ) + (*module) ) {
+ for (QStringList::Iterator module = modules.begin(); module != modules.end(); ++module) {
+ if (configCmdLine.at(i) == QString("-enable-") + (*module)) {
enabledModules += (*module);
break;
}
- else if( configCmdLine.at(i) == QString( "-disable-" ) + (*module) ) {
+ else if (configCmdLine.at(i) == QString("-disable-") + (*module)) {
disabledModules += (*module);
break;
}
@@ -1165,24 +1225,25 @@ void Configure::parseCmdLine()
}
cout << "See the README file for a list of supported operating systems and compilers." << endl;
} else {
- if( dictionary[ "QMAKESPEC" ].endsWith( "-icc" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc.net" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc2002" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc2003" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc2005" ) ||
- dictionary[ "QMAKESPEC" ].endsWith( "-msvc2008" )) {
- if ( dictionary[ "MAKE" ].isEmpty() ) dictionary[ "MAKE" ] = "nmake";
+ if (dictionary[ "QMAKESPEC" ].endsWith("-icc") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc.net") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc2002") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc2003") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc2005") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc2008") ||
+ dictionary[ "QMAKESPEC" ].endsWith("-msvc2010")) {
+ if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "nmake";
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
- } else if ( dictionary[ "QMAKESPEC" ] == QString( "win32-g++" ) ) {
- if ( dictionary[ "MAKE" ].isEmpty() ) dictionary[ "MAKE" ] = "mingw32-make";
+ } else if (dictionary[ "QMAKESPEC" ] == QString("win32-g++")) {
+ if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "mingw32-make";
if (Environment::detectExecutable("sh.exe")) {
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++-sh";
} else {
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32-g++";
}
} else {
- if ( dictionary[ "MAKE" ].isEmpty() ) dictionary[ "MAKE" ] = "make";
+ if (dictionary[ "MAKE" ].isEmpty()) dictionary[ "MAKE" ] = "make";
dictionary[ "QMAKEMAKEFILE" ] = "Makefile.win32";
}
}
@@ -1238,19 +1299,19 @@ void Configure::parseCmdLine()
#if !defined(EVAL)
- for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) {
- modules.removeAll( (*dis) );
+ for (QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis) {
+ modules.removeAll((*dis));
}
- for( QStringList::Iterator ena = enabledModules.begin(); ena != enabledModules.end(); ++ena ) {
- if( modules.indexOf( (*ena) ) == -1 )
+ for (QStringList::Iterator ena = enabledModules.begin(); ena != enabledModules.end(); ++ena) {
+ if (modules.indexOf((*ena)) == -1)
modules += (*ena);
}
qtConfig += modules;
- for( QStringList::Iterator it = disabledModules.begin(); it != disabledModules.end(); ++it )
+ for (QStringList::Iterator it = disabledModules.begin(); it != disabledModules.end(); ++it)
qtConfig.removeAll(*it);
- if( ( dictionary[ "REDO" ] != "yes" ) && ( dictionary[ "HELP" ] != "yes" ) )
+ if ((dictionary[ "REDO" ] != "yes") && (dictionary[ "HELP" ] != "yes"))
saveCmdLine();
#endif
}
@@ -1270,7 +1331,7 @@ void Configure::validateArgs()
QStringList stringList = dir.entryList();
QStringList::Iterator it;
- for( it = stringList.begin(); it != stringList.end(); ++it )
+ for (it = stringList.begin(); it != stringList.end(); ++it)
allConfigs << it->remove("qconfig-").remove(".h");
allConfigs << "full";
@@ -1291,11 +1352,11 @@ void Configure::validateArgs()
// If the internal configurations failed, try others.
QStringList::Iterator config;
- for( config = allConfigs.begin(); config != allConfigs.end(); ++config ) {
- if( (*config) == dictionary[ "QCONFIG" ] )
+ for (config = allConfigs.begin(); config != allConfigs.end(); ++config) {
+ if ((*config) == dictionary[ "QCONFIG" ])
break;
}
- if( config == allConfigs.end() ) {
+ if (config == allConfigs.end()) {
dictionary[ "HELP" ] = "yes";
cout << "No such configuration \"" << qPrintable(dictionary[ "QCONFIG" ]) << "\"" << endl ;
}
@@ -1448,7 +1509,7 @@ void Configure::applySpecSpecifics()
dictionary[ "QT_HOST_PREFIX" ] = dictionary[ "QT_INSTALL_PREFIX" ];
dictionary[ "QT_INSTALL_PREFIX" ] = "";
- } else if(dictionary[ "XQMAKESPEC" ].startsWith("symbian")) {
+ } else if (dictionary[ "XQMAKESPEC" ].startsWith("symbian")) {
dictionary[ "ACCESSIBILITY" ] = "no";
dictionary[ "STYLE_WINDOWSXP" ] = "no";
dictionary[ "STYLE_WINDOWSVISTA" ] = "no";
@@ -1463,6 +1524,10 @@ void Configure::applySpecSpecifics()
dictionary[ "QT3SUPPORT" ] = "no";
dictionary[ "OPENGL" ] = "no";
dictionary[ "OPENSSL" ] = "yes";
+ // We accidently enabled IPv6 for Qt Symbian in 4.6.x. However the underlying OpenC does not fully support IPV6.
+ // Therefore for 4.7.1 and following we disable it until OpenC either supports it or we have the native Qt
+ // symbian socket engine.
+ dictionary[ "IPV6" ] = "no";
dictionary[ "STL" ] = "yes";
dictionary[ "EXCEPTIONS" ] = "yes";
dictionary[ "RTTI" ] = "yes";
@@ -1488,6 +1553,7 @@ void Configure::applySpecSpecifics()
dictionary[ "QT_HOST_PREFIX" ] = dictionary[ "QT_INSTALL_PREFIX" ];
dictionary[ "QT_INSTALL_PREFIX" ] = "";
dictionary[ "QT_INSTALL_PLUGINS" ] = "\\resource\\qt\\plugins";
+ dictionary[ "QT_INSTALL_IMPORTS" ] = "\\resource\\qt\\imports";
dictionary[ "QT_INSTALL_TRANSLATIONS" ] = "\\resource\\qt\\translations";
dictionary[ "ARM_FPU_TYPE" ] = "softvfp";
dictionary[ "SQL_SQLITE" ] = "yes";
@@ -1496,7 +1562,7 @@ void Configure::applySpecSpecifics()
// Disable building docs and translations for now
disabledBuildParts << "docs" << "translations";
- } else if(dictionary[ "XQMAKESPEC" ].startsWith("linux")) { //TODO actually wrong.
+ } else if (dictionary[ "XQMAKESPEC" ].startsWith("linux")) { //TODO actually wrong.
//TODO
dictionary[ "STYLE_WINDOWSXP" ] = "no";
dictionary[ "STYLE_WINDOWSVISTA" ] = "no";
@@ -1516,29 +1582,28 @@ void Configure::applySpecSpecifics()
dictionary[ "QT_ICONV" ] = "no";
dictionary["DECORATIONS"] = "default windows styled";
- dictionary[ "QMAKEADDITIONALARGS" ] = "-unix";
}
}
QString Configure::locateFileInPaths(const QString &fileName, const QStringList &paths)
{
QDir d;
- for( QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it ) {
+ for (QStringList::ConstIterator it = paths.begin(); it != paths.end(); ++it) {
// Remove any leading or trailing ", this is commonly used in the environment
// variables
QString path = (*it);
- if ( path.startsWith( "\"" ) )
- path = path.right( path.length() - 1 );
- if ( path.endsWith( "\"" ) )
- path = path.left( path.length() - 1 );
- if( d.exists(path + QDir::separator() + fileName) ) {
+ if (path.startsWith("\""))
+ path = path.right(path.length() - 1);
+ if (path.endsWith("\""))
+ path = path.left(path.length() - 1);
+ if (d.exists(path + QDir::separator() + fileName)) {
return (path);
}
}
return QString();
}
-QString Configure::locateFile( const QString &fileName )
+QString Configure::locateFile(const QString &fileName)
{
QString file = fileName.toLower();
QStringList paths;
@@ -1549,7 +1614,7 @@ QString Configure::locateFile( const QString &fileName )
#endif
if (file.endsWith(".h"))
paths = QString::fromLocal8Bit(getenv("INCLUDE")).split(splitReg, QString::SkipEmptyParts);
- else if ( file.endsWith( ".lib" ) )
+ else if (file.endsWith(".lib"))
paths = QString::fromLocal8Bit(getenv("LIB")).split(splitReg, QString::SkipEmptyParts);
else
paths = QString::fromLocal8Bit(getenv("PATH")).split(splitReg, QString::SkipEmptyParts);
@@ -1561,11 +1626,11 @@ QString Configure::locateFile( const QString &fileName )
bool Configure::displayHelp()
{
- if( dictionary[ "HELP" ] == "yes" ) {
+ if (dictionary[ "HELP" ] == "yes") {
desc("Usage: configure [-buildkey <key>]\n"
// desc("Usage: configure [-prefix dir] [-bindir <dir>] [-libdir <dir>]\n"
// "[-docdir <dir>] [-headerdir <dir>] [-plugindir <dir>]\n"
-// "[-datadir <dir>] [-translationdir <dir>]\n"
+// "[-importdir <dir>] [-datadir <dir>] [-translationdir <dir>]\n"
// "[-examplesdir <dir>] [-demosdir <dir>][-buildkey <key>]\n"
"[-release] [-debug] [-debug-and-release] [-shared] [-static]\n"
"[-no-fast] [-fast] [-no-exceptions] [-exceptions]\n"
@@ -1588,7 +1653,7 @@ bool Configure::displayHelp()
"[-phonon] [-no-phonon-backend] [-phonon-backend]\n"
"[-no-multimedia] [-multimedia] [-no-audio-backend] [-audio-backend]\n"
"[-no-script] [-script] [-no-scripttools] [-scripttools]\n"
- "[-no-webkit] [-webkit] [-graphicssystem raster|opengl|openvg]\n\n", 0, 7);
+ "[-no-webkit] [-webkit] [-webkit-debug] [-graphicssystem raster|opengl|openvg]\n\n", 0, 7);
desc("Installation options:\n\n");
@@ -1605,6 +1670,7 @@ bool Configure::displayHelp()
desc( "-docdir <dir>", "Documentation will be installed to dir\n(default PREFIX/doc)");
desc( "-headerdir <dir>", "Headers will be installed to dir\n(default PREFIX/include)");
desc( "-plugindir <dir>", "Plugins will be installed to dir\n(default PREFIX/plugins)");
+ desc( "-importdir <dir>", "Imports for QML will be installed to dir\n(default PREFIX/imports)");
desc( "-datadir <dir>", "Data used by Qt programs will be installed to dir\n(default PREFIX)");
desc( "-translationdir <dir>","Translations of Qt programs will be installed to dir\n(default PREFIX/translations)\n");
desc( "-examplesdir <dir>", "Examples will be installed to dir\n(default PREFIX/examples)");
@@ -1690,10 +1756,9 @@ bool Configure::displayHelp()
#endif
desc( "-graphicssystem <sys>", "Specify which graphicssystem should be used.\n"
"Available values for <sys>:");
- desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' ');
- desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' ');
- desc("GRAPHICS_SYSTEM", "openvg", "", " openvg - Using OpenVG acceleration, experimental!", ' ');
-
+ desc("GRAPHICS_SYSTEM", "raster", "", " raster - Software rasterizer", ' ');
+ desc("GRAPHICS_SYSTEM", "opengl", "", " opengl - Using OpenGL acceleration, experimental!", ' ');
+ desc("GRAPHICS_SYSTEM", "openvg", "", " openvg - Using OpenVG acceleration, experimental!\n", ' ');
desc( "-help, -h, -?", "Display this information.\n");
@@ -1704,22 +1769,22 @@ bool Configure::displayHelp()
desc("ZLIB", "qt", "-qt-zlib", "Use the zlib bundled with Qt.");
desc("ZLIB", "system", "-system-zlib", "Use zlib from the operating system.\nSee http://www.gzip.org/zlib\n");
- desc("GIF", "no", "-no-gif", "Do not compile the plugin for GIF reading support.");
- desc("GIF", "auto", "-qt-gif", "Compile the plugin for GIF reading support.\nSee also src/plugins/imageformats/gif/qgifhandler.h\n");
+ desc("GIF", "no", "-no-gif", "Do not compile GIF reading support.");
+ desc("GIF", "auto", "-qt-gif", "Compile GIF reading support.\nSee also src/gui/image/qgifhandler_p.h\n");
- desc("LIBPNG", "no", "-no-libpng", "Do not compile in PNG support.");
+ desc("LIBPNG", "no", "-no-libpng", "Do not compile PNG support.");
desc("LIBPNG", "qt", "-qt-libpng", "Use the libpng bundled with Qt.");
desc("LIBPNG", "system","-system-libpng", "Use libpng from the operating system.\nSee http://www.libpng.org/pub/png\n");
- desc("LIBMNG", "no", "-no-libmng", "Do not compile in MNG support.");
+ desc("LIBMNG", "no", "-no-libmng", "Do not compile MNG support.");
desc("LIBMNG", "qt", "-qt-libmng", "Use the libmng bundled with Qt.");
desc("LIBMNG", "system","-system-libmng", "Use libmng from the operating system.\nSee See http://www.libmng.com\n");
- desc("LIBTIFF", "no", "-no-libtiff", "Do not compile the plugin for TIFF support.");
+ desc("LIBTIFF", "no", "-no-libtiff", "Do not compile TIFF support.");
desc("LIBTIFF", "qt", "-qt-libtiff", "Use the libtiff bundled with Qt.");
desc("LIBTIFF", "system","-system-libtiff", "Use libtiff from the operating system.\nSee http://www.libtiff.org\n");
- desc("LIBJPEG", "no", "-no-libjpeg", "Do not compile the plugin for JPEG support.");
+ desc("LIBJPEG", "no", "-no-libjpeg", "Do not compile JPEG support.");
desc("LIBJPEG", "qt", "-qt-libjpeg", "Use the libjpeg bundled with Qt.");
desc("LIBJPEG", "system","-system-libjpeg", "Use libjpeg from the operating system.\nSee http://www.ijg.org\n");
@@ -1772,12 +1837,15 @@ bool Configure::displayHelp()
desc("AUDIO_BACKEND", "yes","-audio-backend", "Compile in the platform audio backend into QtMultimedia");
desc("WEBKIT", "no", "-no-webkit", "Do not compile in the WebKit module");
desc("WEBKIT", "yes", "-webkit", "Compile in the WebKit module (WebKit is built if a decent C++ compiler is used.)");
+ desc("WEBKIT", "debug", "-webkit-debug", "Compile in the WebKit module with debug symbols.");
desc("SCRIPT", "no", "-no-script", "Do not build the QtScript module.");
desc("SCRIPT", "yes", "-script", "Build the QtScript module.");
desc("SCRIPTTOOLS", "no", "-no-scripttools", "Do not build the QtScriptTools module.");
desc("SCRIPTTOOLS", "yes", "-scripttools", "Build the QtScriptTools module.");
desc("DECLARATIVE", "no", "-no-declarative", "Do not build the declarative module");
desc("DECLARATIVE", "yes", "-declarative", "Build the declarative module");
+ desc("DECLARATIVE_DEBUG", "no", "-no-declarative-debug", "Do not build the declarative debugging support");
+ desc("DECLARATIVE_DEBUG", "yes", "-declarative-debug", "Build the declarative debugging support");
desc( "-arch <arch>", "Specify an architecture.\n"
"Available values for <arch>:");
@@ -1802,6 +1870,8 @@ bool Configure::displayHelp()
desc("STYLE_S60" , "yes", "", " s60\n", ' ');
desc("NATIVE_GESTURES", "no", "-no-native-gestures", "Do not use native gestures on Windows 7.");
desc("NATIVE_GESTURES", "yes", "-native-gestures", "Use native gestures on Windows 7.");
+ desc("MSVC_MP", "no", "-no-mp", "Do not use multiple processors for compiling with MSVC");
+ desc("MSVC_MP", "yes", "-mp", "Use multiple processors for compiling with MSVC (-MP)");
/* We do not support -qconfig on Windows yet
@@ -1826,7 +1896,6 @@ bool Configure::displayHelp()
desc("CETEST", "yes", "-cetest", "Compile Windows CE remote test application");
desc( "-signature <file>", "Use file for signing the target project");
desc("OPENGL_ES_CM", "no", "-opengl-es-cm", "Enable support for OpenGL ES Common");
- desc("OPENGL_ES_CL", "no", "-opengl-es-cl", "Enable support for OpenGL ES Common Lite");
desc("OPENGL_ES_2", "no", "-opengl-es-2", "Enable support for OpenGL ES 2.0");
desc("DIRECTSHOW", "no", "-phonon-wince-ds9", "Enable Phonon Direct Show 9 backend for Windows CE");
@@ -1853,35 +1922,43 @@ QString Configure::findFileInPaths(const QString &fileName, const QString &paths
#endif
QStringList pathList = paths.split(splitReg, QString::SkipEmptyParts);
QDir d;
- for( QStringList::ConstIterator it = pathList.begin(); it != pathList.end(); ++it ) {
+ for (QStringList::ConstIterator it = pathList.begin(); it != pathList.end(); ++it) {
// Remove any leading or trailing ", this is commonly used in the environment
// variables
QString path = (*it);
- if ( path.startsWith( '\"' ) )
- path = path.right( path.length() - 1 );
- if ( path.endsWith( '\"' ) )
- path = path.left( path.length() - 1 );
- if( d.exists( path + QDir::separator() + fileName ) )
+ if (path.startsWith('\"'))
+ path = path.right(path.length() - 1);
+ if (path.endsWith('\"'))
+ path = path.left(path.length() - 1);
+ if (d.exists(path + QDir::separator() + fileName))
return path;
}
return QString();
}
-bool Configure::findFile( const QString &fileName )
+bool Configure::findFile(const QString &fileName)
{
const QString file = fileName.toLower();
const QString pathEnvVar = QString::fromLocal8Bit(getenv("PATH"));
const QString mingwPath = dictionary["QMAKESPEC"].endsWith("-g++") ?
- findFileInPaths("mingw32-g++.exe", pathEnvVar) : QString();
+ findFileInPaths("g++.exe", pathEnvVar) : QString();
QString paths;
if (file.endsWith(".h")) {
- if (!mingwPath.isNull() && !findFileInPaths(file, mingwPath + QLatin1String("/../include")).isNull())
- return true;
+ if (!mingwPath.isNull()) {
+ if (!findFileInPaths(file, mingwPath + QLatin1String("/../include")).isNull())
+ return true;
+ //now let's try the additional compiler path
+ QDir mingwLibDir = mingwPath + QLatin1String("/../lib/gcc/mingw32");
+ foreach(const QFileInfo &version, mingwLibDir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
+ if (!findFileInPaths(file, version.absoluteFilePath() + QLatin1String("/include")).isNull())
+ return true;
+ }
+ }
paths = QString::fromLocal8Bit(getenv("INCLUDE"));
- } else if ( file.endsWith( ".lib" ) || file.endsWith( ".a" ) ) {
+ } else if (file.endsWith(".lib") || file.endsWith(".a")) {
if (!mingwPath.isNull() && !findFileInPaths(file, mingwPath + QLatin1String("/../lib")).isNull())
- return true;
+ return true;
paths = QString::fromLocal8Bit(getenv("LIB"));
} else {
paths = pathEnvVar;
@@ -1904,21 +1981,28 @@ QString Configure::defaultTo(const QString &option)
|| option == "LIBTIFF")
return "system";
- // We want PNG built-in
+ // PNG is always built-in, never a plugin
if (option == "PNG")
- return "qt";
-
- // The JPEG image library can only be a plugin
- if (option == "JPEG"
- || option == "MNG" || option == "TIFF")
- return "plugin";
-
- // GIF off by default
- if (option == "GIF") {
- if (dictionary["SHARED"] == "yes")
+ return "yes";
+
+ // These database drivers and image formats can be built-in or plugins.
+ // Prefer plugins when Qt is shared.
+ if (dictionary[ "SHARED" ] == "yes") {
+ if (option == "SQL_MYSQL"
+ || option == "SQL_MYSQL"
+ || option == "SQL_ODBC"
+ || option == "SQL_OCI"
+ || option == "SQL_PSQL"
+ || option == "SQL_TDS"
+ || option == "SQL_DB2"
+ || option == "SQL_SQLITE"
+ || option == "SQL_SQLITE2"
+ || option == "SQL_IBASE"
+ || option == "JPEG"
+ || option == "MNG"
+ || option == "TIFF"
+ || option == "GIF")
return "plugin";
- else
- return "yes";
}
// By default we do not want to compile OCI driver when compiling with
@@ -1928,18 +2012,6 @@ QString Configure::defaultTo(const QString &option)
&& option == "SQL_OCI")
return "no";
- if (option == "SQL_MYSQL"
- || option == "SQL_MYSQL"
- || option == "SQL_ODBC"
- || option == "SQL_OCI"
- || option == "SQL_PSQL"
- || option == "SQL_TDS"
- || option == "SQL_DB2"
- || option == "SQL_SQLITE"
- || option == "SQL_SQLITE2"
- || option == "SQL_IBASE")
- return "plugin";
-
if (option == "SYNCQT"
&& (!QFile::exists(sourcePath + "/bin/syncqt") ||
!QFile::exists(sourcePath + "/bin/syncqt.bat")))
@@ -1956,7 +2028,7 @@ bool Configure::checkAvailability(const QString &part)
{
bool available = false;
if (part == "STYLE_WINDOWSXP")
- available = (findFile("uxtheme.h"));
+ available = findFile("uxtheme.h");
else if (part == "ZLIB")
available = findFile("zlib.h");
@@ -1988,15 +2060,15 @@ bool Configure::checkAvailability(const QString &part)
available = true; // Built in, we have a fork
else if (part == "SQL_SQLITE_LIB") {
if (dictionary[ "SQL_SQLITE_LIB" ] == "system") {
- // Symbian has multiple .lib/.dll files we need to find
+ // Symbian has multiple .lib/.dll files we need to find
if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) {
- available = true; // There is sqlite_symbian plugin which exports the necessary stuff
- dictionary[ "QT_LFLAGS_SQLITE" ] += "-lsqlite3";
- } else {
- available = findFile("sqlite3.h") && findFile("sqlite3.lib");
- if (available)
- dictionary[ "QT_LFLAGS_SQLITE" ] += "sqlite3.lib";
- }
+ available = true; // There is sqlite_symbian plugin which exports the necessary stuff
+ dictionary[ "QT_LFLAGS_SQLITE" ] += "-lsqlite3";
+ } else {
+ available = findFile("sqlite3.h") && findFile("sqlite3.lib");
+ if (available)
+ dictionary[ "QT_LFLAGS_SQLITE" ] += "sqlite3.lib";
+ }
} else
available = true;
} else if (part == "SQL_SQLITE2")
@@ -2007,18 +2079,16 @@ bool Configure::checkAvailability(const QString &part)
available = (dictionary[ "ARCHITECTURE" ] == "windowsce");
else if (part == "OPENGL_ES_CM")
available = (dictionary[ "ARCHITECTURE" ] == "windowsce");
- else if (part == "OPENGL_ES_CL")
- available = (dictionary[ "ARCHITECTURE" ] == "windowsce");
else if (part == "OPENGL_ES_2")
available = (dictionary[ "ARCHITECTURE" ] == "windowsce");
else if (part == "DIRECTSHOW")
available = (dictionary[ "ARCHITECTURE" ] == "windowsce");
else if (part == "SSE2")
- available = (dictionary.value("QMAKESPEC") != "win32-msvc") && (dictionary.value("QMAKESPEC") != "win32-g++");
- else if (part == "3DNOW" )
- available = (dictionary.value("QMAKESPEC") != "win32-msvc") && (dictionary.value("QMAKESPEC") != "win32-icc") && findFile("mm3dnow.h") && (dictionary.value("QMAKESPEC") != "win32-g++");
+ available = (dictionary.value("QMAKESPEC") != "win32-msvc");
+ else if (part == "3DNOW")
+ available = (dictionary.value("QMAKESPEC") != "win32-msvc") && (dictionary.value("QMAKESPEC") != "win32-icc") && findFile("mm3dnow.h");
else if (part == "MMX" || part == "SSE")
- available = (dictionary.value("QMAKESPEC") != "win32-msvc") && (dictionary.value("QMAKESPEC") != "win32-g++");
+ available = (dictionary.value("QMAKESPEC") != "win32-msvc");
else if (part == "OPENSSL")
available = findFile("openssl\\ssl.h");
else if (part == "DBUS")
@@ -2047,29 +2117,38 @@ bool Configure::checkAvailability(const QString &part)
&& dictionary.value("QMAKESPEC") != "win32-msvc2002"
&& dictionary.value("EXCEPTIONS") == "yes";
} else if (part == "PHONON") {
- available = findFile("vmr9.h") && findFile("dshow.h") && findFile("dmo.h") && findFile("dmodshow.h")
- && (findFile("strmiids.lib") || findFile("libstrmiids.a"))
- && (findFile("dmoguids.lib") || findFile("libdmoguids.a"))
- && (findFile("msdmo.lib") || findFile("libmsdmo.a"))
- && findFile("d3d9.h");
-
- if (!available) {
- cout << "All the required DirectShow/Direct3D files couldn't be found." << endl
- << "Make sure you have either the platform SDK AND the DirectShow SDK or the Windows SDK installed." << endl
- << "If you have the DirectShow SDK installed, please make sure that you have run the <path to SDK>\\SetEnv.Cmd script." << endl;
- if (!findFile("vmr9.h")) cout << "vmr9.h not found" << endl;
- if (!findFile("dshow.h")) cout << "dshow.h not found" << endl;
- if (!findFile("strmiids.lib")) cout << "strmiids.lib not found" << endl;
- if (!findFile("dmoguids.lib")) cout << "dmoguids.lib not found" << endl;
- if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl;
- if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl;
- }
- } else if (part == "MULTIMEDIA" || part == "SCRIPT" || part == "SCRIPTTOOLS") {
+ if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) {
+ available = true;
+ } else {
+ available = findFile("vmr9.h") && findFile("dshow.h") && findFile("dmo.h") && findFile("dmodshow.h")
+ && (findFile("strmiids.lib") || findFile("libstrmiids.a"))
+ && (findFile("dmoguids.lib") || findFile("libdmoguids.a"))
+ && (findFile("msdmo.lib") || findFile("libmsdmo.a"))
+ && findFile("d3d9.h");
+
+ if (!available) {
+ cout << "All the required DirectShow/Direct3D files couldn't be found." << endl
+ << "Make sure you have either the platform SDK AND the DirectShow SDK or the Windows SDK installed." << endl
+ << "If you have the DirectShow SDK installed, please make sure that you have run the <path to SDK>\\SetEnv.Cmd script." << endl;
+ if (!findFile("vmr9.h")) cout << "vmr9.h not found" << endl;
+ if (!findFile("dshow.h")) cout << "dshow.h not found" << endl;
+ if (!findFile("strmiids.lib")) cout << "strmiids.lib not found" << endl;
+ if (!findFile("dmoguids.lib")) cout << "dmoguids.lib not found" << endl;
+ if (!findFile("msdmo.lib")) cout << "msdmo.lib not found" << endl;
+ if (!findFile("d3d9.h")) cout << "d3d9.h not found" << endl;
+ }
+ }
+ } else if (part == "WMSDK") {
+ available = findFile("wmsdk.h");
+ } else if (part == "MULTIMEDIA" || part == "SCRIPT" || part == "SCRIPTTOOLS" || part == "DECLARATIVE") {
available = true;
} else if (part == "WEBKIT") {
- available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-g++");
- } else if (part == "DECLARATIVE") {
- available = QFile::exists(sourcePath + "/src/declarative/qml/qmlcomponent.h");
+ available = (dictionary.value("QMAKESPEC") == "win32-msvc2005") || (dictionary.value("QMAKESPEC") == "win32-msvc2008") || (dictionary.value("QMAKESPEC") == "win32-msvc2010") || (dictionary.value("QMAKESPEC") == "win32-g++");
+ if (dictionary[ "SHARED" ] == "no") {
+ cout << endl << "WARNING: Using static linking will disable the WebKit module." << endl
+ << endl;
+ available = false;
+ }
} else if (part == "AUDIO_BACKEND") {
available = true;
if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) {
@@ -2195,7 +2274,7 @@ void Configure::autoDetection()
if (dictionary["SCRIPT"] == "auto")
dictionary["SCRIPT"] = checkAvailability("SCRIPT") ? "yes" : "no";
if (dictionary["SCRIPTTOOLS"] == "auto")
- dictionary["SCRIPTTOOLS"] = checkAvailability("SCRIPTTOOLS") ? "yes" : "no";
+ dictionary["SCRIPTTOOLS"] = dictionary["SCRIPT"] == "yes" ? "yes" : "no";
if (dictionary["XMLPATTERNS"] == "auto")
dictionary["XMLPATTERNS"] = checkAvailability("XMLPATTERNS") ? "yes" : "no";
if (dictionary["PHONON"] == "auto")
@@ -2203,9 +2282,13 @@ void Configure::autoDetection()
if (dictionary["WEBKIT"] == "auto")
dictionary["WEBKIT"] = checkAvailability("WEBKIT") ? "yes" : "no";
if (dictionary["DECLARATIVE"] == "auto")
- dictionary["DECLARATIVE"] = checkAvailability("DECLARATIVE") ? "yes" : "no";
+ dictionary["DECLARATIVE"] = dictionary["SCRIPT"] == "yes" ? "yes" : "no";
+ if (dictionary["DECLARATIVE_DEBUG"] == "auto")
+ dictionary["DECLARATIVE_DEBUG"] = dictionary["DECLARATIVE"] == "yes" ? "yes" : "no";
if (dictionary["AUDIO_BACKEND"] == "auto")
dictionary["AUDIO_BACKEND"] = checkAvailability("AUDIO_BACKEND") ? "yes" : "no";
+ if (dictionary["WMSDK"] == "auto")
+ dictionary["WMSDK"] = checkAvailability("WMSDK") ? "yes" : "no";
// Qt/WinCE remote test application
if (dictionary["CETEST"] == "auto")
@@ -2228,7 +2311,7 @@ bool Configure::verifyConfiguration()
cout << "WARNING: Configure could not detect the presence of a system SQLite3 lib." << endl
<< "Configure will therefore continue with the SQLite3 lib bundled with Qt." << endl
<< "(Press any key to continue..)";
- if(_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
+ if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
exit(0); // Exit cleanly for Ctrl+C
dictionary["SQL_SQLITE_LIB"] = "qt"; // Set to Qt's bundled lib an continue
@@ -2239,25 +2322,33 @@ bool Configure::verifyConfiguration()
<< "MinGW, due to lack of such support from Oracle. Consider disabling the" << endl
<< "Oracle driver, as the current build will most likely fail." << endl;
cout << "(Press any key to continue..)";
- if(_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
+ if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
exit(0); // Exit cleanly for Ctrl+C
}
if (dictionary["QMAKESPEC"].endsWith("win32-msvc.net")) {
cout << "WARNING: The makespec win32-msvc.net is deprecated. Consider using" << endl
<< "win32-msvc2002 or win32-msvc2003 instead." << endl;
cout << "(Press any key to continue..)";
- if(_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
+ if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
exit(0); // Exit cleanly for Ctrl+C
}
- if (0 != dictionary["ARM_FPU_TYPE"].size())
- {
- QStringList l= QStringList()
- << "softvfp"
- << "softvfp+vfpv2"
- << "vfpv2";
- if (!(l.contains(dictionary["ARM_FPU_TYPE"])))
- cout << QString("WARNING: Using unsupported fpu flag: %1").arg(dictionary["ARM_FPU_TYPE"]) << endl;
- }
+ if (0 != dictionary["ARM_FPU_TYPE"].size()) {
+ QStringList l= QStringList()
+ << "softvfp"
+ << "softvfp+vfpv2"
+ << "vfpv2";
+ if (!(l.contains(dictionary["ARM_FPU_TYPE"])))
+ cout << QString("WARNING: Using unsupported fpu flag: %1").arg(dictionary["ARM_FPU_TYPE"]) << endl;
+ }
+ if (dictionary["DECLARATIVE"] == "yes" && dictionary["SCRIPT"] == "no") {
+ cout << "WARNING: To be able to compile QtDeclarative we need to also compile the" << endl
+ << "QtScript module. If you continue, we will turn on the QtScript module." << endl
+ << "(Press any key to continue..)";
+ if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
+ exit(0); // Exit cleanly for Ctrl+C
+
+ dictionary["SCRIPT"] = "yes";
+ }
return true;
}
@@ -2330,7 +2421,7 @@ void Configure::generateBuildKey()
+ buildSymbianKey + "\"\n"
"#else\n"
// Debug builds
- "# if (defined(_DEBUG) || defined(DEBUG))\n"
+ "# if !defined(QT_NO_DEBUG)\n"
"# if (defined(WIN64) || defined(_WIN64) || defined(__WIN64__))\n"
+ build64Key.arg("debug") + "\"\n"
"# else\n"
@@ -2353,13 +2444,13 @@ void Configure::generateOutputVars()
{
// Generate variables for output
// Build key ----------------------------------------------------
- if ( dictionary.contains("BUILD_KEY") ) {
+ if (dictionary.contains("BUILD_KEY")) {
qmakeVars += dictionary.value("BUILD_KEY");
}
QString build = dictionary[ "BUILD" ];
bool buildAll = (dictionary[ "BUILDALL" ] == "yes");
- if ( build == "debug") {
+ if (build == "debug") {
if (buildAll)
qtConfig += "release";
qtConfig += "debug";
@@ -2370,142 +2461,146 @@ void Configure::generateOutputVars()
}
// Compression --------------------------------------------------
- if( dictionary[ "ZLIB" ] == "qt" )
+ if (dictionary[ "ZLIB" ] == "qt")
qtConfig += "zlib";
- else if( dictionary[ "ZLIB" ] == "system" )
+ else if (dictionary[ "ZLIB" ] == "system")
qtConfig += "system-zlib";
// Image formates -----------------------------------------------
- if( dictionary[ "GIF" ] == "no" )
+ if (dictionary[ "GIF" ] == "no")
qtConfig += "no-gif";
- else if( dictionary[ "GIF" ] == "yes" )
+ else if (dictionary[ "GIF" ] == "yes")
qtConfig += "gif";
- else if( dictionary[ "GIF" ] == "plugin" )
+ else if (dictionary[ "GIF" ] == "plugin")
qmakeFormatPlugins += "gif";
- if( dictionary[ "TIFF" ] == "no" )
- qtConfig += "no-tiff";
- else if( dictionary[ "TIFF" ] == "plugin" )
+ if (dictionary[ "TIFF" ] == "no")
+ qtConfig += "no-tiff";
+ else if (dictionary[ "TIFF" ] == "yes")
+ qtConfig += "tiff";
+ else if (dictionary[ "TIFF" ] == "plugin")
qmakeFormatPlugins += "tiff";
- if( dictionary[ "LIBTIFF" ] == "system" )
+ if (dictionary[ "LIBTIFF" ] == "system")
qtConfig += "system-tiff";
- if( dictionary[ "JPEG" ] == "no" )
+ if (dictionary[ "JPEG" ] == "no")
qtConfig += "no-jpeg";
- else if( dictionary[ "JPEG" ] == "plugin" )
+ else if (dictionary[ "JPEG" ] == "yes")
+ qtConfig += "jpeg";
+ else if (dictionary[ "JPEG" ] == "plugin")
qmakeFormatPlugins += "jpeg";
- if( dictionary[ "LIBJPEG" ] == "system" )
+ if (dictionary[ "LIBJPEG" ] == "system")
qtConfig += "system-jpeg";
- if( dictionary[ "PNG" ] == "no" )
+ if (dictionary[ "PNG" ] == "no")
qtConfig += "no-png";
- else if( dictionary[ "PNG" ] == "qt" )
+ else if (dictionary[ "PNG" ] == "yes")
qtConfig += "png";
- if( dictionary[ "LIBPNG" ] == "system" )
+ if (dictionary[ "LIBPNG" ] == "system")
qtConfig += "system-png";
- if( dictionary[ "MNG" ] == "no" )
+ if (dictionary[ "MNG" ] == "no")
qtConfig += "no-mng";
- else if( dictionary[ "MNG" ] == "qt" )
+ else if (dictionary[ "MNG" ] == "yes")
qtConfig += "mng";
- if( dictionary[ "LIBMNG" ] == "system" )
+ if (dictionary[ "LIBMNG" ] == "system")
qtConfig += "system-mng";
// Text rendering --------------------------------------------------
- if( dictionary[ "FREETYPE" ] == "yes" )
+ if (dictionary[ "FREETYPE" ] == "yes")
qtConfig += "freetype";
// Styles -------------------------------------------------------
- if ( dictionary[ "STYLE_WINDOWS" ] == "yes" )
+ if (dictionary[ "STYLE_WINDOWS" ] == "yes")
qmakeStyles += "windows";
- if ( dictionary[ "STYLE_PLASTIQUE" ] == "yes" )
+ if (dictionary[ "STYLE_PLASTIQUE" ] == "yes")
qmakeStyles += "plastique";
- if ( dictionary[ "STYLE_CLEANLOOKS" ] == "yes" )
+ if (dictionary[ "STYLE_CLEANLOOKS" ] == "yes")
qmakeStyles += "cleanlooks";
- if ( dictionary[ "STYLE_WINDOWSXP" ] == "yes" )
+ if (dictionary[ "STYLE_WINDOWSXP" ] == "yes")
qmakeStyles += "windowsxp";
- if ( dictionary[ "STYLE_WINDOWSVISTA" ] == "yes" )
+ if (dictionary[ "STYLE_WINDOWSVISTA" ] == "yes")
qmakeStyles += "windowsvista";
- if ( dictionary[ "STYLE_MOTIF" ] == "yes" )
+ if (dictionary[ "STYLE_MOTIF" ] == "yes")
qmakeStyles += "motif";
- if ( dictionary[ "STYLE_SGI" ] == "yes" )
+ if (dictionary[ "STYLE_SGI" ] == "yes")
qmakeStyles += "sgi";
- if ( dictionary[ "STYLE_WINDOWSCE" ] == "yes" )
+ if (dictionary[ "STYLE_WINDOWSCE" ] == "yes")
qmakeStyles += "windowsce";
- if ( dictionary[ "STYLE_WINDOWSMOBILE" ] == "yes" )
+ if (dictionary[ "STYLE_WINDOWSMOBILE" ] == "yes")
qmakeStyles += "windowsmobile";
- if ( dictionary[ "STYLE_CDE" ] == "yes" )
+ if (dictionary[ "STYLE_CDE" ] == "yes")
qmakeStyles += "cde";
- if ( dictionary[ "STYLE_S60" ] == "yes" )
+ if (dictionary[ "STYLE_S60" ] == "yes")
qmakeStyles += "s60";
// Databases ----------------------------------------------------
- if ( dictionary[ "SQL_MYSQL" ] == "yes" )
+ if (dictionary[ "SQL_MYSQL" ] == "yes")
qmakeSql += "mysql";
- else if ( dictionary[ "SQL_MYSQL" ] == "plugin" )
+ else if (dictionary[ "SQL_MYSQL" ] == "plugin")
qmakeSqlPlugins += "mysql";
- if ( dictionary[ "SQL_ODBC" ] == "yes" )
+ if (dictionary[ "SQL_ODBC" ] == "yes")
qmakeSql += "odbc";
- else if ( dictionary[ "SQL_ODBC" ] == "plugin" )
+ else if (dictionary[ "SQL_ODBC" ] == "plugin")
qmakeSqlPlugins += "odbc";
- if ( dictionary[ "SQL_OCI" ] == "yes" )
+ if (dictionary[ "SQL_OCI" ] == "yes")
qmakeSql += "oci";
- else if ( dictionary[ "SQL_OCI" ] == "plugin" )
+ else if (dictionary[ "SQL_OCI" ] == "plugin")
qmakeSqlPlugins += "oci";
- if ( dictionary[ "SQL_PSQL" ] == "yes" )
+ if (dictionary[ "SQL_PSQL" ] == "yes")
qmakeSql += "psql";
- else if ( dictionary[ "SQL_PSQL" ] == "plugin" )
+ else if (dictionary[ "SQL_PSQL" ] == "plugin")
qmakeSqlPlugins += "psql";
- if ( dictionary[ "SQL_TDS" ] == "yes" )
+ if (dictionary[ "SQL_TDS" ] == "yes")
qmakeSql += "tds";
- else if ( dictionary[ "SQL_TDS" ] == "plugin" )
+ else if (dictionary[ "SQL_TDS" ] == "plugin")
qmakeSqlPlugins += "tds";
- if ( dictionary[ "SQL_DB2" ] == "yes" )
+ if (dictionary[ "SQL_DB2" ] == "yes")
qmakeSql += "db2";
- else if ( dictionary[ "SQL_DB2" ] == "plugin" )
+ else if (dictionary[ "SQL_DB2" ] == "plugin")
qmakeSqlPlugins += "db2";
- if ( dictionary[ "SQL_SQLITE" ] == "yes" )
+ if (dictionary[ "SQL_SQLITE" ] == "yes")
qmakeSql += "sqlite";
- else if ( dictionary[ "SQL_SQLITE" ] == "plugin" )
+ else if (dictionary[ "SQL_SQLITE" ] == "plugin")
qmakeSqlPlugins += "sqlite";
- if ( dictionary[ "SQL_SQLITE_LIB" ] == "system" )
+ if (dictionary[ "SQL_SQLITE_LIB" ] == "system")
qmakeConfig += "system-sqlite";
- if ( dictionary[ "SQL_SQLITE2" ] == "yes" )
+ if (dictionary[ "SQL_SQLITE2" ] == "yes")
qmakeSql += "sqlite2";
- else if ( dictionary[ "SQL_SQLITE2" ] == "plugin" )
+ else if (dictionary[ "SQL_SQLITE2" ] == "plugin")
qmakeSqlPlugins += "sqlite2";
- if ( dictionary[ "SQL_IBASE" ] == "yes" )
+ if (dictionary[ "SQL_IBASE" ] == "yes")
qmakeSql += "ibase";
- else if ( dictionary[ "SQL_IBASE" ] == "plugin" )
+ else if (dictionary[ "SQL_IBASE" ] == "plugin")
qmakeSqlPlugins += "ibase";
// Other options ------------------------------------------------
- if( dictionary[ "BUILDALL" ] == "yes" ) {
+ if (dictionary[ "BUILDALL" ] == "yes") {
qmakeConfig += "build_all";
}
qmakeConfig += dictionary[ "BUILD" ];
dictionary[ "QMAKE_OUTDIR" ] = dictionary[ "BUILD" ];
- if ( dictionary[ "SHARED" ] == "yes" ) {
+ if (dictionary[ "SHARED" ] == "yes") {
QString version = dictionary[ "VERSION" ];
if (!version.isEmpty()) {
qmakeVars += "QMAKE_QT_VERSION_OVERRIDE = " + version.left(version.indexOf("."));
@@ -2516,14 +2611,14 @@ void Configure::generateOutputVars()
dictionary[ "QMAKE_OUTDIR" ] += "_static";
}
- if( dictionary[ "ACCESSIBILITY" ] == "yes" )
+ if (dictionary[ "ACCESSIBILITY" ] == "yes")
qtConfig += "accessibility";
- if( !qmakeLibs.isEmpty() )
- qmakeVars += "LIBS += " + qmakeLibs.join( " " );
+ if (!qmakeLibs.isEmpty())
+ qmakeVars += "LIBS += " + escapeSeparators(qmakeLibs.join(" "));
- if( !dictionary["QT_LFLAGS_SQLITE"].isEmpty() )
- qmakeVars += "QT_LFLAGS_SQLITE += " + dictionary["QT_LFLAGS_SQLITE"];
+ if (!dictionary["QT_LFLAGS_SQLITE"].isEmpty())
+ qmakeVars += "QT_LFLAGS_SQLITE += " + escapeSeparators(dictionary["QT_LFLAGS_SQLITE"]);
if (dictionary[ "QT3SUPPORT" ] == "yes")
qtConfig += "qt3support";
@@ -2531,31 +2626,26 @@ void Configure::generateOutputVars()
if (dictionary[ "OPENGL" ] == "yes")
qtConfig += "opengl";
- if ( dictionary["OPENGL_ES_CM"] == "yes" ) {
+ if (dictionary["OPENGL_ES_CM"] == "yes") {
qtConfig += "opengles1";
qtConfig += "egl";
}
- if ( dictionary["OPENGL_ES_2"] == "yes" ) {
+ if (dictionary["OPENGL_ES_2"] == "yes") {
qtConfig += "opengles2";
qtConfig += "egl";
}
- if ( dictionary["OPENGL_ES_CL"] == "yes" ) {
- qtConfig += "opengles1cl";
- qtConfig += "egl";
- }
-
- if ( dictionary["OPENVG"] == "yes" ) {
+ if (dictionary["OPENVG"] == "yes") {
qtConfig += "openvg";
qtConfig += "egl";
}
- if ( dictionary["S60"] == "yes" ) {
+ if (dictionary["S60"] == "yes") {
qtConfig += "s60";
}
- if ( dictionary["DIRECTSHOW"] == "yes" )
+ if (dictionary["DIRECTSHOW"] == "yes")
qtConfig += "directshow";
if (dictionary[ "OPENSSL" ] == "yes")
@@ -2603,13 +2693,26 @@ void Configure::generateOutputVars()
qtConfig += "audio-backend";
}
- if (dictionary["WEBKIT"] == "yes")
- qtConfig += "webkit";
+ QString dst = buildPath + "/mkspecs/modules/qt_webkit_version.pri";
+ QFile::remove(dst);
+ if (dictionary["WEBKIT"] != "no") {
+ // This include takes care of adding "webkit" to QT_CONFIG.
+ QString src = sourcePath + "/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri";
+ QFile::copy(src, dst);
+ if (dictionary["WEBKIT"] == "debug")
+ qtConfig += "webkit-debug";
+ }
- if (dictionary["DECLARATIVE"] == "yes")
+ if (dictionary["DECLARATIVE"] == "yes") {
+ if (dictionary[ "SCRIPT" ] == "no") {
+ cout << "QtDeclarative was requested, but it can't be built due to QtScript being "
+ "disabled." << endl;
+ dictionary[ "DONE" ] = "error";
+ }
qtConfig += "declarative";
+ }
- if( dictionary[ "NATIVE_GESTURES" ] == "yes" )
+ if (dictionary[ "NATIVE_GESTURES" ] == "yes")
qtConfig += "native-gestures";
// We currently have no switch for QtSvg, so add it unconditionally.
@@ -2632,7 +2735,7 @@ void Configure::generateOutputVars()
}
}
- if (dictionary.contains("XQMAKESPEC") && ( dictionary["QMAKESPEC"] != dictionary["XQMAKESPEC"] ) )
+ if (dictionary.contains("XQMAKESPEC") && (dictionary["QMAKESPEC"] != dictionary["XQMAKESPEC"]))
qmakeConfig += "cross_compile";
// Directories and settings for .qmake.cache --------------------
@@ -2640,57 +2743,72 @@ void Configure::generateOutputVars()
// if QT_INSTALL_* have not been specified on commandline, define them now from QT_INSTALL_PREFIX
// if prefix is empty (WINCE), make all of them empty, if they aren't set
bool qipempty = false;
- if(dictionary[ "QT_INSTALL_PREFIX" ].isEmpty())
+ if (dictionary[ "QT_INSTALL_PREFIX" ].isEmpty())
qipempty = true;
- if( !dictionary[ "QT_INSTALL_DOCS" ].size() )
- dictionary[ "QT_INSTALL_DOCS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/doc" );
- if( !dictionary[ "QT_INSTALL_HEADERS" ].size() )
- dictionary[ "QT_INSTALL_HEADERS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/include" );
- if( !dictionary[ "QT_INSTALL_LIBS" ].size() )
- dictionary[ "QT_INSTALL_LIBS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/lib" );
- if( !dictionary[ "QT_INSTALL_BINS" ].size() )
- dictionary[ "QT_INSTALL_BINS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/bin" );
- if( !dictionary[ "QT_INSTALL_PLUGINS" ].size() )
- dictionary[ "QT_INSTALL_PLUGINS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/plugins" );
- if( !dictionary[ "QT_INSTALL_DATA" ].size() )
- dictionary[ "QT_INSTALL_DATA" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] );
- if( !dictionary[ "QT_INSTALL_TRANSLATIONS" ].size() )
- dictionary[ "QT_INSTALL_TRANSLATIONS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/translations" );
- if( !dictionary[ "QT_INSTALL_EXAMPLES" ].size() )
- dictionary[ "QT_INSTALL_EXAMPLES" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/examples");
- if( !dictionary[ "QT_INSTALL_DEMOS" ].size() )
- dictionary[ "QT_INSTALL_DEMOS" ] = qipempty ? "" : fixSeparators( dictionary[ "QT_INSTALL_PREFIX" ] + "/demos" );
-
- if(dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("linux"))
+ if (!dictionary[ "QT_INSTALL_DOCS" ].size())
+ dictionary[ "QT_INSTALL_DOCS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/doc");
+ if (!dictionary[ "QT_INSTALL_HEADERS" ].size())
+ dictionary[ "QT_INSTALL_HEADERS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/include");
+ if (!dictionary[ "QT_INSTALL_LIBS" ].size())
+ dictionary[ "QT_INSTALL_LIBS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/lib");
+ if (!dictionary[ "QT_INSTALL_BINS" ].size())
+ dictionary[ "QT_INSTALL_BINS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/bin");
+ if (!dictionary[ "QT_INSTALL_PLUGINS" ].size())
+ dictionary[ "QT_INSTALL_PLUGINS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/plugins");
+ if (!dictionary[ "QT_INSTALL_IMPORTS" ].size())
+ dictionary[ "QT_INSTALL_IMPORTS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/imports");
+ if (!dictionary[ "QT_INSTALL_DATA" ].size())
+ dictionary[ "QT_INSTALL_DATA" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ]);
+ if (!dictionary[ "QT_INSTALL_TRANSLATIONS" ].size())
+ dictionary[ "QT_INSTALL_TRANSLATIONS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/translations");
+ if (!dictionary[ "QT_INSTALL_EXAMPLES" ].size())
+ dictionary[ "QT_INSTALL_EXAMPLES" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/examples");
+ if (!dictionary[ "QT_INSTALL_DEMOS" ].size())
+ dictionary[ "QT_INSTALL_DEMOS" ] = qipempty ? "" : fixSeparators(dictionary[ "QT_INSTALL_PREFIX" ] + "/demos");
+
+ if (dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("linux"))
dictionary[ "QMAKE_RPATHDIR" ] = dictionary[ "QT_INSTALL_LIBS" ];
- qmakeVars += QString("OBJECTS_DIR = ") + fixSeparators( "tmp/obj/" + dictionary[ "QMAKE_OUTDIR" ] );
- qmakeVars += QString("MOC_DIR = ") + fixSeparators( "tmp/moc/" + dictionary[ "QMAKE_OUTDIR" ] );
- qmakeVars += QString("RCC_DIR = ") + fixSeparators("tmp/rcc/" + dictionary["QMAKE_OUTDIR"]);
+ qmakeVars += QString("OBJECTS_DIR = ") + fixSeparators("tmp/obj/" + dictionary[ "QMAKE_OUTDIR" ], true);
+ qmakeVars += QString("MOC_DIR = ") + fixSeparators("tmp/moc/" + dictionary[ "QMAKE_OUTDIR" ], true);
+ qmakeVars += QString("RCC_DIR = ") + fixSeparators("tmp/rcc/" + dictionary["QMAKE_OUTDIR"], true);
if (!qmakeDefines.isEmpty())
- qmakeVars += QString("DEFINES += ") + qmakeDefines.join( " " );
+ qmakeVars += QString("DEFINES += ") + qmakeDefines.join(" ");
if (!qmakeIncludes.isEmpty())
- qmakeVars += QString("INCLUDEPATH += ") + qmakeIncludes.join( " " );
+ qmakeVars += QString("INCLUDEPATH += ") + escapeSeparators(qmakeIncludes.join(" "));
if (!opensslLibs.isEmpty())
qmakeVars += opensslLibs;
else if (dictionary[ "OPENSSL" ] == "linked") {
- if(dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("symbian") )
+ if (dictionary.contains("XQMAKESPEC") && dictionary[ "XQMAKESPEC" ].startsWith("symbian"))
qmakeVars += QString("OPENSSL_LIBS = -llibssl -llibcrypto");
else
qmakeVars += QString("OPENSSL_LIBS = -lssleay32 -llibeay32");
}
+ if (!psqlLibs.isEmpty())
+ qmakeVars += QString("QT_LFLAGS_PSQL=") + psqlLibs.section("=", 1);
+
+ {
+ QStringList lflagsTDS;
+ if (!sybase.isEmpty())
+ lflagsTDS += QString("-L") + fixSeparators(sybase.section("=", 1) + "/lib");
+ if (!sybaseLibs.isEmpty())
+ lflagsTDS += sybaseLibs.section("=", 1);
+ if (!lflagsTDS.isEmpty())
+ qmakeVars += QString("QT_LFLAGS_TDS=") + lflagsTDS.join(" ");
+ }
+
if (!qmakeSql.isEmpty())
- qmakeVars += QString("sql-drivers += ") + qmakeSql.join( " " );
+ qmakeVars += QString("sql-drivers += ") + qmakeSql.join(" ");
if (!qmakeSqlPlugins.isEmpty())
- qmakeVars += QString("sql-plugins += ") + qmakeSqlPlugins.join( " " );
+ qmakeVars += QString("sql-plugins += ") + qmakeSqlPlugins.join(" ");
if (!qmakeStyles.isEmpty())
- qmakeVars += QString("styles += ") + qmakeStyles.join( " " );
+ qmakeVars += QString("styles += ") + qmakeStyles.join(" ");
if (!qmakeStylePlugins.isEmpty())
- qmakeVars += QString("style-plugins += ") + qmakeStylePlugins.join( " " );
+ qmakeVars += QString("style-plugins += ") + qmakeStylePlugins.join(" ");
if (!qmakeFormatPlugins.isEmpty())
- qmakeVars += QString("imageformat-plugins += ") + qmakeFormatPlugins.join( " " );
+ qmakeVars += QString("imageformat-plugins += ") + qmakeFormatPlugins.join(" ");
if (dictionary["QMAKESPEC"].endsWith("-g++")) {
QString includepath = qgetenv("INCLUDE");
@@ -2702,22 +2820,22 @@ void Configure::generateOutputVars()
qmakeVars += QString("QMAKE_LIBDIR_POST += $$split(TMPPATH,\"%1\")").arg(separator);
}
- if( !dictionary[ "QMAKESPEC" ].length() ) {
+ if (!dictionary[ "QMAKESPEC" ].length()) {
cout << "Configure could not detect your compiler. QMAKESPEC must either" << endl
<< "be defined as an environment variable, or specified as an" << endl
<< "argument with -platform" << endl;
dictionary[ "HELP" ] = "yes";
QStringList winPlatforms;
- QDir mkspecsDir( sourcePath + "/mkspecs" );
+ QDir mkspecsDir(sourcePath + "/mkspecs");
const QFileInfoList &specsList = mkspecsDir.entryInfoList();
- for(int i = 0; i < specsList.size(); ++i) {
+ for (int i = 0; i < specsList.size(); ++i) {
const QFileInfo &fi = specsList.at(i);
- if( fi.fileName().left( 5 ) == "win32" ) {
+ if (fi.fileName().left(5) == "win32") {
winPlatforms += fi.fileName();
}
}
- cout << "Available platforms are: " << qPrintable(winPlatforms.join( ", " )) << endl;
+ cout << "Available platforms are: " << qPrintable(winPlatforms.join(", ")) << endl;
dictionary[ "DONE" ] = "error";
}
}
@@ -2726,102 +2844,104 @@ void Configure::generateOutputVars()
void Configure::generateCachefile()
{
// Generate .qmake.cache
- QFile cacheFile( buildPath + "/.qmake.cache" );
- if( cacheFile.open( QFile::WriteOnly | QFile::Text ) ) { // Truncates any existing file.
- QTextStream cacheStream( &cacheFile );
- for( QStringList::Iterator var = qmakeVars.begin(); var != qmakeVars.end(); ++var ) {
+ QFile cacheFile(buildPath + "/.qmake.cache");
+ if (cacheFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
+ QTextStream cacheStream(&cacheFile);
+ for (QStringList::Iterator var = qmakeVars.begin(); var != qmakeVars.end(); ++var) {
cacheStream << (*var) << endl;
}
- cacheStream << "CONFIG += " << qmakeConfig.join( " " ) << " incremental create_prl link_prl depend_includepath QTDIR_build" << endl;
+ cacheStream << "CONFIG += " << qmakeConfig.join(" ") << " incremental msvc_mp create_prl link_prl depend_includepath QTDIR_build" << endl;
QStringList buildParts;
buildParts << "libs" << "tools" << "examples" << "demos" << "docs" << "translations";
foreach (const QString &item, disabledBuildParts) {
buildParts.removeAll(item);
}
- cacheStream << "QT_BUILD_PARTS = " << buildParts.join( " " ) << endl;
+ cacheStream << "QT_BUILD_PARTS = " << buildParts.join(" ") << endl;
QString targetSpec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
QString mkspec_path = fixSeparators(sourcePath + "/mkspecs/" + targetSpec);
- if(QFile::exists(mkspec_path))
- cacheStream << "QMAKESPEC = " << mkspec_path << endl;
+ if (QFile::exists(mkspec_path))
+ cacheStream << "QMAKESPEC = " << escapeSeparators(mkspec_path) << endl;
else
- cacheStream << "QMAKESPEC = " << fixSeparators(targetSpec) << endl;
- cacheStream << "ARCH = " << fixSeparators(dictionary[ "ARCHITECTURE" ]) << endl;
- cacheStream << "QT_BUILD_TREE = " << fixSeparators(dictionary[ "QT_BUILD_TREE" ]) << endl;
- cacheStream << "QT_SOURCE_TREE = " << fixSeparators(dictionary[ "QT_SOURCE_TREE" ]) << endl;
+ cacheStream << "QMAKESPEC = " << fixSeparators(targetSpec, true) << endl;
+ cacheStream << "ARCH = " << dictionary[ "ARCHITECTURE" ] << endl;
+ cacheStream << "QT_BUILD_TREE = " << fixSeparators(dictionary[ "QT_BUILD_TREE" ], true) << endl;
+ cacheStream << "QT_SOURCE_TREE = " << fixSeparators(dictionary[ "QT_SOURCE_TREE" ], true) << endl;
if (dictionary["QT_EDITION"] != "QT_EDITION_OPENSOURCE")
cacheStream << "DEFINES *= QT_EDITION=QT_EDITION_DESKTOP" << endl;
//so that we can build without an install first (which would be impossible)
- cacheStream << "QMAKE_MOC = $$QT_BUILD_TREE" << fixSeparators("/bin/moc.exe") << endl;
- cacheStream << "QMAKE_UIC = $$QT_BUILD_TREE" << fixSeparators("/bin/uic.exe") << endl;
- cacheStream << "QMAKE_UIC3 = $$QT_BUILD_TREE" << fixSeparators("/bin/uic3.exe") << endl;
- cacheStream << "QMAKE_RCC = $$QT_BUILD_TREE" << fixSeparators("/bin/rcc.exe") << endl;
- cacheStream << "QMAKE_DUMPCPP = $$QT_BUILD_TREE" << fixSeparators("/bin/dumpcpp.exe") << endl;
- cacheStream << "QMAKE_INCDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/include") << endl;
- cacheStream << "QMAKE_LIBDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/lib") << endl;
+ cacheStream << "QMAKE_MOC = $$QT_BUILD_TREE" << fixSeparators("/bin/moc.exe", true) << endl;
+ cacheStream << "QMAKE_UIC = $$QT_BUILD_TREE" << fixSeparators("/bin/uic.exe", true) << endl;
+ cacheStream << "QMAKE_UIC3 = $$QT_BUILD_TREE" << fixSeparators("/bin/uic3.exe", true) << endl;
+ cacheStream << "QMAKE_RCC = $$QT_BUILD_TREE" << fixSeparators("/bin/rcc.exe", true) << endl;
+ cacheStream << "QMAKE_DUMPCPP = $$QT_BUILD_TREE" << fixSeparators("/bin/dumpcpp.exe", true) << endl;
+ cacheStream << "QMAKE_INCDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/include", true) << endl;
+ cacheStream << "QMAKE_LIBDIR_QT = $$QT_BUILD_TREE" << fixSeparators("/lib", true) << endl;
if (dictionary["CETEST"] == "yes") {
- cacheStream << "QT_CE_RAPI_INC = " << fixSeparators(dictionary[ "QT_CE_RAPI_INC" ]) << endl;
- cacheStream << "QT_CE_RAPI_LIB = " << fixSeparators(dictionary[ "QT_CE_RAPI_LIB" ]) << endl;
+ cacheStream << "QT_CE_RAPI_INC = " << fixSeparators(dictionary[ "QT_CE_RAPI_INC" ], true) << endl;
+ cacheStream << "QT_CE_RAPI_LIB = " << fixSeparators(dictionary[ "QT_CE_RAPI_LIB" ], true) << endl;
}
// embedded
- if( !dictionary["KBD_DRIVERS"].isEmpty())
+ if (!dictionary["KBD_DRIVERS"].isEmpty())
cacheStream << "kbd-drivers += "<< dictionary["KBD_DRIVERS"]<<endl;
- if( !dictionary["GFX_DRIVERS"].isEmpty())
+ if (!dictionary["GFX_DRIVERS"].isEmpty())
cacheStream << "gfx-drivers += "<< dictionary["GFX_DRIVERS"]<<endl;
- if( !dictionary["MOUSE_DRIVERS"].isEmpty())
+ if (!dictionary["MOUSE_DRIVERS"].isEmpty())
cacheStream << "mouse-drivers += "<< dictionary["MOUSE_DRIVERS"]<<endl;
- if( !dictionary["DECORATIONS"].isEmpty())
+ if (!dictionary["DECORATIONS"].isEmpty())
cacheStream << "decorations += "<<dictionary["DECORATIONS"]<<endl;
- if( !dictionary["QMAKE_RPATHDIR"].isEmpty() )
+ if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
cacheStream << "QMAKE_RPATHDIR += "<<dictionary["QMAKE_RPATHDIR"];
cacheStream.flush();
cacheFile.close();
}
- QFile configFile( dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri" );
- if( configFile.open( QFile::WriteOnly | QFile::Text ) ) { // Truncates any existing file.
- QTextStream configStream( &configFile );
+ QFile configFile(dictionary[ "QT_BUILD_TREE" ] + "/mkspecs/qconfig.pri");
+ if (configFile.open(QFile::WriteOnly | QFile::Text)) { // Truncates any existing file.
+ QTextStream configStream(&configFile);
configStream << "CONFIG+= ";
configStream << dictionary[ "BUILD" ];
- if( dictionary[ "SHARED" ] == "yes" )
+ if (dictionary[ "SHARED" ] == "yes")
configStream << " shared";
else
configStream << " static";
- if( dictionary[ "LTCG" ] == "yes" )
+ if (dictionary[ "LTCG" ] == "yes")
configStream << " ltcg";
- if( dictionary[ "STL" ] == "yes" )
+ if (dictionary[ "MSVC_MP" ] == "yes")
+ configStream << " msvc_mp";
+ if (dictionary[ "STL" ] == "yes")
configStream << " stl";
- if ( dictionary[ "EXCEPTIONS" ] == "yes" )
+ if (dictionary[ "EXCEPTIONS" ] == "yes")
configStream << " exceptions";
- if ( dictionary[ "EXCEPTIONS" ] == "no" )
+ if (dictionary[ "EXCEPTIONS" ] == "no")
configStream << " exceptions_off";
- if ( dictionary[ "RTTI" ] == "yes" )
+ if (dictionary[ "RTTI" ] == "yes")
configStream << " rtti";
- if ( dictionary[ "MMX" ] == "yes" )
+ if (dictionary[ "MMX" ] == "yes")
configStream << " mmx";
- if ( dictionary[ "3DNOW" ] == "yes" )
+ if (dictionary[ "3DNOW" ] == "yes")
configStream << " 3dnow";
- if ( dictionary[ "SSE" ] == "yes" )
+ if (dictionary[ "SSE" ] == "yes")
configStream << " sse";
- if ( dictionary[ "SSE2" ] == "yes" )
+ if (dictionary[ "SSE2" ] == "yes")
configStream << " sse2";
- if ( dictionary[ "IWMMXT" ] == "yes" )
+ if (dictionary[ "IWMMXT" ] == "yes")
configStream << " iwmmxt";
- if ( dictionary["INCREDIBUILD_XGE"] == "yes" )
+ if (dictionary["INCREDIBUILD_XGE"] == "yes")
configStream << " incredibuild_xge";
- if ( dictionary["PLUGIN_MANIFESTS"] == "no" )
+ if (dictionary["PLUGIN_MANIFESTS"] == "no")
configStream << " no_plugin_manifest";
- if ( dictionary.contains("SYMBIAN_DEFFILES") ) {
- if(dictionary["SYMBIAN_DEFFILES"] == "yes" ) {
+ if (dictionary.contains("SYMBIAN_DEFFILES")) {
+ if (dictionary["SYMBIAN_DEFFILES"] == "yes") {
configStream << " def_files";
- } else if ( dictionary["SYMBIAN_DEFFILES"] == "no" ) {
+ } else if (dictionary["SYMBIAN_DEFFILES"] == "no") {
configStream << " def_files_disabled";
}
}
@@ -2840,21 +2960,24 @@ void Configure::generateCachefile()
<< "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl;
configStream << "#Qt for Windows CE c-runtime deployment" << endl
- << "QT_CE_C_RUNTIME = " << fixSeparators(dictionary[ "CE_CRT" ]) << endl;
+ << "QT_CE_C_RUNTIME = " << fixSeparators(dictionary[ "CE_CRT" ], true) << endl;
- if(dictionary["CE_SIGNATURE"] != QLatin1String("no"))
+ if (dictionary["CE_SIGNATURE"] != QLatin1String("no"))
configStream << "DEFAULT_SIGNATURE=" << dictionary["CE_SIGNATURE"] << endl;
- if(!dictionary["QMAKE_RPATHDIR"].isEmpty())
+ if (!dictionary["QMAKE_RPATHDIR"].isEmpty())
configStream << "QMAKE_RPATHDIR += " << dictionary["QMAKE_RPATHDIR"] << endl;
if (!dictionary["QT_LIBINFIX"].isEmpty())
configStream << "QT_LIBINFIX = " << dictionary["QT_LIBINFIX"] << endl;
configStream << "#Qt for Symbian FPU settings" << endl;
- if(!dictionary["ARM_FPU_TYPE"].isEmpty()) {
+ if (!dictionary["ARM_FPU_TYPE"].isEmpty()) {
configStream<<"MMP_RULES += \"ARMFPU "<< dictionary["ARM_FPU_TYPE"]<< "\"";
}
+ if (!dictionary["QT_NAMESPACE"].isEmpty()) {
+ configStream << "#namespaces" << endl << "QT_NAMESPACE = " << dictionary["QT_NAMESPACE"] << endl;
+ }
configStream.flush();
configFile.close();
@@ -2869,10 +2992,10 @@ QString Configure::addDefine(QString def)
defD.replace(QRegExp("=.*"), "");
def.replace(QRegExp("="), " ");
- if(def.startsWith("QT_NO_")) {
+ if (def.startsWith("QT_NO_")) {
defNeg = defD;
defNeg.replace("QT_NO_", "QT_");
- } else if(def.startsWith("QT_")) {
+ } else if (def.startsWith("QT_")) {
defNeg = defD;
defNeg.replace("QT_", "QT_NO_");
}
@@ -2898,30 +3021,30 @@ QString Configure::addDefine(QString def)
void Configure::generateConfigfiles()
{
QDir(buildPath).mkpath("src/corelib/global");
- QString outName( buildPath + "/src/corelib/global/qconfig.h" );
+ QString outName(buildPath + "/src/corelib/global/qconfig.h");
QTemporaryFile tmpFile;
QTextStream tmpStream;
- if(tmpFile.open()) {
+ if (tmpFile.open()) {
tmpStream.setDevice(&tmpFile);
- if( dictionary[ "QCONFIG" ] == "full" ) {
+ if (dictionary[ "QCONFIG" ] == "full") {
tmpStream << "/* Everything */" << endl;
} else {
- QString configName( "qconfig-" + dictionary[ "QCONFIG" ] + ".h" );
+ QString configName("qconfig-" + dictionary[ "QCONFIG" ] + ".h");
tmpStream << "/* Copied from " << configName << "*/" << endl;
tmpStream << "#ifndef QT_BOOTSTRAPPED" << endl;
- QFile inFile( sourcePath + "/src/corelib/global/" + configName );
- if( inFile.open( QFile::ReadOnly ) ) {
+ QFile inFile(sourcePath + "/src/corelib/global/" + configName);
+ if (inFile.open(QFile::ReadOnly)) {
QByteArray buffer = inFile.readAll();
- tmpFile.write( buffer.constData(), buffer.size() );
+ tmpFile.write(buffer.constData(), buffer.size());
inFile.close();
}
tmpStream << "#endif // QT_BOOTSTRAPPED" << endl;
}
tmpStream << endl;
- if( dictionary[ "SHARED" ] == "yes" ) {
+ if (dictionary[ "SHARED" ] == "yes") {
tmpStream << "#ifndef QT_DLL" << endl;
tmpStream << "#define QT_DLL" << endl;
tmpStream << "#endif" << endl;
@@ -2947,78 +3070,84 @@ void Configure::generateConfigfiles()
tmpStream << "/* Machine byte-order */" << endl;
tmpStream << "#define Q_BIG_ENDIAN 4321" << endl;
tmpStream << "#define Q_LITTLE_ENDIAN 1234" << endl;
- if ( QSysInfo::ByteOrder == QSysInfo::BigEndian )
+ if (QSysInfo::ByteOrder == QSysInfo::BigEndian)
tmpStream << "#define Q_BYTE_ORDER Q_BIG_ENDIAN" << endl;
else
tmpStream << "#define Q_BYTE_ORDER Q_LITTLE_ENDIAN" << endl;
tmpStream << endl << "// Compile time features" << endl;
tmpStream << "#define QT_ARCH_" << dictionary["ARCHITECTURE"].toUpper() << endl;
+ if (dictionary["GRAPHICS_SYSTEM"] == "runtime" && dictionary["RUNTIME_SYSTEM"] != "runtime")
+ tmpStream << "#define QT_DEFAULT_RUNTIME_SYSTEM \"" << dictionary["RUNTIME_SYSTEM"] << "\"" << endl;
+
QStringList qconfigList;
- if(dictionary["STL"] == "no") qconfigList += "QT_NO_STL";
- if(dictionary["STYLE_WINDOWS"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWS";
- if(dictionary["STYLE_PLASTIQUE"] != "yes") qconfigList += "QT_NO_STYLE_PLASTIQUE";
- if(dictionary["STYLE_CLEANLOOKS"] != "yes") qconfigList += "QT_NO_STYLE_CLEANLOOKS";
- if(dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
+ if (dictionary["STL"] == "no") qconfigList += "QT_NO_STL";
+ if (dictionary["STYLE_WINDOWS"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWS";
+ if (dictionary["STYLE_PLASTIQUE"] != "yes") qconfigList += "QT_NO_STYLE_PLASTIQUE";
+ if (dictionary["STYLE_CLEANLOOKS"] != "yes") qconfigList += "QT_NO_STYLE_CLEANLOOKS";
+ if (dictionary["STYLE_WINDOWSXP"] != "yes" && dictionary["STYLE_WINDOWSVISTA"] != "yes")
qconfigList += "QT_NO_STYLE_WINDOWSXP";
- if(dictionary["STYLE_WINDOWSVISTA"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
- if(dictionary["STYLE_MOTIF"] != "yes") qconfigList += "QT_NO_STYLE_MOTIF";
- if(dictionary["STYLE_CDE"] != "yes") qconfigList += "QT_NO_STYLE_CDE";
- if(dictionary["STYLE_S60"] != "yes") qconfigList += "QT_NO_STYLE_S60";
- if(dictionary["STYLE_WINDOWSCE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSCE";
- if(dictionary["STYLE_WINDOWSMOBILE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
- if(dictionary["STYLE_GTK"] != "yes") qconfigList += "QT_NO_STYLE_GTK";
-
- if(dictionary["GIF"] == "yes") qconfigList += "QT_BUILTIN_GIF_READER=1";
- if(dictionary["PNG"] == "no") qconfigList += "QT_NO_IMAGEFORMAT_PNG";
- if(dictionary["MNG"] == "no") qconfigList += "QT_NO_IMAGEFORMAT_MNG";
- if(dictionary["JPEG"] == "no") qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
- if(dictionary["TIFF"] == "no") qconfigList += "QT_NO_IMAGEFORMAT_TIFF";
- if(dictionary["ZLIB"] == "no") {
+ if (dictionary["STYLE_WINDOWSVISTA"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSVISTA";
+ if (dictionary["STYLE_MOTIF"] != "yes") qconfigList += "QT_NO_STYLE_MOTIF";
+ if (dictionary["STYLE_CDE"] != "yes") qconfigList += "QT_NO_STYLE_CDE";
+ if (dictionary["STYLE_S60"] != "yes") qconfigList += "QT_NO_STYLE_S60";
+ if (dictionary["STYLE_WINDOWSCE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSCE";
+ if (dictionary["STYLE_WINDOWSMOBILE"] != "yes") qconfigList += "QT_NO_STYLE_WINDOWSMOBILE";
+ if (dictionary["STYLE_GTK"] != "yes") qconfigList += "QT_NO_STYLE_GTK";
+
+ if (dictionary["GIF"] == "yes") qconfigList += "QT_BUILTIN_GIF_READER=1";
+ if (dictionary["PNG"] != "yes") qconfigList += "QT_NO_IMAGEFORMAT_PNG";
+ if (dictionary["MNG"] != "yes") qconfigList += "QT_NO_IMAGEFORMAT_MNG";
+ if (dictionary["JPEG"] != "yes") qconfigList += "QT_NO_IMAGEFORMAT_JPEG";
+ if (dictionary["TIFF"] != "yes") qconfigList += "QT_NO_IMAGEFORMAT_TIFF";
+ if (dictionary["ZLIB"] == "no") {
qconfigList += "QT_NO_ZLIB";
qconfigList += "QT_NO_COMPRESS";
}
- if(dictionary["ACCESSIBILITY"] == "no") qconfigList += "QT_NO_ACCESSIBILITY";
- if(dictionary["EXCEPTIONS"] == "no") qconfigList += "QT_NO_EXCEPTIONS";
- if(dictionary["OPENGL"] == "no") qconfigList += "QT_NO_OPENGL";
- if(dictionary["OPENVG"] == "no") qconfigList += "QT_NO_OPENVG";
- if(dictionary["OPENSSL"] == "no") qconfigList += "QT_NO_OPENSSL";
- if(dictionary["OPENSSL"] == "linked") qconfigList += "QT_LINKED_OPENSSL";
- if(dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS";
- if(dictionary["IPV6"] == "no") qconfigList += "QT_NO_IPV6";
- if(dictionary["WEBKIT"] == "no") qconfigList += "QT_NO_WEBKIT";
- if(dictionary["DECLARATIVE"] == "no") qconfigList += "QT_NO_DECLARATIVE";
- if(dictionary["PHONON"] == "no") qconfigList += "QT_NO_PHONON";
- if(dictionary["MULTIMEDIA"] == "no") qconfigList += "QT_NO_MULTIMEDIA";
- if(dictionary["XMLPATTERNS"] == "no") qconfigList += "QT_NO_XMLPATTERNS";
- if(dictionary["SCRIPT"] == "no") qconfigList += "QT_NO_SCRIPT";
- if(dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS";
- if(dictionary["FREETYPE"] == "no") qconfigList += "QT_NO_FREETYPE";
- if(dictionary["S60"] == "no") qconfigList += "QT_NO_S60";
- if(dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES";
-
- if(dictionary["OPENGL_ES_CM"] == "yes" ||
- dictionary["OPENGL_ES_CL"] == "yes" ||
+ if (dictionary["ACCESSIBILITY"] == "no") qconfigList += "QT_NO_ACCESSIBILITY";
+ if (dictionary["EXCEPTIONS"] == "no") qconfigList += "QT_NO_EXCEPTIONS";
+ if (dictionary["OPENGL"] == "no") qconfigList += "QT_NO_OPENGL";
+ if (dictionary["OPENVG"] == "no") qconfigList += "QT_NO_OPENVG";
+ if (dictionary["OPENSSL"] == "no") qconfigList += "QT_NO_OPENSSL";
+ if (dictionary["OPENSSL"] == "linked") qconfigList += "QT_LINKED_OPENSSL";
+ if (dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS";
+ if (dictionary["IPV6"] == "no") qconfigList += "QT_NO_IPV6";
+ if (dictionary["WEBKIT"] == "no") qconfigList += "QT_NO_WEBKIT";
+ if (dictionary["DECLARATIVE"] == "no") qconfigList += "QT_NO_DECLARATIVE";
+ if (dictionary["DECLARATIVE_DEBUG"] == "no") qconfigList += "QDECLARATIVE_NO_DEBUG_PROTOCOL";
+ if (dictionary["PHONON"] == "no") qconfigList += "QT_NO_PHONON";
+ if (dictionary["MULTIMEDIA"] == "no") qconfigList += "QT_NO_MULTIMEDIA";
+ if (dictionary["XMLPATTERNS"] == "no") qconfigList += "QT_NO_XMLPATTERNS";
+ if (dictionary["SCRIPT"] == "no") qconfigList += "QT_NO_SCRIPT";
+ if (dictionary["SCRIPTTOOLS"] == "no") qconfigList += "QT_NO_SCRIPTTOOLS";
+ if (dictionary["FREETYPE"] == "no") qconfigList += "QT_NO_FREETYPE";
+ if (dictionary["S60"] == "no") qconfigList += "QT_NO_S60";
+ if (dictionary["NATIVE_GESTURES"] == "no") qconfigList += "QT_NO_NATIVE_GESTURES";
+
+ if (dictionary["OPENGL_ES_CM"] == "no" &&
+ dictionary["OPENGL_ES_2"] == "no" &&
+ dictionary["OPENVG"] == "no") qconfigList += "QT_NO_EGL";
+
+ if (dictionary["OPENGL_ES_CM"] == "yes" ||
dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES";
- if(dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1";
- if(dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2";
- if(dictionary["OPENGL_ES_CL"] == "yes") qconfigList += "QT_OPENGL_ES_1_CL";
-
- if(dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL";
- if(dictionary["SQL_ODBC"] == "yes") qconfigList += "QT_SQL_ODBC";
- if(dictionary["SQL_OCI"] == "yes") qconfigList += "QT_SQL_OCI";
- if(dictionary["SQL_PSQL"] == "yes") qconfigList += "QT_SQL_PSQL";
- if(dictionary["SQL_TDS"] == "yes") qconfigList += "QT_SQL_TDS";
- if(dictionary["SQL_DB2"] == "yes") qconfigList += "QT_SQL_DB2";
- if(dictionary["SQL_SQLITE"] == "yes") qconfigList += "QT_SQL_SQLITE";
- if(dictionary["SQL_SQLITE2"] == "yes") qconfigList += "QT_SQL_SQLITE2";
- if(dictionary["SQL_IBASE"] == "yes") qconfigList += "QT_SQL_IBASE";
-
- if (dictionary["GRAPHICS_SYSTEM"] == "openvg") qconfigList += "QT_GRAPHICSSYSTEM_OPENVG";
- if (dictionary["GRAPHICS_SYSTEM"] == "opengl") qconfigList += "QT_GRAPHICSSYSTEM_OPENGL";
- if (dictionary["GRAPHICS_SYSTEM"] == "raster") qconfigList += "QT_GRAPHICSSYSTEM_RASTER";
+ if (dictionary["OPENGL_ES_CM"] == "yes") qconfigList += "QT_OPENGL_ES_1";
+ if (dictionary["OPENGL_ES_2"] == "yes") qconfigList += "QT_OPENGL_ES_2";
+ if (dictionary["SQL_MYSQL"] == "yes") qconfigList += "QT_SQL_MYSQL";
+ if (dictionary["SQL_ODBC"] == "yes") qconfigList += "QT_SQL_ODBC";
+ if (dictionary["SQL_OCI"] == "yes") qconfigList += "QT_SQL_OCI";
+ if (dictionary["SQL_PSQL"] == "yes") qconfigList += "QT_SQL_PSQL";
+ if (dictionary["SQL_TDS"] == "yes") qconfigList += "QT_SQL_TDS";
+ if (dictionary["SQL_DB2"] == "yes") qconfigList += "QT_SQL_DB2";
+ if (dictionary["SQL_SQLITE"] == "yes") qconfigList += "QT_SQL_SQLITE";
+ if (dictionary["SQL_SQLITE2"] == "yes") qconfigList += "QT_SQL_SQLITE2";
+ if (dictionary["SQL_IBASE"] == "yes") qconfigList += "QT_SQL_IBASE";
+
+ if (dictionary["GRAPHICS_SYSTEM"] == "openvg") qconfigList += "QT_GRAPHICSSYSTEM_OPENVG";
+ if (dictionary["GRAPHICS_SYSTEM"] == "opengl") qconfigList += "QT_GRAPHICSSYSTEM_OPENGL";
+ if (dictionary["GRAPHICS_SYSTEM"] == "raster") qconfigList += "QT_GRAPHICSSYSTEM_RASTER";
+ if (dictionary["GRAPHICS_SYSTEM"] == "runtime") qconfigList += "QT_GRAPHICSSYSTEM_RUNTIME";
if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) {
// These features are not ported to Symbian (yet)
@@ -3035,14 +3164,14 @@ void Configure::generateConfigfiles()
for (int i = 0; i < qconfigList.count(); ++i)
tmpStream << addDefine(qconfigList.at(i));
- if(dictionary["EMBEDDED"] == "yes")
+ if (dictionary["EMBEDDED"] == "yes")
{
// Check for keyboard, mouse, gfx.
QStringList kbdDrivers = dictionary["KBD_DRIVERS"].split(" ");;
QStringList allKbdDrivers;
allKbdDrivers<<"tty"<<"usb"<<"sl5000"<<"yopy"<<"vr41xx"<<"qvfb"<<"um";
foreach (const QString &kbd, allKbdDrivers) {
- if( !kbdDrivers.contains(kbd))
+ if (!kbdDrivers.contains(kbd))
tmpStream<<"#define QT_NO_QWS_KBD_"<<kbd.toUpper()<<endl;
}
@@ -3050,7 +3179,7 @@ void Configure::generateConfigfiles()
QStringList allMouseDrivers;
allMouseDrivers << "pc"<<"bus"<<"linuxtp"<<"yopy"<<"vr41xx"<<"tslib"<<"qvfb";
foreach (const QString &mouse, allMouseDrivers) {
- if( !mouseDrivers.contains(mouse) )
+ if (!mouseDrivers.contains(mouse))
tmpStream<<"#define QT_NO_QWS_MOUSE_"<<mouse.toUpper()<<endl;
}
@@ -3058,7 +3187,7 @@ void Configure::generateConfigfiles()
QStringList allGfxDrivers;
allGfxDrivers<<"linuxfb"<<"transformed"<<"qvfb"<<"vnc"<<"multiscreen"<<"ahi";
foreach (const QString &gfx, allGfxDrivers) {
- if( !gfxDrivers.contains(gfx))
+ if (!gfxDrivers.contains(gfx))
tmpStream<<"#define QT_NO_QWS_"<<gfx.toUpper()<<endl;
}
@@ -3069,22 +3198,22 @@ void Configure::generateConfigfiles()
tmpStream<<"#define QT_QWS_DEPTH_"+depth<<endl;
}
- if( dictionary[ "QT_CUPS" ] == "no")
+ if (dictionary[ "QT_CUPS" ] == "no")
tmpStream<<"#define QT_NO_CUPS"<<endl;
- if( dictionary[ "QT_ICONV" ] == "no")
+ if (dictionary[ "QT_ICONV" ] == "no")
tmpStream<<"#define QT_NO_ICONV"<<endl;
- if(dictionary[ "QT_GLIB" ] == "no")
+ if (dictionary[ "QT_GLIB" ] == "no")
tmpStream<<"#define QT_NO_GLIB"<<endl;
- if(dictionary[ "QT_LPR" ] == "no")
+ if (dictionary[ "QT_LPR" ] == "no")
tmpStream<<"#define QT_NO_LPR"<<endl;
- if(dictionary[ "QT_INOTIFY" ] == "no" )
+ if (dictionary[ "QT_INOTIFY" ] == "no")
tmpStream<<"#define QT_NO_INOTIFY"<<endl;
- if(dictionary[ "QT_SXE" ] == "no")
+ if (dictionary[ "QT_SXE" ] == "no")
tmpStream<<"#define QT_NO_SXE"<<endl;
tmpStream.flush();
@@ -3095,20 +3224,11 @@ void Configure::generateConfigfiles()
QFile::remove(outName);
tmpFile.copy(outName);
tmpFile.close();
-
- if(!QFile::exists(buildPath + "/include/QtCore/qconfig.h")) {
- if (!writeToFile("#include \"../../src/corelib/global/qconfig.h\"\n",
- buildPath + "/include/QtCore/qconfig.h")
- || !writeToFile("#include \"../../src/corelib/global/qconfig.h\"\n",
- buildPath + "/include/Qt/qconfig.h")) {
- dictionary["DONE"] = "error";
- return;
- }
- }
}
// Copy configured mkspec to default directory, but remove the old one first, if there is any
- QString defSpec = buildPath + "/mkspecs/default";
+ QString mkspecsPath = buildPath + "/mkspecs";
+ QString defSpec = mkspecsPath + "/default";
QFileInfo defSpecInfo(defSpec);
if (defSpecInfo.exists()) {
if (!Environment::rmdir(defSpec)) {
@@ -3118,21 +3238,22 @@ void Configure::generateConfigfiles()
}
}
- QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
- QString pltSpec = sourcePath + "/mkspecs/" + spec;
- if (!Environment::cpdir(pltSpec, defSpec)) {
- cout << "Couldn't update default mkspec! Does " << qPrintable(pltSpec) << " exist?" << endl;
+ QDir mkspecsDir(mkspecsPath);
+ if (!mkspecsDir.mkdir("default")) {
+ cout << "Couldn't create default mkspec dir!" << endl;
dictionary["DONE"] = "error";
return;
}
+ QString spec = dictionary.contains("XQMAKESPEC") ? dictionary["XQMAKESPEC"] : dictionary["QMAKESPEC"];
+ QString pltSpec = sourcePath + "/mkspecs/" + spec;
outName = defSpec + "/qmake.conf";
- ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
QFile qmakeConfFile(outName);
- if (qmakeConfFile.open(QFile::Append | QFile::WriteOnly | QFile::Text)) {
+ if (qmakeConfFile.open(QFile::WriteOnly | QFile::Text)) {
QTextStream qmakeConfStream;
qmakeConfStream.setDevice(&qmakeConfFile);
- qmakeConfStream << endl << "QMAKESPEC_ORIGINAL=" << pltSpec << endl;
+ qmakeConfStream << "QMAKESPEC_ORIGINAL=" << pltSpec << endl << endl;
+ qmakeConfStream << "include(" << pltSpec << "/qmake.conf)" << endl;
qmakeConfStream.flush();
qmakeConfFile.close();
}
@@ -3151,35 +3272,37 @@ void Configure::generateConfigfiles()
<< "/* Build date */" << endl
<< "static const char qt_configure_installation [11 + 12] = \"qt_instdate=" << QDate::currentDate().toString(Qt::ISODate) << "\";" << endl
<< endl;
- if(!dictionary[ "QT_HOST_PREFIX" ].isNull())
+ if (!dictionary[ "QT_HOST_PREFIX" ].isNull())
tmpStream << "#if !defined(QT_BOOTSTRAPPED) && !defined(QT_BUILD_QMAKE)" << endl;
- tmpStream << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << QString(dictionary["QT_INSTALL_PREFIX"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_documentation_path_str[512 + 12] = \"qt_docspath=" << QString(dictionary["QT_INSTALL_DOCS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_headers_path_str [512 + 12] = \"qt_hdrspath=" << QString(dictionary["QT_INSTALL_HEADERS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_libraries_path_str [512 + 12] = \"qt_libspath=" << QString(dictionary["QT_INSTALL_LIBS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_binaries_path_str [512 + 12] = \"qt_binspath=" << QString(dictionary["QT_INSTALL_BINS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_plugins_path_str [512 + 12] = \"qt_plugpath=" << QString(dictionary["QT_INSTALL_PLUGINS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_data_path_str [512 + 12] = \"qt_datapath=" << QString(dictionary["QT_INSTALL_DATA"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_translations_path_str [512 + 12] = \"qt_trnspath=" << QString(dictionary["QT_INSTALL_TRANSLATIONS"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_examples_path_str [512 + 12] = \"qt_xmplpath=" << QString(dictionary["QT_INSTALL_EXAMPLES"]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_demos_path_str [512 + 12] = \"qt_demopath=" << QString(dictionary["QT_INSTALL_DEMOS"]).replace( "\\", "\\\\" ) << "\";" << endl
- //<< "static const char qt_configure_settings_path_str [256] = \"qt_stngpath=" << QString(dictionary["QT_INSTALL_SETTINGS"]).replace( "\\", "\\\\" ) << "\";" << endl
+ tmpStream << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << escapeSeparators(dictionary["QT_INSTALL_PREFIX"]) << "\";" << endl
+ << "static const char qt_configure_documentation_path_str[512 + 12] = \"qt_docspath=" << escapeSeparators(dictionary["QT_INSTALL_DOCS"]) << "\";" << endl
+ << "static const char qt_configure_headers_path_str [512 + 12] = \"qt_hdrspath=" << escapeSeparators(dictionary["QT_INSTALL_HEADERS"]) << "\";" << endl
+ << "static const char qt_configure_libraries_path_str [512 + 12] = \"qt_libspath=" << escapeSeparators(dictionary["QT_INSTALL_LIBS"]) << "\";" << endl
+ << "static const char qt_configure_binaries_path_str [512 + 12] = \"qt_binspath=" << escapeSeparators(dictionary["QT_INSTALL_BINS"]) << "\";" << endl
+ << "static const char qt_configure_plugins_path_str [512 + 12] = \"qt_plugpath=" << escapeSeparators(dictionary["QT_INSTALL_PLUGINS"]) << "\";" << endl
+ << "static const char qt_configure_imports_path_str [512 + 12] = \"qt_impspath=" << escapeSeparators(dictionary["QT_INSTALL_IMPORTS"]) << "\";" << endl
+ << "static const char qt_configure_data_path_str [512 + 12] = \"qt_datapath=" << escapeSeparators(dictionary["QT_INSTALL_DATA"]) << "\";" << endl
+ << "static const char qt_configure_translations_path_str [512 + 12] = \"qt_trnspath=" << escapeSeparators(dictionary["QT_INSTALL_TRANSLATIONS"]) << "\";" << endl
+ << "static const char qt_configure_examples_path_str [512 + 12] = \"qt_xmplpath=" << escapeSeparators(dictionary["QT_INSTALL_EXAMPLES"]) << "\";" << endl
+ << "static const char qt_configure_demos_path_str [512 + 12] = \"qt_demopath=" << escapeSeparators(dictionary["QT_INSTALL_DEMOS"]) << "\";" << endl
+ //<< "static const char qt_configure_settings_path_str [256] = \"qt_stngpath=" << escapeSeparators(dictionary["QT_INSTALL_SETTINGS"]) << "\";" << endl
;
- if(!dictionary[ "QT_HOST_PREFIX" ].isNull()) {
+ if (!dictionary[ "QT_HOST_PREFIX" ].isNull()) {
tmpStream << "#else" << endl
- << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << QString(dictionary[ "QT_HOST_PREFIX" ]).replace( "\\", "\\\\" ) << "\";" << endl
- << "static const char qt_configure_documentation_path_str[512 + 12] = \"qt_docspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/doc").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_headers_path_str [512 + 12] = \"qt_hdrspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/include").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_libraries_path_str [512 + 12] = \"qt_libspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/lib").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_binaries_path_str [512 + 12] = \"qt_binspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/bin").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_plugins_path_str [512 + 12] = \"qt_plugpath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/plugins").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_data_path_str [512 + 12] = \"qt_datapath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ]).replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_translations_path_str [512 + 12] = \"qt_trnspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/translations").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_examples_path_str [512 + 12] = \"qt_xmplpath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/example").replace( "\\", "\\\\" ) <<"\";" << endl
- << "static const char qt_configure_demos_path_str [512 + 12] = \"qt_demopath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/demos").replace( "\\", "\\\\" ) <<"\";" << endl
+ << "static const char qt_configure_prefix_path_str [512 + 12] = \"qt_prfxpath=" << escapeSeparators(dictionary[ "QT_HOST_PREFIX" ]) << "\";" << endl
+ << "static const char qt_configure_documentation_path_str[512 + 12] = \"qt_docspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/doc", true) <<"\";" << endl
+ << "static const char qt_configure_headers_path_str [512 + 12] = \"qt_hdrspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/include", true) <<"\";" << endl
+ << "static const char qt_configure_libraries_path_str [512 + 12] = \"qt_libspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/lib", true) <<"\";" << endl
+ << "static const char qt_configure_binaries_path_str [512 + 12] = \"qt_binspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/bin", true) <<"\";" << endl
+ << "static const char qt_configure_plugins_path_str [512 + 12] = \"qt_plugpath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/plugins", true) <<"\";" << endl
+ << "static const char qt_configure_imports_path_str [512 + 12] = \"qt_impspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/imports", true) <<"\";" << endl
+ << "static const char qt_configure_data_path_str [512 + 12] = \"qt_datapath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ], true) <<"\";" << endl
+ << "static const char qt_configure_translations_path_str [512 + 12] = \"qt_trnspath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/translations", true) <<"\";" << endl
+ << "static const char qt_configure_examples_path_str [512 + 12] = \"qt_xmplpath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/example", true) <<"\";" << endl
+ << "static const char qt_configure_demos_path_str [512 + 12] = \"qt_demopath=" << fixSeparators(dictionary[ "QT_HOST_PREFIX" ] + "/demos", true) <<"\";" << endl
<< "#endif //QT_BOOTSTRAPPED" << endl;
}
- tmpStream << "/* strlen( \"qt_lcnsxxxx\" ) == 12 */" << endl
+ tmpStream << "/* strlen( \"qt_lcnsxxxx\") == 12 */" << endl
<< "#define QT_CONFIGURE_LICENSEE qt_configure_licensee_str + 12;" << endl
<< "#define QT_CONFIGURE_LICENSED_PRODUCTS qt_configure_licensed_products_str + 12;" << endl
<< "#define QT_CONFIGURE_PREFIX_PATH qt_configure_prefix_path_str + 12;" << endl
@@ -3188,6 +3311,7 @@ void Configure::generateConfigfiles()
<< "#define QT_CONFIGURE_LIBRARIES_PATH qt_configure_libraries_path_str + 12;" << endl
<< "#define QT_CONFIGURE_BINARIES_PATH qt_configure_binaries_path_str + 12;" << endl
<< "#define QT_CONFIGURE_PLUGINS_PATH qt_configure_plugins_path_str + 12;" << endl
+ << "#define QT_CONFIGURE_IMPORTS_PATH qt_configure_imports_path_str + 12;" << endl
<< "#define QT_CONFIGURE_DATA_PATH qt_configure_data_path_str + 12;" << endl
<< "#define QT_CONFIGURE_TRANSLATIONS_PATH qt_configure_translations_path_str + 12;" << endl
<< "#define QT_CONFIGURE_EXAMPLES_PATH qt_configure_examples_path_str + 12;" << endl
@@ -3199,8 +3323,8 @@ void Configure::generateConfigfiles()
tmpFile2.flush();
// Replace old qconfig.cpp with new one
- ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
- QFile::remove( outName );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
+ QFile::remove(outName);
tmpFile2.copy(outName);
tmpFile2.close();
}
@@ -3215,8 +3339,8 @@ void Configure::generateConfigfiles()
tmpFile3.flush();
outName = buildPath + "/src/corelib/global/qconfig_eval.cpp";
- ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
- QFile::remove( outName );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
+ QFile::remove(outName);
if (dictionary["EDITION"] == "Evaluation" || qmakeDefines.contains("QT_EVAL"))
tmpFile3.copy(outName);
@@ -3260,9 +3384,9 @@ void Configure::displayConfig()
}
cout << "Configuration:" << endl;
- cout << " " << qmakeConfig.join( "\r\n " ) << endl;
+ cout << " " << qmakeConfig.join("\r\n ") << endl;
cout << "Qt Configuration:" << endl;
- cout << " " << qtConfig.join( "\r\n " ) << endl;
+ cout << " " << qtConfig.join("\r\n ") << endl;
cout << endl;
if (dictionary.contains("XQMAKESPEC"))
@@ -3289,8 +3413,14 @@ void Configure::displayConfig()
cout << "QtXmlPatterns support......." << dictionary[ "XMLPATTERNS" ] << endl;
cout << "Phonon support.............." << dictionary[ "PHONON" ] << endl;
cout << "QtMultimedia support........" << dictionary[ "MULTIMEDIA" ] << endl;
- cout << "WebKit support.............." << dictionary[ "WEBKIT" ] << endl;
+ {
+ QString webkit = dictionary[ "WEBKIT" ];
+ if (webkit == "debug")
+ webkit = "yes (debug)";
+ cout << "WebKit support.............." << webkit;
+ }
cout << "Declarative support........." << dictionary[ "DECLARATIVE" ] << endl;
+ cout << "Declarative debugging......." << dictionary[ "DECLARATIVE_DEBUG" ] << endl;
cout << "QtScript support............" << dictionary[ "SCRIPT" ] << endl;
cout << "QtScriptTools support......." << dictionary[ "SCRIPTTOOLS" ] << endl;
cout << "Graphics System............." << dictionary[ "GRAPHICS_SYSTEM" ] << endl;
@@ -3334,6 +3464,7 @@ void Configure::displayConfig()
cout << "Headers installed to........" << dictionary[ "QT_INSTALL_HEADERS" ] << endl;
cout << "Libraries installed to......" << dictionary[ "QT_INSTALL_LIBS" ] << endl;
cout << "Plugins installed to........" << dictionary[ "QT_INSTALL_PLUGINS" ] << endl;
+ cout << "Imports installed to........" << dictionary[ "QT_INSTALL_IMPORTS" ] << endl;
cout << "Binaries installed to......." << dictionary[ "QT_INSTALL_BINS" ] << endl;
cout << "Docs installed to..........." << dictionary[ "QT_INSTALL_DOCS" ] << endl;
cout << "Data installed to..........." << dictionary[ "QT_INSTALL_DATA" ] << endl;
@@ -3353,51 +3484,51 @@ void Configure::displayConfig()
if (dictionary.contains("SYMBIAN_DEFFILES")) {
cout << "Symbian DEF files enabled..." << dictionary[ "SYMBIAN_DEFFILES" ] << endl;
- if(dictionary["SYMBIAN_DEFFILES"] == "no") {
+ if (dictionary["SYMBIAN_DEFFILES"] == "no") {
cout << "WARNING: Disabling DEF files will mean that Qt is NOT binary compatible with previous versions." << endl;
cout << " This feature is only intended for use during development, NEVER for release builds." << endl;
}
}
- if(dictionary["ASSISTANT_WEBKIT"] == "yes")
+ if (dictionary["ASSISTANT_WEBKIT"] == "yes")
cout << "Using WebKit as html rendering engine in Qt Assistant." << endl;
- if(checkAvailability("INCREDIBUILD_XGE"))
+ if (checkAvailability("INCREDIBUILD_XGE"))
cout << "Using IncrediBuild XGE......" << dictionary["INCREDIBUILD_XGE"] << endl;
- if( !qmakeDefines.isEmpty() ) {
+ if (!qmakeDefines.isEmpty()) {
cout << "Defines.....................";
- for( QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs )
+ for (QStringList::Iterator defs = qmakeDefines.begin(); defs != qmakeDefines.end(); ++defs)
cout << (*defs) << " ";
cout << endl;
}
- if( !qmakeIncludes.isEmpty() ) {
+ if (!qmakeIncludes.isEmpty()) {
cout << "Include paths...............";
- for( QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs )
+ for (QStringList::Iterator incs = qmakeIncludes.begin(); incs != qmakeIncludes.end(); ++incs)
cout << (*incs) << " ";
cout << endl;
}
- if( !qmakeLibs.isEmpty() ) {
+ if (!qmakeLibs.isEmpty()) {
cout << "Additional libraries........";
- for( QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs )
+ for (QStringList::Iterator libs = qmakeLibs.begin(); libs != qmakeLibs.end(); ++libs)
cout << (*libs) << " ";
cout << endl;
}
- if( dictionary[ "QMAKE_INTERNAL" ] == "yes" ) {
+ if (dictionary[ "QMAKE_INTERNAL" ] == "yes") {
cout << "Using internal configuration." << endl;
}
- if( dictionary[ "SHARED" ] == "no" ) {
+ if (dictionary[ "SHARED" ] == "no") {
cout << "WARNING: Using static linking will disable the use of plugins." << endl;
cout << " Make sure you compile ALL needed modules into the library." << endl;
}
- if( dictionary[ "OPENSSL" ] == "linked" && opensslLibs.isEmpty() ) {
+ if (dictionary[ "OPENSSL" ] == "linked" && opensslLibs.isEmpty()) {
cout << "NOTE: When linking against OpenSSL, you can override the default" << endl;
cout << "library names through OPENSSL_LIBS." << endl;
cout << "For example:" << endl;
- cout << " configure -openssl-linked OPENSSL_LIBS='-lssleay32 -llibeay32'" << endl;
+ cout << " configure -openssl-linked OPENSSL_LIBS=\"-lssleay32 -llibeay32\"" << endl;
}
- if( dictionary[ "ZLIB_FORCED" ] == "yes" ) {
+ if (dictionary[ "ZLIB_FORCED" ] == "yes") {
QString which_zlib = "supplied";
- if( dictionary[ "ZLIB" ] == "system")
+ if (dictionary[ "ZLIB" ] == "system")
which_zlib = "system";
cout << "NOTE: The -no-zlib option was supplied but is no longer supported." << endl
@@ -3426,17 +3557,17 @@ void Configure::generateHeaders()
void Configure::buildQmake()
{
- if( dictionary[ "BUILD_QMAKE" ] == "yes" ) {
+ if (dictionary[ "BUILD_QMAKE" ] == "yes") {
QStringList args;
// Build qmake
QString pwd = QDir::currentPath();
- QDir::setCurrent(buildPath + "/qmake" );
+ QDir::setCurrent(buildPath + "/qmake");
QString makefile = "Makefile";
{
QFile out(makefile);
- if(out.open(QFile::WriteOnly | QFile::Text)) {
+ if (out.open(QFile::WriteOnly | QFile::Text)) {
QTextStream stream(&out);
stream << "#AutoGenerated by configure.exe" << endl
<< "BUILD_PATH = " << QDir::convertSeparators(buildPath) << endl
@@ -3449,7 +3580,7 @@ void Configure::buildQmake()
stream << "\n\n";
QFile in(sourcePath + "/qmake/" + dictionary["QMAKEMAKEFILE"]);
- if(in.open(QFile::ReadOnly | QFile::Text)) {
+ if (in.open(QFile::ReadOnly | QFile::Text)) {
QString d = in.readAll();
//### need replaces (like configure.sh)? --Sam
stream << d << endl;
@@ -3464,14 +3595,15 @@ void Configure::buildQmake()
args += makefile;
cout << "Creating qmake..." << endl;
- int exitCode = 0;
- if( exitCode = Environment::execute(args, QStringList(), QStringList()) ) {
+ int exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
args.clear();
args += dictionary[ "MAKE" ];
args += "-f";
args += makefile;
args += "clean";
- if( exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
cout << "Cleaning qmake failed, return code " << exitCode << endl << endl;
dictionary[ "DONE" ] = "error";
} else {
@@ -3479,13 +3611,14 @@ void Configure::buildQmake()
args += dictionary[ "MAKE" ];
args += "-f";
args += makefile;
- if (exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
cout << "Building qmake failed, return code " << exitCode << endl << endl;
dictionary[ "DONE" ] = "error";
}
}
}
- QDir::setCurrent( pwd );
+ QDir::setCurrent(pwd);
}
}
#endif
@@ -3504,7 +3637,7 @@ void Configure::buildHostTools()
<< "src/tools"
<< "tools/linguist/lrelease";
- if(dictionary["XQMAKESPEC"].startsWith("wince"))
+ if (dictionary["XQMAKESPEC"].startsWith("wince"))
hostToolsDirs << "tools/checksdk";
if (dictionary[ "CETEST" ] == "yes")
@@ -3518,13 +3651,16 @@ void Configure::buildHostTools()
// generate Makefile
QStringList args;
args << QDir::toNativeSeparators(buildPath + "/bin/qmake");
- args << "-spec" << dictionary["QMAKESPEC"] << "-r";
+ // override .qmake.cache because we are not cross-building these.
+ // we need a full path so that a build with -prefix will still find it.
+ args << "-spec" << QDir::toNativeSeparators(buildPath + "/mkspecs/" + dictionary["QMAKESPEC"]);
+ args << "-r";
args << "-o" << QDir::toNativeSeparators(toolBuildPath + "/Makefile");
QDir().mkpath(toolBuildPath);
QDir::setCurrent(toolSourcePath);
- int exitCode = 0;
- if (exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ int exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
cout << "qmake failed, return code " << exitCode << endl << endl;
dictionary["DONE"] = "error";
break;
@@ -3534,18 +3670,21 @@ void Configure::buildHostTools()
args.clear();
args += dictionary["MAKE"];
QDir::setCurrent(toolBuildPath);
- if (exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
args.clear();
args += dictionary["MAKE"];
args += "clean";
- if(exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
cout << "Cleaning " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
dictionary["DONE"] = "error";
break;
} else {
args.clear();
args += dictionary["MAKE"];
- if (exitCode = Environment::execute(args, QStringList(), QStringList())) {
+ exitCode = Environment::execute(args, QStringList(), QStringList());
+ if (exitCode) {
cout << "Building " << hostToolsDirs.at(i) << " failed, return code " << exitCode << endl << endl;
dictionary["DONE"] = "error";
break;
@@ -3556,24 +3695,24 @@ void Configure::buildHostTools()
QDir::setCurrent(pwd);
}
-void Configure::findProjects( const QString& dirName )
+void Configure::findProjects(const QString& dirName)
{
- if( dictionary[ "NOPROCESS" ] == "no" ) {
- QDir dir( dirName );
+ if (dictionary[ "NOPROCESS" ] == "no") {
+ QDir dir(dirName);
QString entryName;
int makeListNumber;
ProjectType qmakeTemplate;
const QFileInfoList &list = dir.entryInfoList(QStringList(QLatin1String("*.pro")),
QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
- for(int i = 0; i < list.size(); ++i) {
+ for (int i = 0; i < list.size(); ++i) {
const QFileInfo &fi = list.at(i);
- if(fi.fileName() != "qmake.pro") {
+ if (fi.fileName() != "qmake.pro") {
entryName = dirName + "/" + fi.fileName();
- if(fi.isDir()) {
- findProjects( entryName );
+ if (fi.isDir()) {
+ findProjects(entryName);
} else {
- qmakeTemplate = projectType( fi.absoluteFilePath() );
- switch ( qmakeTemplate ) {
+ qmakeTemplate = projectType(fi.absoluteFilePath());
+ switch (qmakeTemplate) {
case Lib:
case Subdirs:
makeListNumber = 1;
@@ -3600,33 +3739,33 @@ void Configure::appendMakeItem(int inList, const QString &item)
dir = "/" + item;
dir.prepend("/src");
makeList[inList].append(new MakeItem(sourcePath + dir,
- item + ".pro", buildPath + dir + "/Makefile", Lib ) );
- if( dictionary[ "DSPFILES" ] == "yes" ) {
- makeList[inList].append( new MakeItem(sourcePath + dir,
- item + ".pro", buildPath + dir + "/" + item + ".dsp", Lib ) );
+ item + ".pro", buildPath + dir + "/Makefile", Lib));
+ if (dictionary[ "DSPFILES" ] == "yes") {
+ makeList[inList].append(new MakeItem(sourcePath + dir,
+ item + ".pro", buildPath + dir + "/" + item + ".dsp", Lib));
}
- if( dictionary[ "VCPFILES" ] == "yes" ) {
- makeList[inList].append( new MakeItem(sourcePath + dir,
- item + ".pro", buildPath + dir + "/" + item + ".vcp", Lib ) );
+ if (dictionary[ "VCPFILES" ] == "yes") {
+ makeList[inList].append(new MakeItem(sourcePath + dir,
+ item + ".pro", buildPath + dir + "/" + item + ".vcp", Lib));
}
- if( dictionary[ "VCPROJFILES" ] == "yes" ) {
- makeList[inList].append( new MakeItem(sourcePath + dir,
- item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib ) );
+ if (dictionary[ "VCPROJFILES" ] == "yes") {
+ makeList[inList].append(new MakeItem(sourcePath + dir,
+ item + ".pro", buildPath + dir + "/" + item + ".vcproj", Lib));
}
}
void Configure::generateMakefiles()
{
- if( dictionary[ "NOPROCESS" ] == "no" ) {
+ if (dictionary[ "NOPROCESS" ] == "no") {
#if !defined(EVAL)
cout << "Creating makefiles in src..." << endl;
#endif
QString spec = dictionary.contains("XQMAKESPEC") ? dictionary[ "XQMAKESPEC" ] : dictionary[ "QMAKESPEC" ];
- if( spec != "win32-msvc" )
+ if (spec != "win32-msvc")
dictionary[ "DSPFILES" ] = "no";
- if( spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
+ if (spec != "win32-msvc.net" && !spec.startsWith("win32-msvc2") && !spec.startsWith(QLatin1String("wince")))
dictionary[ "VCPROJFILES" ] = "no";
int i = 0;
@@ -3641,10 +3780,10 @@ void Configure::generateMakefiles()
QString dirPath = fixSeparators(buildPath + dirName);
QStringList args;
- args << fixSeparators( buildPath + "/bin/qmake" );
+ args << fixSeparators(buildPath + "/bin/qmake");
if (doDsp) {
- if( dictionary[ "DEPENDENCIES" ] == "no" )
+ if (dictionary[ "DEPENDENCIES" ] == "no")
args << "-nodepend";
args << "-tp" << "vc";
doDsp = false; // DSP files will be done
@@ -3653,27 +3792,26 @@ void Configure::generateMakefiles()
printf("Generating Makefiles...\n");
generate = false; // Now Makefiles will be done
}
- args << "-spec";
- args << spec;
+ // don't pass -spec - .qmake.cache has it already
args << "-r";
args << (sourcePath + "/projects.pro");
args << "-o";
args << buildPath;
- if(!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
+ if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
args << dictionary[ "QMAKEADDITIONALARGS" ];
- QDir::setCurrent( fixSeparators( dirPath ) );
- if( int exitCode = Environment::execute(args, QStringList(), QStringList()) ) {
+ QDir::setCurrent(fixSeparators(dirPath));
+ if (int exitCode = Environment::execute(args, QStringList(), QStringList())) {
cout << "Qmake failed, return code " << exitCode << endl << endl;
dictionary[ "DONE" ] = "error";
}
}
} else {
findProjects(sourcePath);
- for ( i=0; i<3; i++ ) {
- for ( int j=0; j<makeList[i].size(); ++j) {
+ for (i=0; i<3; i++) {
+ for (int j=0; j<makeList[i].size(); ++j) {
MakeItem *it=makeList[i][j];
- QString dirPath = fixSeparators( it->directory + "/" );
+ QString dirPath = fixSeparators(it->directory + "/");
QString projectName = it->proFile;
QString makefileName = buildPath + "/" + dirPath + it->target;
@@ -3684,7 +3822,7 @@ void Configure::generateMakefiles()
QStringList args;
- args << fixSeparators( buildPath + "/bin/qmake" );
+ args << fixSeparators(buildPath + "/bin/qmake");
args << sourcePath + "/" + dirPath + projectName;
args << dictionary[ "QMAKE_ALL_ARGS" ];
@@ -3693,10 +3831,10 @@ void Configure::generateMakefiles()
args << it->target;
args << "-spec";
args << spec;
- if(!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
+ if (!dictionary[ "QMAKEADDITIONALARGS" ].isEmpty())
args << dictionary[ "QMAKEADDITIONALARGS" ];
- QDir::setCurrent( fixSeparators( dirPath ) );
+ QDir::setCurrent(fixSeparators(dirPath));
QFile file(makefileName);
if (!file.open(QFile::WriteOnly)) {
@@ -3714,7 +3852,7 @@ void Configure::generateMakefiles()
}
}
}
- QDir::setCurrent( pwd );
+ QDir::setCurrent(pwd);
} else {
cout << "Processing of project files have been disabled." << endl;
cout << "Only use this option if you really know what you're doing." << endl << endl;
@@ -3728,7 +3866,7 @@ void Configure::showSummary()
if (!dictionary.contains("XQMAKESPEC")) {
cout << endl << endl << "Qt is now configured for building. Just run " << qPrintable(make) << "." << endl;
cout << "To reconfigure, run " << qPrintable(make) << " confclean and configure." << endl << endl;
- } else if(dictionary.value("QMAKESPEC").startsWith("wince")) {
+ } else if (dictionary.value("QMAKESPEC").startsWith("wince")) {
// we are cross compiling for Windows CE
cout << endl << endl << "Qt is now configured for building. To start the build run:" << endl
<< "\tsetcepaths " << dictionary.value("XQMAKESPEC") << endl
@@ -3740,24 +3878,24 @@ void Configure::showSummary()
}
}
-Configure::ProjectType Configure::projectType( const QString& proFileName )
+Configure::ProjectType Configure::projectType(const QString& proFileName)
{
- QFile proFile( proFileName );
- if( proFile.open( QFile::ReadOnly ) ) {
+ QFile proFile(proFileName);
+ if (proFile.open(QFile::ReadOnly)) {
QString buffer = proFile.readLine(1024);
while (!buffer.isEmpty()) {
- QStringList segments = buffer.split(QRegExp( "\\s" ));
+ QStringList segments = buffer.split(QRegExp("\\s"));
QStringList::Iterator it = segments.begin();
- if(segments.size() >= 3) {
+ if (segments.size() >= 3) {
QString keyword = (*it++);
QString operation = (*it++);
QString value = (*it++);
- if( keyword == "TEMPLATE" ) {
- if( value == "lib" )
+ if (keyword == "TEMPLATE") {
+ if (value == "lib")
return Lib;
- else if( value == "subdirs" )
+ else if (value == "subdirs")
return Subdirs;
}
}
@@ -3843,11 +3981,11 @@ bool Configure::showLicense(QString orgLicenseFile)
return false;
}
QStringList licenseContent = QString(file.readAll()).split('\n');
- while(i < licenseContent.size()) {
+ while (i < licenseContent.size()) {
cout << licenseContent.at(i) << endl;
if (++i % screenHeight == 0) {
cout << "(Press any key for more..)";
- if(_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
+ if (_getch() == 3) // _Any_ keypress w/no echo(eat <Enter> for stdout)
exit(0); // Exit cleanly for Ctrl+C
cout << "\r"; // Overwrite text above
}
@@ -3929,13 +4067,13 @@ void Configure::readLicense()
void Configure::reloadCmdLine()
{
- if( dictionary[ "REDO" ] == "yes" ) {
- QFile inFile( buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache" );
- if( inFile.open( QFile::ReadOnly ) ) {
- QTextStream inStream( &inFile );
+ if (dictionary[ "REDO" ] == "yes") {
+ QFile inFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
+ if (inFile.open(QFile::ReadOnly)) {
+ QTextStream inStream(&inFile);
QString buffer;
inStream >> buffer;
- while( buffer.length() ) {
+ while (buffer.length()) {
configCmdLine += buffer;
inStream >> buffer;
}
@@ -3946,11 +4084,11 @@ void Configure::reloadCmdLine()
void Configure::saveCmdLine()
{
- if( dictionary[ "REDO" ] != "yes" ) {
- QFile outFile( buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache" );
- if( outFile.open( QFile::WriteOnly | QFile::Text ) ) {
- QTextStream outStream( &outFile );
- for( QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it ) {
+ if (dictionary[ "REDO" ] != "yes") {
+ QFile outFile(buildPath + "/configure" + dictionary[ "CUSTOMCONFIG" ] + ".cache");
+ if (outFile.open(QFile::WriteOnly | QFile::Text)) {
+ QTextStream outStream(&outFile);
+ for (QStringList::Iterator it = configCmdLine.begin(); it != configCmdLine.end(); ++it) {
outStream << (*it) << " " << endl;
}
outStream.flush();
@@ -3974,23 +4112,23 @@ bool
Configure::filesDiffer(const QString &fn1, const QString &fn2)
{
QFile file1(fn1), file2(fn2);
- if(!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
+ if (!file1.open(QFile::ReadOnly) || !file2.open(QFile::ReadOnly))
return true;
const int chunk = 2048;
int used1 = 0, used2 = 0;
char b1[chunk], b2[chunk];
- while(!file1.atEnd() && !file2.atEnd()) {
- if(!used1)
+ while (!file1.atEnd() && !file2.atEnd()) {
+ if (!used1)
used1 = file1.read(b1, chunk);
- if(!used2)
+ if (!used2)
used2 = file2.read(b2, chunk);
- if(used1 > 0 && used2 > 0) {
+ if (used1 > 0 && used2 > 0) {
const int cmp = qMin(used1, used2);
- if(memcmp(b1, b2, cmp))
+ if (memcmp(b1, b2, cmp))
return true;
- if((used1 -= cmp))
+ if ((used1 -= cmp))
memcpy(b1, b1+cmp, used1);
- if((used2 -= cmp))
+ if ((used2 -= cmp))
memcpy(b2, b2+cmp, used2);
}
}
diff --git a/tools/configure/configureapp.h b/tools/configure/configureapp.h
index c441129..b3c07f7 100644
--- a/tools/configure/configureapp.h
+++ b/tools/configure/configureapp.h
@@ -133,6 +133,9 @@ private:
QStringList qmakeIncludes;
QStringList qmakeLibs;
QString opensslLibs;
+ QString psqlLibs;
+ QString sybase;
+ QString sybaseLibs;
QMap<QString,QString> licenseInfo;
QString outputLine;
@@ -147,7 +150,8 @@ private:
int outputWidth;
bool useUnixSeparators;
- QString fixSeparators(QString somePath);
+ QString fixSeparators(const QString &somePath, bool escape = false);
+ QString escapeSeparators(const QString &somePath);
bool filesDiffer(const QString &file1, const QString &file2);
bool findFile(const QString &fileName);
diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp
index 62b32f1..1866ef4 100644
--- a/tools/configure/environment.cpp
+++ b/tools/configure/environment.cpp
@@ -60,8 +60,8 @@ using namespace std;
#include <qt_windows.h>
#endif
-#include <symbian/epocroot.h> // from tools/shared
-#include <windows/registry.h> // from tools/shared
+#include <symbian/epocroot_p.h> // from tools/shared
+#include <windows/registry_p.h> // from tools/shared
QT_BEGIN_NAMESPACE
@@ -73,13 +73,14 @@ struct CompilerInfo{
} compiler_info[] = {
// The compilers here are sorted in a reversed-preferred order
{CC_BORLAND, "Borland C++", 0, "bcc32.exe"},
- {CC_MINGW, "MinGW (Minimalist GNU for Windows)", 0, "mingw32-gcc.exe"},
+ {CC_MINGW, "MinGW (Minimalist GNU for Windows)", 0, "g++.exe"},
{CC_INTEL, "Intel(R) C++ Compiler for 32-bit applications", 0, "icl.exe"}, // xilink.exe, xilink5.exe, xilink6.exe, xilib.exe
{CC_MSVC6, "Microsoft (R) 32-bit C/C++ Optimizing Compiler (6.x)", "Software\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++\\ProductDir", "cl.exe"}, // link.exe, lib.exe
{CC_NET2002, "Microsoft (R) 32-bit C/C++ Optimizing Compiler.NET 2002 (7.0)", "Software\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir", "cl.exe"}, // link.exe, lib.exe
{CC_NET2003, "Microsoft (R) 32-bit C/C++ Optimizing Compiler.NET 2003 (7.1)", "Software\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir", "cl.exe"}, // link.exe, lib.exe
{CC_NET2005, "Microsoft (R) 32-bit C/C++ Optimizing Compiler.NET 2005 (8.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\8.0", "cl.exe"}, // link.exe, lib.exe
{CC_NET2008, "Microsoft (R) 32-bit C/C++ Optimizing Compiler.NET 2008 (9.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\9.0", "cl.exe"}, // link.exe, lib.exe
+ {CC_NET2010, "Microsoft (R) 32-bit C/C++ Optimizing Compiler.NET 2010 (10.0)", "Software\\Microsoft\\VisualStudio\\SxS\\VC7\\10.0", "cl.exe"}, // link.exe, lib.exe
{CC_UNKNOWN, "Unknown", 0, 0},
};
@@ -105,6 +106,9 @@ QString Environment::detectQMakeSpec()
{
QString spec;
switch (detectCompiler()) {
+ case CC_NET2010:
+ spec = "win32-msvc2010";
+ break;
case CC_NET2008:
spec = "win32-msvc2008";
break;
@@ -159,7 +163,7 @@ Compiler Environment::detectCompiler()
QString paths = qgetenv("PATH");
QStringList pathlist = paths.toLower().split(";");
for(int i = 0; compiler_info[i].compiler; ++i) {
- QString productPath = readRegistryKey(HKEY_LOCAL_MACHINE, compiler_info[i].regKey).toLower();
+ QString productPath = qt_readRegistryKey(HKEY_LOCAL_MACHINE, compiler_info[i].regKey).toLower();
if (productPath.length()) {
QStringList::iterator it;
for(it = pathlist.begin(); it != pathlist.end(); ++it) {
@@ -356,7 +360,7 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
QString args = qt_create_commandline(program, arguments);
QByteArray envlist = qt_create_environment(fullEnv);
- DWORD exitCode = -1;
+ DWORD exitCode = DWORD(-1);
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
@@ -377,7 +381,7 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
}
- if (exitCode == -1) {
+ if (exitCode == DWORD(-1)) {
switch(GetLastError()) {
case E2BIG:
cerr << "execute: Argument list exceeds 1024 bytes" << endl;
@@ -462,8 +466,8 @@ bool Environment::rmdir(const QString &name)
QString Environment::symbianEpocRoot()
{
- // Call function defined in tools/shared/symbian/epocroot.h
- return ::epocRoot();
+ // Call function defined in tools/shared/symbian/epocroot_p.h
+ return ::qt_epocRoot();
}
QT_END_NAMESPACE
diff --git a/tools/configure/environment.h b/tools/configure/environment.h
index b1cbe3a..16af8df 100644
--- a/tools/configure/environment.h
+++ b/tools/configure/environment.h
@@ -56,7 +56,8 @@ enum Compiler {
CC_NET2002 = 0x70,
CC_NET2003 = 0x71,
CC_NET2005 = 0x80,
- CC_NET2008 = 0x90
+ CC_NET2008 = 0x90,
+ CC_NET2010 = 0x91
};
struct CompilerInfo;
diff --git a/tools/designer/src/components/buddyeditor/buddyeditor.cpp b/tools/designer/src/components/buddyeditor/buddyeditor.cpp
index 9da257e..e367f9a 100644
--- a/tools/designer/src/components/buddyeditor/buddyeditor.cpp
+++ b/tools/designer/src/components/buddyeditor/buddyeditor.cpp
@@ -405,6 +405,7 @@ QWidget *BuddyEditor::findBuddy(QLabel *l, const QWidgetList &existingBuddies) c
const int y = geom.center().y();
QWidget *neighbour = 0;
switch (l->layoutDirection()) {
+ case Qt::LayoutDirectionAuto:
case Qt::LeftToRight: { // Walk right to find next managed neighbour
const int xEnd = parent->size().width();
for (int x = geom.right() + 1; x < xEnd; x += DeltaX)
diff --git a/tools/designer/src/components/formeditor/formeditor.pri b/tools/designer/src/components/formeditor/formeditor.pri
index bbe96d5..b1a9318 100644
--- a/tools/designer/src/components/formeditor/formeditor.pri
+++ b/tools/designer/src/components/formeditor/formeditor.pri
@@ -8,6 +8,7 @@ FORMS += $$PWD/deviceprofiledialog.ui \
$$PWD/templateoptionspage.ui
HEADERS += $$PWD/qdesigner_resource.h \
+ $$PWD/qdesignerundostack.h \
$$PWD/formwindow.h \
$$PWD/formwindow_widgetstack.h \
$$PWD/formwindow_dnditem.h \
@@ -41,6 +42,7 @@ HEADERS += $$PWD/qdesigner_resource.h \
$$PWD/templateoptionspage.h
SOURCES += $$PWD/qdesigner_resource.cpp \
+ $$PWD/qdesignerundostack.cpp \
$$PWD/formwindow.cpp \
$$PWD/formwindow_widgetstack.cpp \
$$PWD/formwindow_dnditem.cpp \
diff --git a/tools/designer/src/components/formeditor/formeditor.qrc b/tools/designer/src/components/formeditor/formeditor.qrc
index 83cc9c7..42724dd 100644
--- a/tools/designer/src/components/formeditor/formeditor.qrc
+++ b/tools/designer/src/components/formeditor/formeditor.qrc
@@ -63,6 +63,7 @@
<file>images/qtlogo.png</file>
<file>images/qt3logo.png</file>
<file>images/resetproperty.png</file>
+ <file>images/cleartext.png</file>
<file>images/sort.png</file>
<file>images/edit.png</file>
<file>images/reload.png</file>
@@ -112,7 +113,6 @@
<file>images/widgets/vslider.png</file>
<file>images/widgets/vspacer.png</file>
<file>images/widgets/widget.png</file>
- <file>images/widgets/widget.png</file>
<file>images/widgets/widgetstack.png</file>
<file>images/widgets/wizard.png</file>
<file>images/win/adjustsize.png</file>
diff --git a/tools/designer/src/components/formeditor/formeditor_optionspage.cpp b/tools/designer/src/components/formeditor/formeditor_optionspage.cpp
index 102f44a..8e0cc66 100644
--- a/tools/designer/src/components/formeditor/formeditor_optionspage.cpp
+++ b/tools/designer/src/components/formeditor/formeditor_optionspage.cpp
@@ -86,9 +86,11 @@ ZoomSettingsWidget::ZoomSettingsWidget(QWidget *parent) :
m_zoomCombo->setEditable(false);
const IntList zoomValues = ZoomMenu::zoomValues();
const IntList::const_iterator cend = zoomValues.constEnd();
- //: Zoom percentage
- for (IntList::const_iterator it = zoomValues.constBegin(); it != cend; ++it)
+
+ for (IntList::const_iterator it = zoomValues.constBegin(); it != cend; ++it) {
+ //: Zoom percentage
m_zoomCombo->addItem(QCoreApplication::translate("FormEditorOptionsPage", "%1 %").arg(*it), QVariant(*it));
+ }
// Layout
setCheckable(true);
diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp
index 9fd084d..38a0544 100644
--- a/tools/designer/src/components/formeditor/formwindow.cpp
+++ b/tools/designer/src/components/formeditor/formwindow.cpp
@@ -399,8 +399,7 @@ void FormWindow::setCursorToAll(const QCursor &c, QWidget *start)
void FormWindow::init()
{
if (FormWindowManager *manager = qobject_cast<FormWindowManager*> (core()->formWindowManager())) {
- m_commandHistory = new QUndoStack(this);
- manager->undoGroup()->addStack(m_commandHistory);
+ manager->undoGroup()->addStack(m_undoStack.qundoStack());
}
m_blockSelectionChanged = false;
@@ -429,9 +428,8 @@ void FormWindow::init()
m_mainContainer = 0;
m_currentWidget = 0;
- connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(updateDirty()));
- connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
- connect(m_commandHistory, SIGNAL(indexChanged(int)), this, SLOT(checkSelection()));
+ connect(&m_undoStack, SIGNAL(changed()), this, SIGNAL(changed()));
+ connect(&m_undoStack, SIGNAL(changed()), this, SLOT(checkSelection()));
core()->metaDataBase()->add(this);
@@ -484,6 +482,7 @@ void FormWindow::setMainContainer(QWidget *w)
sheet->setVisible(sheet->indexOf(QLatin1String("windowTitle")), true);
sheet->setVisible(sheet->indexOf(QLatin1String("windowIcon")), true);
sheet->setVisible(sheet->indexOf(QLatin1String("windowModality")), true);
+ sheet->setVisible(sheet->indexOf(QLatin1String("windowOpacity")), true);
sheet->setVisible(sheet->indexOf(QLatin1String("windowFilePath")), true);
// ### generalize
}
@@ -1226,14 +1225,14 @@ void FormWindow::insertWidget(QWidget *w, const QRect &rect, QWidget *container,
if (w->parentWidget() != container) {
ReparentWidgetCommand *cmd = new ReparentWidgetCommand(this);
cmd->init(w, container);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
- m_commandHistory->push(geom_cmd);
+ m_undoStack.push(geom_cmd);
InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
cmd->init(w, already_in_form);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
endCommand();
@@ -1276,12 +1275,10 @@ void FormWindow::resizeWidget(QWidget *widget, const QRect &geometry)
Q_ASSERT(isDescendant(this, widget));
QRect r = geometry;
- if (m_lastIndex > m_commandHistory->index())
- m_lastIndex = -1;
SetPropertyCommand *cmd = new SetPropertyCommand(this);
cmd->init(widget, QLatin1String("geometry"), r);
cmd->setText(tr("Resize"));
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
void FormWindow::raiseChildSelections(QWidget *w)
@@ -1427,26 +1424,125 @@ int FormWindow::calcValue(int val, bool forward, bool snap, int snapOffset) cons
return (forward ? val + 1 : val - 1);
}
-QRect FormWindow::applyValue(const QRect &rect, int val, int key, bool size) const
+// ArrowKeyOperation: Stores a keyboard move or resize (Shift pressed)
+// operation.
+struct ArrowKeyOperation {
+ ArrowKeyOperation() : resize(false), distance(0), arrowKey(Qt::Key_Left) {}
+
+ QRect apply(const QRect &in) const;
+
+ bool resize; // Resize: Shift-Key->drag bottom/right corner, else just move
+ int distance;
+ int arrowKey;
+};
+
+} // namespace
+
+QT_END_NAMESPACE
+Q_DECLARE_METATYPE(qdesigner_internal::ArrowKeyOperation)
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QRect ArrowKeyOperation::apply(const QRect &rect) const
{
QRect r = rect;
- if (size) {
- if (key == Qt::Key_Left || key == Qt::Key_Right)
- r.setWidth(val);
+ if (resize) {
+ if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
+ r.setWidth(r.width() + distance);
else
- r.setHeight(val);
+ r.setHeight(r.height() + distance);
} else {
- if (key == Qt::Key_Left || key == Qt::Key_Right)
- r.moveLeft(val);
+ if (arrowKey == Qt::Key_Left || arrowKey == Qt::Key_Right)
+ r.moveLeft(r.x() + distance);
else
- r.moveTop(val);
+ r.moveTop(r.y() + distance);
}
return r;
}
+QDebug operator<<(QDebug in, const ArrowKeyOperation &op)
+{
+ in.nospace() << "Resize=" << op.resize << " dist=" << op.distance << " Key=" << op.arrowKey << ' ';
+ return in;
+}
+
+// ArrowKeyPropertyHelper: Applies a struct ArrowKeyOperation
+// (stored as new value) to a list of widgets using to calculate the
+// changed geometry of the widget in setValue(). Thus, the 'newValue'
+// of the property command is the relative move distance, which is the same
+// for all widgets (although resulting in different geometries for the widgets).
+// The command merging can then work as it would when applying the same text
+// to all QLabels.
+
+class ArrowKeyPropertyHelper : public PropertyHelper {
+public:
+ ArrowKeyPropertyHelper(QObject* o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *s, int i) :
+ PropertyHelper(o, sp, s, i) {}
+
+ virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
+};
+
+PropertyHelper::Value ArrowKeyPropertyHelper::setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask)
+{
+ // Apply operation to obtain the new geometry value.
+ QWidget *w = qobject_cast<QWidget*>(object());
+ const ArrowKeyOperation operation = qvariant_cast<ArrowKeyOperation>(value);
+ const QRect newGeom = operation.apply(w->geometry());
+ return PropertyHelper::setValue(fw, QVariant(newGeom), changed, subPropertyMask);
+}
+
+// ArrowKeyPropertyCommand: Helper factory overwritten to create
+// ArrowKeyPropertyHelper and a merge operation that merges values of
+// the same direction.
+class ArrowKeyPropertyCommand: public SetPropertyCommand {
+public:
+ explicit ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
+ QUndoCommand *p = 0);
+
+ void init(QWidgetList &l, const ArrowKeyOperation &op);
+
+protected:
+ virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *s, int i) const
+ { return new ArrowKeyPropertyHelper(o, sp, s, i); }
+ virtual QVariant mergeValue(const QVariant &newValue);
+};
+
+ArrowKeyPropertyCommand::ArrowKeyPropertyCommand(QDesignerFormWindowInterface *fw,
+ QUndoCommand *p) :
+ SetPropertyCommand(fw, p)
+{
+ static const int mid = qRegisterMetaType<qdesigner_internal::ArrowKeyOperation>();
+ Q_UNUSED(mid)
+}
+
+void ArrowKeyPropertyCommand::init(QWidgetList &l, const ArrowKeyOperation &op)
+{
+ QObjectList ol;
+ foreach(QWidget *w, l)
+ ol.push_back(w);
+ SetPropertyCommand::init(ol, QLatin1String("geometry"), qVariantFromValue(op));
+
+ setText(op.resize ? FormWindow::tr("Key Resize") : FormWindow::tr("Key Move"));
+}
+
+QVariant ArrowKeyPropertyCommand::mergeValue(const QVariant &newMergeValue)
+{
+ // Merge move operations of the same arrow key
+ if (!qVariantCanConvert<ArrowKeyOperation>(newMergeValue))
+ return QVariant();
+ ArrowKeyOperation mergedOperation = qvariant_cast<ArrowKeyOperation>(newValue());
+ const ArrowKeyOperation newMergeOperation = qvariant_cast<ArrowKeyOperation>(newMergeValue);
+ if (mergedOperation.resize != newMergeOperation.resize || mergedOperation.arrowKey != newMergeOperation.arrowKey)
+ return QVariant();
+ mergedOperation.distance += newMergeOperation.distance;
+ return qVariantFromValue(mergedOperation);
+}
+
void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
{
- bool startMacro = false;
const QDesignerFormWindowCursorInterface *c = cursor();
if (!c->hasSelection())
return;
@@ -1479,57 +1575,14 @@ void FormWindow::handleArrowKeyEvent(int key, Qt::KeyboardModifiers modifiers)
const int newValue = calcValue(oldValue, forward, snap, snapPoint);
- const int offset = newValue - oldValue;
-
- const int selCount = selection.count();
- // check if selection is the same as last time
- if (selCount != m_moveSelection.count() ||
- m_lastUndoIndex != m_commandHistory->index()) {
- m_moveSelection.clear();
- startMacro = true;
- } else {
- for (int index = 0; index < selCount; ++index) {
- if (m_moveSelection[index]->object() != selection.at(index)) {
- m_moveSelection.clear();
- startMacro = true;
- break;
- }
- }
- }
-
- if (startMacro)
- beginCommand(tr("Key Move"));
-
- for (int index = 0; index < selCount; ++index) {
- QWidget *w = selection.at(index);
- const QRect oldGeom = w->geometry();
- const QRect geom = applyValue(oldGeom, getValue(oldGeom, key, size) + offset, key, size);
-
- SetPropertyCommand *cmd = 0;
-
- if (m_moveSelection.count() > index)
- cmd = m_moveSelection[index];
-
- if (!cmd) {
- cmd = new SetPropertyCommand(this);
- cmd->init(w, QLatin1String("geometry"), geom);
- cmd->setText(tr("Key Move"));
- m_commandHistory->push(cmd);
-
- if (m_moveSelection.count() > index)
- m_moveSelection.replace(index, cmd);
- else
- m_moveSelection.append(cmd);
- } else {
- cmd->setNewValue(geom);
- cmd->redo();
- }
- }
+ ArrowKeyOperation operation;
+ operation.resize = modifiers & Qt::ShiftModifier;
+ operation.distance = newValue - oldValue;
+ operation.arrowKey = key;
- if (startMacro) {
- endCommand();
- m_lastUndoIndex = m_commandHistory->index();
- }
+ ArrowKeyPropertyCommand *cmd = new ArrowKeyPropertyCommand(this);
+ cmd->init(selection, operation);
+ m_undoStack.push(cmd);
}
bool FormWindow::handleKeyReleaseEvent(QWidget *, QWidget *, QKeyEvent *e)
@@ -1630,10 +1683,13 @@ void FormWindow::cut()
// for cases like QMainWindow (central widget is an inner container) or QStackedWidget (page is an inner container)
QWidget *FormWindow::innerContainer(QWidget *outerContainer) const
{
- bool isContainer = m_core->widgetDataBase()->isContainer(outerContainer);
- if (isContainer)
- if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), outerContainer))
- return container->widget(container->currentIndex());
+ if (m_core->widgetDataBase()->isContainer(outerContainer))
+ if (const QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(m_core->extensionManager(), outerContainer)) {
+ const int currentIndex = container->currentIndex();
+ return currentIndex >= 0 ?
+ container->widget(currentIndex) :
+ static_cast<QWidget *>(0);
+ }
return outerContainer;
}
@@ -1653,8 +1709,10 @@ QWidget *FormWindow::containerForPaste() const
QWidget *containerOfW = findContainer(selection.first(), /* exclude layouts */ true);
if (!containerOfW || containerOfW == mainContainer())
break;
- // No layouts, must be container
+ // No layouts, must be container. No empty page-based containers.
containerOfW = innerContainer(containerOfW);
+ if (!containerOfW)
+ break;
if (LayoutInfo::layoutType(m_core, containerOfW) != LayoutInfo::NoLayout || !m_core->widgetDataBase()->isContainer(containerOfW))
break;
w = containerOfW;
@@ -1663,6 +1721,8 @@ QWidget *FormWindow::containerForPaste() const
// and the like as the central widget has the layout).
w = innerContainer(w);
+ if (!w)
+ return 0;
if (LayoutInfo::layoutType(m_core, w) != LayoutInfo::NoLayout)
return 0;
// Go up via container extension (also includes step from QMainWindow to its central widget)
@@ -1808,7 +1868,7 @@ void FormWindow::paste(PasteMode pasteMode)
foreach (QWidget *w, clipboard.m_widgets) {
InsertWidgetCommand *cmd = new InsertWidgetCommand(this);
cmd->init(w);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
selectWidget(w);
}
}
@@ -1818,7 +1878,7 @@ void FormWindow::paste(PasteMode pasteMode)
ensureUniqueObjectName(a);
AddActionCommand *cmd = new AddActionCommand(this);
cmd->init(a);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
endCommand();
} while (false);
@@ -1954,14 +2014,12 @@ void FormWindow::breakLayout(QWidget *w)
void FormWindow::beginCommand(const QString &description)
{
- if (m_lastIndex > m_commandHistory->index())
- m_lastIndex = -1;
- m_commandHistory->beginMacro(description);
+ m_undoStack.beginMacro(description);
}
void FormWindow::endCommand()
{
- m_commandHistory->endMacro();
+ m_undoStack.endMacro();
}
void FormWindow::raiseWidgets()
@@ -1976,7 +2034,7 @@ void FormWindow::raiseWidgets()
foreach (QWidget *widget, widgets) {
RaiseWidgetCommand *cmd = new RaiseWidgetCommand(this);
cmd->init(widget);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
endCommand();
}
@@ -1993,7 +2051,7 @@ void FormWindow::lowerWidgets()
foreach (QWidget *widget, widgets) {
LowerWidgetCommand *cmd = new LowerWidgetCommand(this);
cmd->init(widget);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
endCommand();
}
@@ -2374,20 +2432,12 @@ FormWindow *FormWindow::findFormWindow(QWidget *w)
bool FormWindow::isDirty() const
{
- return m_dirty;
+ return m_undoStack.isDirty();
}
void FormWindow::setDirty(bool dirty)
{
- m_dirty = dirty;
-
- if (!m_dirty)
- m_lastIndex = m_commandHistory->index();
-}
-
-void FormWindow::updateDirty()
-{
- m_dirty = m_commandHistory->index() != m_lastIndex;
+ m_undoStack.setDirty(dirty);
}
QWidget *FormWindow::containerAt(const QPoint &pos)
@@ -2756,7 +2806,7 @@ bool FormWindow::dropDockWidget(QDesignerDnDItemInterface *item, const QPoint &g
qVariantSetValue(v, e);
SetPropertyCommand *cmd = new SetPropertyCommand(this);
cmd->init(widget, dockWidgetAreaName, v);
- m_commandHistory->push(cmd);
+ m_undoStack.push(cmd);
}
endCommand();
@@ -2920,6 +2970,12 @@ QWidget *FormWindow::formContainer() const
return m_widgetStack->formContainer();
}
+QUndoStack *FormWindow::commandHistory() const
+{
+ return const_cast<QDesignerUndoStack &>(m_undoStack).qundoStack();
+}
+
} // namespace
QT_END_NAMESPACE
+
diff --git a/tools/designer/src/components/formeditor/formwindow.h b/tools/designer/src/components/formeditor/formwindow.h
index 3eee476..dc0026f 100644
--- a/tools/designer/src/components/formeditor/formwindow.h
+++ b/tools/designer/src/components/formeditor/formwindow.h
@@ -43,6 +43,7 @@
#define FORMWINDOW_H
#include "formeditor_global.h"
+#include "qdesignerundostack.h"
#include <formwindowbase_p.h>
// Qt
@@ -64,7 +65,6 @@ class QLabel;
class QTimer;
class QAction;
class QMenu;
-class QUndoStack;
class QRubberBand;
namespace qdesigner_internal {
@@ -165,9 +165,7 @@ public:
void manageWidget(QWidget *w);
void unmanageWidget(QWidget *w);
- inline QUndoStack *commandHistory() const
- { return m_commandHistory; }
-
+ virtual QUndoStack *commandHistory() const;
void beginCommand(const QString &description);
void endCommand();
@@ -238,7 +236,6 @@ protected:
private slots:
void selectionChangedTimerDone();
- void updateDirty();
void checkSelection();
void checkSelectionNow();
void slotSelectWidget(QAction *);
@@ -263,7 +260,6 @@ private:
int getValue(const QRect &rect, int key, bool size) const;
int calcValue(int val, bool forward, bool snap, int snapOffset) const;
- QRect applyValue(const QRect &rect, int val, int key, bool size) const;
void handleClickSelection(QWidget *managedWidget, unsigned mouseFlags);
bool frameNeeded(QWidget *w) const;
@@ -338,7 +334,7 @@ private:
QPoint m_startPos;
- QUndoStack *m_commandHistory;
+ QDesignerUndoStack m_undoStack;
QString m_fileName;
@@ -352,9 +348,6 @@ private:
QTimer *m_checkSelectionTimer;
QTimer *m_geometryChangedTimer;
- int m_dirty;
- int m_lastIndex;
-
FormWindowWidgetStack *m_widgetStack;
WidgetEditorTool *m_widgetEditor;
@@ -368,8 +361,6 @@ private:
QString m_exportMacro;
QStringList m_includeHints;
- QList<SetPropertyCommand*> m_moveSelection;
- int m_lastUndoIndex;
QPoint m_contextMenuPosition;
private:
diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp
index 88b4ac5..ce809ff 100644
--- a/tools/designer/src/components/formeditor/formwindowmanager.cpp
+++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp
@@ -523,10 +523,11 @@ void FormWindowManager::setupActions()
connect(m_actionShowFormWindowSettingsDialog, SIGNAL(triggered()), this, SLOT(slotActionShowFormWindowSettingsDialog()));
m_actionShowFormWindowSettingsDialog->setEnabled(false);
-
+#ifdef Q_WS_X11
m_actionCopy->setIcon(QIcon::fromTheme("edit-copy", m_actionCopy->icon()));
m_actionCut->setIcon(QIcon::fromTheme("edit-cut", m_actionCut->icon()));
m_actionPaste->setIcon(QIcon::fromTheme("edit-paste", m_actionPaste->icon()));
+ m_actionDelete->setIcon(QIcon::fromTheme("edit-delete", m_actionDelete->icon()));
// These do not currently exist, but will allow theme authors to fill in the gaps
m_actionBreakLayout->setIcon(QIcon::fromTheme("designer-break-layout", m_actionBreakLayout->icon()));
@@ -536,6 +537,7 @@ void FormWindowManager::setupActions()
m_actionSplitHorizontal->setIcon(QIcon::fromTheme("designer-split-horizontal", m_actionSplitHorizontal->icon()));
m_actionSplitVertical->setIcon(QIcon::fromTheme("designer-split-vertical", m_actionSplitVertical->icon()));
m_actionAdjustSize->setIcon(QIcon::fromTheme("designer-adjust-size", m_actionAdjustSize->icon()));
+#endif
}
void FormWindowManager::slotActionCutActivated()
diff --git a/tools/designer/src/components/formeditor/images/cleartext.png b/tools/designer/src/components/formeditor/images/cleartext.png
new file mode 100644
index 0000000..74133ba
--- /dev/null
+++ b/tools/designer/src/components/formeditor/images/cleartext.png
Binary files differ
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
index b659179..1d78695 100644
--- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -53,7 +53,6 @@
#include "qtresourcemodel_p.h"
#include "qmdiarea_container.h"
#include "qwizard_container.h"
-#include "itemview_propertysheet.h"
#include "layout_propertysheet.h"
#include <ui4_p.h>
@@ -106,8 +105,6 @@
#include <QtGui/QMenuBar>
#include <QtGui/QFileDialog>
#include <QtGui/QHeaderView>
-#include <QtGui/QTreeView>
-#include <QtGui/QTableView>
#include <QtGui/QWizardPage>
#include <private/qlayoutengine_p.h>
@@ -1275,10 +1272,6 @@ DomWidget *QDesignerResource::createDom(QWidget *widget, DomWidget *ui_parentWid
w = saveWidget(dockWidget, ui_parentWidget);
else if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget))
w = saveWidget(widget, container, ui_parentWidget);
- else if (QTreeView *treeView = qobject_cast<QTreeView*>(widget))
- w = saveWidget(treeView, ui_parentWidget);
- else if (QTableView *tableView = qobject_cast<QTableView*>(widget))
- w = saveWidget(tableView, ui_parentWidget);
else if (QWizardPage *wizardPage = qobject_cast<QWizardPage*>(widget))
w = saveWidget(wizardPage, ui_parentWidget);
else
@@ -1553,60 +1546,6 @@ DomWidget *QDesignerResource::saveWidget(QDesignerDockWidget *dockWidget, DomWid
return ui_widget;
}
-DomWidget *QDesignerResource::saveWidget(QTreeView *treeView, DomWidget *ui_parentWidget)
-{
- DomWidget *ui_widget = QAbstractFormBuilder::createDom(treeView, ui_parentWidget, true);
-
- QDesignerPropertySheetExtension *sheet
- = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), treeView);
- ItemViewPropertySheet *itemViewSheet = static_cast<ItemViewPropertySheet*>(sheet);
-
- if (itemViewSheet) {
- QHash<QString,QString> nameMap = itemViewSheet->propertyNameMap();
- foreach (const QString &fakeName, nameMap.keys()) {
- int index = itemViewSheet->indexOf(fakeName);
- if (sheet->isChanged(index)) {
- DomProperty *domAttr = createProperty(treeView->header(), nameMap.value(fakeName),
- itemViewSheet->property(index));
- domAttr->setAttributeName(fakeName);
- ui_widget->setElementAttribute(ui_widget->elementAttribute() << domAttr);
- }
- }
- }
-
- return ui_widget;
-}
-
-DomWidget *QDesignerResource::saveWidget(QTableView *tableView, DomWidget *ui_parentWidget)
-{
- DomWidget *ui_widget = QAbstractFormBuilder::createDom(tableView, ui_parentWidget, true);
-
- QDesignerPropertySheetExtension *sheet
- = qt_extension<QDesignerPropertySheetExtension*>(core()->extensionManager(), tableView);
- ItemViewPropertySheet *itemViewSheet = static_cast<ItemViewPropertySheet*>(sheet);
-
- if (itemViewSheet) {
- QHash<QString,QString> nameMap = itemViewSheet->propertyNameMap();
- foreach (const QString &fakeName, nameMap.keys()) {
- int index = itemViewSheet->indexOf(fakeName);
- if (sheet->isChanged(index)) {
- DomProperty *domAttr;
- if (fakeName.startsWith(QLatin1String("horizontal"))) {
- domAttr = createProperty(tableView->horizontalHeader(), nameMap.value(fakeName),
- itemViewSheet->property(index));
- } else {
- domAttr = createProperty(tableView->verticalHeader(), nameMap.value(fakeName),
- itemViewSheet->property(index));
- }
- domAttr->setAttributeName(fakeName);
- ui_widget->setElementAttribute(ui_widget->elementAttribute() << domAttr);
- }
- }
- }
-
- return ui_widget;
-}
-
static void saveStringProperty(DomProperty *property, const PropertySheetStringValue &value)
{
DomString *str = new DomString();
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.h b/tools/designer/src/components/formeditor/qdesigner_resource.h
index 33b5b88..47dd263 100644
--- a/tools/designer/src/components/formeditor/qdesigner_resource.h
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.h
@@ -64,8 +64,6 @@ class QTabWidget;
class QStackedWidget;
class QToolBox;
class QToolBar;
-class QTreeView;
-class QTableView;
class QDesignerDockWidget;
class QLayoutWidget;
class QWizardPage;
@@ -138,8 +136,6 @@ protected:
DomWidget *saveWidget(QWidget *widget, QDesignerContainerExtension *container, DomWidget *ui_parentWidget);
DomWidget *saveWidget(QToolBar *toolBar, DomWidget *ui_parentWidget);
DomWidget *saveWidget(QDesignerDockWidget *dockWidget, DomWidget *ui_parentWidget);
- DomWidget *saveWidget(QTreeView *treeView, DomWidget *ui_parentWidget);
- DomWidget *saveWidget(QTableView *tableView, DomWidget *ui_parentWidget);
DomWidget *saveWidget(QWizardPage *wizardPage, DomWidget *ui_parentWidget);
virtual DomCustomWidgets *saveCustomWidgets();
diff --git a/tools/designer/src/components/formeditor/qdesignerundostack.cpp b/tools/designer/src/components/formeditor/qdesignerundostack.cpp
new file mode 100644
index 0000000..007031d
--- /dev/null
+++ b/tools/designer/src/components/formeditor/qdesignerundostack.cpp
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdesignerundostack.h"
+
+#include <QtGui/QUndoStack>
+#include <QtGui/QUndoCommand>
+
+QT_BEGIN_NAMESPACE
+
+namespace qdesigner_internal {
+
+QDesignerUndoStack::QDesignerUndoStack(QObject *parent) :
+ QObject(parent),
+ m_undoStack(new QUndoStack),
+ m_fakeDirty(false)
+{
+ connect(m_undoStack, SIGNAL(indexChanged(int)), this, SIGNAL(changed()));
+}
+
+QDesignerUndoStack::~QDesignerUndoStack()
+{ // QUndoStack is managed by the QUndoGroup
+}
+
+void QDesignerUndoStack::push(QUndoCommand * cmd)
+{
+ m_undoStack->push(cmd);
+}
+
+void QDesignerUndoStack::beginMacro(const QString &text)
+{
+ m_undoStack->beginMacro(text);
+}
+
+void QDesignerUndoStack::endMacro()
+{
+ m_undoStack->endMacro();
+}
+
+int QDesignerUndoStack::index() const
+{
+ return m_undoStack->index();
+}
+
+const QUndoStack *QDesignerUndoStack::qundoStack() const
+{
+ return m_undoStack;
+}
+QUndoStack *QDesignerUndoStack::qundoStack()
+{
+ return m_undoStack;
+}
+
+bool QDesignerUndoStack::isDirty() const
+{
+ return m_fakeDirty || !m_undoStack->isClean();
+}
+
+void QDesignerUndoStack::setDirty(bool v)
+{
+ if (isDirty() == v)
+ return;
+ if (v) {
+ m_fakeDirty = true;
+ emit changed();
+ } else {
+ m_fakeDirty = false;
+ m_undoStack->setClean();
+ }
+}
+
+} // namespace qdesigner_internal
+
+QT_END_NAMESPACE
diff --git a/tools/assistant/compat/lib/qassistantclient.h b/tools/designer/src/components/formeditor/qdesignerundostack.h
index fc8bb5b..5451ad8 100644
--- a/tools/assistant/compat/lib/qassistantclient.h
+++ b/tools/designer/src/components/formeditor/qdesignerundostack.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the Qt Assistant of the Qt Toolkit.
+** This file is part of the Qt Designer of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -39,62 +39,52 @@
**
****************************************************************************/
-#ifndef QASSISTANTCLIENT_H
-#define QASSISTANTCLIENT_H
+#ifndef QDESIGNERUNDOSTACK_H
+#define QDESIGNERUNDOSTACK_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 QUndoStack;
+class QUndoCommand;
-class QTcpSocket;
+namespace qdesigner_internal {
-class QT_ASSISTANT_CLIENT_EXPORT QAssistantClient : public QObject
+/* QDesignerUndoStack: A QUndoStack extended by a way of setting it to
+ * "dirty" indepently of commands (by modifications without commands
+ * such as resizing). Accomplished via bool m_fakeDirty flag. The
+ * lifecycle of the QUndoStack is managed by the QUndoGroup. */
+class QDesignerUndoStack : public QObject
{
+ Q_DISABLE_COPY(QDesignerUndoStack)
Q_OBJECT
- Q_PROPERTY( bool open READ isOpen )
-
public:
- QAssistantClient( const QString &path, QObject *parent = 0);
- ~QAssistantClient();
+ explicit QDesignerUndoStack(QObject *parent = 0);
+ virtual ~QDesignerUndoStack();
- bool isOpen() const;
+ void push(QUndoCommand * cmd);
+ void beginMacro(const QString &text);
+ void endMacro();
+ int index() const;
- void setArguments( const QStringList &args );
+ const QUndoStack *qundoStack() const;
+ QUndoStack *qundoStack();
-public Q_SLOTS:
- virtual void openAssistant();
- virtual void closeAssistant();
- virtual void showPage( const QString &page );
+ bool isDirty() const;
-Q_SIGNALS:
- void assistantOpened();
- void assistantClosed();
- void error( const QString &msg );
+signals:
+ void changed();
-private Q_SLOTS:
- void socketConnected();
- void socketConnectionClosed();
- void readPort();
- void procError(QProcess::ProcessError err);
- void socketError();
- void readStdError();
+public slots:
+ void setDirty(bool);
private:
- QTcpSocket *socket;
- QProcess *proc;
- quint16 port;
- QString host, assistantCommand, pageBuffer;
- bool opened;
+ QUndoStack *m_undoStack;
+ bool m_fakeDirty;
};
-QT_END_NAMESPACE
+} // namespace qdesigner_internal
-QT_END_HEADER
+QT_END_NAMESPACE
-#endif
+#endif // QDESIGNERUNDOSTACK_H
diff --git a/tools/designer/src/components/formeditor/qmdiarea_container.cpp b/tools/designer/src/components/formeditor/qmdiarea_container.cpp
index 5971094..5e266f4 100644
--- a/tools/designer/src/components/formeditor/qmdiarea_container.cpp
+++ b/tools/designer/src/components/formeditor/qmdiarea_container.cpp
@@ -105,6 +105,7 @@ void QMdiAreaContainer::positionNewMdiChild(const QWidget *area, QWidget *mdiChi
const QPoint pos = mdiChild->pos();
const QSize areaSize = area->size();
switch (QApplication::layoutDirection()) {
+ case Qt::LayoutDirectionAuto:
case Qt::LeftToRight: {
const QSize fullSize = QSize(areaSize.width() - pos.x(), areaSize.height() - pos.y());
if (fullSize.width() > MinSize && fullSize.height() > MinSize)
diff --git a/tools/designer/src/components/lib/lib.pro b/tools/designer/src/components/lib/lib.pro
index 8d0e692..0ada845 100644
--- a/tools/designer/src/components/lib/lib.pro
+++ b/tools/designer/src/components/lib/lib.pro
@@ -44,11 +44,11 @@ SOURCES += qdesigner_components.cpp
}
INCLUDEPATH += . .. \
- $$QT_SOURCE_TREE/tools/designer/src/lib/components \
- $$QT_SOURCE_TREE/tools/designer/src/lib/sdk \
- $$QT_SOURCE_TREE/tools/designer/src/lib/extension \
- $$QT_SOURCE_TREE/tools/designer/src/lib/uilib \
- $$QT_SOURCE_TREE/tools/designer/src/lib/shared
+ $$PWD/../../lib/components \
+ $$PWD/../../lib/sdk \
+ $$PWD/../../lib/extension \
+ $$PWD/../../lib/uilib \
+ $$PWD/../../lib/shared
include(../propertyeditor/propertyeditor.pri)
include(../objectinspector/objectinspector.pri)
diff --git a/tools/designer/src/components/objectinspector/objectinspector.pri b/tools/designer/src/components/objectinspector/objectinspector.pri
index 733c4b3..565f78b 100644
--- a/tools/designer/src/components/objectinspector/objectinspector.pri
+++ b/tools/designer/src/components/objectinspector/objectinspector.pri
@@ -3,7 +3,7 @@
contains(CONFIG, static) {
INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/findwidget
} else {
- include($$QT_SOURCE_TREE/tools/shared/findwidget/findwidget.pri)
+ include(../../../../shared/findwidget/findwidget.pri)
}
INCLUDEPATH += $$PWD
diff --git a/tools/designer/src/components/propertyeditor/brushpropertymanager.cpp b/tools/designer/src/components/propertyeditor/brushpropertymanager.cpp
index 6e9a698..2300b47 100644
--- a/tools/designer/src/components/propertyeditor/brushpropertymanager.cpp
+++ b/tools/designer/src/components/propertyeditor/brushpropertymanager.cpp
@@ -119,21 +119,31 @@ Qt::BrushStyle BrushPropertyManager::brushStyleIndexToStyle(int brushStyleIndex)
return Qt::NoBrush;
}
+
+typedef QMap<int, QIcon> EnumIndexIconMap;
+
+static void clearBrushIcons();
+Q_GLOBAL_STATIC_WITH_INITIALIZER(EnumIndexIconMap, brushIcons, qAddPostRoutine(clearBrushIcons))
+
+static void clearBrushIcons()
+{
+ brushIcons()->clear();
+}
+
const BrushPropertyManager::EnumIndexIconMap &BrushPropertyManager::brushStyleIcons()
{
// Create a map of icons for the brush style editor
- static EnumIndexIconMap rc;
- if (rc.empty()) {
+ if (brushIcons()->empty()) {
const int brushStyleCount = sizeof(brushStyles)/sizeof(const char *);
QBrush brush(Qt::black);
const QIcon solidIcon = QtPropertyBrowserUtils::brushValueIcon(brush);
for (int i = 0; i < brushStyleCount; i++) {
const Qt::BrushStyle style = brushStyleIndexToStyle(i);
brush.setStyle(style);
- rc.insert(i, QtPropertyBrowserUtils::brushValueIcon(brush));
+ brushIcons()->insert(i, QtPropertyBrowserUtils::brushValueIcon(brush));
}
}
- return rc;
+ return *(brushIcons());
}
QString BrushPropertyManager::brushStyleIndexToString(int brushStyleIndex)
diff --git a/tools/designer/src/components/propertyeditor/defs.cpp b/tools/designer/src/components/propertyeditor/defs.cpp
deleted file mode 100644
index 54dec74..0000000
--- a/tools/designer/src/components/propertyeditor/defs.cpp
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the Qt Designer 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 Technology Preview License Agreement accompanying
-** this package.
-**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "defs.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace qdesigner_internal {
-
-int size_type_to_int( QSizePolicy::Policy t )
-{
- if ( t == QSizePolicy::Fixed )
- return 0;
- if ( t == QSizePolicy::Minimum )
- return 1;
- if ( t == QSizePolicy::Maximum )
- return 2;
- if ( t == QSizePolicy::Preferred )
- return 3;
- if ( t == QSizePolicy::MinimumExpanding )
- return 4;
- if ( t == QSizePolicy::Expanding )
- return 5;
- if ( t == QSizePolicy::Ignored )
- return 6;
- return 0;
-}
-
-QString size_type_to_string( QSizePolicy::Policy t )
-{
- if ( t == QSizePolicy::Fixed )
- return QString::fromUtf8("Fixed");
- if ( t == QSizePolicy::Minimum )
- return QString::fromUtf8("Minimum");
- if ( t == QSizePolicy::Maximum )
- return QString::fromUtf8("Maximum");
- if ( t == QSizePolicy::Preferred )
- return QString::fromUtf8("Preferred");
- if ( t == QSizePolicy::MinimumExpanding )
- return QString::fromUtf8("MinimumExpanding");
- if ( t == QSizePolicy::Expanding )
- return QString::fromUtf8("Expanding");
- if ( t == QSizePolicy::Ignored )
- return QString::fromUtf8("Ignored");
- return QString();
-}
-
-QSizePolicy::Policy int_to_size_type( int i )
-{
- if ( i == 0 )
- return QSizePolicy::Fixed;
- if ( i == 1 )
- return QSizePolicy::Minimum;
- if ( i == 2 )
- return QSizePolicy::Maximum;
- if ( i == 3 )
- return QSizePolicy::Preferred;
- if ( i == 4 )
- return QSizePolicy::MinimumExpanding;
- if ( i == 5 )
- return QSizePolicy::Expanding;
- if ( i == 6 )
- return QSizePolicy::Ignored;
- return QSizePolicy::Preferred;
-}
-
-} // namespace qdesigner_internal
-
-QT_END_NAMESPACE
diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.cpp b/tools/designer/src/components/propertyeditor/propertyeditor.cpp
index b171ddc..a8ca8ad 100644
--- a/tools/designer/src/components/propertyeditor/propertyeditor.cpp
+++ b/tools/designer/src/components/propertyeditor/propertyeditor.cpp
@@ -79,6 +79,7 @@
#include <QtGui/QToolButton>
#include <QtGui/QActionGroup>
#include <QtGui/QLabel>
+#include <QtGui/QPainter>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
@@ -98,6 +99,53 @@ QT_BEGIN_NAMESPACE
// ---------------------------------------------------------------------------------
namespace qdesigner_internal {
+
+// ----------- ElidingLabel
+// QLabel does not support text eliding so we need a helper class
+
+class ElidingLabel : public QWidget
+{
+public:
+ ElidingLabel(const QString &text = QString(), QWidget *parent = 0)
+ : QWidget(parent),
+ m_text(text),
+ m_mode(Qt::ElideRight) {
+ setContentsMargins(3, 2, 3, 2);
+ }
+ QSize sizeHint() const;
+ void paintEvent(QPaintEvent *e);
+ void setText(const QString &text) {
+ m_text = text;
+ updateGeometry();
+ }
+ void setElidemode(Qt::TextElideMode mode) {
+ m_mode = mode;
+ updateGeometry();
+ }
+private:
+ QString m_text;
+ Qt::TextElideMode m_mode;
+};
+
+QSize ElidingLabel::sizeHint() const
+{
+ QSize size = fontMetrics().boundingRect(m_text).size();
+ size += QSize(contentsMargins().left() + contentsMargins().right(),
+ contentsMargins().top() + contentsMargins().bottom());
+ return size;
+}
+
+void ElidingLabel::paintEvent(QPaintEvent *) {
+ QPainter painter(this);
+ painter.setPen(QColor(0, 0, 0, 60));
+ painter.setBrush(QColor(255, 255, 255, 40));
+ painter.drawRect(rect().adjusted(0, 0, -1, -1));
+ painter.setPen(palette().windowText().color());
+ painter.drawText(contentsRect(), Qt::AlignLeft,
+ fontMetrics().elidedText(m_text, Qt::ElideRight, width(), 0));
+}
+
+
// ----------- PropertyEditor::Strings
PropertyEditor::Strings::Strings() :
@@ -186,7 +234,7 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare
m_coloringAction(new QAction(createIconSet(QLatin1String("color.png")), tr("Color Groups"), this)),
m_treeAction(new QAction(tr("Tree View"), this)),
m_buttonAction(new QAction(tr("Drop Down Button View"), this)),
- m_classLabel(new QLabel),
+ m_classLabel(new ElidingLabel),
m_sorting(false),
m_coloring(false),
m_brightness(false)
@@ -223,11 +271,6 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare
actionGroup->addAction(m_buttonAction);
connect(actionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotViewTriggered(QAction*)));
- QWidget *classWidget = new QWidget;
- QHBoxLayout *l = new QHBoxLayout(classWidget);
- l->setContentsMargins(5, 0, 5, 0);
- l->addWidget(m_classLabel);
-
// Add actions
QActionGroup *addDynamicActionGroup = new QActionGroup(this);
connect(addDynamicActionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotAddDynamicProperty(QAction*)));
@@ -269,7 +312,6 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare
#endif
// Assemble toolbar
QToolBar *toolBar = new QToolBar;
- toolBar->addWidget(classWidget);
toolBar->addWidget(m_filterWidget);
toolBar->addWidget(createDropDownButton(m_addDynamicAction));
toolBar->addAction(m_removeDynamicAction);
@@ -292,6 +334,8 @@ PropertyEditor::PropertyEditor(QDesignerFormEditorInterface *core, QWidget *pare
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(toolBar);
+ layout->addWidget(m_classLabel);
+ layout->addSpacerItem(new QSpacerItem(0,1));
layout->addWidget(m_stackedWidget);
layout->setMargin(0);
layout->setSpacing(0);
@@ -778,9 +822,14 @@ void PropertyEditor::updateToolBarLabel()
className = realClassName(m_object);
}
- QString classLabelText = objectName;
- classLabelText += QLatin1Char('\n');
+ m_classLabel->setVisible(!objectName.isEmpty() || !className.isEmpty());
+ m_classLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+
+ QString classLabelText;
+ if (!objectName.isEmpty())
+ classLabelText += objectName + QLatin1String(" : ");
classLabelText += className;
+
m_classLabel->setText(classLabelText);
m_classLabel->setToolTip(tr("Object: %1\nClass: %2").arg(objectName).arg(className));
}
@@ -1175,11 +1224,11 @@ void PropertyEditor::slotValueChanged(QtProperty *property, const QVariant &valu
Q_ASSERT(ok);
QVariant v;
qVariantSetValue(v, e);
- emit propertyValueChanged(property->propertyName(), v, true);
+ emitPropertyValueChanged(property->propertyName(), v, true);
return;
}
- emit propertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
+ emitPropertyValueChanged(property->propertyName(), value, enableSubPropertyHandling);
}
bool PropertyEditor::isDynamicProperty(const QtBrowserItem* item) const
diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.h b/tools/designer/src/components/propertyeditor/propertyeditor.h
index 5869c94..f0ea94f 100644
--- a/tools/designer/src/components/propertyeditor/propertyeditor.h
+++ b/tools/designer/src/components/propertyeditor/propertyeditor.h
@@ -62,9 +62,7 @@ class QtTreePropertyBrowser;
class QtProperty;
class QtVariantProperty;
class QtBrowserItem;
-
class QStackedWidget;
-class QLabel;
namespace qdesigner_internal {
@@ -72,6 +70,7 @@ class StringProperty;
class DesignerPropertyManager;
class DesignerEditorFactory;
class FilterWidget;
+class ElidingLabel;
class QT_PROPERTYEDITOR_EXPORT PropertyEditor: public QDesignerPropertyEditor
{
@@ -186,7 +185,7 @@ private:
QAction *m_coloringAction;
QAction *m_treeAction;
QAction *m_buttonAction;
- QLabel *m_classLabel;
+ ElidingLabel *m_classLabel;
bool m_sorting;
bool m_coloring;
diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.pri b/tools/designer/src/components/propertyeditor/propertyeditor.pri
index a8ed37e..bb1afdb 100644
--- a/tools/designer/src/components/propertyeditor/propertyeditor.pri
+++ b/tools/designer/src/components/propertyeditor/propertyeditor.pri
@@ -10,8 +10,8 @@ contains(CONFIG, static) {
INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtpropertybrowser
INCLUDEPATH *= $$QT_SOURCE_TREE/tools/shared/qtgradienteditor
} else {
- include($$QT_SOURCE_TREE/tools/shared/qtpropertybrowser/qtpropertybrowser.pri)
- include($$QT_SOURCE_TREE/tools/shared/qtgradienteditor/qtcolorbutton.pri)
+ include(../../../../shared/qtpropertybrowser/qtpropertybrowser.pri)
+ include(../../../../shared/qtgradienteditor/qtcolorbutton.pri)
}
FORMS += $$PWD/paletteeditor.ui \
@@ -45,10 +45,8 @@ SOURCES += $$PWD/propertyeditor.cpp \
HEADERS += \
$$PWD/propertyeditor_global.h \
- $$PWD/defs.h \
$$PWD/qlonglongvalidator.h
-SOURCES += $$PWD/defs.cpp \
- $$PWD/qlonglongvalidator.cpp
+SOURCES += $$PWD/qlonglongvalidator.cpp
RESOURCES += $$PWD/propertyeditor.qrc
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
index a25bd5d..794722e 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
@@ -63,6 +63,7 @@
#include <QtGui/QAction>
#include <QtGui/QButtonGroup>
#include <QtGui/QMenu>
+#include <QtGui/QSortFilterProxyModel>
#include <QtGui/QStandardItemModel>
#include <QtGui/QComboBox>
#include <QtGui/QApplication>
@@ -712,15 +713,18 @@ SignalSlotEditorWindow::SignalSlotEditorWindow(QDesignerFormEditorInterface *cor
m_remove_button(new QToolButton),
m_core(core),
m_model(new ConnectionModel(this)),
+ m_proxy_model(new QSortFilterProxyModel(this)),
m_handling_selection_change(false)
{
- m_view->setModel(m_model);
+ m_proxy_model->setSourceModel(m_model);
+ m_view->setModel(m_proxy_model);
+ m_view->setSortingEnabled(true);
m_view->setItemDelegate(new ConnectionDelegate(this));
m_view->setEditTriggers(QAbstractItemView::DoubleClicked
| QAbstractItemView::EditKeyPressed);
m_view->setRootIsDecorated(false);
m_view->setTextElideMode (Qt::ElideMiddle);
- connect(m_view, SIGNAL(activated(QModelIndex)), this, SLOT(updateUi()));
+ connect(m_view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(updateUi()));
connect(m_view->header(), SIGNAL(sectionDoubleClicked(int)), m_view, SLOT(resizeColumnToContents(int)));
QVBoxLayout *layout = new QVBoxLayout(this);
@@ -790,7 +794,7 @@ void SignalSlotEditorWindow::updateDialogSelection(Connection *con)
if (m_handling_selection_change || m_editor == 0)
return;
- QModelIndex index = m_model->connectionToIndex(con);
+ QModelIndex index = m_proxy_model->mapFromSource(m_model->connectionToIndex(con));
if (index == m_view->currentIndex())
return;
m_handling_selection_change = true;
@@ -808,7 +812,7 @@ void SignalSlotEditorWindow::updateEditorSelection(const QModelIndex &index)
if (m_editor == 0)
return;
- Connection *con = m_model->indexToConnection(index);
+ Connection *con = m_model->indexToConnection(m_proxy_model->mapToSource(index));
if (m_editor->selected(con))
return;
m_handling_selection_change = true;
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.h b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.h
index 9315955..665f0b7 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.h
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.h
@@ -50,6 +50,7 @@ QT_BEGIN_NAMESPACE
class QDesignerFormWindowInterface;
class QDesignerFormEditorInterface;
class QModelIndex;
+class QSortFilterProxyModel;
class QTreeView;
class QToolButton;
@@ -84,6 +85,7 @@ private:
QToolButton *m_add_button, *m_remove_button;
QDesignerFormEditorInterface *m_core;
ConnectionModel *m_model;
+ QSortFilterProxyModel *m_proxy_model;
bool m_handling_selection_change;
};
diff --git a/tools/designer/src/components/taskmenu/itemlisteditor.cpp b/tools/designer/src/components/taskmenu/itemlisteditor.cpp
index 94959fd..9f8e9c8 100644
--- a/tools/designer/src/components/taskmenu/itemlisteditor.cpp
+++ b/tools/designer/src/components/taskmenu/itemlisteditor.cpp
@@ -114,20 +114,20 @@ void AbstractItemEditor::keyPressEvent(QKeyEvent *e)
}
static const char * const itemFlagNames[] = {
- "Selectable",
- "Editable",
- "DragEnabled",
- "DropEnabled",
- "UserCheckable",
- "Enabled",
- "Tristate",
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Selectable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Editable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "DragEnabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "DropEnabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "UserCheckable"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Enabled"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Tristate"),
0
};
static const char * const checkStateNames[] = {
- "Unchecked",
- "PartiallyChecked",
- "Checked",
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Unchecked"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "PartiallyChecked"),
+ QT_TRANSLATE_NOOP("AbstractItemEditor", "Checked"),
0
};
@@ -135,7 +135,7 @@ static QStringList c2qStringList(const char * const in[])
{
QStringList out;
for (int i = 0; in[i]; i++)
- out << QLatin1String(in[i]);
+ out << AbstractItemEditor::tr(in[i]);
return out;
}
diff --git a/tools/designer/src/components/widgetbox/widgetbox.cpp b/tools/designer/src/components/widgetbox/widgetbox.cpp
index 512d6ba..091135a 100644
--- a/tools/designer/src/components/widgetbox/widgetbox.cpp
+++ b/tools/designer/src/components/widgetbox/widgetbox.cpp
@@ -74,7 +74,10 @@ WidgetBox::WidgetBox(QDesignerFormEditorInterface *core, QWidget *parent, Qt::Wi
FilterWidget *filterWidget = new FilterWidget(0, FilterWidget::LayoutAlignNone);
filterWidget->setRefuseFocus(true);
connect(filterWidget, SIGNAL(filterChanged(QString)), m_view, SLOT(filter(QString)));
- l->addWidget(filterWidget);
+
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->addWidget(filterWidget);
+ l->addWidget(toolBar);
// View
connect(m_view, SIGNAL(pressed(QString,QString,QPoint)),
diff --git a/tools/designer/src/components/widgetbox/widgetboxcategorylistview.cpp b/tools/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
index 674c3a8..1a8611c 100644
--- a/tools/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
+++ b/tools/designer/src/components/widgetbox/widgetboxcategorylistview.cpp
@@ -88,11 +88,15 @@ namespace qdesigner_internal {
struct WidgetBoxCategoryEntry {
WidgetBoxCategoryEntry();
- explicit WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon, bool editable);
+ explicit WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &widget,
+ const QString &filter,
+ const QIcon &icon,
+ bool editable);
QDesignerWidgetBoxInterface::Widget widget;
QString toolTip;
QString whatsThis;
+ QString filter;
QIcon icon;
bool editable;
};
@@ -103,8 +107,11 @@ WidgetBoxCategoryEntry::WidgetBoxCategoryEntry() :
{
}
-WidgetBoxCategoryEntry::WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &w, const QIcon &i, bool e) :
+WidgetBoxCategoryEntry::WidgetBoxCategoryEntry(const QDesignerWidgetBoxInterface::Widget &w,
+ const QString &filterIn,
+ const QIcon &i, bool e) :
widget(w),
+ filter(filterIn),
icon(i),
editable(e)
{
@@ -142,6 +149,7 @@ public:
private:
typedef QList<WidgetBoxCategoryEntry> WidgetBoxCategoryEntrys;
+ QRegExp m_classNameRegExp;
QDesignerFormEditorInterface *m_core;
WidgetBoxCategoryEntrys m_items;
QListView::ViewMode m_viewMode;
@@ -149,9 +157,11 @@ private:
WidgetBoxCategoryModel::WidgetBoxCategoryModel(QDesignerFormEditorInterface *core, QObject *parent) :
QAbstractListModel(parent),
+ m_classNameRegExp(QLatin1String("<widget +class *= *\"([^\"]+)\"")),
m_core(core),
m_viewMode(QListView::ListMode)
{
+ Q_ASSERT(m_classNameRegExp.isValid());
}
QListView::ViewMode WidgetBoxCategoryModel::viewMode() const
@@ -205,8 +215,14 @@ bool WidgetBoxCategoryModel::removeCustomWidgets()
void WidgetBoxCategoryModel::addWidget(const QDesignerWidgetBoxInterface::Widget &widget, const QIcon &icon,bool editable)
{
- // build item
- WidgetBoxCategoryEntry item(widget, icon, editable);
+ // build item. Filter on name + class name if it is different and not a layout.
+ QString filter = widget.name();
+ if (!filter.contains(QLatin1String("Layout")) && m_classNameRegExp.indexIn(widget.domXml()) != -1) {
+ const QString className = m_classNameRegExp.cap(1);
+ if (!filter.contains(className))
+ filter += className;
+ }
+ WidgetBoxCategoryEntry item(widget, filter, icon, editable);
const QDesignerWidgetDataBaseInterface *db = m_core->widgetDataBase();
const int dbIndex = db->indexOfClassName(widget.name());
if (dbIndex != -1) {
@@ -255,7 +271,7 @@ QVariant WidgetBoxCategoryModel::data(const QModelIndex &index, int role) const
case Qt::WhatsThisRole:
return QVariant(item.whatsThis);
case FilterRole:
- return item.widget.name();
+ return item.filter;
}
return QVariant();
}
diff --git a/tools/designer/src/designer/assistantclient.cpp b/tools/designer/src/designer/assistantclient.cpp
index e47817f..bddaf63 100644
--- a/tools/designer/src/designer/assistantclient.cpp
+++ b/tools/designer/src/designer/assistantclient.cpp
@@ -101,7 +101,7 @@ bool AssistantClient::sendCommand(const QString &cmd, QString *errorMessage)
return false;
}
QTextStream str(m_process);
- str << cmd << QLatin1Char('\0') << endl;
+ str << cmd << QLatin1Char('\n') << endl;
return true;
}
diff --git a/tools/designer/src/designer/designer.pro b/tools/designer/src/designer/designer.pro
index 2050c72..8564e96 100644
--- a/tools/designer/src/designer/designer.pro
+++ b/tools/designer/src/designer/designer.pro
@@ -14,10 +14,8 @@ INCLUDEPATH += \
../lib/uilib \
extra
-LIBS += -L../../lib \
- -L../../../../lib \
- -lQtDesignerComponents \
- -lQtDesigner
+QMAKE_LIBDIR += ../../lib ../../../../lib
+LIBS += -lQtDesignerComponents -lQtDesigner
RESOURCES += designer.qrc
@@ -27,8 +25,8 @@ contains(CONFIG, static) {
TARGET = designer
-include($$QT_SOURCE_TREE/tools/shared/fontpanel/fontpanel.pri)
-include($$QT_SOURCE_TREE/tools/shared/qttoolbardialog/qttoolbardialog.pri)
+include(../../../shared/fontpanel/fontpanel.pri)
+include(../../../shared/qttoolbardialog/qttoolbardialog.pri)
HEADERS += \
qdesigner.h \
@@ -90,4 +88,3 @@ INSTALLS += target
include(../sharedcomponents.pri)
unix:!mac:LIBS += -lm
-TRANSLATIONS = designer_de.ts
diff --git a/tools/designer/src/designer/mainwindow.cpp b/tools/designer/src/designer/mainwindow.cpp
index c27e2b4..86bc47e 100644
--- a/tools/designer/src/designer/mainwindow.cpp
+++ b/tools/designer/src/designer/mainwindow.cpp
@@ -75,7 +75,7 @@ static void addActionsToToolBar(const ActionList &actions, QToolBar *t)
const ActionList::const_iterator cend = actions.constEnd();
for (ActionList::const_iterator it = actions.constBegin(); it != cend; ++it) {
QAction *action = *it;
- if (!action->icon().isNull())
+ if (action->property(QDesignerActions::defaultToolbarPropertyName).toBool())
t->addAction(action);
}
}
@@ -113,6 +113,8 @@ void MainWindowBase::closeEvent(QCloseEvent *e)
QList<QToolBar *> MainWindowBase::createToolBars(const QDesignerActions *actions, bool singleToolBar)
{
+ // Note that whenever you want to add a new tool bar here, you also have to update the default
+ // action groups added to the toolbar manager in the mainwindow constructor
QList<QToolBar *> rc;
if (singleToolBar) {
//: Not currently used (main tool bar)
@@ -252,6 +254,22 @@ ToolBarManager::ToolBarManager(QMainWindow *configureableMainWindow,
m_manager->addAction(action, dockTitle);
}
+ QString category(tr("File"));
+ foreach(QAction *action, actions->fileActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Edit");
+ foreach(QAction *action, actions->editActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Tools");
+ foreach(QAction *action, actions->toolActions()->actions())
+ m_manager->addAction(action, category);
+
+ category = tr("Form");
+ foreach(QAction *action, actions->formActions()->actions())
+ m_manager->addAction(action, category);
+
m_manager->addAction(m_configureAction, tr("Toolbars"));
updateToolBarMenu();
}
diff --git a/tools/designer/src/designer/qdesigner_actions.cpp b/tools/designer/src/designer/qdesigner_actions.cpp
index 887ba98..86b6214 100644
--- a/tools/designer/src/designer/qdesigner_actions.cpp
+++ b/tools/designer/src/designer/qdesigner_actions.cpp
@@ -107,6 +107,8 @@ QT_BEGIN_NAMESPACE
using namespace qdesigner_internal;
+const char *QDesignerActions::defaultToolbarPropertyName = "__qt_defaultToolBarAction";
+
//#ifdef Q_WS_MAC
# define NONMODAL_PREVIEW
//#endif
@@ -200,9 +202,15 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
#endif
m_previewManager(0)
{
+#ifdef Q_WS_X11
m_newFormAction->setIcon(QIcon::fromTheme("document-new", m_newFormAction->icon()));
m_openFormAction->setIcon(QIcon::fromTheme("document-open", m_openFormAction->icon()));
m_saveFormAction->setIcon(QIcon::fromTheme("document-save", m_saveFormAction->icon()));
+ m_saveFormAsAction->setIcon(QIcon::fromTheme("document-save-as", m_saveFormAsAction->icon()));
+ m_printPreviewAction->setIcon(QIcon::fromTheme("document-print", m_printPreviewAction->icon()));
+ m_closeFormAction->setIcon(QIcon::fromTheme("window-close", m_closeFormAction->icon()));
+ m_quitAction->setIcon(QIcon::fromTheme("application-exit", m_quitAction->icon()));
+#endif
Q_ASSERT(m_core != 0);
qdesigner_internal::QDesignerFormWindowManager *ifwm = qobject_cast<qdesigner_internal::QDesignerFormWindowManager *>(m_core->formWindowManager());
@@ -230,6 +238,10 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
m_helpActions = createHelpActions();
+ m_newFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_openFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ m_saveFormAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
QDesignerFormWindowManagerInterface *formWindowManager = m_core->formWindowManager();
Q_ASSERT(formWindowManager != 0);
@@ -316,6 +328,9 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
m_editActions->addAction(formWindowManager->actionLower());
m_editActions->addAction(formWindowManager->actionRaise());
+ formWindowManager->actionLower()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionRaise()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
//
// edit mode actions
//
@@ -332,6 +347,7 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
connect(m_editWidgetsAction, SIGNAL(triggered()), this, SLOT(editWidgetsSlot()));
m_editWidgetsAction->setChecked(true);
m_editWidgetsAction->setEnabled(false);
+ m_editWidgetsAction->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
m_toolActions->addAction(m_editWidgetsAction);
connect(formWindowManager, SIGNAL(activeFormWindowChanged(QDesignerFormWindowInterface*)),
@@ -343,6 +359,7 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
if (QDesignerFormEditorPluginInterface *formEditorPlugin = qobject_cast<QDesignerFormEditorPluginInterface*>(plugin)) {
if (QAction *action = formEditorPlugin->action()) {
m_toolActions->addAction(action);
+ action->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
action->setCheckable(true);
}
}
@@ -370,6 +387,15 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
m_formActions->addAction(formWindowManager->actionSimplifyLayout());
m_formActions->addAction(createSeparator(this));
+ formWindowManager->actionHorizontalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionVerticalLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitHorizontal()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionSplitVertical()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionGridLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionFormLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionBreakLayout()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+ formWindowManager->actionAdjustSize()->setProperty(QDesignerActions::defaultToolbarPropertyName, true);
+
m_previewFormAction->setShortcut(tr("CTRL+R"));
m_formActions->addAction(m_previewFormAction);
connect(m_previewManager, SIGNAL(firstPreviewOpened()), this, SLOT(updateCloseAction()));
@@ -490,13 +516,13 @@ QAction *QDesignerActions::createRecentFilesMenu()
}
updateRecentFileActions();
menu->addSeparator();
- act = new QAction(tr("Clear &Menu"), this);
+ act = new QAction(QIcon::fromTheme("edit-clear"), tr("Clear &Menu"), this);
act->setObjectName(QLatin1String("__qt_action_clear_menu_"));
connect(act, SIGNAL(triggered()), this, SLOT(clearRecentFiles()));
m_recentFilesActions->addAction(act);
menu->addAction(act);
- act = new QAction(tr("&Recent Forms"), this);
+ act = new QAction(QIcon::fromTheme("document-open-recent"), tr("&Recent Forms"), this);
act->setMenu(menu);
return act;
}
diff --git a/tools/designer/src/designer/qdesigner_actions.h b/tools/designer/src/designer/qdesigner_actions.h
index 9dfcef1..d8f9e42 100644
--- a/tools/designer/src/designer/qdesigner_actions.h
+++ b/tools/designer/src/designer/qdesigner_actions.h
@@ -113,6 +113,10 @@ public:
QString uiExtension() const;
+ // Boolean dynamic property set on actions to
+ // show them in the default toolbar layout
+ static const char *defaultToolbarPropertyName;
+
public slots:
void activeFormWindowChanged(QDesignerFormWindowInterface *formWindow);
void createForm();
diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp
index b65ce7e..168c468 100644
--- a/tools/designer/src/designer/qdesigner_workbench.cpp
+++ b/tools/designer/src/designer/qdesigner_workbench.cpp
@@ -419,6 +419,7 @@ void QDesignerWorkbench::switchToDockedMode()
m_mode = DockedMode;
const QDesignerSettings settings(m_core);
m_dockedMainWindow = new DockedMainWindow(this, m_toolbarMenu, m_toolWindows);
+ m_dockedMainWindow->setUnifiedTitleAndToolBarOnMac(true);
m_dockedMainWindow->setCloseEventPolicy(MainWindowBase::EmitCloseEventSignal);
connect(m_dockedMainWindow, SIGNAL(closeEventReceived(QCloseEvent*)), this, SLOT(handleCloseEvent(QCloseEvent*)));
connect(m_dockedMainWindow, SIGNAL(fileDropped(QString)), this, SLOT(slotFileDropped(QString)));
diff --git a/tools/designer/src/lib/sdk/abstractdnditem.qdoc b/tools/designer/src/lib/sdk/abstractdnditem.qdoc
index 610ead1..0d63954 100644
--- a/tools/designer/src/lib/sdk/abstractdnditem.qdoc
+++ b/tools/designer/src/lib/sdk/abstractdnditem.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/abstractformeditor.cpp b/tools/designer/src/lib/sdk/abstractformeditor.cpp
index 5353cab..c301f46 100644
--- a/tools/designer/src/lib/sdk/abstractformeditor.cpp
+++ b/tools/designer/src/lib/sdk/abstractformeditor.cpp
@@ -71,7 +71,6 @@ static void initResources()
{
Q_INIT_RESOURCE(shared);
Q_INIT_RESOURCE(ClamshellPhone);
- Q_INIT_RESOURCE(PDAPhone);
Q_INIT_RESOURCE(PortableMedia);
Q_INIT_RESOURCE(S60_nHD_Touchscreen);
Q_INIT_RESOURCE(S60_QVGA_Candybar);
@@ -79,8 +78,6 @@ static void initResources()
Q_INIT_RESOURCE(SmartPhone);
Q_INIT_RESOURCE(SmartPhoneWithButtons);
Q_INIT_RESOURCE(TouchscreenPhone);
- Q_INIT_RESOURCE(Trolltech_Keypad);
- Q_INIT_RESOURCE(Trolltech_Touchscreen);
}
QT_BEGIN_NAMESPACE
diff --git a/tools/designer/src/lib/sdk/abstracticoncache.qdoc b/tools/designer/src/lib/sdk/abstracticoncache.qdoc
index a47a0ee..467eca2 100644
--- a/tools/designer/src/lib/sdk/abstracticoncache.qdoc
+++ b/tools/designer/src/lib/sdk/abstracticoncache.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/dynamicpropertysheet.qdoc b/tools/designer/src/lib/sdk/dynamicpropertysheet.qdoc
index 89914c7..93690cd 100644
--- a/tools/designer/src/lib/sdk/dynamicpropertysheet.qdoc
+++ b/tools/designer/src/lib/sdk/dynamicpropertysheet.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/layoutdecoration.qdoc b/tools/designer/src/lib/sdk/layoutdecoration.qdoc
index 6aeed01..1dacbb2 100644
--- a/tools/designer/src/lib/sdk/layoutdecoration.qdoc
+++ b/tools/designer/src/lib/sdk/layoutdecoration.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/membersheet.qdoc b/tools/designer/src/lib/sdk/membersheet.qdoc
index feb530f..f9d76cf 100644
--- a/tools/designer/src/lib/sdk/membersheet.qdoc
+++ b/tools/designer/src/lib/sdk/membersheet.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/propertysheet.qdoc b/tools/designer/src/lib/sdk/propertysheet.qdoc
index 87cb4e4..ab2477b 100644
--- a/tools/designer/src/lib/sdk/propertysheet.qdoc
+++ b/tools/designer/src/lib/sdk/propertysheet.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/sdk/taskmenu.qdoc b/tools/designer/src/lib/sdk/taskmenu.qdoc
index 565a902..68854b3 100644
--- a/tools/designer/src/lib/sdk/taskmenu.qdoc
+++ b/tools/designer/src/lib/sdk/taskmenu.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/shared/actionrepository.cpp b/tools/designer/src/lib/shared/actionrepository.cpp
index 1076ff4..a54c1e7 100644
--- a/tools/designer/src/lib/shared/actionrepository.cpp
+++ b/tools/designer/src/lib/shared/actionrepository.cpp
@@ -397,9 +397,10 @@ void ActionTreeView::contextMenuEvent(QContextMenuEvent *event)
emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
}
-void ActionTreeView::currentChanged(const QModelIndex &current, const QModelIndex &/*previous*/)
+void ActionTreeView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
emit currentChanged(m_model->actionAt(current));
+ QTreeView::currentChanged(current, previous);
}
void ActionTreeView::slotActivated(const QModelIndex &index)
@@ -478,9 +479,10 @@ void ActionListView::contextMenuEvent(QContextMenuEvent *event)
emit contextMenuRequested(event, m_model->actionAt(indexAt(event->pos())));
}
-void ActionListView::currentChanged(const QModelIndex &current, const QModelIndex & /*previous*/)
+void ActionListView::currentChanged(const QModelIndex &current, const QModelIndex &previous)
{
emit currentChanged(m_model->actionAt(current));
+ QListView::currentChanged(current, previous);
}
void ActionListView::slotActivated(const QModelIndex &index)
diff --git a/tools/designer/src/lib/shared/filterwidget.cpp b/tools/designer/src/lib/shared/filterwidget.cpp
index 6c73a08..a501c02 100644
--- a/tools/designer/src/lib/shared/filterwidget.cpp
+++ b/tools/designer/src/lib/shared/filterwidget.cpp
@@ -44,13 +44,17 @@
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
-#include <QtGui/QPushButton>
#include <QtGui/QLineEdit>
#include <QtGui/QFocusEvent>
#include <QtGui/QPalette>
#include <QtGui/QCursor>
+#include <QtGui/QToolButton>
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOption>
#include <QtCore/QDebug>
+#include <QtCore/QPropertyAnimation>
enum { debugFilter = 0 };
@@ -61,12 +65,47 @@ namespace qdesigner_internal {
HintLineEdit::HintLineEdit(QWidget *parent) :
QLineEdit(parent),
m_defaultFocusPolicy(focusPolicy()),
- m_hintColor(QColor(0xbbbbbb)),
- m_refuseFocus(false),
- m_showingHintText(false)
+ m_refuseFocus(false)
{
}
+IconButton::IconButton(QWidget *parent)
+ : QToolButton(parent)
+{
+ setCursor(Qt::ArrowCursor);
+}
+
+void IconButton::paintEvent(QPaintEvent *)
+{
+ QPainter painter(this);
+ // Note isDown should really use the active state but in most styles
+ // this has no proper feedback
+ QIcon::Mode state = QIcon::Disabled;
+ if (isEnabled())
+ state = isDown() ? QIcon::Selected : QIcon::Normal;
+ QPixmap iconpixmap = icon().pixmap(QSize(ICONBUTTON_SIZE, ICONBUTTON_SIZE),
+ state, QIcon::Off);
+ QRect pixmapRect = QRect(0, 0, iconpixmap.width(), iconpixmap.height());
+ pixmapRect.moveCenter(rect().center());
+ painter.setOpacity(m_fader);
+ painter.drawPixmap(pixmapRect, iconpixmap);
+}
+
+void IconButton::animateShow(bool visible)
+{
+ if (visible) {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(1.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ } else {
+ QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
+ animation->setDuration(160);
+ animation->setEndValue(0.0);
+ animation->start(QAbstractAnimation::DeleteWhenStopped);
+ }
+}
+
bool HintLineEdit::refuseFocus() const
{
return m_refuseFocus;
@@ -111,92 +150,53 @@ void HintLineEdit::focusInEvent(QFocusEvent *e)
}
}
- hideHintText();
QLineEdit::focusInEvent(e);
}
-void HintLineEdit::focusOutEvent(QFocusEvent *e)
-{
- if (debugFilter)
- qDebug() << Q_FUNC_INFO;
- // Focus out: Switch to displaying the hint text unless there is user input
- showHintText();
- QLineEdit::focusOutEvent(e);
-}
-
-QString HintLineEdit::hintText() const
+// ------------------- FilterWidget
+FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
+ QWidget(parent),
+ m_editor(new HintLineEdit(this)),
+ m_button(new IconButton(m_editor)),
+ m_buttonwidth(0)
{
- return m_hintText;
-}
+ m_editor->setPlaceholderText(tr("Filter"));
-void HintLineEdit::setHintText(const QString &ht)
-{
- if (ht == m_hintText)
- return;
- hideHintText();
- m_hintText = ht;
- if (!hasFocus() && !ht.isEmpty())
- showHintText();
-}
+ // Let the style determine minimum height for our widget
+ QSize size(ICONBUTTON_SIZE + 6, ICONBUTTON_SIZE + 2);
-void HintLineEdit::showHintText(bool force)
-{
- if (m_showingHintText || m_hintText.isEmpty())
- return;
- if (force || text().isEmpty()) {
- m_showingHintText = true;
- setText(m_hintText);
- setTextColor(m_hintColor, &m_textColor);
- }
-}
-void HintLineEdit::hideHintText()
-{
- if (m_showingHintText && !m_hintText.isEmpty()) {
- m_showingHintText = false;
- setText(QString());
- setTextColor(m_textColor);
+ // Note KDE does not reserve space for the highlight color
+ if (style()->inherits("OxygenStyle")) {
+ size = size.expandedTo(QSize(24, 0));
}
-}
-bool HintLineEdit::isShowingHintText() const
-{
- return m_showingHintText;
-}
-
-QString HintLineEdit::typedText() const
-{
- return m_showingHintText ? QString() : text();
-}
+ // Make room for clear icon
+ QMargins margins = m_editor->textMargins();
+ if (layoutDirection() == Qt::LeftToRight)
+ margins.setRight(size.width());
+ else
+ margins.setLeft(size.width());
-void HintLineEdit::setTextColor(const QColor &newColor, QColor *oldColor)
-{
- QPalette pal = palette();
- if (oldColor)
- *oldColor = pal.color(QPalette::Text);
- pal.setColor(QPalette::Text, newColor);
- setPalette(pal);}
+ m_editor->setTextMargins(margins);
-// ------------------- FilterWidget
-FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
- QWidget(parent),
- m_button(new QPushButton),
- m_editor(new HintLineEdit)
-{
- m_editor->setHintText(tr("<Filter>"));
QHBoxLayout *l = new QHBoxLayout(this);
l->setMargin(0);
l->setSpacing(0);
-
if (lm == LayoutAlignRight)
l->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
l->addWidget(m_editor);
- m_button->setIcon(createIconSet(QLatin1String("resetproperty.png")));
- m_button->setIconSize(QSize(8, 8));
- m_button->setFlat(true);
- l->addWidget(m_button);
+ // KDE has custom icons for this. Notice that icon namings are counter intuitive
+ // If these icons are not avaiable we use the freedesktop standard name before
+ // falling back to a bundled resource
+ QIcon icon = QIcon::fromTheme(layoutDirection() == Qt::LeftToRight ?
+ QLatin1String("edit-clear-locationbar-rtl") :
+ QLatin1String("edit-clear-locationbar-ltr"),
+ QIcon::fromTheme("edit-clear", createIconSet(QLatin1String("cleartext.png"))));
+ m_button->setIcon(icon);
+ m_button->setToolTip(tr("Clear text"));
connect(m_button, SIGNAL(clicked()), this, SLOT(reset()));
connect(m_editor, SIGNAL(textChanged(QString)), this, SLOT(checkButton(QString)));
connect(m_editor, SIGNAL(textEdited(QString)), this, SIGNAL(filterChanged(QString)));
@@ -204,25 +204,40 @@ FilterWidget::FilterWidget(QWidget *parent, LayoutMode lm) :
QString FilterWidget::text() const
{
- return m_editor->typedText();
+ return m_editor->text();
}
-void FilterWidget::checkButton(const QString &)
+void FilterWidget::checkButton(const QString &text)
{
- m_button->setEnabled(!text().isEmpty());
+ if (m_oldText.isEmpty() || text.isEmpty())
+ m_button->animateShow(!m_editor->text().isEmpty());
+ m_oldText = text;
}
void FilterWidget::reset()
{
if (debugFilter)
qDebug() << Q_FUNC_INFO;
- if (!text().isEmpty()) {
+
+ if (!m_editor->text().isEmpty()) {
// Editor has lost focus once this is pressed
- m_editor->showHintText(true);
+ m_editor->clear();
emit filterChanged(QString());
}
}
+void FilterWidget::resizeEvent(QResizeEvent *)
+{
+ QRect contentRect = m_editor->rect();
+ if (layoutDirection() == Qt::LeftToRight) {
+ const int iconoffset = m_editor->textMargins().right() + 4;
+ m_button->setGeometry(contentRect.adjusted(m_editor->width() - iconoffset, 0, 0, 0));
+ } else {
+ const int iconoffset = m_editor->textMargins().left() + 4;
+ m_button->setGeometry(contentRect.adjusted(0, 0, -m_editor->width() + iconoffset, 0));
+ }
+}
+
bool FilterWidget::refuseFocus() const
{
return m_editor->refuseFocus();
diff --git a/tools/designer/src/lib/shared/filterwidget_p.h b/tools/designer/src/lib/shared/filterwidget_p.h
index 025d708..8ca2073 100644
--- a/tools/designer/src/lib/shared/filterwidget_p.h
+++ b/tools/designer/src/lib/shared/filterwidget_p.h
@@ -58,58 +58,55 @@
#include <QtGui/QWidget>
#include <QtGui/QLineEdit>
#include <QtGui/QColor>
+#include <QtGui/QToolButton>
QT_BEGIN_NAMESPACE
-class QPushButton;
+class QToolButton;
namespace qdesigner_internal {
-/* A line edit that displays a grayed hintText (like "Type Here to Filter")
- * when not focused and empty. When connecting to the changed signals and
- * querying text, one has to be aware that the text is set to that hint
- * text if isShowingHintText() returns true (that is, does not contain
- * valid user input). This widget should never have initial focus
+/* This widget should never have initial focus
* (ie, be the first widget of a dialog, else, the hint cannot be displayed.
* For situations, where it is the only focusable control (widget box),
* there is a special "refuseFocus()" mode, in which it clears the focus
* policy and focusses explicitly on click (note that setting Qt::ClickFocus
* is not sufficient for that as an ActivationFocus will occur). */
+#define ICONBUTTON_SIZE 16
+
class QDESIGNER_SHARED_EXPORT HintLineEdit : public QLineEdit {
Q_OBJECT
public:
explicit HintLineEdit(QWidget *parent = 0);
- QString hintText() const;
-
- bool isShowingHintText() const;
-
- // Convenience for accessing the text that returns "" in case of isShowingHintText().
- QString typedText() const;
-
bool refuseFocus() const;
void setRefuseFocus(bool v);
-public slots:
- void setHintText(const QString &ht);
- void showHintText(bool force = false);
- void hideHintText();
-
protected:
virtual void mousePressEvent(QMouseEvent *event);
virtual void focusInEvent(QFocusEvent *e);
- virtual void focusOutEvent(QFocusEvent *e);
private:
- void setTextColor(const QColor &newColor, QColor *oldColor = 0);
-
const Qt::FocusPolicy m_defaultFocusPolicy;
- const QColor m_hintColor;
- QColor m_textColor;
bool m_refuseFocus;
- QString m_hintText;
- bool m_showingHintText;
+};
+
+// IconButton: This is a simple helper class that represents clickable icons
+
+class IconButton: public QToolButton
+{
+ Q_OBJECT
+ Q_PROPERTY(float fader READ fader WRITE setFader)
+public:
+ IconButton(QWidget *parent);
+ void paintEvent(QPaintEvent *event);
+ float fader() { return m_fader; }
+ void setFader(float value) { m_fader = value; update(); }
+ void animateShow(bool visible);
+
+private:
+ float m_fader;
};
// FilterWidget: For filtering item views, with reset button Uses HintLineEdit.
@@ -128,7 +125,7 @@ public:
explicit FilterWidget(QWidget *parent = 0, LayoutMode lm = LayoutAlignRight);
QString text() const;
-
+ void resizeEvent(QResizeEvent *);
bool refuseFocus() const; // see HintLineEdit
void setRefuseFocus(bool v);
@@ -142,8 +139,10 @@ private slots:
void checkButton(const QString &text);
private:
- QPushButton *m_button;
HintLineEdit *m_editor;
+ IconButton *m_button;
+ int m_buttonwidth;
+ QString m_oldText;
};
} // namespace qdesigner_internal
diff --git a/tools/designer/src/lib/shared/formwindowbase.cpp b/tools/designer/src/lib/shared/formwindowbase.cpp
index 2c5efbf..5292f5f 100644
--- a/tools/designer/src/lib/shared/formwindowbase.cpp
+++ b/tools/designer/src/lib/shared/formwindowbase.cpp
@@ -72,6 +72,7 @@
#include <QtGui/QStatusBar>
#include <QtGui/QMenu>
#include <QtGui/QAction>
+#include <QtGui/QLabel>
QT_BEGIN_NAMESPACE
@@ -181,7 +182,17 @@ void FormWindowBase::reloadProperties()
QMapIterator<int, bool> itIndex(itSheet.value());
while (itIndex.hasNext()) {
const int index = itIndex.next().key();
- sheet->setProperty(index, sheet->property(index));
+ const QVariant newValue = sheet->property(index);
+ if (qobject_cast<QLabel *>(sheet->object()) && sheet->propertyName(index) == QLatin1String("text")) {
+ const PropertySheetStringValue newString = qVariantValue<PropertySheetStringValue>(newValue);
+ // optimize a bit, reset only if the text value might contain a reference to qt resources
+ // (however reloading of icons other than taken from resources might not work here)
+ if (newString.value().contains(QLatin1String(":/"))) {
+ const QVariant resetValue = qVariantFromValue(PropertySheetStringValue());
+ sheet->setProperty(index, resetValue);
+ }
+ }
+ sheet->setProperty(index, newValue);
}
if (QTabWidget *tabWidget = qobject_cast<QTabWidget *>(sheet->object())) {
const int count = tabWidget->count();
diff --git a/tools/designer/src/lib/shared/plugindialog.cpp b/tools/designer/src/lib/shared/plugindialog.cpp
index 3e88043..63ba81c 100644
--- a/tools/designer/src/lib/shared/plugindialog.cpp
+++ b/tools/designer/src/lib/shared/plugindialog.cpp
@@ -102,7 +102,7 @@ void PluginDialog::populateTreeWidget()
const QStringList fileNames = pluginManager->registeredPlugins();
if (!fileNames.isEmpty()) {
- QTreeWidgetItem *topLevelItem = setTopLevelItem(QLatin1String("Loaded Plugins"));
+ QTreeWidgetItem *topLevelItem = setTopLevelItem(tr("Loaded Plugins"));
QFont boldFont = topLevelItem->font(0);
foreach (const QString &fileName, fileNames) {
@@ -125,7 +125,7 @@ void PluginDialog::populateTreeWidget()
const QStringList notLoadedPlugins = pluginManager->failedPlugins();
if (!notLoadedPlugins.isEmpty()) {
- QTreeWidgetItem *topLevelItem = setTopLevelItem(QLatin1String("Failed Plugins"));
+ QTreeWidgetItem *topLevelItem = setTopLevelItem(tr("Failed Plugins"));
const QFont boldFont = topLevelItem->font(0);
foreach (const QString &plugin, notLoadedPlugins) {
const QString failureReason = pluginManager->failureReason(plugin);
diff --git a/tools/designer/src/lib/shared/previewconfigurationwidget.cpp b/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
index e07d155..d116d58 100644
--- a/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
+++ b/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
@@ -41,7 +41,7 @@
/* It is possible to link the skins as resources into Designer by specifying:
* QVFB_ROOT=$$QT_SOURCE_TREE/tools/qvfb
- * RESOURCES += $$QVFB_ROOT/ClamshellPhone.qrc $$QVFB_ROOT/PDAPhone.qrc ...
+ * RESOURCES += $$QVFB_ROOT/ClamshellPhone.qrc $$QVFB_ROOT/TouchScreenPhone.qrc ...
* in lib/shared/shared.pri. However, this exceeds a limit of Visual Studio 6. */
#include "previewconfigurationwidget_p.h"
diff --git a/tools/designer/src/lib/shared/qdesigner_formwindowcommand.cpp b/tools/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
index 8c55d26..490373e 100644
--- a/tools/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_formwindowcommand.cpp
@@ -62,8 +62,10 @@ QT_BEGIN_NAMESPACE
namespace qdesigner_internal {
// ---- QDesignerFormWindowCommand ----
-QDesignerFormWindowCommand::QDesignerFormWindowCommand(const QString &description, QDesignerFormWindowInterface *formWindow)
- : QUndoCommand(description),
+QDesignerFormWindowCommand::QDesignerFormWindowCommand(const QString &description,
+ QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent)
+ : QUndoCommand(description, parent),
m_formWindow(formWindow)
{
}
diff --git a/tools/designer/src/lib/shared/qdesigner_formwindowcommand_p.h b/tools/designer/src/lib/shared/qdesigner_formwindowcommand_p.h
index d8cd018..d73d70c 100644
--- a/tools/designer/src/lib/shared/qdesigner_formwindowcommand_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_formwindowcommand_p.h
@@ -70,7 +70,9 @@ class QDESIGNER_SHARED_EXPORT QDesignerFormWindowCommand: public QUndoCommand
{
public:
- QDesignerFormWindowCommand(const QString &description, QDesignerFormWindowInterface *formWindow);
+ QDesignerFormWindowCommand(const QString &description,
+ QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent = 0);
virtual void undo();
virtual void redo();
diff --git a/tools/designer/src/lib/shared/qdesigner_menu.cpp b/tools/designer/src/lib/shared/qdesigner_menu.cpp
index ba512e4..31a226a 100644
--- a/tools/designer/src/lib/shared/qdesigner_menu.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_menu.cpp
@@ -77,6 +77,7 @@ using namespace qdesigner_internal;
static inline void extendClickableArea(QRect *subMenuRect, Qt::LayoutDirection dir)
{
switch (dir) {
+ case Qt::LayoutDirectionAuto: // Should never happen
case Qt::LeftToRight:
subMenuRect->setLeft(subMenuRect->left() - 20);
break;
@@ -931,8 +932,8 @@ void QDesignerMenu::moveUp(bool ctrl)
if (ctrl)
(void) swap(m_currentIndex, m_currentIndex - 1);
-
- m_currentIndex = qMax(0, --m_currentIndex);
+ --m_currentIndex;
+ m_currentIndex = qMax(0, m_currentIndex);
// Always re-select, swapping destroys order
update();
selectCurrentAction();
@@ -947,7 +948,8 @@ void QDesignerMenu::moveDown(bool ctrl)
if (ctrl)
(void) swap(m_currentIndex + 1, m_currentIndex);
- m_currentIndex = qMin(actions().count() - 1, ++m_currentIndex);
+ ++m_currentIndex;
+ m_currentIndex = qMin(actions().count() - 1, m_currentIndex);
update();
if (!ctrl)
selectCurrentAction();
diff --git a/tools/designer/src/lib/shared/qdesigner_propertycommand.cpp b/tools/designer/src/lib/shared/qdesigner_propertycommand.cpp
index 822c14b..6cc054c 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertycommand.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_propertycommand.cpp
@@ -926,8 +926,9 @@ bool PropertyListCommand::PropertyDescription::equals(const PropertyDescription
// ---- PropertyListCommand
-PropertyListCommand::PropertyListCommand(QDesignerFormWindowInterface *formWindow) :
- QDesignerFormWindowCommand(QString(), formWindow)
+PropertyListCommand::PropertyListCommand(QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent) :
+ QDesignerFormWindowCommand(QString(), formWindow, parent)
{
}
@@ -966,10 +967,17 @@ bool PropertyListCommand::add(QObject *object, const QString &propertyName)
if (!match || m_propertyDescription.m_specialProperty == SP_ObjectName)
return false;
}
- m_propertyHelperList.push_back(PropertyHelper(object, m_propertyDescription.m_specialProperty, sheet, index));
+
+ const PropertyHelperPtr ph(createPropertyHelper(object, m_propertyDescription.m_specialProperty, sheet, index));
+ m_propertyHelperList.push_back(ph);
return true;
}
+PropertyHelper *PropertyListCommand::createPropertyHelper(QObject *object, SpecialProperty sp,
+ QDesignerPropertySheetExtension *sheet, int sheetIndex) const
+{
+ return new PropertyHelper(object, sp, sheet, sheetIndex);
+}
// Init from a list and make sure referenceObject is added first to obtain the right property group
bool PropertyListCommand::initList(const ObjectList &list, const QString &apropertyName, QObject *referenceObject)
@@ -993,19 +1001,19 @@ bool PropertyListCommand::initList(const ObjectList &list, const QString &aprope
QObject* PropertyListCommand::object(int index) const
{
Q_ASSERT(index < m_propertyHelperList.size());
- return m_propertyHelperList[index].object();
+ return m_propertyHelperList.at(index)->object();
}
QVariant PropertyListCommand::oldValue(int index) const
{
Q_ASSERT(index < m_propertyHelperList.size());
- return m_propertyHelperList[index].oldValue();
+ return m_propertyHelperList.at(index)->oldValue();
}
void PropertyListCommand::setOldValue(const QVariant &oldValue, int index)
{
Q_ASSERT(index < m_propertyHelperList.size());
- m_propertyHelperList[index].setOldValue(oldValue);
+ m_propertyHelperList.at(index)->setOldValue(oldValue);
}
// ----- SetValueFunction: Set a new value when applied to a PropertyHelper.
class SetValueFunction {
@@ -1065,9 +1073,10 @@ template <class PropertyListIterator, class Function>
bool updatedPropertyEditor = false;
for (PropertyListIterator it = begin; it != end; ++it) {
- if (QObject* object = it->object()) { // Might have been deleted in the meantime
- const PropertyHelper::Value newValue = function(*it);
- updateMask |= it->updateMask();
+ PropertyHelper *ph = it->data();
+ if (QObject* object = ph->object()) { // Might have been deleted in the meantime
+ const PropertyHelper::Value newValue = function( *ph );
+ updateMask |= ph->updateMask();
// Update property editor if it is the current object
if (!updatedPropertyEditor && propertyEditor && object == propertyEditor->object()) {
propertyEditor->setPropertyValue(propertyName, newValue.first, newValue.second);
@@ -1084,9 +1093,11 @@ template <class PropertyListIterator, class Function>
unsigned PropertyListCommand::setValue(QVariant value, bool changed, unsigned subPropertyMask)
{
if(debugPropertyCommands)
- qDebug() << "PropertyListCommand::setValue(" << value << changed << subPropertyMask << ')';
+ qDebug() << "PropertyListCommand::setValue(" << value
+ << changed << subPropertyMask << ')';
return changePropertyList(formWindow()->core(),
- m_propertyDescription.m_propertyName, m_propertyHelperList.begin(), m_propertyHelperList.end(),
+ m_propertyDescription.m_propertyName,
+ m_propertyHelperList.begin(), m_propertyHelperList.end(),
SetValueFunction(formWindow(), PropertyHelper::Value(value, changed), subPropertyMask));
}
@@ -1146,15 +1157,16 @@ bool PropertyListCommand::canMergeLists(const PropertyHelperList& other) const
if (m_propertyHelperList.size() != other.size())
return false;
for (int i = 0; i < m_propertyHelperList.size(); i++) {
- if (!m_propertyHelperList[i].canMerge(other[i]))
+ if (!m_propertyHelperList.at(i)->canMerge(*other.at(i)))
return false;
}
return true;
}
// ---- SetPropertyCommand ----
-SetPropertyCommand::SetPropertyCommand(QDesignerFormWindowInterface *formWindow)
- : PropertyListCommand(formWindow),
+SetPropertyCommand::SetPropertyCommand(QDesignerFormWindowInterface *formWindow,
+ QUndoCommand *parent)
+ : PropertyListCommand(formWindow, parent),
m_subPropertyMask(SubPropertyAll)
{
}
@@ -1210,7 +1222,7 @@ unsigned SetPropertyCommand::subPropertyMask(const QVariant &newValue, QObject *
void SetPropertyCommand::setDescription()
{
if (propertyHelperList().size() == 1) {
- setText(QApplication::translate("Command", "Changed '%1' of '%2'").arg(propertyName()).arg(propertyHelperList()[0].object()->objectName()));
+ setText(QApplication::translate("Command", "Changed '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
} else {
int count = propertyHelperList().size();
setText(QApplication::translate("Command", "Changed '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
@@ -1231,6 +1243,11 @@ int SetPropertyCommand::id() const
return 1976;
}
+QVariant SetPropertyCommand::mergeValue(const QVariant &newValue)
+{
+ return newValue;
+}
+
bool SetPropertyCommand::mergeWith(const QUndoCommand *other)
{
if (id() != other->id() || !formWindow()->isDirty())
@@ -1248,7 +1265,10 @@ bool SetPropertyCommand::mergeWith(const QUndoCommand *other)
!canMergeLists(cmd->propertyHelperList()))
return false;
- m_newValue = cmd->newValue();
+ const QVariant newValue = mergeValue(cmd->newValue());
+ if (!newValue.isValid())
+ return false;
+ m_newValue = newValue;
m_subPropertyMask |= cmd->m_subPropertyMask;
if(debugPropertyCommands)
qDebug() << "SetPropertyCommand::mergeWith() succeeded " << propertyName();
@@ -1289,7 +1309,7 @@ bool ResetPropertyCommand::init(const ObjectList &list, const QString &aproperty
void ResetPropertyCommand::setDescription()
{
if (propertyHelperList().size() == 1) {
- setText(QApplication::translate("Command", "Reset '%1' of '%2'").arg(propertyName()).arg(propertyHelperList()[0].object()->objectName()));
+ setText(QApplication::translate("Command", "Reset '%1' of '%2'").arg(propertyName()).arg(propertyHelperList().at(0)->object()->objectName()));
} else {
int count = propertyHelperList().size();
setText(QApplication::translate("Command", "Reset '%1' of %n objects", "", QCoreApplication::UnicodeUTF8, count).arg(propertyName()));
diff --git a/tools/designer/src/lib/shared/qdesigner_propertycommand_p.h b/tools/designer/src/lib/shared/qdesigner_propertycommand_p.h
index f6b7262..75b23ca 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertycommand_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_propertycommand_p.h
@@ -58,6 +58,7 @@
#include <QtCore/QVariant>
#include <QtCore/QList>
#include <QtCore/QPair>
+#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
@@ -77,11 +78,12 @@ enum SpecialProperty {
//Determine special property
enum SpecialProperty getSpecialProperty(const QString& propertyName);
-
// A helper class for applying properties to objects.
// Can be used for Set commands (setValue(), restoreOldValue()) or
// Reset Commands restoreDefaultValue(), restoreOldValue()).
-class PropertyHelper {
+//
+class QDESIGNER_SHARED_EXPORT PropertyHelper {
+ Q_DISABLE_COPY(PropertyHelper)
public:
// A pair of Value and changed flag
typedef QPair<QVariant, bool> Value;
@@ -92,11 +94,13 @@ public:
SpecialProperty specialProperty,
QDesignerPropertySheetExtension *sheet,
int index);
+ virtual ~PropertyHelper() {}
QObject *object() const { return m_object; }
SpecialProperty specialProperty() const { return m_specialProperty; }
- // set a new value
- Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
+ // set a new value. Can be overwritten to perform a transformation (see
+ // handling of Arrow key move in FormWindow class).
+ virtual Value setValue(QDesignerFormWindowInterface *fw, const QVariant &value, bool changed, unsigned subPropertyMask);
// restore old value
Value restoreOldValue(QDesignerFormWindowInterface *fw);
@@ -147,7 +151,7 @@ class QDESIGNER_SHARED_EXPORT PropertyListCommand : public QDesignerFormWindowCo
public:
typedef QList<QObject *> ObjectList;
- explicit PropertyListCommand(QDesignerFormWindowInterface *formWindow);
+ explicit PropertyListCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = 0);
QObject* object(int index = 0) const;
@@ -159,8 +163,8 @@ public:
virtual void undo();
protected:
- typedef QList<PropertyHelper> PropertyHelperList;
-
+ typedef QSharedPointer<PropertyHelper> PropertyHelperPtr;
+ typedef QList<PropertyHelperPtr> PropertyHelperList;
// add an object
bool add(QObject *object, const QString &propertyName);
@@ -204,6 +208,10 @@ protected:
};
const PropertyDescription &propertyDescription() const { return m_propertyDescription; }
+protected:
+ virtual PropertyHelper *createPropertyHelper(QObject *o, SpecialProperty sp,
+ QDesignerPropertySheetExtension *sheet, int sheetIndex) const;
+
private:
PropertyDescription m_propertyDescription;
PropertyHelperList m_propertyHelperList;
@@ -215,7 +223,7 @@ class QDESIGNER_SHARED_EXPORT SetPropertyCommand: public PropertyListCommand
public:
typedef QList<QObject *> ObjectList;
- explicit SetPropertyCommand(QDesignerFormWindowInterface *formWindow);
+ explicit SetPropertyCommand(QDesignerFormWindowInterface *formWindow, QUndoCommand *parent = 0);
bool init(QObject *object, const QString &propertyName, const QVariant &newValue);
bool init(const ObjectList &list, const QString &propertyName, const QVariant &newValue,
@@ -232,6 +240,10 @@ public:
bool mergeWith(const QUndoCommand *other);
virtual void redo();
+
+protected:
+ virtual QVariant mergeValue(const QVariant &newValue);
+
private:
unsigned subPropertyMask(const QVariant &newValue, QObject *referenceObject);
void setDescription();
diff --git a/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp b/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
index e89c47c..9a1739e 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
@@ -92,7 +92,8 @@ static const PropertyNameTypeMap &stringPropertyTypes()
}
QDesignerPropertyEditor::QDesignerPropertyEditor(QWidget *parent, Qt::WindowFlags flags) :
- QDesignerPropertyEditorInterface(parent, flags)
+ QDesignerPropertyEditorInterface(parent, flags),
+ m_propertyChangedForwardingBlocked(false)
{
// Make old signal work for compatibility
connect(this, SIGNAL(propertyChanged(QString,QVariant)), this, SLOT(slotPropertyChanged(QString,QVariant)));
@@ -147,9 +148,20 @@ QDesignerPropertyEditor::StringPropertyParameters QDesignerPropertyEditor::textP
return StringPropertyParameters(ValidationSingleLine, true);
}
+void QDesignerPropertyEditor::emitPropertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling)
+{
+ // Avoid duplicate signal emission - see below
+ m_propertyChangedForwardingBlocked = true;
+ emit propertyValueChanged(name, value, enableSubPropertyHandling);
+ emit propertyChanged(name, value);
+ m_propertyChangedForwardingBlocked = false;
+}
+
void QDesignerPropertyEditor::slotPropertyChanged(const QString &name, const QVariant &value)
{
- emit propertyValueChanged(name, value, true);
+ // Forward signal from Integration using the old interfaces.
+ if (!m_propertyChangedForwardingBlocked)
+ emit propertyValueChanged(name, value, true);
}
}
diff --git a/tools/designer/src/lib/shared/qdesigner_propertyeditor_p.h b/tools/designer/src/lib/shared/qdesigner_propertyeditor_p.h
index cdd53f0..27078f2 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertyeditor_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_propertyeditor_p.h
@@ -79,7 +79,6 @@ public:
static StringPropertyParameters textPropertyValidationMode(QDesignerFormEditorInterface *core,
const QObject *object, const QString &propertyName, bool isMainContainer);
-
Q_SIGNALS:
void propertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
void resetProperty(const QString &name);
@@ -97,6 +96,13 @@ public Q_SLOTS:
private Q_SLOTS:
void slotPropertyChanged(const QString &name, const QVariant &value);
+
+protected:
+ void emitPropertyValueChanged(const QString &name, const QVariant &value, bool enableSubPropertyHandling);
+
+private:
+ bool m_propertyChangedForwardingBlocked;
+
};
} // namespace qdesigner_internal
diff --git a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
index b4b962c..086f46d 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_propertysheet.cpp
@@ -271,6 +271,7 @@ bool QDesignerPropertySheetPrivate::isReloadableProperty(int index) const
{
return isResourceProperty(index)
|| propertyType(index) == QDesignerPropertySheet::PropertyStyleSheet
+ || propertyType(index) == QDesignerPropertySheet::PropertyText
|| q->property(index).type() == QVariant::Url;
}
@@ -549,6 +550,7 @@ QDesignerPropertySheet::PropertyType QDesignerPropertySheet::propertyTypeFromNam
propertyTypeHash.insert(QLatin1String("windowModality"), PropertyWindowModality);
propertyTypeHash.insert(QLatin1String("windowModified"), PropertyWindowModified);
propertyTypeHash.insert(QLatin1String("styleSheet"), PropertyStyleSheet);
+ propertyTypeHash.insert(QLatin1String("text"), PropertyText);
}
return propertyTypeHash.value(name, PropertyNone);
}
@@ -610,8 +612,9 @@ QDesignerPropertySheet::QDesignerPropertySheet(QObject *object, QObject *parent)
createFakeProperty(QLatin1String("whatsThis"));
createFakeProperty(QLatin1String("acceptDrops"));
createFakeProperty(QLatin1String("dragEnabled"));
- // windowModality is visible only for the main container, in which case the form windows enables it on loading
+ // windowModality/Opacity is visible only for the main container, in which case the form windows enables it on loading
setVisible(createFakeProperty(QLatin1String("windowModality")), false);
+ setVisible(createFakeProperty(QLatin1String("windowOpacity"), double(1.0)), false);
if (qobject_cast<const QToolBar *>(d->m_object)) { // prevent toolbars from being dragged off
createFakeProperty(QLatin1String("floatable"), QVariant(true));
} else {
@@ -690,6 +693,10 @@ bool QDesignerPropertySheet::dynamicPropertiesAllowed() const
bool QDesignerPropertySheet::canAddDynamicProperty(const QString &propName) const
{
+ // used internally
+ if (propName == QLatin1String("database") ||
+ propName == QLatin1String("buttonGroupId"))
+ return false;
const int index = d->m_meta->indexOfProperty(propName);
if (index != -1)
return false; // property already exists and is not a dynamic one
@@ -719,10 +726,11 @@ int QDesignerPropertySheet::addDynamicProperty(const QString &propName, const QV
else if (value.type() == QVariant::Pixmap)
v = qVariantFromValue(qdesigner_internal::PropertySheetPixmapValue());
else if (value.type() == QVariant::String)
- v = qVariantFromValue(qdesigner_internal::PropertySheetStringValue());
- else if (value.type() == QVariant::KeySequence)
- v = qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue());
-
+ v = qVariantFromValue(qdesigner_internal::PropertySheetStringValue(value.toString()));
+ else if (value.type() == QVariant::KeySequence) {
+ const QKeySequence keySequence = qVariantValue<QKeySequence>(value);
+ v = qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue(keySequence));
+ }
if (d->m_addIndex.contains(propName)) {
const int idx = d->m_addIndex.value(propName);
@@ -1127,7 +1135,7 @@ void QDesignerPropertySheet::setProperty(int index, const QVariant &value)
}
}
- if (isDynamicProperty(index)) {
+ if (isDynamicProperty(index) || isDefaultDynamicProperty(index)) {
if (d->isResourceProperty(index))
d->setResourceProperty(index, value);
if (d->isStringProperty(index))
@@ -1197,10 +1205,17 @@ bool QDesignerPropertySheet::reset(int index)
} else if (isDynamic(index)) {
const QString propName = propertyName(index);
const QVariant oldValue = d->m_addProperties.value(index);
- const QVariant newValue = d->m_info.value(index).defaultValue;
+ const QVariant defaultValue = d->m_info.value(index).defaultValue;
+ QVariant newValue = defaultValue;
+ if (d->isStringProperty(index)) {
+ newValue = qVariantFromValue(qdesigner_internal::PropertySheetStringValue(newValue.toString()));
+ } else if (d->isKeySequenceProperty(index)) {
+ const QKeySequence keySequence = qVariantValue<QKeySequence>(newValue);
+ newValue = qVariantFromValue(qdesigner_internal::PropertySheetKeySequenceValue(keySequence));
+ }
if (oldValue == newValue)
return true;
- d->m_object->setProperty(propName.toUtf8(), newValue);
+ d->m_object->setProperty(propName.toUtf8(), defaultValue);
d->m_addProperties[index] = newValue;
return true;
} else if (!d->m_info.value(index).defaultValue.isNull()) {
@@ -1451,8 +1466,13 @@ bool QDesignerPropertySheet::isVisible(int index) const
}
if (isFakeProperty(index)) {
- if (type == PropertyWindowModality) // Hidden for child widgets
+ switch (type) {
+ case PropertyWindowModality: // Hidden for child widgets
+ case PropertyWindowOpacity:
return d->m_info.value(index).visible;
+ default:
+ break;
+ }
return true;
}
diff --git a/tools/designer/src/lib/shared/qdesigner_propertysheet_p.h b/tools/designer/src/lib/shared/qdesigner_propertysheet_p.h
index 9db7367..0105eac 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertysheet_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_propertysheet_p.h
@@ -176,7 +176,8 @@ public:
PropertyWindowIconText,
PropertyWindowModality,
PropertyWindowModified,
- PropertyStyleSheet
+ PropertyStyleSheet,
+ PropertyText
};
enum ObjectType { ObjectNone, ObjectLabel, ObjectLayout, ObjectLayoutWidget, ObjectQ3GroupBox };
diff --git a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
index 02a2f6d..e3bc64c 100644
--- a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
@@ -467,6 +467,7 @@ QRect ToolBarEventFilter::freeArea(const QToolBar *tb)
switch (tb->orientation()) {
case Qt::Horizontal:
switch (tb->layoutDirection()) {
+ case Qt::LayoutDirectionAuto: // Should never happen
case Qt::LeftToRight:
rc.setX(exclusionRectangle.right() + 1);
break;
diff --git a/tools/designer/src/lib/shared/qtresourcemodel.cpp b/tools/designer/src/lib/shared/qtresourcemodel.cpp
index 709f389..e3fc805 100644
--- a/tools/designer/src/lib/shared/qtresourcemodel.cpp
+++ b/tools/designer/src/lib/shared/qtresourcemodel.cpp
@@ -428,10 +428,10 @@ void QtResourceModelPrivate::removeOldPaths(QtResourceSet *resourceSet, const QS
void QtResourceModelPrivate::setWatcherEnabled(const QString &path, bool enable)
{
- m_fileWatcher->removePath(path);
-
- if (!enable)
+ if (!enable) {
+ m_fileWatcher->removePath(path);
return;
+ }
QFileInfo fi(path);
if (fi.exists())
diff --git a/tools/designer/src/lib/shared/qtresourceview.cpp b/tools/designer/src/lib/shared/qtresourceview.cpp
index c15942f..18fd07b 100644
--- a/tools/designer/src/lib/shared/qtresourceview.cpp
+++ b/tools/designer/src/lib/shared/qtresourceview.cpp
@@ -377,7 +377,8 @@ void QtResourceViewPrivate::createPaths()
if (!m_resourceModel)
return;
- const QString root(QLatin1Char(':'));
+ // Resource root up until 4.6 was ':', changed to ":/" as of 4.7
+ const QString root(QLatin1String(":/"));
QMap<QString, QString> contents = m_resourceModel->contents();
QMapIterator<QString, QString> itContents(contents);
@@ -420,7 +421,7 @@ void QtResourceViewPrivate::filterOutResources()
// 3) we hide these items which has pathToVisible value false.
const bool matchAll = m_filterPattern.isEmpty();
- const QString root(QLatin1Char(':'));
+ const QString root(QLatin1String(":/"));
QQueue<QString> pathQueue;
pathQueue.enqueue(root);
@@ -664,6 +665,8 @@ QString QtResourceView::selectedResource() const
void QtResourceView::selectResource(const QString &resource)
{
+ if (resource.isEmpty())
+ return;
QFileInfo fi(resource);
QDir dir = fi.absoluteDir();
if (fi.isDir())
diff --git a/tools/designer/src/lib/shared/shared.pri b/tools/designer/src/lib/shared/shared.pri
index 570b208..8286360 100644
--- a/tools/designer/src/lib/shared/shared.pri
+++ b/tools/designer/src/lib/shared/shared.pri
@@ -2,11 +2,11 @@
INCLUDEPATH += $$PWD
contains(QT_CONFIG, script): QT += script
-include($$QT_SOURCE_TREE/tools/shared/qtpropertybrowser/qtpropertybrowser.pri)
-include($$QT_SOURCE_TREE/tools/shared/deviceskin/deviceskin.pri)
-include($$QT_SOURCE_TREE/src/tools/rcc/rcc.pri)
-include($$QT_SOURCE_TREE/tools/shared/findwidget/findwidget.pri)
-include($$QT_SOURCE_TREE/tools/shared/qtgradienteditor/qtgradienteditor.pri)
+include(../../../../shared/qtpropertybrowser/qtpropertybrowser.pri)
+include(../../../../shared/deviceskin/deviceskin.pri)
+include(../../../../../src/tools/rcc/rcc.pri)
+include(../../../../shared/findwidget/findwidget.pri)
+include(../../../../shared/qtgradienteditor/qtgradienteditor.pri)
# Input
FORMS += $$PWD/addlinkdialog.ui \
diff --git a/tools/designer/src/lib/shared/stylesheeteditor.cpp b/tools/designer/src/lib/shared/stylesheeteditor.cpp
index b76d700..e809447 100644
--- a/tools/designer/src/lib/shared/stylesheeteditor.cpp
+++ b/tools/designer/src/lib/shared/stylesheeteditor.cpp
@@ -79,6 +79,7 @@ StyleSheetEditor::StyleSheetEditor(QWidget *parent)
: QTextEdit(parent)
{
setTabStopWidth(fontMetrics().width(QLatin1Char(' '))*4);
+ setAcceptRichText(false);
new CssHighlighter(document());
}
diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
index a0c9e83..6f009e3 100644
--- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp
+++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
@@ -2125,6 +2125,21 @@ void QAbstractFormBuilder::saveComboBoxExtraInfo(QComboBox *comboBox, DomWidget
ui_widget->setElementItem(ui_items);
}
+// Return the buttongroups assigned to a button except the internal one
+// (with empty object name) used by Q3ButtonGroup.
+static inline const QButtonGroup *formButtonGroup(const QAbstractButton *widget)
+{
+ const QButtonGroup *buttonGroup = widget->group();
+ if (!buttonGroup)
+ return 0;
+ if (buttonGroup->objectName().isEmpty()) {
+ if (const QWidget *parent = widget->parentWidget())
+ if (!qstrcmp(parent->metaObject()->className(), "Q3ButtonGroup"))
+ return 0;
+ }
+ return buttonGroup;
+}
+
/*!
\internal
\since 4.5
@@ -2133,7 +2148,7 @@ void QAbstractFormBuilder::saveComboBoxExtraInfo(QComboBox *comboBox, DomWidget
void QAbstractFormBuilder::saveButtonExtraInfo(const QAbstractButton *widget, DomWidget *ui_widget, DomWidget *)
{
typedef QList<DomProperty*> DomPropertyList;
- if (const QButtonGroup *buttonGroup = widget->group()) {
+ if (const QButtonGroup *buttonGroup = formButtonGroup(widget)) {
DomPropertyList attributes = ui_widget->elementAttribute();
DomString *domString = new DomString();
domString->setText(buttonGroup->objectName());
diff --git a/tools/designer/src/lib/uilib/container.qdoc b/tools/designer/src/lib/uilib/container.qdoc
index c5b48f5..cea5a45 100644
--- a/tools/designer/src/lib/uilib/container.qdoc
+++ b/tools/designer/src/lib/uilib/container.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/uilib/customwidget.qdoc b/tools/designer/src/lib/uilib/customwidget.qdoc
index 78e7f9d..88c169a 100644
--- a/tools/designer/src/lib/uilib/customwidget.qdoc
+++ b/tools/designer/src/lib/uilib/customwidget.qdoc
@@ -6,35 +6,21 @@
**
** This file is part of the documentation of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:FDL$
** 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 Technology Preview License Agreement accompanying
** this package.
**
-** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
-**
-**
-**
-**
-**
-**
-**
-**
** $QT_END_LICENSE$
**
****************************************************************************/
diff --git a/tools/designer/src/lib/uilib/properties.cpp b/tools/designer/src/lib/uilib/properties.cpp
index 8eccee1..615aa8a 100644
--- a/tools/designer/src/lib/uilib/properties.cpp
+++ b/tools/designer/src/lib/uilib/properties.cpp
@@ -655,16 +655,21 @@ DomProperty *variantToDomProperty(QAbstractFormBuilder *afb, const QMetaObject *
case QVariant::Brush:
dom_prop->setElementBrush(afb->saveBrush(qvariant_cast<QBrush>(v)));
break;
- default:
+ default: {
+ const bool hadAttributeStdset = dom_prop->hasAttributeStdset();
+ const bool attributeStdset = dom_prop->attributeStdset();
delete dom_prop;
if (afb->resourceBuilder()->isResourceType(v)) {
dom_prop = afb->resourceBuilder()->saveResource(afb->workingDirectory(), v);
- if (dom_prop)
+ if (dom_prop) {
dom_prop->setAttributeName(pname);
+ if (hadAttributeStdset)
+ dom_prop->setAttributeStdset(attributeStdset);
+ }
break;
}
uiLibWarning(msgCannotWriteProperty(pname, v));
- return 0;
+ } return 0;
}
return dom_prop;
}
diff --git a/tools/designer/src/plugins/phononwidgets/seeksliderplugin.cpp b/tools/designer/src/plugins/phononwidgets/seeksliderplugin.cpp
index c508fa2..7f597ff 100644
--- a/tools/designer/src/plugins/phononwidgets/seeksliderplugin.cpp
+++ b/tools/designer/src/plugins/phononwidgets/seeksliderplugin.cpp
@@ -66,12 +66,12 @@ QString SeekSliderPlugin::group() const
QString SeekSliderPlugin::toolTip() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString SeekSliderPlugin::whatsThis() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString SeekSliderPlugin::includeFile() const
diff --git a/tools/designer/src/plugins/phononwidgets/videoplayerplugin.cpp b/tools/designer/src/plugins/phononwidgets/videoplayerplugin.cpp
index d4af121..489a08c 100644
--- a/tools/designer/src/plugins/phononwidgets/videoplayerplugin.cpp
+++ b/tools/designer/src/plugins/phononwidgets/videoplayerplugin.cpp
@@ -72,12 +72,12 @@ QString VideoPlayerPlugin::group() const
QString VideoPlayerPlugin::toolTip() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString VideoPlayerPlugin::whatsThis() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString VideoPlayerPlugin::includeFile() const
diff --git a/tools/designer/src/plugins/phononwidgets/volumesliderplugin.cpp b/tools/designer/src/plugins/phononwidgets/volumesliderplugin.cpp
index becd5d9..24eb829 100644
--- a/tools/designer/src/plugins/phononwidgets/volumesliderplugin.cpp
+++ b/tools/designer/src/plugins/phononwidgets/volumesliderplugin.cpp
@@ -66,12 +66,12 @@ QString VolumeSliderPlugin::group() const
QString VolumeSliderPlugin::toolTip() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString VolumeSliderPlugin::whatsThis() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString VolumeSliderPlugin::includeFile() const
diff --git a/tools/designer/src/plugins/plugins.pro b/tools/designer/src/plugins/plugins.pro
index baf5261..bcebb82 100644
--- a/tools/designer/src/plugins/plugins.pro
+++ b/tools/designer/src/plugins/plugins.pro
@@ -3,7 +3,8 @@ CONFIG += ordered
REQUIRES = !CONFIG(static,shared|static)
contains(QT_CONFIG, qt3support): SUBDIRS += widgets
-win32:!contains(QT_EDITION, OpenSource):SUBDIRS += activeqt
+win32: SUBDIRS += activeqt
# contains(QT_CONFIG, opengl): SUBDIRS += tools/view3d
contains(QT_CONFIG, webkit): SUBDIRS += qwebview
contains(QT_CONFIG, phonon): SUBDIRS += phononwidgets
+contains(QT_CONFIG, declarative): SUBDIRS += qdeclarativeview
diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro
new file mode 100644
index 0000000..b8abe87
--- /dev/null
+++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview.pro
@@ -0,0 +1,13 @@
+TEMPLATE = lib
+TARGET = qdeclarativeview
+CONFIG += qt warn_on plugin designer
+QT += declarative
+
+include(../plugins.pri)
+build_all:!build_pass {
+ CONFIG -= build_all
+ CONFIG += release
+}
+
+SOURCES += qdeclarativeview_plugin.cpp
+HEADERS += qdeclarativeview_plugin.h
diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp
new file mode 100644
index 0000000..7148ad0
--- /dev/null
+++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.cpp
@@ -0,0 +1,132 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarativeview_plugin.h"
+
+#include <QtDesigner/QExtensionFactory>
+#include <QtDesigner/QExtensionManager>
+
+#include <QtCore/qplugin.h>
+#include <QtDeclarative/QDeclarativeView>
+
+static const char toolTipC[] = "QtDeclarative view widget";
+
+QT_BEGIN_NAMESPACE
+
+QDeclarativeViewPlugin::QDeclarativeViewPlugin(QObject *parent) :
+ QObject(parent),
+ m_initialized(false)
+{
+}
+
+QString QDeclarativeViewPlugin::name() const
+{
+ return QLatin1String("QDeclarativeView");
+}
+
+QString QDeclarativeViewPlugin::group() const
+{
+ return QLatin1String("Display Widgets");
+}
+
+QString QDeclarativeViewPlugin::toolTip() const
+{
+ return tr(toolTipC);
+}
+
+QString QDeclarativeViewPlugin::whatsThis() const
+{
+ return tr(toolTipC);
+}
+
+QString QDeclarativeViewPlugin::includeFile() const
+{
+ return QLatin1String("QtDeclarative/QDeclarativeView");
+}
+
+QIcon QDeclarativeViewPlugin::icon() const
+{
+ return QIcon();
+}
+
+bool QDeclarativeViewPlugin::isContainer() const
+{
+ return false;
+}
+
+QWidget *QDeclarativeViewPlugin::createWidget(QWidget *parent)
+{
+ return new QDeclarativeView(parent);
+}
+
+bool QDeclarativeViewPlugin::isInitialized() const
+{
+ return m_initialized;
+}
+
+void QDeclarativeViewPlugin::initialize(QDesignerFormEditorInterface * /*core*/)
+{
+ if (m_initialized)
+ return;
+
+ m_initialized = true;
+}
+
+QString QDeclarativeViewPlugin::domXml() const
+{
+ return QLatin1String("\
+ <ui language=\"c++\">\
+ <widget class=\"QDeclarativeView\" name=\"declarativeView\">\
+ <property name=\"geometry\">\
+ <rect>\
+ <x>0</x>\
+ <y>0</y>\
+ <width>300</width>\
+ <height>200</height>\
+ </rect>\
+ </property>\
+ </widget>\
+ </ui>");
+}
+
+Q_EXPORT_PLUGIN2(customwidgetplugin, QDeclarativeViewPlugin)
+
+QT_END_NAMESPACE
diff --git a/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h
new file mode 100644
index 0000000..2f13f16
--- /dev/null
+++ b/tools/designer/src/plugins/qdeclarativeview/qdeclarativeview_plugin.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Designer 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEVIEW_PLUGIN_H
+#define QDECLARATIVEVIEW_PLUGIN_H
+
+#include <QtDesigner/QDesignerCustomWidgetInterface>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeViewPlugin: public QObject, public QDesignerCustomWidgetInterface
+{
+ Q_OBJECT
+ Q_INTERFACES(QDesignerCustomWidgetInterface)
+public:
+ QDeclarativeViewPlugin(QObject *parent = 0);
+
+ virtual QString name() const;
+ virtual QString group() const;
+ virtual QString toolTip() const;
+ virtual QString whatsThis() const;
+ virtual QString includeFile() const;
+ virtual QIcon icon() const;
+ virtual bool isContainer() const;
+ virtual QWidget *createWidget(QWidget *parent);
+ virtual bool isInitialized() const;
+ virtual void initialize(QDesignerFormEditorInterface *core);
+ virtual QString domXml() const;
+
+private:
+ bool m_initialized;
+};
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVEVIEW_PLUGIN_H
diff --git a/tools/designer/src/plugins/qwebview/qwebview_plugin.cpp b/tools/designer/src/plugins/qwebview/qwebview_plugin.cpp
index 61f7e66..c90e191 100644
--- a/tools/designer/src/plugins/qwebview/qwebview_plugin.cpp
+++ b/tools/designer/src/plugins/qwebview/qwebview_plugin.cpp
@@ -69,12 +69,12 @@ QString QWebViewPlugin::group() const
QString QWebViewPlugin::toolTip() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString QWebViewPlugin::whatsThis() const
{
- return QString(QLatin1String(toolTipC));
+ return tr(toolTipC);
}
QString QWebViewPlugin::includeFile() const
diff --git a/tools/designer/translations/translations.pro b/tools/designer/translations/translations.pro
deleted file mode 100644
index a1b99fd..0000000
--- a/tools/designer/translations/translations.pro
+++ /dev/null
@@ -1,140 +0,0 @@
-include(../src/components/buddyeditor/buddyeditor.pri)
-include(../src/components/component.pri)
-include(../src/components/formeditor/formeditor.pri)
-include(../src/components/objectinspector/objectinspector.pri)
-include(../src/components/propertyeditor/propertyeditor.pri)
-include(../src/components/signalsloteditor/signalsloteditor.pri)
-include(../src/components/tabordereditor/tabordereditor.pri)
-include(../src/components/taskmenu/taskmenu.pri)
-include(../src/components/widgetbox/widgetbox.pri)
-include(../src/lib/extension/extension.pri)
-include(../src/lib/sdk/sdk.pri)
-include(../src/lib/shared/shared.pri)
-include(../src/lib/uilib/uilib.pri)
-include(../../shared/qttoolbardialog/qttoolbardialog.pri)
-include(../../shared/qtpropertybrowser/qtpropertybrowser.pri)
-include(../../shared/qtgradienteditor/qtgradienteditor.pri)
-
-# Include ActiveQt plugin
-SOURCES += ../src/plugins/activeqt/qaxwidgetextrainfo.cpp \
- ../src/plugins/activeqt/qaxwidgetplugin.cpp \
- ../src/plugins/activeqt/qaxwidgetpropertysheet.cpp \
- ../src/plugins/activeqt/qaxwidgettaskmenu.cpp \
- ../src/plugins/activeqt/qdesigneraxwidget.cpp
-
-HEADERS += ../src/plugins/activeqt/qaxwidgetextrainfo.h \
- ../src/plugins/activeqt/qaxwidgetplugin.h \
- ../src/plugins/activeqt/qaxwidgetpropertysheet.h \
- ../src/plugins/activeqt/qaxwidgettaskmenu.h \
- ../src/plugins/activeqt/qdesigneraxwidget.h \
- ../../../src/activeqt/shared/qaxtypes.h
-
-
-# Include Qt3Support plugin
-
-SOURCES += ../src/plugins/widgets/qt3supportwidgets.cpp
-HEADERS += ../src/plugins/widgets/q3iconview/q3iconview_extrainfo.h \
- ../src/plugins/widgets/q3iconview/q3iconview_plugin.h \
- ../src/plugins/widgets/q3listview/q3listview_extrainfo.h \
- ../src/plugins/widgets/q3listview/q3listview_plugin.h \
- ../src/plugins/widgets/q3mainwindow/q3mainwindow_container.h \
- ../src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.h \
- ../src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.h \
- ../src/plugins/widgets/q3toolbar/q3toolbar_plugin.h \
- ../src/plugins/widgets/q3widgetstack/q3widgetstack_container.h \
- ../src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.h \
- ../src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack_p.h \
- ../src/plugins/widgets/q3wizard/q3wizard_container.h \
- ../src/plugins/widgets/q3wizard/q3wizard_plugin.h \
- ../src/plugins/widgets/q3listbox/q3listbox_extrainfo.h \
- ../src/plugins/widgets/q3listbox/q3listbox_plugin.h \
- ../src/plugins/widgets/q3table/q3table_extrainfo.h \
- ../src/plugins/widgets/q3table/q3table_plugin.h \
- ../src/plugins/widgets/q3textedit/q3textedit_extrainfo.h \
- ../src/plugins/widgets/q3textedit/q3textedit_plugin.h \
- ../src/plugins/widgets/q3widgets/q3widget_plugins.h
-
-SOURCES += ../src/plugins/widgets/q3iconview/q3iconview_extrainfo.cpp \
- ../src/plugins/widgets/q3iconview/q3iconview_plugin.cpp \
- ../src/plugins/widgets/q3listview/q3listview_extrainfo.cpp \
- ../src/plugins/widgets/q3listview/q3listview_plugin.cpp \
- ../src/plugins/widgets/q3mainwindow/q3mainwindow_container.cpp \
- ../src/plugins/widgets/q3mainwindow/q3mainwindow_plugin.cpp \
- ../src/plugins/widgets/q3toolbar/q3toolbar_extrainfo.cpp \
- ../src/plugins/widgets/q3toolbar/q3toolbar_plugin.cpp \
- ../src/plugins/widgets/q3widgetstack/q3widgetstack_container.cpp \
- ../src/plugins/widgets/q3widgetstack/q3widgetstack_plugin.cpp \
- ../src/plugins/widgets/q3widgetstack/qdesigner_q3widgetstack.cpp \
- ../src/plugins/widgets/q3wizard/q3wizard_container.cpp \
- ../src/plugins/widgets/q3wizard/q3wizard_plugin.cpp \
- ../src/plugins/widgets/q3listbox/q3listbox_extrainfo.cpp \
- ../src/plugins/widgets/q3listbox/q3listbox_plugin.cpp \
- ../src/plugins/widgets/q3table/q3table_extrainfo.cpp \
- ../src/plugins/widgets/q3table/q3table_plugin.cpp \
- ../src/plugins/widgets/q3textedit/q3textedit_extrainfo.cpp \
- ../src/plugins/widgets/q3textedit/q3textedit_plugin.cpp \
- ../src/plugins/widgets/q3widgets/q3widget_plugins.cpp
-
-# Include those manually as they do not contain any directory specification
-APP_DIR=../src/designer
-SOURCES += $$APP_DIR/appfontdialog.cpp \
- $$APP_DIR/assistantclient.cpp \
- $$APP_DIR/main.cpp \
- $$APP_DIR/mainwindow.cpp \
- $$APP_DIR/newform.cpp \
- $$APP_DIR/preferencesdialog.cpp \
- $$APP_DIR/qdesigner_actions.cpp \
- $$APP_DIR/qdesigner_appearanceoptions.cpp \
- $$APP_DIR/qdesigner.cpp \
- $$APP_DIR/qdesigner_formwindow.cpp \
- $$APP_DIR/qdesigner_server.cpp \
- $$APP_DIR/qdesigner_settings.cpp \
- $$APP_DIR/qdesigner_toolwindow.cpp \
- $$APP_DIR/qdesigner_workbench.cpp \
- $$APP_DIR/saveformastemplate.cpp \
- $$APP_DIR/versiondialog.cpp
-
-HEADERS+= $$APP_DIR/appfontdialog.h \
- $$APP_DIR/assistantclient.h \
- $$APP_DIR/designer_enums.h \
- $$APP_DIR/mainwindow.h \
- $$APP_DIR/newform.h \
- $$APP_DIR/preferencesdialog.h \
- $$APP_DIR/qdesigner_actions.h \
- $$APP_DIR/qdesigner_appearanceoptions.h \
- $$APP_DIR/qdesigner_formwindow.h \
- $$APP_DIR/qdesigner.h \
- $$APP_DIR/qdesigner_pch.h \
- $$APP_DIR/qdesigner_server.h \
- $$APP_DIR/qdesigner_settings.h \
- $$APP_DIR/qdesigner_toolwindow.h \
- $$APP_DIR/qdesigner_workbench.h \
- $$APP_DIR/saveformastemplate.h \
- $$APP_DIR/versiondialog.h
-
-FORMS += $$APP_DIR/preferencesdialog.ui \
- $$APP_DIR/qdesigner_appearanceoptions.ui \
- $$APP_DIR/saveformastemplate.ui
-
-# Shared solutions
-SOURCES += ../../shared/fontpanel/fontpanel.cpp \
- ../../shared/deviceskin/deviceskin.cpp \
- ../../shared/findwidget/abstractfindwidget.cpp \
- ../../shared/findwidget/itemviewfindwidget.cpp \
- ../../shared/findwidget/texteditfindwidget.cpp \
-
-HEADERS += ../../shared/findwidget/abstractfindwidget.h \
- ../../shared/findwidget/itemviewfindwidget.h \
- ../../shared/findwidget/texteditfindwidget.h
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/designer_cs.ts \
- $$TR_DIR/designer_de.ts \
- $$TR_DIR/designer_fr.ts \
- $$TR_DIR/designer_ja.ts \
- $$TR_DIR/designer_pl.ts \
- $$TR_DIR/designer_ru.ts \
- $$TR_DIR/designer_sl.ts \
- $$TR_DIR/designer_zh_CN.ts \
- $$TR_DIR/designer_zh_TW.ts
diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp
index 3a30027..2e397ad 100644
--- a/tools/linguist/lconvert/main.cpp
+++ b/tools/linguist/lconvert/main.cpp
@@ -45,9 +45,17 @@
#include <QtCore/QDebug>
#include <QtCore/QString>
#include <QtCore/QStringList>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
#include <iostream>
+QT_USE_NAMESPACE
+
+class LC {
+ Q_DECLARE_TR_FUNCTIONS(LConvert)
+};
+
static int usage(const QStringList &args)
{
Q_UNUSED(args);
@@ -57,7 +65,7 @@ static int usage(const QStringList &args)
foreach (Translator::FileFormat format, Translator::registeredFileFormats())
loaders += line.arg(format.extension, -5).arg(format.description);
- std::cerr << qPrintable(QString(QLatin1String("\nUsage:\n"
+ std::cerr << qPrintable(LC::tr("\nUsage:\n"
" lconvert [options] <infile> [<infile>...]\n\n"
"lconvert is part of Qt's Linguist tool chain. It can be used as a\n"
"stand-alone tool to convert and filter translation data files.\n"
@@ -119,7 +127,7 @@ static int usage(const QStringList &args)
" 0 on success\n"
" 1 on command line parse failures\n"
" 2 on read failures\n"
- " 3 on write failures\n")).arg(loaders));
+ " 3 on write failures\n").arg(loaders));
return 1;
}
@@ -132,8 +140,19 @@ struct File
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
- QStringList args = app.arguments();
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+ QStringList args = app.arguments();
QList<File> inFiles;
QString inFormat(QLatin1String("auto"));
QString outFileName;
@@ -238,7 +257,7 @@ int main(int argc, char *argv[])
tr.setLanguageCode(Translator::guessLanguageCodeFromFileName(inFiles[0].name));
if (!tr.load(inFiles[0].name, cd, inFiles[0].format)) {
- qWarning() << qPrintable(cd.error());
+ std::cerr << qPrintable(cd.error());
return 2;
}
tr.reportDuplicates(tr.resolveDuplicates(), inFiles[0].name, verbose);
@@ -246,7 +265,7 @@ int main(int argc, char *argv[])
for (int i = 1; i < inFiles.size(); ++i) {
Translator tr2;
if (!tr2.load(inFiles[i].name, cd, inFiles[i].format)) {
- qWarning() << qPrintable(cd.error());
+ std::cerr << qPrintable(cd.error());
return 2;
}
tr2.reportDuplicates(tr2.resolveDuplicates(), inFiles[i].name, verbose);
@@ -271,11 +290,11 @@ int main(int argc, char *argv[])
tr.normalizeTranslations(cd);
if (!cd.errors().isEmpty()) {
- qWarning("%s", qPrintable(cd.error()));
+ std::cerr << qPrintable(cd.error());
cd.clearErrors();
}
if (!tr.save(outFileName, cd, outFormat)) {
- qWarning("%s", qPrintable(cd.error()));
+ std::cerr << qPrintable(cd.error());
return 3;
}
return 0;
diff --git a/tools/linguist/linguist.pro b/tools/linguist/linguist.pro
index 85ecd5a..248c89e 100644
--- a/tools/linguist/linguist.pro
+++ b/tools/linguist/linguist.pro
@@ -1,6 +1,6 @@
TEMPLATE = subdirs
SUBDIRS = \
- linguist \
lrelease \
lupdate \
lconvert
+!no-png:!contains(QT_CONFIG, no-gui):SUBDIRS += linguist
diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro
index 693bc71..ce8d585 100644
--- a/tools/linguist/linguist/linguist.pro
+++ b/tools/linguist/linguist/linguist.pro
@@ -9,7 +9,7 @@ CONFIG += qt \
uitools
DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
-build_all:!build_pass {
+build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
}
@@ -42,7 +42,7 @@ SOURCES += \
statistics.cpp \
translatedialog.cpp \
translationsettingsdialog.cpp \
- ../shared/simtexth.cpp
+ ../shared/simtexth.cpp
HEADERS += \
batchtranslationdialog.h \
@@ -71,7 +71,7 @@ contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE
DEFINES += QT_KEYWORDS
TARGET = linguist
win32:RC_FILE = linguist.rc
-mac {
+mac {
static:CONFIG -= global_init_link_order
ICON = linguist.icns
TARGET = Linguist
@@ -94,14 +94,3 @@ FORMS += statistics.ui \
translationsettings.ui \
finddialog.ui
RESOURCES += linguist.qrc
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/linguist_cs.ts \
- $$TR_DIR/linguist_de.ts \
- $$TR_DIR/linguist_fr.ts \
- $$TR_DIR/linguist_ja.ts \
- $$TR_DIR/linguist_pl.ts \
- $$TR_DIR/linguist_ru.ts \
- $$TR_DIR/linguist_zh_CN.ts \
- $$TR_DIR/linguist_zh_TW.ts
diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp
index 321fe8c..1189b99 100644
--- a/tools/linguist/linguist/mainwindow.cpp
+++ b/tools/linguist/linguist/mainwindow.cpp
@@ -142,10 +142,13 @@ static Ending ending(QString str, QLocale::Language lang)
case 0x2048: // question exclamation mark
case 0x2049: // exclamation question mark
case 0x2762: // heavy exclamation mark ornament
+ case 0xff01: // full width exclamation mark
+ case 0xff1f: // full width question mark
return End_Interrobang;
case 0x003b: // greek 'compatibility' questionmark
return lang == QLocale::Greek ? End_Interrobang : End_None;
case 0x003a: // colon
+ case 0xff1a: // full width colon
return End_Colon;
case 0x2026: // horizontal ellipsis
return End_Ellipsis;
@@ -1027,6 +1030,8 @@ void MainWindow::findAgain()
break;
if (searchItem(m->extraComment()))
break;
+ if (searchItem(m->translatorComment()))
+ break;
m_foundWhere = DataModel::NoLocation;
// did not find the search string in this message
}
@@ -1347,7 +1352,7 @@ void MainWindow::manual()
<< (QT_VERSION >> 16) << ((QT_VERSION >> 8) & 0xFF)
<< (QT_VERSION & 0xFF)
<< QLatin1String("/qdoc/linguist-manual.html")
- << QLatin1Char('\0') << endl;
+ << QLatin1Char('\n') << endl;
}
void MainWindow::about()
@@ -1517,7 +1522,7 @@ void MainWindow::selectedMessageChanged(const QModelIndex &sortedIndex, const QM
}
m_phraseView->setSourceText(-1, QString());
}
- if (m) {
+ if (m && !m->fileName().isEmpty()) {
if (hasFormPreview(m->fileName())) {
m_sourceAndFormView->setCurrentWidget(m_formPreviewView);
m_formPreviewView->setSourceContext(model, m);
@@ -1572,7 +1577,7 @@ void MainWindow::updateTranslation(const QStringList &translations)
return;
m->setTranslations(translations);
- if (hasFormPreview(m->fileName()))
+ if (!m->fileName().isEmpty() && hasFormPreview(m->fileName()))
m_formPreviewView->setSourceContext(m_currentIndex.model(), m);
updateDanger(m_currentIndex, true);
@@ -1810,28 +1815,50 @@ QString MainWindow::friendlyString(const QString& str)
return f.simplified();
}
+static inline void setThemeIcon(QAction *action, const char *name, const char *fallback)
+{
+ const QIcon fallbackIcon(MainWindow::resourcePrefix() + QLatin1String(fallback));
+#ifdef Q_WS_X11
+ action->setIcon(QIcon::fromTheme(QLatin1String(name), fallbackIcon));
+#else
+ Q_UNUSED(name)
+ action->setIcon(fallbackIcon);
+#endif
+}
+
void MainWindow::setupMenuBar()
{
+ // There are no fallback icons for these
+#ifdef Q_WS_X11
+ m_ui.menuRecentlyOpenedFiles->setIcon(QIcon::fromTheme(QLatin1String("document-open-recent")));
+ m_ui.actionCloseAll->setIcon(QIcon::fromTheme(QLatin1String("window-close")));
+ m_ui.actionExit->setIcon(QIcon::fromTheme(QLatin1String("application-exit")));
+ m_ui.actionSelectAll->setIcon(QIcon::fromTheme(QLatin1String("edit-select-all")));
+#endif
+
+ // Prefer theme icons when available for these actions
+ setThemeIcon(m_ui.actionOpen, "document-open", "/fileopen.png");
+ setThemeIcon(m_ui.actionOpenAux, "document-open", "/fileopen.png");
+ setThemeIcon(m_ui.actionSave, "document-save", "/filesave.png");
+ setThemeIcon(m_ui.actionSaveAll, "document-save", "/filesave.png");
+ setThemeIcon(m_ui.actionPrint, "document-print", "/print.png");
+ setThemeIcon(m_ui.actionRedo, "edit-redo", "/redo.png");
+ setThemeIcon(m_ui.actionUndo, "edit-undo", "/undo.png");
+ setThemeIcon(m_ui.actionCut, "edit-cut", "/editcut.png");
+ setThemeIcon(m_ui.actionCopy, "edit-copy", "/editcopy.png");
+ setThemeIcon(m_ui.actionPaste, "edit-paste", "/editpaste.png");
+ setThemeIcon(m_ui.actionFind, "edit-find", "/searchfind.png");
+
+ // No well defined theme icons for these actions
m_ui.actionAccelerators->setIcon(QIcon(resourcePrefix() + QLatin1String("/accelerator.png")));
m_ui.actionOpenPhraseBook->setIcon(QIcon(resourcePrefix() + QLatin1String("/book.png")));
m_ui.actionDoneAndNext->setIcon(QIcon(resourcePrefix() + QLatin1String("/doneandnext.png")));
- m_ui.actionCopy->setIcon(QIcon(resourcePrefix() + QLatin1String("/editcopy.png")));
- m_ui.actionCut->setIcon(QIcon(resourcePrefix() + QLatin1String("/editcut.png")));
- m_ui.actionPaste->setIcon(QIcon(resourcePrefix() + QLatin1String("/editpaste.png")));
- m_ui.actionOpen->setIcon(QIcon(resourcePrefix() + QLatin1String("/fileopen.png")));
- m_ui.actionOpenAux->setIcon(QIcon(resourcePrefix() + QLatin1String("/fileopen.png")));
- m_ui.actionSaveAll->setIcon(QIcon(resourcePrefix() + QLatin1String("/filesave.png")));
- m_ui.actionSave->setIcon(QIcon(resourcePrefix() + QLatin1String("/filesave.png")));
m_ui.actionNext->setIcon(QIcon(resourcePrefix() + QLatin1String("/next.png")));
m_ui.actionNextUnfinished->setIcon(QIcon(resourcePrefix() + QLatin1String("/nextunfinished.png")));
m_ui.actionPhraseMatches->setIcon(QIcon(resourcePrefix() + QLatin1String("/phrase.png")));
m_ui.actionEndingPunctuation->setIcon(QIcon(resourcePrefix() + QLatin1String("/punctuation.png")));
m_ui.actionPrev->setIcon(QIcon(resourcePrefix() + QLatin1String("/prev.png")));
m_ui.actionPrevUnfinished->setIcon(QIcon(resourcePrefix() + QLatin1String("/prevunfinished.png")));
- m_ui.actionPrint->setIcon(QIcon(resourcePrefix() + QLatin1String("/print.png")));
- m_ui.actionRedo->setIcon(QIcon(resourcePrefix() + QLatin1String("/redo.png")));
- m_ui.actionFind->setIcon(QIcon(resourcePrefix() + QLatin1String("/searchfind.png")));
- m_ui.actionUndo->setIcon(QIcon(resourcePrefix() + QLatin1String("/undo.png")));
m_ui.actionPlaceMarkerMatches->setIcon(QIcon(resourcePrefix() + QLatin1String("/validateplacemarkers.png")));
m_ui.actionWhatsThis->setIcon(QIcon(resourcePrefix() + QLatin1String("/whatsthis.png")));
@@ -1969,7 +1996,7 @@ void MainWindow::updateLatestModel(int model)
if (m_currentIndex.isValid()) {
if (MessageItem *item = m_dataModel->messageItem(m_currentIndex)) {
- if (hasFormPreview(item->fileName()))
+ if (!item->fileName().isEmpty() && hasFormPreview(item->fileName()))
m_formPreviewView->setSourceContext(model, item);
if (enableRw && !item->isObsolete())
m_phraseView->setSourceText(model, item->text());
@@ -2370,7 +2397,7 @@ static bool haveMnemonic(const QString &str)
// because we get a lot of false positives.
if (c != '&' && c != ' ' && QChar(c).isPrint()) {
const ushort *pp = p;
- for (; *p < 256 && ::isalpha(*p); p++) ;
+ for (; *p < 256 && isalpha(*p); p++) ;
if (pp == p || *p != ';')
return true;
// This looks like a HTML &entity;, so ignore it. As a HTML string
@@ -2471,8 +2498,8 @@ void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose)
}
if (m_ui.actionPlaceMarkerMatches->isChecked()) {
- // Stores the occurence count of the place markers in the map placeMarkerIndexes.
- // i.e. the occurence count of %1 is stored at placeMarkerIndexes[1],
+ // Stores the occurrence count of the place markers in the map placeMarkerIndexes.
+ // i.e. the occurrence count of %1 is stored at placeMarkerIndexes[1],
// count of %2 is stored at placeMarkerIndexes[2] etc.
// In the first pass, it counts all place markers in the sourcetext.
// In the second pass it (de)counts all place markers in the translation.
diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui
index 450ce89..4edde5e 100644
--- a/tools/linguist/linguist/mainwindow.ui
+++ b/tools/linguist/linguist/mainwindow.ui
@@ -679,7 +679,7 @@
<string>About Qt</string>
</property>
<property name="whatsThis">
- <string>Display information about the Qt toolkit by Trolltech.</string>
+ <string>Display information about the Qt toolkit by Nokia.</string>
</property>
<property name="menuRole">
<enum>QAction::AboutQtRole</enum>
diff --git a/tools/linguist/linguist/messagemodel.cpp b/tools/linguist/linguist/messagemodel.cpp
index 4e2b473..39ba9fd 100644
--- a/tools/linguist/linguist/messagemodel.cpp
+++ b/tools/linguist/linguist/messagemodel.cpp
@@ -402,7 +402,7 @@ bool DataModel::setLanguageAndCountry(QLocale::Language lang, QLocale::Country c
if (lang == QLocale::C || uint(lang) > uint(QLocale::LastLanguage)) // XXX does this make any sense?
lang = QLocale::English;
QByteArray rules;
- bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms);
+ bool ok = getNumerusInfo(lang, country, &rules, &m_numerusForms, 0);
m_localizedLanguage = QCoreApplication::translate("MessageEditor", QLocale::languageToString(lang).toAscii());
m_countRefNeeds.clear();
for (int i = 0; i < rules.size(); ++i) {
diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp
index 254daf4..709ec35 100644
--- a/tools/linguist/linguist/phrase.cpp
+++ b/tools/linguist/linguist/phrase.cpp
@@ -188,10 +188,9 @@ bool QphHandler::characters(const QString &ch)
bool QphHandler::fatalError(const QXmlParseException &exception)
{
if (ferrorCount++ == 0) {
- QString msg;
- msg.sprintf("Parse error at line %d, column %d (%s).",
- exception.lineNumber(), exception.columnNumber(),
- exception.message().toLatin1().constData());
+ QString msg = PhraseBook::tr("Parse error at line %1, column %2 (%3).")
+ .arg(exception.lineNumber()).arg(exception.columnNumber())
+ .arg(exception.message());
QMessageBox::information(0,
QObject::tr("Qt Linguist"), msg);
}
diff --git a/tools/linguist/linguist/printout.cpp b/tools/linguist/linguist/printout.cpp
index 581dc00..7ec6875 100644
--- a/tools/linguist/linguist/printout.cpp
+++ b/tools/linguist/linguist/printout.cpp
@@ -130,7 +130,7 @@ void PrintOut::addBox(int percent, const QString &text, Style style, Qt::Alignme
cp.rect.setSize(QSize(cp.rect.width() + wd, qMax(cp.rect.height(), ht)));
}
-// use init if inital vsize should be calculated (first breakPage call)
+// use init if initial vsize should be calculated (first breakPage call)
void PrintOut::breakPage(bool init)
{
static const int LeftAlign = Qt::AlignLeft | Qt::AlignTop;
diff --git a/tools/linguist/linguist/sourcecodeview.cpp b/tools/linguist/linguist/sourcecodeview.cpp
index b8dd9c0..d2eef56 100644
--- a/tools/linguist/linguist/sourcecodeview.cpp
+++ b/tools/linguist/linguist/sourcecodeview.cpp
@@ -64,7 +64,7 @@ void SourceCodeView::setSourceContext(const QString &fileName, const int lineNum
m_fileToLoad.clear();
setToolTip(fileName);
- if (fileName.isNull()) {
+ if (fileName.isEmpty()) {
clear();
m_currentFileName.clear();
appendHtml(tr("<i>Source code not available</i>"));
diff --git a/tools/linguist/lrelease/lrelease.pro b/tools/linguist/lrelease/lrelease.pro
index 6beafa3..89694be 100644
--- a/tools/linguist/lrelease/lrelease.pro
+++ b/tools/linguist/lrelease/lrelease.pro
@@ -15,6 +15,7 @@ macx:SOURCES += $$QT_SOURCE_TREE/src/corelib/io/qsettings_mac.cpp
include(../../../src/tools/bootstrap/bootstrap.pri)
include(../shared/formats.pri)
include(../shared/proparser.pri)
+include(../../shared/symbian/epocroot.pri)
win32:LIBS += -ladvapi32 # for qsettings_win.cpp
diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 266474e..5e6edb4 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -55,6 +55,8 @@
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
+#include <iostream>
+
QT_USE_NAMESPACE
#ifdef QT_BOOTSTRAPPED
@@ -63,6 +65,17 @@ static void initBinaryDir(
const char *argv0
#endif
);
+
+struct LR {
+ static inline QString tr(const char *sourceText, const char *comment = 0)
+ {
+ return QCoreApplication::translate("LRelease", sourceText, comment);
+ }
+};
+#else
+class LR {
+ Q_DECLARE_TR_FUNCTIONS(LRelease)
+};
#endif
static void printOut(const QString & out)
@@ -73,7 +86,7 @@ static void printOut(const QString & out)
static void printUsage()
{
- printOut(QCoreApplication::tr(
+ printOut(LR::tr(
"Usage:\n"
" lrelease [options] project-file\n"
" lrelease [options] ts-files [-qm qm-file]\n\n"
@@ -106,7 +119,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo
ConversionData cd;
bool ok = tor.load(tsFileName, cd, QLatin1String("auto"));
if (!ok) {
- qWarning("lrelease error: %s\n", qPrintable(cd.error()));
+ std::cerr << qPrintable(LR::tr("lrelease error: %1").arg(cd.error()));
} else {
if (!cd.errors().isEmpty())
printOut(cd.error());
@@ -121,17 +134,17 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
tor.reportDuplicates(tor.resolveDuplicates(), qmFileName, cd.isVerbose());
if (cd.isVerbose())
- printOut(QCoreApplication::tr( "Updating '%1'...\n").arg(qmFileName));
+ printOut(LR::tr("Updating '%1'...\n").arg(qmFileName));
if (removeIdentical) {
if (cd.isVerbose())
- printOut(QCoreApplication::tr( "Removing translations equal to source text in '%1'...\n").arg(qmFileName));
+ printOut(LR::tr("Removing translations equal to source text in '%1'...\n").arg(qmFileName));
tor.stripIdenticalSourceTranslations();
}
QFile file(qmFileName);
if (!file.open(QIODevice::WriteOnly)) {
- qWarning("lrelease error: cannot create '%s': %s\n",
- qPrintable(qmFileName), qPrintable(file.errorString()));
+ std::cerr << qPrintable(LR::tr("lrelease error: cannot create '%1': %2\n")
+ .arg(qmFileName, file.errorString()));
return false;
}
@@ -140,8 +153,8 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
file.close();
if (!ok) {
- qWarning("lrelease error: cannot save '%s': %s\n",
- qPrintable(qmFileName), qPrintable(cd.error()));
+ std::cerr << qPrintable(LR::tr("lrelease error: cannot save '%1': %2")
+ .arg(qmFileName, cd.error()));
} else if (!cd.errors().isEmpty()) {
printOut(cd.error());
}
@@ -178,10 +191,18 @@ int main(int argc, char **argv)
);
#else
QCoreApplication app(argc, argv);
+#ifndef Q_OS_WIN32
QTranslator translator;
- if (translator.load(QLatin1String("lrelease_") + QLocale::system().name()))
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
app.installTranslator(&translator);
-#endif
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+#endif // QT_BOOTSTRAPPED
ConversionData cd;
cd.m_verbose = true; // the default is true starting with Qt 4.2
@@ -219,7 +240,7 @@ int main(int argc, char **argv)
cd.m_verbose = true;
continue;
} else if (!strcmp(argv[i], "-version")) {
- printOut(QCoreApplication::tr( "lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)) );
+ printOut(LR::tr("lrelease version %1\n").arg(QLatin1String(QT_VERSION_STR)));
return 0;
} else if (!strcmp(argv[i], "-qm")) {
if (i == argc - 1) {
@@ -253,19 +274,23 @@ int main(int argc, char **argv)
visitor.setVerbose(cd.isVerbose());
if (!visitor.queryProFile(&pro)) {
- qWarning("lrelease error: cannot read project file '%s'.", qPrintable(inputFile));
+ std::cerr << qPrintable(LR::tr(
+ "lrelease error: cannot read project file '%1'.\n")
+ .arg(inputFile));
continue;
}
if (!visitor.accept(&pro)) {
- qWarning("lrelease error: cannot process project file '%s'.", qPrintable(inputFile));
+ std::cerr << qPrintable(LR::tr(
+ "lrelease error: cannot process project file '%1'.\n")
+ .arg(inputFile));
continue;
}
QStringList translations = visitor.values(QLatin1String("TRANSLATIONS"));
if (translations.isEmpty()) {
- qWarning("lrelease warning: Met no 'TRANSLATIONS' entry in"
- " project file '%s'\n",
- qPrintable(inputFile));
+ std::cerr << qPrintable(LR::tr(
+ "lrelease warning: Met no 'TRANSLATIONS' entry in project file '%1'\n")
+ .arg(inputFile));
} else {
QDir proDir(fi.absolutePath());
foreach (const QString &trans, translations)
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
index db4bbca..6ea7299 100644
--- a/tools/linguist/lupdate/cpp.cpp
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -50,11 +50,18 @@
#include <QtCore/QString>
#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
+#include <QtCore/QCoreApplication>
+
+#include <iostream>
#include <ctype.h> // for isXXX()
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
/* qmake ignore Q_OBJECT */
static QString MagicComment(QLatin1String("TRANSLATOR"));
@@ -226,6 +233,8 @@ private:
int elseLine;
};
+ std::ostream &yyMsg(int line = 0);
+
uint getChar();
uint getToken();
bool getMacroArgs();
@@ -352,6 +361,12 @@ CppParser::CppParser(ParseResults *_results)
inDefine = false;
}
+
+std::ostream &CppParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(yyFileName) << ':' << (line ? line : yyLineNo) << ": ";
+}
+
void CppParser::setInput(const QString &in)
{
yyInStr = in;
@@ -474,6 +489,7 @@ STRING(class);
STRING(findMessage);
STRING(friend);
STRING(namespace);
+STRING(operator);
STRING(qtTrId);
STRING(return);
STRING(struct);
@@ -613,9 +629,9 @@ uint CppParser::getToken()
if (yyBracketDepth != is.bracketDepth1st
|| yyBraceDepth != is.braceDepth1st
|| yyParenDepth != is.parenDepth1st)
- qWarning("%s:%d: Parenthesis/bracket/brace mismatch between "
- "#if and #else branches; using #if branch\n",
- qPrintable(yyFileName), is.elseLine);
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/bracket/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
} else {
is.bracketDepth1st = yyBracketDepth;
is.braceDepth1st = yyBraceDepth;
@@ -636,9 +652,9 @@ uint CppParser::getToken()
if (yyBracketDepth != is.bracketDepth1st
|| yyBraceDepth != is.braceDepth1st
|| yyParenDepth != is.parenDepth1st)
- qWarning("%s:%d: Parenthesis/brace mismatch between "
- "#if and #else branches; using #if branch\n",
- qPrintable(yyFileName), is.elseLine);
+ yyMsg(is.elseLine)
+ << qPrintable(LU::tr("Parenthesis/brace mismatch between "
+ "#if and #else branches; using #if branch\n"));
yyBracketDepth = is.bracketDepth1st;
yyBraceDepth = is.braceDepth1st;
yyParenDepth = is.parenDepth1st;
@@ -664,8 +680,7 @@ uint CppParser::getToken()
forever {
yyCh = getChar();
if (yyCh == EOF) {
- qWarning("%s:%d: Unterminated C++ comment\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
break;
}
@@ -739,6 +754,20 @@ uint CppParser::getToken()
if (yyWord == strnamespace)
return Tok_namespace;
break;
+ case 'o':
+ if (yyWord == stroperator) {
+ // Operator overload declaration/definition.
+ // We need to prevent those characters from confusing the followup
+ // parsing. Actually using them does not add value, so just eat them.
+ while (isspace(yyCh))
+ yyCh = getChar();
+ while (yyCh == '+' || yyCh == '-' || yyCh == '*' || yyCh == '/' || yyCh == '%'
+ || yyCh == '=' || yyCh == '<' || yyCh == '>' || yyCh == '!'
+ || yyCh == '&' || yyCh == '|' || yyCh == '~' || yyCh == '^'
+ || yyCh == '[' || yyCh == ']')
+ yyCh = getChar();
+ }
+ break;
case 'q':
if (yyWord == strqtTrId)
return Tok_trid;
@@ -795,8 +824,7 @@ uint CppParser::getToken()
forever {
yyCh = getChar();
if (yyCh == EOF) {
- qWarning("%s:%d: Unterminated C++ comment\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ comment\n"));
break;
}
*ptr++ = yyCh;
@@ -829,8 +857,7 @@ uint CppParser::getToken()
yyWord.resize(ptr - (ushort *)yyWord.unicode());
if (yyCh != '"')
- qWarning("%s:%d: Unterminated C++ string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated C++ string\n"));
else
yyCh = getChar();
return Tok_String;
@@ -867,8 +894,7 @@ uint CppParser::getToken()
forever {
if (yyCh == EOF || yyCh == '\n') {
- qWarning("%s:%d: Unterminated C++ character\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << "Unterminated C++ character\n";
break;
}
yyCh = getChar();
@@ -887,9 +913,9 @@ uint CppParser::getToken()
case '}':
if (yyBraceDepth == yyMinBraceDepth) {
if (!inDefine)
- qWarning("%s:%d: Excess closing brace in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyCurLineNo);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
// Avoid things getting messed up even more
yyCh = getChar();
return Tok_Semicolon;
@@ -905,9 +931,9 @@ uint CppParser::getToken()
return Tok_LeftParen;
case ')':
if (yyParenDepth == 0)
- qWarning("%s:%d: Excess closing parenthesis in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyCurLineNo);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else
yyParenDepth--;
yyCh = getChar();
@@ -920,9 +946,9 @@ uint CppParser::getToken()
return Tok_LeftBracket;
case ']':
if (yyBracketDepth == 0)
- qWarning("%s:%d: Excess closing bracket in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyCurLineNo);
+ yyMsg(yyCurLineNo)
+ << qPrintable(LU::tr("Excess closing bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else
yyBracketDepth--;
yyCh = getChar();
@@ -1290,8 +1316,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
QString cleanFile = QDir::cleanPath(file);
if (inclusions.contains(cleanFile)) {
- qWarning("%s:%d: circular inclusion of %s\n",
- qPrintable(yyFileName), yyLineNo, qPrintable(cleanFile));
+ yyMsg() << qPrintable(LU::tr("circular inclusion of %1\n").arg(cleanFile));
return;
}
@@ -1315,9 +1340,7 @@ void CppParser::processInclude(const QString &file, ConversionData &cd,
QFile f(cleanFile);
if (!f.open(QIODevice::ReadOnly)) {
- qWarning("%s:%d: Cannot open %s: %s\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(cleanFile), qPrintable(f.errorString()));
+ yyMsg() << qPrintable(LU::tr("Cannot open %1: %2\n").arg(cleanFile, f.errorString()));
return;
}
@@ -1656,8 +1679,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
// Forward-declared class definitions can be namespaced.
NamespaceList nsl;
if (!fullyQualify(namespaces, quali, true, &nsl, 0)) {
- qWarning("%s:%d: Ignoring definition of undeclared qualified class\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << "Ignoring definition of undeclared qualified class\n";
break;
}
namespaceDepths.push(namespaces.count());
@@ -1671,6 +1693,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
functionContextUnresolved.clear(); // Pointless
prospectiveContext.clear();
pendingContext.clear();
+
+ yyTok = getToken();
}
break;
case Tok_namespace:
@@ -1684,6 +1708,11 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (yyTok == Tok_LeftBrace) {
namespaceDepths.push(namespaces.count());
enterNamespace(&namespaces, ns);
+
+ functionContext = namespaces;
+ functionContextUnresolved.clear();
+ prospectiveContext.clear();
+ pendingContext.clear();
yyTok = getToken();
} else if (yyTok == Tok_Equals) {
// e.g. namespace Is = OuterSpace::InnerSpace;
@@ -1757,8 +1786,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
- qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n"));
utf8 = (yyTok == Tok_trUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1779,10 +1807,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
QStringList unresolved;
if (!fullyQualify(namespaces, pendingContext, true, &functionContext, &unresolved)) {
functionContextUnresolved = unresolved.join(strColons);
- qWarning("%s:%d: Qualifying with unknown namespace/class %s::%s\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(stringifyNamespace(functionContext)),
- qPrintable(unresolved.first()));
+ yyMsg() << qPrintable(LU::tr("Qualifying with unknown namespace/class %1::%2\n")
+ .arg(stringifyNamespace(functionContext)).arg(unresolved.first()));
}
pendingContext.clear();
}
@@ -1790,8 +1816,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (functionContextUnresolved.isEmpty()) {
int idx = functionContext.length();
if (idx < 2) {
- qWarning("%s:%d: tr() cannot be called without context\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("tr() cannot be called without context\n"));
break;
}
Namespace *fctx;
@@ -1800,9 +1825,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
context = stringifyNamespace(functionContext);
fctx = findNamespace(functionContext)->classDef;
if (!fctx->complained) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(context));
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n")
+ .arg(context));
fctx->complained = true;
}
goto gotctx;
@@ -1830,9 +1854,8 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
int last = prefix.lastIndexOf(strColons);
QString className = prefix.mid(last == -1 ? 0 : last + 2);
if (!className.isEmpty() && className == functionName) {
- qWarning("%s::%d: It is not recommended to call tr() from within a constructor '%s::%s' ",
- qPrintable(yyFileName), yyLineNo,
- className.constData(), functionName.constData());
+ yyMsg() << qPrintable(LU::tr("It is not recommended to call tr() from within a constructor '%1::%2'\n")
+ .arg(className).arg(functionName));
}
#endif
prefix.chop(2);
@@ -1847,9 +1870,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
context = fctx->trQualification;
}
if (!fctx->hasTrFunctions && !fctx->complained) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(context));
+ yyMsg() << qPrintable(LU::tr("Class '%1' lacks Q_OBJECT macro\n").arg(context));
fctx->complained = true;
}
} else {
@@ -1861,6 +1882,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
gotctx:
recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
+ sourcetext.clear(); // Will have warned about that already
extracomment.clear();
msgid.clear();
extra.clear();
@@ -1870,8 +1892,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!sourcetext.isEmpty())
- qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n"));
utf8 = (yyTok == Tok_translateUtf8);
line = yyLineNo;
yyTok = getToken();
@@ -1917,6 +1938,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
}
+ sourcetext.clear(); // Will have warned about that already
extracomment.clear();
msgid.clear();
extra.clear();
@@ -1925,8 +1947,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (!tor)
goto case_default;
if (!msgid.isEmpty())
- qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("//= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n"));
//utf8 = false; // Maybe use //%% or something like that
line = yyLineNo;
yyTok = getToken();
@@ -1993,15 +2014,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
if (isspace(c))
continue;
if (c != '"') {
- qWarning("%s:%d: Unexpected character in meta string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
break;
}
forever {
if (p >= yyWord.length()) {
whoops:
- qWarning("%s:%d: Unterminated meta string\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
break;
}
c = yyWord.unicode()[p++].unicode();
@@ -2054,8 +2073,7 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
case Tok_Arrow:
yyTok = getToken();
if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
- qWarning("%s:%d: Cannot invoke tr() like this\n",
- qPrintable(yyFileName), yyLineNo);
+ yyMsg() << qPrintable(LU::tr("Cannot invoke tr() like this\n"));
break;
case Tok_ColonColon:
if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen)
@@ -2087,9 +2105,13 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
case Tok_Semicolon:
prospectiveContext.clear();
prefix.clear();
- extracomment.clear();
- msgid.clear();
- extra.clear();
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
yyTokColonSeen = false;
yyTok = getToken();
break;
@@ -2123,17 +2145,17 @@ void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
}
if (yyBraceDepth != 0)
- qWarning("%s:%d: Unbalanced opening brace in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyBraceLineNo);
+ yyMsg(yyBraceLineNo)
+ << qPrintable(LU::tr("Unbalanced opening brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else if (yyParenDepth != 0)
- qWarning("%s:%d: Unbalanced opening parenthesis in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyParenLineNo);
+ yyMsg(yyParenLineNo)
+ << qPrintable(LU::tr("Unbalanced opening parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
else if (yyBracketDepth != 0)
- qWarning("%s:%d: Unbalanced opening bracket in C++ code"
- " (or abuse of the C++ preprocessor)\n",
- qPrintable(yyFileName), yyBracketLineNo);
+ yyMsg(yyBracketLineNo)
+ << qPrintable(LU::tr("Unbalanced opening bracket in C++ code"
+ " (or abuse of the C++ preprocessor)\n"));
}
const ParseResults *CppParser::recordResults(bool isHeader)
@@ -2194,8 +2216,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
continue;
}
diff --git a/tools/linguist/lupdate/java.cpp b/tools/linguist/lupdate/java.cpp
index 27988b04..165b6a3 100644
--- a/tools/linguist/lupdate/java.cpp
+++ b/tools/linguist/lupdate/java.cpp
@@ -50,11 +50,18 @@
#include <QtCore/QStack>
#include <QtCore/QString>
#include <QtCore/QTextCodec>
+#include <QtCore/QCoreApplication>
+
+#include <iostream>
#include <ctype.h>
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
enum { Tok_Eof, Tok_class, Tok_return, Tok_tr,
Tok_translate, Tok_Ident, Tok_Package,
Tok_Comment, Tok_String, Tok_Colon, Tok_Dot,
@@ -107,6 +114,11 @@ static QString yyPackage;
static QStack<Scope*> yyScope;
static QString yyDefaultContext;
+std::ostream &yyMsg(int line = 0)
+{
+ return std::cerr << qPrintable(yyFileName) << ':' << (line ? line : yyLineNo) << ": ";
+}
+
static QChar getChar()
{
if (yyInPos >= yyInStr.size())
@@ -189,10 +201,7 @@ static int getToken()
while ( !metAsterSlash ) {
yyCh = getChar();
if ( yyCh == EOF ) {
- qFatal( "%s: Unterminated Java comment starting at"
- " line %d\n",
- qPrintable(yyFileName), yyLineNo );
-
+ yyMsg() << qPrintable(LU::tr("Unterminated Java comment.\n"));
return Tok_Comment;
}
@@ -228,8 +237,8 @@ static int getToken()
else {
int sub(yyCh.toLower().toAscii() - 87);
if( sub > 15 || sub < 10) {
- qFatal( "%s:%d: Invalid Unicode",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr("Invalid Unicode value.\n"));
+ break;
}
unicode += sub;
}
@@ -251,8 +260,7 @@ static int getToken()
}
if ( yyCh != QLatin1Char('"') )
- qFatal( "%s:%d: Unterminated string",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr("Unterminated string.\n"));
yyCh = getChar();
@@ -365,9 +373,9 @@ static bool matchString( QString &s )
if (yyTok == Tok_String)
s += yyString;
else {
- qWarning( "%s:%d: String used in translation can only contain strings"
- " concatenated with other strings, not expressions or numbers.",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr(
+ "String used in translation can contain only literals"
+ " concatenated with other literals, not expressions or numbers.\n"));
return false;
}
yyTok = getToken();
@@ -475,8 +483,8 @@ static void parse( Translator *tor )
yyScope.push(new Scope(yyIdent, Scope::Clazz, yyLineNo));
}
else {
- qFatal( "%s:%d: Class must be followed by a classname",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr("'class' must be followed by a class name.\n"));
+ break;
}
while (!match(Tok_LeftBrace)) {
yyTok = getToken();
@@ -547,8 +555,7 @@ static void parse( Translator *tor )
case Tok_RightBrace:
if ( yyScope.isEmpty() ) {
- qFatal( "%s:%d: Unbalanced right brace in Java code\n",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr("Excess closing brace.\n"));
}
else
delete (yyScope.pop());
@@ -577,8 +584,7 @@ static void parse( Translator *tor )
yyPackage.append(QLatin1String("."));
break;
default:
- qFatal( "%s:%d: Package keyword should be followed by com.package.name;",
- qPrintable(yyFileName), yyLineNo );
+ yyMsg() << qPrintable(LU::tr("'package' must be followed by package name.\n"));
break;
}
yyTok = getToken();
@@ -591,11 +597,9 @@ static void parse( Translator *tor )
}
if ( !yyScope.isEmpty() )
- qFatal( "%s:%d: Unbalanced braces in Java code\n",
- qPrintable(yyFileName), yyScope.top()->line );
+ yyMsg(yyScope.top()->line) << qPrintable(LU::tr("Unbalanced opening brace.\n"));
else if ( yyParenDepth != 0 )
- qFatal( "%s:%d: Unbalanced parentheses in Java code\n",
- qPrintable(yyFileName), yyParenLineNo );
+ yyMsg(yyParenLineNo) << qPrintable(LU::tr("Unbalanced opening parenthesis.\n"));
}
@@ -603,8 +607,7 @@ bool loadJava(Translator &translator, const QString &filename, ConversionData &c
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
return false;
}
diff --git a/tools/linguist/lupdate/lupdate.h b/tools/linguist/lupdate/lupdate.h
index 70332cd..136884b 100644
--- a/tools/linguist/lupdate/lupdate.h
+++ b/tools/linguist/lupdate/lupdate.h
@@ -79,6 +79,7 @@ void loadCPP(Translator &translator, const QStringList &filenames, ConversionDat
bool loadJava(Translator &translator, const QString &filename, ConversionData &cd);
bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd);
bool loadUI(Translator &translator, const QString &filename, ConversionData &cd);
+bool loadQml(Translator &translator, const QString &filename, ConversionData &cd);
QT_END_NAMESPACE
diff --git a/tools/linguist/lupdate/lupdate.pro b/tools/linguist/lupdate/lupdate.pro
index ccc2d47..3ed909a 100644
--- a/tools/linguist/lupdate/lupdate.pro
+++ b/tools/linguist/lupdate/lupdate.pro
@@ -15,6 +15,9 @@ build_all:!build_pass {
include(../shared/formats.pri)
include(../shared/proparser.pri)
+include($$QT_SOURCE_TREE/src/declarative/qml/parser/parser.pri)
+INCLUDEPATH += $$QT_SOURCE_TREE/src/declarative/qml $$QT_BUILD_TREE/include/QtDeclarative
+
SOURCES += \
main.cpp \
merge.cpp \
@@ -23,6 +26,7 @@ SOURCES += \
cpp.cpp \
java.cpp \
qscript.cpp \
+ qdeclarative.cpp \
ui.cpp
HEADERS += \
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 274e33c..76a8756 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -52,21 +52,22 @@
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QTextCodec>
+#include <QtCore/QTranslator>
+#include <QtCore/QLibraryInfo>
#include <iostream>
static QString m_defaultExtensions;
-static void printErr(const QString & out)
-{
- qWarning("%s", qPrintable(out));
-}
-
static void printOut(const QString & out)
{
std::cerr << qPrintable(out);
}
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
static void recursiveFileInfoList(const QDir &dir,
const QSet<QString> &nameFilters, QDir::Filters filter,
QFileInfoList *fileinfolist)
@@ -80,10 +81,10 @@ static void recursiveFileInfoList(const QDir &dir,
static void printUsage()
{
- printOut(QObject::tr(
+ printOut(LU::tr(
"Usage:\n"
" lupdate [options] [project-file]...\n"
- " lupdate [options] [source-file|path]... -ts ts-files\n\n"
+ " lupdate [options] [source-file|path|@lst-file]... -ts ts-files|@lst-file\n\n"
"lupdate is part of Qt's Linguist tool chain. It extracts translatable\n"
"messages from Qt UI files, C++, Java and JavaScript/QtScript source code.\n"
"Extracted messages are stored in textual translation source files (typically\n"
@@ -132,6 +133,8 @@ static void printUsage()
" Specify the codec assumed for tr() calls. Effective only with -ts.\n"
" -version\n"
" Display the version of lupdate and exit.\n"
+ " @lst-file\n"
+ " Read additional file names (one per line) from lst-file.\n"
).arg(m_defaultExtensions));
}
@@ -148,24 +151,25 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
cd.m_sortContexts = !(options & NoSort);
if (QFile(fileName).exists()) {
if (!tor.load(fileName, cd, QLatin1String("auto"))) {
- printErr(cd.error());
+ printOut(cd.error());
*fail = true;
continue;
}
tor.resolveDuplicates();
cd.clearErrors();
if (setCodec && fetchedTor.codec() != tor.codec())
- qWarning("lupdate warning: Codec for tr() '%s' disagrees with "
- "existing file's codec '%s'. Expect trouble.",
- fetchedTor.codecName().constData(), tor.codecName().constData());
+ printOut(LU::tr("lupdate warning: Codec for tr() '%1' disagrees with"
+ " existing file's codec '%2'. Expect trouble.\n")
+ .arg(QString::fromLatin1(fetchedTor.codecName()),
+ QString::fromLatin1(tor.codecName())));
if (!targetLanguage.isEmpty() && targetLanguage != tor.languageCode())
- qWarning("lupdate warning: Specified target language '%s' disagrees with "
- "existing file's language '%s'. Ignoring.",
- qPrintable(targetLanguage), qPrintable(tor.languageCode()));
+ printOut(LU::tr("lupdate warning: Specified target language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(targetLanguage, tor.languageCode()));
if (!sourceLanguage.isEmpty() && sourceLanguage != tor.sourceLanguageCode())
- qWarning("lupdate warning: Specified source language '%s' disagrees with "
- "existing file's language '%s'. Ignoring.",
- qPrintable(sourceLanguage), qPrintable(tor.sourceLanguageCode()));
+ printOut(LU::tr("lupdate warning: Specified source language '%1' disagrees with"
+ " existing file's language '%2'. Ignoring.\n")
+ .arg(sourceLanguage, tor.sourceLanguageCode()));
} else {
if (setCodec)
tor.setCodec(fetchedTor.codec());
@@ -184,7 +188,7 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
else if (options & AbsoluteLocations)
tor.setLocationsType(Translator::AbsoluteLocations);
if (options & Verbose)
- printOut(QObject::tr("Updating '%1'...\n").arg(fn));
+ printOut(LU::tr("Updating '%1'...\n").arg(fn));
UpdateOptions theseOptions = options;
if (tor.locationsType() == Translator::NoLocations) // Could be set from file
@@ -199,7 +203,7 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
}
if (options & PluralOnly) {
if (options & Verbose)
- printOut(QObject::tr("Stripping non plural forms in '%1'...\n").arg(fn));
+ printOut(LU::tr("Stripping non plural forms in '%1'...\n").arg(fn));
out.stripNonPluralForms();
}
if (options & NoObsolete)
@@ -208,11 +212,11 @@ static void updateTsFiles(const Translator &fetchedTor, const QStringList &tsFil
out.normalizeTranslations(cd);
if (!cd.errors().isEmpty()) {
- printErr(cd.error());
+ printOut(cd.error());
cd.clearErrors();
}
if (!out.save(fileName, cd, QLatin1String("auto"))) {
- printErr(cd.error());
+ printOut(cd.error());
*fail = true;
}
}
@@ -267,6 +271,8 @@ static void processSources(Translator &fetchedTor,
else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
|| it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
loadQScript(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".qml"), Qt::CaseInsensitive))
+ loadQml(fetchedTor, *it, cd);
else
sourceFilesCpp << *it;
}
@@ -292,8 +298,9 @@ static void processProject(
if (!tmp.isEmpty()) {
codecForSource = tmp.last().toLatin1();
if (!QTextCodec::codecForName(codecForSource)) {
- qWarning("lupdate warning: Codec for source '%s' is invalid. "
- "Falling back to codec for tr().", codecForSource.constData());
+ printOut(LU::tr("lupdate warning: Codec for source '%1' is invalid."
+ " Falling back to codec for tr().\n")
+ .arg(QString::fromLatin1(codecForSource)));
codecForSource.clear();
}
}
@@ -343,6 +350,10 @@ static void processProjects(
ProFileEvaluator visitor;
visitor.setVerbose(options & Verbose);
+ QHash<QString, QStringList> lupdateConfig;
+ lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run")));
+ visitor.addVariables(lupdateConfig);
+
QFileInfo pfi(proFile);
ProFile pro(pfi.absoluteFilePath());
if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) {
@@ -354,12 +365,12 @@ static void processProjects(
if (visitor.contains(QLatin1String("TRANSLATIONS"))) {
if (parentTor) {
if (topLevel) {
- std::cerr << "lupdate warning: TS files from command line "
- "will override TRANSLATIONS in " << qPrintable(proFile) << ".\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line "
+ "will override TRANSLATIONS in %1.\n").arg(proFile));
goto noTrans;
} else if (nestComplain) {
- std::cerr << "lupdate warning: TS files from command line "
- "prevent recursing into " << qPrintable(proFile) << ".\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: TS files from command line "
+ "prevent recursing into %1.\n").arg(proFile));
continue;
}
}
@@ -390,8 +401,8 @@ static void processProjects(
noTrans:
if (!parentTor) {
if (topLevel)
- std::cerr << "lupdate warning: no TS files specified. Only diagnostics "
- "will be produced for '" << qPrintable(proFile) << "'.\n";
+ std::cerr << qPrintable(LU::tr("lupdate warning: no TS files specified. Only diagnostics "
+ "will be produced for '%1'.\n").arg(proFile));
Translator tor;
processProject(nestComplain, pfi, visitor, options, codecForSource,
targetLanguage, sourceLanguage, &tor, fail);
@@ -405,7 +416,19 @@ static void processProjects(
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
- m_defaultExtensions = QLatin1String("ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx");
+#ifndef Q_OS_WIN32
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+#endif // Q_OS_WIN32
+
+ m_defaultExtensions = QLatin1String("java,jui,ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx,js,qs,qml");
QStringList args = app.arguments();
QStringList tsFileNames;
@@ -448,7 +471,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-target-language")) {
++i;
if (i == argc) {
- qWarning("The option -target-language requires a parameter.");
+ printOut(LU::tr("The option -target-language requires a parameter.\n"));
return 1;
}
targetLanguage = args[i];
@@ -456,7 +479,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-source-language")) {
++i;
if (i == argc) {
- qWarning("The option -source-language requires a parameter.");
+ printOut(LU::tr("The option -source-language requires a parameter.\n"));
return 1;
}
sourceLanguage = args[i];
@@ -464,7 +487,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-disable-heuristic")) {
++i;
if (i == argc) {
- qWarning("The option -disable-heuristic requires a parameter.");
+ printOut(LU::tr("The option -disable-heuristic requires a parameter.\n"));
return 1;
}
arg = args[i];
@@ -475,14 +498,14 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("number")) {
options &= ~HeuristicNumber;
} else {
- qWarning("Invalid heuristic name passed to -disable-heuristic.");
+ printOut(LU::tr("Invalid heuristic name passed to -disable-heuristic.\n"));
return 1;
}
continue;
} else if (arg == QLatin1String("-locations")) {
++i;
if (i == argc) {
- qWarning("The option -locations requires a parameter.");
+ printOut(LU::tr("The option -locations requires a parameter.\n"));
return 1;
}
if (args[i] == QLatin1String("none")) {
@@ -492,7 +515,7 @@ int main(int argc, char **argv)
} else if (args[i] == QLatin1String("absolute")) {
options |= AbsoluteLocations;
} else {
- qWarning("Invalid parameter passed to -locations.");
+ printOut(LU::tr("Invalid parameter passed to -locations.\n"));
return 1;
}
continue;
@@ -518,7 +541,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-codecfortr")) {
++i;
if (i == argc) {
- qWarning("The -codecfortr option should be followed by a codec name.");
+ printOut(LU::tr("The -codecfortr option should be followed by a codec name.\n"));
return 1;
}
codecForTr = args[i].toLatin1();
@@ -529,7 +552,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-extensions")) {
++i;
if (i == argc) {
- qWarning("The -extensions option should be followed by an extension list.");
+ printOut(LU::tr("The -extensions option should be followed by an extension list.\n"));
return 1;
}
extensions = args[i];
@@ -537,7 +560,7 @@ int main(int argc, char **argv)
} else if (arg == QLatin1String("-pro")) {
++i;
if (i == argc) {
- qWarning("The -pro option should be followed by a filename of .pro file.");
+ printOut(LU::tr("The -pro option should be followed by a filename of .pro file.\n"));
return 1;
}
proFiles += args[i];
@@ -547,7 +570,7 @@ int main(int argc, char **argv)
if (arg.length() == 2) {
++i;
if (i == argc) {
- qWarning("The -I option should be followed by a path.");
+ printOut(LU::tr("The -I option should be followed by a path.\n"));
return 1;
}
includePath += args[i];
@@ -556,78 +579,98 @@ int main(int argc, char **argv)
}
continue;
} else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
- qWarning("Unrecognized option '%s'", qPrintable(arg));
+ printOut(LU::tr("Unrecognized option '%1'.\n").arg(arg));
return 1;
}
+ QStringList files;
+ if (arg.startsWith(QLatin1String("@"))) {
+ QFile lstFile(arg.mid(1));
+ if (!lstFile.open(QIODevice::ReadOnly)) {
+ printOut(LU::tr("lupdate error: List file '%1' is not readable.\n")
+ .arg(lstFile.fileName()));
+ return 1;
+ }
+ while (!lstFile.atEnd())
+ files << QString::fromLocal8Bit(lstFile.readLine().trimmed());
+ } else {
+ files << arg;
+ }
if (metTsFlag) {
- bool found = false;
- foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
- if (arg.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
- QFileInfo fi(arg);
- if (!fi.exists() || fi.isWritable()) {
- tsFileNames.append(QFileInfo(arg).absoluteFilePath());
- } else {
- qWarning("lupdate warning: For some reason, '%s' is not writable.\n",
- qPrintable(arg));
+ foreach (const QString &file, files) {
+ bool found = false;
+ foreach (const Translator::FileFormat &fmt, Translator::registeredFileFormats()) {
+ if (file.endsWith(QLatin1Char('.') + fmt.extension, Qt::CaseInsensitive)) {
+ QFileInfo fi(file);
+ if (!fi.exists() || fi.isWritable()) {
+ tsFileNames.append(QFileInfo(file).absoluteFilePath());
+ } else {
+ printOut(LU::tr("lupdate warning: For some reason, '%1' is not writable.\n")
+ .arg(file));
+ }
+ found = true;
+ break;
}
- found = true;
- break;
+ }
+ if (!found) {
+ printOut(LU::tr("lupdate error: File '%1' has no recognized extension.\n")
+ .arg(file));
+ return 1;
}
}
- if (!found) {
- qWarning("lupdate error: File '%s' has no recognized extension\n",
- qPrintable(arg));
- return 1;
- }
- } else if (arg.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
- || arg.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
- proFiles << arg;
numFiles++;
} else {
- QFileInfo fi(arg);
- if (!fi.exists()) {
- qWarning("lupdate error: File '%s' does not exists\n", qPrintable(arg));
- return 1;
- } else if (fi.isDir()) {
- if (options & Verbose)
- printOut(QObject::tr("Scanning directory '%1'...").arg(arg));
- QDir dir = QDir(fi.filePath());
- projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
- if (extensionsNameFilters.isEmpty()) {
- foreach (QString ext, extensions.split(QLatin1Char(','))) {
- ext = ext.trimmed();
- if (ext.startsWith(QLatin1Char('.')))
- ext.remove(0, 1);
- extensionsNameFilters.insert(ext);
- }
+ foreach (const QString &file, files) {
+ QFileInfo fi(file);
+ if (!fi.exists()) {
+ printOut(LU::tr("lupdate error: File '%1' does not exist.\n").arg(file));
+ return 1;
}
- QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
- if (recursiveScan)
- filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
- QFileInfoList fileinfolist;
- recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
- int scanRootLen = dir.absolutePath().length();
- foreach (const QFileInfo &fi, fileinfolist) {
- QString fn = QDir::cleanPath(fi.absoluteFilePath());
- sourceFiles << fn;
-
- if (!fn.endsWith(QLatin1String(".java"))
- && !fn.endsWith(QLatin1String(".ui"))
- && !fn.endsWith(QLatin1String(".js"))
- && !fn.endsWith(QLatin1String(".qs"))) {
- int offset = 0;
- int depth = 0;
- do {
- offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
- QString ffn = fn.mid(offset + 1);
- allCSources.insert(ffn, fn);
- } while (++depth < 3 && offset > scanRootLen);
+ if (file.endsWith(QLatin1String(".pro"), Qt::CaseInsensitive)
+ || file.endsWith(QLatin1String(".pri"), Qt::CaseInsensitive)) {
+ proFiles << file;
+ } else if (fi.isDir()) {
+ if (options & Verbose)
+ printOut(LU::tr("Scanning directory '%1'...\n").arg(file));
+ QDir dir = QDir(fi.filePath());
+ projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
+ if (extensionsNameFilters.isEmpty()) {
+ foreach (QString ext, extensions.split(QLatin1Char(','))) {
+ ext = ext.trimmed();
+ if (ext.startsWith(QLatin1Char('.')))
+ ext.remove(0, 1);
+ extensionsNameFilters.insert(ext);
+ }
}
+ QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
+ if (recursiveScan)
+ filters |= QDir::AllDirs | QDir::NoDotAndDotDot;
+ QFileInfoList fileinfolist;
+ recursiveFileInfoList(dir, extensionsNameFilters, filters, &fileinfolist);
+ int scanRootLen = dir.absolutePath().length();
+ foreach (const QFileInfo &fi, fileinfolist) {
+ QString fn = QDir::cleanPath(fi.absoluteFilePath());
+ sourceFiles << fn;
+
+ if (!fn.endsWith(QLatin1String(".java"))
+ && !fn.endsWith(QLatin1String(".jui"))
+ && !fn.endsWith(QLatin1String(".ui"))
+ && !fn.endsWith(QLatin1String(".js"))
+ && !fn.endsWith(QLatin1String(".qs"))
+ && !fn.endsWith(QLatin1String(".qml"))) {
+ int offset = 0;
+ int depth = 0;
+ do {
+ offset = fn.lastIndexOf(QLatin1Char('/'), offset - 1);
+ QString ffn = fn.mid(offset + 1);
+ allCSources.insert(ffn, fn);
+ } while (++depth < 3 && offset > scanRootLen);
+ }
+ }
+ } else {
+ sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
+ projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
}
- } else {
- sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
- projectRoots.insert(fi.absolutePath() + QLatin1Char('/'));
}
numFiles++;
}
@@ -639,16 +682,16 @@ int main(int argc, char **argv)
}
if (!targetLanguage.isEmpty() && tsFileNames.count() != 1)
- std::cerr << "lupdate warning: -target-language usually only "
- "makes sense with exactly one TS file.\n";
+ printOut(LU::tr("lupdate warning: -target-language usually only"
+ " makes sense with exactly one TS file.\n"));
if (!codecForTr.isEmpty() && tsFileNames.isEmpty())
- std::cerr << "lupdate warning: -codecfortr has no effect without -ts.\n";
+ printOut(LU::tr("lupdate warning: -codecfortr has no effect without -ts.\n"));
bool fail = false;
if (proFiles.isEmpty()) {
if (tsFileNames.isEmpty())
- std::cerr << "lupdate warning: no TS files specified. "
- "Only diagnostics will be produced.\n";
+ printOut(LU::tr("lupdate warning:"
+ " no TS files specified. Only diagnostics will be produced.\n"));
Translator fetchedTor;
ConversionData cd;
@@ -662,7 +705,8 @@ int main(int argc, char **argv)
sourceLanguage, targetLanguage, options, &fail);
} else {
if (!sourceFiles.isEmpty() || !includePath.isEmpty()) {
- qWarning("lupdate error: Both project and source files / include paths specified.\n");
+ printOut(LU::tr("lupdate error:"
+ " Both project and source files / include paths specified.\n"));
return 1;
}
if (!tsFileNames.isEmpty()) {
diff --git a/tools/linguist/lupdate/merge.cpp b/tools/linguist/lupdate/merge.cpp
index fffdf9b..87c150c 100644
--- a/tools/linguist/lupdate/merge.cpp
+++ b/tools/linguist/lupdate/merge.cpp
@@ -44,15 +44,19 @@
#include "simtexth.h"
#include "translator.h"
+#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QMap>
#include <QtCore/QStringList>
#include <QtCore/QTextCodec>
#include <QtCore/QVector>
-
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
static bool isDigitFriendly(QChar c)
{
return c.isPunct() || c.isSpace();
@@ -485,24 +489,24 @@ Translator merge(const Translator &tor, const Translator &virginTor,
if (options & Verbose) {
int totalFound = neww + known;
- err += QObject::tr(" Found %n source text(s) (%1 new and %2 already existing)\n", 0, totalFound).arg(neww).arg(known);
+ err += LU::tr(" Found %n source text(s) (%1 new and %2 already existing)\n", 0, totalFound).arg(neww).arg(known);
if (obsoleted) {
if (options & NoObsolete) {
- err += QObject::tr(" Removed %n obsolete entries\n", 0, obsoleted);
+ err += LU::tr(" Removed %n obsolete entries\n", 0, obsoleted);
} else {
- err += QObject::tr(" Kept %n obsolete entries\n", 0, obsoleted);
+ err += LU::tr(" Kept %n obsolete entries\n", 0, obsoleted);
}
}
if (sameNumberHeuristicCount)
- err += QObject::tr(" Number heuristic provided %n translation(s)\n",
+ err += LU::tr(" Number heuristic provided %n translation(s)\n",
0, sameNumberHeuristicCount);
if (sameTextHeuristicCount)
- err += QObject::tr(" Same-text heuristic provided %n translation(s)\n",
+ err += LU::tr(" Same-text heuristic provided %n translation(s)\n",
0, sameTextHeuristicCount);
if (similarTextHeuristicCount)
- err += QObject::tr(" Similar-text heuristic provided %n translation(s)\n",
+ err += LU::tr(" Similar-text heuristic provided %n translation(s)\n",
0, similarTextHeuristicCount);
}
return outTor;
diff --git a/tools/linguist/lupdate/qdeclarative.cpp b/tools/linguist/lupdate/qdeclarative.cpp
new file mode 100644
index 0000000..01b9a1d
--- /dev/null
+++ b/tools/linguist/lupdate/qdeclarative.cpp
@@ -0,0 +1,432 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Linguist 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QFile>
+#include <QtCore/QString>
+
+#include "parser/qdeclarativejsengine_p.h"
+#include "parser/qdeclarativejsparser_p.h"
+#include "parser/qdeclarativejslexer_p.h"
+#include "parser/qdeclarativejsnodepool_p.h"
+#include "parser/qdeclarativejsastvisitor_p.h"
+#include "parser/qdeclarativejsast_p.h"
+
+#include <QCoreApplication>
+#include <QFile>
+#include <QFileInfo>
+#include <QtDebug>
+#include <QStringList>
+
+#include <iostream>
+#include <cstdlib>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
+using namespace QDeclarativeJS;
+
+class Comment
+{
+public:
+ Comment() : lastLine(-1) {}
+ QString extracomment;
+ QString msgid;
+ TranslatorMessage::ExtraData extra;
+ QString sourcetext;
+ int lastLine;
+
+ bool isValid() const
+ { return !extracomment.isEmpty() || !msgid.isEmpty() || !sourcetext.isEmpty() || !extra.isEmpty(); }
+};
+
+class FindTrCalls: protected AST::Visitor
+{
+public:
+ void operator()(Translator *translator, const QString &fileName, AST::Node *node)
+ {
+ m_translator = translator;
+ m_fileName = fileName;
+ m_component = QFileInfo(fileName).baseName(); //matches qsTr usage in QScriptEngine
+ accept(node);
+ }
+
+ QList<Comment> comments;
+
+protected:
+ using AST::Visitor::visit;
+ using AST::Visitor::endVisit;
+
+ void accept(AST::Node *node)
+ { AST::Node::acceptChild(node, this); }
+
+ virtual void endVisit(AST::CallExpression *node)
+ {
+ m_bSource.clear();
+ if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(node->base)) {
+ if (idExpr->name->asString() == QLatin1String("qsTr") ||
+ idExpr->name->asString() == QLatin1String("QT_TR_NOOP")) {
+ if (!node->arguments)
+ return;
+ AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(node->arguments->expression);
+ if (binary) {
+ if (!createString(binary))
+ m_bSource.clear();
+ }
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ if (literal || !m_bSource.isEmpty()) {
+ const QString source = literal ? literal->value->asString() : m_bSource;
+
+ QString comment;
+ bool plural = false;
+ AST::ArgumentList *commentNode = node->arguments->next;
+ if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
+ literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
+ comment = literal->value->asString();
+
+ AST::ArgumentList *nNode = commentNode->next;
+ if (nNode)
+ plural = true;
+ }
+
+ QString id;
+ QString extracomment;
+ TranslatorMessage::ExtraData extra;
+ Comment scomment = findComment(node->firstSourceLocation().startLine);
+ if (scomment.isValid()) {
+ extracomment = scomment.extracomment;
+ extra = scomment.extra;
+ id = scomment.msgid;
+ }
+
+ TranslatorMessage msg(m_component, source,
+ comment, QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ } else if (idExpr->name->asString() == QLatin1String("qsTranslate") ||
+ idExpr->name->asString() == QLatin1String("QT_TRANSLATE_NOOP")) {
+ if (node->arguments && AST::cast<AST::StringLiteral *>(node->arguments->expression)) {
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ const QString context = literal->value->asString();
+
+ QString source;
+ QString comment;
+ bool plural = false;
+ AST::ArgumentList *sourceNode = node->arguments->next;
+ if (!sourceNode)
+ return;
+ literal = AST::cast<AST::StringLiteral *>(sourceNode->expression);
+ AST::BinaryExpression *binary = AST::cast<AST::BinaryExpression *>(sourceNode->expression);
+ if (binary) {
+ if (!createString(binary))
+ m_bSource.clear();
+ }
+ if (!literal && m_bSource.isEmpty())
+ return;
+
+ QString id;
+ QString extracomment;
+ TranslatorMessage::ExtraData extra;
+ Comment scomment = findComment(node->firstSourceLocation().startLine);
+ if (scomment.isValid()) {
+ extracomment = scomment.extracomment;
+ extra = scomment.extra;
+ id = scomment.msgid;
+ }
+
+ source = literal ? literal->value->asString() : m_bSource;
+ AST::ArgumentList *commentNode = sourceNode->next;
+ if (commentNode && AST::cast<AST::StringLiteral *>(commentNode->expression)) {
+ literal = AST::cast<AST::StringLiteral *>(commentNode->expression);
+ comment = literal->value->asString();
+
+ AST::ArgumentList *nNode = commentNode->next;
+ if (nNode)
+ plural = true;
+ }
+
+ TranslatorMessage msg(context, source,
+ comment, QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ } else if (idExpr->name->asString() == QLatin1String("qsTrId") ||
+ idExpr->name->asString() == QLatin1String("QT_TRID_NOOP")) {
+ if (!node->arguments)
+ return;
+
+ AST::StringLiteral *literal = AST::cast<AST::StringLiteral *>(node->arguments->expression);
+ if (literal) {
+
+ QString extracomment;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+ Comment comment = findComment(node->firstSourceLocation().startLine);
+ if (comment.isValid()) {
+ extracomment = comment.extracomment;
+ sourcetext = comment.sourcetext;
+ extra = comment.extra;
+ }
+
+ const QString id = literal->value->asString();
+ bool plural = node->arguments->next;
+
+ TranslatorMessage msg(QString(), QString(),
+ QString(), QString(), m_fileName,
+ node->firstSourceLocation().startLine, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(extracomment.simplified());
+ msg.setId(id);
+ msg.setExtras(extra);
+ m_translator->extend(msg);
+ }
+ }
+ }
+ }
+
+private:
+ bool createString(AST::BinaryExpression *b)
+ {
+ if (!b || b->op != 0)
+ return false;
+ AST::BinaryExpression *l = AST::cast<AST::BinaryExpression *>(b->left);
+ AST::BinaryExpression *r = AST::cast<AST::BinaryExpression *>(b->right);
+ AST::StringLiteral *ls = AST::cast<AST::StringLiteral *>(b->left);
+ AST::StringLiteral *rs = AST::cast<AST::StringLiteral *>(b->right);
+ if ((!l && !ls) || (!r && !rs))
+ return false;
+ if (l) {
+ if (!createString(l))
+ return false;
+ } else
+ m_bSource.prepend(ls->value->asString());
+
+ if (r) {
+ if (!createString(r))
+ return false;
+ } else
+ m_bSource.append(rs->value->asString());
+
+ return true;
+ }
+
+ Comment findComment(int loc)
+ {
+ if (comments.isEmpty())
+ return Comment();
+
+ int i = 0;
+ int commentLoc = comments.at(i).lastLine;
+ while (commentLoc <= loc) {
+ if (commentLoc == loc)
+ return comments.at(i);
+ if (i == comments.count()-1)
+ break;
+ commentLoc = comments.at(++i).lastLine;
+ }
+ return Comment();
+ }
+
+ Translator *m_translator;
+ QString m_fileName;
+ QString m_component;
+ QString m_bSource;
+};
+
+QString createErrorString(const QString &filename, const QString &code, Parser &parser)
+{
+ // print out error
+ QStringList lines = code.split(QLatin1Char('\n'));
+ lines.append(QLatin1String("\n")); // sentinel.
+ QString errorString;
+
+ foreach (const DiagnosticMessage &m, parser.diagnosticMessages()) {
+
+ if (m.isWarning())
+ continue;
+
+ QString error = filename + QLatin1Char(':') + QString::number(m.loc.startLine)
+ + QLatin1Char(':') + QString::number(m.loc.startColumn) + QLatin1String(": error: ")
+ + m.message + QLatin1Char('\n');
+
+ int line = 0;
+ if (m.loc.startLine > 0)
+ line = m.loc.startLine - 1;
+
+ const QString textLine = lines.at(line);
+
+ error += textLine + QLatin1Char('\n');
+
+ int column = m.loc.startColumn - 1;
+ if (column < 0)
+ column = 0;
+
+ column = qMin(column, textLine.length());
+
+ for (int i = 0; i < column; ++i) {
+ const QChar ch = textLine.at(i);
+ if (ch.isSpace())
+ error += ch.unicode();
+ else
+ error += QLatin1Char(' ');
+ }
+ error += QLatin1String("^\n");
+ errorString += error;
+ }
+ return errorString;
+}
+
+bool processComment(const QChar *chars, int length, Comment &comment)
+{
+ // Try to match the logic of the QtScript parser.
+ if (!length)
+ return comment.isValid();
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ comment.extracomment += QString(chars+1, length-1);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ comment.msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ comment.extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ comment.sourcetext.reserve(comment.sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)comment.sourcetext.data() + comment.sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"')
+ break;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ break;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ comment.sourcetext.resize(ptr - (ushort *)comment.sourcetext.data());
+ }
+ return comment.isValid();
+}
+
+bool loadQml(Translator &translator, const QString &filename, ConversionData &cd)
+{
+ cd.m_sourceFileName = filename;
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
+ return false;
+ }
+
+ const QString code = QTextStream(&file).readAll();
+
+ Engine driver;
+ Parser parser(&driver);
+
+ NodePool nodePool(filename, &driver);
+ driver.setNodePool(&nodePool);
+
+ Lexer lexer(&driver);
+ lexer.setCode(code, /*line = */ 1);
+ driver.setLexer(&lexer);
+
+ if (parser.parse()) {
+ FindTrCalls trCalls;
+
+ // build up a list of comments that contain translation information.
+ for (int i = 0; i < driver.comments().size(); ++i) {
+ AST::SourceLocation loc = driver.comments().at(i);
+ QString commentStr = code.mid(loc.offset, loc.length);
+
+ if (trCalls.comments.isEmpty() || trCalls.comments.last().lastLine != int(loc.startLine)) {
+ Comment comment;
+ comment.lastLine = loc.startLine+1;
+ if (processComment(commentStr.constData(), commentStr.length(), comment))
+ trCalls.comments.append(comment);
+ } else {
+ Comment &lastComment = trCalls.comments.last();
+ lastComment.lastLine += 1;
+ processComment(commentStr.constData(), commentStr.length(), lastComment);
+ }
+ }
+
+ //find all tr calls in the code
+ trCalls(&translator, filename, parser.ast());
+ } else {
+ QString error = createErrorString(filename, code, parser);
+ cd.appendError(error);
+ return false;
+ }
+ return true;
+}
+
+QT_END_NAMESPACE
diff --git a/tools/linguist/lupdate/qscript.cpp b/tools/linguist/lupdate/qscript.cpp
index 6f34c2b..5323022 100644
--- a/tools/linguist/lupdate/qscript.cpp
+++ b/tools/linguist/lupdate/qscript.cpp
@@ -40,6 +40,33 @@
**
****************************************************************************/
+
+#define Q_SCRIPT_REGEXPLITERAL_RULE1 7
+
+#define Q_SCRIPT_REGEXPLITERAL_RULE2 8
+
+#include <translator.h>
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/qdebug.h>
+#include <QtCore/qnumeric.h>
+#include <QtCore/qstring.h>
+#include <QtCore/qtextcodec.h>
+#include <QtCore/qvariant.h>
+
+#include <iostream>
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+QT_BEGIN_NAMESPACE
+
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
class QScriptGrammar
{
public:
@@ -174,7 +201,6 @@ public:
}
};
-
const char *const QScriptGrammar::spell [] = {
"end of file", "&", "&&", "&=", "break", "case", "catch", ":", ";", "continue",
"default", "delete", "/", "/=", "do", ".", "else", "=", "==", "===",
@@ -747,35 +773,18 @@ const int QScriptGrammar::action_check [] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1};
-
-#define Q_SCRIPT_REGEXPLITERAL_RULE1 7
-
-#define Q_SCRIPT_REGEXPLITERAL_RULE2 8
-
-#include <translator.h>
-
-#include <QtCore/qdebug.h>
-#include <QtCore/qnumeric.h>
-#include <QtCore/qstring.h>
-#include <QtCore/qtextcodec.h>
-#include <QtCore/qvariant.h>
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-QT_BEGIN_NAMESPACE
-
static void recordMessage(
Translator *tor, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool plural, const QString &fileName, int lineNo)
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool plural, const QString &fileName, int lineNo)
{
TranslatorMessage msg(
context, text, comment, QString(),
fileName, lineNo, QStringList(),
TranslatorMessage::Unfinished, plural);
msg.setExtraComment(extracomment.simplified());
+ msg.setId(msgid);
+ msg.setExtras(extra);
tor->extend(msg);
}
@@ -783,15 +792,23 @@ static void recordMessage(
namespace QScript
{
+class CommentProcessor
+{
+public:
+ virtual ~CommentProcessor() {}
+ virtual void processComment(const QChar *chars, int length) = 0;
+};
+
class Lexer
{
public:
- Lexer();
+ Lexer(CommentProcessor *);
~Lexer();
- void setCode(const QString &c, int lineno);
+ void setCode(const QString &c, const QString &fileName, int lineno);
int lex();
+ QString fileName() const { return yyfilename; }
int currentLineNo() const { return yylineno; }
int currentColumnNo() const { return yycolumn; }
@@ -871,6 +888,7 @@ public:
{ err = NoError; }
private:
+ QString yyfilename;
int yylineno;
bool done;
char *buffer8;
@@ -924,6 +942,8 @@ private:
void syncProhibitAutomaticSemicolon();
+ void processComment(const QChar *, int);
+
const QChar *code;
uint length;
int yycolumn;
@@ -950,6 +970,8 @@ private:
ParenthesesState parenthesesState;
int parenthesesCount;
bool prohibitAutomaticSemicolon;
+
+ CommentProcessor *commentProcessor;
};
} // namespace QScript
@@ -1026,7 +1048,7 @@ double integerFromString(const char *buf, int size, int radix)
} // namespace QScript
-QScript::Lexer::Lexer()
+QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
:
yylineno(0),
size8(128), size16(128), restrKeyword(false),
@@ -1037,7 +1059,8 @@ QScript::Lexer::Lexer()
err(NoError),
check_reserved(true),
parenthesesState(IgnoreParentheses),
- prohibitAutomaticSemicolon(false)
+ prohibitAutomaticSemicolon(false),
+ commentProcessor(proc)
{
// allocate space for read buffers
buffer8 = new char[size8];
@@ -1052,9 +1075,10 @@ QScript::Lexer::~Lexer()
delete [] buffer16;
}
-void QScript::Lexer::setCode(const QString &c, int lineno)
+void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
{
errmsg = QString();
+ yyfilename = fileName;
yylineno = lineno;
yycolumn = 1;
restrKeyword = false;
@@ -1403,10 +1427,12 @@ int QScript::Lexer::lex()
} else if (current == '/' && next1 == '/') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InSingleLineComment;
} else if (current == '/' && next1 == '*') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InMultiLineComment;
} else if (current == 0) {
syncProhibitAutomaticSemicolon();
@@ -1465,7 +1491,7 @@ int QScript::Lexer::lex()
else {
setDone(Bad);
err = IllegalCharacter;
- errmsg = QLatin1String("Illegal character");
+ errmsg = LU::tr("Illegal character");
}
}
break;
@@ -1476,7 +1502,7 @@ int QScript::Lexer::lex()
} else if (current == 0 || isLineTerminator()) {
setDone(Bad);
err = UnclosedStringLiteral;
- errmsg = QLatin1String("Unclosed string at end of line");
+ errmsg = LU::tr("Unclosed string at end of line");
} else if (current == '\\') {
state = InEscapeSequence;
} else {
@@ -1502,7 +1528,7 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalEscapeSequence;
- errmsg = QLatin1String("Illegal escape squence");
+ errmsg = LU::tr("Illegal escape squence");
}
} else if (current == 'x')
state = InHexEscape;
@@ -1541,14 +1567,17 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalUnicodeEscapeSequence;
- errmsg = QLatin1String("Illegal unicode escape sequence");
+ errmsg = LU::tr("Illegal unicode escape sequence");
}
break;
case InSingleLineComment:
if (isLineTerminator()) {
+ record16(current); // include newline
+ processComment(buffer16, pos16);
shiftWindowsLineBreak();
yylineno++;
yycolumn = 0;
+ pos16 = 0;
terminator = true;
bol = true;
if (restrKeyword) {
@@ -1558,19 +1587,25 @@ int QScript::Lexer::lex()
state = Start;
} else if (current == 0) {
setDone(Eof);
+ } else {
+ record16(current);
}
break;
case InMultiLineComment:
if (current == 0) {
setDone(Bad);
err = UnclosedComment;
- errmsg = QLatin1String("Unclosed comment at end of file");
+ errmsg = LU::tr("Unclosed comment at end of file");
} else if (isLineTerminator()) {
shiftWindowsLineBreak();
yylineno++;
} else if (current == '*' && next1 == '/') {
+ processComment(buffer16, pos16);
+ pos16 = 0;
state = Start;
shift(1);
+ } else {
+ record16(current);
}
break;
case InIdentifier:
@@ -1648,7 +1683,7 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalExponentIndicator;
- errmsg = QLatin1String("Illegal syntax for exponential number");
+ errmsg = LU::tr("Illegal syntax for exponential number");
}
break;
case InExponent:
@@ -1674,7 +1709,7 @@ int QScript::Lexer::lex()
&& isIdentLetter(current)) {
state = Bad;
err = IllegalIdentifier;
- errmsg = QLatin1String("Identifier cannot start with numeric literal");
+ errmsg = LU::tr("Identifier cannot start with numeric literal");
}
// terminate string
@@ -1993,7 +2028,7 @@ bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix)
while (1) {
if (isLineTerminator() || current == 0) {
- errmsg = QLatin1String("Unterminated regular expression literal");
+ errmsg = LU::tr("Unterminated regular expression literal");
return false;
}
else if (current != '/' || lastWasEscape == true)
@@ -2032,10 +2067,15 @@ void QScript::Lexer::syncProhibitAutomaticSemicolon()
}
}
+void QScript::Lexer::processComment(const QChar *chars, int length)
+{
+ commentProcessor->processComment(chars, length);
+}
+
class Translator;
-class QScriptParser: protected QScriptGrammar
+class QScriptParser: protected QScriptGrammar, public QScript::CommentProcessor
{
public:
QVariant val;
@@ -2051,10 +2091,12 @@ public:
QScriptParser();
~QScriptParser();
- bool parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator);
+ void setLexer(QScript::Lexer *);
+
+ bool parse(Translator *translator);
+ QString fileName() const
+ { return lexer->fileName(); }
inline QString errorMessage() const
{ return error_message; }
inline int errorLineNumber() const
@@ -2071,6 +2113,10 @@ protected:
inline Location &loc(int index)
{ return location_stack [tos + index - 2]; }
+ std::ostream &yyMsg(int line = 0);
+
+ virtual void processComment(const QChar *, int);
+
protected:
int tos;
int stack_size;
@@ -2080,6 +2126,13 @@ protected:
QString error_message;
int error_lineno;
int error_column;
+
+private:
+ QScript::Lexer *lexer;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
};
inline void QScriptParser::reallocateStack()
@@ -2106,7 +2159,8 @@ QScriptParser::QScriptParser():
stack_size(0),
sym_stack(0),
state_stack(0),
- location_stack(0)
+ location_stack(0),
+ lexer(0)
{
}
@@ -2128,10 +2182,14 @@ static inline QScriptParser::Location location(QScript::Lexer *lexer)
return loc;
}
-bool QScriptParser::parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator)
+void QScriptParser::setLexer(QScript::Lexer *lex)
+{
+ lexer = lex;
+}
+
+bool QScriptParser::parse(Translator *translator)
{
+ Q_ASSERT(lexer != 0);
const int INITIAL_STATE = 0;
int yytoken = -1;
@@ -2213,44 +2271,70 @@ case 8: {
case 66: {
QString name = sym(1).toString();
if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
QVariantList args = sym(2).toList();
if (args.size() < 2) {
- qWarning("%s:%d: %s() requires at least two arguments",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name));
} else {
if ((args.at(0).type() != QVariant::String)
|| (args.at(1).type() != QVariant::String)) {
- qWarning("%s:%d: %s(): both arguments must be literal strings",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name));
} else {
QString context = args.at(0).toString();
QString text = args.at(1).toString();
QString comment = args.value(2).toString();
- QString extracomment;
bool plural = (args.size() > 4);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
} else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
QVariantList args = sym(2).toList();
if (args.size() < 1) {
- qWarning("%s:%d: %s() requires at least one argument",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
} else {
if (args.at(0).type() != QVariant::String) {
- qWarning("%s:%d: %s(): text to translate must be a literal string",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
} else {
- QString context = QFileInfo(fileName).baseName();
+ QString context = QFileInfo(fileName()).baseName();
QString text = args.at(0).toString();
QString comment = args.value(1).toString();
- QString extracomment;
bool plural = (args.size() > 2);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) {
+ if (!msgid.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name));
+ } else {
+ msgid = args.at(0).toString();
+ bool plural = (args.size() > 1);
+ recordMessage(translator, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
}
} break;
@@ -2277,6 +2361,44 @@ case 94: {
sym(1) = QVariant();
} break;
+ case 171:
+
+ case 172:
+
+ case 173:
+
+ case 174:
+
+ case 175:
+
+ case 176:
+
+ case 177:
+
+ case 178:
+
+ case 179:
+
+ case 180:
+
+ case 181:
+
+ case 182:
+
+ case 183:
+
+ case 184:
+
+ case 185:
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ break;
+
} // switch
state_stack [tos] = nt_action (act, lhs [r] - TERMINAL_COUNT);
@@ -2331,7 +2453,9 @@ case 94: {
for (int s = 0; s < shifts; ++s)
{
if (first)
- error_message += QLatin1String ("Expected ");
+ //: Beginning of the string that contains
+ //: comma-separated list of expected tokens
+ error_message += LU::tr("Expected ");
else
error_message += QLatin1String (", ");
@@ -2355,13 +2479,69 @@ case 94: {
return false;
}
+std::ostream &QScriptParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
+}
+
+void QScriptParser::processComment(const QChar *chars, int length)
+{
+ if (!length)
+ return;
+ // Try to match the logic of the C++ parser.
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ extracomment += QString(chars+2, length-2);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
+ break;
+ }
+ forever {
+ if (p >= length) {
+ whoops:
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
+ break;
+ }
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ goto whoops;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ }
+}
+
bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
return false;
}
QTextStream ts(&file);
@@ -2374,12 +2554,13 @@ bool loadQScript(Translator &translator, const QString &filename, ConversionData
ts.setAutoDetectUnicode(true);
QString code = ts.readAll();
- QScript::Lexer lexer;
- lexer.setCode(code, /*lineNumber=*/1);
QScriptParser parser;
- if (!parser.parse(&lexer, filename, &translator)) {
- qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(),
- qPrintable(parser.errorMessage()));
+ QScript::Lexer lexer(&parser);
+ lexer.setCode(code, filename, /*lineNumber=*/1);
+ parser.setLexer(&lexer);
+ if (!parser.parse(&translator)) {
+ std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
+ << qPrintable(parser.errorMessage()) << std::endl;
return false;
}
diff --git a/tools/linguist/lupdate/qscript.g b/tools/linguist/lupdate/qscript.g
index 5445a64..3655f2e 100644
--- a/tools/linguist/lupdate/qscript.g
+++ b/tools/linguist/lupdate/qscript.g
@@ -84,12 +84,15 @@
/.
#include <translator.h>
+#include <QtCore/QCoreApplication>
#include <QtCore/qdebug.h>
#include <QtCore/qnumeric.h>
#include <QtCore/qstring.h>
#include <QtCore/qtextcodec.h>
#include <QtCore/qvariant.h>
+#include <iostream>
+
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
@@ -97,15 +100,22 @@
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
static void recordMessage(
Translator *tor, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool plural, const QString &fileName, int lineNo)
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool plural, const QString &fileName, int lineNo)
{
TranslatorMessage msg(
context, text, comment, QString(),
fileName, lineNo, QStringList(),
TranslatorMessage::Unfinished, plural);
msg.setExtraComment(extracomment.simplified());
+ msg.setId(msgid);
+ msg.setExtras(extra);
tor->extend(msg);
}
@@ -113,15 +123,23 @@ static void recordMessage(
namespace QScript
{
+class CommentProcessor
+{
+public:
+ virtual ~CommentProcessor() {}
+ virtual void processComment(const QChar *chars, int length) = 0;
+};
+
class Lexer
{
public:
- Lexer();
+ Lexer(CommentProcessor *);
~Lexer();
- void setCode(const QString &c, int lineno);
+ void setCode(const QString &c, const QString &fileName, int lineno);
int lex();
+ QString fileName() const { return yyfilename; }
int currentLineNo() const { return yylineno; }
int currentColumnNo() const { return yycolumn; }
@@ -201,6 +219,7 @@ public:
{ err = NoError; }
private:
+ QString yyfilename;
int yylineno;
bool done;
char *buffer8;
@@ -254,6 +273,8 @@ private:
void syncProhibitAutomaticSemicolon();
+ void processComment(const QChar *, int);
+
const QChar *code;
uint length;
int yycolumn;
@@ -280,6 +301,8 @@ private:
ParenthesesState parenthesesState;
int parenthesesCount;
bool prohibitAutomaticSemicolon;
+
+ CommentProcessor *commentProcessor;
};
} // namespace QScript
@@ -356,7 +379,7 @@ double integerFromString(const char *buf, int size, int radix)
} // namespace QScript
-QScript::Lexer::Lexer()
+QScript::Lexer::Lexer(QScript::CommentProcessor *proc)
:
yylineno(0),
size8(128), size16(128), restrKeyword(false),
@@ -367,7 +390,8 @@ QScript::Lexer::Lexer()
err(NoError),
check_reserved(true),
parenthesesState(IgnoreParentheses),
- prohibitAutomaticSemicolon(false)
+ prohibitAutomaticSemicolon(false),
+ commentProcessor(proc)
{
// allocate space for read buffers
buffer8 = new char[size8];
@@ -382,9 +406,10 @@ QScript::Lexer::~Lexer()
delete [] buffer16;
}
-void QScript::Lexer::setCode(const QString &c, int lineno)
+void QScript::Lexer::setCode(const QString &c, const QString &fileName, int lineno)
{
errmsg = QString();
+ yyfilename = fileName;
yylineno = lineno;
yycolumn = 1;
restrKeyword = false;
@@ -733,10 +758,12 @@ int QScript::Lexer::lex()
} else if (current == '/' && next1 == '/') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InSingleLineComment;
} else if (current == '/' && next1 == '*') {
recordStartPos();
shift(1);
+ Q_ASSERT(pos16 == 0);
state = InMultiLineComment;
} else if (current == 0) {
syncProhibitAutomaticSemicolon();
@@ -795,7 +822,7 @@ int QScript::Lexer::lex()
else {
setDone(Bad);
err = IllegalCharacter;
- errmsg = QLatin1String("Illegal character");
+ errmsg = LU::tr("Illegal character");
}
}
break;
@@ -806,7 +833,7 @@ int QScript::Lexer::lex()
} else if (current == 0 || isLineTerminator()) {
setDone(Bad);
err = UnclosedStringLiteral;
- errmsg = QLatin1String("Unclosed string at end of line");
+ errmsg = LU::tr("Unclosed string at end of line");
} else if (current == '\\') {
state = InEscapeSequence;
} else {
@@ -832,7 +859,7 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalEscapeSequence;
- errmsg = QLatin1String("Illegal escape squence");
+ errmsg = LU::tr("Illegal escape squence");
}
} else if (current == 'x')
state = InHexEscape;
@@ -871,14 +898,17 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalUnicodeEscapeSequence;
- errmsg = QLatin1String("Illegal unicode escape sequence");
+ errmsg = LU::tr("Illegal unicode escape sequence");
}
break;
case InSingleLineComment:
if (isLineTerminator()) {
+ record16(current); // include newline
+ processComment(buffer16, pos16);
shiftWindowsLineBreak();
yylineno++;
yycolumn = 0;
+ pos16 = 0;
terminator = true;
bol = true;
if (restrKeyword) {
@@ -888,19 +918,25 @@ int QScript::Lexer::lex()
state = Start;
} else if (current == 0) {
setDone(Eof);
+ } else {
+ record16(current);
}
break;
case InMultiLineComment:
if (current == 0) {
setDone(Bad);
err = UnclosedComment;
- errmsg = QLatin1String("Unclosed comment at end of file");
+ errmsg = LU::tr("Unclosed comment at end of file");
} else if (isLineTerminator()) {
shiftWindowsLineBreak();
yylineno++;
} else if (current == '*' && next1 == '/') {
+ processComment(buffer16, pos16);
+ pos16 = 0;
state = Start;
shift(1);
+ } else {
+ record16(current);
}
break;
case InIdentifier:
@@ -978,7 +1014,7 @@ int QScript::Lexer::lex()
} else {
setDone(Bad);
err = IllegalExponentIndicator;
- errmsg = QLatin1String("Illegal syntax for exponential number");
+ errmsg = LU::tr("Illegal syntax for exponential number");
}
break;
case InExponent:
@@ -1004,7 +1040,7 @@ int QScript::Lexer::lex()
&& isIdentLetter(current)) {
state = Bad;
err = IllegalIdentifier;
- errmsg = QLatin1String("Identifier cannot start with numeric literal");
+ errmsg = LU::tr("Identifier cannot start with numeric literal");
}
// terminate string
@@ -1323,7 +1359,7 @@ bool QScript::Lexer::scanRegExp(RegExpBodyPrefix prefix)
while (1) {
if (isLineTerminator() || current == 0) {
- errmsg = QLatin1String("Unterminated regular expression literal");
+ errmsg = LU::tr("Unterminated regular expression literal");
return false;
}
else if (current != '/' || lastWasEscape == true)
@@ -1362,10 +1398,15 @@ void QScript::Lexer::syncProhibitAutomaticSemicolon()
}
}
+void QScript::Lexer::processComment(const QChar *chars, int length)
+{
+ commentProcessor->processComment(chars, length);
+}
+
class Translator;
-class QScriptParser: protected $table
+class QScriptParser: protected $table, public QScript::CommentProcessor
{
public:
QVariant val;
@@ -1381,10 +1422,12 @@ public:
QScriptParser();
~QScriptParser();
- bool parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator);
+ void setLexer(QScript::Lexer *);
+
+ bool parse(Translator *translator);
+ QString fileName() const
+ { return lexer->fileName(); }
inline QString errorMessage() const
{ return error_message; }
inline int errorLineNumber() const
@@ -1401,6 +1444,10 @@ protected:
inline Location &loc(int index)
{ return location_stack [tos + index - 2]; }
+ std::ostream &yyMsg(int line = 0);
+
+ virtual void processComment(const QChar *, int);
+
protected:
int tos;
int stack_size;
@@ -1410,6 +1457,13 @@ protected:
QString error_message;
int error_lineno;
int error_column;
+
+private:
+ QScript::Lexer *lexer;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
};
inline void QScriptParser::reallocateStack()
@@ -1436,7 +1490,8 @@ QScriptParser::QScriptParser():
stack_size(0),
sym_stack(0),
state_stack(0),
- location_stack(0)
+ location_stack(0),
+ lexer(0)
{
}
@@ -1458,10 +1513,14 @@ static inline QScriptParser::Location location(QScript::Lexer *lexer)
return loc;
}
-bool QScriptParser::parse(QScript::Lexer *lexer,
- const QString &fileName,
- Translator *translator)
+void QScriptParser::setLexer(QScript::Lexer *lex)
{
+ lexer = lex;
+}
+
+bool QScriptParser::parse(Translator *translator)
+{
+ Q_ASSERT(lexer != 0);
const int INITIAL_STATE = 0;
int yytoken = -1;
@@ -1628,44 +1687,70 @@ CallExpression: MemberExpression Arguments ;
case $rule_number: {
QString name = sym(1).toString();
if ((name == QLatin1String("qsTranslate")) || (name == QLatin1String("QT_TRANSLATE_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
QVariantList args = sym(2).toList();
if (args.size() < 2) {
- qWarning("%s:%d: %s() requires at least two arguments",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least two arguments.\n").arg(name));
} else {
if ((args.at(0).type() != QVariant::String)
|| (args.at(1).type() != QVariant::String)) {
- qWarning("%s:%d: %s(): both arguments must be literal strings",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): both arguments must be literal strings.\n").arg(name));
} else {
QString context = args.at(0).toString();
QString text = args.at(1).toString();
QString comment = args.value(2).toString();
- QString extracomment;
bool plural = (args.size() > 4);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
} else if ((name == QLatin1String("qsTr")) || (name == QLatin1String("QT_TR_NOOP"))) {
+ if (!sourcetext.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//% cannot be used with %1(). Ignoring\n").arg(name));
QVariantList args = sym(2).toList();
if (args.size() < 1) {
- qWarning("%s:%d: %s() requires at least one argument",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
} else {
if (args.at(0).type() != QVariant::String) {
- qWarning("%s:%d: %s(): text to translate must be a literal string",
- qPrintable(fileName), identLineNo, qPrintable(name));
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): text to translate must be a literal string.\n").arg(name));
} else {
- QString context = QFileInfo(fileName).baseName();
+ QString context = QFileInfo(fileName()).baseName();
QString text = args.at(0).toString();
QString comment = args.value(1).toString();
- QString extracomment;
bool plural = (args.size() > 2);
recordMessage(translator, context, text, comment, extracomment,
- plural, fileName, identLineNo);
+ msgid, extra, plural, fileName(), identLineNo);
}
}
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ } else if ((name == QLatin1String("qsTrId")) || (name == QLatin1String("QT_TRID_NOOP"))) {
+ if (!msgid.isEmpty())
+ yyMsg(identLineNo) << qPrintable(LU::tr("//= cannot be used with %1(). Ignoring\n").arg(name));
+ QVariantList args = sym(2).toList();
+ if (args.size() < 1) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1() requires at least one argument.\n").arg(name));
+ } else {
+ if (args.at(0).type() != QVariant::String) {
+ yyMsg(identLineNo) << qPrintable(LU::tr("%1(): identifier must be a literal string.\n").arg(name));
+ } else {
+ msgid = args.at(0).toString();
+ bool plural = (args.size() > 1);
+ recordMessage(translator, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, plural, fileName(), identLineNo);
+ }
+ }
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
}
} break;
./
@@ -1811,20 +1896,73 @@ ExpressionNotInOpt: ;
ExpressionNotInOpt: ExpressionNotIn ;
Statement: Block ;
+/.
+ case $rule_number:
+./
Statement: VariableStatement ;
+/.
+ case $rule_number:
+./
Statement: EmptyStatement ;
+/.
+ case $rule_number:
+./
Statement: ExpressionStatement ;
+/.
+ case $rule_number:
+./
Statement: IfStatement ;
+/.
+ case $rule_number:
+./
Statement: IterationStatement ;
+/.
+ case $rule_number:
+./
Statement: ContinueStatement ;
+/.
+ case $rule_number:
+./
Statement: BreakStatement ;
+/.
+ case $rule_number:
+./
Statement: ReturnStatement ;
+/.
+ case $rule_number:
+./
Statement: WithStatement ;
+/.
+ case $rule_number:
+./
Statement: LabelledStatement ;
+/.
+ case $rule_number:
+./
Statement: SwitchStatement ;
+/.
+ case $rule_number:
+./
Statement: ThrowStatement ;
+/.
+ case $rule_number:
+./
Statement: TryStatement ;
+/.
+ case $rule_number:
+./
Statement: DebuggerStatement ;
+/.
+ case $rule_number:
+ if (!sourcetext.isEmpty() || !extracomment.isEmpty() || !msgid.isEmpty() || !extra.isEmpty()) {
+ yyMsg() << qPrintable(LU::tr("Discarding unconsumed meta data\n"));
+ sourcetext.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ }
+ break;
+./
Block: T_LBRACE StatementListOpt T_RBRACE ;
StatementList: Statement ;
@@ -1963,6 +2101,9 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
{
if (first)
error_message += QLatin1String ("Expected ");
+ //: Beginning of the string that contains
+ //: comma-separated list of expected tokens
+ error_message += LU::tr("Expected ");
else
error_message += QLatin1String (", ");
@@ -1986,13 +2127,69 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
return false;
}
+std::ostream &QScriptParser::yyMsg(int line)
+{
+ return std::cerr << qPrintable(fileName()) << ':' << (line ? line : lexer->startLineNo()) << ": ";
+}
+
+void QScriptParser::processComment(const QChar *chars, int length)
+{
+ if (!length)
+ return;
+ // Try to match the logic of the C++ parser.
+ if (*chars == QLatin1Char(':') && chars[1].isSpace()) {
+ extracomment += QString(chars+2, length-2);
+ } else if (*chars == QLatin1Char('=') && chars[1].isSpace()) {
+ msgid = QString(chars+2, length-2).simplified();
+ } else if (*chars == QLatin1Char('~') && chars[1].isSpace()) {
+ QString text = QString(chars+2, length-2).trimmed();
+ int k = text.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(text.left(k), text.mid(k + 1).trimmed());
+ } else if (*chars == QLatin1Char('%') && chars[1].isSpace()) {
+ sourcetext.reserve(sourcetext.length() + length-2);
+ ushort *ptr = (ushort *)sourcetext.data() + sourcetext.length();
+ int p = 2, c;
+ forever {
+ if (p >= length)
+ break;
+ c = chars[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ yyMsg() << qPrintable(LU::tr("Unexpected character in meta string\n"));
+ break;
+ }
+ forever {
+ if (p >= length) {
+ whoops:
+ yyMsg() << qPrintable(LU::tr("Unterminated meta string\n"));
+ break;
+ }
+ c = chars[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= length)
+ goto whoops;
+ c = chars[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ *ptr++ = '\\';
+ }
+ *ptr++ = c;
+ }
+ }
+ sourcetext.resize(ptr - (ushort *)sourcetext.data());
+ }
+}
+
bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
{
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
return false;
}
QTextStream ts(&file);
@@ -2005,12 +2202,13 @@ bool loadQScript(Translator &translator, const QString &filename, ConversionData
ts.setAutoDetectUnicode(true);
QString code = ts.readAll();
- QScript::Lexer lexer;
- lexer.setCode(code, /*lineNumber=*/1);
QScriptParser parser;
- if (!parser.parse(&lexer, filename, &translator)) {
- qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(),
- qPrintable(parser.errorMessage()));
+ QScript::Lexer lexer(&parser);
+ lexer.setCode(code, filename, /*lineNumber=*/1);
+ parser.setLexer(&lexer);
+ if (!parser.parse(&translator)) {
+ std::cerr << qPrintable(filename) << ':' << parser.errorLineNumber() << ": "
+ << qPrintable(parser.errorMessage()) << std::endl;
return false;
}
diff --git a/tools/linguist/lupdate/ui.cpp b/tools/linguist/lupdate/ui.cpp
index 9e22922..797ab1f 100644
--- a/tools/linguist/lupdate/ui.cpp
+++ b/tools/linguist/lupdate/ui.cpp
@@ -43,6 +43,7 @@
#include <translator.h>
+#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QString>
@@ -55,6 +56,10 @@
QT_BEGIN_NAMESPACE
+class LU {
+ Q_DECLARE_TR_FUNCTIONS(LUpdate)
+};
+
class UiReader : public QXmlDefaultHandler
{
public:
@@ -152,11 +157,10 @@ bool UiReader::characters(const QString &ch)
bool UiReader::fatalError(const QXmlParseException &exception)
{
- QString msg;
- msg.sprintf("XML error: Parse error at line %d, column %d (%s).",
- exception.lineNumber(), exception.columnNumber(),
- exception.message().toLatin1().data());
- m_cd.appendError(msg);
+ QString msg = LU::tr("XML error: Parse error at line %1, column %2 (%3).")
+ .arg(exception.lineNumber()).arg(exception.columnNumber())
+ .arg(exception.message());
+ m_cd.appendError(msg);
return false;
}
@@ -181,8 +185,7 @@ bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
cd.m_sourceFileName = filename;
QFile file(filename);
if (!file.open(QIODevice::ReadOnly)) {
- cd.appendError(QString::fromLatin1("Cannot open %1: %2")
- .arg(filename, file.errorString()));
+ cd.appendError(LU::tr("Cannot open %1: %2").arg(filename, file.errorString()));
return false;
}
QXmlInputSource in(&file);
@@ -196,7 +199,7 @@ bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
reader.setErrorHandler(&handler);
bool result = reader.parse(in);
if (!result)
- cd.appendError(QLatin1String("Parse error in UI file"));
+ cd.appendError(LU::tr("Parse error in UI file"));
reader.setContentHandler(0);
reader.setErrorHandler(0);
return result;
diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph
index 9e1a580..1884ed3 100644
--- a/tools/linguist/phrasebooks/french.qph
+++ b/tools/linguist/phrasebooks/french.qph
@@ -801,7 +801,7 @@
</phrase>
<phrase>
<source>Redo</source>
- <target>Annuler Annuler</target>
+ <target>Rétablir</target>
</phrase>
<phrase>
<source>region selection</source>
@@ -1111,10 +1111,6 @@
<target>&amp;Édition</target>
</phrase>
<phrase>
- <source>&amp;Redo</source>
- <target>Re&amp;faire</target>
-</phrase>
-<phrase>
<source>debugger</source>
<target>débogueur</target>
</phrase>
@@ -1438,4 +1434,60 @@
<source>&amp;Debug</source>
<target>&amp;Déboguer</target>
</phrase>
+<phrase>
+ <source>Slider</source>
+ <target>Barre de défilement</target>
+</phrase>
+<phrase>
+ <source>&amp;Restore</source>
+ <target>&amp;Restaurer</target>
+</phrase>
+<phrase>
+ <source>&amp;Move</source>
+ <target>&amp;Déplacer</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Créer</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lecture</target>
+</phrase>
+<phrase>
+ <source>Slider</source>
+ <target>Barre de défilement</target>
+</phrase>
+<phrase>
+ <source>&amp;Restore</source>
+ <target>&amp;Restaurer</target>
+</phrase>
+<phrase>
+ <source>&amp;Move</source>
+ <target>&amp;Déplacer</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Créer</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lecture</target>
+</phrase>
+<phrase>
+ <source>&amp;Redo</source>
+ <target>&amp;Refaire</target>
+</phrase>
+<phrase>
+ <source>Raised</source>
+ <target>Bombé</target>
+</phrase>
+<phrase>
+ <source>Sunken</source>
+ <target>Enfoncé</target>
+</phrase>
+<phrase>
+ <source>Run:</source>
+ <target>Exécution :</target>
+</phrase>
</QPH>
diff --git a/tools/linguist/phrasebooks/hungarian.qph b/tools/linguist/phrasebooks/hungarian.qph
new file mode 100644
index 0000000..0e1dd12
--- /dev/null
+++ b/tools/linguist/phrasebooks/hungarian.qph
@@ -0,0 +1,752 @@
+<!DOCTYPE QPH>
+<QPH language="hu_HU">
+<phrase>
+ <source>OK</source>
+ <target>OK</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Könyvjelzők</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Törlés</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Új könyvtár</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Hozzáadás</target>
+</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Előző</target>
+</phrase>
+<phrase>
+ <source>Font</source>
+ <target>Betűtípus</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Segítség</target>
+</phrase>
+<phrase>
+ <source>Done</source>
+ <target>Kész</target>
+</phrase>
+<phrase>
+ <source>Install</source>
+ <target>Telepítés</target>
+</phrase>
+<phrase>
+ <source>Cancel</source>
+ <target>Mégsem</target>
+</phrase>
+<phrase>
+ <source>Installation Path:</source>
+ <target>Telepítési útvonal:</target>
+</phrase>
+<phrase>
+ <source>Index</source>
+ <target>Index</target>
+</phrase>
+<phrase>
+ <source>Contents</source>
+ <target>Tartalom</target>
+</phrase>
+<phrase>
+ <source>Search</source>
+ <target>Keresés</target>
+</phrase>
+<phrase>
+ <source>Print Preview...</source>
+ <target>Nyomtatási kép...</target>
+</phrase>
+<phrase>
+ <source>About...</source>
+ <target>Névjegy...</target>
+</phrase>
+<phrase>
+ <source>Toolbars</source>
+ <target>Eszköztárak</target>
+</phrase>
+<phrase>
+ <source>Address:</source>
+ <target>Cím:</target>
+</phrase>
+<phrase>
+ <source>Open Source Edition</source>
+ <target>Nyíltforrású kiadás</target>
+</phrase>
+<phrase>
+ <source>Yes</source>
+ <target>Igen</target>
+</phrase>
+<phrase>
+ <source>No</source>
+ <target>Nem</target>
+</phrase>
+<phrase>
+ <source>Apply</source>
+ <target>Alkalmaz</target>
+</phrase>
+<phrase>
+ <source>Ignore</source>
+ <target>Kihagyás</target>
+</phrase>
+<phrase>
+ <source>Abort</source>
+ <target>Megszakítás</target>
+</phrase>
+<phrase>
+ <source>Play</source>
+ <target>Lejátszás</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Szünet</target>
+</phrase>
+<phrase>
+ <source>File</source>
+ <target>Fájl</target>
+ <definition>menu</definition>
+</phrase>
+<phrase>
+ <source>file</source>
+ <target>fájl</target>
+</phrase>
+<phrase>
+ <source>directory</source>
+ <target>könyvtár</target>
+</phrase>
+<phrase>
+ <source>Symlink</source>
+ <target>Szimbolikus link</target>
+</phrase>
+<phrase>
+ <source>Delete</source>
+ <target>Törlés</target>
+</phrase>
+<phrase>
+ <source>Rename</source>
+ <target>Átnevezés</target>
+</phrase>
+<phrase>
+ <source>Back</source>
+ <target>Vissza</target>
+</phrase>
+<phrase>
+ <source>Forward</source>
+ <target>Előre</target>
+</phrase>
+<phrase>
+ <source>Finish</source>
+ <target>Befejezés</target>
+</phrase>
+<phrase>
+ <source>Quit</source>
+ <target>Kilépés</target>
+</phrase>
+<phrase>
+ <source>Exit</source>
+ <target>Kilépés</target>
+</phrase>
+<phrase>
+ <source>Close</source>
+ <target>Bezárás</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Mindent bezár</target>
+</phrase>
+<phrase>
+ <source>Error</source>
+ <target>Hiba</target>
+</phrase>
+<phrase>
+ <source>Warning</source>
+ <target>Figyelmeztetés</target>
+</phrase>
+<phrase>
+ <source>Information</source>
+ <target>Információ</target>
+</phrase>
+<phrase>
+ <source>Question</source>
+ <target>Kérdés</target>
+</phrase>
+<phrase>
+ <source>document</source>
+ <target>dokumentum</target>
+</phrase>
+<phrase>
+ <source>author</source>
+ <target>szerző</target>
+</phrase>
+<phrase>
+ <source>subsidiary(-ies)</source>
+ <target>leányvállalata(i)</target>
+</phrase>
+<phrase>
+ <source>Help</source>
+ <target>Súgó</target>
+</phrase>
+<phrase>
+ <source>Undo</source>
+ <target>Visszavonás</target>
+</phrase>
+<phrase>
+ <source>Redo</source>
+ <target>Újra</target>
+</phrase>
+<phrase>
+ <source>Open</source>
+ <target>Megnyitás</target>
+</phrase>
+<phrase>
+ <source>Save</source>
+ <target>Mentés</target>
+</phrase>
+<phrase>
+ <source>Save all</source>
+ <target>Mindet menti</target>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>kattintás</target>
+ <definition>noun</definition>
+</phrase>
+<phrase>
+ <source>click</source>
+ <target>kattintson</target>
+ <definition>ask</definition>
+</phrase>
+<phrase>
+ <source>Recent</source>
+ <target>Előző</target>
+ <definition>Recent files/Előző fájlok</definition>
+</phrase>
+<phrase>
+ <source>Window</source>
+ <target>Ablak</target>
+</phrase>
+<phrase>
+ <source>Cascade</source>
+ <target>Lépcsőzetes</target>
+</phrase>
+<phrase>
+ <source>Tile</source>
+ <target>Mozaikszerű</target>
+</phrase>
+<phrase>
+ <source>Game</source>
+ <target>Játék</target>
+</phrase>
+<phrase>
+ <source>New Game</source>
+ <target>Új játék</target>
+</phrase>
+<phrase>
+ <source>Untitled</source>
+ <target>Névtelen</target>
+</phrase>
+<phrase>
+ <source>Unknown error</source>
+ <target>Ismeretlen hiba</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Új mappa</target>
+</phrase>
+<phrase>
+ <source>folder</source>
+ <target>mappa</target>
+</phrase>
+<phrase>
+ <source>New Directory</source>
+ <target>Új könyvtár</target>
+</phrase>
+<phrase>
+ <source>unknown</source>
+ <target>ismeretlen</target>
+</phrase>
+<phrase>
+ <source>Copy</source>
+ <target>Másolás</target>
+</phrase>
+<phrase>
+ <source>Cut</source>
+ <target>Kivágás</target>
+</phrase>
+<phrase>
+ <source>Paste</source>
+ <target>Beillesztés</target>
+</phrase>
+<phrase>
+ <source>Paste special</source>
+ <target>Speciális beillesztés</target>
+</phrase>
+<phrase>
+ <source>Insert</source>
+ <target>Beszúrás</target>
+</phrase>
+<phrase>
+ <source>Copy here</source>
+ <target>Másolás ide</target>
+</phrase>
+<phrase>
+ <source>Minimize</source>
+ <target>Minimalizálás</target>
+</phrase>
+<phrase>
+ <source>Zoom</source>
+ <target>Nagyítás</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <target>S&amp;zerkesztés</target>
+</phrase>
+<phrase>
+ <source>&amp;View</source>
+ <target>&amp;Nézet</target>
+</phrase>
+<phrase>
+ <source>Application</source>
+ <target>Alkalmazás</target>
+</phrase>
+<phrase>
+ <source>Documentation</source>
+ <target>Dokumentáció</target>
+</phrase>
+<phrase>
+ <source>Network</source>
+ <target>Hálózat</target>
+</phrase>
+<phrase>
+ <source>Current Page</source>
+ <target>Aktuális oldal</target>
+</phrase>
+<phrase>
+ <source>Find</source>
+ <target>Keresés</target>
+</phrase>
+<phrase>
+ <source>Locale</source>
+ <target>Nyelv</target>
+</phrase>
+<phrase>
+ <source>Cannot open &apos;%1&apos;.</source>
+ <target>&apos;%1&apos; nem nyitható meg.</target>
+</phrase>
+<phrase>
+ <source>Cannot find the string &apos;%1&apos;.</source>
+ <target>A szöveg nem található: &apos;%1&apos;.</target>
+</phrase>
+<phrase>
+ <source>A file called &apos;%1&apos; already exists. Please choose another name.</source>
+ <target>&apos;%1&apos; nevű fájl már létezik. Válasszon egy másik nevet.</target>
+</phrase>
+<phrase>
+ <source>The program is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.</source>
+ <target>Ez a program abban a reményben került közreadásra, hogy hasznos lesz, de minden egyéb GARANCIA NÉLKÜL, az ELADHATÓSÁGRA vagy VALAMELY CÉLRA VALÓ ALKALMAZHATÓSÁGRA való származtatott garanciát is beleértve.</target>
+ <definition>License text in most Qt programs</definition>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Link megnyitása</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Következő</target>
+</phrase>
+<phrase>
+ <source>Case Sensitive</source>
+ <target>Kis/nagybetű érzékeny</target>
+</phrase>
+<phrase>
+ <source>Whole words</source>
+ <target>Teljes szó</target>
+</phrase>
+<phrase>
+ <source>Open Link in New Tab</source>
+ <target>Link megnyitása új lapon</target>
+</phrase>
+<phrase>
+ <source>Download canceled.</source>
+ <target>Letöltés megszakítva.</target>
+</phrase>
+<phrase>
+ <source>The file %1 already exists. Do you want to overwrite it?</source>
+ <target>A(z) &apos;%1&apos; nevű fájl már létezik. Felülírja?</target>
+</phrase>
+<phrase>
+ <source>Qt Assistant</source>
+ <target>Qt Asszisztens</target>
+</phrase>
+<phrase>
+ <source>Preferences...</source>
+ <target>Beállítások...</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fájl</target>
+</phrase>
+<phrase>
+ <source>Browser</source>
+ <target>Böngésző</target>
+</phrase>
+<phrase>
+ <source>Filters</source>
+ <target>Szűrők</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Mappa törlése</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Mappa átnevezése</target>
+</phrase>
+<phrase>
+ <source>You need a commercial Qt license for development of proprietary (closed source) applications. Please see &lt;a href=&quot;http://www.trolltech.com/company/model.html&quot;&gt;www.trolltech.com/company/model.html&lt;/a&gt; for an overview of Qt licensing.</source>
+ <target>Amennyiben zárt forrású alkalmazás fejlesztéséhez kívánja a Qt-t felhasználni, szüksége lesz a Qt kereskedelmi verziójára. Kérem tekintse meg az &lt;tt&gt;http://www.trolltech.com/company/model.html&lt;/tt&gt; oldalt a Qt licenszelésének áttekintéséhez.</target>
+</phrase>
+<phrase>
+ <source>New Tab</source>
+ <target>Új fül</target>
+</phrase>
+<phrase>
+ <source>Close Tab</source>
+ <target>Fül bezárása</target>
+</phrase>
+<phrase>
+ <source>Close Other Tabs</source>
+ <target>A többi fül bezárása</target>
+</phrase>
+<phrase>
+ <source>True</source>
+ <target>Igaz</target>
+</phrase>
+<phrase>
+ <source>False</source>
+ <target>Hamis</target>
+</phrase>
+<phrase>
+ <source>Update</source>
+ <target>Frissítés</target>
+</phrase>
+<phrase>
+ <source>Normal</source>
+ <target>Normál</target>
+</phrase>
+<phrase>
+ <source>Bold</source>
+ <target>Félkövér</target>
+</phrase>
+<phrase>
+ <source>Italic</source>
+ <target>Dőlt</target>
+</phrase>
+<phrase>
+ <source>Greek</source>
+ <target>Görög</target>
+</phrase>
+<phrase>
+ <source>Cyrillic</source>
+ <target>Cirill</target>
+</phrase>
+<phrase>
+ <source>Armenian</source>
+ <target>Örmény</target>
+</phrase>
+<phrase>
+ <source>Hebrew</source>
+ <target>Héber</target>
+</phrase>
+<phrase>
+ <source>Arabic</source>
+ <target>Arab</target>
+</phrase>
+<phrase>
+ <source>Syriac</source>
+ <target>Szír</target>
+</phrase>
+<phrase>
+ <source>Permission denied</source>
+ <target>Hozzáférés megtagadva</target>
+</phrase>
+<phrase>
+ <source>Too many open files</source>
+ <target>Túl sok fájl van nyitva</target>
+</phrase>
+<phrase>
+ <source>No such file or directory</source>
+ <target>Nincs ilyen fájl vagy könyvtár</target>
+</phrase>
+<phrase>
+ <source>No space left on device</source>
+ <target>Nincs több hely az eszközön</target>
+</phrase>
+<phrase>
+ <source>Width:</source>
+ <target>Szélesség:</target>
+</phrase>
+<phrase>
+ <source>Height:</source>
+ <target>Magasság:</target>
+</phrase>
+<phrase>
+ <source>Margins</source>
+ <target>Margók</target>
+</phrase>
+<phrase>
+ <source>top margin</source>
+ <target>felső margó</target>
+</phrase>
+<phrase>
+ <source>left margin</source>
+ <target>bal margó</target>
+</phrase>
+<phrase>
+ <source>right margin</source>
+ <target>jobb margó</target>
+</phrase>
+<phrase>
+ <source>bottom margin</source>
+ <target>alsó margó</target>
+</phrase>
+<phrase>
+ <source>Next page</source>
+ <target>Következő oldal</target>
+</phrase>
+<phrase>
+ <source>Previous page</source>
+ <target>Előző oldal</target>
+</phrase>
+<phrase>
+ <source>First page</source>
+ <target>Első oldal</target>
+</phrase>
+<phrase>
+ <source>Last page</source>
+ <target>Utolsó oldal</target>
+</phrase>
+<phrase>
+ <source>Fit width</source>
+ <target>Szélesség igazítása</target>
+</phrase>
+<phrase>
+ <source>Fit page</source>
+ <target>Oldal igazítása</target>
+</phrase>
+<phrase>
+ <source>Zoom in</source>
+ <target>Nagyítás</target>
+</phrase>
+<phrase>
+ <source>Zoom out</source>
+ <target>Kicsinyítés</target>
+</phrase>
+<phrase>
+ <source>Portrait</source>
+ <target>Álló</target>
+</phrase>
+<phrase>
+ <source>Landscape</source>
+ <target>Fekvő</target>
+</phrase>
+<phrase>
+ <source>Print</source>
+ <target>Nyomtatás</target>
+</phrase>
+<phrase>
+ <source>Page setup</source>
+ <target>Oldalbeállítás</target>
+</phrase>
+<phrase>
+ <source>Color</source>
+ <target>Szín</target>
+</phrase>
+<phrase>
+ <source>Grayscale</source>
+ <target>Szürkeárnyalatos</target>
+</phrase>
+<phrase>
+ <source>None</source>
+ <target>Nincs</target>
+</phrase>
+<phrase>
+ <source>...</source>
+ <target>...</target>
+</phrase>
+<phrase>
+ <source>Menu</source>
+ <target>Menü</target>
+</phrase>
+<phrase>
+ <source>Keep</source>
+ <target>Meghagy</target>
+</phrase>
+<phrase>
+ <source>Pause</source>
+ <target>Megállít</target>
+</phrase>
+<phrase>
+ <source>Log</source>
+ <target>Napló</target>
+</phrase>
+<phrase>
+ <source>Mi&amp;nimize</source>
+ <target>&amp;Kis méret</target>
+</phrase>
+<phrase>
+ <source>Press</source>
+ <target>Nyomja meg</target>
+</phrase>
+<phrase>
+ <source>Submit</source>
+ <target>Küldés</target>
+</phrase>
+<phrase>
+ <source>Underline</source>
+ <target>Aláhúzott</target>
+</phrase>
+<phrase>
+ <source>Outline</source>
+ <target>Áthúzott</target>
+</phrase>
+<phrase>
+ <source>Direction</source>
+ <target>Irány</target>
+</phrase>
+<phrase>
+ <source>Configuration</source>
+ <target>Konfiguráció</target>
+</phrase>
+<phrase>
+ <source>None</source>
+ <target>Semmi</target>
+</phrase>
+<phrase>
+ <source>Save As...</source>
+ <target>Mentés másként...</target>
+</phrase>
+<phrase>
+ <source>Context</source>
+ <target>Környezet</target>
+</phrase>
+<phrase>
+ <source>Edit</source>
+ <target>Szerkesztés</target>
+</phrase>
+<phrase>
+ <source>Toolbar</source>
+ <target>Eszköztár</target>
+</phrase>
+<phrase>
+ <source>&amp;Print...</source>
+ <target>&amp;Nyomtatás...</target>
+</phrase>
+<phrase>
+ <source>E&amp;xit</source>
+ <target>&amp;Kilépés</target>
+</phrase>
+<phrase>
+ <source>Sidebar</source>
+ <target>Oldalsáv</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Könyvjelző</target>
+</phrase>
+<phrase>
+ <source>Save As</source>
+ <target>Mentés másként</target>
+</phrase>
+<phrase>
+ <source>Select All</source>
+ <target>Összes kijelölése</target>
+</phrase>
+<phrase>
+ <source>Name</source>
+ <target>Név</target>
+</phrase>
+<phrase>
+ <source>Type</source>
+ <target>Típus</target>
+</phrase>
+<phrase>
+ <source>Date</source>
+ <target>Dátum</target>
+</phrase>
+<phrase>
+ <source>Name</source>
+ <target>Név</target>
+</phrase>
+<phrase>
+ <source>Unknown</source>
+ <target>Ismeretlen</target>
+</phrase>
+<phrase>
+ <source>Value</source>
+ <target>Érték</target>
+</phrase>
+<phrase>
+ <source>Default</source>
+ <target>Alapértelmezett</target>
+</phrase>
+<phrase>
+ <source>New</source>
+ <target>Új</target>
+</phrase>
+<phrase>
+ <source>Level</source>
+ <target>Szint</target>
+</phrase>
+<phrase>
+ <source>Location</source>
+ <target>Hely</target>
+</phrase>
+<phrase>
+ <source>Reload</source>
+ <target>Újratöltés</target>
+</phrase>
+<phrase>
+ <source>Pictures</source>
+ <target>Képek</target>
+</phrase>
+<phrase>
+ <source>Battery</source>
+ <target>Elem</target>
+</phrase>
+<phrase>
+ <source>No error</source>
+ <target>Nincs hiba</target>
+</phrase>
+<phrase>
+ <source>Whole words</source>
+ <target>Teljes szó</target>
+</phrase>
+<phrase>
+ <source>(Új bejegyzés)</source>
+ <target></target>
+</phrase>
+<phrase>
+ <source>Horizontal</source>
+ <target>Vízszintes</target>
+</phrase>
+<phrase>
+ <source>Enabled</source>
+ <target>Engedélyezve</target>
+</phrase>
+<phrase>
+ <source>Up</source>
+ <target>Fel</target>
+</phrase>
+<phrase>
+ <source>Down</source>
+ <target>Le</target>
+</phrase>
+</QPH>
diff --git a/tools/linguist/phrasebooks/russian.qph b/tools/linguist/phrasebooks/russian.qph
index ae1a9b9..5876ee9 100644
--- a/tools/linguist/phrasebooks/russian.qph
+++ b/tools/linguist/phrasebooks/russian.qph
@@ -498,7 +498,7 @@
</phrase>
<phrase>
<source>Next</source>
- <target>Следующий</target>
+ <target>Далее</target>
</phrase>
<phrase>
<source>object</source>
@@ -826,7 +826,7 @@
</phrase>
<phrase>
<source>slider</source>
- <target>ползунок</target>
+ <target>регулятор</target>
</phrase>
<phrase>
<source>spin box</source>
@@ -1070,7 +1070,7 @@
</phrase>
<phrase>
<source>Next</source>
- <target>Далее</target>
+ <target>Следующий</target>
</phrase>
<phrase>
<source>tree view</source>
@@ -1204,4 +1204,16 @@
<source>Permission denied</source>
<target>Доступ запрещён</target>
</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Предыдущий</target>
+</phrase>
+<phrase>
+ <source>Next</source>
+ <target>Следующее</target>
+</phrase>
+<phrase>
+ <source>Previous</source>
+ <target>Предыдущее</target>
+</phrase>
</QPH>
diff --git a/tools/linguist/shared/numerus.cpp b/tools/linguist/shared/numerus.cpp
index d45dfed..6066732 100644
--- a/tools/linguist/shared/numerus.cpp
+++ b/tools/linguist/shared/numerus.cpp
@@ -64,7 +64,7 @@ static const uchar icelandicRules[] =
static const uchar irishStyleRules[] =
{ Q_EQ, 1, Q_NEWRULE,
Q_EQ, 2 };
-static const uchar slovakRules[] =
+static const uchar slovakStyleRules[] =
{ Q_EQ, 1, Q_NEWRULE,
Q_BETWEEN, 2, 4 };
static const uchar macedonianRules[] =
@@ -100,7 +100,7 @@ static const uchar arabicRules[] =
Q_EQ, 1, Q_NEWRULE,
Q_EQ, 2, Q_NEWRULE,
Q_MOD_100 | Q_BETWEEN, 3, 10, Q_NEWRULE,
- Q_MOD_100 | Q_NOT | Q_BETWEEN, 0, 2 };
+ Q_MOD_100 | Q_GEQ, 11 };
static const uchar tagalogRules[] =
{ Q_LEQ, 1, Q_NEWRULE,
Q_MOD_10 | Q_EQ, 4, Q_OR, Q_MOD_10 | Q_EQ, 6, Q_OR, Q_MOD_10 | Q_EQ, 9 };
@@ -114,7 +114,7 @@ static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 };
static const char * const icelandicForms[] = { "Singular", "Plural", 0 };
static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 };
static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 };
-static const char * const slovakForms[] = { "Singular", "Paucal", "Plural", 0 };
+static const char * const slovakStyleForms[] = { "Singular", "Paucal", "Plural", 0 };
static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 };
static const char * const lithuanianForms[] = { "Singular", "Paucal", "Plural", 0 };
static const char * const russianStyleForms[] = { "Singular", "Dual", "Plural", 0 };
@@ -279,7 +279,7 @@ static const QLocale::Language irishStyleLanguages[] = {
QLocale::Sanskrit,
EOL
};
-static const QLocale::Language slovakLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL };
+static const QLocale::Language slovakStyleLanguages[] = { QLocale::Slovak, QLocale::Czech, EOL };
static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL };
static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL };
static const QLocale::Language russianStyleLanguages[] = {
@@ -318,28 +318,45 @@ struct NumerusTableEntry {
const char * const *forms;
const QLocale::Language *languages;
const QLocale::Country *countries;
+ const char * const gettextRules;
};
static const NumerusTableEntry numerusTable[] = {
- { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0 },
- { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0 },
+ { 0, 0, japaneseStyleForms, japaneseStyleLanguages, 0, "nplurals=1; plural=0;" },
+ { englishStyleRules, sizeof(englishStyleRules), englishStyleForms, englishStyleLanguages, 0,
+ "nplurals=2; plural=(n != 1);" },
{ frenchStyleRules, sizeof(frenchStyleRules), frenchStyleForms, frenchStyleLanguages,
- frenchStyleCountries },
- { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0 },
- { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0 },
- { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0 },
- { slovakRules, sizeof(slovakRules), slovakForms, slovakLanguages, 0 },
- { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0 },
- { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0 },
- { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0 },
- { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0 },
- { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0 },
- { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0 },
- { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0 },
- { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0 },
- { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0 },
- { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0 },
- { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0 }
+ frenchStyleCountries, "nplurals=2; plural=(n > 1);" },
+ { latvianRules, sizeof(latvianRules), latvianForms, latvianLanguage, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);" },
+ { icelandicRules, sizeof(icelandicRules), icelandicForms, icelandicLanguage, 0,
+ "nplurals=2; plural=(n%10==1 && n%100!=11 ? 0 : 1);" },
+ { irishStyleRules, sizeof(irishStyleRules), irishStyleForms, irishStyleLanguages, 0,
+ "nplurals=3; plural=(n==1 ? 0 : n==2 ? 1 : 2);" },
+ { slovakStyleRules, sizeof(slovakStyleRules), slovakStyleForms, slovakStyleLanguages, 0,
+ "nplurals=3; plural=((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2);" },
+ { macedonianRules, sizeof(macedonianRules), macedonianForms, macedonianLanguage, 0,
+ "nplurals=3; plural=(n%100==1 ? 0 : n%100==2 ? 1 : 2);" },
+ { lithuanianRules, sizeof(lithuanianRules), lithuanianForms, lithuanianLanguage, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { russianStyleRules, sizeof(russianStyleRules), russianStyleForms, russianStyleLanguages, 0,
+ "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { polishRules, sizeof(polishRules), polishForms, polishLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" },
+ { romanianRules, sizeof(romanianRules), romanianForms, romanianLanguages, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2);" },
+ { slovenianRules, sizeof(slovenianRules), slovenianForms, slovenianLanguage, 0,
+ "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);" },
+ { malteseRules, sizeof(malteseRules), malteseForms, malteseLanguage, 0,
+ "nplurals=4; plural=(n==1 ? 0 : (n==0 || (n%100>=1 && n%100<=10)) ? 1 : (n%100>=11 && n%100<=19) ? 2 : 3);" },
+ { welshRules, sizeof(welshRules), welshForms, welshLanguage, 0,
+ "nplurals=5; plural=(n==0 ? 0 : n==1 ? 1 : (n>=2 && n<=5) ? 2 : n==6 ? 3 : 4);" },
+ { arabicRules, sizeof(arabicRules), arabicForms, arabicLanguage, 0,
+ "nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : (n%100>=3 && n%100<=10) ? 3 : n%100>=11 ? 4 : 5);" },
+ { tagalogRules, sizeof(tagalogRules), tagalogForms, tagalogLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n%10==4 || n%10==6 || n%10== 9) ? 1 : 2);" },
+ { catalanRules, sizeof(catalanRules), catalanForms, catalanLanguage, 0,
+ "nplurals=3; plural=(n==1 ? 0 : (n==11 || n/1000==11 || n/1000000==11 || n/1000000000==11) ? 1 : 2);" },
};
static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]);
@@ -352,7 +369,7 @@ static const uchar magic[MagicLength] = {
};
bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
- QByteArray *rules, QStringList *forms)
+ QByteArray *rules, QStringList *forms, const char **gettextRules)
{
while (true) {
for (int i = 0; i < NumerusTableSize; ++i) {
@@ -365,6 +382,8 @@ bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
*rules = QByteArray::fromRawData(reinterpret_cast<const char *>(entry.rules),
entry.rulesSize);
}
+ if (gettextRules)
+ *gettextRules = entry.gettextRules;
if (forms) {
forms->clear();
for (int k = 0; entry.forms[k]; ++k)
diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp
index 3354d61..3fd05ee 100644
--- a/tools/linguist/shared/po.cpp
+++ b/tools/linguist/shared/po.cpp
@@ -45,12 +45,11 @@
#include <QtCore/QIODevice>
#include <QtCore/QHash>
#include <QtCore/QString>
+#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
#include <ctype.h>
-#define MAGIC_OBSOLETE_REFERENCE "Obsolete_PO_entries"
-
// Uncomment if you wish to hard wrap long lines in .po files. Note that this
// affects only msg strings, not comments.
//#define HARD_WRAP_LONG_WORDS
@@ -201,55 +200,54 @@ public:
public:
- QString id;
- QString context;
- QString tscomment;
- QString oldTscomment;
- QString lineNumber;
- QString fileName;
- QString references;
- QString translatorComments;
- QString automaticComments;
- QString msgId;
- QString oldMsgId;
- QStringList msgStr;
+ QByteArray id;
+ QByteArray context;
+ QByteArray tscomment;
+ QByteArray oldTscomment;
+ QByteArray lineNumber;
+ QByteArray fileName;
+ QByteArray references;
+ QByteArray translatorComments;
+ QByteArray automaticComments;
+ QByteArray msgId;
+ QByteArray oldMsgId;
+ QList<QByteArray> msgStr;
bool isPlural;
bool isFuzzy;
QHash<QString, QString> extra;
};
-static bool isTranslationLine(const QString &line)
+static bool isTranslationLine(const QByteArray &line)
{
- return line.startsWith(QLatin1String("#~ msgstr"))
- || line.startsWith(QLatin1String("msgstr"));
+ return line.startsWith("#~ msgstr") || line.startsWith("msgstr");
}
-static QString slurpEscapedString(const QStringList &lines, int & l,
- int offset, const QString &prefix, ConversionData &cd)
+static QByteArray slurpEscapedString(const QList<QByteArray> &lines, int &l,
+ int offset, const QByteArray &prefix, ConversionData &cd)
{
- QString msg;
+ QByteArray msg;
int stoff;
for (; l < lines.size(); ++l) {
- const QString &line = lines.at(l);
+ const QByteArray &line = lines.at(l);
if (line.isEmpty() || !line.startsWith(prefix))
break;
- while (line[offset].isSpace()) // No length check, as string has no trailing spaces.
+ while (isspace(line[offset])) // No length check, as string has no trailing spaces.
offset++;
- if (line[offset].unicode() != '"')
+ if (line[offset] != '"')
break;
offset++;
forever {
if (offset == line.length())
goto premature_eol;
- ushort c = line[offset++].unicode();
+ uchar c = line[offset++];
if (c == '"') {
if (offset == line.length())
break;
- while (line[offset].isSpace())
+ while (isspace(line[offset]))
offset++;
- if (line[offset++].unicode() != '"') {
+ if (line[offset++] != '"') {
cd.appendError(QString::fromLatin1(
"PO parsing error: extra characters on line %1.")
.arg(l + 1));
@@ -260,34 +258,34 @@ static QString slurpEscapedString(const QStringList &lines, int & l,
if (c == '\\') {
if (offset == line.length())
goto premature_eol;
- c = line[offset++].unicode();
+ c = line[offset++];
switch (c) {
case 'r':
- msg += QLatin1Char('\r'); // Maybe just throw it away?
+ msg += '\r'; // Maybe just throw it away?
break;
case 'n':
- msg += QLatin1Char('\n');
+ msg += '\n';
break;
case 't':
- msg += QLatin1Char('\t');
+ msg += '\t';
break;
case 'v':
- msg += QLatin1Char('\v');
+ msg += '\v';
break;
case 'a':
- msg += QLatin1Char('\a');
+ msg += '\a';
break;
case 'b':
- msg += QLatin1Char('\b');
+ msg += '\b';
break;
case 'f':
- msg += QLatin1Char('\f');
+ msg += '\f';
break;
case '"':
- msg += QLatin1Char('"');
+ msg += '"';
break;
case '\\':
- msg += QLatin1Char('\\');
+ msg += '\\';
break;
case '0':
case '1':
@@ -298,28 +296,28 @@ static QString slurpEscapedString(const QStringList &lines, int & l,
case '6':
case '7':
stoff = offset - 1;
- while ((c = line[offset].unicode()) >= '0' && c <= '7')
+ while ((c = line[offset]) >= '0' && c <= '7')
if (++offset == line.length())
goto premature_eol;
- msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 8));
+ msg += line.mid(stoff, offset - stoff).toUInt(0, 8);
break;
case 'x':
stoff = offset;
- while (isxdigit(line[offset].unicode()))
+ while (isxdigit(line[offset]))
if (++offset == line.length())
goto premature_eol;
- msg += QChar(line.mid(stoff, offset - stoff).toUInt(0, 16));
+ msg += line.mid(stoff, offset - stoff).toUInt(0, 16);
break;
default:
cd.appendError(QString::fromLatin1(
"PO parsing error: invalid escape '\\%1' (line %2).")
- .arg(QChar(c)).arg(l + 1));
- msg += QLatin1Char('\\');
- msg += QChar(c);
+ .arg(QChar((uint)c)).arg(l + 1));
+ msg += '\\';
+ msg += c;
break;
}
} else {
- msg += QChar(c);
+ msg += c;
}
}
offset = prefix.size();
@@ -330,36 +328,84 @@ static QString slurpEscapedString(const QStringList &lines, int & l,
premature_eol:
cd.appendError(QString::fromLatin1(
"PO parsing error: premature end of line %1.").arg(l + 1));
- return QString();
+ return QByteArray();
}
-static void slurpComment(QString &msg, const QStringList &lines, int & l)
+static void slurpComment(QByteArray &msg, const QList<QByteArray> &lines, int & l)
{
- const QChar newline = QLatin1Char('\n');
- QString prefix = lines.at(l);
+ QByteArray prefix = lines.at(l);
for (int i = 1; ; i++) {
- if (prefix.at(i).unicode() != ' ') {
+ if (prefix.at(i) != ' ') {
prefix.truncate(i);
break;
}
}
for (; l < lines.size(); ++l) {
- const QString &line = lines.at(l);
+ const QByteArray &line = lines.at(l);
if (line.startsWith(prefix))
msg += line.mid(prefix.size());
- else if (line != QLatin1String("#"))
+ else if (line != "#")
break;
- msg += newline;
+ msg += '\n';
}
--l;
}
+static void splitContext(QByteArray *comment, QByteArray *context)
+{
+ char *data = comment->data();
+ int len = comment->size();
+ int sep = -1, j = 0;
+
+ for (int i = 0; i < len; i++, j++) {
+ if (data[i] == '~' && i + 1 < len)
+ i++;
+ else if (data[i] == '|')
+ sep = j;
+ data[j] = data[i];
+ }
+ if (sep >= 0) {
+ QByteArray tmp = comment->mid(sep + 1, j - sep - 1);
+ comment->truncate(sep);
+ *context = *comment;
+ *comment = tmp;
+ } else {
+ comment->truncate(j);
+ }
+}
+
+static QString makePoHeader(const QString &str)
+{
+ return QLatin1String("po-header-") + str.toLower().replace(QLatin1Char('-'), QLatin1Char('_'));
+}
+
+static QByteArray QByteArrayList_join(const QList<QByteArray> &that, char sep)
+{
+ int totalLength = 0;
+ const int size = that.size();
+
+ for (int i = 0; i < size; ++i)
+ totalLength += that.at(i).size();
+
+ if (size > 0)
+ totalLength += size - 1;
+
+ QByteArray res;
+ if (totalLength == 0)
+ return res;
+ res.reserve(totalLength);
+ for (int i = 0; i < that.size(); ++i) {
+ if (i)
+ res += sep;
+ res += that.at(i);
+ }
+ return res;
+}
+
bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
{
- const QChar quote = QLatin1Char('"');
- const QChar newline = QLatin1Char('\n');
- QTextStream in(&dev);
- in.setCodec(cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource);
+ QTextCodec *codec = QTextCodec::codecForName(
+ cd.m_codecForSource.isEmpty() ? QByteArray("UTF-8") : cd.m_codecForSource);
bool error = false;
// format of a .po file entry:
@@ -380,25 +426,24 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
// ...
// we need line based lookahead below.
- QStringList lines;
- while (!in.atEnd())
- lines.append(in.readLine().trimmed());
- lines.append(QString());
+ QList<QByteArray> lines;
+ while (!dev.atEnd())
+ lines.append(dev.readLine().trimmed());
+ lines.append(QByteArray());
- int l = 0;
+ int l = 0, lastCmtLine = -1;
+ bool qtContexts = false;
PoItem item;
for (; l != lines.size(); ++l) {
- QString line = lines.at(l);
+ QByteArray line = lines.at(l);
if (line.isEmpty())
continue;
if (isTranslationLine(line)) {
- bool isObsolete = line.startsWith(QLatin1String("#~ msgstr"));
- const QString prefix = QLatin1String(isObsolete ? "#~ " : "");
+ bool isObsolete = line.startsWith("#~ msgstr");
+ const QByteArray prefix = isObsolete ? "#~ " : "";
while (true) {
- int idx = line.indexOf(QLatin1Char(' '), prefix.length());
- QString str = slurpEscapedString(lines, l, idx, prefix, cd);
- str.replace(QChar(Translator::TextVariantSeparator),
- QChar(Translator::BinaryVariantSeparator));
+ int idx = line.indexOf(' ', prefix.length());
+ QByteArray str = slurpEscapedString(lines, l, idx, prefix, cd);
item.msgStr.append(str);
if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1)))
break;
@@ -406,50 +451,148 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
line = lines.at(l);
}
if (item.msgId.isEmpty()) {
- QRegExp rx(QLatin1String("\\bX-Language: ([^\n]*)\n"));
- int idx = rx.indexIn(item.msgStr.first());
- if (idx >= 0) {
- translator.setLanguageCode(rx.cap(1));
- item.msgStr.first().remove(idx, rx.matchedLength());
+ QHash<QString, QByteArray> extras;
+ QList<QByteArray> hdrOrder;
+ QByteArray pluralForms;
+ foreach (const QByteArray &hdr, item.msgStr.first().split('\n')) {
+ if (hdr.isEmpty())
+ continue;
+ int idx = hdr.indexOf(':');
+ if (idx < 0) {
+ cd.appendError(QString::fromLatin1("Unexpected PO header format '%1'")
+ .arg(QString::fromLatin1(hdr)));
+ error = true;
+ break;
+ }
+ QByteArray hdrName = hdr.left(idx).trimmed();
+ QByteArray hdrValue = hdr.mid(idx + 1).trimmed();
+ hdrOrder << hdrName;
+ if (hdrName == "X-Language") {
+ translator.setLanguageCode(QString::fromLatin1(hdrValue));
+ } else if (hdrName == "X-Source-Language") {
+ translator.setSourceLanguageCode(QString::fromLatin1(hdrValue));
+ } else if (hdrName == "X-Qt-Contexts") {
+ qtContexts = (hdrValue == "true");
+ } else if (hdrName == "Plural-Forms") {
+ pluralForms = hdrValue;
+ } else if (hdrName == "MIME-Version") {
+ // just assume it is 1.0
+ } else if (hdrName == "Content-Type") {
+ if (cd.m_codecForSource.isEmpty()) {
+ if (!hdrValue.startsWith("text/plain; charset=")) {
+ cd.appendError(QString::fromLatin1("Unexpected Content-Type header '%1'")
+ .arg(QString::fromLatin1(hdrValue)));
+ error = true;
+ // This will avoid a flood of conversion errors.
+ codec = QTextCodec::codecForName("latin1");
+ } else {
+ QByteArray cod = hdrValue.mid(20);
+ QTextCodec *cdc = QTextCodec::codecForName(cod);
+ if (!cdc) {
+ cd.appendError(QString::fromLatin1("Unsupported codec '%1'")
+ .arg(QString::fromLatin1(cod)));
+ error = true;
+ // This will avoid a flood of conversion errors.
+ codec = QTextCodec::codecForName("latin1");
+ } else {
+ codec = cdc;
+ }
+ }
+ }
+ } else if (hdrName == "Content-Transfer-Encoding") {
+ if (hdrValue != "8bit") {
+ cd.appendError(QString::fromLatin1("Unexpected Content-Transfer-Encoding '%1'")
+ .arg(QString::fromLatin1(hdrValue)));
+ return false;
+ }
+ } else if (hdrName == "X-Virgin-Header") {
+ // legacy
+ } else {
+ extras[makePoHeader(QString::fromLatin1(hdrName))] = hdrValue;
+ }
}
- QRegExp rx2(QLatin1String("\\bX-Source-Language: ([^\n]*)\n"));
- int idx2 = rx2.indexIn(item.msgStr.first());
- if (idx2 >= 0) {
- translator.setSourceLanguageCode(rx2.cap(1));
- item.msgStr.first().remove(idx2, rx2.matchedLength());
+ if (!pluralForms.isEmpty()) {
+ if (translator.languageCode().isEmpty()) {
+ extras[makePoHeader(QLatin1String("Plural-Forms"))] = pluralForms;
+ } else {
+ // FIXME: have fun with making a consistency check ...
+ }
}
- if (item.msgStr.first().indexOf(
- QRegExp(QLatin1String("\\bX-Virgin-Header:[^\n]*\n"))) >= 0) {
- item = PoItem();
- continue;
+ // Eliminate the field if only headers we added are present in standard order.
+ // Keep in sync with savePO
+ static const char * const dfltHdrs[] = {
+ "MIME-Version", "Content-Type", "Content-Transfer-Encoding",
+ "Plural-Forms", "X-Language", "X-Source-Language", "X-Qt-Contexts"
+ };
+ uint cdh = 0;
+ for (int cho = 0; cho < hdrOrder.length(); cho++) {
+ for (;; cdh++) {
+ if (cdh == sizeof(dfltHdrs)/sizeof(dfltHdrs[0])) {
+ extras[QLatin1String("po-headers")] =
+ QByteArrayList_join(hdrOrder, ',');
+ goto doneho;
+ }
+ if (hdrOrder.at(cho) == dfltHdrs[cdh]) {
+ cdh++;
+ break;
+ }
+ }
}
+ doneho:
+ if (lastCmtLine != -1)
+ extras[QLatin1String("po-header_comment")] =
+ QByteArrayList_join(lines.mid(0, lastCmtLine + 1), '\n');
+ for (QHash<QString, QByteArray>::ConstIterator it = extras.constBegin(),
+ end = extras.constEnd();
+ it != end; ++it)
+ translator.setExtra(it.key(), codec->toUnicode(it.value()));
+ item = PoItem();
+ continue;
}
// build translator message
TranslatorMessage msg;
- msg.setContext(item.context);
+ msg.setContext(codec->toUnicode(item.context));
if (!item.references.isEmpty()) {
+ QString xrefs;
foreach (const QString &ref,
- item.references.split(QRegExp(QLatin1String("\\s")),
- QString::SkipEmptyParts)) {
- int pos = ref.lastIndexOf(QLatin1Char(':'));
- if (pos != -1)
- msg.addReference(ref.left(pos), ref.mid(pos + 1).toInt());
+ codec->toUnicode(item.references).split(
+ QRegExp(QLatin1String("\\s")), QString::SkipEmptyParts)) {
+ int pos = ref.indexOf(QLatin1Char(':'));
+ int lpos = ref.lastIndexOf(QLatin1Char(':'));
+ if (pos != -1 && pos == lpos) {
+ bool ok;
+ int lno = ref.mid(pos + 1).toInt(&ok);
+ if (ok) {
+ msg.addReference(ref.left(pos), lno);
+ continue;
+ }
+ }
+ if (!xrefs.isEmpty())
+ xrefs += QLatin1Char(' ');
+ xrefs += ref;
}
- } else if (isObsolete) {
- msg.setFileName(QLatin1String(MAGIC_OBSOLETE_REFERENCE));
+ if (!xrefs.isEmpty())
+ item.extra[QLatin1String("po-references")] = xrefs;
}
- msg.setId(item.id);
- msg.setSourceText(item.msgId);
- msg.setOldSourceText(item.oldMsgId);
- msg.setComment(item.tscomment);
- msg.setOldComment(item.oldTscomment);
- msg.setExtraComment(item.automaticComments);
- msg.setTranslatorComment(item.translatorComments);
+ msg.setId(codec->toUnicode(item.id));
+ msg.setSourceText(codec->toUnicode(item.msgId));
+ msg.setOldSourceText(codec->toUnicode(item.oldMsgId));
+ msg.setComment(codec->toUnicode(item.tscomment));
+ msg.setOldComment(codec->toUnicode(item.oldTscomment));
+ msg.setExtraComment(codec->toUnicode(item.automaticComments));
+ msg.setTranslatorComment(codec->toUnicode(item.translatorComments));
msg.setPlural(item.isPlural || item.msgStr.size() > 1);
- msg.setTranslations(item.msgStr);
+ QStringList translations;
+ foreach (const QByteArray &bstr, item.msgStr) {
+ QString str = codec->toUnicode(bstr);
+ str.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
+ translations << str;
+ }
+ msg.setTranslations(translations);
if (isObsolete)
msg.setType(TranslatorMessage::Obsolete);
- else if (item.isFuzzy)
+ else if (item.isFuzzy || (!msg.sourceText().isEmpty() && !msg.isTranslated()))
msg.setType(TranslatorMessage::Unfinished);
else
msg.setType(TranslatorMessage::Finished);
@@ -460,18 +603,19 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
//qDebug() << flags << msg.m_extra;
translator.append(msg);
item = PoItem();
- } else if (line.startsWith(QLatin1Char('#'))) {
- switch(line.size() < 2 ? 0 : line.at(1).unicode()) {
+ } else if (line.startsWith('#')) {
+ switch (line.size() < 2 ? 0 : line.at(1)) {
case ':':
item.references += line.mid(3);
- item.references += newline;
+ item.references += '\n';
break;
case ',': {
QStringList flags =
- line.mid(2).split(QRegExp(QLatin1String("[, ]")),
- QString::SkipEmptyParts);
+ QString::fromLatin1(line.mid(2)).split(
+ QRegExp(QLatin1String("[, ]")), QString::SkipEmptyParts);
if (flags.removeOne(QLatin1String("fuzzy")))
item.isFuzzy = true;
+ flags.removeOne(QLatin1String("qt-format"));
TranslatorMessage::ExtraData::const_iterator it =
item.extra.find(QLatin1String("po-flags"));
if (it != item.extra.end())
@@ -481,103 +625,155 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
break;
}
case 0:
- item.translatorComments += newline;
+ item.translatorComments += '\n';
break;
case ' ':
slurpComment(item.translatorComments, lines, l);
break;
case '.':
- if (line.startsWith(QLatin1String("#. ts-context "))) {
+ if (line.startsWith("#. ts-context ")) { // legacy
item.context = line.mid(14);
- } else if (line.startsWith(QLatin1String("#. ts-id "))) {
+ } else if (line.startsWith("#. ts-id ")) {
item.id = line.mid(9);
} else {
item.automaticComments += line.mid(3);
- item.automaticComments += newline;
+ item.automaticComments += '\n';
}
break;
case '|':
- if (line.startsWith(QLatin1String("#| msgid "))) {
- item.oldMsgId = slurpEscapedString(lines, l, 9, QLatin1String("#| "), cd);
- } else if (line.startsWith(QLatin1String("#| msgid_plural "))) {
- QString extra = slurpEscapedString(lines, l, 16, QLatin1String("#| "), cd);
+ if (line.startsWith("#| msgid ")) {
+ item.oldMsgId = slurpEscapedString(lines, l, 9, "#| ", cd);
+ } else if (line.startsWith("#| msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 16, "#| ", cd);
if (extra != item.oldMsgId)
- item.extra[QLatin1String("po-old_msgid_plural")] = extra;
- } else if (line.startsWith(QLatin1String("#| msgctxt "))) {
- item.oldTscomment = slurpEscapedString(lines, l, 11, QLatin1String("#| "), cd);
+ item.extra[QLatin1String("po-old_msgid_plural")] =
+ codec->toUnicode(extra);
+ } else if (line.startsWith("#| msgctxt ")) {
+ item.oldTscomment = slurpEscapedString(lines, l, 11, "#| ", cd);
+ if (qtContexts)
+ splitContext(&item.oldTscomment, &item.context);
} else {
- cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n"))
- .arg(l + 1).arg(lines[l]));
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
error = true;
}
break;
case '~':
- if (line.startsWith(QLatin1String("#~ msgid "))) {
- item.msgId = slurpEscapedString(lines, l, 9, QLatin1String("#~ "), cd);
- } else if (line.startsWith(QLatin1String("#~ msgid_plural "))) {
- QString extra = slurpEscapedString(lines, l, 16, QLatin1String("#~ "), cd);
+ if (line.startsWith("#~ msgid ")) {
+ item.msgId = slurpEscapedString(lines, l, 9, "#~ ", cd);
+ } else if (line.startsWith("#~ msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 16, "#~ ", cd);
if (extra != item.msgId)
- item.extra[QLatin1String("po-msgid_plural")] = extra;
+ item.extra[QLatin1String("po-msgid_plural")] =
+ codec->toUnicode(extra);
item.isPlural = true;
- } else if (line.startsWith(QLatin1String("#~ msgctxt "))) {
- item.tscomment = slurpEscapedString(lines, l, 11, QLatin1String("#~ "), cd);
+ } else if (line.startsWith("#~ msgctxt ")) {
+ item.tscomment = slurpEscapedString(lines, l, 11, "#~ ", cd);
+ if (qtContexts)
+ splitContext(&item.tscomment, &item.context);
} else {
- cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n"))
- .arg(l + 1).arg(lines[l]));
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
error = true;
}
break;
default:
- cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'\n"))
- .arg(l + 1).arg(lines[l]));
+ cd.appendError(QString(QLatin1String("PO-format parse error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
error = true;
break;
}
- } else if (line.startsWith(QLatin1String("msgctxt "))) {
- item.tscomment = slurpEscapedString(lines, l, 8, QString(), cd);
- } else if (line.startsWith(QLatin1String("msgid "))) {
- item.msgId = slurpEscapedString(lines, l, 6, QString(), cd);
- } else if (line.startsWith(QLatin1String("msgid_plural "))) {
- QString extra = slurpEscapedString(lines, l, 13, QString(), cd);
+ lastCmtLine = l;
+ } else if (line.startsWith("msgctxt ")) {
+ item.tscomment = slurpEscapedString(lines, l, 8, QByteArray(), cd);
+ if (qtContexts)
+ splitContext(&item.tscomment, &item.context);
+ } else if (line.startsWith("msgid ")) {
+ item.msgId = slurpEscapedString(lines, l, 6, QByteArray(), cd);
+ } else if (line.startsWith("msgid_plural ")) {
+ QByteArray extra = slurpEscapedString(lines, l, 13, QByteArray(), cd);
if (extra != item.msgId)
- item.extra[QLatin1String("po-msgid_plural")] = extra;
+ item.extra[QLatin1String("po-msgid_plural")] = codec->toUnicode(extra);
item.isPlural = true;
} else {
- cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'\n"))
- .arg(l + 1).arg(lines[l]));
+ cd.appendError(QString(QLatin1String("PO-format error in line %1: '%2'"))
+ .arg(l + 1).arg(codec->toUnicode(lines[l])));
error = true;
}
}
return !error && cd.errors().isEmpty();
}
+static void addPoHeader(Translator::ExtraData &headers, QStringList &hdrOrder,
+ const char *name, const QString &value)
+{
+ QString qName = QLatin1String(name);
+ if (!hdrOrder.contains(qName))
+ hdrOrder << qName;
+ headers[makePoHeader(qName)] = value;
+}
+
+static QString escapeComment(const QString &in, bool escape)
+{
+ QString out = in;
+ if (escape) {
+ out.replace(QLatin1Char('~'), QLatin1String("~~"));
+ out.replace(QLatin1Char('|'), QLatin1String("~|"));
+ }
+ return out;
+}
+
bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
{
+ QString str_format = QLatin1String("-format");
+
bool ok = true;
QTextStream out(&dev);
out.setCodec(cd.m_outputCodec.isEmpty() ? QByteArray("UTF-8") : cd.m_outputCodec);
- bool first = true;
- if (translator.messages().isEmpty() || !translator.messages().first().sourceText().isEmpty()) {
- out <<
- "# SOME DESCRIPTIVE TITLE.\n"
- "# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n"
- "# This file is distributed under the same license as the PACKAGE package.\n"
- "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"
- "#\n"
- "#, fuzzy\n"
- "msgid \"\"\n"
- "msgstr \"\"\n"
- "\"X-Virgin-Header: remove this line if you change anything in the header.\\n\"\n";
- if (!translator.languageCode().isEmpty())
- out << "\"X-Language: " << translator.languageCode() << "\\n\"\n";
- if (!translator.sourceLanguageCode().isEmpty())
- out << "\"X-Source-Language: " << translator.sourceLanguageCode() << "\\n\"\n";
- first = false;
+ bool qtContexts = false;
+ foreach (const TranslatorMessage &msg, translator.messages())
+ if (!msg.context().isEmpty()) {
+ qtContexts = true;
+ break;
+ }
+
+ QString cmt = translator.extra(QLatin1String("po-header_comment"));
+ if (!cmt.isEmpty())
+ out << cmt << '\n';
+ out << "msgid \"\"\n";
+ Translator::ExtraData headers = translator.extras();
+ QStringList hdrOrder = translator.extra(QLatin1String("po-headers")).split(
+ QLatin1Char(','), QString::SkipEmptyParts);
+ // Keep in sync with loadPO
+ addPoHeader(headers, hdrOrder, "MIME-Version", QLatin1String("1.0"));
+ addPoHeader(headers, hdrOrder, "Content-Type",
+ QLatin1String("text/plain; charset=" + out.codec()->name()));
+ addPoHeader(headers, hdrOrder, "Content-Transfer-Encoding", QLatin1String("8bit"));
+ if (!translator.languageCode().isEmpty()) {
+ QLocale::Language l;
+ QLocale::Country c;
+ Translator::languageAndCountry(translator.languageCode(), &l, &c);
+ const char *gettextRules;
+ if (getNumerusInfo(l, c, 0, 0, &gettextRules))
+ addPoHeader(headers, hdrOrder, "Plural-Forms", QLatin1String(gettextRules));
+ addPoHeader(headers, hdrOrder, "X-Language", translator.languageCode());
+ }
+ if (!translator.sourceLanguageCode().isEmpty())
+ addPoHeader(headers, hdrOrder, "X-Source-Language", translator.sourceLanguageCode());
+ if (qtContexts)
+ addPoHeader(headers, hdrOrder, "X-Qt-Contexts", QLatin1String("true"));
+ QString hdrStr;
+ foreach (const QString &hdr, hdrOrder) {
+ hdrStr += hdr;
+ hdrStr += QLatin1String(": ");
+ hdrStr += headers.value(makePoHeader(hdr));
+ hdrStr += QLatin1Char('\n');
}
+ out << poEscapedString(QString(), QString::fromLatin1("msgstr"), true, hdrStr);
+
foreach (const TranslatorMessage &msg, translator.messages()) {
- if (!first)
- out << endl;
+ out << endl;
if (!msg.translatorComment().isEmpty())
out << poEscapedLines(QLatin1String("#"), true, msg.translatorComment());
@@ -585,52 +781,76 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
if (!msg.extraComment().isEmpty())
out << poEscapedLines(QLatin1String("#."), true, msg.extraComment());
- if (!msg.context().isEmpty())
- out << QLatin1String("#. ts-context ") << msg.context() << '\n';
if (!msg.id().isEmpty())
out << QLatin1String("#. ts-id ") << msg.id() << '\n';
- if (!msg.fileName().isEmpty() && msg.fileName() != QLatin1String(MAGIC_OBSOLETE_REFERENCE)) {
+ QString xrefs = msg.extra(QLatin1String("po-references"));
+ if (!msg.fileName().isEmpty() || !xrefs.isEmpty()) {
QStringList refs;
foreach (const TranslatorMessage::Reference &ref, msg.allReferences())
refs.append(QString(QLatin1String("%2:%1"))
.arg(ref.lineNumber()).arg(ref.fileName()));
+ if (!xrefs.isEmpty())
+ refs << xrefs;
out << poWrappedEscapedLines(QLatin1String("#:"), true, refs.join(QLatin1String(" ")));
}
bool noWrap = false;
+ bool skipFormat = false;
QStringList flags;
- if (msg.type() == TranslatorMessage::Unfinished)
+ if (msg.type() == TranslatorMessage::Unfinished && msg.isTranslated())
flags.append(QLatin1String("fuzzy"));
TranslatorMessage::ExtraData::const_iterator itr =
msg.extras().find(QLatin1String("po-flags"));
if (itr != msg.extras().end()) {
- if (itr->split(QLatin1String(", ")).contains(QLatin1String("no-wrap")))
+ QStringList atoms = itr->split(QLatin1String(", "));
+ foreach (const QString &atom, atoms)
+ if (atom.endsWith(str_format)) {
+ skipFormat = true;
+ break;
+ }
+ if (atoms.contains(QLatin1String("no-wrap")))
noWrap = true;
flags.append(*itr);
}
+ if (!skipFormat) {
+ QString source = msg.sourceText();
+ // This is fuzzy logic, as we don't know whether the string is
+ // actually used with QString::arg().
+ for (int off = 0; (off = source.indexOf(QLatin1Char('%'), off)) >= 0; ) {
+ if (++off >= source.length())
+ break;
+ if (source.at(off) == QLatin1Char('n') || source.at(off).isDigit()) {
+ flags.append(QLatin1String("qt-format"));
+ break;
+ }
+ }
+ }
if (!flags.isEmpty())
out << "#, " << flags.join(QLatin1String(", ")) << '\n';
QString prefix = QLatin1String("#| ");
if (!msg.oldComment().isEmpty())
- out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, msg.oldComment());
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.oldComment(), qtContexts));
if (!msg.oldSourceText().isEmpty())
out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.oldSourceText());
QString plural = msg.extra(QLatin1String("po-old_msgid_plural"));
if (!plural.isEmpty())
out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
prefix = QLatin1String((msg.type() == TranslatorMessage::Obsolete) ? "#~ " : "");
- if (!msg.comment().isEmpty())
- out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap, msg.comment());
+ if (!msg.context().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.context(), true) + QLatin1Char('|')
+ + escapeComment(msg.comment(), true));
+ else if (!msg.comment().isEmpty())
+ out << poEscapedString(prefix, QLatin1String("msgctxt"), noWrap,
+ escapeComment(msg.comment(), qtContexts));
out << poEscapedString(prefix, QLatin1String("msgid"), noWrap, msg.sourceText());
if (!msg.isPlural()) {
QString transl = msg.translation();
- if (first) {
- transl.remove(QRegExp(QLatin1String("\\bX-Language:[^\n]*\n")));
- if (!translator.languageCode().isEmpty())
- transl += QLatin1String("X-Language: ") + translator.languageCode() + QLatin1Char('\n');
- }
+ transl.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
out << poEscapedString(prefix, QLatin1String("msgstr"), noWrap, transl);
} else {
QString plural = msg.extra(QLatin1String("po-msgid_plural"));
@@ -646,11 +866,17 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
str);
}
}
- first = false;
}
return ok;
}
+static bool savePOT(const Translator &translator, QIODevice &dev, ConversionData &cd)
+{
+ Translator ttor = translator;
+ ttor.dropTranslations();
+ return savePO(ttor, dev, cd);
+}
+
int initPO()
{
Translator::FileFormat format;
@@ -661,6 +887,13 @@ int initPO()
format.fileType = Translator::FileFormat::TranslationSource;
format.priority = 1;
Translator::registerFileFormat(format);
+ format.extension = QLatin1String("pot");
+ format.description = QObject::tr("GNU Gettext localization template files");
+ format.loader = &loadPO;
+ format.saver = &savePOT;
+ format.fileType = Translator::FileFormat::TranslationSource;
+ format.priority = -1;
+ Translator::registerFileFormat(format);
return 1;
}
diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp
index 5e1ee1f..a21408c 100644
--- a/tools/linguist/shared/profileevaluator.cpp
+++ b/tools/linguist/shared/profileevaluator.cpp
@@ -2594,19 +2594,19 @@ void ProFileEvaluator::addProperties(const QHash<QString, QString> &properties)
void ProFileEvaluator::logMessage(const QString &message)
{
if (d->m_verbose && !d->m_skipLevel)
- qWarning("%s", qPrintable(message));
+ fprintf(stderr, "%s\n", qPrintable(message));
}
void ProFileEvaluator::fileMessage(const QString &message)
{
if (!d->m_skipLevel)
- qWarning("%s", qPrintable(message));
+ fprintf(stderr, "%s\n", qPrintable(message));
}
void ProFileEvaluator::errorMessage(const QString &message)
{
if (!d->m_skipLevel)
- qWarning("%s", qPrintable(message));
+ fprintf(stderr, "%s\n", qPrintable(message));
}
void ProFileEvaluator::setVerbose(bool on)
diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp
index de1284f..6678943 100644
--- a/tools/linguist/shared/qm.cpp
+++ b/tools/linguist/shared/qm.cpp
@@ -564,7 +564,7 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
Translator::languageAndCountry(translator.languageCode(), &l, &c);
QStringList numerusForms;
bool guessPlurals = true;
- if (getNumerusInfo(l, c, 0, &numerusForms))
+ if (getNumerusInfo(l, c, 0, &numerusForms, 0))
guessPlurals = (numerusForms.count() == 1);
QString context, contextUtf8;
@@ -704,7 +704,7 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
QLocale::Country c;
Translator::languageAndCountry(translator.languageCode(), &l, &c);
QByteArray rules;
- if (getNumerusInfo(l, c, &rules, 0))
+ if (getNumerusInfo(l, c, &rules, 0, 0))
releaser.setNumerusRules(rules);
releaser.setCodecName(translator.codecName());
@@ -773,11 +773,11 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
if (saved && cd.isVerbose()) {
int generatedCount = finished + unfinished;
cd.appendError(QCoreApplication::translate("LRelease",
- " Generated %n translation(s) (%1 finished and %2 unfinished)\n", 0,
+ " Generated %n translation(s) (%1 finished and %2 unfinished)", 0,
QCoreApplication::CodecForTr, generatedCount).arg(finished).arg(unfinished));
if (untranslated)
cd.appendError(QCoreApplication::translate("LRelease",
- " Ignored %n untranslated source text(s)\n", 0,
+ " Ignored %n untranslated source text(s)", 0,
QCoreApplication::CodecForTr, untranslated));
}
return saved;
diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp
index 4331ce6..36af8da 100644
--- a/tools/linguist/shared/translator.cpp
+++ b/tools/linguist/shared/translator.cpp
@@ -43,10 +43,17 @@
#include "simtexth.h"
+#include <iostream>
+
#include <stdio.h>
#ifdef Q_OS_WIN
-#include <io.h> // required for _setmode, to avoid _O_TEXT streams...
-#include <fcntl.h> // for _O_BINARY
+// required for _setmode, to avoid _O_TEXT streams...
+# ifdef Q_OS_WINCE
+# include <stdlib.h>
+# else
+# include <io.h> // for _setmode
+# include <fcntl.h> // for _O_BINARY
+# endif
#endif
#include <QtCore/QDebug>
@@ -213,7 +220,11 @@ bool Translator::load(const QString &filename, ConversionData &cd, const QString
if (filename.isEmpty() || filename == QLatin1String("-")) {
#ifdef Q_OS_WIN
// QFile is broken for text files
+# ifdef Q_OS_WINCE
+ ::_setmode(stdin, _O_BINARY);
+# else
::_setmode(0, _O_BINARY);
+# endif
#endif
if (!file.open(stdin, QIODevice::ReadOnly)) {
cd.appendError(QString::fromLatin1("Cannot open stdin!? (%1)")
@@ -253,7 +264,11 @@ bool Translator::save(const QString &filename, ConversionData &cd, const QString
if (filename.isEmpty() || filename == QLatin1String("-")) {
#ifdef Q_OS_WIN
// QFile is broken for text files
+# ifdef Q_OS_WINCE
+ ::_setmode(stdout, _O_BINARY);
+# else
::_setmode(1, _O_BINARY);
+# endif
#endif
if (!file.open(stdout, QIODevice::WriteOnly)) {
cd.appendError(QString::fromLatin1("Cannot open stdout!? (%1)")
@@ -573,22 +588,21 @@ void Translator::reportDuplicates(const Duplicates &dupes,
const QString &fileName, bool verbose)
{
if (!dupes.byId.isEmpty() || !dupes.byContents.isEmpty()) {
+ std::cerr << "Warning: dropping duplicate messages in '" << qPrintable(fileName);
if (!verbose) {
- qWarning("Warning: dropping duplicate messages in '%s'\n(try -verbose for more info).",
- qPrintable(fileName));
+ std::cerr << "'\n(try -verbose for more info).\n";
} else {
- qWarning("Warning: dropping duplicate messages in '%s':", qPrintable(fileName));
+ std::cerr << "':\n";
foreach (int i, dupes.byId)
- qWarning("\n* ID: %s", qPrintable(message(i).id()));
+ std::cerr << "\n* ID: " << qPrintable(message(i).id()) << std::endl;
foreach (int j, dupes.byContents) {
const TranslatorMessage &msg = message(j);
- qWarning("\n* Context: %s\n* Source: %s",
- qPrintable(msg.context()),
- qPrintable(msg.sourceText()));
+ std::cerr << "\n* Context: " << qPrintable(msg.context())
+ << "\n* Source: " << qPrintable(msg.sourceText()) << std::endl;
if (!msg.comment().isEmpty())
- qWarning("* Comment: %s", qPrintable(msg.comment()));
+ std::cerr << "* Comment: " << qPrintable(msg.comment()) << std::endl;
}
- qWarning();
+ std::cerr << std::endl;
}
}
}
@@ -652,7 +666,7 @@ void Translator::normalizeTranslations(ConversionData &cd)
int numPlurals = 1;
if (l != QLocale::C) {
QStringList forms;
- if (getNumerusInfo(l, c, 0, &forms))
+ if (getNumerusInfo(l, c, 0, &forms, 0))
numPlurals = forms.count(); // includes singular
}
for (int i = 0; i < m_messages.count(); ++i) {
@@ -675,7 +689,7 @@ void Translator::normalizeTranslations(ConversionData &cd)
cd.appendError(QLatin1String(
"Removed plural forms as the target language has less "
"forms.\nIf this sounds wrong, possibly the target language is "
- "not set or recognized.\n"));
+ "not set or recognized."));
}
QString Translator::guessLanguageCodeFromFileName(const QString &filename)
@@ -724,7 +738,7 @@ void Translator::setCodecName(const QByteArray &name)
QTextCodec *codec = QTextCodec::codecForName(name);
if (!codec) {
if (!name.isEmpty())
- qWarning("No QTextCodec for %s available. Using Latin1\n", name.constData());
+ std::cerr << "No QTextCodec for " << name.constData() << " available. Using Latin1.\n";
m_codec = QTextCodec::codecForName("ISO-8859-1");
} else {
m_codec = codec;
diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h
index 0b88c07..02cfb07 100644
--- a/tools/linguist/shared/translator.h
+++ b/tools/linguist/shared/translator.h
@@ -92,7 +92,7 @@ public:
bool sortContexts() const { return m_sortContexts; }
void appendError(const QString &error) { m_errors.append(error); }
- QString error() const { return m_errors.join(QLatin1String("\n")); }
+ QString error() const { return m_errors.isEmpty() ? QString() : m_errors.join(QLatin1String("\n")) + QLatin1Char('\n'); }
QStringList errors() const { return m_errors; }
void clearErrors() { m_errors.clear(); }
@@ -123,8 +123,8 @@ class Translator
public:
Translator();
- bool load(const QString &filename, ConversionData &err, const QString &format /*= "auto"*/);
- bool save(const QString &filename, ConversionData &err, const QString &format /*= "auto"*/) const;
+ bool load(const QString &filename, ConversionData &err, const QString &format /* = "auto" */);
+ bool save(const QString &filename, ConversionData &err, const QString &format /* = "auto" */) const;
bool release(QFile *iod, ConversionData &cd) const;
int find(const TranslatorMessage &msg) const;
@@ -233,7 +233,7 @@ private:
};
bool getNumerusInfo(QLocale::Language language, QLocale::Country country,
- QByteArray *rules, QStringList *forms);
+ QByteArray *rules, QStringList *forms, const char **gettextRules);
/*
This is a quick hack. The proper way to handle this would be
diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd
index 4d2cdeb..12d3562 100644
--- a/tools/linguist/shared/ts.dtd
+++ b/tools/linguist/shared/ts.dtd
@@ -4,8 +4,6 @@
!
! The location element is set as optional since it was introduced first in Qt 4.2.
! The userdata element is set as optional since it was introduced first in Qt 4.4.
- ! The source and translation elements are optional starting with version 3.0
- ! (Qt 4.6) to support S60 blank messages.
!
-->
<!--
@@ -36,13 +34,10 @@
language CDATA #IMPLIED>
<!-- The encoding to use in the QM file by default. Default is ISO-8859-1. -->
<!ELEMENT defaultcodec (#PCDATA) >
-<!ELEMENT context (name?, comment?, (context|message)+) >
+<!ELEMENT context (name, comment?, (context|message)+) >
<!ATTLIST context
encoding CDATA #IMPLIED>
<!ELEMENT name %evilstring; >
-<!-- If "no", then the context nesting is for informational puposes only -->
-<!ATTLIST name
- nest (yes|no) "yes">
<!-- This is "disambiguation" in the (new) API, or "msgctxt" in gettext speak -->
<!ELEMENT comment %evilstring; >
<!-- Previous content of comment (result of merge) -->
@@ -53,12 +48,13 @@
<!ELEMENT translatorcomment %evilstring; >
<!ELEMENT message (location*, source?, oldsource?, comment?, oldcomment?, extracomment?, translatorcomment?, translation?, userdata?, extra-**) >
<!--
- ! If utf8 is true, the defaultcodec is overridden and the message is encoded
- ! in UTF-8 in the QM file.
+ ! If utf8 is "true", the defaultcodec is overridden and the message is encoded
+ ! in UTF-8 in the QM file. If it is "both", both source encodings are stored
+ ! in the QM file.
-->
<!ATTLIST message
id CDATA #IMPLIED
- utf8 (true|false) "false"
+ utf8 (true|false|both) "false"
numerus (yes|no) "no">
<!ELEMENT location EMPTY>
<!--
@@ -100,14 +96,5 @@
-->
<!ELEMENT numerusform (#PCDATA|byte|lengthvariant)* >
<!ATTLIST numerusform
- plurality (nullar|singular|dual|trial|paucal|greaterpaucal|plural|greaterplural) #IMPLIED>
variants (yes|no) "no">
<!ELEMENT lengthvariant %evilstring; >
-<!--
- ! The translation variants have a priority between 1 ("highest") and 9 ("lowest")
- ! Typically longer translations get a higher priority.
- ! If omitted, the order of appearance of the variants in the TS files is used.
- -->
-<!ATTLIST lengthvariant
- priority (1|2|3|4|5|6|7|8|9) #IMPLIED>
-
diff --git a/tools/linguist/shared/xliff.cpp b/tools/linguist/shared/xliff.cpp
index 20303ec..70724ef 100644
--- a/tools/linguist/shared/xliff.cpp
+++ b/tools/linguist/shared/xliff.cpp
@@ -53,6 +53,11 @@
#include <QtXml/QXmlParseException>
+// The string value is historical and reflects the main purpose: Keeping
+// obsolete entries separate from the magic file message (which both have
+// no location information, but typically reside at opposite ends of the file).
+#define MAGIC_OBSOLETE_REFERENCE "Obsolete_PO_entries"
+
QT_BEGIN_NAMESPACE
/**
@@ -503,6 +508,8 @@ bool XLIFFHandler::startElement(const QString& namespaceURI,
m_language.replace(QLatin1Char('-'), QLatin1Char('_'));
m_sourceLanguage = atts.value(QLatin1String("source-language"));
m_sourceLanguage.replace(QLatin1Char('-'), QLatin1Char('_'));
+ if (m_sourceLanguage == QLatin1String("en"))
+ m_sourceLanguage.clear();
} else if (localName == QLatin1String("group")) {
if (atts.value(QLatin1String("restype")) == QLatin1String(restypeContext)) {
m_context = atts.value(QLatin1String("resname"));
@@ -690,6 +697,9 @@ bool XLIFFHandler::finalizeMessage(bool isPlural)
m_cd.appendError(QLatin1String("XLIFF syntax error: Message without source string."));
return false;
}
+ if (m_type == TranslatorMessage::Obsolete && m_refs.size() == 1
+ && m_refs.at(0).fileName() == QLatin1String(MAGIC_OBSOLETE_REFERENCE))
+ m_refs.clear();
TranslatorMessage msg(m_context, m_sources[0],
m_comment, QString(), QString(), -1,
m_translations, m_type, isPlural);
@@ -759,12 +769,15 @@ bool saveXLIFF(const Translator &translator, QIODevice &dev, ConversionData &cd)
QHash<QString, QList<QString> > contextOrder;
QList<QString> fileOrder;
foreach (const TranslatorMessage &msg, translator.messages()) {
- QHash<QString, QList<TranslatorMessage> > &file = messageOrder[msg.fileName()];
+ QString fn = msg.fileName();
+ if (fn.isEmpty() && msg.type() == TranslatorMessage::Obsolete)
+ fn = QLatin1String(MAGIC_OBSOLETE_REFERENCE);
+ QHash<QString, QList<TranslatorMessage> > &file = messageOrder[fn];
if (file.isEmpty())
- fileOrder.append(msg.fileName());
+ fileOrder.append(fn);
QList<TranslatorMessage> &context = file[msg.context()];
if (context.isEmpty())
- contextOrder[msg.fileName()].append(msg.context());
+ contextOrder[fn].append(msg.context());
context.append(msg);
}
diff --git a/tools/macdeployqt/shared/shared.cpp b/tools/macdeployqt/shared/shared.cpp
index 52cf04b..c7d23c0 100644
--- a/tools/macdeployqt/shared/shared.cpp
+++ b/tools/macdeployqt/shared/shared.cpp
@@ -388,7 +388,7 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
foreach (FrameworkInfo dependency, dependencies) {
changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath);
- // Deploy framework if neccesary.
+ // Deploy framework if necessary.
if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) {
frameworks.append(dependency);
}
diff --git a/tools/makeqpf/qpf2.cpp b/tools/makeqpf/qpf2.cpp
index ab57cea..cafdb79 100644
--- a/tools/makeqpf/qpf2.cpp
+++ b/tools/makeqpf/qpf2.cpp
@@ -543,7 +543,7 @@ void QPF::addGlyphs(QFontEngine *fe, const QList<CharacterRange> &ranges)
;
}
- qMemCopy(data, img.bits(), img.byteCount());
+ memcpy(data, img.bits(), img.byteCount());
}
}
}
diff --git a/tools/pixeltool/qpixeltool.cpp b/tools/pixeltool/qpixeltool.cpp
index c684688..f64dfba 100644
--- a/tools/pixeltool/qpixeltool.cpp
+++ b/tools/pixeltool/qpixeltool.cpp
@@ -356,7 +356,7 @@ void QPixelTool::contextMenuEvent(QContextMenuEvent *e)
freeze.setCheckable(true);
freeze.setChecked(tmpFreeze);
freeze.setShortcut(QKeySequence(Qt::Key_Space));
- QAction autoUpdate(QLatin1String("Continous update"), &menu);
+ QAction autoUpdate(QLatin1String("Continuous update"), &menu);
autoUpdate.setCheckable(true);
autoUpdate.setChecked(m_autoUpdate);
autoUpdate.setShortcut(QKeySequence(Qt::Key_A));
diff --git a/tools/porting/src/codemodel.h b/tools/porting/src/codemodel.h
index cb3088f..04ad178 100644
--- a/tools/porting/src/codemodel.h
+++ b/tools/porting/src/codemodel.h
@@ -96,7 +96,7 @@ class Collection: public QMultiHash<QByteArray, CollectedType *>
{
public:
void add(CollectedType *collectedItem)
- { insert(collectedItem->name(), collectedItem); }
+ { this->insert(collectedItem->name(), collectedItem); }
};
typedef Collection<Scope> ScopeCollection;
diff --git a/tools/porting/src/errors.cpp b/tools/porting/src/errors.cpp
index 580efb5..9081dba 100644
--- a/tools/porting/src/errors.cpp
+++ b/tools/porting/src/errors.cpp
@@ -44,8 +44,8 @@
QT_BEGIN_NAMESPACE
-QT_STATIC_CONST_IMPL Error& Errors::InternalError = Error( 1, -1, QLatin1String("Internal Error") );
-QT_STATIC_CONST_IMPL Error& Errors::SyntaxError = Error( 2, -1, QLatin1String("Syntax Error before '%1'") );
-QT_STATIC_CONST_IMPL Error& Errors::ParseError = Error( 3, -1, QLatin1String("Parse Error before '%1'") );
+QT_STATIC_CONST_IMPL Error Errors::InternalError = Error( 1, -1, QLatin1String("Internal Error") );
+QT_STATIC_CONST_IMPL Error Errors::SyntaxError = Error( 2, -1, QLatin1String("Syntax Error before '%1'") );
+QT_STATIC_CONST_IMPL Error Errors::ParseError = Error( 3, -1, QLatin1String("Parse Error before '%1'") );
QT_END_NAMESPACE
diff --git a/tools/porting/src/errors.h b/tools/porting/src/errors.h
index f0ad691..dbac833 100644
--- a/tools/porting/src/errors.h
+++ b/tools/porting/src/errors.h
@@ -61,9 +61,9 @@ public:
class Errors
{
public:
- QT_STATIC_CONST Error& InternalError;
- QT_STATIC_CONST Error& SyntaxError;
- QT_STATIC_CONST Error& ParseError;
+ QT_STATIC_CONST Error InternalError;
+ QT_STATIC_CONST Error SyntaxError;
+ QT_STATIC_CONST Error ParseError;
};
QT_END_NAMESPACE
diff --git a/tools/porting/src/preprocessorcontrol.cpp b/tools/porting/src/preprocessorcontrol.cpp
index 673ed08..31adc32 100644
--- a/tools/porting/src/preprocessorcontrol.cpp
+++ b/tools/porting/src/preprocessorcontrol.cpp
@@ -154,7 +154,7 @@ QByteArray PreprocessorCache::readFile(const QString &filename) const
// read the file for us.
if (receivers(SIGNAL(readFile(QByteArray&,QString))) > 0) {
QByteArray array;
- // Workaround for "not beeing able to emit from const function"
+ // Workaround for "not being able to emit from const function"
PreprocessorCache *cache = const_cast<PreprocessorCache *>(this);
emit cache->readFile(array, filename);
return array;
diff --git a/tools/porting/src/q3porting.xml b/tools/porting/src/q3porting.xml
index 7a31d6e..39f341f 100644
--- a/tools/porting/src/q3porting.xml
+++ b/tools/porting/src/q3porting.xml
@@ -1626,10 +1626,6 @@
<Name>Q3Wizard</Name>
</item>
<item Type="Qt4Class" >
- <Library>QtAssistant</Library>
- <Name>QAssistantClient</Name>
- </item>
- <item Type="Qt4Class" >
<Library>QtCore</Library>
<Name>QAbstractEventDispatcher</Name>
</item>
diff --git a/tools/porting/src/rpp.cpp b/tools/porting/src/rpp.cpp
index 7b0bea1..2e2aa97 100644
--- a/tools/porting/src/rpp.cpp
+++ b/tools/porting/src/rpp.cpp
@@ -60,7 +60,7 @@ Source *Preprocessor::parse(const TokenEngine::TokenContainer &tokenContainer,
const QVector<Type> &tokenTypeList, TypedPool<Item> *memoryPool)
{
m_memoryPool = memoryPool;
- Source *m_source = createNode<Source>(m_memoryPool); //node whith no parent
+ Source *m_source = createNode<Source>(m_memoryPool); //node with no parent
m_tokenContainer = tokenContainer;
m_tokenTypeList = tokenTypeList;
lexerTokenIndex = 0;
@@ -538,7 +538,7 @@ bool Preprocessor::parsePragmaDirective(Item *group)
}
/*
Reads a preprocessor line from the source by advancing lexerTokenIndex and
- returing a TokenSection containg the read line. Text lines separated by
+ returning a TokenSection containing the read line. Text lines separated by
an escaped newline are joined.
*/
TokenSection Preprocessor::readLine()
diff --git a/tools/porting/src/semantic.cpp b/tools/porting/src/semantic.cpp
index 268e037..bd9175f 100644
--- a/tools/porting/src/semantic.cpp
+++ b/tools/porting/src/semantic.cpp
@@ -768,7 +768,7 @@ void Semantic::parseTypedef(TypedefAST *ast)
void Semantic::parseTypeSpecifier(TypeSpecifierAST *ast)
{
// If this is a classSpecifier or a EnumSpecifier we skip the name lookup,
- // becuase looking up the name "E" in a class definition like
+ // because looking up the name "E" in a class definition like
// "class E { ..." makes no sense. (There might be a variable named E
// already declared, but that variable is now shadowed by the class type.)
if( ast->nodeType() != NodeType_EnumSpecifier
@@ -806,10 +806,10 @@ void Semantic::parseNameUse(NameAST* name)
}
/*
- looks up name used in basescope. If name->isGlobal() is true or if classOrNamespaceList()
- returns a non-emty list, the C++ qualified name lookup rules are used. Otherwise the
+ Looks up name used in basescope. If name->isGlobal() is true or if classOrNamespaceList()
+ returns a non-empty list, the C++ qualified name lookup rules are used. Otherwise the
unquialified name lookup rules are used. Returns the a list of members that was found,
- In most cases this list will contain zero or one element, exept in the case of overloaded functions.
+ In most cases this list will contain zero or one element, except in the case of overloaded functions.
TODO: Argument-dependent name lookup
*/
QList<CodeModel::Member *> Semantic::nameLookup(CodeModel::Scope *baseScope, const NameAST* name)
@@ -975,7 +975,7 @@ FunctionMember *Semantic::functionLookup(CodeModel::Scope *baseScope,
*/
FunctionMember *Semantic::selectFunction(QList<CodeModel::Member*> candidatateList, const DeclaratorAST *functionDeclarator)
{
- // get arguments for funciton we are looking for
+ // get arguments for function we are looking for
FunctionMember testFunction;
parseFunctionArguments(functionDeclarator, &testFunction);
const ArgumentCollection testArgumentCollection = testFunction.arguments();
diff --git a/tools/porting/src/textreplacement.h b/tools/porting/src/textreplacement.h
index f90fb82..f351552 100644
--- a/tools/porting/src/textreplacement.h
+++ b/tools/porting/src/textreplacement.h
@@ -53,7 +53,7 @@ class TextReplacement
public:
QByteArray newText;
int insertPosition;
- int currentLenght; //lenght of the text that is going to be replaced.
+ int currentLenght; //length of the text that is going to be replaced.
bool operator<(const TextReplacement &other) const
{
return (insertPosition < other.insertPosition);
@@ -70,7 +70,7 @@ public:
insert maintains the TextReplacement list in sorted order.
- Returns true if the insert was successfull, false otherwise;
+ Returns true if the insert was successful, false otherwise;
*/
bool insert(QByteArray newText, int insertPosition, int currentLenght);
void clear();
diff --git a/tools/porting/src/tokenengine.h b/tools/porting/src/tokenengine.h
index d998411..db68d88 100644
--- a/tools/porting/src/tokenengine.h
+++ b/tools/porting/src/tokenengine.h
@@ -55,7 +55,7 @@ namespace TokenEngine {
class TokenContainer;
/*
- A token is defined as a start-postion and a lenght. Since the actual text
+ A token is defined as a start-position and a length. Since the actual text
storage is not reffered to here, Token needs to be used together with
a TokenContainer in order to be useful.
*/
diff --git a/tools/porting/src/tokenreplacements.cpp b/tools/porting/src/tokenreplacements.cpp
index 02b7751..fa3cff8 100644
--- a/tools/porting/src/tokenreplacements.cpp
+++ b/tools/porting/src/tokenreplacements.cpp
@@ -126,7 +126,7 @@ int QualifiedNameParser::findScopeOperator(Direction direction)
{
int tokenIndex = currentIndex;
QByteArray tokenText;
- //loop until we get a token containg text or we pass the beginning/end of the source
+ //loop until we get a token containing text or we pass the beginning/end of the source
tokenIndex += direction;
while(tokenText.isEmpty() && isValidIndex(tokenIndex)) {
tokenText = tokenContainer.text(tokenIndex).trimmed();
@@ -146,7 +146,7 @@ int QualifiedNameParser::nextScopeToken(Direction direction)
if (tokenIndex == -1)
return -1;
QByteArray tokenText;
- //loop until we get a token containg text or we pass the start of the source
+ //loop until we get a token containing text or we pass the start of the source
tokenIndex += direction;
while(tokenText.isEmpty() && isValidIndex(tokenIndex)) {
tokenText = tokenContainer.text(tokenIndex).trimmed();
@@ -266,7 +266,7 @@ bool ScopedTokenReplacement::doReplace(const TokenContainer &tokenContainer, int
if (!attributes->attribute(sourceIndex, "unknown").isEmpty())
return false;
// If nameUse is set we test if the nameUse refers to the correct declaration.
- // This is done by checking the parentScope attriute, wich returns the scope
+ // This is done by checking the parentScope attribute, which returns the scope
// for the declaration associated with this name use.
const bool haveNameUseInfo = !attributes->attribute(sourceIndex, "nameUse").isEmpty();
if (haveNameUseInfo) {
@@ -314,7 +314,7 @@ bool ScopedTokenReplacement::doReplace(const TokenContainer &tokenContainer, int
const QByteArray sourceScope = tokenContainer.text(sourceScopeIndex);
// If we have no name use info and the source and old scopes don't match,
- // we generally dont't do a replace, unless the old scope is Qt and
+ // we generally don't do a replace, unless the old scope is Qt and
// the source scope inherits Qt. For example, QWidget::ButtonState should
// be renamed to Qt::ButtonState.
if (!haveNameUseInfo && sourceScope != oldScope) {
diff --git a/tools/qconfig/qconfig.pro b/tools/qconfig/qconfig.pro
index efbfcf2..171924f 100644
--- a/tools/qconfig/qconfig.pro
+++ b/tools/qconfig/qconfig.pro
@@ -6,5 +6,4 @@ build_all:!build_pass {
}
HEADERS = feature.h featuretreemodel.h graphics.h
SOURCES = main.cpp feature.cpp featuretreemodel.cpp
-INTERFACES =
TARGET = qconfig
diff --git a/tools/qdbus/qdbus.pro b/tools/qdbus/qdbus.pro
index 01cd246..a264882 100644
--- a/tools/qdbus/qdbus.pro
+++ b/tools/qdbus/qdbus.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
-SUBDIRS = qdbus qdbusxml2cpp qdbuscpp2xml qdbusviewer
+SUBDIRS = qdbus qdbusxml2cpp qdbuscpp2xml
+!contains(QT_CONFIG, no-gui): SUBDIRS += qdbusviewer
diff --git a/tools/qdbus/qdbus/qdbus.cpp b/tools/qdbus/qdbus/qdbus.cpp
index 48b0dad..ce18cb9 100644
--- a/tools/qdbus/qdbus/qdbus.cpp
+++ b/tools/qdbus/qdbus/qdbus.cpp
@@ -248,123 +248,153 @@ static QStringList readList(QStringList &args)
return retval;
}
-static void placeCall(const QString &service, const QString &path, const QString &interface,
- const QString &member, QStringList args)
+static int placeCall(const QString &service, const QString &path, const QString &interface,
+ const QString &member, const QStringList& arguments, bool try_prop=true)
{
QDBusInterface iface(service, path, interface, connection);
// Don't check whether the interface is valid to allow DBus try to
// activate the service if possible.
+ QList<int> knownIds;
+ bool matchFound = false;
+ QStringList args = arguments;
QVariantList params;
if (!args.isEmpty()) {
const QMetaObject *mo = iface.metaObject();
QByteArray match = member.toLatin1();
match += '(';
- int midx = -1;
for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) {
QMetaMethod mm = mo->method(i);
QByteArray signature = mm.signature();
- if (signature.startsWith(match)) {
- midx = i;
- break;
- }
+ if (signature.startsWith(match))
+ knownIds += i;
}
- if (midx == -1) {
- fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
- qPrintable(interface), qPrintable(member), qPrintable(path),
- qPrintable(service));
- exit(1);
- }
- QMetaMethod mm = mo->method(midx);
- QList<QByteArray> types = mm.parameterTypes();
- for (int i = 0; i < types.count(); ++i) {
- if (types.at(i).endsWith('&')) {
- // reference (and not a reference to const): output argument
- // we're done with the inputs
- while (types.count() > i)
- types.removeLast();
- break;
+ while (!matchFound) {
+ args = arguments; // reset
+ params.clear();
+ if (knownIds.isEmpty()) {
+ // Failed to set property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (try_prop && args.size() == 1) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ proparg += args.first();
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Set", proparg, false))
+ return 0;
+ }
+ fprintf(stderr, "Cannot find '%s.%s' in object %s at %s\n",
+ qPrintable(interface), qPrintable(member), qPrintable(path),
+ qPrintable(service));
+ return 1;
}
- }
- for (int i = 0; !args.isEmpty() && i < types.count(); ++i) {
- int id = QVariant::nameToType(types.at(i));
- if (id == QVariant::UserType)
- id = QMetaType::type(types.at(i));
- Q_ASSERT(id);
-
- QVariant p;
- QString argument;
- if ((id == QVariant::List || id == QVariant::StringList)
- && args.at(0) == QLatin1String("("))
- p = readList(args);
- else
- p = argument = args.takeFirst();
-
- if (id == int(QMetaType::UChar)) {
- // special case: QVariant::convert doesn't convert to/from
- // UChar because it can't decide if it's a character or a number
- p = qVariantFromValue<uchar>(p.toUInt());
- } else if (id < int(QMetaType::User) && id != int(QVariant::Map)) {
- p.convert(QVariant::Type(id));
- if (p.type() == QVariant::Invalid) {
- fprintf(stderr, "Could not convert '%s' to type '%s'.\n",
- qPrintable(argument), types.at(i).constData());
- exit(1);
- }
- } else if (id == qMetaTypeId<QDBusVariant>()) {
- QDBusVariant tmp(p);
- p = qVariantFromValue(tmp);
- } else if (id == qMetaTypeId<QDBusObjectPath>()) {
- QDBusObjectPath path(argument);
- if (path.path().isNull()) {
- fprintf(stderr, "Cannot pass argument '%s' because it is not a valid object path.\n",
- qPrintable(argument));
- exit(1);
+ QMetaMethod mm = mo->method(knownIds.takeFirst());
+ QList<QByteArray> types = mm.parameterTypes();
+ for (int i = 0; i < types.count(); ++i) {
+ if (types.at(i).endsWith('&')) {
+ // reference (and not a reference to const): output argument
+ // we're done with the inputs
+ while (types.count() > i)
+ types.removeLast();
+ break;
}
- p = qVariantFromValue(path);
- } else if (id == qMetaTypeId<QDBusSignature>()) {
- QDBusSignature sig(argument);
- if (sig.signature().isNull()) {
- fprintf(stderr, "Cannot pass argument '%s' because it is not a valid signature.\n",
- qPrintable(argument));
- exit(1);
+ }
+
+ for (int i = 0; !args.isEmpty() && i < types.count(); ++i) {
+ int id = QVariant::nameToType(types.at(i));
+ if (id == QVariant::UserType)
+ id = QMetaType::type(types.at(i));
+ Q_ASSERT(id);
+
+ QVariant p;
+ QString argument;
+ if ((id == QVariant::List || id == QVariant::StringList)
+ && args.at(0) == QLatin1String("("))
+ p = readList(args);
+ else
+ p = argument = args.takeFirst();
+
+ if (id == int(QMetaType::UChar)) {
+ // special case: QVariant::convert doesn't convert to/from
+ // UChar because it can't decide if it's a character or a number
+ p = qVariantFromValue<uchar>(p.toUInt());
+ } else if (id < int(QMetaType::User) && id != int(QVariant::Map)) {
+ p.convert(QVariant::Type(id));
+ if (p.type() == QVariant::Invalid) {
+ fprintf(stderr, "Could not convert '%s' to type '%s'.\n",
+ qPrintable(argument), types.at(i).constData());
+ return 1 ;
+ }
+ } else if (id == qMetaTypeId<QDBusVariant>()) {
+ QDBusVariant tmp(p);
+ p = qVariantFromValue(tmp);
+ } else if (id == qMetaTypeId<QDBusObjectPath>()) {
+ QDBusObjectPath path(argument);
+ if (path.path().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid object path.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = qVariantFromValue(path);
+ } else if (id == qMetaTypeId<QDBusSignature>()) {
+ QDBusSignature sig(argument);
+ if (sig.signature().isNull()) {
+ fprintf(stderr, "Cannot pass argument '%s' because it is not a valid signature.\n",
+ qPrintable(argument));
+ return 1;
+ }
+ p = qVariantFromValue(sig);
+ } else {
+ fprintf(stderr, "Sorry, can't pass arg of type '%s'.\n",
+ types.at(i).constData());
+ return 1;
}
- p = qVariantFromValue(sig);
- } else {
- fprintf(stderr, "Sorry, can't pass arg of type '%s'.\n",
- types.at(i).constData());
- exit(1);
+ params += p;
}
- params += p;
- }
- if (params.count() != types.count() || !args.isEmpty()) {
- fprintf(stderr, "Invalid number of parameters\n");
- exit(1);
- }
- }
+ if (params.count() == types.count() && args.isEmpty())
+ matchFound = true;
+ else if (knownIds.isEmpty()) {
+ fprintf(stderr, "Invalid number of parameters\n");
+ return 1;
+ }
+ } // while (!matchFound)
+ } // if (!args.isEmpty()
QDBusMessage reply = iface.callWithArgumentList(QDBus::Block, member, params);
if (reply.type() == QDBusMessage::ErrorMessage) {
QDBusError err = reply;
+ // Failed to retrieve property after falling back?
+ // Bail out without displaying an error
+ if (!try_prop)
+ return 1;
+ if (err.type() == QDBusError::UnknownMethod && try_prop) {
+ QStringList proparg;
+ proparg += interface;
+ proparg += member;
+ if (!placeCall(service, path, "org.freedesktop.DBus.Properties", "Get", proparg, false))
+ return 0;
+ }
if (err.type() == QDBusError::ServiceUnknown)
fprintf(stderr, "Service '%s' does not exist.\n", qPrintable(service));
else
printf("Error: %s\n%s\n", qPrintable(err.name()), qPrintable(err.message()));
- exit(2);
+ return 2;
} else if (reply.type() != QDBusMessage::ReplyMessage) {
fprintf(stderr, "Invalid reply type %d\n", int(reply.type()));
- exit(1);
+ return 1;
}
foreach (QVariant v, reply.arguments())
printArg(v);
- exit(0);
+ return 0;
}
static bool globServices(QDBusConnectionInterface *bus, const QString &glob)
@@ -483,6 +513,7 @@ int main(int argc, char **argv)
exit(1);
}
- placeCall(service, path, interface, member, args);
+ int ret = placeCall(service, path, interface, member, args);
+ exit(ret);
}
diff --git a/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp b/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
index 3a80019..ba2bdd8 100644
--- a/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/tools/qdbus/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -64,7 +64,7 @@ static const char docTypeHeader[] =
// in qdbusxmlgenerator.cpp
QT_BEGIN_NAMESPACE
-extern QDBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo,
+extern Q_DBUS_EXPORT QString qDBusGenerateMetaObjectXml(QString interface, const QMetaObject *mo,
const QMetaObject *base, int flags);
QT_END_NAMESPACE
diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.cpp b/tools/qdbus/qdbusviewer/qdbusmodel.cpp
index befe4b4..f85e288 100644
--- a/tools/qdbus/qdbusviewer/qdbusmodel.cpp
+++ b/tools/qdbus/qdbusviewer/qdbusmodel.cpp
@@ -75,6 +75,7 @@ struct QDBusItem
bool isPrefetched;
QString name;
QString caption;
+ QString typeSignature;
};
QDomDocument QDBusModel::introspect(const QString &path)
@@ -118,6 +119,13 @@ void QDBusModel::addMethods(QDBusItem *parent, const QDomElement &iface)
item = new QDBusItem(QDBusModel::MethodItem,
child.attribute(QLatin1String("name")), parent);
item->caption = QLatin1String("Method: ") + item->name;
+ //get "type" from <arg> where "direction" is "in"
+ QDomElement n = child.firstChildElement();
+ while (!n.isNull()) {
+ if (n.attribute(QLatin1String("direction")) == QLatin1String("in"))
+ item->typeSignature += n.attribute(QLatin1String("type"));
+ n = n.nextSiblingElement();
+ }
} else if (child.tagName() == QLatin1String("signal")) {
item = new QDBusItem(QDBusModel::SignalItem,
child.attribute(QLatin1String("name")), parent);
@@ -298,6 +306,12 @@ QString QDBusModel::dBusMethodName(const QModelIndex &index) const
return item ? item->name : QString();
}
+QString QDBusModel::dBusTypeSignature(const QModelIndex &index) const
+{
+ QDBusItem *item = static_cast<QDBusItem *>(index.internalPointer());
+ return item ? item->typeSignature : QString();
+}
+
QModelIndex QDBusModel::findObject(const QDBusObjectPath &objectPath)
{
QStringList path = objectPath.path().split(QLatin1Char('/'), QString::SkipEmptyParts);
diff --git a/tools/qdbus/qdbusviewer/qdbusmodel.h b/tools/qdbus/qdbusviewer/qdbusmodel.h
index 1a3d8f0..e83c381 100644
--- a/tools/qdbus/qdbusviewer/qdbusmodel.h
+++ b/tools/qdbus/qdbusviewer/qdbusmodel.h
@@ -72,6 +72,7 @@ public:
QString dBusPath(const QModelIndex &index) const;
QString dBusInterface(const QModelIndex &index) const;
QString dBusMethodName(const QModelIndex &index) const;
+ QString dBusTypeSignature(const QModelIndex &index) const;
void refresh(const QModelIndex &index = QModelIndex());
diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.cpp b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
index e9695dc..9878aff 100644
--- a/tools/qdbus/qdbusviewer/qdbusviewer.cpp
+++ b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
@@ -69,9 +69,16 @@ QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
c(connection),
objectPathRegExp(QLatin1String("\\[ObjectPath: (.*)\\]"))
{
- services = new QTreeWidget;
- services->setRootIsDecorated(false);
- services->setHeaderLabels(QStringList(QLatin1String("Services")));
+ servicesModel = new QStringListModel(this);
+ servicesFilterModel = new QSortFilterProxyModel(this);
+ servicesFilterModel->setSourceModel(servicesModel);
+ servicesFilterModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ serviceFilterLine = new QLineEdit(this);
+ serviceFilterLine->setPlaceholderText(tr("Search..."));
+ servicesView = new QListView(this);
+ servicesView->setModel(servicesFilterModel);
+
+ connect(serviceFilterLine, SIGNAL(textChanged(QString)), servicesFilterModel, SLOT(setFilterFixedString(QString)));
tree = new QTreeView;
tree->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -86,19 +93,28 @@ QDBusViewer::QDBusViewer(const QDBusConnection &connection, QWidget *parent) :
QShortcut *refreshShortcut = new QShortcut(QKeySequence::Refresh, tree);
connect(refreshShortcut, SIGNAL(activated()), this, SLOT(refreshChildren()));
- QVBoxLayout *topLayout = new QVBoxLayout(this);
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ QSplitter *topSplitter = new QSplitter(Qt::Vertical, this);
+ layout->addWidget(topSplitter);
+
log = new QTextBrowser;
connect(log, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
- QHBoxLayout *layout = new QHBoxLayout;
- layout->addWidget(services, 1);
- layout->addWidget(tree, 2);
+ QSplitter *splitter = new QSplitter(topSplitter);
+ splitter->addWidget(servicesView);
+
+ QWidget *servicesWidget = new QWidget;
+ QVBoxLayout *servicesLayout = new QVBoxLayout(servicesWidget);
+ servicesLayout->addWidget(serviceFilterLine);
+ servicesLayout->addWidget(servicesView);
+ splitter->addWidget(servicesWidget);
+ splitter->addWidget(tree);
- topLayout->addLayout(layout);
- topLayout->addWidget(log);
+ topSplitter->addWidget(splitter);
+ topSplitter->addWidget(log);
- connect(services, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- this, SLOT(serviceChanged(QTreeWidgetItem*)));
+ connect(servicesView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
+ this, SLOT(serviceChanged(QModelIndex)));
connect(tree, SIGNAL(customContextMenuRequested(QPoint)),
this, SLOT(showContextMenu(QPoint)));
@@ -133,12 +149,11 @@ void QDBusViewer::logError(const QString &msg)
void QDBusViewer::refresh()
{
- services->clear();
+ servicesModel->removeRows(0, servicesModel->rowCount());
if (c.isConnected()) {
const QStringList serviceNames = c.interface()->registeredServiceNames();
- foreach (QString service, serviceNames)
- new QTreeWidgetItem(services, QStringList(service));
+ servicesModel->setStringList(serviceNames);
}
}
@@ -154,6 +169,7 @@ void QDBusViewer::activate(const QModelIndex &item)
sig.mPath = model->dBusPath(item);
sig.mInterface = model->dBusInterface(item);
sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
switch (model->itemType(item)) {
case QDBusModel::SignalItem:
@@ -207,6 +223,17 @@ void QDBusViewer::setProperty(const BusSignature &sig)
}
+static QString getDbusSignature(const QMetaMethod& method)
+{
+ // create a D-Bus type signature from QMetaMethod's parameters
+ QString sig;
+ for (int i = 0; i < method.parameterTypes().count(); ++i) {
+ QVariant::Type type = QVariant::nameToType(method.parameterTypes().at(i));
+ sig.append(QString::fromLatin1(QDBusMetaType::typeToSignature(type)));
+ }
+ return sig;
+}
+
void QDBusViewer::callMethod(const BusSignature &sig)
{
QDBusInterface iface(sig.mService, sig.mPath, sig.mInterface, c);
@@ -217,7 +244,8 @@ void QDBusViewer::callMethod(const BusSignature &sig)
for (int i = 0; i < mo->methodCount(); ++i) {
const QString signature = QString::fromLatin1(mo->method(i).signature());
if (signature.startsWith(sig.mName) && signature.at(sig.mName.length()) == QLatin1Char('('))
- method = mo->method(i);
+ if (getDbusSignature(mo->method(i)) == sig.mTypeSig)
+ method = mo->method(i);
}
if (!method.signature()) {
QMessageBox::warning(this, tr("Unable to find method"),
@@ -277,6 +305,7 @@ void QDBusViewer::showContextMenu(const QPoint &point)
sig.mPath = model->dBusPath(item);
sig.mInterface = model->dBusInterface(item);
sig.mName = model->dBusMethodName(item);
+ sig.mTypeSig = model->dBusTypeSignature(item);
QMenu menu;
menu.addAction(refreshAction);
@@ -379,14 +408,14 @@ void QDBusViewer::dumpMessage(const QDBusMessage &message)
log->append(out);
}
-void QDBusViewer::serviceChanged(QTreeWidgetItem *item)
+void QDBusViewer::serviceChanged(const QModelIndex &index)
{
delete tree->model();
currentService.clear();
- if (!item)
+ if (!index.isValid())
return;
- currentService = item->text(0);
+ currentService = index.data().toString();
tree->setModel(new QDBusViewModel(currentService, c));
connect(tree->model(), SIGNAL(busError(QString)), this, SLOT(logError(QString)));
@@ -397,34 +426,38 @@ void QDBusViewer::serviceRegistered(const QString &service)
if (service == c.baseService())
return;
- new QTreeWidgetItem(services, QStringList(service));
+ servicesModel->insertRows(0, 1);
+ servicesModel->setData(servicesModel->index(0, 0), service);
}
-static QTreeWidgetItem *findItem(const QTreeWidget *services, const QString &name)
+static QModelIndex findItem(QStringListModel *servicesModel, const QString &name)
{
- for (int i = 0; i < services->topLevelItemCount(); ++i) {
- if (services->topLevelItem(i)->text(0) == name)
- return services->topLevelItem(i);
- }
- return 0;
+ QModelIndexList hits = servicesModel->match(servicesModel->index(0, 0), Qt::DisplayRole, name);
+ if (hits.isEmpty())
+ return QModelIndex();
+
+ return hits.first();
}
void QDBusViewer::serviceUnregistered(const QString &name)
{
- delete findItem(services, name);
+ QModelIndex hit = findItem(servicesModel, name);
+ if (!hit.isValid())
+ return;
+ servicesModel->removeRows(hit.row(), 1);
}
void QDBusViewer::serviceOwnerChanged(const QString &name, const QString &oldOwner,
const QString &newOwner)
{
- QTreeWidgetItem *item = findItem(services, name);
+ QModelIndex hit = findItem(servicesModel, name);
- if (!item && oldOwner.isEmpty() && !newOwner.isEmpty())
+ if (!hit.isValid() && oldOwner.isEmpty() && !newOwner.isEmpty())
serviceRegistered(name);
- else if (item && !oldOwner.isEmpty() && newOwner.isEmpty())
- delete item;
- else if (item && !oldOwner.isEmpty() && !newOwner.isEmpty()) {
- delete item;
+ else if (hit.isValid() && !oldOwner.isEmpty() && newOwner.isEmpty())
+ servicesModel->removeRows(hit.row(), 1);
+ else if (hit.isValid() && !oldOwner.isEmpty() && !newOwner.isEmpty()) {
+ servicesModel->removeRows(hit.row(), 1);
serviceRegistered(name);
}
}
diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.h b/tools/qdbus/qdbusviewer/qdbusviewer.h
index 207f7a3..d5d1a69 100644
--- a/tools/qdbus/qdbusviewer/qdbusviewer.h
+++ b/tools/qdbus/qdbusviewer/qdbusviewer.h
@@ -52,6 +52,7 @@ QT_FORWARD_DECLARE_CLASS(QDomElement);
struct BusSignature
{
QString mService, mPath, mInterface, mName;
+ QString mTypeSig;
};
class QDBusViewer: public QWidget
@@ -65,7 +66,7 @@ public slots:
void about();
private slots:
- void serviceChanged(QTreeWidgetItem *item);
+ void serviceChanged(const QModelIndex &index);
void showContextMenu(const QPoint &);
void connectionRequested(const BusSignature &sig);
void callMethod(const BusSignature &sig);
@@ -91,6 +92,10 @@ private:
QTreeView *tree;
QAction *refreshAction;
QTreeWidget *services;
+ QStringListModel *servicesModel;
+ QSortFilterProxyModel *servicesFilterModel;
+ QLineEdit *serviceFilterLine;
+ QListView *servicesView;
QTextBrowser *log;
QRegExp objectPathRegExp;
};
diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
index 8251e2c..a259096 100644
--- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -53,14 +53,9 @@
#include "private/qdbusmetaobject_p.h"
#include "private/qdbusintrospection_p.h"
-#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
-#ifdef Q_WS_WIN
-#include <process.h>
-#endif
-
#define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.7"
#define PROGRAMCOPYRIGHT "Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)."
@@ -1135,11 +1130,11 @@ int main(int argc, char **argv)
static code representing those interfaces, which can then be used to make calls to remote
objects or implement said interfaces.
- \c qdbusxml2dcpp has two modes of operation, that correspond to the two possible outputs it can
+ \c qdbusxml2cpp has two modes of operation, that correspond to the two possible outputs it can
produce: the interface (proxy) class or the adaptor class. The latter consists of both a C++
header and a source file, which are meant to be edited and adapted to your needs.
- The \c qdbusxml2dcpp tool is not meant to be run every time you compile your
+ The \c qdbusxml2cpp tool is not meant to be run every time you compile your
application. Instead, it's meant to be used when developing the code or when the interface
changes.
diff --git a/tools/qdoc3/codechunk.h b/tools/qdoc3/codechunk.h
index e78873c..a0c554e 100644
--- a/tools/qdoc3/codechunk.h
+++ b/tools/qdoc3/codechunk.h
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
/*
The CodeChunk class represents a tiny piece of C++ code.
- The class provides convertion between a list of lexemes and a string. It adds
+ The class provides conversion between a list of lexemes and a string. It adds
spaces at the right place for consistent style. The tiny pieces of code it
represents are data types, enum values, and default parameter values.
diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp
index ee93080..ec86ae3 100644
--- a/tools/qdoc3/codemarker.cpp
+++ b/tools/qdoc3/codemarker.cpp
@@ -177,7 +177,7 @@ const Node *CodeMarker::nodeForString(const QString& string)
QString CodeMarker::stringForNode(const Node *node)
{
if (sizeof(const Node *) == sizeof(ulong)) {
- return QString::number(reinterpret_cast<ulong>(node));
+ return QString::number(reinterpret_cast<quintptr>(node));
}
else {
return QString::number(reinterpret_cast<qulonglong>(node));
@@ -257,6 +257,7 @@ QString CodeMarker::typified(const QString &string)
QString CodeMarker::taggedNode(const Node* node)
{
QString tag;
+ QString name = node->name();
switch (node->type()) {
case Node::Namespace:
@@ -277,11 +278,20 @@ QString CodeMarker::taggedNode(const Node* node)
case Node::Property:
tag = QLatin1String("@property");
break;
+#ifdef QDOC_QML
+ case Node::Fake:
+ if (node->subType() == Node::QmlClass) {
+ if (node->name().startsWith(QLatin1String("QML:")))
+ name = name.mid(4); // remove the "QML:" prefix
+ }
+ tag = QLatin1String("@property");
+ break;
+#endif
default:
tag = QLatin1String("@unknown");
break;
}
- return QLatin1Char('<') + tag + QLatin1Char('>') + protect(node->name())
+ return QLatin1Char('<') + tag + QLatin1Char('>') + protect(name)
+ QLatin1String("</") + tag + QLatin1Char('>');
}
@@ -457,7 +467,7 @@ bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs)
{
if (!fs.isEmpty()) {
- Section section(fs.name,fs.singularMember,fs.pluralMember);
+ Section section(fs.name,fs.divClass,fs.singularMember,fs.pluralMember);
section.members = fs.memberMap.values();
section.reimpMembers = fs.reimpMemberMap.values();
section.inherited = fs.inherited;
@@ -614,10 +624,20 @@ QString CodeMarker::macName(const Node *node, const QString &name)
Get the list of documentation sections for the children of
the specified QmlClassNode.
*/
-QList<Section> CodeMarker::qmlSections(const QmlClassNode* , SynopsisStyle )
+QList<Section> CodeMarker::qmlSections(const QmlClassNode* ,
+ SynopsisStyle ,
+ const Tree* )
{
return QList<Section>();
}
#endif
+const Node* CodeMarker::resolveTarget(const QString& ,
+ const Tree* ,
+ const Node* ,
+ const Node* )
+{
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h
index 1b21753..f17b28e 100644
--- a/tools/qdoc3/codemarker.h
+++ b/tools/qdoc3/codemarker.h
@@ -58,6 +58,7 @@ class Tree;
struct Section
{
QString name;
+ QString divClass;
QString singularMember;
QString pluralMember;
NodeList members;
@@ -66,9 +67,11 @@ struct Section
Section() { }
Section(const QString& name0,
+ const QString& divClass0,
const QString& singularMember0,
const QString& pluralMember0)
- : name(name0),
+ : name(name0),
+ divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
void appendMember(Node* node) { members.append(node); }
@@ -79,6 +82,7 @@ struct FastSection
{
const InnerNode *innerNode;
QString name;
+ QString divClass;
QString singularMember;
QString pluralMember;
QMap<QString, Node *> memberMap;
@@ -86,20 +90,30 @@ struct FastSection
QList<QPair<ClassNode *, int> > inherited;
FastSection(const InnerNode *innerNode0,
- const QString& name0 = "",
- const QString& singularMember0 = "member",
- const QString& pluralMember0 = "members")
+ const QString& name0,
+ const QString& divClass0,
+ const QString& singularMember0,
+ const QString& pluralMember0)
: innerNode(innerNode0),
name(name0),
+ divClass(divClass0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
bool isEmpty() const {
- return (memberMap.isEmpty() && inherited.isEmpty() &&
+ return (memberMap.isEmpty() &&
+ inherited.isEmpty() &&
reimpMemberMap.isEmpty());
}
};
+#if 0
+ const QString& name0 = "",
+ const QString& divClass0 = "",
+ const QString& singularMember0 = "member",
+ const QString& pluralMember0 = "members")
+#endif
+
class CodeMarker
{
public:
@@ -139,12 +153,14 @@ class CodeMarker
Status status) = 0;
#ifdef QDOC_QML
virtual QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
- SynopsisStyle style);
+ SynopsisStyle style,
+ const Tree* tree);
#endif
- virtual const Node *resolveTarget(const QString& target,
- const Tree *tree,
- const Node *relative) = 0;
- virtual QStringList macRefsForNode(const Node *node);
+ virtual const Node* resolveTarget(const QString& target,
+ const Tree* tree,
+ const Node* relative,
+ const Node* self = 0);
+ virtual QStringList macRefsForNode(const Node* node);
static void initialize(const Config& config);
static void terminate();
diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp
index 3ad3372..65d9572 100644
--- a/tools/qdoc3/codeparser.cpp
+++ b/tools/qdoc3/codeparser.cpp
@@ -43,11 +43,11 @@
codeparser.cpp
*/
-#include <QtCore>
#include "codeparser.h"
#include "node.h"
#include "tree.h"
#include "config.h"
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -59,6 +59,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_MAINCLASS Doc::alias(QLatin1String("mainclass"))
#define COMMAND_NONREENTRANT Doc::alias(QLatin1String("nonreentrant"))
#define COMMAND_OBSOLETE Doc::alias(QLatin1String("obsolete"))
+#define COMMAND_PAGEKEYWORDS Doc::alias(QLatin1String("pagekeywords"))
#define COMMAND_PRELIMINARY Doc::alias(QLatin1String("preliminary"))
#define COMMAND_INPUBLICGROUP Doc::alias(QLatin1String("inpublicgroup"))
#define COMMAND_REENTRANT Doc::alias(QLatin1String("reentrant"))
@@ -69,6 +70,7 @@ QT_BEGIN_NAMESPACE
QList<CodeParser *> CodeParser::parsers;
bool CodeParser::showInternal = false;
+QMap<QString,QString> CodeParser::nameToTitle;
/*!
The constructor adds this code parser to the static
@@ -170,6 +172,7 @@ QSet<QString> CodeParser::commonMetaCommands()
<< COMMAND_MAINCLASS
<< COMMAND_NONREENTRANT
<< COMMAND_OBSOLETE
+ << COMMAND_PAGEKEYWORDS
<< COMMAND_PRELIMINARY
<< COMMAND_INPUBLICGROUP
<< COMMAND_REENTRANT
@@ -230,6 +233,9 @@ void CodeParser::processCommonMetaCommand(const Location &location,
else if (command == COMMAND_SINCE) {
node->setSince(arg);
}
+ else if (command == COMMAND_PAGEKEYWORDS) {
+ node->addPageKeywords(arg);
+ }
else if (command == COMMAND_SUBTITLE) {
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
@@ -245,10 +251,20 @@ void CodeParser::processCommonMetaCommand(const Location &location,
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
fake->setTitle(arg);
+ nameToTitle.insert(fake->name(),arg);
}
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
}
}
+/*!
+ Find the page title given the page \a name and return it.
+ */
+const QString CodeParser::titleFromName(const QString& name)
+{
+ const QString t = nameToTitle.value(name);
+ return t;
+}
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/codeparser.h b/tools/qdoc3/codeparser.h
index 7b0d0eb..ebba601 100644
--- a/tools/qdoc3/codeparser.h
+++ b/tools/qdoc3/codeparser.h
@@ -78,6 +78,7 @@ class CodeParser
static void initialize(const Config& config);
static void terminate();
static CodeParser *parserForLanguage(const QString& language);
+ static const QString titleFromName(const QString& name);
protected:
QSet<QString> commonMetaCommands();
@@ -88,6 +89,7 @@ class CodeParser
private:
static QList<CodeParser *> parsers;
static bool showInternal;
+ static QMap<QString,QString> nameToTitle;
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/command.cpp b/tools/qdoc3/command.cpp
index 76b483c..b78ad07 100644
--- a/tools/qdoc3/command.cpp
+++ b/tools/qdoc3/command.cpp
@@ -47,6 +47,8 @@
#include "command.h"
+#include <stdlib.h>
+
QT_BEGIN_NAMESPACE
void executeCommand(const Location& location,
@@ -69,6 +71,12 @@ void executeCommand(const Location& location,
if (space != -1)
toolName.truncate(space);
+#ifdef QT_BOOTSTRAPPED
+ int status = system(qPrintable(actualCommand));
+ int exitCode = WEXITSTATUS(status);
+ if (status == -1 || exitCode != EXIT_SUCCESS)
+ location.fatal(QString("Error executing '$1': $2").arg(toolName).arg(exitCode));
+#else
QProcess process;
process.start(QLatin1String("sh"),
QStringList() << QLatin1String("-c") << actualCommand);
@@ -89,6 +97,7 @@ void executeCommand(const Location& location,
tr("The tool was invoked like this:\n%1\n"
"It emitted these errors:\n%2")
.arg(actualCommand).arg(errors));
+#endif
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp
index f62ec24..4d1c378 100644
--- a/tools/qdoc3/config.cpp
+++ b/tools/qdoc3/config.cpp
@@ -43,7 +43,11 @@
config.cpp
*/
-#include <QtCore>
+#include <QDir>
+#include <QVariant>
+#include <QFile>
+#include <QTemporaryFile>
+#include <QTextStream>
#include "archiveextractor.h"
#include "config.h"
@@ -524,8 +528,11 @@ QString Config::findFile(const Location& location,
{
QStringList::ConstIterator e = fileExtensions.begin();
while (e != fileExtensions.end()) {
- QString filePath = findFile(location, files, dirs, fileBase + "." + *e,
- userFriendlyFilePath);
+ QString filePath = findFile(location,
+ files,
+ dirs,
+ fileBase + "." + *e,
+ userFriendlyFilePath);
if (!filePath.isEmpty())
return filePath;
++e;
@@ -671,7 +678,9 @@ void Config::load(Location location, const QString& fileName)
location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
}
- QString text = fin.readAll();
+ QTextStream stream(&fin);
+ stream.setCodec("UTF-8");
+ QString text = stream.readAll();
text += QLatin1String("\n\n");
text += QChar('\0');
fin.close();
diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h
index 5e7e6f1..335a0d6 100644
--- a/tools/qdoc3/config.h
+++ b/tools/qdoc3/config.h
@@ -119,6 +119,7 @@ class Config
};
#define CONFIG_ALIAS "alias"
+#define CONFIG_APPLICATION "application"
#define CONFIG_BASE "base" // ### don't document for now
#define CONFIG_CODEINDENT "codeindent"
#define CONFIG_DEFINES "defines"
@@ -140,18 +141,26 @@ class Config
#define CONFIG_INDEXES "indexes"
#define CONFIG_LANGUAGE "language"
#define CONFIG_MACRO "macro"
+#define CONFIG_NATURALLANGUAGE "naturallanguage"
#define CONFIG_OBSOLETELINKS "obsoletelinks"
+#define CONFIG_APPLICATION "application"
#define CONFIG_OUTPUTDIR "outputdir"
+#define CONFIG_OUTPUTENCODING "outputencoding"
#define CONFIG_OUTPUTLANGUAGE "outputlanguage"
#define CONFIG_OUTPUTFORMATS "outputformats"
#define CONFIG_PROJECT "project"
#define CONFIG_QHP "qhp"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
+#define CONFIG_SCRIPTDIRS "scriptdirs"
+#define CONFIG_SCRIPTS "scripts"
#define CONFIG_SLOW "slow"
#define CONFIG_SHOWINTERNAL "showinternal"
#define CONFIG_SOURCEDIRS "sourcedirs"
+#define CONFIG_SOURCEENCODING "sourceencoding"
#define CONFIG_SOURCES "sources"
#define CONFIG_SPURIOUS "spurious"
+#define CONFIG_STYLEDIRS "styledirs"
+#define CONFIG_STYLES "styles"
#define CONFIG_STYLESHEETS "stylesheets"
#define CONFIG_TABSIZE "tabsize"
#define CONFIG_TAGFILE "tagfile"
diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp
index 6c33054..3615a84 100644
--- a/tools/qdoc3/cppcodemarker.cpp
+++ b/tools/qdoc3/cppcodemarker.cpp
@@ -145,7 +145,7 @@ QString CppCodeMarker::plainFullName(const Node *node, const Node *relative)
}
else {
QString fullName;
- for (;;) {
+ while (node) {
fullName.prepend(plainName(node));
if (node->parent() == relative || node->parent()->name().isEmpty())
break;
@@ -482,55 +482,66 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
if (style == Summary) {
FastSection privateFunctions(classe,
"Private Functions",
+ "",
"private function",
"private functions");
- FastSection privateSlots(classe, "Private Slots", "private slot", "private slots");
- FastSection privateTypes(classe, "Private Types", "private type", "private types");
+ FastSection privateSlots(classe, "Private Slots", "", "private slot", "private slots");
+ FastSection privateTypes(classe, "Private Types", "", "private type", "private types");
FastSection protectedFunctions(classe,
"Protected Functions",
+ "",
"protected function",
"protected functions");
FastSection protectedSlots(classe,
"Protected Slots",
+ "",
"protected slot",
"protected slots");
FastSection protectedTypes(classe,
"Protected Types",
+ "",
"protected type",
"protected types");
FastSection protectedVariables(classe,
"Protected Variables",
+ "",
"protected type",
"protected variables");
FastSection publicFunctions(classe,
"Public Functions",
+ "",
"public function",
"public functions");
- FastSection publicSignals(classe, "Signals", "signal", "signals");
- FastSection publicSlots(classe, "Public Slots", "public slot", "public slots");
- FastSection publicTypes(classe, "Public Types", "public type", "public types");
+ FastSection publicSignals(classe, "Signals", "", "signal", "signals");
+ FastSection publicSlots(classe, "Public Slots", "", "public slot", "public slots");
+ FastSection publicTypes(classe, "Public Types", "", "public type", "public types");
FastSection publicVariables(classe,
"Public Variables",
- "public type",
+ "",
+ "public variable",
"public variables");
- FastSection properties(classe, "Properties", "property", "properties");
+ FastSection properties(classe, "Properties", "", "property", "properties");
FastSection relatedNonMembers(classe,
"Related Non-Members",
+ "",
"related non-member",
"related non-members");
FastSection staticPrivateMembers(classe,
"Static Private Members",
+ "",
"static private member",
"static private members");
FastSection staticProtectedMembers(classe,
"Static Protected Members",
+ "",
"static protected member",
"static protected members");
FastSection staticPublicMembers(classe,
"Static Public Members",
+ "",
"static public member",
"static public members");
- FastSection macros(inner, "Macros", "macro", "macros");
+ FastSection macros(inner, "Macros", "", "macro", "macros");
NodeList::ConstIterator r = classe->relatedNodes().begin();
while (r != classe->relatedNodes().end()) {
@@ -666,12 +677,12 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
append(sections, macros);
}
else if (style == Detailed) {
- FastSection memberFunctions(classe,"Member Function Documentation");
- FastSection memberTypes(classe,"Member Type Documentation");
- FastSection memberVariables(classe,"Member Variable Documentation");
- FastSection properties(classe,"Property Documentation");
- FastSection relatedNonMembers(classe,"Related Non-Members");
- FastSection macros(classe,"Macro Documentation");
+ FastSection memberFunctions(classe,"Member Function Documentation","func","member","members");
+ FastSection memberTypes(classe,"Member Type Documentation","types","member","members");
+ FastSection memberVariables(classe,"Member Variable Documentation","vars","member","members");
+ FastSection properties(classe,"Property Documentation","prop","member","members");
+ FastSection relatedNonMembers(classe,"Related Non-Members","relnonmem","member","members");
+ FastSection macros(classe,"Macro Documentation","macros","member","members");
NodeList::ConstIterator r = classe->relatedNodes().begin();
while (r != classe->relatedNodes().end()) {
@@ -717,7 +728,7 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
append(sections, macros);
}
else {
- FastSection all(classe);
+ FastSection all(classe,"","","member","members");
QStack<const ClassNode *> stack;
stack.push(classe);
@@ -747,25 +758,29 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
if (style == Summary || style == Detailed) {
FastSection namespaces(inner,
"Namespaces",
+ style == Detailed ? "nmspace" : "",
"namespace",
"namespaces");
FastSection classes(inner,
"Classes",
+ style == Detailed ? "classes" : "",
"class",
"classes");
FastSection types(inner,
- style == Summary ?
- "Types" : "Type Documentation",
+ style == Summary ? "Types" : "Type Documentation",
+ style == Detailed ? "types" : "",
"type",
"types");
FastSection functions(inner,
style == Summary ?
"Functions" : "Function Documentation",
+ style == Detailed ? "func" : "",
"function",
"functions");
FastSection macros(inner,
style == Summary ?
"Macros" : "Macro Documentation",
+ style == Detailed ? "macros" : "",
"macro",
"macros");
@@ -810,9 +825,10 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
return sections;
}
-const Node *CppCodeMarker::resolveTarget(const QString &target,
- const Tree *tree,
- const Node *relative)
+const Node *CppCodeMarker::resolveTarget(const QString& target,
+ const Tree* tree,
+ const Node* relative,
+ const Node* self)
{
if (target.endsWith("()")) {
const FunctionNode *func;
@@ -854,11 +870,13 @@ const Node *CppCodeMarker::resolveTarget(const QString &target,
else {
QStringList path = target.split("::");
const Node *node;
+ int flags = Tree::SearchBaseClasses |
+ Tree::SearchEnumValues |
+ Tree::NonFunction;
if ((node = tree->findNode(path,
relative,
- Tree::SearchBaseClasses |
- Tree::SearchEnumValues |
- Tree::NonFunction)))
+ flags,
+ self)))
return node;
}
return 0;
@@ -881,7 +899,7 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode,
static QRegExp globalX("[\n{()=] *([a-zA-Z_][a-zA-Z_0-9]*)[ \n]*\\(");
static QRegExp multiLineComment("/(?:( )?\\*(?:[^*]+|\\*(?! /))*\\*\\1/)");
multiLineComment.setMinimal(true);
- static QRegExp singleLineComment("//(?!!)[^!\n]*");
+ static QRegExp singleLineComment("[^:]//(?!!)[^!\\n]*");
static QRegExp preprocessor("(?:^|\n)(#[ \t]*(?:include|if|elif|endif|error|pragma|define"
"|warning)(?:(?:\\\\\n|\\n#)[^\n]*)*)");
static QRegExp literals("&quot;(?:[^\\\\&]|\\\\[^\n]|&(?!quot;))*&quot;"
@@ -1067,13 +1085,13 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode,
len = multiLineComment.matchedLength();
}
else if (mlpos == -1) {
- pos = slpos;
- len = singleLineComment.matchedLength();
+ pos = slpos + 1;
+ len = singleLineComment.matchedLength() - 1;
}
else {
if (slpos < mlpos) {
- pos = slpos;
- len = singleLineComment.matchedLength();
+ pos = slpos + 1;
+ len = singleLineComment.matchedLength() - 1;
}
else {
pos = mlpos;
@@ -1109,33 +1127,40 @@ QString CppCodeMarker::addMarkUp(const QString& protectedCode,
Currently, it only handles QML property groups.
*/
QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
- SynopsisStyle style)
+ SynopsisStyle style,
+ const Tree* tree)
{
QList<Section> sections;
if (qmlClassNode) {
if (style == Summary) {
FastSection qmlproperties(qmlClassNode,
"Properties",
+ "",
"property",
"properties");
FastSection qmlattachedproperties(qmlClassNode,
"Attached Properties",
+ "",
"property",
"properties");
FastSection qmlsignals(qmlClassNode,
- "Signals",
- "signal",
- "signals");
+ "Signals",
+ "",
+ "signal",
+ "signals");
FastSection qmlattachedsignals(qmlClassNode,
- "QML Attached Signals",
+ "Attached Signals",
+ "",
"signal",
"signals");
FastSection qmlmethods(qmlClassNode,
"Methods",
+ "",
"method",
"methods");
FastSection qmlattachedmethods(qmlClassNode,
- "QML Attached Methods",
+ "Attached Methods",
+ "",
"method",
"methods");
@@ -1179,12 +1204,15 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
append(sections,qmlattachedmethods);
}
else if (style == Detailed) {
- FastSection qmlproperties(qmlClassNode, "Property Documentation");
- FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation");
- FastSection qmlsignals(qmlClassNode,"Signal Documentation");
- FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation");
- FastSection qmlmethods(qmlClassNode,"Method Documentation");
- FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation");
+ FastSection qmlproperties(qmlClassNode, "Property Documentation","qmlprop","member","members");
+ FastSection qmlattachedproperties(qmlClassNode,"Attached Property Documentation","qmlattprop",
+ "member","members");
+ FastSection qmlsignals(qmlClassNode,"Signal Documentation","qmlsig","member","members");
+ FastSection qmlattachedsignals(qmlClassNode,"Attached Signal Documentation","qmlattsig",
+ "member","members");
+ FastSection qmlmethods(qmlClassNode,"Method Documentation","qmlmeth","member","members");
+ FastSection qmlattachedmethods(qmlClassNode,"Attached Method Documentation","qmlattmeth",
+ "member","members");
NodeList::ConstIterator c = qmlClassNode->childNodes().begin();
while (c != qmlClassNode->childNodes().end()) {
if ((*c)->subType() == Node::QmlPropertyGroup) {
@@ -1217,6 +1245,48 @@ QList<Section> CppCodeMarker::qmlSections(const QmlClassNode* qmlClassNode,
append(sections,qmlmethods);
append(sections,qmlattachedmethods);
}
+ else {
+ FastSection all(qmlClassNode,"","","member","members");
+
+ QStack<const QmlClassNode*> stack;
+ stack.push(qmlClassNode);
+
+ while (!stack.isEmpty()) {
+ const QmlClassNode* ancestorClass = stack.pop();
+
+ NodeList::ConstIterator c = ancestorClass->childNodes().begin();
+ while (c != ancestorClass->childNodes().end()) {
+ // if ((*c)->access() != Node::Private)
+ if ((*c)->subType() == Node::QmlPropertyGroup) {
+ const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(*c);
+ NodeList::ConstIterator p = qpgn->childNodes().begin();
+ while (p != qpgn->childNodes().end()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ insert(all,*p,style,Okay);
+ }
+ ++p;
+ }
+ }
+ else
+ insert(all,*c,style,Okay);
+ ++c;
+ }
+
+ if (!ancestorClass->links().empty()) {
+ if (ancestorClass->links().contains(Node::InheritsLink)) {
+ QPair<QString,QString> linkPair;
+ linkPair = ancestorClass->links()[Node::InheritsLink];
+ QStringList strList(linkPair.first);
+ const Node* n = tree->findNode(strList,Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
+ stack.prepend(qcn);
+ }
+ }
+ }
+ }
+ append(sections, all);
+ }
}
return sections;
diff --git a/tools/qdoc3/cppcodemarker.h b/tools/qdoc3/cppcodemarker.h
index 2dcf400..804a302 100644
--- a/tools/qdoc3/cppcodemarker.h
+++ b/tools/qdoc3/cppcodemarker.h
@@ -80,10 +80,12 @@ class CppCodeMarker : public CodeMarker
SynopsisStyle style,
Status status);
QList<Section> qmlSections(const QmlClassNode* qmlClassNode,
- SynopsisStyle style);
- const Node *resolveTarget(const QString& target,
- const Tree *tree,
- const Node *relative);
+ SynopsisStyle style,
+ const Tree* tree);
+ const Node* resolveTarget(const QString& target,
+ const Tree* tree,
+ const Node* relative,
+ const Node* self = 0);
private:
QString addMarkUp(const QString& protectedCode,
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index 9b6a516..a120e45 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -43,11 +43,11 @@
cppcodeparser.cpp
*/
-#include <QtCore>
#include <qfile.h>
#include <stdio.h>
#include <errno.h>
+#include <qdebug.h>
#include "codechunk.h"
#include "config.h"
@@ -95,6 +95,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_QMLMETHOD Doc::alias("qmlmethod")
#define COMMAND_QMLATTACHEDMETHOD Doc::alias("qmlattachedmethod")
#define COMMAND_QMLDEFAULT Doc::alias("default")
+#define COMMAND_QMLBASICTYPE Doc::alias("qmlbasictype")
#endif
QStringList CppCodeParser::exampleFiles;
@@ -280,8 +281,8 @@ void CppCodeParser::parseHeaderFile(const Location& location,
const QString& filePath,
Tree *tree)
{
- FILE *in = fopen(QFile::encodeName(filePath), "r");
- if (!in) {
+ QFile in(filePath);
+ if (!in.open(QIODevice::ReadOnly)) {
location.error(tr("Cannot open C++ header file '%1'").arg(filePath));
return;
}
@@ -294,7 +295,7 @@ void CppCodeParser::parseHeaderFile(const Location& location,
matchDeclList(tree->root());
if (!fileTokenizer.version().isEmpty())
tree->setVersion(fileTokenizer.version());
- fclose(in);
+ in.close();
if (fileLocation.fileName() == "qiterator.h")
parseQiteratorDotH(location, filePath);
@@ -311,8 +312,8 @@ void CppCodeParser::parseSourceFile(const Location& location,
const QString& filePath,
Tree *tree)
{
- FILE *in = fopen(QFile::encodeName(filePath), "r");
- if (!in) {
+ QFile in(filePath);
+ if (!in.open(QIODevice::ReadOnly)) {
location.error(tr("Cannot open C++ source file '%1' (%2)").arg(filePath).arg(strerror(errno)));
return;
}
@@ -324,7 +325,7 @@ void CppCodeParser::parseSourceFile(const Location& location,
readToken();
usedNamespaces.clear();
matchDocsAndStuff();
- fclose(in);
+ in.close();
}
/*!
@@ -491,7 +492,7 @@ const FunctionNode *CppCodeParser::findFunctionNode(const QString& synopsis,
candidates << overload;
}
-
+
/*
There are several functions with the correct
parameter count, but only one has the correct
@@ -536,14 +537,15 @@ QSet<QString> CppCodeParser::topicCommands()
<< COMMAND_QMLSIGNAL
<< COMMAND_QMLATTACHEDSIGNAL
<< COMMAND_QMLMETHOD
- << COMMAND_QMLATTACHEDMETHOD;
+ << COMMAND_QMLATTACHEDMETHOD
+ << COMMAND_QMLBASICTYPE;
#else
<< COMMAND_VARIABLE;
#endif
}
/*!
- Process the topic \a command in context \a doc with argument \a arg.
+ Process the topic \a command in context \a doc with argument \a arg.
*/
Node *CppCodeParser::processTopicCommand(const Doc& doc,
const QString& command,
@@ -726,7 +728,13 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc,
if (n)
classNode = static_cast<const ClassNode*>(n);
}
- return new QmlClassNode(tre->root(), names[0], classNode);
+ if (names[0].startsWith("Qt"))
+ return new QmlClassNode(tre->root(), QLatin1String("QML:")+names[0], classNode);
+ else
+ return new QmlClassNode(tre->root(), names[0], classNode);
+ }
+ else if (command == COMMAND_QMLBASICTYPE) {
+ return new QmlBasicTypeNode(tre->root(), arg);
}
else if ((command == COMMAND_QMLSIGNAL) ||
(command == COMMAND_QMLMETHOD) ||
@@ -736,6 +744,8 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc,
QString type;
QmlClassNode* qmlClass = 0;
if (splitQmlMethodArg(doc,arg,type,element)) {
+ if (element.startsWith(QLatin1String("Qt")))
+ element = QLatin1String("QML:") + element;
Node* n = tre->findNode(QStringList(element),Node::Fake);
if (n && n->subType() == Node::QmlClass) {
qmlClass = static_cast<QmlClassNode*>(n);
@@ -896,13 +906,13 @@ QSet<QString> CppCodeParser::otherMetaCommands()
<< COMMAND_NEXTPAGE
<< COMMAND_PREVIOUSPAGE
<< COMMAND_INDEXPAGE
-#ifdef QDOC_QML
+#ifdef QDOC_QML
<< COMMAND_STARTPAGE
<< COMMAND_QMLINHERITS
<< COMMAND_QMLDEFAULT;
-#else
+#else
<< COMMAND_STARTPAGE;
-#endif
+#endif
}
/*!
@@ -1017,7 +1027,10 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
#ifdef QDOC_QML
else if (command == COMMAND_QMLINHERITS) {
setLink(node, Node::InheritsLink, arg);
- }
+ if (node->subType() == Node::QmlClass) {
+ QmlClassNode::addInheritedBy(arg,node);
+ }
+ }
else if (command == COMMAND_QMLDEFAULT) {
QmlPropGroupNode* qpgn = static_cast<QmlPropGroupNode*>(node);
qpgn->setDefault();
@@ -1107,6 +1120,17 @@ bool CppCodeParser::match(int target)
}
/*!
+ Skip to \a target. If \a target is found before the end
+ of input, return true. Otherwise return false.
+ */
+bool CppCodeParser::skipTo(int target)
+{
+ while ((tok != Tok_Eoi) && (tok != target))
+ readToken();
+ return (tok == target ? true : false);
+}
+
+/*!
If the current token is one of the keyword thingees that
are used in Qt, skip over it to the next token and return
true. Otherwise just return false without reading the
@@ -1349,7 +1373,9 @@ bool CppCodeParser::matchFunctionDecl(InnerNode *parent,
if (!matchDataType(&returnType)) {
if (tokenizer->parsingFnOrMacro()
- && (match(Tok_Q_DECLARE_FLAGS) || match(Tok_Q_PROPERTY)))
+ && (match(Tok_Q_DECLARE_FLAGS) ||
+ match(Tok_Q_PROPERTY) ||
+ match(Tok_Q_PRIVATE_PROPERTY)))
returnType = CodeChunk(previousLexeme());
else {
return false;
@@ -1632,8 +1658,9 @@ bool CppCodeParser::matchNamespaceDecl(InnerNode *parent)
*/
QString namespaceName = previousLexeme();
NamespaceNode *namespasse = 0;
- if (parent)
+ if (parent) {
namespasse = static_cast<NamespaceNode*>(parent->findNode(namespaceName, Node::Namespace));
+ }
if (!namespasse) {
namespasse = new NamespaceNode(parent, namespaceName);
namespasse->setAccess(access);
@@ -1782,11 +1809,19 @@ bool CppCodeParser::matchTypedefDecl(InnerNode *parent)
bool CppCodeParser::matchProperty(InnerNode *parent)
{
- if (!match(Tok_Q_PROPERTY) &&
- !match(Tok_Q_OVERRIDE) &&
- !match(Tok_QDOC_PROPERTY))
+ int expected_tok = Tok_LeftParen;
+ if (match(Tok_Q_PRIVATE_PROPERTY)) {
+ expected_tok = Tok_Comma;
+ if (!skipTo(Tok_Comma))
+ return false;
+ }
+ else if (!match(Tok_Q_PROPERTY) &&
+ !match(Tok_Q_OVERRIDE) &&
+ !match(Tok_QDOC_PROPERTY)) {
return false;
- if (!match(Tok_LeftParen))
+ }
+
+ if (!match(expected_tok))
return false;
QString name;
@@ -1830,16 +1865,40 @@ bool CppCodeParser::matchProperty(InnerNode *parent)
else if (key == "WRITE") {
tre->addPropertyFunction(property, value, PropertyNode::Setter);
property->setWritable(true);
- } else if (key == "STORED")
+ }
+ else if (key == "STORED")
property->setStored(value.toLower() == "true");
- else if (key == "DESIGNABLE")
- property->setDesignable(value.toLower() == "true");
+ else if (key == "DESIGNABLE") {
+ QString v = value.toLower();
+ if (v == "true")
+ property->setDesignable(true);
+ else if (v == "false")
+ property->setDesignable(false);
+ else {
+ property->setDesignable(false);
+ property->setRuntimeDesFunc(value);
+ }
+ }
else if (key == "RESET")
tre->addPropertyFunction(property, value, PropertyNode::Resetter);
else if (key == "NOTIFY") {
tre->addPropertyFunction(property, value, PropertyNode::Notifier);
}
-
+ else if (key == "SCRIPTABLE") {
+ QString v = value.toLower();
+ if (v == "true")
+ property->setScriptable(true);
+ else if (v == "false")
+ property->setScriptable(false);
+ else {
+ property->setScriptable(false);
+ property->setRuntimeScrFunc(value);
+ }
+ }
+ else if (key == "COSTANT")
+ property->setConstant();
+ else if (key == "FINAL")
+ property->setFinal();
}
match(Tok_RightParen);
return true;
@@ -1911,6 +1970,7 @@ bool CppCodeParser::matchDeclList(InnerNode *parent)
break;
case Tok_Q_OVERRIDE:
case Tok_Q_PROPERTY:
+ case Tok_Q_PRIVATE_PROPERTY:
case Tok_QDOC_PROPERTY:
matchProperty(parent);
break;
@@ -2099,7 +2159,7 @@ bool CppCodeParser::matchDocsAndStuff()
}
++a;
}
-#endif
+#endif
}
NodeList::Iterator n = nodes.begin();
@@ -2248,18 +2308,15 @@ void CppCodeParser::instantiateIteratorMacro(const QString &container,
void CppCodeParser::createExampleFileNodes(FakeNode *fake)
{
QString examplePath = fake->name();
-
- // we can assume that this file always exists
- QString proFileName = examplePath + "/" +
- examplePath.split("/").last() + ".pro";
-
+ QString proFileName = examplePath + "/" + examplePath.split("/").last() + ".pro";
QString userFriendlyFilePath;
+
QString fullPath = Config::findFile(fake->doc().location(),
exampleFiles,
exampleDirs,
proFileName,
userFriendlyFilePath);
-
+
if (fullPath.isEmpty()) {
QString tmp = proFileName;
proFileName = examplePath + "/" + "qbuild.pro";
@@ -2270,9 +2327,18 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake)
proFileName,
userFriendlyFilePath);
if (fullPath.isEmpty()) {
- fake->doc().location().warning(
- tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName));
- return;
+ proFileName = examplePath + "/" + examplePath.split("/").last() + ".qmlproject";
+ userFriendlyFilePath.clear();
+ fullPath = Config::findFile(fake->doc().location(),
+ exampleFiles,
+ exampleDirs,
+ proFileName,
+ userFriendlyFilePath);
+ if (fullPath.isEmpty()) {
+ fake->doc().location().warning(
+ tr("Cannot find file '%1' or '%2'").arg(tmp).arg(proFileName));
+ return;
+ }
}
}
@@ -2283,14 +2349,6 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake)
QString imagesPath = fullPath + "/images";
QStringList imageFiles = Config::getFilesHere(imagesPath,exampleImageFilter);
-#if 0
- qDebug() << "examplePath:" << examplePath;
- qDebug() << " exampleFiles" << exampleFiles;
- qDebug() << "imagesPath:" << imagesPath;
- qDebug() << "fullPath:" << fullPath;
- qDebug() << " imageFiles" << imageFiles;
-#endif
-
if (!exampleFiles.isEmpty()) {
// move main.cpp and to the end, if it exists
QString mainCpp;
@@ -2303,14 +2361,14 @@ void CppCodeParser::createExampleFileNodes(FakeNode *fake)
i.remove();
}
else if (fileName.contains("/qrc_") || fileName.contains("/moc_")
- || fileName.contains("/ui_"))
+ || fileName.contains("/ui_"))
i.remove();
}
if (!mainCpp.isEmpty())
exampleFiles.append(mainCpp);
// add any qmake Qt resource files and qmake project files
- exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro");
+ exampleFiles += Config::getFilesHere(fullPath, "*.qrc *.pro qmldir");
}
foreach (const QString &exampleFile, exampleFiles)
diff --git a/tools/qdoc3/cppcodeparser.h b/tools/qdoc3/cppcodeparser.h
index 3c53f72..55d9ddf 100644
--- a/tools/qdoc3/cppcodeparser.h
+++ b/tools/qdoc3/cppcodeparser.h
@@ -119,6 +119,7 @@ class CppCodeParser : public CodeParser
QString previousLexeme();
QString lexeme();
bool match(int target);
+ bool skipTo(int target);
bool matchCompat();
bool matchTemplateAngles(CodeChunk *type = 0);
bool matchTemplateHeader();
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
new file mode 100644
index 0000000..d43ad96
--- /dev/null
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -0,0 +1,5163 @@
+
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ ditaxmlgenerator.cpp
+*/
+
+#include "codemarker.h"
+#include "codeparser.h"
+#include "ditaxmlgenerator.h"
+#include "node.h"
+#include "separator.h"
+#include "tree.h"
+#include <ctype.h>
+#include <qdebug.h>
+#include <qlist.h>
+#include <qiterator.h>
+#include <qtextcodec.h>
+#include <QUuid>
+
+QT_BEGIN_NAMESPACE
+
+#define COMMAND_VERSION Doc::alias("version")
+int DitaXmlGenerator::id = 0;
+
+#define cxxapi_d_xref Doc::alias("cxxapi-d-xref")
+#define cxxclass Doc::alias("cxxclass")
+#define cxxdefine Doc::alias("cxxdefine")
+#define cxxenumeration Doc::alias("cxxenumeration")
+#define cxxfile Doc::alias("cxxfile")
+#define cxxfunction Doc::alias("cxxfunction")
+#define cxxstruct Doc::alias("cxxstruct")
+#define cxxtypedef Doc::alias("cxxtypedef")
+#define cxxunion Doc::alias("cxxunion")
+#define cxxvariable Doc::alias("cxxvariable")
+
+#define CXXAPIMAP Doc::alias("cxxAPIMap")
+#define CXXCLASSREF Doc::alias("cxxClassRef")
+#define CXXDEFINEREF Doc::alias("cxxDefineRef")
+#define CXXENUMERATIONREF Doc::alias("cxxEnumerationRef")
+#define CXXFILEREF Doc::alias("cxxFileRef")
+#define CXXFUNCTIONREF Doc::alias("cxxFunctionRef")
+#define CXXSTRUCTREF Doc::alias("cxxStructRef")
+#define CXXTYPDEFREF Doc::alias("cxxTypedefRef")
+#define CXXUNIONREF Doc::alias("cxxUnionRef")
+#define CXXVARIABLEREF Doc::alias("cxxVariableRef")
+
+#define CXXCLASS Doc::alias("cxxClass")
+#define CXXCLASSABSTRACT Doc::alias("cxxClassAbstract")
+#define CXXCLASSACCESSSPECIFIER Doc::alias("cxxClassAccessSpecifier")
+#define CXXCLASSAPIITEMLOCATION Doc::alias("cxxClassAPIItemLocation")
+#define CXXCLASSBASECLASS Doc::alias("cxxClassBaseClass")
+#define CXXCLASSBASECLASSSTRUCT Doc::alias("cxxClassBaseStruct")
+#define CXXCLASSBASEUNION Doc::alias("cxxClassBaseUnion")
+#define CXXCLASSDECLARATIONFILE Doc::alias("cxxClassDeclarationFile")
+#define CXXCLASSDECLARATIONFILELINE Doc::alias("cxxClassDeclarationFileLine")
+#define CXXCLASSDEFINITION Doc::alias("cxxClassDefinition")
+#define CXXCLASSDEFINITIONFILE Doc::alias("cxxClassDefinitionFile")
+#define CXXCLASSDEFINITIONFILEEND Doc::alias("cxxClassDefinitionFileLineEnd")
+#define CXXCLASSDEFINITIONFILESTART Doc::alias("cxxClassDefinitionFileLineStart")
+#define CXXCLASSDERIVATION Doc::alias("cxxClassDerivation")
+#define CXXCLASSDERIVATIONACCESSSPECIFIER Doc::alias("cxxClassDerivationAccessSpecifier")
+#define CXXCLASSDERIVATIONS Doc::alias("cxxClassDerivations")
+#define CXXCLASSDERIVATIONVIRTUAL Doc::alias("cxxClassDerivationVirtual")
+#define CXXCLASSDETAIL Doc::alias("cxxClassDetail")
+#define CXXCLASSENUMERATIONINHERITED Doc::alias("cxxClassEnumerationInherited")
+#define CXXCLASSENUMERATORINHERITED Doc::alias("cxxClassEnumeratorInherited")
+#define CXXCLASSFUNCTIONINHERITED Doc::alias("cxxClassFunctionInherited")
+#define CXXCLASSINHERITS Doc::alias("cxxClassInherits")
+#define CXXCLASSINHERITSDETAIL Doc::alias("cxxClassInheritsDetail")
+#define CXXCLASSNESTED Doc::alias("cxxClassNested")
+#define CXXCLASSNESTEDCLASS Doc::alias("cxxClassNestedClass")
+#define CXXCLASSNESTEDDETAIL Doc::alias("cxxClassNestedDetail")
+#define CXXCLASSNESTEDSTRUCT Doc::alias("cxxClassNestedStruct")
+#define CXXCLASSNESTEDUNION Doc::alias("cxxClassNestedUnion")
+#define CXXCLASSTEMPLATEPARAMETER Doc::alias("cxxClassTemplateParameter")
+#define CXXCLASSTEMPLATEPARAMETERS Doc::alias("cxxClassTemplateParameters")
+#define CXXCLASSTEMPLATEPARAMETERTYPE Doc::alias("cxxClassTemplateParameterType")
+#define CXXCLASSVARIABLEINHERITED Doc::alias("cxxClassVariableInherited")
+
+#define CXXDEFINE Doc::alias("cxxDefine")
+#define CXXDEFINEACCESSSPECIFIER Doc::alias("cxxDefineAccessSpecifier")
+#define CXXDEFINEAPIITEMLOCATION Doc::alias("cxxDefineAPIItemLocation")
+#define CXXDEFINEDECLARATIONFILE Doc::alias("cxxDefineDeclarationFile")
+#define CXXDEFINEDECLARATIONFILELINE Doc::alias("cxxDefineDeclarationFileLine")
+#define CXXDEFINEDEFINITION Doc::alias("cxxDefineDefinition")
+#define CXXDEFINEDETAIL Doc::alias("cxxDefineDetail")
+#define CXXDEFINENAMELOOKUP Doc::alias("cxxDefineNameLookup")
+#define CXXDEFINEPARAMETER Doc::alias("cxxDefineParameter")
+#define CXXDEFINEPARAMETERDECLARATIONNAME Doc::alias("cxxDefineParameterDeclarationName")
+#define CXXDEFINEPARAMETERS Doc::alias("cxxDefineParameters")
+#define CXXDEFINEPROTOTYPE Doc::alias("cxxDefinePrototype")
+#define CXXDEFINEREIMPLEMENTED Doc::alias("cxxDefineReimplemented")
+
+#define CXXENUMERATION Doc::alias("cxxEnumeration")
+#define CXXENUMERATIONACCESSSPECIFIER Doc::alias("cxxEnumerationAccessSpecifier")
+#define CXXENUMERATIONAPIITEMLOCATION Doc::alias("cxxEnumerationAPIItemLocation")
+#define CXXENUMERATIONDECLARATIONFILE Doc::alias("cxxEnumerationDeclarationFile")
+#define CXXENUMERATIONDECLARATIONFILELINE Doc::alias("cxxEnumerationDeclarationFileLine")
+#define CXXENUMERATIONDEFINITION Doc::alias("cxxEnumerationDefinition")
+#define CXXENUMERATIONDEFINITIONFILE Doc::alias("cxxEnumerationDefinitionFile")
+#define CXXENUMERATIONDEFINITIONFILELINEEND Doc::alias("cxxEnumerationDefinitionFileLineEnd")
+#define CXXENUMERATIONDEFINITIONFILELINESTART Doc::alias("cxxEnumerationDefinitionFileLineStart")
+#define CXXENUMERATIONDETAIL Doc::alias("cxxEnumerationDetail")
+#define CXXENUMERATIONNAMELOOKUP Doc::alias("cxxEnumerationNameLookup")
+#define CXXENUMERATIONPROTOTYPE Doc::alias("cxxEnumerationPrototype")
+#define CXXENUMERATIONREIMPLEMENTED Doc::alias("cxxEnumerationReimplemented")
+#define CXXENUMERATIONSCOPEDNAME Doc::alias("cxxEnumerationScopedName")
+#define CXXENUMERATOR Doc::alias("cxxEnumerator")
+#define CXXENUMERATORAPIITEMLOCATION Doc::alias("cxxEnumeratorAPIItemLocation")
+#define CXXENUMERATORDECLARATIONFILE Doc::alias("cxxEnumeratorDeclarationFile")
+#define CXXENUMERATORDECLARATIONFILELINE Doc::alias("cxxEnumeratorDeclarationFileLine")
+#define CXXENUMERATORINITIALISER Doc::alias("cxxEnumeratorInitialiser")
+#define CXXENUMERATORNAMELOOKUP Doc::alias("cxxEnumeratorNameLookup")
+#define CXXENUMERATORPROTOTYPE Doc::alias("cxxEnumeratorPrototype")
+#define CXXENUMERATORS Doc::alias("cxxEnumerators")
+#define CXXENUMERATORSCOPEDNAME Doc::alias("cxxEnumeratorScopedName")
+
+#define CXXFILE_INFO_TYPES Doc::alias("cxxFile-info-types")
+#define CXXFILE_TYPES_DEFAULT Doc::alias("cxxFile-types-default")
+#define CXXFILE Doc::alias("cxxFile")
+#define CXXFILEAPIITMELOCATION Doc::alias("cxxFileAPIItemLocation")
+#define CXXFILEDECLARATIONFILE Doc::alias("cxxFileDeclarationFile")
+
+#define CXXFUNCTION Doc::alias("cxxFunction")
+#define CXXFUNCTIONACCESSSPECIFIER Doc::alias("cxxFunctionAccessSpecifier")
+#define CXXFUNCTIONAPIITEMLOCATION Doc::alias("cxxFunctionAPIItemLocation")
+#define CXXFUNCTIONCONST Doc::alias("cxxFunctionConst")
+#define CXXFUNCTIONCONSTRUCTOR Doc::alias("cxxFunctionConstructor")
+#define CXXFUNCTIONDECLARATIONFILE Doc::alias("cxxFunctionDeclarationFile")
+#define CXXFUNCTIONDECLARATIONFILELINE Doc::alias("cxxFunctionDeclarationFileLine")
+#define CXXFUNCTIONDECLAREDTYPE Doc::alias("cxxFunctionDeclaredType")
+#define CXXFUNCTIONDEFINITION Doc::alias("cxxFunctionDefinition")
+#define CXXFUNCTIONDEFINITIONFILE Doc::alias("cxxFunctionDefinitionFile")
+#define CXXFUNCTIONDEFINITIONFILELINEEND Doc::alias("cxxFunctionDefinitionFileLineEnd")
+#define CXXFUNCTIONDEFINITIONFILELINESTART Doc::alias("cxxFunctionDefinitionFileLineStart")
+#define CXXFUNCTIONDESTRUCTOR Doc::alias("cxxFunctionDestructor")
+#define CXXFUNCTIONDETAIL Doc::alias("cxxFunctionDetail")
+#define CXXFUNCTIONEXPLICIT Doc::alias("cxxFunctionExplicit")
+#define CXXFUNCTIONINLINE Doc::alias("cxxFunctionInline")
+#define CXXFUNCTIONNAMELOOKUP Doc::alias("cxxFunctionNameLookup")
+#define CXXFUNCTIONPARAMETER Doc::alias("cxxFunctionParameter")
+#define CXXFUNCTIONPARAMETERDECLARATIONNAME Doc::alias("cxxFunctionParameterDeclarationName")
+#define CXXFUNCTIONPARAMETERDECLAREDTYPE Doc::alias("cxxFunctionParameterDeclaredType")
+#define CXXFUNCTIONPARAMETERDEFAULTVALUE Doc::alias("cxxFunctionParameterDefaultValue")
+#define CXXFUNCTIONPARAMETERDEFINITIONNAME Doc::alias("cxxFunctionParameterDefinitionName")
+#define CXXFUNCTIONPARAMETERS Doc::alias("cxxFunctionParameters")
+#define CXXFUNCTIONPROTOTYPE Doc::alias("cxxFunctionPrototype")
+#define CXXFUNCTIONPUREVIRTUAL Doc::alias("cxxFunctionPureVirtual")
+#define CXXFUNCTIONREIMPLEMENTED Doc::alias("cxxFunctionReimplemented")
+#define CXXFUNCTIONRETURNTYPE Doc::alias("cxxFunctionReturnType")
+#define CXXFUNCTIONSCOPEDNAME Doc::alias("cxxFunctionScopedName")
+#define CXXFUNCTIONSTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxFunctionStorageClassSpecifierExtern")
+#define CXXFUNCTIONSTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxFunctionStorageClassSpecifierMutable")
+#define CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxFunctionStorageClassSpecifierStatic")
+#define CXXFUNCTIONTEMPLATEPARAMETER Doc::alias("cxxFunctionTemplateParameter")
+#define CXXFUNCTIONTEMPLATEPARAMETERS Doc::alias("cxxFunctionTemplateParameters")
+#define CXXFUNCTIONTEMPLATEPARAMETERTYPE Doc::alias("cxxFunctionTemplateParameterType")
+#define CXXFUNCTIONVIRTUAL Doc::alias("cxxFunctionVirtual")
+#define CXXFUNCTIONVOLATILE Doc::alias("cxxFunctionVolatile")
+
+#define CXXSTRUCT Doc::alias("cxxStruct")
+#define CXXSTRUCTABSTRACT Doc::alias("cxxStructAbstract")
+#define CXXSTRUCTACCESSSPECIFIER Doc::alias("cxxStructAccessSpecifier")
+#define CXXSTRUCTAPIITEMLOCATION Doc::alias("cxxStructAPIItemLocation")
+#define CXXSTRUCTBASECLASS Doc::alias("cxxStructBaseClass")
+#define CXXSTRUCTBASESTRUCT Doc::alias("cxxStructBaseStruct")
+#define CXXSTRUCTBASEUNION Doc::alias("cxxStructBaseUnion")
+#define CXXSTRUCTDECLARATIONFILE Doc::alias("cxxStructDeclarationFile")
+#define CXXSTRUCTDECLARATIONFILELINE Doc::alias("cxxStructDeclarationFileLine")
+#define CXXSTRUCTDEFINITION Doc::alias("cxxStructDefinition")
+#define CXXSTRUCTDEFINITIONFILE Doc::alias("cxxStructDefinitionFile")
+#define CXXSTRUCTDEFINITIONFILELINEEND Doc::alias("cxxStructDefinitionFileLineEnd")
+#define CXXSTRUCTDEFINITIONFILELINESTART Doc::alias("cxxStructDefinitionFileLineStart")
+#define CXXSTRUCTDERIVATION Doc::alias("cxxStructDerivation")
+#define CXXSTRUCTDERIVATIONACCESSSPECIFIER Doc::alias("cxxStructDerivationAccessSpecifier")
+#define CXXSTRUCTDERIVATIONS Doc::alias("cxxStructDerivations")
+#define CXXSTRUCTDERIVATIONVIRTUAL Doc::alias("cxxStructDerivationVirtual")
+#define CXXSTRUCTDETAIL Doc::alias("cxxStructDetail")
+#define CXXSTRUCTENUMERATIONINHERITED Doc::alias("cxxStructEnumerationInherited")
+#define CXXSTRUCTENUMERATORINHERITED Doc::alias("cxxStructEnumeratorInherited")
+#define CXXSTRUCTFUNCTIONINHERITED Doc::alias("cxxStructFunctionInherited")
+#define CXXSTRUCTINHERITS Doc::alias("cxxStructInherits")
+#define CXXSTRUCTINHERITSDETAIL Doc::alias("cxxStructInheritsDetail")
+#define CXXSTRUCTNESTED Doc::alias("cxxStructNested")
+#define CXXSTRUCTNESTEDCLASS Doc::alias("cxxStructNestedClass")
+#define CXXSTRUCTNESTEDDETAIL Doc::alias("cxxStructNestedDetail")
+#define CXXSTRUCTNESTEDSTRUCT Doc::alias("cxxStructNestedStruct")
+#define CXXSTRUCTNESTEDUNION Doc::alias("cxxStructNestedUnion")
+#define CXXSTRUCTTEMPLATEPARAMETER Doc::alias("cxxStructTemplateParameter")
+#define CXXSTRUCTTEMPLATEPARAMETERS Doc::alias("cxxStructTemplateParameters")
+#define CXXSTRUCTTEMPLATEPARAMETERTYPE Doc::alias("cxxStructTemplateParameterType")
+#define CXXSTRUCTVARIABLEINHERITED Doc::alias("cxxStructVariableInherited")
+
+#define CXXTYPEDEF Doc::alias("cxxTypedef")
+#define CXXTYPEDEFACCESSSPECIFIER Doc::alias("cxxTypedefAccessSpecifier")
+#define CXXTYPEDEFAPIITEMLOCATION Doc::alias("cxxTypedefAPIItemLocation")
+#define CXXTYPEDEFDECLARATIONFILE Doc::alias("cxxTypedefDeclarationFile")
+#define CXXTYPEDEFDECLARATIONFILELINE Doc::alias("cxxTypedefDeclarationFileLine")
+#define CXXTYPEDEFDECLAREDTYPE Doc::alias("cxxTypedefDeclaredType")
+#define CXXTYPEDEFDEFINITION Doc::alias("cxxTypedefDefinition")
+#define CXXTYPEDEFDETAIL Doc::alias("cxxTypedefDetail")
+#define CXXTYPEDEFNAMELOOKUP Doc::alias("cxxTypedefNameLookup")
+#define CXXTYPEDEFPROTOTYPE Doc::alias("cxxTypedefPrototype")
+#define CXXTYPEDEFREIMPLEMENTED Doc::alias("cxxTypedefReimplemented")
+#define CXXTYPEDEFSCOPEDNAME Doc::alias("cxxTypedefScopedName")
+
+#define CXXUNION Doc::alias("cxxUnion")
+#define CXXUNIONABSTRACT Doc::alias("cxxUnionAbstract")
+#define CXXUNIONACCESSSPECIFIER Doc::alias("cxxUnionAccessSpecifier")
+#define CXXUNIONAPIITEMLOCATION Doc::alias("cxxUnionAPIItemLocation")
+#define CXXUNIONDECLARATIONFILE Doc::alias("cxxUnionDeclarationFile")
+#define CXXUNIONDECLARATIONFILELINE Doc::alias("cxxUnionDeclarationFileLine")
+#define CXXUNIONDEFINITION Doc::alias("cxxUnionDefinition")
+#define CXXUNIONDEFINITIONFILE Doc::alias("cxxUnionDefinitionFile")
+#define CXXUNIONDEFINITIONFILELINEEND Doc::alias("cxxUnionDefinitionFileLineEnd")
+#define CXXUNIONDEFINITIONFILELINESTART Doc::alias("cxxUnionDefinitionFileLineStart")
+#define CXXUNIONDETAIL Doc::alias("cxxUnionDetail")
+#define CXXUNIONNESTED Doc::alias("cxxUnionNested")
+#define CXXUNIONNESTEDCLASS Doc::alias("cxxUnionNestedClass")
+#define CXXUNIONNESTEDDETAIL Doc::alias("cxxUnionNestedDetail")
+#define CXXUNIONNESTEDSTRUCT Doc::alias("cxxUnionNestedStruct")
+#define CXXUNIONNESTEDUNION Doc::alias("cxxUnionNestedUnion")
+#define CXXUNIONTEMPLATEPARAMETER Doc::alias("cxxUnionTemplateParameter")
+#define CXXUNIONTEMPLATEPARAMETERS Doc::alias("cxxUnionTemplateParameters")
+#define CXXUNIONTEMPLATEPARAMETERTYPE Doc::alias("cxxUnionTemplateParameterType")
+
+#define CXXVARIABLE Doc::alias("cxxVariable")
+#define CXXVARIABLEACCESSSPECIFIER Doc::alias("cxxVariableAccessSpecifier")
+#define CXXVARIABLEAPIITEMLOCATION Doc::alias("cxxVariableAPIItemLocation")
+#define CXXVARIABLECONST Doc::alias("cxxVariableConst")
+#define CXXVARIABLEDECLARATIONFILE Doc::alias("cxxVariableDeclarationFile")
+#define CXXVARIABLEDECLARATIONFILELINE Doc::alias("cxxVariableDeclarationFileLine")
+#define CXXVARIABLEDECLAREDTYPE Doc::alias("cxxVariableDeclaredType")
+#define CXXVARIABLEDEFINITION Doc::alias("cxxVariableDefinition")
+#define CXXVARIABLEDETAIL Doc::alias("cxxVariableDetail")
+#define CXXVARIABLENAMELOOKUP Doc::alias("cxxVariableNameLookup")
+#define CXXVARIABLEPROTOTYPE Doc::alias("cxxVariablePrototype")
+#define CXXVARIABLEREIMPLEMENTED Doc::alias("cxxVariableReimplemented")
+#define CXXVARIABLESCOPEDNAME Doc::alias("cxxVariableScopedName")
+#define CXXVARIABLESTORAGECLASSSPECIFIEREXTERN Doc::alias("cxxVariableStorageClassSpecifierExtern")
+#define CXXVARIABLESTORAGECLASSSPECIFIERMUTABLE Doc::alias("cxxVariableStorageClassSpecifierMutable")
+#define CXXVARIABLESTORAGECLASSSPECIFIERSTATIC Doc::alias("cxxVariableStorageClassSpecifierStatic")
+#define CXXVARIABLEVOLATILE Doc::alias("cxxVariableVolatile")
+
+#define APIREF Doc::alias("apiRef")
+#define APINAME Doc::alias("apiName")
+#define APIDETAIL Doc::alias("apiDetail")
+#define APISYNTAX Doc::alias("apiSyntax")
+#define APISYNTAXTEXT Doc::alias("apiSyntaxText")
+#define APISYNTAXITEM Doc::alias("apiSyntaxItem")
+#define APIDEF Doc::alias("apiDef")
+#define APIQUALIFIER Doc::alias("apiQualifier")
+#define APIRELATION Doc::alias("apiRelation")
+#define APITYPE Doc::alias("apiType")
+#define APIARRAY Doc::alias("apiArray")
+#define APIDATA Doc::alias("apiData")
+#define APIDEFNOTE Doc::alias("apiDefNote")
+#define APIDEFITEM Doc::alias("apiDefItem")
+#define APIITEMNAME Doc::alias("apiItemName")
+#define APIDESC Doc::alias("apiDesc")
+#define APIIMPL Doc::alias("apiImpl")
+
+#define APIPACKAGE Doc::alias("apiPackage")
+
+#define APICLASSIFIER Doc::alias("apiClassifier")
+#define APICLASSIFIERDETAIL Doc::alias("apiClassifierDetail")
+#define APICLASSIFIERDEF Doc::alias("apiClassifierDef")
+#define APICLASSIFIERMEMBER Doc::alias("apiClassifierMember")
+#define APIOTHERCLASSIFIER Doc::alias("apiOtherClassifier")
+#define APIBASECLASSIFIER Doc::alias("apiBaseClassifier")
+
+#define APIOPERATION Doc::alias("apiOperation")
+#define APIOPERATIONDETAIL Doc::alias("apiOperationDetail")
+#define APIOPERATIONDEF Doc::alias("apiOperationDef")
+#define APIRETURN Doc::alias("apiReturn")
+#define APIPARAM Doc::alias("apiParam")
+#define APIEVENT Doc::alias("apiEvent")
+#define APIOPERATIONDEFITEM Doc::alias("apiOperationDefItem")
+#define APIOPERATIONCLASSIFIER Doc::alias("apiOperationClassifier")
+#define APICONSTRUCTORDEF Doc::alias("apiConstructorDef")
+
+#define APIVALUE Doc::alias("apiValue")
+#define APIVALUEDETAIL Doc::alias("apiValueDetail")
+#define APIVALUEDEF Doc::alias("apiValueDef")
+#define APIVALUEMEMBER Doc::alias("apiValueMember")
+#define APIVALUECLASSIFIER Doc::alias("apiValueClassifier")
+
+#define APIclassifier Doc::alias("apiclassifier")
+#define APIoperation Doc::alias("apioperation")
+#define APIpackage Doc::alias("apipackage")
+#define APIvalue Doc::alias("apivalue")
+
+#define APIMAP Doc::alias("apiMap")
+#define APIITEMREF Doc::alias("apiItemRef")
+
+#define SHORTDESC Doc::alias("shortdesc")
+
+QString DitaXmlGenerator::sinceTitles[] =
+ {
+ " New Namespaces",
+ " New Classes",
+ " New Member Functions",
+ " New Functions in Namespaces",
+ " New Global Functions",
+ " New Macros",
+ " New Enum Types",
+ " New Typedefs",
+ " New Properties",
+ " New Variables",
+ " New QML Elements",
+ " New Qml Properties",
+ " New Qml Signals",
+ " New Qml Methods",
+ ""
+ };
+
+static bool showBrokenLinks = false;
+
+static void addLink(const QString &linkTarget,
+ const QStringRef &nestedStuff,
+ QString *res)
+{
+ if (!linkTarget.isEmpty()) {
+ *res += "<xref href=\"";
+ *res += linkTarget;
+ *res += "\">";
+ *res += nestedStuff;
+ *res += "</xref>";
+ }
+ else {
+ *res += nestedStuff;
+ }
+}
+
+
+DitaXmlGenerator::DitaXmlGenerator()
+ : inLink(false),
+ inContents(false),
+ inSectionHeading(false),
+ inTableHeader(false),
+ numTableRows(0),
+ threeColumnEnumValueTable(true),
+ offlineDocs(true),
+ funcLeftParen("\\S(\\()"),
+ myTree(0),
+ slow(false),
+ obsoleteLinks(false),
+ noLinks(0)
+{
+}
+
+DitaXmlGenerator::~DitaXmlGenerator()
+{
+ // nothing yet.
+}
+
+void DitaXmlGenerator::initializeGenerator(const Config &config)
+{
+ static const struct {
+ const char *key;
+ const char *tag;
+ } defaults[] = {
+ { ATOM_FORMATTING_BOLD, "b" },
+ { ATOM_FORMATTING_INDEX, "<!--" },
+ { ATOM_FORMATTING_ITALIC, "i" },
+ { ATOM_FORMATTING_PARAMETER, "i" },
+ { ATOM_FORMATTING_SUBSCRIPT, "sub" },
+ { ATOM_FORMATTING_SUPERSCRIPT, "sup" },
+ { ATOM_FORMATTING_TELETYPE, "tt", },
+ { ATOM_FORMATTING_UNDERLINE, "u", },
+ { 0, 0 }
+ };
+
+ Generator::initializeGenerator(config);
+ obsoleteLinks = config.getBool(QLatin1String(CONFIG_OBSOLETELINKS));
+ setImageFileExtensions(QStringList() << "png" << "jpg" << "jpeg" << "gif");
+ int i = 0;
+ while (defaults[i].key) {
+ formattingLeftMap().insert(defaults[i].key, defaults[i].tag);
+ i++;
+ }
+
+ style = config.getString(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_STYLE);
+ postHeader = config.getString(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_POSTHEADER);
+ postPostHeader = config.getString(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_POSTPOSTHEADER);
+ footer = config.getString(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_FOOTER);
+ address = config.getString(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_ADDRESS);
+ pleaseGenerateMacRef = config.getBool(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_GENERATEMACREFS);
+
+ project = config.getString(CONFIG_PROJECT);
+ projectDescription = config.getString(CONFIG_DESCRIPTION);
+ if (projectDescription.isEmpty() && !project.isEmpty())
+ projectDescription = project + " Reference Documentation";
+
+ projectUrl = config.getString(CONFIG_URL);
+
+ outputEncoding = config.getString(CONFIG_OUTPUTENCODING);
+ if (outputEncoding.isEmpty())
+ outputEncoding = QLatin1String("ISO-8859-1");
+ outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit());
+
+ naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE);
+ if (naturalLanguage.isEmpty())
+ naturalLanguage = QLatin1String("en");
+
+ QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
+ QSet<QString>::ConstIterator edition = editionNames.begin();
+ while (edition != editionNames.end()) {
+ QString editionName = *edition;
+ QStringList editionModules = config.getStringList(CONFIG_EDITION +
+ Config::dot +
+ editionName +
+ Config::dot +
+ "modules");
+ QStringList editionGroups = config.getStringList(CONFIG_EDITION +
+ Config::dot +
+ editionName +
+ Config::dot +
+ "groups");
+
+ if (!editionModules.isEmpty())
+ editionModuleMap[editionName] = editionModules;
+ if (!editionGroups.isEmpty())
+ editionGroupMap[editionName] = editionGroups;
+
+ ++edition;
+ }
+
+ slow = config.getBool(CONFIG_SLOW);
+
+ stylesheets = config.getStringList(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_STYLESHEETS);
+ customHeadElements = config.getStringList(DitaXmlGenerator::format() +
+ Config::dot +
+ DITAXMLGENERATOR_CUSTOMHEADELEMENTS);
+ codeIndent = config.getInt(CONFIG_CODEINDENT);
+
+}
+
+void DitaXmlGenerator::terminateGenerator()
+{
+ Generator::terminateGenerator();
+}
+
+QString DitaXmlGenerator::format()
+{
+ return "DITAXML";
+}
+
+/*!
+ Calls lookupGuid() to get a GUID for \a text, then writes
+ it to the XML stream as an "id" attribute, and returns it.
+ */
+QString DitaXmlGenerator::writeGuidAttribute(QString text)
+{
+ QString guid = lookupGuid(text);
+ writer.writeAttribute("id",guid);
+ return guid;
+}
+
+/*!
+ Looks up \a text in the GUID map. If it finds \a text,
+ it returns the associated GUID. Otherwise it inserts
+ \a text into the map with a new GUID, and it returns
+ the new GUID.
+ */
+QString DitaXmlGenerator::lookupGuid(QString text)
+{
+ QMap<QString, QString>::const_iterator i = name2guidMap.find(text);
+ if (i != name2guidMap.end())
+ return i.value();
+ QString guid = QUuid::createUuid().toString();
+ name2guidMap.insert(text,guid);
+ return guid;
+}
+
+/*!
+ This is where the DITA XML files are written.
+ \note The file generation is done in the base class,
+ PageGenerator::generateTree().
+ */
+void DitaXmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
+{
+ myTree = tree;
+ nonCompatClasses.clear();
+ mainClasses.clear();
+ compatClasses.clear();
+ obsoleteClasses.clear();
+ moduleClassMap.clear();
+ moduleNamespaceMap.clear();
+ funcIndex.clear();
+ legaleseTexts.clear();
+ serviceClasses.clear();
+ qmlClasses.clear();
+ findAllClasses(tree->root());
+ findAllFunctions(tree->root());
+ findAllLegaleseTexts(tree->root());
+ findAllNamespaces(tree->root());
+ findAllSince(tree->root());
+
+ PageGenerator::generateTree(tree, marker);
+}
+
+void DitaXmlGenerator::startText(const Node* /* relative */,
+ CodeMarker* /* marker */)
+{
+ inLink = false;
+ inContents = false;
+ inSectionHeading = false;
+ inTableHeader = false;
+ numTableRows = 0;
+ threeColumnEnumValueTable = true;
+ link.clear();
+ sectionNumber.clear();
+}
+
+/*!
+ Generate html from an instance of Atom.
+ */
+int DitaXmlGenerator::generateAtom(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ int skipAhead = 0;
+ QString hx;
+ static bool in_para = false;
+ QString guid;
+
+ switch (atom->type()) {
+ case Atom::AbstractLeft:
+ break;
+ case Atom::AbstractRight:
+ break;
+ case Atom::AutoLink:
+ if ((noLinks > 0) && !inLink && !inContents && !inSectionHeading) {
+ const Node *node = 0;
+ QString link = getLink(atom, relative, marker, &node);
+ if (!link.isEmpty()) {
+ beginLink(link, node, relative, marker);
+ generateLink(atom, relative, marker);
+ endLink();
+ }
+ else {
+ writer.writeCharacters(protectEnc(atom->string()));
+ }
+ }
+ else {
+ writer.writeCharacters(protectEnc(atom->string()));
+ }
+ break;
+ case Atom::BaseName:
+ break;
+ case Atom::BriefLeft:
+ if (relative->type() == Node::Fake) {
+ skipAhead = skipAtoms(atom, Atom::BriefRight);
+ break;
+ }
+ writer.writeStartElement(SHORTDESC);
+ if (relative->type() == Node::Property ||
+ relative->type() == Node::Variable) {
+ QString str;
+ atom = atom->next();
+ while (atom != 0 && atom->type() != Atom::BriefRight) {
+ if (atom->type() == Atom::String ||
+ atom->type() == Atom::AutoLink)
+ str += atom->string();
+ skipAhead++;
+ atom = atom->next();
+ }
+ str[0] = str[0].toLower();
+ if (str.right(1) == ".")
+ str.truncate(str.length() - 1);
+ writer.writeCharacters("This ");
+ if (relative->type() == Node::Property)
+ writer.writeCharacters("property");
+ else
+ writer.writeCharacters("variable");
+ QStringList words = str.split(" ");
+ if (!(words.first() == "contains" || words.first() == "specifies"
+ || words.first() == "describes" || words.first() == "defines"
+ || words.first() == "holds" || words.first() == "determines"))
+ writer.writeCharacters(" holds ");
+ else
+ writer.writeCharacters(" ");
+ writer.writeCharacters(str + ".");
+ }
+ break;
+ case Atom::BriefRight:
+ if (relative->type() != Node::Fake) {
+ writer.writeEndElement(); // </shortdesc>
+ }
+ break;
+ case Atom::C:
+ writer.writeStartElement(formattingLeftMap()[ATOM_FORMATTING_TELETYPE]);
+ if (inLink) {
+ writer.writeCharacters(protectEnc(plainCode(atom->string())));
+ }
+ else {
+ writer.writeCharacters(highlightedCode(atom->string(), marker, relative));
+ }
+ writer.writeEndElement(); // sse writeStartElement() above
+ break;
+ case Atom::Code:
+ writer.writeStartElement("pre");
+ writer.writeAttribute("outputclass","highlightedCode");
+ writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,
+ relative)));
+ writer.writeEndElement(); // </pre>
+ break;
+#ifdef QDOC_QML
+ case Atom::Qml:
+ writer.writeStartElement("pre");
+ writer.writeAttribute("outputclass","highlightedCode");
+ writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,
+ relative)));
+ writer.writeEndElement(); // pre
+ break;
+#endif
+ case Atom::CodeNew:
+ writer.writeStartElement("p");
+ writer.writeCharacters("you can rewrite it as");
+ writer.writeEndElement(); // </p>
+ writer.writeStartElement("pre");
+ writer.writeAttribute("outputclass","highlightedCode");
+ writer.writeCharacters(trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,
+ relative)));
+ writer.writeEndElement(); // </pre>
+ break;
+ case Atom::CodeOld:
+ writer.writeStartElement("p");
+ writer.writeCharacters("For example, if you have code like");
+ writer.writeEndElement(); // </p>
+ // fallthrough
+ case Atom::CodeBad:
+ writer.writeStartElement("pre");
+ writer.writeAttribute("outputclass","highlightedCode");
+ writer.writeCharacters(trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string())))));
+ writer.writeEndElement(); // </pre>
+ break;
+ case Atom::FootnoteLeft:
+ // ### For now
+ if (in_para) {
+ writer.writeEndElement(); // </p>
+ in_para = false;
+ }
+ writer.writeCharacters("<!-- ");
+ break;
+ case Atom::FootnoteRight:
+ // ### For now
+ writer.writeCharacters("-->");
+ break;
+ case Atom::FormatElse:
+ case Atom::FormatEndif:
+ case Atom::FormatIf:
+ break;
+ case Atom::FormattingLeft:
+ writer.writeStartElement(formattingLeftMap()[atom->string()]);
+ if (atom->string() == ATOM_FORMATTING_PARAMETER) {
+ if (atom->next() != 0 && atom->next()->type() == Atom::String) {
+ QRegExp subscriptRegExp("([a-z]+)_([0-9n])");
+ if (subscriptRegExp.exactMatch(atom->next()->string())) {
+ writer.writeCharacters(subscriptRegExp.cap(1));
+ writer.writeStartElement("sub");
+ writer.writeCharacters(subscriptRegExp.cap(2));
+ writer.writeEndElement(); // </sub>
+ skipAhead = 1;
+ }
+ }
+ }
+ break;
+ case Atom::FormattingRight:
+ if (atom->string() == ATOM_FORMATTING_LINK) {
+ endLink();
+ }
+ else {
+ writer.writeEndElement(); // ?
+ }
+ break;
+ case Atom::AnnotatedList:
+ {
+ QList<Node*> values = myTree->groups().values(atom->string());
+ NodeMap nodeMap;
+ for (int i = 0; i < values.size(); ++i) {
+ const Node* n = values.at(i);
+ if ((n->status() != Node::Internal) && (n->access() != Node::Private)) {
+ nodeMap.insert(n->nameForLists(),n);
+ }
+ }
+ generateAnnotatedList(relative, marker, nodeMap);
+ }
+ break;
+ case Atom::GeneratedList:
+ if (atom->string() == "annotatedclasses") {
+ generateAnnotatedList(relative, marker, nonCompatClasses);
+ }
+ else if (atom->string() == "classes") {
+ generateCompactList(relative, marker, nonCompatClasses, true);
+ }
+ else if (atom->string() == "qmlclasses") {
+ generateCompactList(relative, marker, qmlClasses, true);
+ }
+ else if (atom->string().contains("classesbymodule")) {
+ QString arg = atom->string().trimmed();
+ QString moduleName = atom->string().mid(atom->string().indexOf(
+ "classesbymodule") + 15).trimmed();
+ if (moduleClassMap.contains(moduleName))
+ generateAnnotatedList(relative, marker, moduleClassMap[moduleName]);
+ }
+ else if (atom->string().contains("classesbyedition")) {
+
+ QString arg = atom->string().trimmed();
+ QString editionName = atom->string().mid(atom->string().indexOf(
+ "classesbyedition") + 16).trimmed();
+
+ if (editionModuleMap.contains(editionName)) {
+
+ // Add all classes in the modules listed for that edition.
+ NodeMap editionClasses;
+ foreach (const QString &moduleName, editionModuleMap[editionName]) {
+ if (moduleClassMap.contains(moduleName))
+ editionClasses.unite(moduleClassMap[moduleName]);
+ }
+
+ // Add additional groups and remove groups of classes that
+ // should be excluded from the edition.
+
+ QMultiMap <QString, Node *> groups = myTree->groups();
+ foreach (const QString &groupName, editionGroupMap[editionName]) {
+ QList<Node *> groupClasses;
+ if (groupName.startsWith("-")) {
+ groupClasses = groups.values(groupName.mid(1));
+ foreach (const Node *node, groupClasses)
+ editionClasses.remove(node->name());
+ }
+ else {
+ groupClasses = groups.values(groupName);
+ foreach (const Node *node, groupClasses)
+ editionClasses.insert(node->name(), node);
+ }
+ }
+ generateAnnotatedList(relative, marker, editionClasses);
+ }
+ }
+ else if (atom->string() == "classhierarchy") {
+ generateClassHierarchy(relative, marker, nonCompatClasses);
+ }
+ else if (atom->string() == "compatclasses") {
+ generateCompactList(relative, marker, compatClasses, false);
+ }
+ else if (atom->string() == "obsoleteclasses") {
+ generateCompactList(relative, marker, obsoleteClasses, false);
+ }
+ else if (atom->string() == "functionindex") {
+ generateFunctionIndex(relative, marker);
+ }
+ else if (atom->string() == "legalese") {
+ generateLegaleseList(relative, marker);
+ }
+ else if (atom->string() == "mainclasses") {
+ generateCompactList(relative, marker, mainClasses, true);
+ }
+ else if (atom->string() == "services") {
+ generateCompactList(relative, marker, serviceClasses, false);
+ }
+ else if (atom->string() == "overviews") {
+ generateOverviewList(relative, marker);
+ }
+ else if (atom->string() == "namespaces") {
+ generateAnnotatedList(relative, marker, namespaceIndex);
+ }
+ else if (atom->string() == "related") {
+ const FakeNode *fake = static_cast<const FakeNode *>(relative);
+ if (fake && !fake->groupMembers().isEmpty()) {
+ NodeMap groupMembersMap;
+ foreach (const Node *node, fake->groupMembers()) {
+ if (node->type() == Node::Fake)
+ groupMembersMap[fullName(node, relative, marker)] = node;
+ }
+ generateAnnotatedList(fake, marker, groupMembersMap);
+ }
+ }
+ else if (atom->string() == "relatedinline") {
+ const FakeNode *fake = static_cast<const FakeNode *>(relative);
+ if (fake && !fake->groupMembers().isEmpty()) {
+ // Reverse the list into the original scan order.
+ // Should be sorted. But on what? It may not be a
+ // regular class or page definition.
+ QList<const Node *> list;
+ foreach (const Node *node, fake->groupMembers())
+ list.prepend(node);
+ foreach (const Node *node, list)
+ generateBody(node, marker);
+ }
+ }
+ break;
+ case Atom::SinceList:
+ {
+ NewSinceMaps::const_iterator nsmap;
+ nsmap = newSinceMaps.find(atom->string());
+ NewClassMaps::const_iterator ncmap;
+ ncmap = newClassMaps.find(atom->string());
+ NewClassMaps::const_iterator nqcmap;
+ nqcmap = newQmlClassMaps.find(atom->string());
+ if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
+ QList<Section> sections;
+ QList<Section>::ConstIterator s;
+ for (int i=0; i<LastSinceType; ++i)
+ sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
+
+ NodeMultiMap::const_iterator n = nsmap.value().constBegin();
+ while (n != nsmap.value().constEnd()) {
+ const Node* node = n.value();
+ switch (node->type()) {
+ case Node::Fake:
+ if (node->subType() == Node::QmlClass) {
+ sections[QmlClass].appendMember((Node*)node);
+ }
+ break;
+ case Node::Namespace:
+ sections[Namespace].appendMember((Node*)node);
+ break;
+ case Node::Class:
+ sections[Class].appendMember((Node*)node);
+ break;
+ case Node::Enum:
+ sections[Enum].appendMember((Node*)node);
+ break;
+ case Node::Typedef:
+ sections[Typedef].appendMember((Node*)node);
+ break;
+ case Node::Function: {
+ const FunctionNode* fn = static_cast<const FunctionNode*>(node);
+ if (fn->isMacro())
+ sections[Macro].appendMember((Node*)node);
+ else {
+ Node* p = fn->parent();
+ if (p) {
+ if (p->type() == Node::Class)
+ sections[MemberFunction].appendMember((Node*)node);
+ else if (p->type() == Node::Namespace) {
+ if (p->name().isEmpty())
+ sections[GlobalFunction].appendMember((Node*)node);
+ else
+ sections[NamespaceFunction].appendMember((Node*)node);
+ }
+ else
+ sections[GlobalFunction].appendMember((Node*)node);
+ }
+ else
+ sections[GlobalFunction].appendMember((Node*)node);
+ }
+ break;
+ }
+ case Node::Property:
+ sections[Property].appendMember((Node*)node);
+ break;
+ case Node::Variable:
+ sections[Variable].appendMember((Node*)node);
+ break;
+ case Node::QmlProperty:
+ sections[QmlProperty].appendMember((Node*)node);
+ break;
+ case Node::QmlSignal:
+ sections[QmlSignal].appendMember((Node*)node);
+ break;
+ case Node::QmlMethod:
+ sections[QmlMethod].appendMember((Node*)node);
+ break;
+ default:
+ break;
+ }
+ ++n;
+ }
+
+ /*
+ First generate the table of contents.
+ */
+ writer.writeStartElement("ul");
+ s = sections.constBegin();
+ while (s != sections.constEnd()) {
+ if (!(*s).members.isEmpty()) {
+
+ writer.writeStartElement("li");
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",QString("#" + Doc::canonicalTitle((*s).name)));
+ writer.writeCharacters((*s).name);
+ writer.writeEndElement(); // </xref>
+ writer.writeEndElement(); // </li>
+ }
+ ++s;
+ }
+ writer.writeEndElement(); // </ul>
+
+ int idx = 0;
+ s = sections.constBegin();
+ while (s != sections.constEnd()) {
+ if (!(*s).members.isEmpty()) {
+ writer.writeStartElement("p");
+ writeGuidAttribute(Doc::canonicalTitle((*s).name));
+ writer.writeAttribute("outputclass","h3");
+ writer.writeCharacters(protectEnc((*s).name));
+ writer.writeEndElement(); // </p>
+ if (idx == Class)
+ generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
+ else if (idx == QmlClass)
+ generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
+ else if (idx == MemberFunction) {
+ ParentMaps parentmaps;
+ ParentMaps::iterator pmap;
+ NodeList::const_iterator i = s->members.constBegin();
+ while (i != s->members.constEnd()) {
+ Node* p = (*i)->parent();
+ pmap = parentmaps.find(p);
+ if (pmap == parentmaps.end())
+ pmap = parentmaps.insert(p,NodeMultiMap());
+ pmap->insert((*i)->name(),(*i));
+ ++i;
+ }
+ pmap = parentmaps.begin();
+ while (pmap != parentmaps.end()) {
+ NodeList nlist = pmap->values();
+ writer.writeStartElement("p");
+ writer.writeCharacters("Class ");
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",linkForNode(pmap.key(), 0));
+ QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
+ writer.writeCharacters(protectEnc(pieces.last()));
+ writer.writeEndElement(); // </xref>
+ writer.writeCharacters(":");
+ writer.writeEndElement(); // </p>
+
+ generateSection(nlist, 0, marker, CodeMarker::Summary);
+ writer.writeEmptyElement("br");
+ ++pmap;
+ }
+ }
+ else
+ generateSection(s->members, 0, marker, CodeMarker::Summary);
+ }
+ ++idx;
+ ++s;
+ }
+ }
+ }
+ break;
+ case Atom::Image:
+ case Atom::InlineImage:
+ {
+ QString fileName = imageFileName(relative, atom->string());
+ QString text;
+ if (atom->next() != 0)
+ text = atom->next()->string();
+ if (atom->type() == Atom::Image) {
+ writer.writeStartElement("p");
+ writer.writeAttribute("outputclass","centerAlign");
+ }
+ if (fileName.isEmpty()) {
+ writer.writeStartElement("font");
+ writer.writeAttribute("color","red");
+ writer.writeCharacters("[Missing image: ");
+ writer.writeCharacters(protectEnc(atom->string()));
+ writer.writeEndElement(); // </font>
+ }
+ else {
+ writer.writeStartElement("img");
+ writer.writeAttribute("src",protectEnc(fileName));
+ if (!text.isEmpty())
+ writer.writeAttribute("alt",protectEnc(text));
+ writer.writeEndElement(); // </img>
+ }
+ if (atom->type() == Atom::Image)
+ writer.writeEndElement(); // </p>
+ }
+ break;
+ case Atom::ImageText:
+ // nothing
+ break;
+ case Atom::LegaleseLeft:
+ writer.writeStartElement("p");
+ writer.writeAttribute("outputclass","legalese");
+ break;
+ case Atom::LegaleseRight:
+ writer.writeEndElement(); // </p>
+ break;
+ case Atom::LineBreak:
+ writer.writeEmptyElement("br");
+ break;
+ case Atom::Link:
+ {
+ const Node *node = 0;
+ QString myLink = getLink(atom, relative, marker, &node);
+ if (myLink.isEmpty()) {
+ relative->doc().location().warning(tr("Cannot link to '%1' in %2")
+ .arg(atom->string())
+ .arg(marker->plainFullName(relative)));
+ }
+ beginLink(myLink, node, relative, marker);
+ skipAhead = 1;
+ }
+ break;
+ case Atom::LinkNode:
+ {
+ const Node *node = CodeMarker::nodeForString(atom->string());
+ beginLink(linkForNode(node, relative), node, relative, marker);
+ skipAhead = 1;
+ }
+ break;
+ case Atom::ListLeft:
+ if (in_para) {
+ writer.writeEndElement(); // </p>
+ in_para = false;
+ }
+ if (atom->string() == ATOM_LIST_BULLET) {
+ writer.writeStartElement("ul");
+ }
+ else if (atom->string() == ATOM_LIST_TAG) {
+ writer.writeStartElement("dl");
+ }
+ else if (atom->string() == ATOM_LIST_VALUE) {
+ threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
+ if (threeColumnEnumValueTable) {
+ writer.writeStartElement("table");
+ writer.writeAttribute("outputclass","valuelist");
+ writer.writeStartElement("tr");
+ if (++numTableRows % 2 == 1)
+ writer.writeAttribute("outputclass","odd");
+ else
+ writer.writeAttribute("outputclass","even");
+ writer.writeStartElement("th");
+ writer.writeCharacters("Constant");
+ writer.writeEndElement(); // </th>
+ writer.writeStartElement("th");
+ writer.writeCharacters("Value");
+ writer.writeEndElement(); // </th>
+ writer.writeStartElement("th");
+ writer.writeCharacters("Description");
+ writer.writeEndElement(); // </th>
+ writer.writeEndElement(); // </tr>
+ }
+ else {
+ writer.writeStartElement("table");
+ writer.writeAttribute("outputclass","valuelist");
+ writer.writeStartElement("tr");
+ writer.writeStartElement("th");
+ writer.writeCharacters("Constant");
+ writer.writeEndElement(); // </th>
+ writer.writeStartElement("th");
+ writer.writeCharacters("Value");
+ writer.writeEndElement(); // </th>
+ writer.writeEndElement(); // </tr>
+ }
+ }
+ else {
+ writer.writeStartElement("ol");
+ if (atom->string() == ATOM_LIST_UPPERALPHA)
+ writer.writeAttribute("type","A");
+ else if (atom->string() == ATOM_LIST_LOWERALPHA)
+ writer.writeAttribute("type","a");
+ else if (atom->string() == ATOM_LIST_UPPERROMAN)
+ writer.writeAttribute("type","I");
+ else if (atom->string() == ATOM_LIST_LOWERROMAN)
+ writer.writeAttribute("type","i");
+ else // (atom->string() == ATOM_LIST_NUMERIC)
+ writer.writeAttribute("type","1");
+ if (atom->next() != 0 && atom->next()->string().toInt() != 1)
+ writer.writeAttribute("start",atom->next()->string());
+ }
+ break;
+ case Atom::ListItemNumber:
+ // nothing
+ break;
+ case Atom::ListTagLeft:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer.writeStartElement("dt");
+ }
+ else { // (atom->string() == ATOM_LIST_VALUE)
+ writer.writeStartElement("tr");
+ writer.writeStartElement("td");
+ writer.writeAttribute("outputclass","topAlign");
+ writer.writeStartElement("tt");
+ writer.writeCharacters(protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
+ relative))));
+ writer.writeEndElement(); // </tt>
+ writer.writeEndElement(); // </td>
+ writer.writeStartElement("td");
+ writer.writeAttribute("outputclass","topAlign");
+
+ QString itemValue;
+ if (relative->type() == Node::Enum) {
+ const EnumNode *enume = static_cast<const EnumNode *>(relative);
+ itemValue = enume->itemValue(atom->next()->string());
+ }
+
+ if (itemValue.isEmpty())
+ writer.writeCharacters("?");
+ else {
+ writer.writeStartElement("tt");
+ writer.writeCharacters(protectEnc(itemValue));
+ writer.writeEndElement(); // </tt>
+ }
+ skipAhead = 1;
+ }
+ break;
+ case Atom::ListTagRight:
+ if (atom->string() == ATOM_LIST_TAG)
+ writer.writeEndElement(); // </dt>
+ break;
+ case Atom::ListItemLeft:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer.writeStartElement("dd");
+ }
+ else if (atom->string() == ATOM_LIST_VALUE) {
+ if (threeColumnEnumValueTable) {
+ writer.writeEndElement(); // </td>
+ writer.writeStartElement("td");
+ writer.writeAttribute("outputclass","topAlign");
+ if (matchAhead(atom, Atom::ListItemRight))
+ writer.writeCharacters("&nbsp;");
+ }
+ }
+ else {
+ writer.writeStartElement("li");
+ }
+ if (matchAhead(atom, Atom::ParaLeft))
+ skipAhead = 1;
+ break;
+ case Atom::ListItemRight:
+ if (atom->string() == ATOM_LIST_TAG) {
+ writer.writeEndElement(); // </dd>
+ }
+ else if (atom->string() == ATOM_LIST_VALUE) {
+ writer.writeEndElement(); // </td>
+ writer.writeEndElement(); // </tr>
+ }
+ else {
+ writer.writeEndElement(); // </li>
+ }
+ break;
+ case Atom::ListRight:
+ if (atom->string() == ATOM_LIST_BULLET) {
+ writer.writeEndElement(); // </ul>
+ }
+ else if (atom->string() == ATOM_LIST_TAG) {
+ writer.writeEndElement(); // </dl>
+ }
+ else if (atom->string() == ATOM_LIST_VALUE) {
+ writer.writeEndElement(); // </table>
+ }
+ else {
+ writer.writeEndElement(); // </ol>
+ }
+ break;
+ case Atom::Nop:
+ // nothing
+ break;
+ case Atom::ParaLeft:
+ writer.writeStartElement("p");
+ in_para = true;
+ break;
+ case Atom::ParaRight:
+ endLink();
+ if (in_para) {
+ writer.writeEndElement(); // </p?
+ in_para = false;
+ }
+ break;
+ case Atom::QuotationLeft:
+ writer.writeStartElement("blockquote");
+ break;
+ case Atom::QuotationRight:
+ writer.writeEndElement(); // </blockquote>
+ break;
+ case Atom::RawString:
+ writer.writeCharacters(atom->string());
+ break;
+ case Atom::SectionLeft:
+ writer.writeStartElement("p");
+ writeGuidAttribute(Doc::canonicalTitle(Text::sectionHeading(atom).toString()));
+ writer.writeAttribute("outputclass","target");
+ writer.writeCharacters(protectEnc(Text::sectionHeading(atom).toString()));
+ writer.writeEndElement(); // </p>
+ break;
+ case Atom::SectionRight:
+ // nothing
+ break;
+ case Atom::SectionHeadingLeft:
+ writer.writeStartElement("p");
+ hx = "h" + QString::number(atom->string().toInt() + hOffset(relative));
+ writer.writeAttribute("outputclass",hx);
+ inSectionHeading = true;
+ break;
+ case Atom::SectionHeadingRight:
+ writer.writeEndElement(); // </p> (see case Atom::SectionHeadingLeft)
+ inSectionHeading = false;
+ break;
+ case Atom::SidebarLeft:
+ // nothing
+ break;
+ case Atom::SidebarRight:
+ // nothing
+ break;
+ case Atom::String:
+ if (inLink && !inContents && !inSectionHeading) {
+ generateLink(atom, relative, marker);
+ }
+ else {
+ writer.writeCharacters(protectEnc(atom->string()));
+ }
+ break;
+ case Atom::TableLeft:
+ if (in_para) {
+ writer.writeEndElement(); // </p>
+ in_para = false;
+ }
+ writer.writeStartElement("table");
+ writer.writeAttribute("outputclass","generic");
+ numTableRows = 0;
+ break;
+ case Atom::TableRight:
+ writer.writeEndElement(); // </table>
+ break;
+ case Atom::TableHeaderLeft:
+ writer.writeStartElement("thead");
+ writer.writeStartElement("tr");
+ writer.writeAttribute("outputclass","qt-style topAlign");
+ inTableHeader = true;
+ break;
+ case Atom::TableHeaderRight:
+ writer.writeEndElement(); // </tr>
+ if (matchAhead(atom, Atom::TableHeaderLeft)) {
+ skipAhead = 1;
+ writer.writeStartElement("tr");
+ writer.writeAttribute("outputclass","qt-style topAlign");
+ }
+ else {
+ writer.writeEndElement(); // </thead>
+ inTableHeader = false;
+ }
+ break;
+ case Atom::TableRowLeft:
+ writer.writeStartElement("tr");
+ if (++numTableRows % 2 == 1)
+ writer.writeAttribute("outputclass","odd topAlign");
+ else
+ writer.writeAttribute("outputclass","even topAlign");
+ break;
+ case Atom::TableRowRight:
+ writer.writeEndElement(); // </tr>\n";
+ break;
+ case Atom::TableItemLeft:
+ {
+ if (inTableHeader)
+ writer.writeStartElement("th");
+ else
+ writer.writeStartElement("td");
+
+ QStringList spans = atom->string().split(",");
+ if (spans.size() == 2) {
+#if zzz
+
+ if (spans.at(0) != "1")
+ out() << " colspan=\"" << spans.at(0) << "\"";
+ if (spans.at(1) != "1")
+ out() << " rowspan=\"" << spans.at(1) << "\"";
+#endif
+ if (!inTableHeader)
+ writer.writeStartElement("p");
+ }
+ if (matchAhead(atom, Atom::ParaLeft))
+ skipAhead = 1;
+ }
+ break;
+ case Atom::TableItemRight:
+ if (inTableHeader)
+ writer.writeEndElement(); // </th>
+ else {
+ writer.writeEndElement(); // </p>
+ writer.writeEndElement(); // </td>
+ }
+ if (matchAhead(atom, Atom::ParaLeft))
+ skipAhead = 1;
+ break;
+ case Atom::TableOfContents:
+ {
+ int numColumns = 1;
+ const Node *node = relative;
+
+ Doc::SectioningUnit sectioningUnit = Doc::Section4;
+ QStringList params = atom->string().split(",");
+ QString columnText = params.at(0);
+ QStringList pieces = columnText.split(" ", QString::SkipEmptyParts);
+ if (pieces.size() >= 2) {
+ columnText = pieces.at(0);
+ pieces.pop_front();
+ QString path = pieces.join(" ").trimmed();
+ node = findNodeForTarget(path, relative, marker, atom);
+ }
+
+ if (params.size() == 2) {
+ numColumns = qMax(columnText.toInt(), numColumns);
+ sectioningUnit = (Doc::SectioningUnit)params.at(1).toInt();
+ }
+
+ if (node)
+ generateTableOfContents(node,
+ marker,
+ sectioningUnit,
+ numColumns,
+ relative);
+ }
+ break;
+ case Atom::Target:
+ writer.writeStartElement("p");
+ writeGuidAttribute(Doc::canonicalTitle(atom->string()));
+ writer.writeAttribute("outputclass","target");
+ writer.writeCharacters(protectEnc(atom->string()));
+ writer.writeEndElement(); // </p>
+ break;
+ case Atom::UnhandledFormat:
+ writer.writeStartElement("b");
+ writer.writeAttribute("outputclass","redFont");
+ writer.writeCharacters("&lt;Missing DITAXML&gt");
+ writer.writeEndElement(); // </b>
+ break;
+ case Atom::UnknownCommand:
+ writer.writeStartElement("b");
+ writer.writeAttribute("outputclass","redFont code");
+ writer.writeCharacters(protectEnc(atom->string()));
+ writer.writeEndElement(); // </b>
+ break;
+#ifdef QDOC_QML
+ case Atom::QmlText:
+ case Atom::EndQmlText:
+ // don't do anything with these. They are just tags.
+ break;
+#endif
+ default:
+ // unknownAtom(atom);
+ break;
+ }
+ return skipAhead;
+}
+
+/*!
+ Generate a reference page for a C++ class.
+ */
+void
+DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* marker)
+{
+ QList<Section> sections;
+ QList<Section>::ConstIterator s;
+
+ const ClassNode* cn = 0;
+ const NamespaceNode* namespasse = 0;
+
+ QString title;
+ QString rawTitle;
+ QString fullTitle;
+ if (inner->type() == Node::Namespace) {
+ namespasse = const_cast<NamespaceNode*>(static_cast<const NamespaceNode*>(inner));
+ rawTitle = marker->plainName(inner);
+ fullTitle = marker->plainFullName(inner);
+ title = rawTitle + " Namespace";
+ }
+ else if (inner->type() == Node::Class) {
+ cn = const_cast<ClassNode*>(static_cast<const ClassNode*>(inner));
+ rawTitle = marker->plainName(inner);
+ fullTitle = marker->plainFullName(inner);
+ title = rawTitle + " Class Reference";
+
+ generateHeader(inner);
+
+ writer.writeStartElement(CXXCLASS);
+ writer.writeAttribute("id",cn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(fullTitle);
+ writer.writeEndElement(); // </apiName>
+
+ generateBrief(inner, marker);
+
+ writer.writeStartElement(CXXCLASSDETAIL);
+ writer.writeStartElement(CXXCLASSDEFINITION);
+ writer.writeStartElement(CXXCLASSACCESSSPECIFIER);
+ writer.writeAttribute("value",inner->accessString());
+ writer.writeEndElement(); // <cxxClassAccessSpecifier>
+ if (cn->isAbstract()) {
+ writer.writeStartElement(CXXCLASSABSTRACT);
+ writer.writeAttribute("name","abstract");
+ writer.writeAttribute("value","abstract");
+ writer.writeEndElement(); // </cxxClassAbstract>
+ }
+ writeDerivations(cn, marker);
+ writeLocation(cn);
+ writer.writeEndElement(); // <cxxClassDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!inner->doc().isEmpty()) {
+ writer.writeStartElement("p");
+ writer.writeAttribute("outputclass","h2");
+ writer.writeCharacters("Detailed Description");
+ writer.writeEndElement(); // </p>
+ generateBody(inner, marker);
+ // generateAlsoList(inner, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxClassDetail>
+
+ sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
+ s = sections.begin();
+ while (s != sections.end()) {
+ if ((*s).name == "Member Function Documentation") {
+ writeFunctions((*s),cn,marker);
+ }
+ else if ((*s).name == "Member Type Documentation") {
+ writeEnumerations((*s),cn,marker);
+ writeTypedefs((*s),cn,marker);
+ }
+ else if ((*s).name == "Member Variable Documentation") {
+ writeDataMembers((*s),cn,marker);
+ }
+ else if ((*s).name == "Property Documentation") {
+ writeProperties((*s),cn,marker);
+ }
+ else if ((*s).name == "Macro Documentation") {
+ writeMacros((*s),cn,marker);
+ }
+ ++s;
+ }
+ writer.writeEndElement(); // </cxxClass>
+ }
+
+#ifdef WRITE_HTML
+ Text subtitleText;
+ if (rawTitle != fullTitle)
+ subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
+ << Atom(Atom::LineBreak);
+
+ QString shortVersion;
+ shortVersion = project + " " + shortVersion + ": ";
+ shortVersion = myTree->version();
+ if (shortVersion.count(QChar('.')) == 2)
+ shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
+ if (!shortVersion.isEmpty()) {
+ if (project == "QSA")
+ shortVersion = "QSA " + shortVersion + ": ";
+ else
+ shortVersion = "Qt " + shortVersion + ": ";
+ }
+
+ out() << " <title>" << shortVersion << protectEnc(title) << "</title>\n";
+
+#if 0
+ out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ generateBreadCrumbs(title,node,marker);
+ out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+#endif
+
+ sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
+ generateTableOfContents(inner,marker,&sections);
+ generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
+
+#ifdef QDOC_QML
+ if (cn && !cn->qmlElement().isEmpty()) {
+ generateInstantiatedBy(cn,marker);
+ }
+#endif
+
+ generateBrief(inner, marker);
+ generateIncludes(inner, marker);
+ generateStatus(inner, marker);
+ if (cn) {
+ generateInherits(cn, marker);
+ generateInheritedBy(cn, marker);
+ }
+ generateThreadSafeness(inner, marker);
+ generateSince(inner, marker);
+
+ out() << "<ul>\n";
+
+ QString membersLink = generateListOfAllMemberFile(inner, marker);
+ if (!membersLink.isEmpty())
+ out() << "<li><xref href=\"" << membersLink << "\">"
+ << "List of all members, including inherited members</xref></li>\n";
+
+ QString obsoleteLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Obsolete);
+ if (!obsoleteLink.isEmpty())
+ out() << "<li><xref href=\"" << obsoleteLink << "\">"
+ << "Obsolete members</xref></li>\n";
+
+ QString compatLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Compat);
+ if (!compatLink.isEmpty())
+ out() << "<li><xref href=\"" << compatLink << "\">"
+ << "Qt 3 support members</xref></li>\n";
+
+ out() << "</ul>\n";
+
+ bool needOtherSection = false;
+
+ /*
+ sections is built above for the call to generateTableOfContents().
+ */
+ s = sections.begin();
+ while (s != sections.end()) {
+ if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
+ if (!s->inherited.isEmpty())
+ needOtherSection = true;
+ }
+ else {
+ if (!s->members.isEmpty()) {
+ out() << "<hr />\n";
+ out() << "<a name=\""
+ << registerRef((*s).name.toLower())
+ << "\"></a>\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+ generateSection(s->members, inner, marker, CodeMarker::Summary);
+ }
+ if (!s->reimpMembers.isEmpty()) {
+ QString name = QString("Reimplemented ") + (*s).name;
+ out() << "<hr />\n";
+ out() << "<a name=\""
+ << registerRef(name.toLower())
+ << "\"></a>\n";
+ out() << "<h2>" << protectEnc(name) << "</h2>\n";
+ generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
+ }
+
+ if (!s->inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(*s, inner, marker, true);
+ out() << "</ul>\n";
+ }
+ }
+ ++s;
+ }
+
+ if (needOtherSection) {
+ out() << "<h3>Additional Inherited Members</h3>\n"
+ "<ul>\n";
+
+ s = sections.begin();
+ while (s != sections.end()) {
+ if (s->members.isEmpty() && !s->inherited.isEmpty())
+ generateSectionInheritedList(*s, inner, marker);
+ ++s;
+ }
+ out() << "</ul>\n";
+ }
+
+ out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+
+ if (!inner->doc().isEmpty()) {
+ out() << "<hr />\n"
+ << "<div class=\"descr\"/>\n" // QTBUG-9504
+ << "<h2>" << "Detailed Description" << "</h2>\n";
+ generateBody(inner, marker);
+ out() << "</div>\n"; // QTBUG-9504
+ generateAlsoList(inner, marker);
+ }
+
+ sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<hr />\n";
+ if (!(*s).divClass.isEmpty())
+ out() << "<div class=\"" << (*s).divClass << "\"/>\n"; // QTBUG-9504
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+
+ NodeList::ConstIterator m = (*s).members.begin();
+ while (m != (*s).members.end()) {
+ if ((*m)->access() != Node::Private) { // ### check necessary?
+ if ((*m)->type() != Node::Class)
+ generateDetailedMember(*m, inner, marker);
+ else {
+ out() << "<h3> class ";
+ generateFullName(*m, inner, marker);
+ out() << "</h3>";
+ generateBrief(*m, marker, inner);
+ }
+
+ QStringList names;
+ names << (*m)->name();
+ if ((*m)->type() == Node::Function) {
+ const FunctionNode *func = reinterpret_cast<const FunctionNode *>(*m);
+ if (func->metaness() == FunctionNode::Ctor ||
+ func->metaness() == FunctionNode::Dtor ||
+ func->overloadNumber() != 1)
+ names.clear();
+ }
+ else if ((*m)->type() == Node::Property) {
+ const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
+ if (!prop->getters().isEmpty() &&
+ !names.contains(prop->getters().first()->name()))
+ names << prop->getters().first()->name();
+ if (!prop->setters().isEmpty())
+ names << prop->setters().first()->name();
+ if (!prop->resetters().isEmpty())
+ names << prop->resetters().first()->name();
+ }
+ else if ((*m)->type() == Node::Enum) {
+ const EnumNode *enume = reinterpret_cast<const EnumNode*>(*m);
+ if (enume->flagsType())
+ names << enume->flagsType()->name();
+
+ foreach (const QString &enumName,
+ enume->doc().enumItemNames().toSet() -
+ enume->doc().omitEnumItemNames().toSet())
+ names << plainCode(marker->markedUpEnumValue(enumName,
+ enume));
+ }
+ }
+ ++m;
+ }
+ if (!(*s).divClass.isEmpty())
+ out() << "</div>\n"; // QTBUG-9504
+ ++s;
+ }
+#endif
+}
+
+/*!
+ Generate the html page for a qdoc file that doesn't map
+ to an underlying c++ file.
+ */
+void DitaXmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
+{
+ return; // zzz
+
+ SubTitleSize subTitleSize = LargeSubTitle;
+ QList<Section> sections;
+ QList<Section>::const_iterator s;
+ QString fullTitle = fake->fullTitle();
+ QString htmlTitle = fullTitle;
+
+ if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
+ subTitleSize = SmallSubTitle;
+ htmlTitle += " (" + fake->subTitle() + ")";
+ }
+ else if (fake->subType() == Node::QmlBasicType) {
+ fullTitle = "QML Basic Type: " + fullTitle;
+ htmlTitle = fullTitle;
+ }
+
+ generateHeader(fake);
+
+ /*
+ Generate the TOC for the new doc format.
+ Don't generate a TOC for the home page.
+ */
+ if (fake->name() != QString("index.html"))
+ generateTableOfContents(fake,marker,0);
+
+ generateTitle(fullTitle,
+ Text() << fake->subTitle(),
+ subTitleSize,
+ fake,
+ marker);
+
+ if (fake->subType() == Node::Module) {
+ // Generate brief text and status for modules.
+ generateBrief(fake, marker);
+ generateStatus(fake, marker);
+
+ if (moduleNamespaceMap.contains(fake->name())) {
+ out() << "<a name=\"" << registerRef("namespaces") << "\"></a>\n";
+ out() << "<h2>Namespaces</h2>\n";
+ generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
+ }
+ if (moduleClassMap.contains(fake->name())) {
+ out() << "<a name=\"" << registerRef("classes") << "\"></a>\n";
+ out() << "<h2>Classes</h2>\n";
+ generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
+ }
+ }
+ else if (fake->subType() == Node::HeaderFile) {
+ // Generate brief text and status for modules.
+ generateBrief(fake, marker);
+ generateStatus(fake, marker);
+
+ out() << "<ul>\n";
+
+ QString membersLink = generateListOfAllMemberFile(fake, marker);
+ if (!membersLink.isEmpty())
+ out() << "<li><xref href=\"" << membersLink << "\">"
+ << "List of all members, including inherited members</xref></li>\n";
+
+ QString obsoleteLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Obsolete);
+ if (!obsoleteLink.isEmpty())
+ out() << "<li><xref href=\"" << obsoleteLink << "\">"
+ << "Obsolete members</xref></li>\n";
+
+ QString compatLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Compat);
+ if (!compatLink.isEmpty())
+ out() << "<li><xref href=\"" << compatLink << "\">"
+ << "Qt 3 support members</xref></li>\n";
+
+ out() << "</ul>\n";
+ }
+#ifdef QDOC_QML
+ else if (fake->subType() == Node::QmlClass) {
+ const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
+ const ClassNode* cn = qml_cn->classNode();
+ generateQmlInherits(qml_cn, marker);
+ generateQmlInstantiates(qml_cn, marker);
+ generateBrief(qml_cn, marker);
+ generateQmlInheritedBy(qml_cn, marker);
+ sections = marker->qmlSections(qml_cn,CodeMarker::Summary,0);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+ generateQmlSummary(*s,fake,marker);
+ ++s;
+ }
+
+ out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ out() << "<h2>" << "Detailed Description" << "</h2>\n";
+ generateBody(fake, marker);
+ if (cn)
+ generateQmlText(cn->doc().body(), cn, marker, fake->name());
+ generateAlsoList(fake, marker);
+ out() << "<hr />\n";
+
+ sections = marker->qmlSections(qml_cn,CodeMarker::Detailed,0);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+ NodeList::ConstIterator m = (*s).members.begin();
+ while (m != (*s).members.end()) {
+ generateDetailedQmlMember(*m, fake, marker);
+ out() << "<br/>\n";
+ ++m;
+ }
+ ++s;
+ }
+ return;
+ }
+#endif
+
+ sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+ generateSectionList(*s, fake, marker, CodeMarker::Summary);
+ ++s;
+ }
+
+ Text brief = fake->doc().briefText();
+ if (fake->subType() == Node::Module && !brief.isEmpty()) {
+ out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
+ out() << "<h2>" << "Detailed Description" << "</h2>\n";
+ }
+ else
+ out() << "<div class=\"descr\"/>\n"; // QTBUG-9504
+
+ generateBody(fake, marker);
+ out() << "</div>\n"; // QTBUG-9504
+ generateAlsoList(fake, marker);
+
+ if (!fake->groupMembers().isEmpty()) {
+ NodeMap groupMembersMap;
+ foreach (const Node *node, fake->groupMembers()) {
+ if (node->type() == Node::Class || node->type() == Node::Namespace)
+ groupMembersMap[node->name()] = node;
+ }
+ generateAnnotatedList(fake, marker, groupMembersMap);
+ }
+
+ sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
+ s = sections.begin();
+ while (s != sections.end()) {
+ out() << "<hr />\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
+
+ NodeList::ConstIterator m = (*s).members.begin();
+ while (m != (*s).members.end()) {
+ generateDetailedMember(*m, fake, marker);
+ ++m;
+ }
+ ++s;
+ }
+}
+
+/*!
+ Returns "xml" for this subclass of Generator.
+ */
+QString DitaXmlGenerator::fileExtension(const Node * /* node */) const
+{
+ return "xml";
+}
+
+/*!
+ Output breadcrumb list in the html file.
+ */
+void DitaXmlGenerator::generateBreadCrumbs(const QString& title,
+ const Node *node,
+ CodeMarker *marker)
+{
+ Text breadcrumb;
+ if (node->type() == Node::Class) {
+ const ClassNode* cn = static_cast<const ClassNode*>(node);
+ QString name = node->moduleName();
+ out() << " <li><xref href=\"modules.html\">All Modules</xref></li>";
+ if (!name.isEmpty()) {
+ out() << " <li>";
+ breadcrumb << Atom(Atom::AutoLink,name);
+ generateText(breadcrumb, node, marker);
+ out() << "</li>\n";
+ }
+ breadcrumb.clear();
+ if (!cn->name().isEmpty()) {
+ out() << " <li>";
+ breadcrumb << Atom(Atom::AutoLink,cn->name());
+ generateText(breadcrumb, 0, marker);
+ out() << "</li>\n";
+ }
+ }
+ else if (node->type() == Node::Fake) {
+ const FakeNode* fn = static_cast<const FakeNode*>(node);
+ if (node->subType() == Node::Module) {
+ out() << " <li><xref href=\"modules.html\">All Modules</xref></li>";
+ QString name = node->name();
+ if (!name.isEmpty()) {
+ out() << " <li>";
+ breadcrumb << Atom(Atom::AutoLink,name);
+ generateText(breadcrumb, 0, marker);
+ out() << "</li>\n";
+ }
+ }
+ else if (node->subType() == Node::Group) {
+ if (fn->name() == QString("modules"))
+ out() << " <li><xref href=\"modules.html\">All Modules</xref></li>";
+ else {
+ out() << " <li><xref href=\"" << fn->name() << "\">" << title
+ << "</xref></li>";
+ }
+ }
+ else if (node->subType() == Node::Page) {
+ if (fn->name() == QString("examples.html")) {
+ out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>";
+ }
+ else if (fn->name().startsWith("examples-")) {
+ out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>";
+ out() << " <li><xref href=\"" << fn->name() << "\">" << title
+ << "</xref></li>";
+ }
+ else if (fn->name() == QString("namespaces.html")) {
+ out() << " <li><xref href=\"namespaces.html\">All Namespaces</xref></li>";
+ }
+ else {
+ out() << " <li><xref href=\"" << fn->name() << "\">" << title
+ << "</xref></li>";
+ }
+ }
+ else if (node->subType() == Node::QmlClass) {
+ out() << " <li><xref href=\"qdeclarativeelements.html\">QML Elements</xref></li>";
+ out() << " <li><xref href=\"" << fn->name() << "\">" << title
+ << "</xref></li>";
+ }
+ else if (node->subType() == Node::Example) {
+ out() << " <li><xref href=\"all-examples.html\">Examples</xref></li>";
+ QStringList sl = fn->name().split('/');
+ QString name = "examples-" + sl.at(0) + ".html";
+ QString t = CodeParser::titleFromName(name);
+ out() << " <li><xref href=\"" << name << "\">"
+ << t << "</xref></li>";
+ out() << " <li><xref href=\"" << sl.at(0)
+ << "-" << sl.at(sl.size()-1) << ".html\">"
+ << title << "</xref></li>";
+ }
+ }
+ else if (node->type() == Node::Namespace) {
+ const NamespaceNode* nsn = static_cast<const NamespaceNode*>(node);
+ out() << " <li><xref href=\"namespaces.html\">All Namespaces</xref></li>";
+ out() << " <li><xref href=\"" << fileName(nsn) << "\">" << title
+ << "</xref></li>";
+ }
+}
+
+void DitaXmlGenerator::generateHeader(const Node* node)
+{
+ writer.setDevice(out().device());
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(4);
+ writer.writeStartDocument();
+
+ if (!node)
+ return;
+
+ QString docType;
+ QString dtd;
+ QString version;
+ if (node->type() == Node::Class) {
+ docType = "cxxClass";
+ dtd = "dtd/cxxClass.dtd";
+ version = "0.6.0";
+ }
+
+ QString doctype = "<!DOCTYPE " + docType +
+ " PUBLIC \"-//NOKIA//DTD DITA C++ API Class Reference Type v" +
+ version + "//EN\" \"" + dtd + "\">";
+ writer.writeDTD(doctype);
+ writer.writeComment(node->doc().location().fileName());
+}
+
+void DitaXmlGenerator::generateTitle(const QString& title,
+ const Text &subTitle,
+ SubTitleSize subTitleSize,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ if (!title.isEmpty())
+ out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
+ if (!subTitle.isEmpty()) {
+ out() << "<span";
+ if (subTitleSize == SmallSubTitle)
+ out() << " class=\"small-subtitle\">";
+ else
+ out() << " class=\"subtitle\">";
+ generateText(subTitle, relative, marker);
+ out() << "</span>\n";
+ }
+}
+
+/*!
+ Outputs the brief command as a <shortdesc" element.
+ */
+void DitaXmlGenerator::generateBrief(const Node* node, CodeMarker* marker)
+{
+ Text brief = node->doc().briefText();
+ if (!brief.isEmpty()) {
+ ++noLinks;
+ writer.writeStartElement(SHORTDESC);
+ generateText(brief, node, marker);
+ writer.writeEndElement(); // shortdesc
+ --noLinks;
+ }
+}
+
+void DitaXmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
+{
+ if (!inner->includes().isEmpty()) {
+ out() << "<pre class=\"highlightedCode\">"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ marker,inner))
+ << "</pre>";
+ }
+}
+
+/*!
+ Generates a table of contents beginning at \a node.
+ */
+void DitaXmlGenerator::generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ Doc::SectioningUnit sectioningUnit,
+ int numColumns,
+ const Node *relative)
+
+{
+ return;
+ if (!node->doc().hasTableOfContents())
+ return;
+ QList<Atom *> toc = node->doc().tableOfContents();
+ if (toc.isEmpty())
+ return;
+
+ QString nodeName = "";
+ if (node != relative)
+ nodeName = node->name();
+
+ QStringList sectionNumber;
+ int columnSize = 0;
+
+ QString tdTag;
+ if (numColumns > 1) {
+ tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/
+ out() << "<table class=\"toc\">\n<tr class=\"topAlign\">"
+ << tdTag << "\n";
+ }
+
+ // disable nested links in table of contents
+ inContents = true;
+ inLink = true;
+
+ for (int i = 0; i < toc.size(); ++i) {
+ Atom *atom = toc.at(i);
+
+ int nextLevel = atom->string().toInt();
+ if (nextLevel > (int)sectioningUnit)
+ continue;
+
+ if (sectionNumber.size() < nextLevel) {
+ do {
+ out() << "<ul>";
+ sectionNumber.append("1");
+ } while (sectionNumber.size() < nextLevel);
+ }
+ else {
+ while (sectionNumber.size() > nextLevel) {
+ out() << "</ul>\n";
+ sectionNumber.removeLast();
+ }
+ sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
+ }
+ int numAtoms;
+ Text headingText = Text::sectionHeading(atom);
+
+ if (sectionNumber.size() == 1 && columnSize > toc.size() / numColumns) {
+ out() << "</ul></td>" << tdTag << "<ul>\n";
+ columnSize = 0;
+ }
+ out() << "<li>";
+ out() << "<xref href=\""
+ << nodeName
+ << "#"
+ << Doc::canonicalTitle(headingText.toString())
+ << "\">";
+ generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
+ out() << "</xref></li>\n";
+
+ ++columnSize;
+ }
+ while (!sectionNumber.isEmpty()) {
+ out() << "</ul>\n";
+ sectionNumber.removeLast();
+ }
+
+ if (numColumns > 1)
+ out() << "</td></tr></table>\n";
+
+ inContents = false;
+ inLink = false;
+}
+
+/*!
+ Revised for the new doc format.
+ Generates a table of contents beginning at \a node.
+ */
+void DitaXmlGenerator::generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ QList<Section>* sections)
+{
+ QList<Atom*> toc;
+ if (node->doc().hasTableOfContents())
+ toc = node->doc().tableOfContents();
+ if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
+ return;
+
+ QStringList sectionNumber;
+ int detailsBase = 0;
+
+ // disable nested links in table of contents
+ inContents = true;
+ inLink = true;
+
+ out() << "<div class=\"toc\">\n";
+ out() << "<h3>Contents</h3>\n";
+ sectionNumber.append("1");
+ out() << "<ul>\n";
+
+ if (node->subType() == Node::Module) {
+ if (moduleNamespaceMap.contains(node->name())) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><xref href=\"#"
+ << registerRef("namespaces")
+ << "\">Namespaces</xref></li>\n";
+ }
+ if (moduleClassMap.contains(node->name())) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><xref href=\"#"
+ << registerRef("classes")
+ << "\">Classes</xref></li>\n";
+ }
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><xref href=\"#"
+ << registerRef("details")
+ << "\">Detailed Description</xref></li>\n";
+ for (int i = 0; i < toc.size(); ++i) {
+ if (toc.at(i)->string().toInt() == 1) {
+ detailsBase = 1;
+ break;
+ }
+ }
+ }
+ else if (sections && (node->type() == Node::Class)) {
+ QList<Section>::ConstIterator s = sections->begin();
+ while (s != sections->end()) {
+ if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><xref href=\"#"
+ << registerRef((*s).pluralMember)
+ << "\">" << (*s).name
+ << "</xref></li>\n";
+ }
+ ++s;
+ }
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><xref href=\"#"
+ << registerRef("details")
+ << "\">Detailed Description</xref></li>\n";
+ for (int i = 0; i < toc.size(); ++i) {
+ if (toc.at(i)->string().toInt() == 1) {
+ detailsBase = 1;
+ break;
+ }
+ }
+ }
+
+ for (int i = 0; i < toc.size(); ++i) {
+ Atom *atom = toc.at(i);
+ int nextLevel = atom->string().toInt() + detailsBase;
+ if (sectionNumber.size() < nextLevel) {
+ do {
+ sectionNumber.append("1");
+ } while (sectionNumber.size() < nextLevel);
+ }
+ else {
+ while (sectionNumber.size() > nextLevel) {
+ sectionNumber.removeLast();
+ }
+ sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
+ }
+ int numAtoms;
+ Text headingText = Text::sectionHeading(atom);
+ QString s = headingText.toString();
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\">";
+ out() << "<xref href=\""
+ << "#"
+ << Doc::canonicalTitle(s)
+ << "\">";
+ generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
+ out() << "</xref></li>\n";
+ }
+ while (!sectionNumber.isEmpty()) {
+ sectionNumber.removeLast();
+ }
+ out() << "</ul>\n";
+ out() << "</div>\n";
+ inContents = false;
+ inLink = false;
+}
+
+QString DitaXmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
+ CodeMarker *marker)
+{
+ QList<Section> sections;
+ QList<Section>::ConstIterator s;
+
+ sections = marker->sections(inner,
+ CodeMarker::SeparateList,
+ CodeMarker::Okay);
+ if (sections.isEmpty())
+ return QString();
+
+ QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
+ beginSubPage(inner->location(), fileName);
+ QString title = "List of All Members for " + inner->name();
+ generateHeader(inner);
+ generateTitle(title, Text(), SmallSubTitle, inner, marker);
+ out() << "<p>This is the complete list of members for ";
+ generateFullName(inner, 0, marker);
+ out() << ", including inherited members.</p>\n";
+
+ Section section = sections.first();
+ generateSectionList(section, 0, marker, CodeMarker::SeparateList);
+
+ endSubPage();
+ return fileName;
+}
+
+QString DitaXmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
+ CodeMarker *marker,
+ CodeMarker::Status status)
+{
+ QList<Section> sections = marker->sections(inner,
+ CodeMarker::Summary,
+ status);
+ QMutableListIterator<Section> j(sections);
+ while (j.hasNext()) {
+ if (j.next().members.size() == 0)
+ j.remove();
+ }
+ if (sections.isEmpty())
+ return QString();
+
+ int i;
+
+ QString title;
+ QString fileName;
+
+ if (status == CodeMarker::Compat) {
+ title = "Qt 3 Support Members for " + inner->name();
+ fileName = fileBase(inner) + "-qt3." + fileExtension(inner);
+ }
+ else {
+ title = "Obsolete Members for " + inner->name();
+ fileName = fileBase(inner) + "-obsolete." + fileExtension(inner);
+ }
+
+ beginSubPage(inner->location(), fileName);
+ generateHeader(inner);
+ generateTitle(title, Text(), SmallSubTitle, inner, marker);
+
+ if (status == CodeMarker::Compat) {
+ out() << "<p><b>The following class members are part of the "
+ "<xref href=\"qt3support.html\">Qt 3 support layer</xref>.</b> "
+ "They are provided to help you port old code to Qt 4. We advise against "
+ "using them in new code.</p>\n";
+ }
+ else {
+ out() << "<p><b>The following class members are obsolete.</b> "
+ << "They are provided to keep old source code working. "
+ << "We strongly advise against using them in new code.</p>\n";
+ }
+
+ out() << "<p><ul><li><xref href=\""
+ << linkForNode(inner, 0) << "\">"
+ << protectEnc(inner->name())
+ << " class reference</xref></li></ul></p>\n";
+
+ for (i = 0; i < sections.size(); ++i) {
+ out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
+ generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
+ }
+
+ sections = marker->sections(inner, CodeMarker::Detailed, status);
+ for (i = 0; i < sections.size(); ++i) {
+ out() << "<hr />\n";
+ out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
+
+ NodeList::ConstIterator m = sections.at(i).members.begin();
+ while (m != sections.at(i).members.end()) {
+ if ((*m)->access() != Node::Private)
+ generateDetailedMember(*m, inner, marker);
+ ++m;
+ }
+ }
+
+ endSubPage();
+ return fileName;
+}
+
+void DitaXmlGenerator::generateClassHierarchy(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString,const Node*> &classMap)
+{
+ if (classMap.isEmpty())
+ return;
+
+ NodeMap topLevel;
+ NodeMap::ConstIterator c = classMap.begin();
+ while (c != classMap.end()) {
+ const ClassNode *classe = static_cast<const ClassNode *>(*c);
+ if (classe->baseClasses().isEmpty())
+ topLevel.insert(classe->name(), classe);
+ ++c;
+ }
+
+ QStack<NodeMap > stack;
+ stack.push(topLevel);
+
+ out() << "<ul>\n";
+ while (!stack.isEmpty()) {
+ if (stack.top().isEmpty()) {
+ stack.pop();
+ out() << "</ul>\n";
+ }
+ else {
+ const ClassNode *child =
+ static_cast<const ClassNode *>(*stack.top().begin());
+ out() << "<li>";
+ generateFullName(child, relative, marker);
+ out() << "</li>\n";
+ stack.top().erase(stack.top().begin());
+
+ NodeMap newTop;
+ foreach (const RelatedClass &d, child->derivedClasses()) {
+ if (d.access != Node::Private)
+ newTop.insert(d.node->name(), d.node);
+ }
+ if (!newTop.isEmpty()) {
+ stack.push(newTop);
+ out() << "<ul>\n";
+ }
+ }
+ }
+}
+
+void DitaXmlGenerator::generateAnnotatedList(const Node *relative,
+ CodeMarker *marker,
+ const NodeMap &nodeMap)
+{
+ out() << "<table class=\"annotated\">\n";
+
+ int row = 0;
+ foreach (const QString &name, nodeMap.keys()) {
+ const Node *node = nodeMap[name];
+
+ if (node->status() == Node::Obsolete)
+ continue;
+
+ if (++row % 2 == 1)
+ out() << "<tr class=\"odd topAlign\">";
+ else
+ out() << "<tr class=\"even topAlign\">";
+ out() << "<td><p>";
+ generateFullName(node, relative, marker);
+ out() << "</p></td>";
+
+ if (!(node->type() == Node::Fake)) {
+ Text brief = node->doc().trimmedBriefText(name);
+ if (!brief.isEmpty()) {
+ out() << "<td><p>";
+ generateText(brief, node, marker);
+ out() << "</p></td>";
+ }
+ }
+ else {
+ out() << "<td><p>";
+ out() << protectEnc(node->doc().briefText().toString());
+ out() << "</p></td>";
+ }
+ out() << "</tr>\n";
+ }
+ out() << "</table>\n";
+}
+
+/*!
+ This function finds the common prefix of the names of all
+ the classes in \a classMap and then generates a compact
+ list of the class names alphabetized on the part of the
+ name not including the common prefix. You can tell the
+ function to use \a comonPrefix as the common prefix, but
+ normally you let it figure it out itself by looking at
+ the name of the first and last classes in \a classMap.
+ */
+void DitaXmlGenerator::generateCompactList(const Node *relative,
+ CodeMarker *marker,
+ const NodeMap &classMap,
+ bool includeAlphabet,
+ QString commonPrefix)
+{
+ const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
+
+ if (classMap.isEmpty())
+ return;
+
+ /*
+ If commonPrefix is not empty, then the caller knows what
+ the common prefix is and has passed it in, so just use that
+ one.
+ */
+ int commonPrefixLen = commonPrefix.length();
+ if (commonPrefixLen == 0) {
+ QString first;
+ QString last;
+
+ /*
+ The caller didn't pass in a common prefix, so get the common
+ prefix by looking at the class names of the first and last
+ classes in the class map. Discard any namespace names and
+ just use the bare class names. For Qt, the prefix is "Q".
+
+ Note that the algorithm used here to derive the common prefix
+ from the first and last classes in alphabetical order (QAccel
+ and QXtWidget in Qt 2.1), fails if either class name does not
+ begin with Q.
+ */
+
+ NodeMap::const_iterator iter = classMap.begin();
+ while (iter != classMap.end()) {
+ if (!iter.key().contains("::")) {
+ first = iter.key();
+ break;
+ }
+ ++iter;
+ }
+
+ if (first.isEmpty())
+ first = classMap.begin().key();
+
+ iter = classMap.end();
+ while (iter != classMap.begin()) {
+ --iter;
+ if (!iter.key().contains("::")) {
+ last = iter.key();
+ break;
+ }
+ }
+
+ if (last.isEmpty())
+ last = classMap.begin().key();
+
+ if (classMap.size() > 1) {
+ while (commonPrefixLen < first.length() + 1 &&
+ commonPrefixLen < last.length() + 1 &&
+ first[commonPrefixLen] == last[commonPrefixLen])
+ ++commonPrefixLen;
+ }
+
+ commonPrefix = first.left(commonPrefixLen);
+ }
+
+ /*
+ Divide the data into 37 paragraphs: 0, ..., 9, A, ..., Z,
+ underscore (_). QAccel will fall in paragraph 10 (A) and
+ QXtWidget in paragraph 33 (X). This is the only place where we
+ assume that NumParagraphs is 37. Each paragraph is a NodeMap.
+ */
+ NodeMap paragraph[NumParagraphs+1];
+ QString paragraphName[NumParagraphs+1];
+ QSet<char> usedParagraphNames;
+
+ NodeMap::ConstIterator c = classMap.begin();
+ while (c != classMap.end()) {
+ QStringList pieces = c.key().split("::");
+ QString key;
+ int idx = commonPrefixLen;
+ if (!pieces.last().startsWith(commonPrefix))
+ idx = 0;
+ if (pieces.size() == 1)
+ key = pieces.last().mid(idx).toLower();
+ else
+ key = pieces.last().toLower();
+
+ int paragraphNr = NumParagraphs - 1;
+
+ if (key[0].digitValue() != -1) {
+ paragraphNr = key[0].digitValue();
+ }
+ else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
+ paragraphNr = 10 + key[0].unicode() - 'a';
+ }
+
+ paragraphName[paragraphNr] = key[0].toUpper();
+ usedParagraphNames.insert(key[0].toLower().cell());
+ paragraph[paragraphNr].insert(key, c.value());
+ ++c;
+ }
+
+ /*
+ Each paragraph j has a size: paragraph[j].count(). In the
+ discussion, we will assume paragraphs 0 to 5 will have sizes
+ 3, 1, 4, 1, 5, 9.
+
+ We now want to compute the paragraph offset. Paragraphs 0 to 6
+ start at offsets 0, 3, 4, 8, 9, 14, 23.
+ */
+ int paragraphOffset[NumParagraphs + 1]; // 37 + 1
+ paragraphOffset[0] = 0;
+ for (int i=0; i<NumParagraphs; i++) // i = 0..36
+ paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count();
+
+ int curParNr = 0;
+ int curParOffset = 0;
+
+ /*
+ Output the alphabet as a row of links.
+ */
+ if (includeAlphabet) {
+ out() << "<p class=\"centerAlign functionIndex\"><b>";
+ for (int i = 0; i < 26; i++) {
+ QChar ch('a' + i);
+ if (usedParagraphNames.contains(char('a' + i)))
+ out() << QString("<xref href=\"#%1\">%2</xref>&nbsp;").arg(ch).arg(ch.toUpper());
+ }
+ out() << "</b></p>\n";
+ }
+
+ /*
+ Output a <div> element to contain all the <dl> elements.
+ */
+ out() << "<div class=\"flowListDiv\">\n";
+
+ for (int i=0; i<classMap.count()-1; i++) {
+ while ((curParNr < NumParagraphs) &&
+ (curParOffset == paragraph[curParNr].count())) {
+ ++curParNr;
+ curParOffset = 0;
+ }
+
+ /*
+ Starting a new paragraph means starting a new <dl>.
+ */
+ if (curParOffset == 0) {
+ if (i > 0)
+ out() << "</dl>\n";
+ if (++numTableRows % 2 == 1)
+ out() << "<dl class=\"flowList odd\">";
+ else
+ out() << "<dl class=\"flowList even\">";
+ out() << "<dt class=\"alphaChar\">";
+ if (includeAlphabet) {
+ QChar c = paragraphName[curParNr][0].toLower();
+ out() << QString("<a name=\"%1\"></a>").arg(c);
+ }
+ out() << "<b>"
+ << paragraphName[curParNr]
+ << "</b>";
+ out() << "</dt>\n";
+ }
+
+ /*
+ Output a <dd> for the current offset in the current paragraph.
+ */
+ out() << "<dd>";
+ if ((curParNr < NumParagraphs) &&
+ !paragraphName[curParNr].isEmpty()) {
+ NodeMap::Iterator it;
+ it = paragraph[curParNr].begin();
+ for (int i=0; i<curParOffset; i++)
+ ++it;
+
+ /*
+ Previously, we used generateFullName() for this, but we
+ require some special formatting.
+ */
+ out() << "<xref href=\"" << linkForNode(it.value(), relative) << "\">";
+
+ QStringList pieces;
+ if (it.value()->subType() == Node::QmlClass)
+ pieces << it.value()->name();
+ else
+ pieces = fullName(it.value(), relative, marker).split("::");
+ out() << protectEnc(pieces.last());
+ out() << "</xref>";
+ if (pieces.size() > 1) {
+ out() << " (";
+ generateFullName(it.value()->parent(), relative, marker);
+ out() << ")";
+ }
+ }
+ out() << "</dd>\n";
+ curParOffset++;
+ }
+ out() << "</dl>\n";
+ out() << "</div>\n";
+}
+
+void DitaXmlGenerator::generateFunctionIndex(const Node *relative,
+ CodeMarker *marker)
+{
+ out() << "<p class=\"centerAlign functionIndex\"><b>";
+ for (int i = 0; i < 26; i++) {
+ QChar ch('a' + i);
+ out() << QString("<xref href=\"#%1\">%2</xref>&nbsp;").arg(ch).arg(ch.toUpper());
+ }
+ out() << "</b></p>\n";
+
+ char nextLetter = 'a';
+ char currentLetter;
+
+#if 1
+ out() << "<ul>\n";
+#endif
+ QMap<QString, NodeMap >::ConstIterator f = funcIndex.begin();
+ while (f != funcIndex.end()) {
+#if 1
+ out() << "<li>";
+#else
+ out() << "<p>";
+#endif
+ out() << protectEnc(f.key()) << ":";
+
+ currentLetter = f.key()[0].unicode();
+ while (islower(currentLetter) && currentLetter >= nextLetter) {
+ out() << QString("<a name=\"%1\"></a>").arg(nextLetter);
+ nextLetter++;
+ }
+
+ NodeMap::ConstIterator s = (*f).begin();
+ while (s != (*f).end()) {
+ out() << " ";
+ generateFullName((*s)->parent(), relative, marker, *s);
+ ++s;
+ }
+#if 1
+ out() << "</li>";
+#else
+ out() << "</p>";
+#endif
+ out() << "\n";
+ ++f;
+ }
+#if 1
+ out() << "</ul>\n";
+#endif
+}
+
+void DitaXmlGenerator::generateLegaleseList(const Node *relative,
+ CodeMarker *marker)
+{
+ QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
+ while (it != legaleseTexts.end()) {
+ Text text = it.key();
+ out() << "<hr />\n";
+ generateText(text, relative, marker);
+ out() << "<ul>\n";
+ do {
+ out() << "<li>";
+ generateFullName(it.value(), relative, marker);
+ out() << "</li>\n";
+ ++it;
+ } while (it != legaleseTexts.end() && it.key() == text);
+ out() << "</ul>\n";
+ }
+}
+
+/*void DitaXmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
+{
+ QString marked = marker->markedUpSynopsis(node, relative, style);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protectEnc(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
+ }
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
+
+ if (style == CodeMarker::Summary)
+ marked.replace("@name>", "b>");
+
+ if (style == CodeMarker::SeparateList) {
+ QRegExp extraRegExp("<@extra>.*</@extra>");
+ extraRegExp.setMinimal(true);
+ marked.replace(extraRegExp, "");
+ }
+ else {
+ marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("</@extra>", "</tt>");
+ }
+
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
+ }
+ out() << highlightedCode(marked, marker, relative);
+}*/
+
+#ifdef QDOC_QML
+void DitaXmlGenerator::generateQmlItem(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ bool summary)
+{
+ QString marked = marker->markedUpQmlItem(node,summary);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protectEnc(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
+ }
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
+
+ if (summary)
+ marked.replace("@name>", "b>");
+
+ marked.replace("<@extra>", "<tt>");
+ marked.replace("</@extra>", "</tt>");
+
+ if (summary) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
+ }
+ out() << highlightedCode(marked, marker, relative);
+}
+#endif
+
+void DitaXmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
+{
+ QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap;
+ QMap<QString, const FakeNode *> groupTitlesMap;
+ QMap<QString, FakeNode *> uncategorizedNodeMap;
+ QRegExp singleDigit("\\b([0-9])\\b");
+
+ const NodeList children = myTree->root()->childNodes();
+ foreach (Node *child, children) {
+ if (child->type() == Node::Fake && child != relative) {
+ FakeNode *fakeNode = static_cast<FakeNode *>(child);
+
+ // Check whether the page is part of a group or is the group
+ // definition page.
+ QString group;
+ bool isGroupPage = false;
+ if (fakeNode->doc().metaCommandsUsed().contains("group")) {
+ group = fakeNode->doc().metaCommandArgs("group")[0];
+ isGroupPage = true;
+ }
+
+ // there are too many examples; they would clutter the list
+ if (fakeNode->subType() == Node::Example)
+ continue;
+
+ // not interested either in individual (Qt Designer etc.) manual chapters
+ if (fakeNode->links().contains(Node::ContentsLink))
+ continue;
+
+ // Discard external nodes.
+ if (fakeNode->subType() == Node::ExternalPage)
+ continue;
+
+ QString sortKey = fakeNode->fullTitle().toLower();
+ if (sortKey.startsWith("the "))
+ sortKey.remove(0, 4);
+ sortKey.replace(singleDigit, "0\\1");
+
+ if (!group.isEmpty()) {
+ if (isGroupPage) {
+ // If we encounter a group definition page, we add all
+ // the pages in that group to the list for that group.
+ foreach (Node *member, fakeNode->groupMembers()) {
+ if (member->type() != Node::Fake)
+ continue;
+ FakeNode *page = static_cast<FakeNode *>(member);
+ if (page) {
+ QString sortKey = page->fullTitle().toLower();
+ if (sortKey.startsWith("the "))
+ sortKey.remove(0, 4);
+ sortKey.replace(singleDigit, "0\\1");
+ fakeNodeMap[const_cast<const FakeNode *>(fakeNode)].insert(sortKey, page);
+ groupTitlesMap[fakeNode->fullTitle()] = const_cast<const FakeNode *>(fakeNode);
+ }
+ }
+ }
+ else if (!isGroupPage) {
+ // If we encounter a page that belongs to a group then
+ // we add that page to the list for that group.
+ const FakeNode *groupNode = static_cast<const FakeNode *>(myTree->root()->findNode(group, Node::Fake));
+ if (groupNode)
+ fakeNodeMap[groupNode].insert(sortKey, fakeNode);
+ //else
+ // uncategorizedNodeMap.insert(sortKey, fakeNode);
+ }// else
+ // uncategorizedNodeMap.insert(sortKey, fakeNode);
+ }// else
+ // uncategorizedNodeMap.insert(sortKey, fakeNode);
+ }
+ }
+
+ // We now list all the pages found that belong to groups.
+ // If only certain pages were found for a group, but the definition page
+ // for that group wasn't listed, the list of pages will be intentionally
+ // incomplete. However, if the group definition page was listed, all the
+ // pages in that group are listed for completeness.
+
+ if (!fakeNodeMap.isEmpty()) {
+ foreach (const QString &groupTitle, groupTitlesMap.keys()) {
+ const FakeNode *groupNode = groupTitlesMap[groupTitle];
+ out() << QString("<h3><xref href=\"%1\">%2</xref></h3>\n").arg(
+ linkForNode(groupNode, relative)).arg(
+ protectEnc(groupNode->fullTitle()));
+
+ if (fakeNodeMap[groupNode].count() == 0)
+ continue;
+
+ out() << "<ul>\n";
+
+ foreach (const FakeNode *fakeNode, fakeNodeMap[groupNode]) {
+ QString title = fakeNode->fullTitle();
+ if (title.startsWith("The "))
+ title.remove(0, 4);
+ out() << "<li><xref href=\"" << linkForNode(fakeNode, relative) << "\">"
+ << protectEnc(title) << "</xref></li>\n";
+ }
+ out() << "</ul>\n";
+ }
+ }
+
+ if (!uncategorizedNodeMap.isEmpty()) {
+ out() << QString("<h3>Miscellaneous</h3>\n");
+ out() << "<ul>\n";
+ foreach (const FakeNode *fakeNode, uncategorizedNodeMap) {
+ QString title = fakeNode->fullTitle();
+ if (title.startsWith("The "))
+ title.remove(0, 4);
+ out() << "<li><xref href=\"" << linkForNode(fakeNode, relative) << "\">"
+ << protectEnc(title) << "</xref></li>\n";
+ }
+ out() << "</ul>\n";
+ }
+}
+
+void DitaXmlGenerator::generateSection(const NodeList& nl,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
+{
+ bool name_alignment = true;
+ if (!nl.isEmpty()) {
+ bool twoColumn = false;
+ if (style == CodeMarker::SeparateList) {
+ name_alignment = false;
+ twoColumn = (nl.count() >= 16);
+ }
+ else if (nl.first()->type() == Node::Property) {
+ twoColumn = (nl.count() >= 5);
+ name_alignment = false;
+ }
+ if (name_alignment) {
+ out() << "<table class=\"alignedsummary\">\n";
+ }
+ else {
+ if (twoColumn)
+ out() << "<table class=\"propsummary\">\n"
+ << "<tr><td class=\"topAlign\">";
+ out() << "<ul>\n";
+ }
+
+ int i = 0;
+ NodeList::ConstIterator m = nl.begin();
+ while (m != nl.end()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
+
+ if (name_alignment) {
+ out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
+ }
+ else {
+ if (twoColumn && i == (int) (nl.count() + 1) / 2)
+ out() << "</ul></td><td class=\"topAlign\"><ul>\n";
+ out() << "<li class=\"fn\">";
+ }
+
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</li>\n";
+ i++;
+ ++m;
+ }
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table>\n";
+ }
+ }
+}
+
+void DitaXmlGenerator::generateSectionList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
+{
+ bool name_alignment = true;
+ if (!section.members.isEmpty()) {
+ bool twoColumn = false;
+ if (style == CodeMarker::SeparateList) {
+ name_alignment = false;
+ twoColumn = (section.members.count() >= 16);
+ }
+ else if (section.members.first()->type() == Node::Property) {
+ twoColumn = (section.members.count() >= 5);
+ name_alignment = false;
+ }
+ if (name_alignment) {
+ out() << "<table class=\"alignedsummary\">\n";
+ }
+ else {
+ if (twoColumn)
+ out() << "<table class=\"propsummary\">\n"
+ << "<tr><td class=\"topAlign\">";
+ out() << "<ul>\n";
+ }
+
+ int i = 0;
+ NodeList::ConstIterator m = section.members.begin();
+ while (m != section.members.end()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
+
+ if (name_alignment) {
+ out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
+ }
+ else {
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << "</ul></td><td class=\"topAlign\"><ul>\n";
+ out() << "<li class=\"fn\">";
+ }
+
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</li>\n";
+ i++;
+ ++m;
+ }
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table>\n";
+ }
+ }
+
+ if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(section, relative, marker, name_alignment);
+ out() << "</ul>\n";
+ }
+}
+
+void DitaXmlGenerator::generateSectionInheritedList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ bool nameAlignment)
+{
+ QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
+ while (p != section.inherited.end()) {
+ if (nameAlignment)
+ out() << "<li class=\"fn\">";
+ else
+ out() << "<li class=\"fn\">";
+ out() << (*p).second << " ";
+ if ((*p).second == 1) {
+ out() << section.singularMember;
+ }
+ else {
+ out() << section.pluralMember;
+ }
+ out() << " inherited from <xref href=\"" << fileName((*p).first)
+ << "#" << DitaXmlGenerator::cleanRef(section.name.toLower()) << "\">"
+ << protectEnc(marker->plainFullName((*p).first, relative))
+ << "</xref></li>\n";
+ ++p;
+ }
+}
+
+void DitaXmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style,
+ bool nameAlignment)
+{
+ QString marked = marker->markedUpSynopsis(node, relative, style);
+ QRegExp templateTag("(<[^@>]*>)");
+ if (marked.indexOf(templateTag) != -1) {
+ QString contents = protectEnc(marked.mid(templateTag.pos(1),
+ templateTag.cap(1).length()));
+ marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
+ contents);
+ }
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
+
+ if (style == CodeMarker::Summary) {
+ marked.replace("<@name>", ""); // was "<b>"
+ marked.replace("</@name>", ""); // was "</b>"
+ }
+
+ if (style == CodeMarker::SeparateList) {
+ QRegExp extraRegExp("<@extra>.*</@extra>");
+ extraRegExp.setMinimal(true);
+ marked.replace(extraRegExp, "");
+ } else {
+ marked.replace("<@extra>", "<tt>");
+ marked.replace("</@extra>", "</tt>");
+ }
+
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
+ }
+ out() << highlightedCode(marked, marker, relative, style, nameAlignment);
+}
+
+QString DitaXmlGenerator::highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ CodeMarker::SynopsisStyle ,
+ bool nameAlignment)
+{
+ QString src = markedCode;
+ QString html;
+ QStringRef arg;
+ QStringRef par1;
+
+ const QChar charLangle = '<';
+ const QChar charAt = '@';
+
+ // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
+ static const QString linkTag("link");
+ bool done = false;
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
+ if (nameAlignment && !done) {// && (i != 0)) Why was this here?
+ html += "</td><td class=\"memItemRight bottomAlign\">";
+ done = true;
+ }
+ i += 2;
+ if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
+ html += "<b>";
+ QString link = linkForNode(
+ CodeMarker::nodeForString(par1.toString()), relative);
+ addLink(link, arg, &html);
+ html += "</b>";
+ }
+ else {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
+ }
+ }
+
+
+ if (slow) {
+ // is this block ever used at all?
+ // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
+ src = html;
+ html = QString();
+ static const QString funcTag("func");
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
+ i += 2;
+ if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
+ QString link = linkForNode(
+ marker->resolveTarget(par1.toString(),
+ myTree,
+ relative),
+ relative);
+ addLink(link, arg, &html);
+ par1 = QStringRef();
+ }
+ else {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
+ }
+ }
+ }
+
+ // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
+ src = html;
+ html = QString();
+ static const QString typeTags[] = { "type", "headerfile", "func" };
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
+ i += 2;
+ bool handled = false;
+ for (int k = 0; k != 3; ++k) {
+ if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
+ par1 = QStringRef();
+ QString link = linkForNode(
+ marker->resolveTarget(arg.toString(), myTree, relative),
+ relative);
+ addLink(link, arg, &html);
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
+ }
+ }
+
+ // replace all
+ // "<@comment>" -> "<span class=\"comment\">";
+ // "<@preprocessor>" -> "<span class=\"preprocessor\">";
+ // "<@string>" -> "<span class=\"string\">";
+ // "<@char>" -> "<span class=\"char\">";
+ // "</@(?:comment|preprocessor|string|char)>" -> "</span>"
+ src = html;
+ html = QString();
+ static const QString spanTags[] = {
+ "<@comment>", "<span class=\"comment\">",
+ "<@preprocessor>", "<span class=\"preprocessor\">",
+ "<@string>", "<span class=\"string\">",
+ "<@char>", "<span class=\"char\">",
+ "</@comment>", "</span>",
+ "</@preprocessor>","</span>",
+ "</@string>", "</span>",
+ "</@char>", "</span>"
+ // "<@char>", "<font color=blue>",
+ // "</@char>", "</font>",
+ // "<@func>", "<font color=green>",
+ // "</@func>", "</font>",
+ // "<@id>", "<i>",
+ // "</@id>", "</i>",
+ // "<@keyword>", "<b>",
+ // "</@keyword>", "</b>",
+ // "<@number>", "<font color=yellow>",
+ // "</@number>", "</font>",
+ // "<@op>", "<b>",
+ // "</@op>", "</b>",
+ // "<@param>", "<i>",
+ // "</@param>", "</i>",
+ // "<@string>", "<font color=green>",
+ // "</@string>", "</font>",
+ };
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle) {
+ bool handled = false;
+ for (int k = 0; k != 8; ++k) {
+ const QString & tag = spanTags[2 * k];
+ if (tag == QStringRef(&src, i, tag.length())) {
+ html += spanTags[2 * k + 1];
+ i += tag.length();
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ ++i;
+ if (src.at(i) == charAt ||
+ (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {
+ // drop 'our' unknown tags (the ones still containing '@')
+ while (i < n && src.at(i) != QLatin1Char('>'))
+ ++i;
+ ++i;
+ }
+ else {
+ // retain all others
+ html += charLangle;
+ }
+ }
+ }
+ else {
+ html += src.at(i);
+ ++i;
+ }
+ }
+
+ return html;
+}
+
+void DitaXmlGenerator::generateLink(const Atom* atom,
+ const Node* /* relative */,
+ CodeMarker* marker)
+{
+ static QRegExp camelCase("[A-Z][A-Z][a-z]|[a-z][A-Z0-9]|_");
+
+ if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
+ // hack for C++: move () outside of link
+ int k = funcLeftParen.pos(1);
+ writer.writeCharacters(protectEnc(atom->string().left(k)));
+ if (link.isEmpty()) {
+ if (showBrokenLinks)
+ writer.writeEndElement(); // </i>
+ }
+ else {
+ writer.writeEndElement(); // </xref>
+ }
+ inLink = false;
+ writer.writeCharacters(protectEnc(atom->string().mid(k)));
+ } else if (marker->recognizeLanguage("Java")) {
+ // hack for Java: remove () and use <tt> when appropriate
+ bool func = atom->string().endsWith("()");
+ bool tt = (func || atom->string().contains(camelCase));
+ if (tt)
+ writer.writeStartElement("tt");
+ if (func) {
+ writer.writeCharacters(protectEnc(atom->string().left(atom->string().length() - 2)));
+ }
+ else {
+ writer.writeCharacters(protectEnc(atom->string()));
+ }
+ writer.writeEndElement(); // </tt>
+ }
+ else {
+ writer.writeCharacters(protectEnc(atom->string()));
+ }
+}
+
+QString DitaXmlGenerator::cleanRef(const QString& ref)
+{
+ QString clean;
+
+ if (ref.isEmpty())
+ return clean;
+
+ clean.reserve(ref.size() + 20);
+ const QChar c = ref[0];
+ const uint u = c.unicode();
+
+ if ((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ (u >= '0' && u <= '9')) {
+ clean += c;
+ } else if (u == '~') {
+ clean += "dtor.";
+ } else if (u == '_') {
+ clean += "underscore.";
+ } else {
+ clean += "A";
+ }
+
+ for (int i = 1; i < (int) ref.length(); i++) {
+ const QChar c = ref[i];
+ const uint u = c.unicode();
+ if ((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ (u >= '0' && u <= '9') || u == '-' ||
+ u == '_' || u == ':' || u == '.') {
+ clean += c;
+ } else if (c.isSpace()) {
+ clean += "-";
+ } else if (u == '!') {
+ clean += "-not";
+ } else if (u == '&') {
+ clean += "-and";
+ } else if (u == '<') {
+ clean += "-lt";
+ } else if (u == '=') {
+ clean += "-eq";
+ } else if (u == '>') {
+ clean += "-gt";
+ } else if (u == '#') {
+ clean += "#";
+ } else {
+ clean += "-";
+ clean += QString::number((int)u, 16);
+ }
+ }
+ return clean;
+}
+
+QString DitaXmlGenerator::registerRef(const QString& ref)
+{
+ QString clean = DitaXmlGenerator::cleanRef(ref);
+
+ for (;;) {
+ QString& prevRef = refMap[clean.toLower()];
+ if (prevRef.isEmpty()) {
+ prevRef = ref;
+ break;
+ } else if (prevRef == ref) {
+ break;
+ }
+ clean += "x";
+ }
+ return clean;
+}
+
+QString DitaXmlGenerator::protectEnc(const QString &string)
+{
+ return protect(string, outputEncoding);
+}
+
+QString DitaXmlGenerator::protect(const QString &string, const QString &outputEncoding)
+{
+#define APPEND(x) \
+ if (xml.isEmpty()) { \
+ xml = string; \
+ xml.truncate(i); \
+ } \
+ xml += (x);
+
+ QString xml;
+ int n = string.length();
+
+ for (int i = 0; i < n; ++i) {
+ QChar ch = string.at(i);
+
+ if (ch == QLatin1Char('&')) {
+ APPEND("&amp;");
+ } else if (ch == QLatin1Char('<')) {
+ APPEND("&lt;");
+ } else if (ch == QLatin1Char('>')) {
+ APPEND("&gt;");
+ } else if (ch == QLatin1Char('"')) {
+ APPEND("&quot;");
+ } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F)
+ || (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
+ || (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
+ // we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
+ APPEND("&#x");
+ xml += QString::number(ch.unicode(), 16);
+ xml += QLatin1Char(';');
+ } else {
+ if (!xml.isEmpty())
+ xml += ch;
+ }
+ }
+
+ if (!xml.isEmpty())
+ return xml;
+ return string;
+
+#undef APPEND
+}
+
+QString DitaXmlGenerator::fileBase(const Node *node)
+{
+ QString result;
+
+ result = PageGenerator::fileBase(node);
+
+ if (!node->isInnerNode()) {
+ switch (node->status()) {
+ case Node::Compat:
+ result += "-qt3";
+ break;
+ case Node::Obsolete:
+ result += "-obsolete";
+ break;
+ default:
+ ;
+ }
+ }
+ return result;
+}
+
+#if 0
+QString DitaXmlGenerator::fileBase(const Node *node,
+ const SectionIterator& section)
+{
+ QStringList::ConstIterator s = section.sectionNumber().end();
+ QStringList::ConstIterator b = section.baseNameStack().end();
+
+ QString suffix;
+ QString base = fileBase(node);
+
+ while (s != section.sectionNumber().begin()) {
+ --s;
+ --b;
+ if (!(*b).isEmpty()) {
+ base = *b;
+ break;
+ }
+ suffix.prepend("-" + *s);
+ }
+ return base + suffix;
+}
+#endif
+
+QString DitaXmlGenerator::fileName(const Node *node)
+{
+ if (node->type() == Node::Fake) {
+ if (static_cast<const FakeNode *>(node)->subType() == Node::ExternalPage)
+ return node->name();
+ if (static_cast<const FakeNode *>(node)->subType() == Node::Image)
+ return node->name();
+ }
+ return PageGenerator::fileName(node);
+}
+
+QString DitaXmlGenerator::refForNode(const Node *node)
+{
+ const FunctionNode *func;
+ const TypedefNode *typedeffe;
+ QString ref;
+
+ switch (node->type()) {
+ case Node::Namespace:
+ case Node::Class:
+ default:
+ break;
+ case Node::Enum:
+ ref = node->name() + "-enum";
+ break;
+ case Node::Typedef:
+ typedeffe = static_cast<const TypedefNode *>(node);
+ if (typedeffe->associatedEnum()) {
+ return refForNode(typedeffe->associatedEnum());
+ }
+ else {
+ ref = node->name() + "-typedef";
+ }
+ break;
+ case Node::Function:
+ func = static_cast<const FunctionNode *>(node);
+ if (func->associatedProperty()) {
+ return refForNode(func->associatedProperty());
+ }
+ else {
+ ref = func->name();
+ if (func->overloadNumber() != 1)
+ ref += "-" + QString::number(func->overloadNumber());
+ }
+ break;
+#ifdef QDOC_QML
+ case Node::Fake:
+ if (node->subType() != Node::QmlPropertyGroup)
+ break;
+ case Node::QmlProperty:
+#endif
+ case Node::Property:
+ ref = node->name() + "-prop";
+ break;
+#ifdef QDOC_QML
+ case Node::QmlSignal:
+ ref = node->name() + "-signal";
+ break;
+ case Node::QmlMethod:
+ ref = node->name() + "-method";
+ break;
+#endif
+ case Node::Variable:
+ ref = node->name() + "-var";
+ break;
+ case Node::Target:
+ return protectEnc(node->name());
+ }
+ return registerRef(ref);
+}
+
+QString DitaXmlGenerator::linkForNode(const Node *node, const Node *relative)
+{
+ QString link;
+ QString fn;
+ QString ref;
+
+ if (node == 0 || node == relative)
+ return QString();
+ if (!node->url().isEmpty())
+ return node->url();
+ if (fileBase(node).isEmpty())
+ return QString();
+ if (node->access() == Node::Private)
+ return QString();
+
+ fn = fileName(node);
+ link += fn;
+
+ if (!node->isInnerNode() || node->subType() == Node::QmlPropertyGroup) {
+ ref = refForNode(node);
+ if (relative && fn == fileName(relative) && ref == refForNode(relative))
+ return QString();
+
+ link += "#";
+ link += ref;
+ }
+ return link;
+}
+
+QString DitaXmlGenerator::refForAtom(Atom *atom, const Node * /* node */)
+{
+ if (atom->type() == Atom::SectionLeft) {
+ return Doc::canonicalTitle(Text::sectionHeading(atom).toString());
+ }
+ else if (atom->type() == Atom::Target) {
+ return Doc::canonicalTitle(atom->string());
+ }
+ else {
+ return QString();
+ }
+}
+
+void DitaXmlGenerator::generateFullName(const Node *apparentNode,
+ const Node *relative,
+ CodeMarker *marker,
+ const Node *actualNode)
+{
+ if (actualNode == 0)
+ actualNode = apparentNode;
+ out() << "<xref href=\"" << linkForNode(actualNode, relative);
+ if (true || relative == 0 || relative->status() != actualNode->status()) {
+ switch (actualNode->status()) {
+ case Node::Obsolete:
+ out() << "\" class=\"obsolete";
+ break;
+ case Node::Compat:
+ out() << "\" class=\"compat";
+ break;
+ default:
+ ;
+ }
+ }
+ out() << "\">";
+ out() << protectEnc(fullName(apparentNode, relative, marker));
+ out() << "</xref>";
+}
+
+void DitaXmlGenerator::generateDetailedMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker)
+{
+ const EnumNode *enume;
+
+#ifdef GENERATE_MAC_REFS
+ generateMacRef(node, marker);
+#endif
+ if (node->type() == Node::Enum
+ && (enume = static_cast<const EnumNode *>(node))->flagsType()) {
+#ifdef GENERATE_MAC_REFS
+ generateMacRef(enume->flagsType(), marker);
+#endif
+ out() << "<h3 class=\"flags\">";
+ out() << "<a name=\"" + refForNode(node) + "\"></a>";
+ generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
+ out() << "<br/>";
+ generateSynopsis(enume->flagsType(),
+ relative,
+ marker,
+ CodeMarker::Detailed);
+ out() << "</h3>\n";
+ }
+ else {
+ out() << "<h3 class=\"fn\">";
+ out() << "<a name=\"" + refForNode(node) + "\"></a>";
+ generateSynopsis(node, relative, marker, CodeMarker::Detailed);
+ out() << "</h3>\n";
+ }
+
+ generateStatus(node, marker);
+ generateBody(node, marker);
+ generateThreadSafeness(node, marker);
+ generateSince(node, marker);
+
+ if (node->type() == Node::Property) {
+ const PropertyNode *property = static_cast<const PropertyNode *>(node);
+ Section section;
+
+ section.members += property->getters();
+ section.members += property->setters();
+ section.members += property->resetters();
+
+ if (!section.members.isEmpty()) {
+ out() << "<p><b>Access functions:</b></p>\n";
+ generateSectionList(section, node, marker, CodeMarker::Accessors);
+ }
+
+ Section notifiers;
+ notifiers.members += property->notifiers();
+
+ if (!notifiers.members.isEmpty()) {
+ out() << "<p><b>Notifier signal:</b></p>\n";
+ //out() << "<p>This signal is emitted when the property value is changed.</p>\n";
+ generateSectionList(notifiers, node, marker, CodeMarker::Accessors);
+ }
+ }
+ else if (node->type() == Node::Enum) {
+ const EnumNode *enume = static_cast<const EnumNode *>(node);
+ if (enume->flagsType()) {
+ out() << "<p>The " << protectEnc(enume->flagsType()->name())
+ << " type is a typedef for "
+ << "<xref href=\"qflags.html\">QFlags</xref>&lt;"
+ << protectEnc(enume->name())
+ << "&gt;. It stores an OR combination of "
+ << protectEnc(enume->name())
+ << " values.</p>\n";
+ }
+ }
+ generateAlsoList(node, marker);
+}
+
+void DitaXmlGenerator::findAllClasses(const InnerNode *node)
+{
+ NodeList::const_iterator c = node->childNodes().constBegin();
+ while (c != node->childNodes().constEnd()) {
+ if ((*c)->access() != Node::Private && (*c)->url().isEmpty()) {
+ if ((*c)->type() == Node::Class && !(*c)->doc().isEmpty()) {
+ QString className = (*c)->name();
+ if ((*c)->parent() &&
+ (*c)->parent()->type() == Node::Namespace &&
+ !(*c)->parent()->name().isEmpty())
+ className = (*c)->parent()->name()+"::"+className;
+
+ if (!(static_cast<const ClassNode *>(*c))->hideFromMainList()) {
+ if ((*c)->status() == Node::Compat) {
+ compatClasses.insert(className, *c);
+ }
+ else if ((*c)->status() == Node::Obsolete) {
+ obsoleteClasses.insert(className, *c);
+ }
+ else {
+ nonCompatClasses.insert(className, *c);
+ if ((*c)->status() == Node::Main)
+ mainClasses.insert(className, *c);
+ }
+ }
+
+ QString moduleName = (*c)->moduleName();
+ if (moduleName == "Qt3SupportLight") {
+ moduleClassMap[moduleName].insert((*c)->name(), *c);
+ moduleName = "Qt3Support";
+ }
+ if (!moduleName.isEmpty())
+ moduleClassMap[moduleName].insert((*c)->name(), *c);
+
+ QString serviceName =
+ (static_cast<const ClassNode *>(*c))->serviceName();
+ if (!serviceName.isEmpty())
+ serviceClasses.insert(serviceName, *c);
+ }
+ else if ((*c)->type() == Node::Fake &&
+ (*c)->subType() == Node::QmlClass &&
+ !(*c)->doc().isEmpty()) {
+ QString qmlClassName = (*c)->name();
+ qmlClasses.insert(qmlClassName,*c);
+ }
+ else if ((*c)->isInnerNode()) {
+ findAllClasses(static_cast<InnerNode *>(*c));
+ }
+ }
+ ++c;
+ }
+}
+
+/*!
+ For generating the "New Classes... in 4.6" section on the
+ What's New in 4.6" page.
+ */
+void DitaXmlGenerator::findAllSince(const InnerNode *node)
+{
+ NodeList::const_iterator child = node->childNodes().constBegin();
+ while (child != node->childNodes().constEnd()) {
+ QString sinceVersion = (*child)->since();
+ if (((*child)->access() != Node::Private) && !sinceVersion.isEmpty()) {
+ NewSinceMaps::iterator nsmap = newSinceMaps.find(sinceVersion);
+ if (nsmap == newSinceMaps.end())
+ nsmap = newSinceMaps.insert(sinceVersion,NodeMultiMap());
+ NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion);
+ if (ncmap == newClassMaps.end())
+ ncmap = newClassMaps.insert(sinceVersion,NodeMap());
+ NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion);
+ if (nqcmap == newQmlClassMaps.end())
+ nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap());
+
+ if ((*child)->type() == Node::Function) {
+ FunctionNode *func = static_cast<FunctionNode *>(*child);
+ if ((func->status() > Node::Obsolete) &&
+ (func->metaness() != FunctionNode::Ctor) &&
+ (func->metaness() != FunctionNode::Dtor)) {
+ nsmap.value().insert(func->name(),(*child));
+ }
+ }
+ else if ((*child)->url().isEmpty()) {
+ if ((*child)->type() == Node::Class && !(*child)->doc().isEmpty()) {
+ QString className = (*child)->name();
+ if ((*child)->parent() &&
+ (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty())
+ className = (*child)->parent()->name()+"::"+className;
+ nsmap.value().insert(className,(*child));
+ ncmap.value().insert(className,(*child));
+ }
+ else if ((*child)->subType() == Node::QmlClass) {
+ QString className = (*child)->name();
+ if ((*child)->parent() &&
+ (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty())
+ className = (*child)->parent()->name()+"::"+className;
+ nsmap.value().insert(className,(*child));
+ nqcmap.value().insert(className,(*child));
+ }
+ }
+ else {
+ QString name = (*child)->name();
+ if ((*child)->parent() &&
+ (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty())
+ name = (*child)->parent()->name()+"::"+name;
+ nsmap.value().insert(name,(*child));
+ }
+ if ((*child)->isInnerNode()) {
+ findAllSince(static_cast<InnerNode *>(*child));
+ }
+ }
+ ++child;
+ }
+}
+
+#if 0
+ const QRegExp versionSeparator("[\\-\\.]");
+ const int minorIndex = version.indexOf(versionSeparator);
+ const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);
+ version = version.left(patchIndex);
+#endif
+
+void DitaXmlGenerator::findAllFunctions(const InnerNode *node)
+{
+ NodeList::ConstIterator c = node->childNodes().begin();
+ while (c != node->childNodes().end()) {
+ if ((*c)->access() != Node::Private) {
+ if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ findAllFunctions(static_cast<const InnerNode *>(*c));
+ }
+ else if ((*c)->type() == Node::Function) {
+ const FunctionNode *func = static_cast<const FunctionNode *>(*c);
+ if ((func->status() > Node::Obsolete) &&
+ (func->metaness() != FunctionNode::Ctor) &&
+ (func->metaness() != FunctionNode::Dtor)) {
+ funcIndex[(*c)->name()].insert(myTree->fullDocumentName((*c)->parent()), *c);
+ }
+ }
+ }
+ ++c;
+ }
+}
+
+void DitaXmlGenerator::findAllLegaleseTexts(const InnerNode *node)
+{
+ NodeList::ConstIterator c = node->childNodes().begin();
+ while (c != node->childNodes().end()) {
+ if ((*c)->access() != Node::Private) {
+ if (!(*c)->doc().legaleseText().isEmpty())
+ legaleseTexts.insertMulti((*c)->doc().legaleseText(), *c);
+ if ((*c)->isInnerNode())
+ findAllLegaleseTexts(static_cast<const InnerNode *>(*c));
+ }
+ ++c;
+ }
+}
+
+void DitaXmlGenerator::findAllNamespaces(const InnerNode *node)
+{
+ NodeList::ConstIterator c = node->childNodes().begin();
+ while (c != node->childNodes().end()) {
+ if ((*c)->access() != Node::Private) {
+ if ((*c)->isInnerNode() && (*c)->url().isEmpty()) {
+ findAllNamespaces(static_cast<const InnerNode *>(*c));
+ if ((*c)->type() == Node::Namespace) {
+ const NamespaceNode *nspace = static_cast<const NamespaceNode *>(*c);
+ // Ensure that the namespace's name is not empty (the root
+ // namespace has no name).
+ if (!nspace->name().isEmpty()) {
+ namespaceIndex.insert(nspace->name(), *c);
+ QString moduleName = (*c)->moduleName();
+ if (moduleName == "Qt3SupportLight") {
+ moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
+ moduleName = "Qt3Support";
+ }
+ if (!moduleName.isEmpty())
+ moduleNamespaceMap[moduleName].insert((*c)->name(), *c);
+ }
+ }
+ }
+ }
+ ++c;
+ }
+}
+
+int DitaXmlGenerator::hOffset(const Node *node)
+{
+ switch (node->type()) {
+ case Node::Namespace:
+ case Node::Class:
+ return 2;
+ case Node::Fake:
+ return 1;
+#if 0
+ if (node->doc().briefText().isEmpty())
+ return 1;
+ else
+ return 2;
+#endif
+ case Node::Enum:
+ case Node::Typedef:
+ case Node::Function:
+ case Node::Property:
+ default:
+ return 3;
+ }
+}
+
+bool DitaXmlGenerator::isThreeColumnEnumValueTable(const Atom *atom)
+{
+ while (atom != 0 && !(atom->type() == Atom::ListRight && atom->string() == ATOM_LIST_VALUE)) {
+ if (atom->type() == Atom::ListItemLeft && !matchAhead(atom, Atom::ListItemRight))
+ return true;
+ atom = atom->next();
+ }
+ return false;
+}
+
+const Node *DitaXmlGenerator::findNodeForTarget(const QString &target,
+ const Node *relative,
+ CodeMarker *marker,
+ const Atom *atom)
+{
+ const Node *node = 0;
+
+ if (target.isEmpty()) {
+ node = relative;
+ }
+ else if (target.endsWith(".html")) {
+ node = myTree->root()->findNode(target, Node::Fake);
+ }
+ else if (marker) {
+ node = marker->resolveTarget(target, myTree, relative);
+ if (!node)
+ node = myTree->findFakeNodeByTitle(target);
+ if (!node && atom) {
+ node = myTree->findUnambiguousTarget(target,
+ *const_cast<Atom**>(&atom));
+ }
+ }
+
+ if (!node)
+ relative->doc().location().warning(tr("Cannot link to '%1'").arg(target));
+
+ return node;
+}
+
+const QPair<QString,QString> DitaXmlGenerator::anchorForNode(const Node *node)
+{
+ QPair<QString,QString> anchorPair;
+
+ anchorPair.first = PageGenerator::fileName(node);
+ if (node->type() == Node::Fake) {
+ const FakeNode *fakeNode = static_cast<const FakeNode*>(node);
+ anchorPair.second = fakeNode->title();
+ }
+
+ return anchorPair;
+}
+
+QString DitaXmlGenerator::getLink(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker,
+ const Node** node)
+{
+ QString link;
+ *node = 0;
+ inObsoleteLink = false;
+
+ if (atom->string().contains(":") &&
+ (atom->string().startsWith("file:")
+ || atom->string().startsWith("http:")
+ || atom->string().startsWith("https:")
+ || atom->string().startsWith("ftp:")
+ || atom->string().startsWith("mailto:"))) {
+
+ link = atom->string();
+ }
+ else {
+ QStringList path;
+ if (atom->string().contains('#')) {
+ path = atom->string().split('#');
+ }
+ else {
+ path.append(atom->string());
+ }
+
+ Atom *targetAtom = 0;
+
+ QString first = path.first().trimmed();
+ if (first.isEmpty()) {
+ *node = relative;
+ }
+ else if (first.endsWith(".html")) {
+ *node = myTree->root()->findNode(first, Node::Fake);
+ }
+ else {
+ *node = marker->resolveTarget(first, myTree, relative);
+ if (!*node) {
+ *node = myTree->findFakeNodeByTitle(first);
+ }
+ if (!*node) {
+ *node = myTree->findUnambiguousTarget(first, targetAtom);
+ }
+ }
+
+ if (*node) {
+ if (!(*node)->url().isEmpty())
+ return (*node)->url();
+ else
+ path.removeFirst();
+ }
+ else {
+ *node = relative;
+ }
+
+ if (*node) {
+ if ((*node)->status() == Node::Obsolete) {
+ if (relative) {
+ if (relative->parent() != *node) {
+ if (relative->status() != Node::Obsolete) {
+ bool porting = false;
+ if (relative->type() == Node::Fake) {
+ const FakeNode* fake = static_cast<const FakeNode*>(relative);
+ if (fake->title().startsWith("Porting"))
+ porting = true;
+ }
+ QString name = marker->plainFullName(relative);
+ if (!porting && !name.startsWith("Q3")) {
+ if (obsoleteLinks) {
+ relative->doc().location().warning(tr("Link to obsolete item '%1' in %2")
+ .arg(atom->string())
+ .arg(name));
+ }
+ inObsoleteLink = true;
+ }
+ }
+ }
+ }
+ else {
+ qDebug() << "Link to Obsolete entity"
+ << (*node)->name() << "no relative";
+ }
+ }
+#if 0
+ else if ((*node)->status() == Node::Deprecated) {
+ qDebug() << "Link to Deprecated entity";
+ }
+ else if ((*node)->status() == Node::Internal) {
+ qDebug() << "Link to Internal entity";
+ }
+#endif
+ }
+
+ while (!path.isEmpty()) {
+ targetAtom = myTree->findTarget(path.first(), *node);
+ if (targetAtom == 0)
+ break;
+ path.removeFirst();
+ }
+
+ if (path.isEmpty()) {
+ link = linkForNode(*node, relative);
+ if (*node && (*node)->subType() == Node::Image)
+ link = "images/used-in-examples/" + link;
+ if (targetAtom)
+ link += "#" + refForAtom(targetAtom, *node);
+ }
+ }
+ return link;
+}
+
+void DitaXmlGenerator::generateIndex(const QString &fileBase,
+ const QString &url,
+ const QString &title)
+{
+ myTree->generateIndex(outputDir() + "/" + fileBase + ".index", url, title);
+}
+
+void DitaXmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
+{
+ Text text;
+
+ switch (node->status()) {
+ case Node::Obsolete:
+ if (node->isInnerNode())
+ Generator::generateStatus(node, marker);
+ break;
+ case Node::Compat:
+ if (node->isInnerNode()) {
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "This "
+ << typeString(node)
+ << " is part of the Qt 3 support library."
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
+ << " It is provided to keep old source code working. "
+ << "We strongly advise against "
+ << "using it in new code. See ";
+
+ const FakeNode *fakeNode = myTree->findFakeNodeByTitle("Porting To Qt 4");
+ Atom *targetAtom = 0;
+ if (fakeNode && node->type() == Node::Class) {
+ QString oldName(node->name());
+ targetAtom = myTree->findTarget(oldName.replace("3", ""),
+ fakeNode);
+ }
+
+ if (targetAtom) {
+ text << Atom(Atom::Link, linkForNode(fakeNode, node) + "#" +
+ refForAtom(targetAtom, fakeNode));
+ }
+ else
+ text << Atom(Atom::Link, "Porting to Qt 4");
+
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, "Porting to Qt 4")
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK)
+ << " for more information."
+ << Atom::ParaRight;
+ }
+ generateText(text, node, marker);
+ break;
+ default:
+ Generator::generateStatus(node, marker);
+ }
+}
+
+#ifdef GENERATE_MAC_REFS
+/*
+ No longer valid.
+ */
+void DitaXmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
+{
+ if (!pleaseGenerateMacRef || marker == 0)
+ return;
+
+ QStringList macRefs = marker->macRefsForNode(node);
+ foreach (const QString &macRef, macRefs)
+ out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
+}
+#endif
+
+void DitaXmlGenerator::beginLink(const QString &link,
+ const Node *node,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ Q_UNUSED(marker)
+ Q_UNUSED(relative)
+
+ this->link = link;
+ if (link.isEmpty()) {
+ if (showBrokenLinks)
+ writer.writeStartElement("i");
+ }
+ else if (node == 0 || (relative != 0 &&
+ node->status() == relative->status())) {
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",link);
+ }
+ else {
+ switch (node->status()) {
+ case Node::Obsolete:
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",link);
+ writer.writeAttribute("outputclass","obsolete");
+ break;
+ case Node::Compat:
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",link);
+ writer.writeAttribute("outputclass","compat");
+ break;
+ default:
+ writer.writeStartElement("xref");
+ writer.writeAttribute("href",link);
+ }
+ }
+ inLink = true;
+}
+
+void DitaXmlGenerator::endLink()
+{
+ if (inLink) {
+ if (link.isEmpty()) {
+ if (showBrokenLinks)
+ writer.writeEndElement(); // i
+ }
+ else {
+ if (inObsoleteLink) {
+ writer.writeStartElement("sup");
+ writer.writeCharacters("(obsolete)");
+ writer.writeEndElement(); // sup
+ }
+ writer.writeEndElement(); // xref
+ }
+ }
+ inLink = false;
+ inObsoleteLink = false;
+}
+
+#ifdef QDOC_QML
+
+/*!
+ Generates the summary for the \a section. Only used for
+ sections of QML element documentation.
+
+ Currently handles only the QML property group.
+ */
+void DitaXmlGenerator::generateQmlSummary(const Section& section,
+ const Node *relative,
+ CodeMarker *marker)
+{
+ if (!section.members.isEmpty()) {
+ NodeList::ConstIterator m;
+ int count = section.members.size();
+ bool twoColumn = false;
+ if (section.members.first()->type() == Node::QmlProperty) {
+ twoColumn = (count >= 5);
+ }
+ if (twoColumn)
+ out() << "<table class=\"qmlsummary\">\n";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd topAlign\">";
+ else
+ out() << "<tr class=\"even topAlign\">";
+ // << "<tr><td class=\"topAlign\">";
+ out() << "<ul>\n";
+
+ int row = 0;
+ m = section.members.begin();
+ while (m != section.members.end()) {
+ if (twoColumn && row == (int) (count + 1) / 2)
+ out() << "</ul></td><td class=\"topAlign\"><ul>\n";
+ out() << "<li class=\"fn\">";
+ generateQmlItem(*m,relative,marker,true);
+ out() << "</li>\n";
+ row++;
+ ++m;
+ }
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table>\n";
+ }
+}
+
+/*!
+ Outputs the html detailed documentation for a section
+ on a QML element reference page.
+ */
+void DitaXmlGenerator::generateDetailedQmlMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker)
+{
+ const QmlPropertyNode* qpn = 0;
+#ifdef GENERATE_MAC_REFS
+ generateMacRef(node, marker);
+#endif
+ out() << "<div class=\"qmlitem\">";
+ if (node->subType() == Node::QmlPropertyGroup) {
+ const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
+ NodeList::ConstIterator p = qpgn->childNodes().begin();
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+
+ while (p != qpgn->childNodes().end()) {
+ if ((*p)->type() == Node::QmlProperty) {
+ qpn = static_cast<const QmlPropertyNode*>(*p);
+
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+
+ out() << "<td><p>";
+ //out() << "<tr><td>"; // old
+ out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
+ if (!qpn->isWritable(myTree))
+ out() << "<span class=\"qmlreadonly\">read-only</span>";
+ if (qpgn->isDefault())
+ out() << "<span class=\"qmldefault\">default</span>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</td></tr>";
+ }
+ ++p;
+ }
+ out() << "</table>";
+ out() << "</div>";
+ }
+ else if (node->type() == Node::QmlSignal) {
+ const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ //out() << "<tr>";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+ out() << "<td><p>";
+ out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
+ generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
+ //generateQmlItem(qsn,relative,marker,false);
+ out() << "</p></td></tr>";
+ out() << "</table>";
+ out() << "</div>";
+ }
+ else if (node->type() == Node::QmlMethod) {
+ const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
+ out() << "<div class=\"qmlproto\">";
+ out() << "<table class=\"qmlname\">";
+ //out() << "<tr>";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+ out() << "<td><p>";
+ out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
+ generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
+ out() << "</p></td></tr>";
+ out() << "</table>";
+ out() << "</div>";
+ }
+ out() << "<div class=\"qmldoc\">";
+ generateStatus(node, marker);
+ generateBody(node, marker);
+ generateThreadSafeness(node, marker);
+ generateSince(node, marker);
+ generateAlsoList(node, marker);
+ out() << "</div>";
+ out() << "</div>";
+}
+
+/*!
+ Output the "Inherits" line for the QML element,
+ if there should be one.
+ */
+void DitaXmlGenerator::generateQmlInherits(const QmlClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn && !cn->links().empty()) {
+ if (cn->links().contains(Node::InheritsLink)) {
+ QPair<QString,QString> linkPair;
+ linkPair = cn->links()[Node::InheritsLink];
+ QStringList strList(linkPair.first);
+ const Node* n = myTree->findNode(strList,Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
+ out() << "<p class=\"centerAlign\">";
+ Text text;
+ text << "[Inherits ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, linkPair.second);
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, cn, marker);
+ out() << "</p>";
+ }
+ }
+ }
+}
+
+/*!
+ Output the "Inherit by" list for the QML element,
+ if it is inherited by any other elements.
+ */
+void DitaXmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn) {
+ NodeList subs;
+ QmlClassNode::subclasses(cn->name(),subs);
+ if (!subs.isEmpty()) {
+ Text text;
+ text << Atom::ParaLeft << "Inherited by ";
+ appendSortedQmlNames(text,cn,subs,marker);
+ text << Atom::ParaRight;
+ generateText(text, cn, marker);
+ }
+ }
+}
+
+/*!
+ Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]"
+ line for the QML element, if there should be one.
+
+ If there is no class node, or if the class node status
+ is set to Node::Internal, do nothing.
+ */
+void DitaXmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
+ CodeMarker* marker)
+{
+ const ClassNode* cn = qcn->classNode();
+ if (cn && (cn->status() != Node::Internal)) {
+ out() << "<p class=\"centerAlign\">";
+ Text text;
+ text << "[";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, qcn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " instantiates the C++ class ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, qcn, marker);
+ out() << "</p>";
+ }
+}
+
+/*!
+ Output the "[QmlGraphicsXxx is instantiated by QML element Xxx]"
+ line for the class, if there should be one.
+
+ If there is no QML element, or if the class node status
+ is set to Node::Internal, do nothing.
+ */
+void DitaXmlGenerator::generateInstantiatedBy(const ClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
+ const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
+ if (n && n->subType() == Node::QmlClass) {
+ out() << "<p class=\"centerAlign\">";
+ Text text;
+ text << "[";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, cn->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << " is instantiated by QML element ";
+ text << Atom(Atom::LinkNode,CodeMarker::stringForNode(n));
+ text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
+ text << Atom(Atom::String, n->name());
+ text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ text << "]";
+ generateText(text, cn, marker);
+ out() << "</p>";
+ }
+ }
+}
+
+/*!
+ Generate the <page> element for the given \a node using the \a writer.
+ Return true if a <page> element was written; otherwise return false.
+ */
+bool DitaXmlGenerator::generatePageElement(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const
+{
+ if (node->pageType() == Node::NoPageType)
+ return false;
+ if (node->name().isEmpty())
+ return true;
+ if (node->access() == Node::Private)
+ return false;
+ if (!node->isInnerNode())
+ return false;
+
+ QString title;
+ QString rawTitle;
+ QString fullTitle;
+ const InnerNode* inner = static_cast<const InnerNode*>(node);
+
+ writer.writeStartElement("page");
+ QXmlStreamAttributes attributes;
+ QString t;
+ t.setNum(id++);
+ switch (node->type()) {
+ case Node::Fake:
+ {
+ const FakeNode* fake = static_cast<const FakeNode*>(node);
+ title = fake->fullTitle();
+ break;
+ }
+ case Node::Class:
+ {
+ title = node->name() + " Class Reference";
+ break;
+ }
+ case Node::Namespace:
+ {
+ rawTitle = marker->plainName(inner);
+ fullTitle = marker->plainFullName(inner);
+ title = rawTitle + " Namespace Reference";
+ break;
+ }
+ default:
+ title = node->name();
+ break;
+ }
+ writer.writeAttribute("id",t);
+ writer.writeStartElement("pageWords");
+ writer.writeCharacters(title);
+ if (!inner->pageKeywords().isEmpty()) {
+ const QStringList& w = inner->pageKeywords();
+ for (int i = 0; i < w.size(); ++i) {
+ writer.writeCharacters(" ");
+ writer.writeCharacters(w.at(i).toLocal8Bit().constData());
+ }
+ }
+ writer.writeEndElement();
+ writer.writeStartElement("pageTitle");
+ writer.writeCharacters(title);
+ writer.writeEndElement();
+ writer.writeStartElement("pageUrl");
+ writer.writeCharacters(PageGenerator::fileName(node));
+ writer.writeEndElement();
+ writer.writeStartElement("pageType");
+ switch (node->pageType()) {
+ case Node::ApiPage:
+ writer.writeCharacters("APIPage");
+ break;
+ case Node::ArticlePage:
+ writer.writeCharacters("Article");
+ break;
+ case Node::ExamplePage:
+ writer.writeCharacters("Example");
+ break;
+ default:
+ break;
+ }
+ writer.writeEndElement();
+ writer.writeEndElement();
+ return true;
+}
+
+/*!
+ Traverse the tree recursively and generate the <keyword>
+ elements.
+ */
+void DitaXmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const
+{
+ if (generatePageElement(writer, node, marker)) {
+
+ if (node->isInnerNode()) {
+ const InnerNode *inner = static_cast<const InnerNode *>(node);
+
+ // Recurse to write an element for this child node and all its children.
+ foreach (const Node *child, inner->childNodes())
+ generatePageElements(writer, child, marker);
+ }
+ }
+}
+
+/*!
+ Outputs the file containing the index used for searching the html docs.
+ */
+void DitaXmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const
+{
+ QFile file(fileName);
+ if (!file.open(QFile::WriteOnly | QFile::Text))
+ return ;
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
+ writer.writeStartElement("qtPageIndex");
+
+ generatePageElements(writer, myTree->root(), marker);
+
+ writer.writeEndElement(); // qtPageIndex
+ writer.writeEndDocument();
+ file.close();
+}
+
+#endif
+
+/*!
+ Return the full qualification of the node \a n, but without
+ the name of \a n itself. e.g. A::B::C
+ */
+QString DitaXmlGenerator::fullQualification(const Node* n)
+{
+ QString fq;
+ InnerNode* in = n->parent();
+ while (in) {
+ if ((in->type() == Node::Class) ||
+ (in->type() == Node::Namespace)) {
+ if (in->name().isEmpty())
+ break;
+ if (fq.isEmpty())
+ fq = in->name();
+ else
+ fq = in->name() + "::" + fq;
+ }
+ else
+ break;
+ in = in->parent();
+ }
+ return fq;
+}
+
+void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker)
+{
+ QList<RelatedClass>::ConstIterator r;
+ int index;
+
+ if (!cn->baseClasses().isEmpty()) {
+ writer.writeStartElement(CXXCLASSDERIVATIONS);
+ r = cn->baseClasses().begin();
+ index = 0;
+ while (r != cn->baseClasses().end()) {
+ writer.writeStartElement(CXXCLASSDERIVATION);
+ writer.writeStartElement(CXXCLASSDERIVATIONACCESSSPECIFIER);
+ writer.writeAttribute("value",(*r).accessString());
+ writer.writeEndElement(); // </cxxClassDerivationAccessSpecifier>
+ writer.writeStartElement(CXXCLASSBASECLASS);
+ writer.writeAttribute("href",(*r).node->ditaXmlHref());
+ writer.writeCharacters(marker->plainFullName((*r).node));
+ writer.writeEndElement(); // </cxxClassBaseClass>
+ writer.writeEndElement(); // </cxxClassDerivation>
+ ++r;
+ }
+ writer.writeEndElement(); // </cxxClassDerivations>
+ }
+}
+
+void DitaXmlGenerator::writeLocation(const Node* n)
+{
+ QString s1, s2, s3;
+ if (n->type() == Node::Class) {
+ s1 = CXXCLASSAPIITEMLOCATION;
+ s2 = CXXCLASSDECLARATIONFILE;
+ s3 = CXXCLASSDECLARATIONFILELINE;
+ }
+ else if (n->type() == Node::Function) {
+ s1 = CXXFUNCTIONAPIITEMLOCATION;
+ s2 = CXXFUNCTIONDECLARATIONFILE;
+ s3 = CXXFUNCTIONDECLARATIONFILELINE;
+ }
+ else if (n->type() == Node::Enum) {
+ s1 = CXXENUMERATIONAPIITEMLOCATION;
+ s2 = CXXENUMERATIONDECLARATIONFILE;
+ s3 = CXXENUMERATIONDECLARATIONFILELINE;
+ }
+ else if (n->type() == Node::Typedef) {
+ s1 = CXXTYPEDEFAPIITEMLOCATION;
+ s2 = CXXTYPEDEFDECLARATIONFILE;
+ s3 = CXXTYPEDEFDECLARATIONFILELINE;
+ }
+ else if ((n->type() == Node::Property) ||
+ (n->type() == Node::Variable)) {
+ s1 = CXXVARIABLEAPIITEMLOCATION;
+ s2 = CXXVARIABLEDECLARATIONFILE;
+ s3 = CXXVARIABLEDECLARATIONFILELINE;
+ }
+ writer.writeStartElement(s1);
+ writer.writeStartElement(s2);
+ writer.writeAttribute("name","filePath");
+ writer.writeAttribute("value",n->location().filePath());
+ writer.writeEndElement(); // </cxx<s2>DeclarationFile>
+ writer.writeStartElement(s3);
+ writer.writeAttribute("name","lineNumber");
+ QString lineNr;
+ writer.writeAttribute("value",lineNr.setNum(n->location().lineNo()));
+ writer.writeEndElement(); // </cxx<s3>DeclarationFileLine>
+ writer.writeEndElement(); // </cxx<s1>ApiItemLocation>
+}
+
+void DitaXmlGenerator::writeFunctions(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Function) {
+ FunctionNode* fn = const_cast<FunctionNode*>(static_cast<const FunctionNode*>(*m));
+ writer.writeStartElement(CXXFUNCTION);
+ writer.writeAttribute("id",fn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(fn->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(fn,marker);
+ writer.writeStartElement(CXXFUNCTIONDETAIL);
+ writer.writeStartElement(CXXFUNCTIONDEFINITION);
+ writer.writeStartElement(CXXFUNCTIONACCESSSPECIFIER);
+ writer.writeAttribute("value",fn->accessString());
+ writer.writeEndElement(); // <cxxFunctionAccessSpecifier>
+
+ if (fn->isStatic()) {
+ writer.writeStartElement(CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC);
+ writer.writeAttribute("name","static");
+ writer.writeAttribute("value","static");
+ writer.writeEndElement(); // <cxxFunctionStorageClassSpecifierStatic>
+ }
+
+ if (fn->isConst()) {
+ writer.writeStartElement(CXXFUNCTIONCONST);
+ writer.writeAttribute("name","const");
+ writer.writeAttribute("value","const");
+ writer.writeEndElement(); // <cxxFunctionConst>
+ }
+
+ if (fn->virtualness() != FunctionNode::NonVirtual) {
+ writer.writeStartElement(CXXFUNCTIONVIRTUAL);
+ writer.writeAttribute("name","virtual");
+ writer.writeAttribute("value","virtual");
+ writer.writeEndElement(); // <cxxFunctionVirtual>
+ if (fn->virtualness() == FunctionNode::PureVirtual) {
+ writer.writeStartElement(CXXFUNCTIONPUREVIRTUAL);
+ writer.writeAttribute("name","pure virtual");
+ writer.writeAttribute("value","pure virtual");
+ writer.writeEndElement(); // <cxxFunctionPureVirtual>
+ }
+ }
+
+ if (fn->name() == cn->name()) {
+ writer.writeStartElement(CXXFUNCTIONCONSTRUCTOR);
+ writer.writeAttribute("name","constructor");
+ writer.writeAttribute("value","constructor");
+ writer.writeEndElement(); // <cxxFunctionConstructor>
+ }
+ else if (fn->name()[0] == QChar('~')) {
+ writer.writeStartElement(CXXFUNCTIONDESTRUCTOR);
+ writer.writeAttribute("name","destructor");
+ writer.writeAttribute("value","destructor");
+ writer.writeEndElement(); // <cxxFunctionDestructor>
+ }
+ else {
+ writer.writeStartElement(CXXFUNCTIONDECLAREDTYPE);
+ writer.writeCharacters(fn->returnType());
+ writer.writeEndElement(); // <cxxFunctionDeclaredType>
+ }
+ QString fq = fullQualification(fn);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXFUNCTIONSCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxFunctionScopedName>
+ }
+ writer.writeStartElement(CXXFUNCTIONPROTOTYPE);
+ writer.writeCharacters(fn->signature(true));
+ writer.writeEndElement(); // <cxxFunctionPrototype>
+
+ QString fnl = fn->signature(false);
+ int idx = fnl.indexOf(' ');
+ if (idx < 0)
+ idx = 0;
+ else
+ ++idx;
+ fnl = fn->parent()->name() + "::" + fnl.mid(idx);
+ writer.writeStartElement(CXXFUNCTIONNAMELOOKUP);
+ writer.writeCharacters(fnl);
+ writer.writeEndElement(); // <cxxFunctionNameLookup>
+
+ if (fn->isReimp() && fn->reimplementedFrom() != 0) {
+ FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom();
+ writer.writeStartElement(CXXFUNCTIONREIMPLEMENTED);
+ writer.writeAttribute("href",rfn->ditaXmlHref());
+ writer.writeCharacters(marker->plainFullName(rfn));
+ writer.writeEndElement(); // </cxxFunctionReimplemented>
+ }
+ writeParameters(fn,marker);
+ writeLocation(fn);
+ writer.writeEndElement(); // <cxxFunctionDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!fn->doc().isEmpty()) {
+ generateBody(fn, marker);
+ // generateAlsoList(inner, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxFunctionDetail>
+ writer.writeEndElement(); // </cxxFunction>
+
+ if (fn->metaness() == FunctionNode::Ctor ||
+ fn->metaness() == FunctionNode::Dtor ||
+ fn->overloadNumber() != 1) {
+ }
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeParameters(const FunctionNode* fn, CodeMarker* marker)
+{
+ const QList<Parameter>& parameters = fn->parameters();
+ if (!parameters.isEmpty()) {
+ writer.writeStartElement(CXXFUNCTIONPARAMETERS);
+ QList<Parameter>::ConstIterator p = parameters.begin();
+ while (p != parameters.end()) {
+ writer.writeStartElement(CXXFUNCTIONPARAMETER);
+ writer.writeStartElement(CXXFUNCTIONPARAMETERDECLAREDTYPE);
+ writer.writeCharacters((*p).leftType());
+ if (!(*p).rightType().isEmpty())
+ writer.writeCharacters((*p).rightType());
+ writer.writeEndElement(); // <cxxFunctionParameterDeclaredType>
+ writer.writeStartElement(CXXFUNCTIONPARAMETERDECLARATIONNAME);
+ writer.writeCharacters((*p).name());
+ writer.writeEndElement(); // <cxxFunctionParameterDeclarationName>
+ if (!(*p).defaultValue().isEmpty()) {
+ writer.writeStartElement(CXXFUNCTIONPARAMETERDEFAULTVALUE);
+ writer.writeCharacters((*p).defaultValue());
+ writer.writeEndElement(); // <cxxFunctionParameterDefaultValue>
+ }
+ writer.writeEndElement(); // <cxxFunctionParameter>
+ ++p;
+ }
+ writer.writeEndElement(); // <cxxFunctionParameters>
+ }
+}
+
+void DitaXmlGenerator::writeEnumerations(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Enum) {
+ const EnumNode* en = static_cast<const EnumNode*>(*m);
+ writer.writeStartElement(CXXENUMERATION);
+ writer.writeAttribute("id",en->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(en->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(en,marker);
+ writer.writeStartElement(CXXENUMERATIONDETAIL);
+ writer.writeStartElement(CXXENUMERATIONDEFINITION);
+ writer.writeStartElement(CXXENUMERATIONACCESSSPECIFIER);
+ writer.writeAttribute("value",en->accessString());
+ writer.writeEndElement(); // <cxxEnumerationAccessSpecifier>
+
+ QString fq = fullQualification(en);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXENUMERATIONSCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxEnumerationScopedName>
+ }
+ const QList<EnumItem>& items = en->items();
+ if (!items.isEmpty()) {
+ writer.writeStartElement(CXXENUMERATIONPROTOTYPE);
+ writer.writeCharacters(en->name());
+ writer.writeCharacters(" = { ");
+ QList<EnumItem>::ConstIterator i = items.begin();
+ while (i != items.end()) {
+ writer.writeCharacters((*i).name());
+ if (!(*i).value().isEmpty()) {
+ writer.writeCharacters(" = ");
+ writer.writeCharacters((*i).value());
+ }
+ ++i;
+ if (i != items.end())
+ writer.writeCharacters(", ");
+ }
+ writer.writeCharacters(" }");
+ writer.writeEndElement(); // <cxxEnumerationPrototype>
+ }
+
+ writer.writeStartElement(CXXENUMERATIONNAMELOOKUP);
+ writer.writeCharacters(en->parent()->name() + "::" + en->name());
+ writer.writeEndElement(); // <cxxEnumerationNameLookup>
+
+ if (!items.isEmpty()) {
+ writer.writeStartElement(CXXENUMERATORS);
+ QList<EnumItem>::ConstIterator i = items.begin();
+ while (i != items.end()) {
+ writer.writeStartElement(CXXENUMERATOR);
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters((*i).name());
+ writer.writeEndElement(); // </apiName>
+
+ QString fq = fullQualification(en->parent());
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXENUMERATORSCOPEDNAME);
+ writer.writeCharacters(fq + "::" + (*i).name());
+ writer.writeEndElement(); // <cxxEnumeratorScopedName>
+ }
+ writer.writeStartElement(CXXENUMERATORPROTOTYPE);
+ writer.writeCharacters((*i).name());
+ writer.writeEndElement(); // <cxxEnumeratorPrototype>
+ writer.writeStartElement(CXXENUMERATORNAMELOOKUP);
+ writer.writeCharacters(en->parent()->name() + "::" + (*i).name());
+ writer.writeEndElement(); // <cxxEnumeratorNameLookup>
+
+ if (!(*i).value().isEmpty()) {
+ writer.writeStartElement(CXXENUMERATORINITIALISER);
+ writer.writeAttribute("value", (*i).value());
+ writer.writeEndElement(); // <cxxEnumeratorInitialiser>
+ }
+ if (!(*i).text().isEmpty()) {
+ writer.writeStartElement(APIDESC);
+ generateText((*i).text(), en, marker);
+ writer.writeEndElement(); // </apiDesc>
+ }
+ writer.writeEndElement(); // <cxxEnumerator>
+ ++i;
+ }
+ writer.writeEndElement(); // <cxxEnumerators>
+ }
+
+ writeLocation(en);
+ writer.writeEndElement(); // <cxxEnumerationDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!en->doc().isEmpty()) {
+ generateBody(en, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxEnumerationDetail>
+ writer.writeEndElement(); // </cxxEnumeration>
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeTypedefs(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Typedef) {
+ const TypedefNode* tn = static_cast<const TypedefNode*>(*m);
+ writer.writeStartElement(CXXTYPEDEF);
+ writer.writeAttribute("id",tn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(tn->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(tn,marker);
+ writer.writeStartElement(CXXTYPEDEFDETAIL);
+ writer.writeStartElement(CXXTYPEDEFDEFINITION);
+ writer.writeStartElement(CXXTYPEDEFACCESSSPECIFIER);
+ writer.writeAttribute("value",tn->accessString());
+ writer.writeEndElement(); // <cxxTypedefAccessSpecifier>
+
+ QString fq = fullQualification(tn);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXTYPEDEFSCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxTypedefScopedName>
+ }
+ writer.writeStartElement(CXXTYPEDEFNAMELOOKUP);
+ writer.writeCharacters(tn->parent()->name() + "::" + tn->name());
+ writer.writeEndElement(); // <cxxTypedefNameLookup>
+
+ writeLocation(tn);
+ writer.writeEndElement(); // <cxxTypedefDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!tn->doc().isEmpty()) {
+ generateBody(tn, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxTypedefDetail>
+ writer.writeEndElement(); // </cxxTypedef>
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeProperties(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Property) {
+ const PropertyNode* pn = static_cast<const PropertyNode*>(*m);
+ writer.writeStartElement(CXXVARIABLE);
+ writer.writeAttribute("id",pn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(pn->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(pn,marker);
+ writer.writeStartElement(CXXVARIABLEDETAIL);
+ writer.writeStartElement(CXXVARIABLEDEFINITION);
+ writer.writeStartElement(CXXVARIABLEACCESSSPECIFIER);
+ writer.writeAttribute("value",pn->accessString());
+ writer.writeEndElement(); // <cxxVariableAccessSpecifier>
+
+ if (!pn->qualifiedDataType().isEmpty()) {
+ writer.writeStartElement(CXXVARIABLEDECLAREDTYPE);
+ writer.writeCharacters(pn->qualifiedDataType());
+ writer.writeEndElement(); // <cxxVariableDeclaredType>
+ }
+ QString fq = fullQualification(pn);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXVARIABLESCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxVariableScopedName>
+ }
+
+ writer.writeStartElement(CXXVARIABLEPROTOTYPE);
+ writer.writeCharacters("Q_PROPERTY(");
+ writer.writeCharacters(pn->qualifiedDataType());
+ writer.writeCharacters(" ");
+ writer.writeCharacters(pn->name());
+ writePropParams("READ",pn->getters());
+ writePropParams("WRITE",pn->setters());
+ writePropParams("RESET",pn->resetters());
+ writePropParams("NOTIFY",pn->notifiers());
+ if (pn->isDesignable() != pn->designableDefault()) {
+ writer.writeCharacters(" DESIGNABLE ");
+ if (!pn->runtimeDesignabilityFunction().isEmpty())
+ writer.writeCharacters(pn->runtimeDesignabilityFunction());
+ else
+ writer.writeCharacters(pn->isDesignable() ? "true" : "false");
+ }
+ if (pn->isScriptable() != pn->scriptableDefault()) {
+ writer.writeCharacters(" SCRIPTABLE ");
+ if (!pn->runtimeScriptabilityFunction().isEmpty())
+ writer.writeCharacters(pn->runtimeScriptabilityFunction());
+ else
+ writer.writeCharacters(pn->isScriptable() ? "true" : "false");
+ }
+ if (pn->isWritable() != pn->writableDefault()) {
+ writer.writeCharacters(" STORED ");
+ writer.writeCharacters(pn->isStored() ? "true" : "false");
+ }
+ if (pn->isUser() != pn->userDefault()) {
+ writer.writeCharacters(" USER ");
+ writer.writeCharacters(pn->isUser() ? "true" : "false");
+ }
+ if (pn->isConstant())
+ writer.writeCharacters(" CONSTANT");
+ if (pn->isFinal())
+ writer.writeCharacters(" FINAL");
+ writer.writeCharacters(")");
+ writer.writeEndElement(); // <cxxVariablePrototype>
+
+ writer.writeStartElement(CXXVARIABLENAMELOOKUP);
+ writer.writeCharacters(pn->parent()->name() + "::" + pn->name());
+ writer.writeEndElement(); // <cxxVariableNameLookup>
+
+ if (pn->overriddenFrom() != 0) {
+ PropertyNode* opn = (PropertyNode*)pn->overriddenFrom();
+ writer.writeStartElement(CXXVARIABLEREIMPLEMENTED);
+ writer.writeAttribute("href",opn->ditaXmlHref());
+ writer.writeCharacters(marker->plainFullName(opn));
+ writer.writeEndElement(); // </cxxVariableReimplemented>
+ }
+
+ writeLocation(pn);
+ writer.writeEndElement(); // <cxxVariableDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!pn->doc().isEmpty()) {
+ generateBody(pn, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxVariableDetail>
+ writer.writeEndElement(); // </cxxVariable>
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeDataMembers(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Variable) {
+ const VariableNode* vn = static_cast<const VariableNode*>(*m);
+ writer.writeStartElement(CXXVARIABLE);
+ writer.writeAttribute("id",vn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(vn->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(vn,marker);
+ writer.writeStartElement(CXXVARIABLEDETAIL);
+ writer.writeStartElement(CXXVARIABLEDEFINITION);
+ writer.writeStartElement(CXXVARIABLEACCESSSPECIFIER);
+ writer.writeAttribute("value",vn->accessString());
+ writer.writeEndElement(); // <cxxVariableAccessSpecifier>
+
+ if (vn->isStatic()) {
+ writer.writeStartElement(CXXVARIABLESTORAGECLASSSPECIFIERSTATIC);
+ writer.writeAttribute("name","static");
+ writer.writeAttribute("value","static");
+ writer.writeEndElement(); // <cxxVariableStorageClassSpecifierStatic>
+ }
+
+ writer.writeStartElement(CXXVARIABLEDECLAREDTYPE);
+ writer.writeCharacters(vn->leftType());
+ if (!vn->rightType().isEmpty())
+ writer.writeCharacters(vn->rightType());
+ writer.writeEndElement(); // <cxxVariableDeclaredType>
+
+ QString fq = fullQualification(vn);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXVARIABLESCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxVariableScopedName>
+ }
+
+ writer.writeStartElement(CXXVARIABLEPROTOTYPE);
+ writer.writeCharacters(vn->leftType() + " ");
+ //writer.writeCharacters(vn->parent()->name() + "::" + vn->name());
+ writer.writeCharacters(vn->name());
+ if (!vn->rightType().isEmpty())
+ writer.writeCharacters(vn->rightType());
+ writer.writeEndElement(); // <cxxVariablePrototype>
+
+ writer.writeStartElement(CXXVARIABLENAMELOOKUP);
+ writer.writeCharacters(vn->parent()->name() + "::" + vn->name());
+ writer.writeEndElement(); // <cxxVariableNameLookup>
+
+ writeLocation(vn);
+ writer.writeEndElement(); // <cxxVariableDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!vn->doc().isEmpty()) {
+ generateBody(vn, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxVariableDetail>
+ writer.writeEndElement(); // </cxxVariable>
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeMacros(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Function) {
+ const FunctionNode* fn = static_cast<const FunctionNode*>(*m);
+ if (fn->isMacro()) {
+ writer.writeStartElement(CXXDEFINE);
+ writer.writeAttribute("id",fn->guid());
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(fn->name());
+ writer.writeEndElement(); // </apiName>
+ generateBrief(fn,marker);
+ writer.writeStartElement(CXXDEFINEDETAIL);
+ writer.writeStartElement(CXXDEFINEDEFINITION);
+ writer.writeStartElement(CXXDEFINEACCESSSPECIFIER);
+ writer.writeAttribute("value",fn->accessString());
+ writer.writeEndElement(); // <cxxDefineAccessSpecifier>
+
+ writer.writeStartElement(CXXDEFINEPROTOTYPE);
+ writer.writeCharacters("#define ");
+ writer.writeCharacters(fn->name());
+ if (fn->metaness() == FunctionNode::MacroWithParams) {
+ QStringList params = fn->parameterNames();
+ if (!params.isEmpty()) {
+ writer.writeCharacters("(");
+ for (int i = 0; i < params.size(); ++i) {
+ if (params[i].isEmpty())
+ writer.writeCharacters("...");
+ else
+ writer.writeCharacters(params[i]);
+ if ((i+1) < params.size())
+ writer.writeCharacters(", ");
+ }
+ writer.writeCharacters(")");
+ }
+ }
+ writer.writeEndElement(); // <cxxDefinePrototype>
+
+ writer.writeStartElement(CXXDEFINENAMELOOKUP);
+ writer.writeCharacters(fn->name());
+ writer.writeEndElement(); // <cxxDefineNameLookup>
+
+ if (fn->reimplementedFrom() != 0) {
+ FunctionNode* rfn = (FunctionNode*)fn->reimplementedFrom();
+ writer.writeStartElement(CXXDEFINEREIMPLEMENTED);
+ writer.writeAttribute("href",rfn->ditaXmlHref());
+ writer.writeCharacters(marker->plainFullName(rfn));
+ writer.writeEndElement(); // </cxxDefineReimplemented>
+ }
+
+ if (fn->metaness() == FunctionNode::MacroWithParams) {
+ QStringList params = fn->parameterNames();
+ if (!params.isEmpty()) {
+ writer.writeStartElement(CXXDEFINEPARAMETERS);
+ for (int i = 0; i < params.size(); ++i) {
+ writer.writeStartElement(CXXDEFINEPARAMETER);
+ writer.writeStartElement(CXXDEFINEPARAMETERDECLARATIONNAME);
+ writer.writeCharacters(params[i]);
+ writer.writeEndElement(); // <cxxDefineParameterDeclarationName>
+ writer.writeEndElement(); // <cxxDefineParameter>
+ }
+ writer.writeEndElement(); // <cxxDefineParameters>
+ }
+ }
+
+ writeLocation(fn);
+ writer.writeEndElement(); // <cxxDefineDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!fn->doc().isEmpty()) {
+ generateBody(fn, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxDefineDetail>
+ writer.writeEndElement(); // </cxxDefine>
+ }
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writePropParams(const QString& tag, const NodeList& nlist)
+{
+ NodeList::const_iterator n = nlist.begin();
+ while (n != nlist.end()) {
+ writer.writeCharacters(" ");
+ writer.writeCharacters(tag);
+ writer.writeCharacters(" ");
+ writer.writeCharacters((*n)->name());
+ ++n;
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h
new file mode 100644
index 0000000..446f735
--- /dev/null
+++ b/tools/qdoc3/ditaxmlgenerator.h
@@ -0,0 +1,338 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*
+ ditaxmlgenerator.h
+*/
+
+#ifndef DITAXMLGENERATOR_H
+#define DITAXMLGENERATOR_H
+
+#include <qmap.h>
+#include <qregexp.h>
+#include <QXmlStreamWriter>
+#include "codemarker.h"
+#include "config.h"
+#include "pagegenerator.h"
+
+QT_BEGIN_NAMESPACE
+
+typedef QMultiMap<QString, Node*> NodeMultiMap;
+typedef QMap<QString, NodeMultiMap> NewSinceMaps;
+typedef QMap<Node*, NodeMultiMap> ParentMaps;
+typedef QMap<QString, const Node*> NodeMap;
+typedef QMap<QString, NodeMap> NewClassMaps;
+
+class HelpProjectWriter;
+
+class DitaXmlGenerator : public PageGenerator
+{
+ public:
+ enum SinceType {
+ Namespace,
+ Class,
+ MemberFunction,
+ NamespaceFunction,
+ GlobalFunction,
+ Macro,
+ Enum,
+ Typedef,
+ Property,
+ Variable,
+ QmlClass,
+ QmlProperty,
+ QmlSignal,
+ QmlMethod,
+ LastSinceType
+ };
+
+ public:
+ DitaXmlGenerator();
+ ~DitaXmlGenerator();
+
+ virtual void initializeGenerator(const Config& config);
+ virtual void terminateGenerator();
+ virtual QString format();
+ virtual void generateTree(const Tree *tree, CodeMarker *marker);
+
+ QString protectEnc(const QString &string);
+ static QString protect(const QString &string, const QString &encoding = "ISO-8859-1");
+ static QString cleanRef(const QString& ref);
+ static QString sinceTitle(int i) { return sinceTitles[i]; }
+
+ protected:
+ virtual void startText(const Node *relative, CodeMarker *marker);
+ virtual int generateAtom(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker);
+ virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
+ virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
+ virtual QString fileExtension(const Node *node) const;
+ virtual QString refForNode(const Node *node);
+ virtual QString linkForNode(const Node *node, const Node *relative);
+ virtual QString refForAtom(Atom *atom, const Node *node);
+
+ QString fullQualification(const Node* n);
+
+ void writeDerivations(const ClassNode* cn, CodeMarker* marker);
+ void writeLocation(const Node* n);
+ void writeFunctions(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeParameters(const FunctionNode* fn, CodeMarker* marker);
+ void writeEnumerations(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeTypedefs(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeDataMembers(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeProperties(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeMacros(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writePropParams(const QString& tag, const NodeList& nlist);
+
+ private:
+ enum SubTitleSize { SmallSubTitle, LargeSubTitle };
+
+ const QPair<QString,QString> anchorForNode(const Node *node);
+ const Node *findNodeForTarget(const QString &target,
+ const Node *relative,
+ CodeMarker *marker,
+ const Atom *atom = 0);
+ void generateBreadCrumbs(const QString& title,
+ const Node *node,
+ CodeMarker *marker);
+ void generateHeader(const Node* node);
+ void generateTitle(const QString& title,
+ const Text &subTitle,
+ SubTitleSize subTitleSize,
+ const Node *relative,
+ CodeMarker *marker);
+ void generateBrief(const Node* node, CodeMarker* marker);
+ void generateIncludes(const InnerNode *inner, CodeMarker *marker);
+ void generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ Doc::SectioningUnit sectioningUnit,
+ int numColumns,
+ const Node *relative = 0);
+ void generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ QList<Section>* sections = 0);
+ QString generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker);
+ QString generateLowStatusMemberFile(const InnerNode *inner,
+ CodeMarker *marker,
+ CodeMarker::Status status);
+ void generateClassHierarchy(const Node *relative,
+ CodeMarker *marker,
+ const NodeMap &classMap);
+ void generateAnnotatedList(const Node *relative,
+ CodeMarker *marker,
+ const NodeMap &nodeMap);
+ void generateCompactList(const Node *relative,
+ CodeMarker *marker,
+ const NodeMap &classMap,
+ bool includeAlphabet,
+ QString commonPrefix = QString());
+ void generateFunctionIndex(const Node *relative, CodeMarker *marker);
+ void generateLegaleseList(const Node *relative, CodeMarker *marker);
+ void generateOverviewList(const Node *relative, CodeMarker *marker);
+ void generateSectionList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style);
+#ifdef QDOC_QML
+ void generateQmlSummary(const Section& section,
+ const Node *relative,
+ CodeMarker *marker);
+ void generateQmlItem(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ bool summary);
+ void generateDetailedQmlMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker);
+ void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker);
+ void generateQmlInheritedBy(const QmlClassNode* cn, CodeMarker* marker);
+ void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
+ void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
+#endif
+
+ void generateSection(const NodeList& nl,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style);
+ void generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style,
+ bool nameAlignment = false);
+ void generateSectionInheritedList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ bool nameAlignment = false);
+ QString highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ CodeMarker::SynopsisStyle style = CodeMarker::Accessors,
+ bool nameAlignment = false);
+
+ void generateFullName(const Node *apparentNode,
+ const Node *relative,
+ CodeMarker *marker,
+ const Node *actualNode = 0);
+ void generateDetailedMember(const Node *node,
+ const InnerNode *relative,
+ CodeMarker *marker);
+ void generateLink(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker);
+ void generateStatus(const Node *node, CodeMarker *marker);
+
+ QString registerRef(const QString& ref);
+ QString fileBase(const Node *node);
+#if 0
+ QString fileBase(const Node *node, const SectionIterator& section);
+#endif
+ QString fileName(const Node *node);
+ void findAllClasses(const InnerNode *node);
+ void findAllFunctions(const InnerNode *node);
+ void findAllLegaleseTexts(const InnerNode *node);
+ void findAllNamespaces(const InnerNode *node);
+ void findAllSince(const InnerNode *node);
+ static int hOffset(const Node *node);
+ static bool isThreeColumnEnumValueTable(const Atom *atom);
+ virtual QString getLink(const Atom *atom,
+ const Node *relative,
+ CodeMarker *marker,
+ const Node** node);
+ virtual void generateIndex(const QString &fileBase,
+ const QString &url,
+ const QString &title);
+#ifdef GENERATE_MAC_REFS
+ void generateMacRef(const Node *node, CodeMarker *marker);
+#endif
+ void beginLink(const QString &link,
+ const Node *node,
+ const Node *relative,
+ CodeMarker *marker);
+ void endLink();
+ bool generatePageElement(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const;
+ void generatePageElements(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const;
+ void generatePageIndex(const QString& fileName,
+ CodeMarker* marker) const;
+ QString writeGuidAttribute(QString text);
+ QString lookupGuid(QString text);
+
+ private:
+ QMap<QString, QString> refMap;
+ QMap<QString, QString> name2guidMap;
+ int codeIndent;
+ bool inLink;
+ bool inObsoleteLink;
+ bool inContents;
+ bool inSectionHeading;
+ bool inTableHeader;
+ int numTableRows;
+ bool threeColumnEnumValueTable;
+ bool offlineDocs;
+ QString link;
+ QStringList sectionNumber;
+ QRegExp funcLeftParen;
+ QString style;
+ QString postHeader;
+ QString postPostHeader;
+ QString footer;
+ QString address;
+ bool pleaseGenerateMacRef;
+ QString project;
+ QString projectDescription;
+ QString projectUrl;
+ QString navigationLinks;
+ QStringList stylesheets;
+ QStringList customHeadElements;
+ const Tree *myTree;
+ bool slow;
+ bool obsoleteLinks;
+ int noLinks;
+ QMap<QString, NodeMap > moduleClassMap;
+ QMap<QString, NodeMap > moduleNamespaceMap;
+ NodeMap nonCompatClasses;
+ NodeMap mainClasses;
+ NodeMap compatClasses;
+ NodeMap obsoleteClasses;
+ NodeMap namespaceIndex;
+ NodeMap serviceClasses;
+#ifdef QDOC_QML
+ NodeMap qmlClasses;
+#endif
+ QMap<QString, NodeMap > funcIndex;
+ QMap<Text, const Node *> legaleseTexts;
+ NewSinceMaps newSinceMaps;
+ static QString sinceTitles[];
+ NewClassMaps newClassMaps;
+ NewClassMaps newQmlClassMaps;
+ static int id;
+ QXmlStreamWriter writer;
+};
+
+#define DITAXMLGENERATOR_ADDRESS "address"
+#define DITAXMLGENERATOR_FOOTER "footer"
+#define DITAXMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
+#define DITAXMLGENERATOR_POSTHEADER "postheader"
+#define DITAXMLGENERATOR_POSTPOSTHEADER "postpostheader"
+#define DITAXMLGENERATOR_STYLE "style"
+#define DITAXMLGENERATOR_STYLESHEETS "stylesheets"
+#define DITAXMLGENERATOR_CUSTOMHEADELEMENTS "customheadelements"
+
+QT_END_NAMESPACE
+
+#endif
+
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index 17a6efd..280f055 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -2746,18 +2746,6 @@ Doc::SectioningUnit Doc::granularity() const
}
}
-#if notyet // ###
-Doc::SectioningUnit Doc::sectioningUnit() const
-{
- if (priv == 0 || priv->extra == 0) {
- return DocPrivateExtra().sectioningUnit;
- }
- else {
- return priv->extra->sectioningUnit;
- }
-}
-#endif
-
const QSet<QString> &Doc::parameterNames() const
{
return priv == 0 ? *null_Set_QString() : priv->params;
@@ -3036,7 +3024,7 @@ QString Doc::canonicalTitle(const QString &title)
QString result;
result.reserve(title.size());
- bool slurping = false;
+ bool dashAppended = false;
bool begun = false;
int lastAlnum = 0;
for (int i = 0; i != title.size(); ++i) {
@@ -3047,17 +3035,21 @@ QString Doc::canonicalTitle(const QString &title)
if (alnum) {
result += QLatin1Char(c);
begun = true;
- slurping = false;
+ dashAppended = false;
lastAlnum = result.size();
}
- else if (!slurping) {
+ else if (!dashAppended) {
if (begun)
result += QLatin1Char('-');
- slurping = true;
+ dashAppended = true;
}
+#if 0
+ // This was screwing things up.
else {
- // !alnum && slurping -> nothin
+ result += title[i];
+ lastAlnum = result.size();
}
+#endif
}
result.truncate(lastAlnum);
return result;
diff --git a/tools/qdoc3/doc.h b/tools/qdoc3/doc.h
index e98bb26..3e76456 100644
--- a/tools/qdoc3/doc.h
+++ b/tools/qdoc3/doc.h
@@ -48,6 +48,7 @@
#include <QSet>
#include <QString>
+#include <QMap>
#include "location.h"
diff --git a/tools/qdoc3/doc/classic.css b/tools/qdoc3/doc/classic.css
new file mode 100644
index 0000000..b8cae8e
--- /dev/null
+++ b/tools/qdoc3/doc/classic.css
@@ -0,0 +1,284 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Arial, Geneva, Helvetica, sans-serif;
+}
+H1 {
+ text-align: center;
+ font-size: 160%;
+}
+H2 {
+ font-size: 120%;
+}
+H3 {
+ font-size: 100%;
+}
+
+h3.fn,span.fn
+{
+ background-color: #eee;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+ font-weight: bold;
+ padding: 6px 0px 6px 10px;
+ margin: 42px 0px 0px 0px;
+}
+
+hr {
+ border: 0;
+ color: #a0a0a0;
+ background-color: #ccc;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 34px 0px 34px 0px;
+}
+
+table.valuelist {
+ border-width: 1px 1px 1px 1px;
+ border-style: solid;
+ border-color: #dddddd;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+}
+
+table.indextable {
+ border-width: 1px 1px 1px 1px;
+ border-style: solid;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+ font-size: 100%;
+}
+
+table td.largeindex {
+ border-width: 1px 1px 1px 1px;
+ border-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+ font-size: 120%;
+}
+
+table.valuelist th {
+ border-width: 1px 1px 1px 2px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #666;
+ color:white;
+ background-color:#666;
+}
+
+th.titleheader {
+ border-width: 1px 0px 1px 0px;
+ padding: 2px;
+ border-style: solid;
+ border-color: #666;
+ color:white;
+ background-color:#555;
+ background-image:url('images/gradient.png')};
+ background-repeat: repeat-x;
+ font-size: 100%;
+}
+
+
+th.largeheader {
+ border-width: 1px 0px 1px 0px;
+ padding: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#555555;
+ font-size: 120%;
+}
+
+p {
+
+ margin-left: 4px;
+ margin-top: 8px;
+ margin-bottom: 8px;
+}
+
+a:link
+{
+ color: #0046ad;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+a.obsolete
+{
+ color: #661100;
+ text-decoration: none
+}
+
+a.compat
+{
+ color: #661100;
+ text-decoration: none
+}
+
+a.obsolete:visited
+{
+ color: #995500;
+ text-decoration: none
+}
+
+a.compat:visited
+{
+ color: #995500;
+ text-decoration: none
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table.generic, table.annotated
+{
+ border-width: 1px;
+ border-color:#bbb;
+ border-style:solid;
+ border-collapse:collapse;
+}
+
+table td.memItemLeft {
+ width: 180px;
+ padding: 2px 0px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
+ white-space: nowrap
+}
+
+table td.memItemRight {
+ padding: 2px 8px 0px 8px;
+ margin: 4px;
+ border-width: 1px;
+ border-color: #E0E0E0;
+ border-style: none;
+ font-size: 100%;
+}
+
+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: 0px;
+ padding-bottom: 0px;
+ padding-left: 0px;
+ padding-right: 0px;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #96E066;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+table tr.qt-code 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;
+}
+
+.title
+{
+ text-align: center
+}
+
+.subtitle
+{
+ font-size: 0.8em
+}
+
+.small-subtitle
+{
+ font-size: 0.65em
+}
+
+.qmlitem {
+ padding: 0;
+}
+
+.qmlname {
+ white-space: nowrap;
+}
+
+.qmltype {
+ text-align: center;
+ font-size: 160%;
+}
+
+.qmlproto {
+ background-color: #eee;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #ddd;
+ font-weight: bold;
+ padding: 6px 10px 6px 10px;
+ margin: 42px 0px 0px 0px;
+}
+
+.qmlreadonly {
+ float: right;
+ color: red
+}
+
+.qmldoc {
+}
+
+*.qmlitem p {
+}
diff --git a/tools/qdoc3/doc/examples/layoutmanagement.qdocinc b/tools/qdoc3/doc/examples/layoutmanagement.qdocinc
new file mode 100644
index 0000000..01f8acf
--- /dev/null
+++ b/tools/qdoc3/doc/examples/layoutmanagement.qdocinc
@@ -0,0 +1,13 @@
+\section1 Layout Classes
+
+The Qt layout system provides a simple and powerful way of specifying
+the layout of child widgets.
+
+By specifying the logical layout once, you get the following benefits:
+
+\list
+ \o Positioning of child widgets.
+ \o Sensible default sizes for windows.
+ \o Sensible minimum sizes for windows.
+ \o ...
+\endlist
diff --git a/tools/qdoc3/doc/examples/main.cpp b/tools/qdoc3/doc/examples/main.cpp
new file mode 100644
index 0000000..e439d3e
--- /dev/null
+++ b/tools/qdoc3/doc/examples/main.cpp
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QPushButton>
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QPushButton hello("Hello world!");
+ hello.resize(100, 30);
+
+ hello.show();
+ return app.exec();
+}
diff --git a/tools/qdoc3/doc/examples/minimum.qdocconf b/tools/qdoc3/doc/examples/minimum.qdocconf
new file mode 100644
index 0000000..e5e9e67
--- /dev/null
+++ b/tools/qdoc3/doc/examples/minimum.qdocconf
@@ -0,0 +1,42 @@
+# QDoc is a tool that constantly evolves to suit our needs,
+# and there are some compatibility issues between old and new
+# practices. For that reason, any QDoc configuration file needs to
+# include compat.qdocconf.
+
+#include(compat.qdocconf)
+
+
+# The outputdir variable specifies the directory
+# where QDoc will put the generated documentation.
+
+outputdir = html
+
+
+# The headerdirs variable specifies the directories
+# containing the header files associated
+# with the .cpp source files used in the documentation.
+
+headerdirs = .
+
+
+# The sourcedirs variable specifies the
+# directories containing the .cpp or .qdoc
+# files used in the documentation.
+
+#sourcedirs = .
+
+
+# The exampledirs variable specifies the directories containing
+# the source code of the example files.
+
+exampledirs = .
+
+
+# The imagedirs variable specifies the
+# directories containing the images used in the documentation.
+
+imagedirs = ./images
+
+
+
+
diff --git a/tools/qdoc3/doc/examples/objectmodel.qdocinc b/tools/qdoc3/doc/examples/objectmodel.qdocinc
new file mode 100644
index 0000000..02b5991
--- /dev/null
+++ b/tools/qdoc3/doc/examples/objectmodel.qdocinc
@@ -0,0 +1,11 @@
+\section1 Qt Object Model
+
+The standard C++ object model provides very efficient runtime support
+for the object paradigm. But its static nature is inflexibile in
+certain problem domains. Graphical user interface programming is a
+domain that requires both runtime efficiency and a high level of
+flexibility. Qt provides this, by combining the speed of C++ with the
+flexibility of the Qt Object Model.
+
+...
+
diff --git a/tools/qdoc3/doc/examples/signalandslots.qdocinc b/tools/qdoc3/doc/examples/signalandslots.qdocinc
new file mode 100644
index 0000000..cfae43a
--- /dev/null
+++ b/tools/qdoc3/doc/examples/signalandslots.qdocinc
@@ -0,0 +1,9 @@
+\section1 Signals and Slots
+
+Signals and slots are used for communication between objects. The signals and
+slots mechanism is a central feature of Qt and probably the part that differs
+most from the features provided by other frameworks.
+
+\section2 Introduction
+
+In GUI programming, when we ...
diff --git a/tools/qdoc3/doc/files/compat.qdocconf b/tools/qdoc3/doc/files/compat.qdocconf
new file mode 100644
index 0000000..5745ed9
--- /dev/null
+++ b/tools/qdoc3/doc/files/compat.qdocconf
@@ -0,0 +1,31 @@
+alias.i = e
+alias.include = input
+
+macro.0 = "\\\\0"
+macro.b = "\\\\b"
+macro.n = "\\\\n"
+macro.r = "\\\\r"
+macro.i = "\\o"
+macro.i11 = "\\o{1,1}"
+macro.i12 = "\\o{1,2}"
+macro.i13 = "\\o{1,3}"
+macro.i14 = "\\o{1,4}"
+macro.i15 = "\\o{1,5}"
+macro.i16 = "\\o{1,6}"
+macro.i17 = "\\o{1,7}"
+macro.i18 = "\\o{1,8}"
+macro.i19 = "\\o{1,9}"
+macro.i21 = "\\o{2,1}"
+macro.i31 = "\\o{3,1}"
+macro.i41 = "\\o{4,1}"
+macro.i51 = "\\o{5,1}"
+macro.i61 = "\\o{6,1}"
+macro.i71 = "\\o{7,1}"
+macro.i81 = "\\o{8,1}"
+macro.i91 = "\\o{9,1}"
+macro.img = "\\image"
+macro.endquote = "\\endquotation"
+macro.relatesto = "\\relates"
+
+spurious = "Missing comma in .*" \
+ "Missing pattern .*"
diff --git a/tools/qdoc3/doc/files/qt.qdocconf b/tools/qdoc3/doc/files/qt.qdocconf
new file mode 100644
index 0000000..44cfbc1
--- /dev/null
+++ b/tools/qdoc3/doc/files/qt.qdocconf
@@ -0,0 +1,115 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qt
+versionsym =
+version = %VERSION%
+description = Qt Reference Documentation
+url = http://qt.nokia.com/doc/4.7
+
+edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
+ QtXmlPatterns QtTest
+edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
+ QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
+ QtDesigner QtAssistant QAxContainer Phonon \
+ QAxServer QtUiTools QtTest QtDBus
+edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest
+edition.DesktopLight.groups = -graphicsview-api
+
+qhp.projects = Qt
+
+qhp.Qt.file = qt.qhp
+qhp.Qt.namespace = com.trolltech.qt.472
+qhp.Qt.virtualFolder = qdoc
+qhp.Qt.indexTitle = Qt Reference Documentation
+qhp.Qt.indexRoot =
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = classic.css \
+ images/qt-logo.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ images/stylesheet-coffee-plastique.png
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+qhp.Qt.subprojects = classes overviews examples
+qhp.Qt.subprojects.classes.title = Classes
+qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
+qhp.Qt.subprojects.classes.selectors = class fake:headerfile
+qhp.Qt.subprojects.classes.sortPages = true
+qhp.Qt.subprojects.overviews.title = Overviews
+qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs
+qhp.Qt.subprojects.overviews.selectors = fake:page,group,module
+qhp.Qt.subprojects.examples.title = Tutorials and Examples
+qhp.Qt.subprojects.examples.indexTitle = Qt Examples
+qhp.Qt.subprojects.examples.selectors = fake:example
+
+language = Cpp
+
+headerdirs = $QTDIR/src \
+ $QTDIR/extensions/activeqt \
+ $QTDIR/tools/assistant/lib \
+ $QTDIR/tools/assistant/compat/lib \
+ $QTDIR/tools/designer/src/uitools \
+ $QTDIR/tools/designer/src/lib/extension \
+ $QTDIR/tools/designer/src/lib/sdk \
+ $QTDIR/tools/designer/src/lib/uilib \
+ $QTDIR/tools/qtestlib/src \
+ $QTDIR/tools/qdbus/src
+sourcedirs = $QTDIR/src \
+ $QTDIR/doc/src \
+ $QTDIR/extensions/activeqt \
+ $QTDIR/tools/assistant/lib \
+ $QTDIR/tools/assistant/compat/lib \
+ $QTDIR/tools/designer/src/uitools \
+ $QTDIR/tools/designer/src/lib/extension \
+ $QTDIR/tools/designer/src/lib/sdk \
+ $QTDIR/tools/designer/src/lib/uilib \
+ $QTDIR/tools/qtestlib/src \
+ $QTDIR/tools/qdbus
+
+excludedirs = $QTDIR/src/3rdparty/clucene \
+ $QTDIR/src/3rdparty/des \
+ $QTDIR/src/3rdparty/freetype \
+ $QTDIR/src/3rdparty/harfbuzz \
+ $QTDIR/src/3rdparty/kdebase \
+ $QTDIR/src/3rdparty/libjpeg \
+ $QTDIR/src/3rdparty/libmng \
+ $QTDIR/src/3rdparty/libpng \
+ $QTDIR/src/3rdparty/libtiff \
+ $QTDIR/src/3rdparty/md4 \
+ $QTDIR/src/3rdparty/md5 \
+ $QTDIR/src/3rdparty/patches \
+ $QTDIR/src/3rdparty/sha1 \
+ $QTDIR/src/3rdparty/sqlite \
+ $QTDIR/src/3rdparty/webkit/JavaScriptCore \
+ $QTDIR/src/3rdparty/webkit/WebCore \
+ $QTDIR/src/3rdparty/wintab \
+ $QTDIR/src/3rdparty/zlib \
+ $QTDIR/doc/src/snippets \
+ $QTDIR/src/3rdparty/phonon/gstreamer \
+ $QTDIR/src/3rdparty/phonon/ds9 \
+ $QTDIR/src/3rdparty/phonon/qt7 \
+ $QTDIR/src/3rdparty/phonon/waveout
+
+sources.fileextensions = "*.cpp *.qdoc *.mm"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+
+exampledirs = $QTDIR/doc/src \
+ $QTDIR/examples \
+ $QTDIR/examples/tutorials \
+ $QTDIR \
+ $QTDIR/qmake/examples \
+ $QTDIR/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QTDIR/doc/src/images \
+ $QTDIR/examples
+outputdir = $QTDIR/doc/html
+tagfile = $QTDIR/doc/html/qt.tags
+base = file:$QTDIR/doc/html
diff --git a/tools/qdoc3/doc/images/happy.gif b/tools/qdoc3/doc/images/happy.gif
new file mode 100644
index 0000000..a4597f6
--- /dev/null
+++ b/tools/qdoc3/doc/images/happy.gif
Binary files differ
diff --git a/tools/qdoc3/doc/images/happyguy.jpg b/tools/qdoc3/doc/images/happyguy.jpg
new file mode 100644
index 0000000..e860479
--- /dev/null
+++ b/tools/qdoc3/doc/images/happyguy.jpg
Binary files differ
diff --git a/tools/qdoc3/doc/images/qt-logo.png b/tools/qdoc3/doc/images/qt-logo.png
new file mode 100644
index 0000000..14ddf2a
--- /dev/null
+++ b/tools/qdoc3/doc/images/qt-logo.png
Binary files differ
diff --git a/tools/qdoc3/doc/images/training.jpg b/tools/qdoc3/doc/images/training.jpg
new file mode 100644
index 0000000..c2ce5c3
--- /dev/null
+++ b/tools/qdoc3/doc/images/training.jpg
Binary files differ
diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc
new file mode 100644
index 0000000..b557ad9
--- /dev/null
+++ b/tools/qdoc3/doc/qdoc-manual.qdoc
@@ -0,0 +1,8774 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Free Documentation License
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of this
+** file.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \page index.html
+ \nextpage QDoc Manual
+
+ \title QDoc Manual - Table of Contents
+
+ \list
+ \o \l{QDoc Manual}
+ \o \l{QDoc Commands}
+ \list
+ \o \l{Markup Commands}
+ \o \l{Text Formatting Commands}
+ \o \l{Document Structuring Commands}
+ \o \l{Verbatim Code Commands}
+ \o \l{Quoting External Code Commands}
+ \list
+ \o \l{Example File}
+ \endlist
+ \o \l{Linking Commands}
+ \o \l{Graphic Commands}
+ \o \l{Container Commands}
+ \o \l{Document Contents Commands}
+ \o \l{Miscellaneous Commands}
+ \list
+ \o \l{signalandslots.qdocinc}
+ \o \l{objectmodel.qdocinc}
+ \o \l{layoutmanagement.qdocinc}
+ \endlist
+ \o \l{Topical Commands}
+ \o \l{Contextual Commands}
+ \o \l{Navigation Commands}
+ \o \l{Status Commands}
+ \o \l{Thread Support Commands}
+ \o \l{Relating Commands}
+ \o \l{Grouping Commands}
+ \o \l{Title Commands}
+ \endlist
+ \o \l{QDoc Configuration}
+ \list
+ \o \l{General Configuration Variables}
+ \o \l{Creating Help Project Files}
+ \o \l{C++ Specific Configuration Variables}
+ \o \l{HTML Specific Configuration Variables}
+ \o \l{Supporting Derived Projects}
+ \o \l{QDoc Compatibility}
+ \o \l{qt.qdocconf}
+ \o \l{minimum.qdocconf}
+ \endlist
+ \o \l{QDoc Commands - Alphabetical List}
+ \endlist
+*/
+
+/*!
+ \page 01-qdoc-manual.html
+ \contentspage QDoc Manual - Table of Contents
+ \previouspage QDoc Manual - Table of Contents
+ \nextpage QDoc Commands
+
+ \title QDoc Manual
+
+ QDoc is the internal tool used by Qt Development Frameworks for generating
+ documentation. This document is a reference for QDoc command syntax and
+ configuration.
+
+ \section1 Overview
+
+ \list I
+ \o \section2 \l {QDoc Commands}
+
+ \l {QDoc Commands - Alphabetical List}{A complete alphabetical
+ list}.
+
+ There are two main categories of commands for QDoc: markup
+ commands and meta-commands.
+
+ The markup commands indicate the generated documentation's
+ appearance and logical structure. The meta-commands provide
+ information about the document as well as the documented
+ item. The meta-commands can be further categorized as topical
+ commands and contextual commands.
+
+ \list
+ \o \l {Markup Commands}
+ \list
+ \o \l {Text Formatting Commands}{Text Formatting}
+ \o \l {Document Structuring Commands}{Document Structuring}
+ \o \l {Verbatim Code Commands}{Verbatim Code}
+ \o \l {Quoting External Code Commands}{Quoting External Code}
+ \o \l {Linking Commands}{Linking}
+ \o \l {Graphic Commands}{Graphic}
+ \o \l {Container Commands}{Container}
+ \o \l {Document Contents Commands}{Document Contents}
+ \o \l {Miscellaneous Commands}{Miscellaneous}
+ \endlist
+ \o \l {Topical Commands}
+ \o \l {Contextual Commands}
+ \list
+ \o \l {Navigation Commands}{Navigation}
+ \o \l {Status Commands}{Status}
+ \o \l {Thread Support Commands}{Thread Support}
+ \o \l {Relating Commands}{Relating}
+ \o \l {Grouping Commands}{Grouping}
+ \o \l {Title Commands}{Title}
+ \endlist
+ \endlist
+ \endlist
+
+ \list II
+ \o \section2 \l {QDoc Configuration}
+
+ When running QDoc to generate the documentation, you must
+ specify a configuration file on the command line. The
+ configuration file is a list of entries of entries of the form
+ "variable = value".
+
+ \list
+ \o \l {Configuration Variables}
+ \o \l {Configuration File Examples}
+ \endlist
+
+ Some particular configuration variables allow you to use QDoc
+ to support Qt-based projects; i.e to make projects, such as Qt
+ Solutions, contain references to the online Qt documentation.
+
+ \list
+ \o \l {Supporting Derived Projects}
+ \endlist
+
+ QDoc is a tool that constantly evolves to suit our needs, for
+ that reason there are some compatibility issues between old and
+ new practices.
+
+ \list
+ \o \l {QDoc Compatibility}
+ \endlist
+ \endlist
+*/
+
+/*!
+ \page 02-qdoc-commands.html
+ \previouspage QDoc Manual
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Markup Commands
+
+ \title QDoc Commands
+
+ There are two main categories of commands for QDoc: markup
+ commands and meta-commands.
+
+ The markup commands indicate the generated documentation's visual
+ appearance and logical structure. The meta-commands provide
+ information about the documentation unit as well as the documented
+ item. The meta-commands can be further categorized as topical
+ commands and contextual commands.
+
+ \section1 Alphabetical List
+
+ A complete \l{QDoc Commands - Alphabetical List }
+ {alphabetical list of the QDoc commands}.
+
+ \section1 Categories
+
+ \list
+ \o \l {Markup Commands}
+ \o \l {Topical Commands}
+ \o \l {Contextual Commands}
+ \endlist
+*/
+
+/*!
+ \page 03-qdoc-commands-markup.html
+ \contentspage QDoc Manual - Table of Contents
+ \previouspage QDoc Commands
+ \nextpage Text Formatting Commands
+
+ \title Markup Commands
+
+ The markup commands indicate the generated documentation's visual
+ appearance and logical structure.
+
+ \section1 Alphabetical List
+
+ \l {04-qdoc-commands-textformatting.html#backslash}{\\\\},
+ \l {04-qdoc-commands-textformatting.html#a}{\\a},
+ \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract},
+ \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode},
+ \l {04-qdoc-commands-textformatting.html#bold}{\\bold},
+ \l {11-qdoc-commands-documentcontents.html#brief}{\\brief},
+ \l {04-qdoc-commands-textformatting.html#c}{\\c},
+ \l {09-qdoc-commands-graphic.html#caption}{\\caption},
+ \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter},
+ \l {06-qdoc-commands-verbatimcode.html#code}{\\code},
+ \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline},
+ \l {07-0-qdoc-commands-quoting.html#dots}{\\dots},
+ \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else},
+ \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif},
+ \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire},
+ \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote},
+ \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist},
+ \l {10-qdoc-commands-container.html#header}{\\header},
+ \l {04-qdoc-commands-textformatting.html#i}{\\i},
+ \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if},
+ \l {09-qdoc-commands-graphic.html#image}{\\image},
+ \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include},
+ \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage},
+ \l {08-qdoc-commands-linking.html#keyword}{\\keyword},
+ \l {08-qdoc-commands-linking.html#l}{\\l},
+ \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese},
+ \l {10-qdoc-commands-container.html#list}{\\list},
+ \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta},
+ \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode},
+ \l {10-qdoc-commands-container.html#o}{\\o},
+ \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode},
+ \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit},
+ \l {05-qdoc-commands-documentstructuring.html#part}{\\part},
+ \l {07-0-qdoc-commands-quoting.html#printline}{\\printline},
+ \l {07-0-qdoc-commands-quoting.html#printto}{\\printto},
+ \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil},
+ \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation},
+ \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile},
+ \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile},
+ \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw},
+ \l {10-qdoc-commands-container.html#row}{\\row},
+ \l {08-qdoc-commands-linking.html#sa}{\\sa},
+ \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1},
+ \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2},
+ \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3},
+ \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4},
+ \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline},
+ \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto},
+ \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil},
+ \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet},
+ \l {04-qdoc-commands-textformatting.html#sub}{\\sub},
+ \l {04-qdoc-commands-textformatting.html#sup}{\\sup},
+ \l {10-qdoc-commands-container.html#table}{\\table},
+ \l {11-qdoc-commands-documentcontents.html#tableofcontents}
+ {\\tableofcontents},
+ \l {08-qdoc-commands-linking.html#target}{\\target},
+ \l {04-qdoc-commands-textformatting.html#tt}{\\tt},
+ \l {04-qdoc-commands-textformatting.html#underline}{\\underline},
+ \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\unicode},
+ \l {11-qdoc-commands-documentcontents.html#warning}{\\warning}
+
+ \section1 Categories
+ \list
+ \o \l {Text Formatting Commands}
+ \o \l {Document Structuring Commands}
+ \o \l {Verbatim Code Commands}
+ \o \l {Quoting External Code Commands}
+ \o \l {Linking Commands}
+ \o \l {Graphic Commands}
+ \o \l {Container Commands}
+ \o \l {Document Contents Commands}
+ \o \l {Miscellaneous Commands}
+ \endlist
+
+*/
+
+/*!
+ \page 04-qdoc-commands-textformatting.html
+ \contentspage QDoc Manual - Table of Contents
+ \previouspage Markup Commands
+ \nextpage Document Structuring Commands
+
+ \title Text Formatting Commands
+
+ The text formatting commands indicate how the regular text in the
+ documentation is rendered.
+
+ \section1 Alphabetical List
+
+ \l {04-qdoc-commands-textformatting.html#backslash}{\\\\},
+ \l {04-qdoc-commands-textformatting.html#a}{\\a},
+ \l {04-qdoc-commands-textformatting.html#bold}{\\bold},
+ \l {04-qdoc-commands-textformatting.html#c}{\\c},
+ \l {04-qdoc-commands-textformatting.html#i}{\\i},
+ \l {04-qdoc-commands-textformatting.html#sub}{\\sub},
+ \l {04-qdoc-commands-textformatting.html#sup}{\\sup},
+ \l {04-qdoc-commands-textformatting.html#tt}{\\tt},
+ \l {04-qdoc-commands-textformatting.html#underline}{\\underline}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+
+ \o \bold \\\\ \target backslash
+ \o \bold {The \\\\ command expands to a single backslash.}
+
+ QDoc commands always start with a backslash alone. To
+ display an actual backslash in the text you need to type
+ two of the kind. If you want to display two backslashes,
+ you need to type four, and so forth. For example:
+
+ \code
+ / *!
+ The \\\\ command is useful if you want a
+ backslash to appear verbatim, for example,
+ writing C:\\windows\\home\\.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The \\\\ command is useful if you want a
+ backslash to appear verbatim, for example,
+ writing C:\\windows\\home\\.
+ \endquotation
+
+ However, if you want your text to appear in a typewriter
+ font as well, you can use the \l {c}{\\c} command instead,
+ which accepts and renders the backslash as any other
+ character. For example:
+
+ \code
+ / *!
+ The \\c command is useful if you want a
+ backslash to appear verbatim, and the word
+ that contains it written in a typewriter font,
+ like this: \c {C:\windows\home\}.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The \\c command is useful if you want a
+ backslash to appear verbatim, and the word
+ that contains it written in a typewriter font,
+ like this: \c {C:\windows\home\}.
+ \endquotation
+
+ \row
+ \o \bold \\a \target a
+ \o \bold {The \\a command indicates that the next word
+ is a parameter when documenting functions.}
+
+ Warnings are emitted when function parameters are
+ undocumented or misspelled, so whenever you write
+ documentation for functions you should make sure you
+ mention all the parameters and precede each of these by the
+ \\a command. The parameter is then rendered in italic. For
+ example:
+
+ \code
+ / *!
+ Constructs a line edit containing the text
+ \a contents.
+
+ The \a parent parameter is sent to the
+ QWidget constructor.
+ * /
+
+ QLineEdit::QLineEdit(const QString &contents, QWidget *parent)
+ :QWidget(parent)
+ {
+ ...
+ }
+
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \bold {QLineEdit::QLineEdit ( const QString &
+ contents, QWidget *parent )}
+
+ Constructs a line edit containing the text \a contents.
+
+ The \a parent parameter is sent to the QWidget
+ constructor.
+
+ \endquotation
+
+ The \\a command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation, parentheses
+ and use of braces} for the argument. However, a parameter
+ is always a single word, so braces are rarely
+ necessary. And for the same reason, parentheses seldom
+ occur.
+
+ \row
+ \o \bold \\c \target c
+ \o \bold {The \\c command can be used to render variables,
+ user-defined classes and C++ keywords like \c int,
+ \c for, etc.}
+
+ The command renders its argument using a typewriter font. For
+ example:
+
+ \code
+ / *!
+ The \c AnalogClock class provides a clock widget with hour
+ and minute hands that is automatically updated every
+ few seconds.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The \c AnalogClock class provides a clock widget with hour
+ and minute hands that is automatically updated every
+ few seconds.
+ \endquotation
+
+ The \\c command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation, parentheses
+ and use of braces} for the argument.
+
+ The \\c command accepts the special character \c \ within
+ its argument, i.e. it renders it as a normal character. So
+ if you want to use nested commands, you must use the \l
+ {tt}{teletype (\\tt)} command instead.
+
+ See also \l {tt}{\\tt} and \l {code}{\\code}.
+
+ \row
+ \o \bold \\tt \target tt
+ \o \bold {The \\tt command can be used to render variables,
+ user-defined classes and C++ keywords like \c int, \c
+ for, etc.}
+
+ The \\tt command behaves just like the \l {c}{\\c} command,
+ except that \\tt parses QDoc commands (like \l {i}{\\i}, \l
+ {bold}{\\bold} and \l {underline}{\\underline}) contained
+ within its argument.
+
+ The command renders its argument using a monospace
+ font. For example:
+
+ \code
+ / *!
+ After \c setupUi() populates the main container with
+ child widgets it scans the main container's list of
+ slots for names with the form
+ \tt{on_\i{objectName}_\i{signalName}().}
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ After \c setupUi() populates the main container with
+ child widgets it scans the main container's list of
+ slots for names with the form
+ \tt{on_\i{objectName}_\i{signalName}().}
+ \endquotation
+
+ The \\tt command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation, parentheses
+ and use of braces} for the argument.
+
+ See also \l {c}{\\c}.
+
+ \row
+ \o \bold \\bold \target bold
+ \o \bold {The \\bold command renders its argument using
+ a bold font.}
+
+ For example:
+
+ \code
+ / *!
+ This is regular text; \bold {this text is
+ rendered using the \\bold command}.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ This is regular text; \bold {this text is rendered using
+ the \\bold command}.
+ \endquotation
+
+ The command follows the same conventions as the \l {i}{\\i}
+ command for \l {argument}{punctuation, parentheses and use
+ of braces} for the argument.
+
+ \row
+ \o \bold \\i \target i
+ \o \bold {The \\i command renders its argument in italic.}
+
+ \warning This is preliminary functionality. For
+ more information, see the \l
+ {26-qdoc-commands-compatibility.html#i-versus-e}{compatibility}
+ section.
+
+ \target argument
+ Normally, a command argument ends at the next whitespace [1],
+ but braces can be used to group words [2]. For example:
+
+ \code
+ / *!
+ Here, we render \i {a few words} in italic.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Here, we render \i {a few words} in italic.
+ \endquotation
+
+ If you want to use other QDoc commands within an argument
+ that contains spaces, you always need to enclose the
+ argument with braces. But QDoc is smart enough to count
+ parentheses [3], so you don't need braces in cases like this:
+
+ \code
+ / *!
+ An argument can sometimes contain whitespaces,
+ for example: \i QPushButton(tr("A Brand New Button"))
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ An argument can sometimes contain whitespaces,
+ for example: \i QPushButton(tr("A Brand New Button"))
+ \endquotation
+
+ Finally, trailing punctuation is not included in an
+ argument [4], nor is 's [5]
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+ <tr valign="top" bgcolor="#a2c511">
+ <th></th>
+ <th>QDoc Syntax</th>
+ <th>Generated Documentation</th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>1</td>
+ <td>A variation of a command button is a \i menu
+ button.</td>
+ <td>A variation of a command button is a <i>menu</i>
+ button.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>2</td>
+ <td>The QPushButton widget provides a
+ \i {command button}.</td>
+ <td>The QPushButton widget provides a
+ <i>command button</i>.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>3</td>
+ <td>Another class of buttons are option buttons
+ \i (see QRadioButton).</td>
+ <td>Another class of buttons are option buttons
+ <i> (see QRadioButton)</i>.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>4</td>
+ <td>A push button emits the signal \i clicked().</td>
+ <td>A push button emits the signal <i>clicked</i>().</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>5</td>
+ <td>The \i QPushButton's checked property is
+ false by default.</td>
+ <td>The <i>QPushButton</i>'s checked property is
+ false by default.</td>
+ </tr>
+
+ </table>
+ \endraw
+
+ \row
+ \o \bold \\sub \target sub
+ \o \bold {The \\sub command renders its argument lower
+ than the baseline of the regular text, using a smaller font.}
+
+ For example:
+
+ \code
+ / *!
+ Definition (Range): Consider the sequence
+ {x\sub n}\sub {n > 1} . The set
+
+ {x\sub 2, x\sub 3, x\sub 4, ...} = {x\sub n ; n = 2, 3, 4, ...}
+
+ is called the range of the sequence.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Definition (Range): Consider the sequence
+ {x\sub n}\sub {n > 1} . The set
+
+ {x\sub 2, x\sub 3, x\sub 4, ...} = {x\sub n ; n = 2, 3, 4, ...}
+
+ is called the range of the sequence.
+ \endquotation
+
+ The \\sub command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation, parentheses
+ and use of braces} for the argument.
+
+ \row
+ \o \bold \\sup \target sup
+ \o \bold {The \\sup command renders its argument higher than
+ the baseline of the regular text, using a smaller font.}
+
+ For example:
+
+ \code
+ / *!
+ The series
+
+ 1 + a + a\sup 2 + a\sup 3 + a\sup 4 + ...
+
+ is called the \i {geometric series}.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The series
+
+ 1 + a + a\sup 2 + a\sup 3 + a\sup 4 + ...
+
+ is called the \i {geometric series}.
+ \endquotation
+
+ The \\sup command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation, parentheses
+ and use of braces} for the argument.
+
+ \row
+ \o \bold \\underline \target underline
+ \o \bold {The \\underline command renders its argument underlined.}
+
+ For example:
+
+ \code
+ / *!
+ The \underline {F}ile menu gives the users the possibility
+ to open, and edit, an existing file, save a new or modified
+ file, and exit the application.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The \underline {F}ile menu gives the users the possibility
+ to open, and edit, an existing file, save a new or modified
+ file, and exit the application.
+ \endquotation
+
+ The \\underline command follows the same conventions as the
+ \l {i}{\\i} command for \l {argument}{punctuation,
+ parentheses and use of braces} for the argument. \endtable
+*/
+
+/*!
+ \page 05-qdoc-commands-documentstructuring.html
+ \previouspage Text Formatting Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Verbatim Code Commands
+
+ \title Document Structuring Commands
+
+ The document structuring commands divide the documentation into
+ sections. In total, there are six levels of sections in QDoc: \c
+ \part, \c \chapter, \c \section1, \c \section2, \c \section3 and
+ \c \section4. \c \section1 to \c \section4 correspond to the
+ traditional section, subsection, subsubsection and
+ subsubsubsection.
+
+ \section1 Alphabetical List
+
+ \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter},
+ \l {05-qdoc-commands-documentstructuring.html#part}{\\part},
+ \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1},
+ \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2},
+ \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3},
+ \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\part \target part
+ \o \bold {The \\part command is intended for use in
+ larger documents, and divides the document into parts.}
+
+ In general a document structuring command considers
+ everything that follows it until the first line break as
+ its argument. The argument is rendered as the unit's
+ title. If the title needs to be spanned over several lines,
+ make sure that each line (except the last one) is ended
+ with a backslash.
+
+ In total, there are six levels of sections in QDoc: \c
+ \part, \c \chapter, \c \section1, \c \section2, \c
+ \section3 and \c \section4. \c \section1 to \c \section4
+ correspond to the traditional section, subsection,
+ subsubsection and subsubsubsection.
+
+ There is a strict ordering of the section units:
+
+ \code
+ part
+ |
+ chapter
+ |
+ section1
+ |
+ section2
+ |
+ section3
+ |
+ section4
+ \endcode
+
+ For example, a \c section1 unit can only appear as the top
+ level section or inside a \c chapter unit. Skipping a
+ section unit, for example from \c part to \c section1, is
+ not allowed.
+
+ You can \i begin with either of the three: \c part, \c
+ chapter or \c section1. For example:
+
+
+ \code
+ / *!
+ \part Basic Qt
+
+ This is the first part.
+
+
+ \chapter Getting Started
+
+ This is the first part's first chapter.
+
+
+ \section1 Hello Qt
+
+ This is the first chapter's first section.
+
+
+ \section1 Making Connections
+
+ This is the first chapter's second section.
+
+
+ \section1 Using the Reference Documentation
+
+ This is the first chapter's third section.
+
+
+ \chapter Creating Dialogs
+
+ This is the first part's second chapter.
+
+
+ \section1 Subclassing QDialog
+
+ This is the second chapter's first section.
+
+ ...
+
+
+ \part Intermediate Qt
+
+ This is the second part.
+
+
+ \chapter Layout Management
+
+ This is the second part's first chapter.
+
+
+ \section1 Basic Layouts
+
+ This is the first chapter's first section.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <a name="Basic Qt">
+ <h1>Basic Qt</h1>
+ </a>
+ <p>This is the first part.</p>
+
+ <a name="Getting started">
+ <h2>Getting Started</h2>
+ </a>
+ This is the first part's first chapter.</p>
+
+ <a name="Hello Qt">
+ <h3>Hello Qt</h3>
+ </a>
+ <p>This is the first chapter's first section.</p>
+
+ <a name="Making Connections">
+ <h3>Making Connections</h3>
+ </a>
+ <p>This is the first chapter's second section.</p>
+
+ <a name="Using the Reference Documentation">
+ <h3>Using the Reference Documentation</h3>
+ </a>
+ <p>This is the first chapter's third section.</p>
+
+ <a name="Creating Dialogs">
+ <h2>Creating Dialogs</h2>
+ </a>
+ <p>This is the first part's second chapter.</p>
+
+ <a name="Subclassing QDialog">
+ <h3>Subclassing QDialog</h3>
+ </a>
+ <p>This is the second chapter's first section.</p>
+
+ ...
+
+ <a name="Intermediate Qt">
+ <h1>Intermediate Qt</h1>
+ </a>
+ <p>This is the second part.</p>
+
+ <a name="Layout Management">
+ <h2>Layout Management</h2>
+ </a>
+ <p>This is the second part's first chapter.</p>
+
+ <a name="Basic Layouts">
+ <h3>Basic Layouts</h3>
+ </a>
+ <p>This is the first chapter's first section.</p>
+
+ ...
+
+ \endraw
+ \endquotation
+
+ Each section level is a logical unit within the
+ document. Its title will appear on the table of contents
+ generated by the \l
+ {11-qdoc-commands-documentcontents.html#tableofcontents}
+ {\\tableofcontents} command. For example:
+
+ \code
+ / *!
+ Contents:
+
+ \tableofcontents
+
+ ...
+ * /
+ \endcode
+
+ will expand to
+
+ \quotation
+ \raw HTML
+ <p>Contents:</p>
+
+ <ul>
+ <li><a href="#Basic Qt">Basic Qt</a></li>
+ <ul>
+ <li><a href="#Getting Started">Getting Started</a></li>
+ <ul>
+ <li><a href="#Hello Qt">Hello Qt</a></li>
+ <li><a href="#Making Connections">
+ Making Connections</a></li>
+ <li><a href="#Using the Reference Documentation">
+ Using the Reference Documentation</a></li>
+ </ul>
+ <li><a href="#Creating Dialogs">Creating Dialogs</a></li>
+ <ul>
+ <li><a href="#Subclassing QDialog">
+ Subclassing QDialog</a></li>
+ </ul>
+ </ul>
+ <li><a href="#Intermediate Qt">Intermediate Qt</a></li>
+ <ul>
+ <li><a href="#Layout Management">
+ Layout Management</a></li>
+ <ul>
+ <li><a href="#Basic Layouts">Basic Layouts</a></li>
+ </ul>
+ </ul>
+ </ul>
+
+ ...
+ \endraw
+ \endquotation
+
+ \row
+ \o \bold \\chapter \target chapter
+ \o \bold {The \\chapter command is intended for use in
+ larger documents, and divides the document into chapters.}
+
+ See \l{part}{\\part} for an explanation of the various
+ section units, command argument and rendering.
+
+ \row
+ \o \bold \\section1 \target sectionOne
+ \o \bold {The \\section1 command starts a new section.}
+
+ See \l{part}{\\part} for an explanation of the various
+ section units, command argument and rendering.
+ \row
+ \o \bold \\section2 \target sectionTwo
+ \o \bold {The \\section2 command starts a new section.}
+
+ See \l{part}{\\part} for an explanation of the various
+ section units, command argument and rendering.
+
+ \row
+ \o \bold \\section3 \target sectionThree
+ \o \bold {The \\section3 command starts a new section.}
+
+ See \l{part}{\\part} for an explanation of the various
+ section units, command argument and rendering.
+
+ \row
+ \o \bold \\section4 \target sectionFour
+ \o \bold {The \\section4 command starts a new section.}
+
+ See \l{part}{\\part} for an explanation of the various
+ section units, command argument and rendering.
+
+ \endtable
+*/
+
+/*!
+ \page 06-qdoc-commands-verbatimcode.html
+ \previouspage Document Structuring Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Quoting External Code Commands
+
+ \title Verbatim Code Commands
+
+ The following commands are used to render verbatim code within the
+ documentation. The code is rendered on a new line, using a
+ typewriter font and the standard indentation.
+
+ \bold{Note:} Although all of these commands can be used to present
+ C++ code, the \l{07-0-qdoc-commands-quoting.html#snippet}{\\snippet}
+ and \l{07-0-qdoc-commands-quoting.html#codeline}{\\codeline} commands
+ should be used in preference to
+ the others when presenting valid code. This allows auxilliary tools
+ for Qt language bindings to substitute the relevant code snippets in
+ place of the C++ ones.
+
+ \section1 Alphabetical List
+
+ \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode},
+ \l {06-qdoc-commands-verbatimcode.html#code}{\\code},
+ \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode},
+ \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\code \target code
+ \o \bold {The \\code command and the corresponding
+ \\endcode command delimit a piece of verbatim code.}
+
+ Whereas the \l {c}{\\c} command can be used for short code
+ fragments within a sentence, the \\code command is for
+ longer code snippets and renders the code verbatim in a
+ separate paragraph using a typewriter font and the standard
+ indentation.
+
+ When processing any of the \\code, \l {badcode}{\\badcode},
+ \l {newcode}{\\newcode} and \l {oldcode}{\\oldcode}
+ commands, QDoc basically removes all indentation that is
+ common for the verbatim code blocks within a \c{/}\c{*!} ...
+ \c{*}\c{/} comment before it adds the standard
+ indentation. For that reason the recommended style is to
+ use 8 spaces for the verbatim code contained within these
+ commands (note that this doesn't apply to externally
+ quoted code using the \l {quotefromfile}{\\quotefromfile}
+ or \l {quotefile}{\\quotefile} command).
+
+ For example:
+
+ \code
+ / *!
+ \code
+ #include <QApplication>
+ #include <QPushButton>
+
+ int main(int argc, char *argv[])
+ {
+ ...
+ }
+ \ endcode
+ * /
+ \endcode
+
+ will be rendered as
+
+ \code
+ #include <QApplication>
+ #include <QPushButton>
+
+ int main(int argc, char *argv[])
+ {
+ ...
+ }
+ \endcode
+
+ Other QDoc commands are disabled within
+ \\code... \\endcode, and the special character '\\' is
+ accepted and rendered like the rest of the code.
+
+ You need to type the code manually between the \\code and
+ \\endcode commands. If you want to include code snippets
+ from a particular file, use the \l
+ {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile}
+ command instead.
+
+ See also \l {c}{\\c}, \l
+ {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile},
+ \l {badcode}{\\badcode}, \l {newcode}{\\newcode} and \l
+ {oldcode}{\\oldcode}.
+
+ \row
+ \o \bold \\badcode \target badcode
+ \o \bold {The \\badcode command and the corresponding
+ \\endcode command delimit a piece of code that doesn't
+ compile or is wrong for some other reason.}
+
+ The \\badcode command is similar the \l {code}{\\code}
+ command, but renders the code using a grey font instead of
+ black (the default).
+
+ Like the \l {code}{\\code} command, it renders its code on
+ a new line in the documentation using a typewriter font and
+ the standard indentation. For example:
+
+ \code
+ / *!
+ The statement below is rendered using the
+ regular \\code command:
+
+ \code
+ statusbar()->message(tr("Host %1 found").arg(hostName));
+ \ endcode
+
+ While the following statement is rendered using
+ the \\badcode command:
+
+ \badcode
+ statusbar()->message(tr("Host" + hostName + " found"));
+ \ endcode
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The statement below is rendered using the
+ regular \\code command:
+
+ \code
+ statusbar()->message(tr("Host %1 found").arg(hostName));
+ \endcode
+
+ While the following statement is rendered using
+ the \\badcode command:
+
+ \badcode
+ statusbar()->message(tr("Host" + hostName + " found"));
+ \endcode
+ \endquotation
+
+ Other QDoc commands are disabled within
+ \\badcode... \\endcode, and the special character '\\' is
+ accepted and rendered like the rest of the code.
+
+ See also \l {code}{\\code}, \l {newcode}{\\newcode} and \l
+ {oldcode}{\\oldcode}.
+
+ \row
+ \o \bold \\newcode \target newcode
+ \o \bold {The \\newcode command, and the associated \\oldcode
+ and \\endcode commands, indicate how to port a piece of
+ code to a new version of an API.}
+
+ The \\newcode command, and its companion the \\oldcode
+ command, is a convenience combination of the \l
+ {code}{\\code} and \l {badcode}{\\badcode} commands: The
+ combination provides a text relating the two code snippets
+ to each other. The command requires a preceding \\oldcode
+ statement.
+
+ Like the \l {code}{\\code} and \l {badcode}{\\badcode}
+ commands, the \\newcode command renders its code on a new
+ line in the documentation using a typewriter font and the
+ standard indentation. For example:
+
+ \code
+ / *!
+ \oldcode
+ if (printer->setup(parent))
+ ...
+ \newcode
+ QPrintDialog dialog(printer, parent);
+ if (dialog.exec())
+ ...
+ \ endcode
+ * /
+ \endcode
+
+ is rendered like this:
+
+ \quotation
+ \oldcode
+ if (printer->setup(parent))
+ ...
+ \newcode
+ QPrintDialog dialog(printer, parent);
+ if (dialog.exec())
+ ...
+ \endcode
+ \endquotation
+
+ Other QDoc commands are disabled within
+ \\oldcode ... \\endcode, and the '\\' character doesn't need
+ to be escaped.
+
+ \row
+ \o \bold \\oldcode \target oldcode
+ \o \bold {The \\oldcode command requires a corresponding
+ \\newcode statement; otherwise QDoc fails to parse the command
+ and emits a warning.}
+
+ See also \l {newcode}{\\newcode} and \l {badcode}{\\badcode}.
+ \endtable
+*/
+
+/*!
+ \page 07-0-qdoc-commands-quoting.html
+ \previouspage Verbatim Code Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Linking Commands
+
+ \title Quoting External Code Commands
+
+ The following commands enable quoting from files in the
+ documentation: You can make QDoc include the complete contents of
+ a file, or you can quote specific parts of the file and skip
+ others. The typical use of the latter is to quote a file chunk by
+ chunk.
+
+ \bold{Note:} Although all of these commands can be used to present
+ C++ code, the \l{#snippet}{\\snippet} and \l{#codeline}{\\codeline}
+ commands should be used in preference to
+ the others when presenting valid code. This allows auxilliary tools
+ for Qt language bindings to substitute the relevant code snippets in
+ place of the C++ ones.
+
+ \section1 Alphabetical List
+
+ \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline},
+ \l {07-0-qdoc-commands-quoting.html#dots}{\\dots},
+ \l {07-0-qdoc-commands-quoting.html#printline}{\\printline},
+ \l {07-0-qdoc-commands-quoting.html#printto}{\\printto},
+ \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil},
+ \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile},
+ \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile},
+ \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline},
+ \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto},
+ \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil},
+ \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\quotefile \target quotefile
+ \o \bold {The \\quotefile command expands to the complete
+ contents of the file given as argument.}
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the file name with a line
+ break.
+
+ The file's contents is rendered in a separate paragraph,
+ using a typewriter font and the standard indentation. The
+ code is shown verbatim.
+
+ For example:
+
+ \code
+ / *!
+ This is a simple "Hello world" example:
+
+ \quotefile examples/main.cpp
+
+ It contains only the bare minimum you need
+ to get a Qt application up and running.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ This is a simple "Hello world" example:
+
+ \quotefile examples/main.cpp
+
+ It contains only the bare minimum you need to get a Qt
+ application up and running.
+ \endquotation
+
+ \warning If you use the \l {QDoc
+ Compatibility}{compat.qdocconf} file this command is called
+ \\include.
+
+ See also \l {quotefromfile}{\\quotefromfile} and \l
+ {code}{\\code}.
+
+ \row
+ \o \bold \\quotefromfile \target quotefromfile
+ \o \bold {The \\quotefromfile command opens the file
+ given as argument for quoting.}
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the file name with a line
+ break.
+
+ The command is intended for use when quoting parts from
+ file with the walkthrough commands: \l
+ {printline}{\\printline}, \l {printto}{\\printto}, \l
+ {printuntil}{\\printuntil}, \l {skipline}{\\skipline}, \l
+ {skipto}{\\skipto}, \l {skipuntil}{\\skipuntil}. This
+ enables you to quote specific portions of a file. For
+ example:
+
+ \code
+ / *!
+ The whole application is contained within
+ the \c main() function:
+
+ \quotefromfile examples/main.cpp
+
+ \skipto main
+ \printuntil app(argc, argv)
+
+ First we create a QApplication object using
+ the \c argc and \c argv parameters.
+
+ \skipto QPushButton
+ \printuntil resize
+
+ Then we create a QPushButton, and give it a reasonable
+ size using the QWidget::resize() function.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The whole application is contained within
+ the \c main() function:
+
+ \quotefromfile examples/main.cpp
+
+ \skipto main
+ \printuntil app(argc, argv)
+
+ First we create a QApplication object using the \c argc
+ and \c argv parameters.
+
+ \skipto QPushButton
+ \printuntil resize
+
+ Then we create a QPushButton, and give it a reasonable
+ size using the QWidget::resize() function.
+
+ ...
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ QDoc remembers which file it's quoting, and the current
+ position within that file (see \l {file}{\\printline} for
+ more information). There is no need to "close" the file.
+
+ Earlier we called this command \\quotefile. For more
+ information, see the \l
+ {26-qdoc-commands-compatibility.html#quotefromfile-versus-quotefile}
+ {compatibility} section.
+
+ See also \l {quotefile}{\\quotefile}, \l {code}{\\code} and
+ \l {dots}{\\dots}.
+
+ \row
+ \o \bold \\printline \target printline
+ \o \bold {The \\printline command expands to the line
+ from the current position to the next non-blank line of
+ the current souce file.}
+
+ To ensure that the documentation always is synchronized
+ with the source file, a substring of the line must be
+ specified as an argument to the command. Note that the
+ command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break.
+
+ The line from the source file is rendered as a separate
+ paragraph, using a typewriter font and the standard
+ indentation. The code is shown verbatim.
+
+ For example:
+
+ \code
+ / *!
+ There has to be exactly one QApplication object
+ in every GUI application that uses Qt.
+
+ \quotefromfile examples/main.cpp
+
+ \printline QApplication
+
+ This line includes the QApplication class
+ definition. QApplication manages various
+ application-wide resources, such as the
+ default font and cursor.
+
+ \printline QPushButton
+
+ This line includes the QPushButton class
+ definition. The QPushButton widget provides a command
+ button.
+
+ \printline main
+
+ The main function...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ There has to be exactly one QApplication object
+ in every GUI application that uses Qt.
+
+ \quotefromfile examples/main.cpp
+
+ \skipto QApplication
+ \printline QApplication
+
+ This line includes the QApplication class
+ definition. QApplication manages various
+ application-wide resources, such as the
+ default font and cursor.
+
+ \printline QPushButton
+
+ This line includes the QPushButton class
+ definition. The QPushButton widget provides a command
+ button.
+
+ \printline main
+
+ The main function...
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ \target file
+
+ QDoc reads the file sequentially. To move the current
+ position forward you can use either of the \l
+ {skipline}{\\skip...} commands. To move the current
+ position backward, you can use the \l
+ {quotefromfile}{\\quotefromfile} command again.
+
+ \target substring
+
+ If the substring argument is surrounded by slashes it is
+ interpreted as a \l {regular expression}.
+
+ For example:
+
+ \code
+ / *!
+ \quotefromfile widgets/scribble/mainwindow.cpp
+
+ \skipto closeEvent
+ \printuntil /^\}/
+
+ Close events are sent to widgets that the users want to
+ close, usually by clicking \c File|Exit or by clicking
+ the \c X title bar button. By reimplementing the event
+ handler, we can intercept attempts to close the
+ application.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \quotefromfile widgets/scribble/mainwindow.cpp
+
+ \skipto closeEvent
+ \printuntil /^\}/
+
+ Close events are sent to widgets that the users want to
+ close, usually by clicking \c File|Exit or by clicking
+ the \c X title bar button. By reimplementing the event
+ handler, we can intercept attempts to close the
+ application.
+ \endquotation
+
+ (\l {widgets/scribble}{The complete example file...})
+
+ The regular expression \c /^\}/ makes QDoc print until the
+ first '}' character occurring at the beginning of the line
+ without indentation. /.../ encloses the regular expression,
+ and '^' means the beginning of the line. The '}' character
+ must be escaped since it is a special character in regular
+ expressions.
+
+ QDoc will emit a warning if the specified substring or
+ regular expression cannot be located, i.e. if the source
+ code has changed.
+
+ See also \l {printto}{\\printto} and \l
+ {printuntil}{\\printuntil}.
+
+ \row
+ \o \bold \\printto \target printto
+ \o \bold {The \\printto command expands to all the lines
+ from the current position up to and \i excluding the
+ next line containing a given substring.}
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break. The command also follows the same conventions for \l
+ {file}{positioning} and \l {substring}{argument} as the \l
+ {printline}{\\printline} command.
+
+ The lines from the source file are rendered in a separate
+ paragraph, using a typewriter font and the standard
+ indentation. The code is shown verbatim.
+
+ For example:
+
+ \code
+ / *!
+ The whole application is contained within the
+ \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \printto hello
+
+ First we create a QApplication object using the \c argc and
+ \c argv parameters...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The whole application is contained within the
+ \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printto hello
+
+ First we create a QApplication object using the \c argc
+ and \c argv parameters...
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ See also \l {printline}{\\printline} and \l
+ {printuntil}{\\printuntil}.
+
+ \row
+ \o \bold \\printuntil \target printuntil
+ \o \bold {The \\printuntil command expands to all the lines
+ from the current position up to and \i including the next line
+ containing a given substring.}
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break. The command also follows the same conventions for \l
+ {file}{positioning} and \l {substring}{argument} as the \l
+ {printline}{\\printline} command.
+
+ The lines from the source file are rendered in a separate
+ paragraph, using a typewriter font and the standard
+ indentation. The code is shown verbatim.
+
+ For example:
+
+ \code
+ / *!
+ The whole application is contained within the
+ \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil hello
+
+ First we create a QApplication object using the
+ \c argc and \c argv parameters, then we create
+ a QPushButton.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The whole application is contained within the
+ \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil hello
+
+ First we create a \l
+ {http://qt.nokia.com/doc/4.0/qapplication}{QApplication}
+ object using the \c argc and \c argv parameters, then we
+ create a \l
+ {http://qt.nokia.com/doc/4.0/qpushbutton}{QPushButton}.
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ See also \l {printline}{\\printline} and \l
+ {printto}{\\printto}.
+
+ \row
+ \o \bold \\skipline \target skipline
+ \o \bold {The \\skipline command ignores the next non-blank
+ line in the current source file.}
+
+ Doc reads the file sequentially, and the \\skipline command
+ is used to move the current position (omitting a line of
+ the source file). See the remark about \l {file}{file
+ positioning} above.
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break. The command also follows the same conventions for \l
+ {substring}{argument} as the \l {printline}{\\printline}
+ command, and it is used in conjunction with the \l
+ {quotefromfile}{\\quotefromfile} command. For example:
+
+ \code
+ / *!
+ QPushButton is a GUI push button that the user
+ can press and release.
+
+ \quotefromfile examples/main.cpp
+ \skipline QApplication
+ \printline QPushButton
+
+ This line includes the QPushButton class
+ definition. For each class that is part of the
+ public Qt API, there exists a header file of
+ the same name that contains its definition.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \l
+ QPushButton is a GUI push button that the user
+ can press and release.
+
+ \quotefromfile examples/main.cpp
+ \skipto QApplication
+ \skipline QApplication
+ \printline QPushButton
+
+ This line includes the QPushButton class
+ definition. For each class that is part of the public
+ Qt API, there exists a header file of the same name
+ that contains its definition.
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ See also \l {skipto}{\\skipto}, \l
+ {skipuntil}{\\skipuntil} and \l {dots}{\\dots}.
+
+ \row
+ \o \bold \\skipto \target skipto
+ \o \bold {The \\skipto command ignores all the lines from the
+ current position up to and \i excluding the next line
+ containing a given substring.}
+
+ QDoc reads the file sequentially, and the \\skipto command
+ is used to move the current position (omitting one or
+ several lines of the source file). See the remark about \l
+ {file}{file positioning} above.
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break.
+
+ The command also follows the same conventions for \l
+ {substring}{argument} as the \l {printline}{\\printline}
+ command, and it is used in conjunction with the \l
+ {quotefromfile}{\\quotefromfile} command. For example:
+
+ \code
+ / *!
+ The whole application is contained within
+ the \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil }
+
+ First we create a QApplication object. There
+ has to be exactly one such object in
+ every GUI application that uses Qt. Then
+ we create a QPushButton, resize it to a reasonable
+ size...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The whole application is contained within
+ the \c main() function:
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil }
+
+ First we create a QApplication object. There has to be
+ exactly one such object in every GUI application that
+ uses Qt. Then we create a QPushButton, resize it to a
+ reasonable size ...
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ See also \l {skipline}{\\skipline}, \l
+ {skipuntil}{\\skipuntil} and \l {dots}{\\dots}.
+
+ \row
+ \o \bold \\skipuntil \target skipuntil
+ \o \bold {The \\skipuntil command ignores all the lines from
+ the current position up to and \i including the next line
+ containing a given substring.}
+
+ QDoc reads the file sequentially, and the \\skipuntil
+ command is used to move the current position (omitting one
+ or several lines of the source file). See the remark about
+ \l {file}{file positioning} above.
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the substring with a line
+ break.
+
+ The command also follows the same conventions for \l
+ {substring}{argument} as the \l {printline}{\\printline}
+ command, and it is used in conjunction with the \l
+ {quotefromfile}{\\quotefromfile} command. For example:
+
+ \code
+ / *!
+ The first thing we did in the \c main() function
+ was to create a QApplication object \c app.
+
+ \quotefromfile examples/main.cpp
+ \skipuntil show
+ \dots
+ \printuntil }
+
+ In the end we must remember to make \c main() pass the
+ control to Qt. QCoreApplication::exec() will return when
+ the application exits...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The first thing we did in the \c main() function was to
+ create a QApplication object \c app.
+
+ \quotefromfile examples/main.cpp
+ \skipuntil show
+ \dots
+ \printuntil }
+
+ In the end we must remember to make \c main() pass the
+ control to Qt. QCoreApplication::exec()
+ will return when the application exits...
+ \endquotation
+
+ (\l {Example File}{The complete example file...})
+
+ See also \l {skipline}{\\skipline}, \l {skipto}{\\skipto}
+ and \l {dots}{\\dots}.
+
+ \row
+ \o \bold \\dots \target dots
+ \o \bold {The \\dots command indicates that parts of the
+ source file have been omitted when quoting a file.}
+
+ The command is used in conjunction with the \l
+ {quotefromfile}{\\quotefromfile} command, and should be
+ stated on its own line. The dots are rendered on a new
+ line, using a typewriter font. For example:
+
+ \code
+ / *!
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil {
+ \dots
+ \skipuntil exec
+ \printline }
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotefromfile examples/main.cpp
+ \skipto main
+ \printuntil {
+ \dots
+ \skipuntil exec
+ \printline }
+
+ (\l {Example File}{The complete example file...})
+
+ The default indentation is 4 spaces, but this can be
+ adjusted using the command's optional argument. For
+ example:
+
+ \code
+ / *!
+ \dots 0
+ \dots
+ \dots 8
+ \dots 12
+ \dots 16
+ * /
+ \endcode
+
+ will be rendered as
+
+ \dots 0
+ \dots
+ \dots 8
+ \dots 12
+ \dots 16
+
+ See also \l {skipline}{\\skipline}, \l
+ {skipto}{\\skipto} and \l {skipuntil}{\\skipuntil}.
+
+ \row
+ \o \bold \\snippet \target snippet
+ \o \bold {The \\snippet command causes a code snippet to be included
+ verbatim as preformatted text, which may be syntax highlighted.}
+
+ Each code snippet are referenced by the file that holds it and by
+ a unique identifier for that file. Snippet files are typically
+ stored in a \c{snippets} directory inside the documentation
+ directory (e.g., \c{$QTDIR/doc/src/snippets}).
+
+ For example, the following documentation references a snippet in
+ a file residing in a subdirectory of the documentation directory:
+
+ \code
+ \snippet snippets/textdocument-resources/main.cpp Adding a resource
+ \endcode
+
+ The text following the file name is the unique identifier for the
+ snippet. This is used to delimit the quoted code in the relevant
+ snippet file as shown in the following example that corresponds to
+ the above \c{\\snippet} command:
+
+ \dots
+ \code
+ QImage image(64, 64, QImage::Format_RGB32);
+ image.fill(qRgb(255, 160, 128));
+
+ //! [Adding a resource]
+ document->addResource(QTextDocument::ImageResource,
+ QUrl("mydata://image.png"), QVariant(image));
+ //! [Adding a resource]
+ \endcode
+ \dots
+ \row
+ \o \bold \\codeline \target codeline
+ \o \bold{The \\codeline command inserts a blank line of preformatted
+ text. It is used to insert gaps between snippets without closing
+ the current preformatted text area and opening a new one.}
+ \endtable
+*/
+
+/*!
+ \page 07-1-example.html
+ \previouspage Quoting External Code Commands
+ \contentspage QDoc Manual - Table of Contents
+
+ \title Example File
+
+ \quotefile examples/main.cpp
+*/
+
+/*!
+ \page 08-qdoc-commands-linking.html
+ \previouspage Quoting External Code Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Graphic Commands
+
+ \title Linking Commands
+
+ The linking commands make it possible to create hyperlinks to
+ classes, functions, header files and examples. They also make it
+ possible to link to targets within a document, as well as to other
+ documents and URLs.
+
+ \section1 Alphabetical List
+
+ \l {08-qdoc-commands-linking.html#keyword}{\\keyword},
+ \l {08-qdoc-commands-linking.html#l}{\\l},
+ \l {08-qdoc-commands-linking.html#sa}{\\sa},
+ \l {08-qdoc-commands-linking.html#target}{\\target}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\l \target l
+ \o \bold {The \\l command is used to create hyperlinks. }
+
+ The command's general syntax is
+
+ \code
+ \l {link target}{link text}
+ \endcode
+
+ For example:
+
+ \code
+ / *!
+ Read the \l {http://qt.nokia.com/doc/4.0/}
+ {Qt's Reference Documentation} carefully.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Read the \l {http://qt.nokia.com/doc/4.0/}
+ {Qt's Reference Documentation} carefully.
+ \endquotation
+
+ If the link target is equivalent to the link text, the
+ second argument can be omitted.
+
+ For example, if you have documentation like:
+
+ \code
+ / *!
+ \target assertions
+
+ Assertions make some statement about the text at the
+ point where they occur in the regexp but they do not
+ match any characters.
+
+ ...
+
+ Regexps are built up from expressions, quantifiers, and
+ \l {assertions}{assertions}.
+ * /
+ \endcode
+
+ you can rewrite it as
+
+ \code
+ / *!
+ \target assertions
+
+ Assertions make some statement about the text at the
+ point where they occur in the regexp but they do not
+ match any characters.
+
+ ...
+
+ Regexps are built up from expressions, quantifiers, and
+ \l assertions.
+ * /
+ \endcode
+
+ For the one-parameter version the braces can often
+ be omitted. See the \l {i}{\\i} command for the \l
+ {argument}{argument conventions}.
+
+ The \\l command supports several kinds of links:
+
+ \list
+ \o \c {\l QWidget} - a defined \l {class}{\\class}
+ \o \c {\l QWidget::sizeHint()} - a defined member
+ function (\l {fn}{\\fn})
+ \o \c {\l <QtGlobal>} - a defined \l {headerfile}{\\headerfile}
+ \o \c {\l widgets/wiggly} - a defined
+ \l {example-command}{\\example}
+ \o \c {\l {QWidget Class Reference}} - a defined \l {title}{\\title}
+ \o \c {\l {Introduction}}- a defined \l{part}{\\part},
+ \l{chapter}{\\chapter} or \l {sectionOne}{\\section...}
+ \o \c {\l fontmatching} - a defined \l {target}{\\target}
+ \o \c {\l {Shared Classes}} - a defined \l {keyword}{\\keyword}
+ \o \c {\l network.html} - a defined \l {page}{\\page}
+ \o \c {\l http://www.trolltech.com/} - a URL
+ \endlist
+
+ QDoc also tries to make a link out of any words that don't
+ resemble any normal English words, for example Qt class
+ names or functions, like QWidget or QWidget::sizeHint(). In
+ these cases, the \\l command can actually be omitted, but
+ by using the command, you ensure that QDoc will emit a
+ warning if it cannot find the link target. In addition, if
+ you only want the function name to appear in the link, you
+ can use the following syntax:
+
+ \list
+ \o \c {\l {QWidget::}{sizeHint()}}
+ \endlist
+
+ See also \l {sa}{\\sa}, \l {target}{\\target} and \l
+ {keyword}{\\keyword}.
+
+ \row
+ \o \bold \\sa \target sa
+ \o \bold {The \\sa command defines a list of links that will
+ be rendered in a separate "See also" section at the bottom
+ of the documentation.}
+
+ The command takes a comma-separated list of links as its
+ argument. If the line ends with a comma, you can continue
+ on a second line. The general syntax is:
+
+ \code
+ \sa {the first link}, {the second link},
+ {the third link}, ...
+ \endcode
+
+ QDoc will automatically try to generate "See also" links
+ interconnecting a property's various functions. For
+ example, an setVisible() function will automatically get a
+ link to visible() and vice versa.
+
+ In general, QDoc will generate "See also" links that
+ interconnect the functions that access the same
+ property. It recognizes four different syntax versions:
+
+ \list
+ \o \c property()
+ \o \c setProperty()
+ \o \c isProperty()
+ \o \c hasProperty()
+ \endlist
+
+ The \\sa command supports the same kind
+ of links as the \l {l}{\\l} command. For example:
+
+ \code
+ / *!
+ Appends the actions \a actions to this widget's
+ list of actions.
+
+ \sa removeAction(), QMenu, addAction()
+ * /
+ void QWidget::addActions(QList<QAction *> actions)
+ {
+ ...
+ }
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \bold {void QWidget::addActions ( QList<QAction*>
+ \i actions )}
+
+ Appends the actions \i actions to this widget's
+ list of actions.
+
+ See also \l {QWidget::removeAction()}{removeAction()},
+ \l QMenu, and \l {QWidget::addAction()}{addAction()}.
+ \endquotation
+
+ See also \l {l}{\\l}, \l {target}{\\target} and \l
+ {keyword}{\\keyword}.
+
+ \row
+ \o \bold \\target \target target
+ \o \bold {The \\target command defines an explicit point in the
+ documentation that you can later link to using the \l {l}{\\l}
+ and \l {sa}{\\sa} commands.}
+
+ The command considers the rest of the line as part of its
+ argument, make sure to follow the target name with a line
+ break.
+
+ For example:
+
+ \code
+ / *!
+ \target capturing parentheses
+ \section1 Capturing Text
+
+ Parentheses allow us to group elements together so that
+ we can quantify and capture them.
+
+ ...
+ * /
+ \endcode
+
+ can be referenced with
+
+ \list
+ \o \c {\l {capturing parentheses}}
+ (from elsewhere in the same comment)
+ \o \c {\l qregexp.html#capturing-parentheses}
+ (from anywhere else)
+ \endlist
+
+ within a documentation unit, and with
+
+ \list
+ \o \c {\l http://www.trolltech.com/4.0/doc/html/qregexp.html#capturing-parentheses}
+ \endlist
+
+ on a more global scale.
+
+ If the target name does't contain any spaces, the brackets can
+ be omitted as well.
+
+ See also \l {l}{\\l}, \l {sa}{\\sa} and \l
+ {keyword}{\\keyword}.
+
+ \row
+ \o \bold \\keyword \target keyword
+ \o \bold {The \\keyword command defines an explicit point in the
+ documentation that you can later link to using the \l {l}{\\l}
+ and \l {sa}{\\sa} commands.}
+
+ Keywords must be unique within the entire set of
+ documentation processed in on QDoc run. The command
+ considers the rest of the line as part of its argument,
+ make sure to follow the keyword with a line break.
+
+ The \\keyword command is similar to \l {target}{\\target},
+ but stronger. A keyword can be referenced from anywhere
+ using a simple syntax. For example:
+
+ \code
+ / *!
+ \class QRegExp
+ \reentrant
+ \brief The QRegExp class provides pattern
+ matching using regular expressions.
+ \ingroup tools
+ \ingroup misc
+ \ingroup shared
+ \mainclass
+
+ \keyword regular expression
+
+ Regular expressions, or "regexps", provide a way to
+ find patterns within text.
+
+ ...
+ * /
+ \endcode
+
+ can be referenced like this
+
+ \code
+ / *!
+ When a string is surrounded by slashes, it's
+ interpreted as a \l regular expression.
+ * /
+ \endcode
+
+ which will be rendered as
+
+ \quotation
+ When a string is surrounded by slashes, it's
+ interpreted as a \l {regular expression}.
+ \endquotation
+
+ If the keyword does't contain any spaces, the brackets can
+ be omitted as well.
+
+ See also \l {l}{\\l}, \l {sa}{\\sa} and \l
+ {target}{\\target}.
+ \endtable
+*/
+
+/*!
+ \page 09-qdoc-commands-graphic.html
+ \previouspage Linking Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Container Commands
+
+ \title Graphic Commands
+
+ The graphic commands makes it possible to include images in the
+ documentation. The images can be rendered as separate paragraphs,
+ or within running text.
+
+ \section1 Alphabetical List
+
+ \l {09-qdoc-commands-graphic.html#caption}{\\caption},
+ \l {09-qdoc-commands-graphic.html#image}{\\image},
+ \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\image \target image
+ \o \bold {The \\image command expands to the image specified by its
+ argument, and renders it centered as a separate paragraph.}
+
+ The \\image command replaces the old \\img command. For more
+ information, see the \l
+ {26-qdoc-commands-compatibility.html#image-versus-img}
+ {compatibility} section.
+
+ The command takes two arguments. The first is the name of
+ the image file. The second argument is optional and is a
+ simple description of the image equivalent to the HTML
+ alt="" in an image tag. The description is used for
+ tooltips, and when a browser doesn't support images like
+ the Lynx text browser.
+
+ The command considers the rest of the line after the file
+ name its second argument, make sure that you follow the
+ filename or description with a line break. Braces are only
+ necessary if the description spans several lines.
+
+ For example:
+
+ \code
+ / *!
+ Qt by Trolltech is a C++ toolkit for cross-platform GUI
+ application development.
+
+ \image happyguy.jpg "Happy guy"
+
+ Qt provides single-source portability across Microsoft
+ Windows, Mac OS X, Linux, and all major commercial Unix
+ variants. It is also available for embedded devices.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Qt by Trolltech is a C++ toolkit for cross-platform GUI
+ application development.
+
+ \image happyguy.jpg image "Happy guy"
+
+ Qt provides single-source portability across Microsoft
+ Windows, Mac OS X, Linux, and all major commercial Unix
+ variants. It is also available for embedded devices.
+ \endquotation
+
+ See also \l {inlineimage}{\\inlineimage} and \l
+ {caption}{\\caption}.
+
+ \row
+ \o \bold \\inlineimage \target inlineimage
+ \o \bold {The \\inlineimage command expands to the image
+ specified by its argument; the image is rendered inline
+ with the rest of the text.}
+
+ The command takes two arguments. The first is the name of
+ the image file. The second argument is optional and is a
+ simple description of the image equivalent to the HTML
+ alt="" in an image tag. The description is used for
+ tooltips, and when a browser doesn't support images like
+ the Lynx text browser.
+
+ The most common use of the \\inlineimage command is in
+ lists and tables. For example:
+
+ \code
+ / *!
+ \list 1
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \endlist
+ * /
+ \endcode
+
+ will be rendered as
+
+ \list 1
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \endlist
+
+ And
+
+ \code
+ / *!
+ \table
+ \header
+ \o Trolltech
+ \o Trolltech
+ \row
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \row
+ \o \inlineimage happy.gif Oh so happy!
+ \o \inlineimage happy.gif Oh so happy!
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+ <tr valign="top" bgcolor="#a2c511">
+ <th>Trolltech</th>
+ <th>Trolltech</th>
+ </tr>
+
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><img src="images/happy.gif" alt="Oh so happy!" />
+ </td>
+ <td><img src="images/happy.gif" alt="Oh so happy!" />
+ </td>
+ </tr>
+
+ <tr valign="top" bgcolor="#f0f0f0">
+ <td><img src="images/happy.gif" alt="Oh so happy!"/>
+ </td>
+ <td><img src="images/happy.gif" alt="Oh so happy!" />
+ </td>
+ </tr>
+
+ </table>
+ \endraw
+
+ The command can also be used to insert an image
+ inline with the regular text. For example:
+
+ \code
+ / *!
+ \inlineimage training.jpg Training by Trolltech
+ The Qt Programming course is offered as a
+ five day Open Enrollment Course. The classes
+ are open to the public.While the course is open
+ to anyone who wants to learn, attendees should
+ have significant experience in C++ development
+ to derive maximum benefit from the course.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \inlineimage training.jpg Training by Trolltech
+ The Qt Programming course is offered as a
+ five day Open Enrollment Course. The classes
+ are open to the public.While the course is open
+ to anyone who wants to learn, attendees should
+ have significant experience in C++ development
+ to derive maximum benefit from the course.
+ \endquotation
+
+ See also \l {image}{\\image} and \l {caption}{\\caption}.
+
+ \row
+ \o \bold \\caption \target caption
+ \o \bold {The \\caption command provides a caption for an image.}
+
+ The command follows the same conventions for parentheses and use
+ of braces for its \l argument as the \l {i}{\\i} command.
+
+ \warning This is preliminary functionality. The
+ command is not fully implemented.
+
+ See also \l {image}{\\image} and \l
+ {inlineimage}{\\inlineimage}
+
+ \endtable
+*/
+
+/*!
+ \page 10-qdoc-commands-container.html
+ \previouspage Graphic Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Document Contents Commands
+
+ \title Container Commands
+
+ The container commands create tables and lists with associated
+ items and contents. A list is rendered left aligned as a separate
+ paragraph. A table is rendered centered as a separate paragraph,
+ and its width depends on its content.
+
+ \section1 Alphabetical List
+
+ \l {10-qdoc-commands-container.html#header}{\\header},
+ \l {10-qdoc-commands-container.html#list}{\\list},
+ \l {10-qdoc-commands-container.html#o}{\\o},
+ \l {10-qdoc-commands-container.html#omitvalue}{\\omitvalue},
+ \l {10-qdoc-commands-container.html#row}{\\row},
+ \l {10-qdoc-commands-container.html#table}{\\table},
+ \l {10-qdoc-commands-container.html#value}{\\value}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\table \target table
+ \o \bold {The \\table command and the corresponding \\endtable
+ command delimit the contents of a table.}
+
+ The command accepts a single argument specifying the
+ table's width in percentage:
+
+ \code
+ / *!
+ \table 100 %
+
+ ...
+
+ \endtable
+ * /
+ \endcode
+
+ The code above ensures that the table will fill all
+ available space. If the table's width is smaller than 100 %,
+ the table will be centered in the generated documentation.
+
+ A table can contain headers, rows and columns. A row starts
+ with a \l {row}{\\row} command and consists of cells, which
+ starts with a \l {o}{\\o} command. There is also a \l
+ {header}{\\header} command which is a special kind of row
+ with a special formatting. For example:
+
+ \code
+ / *!
+ \table
+ \header
+ \o Qt Core Feature
+ \o Brief Description
+ \row
+ \o \l {Signal and Slots}
+ \o Signals and slots are used for communication
+ between objects.
+ \row
+ \o \l {Layout Management}
+ \o The Qt layout system provides a simple
+ and powerful way of specifying the layout
+ of child widgets.
+ \row
+ \o \l {Drag and Drop}
+ \o Drag and drop provides a simple visual
+ mechanism which users can use to transfer
+ information between and within applications.
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+ <tr valign="top" bgcolor="#a2c511">
+ <th>Qt Core Feature</th>
+ <th>Brief Description</th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html">
+ Signals and Slots</a>
+ </td>
+ <td>Signals and slots are used for communication
+ between objects.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>
+ <a href=http://qt.nokia.com/doc/4.0/layout.html">
+ Layout Management</a></td>
+ <td>The Qt layout system provides a simple
+ and powerful way of specifying the layout
+ of child widgets.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href=http://qt.nokia.com/doc/4.0/dnd.html">
+ Drag and Drop</a></td>
+ <td>Drag and drop provides a simple visual
+ mechanism which users can use to transfer
+ information between and within applications.</td>
+ </tr>
+
+ </table>
+ \endraw
+
+ You can also make cells span several rows and columns. For
+ example:
+
+ \code
+ / *!
+ \table
+ \header
+ \o {3,1} This header cell spans three columns
+ but only one row.
+ \row
+ \o {2, 1} This table cell spans two columns
+ but only one row
+ \o {1, 2} This table cell spans only one column,
+ but two rows.
+ \row
+ \o A regular table cell
+ \o A regular table cell
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2" cellspacing="1"
+ border="0">
+
+ <tr valign="top" bgcolor="#a2c511">
+ <th colspan="3" rowspan=" 1">
+ This header cell spans three columns but only one row
+ </th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td colspan="2" rowspan=" 1">
+ This table cell spans two columns but only one row
+ </td>
+ <td rowspan=" 2">
+ This table cell spans only one column, but two rows.
+ </td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>A regular table cell</td>
+ <td>A regular table cell</td>
+ </tr>
+
+ </table>
+ \endraw
+
+ See also \l {header}{\\header}, \l {row}{\\row} and \l {o}{\\o}.
+
+ \row
+ \o \bold \\header \target header
+ \o \bold {The \\header command indicates that the following
+ table cells are the current table's column headers.}
+
+ The command can only be used within the \l{table}
+ {\\table...\\endtable} commands. A header can contain
+ several cells. A cell is created with the \l {o}{\\o}
+ command.
+
+ A header cell's text is centered within the table cell and
+ rendered using a bold font. For example:
+
+ \code
+ / *!
+ \table
+ \header
+ \o Qt Core Feature
+ \o Brief Description
+ \row
+ \o \l {Signal and Slots}
+ \o Signals and slots are used for communication
+ between objects.
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+ <tr valign="top" bgcolor="#a2c511">
+ <th>Qt Core Feature</th>
+ <th>Brief Description</th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html">
+ Signals and Slots</a>
+ </td>
+ <td>Signals and slots are used for communication
+ between objects.</td>
+ </tr>
+ </table>
+ \endraw
+
+ See also \l {table}{\\table}, \l {row}{\\row} and \l {o}{\\o}.
+
+ \row
+ \o \bold \\row \target row
+ \o \bold {The \\row command indicates that the following table
+ cells belong to the same row in the current table.}
+
+ The command can only be used within the \l{table}
+ {\\table...\\endtable} commands. A row can contain
+ several cells. A cell is created with the \l {o}{\\o}
+ command.
+
+ The background cell color of each row alternate between two
+ shades of grey, making it easier to distinguish the rows
+ from each other. The cells' contents is left aligned.
+
+ For example:
+
+ \code
+ / *!
+ \table
+ \header
+ \o Qt Core Feature
+ \o Brief Description
+ \row
+ \o \l {Signal and Slots}
+ \o Signals and slots are used for communication
+ between objects.
+ \row
+ \o \l {Layout Management}
+ \o The Qt layout system provides a simple
+ and powerful way of specifying the layout
+ of child widgets.
+ \row
+ \o \l {Drag and Drop}
+ \o Drag and drop provides a simple visual
+ mechanism which users can use to transfer
+ information between and within applications.
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+ <tr valign="top" bgcolor="#a2c511">
+ <th>Qt Core Feature</th>
+ <th>Brief Description</th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/signalsandslots.html">
+ Signals and Slots</a>
+ </td>
+ <td>Signals and slots are used for communication
+ between objects.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>
+ <a href=http://qt.nokia.com/doc/4.0/layout.html">
+ Layout Management</a></td>
+ <td>The Qt layout system provides a simple
+ and powerful way of specifying the layout
+ of child widgets.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href=http://qt.nokia.com/doc/4.0/dnd.html">
+ Drag and Drop</a></td>
+ <td>Drag and drop provides a simple visual
+ mechanism which users can use to transfer
+ information between and within applications.</td>
+ </tr>
+
+ </table>
+ \endraw
+
+ See also \l {table}{\\table}, \l {header}{\\header} and \l
+ {o}{\\o}.
+
+ \row
+ \o \bold \\value \target value
+ \o \bold {The \\value command starts the documentation of a C++ enum
+ item}.
+
+ The command's first argument is the enum item. Then follows
+ its associated description. The description argument ends
+ at the next blank line or \\value. The arguments are
+ rendered within a table.
+
+ The documentation will be located in the associated class,
+ header file or namespace documentation. See the \l
+ {enum}{\\enum} documentation for an example.
+
+ See also \l {enum}{\\enum} and \l {omitvalue}{\\omitvalue}.
+
+ \row
+ \o \bold \\omitvalue \target omitvalue
+ \o \bold {The \\omitvalue command excludes a C++ enum item
+ from the documentation}.
+
+ The command's only argument is the name of the enum item
+ that will be omitted. See the \l {enum}{\\enum}
+ documentation for an example.
+
+ See also \l {enum}{\\enum} and \l {value}{\\value}.
+
+ \row
+ \o \bold \\list \target list
+ \o \bold {The \\list command and the corresponding \\endlist
+ command delimit a list of items.}
+
+ You need to create each list item explicitly using the \l
+ {o}{\\o} command. A list can contain one or more items; it
+ can also be nested. For example:
+
+ \code
+ / *!
+ \list
+ \o Qt Reference Documentation: Getting Started
+ \list
+ \o How to Learn Qt
+ \o Installation
+ \list
+ \o Qt/X11
+ \o Qt/Windows
+ \o Qt/Mac
+ \o Qt/Embedded
+ \endlist
+ \o Tutorial and Examples
+ \endlist
+ \endlist
+ * /
+ \endcode
+
+ will be rendered as
+
+ \list
+ \o Qt Reference Documentation: Getting Started
+ \list
+ \o How to Learn Qt
+ \o Installation
+ \list
+ \o Qt/X11
+ \o Qt/Windows
+ \o Qt/Mac
+ \o Qt/Embedded
+ \endlist
+ \o Tutorial and Examples
+ \endlist
+ \endlist
+
+ The \\list command takes an optional argument providing
+ alternative appearances for the list items. For example:
+
+ \code
+ / *!
+ \list
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+ * /
+ \endcode
+
+ will render the list items with bullets (the default):
+
+ \list
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+
+ If you provide 'A' as an argument to the \\list command,
+ the bullets are replaced with characters following in
+ alphabetical order:
+
+ \list A
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+
+ If you replace 'A' with '1', the list items are rendered
+ with numbers following in ascending order:
+
+ \list 1
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+
+ \endlist
+
+ If you provide 'i' as the argument, the default bullets are
+ replaced with roman numerals:
+
+ \list i
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+
+ Or finally, you can make the list items appear with roman
+ numbers following in ascending order if you provide 'I' as
+ the optional argument:
+
+ \list I
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+
+ You can also make the listing start at any character or
+ number by simply provide the number or character you want
+ to start at. For example:
+
+ \code
+ / *!
+ \list G
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+ * /
+ \endcode
+
+ will be rendered as
+
+ \list G
+ \o How to Learn Qt
+ \o Installation
+ \o Tutorial and Examples
+ \endlist
+
+ See also \l {o}{\\o}.
+
+ \row
+ \o \bold \\o \target o
+ \o \bold {The \\o command announce a table or list item.}
+
+ Earlier we used the \l {i}{\\i} command for this purpose. For more
+ information see the \l
+ {26-qdoc-commands-compatibility.html#o-versus-i}{compatibility}
+ section.
+
+ The command can only be used within the \l{table}
+ {\\table...\\endtable} or \l{list}{\\list... \\endlist}
+ commands.
+
+ It considers everything until the next occurrence
+ of the \\o command, or the currently applicable \l
+ {table}{\\endtable} or \l {list}{\\endlist} command, as its
+ argument. For examples, see \l {table}{\\table} and \l
+ {list}{\\list}.
+
+ If the command is used within a table, you can in addition
+ specify how many rows or columns the item should span. For
+ example:
+
+ \code
+ / *!
+ \table
+ \header
+ \o {3,1} This header cell spans three columns
+ but only one row.
+ \row
+ \o {2, 1} This table item spans two columns
+ but only one row
+ \o {1, 2} This table item spans only one column,
+ but two rows.
+ \row
+ \o A regular table item
+ \o A regular table item
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2" cellspacing="1"
+ border="0">
+
+ <tr valign="top" bgcolor="#a2c511">
+ <th colspan="3" rowspan=" 1">
+ This header cell spans three columns but only one row
+ </th>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td colspan="2" rowspan=" 1">
+ This table item spans two columns but only one row
+ </td>
+ <td rowspan=" 2">
+ This table item spans only one column, but two rows.
+ </td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>A regular table item</td>
+ <td>A regular table item</td>
+ </tr>
+
+ </table>
+ \endraw
+
+ If not specified, the item will span one column and one row.
+
+ See also \l {table}{\\table}, \l {header}{\\header},
+ \l {list}{\\list} and \l {o}{\\o}.
+ \endtable
+*/
+
+/*!
+ \page 11-qdoc-commands-documentcontents.html
+ \previouspage Container Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Miscellaneous Commands
+
+ \title Document Contents Commands
+
+ The document contents commands identify parts of the documentation,
+ i.e. parts with a special rendering, conceptual meaning or
+ function.
+
+ \section1 Alphabetical List
+
+ \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract},
+ \l {11-qdoc-commands-documentcontents.html#brief}{\\brief},
+ \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote},
+ \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese},
+ \l {11-qdoc-commands-documentcontents.html#tableofcontents}
+ {\\tableofcontents},
+ \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation},
+ \l {11-qdoc-commands-documentcontents.html#warning}{\\warning}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\abstract \target abstract
+ \o \bold {The \\abstract command and the corresponding \\endabstract
+ command delimit a document's abstract section.}
+
+ The abstract section is rendered as an indented italicized
+ paragraph.
+
+ \warning This is preliminary funcionality. The
+ command is not fully implemented. Currently, the abstract
+ section is rendered as a regular HTML paragraph. For
+ example:
+
+ \code
+ / *!
+ \abstract
+ Qt by Trolltech is a C++ toolkit for cross-platform
+ GUI application development. Qt provides
+ single-source portability across Microsoft Windows,
+ Mac OS X, Linux, and all major commercial Unix
+ variants. It is also available for embedded
+ devices.
+ \endabstract
+ * /
+ \endcode
+
+ will be rendered as
+
+ \abstract
+ Qt by Trolltech is a C++ toolkit for cross-platform GUI
+ application development. Qt provides single-source
+ portability across Microsoft Windows, Mac OS X, Linux,
+ and all major commercial Unix variants. It is also
+ available for embedded devices.
+ \endabstract
+
+ \row
+ \o \bold \\quotation \target quotation
+ \o \bold { The \\quotation command and the corresponding
+ \\endquotation command delimit a quotation remark.}
+
+ This command replaces the old \\quote command. For more
+ information see the \l
+ {26-qdoc-commands-compatibility.html#quotation-versus-quote}
+ {compatibility} section.
+
+ The remark is rendered as a separate centered
+ paragraph. For example:
+
+ \code
+ / *!
+ While the prospect of a significantly broader market is
+ good news for Firstlogic, the notion also posed some
+ challenges. Dave Dobson, director of technology for the La
+ Crosse, Wisconsin-based company, said:
+
+
+ \quotation
+ As our solutions were being adopted into new
+ environments, we saw an escalating need for easier
+ integration with a wider range of enterprise
+ applications.
+ \endquotation
+ * /
+ \endcode
+
+ will be rendered as
+
+ While the prospect of a significantly broader market is
+ good news for Firstlogic, the notion also posed some
+ challenges. Dave Dobson, director of technology for the La
+ Crosse, Wisconsin-based company, said:
+
+ \quotation
+ As our solutions were being adopted into new
+ environments, we saw an escalating need for easier
+ integration with a wider range of enterprise
+ applications.
+ \endquotation
+
+ \row
+ \o \bold \\footnote \target footnote
+ \o \bold {The \\footnote command and the corresponding
+ \\endfootnote command delimit a footnote.}
+
+ The footnote follows the standard conventions, rendered at the
+ bottom of the page.
+
+ \warning This is preliminary funcionality. The
+ command is not fully implemented.
+
+ For example:
+
+ \code
+ / *!
+ In Qt 4 we have tried to simplify the constructors of
+ QObject/QWidget subclasses. This makes subclassing
+ easier, at the same time as it helps make the Qt
+ library more efficient.
+
+ \footnote
+ Constructors no longer take a "const char *name"
+ parameter. If you want to specify a name for a QObject,
+ you must call QObject::setObjectName() after
+ construction. The object name is now a QString.
+ \endfootnote
+
+ QWidget's WFlags data type has been split in two:
+ Qt::WindowFlags specifies low-level window flags (the
+ type of window and the frame style), whereas
+ Qt::WidgetAttribute specifies various higher-level
+ attributes about the widget (e.g.,
+ WA_StaticContents).
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ In Qt 4 we have tried to simplify the constructors of
+ QObject/QWidget subclasses. This makes subclassing
+ easier, at the same time as it helps make the Qt
+ library more efficient.
+
+ \footnote
+ Constructors no longer take a "const char *name"
+ parameter. If you want to specify a name for a QObject,
+ you must call QObject::setObjectName() after
+ construction. The object name is now a QString.
+ \endfootnote
+
+ QWidget's WFlags data type has been split in two:
+ Qt::WindowFlags specifies low-level window flags (the
+ type of window and the frame style), whereas
+ Qt::WidgetAttribute specifies various higher-level
+ attributes about the widget (e.g.,
+ WA_StaticContents).
+ \endquotation
+
+ \row
+ \o \bold \\tableofcontents \target tableofcontents
+ \o \bold {The \\tableofcontents command generates a
+ table displaying the titles of the current documentation
+ unit's parts, chapters, sections, etc.}
+
+ The command accepts a single optional argument:
+
+ \code
+ \tableofcontents sectionN
+ \endcode
+
+ where \c sectionN is the deepest section to include (by
+ default all sections are included).
+
+ For example, it the documentation unit's structure looks
+ something like this:
+
+ \quotation
+ \raw HTML
+ <a name="Basic Qt">
+ <h1>Basic Qt</h1>
+ </a>
+ <p>This is the first part.</p>
+
+ <a name="Getting started">
+ <h2>Getting Started</h2>
+ </a>
+ This is the first part's first chapter.</p>
+
+ <a name="Hello Qt">
+ <h3>Hello Qt</h3>
+ </a>
+ <p>This is the first chapter's first section.</p>
+
+ <a name="Making Connections">
+ <h3>Making Connections</h3>
+ </a>
+ <p>This is the first chapter's second section.</p>
+
+ <a name="Using the Reference Documentation">
+ <h3>Using the Reference Documentation</h3>
+ </a>
+ <p>This is the first chapter's third section.</p>
+
+ <a name="Creating Dialogs">
+ <h2>Creating Dialogs</h2>
+ </a>
+ <p>This is the first part's second chapter.</p>
+
+ <a name="Subclassing QDialog">
+ <h3>Subclassing QDialog</h3>
+ </a>
+ <p>This is the second chapter's first section.</p>
+
+ ...
+
+ <a name="Intermediate Qt">
+ <h1>Intermediate Qt</h1>
+ </a>
+ <p>This is the second part.</p>
+
+ <a name="Layout Management">
+ <h2>Layout Management</h2>
+ </a>
+ <p>This is the second part's first chapter.</p>
+
+ <a name="Basic Layouts">
+ <h3>Basic Layouts</h3>
+ </a>
+ <p>This is the first chapter's first section.</p>
+
+ ...
+
+ \endraw
+ \endquotation
+
+ Then
+
+ \code
+ / *!
+ Contents:
+
+ \tableofcontents
+
+ ...
+ * /
+ \endcode
+
+ will expand to
+
+ \quotation
+ \raw HTML
+ <p>Contents:</p>
+
+ <ul>
+ <li><a href="#Basic Qt">Basic Qt</a></li>
+ <ul>
+ <li><a href="#Getting Started">Getting Started</a></li>
+ <ul>
+ <li><a href="#Hello Qt">Hello Qt</a></li>
+ <li><a href="#Making Connections">
+ Making Connections</a></li>
+ <li><a href="#Using the Reference Documentation">
+ Using the Reference Documentation</a></li>
+ </ul>
+ <li><a href="#Creating Dialogs">Creating Dialogs</a></li>
+ <ul>
+ <li><a href="#Subclassing QDialog">
+ Subclassing QDialog</a></li>
+ </ul>
+ </ul>
+ <li><a href="#Intermediate Qt">Intermediate Qt</a></li>
+ <ul>
+ <li><a href="#Layout Management">Layout Management</a></li>
+ <ul>
+ <li><a href="#Basic Layouts">Basic Layouts</a></li>
+ </ul>
+ </ul>
+ </ul>
+
+ ...
+ \endraw
+ \endquotation
+
+ Each table entry becomes a link to the corresponding part,
+ chapter or section.
+
+ \row
+ \o \bold \\brief \target brief
+ \o \bold {The \\brief command introduces a one-sentence
+ description of a class, namespace, header file, property
+ or variable.}
+
+ The brief text is used to introduce the documentation of
+ the associated object, and in lists generated using the \l
+ {generatelist}{\\generatelist} command.
+
+ The \\brief command can be used in two significant
+ different ways: \l {brief class}{One for classes,
+ namespaces and header files}, and \l {brief property}{one
+ for properties and variables}.
+
+ \target brief property
+
+ When the \\brief command is used to describe a property or
+ a variable, the brief text must only be a sentence fragment
+ and start with "whether" (for boolean properties and
+ variables) or "the" (for any other property or variable).
+
+ For example the boolean QWidget::isWindow property:
+
+ \code
+ / *!
+ \property QWidget::isActiveWindow
+ \brief whether this widget's window is the active window
+
+ The active window is the window that contains the widget that
+ has keyboard focus.
+
+ When popup windows are visible, this property is true
+ for both the active window \e and for the popup.
+
+ \sa activateWindow(), QApplication::activeWindow()
+ * /
+ \endcode
+
+ and the QWidget::geometry property
+
+ \code
+ / *!
+ \property QWidget::geometry
+ \brief the geometry of the widget relative to its parent and
+ excluding the window frame
+
+ When changing the geometry, the widget, if visible,
+ receives a move event (moveEvent()) and/or a resize
+ event (resizeEvent()) immediately.
+
+ ...
+
+ \sa frameGeometry(), rect(), ...
+ * /
+ \endcode
+
+ The latter will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>geometry :
+ <a href="http://qt.nokia.com/doc/4.0/qrect.html">QRect</a>
+ </h3>
+ \endraw
+
+ This property holds the geometry of the widget relative
+ to its parent and excluding the window frame.
+
+ ...
+
+ Access functions:
+ \list
+ \o \bold {const QRect & geometry () const}
+ \o \bold {void setGeometry ( int x, int y, int w, int h )}
+ \o \bold {void setGeometry ( const QRect & )}
+ \endlist
+
+ See also \l
+ {QWidget::frameGeometry()}{frameGeometry()}, \l
+ {QWidget::rect()}{rect()}, ...
+ \endquotation
+
+ \target brief class
+
+ When the \\brief command is used to describe a class, the
+ brief text should be a complete sentence and must start
+ like this:
+
+ \code
+ The <classname> class is|provides|contains|specifies...
+ \endcode
+
+ and likewise when the command is used for namespaces or
+ header files.
+
+ \warning The brief statement is used as the first
+ paragraph of the detailed description. Do not repeat the
+ sentence.
+
+ For example:
+
+ \code
+ / *!
+ \class PreviewWindow
+ \brief The PreviewWindow class is a custom widget
+ displaying the names of its currently set
+ window flags in a read-only text editor.
+
+ The PreviewWindow class inherits QWidget. The widget
+ displays the names of its window flags set with the
+ setWindowFlags() function. It is also provided with a
+ QPushButton that closes the window.
+
+ ...
+
+ \sa QWidget
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1>PreviewWindow Class Reference</h1>
+ \endraw
+
+ The PreviewWindow class is a custom widget displaying
+ the names of its currently set window flags in a
+ read-only text editor. \l {preview window}{More...}
+
+ \raw HTML
+ <h3>Properties</h3>
+ \endraw
+
+ \list
+ \o 52 properties inherited from QWidget
+ \o 1 property inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Public Functions</h3>
+ \endraw
+
+ \list
+ \o \l {constructor}{PreviewWindow}(QWidget *parent = 0)
+ \o void \l {function}{setWindowFlags}(Qt::WindowFlags flags)
+ \endlist
+
+ \list
+ \o 183 public functions inherited from QWidget
+ \o 28 public functions inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Public Slots</h3>
+ \endraw
+
+ \list
+ \o 17 public slots inherited from QWidget
+ \o 1 public slot inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Additional Inherited Members</h3>
+ \endraw
+
+ \list
+ \o 1 signal inherited from QWidget
+ \o 1 signal inherited from QObject
+ \o 4 static public members inherited from QWidget
+ \o 4 static public members inherited from QObject
+ \o 39 protected functions inherited from QWidget
+ \o 7 protected functions inherited from QObject
+ \endlist
+
+ \target preview window
+
+ \raw HTML
+ <hr />
+ <h2>Detailed Description</h2>
+ \endraw
+ The PreviewWindow class is a custom widget displaying
+ the names of its currently set window flags in a
+ read-only text editor.
+
+ The PreviewWindow class inherits QWidget. The widget
+ displays the names of its window flags set with the \l
+ {function}{setWindowFlags()} function. It is also
+ provided with a QPushButton that closes the window.
+
+ ...
+
+ See also QWidget.
+
+ \raw HTML
+ <hr />
+ <h2>Member Function Documentation</h2>
+ \endraw
+
+ \target constructor
+ \raw HTML
+ <h3>PreviewWindow(QWidget *parent = 0)</h3>
+ \endraw
+
+ Constructs a preview window widget with \i parent.
+
+ \target function
+ \raw HTML
+ <h3>setWindowFlags(Qt::WindowFlags flags)</h3>
+ \endraw
+
+ Sets the widgets flags using the
+ QWidget::setWindowFlags() function.
+
+ Then runs through the available window flags,
+ creating a text that contains the names of the flags
+ that matches the flags parameter, displaying
+ the text in the widgets text editor.
+ \endquotation
+
+ Using \\brief with a namespace can for example look like this:
+
+ \code
+ / *!
+ \namespace Qt
+
+ \brief The Qt namespace contains miscellaneous identifiers
+ used throughout the Qt library.
+ * /
+ \endcode
+
+ and finally using \\brief with a header file can look
+ something like this:
+
+ \code
+ / *!
+ \headerfile <QtGlobal>
+ \title Global Qt Declarations
+
+ \brief The <QtGlobal> header file provides basic
+ declarations and is included by all other Qt headers.
+
+ \sa <QtAlgorithms>
+ * /
+ \endcode
+
+ See also \l{property}{\\property}, \l{class}{\\class},
+ \l{namespace}{\\namespace} and \l{headerfile}{\\headerfile}.
+
+ \row
+ \o \bold \\legalese \target legalese
+ \o \bold {The \\legalese command, and the corresponding \\endlegalese
+ command, delimit a licence agreement.}
+
+ If the \\endlegalese command is omitted, QDoc will still
+ process the \\legalese command but considers the rest of
+ the documentation page as the license agreement.
+
+ Ideally, the license documentation is located where the
+ licensed code is used.
+
+ Later the documentation identified by the \\legalese
+ command can be accumulated into a list using the \l
+ {generatelist}{\\generatelist} command with the \c legalese
+ argument. This is useful to generate an overview of all the
+ licenses associated with the source code.
+
+ For example:
+
+ \code
+ \ * !
+ ...
+
+ On X11, Qt also supports drops via the Motif Drag \&
+ Drop Protocol. The implementation incorporates some
+ code that was originally written by Daniel Dardailler,
+ and adapted for Qt by Matt Koss \<koss@napri.sk\> and
+ Trolltech. Here is the original copyright notice:
+
+ \legalese
+ \code
+
+ Copyright 1996 Daniel Dardailler.
+
+ Permission to use, copy, modify, distribute, and sell
+ this software for any purpose is hereby granted without
+ fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this
+ permission notice appear in supporting documentation,
+ and that the name of Daniel Dardailler not be used in
+ advertising or publicity pertaining to distribution of
+ the software without specific, written prior
+ permission. Daniel Dardailler makes no representations
+ about the suitability of this software for any
+ purpose. It is provided "as is" without express or
+ implied warranty.
+
+ Modifications Copyright 1999 Matt Koss, under the same
+ license as above.
+
+ \ endcode
+ \endlegalese
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ ...
+
+ On X11, Qt also supports drops via the Motif Drag \&
+ Drop Protocol. The implementation incorporates some
+ code that was originally written by Daniel Dardailler,
+ and adapted for Qt by Matt Koss \<koss@napri.sk\> and
+ Trolltech. Here is the original copyright notice:
+
+ \legalese
+ \code
+
+ Copyright 1996 Daniel Dardailler.
+
+ Permission to use, copy, modify, distribute, and sell
+ this software for any purpose is hereby granted without
+ fee, provided that the above copyright notice appear in
+ all copies and that both that copyright notice and this
+ permission notice appear in supporting documentation,
+ and that the name of Daniel Dardailler not be used in
+ advertising or publicity pertaining to distribution of
+ the software without specific, written prior
+ permission. Daniel Dardailler makes no representations
+ about the suitability of this software for any
+ purpose. It is provided "as is" without express or
+ implied warranty.
+
+ Modifications Copyright 1999 Matt Koss, under the same
+ license as above.
+
+ \endcode
+ \endlegalese
+ \endquotation
+
+ \row
+ \o \bold \\warning \target warning
+ \o \bold {The \\warning command renders a "Warning:" prefix to
+ the command's argument.}
+
+ For example:
+
+ \code
+ / *!
+ Qt::HANDLE is a platform-specific handle type
+ for system objects. This is equivalent to
+ \c{void *} on Windows and Mac OS X, and to
+ \c{unsigned long} on X11.
+
+ \warning Using this type is not portable.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Qt::HANDLE is a platform-specific handle type
+ for system objects. This is equivalent to
+ \c{void *} on Windows and Mac OS X, and to
+ \c{unsigned long} on X11.
+
+ \warning Using this type is not portable.
+ \endquotation
+ \endtable
+*/
+
+/*!
+ \page 12-0-qdoc-commands-miscellaneous.html
+ \previouspage Document Contents Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Topical Commands
+
+ \title Miscellaneous Commands
+
+ These commands provide miscellaneous functions
+ connected to the visual appearance of the documentation, and to the
+ process of generating the documentation.
+
+ \section1 Alphabetical List
+
+ \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else},
+ \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif},
+ \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire},
+ \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist},
+ \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if},
+ \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include},
+ \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta},
+ \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit},
+ \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw},
+ \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\unicode}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\expire \target expire
+ \o \bold {The \\expire command allows you to define an expiration
+ date for your documentation.}
+
+ When using the \\expire command, QDoc will emit a warning
+ when the current date is larger than the specified
+ date. The command accepts one argument; the argument's
+ format is yyyy-mm-dd. For example:
+
+ \code
+ / *!
+ \page porting.html
+
+ \title Porting to Qt 3.x
+
+ \expire 2004-12-31
+
+ This document describes porting applications from Qt
+ 2.x to Qt 3.x.
+
+ The Qt 3.x series is not binary compatible with the
+ 2.x series.
+ ...
+ * /
+ \endcode
+
+ If you run QDoc on 4 July 2005, it will emit the warning
+
+ \quotation
+ porting.qdoc:6: Documentation expired 185 days ago
+ \endquotation
+
+ \row
+ \o \bold \\generatelist \target generatelist
+ \o \bold {The \\generatelist command expands to a list of
+ various documentation or links to documentation.}
+
+ For example in the Qt Reference Documentation:
+
+ \code
+ / *!
+ \page classes.html
+ \title All Qt Classes (main index)
+
+ For a shorter list that only includes the most
+ frequently used classes, see \l{Qt's Main Classes}. For
+ a list of Qt 3 support classes, see \l{Qt3Support
+ Classes}.
+
+ \generatelist classes
+ * /
+ \endcode
+
+ is used to generate \l {All Qt Classes (main index)}.
+
+ The command accepts the following arguments:
+
+ \target table example
+
+ \list
+ \o \c annotatedclasses
+
+ The \c annotatedclasses argument provides a table
+ containing the names of all the classes, and a
+ description of each class. Each class name is a link to
+ the class's reference documentation.
+
+ For example:
+
+ \quotation
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/qdial.html">
+ QDial</a>
+ </td>
+ <td>Rounded range control (like a speedometer
+ or potentiometer)</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/qdialog.html">
+ QDialog</a>
+ </td>
+ <td>The base class of dialog windows</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>
+ <a href="http://qt.nokia.com/doc/4.0/qdir.html">
+ QDir</a>
+ </td>
+ <td>Access to directory structures and their
+ contents</td>
+ </tr>
+ </table>
+ \endraw
+ \endquotation
+
+ A class is identified within the documentation by the
+ the \l {class}{\\class} command, and the descriptions
+ are based on the argument of the \l {brief}{\\brief}
+ commands in the class documentation.
+
+ \target list example
+
+ \o \c classes
+
+ The \c classes argument provides a complete alphabetical
+ list of the classes. Each class name is a link to the
+ class's reference documentation.
+
+ For example:
+
+ \quotation
+ \raw HTML
+ <p><table width="100%">
+
+ <tr>
+ <td align="right"><b>A&nbsp;</b></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractbutton.html">QAbstractButton</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractextensionmanager.html">QAbstractExtensionManager</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemmodel.html">QAbstractItemModel</a></td>
+ </tr>
+
+ <tr>
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstracteventdispatcher.html">QAbstractEventDispatcher</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractformbuilder.html">QAbstractFormBuilder</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemview.html">QAbstractItemView</a></td>
+ </tr>
+
+ <tr>
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractextensionfactory.html">QAbstractExtensionFactory</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractitemdelegate.html">QAbstractItemDelegate</a></td>
+
+ <td align="right"></td>
+ <td><a href="http://qt.nokia.com/doc/4.0/qabstractlistmodel.html">QAbstractListModel</a></td>
+ </tr>
+ </table></p>
+ \endraw
+ \endquotation
+
+ A class is identified within the documentation by the
+ the \l {class}{\\class} command.
+
+ \o \c classesbymodule
+
+ This particular argument requests an additional argument,
+ i.e. a specification of the module.
+
+ For example:
+
+ \code
+ / *!
+ \page qtgui.html
+ \contentspage Qt Classes by Module
+ \previouspage QtCore Classes
+ \nextpage QtNetwork Classes
+
+ \title QtGui Classes
+
+ \keyword QtGui
+
+ \generatelist {classesbymodule QtGui}
+ * /
+ \endcode
+
+ Together, these arguments provide a table containing the
+ classes considered members of the specified module,
+ accompanied with a brief description. Each class name is
+ a link to the class's reference documentation.
+
+ The generated table is rendered similarily to the one
+ generated when using the \l {table example}{\c
+ annotatedclasses} argument.
+
+ For the basic classes in Qt, a class's module is
+ determined by its location, i.e. its directory. However,
+ for extensions, like ActiveQt and Qt Designer, a class
+ is related to a module with the \l
+ {inmodule}{\\inmodule} command.
+
+ \o \c classesbyedition
+
+ This particular argument requests an additional argument,
+ i.e. a specification of the edition.
+
+ For example:
+
+ \code
+ / *!
+ \page console-edition-classes.html
+ \title Qt Console Edition Classes
+
+ \generatelist{classesbyedition Console}
+ * /
+ \endcode
+
+ Together, these arguments provide a table containing the
+ classes considered members of the specified edition,
+ accompanied with a brief description. Each class name is
+ a link to the class's reference documentation.
+
+ The edition a given class can be found in is determined by
+ the module it belongs to.
+
+ \o \c compatclasses
+
+ The \c compatclasses argument provides a complete and
+ alphabetical list of the support classes. A support
+ class is identified within the documentation by the \l
+ {compat}{\\compat} command. Each class name is a link to
+ the class's reference documentation. The list is
+ rendered similarily to the list generated by the \l
+ {list example}{\c classes} argument.
+
+ \warning The \c classesbymodule argument will at some
+ point replace the this argument.
+
+ \o \c functionindex
+
+ The \c functionindex argument provides a complete
+ alphabetical list of all the documented member
+ functions.
+
+ For example:
+
+ \quotation
+ \raw HTML
+ <p><center><font size="+1"><b><a href="#a">A</a>&nbsp;<a href="#b">B</a>&nbsp;<a href="#c">C</a>&nbsp;<a href="#d">D</a>&nbsp;<a href="#e">E</a>&nbsp;<a href="#f">F</a>&nbsp;<a href="#g">G</a>&nbsp;<a href="#h">H</a>&nbsp;<a href="#i">I</a>&nbsp;<a href="#j">J</a>&nbsp;<a href="#k">K</a>&nbsp;<a href="#l">L</a>&nbsp;<a href="#m">M</a>&nbsp;<a href="#n">N</a>&nbsp;<a href="#o">O</a>&nbsp;<a href="#p">P</a>&nbsp;<a href="#q">Q</a>&nbsp;<a href="#r">R</a>&nbsp;<a href="#s">S</a>&nbsp;<a href="#t">T</a>&nbsp;<a href="#u">U</a>&nbsp;<a href="#v">V</a>&nbsp;<a href="#w">W</a>&nbsp;<a href="#x">X</a>&nbsp;<a href="#y">Y</a>&nbsp;<a href="#z">Z</a>&nbsp;</b></font></center></p>
+
+ <p>DTDHandler: <a href="http://qt.nokia.com/doc/4.0/qxmlreader.html#DTDHandler">QXmlReader</a></p>
+
+ <p>QAXCLASS: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXCLASS">global</a></p>
+
+ <p>QAXFACTORY_BEGIN: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_BEGIN">global</a></p>
+
+ <p>QAXFACTORY_DEFAULT: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_DEFAULT">global</a></p>
+
+ <p>QAXFACTORY_END: <a href="http://qt.nokia.com/doc/4.0/qaxfactory.html#QAXFACTORY_END">global</a></p>
+
+ \endraw
+
+ ...
+ \endquotation
+
+ \o \c legalese
+
+ The \c legalese argument provides a complete list of all
+ the licenses. The licenses are identified within the
+ documentation using the \l {legalese}{\\legalese}
+ command.
+
+ For example:
+
+ \quotation
+ \raw HTML
+ <hr />
+ <p>
+ Copyright (c) 1989 The Regents of the
+ University of California. All rights reserved.
+ </p>
+
+ <p>
+ Redistribution and use in source and binary
+ forms are permitted provided that the above
+ copyright notice and this paragraph are
+ duplicated in all such forms and that any
+ documentation, advertising materials, and other
+ materials related to such distribution and use
+ acknowledge that the software was developed by
+ the University of California, Berkeley...
+ </p>
+
+ <ul>
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qdate.html#weekNumber">QDate::weekNumber()</a>
+ </li>
+ </ul>
+
+ <hr />
+ <p>
+ Copyright (c) 1991 by AT&amp;T.
+ </p>
+
+ <p>
+ Permission to use, copy, modify, and distribute
+ this software for any purpose without fee is
+ hereby granted, provided that this entire notice
+ is included in all copies of any software which
+ is or includes a copy or modification of this
+ software and in all copies of the supporting
+ documentation for such software...
+ </p>
+
+ <ul>
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qlocale.html">QLocale</a>
+ </li>
+ </ul>
+ <hr />
+ \endraw
+ ...
+ \endquotation
+
+ \o \c mainclasses
+
+ The \c mainclasses argument provides a complete
+ alphabetical list of the main classes. Each class name
+ is a link to the class's reference documentation. A
+ class is related to the group of main classes by using
+ the \l {mainclass}{\\mainclass} command.
+
+ The list is rendered similarily to the list generated by
+ the \l {list example}{\c classes} argument.
+
+ \o \c overviews
+
+ The \c overviews argument provides a complete
+ alphabetical overview of the documentation. Each list
+ entry is a link to the respective documentation page.
+
+ The list includes pages declared using commands like \l
+ {page}{\\page} and \l {group}{\\group}. The list omits
+ examples and classes, and only lists the first page of
+ documentation that contains two or more pages using
+ commands like \l {nextpage}{\\nextpage}.
+
+ For example:
+
+ \quotation
+ \raw HTML
+ <ul>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qtalgorithms.html">
+ &lt;QtAlgorithms&gt; - Generic Algorithms
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qtglobal.html">
+ &lt;QtGlobal&gt; - Global Qt Declarations
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qaxserver-demo-simple.html">
+ A standard ActiveX and the &quot;simple&quot; ActiveQt widget
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/aboutqt.html">
+ About Qt
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/trolltech.html">
+ About Trolltech
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/abstractwidgets.html">
+ Abstract Widget Classes
+ </a>
+ </li>
+
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/accessibility.html">
+ Accessibility Classes
+ </a>
+ </li>
+ ...
+ </ul>
+ \endraw
+ \endquotation
+
+ \o \c related
+
+ The \c related argument is used in combination with the
+ \l {group}{\\group} command to list all the overviews
+ related to the given group. Each list entry is a link to
+ the respective documentation page.
+
+ \o \c relatedinline
+
+ The \c related argument is used in combination with the
+ \l {group}{\\group} command to collect all documentation
+ related to the given group. The various documentation
+ snippets are copied directly into the group page.
+
+ \o \c service
+
+ The \c service argument provides a complete alphabetical
+ list of the services. Each service name is a link to the
+ service's reference documentation.
+
+ A service is identified within the documentation by the
+ \l {service}{\\service} command.
+
+ \endlist
+
+
+ \row
+ \o \bold \\if \target if
+ \o \bold {The \\if command and the corresponding \\endif command
+ enclose parts of a QDoc comment that only will be included if
+ the condition specified by the command's argument is true.}
+
+ The command reads the rest of the line and parses it as an
+ C++ #if statement. For example:
+
+ \code
+ / *!
+ \if defined(opensourceedition)
+
+ \bold{Note:} This edition is for the development of
+ \l{Qt Open Source Edition}{Free and Open Source}
+ software only; see \l{Qt Commercial Editions}.
+
+ \endif
+ * /
+ \endcode
+
+ This QDoc comment will only be rendered if the \c
+ opensourceedition preprocessor symbol is defined, and
+ specified in the \l {definesvariable}{defines} variable in
+ the configuration file to make QDoc process
+ the code within #ifdef and #endif:
+
+ \code
+ defines = opensourceedition
+ \endcode
+
+ You can also define the preprocessor symbol manually on the
+ command line. For more information see the documentation of
+ the \l {definesvariable}{defines} variable.
+
+ See also \l{endif}{\\endif}, \l{else}{\\else}, \l
+ {definesvariable}{defines} and \l falsehoods.
+
+ \row
+ \o \bold \\endif \target endif
+ \o \bold {The \\endif command and the corresponding \\if command
+ enclose parts of a QDoc comment that will be included if
+ the condition specified by the \l {if}{\\if} command's
+ argument is true.}
+
+ For more information, see the documentation of the \l
+ {if}{\\if} command.
+
+ See also \l{if}{\\if}, \l{else}{\\else}, \l
+ {definesvariable}{defines} and \l falsehoods.
+
+ \row
+ \o \bold \\else \target else
+ \o \bold {The \\else command specifies an alternative if the
+ condition in the \l {if}{\\if} command is false.}
+
+ The \\else command can only be used within \l
+ {if}{\\if...\\endif} commands, but is useful when there is
+ only two alternatives. For example:
+
+ \code
+ / *!
+ The Qt 3 support library is provided to keep old
+ source code working.
+
+ In addition to the \c Qt3Support classes, Qt 4 provides
+ compatibility functions when it's possible for an old
+ API to cohabit with the new one.
+
+ \if !defined(QT3_SUPPORT)
+ \if defined(QT3_SUPPORTWARNINGS)
+ The compiler emits a warning when a
+ compatibility function is called. (This works
+ only with GCC 3.2+ and MSVC 7.)
+ \else
+ To use the Qt 3 support library, you need to
+ have the line QT += qt3support in your .pro
+ file (qmake automatically define the
+ QT3_SUPPORT symbol, turning on compatibility
+ function support).
+
+ You can also define the symbol manually (e.g.,
+ if you don't want to link against the \c
+ Qt3Support library), or you can define \c
+ QT3_SUPPORT_WARNINGS instead, telling the
+ compiler to emit a warning when a compatibility
+ function is called. (This works only with GCC
+ 3.2+ and MSVC 7.)
+ \endif
+ \endif
+ * /
+ \endcode
+
+ If the \c QT3_SUPPORT is defined, the comment will be rendered
+ as
+
+ \quotation
+ The Qt 3 support library is provided to keep old source
+ code working.
+
+ In addition to the Qt3Support classes, Qt 4 provides
+ compatibility functions when it's possible for an old
+ API to cohabit with the new one.
+ \endquotation
+
+ If \c QT3_SUPPORT isn't defined but \c QT3_SUPPORT_WARNINGS
+ is, the comment will be rendered as
+
+ \quotation
+ The Qt 3 support library is provided to keep old source
+ code working.
+
+ In addition to the Qt3Support classes, Qt 4 provides
+ compatibility functions when it's possible for an old
+ API to cohabit with the new one.
+
+ The compiler emits a warning when a compatibility
+ function is called. (This works only with GCC 3.2+ and
+ MSVC 7.)
+ \endquotation
+
+ If none of the symbols are defined, the comment will be
+ rendered as
+
+ \quotation
+ The Qt 3 support library is provided to keep old
+ source code working.
+
+ In addition to the \c Qt3Support classes, Qt 4 provides
+ compatibility functions when it's possible for an old
+ API to cohabit with the new one.
+
+ To use the Qt 3 support library, you need to have the
+ line QT += qt3support in your .pro file (qmake
+ automatically define the QT3_SUPPORT symbol, turning on
+ compatibility function support).
+
+ You can also define the symbol manually (e.g., if you
+ don't want to link against the \c Qt3Support library),
+ or you can define \c QT3_SUPPORT_WARNINGS instead,
+ telling the compiler to emit a warning when a
+ compatibility function is called. (This works only with
+ GCC 3.2+ and MSVC 7.)
+ \endquotation
+
+ See also \l{if}{\\if}, \l{endif}{\\endif}, \l
+ {definesvariable}{defines} and \l falsehoods.
+
+ \row
+ \o \bold \\include \target include
+ \o \bold {The \\include command expands to the contents of the
+ file specified by the command's argument.}
+
+ \warning This is preliminary functionality. For more
+ information, see the \l
+ {26-qdoc-commands-compatibility.html#include-versus-input}
+ {compatibility} section.
+
+ The command takes a file name as an argument, and is
+ useful when some piece of the documentation is used
+ repeatedly: Move the repetetive text into a separate file,
+ and use the \\include command whenever you want to insert
+ the separate documentation.
+
+ The contents of such a file should follow QDoc syntax,
+ excluding the enclosing \c{/}\c{*!} ... \c{*}\c{/} marks.
+ To ensure that QDoc won't attempt to read the file as a
+ stand-alone piece of documentation, we recommend that you
+ use the \c .qdocinc extension.
+
+ For example:
+
+ \code
+ / *!
+ \page corefeatures.html
+ \title Core Features
+
+ \include examples/signalandslots.qdocinc
+ \include examples/objectmodel.qdocinc
+ \include examples/layoutmanagement.qdocinc
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1>Core Features</h1>
+ \endraw
+
+ \include examples/signalandslots.qdocinc
+ \include examples/objectmodel.qdocinc
+ \include examples/layoutmanagement.qdocinc
+ \endquotation
+
+ Here is the actual \c .qdocinc files: \l
+ signalandslots.qdocinc, \l objectmodel.qdocinc, \l
+ layoutmanagement.qdocinc
+
+ \row
+ \o \bold \\meta \target meta
+ \o \bold {The \\meta command is the QDoc equivalent to the HTML
+ \c meta tag.}
+
+ The command accepts two arguments: The first argument (the
+ following word) is equivalent to the HTML meta tag's \i
+ name variable, and the second argument (the rest of the
+ line) is equivalent to the tag's \i contents variable.
+
+ For example:
+
+ \code
+ / *!
+ \meta author Summerfield
+
+ \section1 Automatic Dialogs
+
+ \abstract
+ This article shows how to maintain sets of
+ "attributes" (QVariant values), and how to allow
+ users to view and edit them using dialogs that are
+ created dynamically based on the attributes and
+ their types.
+ \endabstract
+
+ The Attributes class described in this article holds a
+ set of QVariants, and can create a dialog to present
+ the QVariants to the user in an appropriate way.
+
+ ...
+ * /
+ \endcode
+
+ will be included in the generated HTML page as
+
+ \code
+ <head>
+ ...
+ <meta name="author" content="Summerfield" />
+ ...
+ </head>
+ \endcode
+
+ \row
+ \o \bold \\omit \target omit
+ \o \bold {The \\omit command and the correspondning \\endomit
+ command delimit parts of the documentation that
+ you want QDoc to skip.}
+
+ For example:
+
+ \code
+ / *!
+ \table
+ \row
+ \o Basic Widgets
+ \o Basic GUI widgets such as buttons, comboboxes
+ and scrollbars.
+
+ \omit
+ \row
+ \o Component Model
+ \o Interfaces and helper classes for the Qt
+ Component Model.
+ \endomit
+
+ \row
+ \o Database Classes
+ \o Database related classes, e.g. for SQL databases.
+ \endtable
+ * /
+ \endcode
+
+ will be rendered as
+
+ \raw HTML
+ <table align="center" cellpadding="2"
+ cellspacing="1" border="0">
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>Basic Widgets</td>
+ <td>Basic GUI widgets such as buttons, comboboxes
+ and scrollbars.</td>
+ </tr>
+
+ <tr valign="top" bgcolor="#c0c0c0">
+ <td>Database Classes</td>
+ <td>Database related classes, e.g. for SQL databases.</td>
+ </tr>
+ </table>
+ \endraw
+
+
+ \row
+ \o \bold \\raw \target raw
+ \o \bold {The \\raw command and the corresponding
+ \\endraw command delimit a block of raw mark-up language code.}
+
+ The command takes an argument specifying the code's format;
+ currently the only supported format is HTML.
+
+ The \\raw command is useful if you want some special HTML
+ effects in your documentation. For example:
+
+ \code
+ / *!
+ Qt has some predefined QColor objects. For example:
+
+ \raw HTML
+ <style type="text/css" id="colorstyles">
+ #blue { background-color: #0000ff; color: #ffffff }
+ #darkBlue { background-color: #000080; color: #ffffff }
+ #cyan { background-color: #00ffff; color: #000000 }
+ </style>
+
+ <p>
+ <tt id="blue">Blue(#0000ff)</tt>,
+ <tt id="darkBlue">dark blue(#000080)</tt> and
+ <tt id="cyan">cyan(#00ffff)</tt>.
+ \endraw
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ Qt has some predefined QColor objects. For example:
+
+ \raw HTML
+ <style type="text/css" id="colorstyles">
+ #blue { background-color: #0000ff; color: #ffffff }
+ #darkBlue { background-color: #000080; color: #ffffff }
+ #cyan { background-color: #00ffff; color: #000000 }
+ </style>
+
+ <p>
+ <tt id="blue">Blue(#0000ff)</tt>,
+ <tt id="darkBlue">dark blue(#000080)</tt> and
+ <tt id="cyan">cyan(#00ffff)</tt>.
+ \endraw
+ \endquotation
+
+ \row
+ \o \bold \\unicode \target unicode
+ \o \bold {The \\unicode command allows you to insert an
+ arbitrary Unicode character in the document.}
+
+ The command takes an argument specifying the character as
+ an integer. By default, base 10 is assumed, unless a '0x'
+ or '0' prefix is specified (for base 16 and 8,
+ respectively). For example:
+
+ \code
+ O G\unicode{0xEA}nio e as Rosas
+
+ \unicode 0xC0 table en famille avec 15 \unicode 0x20AC par jour
+
+ \unicode 0x3A3 \i{a}\sub{\i{i}}
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ O G\unicode{0xEA}nio e as Rosas
+
+ \unicode 0xC0 table en famille avec 15 \unicode 0x20AC par jour
+
+ \unicode 0x3A3 \i{a}\sub{\i{i}}
+ \endquotation
+
+ The \\raw command follows the same conventions as the \l
+ {i}{\\i} command for \l {argument}{punctuation and use of
+ braces} for the argument.
+ \endtable
+*/
+
+/*!
+ \page 12-1-signalandslots.html
+ \previouspage Miscellaneous Commands
+ \contentspage QDoc Manual - Table of Contents
+
+ \title signalandslots.qdocinc
+
+ \quotefile examples/signalandslots.qdocinc
+*/
+
+/*!
+ \page 12-2-objectmodel.html
+ \previouspage Miscellaneous Commands
+ \contentspage QDoc Manual - Table of Contents
+
+ \title objectmodel.qdocinc
+
+ \quotefile examples/objectmodel.qdocinc
+*/
+
+/*!
+ \page 12-3-layoutmanagement.html
+ \previouspage Miscellaneous Commands
+ \contentspage QDoc Manual - Table of Contents
+
+ \title layoutmanagement.qdocinc
+
+ \quotefile examples/layoutmanagement.qdocinc
+*/
+
+/*!
+ \page 13-qdoc-commands-topical.html
+ \previouspage Miscellaneous Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Contextual Commands
+
+ \title Topical Commands
+
+ The topical commands tell QDoc what is being documented
+ (i.e. existing units like classes, functions and examples), and
+ some of the commands allows you to create extra pages.
+
+ \section1 Alphabetical List
+
+ \l {13-qdoc-commands-topical.html#class}{\\class},
+ \l {13-qdoc-commands-topical.html#enum}{\\enum},
+ \l {13-qdoc-commands-topical.html#example-command}{\\example},
+ \l {13-qdoc-commands-topical.html#externalpage}{\\externalpage},
+ \l {13-qdoc-commands-topical.html#fn}{\\fn},
+ \l {13-qdoc-commands-topical.html#group}{\\group},
+ \l {13-qdoc-commands-topical.html#headerfile}{\\headerfile},
+ \l {13-qdoc-commands-topical.html#macro}{\\macro},
+ \l {13-qdoc-commands-topical.html#module}{\\module},
+ \l {13-qdoc-commands-topical.html#namespace}{\\namespace},
+ \l {13-qdoc-commands-topical.html#page}{\\page},
+ \l {13-qdoc-commands-topical.html#property}{\\property},
+ \l {13-qdoc-commands-topical.html#service}{\\service},
+ \l {13-qdoc-commands-topical.html#typedef}{\\typedef},
+ \l {13-qdoc-commands-topical.html#variable}{\\variable},
+
+ \section1 General Description
+
+ When QDoc is processing a comment, it will try to connect the
+ documentation to the source code. For that reason it will first
+ look for the topical commands. If there is no such command, it
+ will try to tie the documentation to the immediately following
+ code. If there is no topical command, and the documentation cannot
+ be tied to following code, the documentation is simply lost.
+
+ \target topical argument
+
+ The documented unit's name is passed as the unique argument for
+ all the topical commands. The argument's naming convention is the
+ documented unit's complete name. For example:
+
+ \code
+ \enum QComboBox::InsertPolicy
+ \endcode
+
+ Functions is a special case, the argument's naming convention for
+ the \l {fn}{\\fn} command is that of the function's definition
+ outside the class definition. For example:
+
+ \code
+ \fn void PreviewWindow::setWindowFlags()
+ \endcode
+
+ A topical command can appear anywhere in a comment, but must stand
+ alone on its own line. If the argument spans several lines, make
+ sure that each line (except the last one) is ended with a
+ backslash. In addition QDoc counts parentheses, which means that
+ if it encounters a '(' it considers everything until the closing
+ ')' as its argument.
+
+ If a topical command is repeated with different arguments, the
+ same documentation will appear for both the units. For example:
+
+ \code
+ / *!
+ \fn void PreviewWindow::setWindowFlags()
+ \fn void ControllerWindow::setWindowFlags()
+
+ Sets the widgets flags using the QWidget::setWindowFlags()
+ function.
+
+ Then runs through the available window flags, creating a text
+ that contains the names of the flags that matches the flags
+ parameter, displaying the text in the widgets text editor.
+ * /
+ \endcode
+
+ The \c PreviewWindow::setWindowFlags() and \c
+ ControllerWindow::setWindowFlags() functions will get the same
+ documentation.
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\class \target class
+ \o \bold {The \\class command tells QDoc that a class is
+ part of the public API, and lets you enter a detailed
+ description.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument, and supports
+ nested classes, for example:
+
+ \code
+ / *!
+ \class QMap::iterator
+
+ \brief The QMap::iterator class provides an STL-style
+ non-const iterator for QMap and QMultiMap.
+
+ QMap features both \l{STL-style iterators} and
+ \l{Java-style iterators}. The STL-style iterators ...
+ * /
+ \endcode
+
+ The generated HTML documentation for the specified class is
+ put in \c <lower-case>classname.html. For example, the
+ documentation for the \c PreviewWindow class is located in
+ \c previewwindow.html.
+
+ \target framework
+
+ In addition to render the detailed description, the \\class
+ comand will generate the documentation framework, i.e. a
+ list of the class's types, properties, functions, signals
+ and slots with empty documentation.
+
+ The command is typically accompanied with a \l
+ {brief}{\\brief} command, a \l {mainclass}{\\mainclass}
+ command, an \l {ingroup}{\\ingroup} command and a \l
+ {sa}{\\sa} command. For example:
+
+ \code
+ / *!
+ \class PreviewWindow
+ \brief The PreviewWindow class is a custom widget
+ displaying the names of its currently set
+ window flags in a read-only text editor.
+
+ \mainclass
+ \ingroup miscellaneous
+
+ The PreviewWindow class inherits QWidget. The widget
+ displays the names of its window flags set with the \l
+ {function}{setWindowFlags()} function. It is also
+ provided with a QPushButton that closes the window.
+
+ ...
+
+ \sa QWidget
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1>PreviewWindow Class Reference</h1>
+ \endraw
+
+ The PreviewWindow class is a custom widget displaying
+ the names of its currently set window flags in a
+ read-only text editor. \l {preview window}{More...}
+
+ \raw HTML
+ <h3>Properties</h3>
+ \endraw
+
+ \list
+ \o 52 properties inherited from QWidget
+ \o 1 property inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Public Functions</h3>
+ \endraw
+
+ \list
+ \o \l {constructor}{PreviewWindow}(QWidget *parent = 0)
+ \o void \l {function}{setWindowFlags}(Qt::WindowFlags flags)
+ \endlist
+
+ \list
+ \o 183 public functions inherited from QWidget
+ \o 28 public functions inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Public Slots</h3>
+ \endraw
+
+ \list
+ \o 17 public slots inherited from QWidget
+ \o 1 public slot inherited from QObject
+ \endlist
+
+ \raw HTML
+ <h3>Additional Inherited Members</h3>
+ \endraw
+
+ \list
+ \o 1 signal inherited from QWidget
+ \o 1 signal inherited from QObject
+ \o 4 static public members inherited from QWidget
+ \o 4 static public members inherited from QObject
+ \o 39 protected functions inherited from QWidget
+ \o 7 protected functions inherited from QObject
+ \endlist
+
+ \target preview window
+
+ \raw HTML
+ <hr />
+ <h2>Detailed Description</h2>
+ \endraw
+
+ The PreviewWindow class is a custom widget displaying
+ the names of its currently set window flags in a
+ read-only text editor.
+
+ The PreviewWindow class inherits QWidget. The widget
+ displays the names of its window flags set with the \l
+ {function}{setWindowFlags()} function. It is also
+ provided with a QPushButton that closes the window.
+
+ ...
+
+ See also QWidget.
+
+ \raw HTML
+ <hr />
+ <h2>Member Function Documentation</h2>
+ \endraw
+
+ \target constructor
+ \raw HTML
+ <h3>PreviewWindow(QWidget *parent = 0)</h3>
+ \endraw
+
+ Constructs a preview window widget with \i parent.
+
+ \target function
+ \raw HTML
+ <h3>setWindowFlags(Qt::WindowFlags flags)</h3>
+ \endraw
+
+ Sets the widgets flags using the
+ QWidget::setWindowFlags() function.
+
+ Then runs through the available window flags,
+ creating a text that contains the names of the flags
+ that matches the flags parameter, displaying
+ the text in the widgets text editor.
+ \endquotation
+
+ \row
+ \o \bold \\enum \target enum
+ \o \bold {The \\enum command allows you to document a C++ enum.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ The enum items are documented using the \l {value}{\\value}
+ command. If an item isn't documented, QDoc will emit a
+ warning. This can be avoided using the \l
+ {omitvalue}{\\omitvalue} command excluding an item from the
+ documentation. The enum documentation will be located in
+ the associated class, header file or namespace
+ documentation.
+
+ For example:
+
+ \code
+ enum Corner {
+ TopLeftCorner = 0x00000,
+ TopRightCorner = 0x00001,
+ BottomLeftCorner = 0x00002,
+ BottomRightCorner = 0x00003
+ #if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN)
+ ,TopLeft = TopLeftCorner,
+ TopRight = TopRightCorner,
+ BottomLeft = BottomLeftCorner,
+ BottomRight = BottomRightCorner
+ #endif
+ };
+ \endcode
+
+ In case of the Qt::Corner enum,
+
+ \code
+ / *!
+ \enum Qt::Corner
+
+ This enum type specifies a corner in a rectangle:
+
+ \value TopLeftCorner
+ The top-left corner of the rectangle.
+ \value TopRightCorner
+ The top-right corner of the rectangle.
+ \value BottomLeftCorner
+ The bottom-left corner of the rectangle.
+ \value BottomRightCorner
+ The bottom-right corner of the rectangle.
+
+ \omitvalue TopLeft
+ \omitvalue TopRight
+ \omitvalue BottomLeft
+ \omitvalue BottomRight
+ * /
+ \endcode
+
+ this associated QDoc comment will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3 class="fn"><a name="Corner-enum"></a>enum Qt::Corner</h3>
+
+ <p>This enum type specifies a corner in a rectangle:</p>
+
+ <table border="1" cellpadding="2" cellspacing="1" width="100%">
+ <tr>
+ <th width="25%">Constant</th>
+ <th width="15%">Value</th>
+ <th width="60%">Description</th>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>Qt::TopLeftCorner</tt></td>
+ <td align="center" valign="top"><tt>0x00000</tt></td>
+ <td valign="top">The top-left corner of the rectangle.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>Qt::TopRightCorner</tt></td>
+ <td align="center" valign="top"><tt>0x00001</tt></td>
+ <td valign="top">The top-right corner of the rectangle.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>Qt::BottomLeftCorner</tt></td>
+ <td align="center" valign="top"><tt>0x00002</tt></td>
+ <td valign="top">The bottom-left corner of the rectangle.</td>
+ </tr>
+
+ <tr>
+ <td valign="top"><tt>Qt::BottomRightCorner</tt></td>
+ <td align="center" valign="top"><tt>0x00003</tt></td>
+ <td valign="top">The bottom-right corner of the rectangle.</td>
+ </tr>
+
+ </table>
+ \endraw
+ \endquotation
+
+ in qt.html.
+
+ See also \l {value}{\\value} and \l {omitvalue}{\\omitvalue}.
+
+ \row
+ \o \bold \\example \target example-command
+ \o \bold {The \\example command allows you to document an
+ example.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument. In particular
+ the command's argument is the example's path relative to
+ the paths listed in the \l exampledirs configuration
+ variable.
+
+ The documentation will be located in \i
+ {path-to-example}.html, and QDoc will add a list of all the
+ example files at the top of this documentation page.
+
+ For example, if \l exampledirs contain \c
+ $QTDIR/examples/widgets/imageviewer, then
+
+ \code
+ / *!
+ \example widgets/imageviewer
+ \title ImageViewer Example
+ \subtitle
+
+ The example shows how to combine QLabel and QScrollArea
+ to display an image.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <center><h1>Image Viewer Example</h1></center>
+ \endraw
+
+ Files:
+ \list
+ \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-imageviewer-cpp.html}
+ {widgets/imageviewer/imageviewer.cpp}
+ \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-imageviewer-h.html}
+ {widgets/imageviewer/imageviewer.h}
+ \o \l{http://qt.nokia.com/doc/4.0/widgets-imageviewer-main-cpp.html}
+ {widgets/imageviewer/main.cpp}
+ \endlist
+
+ The example shows how to combine QLabel and QScrollArea
+ to display an image.
+
+ ...
+ \endquotation
+
+ in widgets-imageviewer.html.
+
+ \row
+ \o \bold \\fn \target fn
+ \o \bold {The \\fn command allows you to document a function.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument. In particular
+ it is important that the return type of the function,
+ whether it is \c const or not and the complete set of
+ arguments with type are included in the argument. If the
+ referenced function doesn't exist, QDoc will emit a
+ warning.
+
+ Also, the \\fn command is QDoc's default command, i.e. when
+ no topical command can be found within a QDoc comment, QDoc
+ tries to tie the documentation to the following code as if
+ it was function documentation.
+
+ This means that the command normally isn't necessary since
+ the recommended style is to write the function
+ documentation directly before the function implementation
+ in the \c .cpp file. In fact, it should only be used for
+ inline functions implemented in the \c .h file.
+
+ For example:
+
+ \code
+ / *!
+ \fn bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const
+
+ Returns true if this toolbar is dockable in the given
+ \a area; otherwise returns false.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>bool QToolBar::isAreaAllowed(Qt::ToolBarArea area) const
+ </h3>
+ \endraw
+
+ Returns true if this toolbar is dockable in the given
+ \a area; otherwise returns false.
+ \endquotation
+
+ See also \l {overload}{\\overload}.
+
+ \row
+ \o \bold \\group \target group
+ \o \bold {The \\group command creates a separate page that
+ lists the classes belonging to the group specified by the
+ command's argument.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument. The \\group
+ command is typically followed by a \l {title}{\\title}
+ command and a short introduction to the group. The
+ generated HTML documentation for the specified group is put
+ in <lower-case>\i{group}.html.
+
+ A class can be related to a group by using the \l
+ {ingroup}{\\ingroup} command. In addition, overviews can be
+ related to a group using the same command, but these must
+ be listed explicitly using the \l
+ {generatelist}{\\generatelist} command (see example below).
+
+ Each class is listed with a link to the class reference
+ page and a brief description based on the classes' \l
+ {brief}{\\brief} texts. For example:
+
+ \code
+ / *!
+ \group io
+
+ \title Input/Output and Networking
+
+ These classes are used to handle input and output to
+ and from external devices, processes, files etc. as
+ well as manipulating files and directories.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+
+ <h1>Input/Output and Networking</h1>
+
+ <p>These classes are used to handle input and output
+ to and from external devices, processes, files etc. as
+ well as manipulating files and directories.</p>
+
+ <p>
+ <table width="100%">
+ <tr valign="top" bgcolor="#e0e0e0">
+ <td><b>
+ <a href="http://qt.nokia.com/doc/4.0/qabstractsocket.html">QAbstractSocket</a>
+ </b></td>
+ <td>
+ The base functionality common to all socket types
+ </td></tr>
+
+ <tr valign="top" bgcolor="#e0e0e0">
+ <td><b>
+ <a href="http://qt.nokia.com/doc/4.0/qbuffer.html">QBuffer</a>
+ </b></td>
+ <td>
+ QIODevice interface for a QByteArray
+ </td></tr>
+
+ <tr valign="top" bgcolor="#e0e0e0">
+ <td><b>
+ <a href="http://qt.nokia.com/doc/4.0/qclipboard.html">QClipboard</a>
+ </b></td>
+ <td>
+ Access to the window system clipboard
+ </td></tr>
+ </table>
+ \endraw
+ \endquotation
+
+ in io.html.
+
+ Note that overviews related to the given group, must be
+ listed explicitly using the \l
+ {generatelist}{\\generatelist} command with the \c related
+ argument. For example:
+
+ \code
+ / *!
+ \group architecture
+
+ \title Architecture
+
+ These documents describe aspects of Qt's architecture
+ and design, including overviews of core Qt features and
+ technologies.
+
+ \generatelist{related}
+ * /
+ \endcode
+
+ See also \l {ingroup}{\\ingroup} and \l
+ {generatelist}{\\generatelist}.
+
+ \row
+ \o \bold \\headerfile \target headerfile
+ \o \bold {The \\headerfile command allows you to document
+ global functions, types and macros declared in a header file.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument, and the
+ generated HTML documentation for the specified header file
+ is put in <lower-case>\i{headerfilename}.html.
+
+ A function, type or macro can be associated with a
+ headerfile using the \l {relates}{\\relates} command.
+
+ If the referenced header file doesn't exist, the
+ \\headerfile command will still create a documentation page
+ for a header file with the referenced file's name.
+
+ For example:
+
+ \code
+ / *!
+ \headerfile <QtAlgorithms>
+
+ \title Generic Algorithms
+
+ \brief The <QtAlgorithms> header file provides
+ generic template-based algorithms.
+
+ Qt provides a number of global template functions in \c
+ <QtAlgorithms> that work on containers and perform
+ well-know algorithms.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <center><h1>&lt;QtAlgorithms&gt; -
+ Generic Algorithms</h1></center>
+ <p>The <QtAlgorithms> header file provides generic
+ template-based algorithms.
+ <a href="13-qdoc-commands-topical.html#header">More...</a>
+ </p>
+
+ <h3>Functions</h3>
+ <ul>
+ <li>RandomAccessIterator
+ <a href="http://qt.nokia.com/doc/4.0/qlineedit.html#EchoMode-enum">qBinaryFind</a></b>
+ (RandomAccessIterator begin, RandomAccessIterator end,
+ const T & value)</li>
+ <li>...</li></ul>
+ <hr />
+ \endraw
+
+ \target header
+
+ \raw HTML
+ <h2>Detailed Description</h2>
+ <p>The <QtAlgorithms> header file provides generic
+ template-based algorithms. </p>
+ \endraw
+
+ Qt provides a number of global template functions in \c
+ <QtAlgorithms> that work on containers and perform
+ well-know algorithms.
+
+ ...
+ \endquotation
+
+ in qtalgorithms.html.
+
+ \row
+ \o \bold \\macro \target macro
+ \o \bold {The \\macro command allows you to document a C++ macro.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ QDoc recognizes three different macro syntax: function-like
+ macros like Q_ASSERT(), declaration-style macros like
+ Q_PROPERTY() and macros without parentheses like Q_OBJECT.
+
+ The \\macro command must be followed by a \l
+ {relates}{\\relates} command which attaches the
+ documentation to that of a related class, header file. or
+ namespace. Otherwise the documentation will be lost.
+
+ For example:
+
+ \code
+ / *!
+ \macro void Q_ASSERT(bool test)
+ \relates <QtGlobal>
+
+ Prints a warning message containing the source code
+ file name and line number if \a test is false.
+
+ ...
+
+ \sa Q_ASSERT_X(), qFatal(), {Debugging Techniques}
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>void Q_ASSERT ( bool <i>test</i> )</h3>
+ \endraw
+
+ Prints a warning message containing the source code
+ file name and line number if \a test is false.
+
+ ...
+
+ See also Q_ASSERT_X(), qFatal() and \l {Debugging
+ Techniques}.
+ \endquotation
+
+ in qtglobal.html. And
+
+ \code
+ / *!
+ \macro Q_PROPERTY(...)
+ \relates QObject
+
+ This macro declares a QObject property. The syntax is:
+
+ ...
+
+ \sa {Qt's Property System}
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>Q_PROPERTY ( ... )</h3>
+ \endraw
+
+ This macro declares a QObject property. The syntax is:
+
+ ...
+
+ See also \l {Qt's Property System}.
+ \endquotation
+
+ in qobject.html. And
+
+ \code
+ / *!
+ \macro Q_OBJECT
+ \relates QObject
+
+ The Q_OBJECT macro must appear in the private section
+ of a class definition that declares its own signals and
+ slots or that uses other services provided by Qt's
+ meta-object system.
+
+ ...
+
+ \sa {Meta-Object System}, {Signals and Slots}, {Qt's
+ Property System}
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>Q_OBJECT</h3>
+ \endraw
+
+ The Q_OBJECT macro must appear in the private section
+ of a class definition that declares its own signals and
+ slots or that uses other services provided by Qt's
+ meta-object system.
+
+ ...
+
+ See also \l {Meta-Object System}, \l {Signals and
+ Slots} and \l {Qt's Property System}.
+ \endquotation
+
+ in qobject.html.
+
+ \row
+ \o \bold \\module \target module
+ \o \bold {The \\module creates a separate page that lists the
+ classes belonging to the module specified by the command's
+ argument.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ A class can be related to a module using the \l
+ {inmodule}{\\inmodule} command.
+
+ The \\module command is typically followed by the \l
+ {title}{\\title} and \l {brief}{\\brief} commands. Each
+ class is listed with a link to the class reference page and
+ a brief description based on the classes' \l
+ {brief}{\\brief} texts.
+
+ For example:
+
+ \code
+ / *!
+ \module QtNetwork
+
+ \title QtNetwork Module
+
+ \brief The QtNetwork module offers classes that allow
+ you to write TCP/IP clients and servers.
+
+ The network module provides classes to make network
+ programming easier and portable. It offers both
+ high-level classes such as QHttp and QFtp that
+ implement specific application-level protocols, and
+ lower-level classes such as QTcpSocket, QTcpServer, and
+ QUdpSocket.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1><center>QtNetwork Module</center></h1>
+ \endraw
+
+ The QtNetwork module offers classes that allow you to
+ write TCP/IP clients and servers.\l {module
+ details}{More...}
+
+ \raw HTML
+ <p>
+ <table width="100%">
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td><b>
+ <a href="http://qt.nokia.com/doc/4.0/qabstractsocket.html">QAbstractSocket</a>
+ </b></td>
+ <td>
+ The base functionality common to all socket types
+ </td></tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td><b>
+ <a href="http://qt.nokia.com/doc/4.0/qftp.html">QFtp</a>
+ </b></td>
+ <td>
+ Implementation of the FTP protocol
+ </td></tr>
+
+ <tr valign="top" bgcolor="#d0d0d0">
+ <td>...</td>
+ <td>...</td>
+ </tr>
+ </table>
+
+ <p><hr /></p>
+ \endraw
+
+ \target module details
+
+ \raw HTML
+ <h2>Detailed Description</h2>
+
+ <p>
+ The QtNetwork module offers classes that allow you to
+ write TCP/IP clients and servers.
+ </p>
+
+ <p>
+ The network module provides classes to make network
+ programming easier and portable. It offers both
+ high-level classes such as QHttp and QFtp that
+ implement specific application-level protocols, and
+ lower-level classes such as QTcpSocket, QTcpServer, and
+ QUdpSocket.
+ </p>
+ \endraw
+
+ ...
+
+ \endquotation
+
+ in qtnetwork.html.
+
+ See also \l {inmodule}{\\inmodule}
+
+ \row
+ \o \bold \\namespace \target namespace
+ \o \bold {The \\namespace command allows you to document a C++
+ namespace.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ QDoc will generate the same additional links and
+ documentation for all the members of the namespace as it
+ does for \l {framework}{classes}. The documentation for
+ the specified namespace is put in <lower-case>\i
+ {namespace}.html.
+
+ For example:
+
+ \code
+ / *!
+ \namespace Qt
+
+ \brief The Qt namespace contains miscellaneous
+ identifiers used throughout the Qt library.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <center><h1>Qt Namespace Reference</h1></center>
+ <p>The Qt namespace contains miscellaneous
+ identifiers used throughout the Qt library.
+ <a href="13-qdoc-commands-topical.html#name">More...</a>
+ </p>
+
+ <pre>#include &lt;Qt&gt;</pre>
+ <ul>
+ <li>
+ <a href="http://qt.nokia.com/doc/4.0/qt-qt3.html">
+ Qt 3 support members</a></li>
+ </ul>
+
+
+ <h3>Types</h3>
+ <ul>
+ <li>flags
+ <a href="http://qt.nokia.com/doc/4.0/qt.html#AlignmentFlag-enum">Alignment</a></b></li>
+ <li>...</li></ul>
+ <hr />
+ \endraw
+
+ \target name
+
+ \raw HTML
+ <h2>Detailed Description</h2>
+ <p>The Qt namespace contains miscellaneous identifiers
+ used throughout the Qt library.</p>
+ \endraw
+
+ ...
+ \endquotation
+
+ in qt.html.
+
+ \row
+ \o \bold \\page \target page
+ \o \bold {The \\page command allows you to create a stand-alone
+ documentation page.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ The page's title can be set using the \l {title}{\\title}
+ command. For example:
+
+ \code
+ / *!
+ \page aboutqt.html
+
+ \title About Qt
+
+ Qt by Trolltech is a C++ toolkit for cross-platform GUI
+ application development. Qt provides single-source
+ portability across Microsoft Windows, Mac OS X, Linux,
+ and all major commercial Unix variants. (A version of
+ Qt 4 for embedded Linux will be available in
+ August/September 2005.)
+
+ Qt provides application developers with all the
+ functionality needed to build applications with
+ state-of-the-art graphical user interfaces. Qt is fully
+ object-oriented, easily extensible, and allows true
+ component programming.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered in its own HTML file: \l{About Qt}.
+
+ \row
+ \o \bold {\\externalpage} \target externalpage
+ \o \bold {The \\externalpage command gives a title to
+ an external URL.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ For example:
+
+ \code
+ / *!
+ \externalpage http://www.trolltech.com/products/embedded/index.html
+ \title Qtopia Core
+ * /
+ \endcode
+
+ The QDoc comment above allows you to link to the Qtopia
+ Core webpage by simply linking to the given title. For
+ example:
+
+ \code
+ / *!
+ The broad scope of the \l {Qtopia Core} API enables it to
+ be used across a wide variety of development projects.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ The broad scope of the \l
+ {http://www.trolltech.com/products/embedded/index.html}{Qtopia
+ Core} API enables it to be used across a wide variety
+ of development projects.
+ \endquotation
+
+ To achieve the same result without using the
+ \\externalpage command, you would have to hard code the
+ adress into your documentation:
+
+ \code
+ / *!
+ The broad scope of the \l
+ {http://www.trolltech.com/products/embedded/index.html}{Qtopia
+ Core} API enables it to be used across a wide variety
+ of development projects.
+ * /
+ \endcode
+
+ The \\externalpage command makes it easier to maintain the
+ documentation. If the adress changes, you only need to change the
+ argument of the \\externalpage command.
+
+ \row
+ \o \bold \\property \target property
+ \o \bold {The \\property command allows you to document a Qt
+ property.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ A property is defined using the Q_PROPERTY() macro. The
+ macro takes as arguments the property's name and its set,
+ reset and get functions. For example:
+
+ \code
+ Q_PROPERTY(QString state READ state WRITE setState)
+ \endcode
+
+ The set, reset and get functions don't need to be
+ documented, documenting the property is sufficient. QDoc
+ will generate a list of the access function that will
+ appear in the property documentation which in turn will be
+ located in the documentation of the class that defines the
+ property.
+
+ The \\property command is typically accompanied with a \l
+ {brief}{\\brief} command. In the case of a property, the
+ \l {brief}{\\brief} command's argument is a sentence
+ fragment that will be included in a one-sentence
+ description of the property generated by QDoc. The command
+ follows the same rules for the \l {brief
+ property}{description} as the \l {variable}{\\variable}
+ command.
+
+ For example:
+
+ \code
+ / *!
+ \property QPushButton::flat
+ \brief whether the border is disabled
+
+ This property's default is false.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>flat : bool</h3>
+ \endraw
+
+ This property holds whether the border is disabled.
+
+ This property's default is false.
+
+ Access functions:
+
+ \list
+ \o \bold { bool isFlat () const}
+ \o \bold { void setFlat ( bool )}
+ \endlist
+
+ \endquotation
+
+ in qpushbutton.html. And
+
+ \code
+ / *!
+ \property QWidget::width
+ \brief the width of the widget excluding any window frame
+
+ See the \l {Window Geometry} documentation for an
+ overview of window geometry.
+
+ \sa geometry, height, size
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>width : const int</h3>
+ \endraw
+
+ This property holds the width of the widget excluding
+ any window frame.
+
+ See the \l {Window Geometry} documentation for an
+ overview of window geometry.
+
+ Access functions:
+
+ \list
+ \o \bold { int width () const}
+ \endlist
+
+ See also \l{QWidget::geometry}{geometry},
+ \l{QWidget::height}{height}, and \l{QWidget::size}{size}.
+ \endquotation
+
+ in qwidget.html.
+
+ \row
+ \o \bold \\service \target service
+
+ \o \bold {The \\service command tells QDoc that a class is a
+ service class and specifies its alias, i.e. the associated
+ service's name.}
+
+ The command takes two arguments, the service class's name
+ and the associated alias. For example:
+
+ \code
+ / *!
+ \service TimeService Time
+ ...
+ * /
+ class TimeService : public QCopObjectService
+ {
+ ...
+ }
+ \endcode
+
+ See also \l {class}{\\class} and \l
+ {generatelist}{\\generatelist}.
+
+ \row
+ \o \bold \\typedef \target typedef
+ \o \bold {The \\typedef command allows you to document a C++ type
+ definition.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ The documentation will be located in the associated class,
+ header file or namespace documentation. When documenting a
+ global type definition, the \\typedef command must be
+ accompanied with a \l {relates}{\\relates} command. For
+ example:
+
+ \code
+ / *!
+ \typedef QObjectList
+ \relates QObject
+
+ Synonym for QList<QObject>.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>typedef QObjectList</h3>
+ \endraw
+
+ Synonym for QList<QObject>.
+ \endquotation
+
+ in qobject.html. Another, although more rare, example is
+
+ \code
+ / *!
+ \typedef QMsgHandler
+ \relates QtGlobal
+
+ This is a typedef for a pointer to a function with the
+ following signature:
+
+ \code
+ void myMsgHandler(QtMsgType, const char *);
+ \ endcode
+
+ \sa QtMsgType, qInstallMsgHandler()
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>typedef QtMsgHandler</h3>
+ \endraw
+
+ This is a typedef for a pointer to a function with the
+ following signature:
+
+ \raw HTML
+ <tt>
+ <pre> void myMsgHandler(QtMsgType, const char *);</pre>
+ </tt>
+ \endraw
+
+ See also QtMsgType and qInstallMsgHandler().
+
+ \endquotation
+
+ in qtglobal.html. Other type definitions are located in the
+ documentation of the class that defines it, for example:
+
+ \code
+ / *!
+ \typedef QLinkedList::Iterator
+
+ Qt-style synonym for QList::iterator.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>typedef QLinkedList::Iterator</h3>
+ \endraw
+
+ Qt-style synonym for QList::iterator.
+ \endquotation
+
+ in qlinkedlist.html.
+
+ \row
+ \o \bold \\variable \target variable
+ \o \bold {The \\variable command allows you to document a
+ member variable or a constant.}
+
+ The command follows \l {topical argument}{the general
+ topical command convention} for the argument.
+
+ The \\variable command is typically followed by a \l
+ {brief}{\\brief} command; QDoc will generate the
+ documentation for the variable based on the brief
+ description. The command follows the same rules for the \l
+ {brief property}{description} as the \l
+ {property}{\\property} command.
+
+ The documentation will be located in the in the associated
+ class, header file or namespace documentation.
+
+ In case of a member variable:
+
+ \code
+ / *!
+ \variable QStyleOption::palette
+ \brief the palette that should be used when painting
+ the control
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>
+ <a href="http://qt.nokia.com/doc/4.0/qpalette.html">
+ QPalette
+ </a>
+ QStyleOption::palette
+ </h3>
+ \endraw
+
+ This variable holds the palette that should be used
+ when painting the control.
+ \endquotation
+
+ in qstyleoption.html.
+
+ But you can also use the \\variable command to document
+ constants like for example the \c Type and \c UserType
+ constants in the QTreeWidgetItem class:
+
+ \code
+ enum { Type = 0, UserType = 1000 };
+ \endcode
+
+ Then
+
+ \code
+ / *!
+ \variable QTreeWidgetItem::Type
+
+ The default type for tree widget items.
+
+ \sa UserType, type()
+ * /
+ \endcode
+
+ and
+
+ \code
+ / *!
+ \variable QTreeWidgetItem::UserType
+
+ The minimum value for custom types. Values below
+ UserType are reserved by Qt.
+
+ \sa Type, type()
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>
+ const int QTreeWidgetItem::Type
+ </h3>
+ \endraw
+
+ The default type for tree widget items.
+
+ See also \l {QTreeWidgetItem::UserType}{UserType} and
+ \l {QTreeWidgetItem::type()}{type()}.
+
+ \raw HTML
+ <h3>
+ const int QTreeWidgetItem::UserType
+ </h3>
+ \endraw
+
+ The minimum value for custom types. Values below
+ UserType are reserved by Qt.
+
+ See also \l {QTreeWidgetItem::Type}{Type} and
+ \l{QTreeWidgetItem::type()}{type()}.
+
+ \endquotation
+
+ in qtreewidget.html.
+ \endtable
+*/
+
+/*!
+ \page 14-qdoc-commands-contextualcommands.html
+ \previouspage Topical Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Navigation Commands
+
+ \title Contextual Commands
+
+ The contextual commands provide QDoc with information, that it
+ wouldn't figure out otherwise, about the documented object. For
+ example whether a class is thread-safe or not.
+
+ These commands can appear anywhere within a QDoc comment.
+
+ \section1 Alphabetical List
+
+ \l {16-qdoc-commands-status.html#compat}{\\compat},
+ \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage},
+ \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage},
+ \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup},
+ \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule},
+ \l {16-qdoc-commands-status.html#internal}{\\internal},
+ \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass},
+ \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage},
+ \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant},
+ \l {16-qdoc-commands-status.html#obsolete}{\\obsolete},
+ \l {18-qdoc-commands-relating.html#overload}{\\overload},
+ \l {16-qdoc-commands-status.html#preliminary}{\\preliminary},
+ \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage},
+ \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant},
+ \l {18-qdoc-commands-relating.html#reimp}{\\reimp},
+ \l {18-qdoc-commands-relating.html#relates}{\\relates},
+ \l {15-qdoc-commands-navigation.html#startpage}{\\startpage},
+ \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe},
+ \l {20-qdoc-commands-title.html#title}{\\title}
+
+ \section1 Categories
+ \list
+ \o \l {Navigation Commands}
+ \o \l {Status Commands}
+ \o \l {Thread Support Commands}
+ \o \l {Relating Commands}
+ \o \l {Grouping Commands}
+ \o \l {Title Commands}
+ \endlist
+*/
+
+/*!
+ \page 15-qdoc-commands-navigation.html
+ \previouspage Contextual Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Status Commands
+
+ \title Navigation Commands
+
+ The navigation commands allow you to link the pages of a multipage
+ document together. They provide the components of a navigation bar
+ at the top and bottom of the document. They also provide browser
+ and search engine support.
+
+ \section1 Alphabetical List
+
+ \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage},
+ \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage},
+ \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage},
+ \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage},
+ \l {15-qdoc-commands-navigation.html#startpage}{\\startpage}
+
+ \section1 General Description
+
+ The QDoc comments below shows a typical example using the
+ navigation commands.
+
+ \code
+ / *!
+ \page basicqt.html
+ \contentspage {Basic Qt}{Contents}
+ \nextpage Getting Started
+
+ \indexpage Index
+ \startpage Basic Qt
+
+ \title Basic Qt
+
+ The Qt toolkit is a C++ class library and a set of tools for
+ building multiplatform GUI programs using a "write once,
+ compile anywhere approach".
+
+ Table of contents:
+
+ \list
+ \o \l {Getting Started}
+ \o \l {Creating Dialogs}
+ \o \l {Creating Main Windows}
+ \endlist
+ * /
+
+ / *!
+ \page gettingstarted.html
+ \previouspage Basic Qt
+ \contentspage {Basic Qt}{Contents}
+ \nextpage Creating Dialogs
+
+ \indexpage Index
+ \startpage Basic Qt
+
+ \title Getting Started
+
+ This chapter shows how to combine basic C++ with the
+ functionality provided by Qt to create a few small graphical
+ interface (GUI) applications.
+ * /
+
+ / *!
+ \page creatingdialogs.html
+ \previouspage Getting Started
+ \contentspage {Basic Qt}{Contents}
+
+ \indexpage Index
+ \startpage Basic Qt
+
+ \title Creating Dialogs
+
+ This chapter will teach you how to create dialog boxes using Qt.
+ * /
+
+ / *!
+ \page index.html
+
+ \indexpage Index
+ \startpage Basic Qt
+
+ \title Index
+
+ \list
+ \o \l {Basic Qt}
+ \o \l {Creating Dialogs}
+ \o \l {Getting Started}
+ \endlist
+ * /
+ \endcode
+
+ The second page of this multipage document, "Getting Started",
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <table border="0" cellpadding="0" cellspacing="5" width="100%">
+
+ <tr>
+ <p>
+ [Previous: <a href="15-qdoc-commands-navigation.html#deadlink">
+ Basic Qt</a>]
+ [<a href="15-qdoc-commands-navigation.html#deadlink">Contents</a>]
+ [Next: <a href="15-qdoc-commands-navigation.html#deadlink">
+ Creating Dialogs</a>]
+ </p>
+
+ <h1 align="center">Getting Started<br /></h1>
+
+ <p>
+ This chapter shows how to combine basic C++ with the
+ functionality provided by Qt to create a few small graphical
+ interface (GUI) applications.
+ </p>
+
+ <p>
+ [Previous: <a href="15-qdoc-commands-navigation.html#deadlink">
+ Basic Qt</a>]
+ [<a href="15-qdoc-commands-navigation.html#deadlink">Contents</a>]
+ [Next: <a href="15-qdoc-commands-navigation.html#deadlink">
+ Creating Dialogs</a>]
+ </p>
+
+ </table>
+ \endraw
+ \endquotation
+
+ in creatingdialogs.html.
+
+ In addition, the \l {indexpage}{\\indexpage} and \l
+ {startpage}{\\startpage} commands specifies links to the page's
+ index page and start page. These links are used by browsers and
+ search engines.
+
+ The index page is typically an alphabetical list of the document's
+ titles and topics, while the start page is the page considered by
+ the author to be the starting point of a multipage document.
+
+ The links are included in the generated HTML source code but has
+ no visual effect on the documentation:
+
+ \code
+ <head>
+ ...
+ <link rel="index" href="index.html" />
+ <link rel="start" href="basicqt.html" />
+ ...
+ </head>
+ \endcode
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\previouspage \target previouspage
+ \o \bold {The \\previouspage command links the current page
+ to the previous one in an ordered series of documents}.
+
+ The command has two arguments, each enclosed by curly
+ braces: The first is the link target, i.e. the title of the
+ previous page, the second is the link text. If the page's
+ title is equivalent to the link text, the second argument
+ can be omitted.
+
+ The command must stand alone on its own line.
+
+ In the end, the link is rendered at the top and bottom of
+ the current page. For an example, see the \l {General
+ Description} section.
+
+ \row
+ \o \bold \\nextpage \target nextpage
+ \o \bold {The \\nextpage command links the current
+ page to the next page in an ordered series of documents}.
+
+ The command follows the same syntax and argument convention
+ as the \l {previouspage}{\\previouspage} command.
+
+ For an example, see the \l {General Description} section.
+
+ \row
+ \o \bold \\startpage \target startpage
+ \o \bold {The \\startpage command specifies the first document
+ in a collection of documents.}
+
+ The command must stand alone on its own line, and its
+ unique argument is the title of the first document.
+
+ QDoc will generate a link to the specified document which
+ is included in the HTML file but has no visual effect on
+ the documentation. The generated link type tells browsers
+ and search engines which document is considered by the
+ author to be the starting point of the collection.
+
+ For an example, see the \l {General Description} section.
+
+ \row
+ \o \bold \\contentspage \target contentspage
+ \o \bold {The \\contentspage command links the current
+ page to a contents page}.
+
+ The command follows the same syntax and argument convention
+ as the \l {previouspage}{\\previouspage} command.
+
+ For an example, see the \l {General Description} section.
+
+ \row
+ \o \bold \\indexpage \target indexpage
+ \o \bold {The \\indexpage command specifies a document providing
+ an index for the current document}.
+
+ The command must stand alone on its own line, and its
+ unique argument is the title of the index document.
+
+ QDoc will generate a link to the specified document which
+ is included in the HTML file but has no visual effect on
+ the documentation. The generated link type tells browsers
+ and search engines which document is considered by the
+ author to be the index page for the current document.
+
+ For an example, see the \l {General Description} section.
+
+ \endtable
+*/
+
+/*!
+ \page 16-qdoc-commands-status.html
+ \previouspage Navigation Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Thread Support Commands
+
+ \title Status Commands
+
+ The usage commands can indicate whether a documented object is
+ under development, becoming obsolete, provided for compatibility
+ reasons or simply not part of the public interface. They can
+ describe the history of minor versions. And they can also describe
+ a documented object's ability to handle multithreaded programming.
+
+ \section1 Alphabetical List
+
+ \l {16-qdoc-commands-status.html#compat}{\\compat},
+ \l {16-qdoc-commands-status.html#internal}{\\internal},
+ \l {16-qdoc-commands-status.html#obsolete}{\\obsolete},
+ \l {16-qdoc-commands-status.html#preliminary}{\\preliminary},
+ \l {16-qdoc-commands-status.html#since}{\\since}
+
+ \section1 Command Description
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\preliminary \target preliminary
+ \o \bold {The \\preliminary command indicates that the
+ referenced function is under development.}
+
+ The command must stand on its own line.
+
+ The \\preliminary command expands to a notification in the
+ function documentation, and marks the function as
+ preliminary when it appears in lists. For example:
+
+ \code
+ / *!
+ \preliminary
+
+ Returns information about the joining properties of the
+ character (needed for certain languages such as
+ Arabic).
+ * /
+ QChar::Joining QChar::joining() const
+ {
+ return ::joining(*this);
+ }
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>
+ <a href="http://qt.nokia.com/doc/4.0/qchar.html#Joining-enum">Joining</a>
+ QChar::joining () const</h3>
+ \endraw
+
+ \bold {This function is under development and
+ is subject to change.}
+
+ Returns information about the joining properties of the
+ character (needed for certain languages such as
+ Arabic).
+ \endquotation
+
+ And the function's entry in QChar's list of functions will
+ be rendered as
+
+ \quotation
+ \list
+ \o ...
+ \o Joining
+ \l {http://qt.nokia.com/doc/4.0/qchar.html#Joining-enum}
+ {joining}()
+ const \c (preliminary)
+ \o ...
+ \endlist
+ \endquotation
+
+ \row
+ \o \bold \\obsolete \target obsolete
+ \o \bold {The \\obsolete command indicates that the referenced
+ function no longer should be used in new code;
+ there is no guarantee for how long it will remain in
+ the library.}
+
+ The command must stand on its own line.
+
+ When generating the reference documentation for a class,
+ QDoc will create and link to a separate page documenting
+ its obsolete functions. Usually an equivalent function is
+ provided as an alternative.
+
+ For example:
+
+ \code
+ / *!
+ \fn MyClass::MyObsoleteFunction
+ \obsolete
+
+ Use MyNewFunction() instead.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1>Obsolete Members for MyClass</h1>
+ \endraw
+
+ \bold {The following class members are obsolete.} They
+ are provided to keep old source code working. We
+ strongly advise against using them in new code.
+
+ ...
+
+ \list
+ \o void MyObsoleteFunction() \c (obsolete)
+ \o ...
+ \endlist
+
+ \raw HTML
+ <hr />
+ <h2>Member Function Documentation</h2>
+ <h3>void MyObsoleteFunction ()</h3>
+ <p>Use MyNewFunction() instead.</p>
+ \endraw
+
+ ...
+ \endquotation
+
+ in myclass-obsolete.html
+
+
+ \row
+ \o \bold \\compat \target compat
+ \o \bold {The \\compat command indicates that the referenced class
+ or function is part of the support library provided to keep
+ old source code working.}
+
+ The command must stand on its own line.
+
+ Usually an equivalent function or class is provided as an
+ alternative.
+
+ If the command is used within the documentation of a class,
+ the command expands to a warning that the referenced class
+ is part of the support library. The warning is located on
+ top of the associated documentation. For example:
+
+ \code
+ / *!
+ \class MyQt3SupportClass
+ \compat
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \bold {This class is part of the Qt 3 support
+ library.} It is provided to keep old source code
+ working. We strongly advise against using it in new
+ code. See the \l
+ {http://qt.nokia.com/doc/4.0/porting4.html}{Porting
+ Guide} for more information.
+ \endquotation
+
+ on the top of the MyQt3SupportClass class reference.
+
+ If the command is used when documenting a function, QDoc
+ will create and link to a separate page documenting Qt 3
+ support members when generating the reference documentation
+ for the associated class. For example:
+
+ \code
+ / *!
+ \fn MyClass::MyQt3SupportMemberFunction
+ \compat
+
+ Use MyNewFunction() instead.
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1>Qt 3 Support Members for MyClass</h1>
+ \endraw
+
+ \bold {The following class members are part of the Qt
+ 3 support layer.} They are provided to help you port
+ old code to Qt 4. We advise against using them in new
+ code.
+
+ ...
+
+ \list
+ \o void MyQt3SupportMemberFunction()
+ \o ...
+ \endlist
+
+ \raw HTML
+ <hr />
+ <h2>Member Function Documentation</h2>
+ <h3>void MyQt3SupportMemberFunction ()</h3>
+ <p>Use MyNewFunction() instead.</p>
+ \endraw
+
+ ...
+ \endquotation
+
+ in myclass-qt3.html
+
+
+ \row
+ \o \bold \\internal \target internal
+ \o \bold {The \\internal command indicates that the referenced
+ function is not part of the public interface.}
+
+ The command must stand on its own line.
+
+ QDoc ignores the documentation as well as the documented
+ item, when generating the associated class reference
+ documenation. For example:
+
+ \code
+ / *!
+ \internal
+
+ Tries to find the decimal separator. If it can't find
+ it and the thousand delimiter is != '.' it will try to
+ find a '.';
+ * /
+ int QDoubleSpinBoxPrivate::findDelimiter
+ (const QString &str, int index) const
+ {
+ int dotindex = str.indexOf(delimiter, index);
+ if (dotindex == -1 && thousand != dot && delimiter != dot)
+ dotindex = str.indexOf(dot, index);
+ return dotindex;
+ }
+ \endcode
+
+ in qspinbox.cpp, will not be rendered at all.
+
+ \row
+ \o \bold \\since \target since
+ \o \bold {The \\since command tells in which minor release
+ the associated functionality was added.}
+
+ For example:
+
+ \code
+ / *!
+ \since 4.1
+
+ Returns an icon for \a standardIcon.
+
+ ...
+
+ \sa standardIconImplementation(), standardPixmap()
+ * /
+ QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const
+ {
+ }
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3>QIcon QStyle::standardIcon(StandardPixmap standardIcon, const QStyleOption *option, const QWidget *widget) const</h3>
+ \endraw
+
+ This function was introduced in Qt version 4.1
+
+ Returns an icon for \a standardIcon.
+
+ ...
+
+ See also \l
+ {QStyle::standardIconImplementation()}{standardIconImplementation()}
+ and \l {QStyle::standardPixmap()}{standardPixmap()}.
+ \endquotation
+
+ QDoc generates the "Qt" reference from the \l
+ {25-qdoc-configuration-derivedprojects.html#project}{\c
+ project} configuration variable. For that reason this
+ reference will change according to the current
+ documentation project.
+
+ See also \l
+ {25-qdoc-configuration-derivedprojects.html#project}{\c
+ project}.
+
+ \endtable
+*/
+
+/*!
+ \page 17-qdoc-commands-thread.html
+ \previouspage Status Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Relating Commands
+
+ \title Thread Support Commands
+
+ The thread support commands specify the level of support for
+ multithreaded programming of a class or function.
+
+ \section1 Alphabetical List
+
+ \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant},
+ \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant},
+ \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe}
+
+ \section1 General Description
+
+ There are three levels of support for multithreaded programming of
+ a class or function: \c threadsafe, \c reentrant and \c
+ nonreentrant.
+
+ The default is \c nonreentrant which means that the associated
+ class or function cannot be called by multiple threads. \c
+ Reentrant and \c threadsafe are levels primarily used for classes.
+
+ \c Reentrant means that all the functions in the referenced class
+ can be called simultaneously by multiple threads, provided that
+ each invocation of the functions reference unique data. While \c
+ threadsafe means that all the functions in the referenced class
+ can be called simultaneously by multiple threads even when each
+ invocation references shared data.
+
+ When a class is declared \c reentrant or \c threadsafe, using the
+ \l {reentrant}{\\reentrant} and \l {threadsafe}{\\threadsafe}
+ commands respectively, functions in the referenced class can be
+ declared \c nonreentrant, using the \l
+ {nonreentrant}{\\nonreentrant} command, excluding the functions
+ from the general view.
+
+ For example:
+
+ \code
+ / *!
+ \class QLocale
+ \brief The QLocale class converts between numbers and their
+ string representations in various languages.
+
+ \reentrant
+ \ingroup i18n
+ \ingroup text
+ \mainclass
+
+ QLocale is initialized with a language/country pair in its
+ constructor and offers number-to-string and string-to-number
+ conversion functions similar to those in QString.
+
+ ...
+ * /
+
+ / *!
+ \nonreentrant
+
+ Sets the global default locale to \a locale. These values are
+ used when a QLocale object is constructed with no
+ arguments. If this function is not called, the system's locale
+ is used.
+
+ \warning In a multithreaded application, the default locale
+ should be set at application startup, before any non-GUI
+ threads are created.
+
+ \sa system() c()
+ * /
+ void QLocale::setDefault(const QLocale &locale)
+ {
+ default_d = locale.d;
+ }
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1><center>QLocale Class Reference</center></h1>
+ \endraw
+
+ The QLocale class converts between numbers and their string
+ representations in various languages. More...
+
+ \code
+ #include <QLocale>
+ \endcode
+
+ \bold {Note:} All the functions in this class are \l
+ {threads.html#reentrant}{reentrant}, except \l
+ {QLocale::setDefault()}{setDefault()}.
+
+ ...
+
+ \raw HTML
+ <hr />
+ <h2>Member Type Documentation</h2>
+ \endraw
+
+ ...
+
+ \raw HTML
+ <h3>void QLocale::setDefault ( const QLocale & locale ) </h3>
+ \endraw
+
+ Sets the global default locale to locale. These values are
+ used when a QLocale object is constructed with no
+ arguments. If this function is not called, the system's locale
+ is used.
+
+ \warning In a multithreaded application, the default locale
+ should be set at application startup, before any non-GUI
+ threads are created.
+
+ \warning This function is not reentrant.
+
+ See also \l {QLocale::system()}{system()} and \l
+ {QLocale::c()}{c()}.
+
+ ...
+ \endquotation
+
+ As shown above, QDoc generates a notification when a class is
+ declared reentrant, and lists the exceptions (the declared
+ nonreentrant functions). A link to the general documentation on \l
+ {threads.html#reentrant}{reentrancy and thread-safety} is
+ included. In addition a warning, "\bold Warning: This function is
+ not reentrant.", is generated in the nonreentrant functions'
+ documentation.
+
+ QDoc will generate the same notification and warnings when a class
+ is declared threadsafe.
+
+ For more information see the general documentation on \l
+ {threads.html#reentrant}{reentrancy and thread-safety}.
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\threadsafe \target threadsafe
+ \o \bold {The \\threadsafe command indicates that the
+ associated class or function can be called simultaneously by
+ multiple threads even when each invocation references
+ shared data.}
+
+ The command must stand on its own line.
+
+ The generated documentation resulting from using the
+ \\threadsafe command is similar to the result of using the
+ \l {reentrant}{\\reentrant} command. For an example, see
+ the \l {General Description} section.
+
+ See also \l{reentrant}{\\reentrant} and
+ \l{nonreentrant}{\\nonreentrant}.
+
+ \row
+ \o \bold \\reentrant \target reentrant
+ \o \bold {The \\reentrant command indicates that the associated
+ class or function can be called simultaneously
+ by multiple threads, provided that each invocation of the
+ functions reference unique data.}
+
+ The command must stand on its own line.
+
+ For an example, see the \l {General Description} section.
+
+ See also \l{nonreentrant}{\\nonreentrant} and
+ \l{threadsafe}{\\threadsafe}.
+
+ \row
+ \o \bold \\nonreentrant \target nonreentrant
+ \o \bold {The \\nonreentrant command indicates that the
+ associated class or function cannot be called by
+ multiple threads.}
+
+ The command must stand on its own line.
+
+ For an example, see the \l {General Description} section.
+
+ See also \l{reentrant}{\\reentrant} and
+ \l{threadsafe}{\\threadsafe}.
+
+ \endtable
+*/
+
+/*!
+ \page 18-qdoc-commands-relating.html
+ \previouspage Thread Support Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Grouping Commands
+
+ \title Relating Commands
+
+ The relation commands discribe how the documented object relates
+ to its context: Whether it is an overloaded function, a
+ reimplemented function or a global function related to a specified
+ class or header file.
+
+ \section1 Alphabetical List
+
+ \l {18-qdoc-commands-relating.html#overload}{\\overload},
+ \l {18-qdoc-commands-relating.html#reimp}{\\reimp},
+ \l {18-qdoc-commands-relating.html#relates}{\\relates},
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\overload \target overload
+ \o \bold {The \\overload command indicates that the
+ function is a secondary overload of its name.}
+
+ The command must stand on its own line.
+
+ For any overloaded function (except constructors), QDoc
+ expects one primary version of the function and all the
+ the overloads marked with the \bold{\\overload command}.
+ The primary version should be fully documented. Each
+ overload can have whatever extra documentation you want
+ to add for just that overload.
+
+ From Qt 4.5, you can include the function name plus '()'
+ as a parameter to the \bold{\\overload} command, which
+ will include a standard \i{This function overloads...}
+ line of text with a link to the documentation for the
+ primary version of the function.
+
+ For example:
+
+ \code
+ / *!
+ \overload addAction()
+
+ This convenience function creates a new action with an
+ \a icon and some \a text. The function adds the newly
+ created action to the menu's list of actions, and
+ returns it.
+
+ \sa QWidget::addAction()
+ * /
+ QAction *QMenu::addAction(const QIcon &icon, const QString &text)
+ {
+ QAction *ret = new QAction(icon, text, this);
+ addAction(ret);
+ return ret;
+ }
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h3><a href="http://qt.nokia.com/doc/4.0/qaction.html">QAction</a>
+ * QMenu::addAction ( const QIcon & <i>icon</i>,
+ const QString & <i>text</i> )
+ </h3>
+ \endraw
+
+ This function overloads \l {http://qt.nokia.com/doc/4.0/qwidget.html#addAction}{addAction()}
+
+ This convenience function creates a new action with an
+ \i icon and some \i text. The function adds the newly
+ created action to the menu's list of actions, and
+ returns it.
+
+ See also
+ \l {http://qt.nokia.com/doc/4.0/qwidget.html#addAction}
+ {QWidget::addAction}().
+ \endquotation
+
+ If you don't include the function name with the
+ \bold{\\overlaod} command, then instead of the "This
+ function overloads..." line with the link to the
+ documentation for the primary version, you get the old
+ standard line:
+
+ \quotation
+ This is an overloaded member function, provided for
+ convenience.
+ \endquotation.
+
+ \row
+ \o \bold \\reimp \target reimp
+ \o \bold {The \\reimp command indicates that the
+ referenced function is a reimplementation of a virtual function,
+ where the reimplementation has no effect on the interface.}
+
+ The command must stand on its own line.
+
+ QDoc will omit the reimplemented function from the class
+ reference. For example:
+
+ \code
+ / *!
+ \reimp
+ * /
+ void QToolButton::nextCheckState()
+ {
+ Q_D(QToolButton);
+ if (!d->defaultAction)
+ QAbstractButton::nextCheckState();
+ else
+ d->defaultAction->trigger();
+ }
+ \endcode
+
+ will not be rendered at all; only a link to the inherited
+ QAbstractButton::nextCheckState() will appear in the
+ documentation.
+
+ \row
+ \o \bold \\relates \target relates
+ \o \bold {The \\relates command attaches the documentation of
+ a global function to that of a related class or header file.}
+
+ The command's argument is a class name, an the command (and
+ its argument) must stand on its own line.
+
+ \code
+ / *!
+ \relates QChar
+
+ Reads a char from the stream \a in into char \a chr.
+
+ \sa {Format of the QDataStream operators}
+ * /
+ QDataStream &operator>>(QDataStream &in, QChar &chr)
+ {
+ quint16 u;
+ in >> u;
+ chr.unicode() = ushort(u);
+ return in;
+ }
+ \endcode
+
+ will be rendered with the QChar documentation.
+
+ \endtable
+*/
+
+/*!
+ \page 19-qdoc-commands-grouping.html
+ \previouspage Relating Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Title Commands
+
+ \title Grouping Commands
+
+ The grouping commands relate classes to defined groups and
+ modules. The groups are used when generating lists of related
+ classes in the documentation, while the modules are elements of
+ Qt's structure.
+
+ \section1 Alphabetical List
+
+ \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup},
+ \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule},
+ \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass},
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\mainclass \target mainclass
+ \o \bold {The \\mainclass command relates the documented class to
+ a group called mainclasses.}
+
+ The command must stand on its own line.
+
+ For example:
+
+ \code
+ / *!
+ \class QWidget qwidget.h
+ \brief The QWidget class is the base class of
+ all user interface objects.
+
+ \mainclass
+
+ ...
+ * /
+ \endcode
+
+ will ensure that the QWidget class is included in the \c
+ mainclasses group, which means, for example, that the class
+ will appear on the list created by calling the \l
+ {generatelist}{\\generatelist} command with the \c
+ mainclasses argument:
+
+ \l http://qt.nokia.com/doc/4.0/mainclasses.html
+
+ See also \l {generatelist}{\\generatelist}.
+
+ \row
+ \o \bold \\ingroup \target ingroup
+
+ \o \bold {The \\ingroup command indicates that the given
+ overview or documented class belongs to a certain group of
+ related docmentation.}
+
+ A class or overview may belong to many groups.
+
+ The \\ingroup command's argument is a group name, but note
+ that the command considers the rest of the line as part of
+ its argument. Make sure that the group name is followed by
+ a linebreak. For example:
+
+ \code
+ / *!
+ \class QDir
+ \brief The QDir class provides access to directory
+ structures and their contents.
+
+ \ingroup io
+ ...
+ * /
+ \endcode
+
+ will ensure that the QDir class is included in the \c io
+ group, which means, for example, that QDir will appear on
+ the list created by calling the \l {group}{\\group} command
+ with the \c io argument.
+
+ Note that to list overviews that are related to a given
+ group, you must generate the list exlicitly by using the \l
+ {generatelist}{\\generatelist} command with the \c related
+ argument.
+
+ See also \l {group}{\\group}.
+ \row
+ \o \bold \\inmodule \target inmodule
+ \o \bold {The \\inmodule command relates the documented class
+ to the module specified by the command's argument.}
+
+ For the basic classes in Qt, a class's module is determined
+ by its location, i.e. its directory. However, for
+ extensions, like ActiveQt and Qt Designer, a class needs to
+ be related to a module explicitly.
+
+ The command's argument is a module name, but note that the
+ command considers the rest of the line as part of its
+ argument. Make sure that the module name is followed by a
+ linebreak. For example:
+
+ \code
+ /*!
+ \class QDesignerTaskMenuExtension
+ \inmodule QtDesigner
+ * /
+ \endcode
+
+ will ensure that the QDesignerTaskMenuExtension class is
+ included in the \c QtDesigner module, which means, for
+ example, that the class will appear on the list created by
+ calling the \l {generatelist}{\\generatelist} command with
+ the \c {{classesbymodule QtDesigner}} argument.
+
+ See also \l {module}{\\module} and \l
+ {generatelist}{\\generatelist}.
+ \endtable
+*/
+
+/*!
+ \page 20-qdoc-commands-title.html
+ \previouspage Grouping Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage QDoc Configuration
+
+ \title Title Commands
+
+ In general a title command considers everything that follows it
+ until the first line break as its argument. If the title needs to
+ be spanned over several lines, make sure to end each line (except
+ the last one) with a backslash.
+
+ \section1 Alphabetical List
+
+ \l {20-qdoc-commands-title.html#title}{\\title},
+ \l {20-qdoc-commands-title.html#subtitle}{\\subtitle}
+
+ \section1 Command Descriptions
+
+ \table
+ \header
+ \o Command
+ \o Description
+
+ \row
+ \o \bold \\title \target title
+ \o \bold {The \\title command sets the title for a
+ documentation page, or allows you to override it.}
+
+ For example:
+
+ \code
+ / *!
+ \page signalandslots.html
+
+ \title Signals and Slots
+
+ Signals and slots are used for communication between
+ objects. The signals and slots mechanism is a central
+ feature of Qt and probably the part that differs most
+ from the features provided by other frameworks.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1><center>Signal and Slots</center></h1>
+ \endraw
+
+ Signals and slots are used for communication between
+ objects. The signals and slots mechanism is a central
+ feature of Qt and probably the part that differs most
+ from the features provided by other frameworks.
+
+ ...
+ \endquotation
+ See also \l {subtitle}{\\subtitle}.
+
+ \row
+ \o \bold \\subtitle \target subtitle
+ \o \bold {The \\subtitle command sets a subtitle for a
+ documentation page.}
+
+ For example:
+
+ \code
+ / *!
+ \page qtopiacore-overview.html
+
+ \title Qtopia Core
+ \subtitle Qt for Embedded Linux
+
+ Qt/Embedded, the embedded Linux port of Qt, is a
+ complete and self-contained C++ GUI and platform
+ development tool for Linux-based embedded development.
+
+ ...
+ * /
+ \endcode
+
+ will be rendered as
+
+ \quotation
+ \raw HTML
+ <h1><center>Qtopia Core</center></h1>
+ <h2><center>Qt for Embedded Linux</center></h2>
+ \endraw
+
+ Qt/Embedded, the embedded Linux port of Qt, is a
+ complete and self-contained C++ GUI and platform
+ development tool for Linux-based embedded development.
+
+ ...
+ \endquotation
+
+ See also \l {title}{\\title}.
+ \endtable
+*/
+
+/*!
+ \page 21-0-qdoc-configuration.html
+ \previouspage Title Commands
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage General Configuration Variables
+
+ \title QDoc Configuration
+
+ \tableofcontents
+
+ \list
+ \o \l {Supporting Derived Projects}
+ \o \l {QDoc Compatibility}
+ \endlist
+
+ When running QDoc to generate the documentation, you must specify
+ a configuration file on the command line:
+
+ \quotation
+ \bold {/currentdirectory$ qdoc3 my-documentation.qdocconf}
+ \endquotation
+
+ \section1 General Description
+
+ The configuration file is a list of entries of entries of the form
+ \i {"variable = value"}. Using the configuration variables, you
+ can define where QDoc should find the various source files, images
+ and examples, where to put generated documentation etc. The
+ configuration file can also contain directives like \c
+ include. For an example, see the \l minimum.qdocconf file.
+
+ In addition, you can use some particular configuration variables
+ to make QDoc support derived projects, i.e make the projects, for
+ example Qt Solutions, contain links to the online Qt
+ documentation. These variables are documented in the \l
+ {Supporting Derived projects} section. In this section you can
+ also find out how to use these variables to support your derived
+ projects.
+
+ If some of the variable keys have the same values, they can be set
+ at the same time. For example:
+
+ \code
+ {header, source}dirs = kernel
+ \endcode
+
+ is equivalent to
+
+ \code
+ headerdirs = kernel
+ sourcedirs = kernel
+ \endcode
+
+ A variable's value can be set using either '=' or '+='. The
+ difference is that '=' overrides any previously set value, while
+ '+=' only adds the value to the previously set ones.
+
+ In general, some of the variables accepts a list of strings as
+ their value, while others only accept a single string. If you
+ provide a variable of the latter type with several strings they
+ will simply be concatenated. The quotes around the value string
+ are optional. But applying them allows you to use special
+ characters like '=' and ' \" ' within the string. For example:
+
+ \code
+ HTML.postheader = "<a href=\"index.html\">Home</a>"
+ \endcode
+
+ If an entry spans many lines, use a backslash at the end of every
+ line but the last:
+
+ \code
+ sourcedirs = kernel \
+ tools \
+ widgets
+ \endcode
+
+ \section1 Configuration Variables
+
+ \section2 Alphabetical List
+
+ \l {22-qdoc-configuration-generalvariables.html#alias}{alias},
+ \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoredirectives}
+ {Cpp.ignoredirectives},
+ \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoretoken}
+ {Cpp.ignoretokens},
+ \l {22-qdoc-configuration-generalvariables.html#definesvariable}{defines},
+ \l {22-qdoc-configuration-generalvariables.html#edition}{edition},
+ \l {22-qdoc-configuration-generalvariables.html#exampledirs}{exampledirs},
+ \l {22-qdoc-configuration-generalvariables.html#examples}{examples},
+ \l {22-qdoc-configuration-generalvariables.html#examples.fileextensions}
+ {examples.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#extraimages}{extraimages},
+ \l {22-qdoc-configuration-generalvariables.html#falsehoods}{falsehoods},
+ \l {22-qdoc-configuration-generalvariables.html#headerdirs}{headerdirs},
+ \l {22-qdoc-configuration-generalvariables.html#headers}{headers},
+ \l {22-qdoc-configuration-generalvariables.html#headers.fileextensions}
+ {headers.fileextensions},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.footer}{HTML.footer},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.postheader}
+ {HTML.postheader},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.style}{HTML.style},
+ \l {22-qdoc-configuration-generalvariables.html#imagedirs}{imagedirs},
+ \l {22-qdoc-configuration-generalvariables.html#images}{images},
+ \l {22-qdoc-configuration-generalvariables.html#images.fileextensions}
+ {images.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#language}{language},
+ \l {22-qdoc-configuration-generalvariables.html#macro}{macro},
+ \l {22-qdoc-configuration-generalvariables.html#outputdir}{outputdir},
+ \l {22-qdoc-configuration-generalvariables.html#outputformats}
+ {outputformats},
+ \l {22-qdoc-configuration-generalvariables.html#slow}{slow},
+ \l {22-qdoc-configuration-generalvariables.html#sourcedirs}{sourcedirs},
+ \l {22-qdoc-configuration-generalvariables.html#sources}{sources},
+ \l {22-qdoc-configuration-generalvariables.html#sources.fileextensions}
+ {sources.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#spurious}{spurious},
+ \l {22-qdoc-configuration-generalvariables.html#tabsize}{tabsize},
+ \l {22-qdoc-configuration-generalvariables.html#version}{version},
+ \l {22-qdoc-configuration-generalvariables.html#versionsym}{versionsym}
+
+ \section2 Categories
+
+ \list
+ \o \l {General Configuration Variables}
+ \o \l {C++ Specific Configuration Variables}
+ \o \l {HTML Specific Configuration Variables}
+ \endlist
+
+ \section1 Configuration File Examples
+
+ \list
+ \o A minimum configuration file: \l minimum.qdocconf
+ \o The Qt configuration file: \l qt.qdocconf
+ \endlist
+*/
+
+/*!
+ \page 21-1-minimum-qdocconf.html
+ \previouspage QDoc Configuration
+ \contentspage QDoc Manual - Table of Contents
+
+ \title minimum.qdocconf
+
+ \quotefile examples/minimum.qdocconf
+*/
+
+/*!
+ \page 21-2-qt-qdocconf.html
+ \previouspage QDoc Configuration
+ \contentspage QDoc Manual - Table of Contents
+
+ \title qt.qdocconf
+
+ \quotefile files/qt.qdocconf
+*/
+
+/*!
+ \page 22-qdoc-configuration-generalvariables.html
+ \previouspage QDoc Configuration
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Creating Help Project Files
+
+ \title General Configuration Variables
+
+ With the general QDoc configuration variables, you can define
+ where QDoc will find the various source files it needs to generate
+ the documentation, as well as the directory to put the generated
+ documentation. You can also do some minor manipulation of QDoc
+ itself, controlling its output and processing behavior.
+
+ \section1 Alphabetical List
+
+ \l {22-qdoc-configuration-generalvariables.html#alias}{alias},
+ \l {22-qdoc-configuration-generalvariables.html#codeindent}{codeindent},
+ \l {22-qdoc-configuration-generalvariables.html#definesvariable}{defines},
+ \l {22-qdoc-configuration-generalvariables.html#edition}{edition},
+ \l {22-qdoc-configuration-generalvariables.html#exampledirs}{exampledirs},
+ \l {22-qdoc-configuration-generalvariables.html#examples}{examples},
+ \l {22-qdoc-configuration-generalvariables.html#examples.fileextensions}
+ {examples.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#extraimages}{extraimages},
+ \l {22-qdoc-configuration-generalvariables.html#falsehoods}{falsehoods},
+ \l {22-qdoc-configuration-generalvariables.html#generateindex}{generateindex},
+ \l {22-qdoc-configuration-generalvariables.html#headerdirs}{headerdirs},
+ \l {22-qdoc-configuration-generalvariables.html#headers}{headers},
+ \l {22-qdoc-configuration-generalvariables.html#headers.fileextensions}
+ {headers.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#imagedirs}{imagedirs},
+ \l {22-qdoc-configuration-generalvariables.html#images}{images},
+ \l {22-qdoc-configuration-generalvariables.html#images.fileextensions}
+ {images.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#language}{language},
+ \l {22-qdoc-configuration-generalvariables.html#macro}{macro},
+ \l {22-qdoc-configuration-generalvariables.html#outputdir}{outputdir},
+ \l {22-qdoc-configuration-generalvariables.html#outputformats}
+ {outputformats},
+ \l {22-qdoc-configuration-generalvariables.html#slow}{slow},
+ \l {22-qdoc-configuration-generalvariables.html#sourcedirs}{sourcedirs},
+ \l {22-qdoc-configuration-generalvariables.html#sources}{sources},
+ \l {22-qdoc-configuration-generalvariables.html#sources.fileextensions}
+ {sources.fileextensions},
+ \l {22-qdoc-configuration-generalvariables.html#spurious}{spurious},
+ \l {22-qdoc-configuration-generalvariables.html#tabsize}{tabsize},
+ \l {22-qdoc-configuration-generalvariables.html#tagfile}{tagfile},
+ \l {22-qdoc-configuration-generalvariables.html#version}{version},
+ \l {22-qdoc-configuration-generalvariables.html#versionsym}{versionsym}
+
+ \section1 Variable Descriptions
+
+ \table
+
+ \header
+ \o Variable
+ \o Description
+
+ \row
+ \o \bold alias \target alias
+ \o \bold {The \c alias variable renames a QDoc command.}
+
+ The general syntax is \tt {alias.\i{original-command-name}
+ = \i temporary-command-name}.
+
+ For example:
+
+ \code
+ alias.i = e
+ \endcode
+
+ renames the built-in command \\i (italics) to \\e.
+
+ The \c alias variable is often used for compatibility
+ reasons; for more information see the \l {QDoc
+ Compatibility}{compatibility section}.
+
+ See also \l macro.
+
+ \row
+ \o \bold codeindent \target codeindent
+ \o \bold {The \c codeindent variable specifies the level of
+ indentation that QDoc uses when writing code snippets.}
+
+ QDoc originally used a hard-coded value of four spaces for
+ code indentation to ensure that code snippets could be easily
+ distinguished from surrounding text. Since we can use
+ \l{HTML Specific Configuration Variables#HTML.stylesheets}{stylesheets} to
+ adjust the appearance of certain types of HTML elements, this
+ level of indentation is not always required.
+
+ \row
+ \o \bold defines \target definesvariable
+ \o \bold {The \c defines variable specifies the C++ preprocessor
+ symbols that QDoc will recognize and respond to.}
+
+ When a preprocessor symbol is specified using the \c
+ defines variable, you can also use the \l {if}{\\if}
+ command to enclose documentation that only will be included
+ if the preprocessor symbol is defined.
+
+ The values of the variable are regular expressions (see
+ QRegExp for details). By default, no symbol is defined,
+ meaning that code protected with #ifdef...#endif will be
+ ignored.
+
+ For example:
+
+ \code
+ defines = Q_QDOC \
+ QT_.*_SUPPORT \
+ QT_.*_LIB \
+ QT_COMPAT \
+ QT3_SUPPORT \
+ Q_WS_.* \
+ Q_OS_.* \
+ Q_BYTE_ORDER \
+ __cplusplus
+ \endcode
+
+ ensures that QDoc will process the code that requires these
+ symbols to be defined. For example:
+
+ \code
+ #ifdef Q_WS_WIN
+ HDC getDC() const;
+ void releaseDC(HDC) const;
+ #endif
+ \endcode
+
+ Since the Q_WS_.* regular expression (specified using the
+ \c defines variable) matches Q_WS_WIN, QDoc will process
+ the code within #ifdef and #endif in our example.
+
+ You can also define preprocessor symbols manually on the
+ command line using the -D option. For example:
+
+ \code
+ currentdirectory$ qdoc3 -Dconsoleedition qt.qdocconf
+ \endcode
+
+ In this case the -D option ensures that the \c
+ consoleedition preprocessor symbol is defined when QDoc
+ processes the source files defined in the qt.qdocconf file.
+
+ See also \l falsehoods and \l {if}{\\if}.
+
+ \row
+ \o \bold edition \target edition
+ \o \bold {The \c edition variable specifies which modules are
+ included in each edition of a package, and provides QDoc
+ with information to provide class lists for each edition.}
+
+ This feature is mostly used when providing documentation
+ for Qt packages.
+
+ The \c edition variable is always used with a particular
+ edition name to define the modules for that edition:
+
+ \code
+ edition.Console = QtCore QtNetwork QtSql QtXml
+ edition.Desktop = QtCore QtGui QtNetwork QtOpenGL QtSql QtXml \
+ QtDesigner QtAssistant Qt3Support QAxContainer \
+ QAxServer
+ edition.DesktopLight = QtCore QtGui Qt3SupportLight
+ \endcode
+
+ In the above examples, the \c Console edition only includes
+ the contents of four modules. Only the classes from these
+ modules will be used when the
+ \l{Miscellaneous Commands#generatelist}{generatelist} command
+ is used to generate a list of classes for this edition:
+
+ \code
+ \generatelist{classesbyedition Console}
+ \endcode
+
+ \row
+ \o \bold exampledirs \target exampledirs
+ \o \bold {The \c exampledirs variable specifies the directories
+ containing the source code of the example files.}
+
+ The \l {examples}{\c examples} and \c exampledirs variables
+ are used by the \l {quotefromfile}{\\quotefromfile}, \l
+ {quotefile}{\\quotefile} and \l {example}{\\example}
+ commands. If both the \l {examples}{\c examples} and \c
+ exampledirs variables are defined, QDoc will search in
+ both, first in \l {examples}{\c examples} then in \c
+ exampledirs.
+
+ QDoc will search through the directories in the specified
+ order, and accept the first matching file it finds. It will
+ only search in the specified directories, \i not in
+ subdirectories.
+
+ For example:
+
+ \code
+ exampledirs = $QTDIR/doc/src \
+ $QTDIR/examples \
+ $QTDIR \
+ $QTDIR/qmake/examples
+
+ examples = $QTDIR/examples/widgets/analogclock/analogclock.cpp
+ \endcode
+
+ When processing
+
+ \code
+ \quotefromfile widgets/calculator/calculator.cpp
+ \endcode
+
+ QDoc will then see if there exists a file called \c
+ calculator.cpp listed as a value in the \l {examples}{\c
+ examples} variable. If it doesn't, it will search in the \c
+ exampledirs variable, and first see if there exists a file
+ called
+
+ \code
+ $QTDIR/doc/src/widgets/calculator/calculator.cpp
+ \endcode
+
+ If it doesn't, QDoc will continue looking for a file
+ called
+
+ \code
+ $QTDIR/examples/widgets/calculator/calculator.cpp
+ \endcode
+
+ and so forth.
+
+ See also \l examples.
+
+ \row
+ \o \bold examples \target examples
+ \o \bold {The \c examples variable allows you to specify individual
+ example files in addition to those located in the directories
+ specified by the \l {exampledirs}{\c exampledirs} variable.}
+
+ The \c examples and \l {exampledirs}{\c exampledirs}
+ variables are used by the \l
+ {quotefromfile}{\\quotefromfile}, \l
+ {quotefile}{\\quotefile} and \l {example}{\\example}
+ commands. If both the \c examples and \l {exampledirs}{\c
+ exampledirs} variables are defined, QDoc will search in
+ both, first in \c examples then in \l {exampledirs}{\c
+ exampledirs}.
+
+ QDoc will search through the values listed for the \c
+ examples variable, in the specified order, and accept
+ the first one it finds.
+
+ For an extensive example, see the \l {exampledirs}{\c
+ exampledirs} command. But note that if you know the file is
+ listed in the \c examples variable, you don't need to
+ specify its path:
+
+ \code
+ \quotefromfile calculator.cpp
+ \endcode
+
+ See also \l exampledirs.
+
+ \row
+ \o \bold examples.fileextensions \target examples.fileextensions
+ \o \bold {The \c examples.fileextensions variable specifies the
+ file extensions that qdoc will look for when collecting example
+ files for display in the documentation.}
+
+ The default extensions are *.cpp, *.h, *.js, *.xq, *.svg, *.xml
+ and *.ui. However, if
+
+ The extensions are given as standard wildcard expressions.
+ You can add a file extension to the filter using '+='. For
+ example:
+
+ \code
+ examples.fileextensions += *.qrc
+ \endcode
+
+ See also \l{headers.fileextensions}.
+
+ \row
+ \o \bold extraimages \target extraimages
+ \o \bold {The \c extraimages variable tells QDoc to incorporate
+ specific images in the generated documentation.}
+
+ QDoc will not recognize images used within HTML (or any
+ other markup language). If we want the images to be copied
+ from the directories specified by \l {imagedirs}{\c
+ imagedirs} (the images in question must be located in these
+ directories) to the output directory, we must specify the
+ images using the \c extraimages variable.
+
+ The general syntax is \tt {extraimages.\i{format} = \i
+ image}. The file extension is optional.
+
+ For example, in \l qt.qdocconf we use a couple of images
+ within the HTML.postheader variable which value is pure
+ HTML. For that reason, these images are specified using the
+ \c extraimages variable:
+
+ \code
+ extraimages.HTML = qt-logo
+ \endcode
+
+ See also \l images and \l imagedirs.
+
+ \row
+ \o \bold falsehoods \target falsehoods
+ \o \bold {The \c falsehoods variable defines the truth value of
+ specified preprocessor symbols as false.}
+
+ If this variable is not set for a preprocessor symbol, QDoc
+ assumes its truth value is true. The exception is '0',
+ which value always is false.
+
+ QDoc will recognize, and is able to evaluate, the following
+ preprocessor syntax:
+
+ \code
+ #ifdef NOTYET
+ ...
+ #endif
+
+ #if defined (NOTYET)
+ ...
+ #end if
+ \endcode
+
+ However, faced with unknown syntax like
+
+ \code
+ #if NOTYET
+ ...
+ #endif
+ \endcode
+
+ QDoc will evaluate it as true by default, \i unless the
+ preprocessor symbol is specified within the \c falsehoods
+ variable entry:
+
+ \code
+ falsehoods = NOTYET
+ \endcode
+
+ See also \l defines.
+
+ \row
+ \o \bold generateindex \target generateindex
+ \o \bold{The \c generateindex variable contains a boolean value that
+ specifies whether to generate an index file when HTML documentation
+ is generated.}
+
+ By default, an index file is always generated with HTML documentation,
+ so this variable is typically only used when disabling this feature
+ (by setting the value to \c false) or when enabling index generation
+ for the WebXML output (by setting the value to \c true).
+ \row
+ \o \bold headerdirs \target headerdirs
+ \o \bold {The \c headerdirs variable specifies the directories
+ containing the header files associated with the \c .cpp source
+ files used in the documentation.}
+
+ For example:
+
+ \code
+ headerdirs = $QTDIR/src \
+ $QTDIR/extensions/activeqt \
+ $QTDIR/extensions/motif \
+ $QTDIR/tools/designer/src/lib/extension \
+ $QTDIR/tools/designer/src/lib/sdk \
+ $QTDIR/tools/designer/src/lib/uilib
+ \endcode
+
+ When executed, the first QDoc will do is to read through
+ the headers specified in the \l {headers}{\c headers}
+ variable, and the ones located in the directories specified
+ in the \c headerdir variable (including all
+ subdirectories), building an internal structure of the
+ classes and their functions.
+
+ Then it will read through the sources specified in the \l
+ {sources}{\c sources}, and the ones located in the
+ directories specified in the \l {sourcedirs}{\c sourcedirs}
+ varible (including all subdirectories), merging the
+ documentation with the structure it retrieved from the
+ header files.
+
+ If both the \c headers and \c headerdirs variables are
+ defined, QDoc will read through both, first \l {headers}{\c
+ headers} then \c headerdirs.
+
+ In the specified directories, QDoc will only read the files
+ with the fileextensions specified in the \l
+ {headers.fileextensions}{\c headers.fileextensions}
+ variable. The default extensions are *.ch, *.h, *.h++,
+ *.hh, *.hpp and *.hxx". The files specified by \l
+ {headers}{\c headers} will be read independent of their
+ fileextensions.
+
+ See also \l headers and \l headers.fileextensions.
+
+ \row
+ \o \bold headers \target headers
+ \o \bold {The \c headers variable allows you to specify individual
+ header files in addition to those located in the directories
+ specified by the \l {headerdirs}{\c headerdirs} variable.}
+
+ For example:
+
+ \code
+ headers = $QTDIR/src/gui/widgets/qlineedit.h \
+ $QTDIR/src/gui/widgets/qpushbutton.h
+ \endcode
+
+ When processing the \c headers variable, QDoc behaves in the
+ same way as it does when processing the \l {headerdirs}{\c
+ headerdirs} variable. For more information, see the \l
+ {headerdirs}{\c headerdirs} variable.
+
+ See also \l headerdirs.
+
+ \row
+ \o \bold headers.fileextensions \target headers.fileextensions
+ \o \bold {The \c headers.fileextensions variable specify the
+ extension used by the headers.}
+
+ When processing the header files specified in the \l
+ {headerdirs}{\c headerdirs} variable, QDoc will only read
+ the files with the fileextensions specified in the \c
+ headers.fileextensions variable. In this way QDoc avoid
+ spending time reading irrelevant files.
+
+ The default extensions are *.ch, *.h, *.h++, *.hh, *.hpp
+ and *.hxx.
+
+ The extensions are given as standard wildcard expressions.
+ You can add a file extension to the filter using '+='. For
+ example:
+
+ \code
+ header.fileextensions += *.H
+ \endcode
+
+ \warning The above assignment may not work as described.
+
+ See also \l headerdirs.
+
+ \row
+ \o \bold imagedirs \target imagedirs
+ \o \bold {The \c imagedirs variable specifies the directories
+ containing the images used in the documentation.}
+
+ The \l {images}{\c images} and \c imagedirs variables are
+ used by the \l {image}{\\image} and \l
+ {inlineimage}{\\inlineimage} commands. If both the \l
+ {images}{\c images} and \c imagedirs variables are defined,
+ QDoc will search in both, first in \l {images}{\c images}
+ then in \c imagedirs.
+
+ QDoc will search through the directories in the specified
+ order, and accept the first matching file it finds. It will
+ only search in the specified directories, \i not in
+ subdirectories.
+
+ For example:
+
+ \code
+ imagedirs = $QTDIR/doc/src/images \
+ $QTDIR/examples
+
+ images = $QTDIR/doc/src/images/calculator-example.png
+ \endcode
+
+ When processing
+
+ \code
+ \image calculator-example.png
+ \endcode
+
+ QDoc will then see if there exists a file called
+ calculator-example.png listed as a value in the \c images
+ variable. If it doesn't, it will search in the \c imagedirs
+ variable, and first see if there exists a file called
+
+ \code
+ $QTDIR/doc/src/images/calculator-example.png
+ \endcode
+
+ If it doesn't, QDoc will look for a file called
+
+ \code
+ $QTDIR/examples/calculator-example.png
+ \endcode
+
+ You can filter the images in an image directory using the
+ \l {images.fileextensions}{\c images.fileextensions}
+ variable. The general idea behind the \l
+ {images.fileextensions}{\c images.fileextensions} variable
+ is to enable different image format for different output
+ format.
+
+ \warning The \l {images.fileextensions}{\c
+ images.fileextensions} variable's functionality is
+ preliminay since QDoc at this point only support HTML.
+
+ See also \l images and \l images.fileextensions.
+
+ \row
+ \o \bold images \target images
+ \o \bold {The \c images variable allows you to specify individual
+ image files in addition to those located in the directories
+ specified by the \l {imagedirs}{\c imagedirs} variable.}
+
+ For example:
+
+ \code
+ images = $QTDIR/doc/src/images/calculator-example.png
+ \endcode
+
+ When processing the \c images variable, QDoc behaves in the
+ same way as it does when processing the \l {imagedirs}{\c
+ imagedirs} variable. For more information, see the \l
+ {imagedirs}{\c imagedirs} variable.
+
+ See also \l imagedirs and \l images.fileextensions.
+
+ \row
+ \o \bold images.fileextensions \target images.fileextensions
+ \o \bold {The images.fileextensions variable filters the files within
+ an image directory.}
+
+ The variable's values (the extensions) are given as
+ standard wildcard expressions. The general syntax is: \tt
+ {images.fileextensions.\i{format} = *.\i{extension}}.
+
+ The idea is to enable different image format for different
+ output format. For example:
+
+ \code
+ images.fileextensions.HTML = *.png
+ images.fileextensions.LOUT = *.eps
+ \endcode
+
+ Then, when processing the \l {image}{\\image} and \l
+ {inlineimage}{\\inlineimage} commands, QDoc will only
+ search for files with extensions specified in the output
+ format's associated image extension variable.
+
+ \warning This is preliminary functionality since QDoc at
+ this point only support HTML.
+
+ The default extensions for HTML are *.png, *.jpg, *.jpeg
+ and *.gif.
+
+ You can add a file extension to the filter using '+='. For
+ example:
+
+ \code
+ images.fileextensions.HTML += *.eps
+ \endcode
+
+ See also \l imagedirs and \l images.
+
+ \row
+ \o \bold language \target language
+ \o \bold {The \c language variable specifies the language of the
+ source code that is used in the documentation.}
+
+ Currently, C++ is the only language that QDoc
+ understands. It is also the default language, and doesn't
+ really need to be specified. But for example in \l
+ qt.qdocconf:
+
+ \code
+ language = Cpp
+ \endcode
+
+ identifies the language of the Qt source code as C++.
+
+ \row
+ \o \bold macro \target macro
+ \o \bold {The \c macro variable can be used to create your
+ own QDoc commands.}
+
+ The general syntax is \tt {macro.\i{command} =
+ "\i{definition}}". The definition can be described using
+ QDoc syntax. In addition it is possible to provide an HTML
+ definition by appending .HTML to the variable.
+
+ For example in \l qt.qdocconf:
+
+ \code
+ macro.gui = "\\bold"
+ macro.raisedaster.HTML = "<sup>*</sup>"
+ \endcode
+
+ makes sure that the \\gui command renders its argument using a
+ bold font, and that \\raisedaster renders a '*'.
+
+ \row
+ \o \bold naturallanguage \target naturallanguage
+ \o \bold {The \c naturallanguage variable specifies the natural
+ language used for the documentation generated by qdoc.}
+
+ For example:
+
+ \code
+ naturallanguage = zh-Hans
+ \endcode
+
+ By default, the natural language is \c en for compatibility
+ with legacy documentation.
+
+ qdoc will add the natural language information to the HTML
+ it generates, using the \c lang and \c xml:lang attributes.
+
+ See also \l sourceencoding, \l outputencoding,
+ \l{http://www.w3.org/TR/xhtml1/#C_7}{C.7. The lang and xml:lang Attributes} and
+ \l{http://www.w3.org/TR/i18n-html-tech-lang/#ri20040429.113217290}{Best Practice 13: Using Hans and Hant codes}.
+
+ \row
+ \o \bold outputdir \target outputdir
+ \o \bold {The \c outputdir variable specifies the directory
+ where QDoc will put the generated documentation.}
+
+ In qt.qdocconf:
+
+ \code
+ outputdir = $QTDIR/doc/html
+ \endcode
+
+ locates the generated Qt reference documentation in
+ $QTDIR/doc/html. For example, the documentation of the
+ QWidget class is located in
+
+ \code
+ $QTDIR/doc/html/qwidget.html
+ \endcode
+
+ The associated images will be put in an \c images subdirectory.
+
+ \warning When running QDoc multiple times using the same output
+ directory, all files from the previous run will be lost.
+
+ \row
+ \o \bold outputencoding \target outputencoding
+ \o \bold {The \c outputencoding variable specifies the encoding
+ used for the documentation generated by qdoc.}
+
+ For example:
+
+ \code
+ outputencoding = UTF-8
+ \endcode
+
+ By default, the output encoding is \c ISO-8859-1 (Latin1) for
+ compatibility with legacy documentation. When generating
+ documentation for some languages, particularly non-European
+ languages, this is not sufficient and an encoding such as UTF-8
+ is required.
+
+ qdoc will encode HTML using this encoding and generate the
+ correct declarations to indicate to browsers which encoding
+ is being used. The \l naturallanguage configuration variable
+ should also be specified to provide browsers with a complete
+ set of character encoding and language information.
+
+ See also \l outputencoding and \l naturallanguage.
+
+ \row
+ \o \bold outputformats \target outputformats
+ \o \bold {The \c outputformats variable specifies the format of
+ the generated documentation.}
+
+ Currently, QDoc only supports the HTML format. It is also
+ the default format, and doesn't need to be specified.
+
+ \row
+ \o \bold qhp \target qhp
+ \o \bold{The \c qhp variable is used to define the information to be
+ written out to Qt Help Project (\c{qhp}) files.}
+
+ See the \l{Creating Help Project Files} chapter for information
+ about this process.
+
+ \row
+ \o \bold slow \target slow
+ \o \bold {The \c slow variable specifies whether QDoc should do
+ time-consuming processing, such as syntax highlighting.}
+
+ By default, this setting is false.
+
+ Example:
+
+ \code
+ slow = true
+ \endcode
+
+ Another way to turn on "slowness" is to invoke QDoc with the
+ \c -slow command-line option.
+
+ \row
+ \o \bold sourcedirs \target sourcedirs
+ \o \bold {The \c sourcedirs variable specifies the directories
+ containing the \c .cpp or \c .qdoc files used in
+ the documentation.}
+
+ For example in \l qt.qdocconf
+
+ \code
+ sourcedirs = $QTDIR/src \
+ $QTDIR/doc/src \
+ $QTDIR/extensions/activeqt \
+ $QTDIR/extensions/motif \
+ $QTDIR/tools/designer/src/lib/extension \
+ $QTDIR/tools/designer/src/lib/sdk \
+ $QTDIR/tools/designer/src/lib/uilib
+ \endcode
+
+ When executed, the first QDoc will do is to read through
+ the headers specified in the \l {header}{\c header}
+ variable, and the ones located in the directories specified
+ in the \c headerdir variable (including all
+ subdirectories), building an internal structure of the
+ classes and their functions.
+
+ Then it will read through the sources specified in the \l
+ {sources}{\c sources}, and the ones located in the
+ directories specified in the \l {sourcedirs}{\c sourcedirs}
+ varible (including all subdirectories), merging the
+ documentation with the structure it retrieved from the
+ header files.
+
+ If both the \c sources and \c sourcedirs variables are
+ defined, QDoc will read through both, first \l {sources}{\c
+ sources} then \c sourcedirs.
+
+ In the specified directories, QDoc will only read the files
+ with the fileextensions specified in the \l
+ {sources.fileextensions}{\c sources.fileextensions}
+ variable. The default extensions are *.c++, *.cc, *.cpp and
+ *.cxx. The files specified by \l {sources}{\c sources} will
+ be read independent of their fileextensions.
+
+ See also \l sources and \l sources.fileextensions.
+
+ \row
+ \o \bold sourceencoding \target sourceencoding
+ \o \bold {The \c sourceencoding variable specifies the encoding
+ used for the source code and documentation.}
+
+ For example:
+
+ \code
+ sourceencoding = UTF-8
+ \endcode
+
+ By default, the source encoding is \c ISO-8859-1 (Latin1) for
+ compatibility with legacy documentation. For some languages,
+ particularly non-European languages, this is not sufficient
+ and an encoding such as UTF-8 is required.
+
+ Although qdoc will use the encoding to read source and
+ documentation files, limitations of C++ compilers may prevent
+ you from using non-ASCII characters in source code comments.
+ In cases like these, it is possible to write API documentation
+ completely in documentation files.
+
+ See also \l naturallanguage and \l outputencoding.
+
+ \row
+ \o \bold sources \target sources
+ \o \bold {The \c sources variable allows you to specify
+ individual source files in addition to those located in the
+ directories specified by the \l {sourcedir}{\c sourcedir}
+ variable.}
+
+ For example:
+
+ \code
+ sources = $QTDIR/src/gui/widgets/qlineedit.cpp \
+ $QTDIR/src/gui/widgets/qpushbutton.cpp
+ \endcode
+
+ When processing the \c sources variable, QDoc behaves in the
+ same way as it does when processing the \l {sourcedirs}{\c
+ sourcedirs} variable. For more information, see the \l
+ {sourcedirs}{\c sourcedirs} variable.
+
+ See also \l sourcedirs.
+
+ \row
+ \o \bold sources.fileextensions \target sources.fileextensions
+ \o \bold {The \c sources.fileextensions variable filters the
+ files within a source directory.}
+
+ When processing the source files specified in the \l
+ {sourcedirs}{\c sourcedirs} variable, QDoc will only read
+ the files with the fileextensions specified in the \c
+ sources.fileextensions variable. In this way QDoc avoid
+ spending time reading irrelevant files.
+
+ The default extensions are *.c++, *.cc, *.cpp and *.cxx.
+
+ The extensions are given as standard wildcard expressions.
+ You can add a file extension to the filter using '+='. For
+ example:
+
+ \code
+ sources.fileextensions += *.CC
+ \endcode
+
+ \warning The above assignment may not work as described.
+
+ See also \l sourcedirs and \l sources.
+
+ \row
+ \o \bold spurious \target spurious
+ \o \bold {The \c spurious variable excludes specified
+ QDoc warnings from the output.}
+
+ The warnings are specified using standard wildcard
+ expressions. For example:
+
+ \code
+ spurious = "Cannot find .*" \
+ "Missing .*"
+ \endcode
+
+ makes sure that warnings matching either of these
+ expressions, will not be part of the output when running
+ QDoc. For example would the following warning be omitted
+ from the output:
+
+ \code
+ qt-4.0/src/opengl/qgl_mac.cpp:156: Missing parameter name
+ \endcode
+
+ \row
+ \o \bold tabsize \target tabsize
+ \o \bold {The \c tabsize variable defines the size of a tab
+ character.}
+
+ For example:
+
+ \code
+ tabsize = 4
+ \endcode
+
+ will give the tab character the size of 4 spaces.
+
+ The default value of the variable is 8, and doesn't need to
+ be specified.
+
+ \row
+ \o \bold tagfile \target tagfile
+ \o \bold{The \c tagfile variable specifies the Doxygen tag file to be written
+ when HTML is generated.}
+ \row
+ \o \bold version \target version
+ \o \bold {The \c version variable specifies the version number of the
+ documented software.}
+
+ For example:
+
+ \code
+ version = 4.0.1
+ \endcode
+
+ When a version number is specified (using the \tt{\l
+ version} or \tt {\l versionsym} variables in a \c .qdocconf
+ file), it is accessible through the corresponding \\version
+ command for use in the documentation.
+
+ \warning The \\version command's functionality is not
+ fully implemented; currently it only works within raw HTML
+ code.
+
+ See also \l versionsym.
+
+ \row
+ \o \bold versionsym \target versionsym
+ \o \bold {The \c versionsym variable specifies a C++
+ preprocessor symbol that defines the version number
+ of the documented software.}
+
+ For example in \l qt.qdocconf:
+
+ \code
+ versionsym = QT_VERSION_STR
+ \endcode
+
+ QT_VERSION_STR is defined in qglobal.h as follows
+
+ \code
+ #define QT_VERSION_STR "4.0.1"
+ \endcode
+
+ When a version number is specified (using the \tt{\l
+ version} or \tt {\l versionsym} variables in a \c .qdocconf
+ file), it is accessible through the corresponding \\version
+ command for use in the documentation.
+
+ \warning The \\version command's functionality is not fully
+ implemented; currently it only works within raw HTML code.
+
+ See also \l {version}{\\version}.
+
+ \endtable
+*/
+
+/*!
+ \page 22-creating-help-project-files.html
+ \previouspage General Configuration Variables
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage C++ Specific Configuration Variables
+
+ \title Creating Help Project Files
+
+ \section1 Overview
+
+ Starting with Qt 4.4, Qt Assistant uses a different system for managing
+ Qt documentation that requires QDoc to generate inventories of files in a
+ format that is similar to the old style DCF format, but with additional
+ features.
+
+ Instead of hard-coding information about the documentation sets for Qt,
+ QDoc allows configuration variables to be used to specify which pages are
+ to be used in each documentation set it generates. These are specified as
+ subvariables of the \c qch variable with each set declared using a unique
+ identifier as a subvariable.
+
+ For example, the configuration file for the Qt documentation defines a
+ \c Qt documentation set by specifying information about the set as
+ subvariables with the \c{qhp.Qt} prefix:
+
+ \code
+ qhp.Qt.file = qt.qhp
+ qhp.Qt.namespace = com.trolltech.qt.440
+ qhp.Qt.virtualFolder = qdoc
+ qhp.Qt.indexTitle = Qt Reference Documentation
+ qhp.Qt.indexRoot =
+ qhp.Qt.extraFiles = classic.css images/qt-logo.png
+ qhp.Qt.filterAttributes = qt 4.4.0 qtrefdoc
+ qhp.Qt.customFilters.Qt.name = Qt 4.4.0
+ qhp.Qt.customFilters.Qt.filterAttributes = qt 4.4.0
+ qhp.Qt.subprojects = classes overviews examples
+ qhp.Qt.subprojects.classes.title = Classes
+ qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
+ qhp.Qt.subprojects.classes.selectors = class
+ qhp.Qt.subprojects.overviews.title = Overviews
+ qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs
+ qhp.Qt.subprojects.overviews.selectors = fake:page,group,module
+ qhp.Qt.subprojects.examples.title = Tutorials and Examples
+ qhp.Qt.subprojects.examples.indexTitle = Qt Examples
+ qhp.Qt.subprojects.examples.selectors = fake:example
+ \endcode
+
+ To create a table of contents for a manual, create a subproject with
+ a \c{type} property and set it to \c{manual}. The page in the documentation
+ referred to by the \c{indexTitle} property must contain a list of links
+ that acts as a table of contents for the whole manual. QDoc will take the
+ information in this list and create a table of contents for the subproject.
+
+ For example, the configuration file for Qt Creator defines only one
+ subproject for its documentation, including all the documentation in a
+ single manual:
+
+ \code
+ qhp.QtCreator.subprojects = manual
+ qhp.QtCreator.subprojects.manual.title = Qt Creator Manual
+ qhp.QtCreator.subprojects.manual.indexTitle = Qt Creator Manual
+ qhp.QtCreator.subprojects.manual.type = manual
+ \endcode
+
+ In this example, the page entitled "Qt Creator Manual" contains a nested
+ list of links to pages in the documentation which is duplicated in
+ Qt Assistant's Contents tab.
+*/
+
+/*!
+ \page 23-qdoc-configuration-cppvariables.html
+ \previouspage Creating Help Project Files
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage HTML Specific Configuration Variables
+
+ \title C++ Specific Configuration Variables
+
+ The C++ specific configuration variables are provided to avoid
+ erroneous documentation due to non-standard C++ constructs.
+
+ \section1 Alphabetical List
+
+ \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoredirectives}
+ {Cpp.ignoredirectives},
+ \l {23-qdoc-configuration-cppvariables.html#Cpp.ignoretoken}
+ {Cpp.ignoretokens}
+
+ \section1 Variable Descriptions
+
+ \table
+
+ \header
+ \o Variable
+ \o Description
+
+ \row
+ \o \bold Cpp.ignoredirectives \target Cpp.ignoredirectives
+ \o \bold {The \c Cpp.ignoredirectives variable makes QDoc ignore
+ the specified non-standard constructs, within C++ source code.}
+
+ If not specified by the \tt {\l Cpp.ignoretokens} or \tt
+ {\l Cpp.ignoredirectives} variables, non-standard
+ constructs (typically macros) can result in erroneous
+ documentation.
+
+ In \l qt.qdocconf:
+
+ \code
+ Cpp.ignoredirectives = Q_DECLARE_INTERFACE \
+ Q_DECLARE_OPERATORS_FOR_FLAGS \
+ Q_DECLARE_PRIVATE \
+ Q_DECLARE_PUBLIC \
+ Q_DISABLE_COPY \
+ Q_DUMMY_COMPARISON_OPERATOR \
+ Q_ENUMS \
+ Q_FLAGS \
+ Q_INTERFACES \
+ __attribute__
+ \endcode
+
+ makes sure that when processing the code below, for
+ example, QDoc will simply ignore the 'Q_ENUMS' and
+ 'Q_FLAGS' expressions:
+
+ \code
+ class Q_CORE_EXPORT Qt {
+ Q_OBJECT
+ Q_ENUMS(Orientation TextFormat BackgroundMode
+ DateFormat ScrollBarPolicy FocusPolicy
+ ContextMenuPolicy CaseSensitivity
+ LayoutDirection ArrowType)
+ Q_ENUMS(ToolButtonStyle)
+ Q_FLAGS(Alignment)
+ Q_FLAGS(Orientations)
+ Q_FLAGS(DockWidgetAreas)
+
+ public:
+ ...
+ };
+ \endcode
+
+ The Q_OBJECT macro, however, is an exception: QDoc
+ recognizes this particular non-standard construct, so there
+ is no need specifying it using the \tt {\l
+ Cpp.ignoredirectives} variable.
+
+ Regarding the Q_CORE_EXPORT macro; see the documentation of
+ the \tt {\l Cpp.ignoretokens} variable.
+
+ See also \l Cpp.ignoretokens.
+
+ \row
+ \o \bold Cpp.ignoretokens \target Cpp.ignoretokens
+ \o \bold {The \c Cpp.ignoretokens variable makes QDoc ignore
+ the specified non-standard constructs, within C++ source code.}
+
+ If not specified by the \tt {\l Cpp.ignoretokens} or \tt
+ {\l Cpp.ignoredirectives} variables, non-standard
+ constructs (typically macros) can result in erroneous
+ documentation.
+
+ In \l qt.qdocconf:
+
+ \code
+ Cpp.ignoretokens = QAXFACTORY_EXPORT \
+ QM_EXPORT_CANVAS \
+ ...
+ Q_COMPAT_EXPORT \
+ Q_CORE_EXPORT \
+ Q_EXPLICIT \
+ Q_EXPORT \
+ ...
+ Q_TYPENAME \
+ Q_XML_EXPORT
+ \endcode
+
+ makes sure that when processing the code below, for
+ example, QDoc will simply ignore the 'Q_CORE_EXPORT'
+ expression:
+
+ \code
+ class Q_CORE_EXPORT Qt {
+ Q_OBJECT
+ Q_ENUMS(Orientation TextFormat BackgroundMode
+ DateFormat ScrollBarPolicy FocusPolicy
+ ContextMenuPolicy CaseSensitivity
+ LayoutDirection ArrowType)
+ Q_ENUMS(ToolButtonStyle)
+ Q_FLAGS(Alignment)
+ Q_FLAGS(Orientations)
+ Q_FLAGS(DockWidgetAreas)
+
+ public:
+ ...
+ };
+ \endcode
+
+ Regarding the Q_OBJECT, Q_ENUMS and Q_FLAGS macros; see the
+ documentation of the \tt {\l Cpp.ignoredirectives}
+ variable.
+
+ See also \l Cpp.ignoredirectives.
+
+ \endtable
+*/
+
+
+/*!
+ \page 24-qdoc-configuration-htmlvariables.html
+ \previouspage C++ Specific Configuration Variables
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage Supporting Derived Projects
+
+ \title HTML Specific Configuration Variables
+
+ The HTML specific configuration variables define the generated
+ documentation's style, or define the contents of the
+ documentation's footer or postheader. The format of the variable
+ values are raw HTML.
+
+ \section1 Alphabetical List
+
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.footer}{HTML.footer},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.postheader}
+ {HTML.postheader},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.style}{HTML.style},
+ \l {24-qdoc-configuration-htmlvariables.html#HTML.stylesheets}{HTML.stylesheets}
+
+
+ \section1 Variable Descriptions
+
+ \table
+
+ \header
+ \o Variable
+ \o Description
+
+ \row
+ \o \bold HTML.footer \target HTML.footer
+ \o \bold {The \c HTML.footer variable defines the content
+ of the generated HTML documentation's footer.}
+
+ The footer is rendered at the bottom of the generated
+ documentation page.
+
+ The variable's value is given as raw HTML code enclosed by
+ quotation marks. Note that if the value spans several
+ lines, each line needs to be enclosed by quotation marks.
+
+ For example in \l qt.qdocconf:
+
+ \code
+ HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ ...
+ "</tr></table></div></address>"
+ \endcode
+
+ The complete variable entry in \l qt.qdocconf provides the
+ standard footer of the \l
+ {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference
+ Documentation}.
+
+ \row
+ \o \bold HTML.postheader \target HTML.postheader
+ \o \bold {The \c HTML.postheader variable defines the content
+ of the generated HTML documentation's postheader.}
+
+ The header is rendered at the top of the generated
+ documentation page.
+
+ The variable's value is given as raw HTML enclosed by
+ quotation marks. Note that if the value spans several
+ lines, each line needs to be enclosed by quotation marks.
+
+ For example in \l qt.qdocconf:
+
+ \code
+ HTML.postheader = "<table border=\"0\"..." \
+ ...
+ "<img src=\"images/trolltech-logo.png\" \
+ "align=\"right\" width=\"203\" height=\"32\""\
+ "border=\"0\" />" \
+ "</td></tr>" \
+ "</table>"
+ \endcode
+
+ The complete variable entry in \l qt.qdocconf provides the
+ standard header of the \l
+ {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference
+ Documentation}.
+
+ \row
+ \o \bold HTML.style \target HTML.style
+ \o \bold {The HTML.style variable defines the style for
+ the generated HTML documentation.}
+
+ The variable's value is given as raw HTML enclosed by
+ quotation marks. Note that if the value spans several
+ lines, each line needs to be enclosed by quotation marks.
+
+ For example in \l qt.qdocconf:
+
+ \code
+ HTML.style = "h3.fn,span.fn" \
+ "{ margin-left: 1cm; text-indent: -1cm; }\n" \
+ "a:link { color: #004faf; text-decoration: none }\n" \
+ "a:visited" \
+ "{ color: #672967; text-decoration: none }\n" \
+ "td.postheader { font-family: sans-serif }\n" \
+ "tr.address { font-family: sans-serif }\n" \
+ "body { background: #ffffff; color: black; }"
+ \endcode
+
+ provides the HTML style for the \l
+ {http://qt.nokia.com/doc/4.0/index.html}{Qt Reference
+ Documentation}.
+
+ \row
+ \o \bold HTML.stylesheets \target HTML.stylesheets
+ \o \bold {The HTML.stylesheets variable defines a list of stylesheets
+ to use for the generated HTML documentation.}
+
+ Using separate stylesheets for the documentation makes it easier to
+ customize and experiment with the style used once the contents has
+ been generated. Typically, it is only necessary to define a single
+ stylesheet for any set of documentation; for example:
+
+ \code
+ HTML.stylesheets = classic.css
+ \endcode
+
+ QDoc expects to find stylesheets in the directory containing the
+ \l qt.qdocconf file, and it will copy those specified to the output
+ directory alongside the HTML pages.
+ \endtable
+*/
+
+/*!
+ \page 25-qdoc-configuration-derivedprojects.html
+ \previouspage HTML Specific Configuration Variables
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage QDoc Compatibility
+
+ \title Supporting Derived Projects
+
+ \tableofcontents
+
+ Some particular configuration variables allow you to use QDoc to
+ support Qt-based projects; i.e to make projects, such as Qt Solutions,
+ contain references to the online Qt documentation. This
+ means that QDoc will be able to create links to the class reference
+ documentation, without any explicit linking command.
+
+ \section1 The Configuration Variables
+
+ \section2 Alphabetical List
+
+ \l{25-qdoc-configuration-derivedprojects.html#description}{description},
+ \l{25-qdoc-configuration-derivedprojects.html#indexes}{indexes},
+ \l{25-qdoc-configuration-derivedprojects.html#project}{project},
+ \l{25-qdoc-configuration-derivedprojects.html#url}{url}
+
+ \section2 Variable Descriptions
+
+ \table
+ \header
+ \o Variable
+ \o Description
+ \row
+ \o \bold description \target description
+ \o \bold {The description variable holds a short description of
+ the associated project.}
+
+ See also \l project.
+
+ \row
+ \o \bold indexes \target indexes
+ \o \bold {The \c indexes variable lists the index files
+ that will be used to generate references.}
+
+ For example. to make a derived Qt project contain links to
+ the Qt Reference documentation, you need to specify the
+ associated index file:
+
+ \code
+ indexes = $QTDIR/doc/html/qt.index
+ \endcode
+
+ See also \l project and \l url.
+
+ \row
+ \o \bold project \target project
+ \o \bold {The \c project variable provides a name for the project
+ associated with the \c .qdocconf file.}
+
+ The project's name is used to form a file name for the
+ associated project's \i index file. For example:
+
+ \code
+ project = QtMotif
+ \endcode
+
+ This will cause an index file called \c qtmotif.index to be
+ created.
+
+ See also \l description and \l indexes.
+ \row
+ \o \bold url \target url
+ \o \bold {The \c url variable holds the base URL for the
+ reference documentation associated with the current project.}
+
+ The URL is stored in the generated index file for the
+ project. When we use the index on its own, QDoc will use
+ this as the base URL when constructing links to classes,
+ functions, and other things listed in the index.
+
+ For example:
+
+ \code
+ project = Qt
+ description = Qt Reference Documentation
+ url = http://qt.nokia.com/doc/4.0
+
+ ...
+ \endcode
+
+ This makes sure that whenever \c qt.index is used to generate
+ references to for example Qt classes, the base URL is
+ \c http://qt.nokia.com/doc/4.0.
+
+ See also \l indexes.
+
+ \endtable
+
+ \target howto
+ \section1 How to Support Derived Projects
+
+ This feature makes use of the comprehensive indexes generated by
+ QDoc when it creates the Qt reference documentation.
+
+ For example, \l qt.qdocconf (the configuration file for Qt)
+ contains the following variable definitions:
+
+ \code
+ project = Qt
+ description = Qt Reference Documentation
+ url = http://qt.nokia.com/doc/4.0
+
+ ...
+ \endcode
+
+ The \l project variable name is used to form a file name for the
+ index file; in this case the \c qt.index file is created. The \l
+ url is stored in the index file. Later, when we use the index on
+ its own, QDoc will use this as the base URL when constructing
+ links to classes, functions, and other things listed in the index.
+
+ In a mini-project, you can use an index file by defining an \l
+ indexes configuration variable in your \c .qdocconf file.
+
+ For example, you can create a \c qtmotif.qdocconf file to help you
+ check the QtMotif documentation (which is part of Qt Solutions):
+
+ \code
+ include($QTDIR/tools/qdoc3/test/compat.qdocconf)
+
+ project = QtMotif
+ description = QtMotif Class Documentation
+ url = http://www.trolltech.com/products/solutions/catalog/4/Migration/qtmotifextension
+
+ indexes = $QTDIR/doc/html/qt.index
+
+ outputdir = html
+
+ headerdirs = src
+ sourcedirs = src \
+ examples
+ sources.fileextensions = "*.cpp *.qdoc *.doc"
+
+ exampledirs = examples
+ \endcode
+
+ The code above requires that you run QDoc from the directory that
+ contains this file. You need to include the compat.qdocconf
+ file for compatibility reasons; this is further explained in the
+ \l {QDoc Compatibility} section.
+
+ \bold {To resolve the actual links to Qt classes, the
+ mini-project's \c .qdocconf file needs to assign a value to the \l
+ indexes variable; \c $QTDIR/doc/html/qt.index makes sure that you
+ always use the updated index file for the Qt documentation.}
+
+ The only disadvantages with this approach are the extra file that
+ QDoc has to generate and the time it takes to do so. Reading the
+ index back again later isn't instantaneous either, but it's
+ quicker than processing all the Qt classes each time you need to
+ write a new document.
+*/
+
+/*!
+ \page 26-qdoc-commands-compatibility.html
+ \previouspage Supporting Derived Projects
+ \contentspage QDoc Manual - Table of Contents
+ \nextpage QDoc Commands - Alphabetical List
+
+ \title QDoc Compatibility
+
+ \tableofcontents
+
+ \section1 General Description
+
+ \target reason
+
+ QDoc is a tool that constantly evolves to suit our needs, for that
+ reason there are some compatibility issues in the transition
+ between old and new practices.
+
+ To make the transition as smooth and rapid as possible, the
+ general idea is to adopt the new commands and usage in new
+ documentation. While waiting for the occurrences of the old
+ practices to be eliminated from the old parts of the
+ documentation, you can map the new commands and usage to the old
+ ones using a compat.qdocconf file.
+
+ A compat.qdocconf file is a separate \c .qdocconf file which you
+ can include in your main configuration file. It typically contains
+ the mapping between old and new commands using the \l alias and \l
+ {22-qdoc-configuration-generalvariables.html#macro}{macro}
+ configuration variables.
+
+ \section1 Qt Compatibility
+
+ In Qt's documentation there still exist occurrences of old
+ commands, and the Qt \l {qt.qdocconf}{configuration file} needs to
+ include the compat.qdocconf file tailored for Qt. For more
+ detailed information about the commands creating compatibility
+ issues, see the \l {Command Comments}{command comments}.
+
+ \section2 Qt's current compat.qdocconf file
+
+ \quotefile files/compat.qdocconf
+
+ \section2 Command Comments
+
+ \table
+ \header
+ \o New Command
+ \o Old Command
+ \o Description
+
+ \row
+ \o \\i \target i-versus-e
+ \o \\e
+ \o Earlier we
+ used the \\i command to indicate a list or table item, and
+ the \\e command for rendering in italic. Now we want the
+ \\i command to render in italic discarding the
+ \\e command name.
+
+ \bold {We still need to use the \\e command to render in
+ italic in new documentation for \l {reason}{compatibility
+ reasons}}.
+
+ \row
+ \o \\include \target include-versus-input
+ \o \\input
+ \o The \\include command was previously used to quote the
+ complete contents of a source file, now we want to use the
+ command to include separate documentation.
+ That is the functionality of the old \\input command
+ which name we want to discard.
+
+ \bold {We still need to use the \\input command to include
+ plain text in new documentation for \l
+ {reason}{compatibility reasons}}.
+
+ \row
+ \o \\quotefile \target quotefile-versus-include
+ \o \\include
+ \o Earlier, we have used the \\quotefile command to
+ quote from file, i.e. quote parts from file, and the
+ \\include command to quote the entire file. Since we now want
+ \\include to include separate documentation, we change the use of
+ \\quotefile to quote a complete source file.
+
+ \bold {We still need to use the \\include command to quote
+ the entire contents of a source file in new documentation
+ for \l {reason}{compatibility reasons}}.
+
+ \row
+ \o \\quotefromfile \target quotefromfile-versus-quotefile
+ \o \\quotefile
+ \o Earlier, we have used the \\quotefile command to
+ quote from file, i.e. quote parts from file. Since we now want
+ that command to quote an entire file, we introduce the new
+ \\quotefromfile command to quote from file.
+
+ \bold {Use \l {quotefromfile}{\\quotefromfile} to quote
+ parts from a source file in new documentation}.
+
+ \row
+ \o \\o \target o-versus-i
+ \o \\i
+ \o Earlier we used the \\i command to indicate list items
+ and table items. Since we now want the \\i command to render
+ in italic instead, we introduce the new \\o command for
+ this purpose.
+
+ \bold {Use \l {o}{\\o} to indicate list and table items in
+ new documentation}.
+
+ \row
+ \o \\quotation \target quotation-versus-quote
+ \o \\quote
+ \o These commands are equivalent, and represent a simple name
+ change.
+
+ \bold {Use \l {quotation}{\\quotation} in new
+ documentation}.
+
+ \row
+ \o \\image \target image-versus-img
+ \o \\img
+ \o These commands are equivalent, and represent a simple name
+ change.
+
+ \bold {Use \l {image}{\\image} in new documentation}.
+
+ \endtable
+*/
+
+/*!
+ \page 27-qdoc-commmands-alphabetical.html
+ \previouspage QDoc Compatibility
+ \contentspage QDoc Manual - Table of Contents
+
+ \title QDoc Commands - Alphabetical List
+
+ \list
+
+ \o \l {04-qdoc-commands-textformatting.html#a}{\\a}
+ \o \l {11-qdoc-commands-documentcontents.html#abstract}{\\abstract}
+ \o \l {06-qdoc-commands-verbatimcode.html#badcode}{\\badcode}
+ \o \l {04-qdoc-commands-textformatting.html#bold}{\\bold}
+ \o \l {11-qdoc-commands-documentcontents.html#brief}{\\brief}
+ \o \l {04-qdoc-commands-textformatting.html#c}{\\c}
+ \o \l {09-qdoc-commands-graphic.html#caption}{\\caption}
+ \o \l {05-qdoc-commands-documentstructuring.html#chapter}{\\chapter}
+ \o \l {13-qdoc-commands-topical.html#class}{\\class}
+ \o \l {06-qdoc-commands-verbatimcode.html#code}{\\code}
+ \o \l {07-0-qdoc-commands-quoting.html#codeline}{\\codeline},
+ \o \l {16-qdoc-commands-status.html#compat}{\\compat}
+ \o \l {15-qdoc-commands-navigation.html#contentspage}{\\contentspage}
+ \o \l {07-0-qdoc-commands-quoting.html#dots}{\\dots}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#else}{\\else}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#endif}{\\endif}
+ \o \l {13-qdoc-commands-topical.html#enum}{\\enum}
+ \o \l {13-qdoc-commands-topical.html#example-command}{\\example}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#expire}{\\expire}
+ \o \l {13-qdoc-commands-topical.html#externalpage}{\\externalpage}
+ \o \l {13-qdoc-commands-topical.html#fn}{\\fn}
+ \o \l {11-qdoc-commands-documentcontents.html#footnote}{\\footnote}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#generatelist}{\\generatelist}
+ \o \l {13-qdoc-commands-topical.html#group}{\\group}
+ \o \l {10-qdoc-commands-container.html#header}{\\header}
+ \o \l {13-qdoc-commands-topical.html#headerfile}{\\headerfile}
+ \o \l {04-qdoc-commands-textformatting.html#i}{\\i}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#if}{\\if}
+ \o \l {09-qdoc-commands-graphic.html#image}{\\image}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#include}{\\include}
+ \o \l {15-qdoc-commands-navigation.html#indexpage}{\\indexpage}
+ \o \l {19-qdoc-commands-grouping.html#ingroup}{\\ingroup}
+ \o \l {19-qdoc-commands-grouping.html#inmodule}{\\inmodule}
+ \o \l {09-qdoc-commands-graphic.html#inlineimage}{\\inlineimage}
+ \o \l {16-qdoc-commands-status.html#internal}{\\internal}
+ \o \l {08-qdoc-commands-linking.html#keyword}{\\keyword}
+ \o \l {08-qdoc-commands-linking.html#l}{\\l}
+ \o \l {11-qdoc-commands-documentcontents.html#legalese}{\\legalese}
+ \o \l {10-qdoc-commands-container.html#list}{\\list}
+ \o \l {13-qdoc-commands-topical.html#macro}{\\macro}
+ \o \l {19-qdoc-commands-grouping.html#mainclass}{\\mainclass}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#meta}{\\meta}
+ \o \l {13-qdoc-commands-topical.html#module}{\\module}
+ \o \l {13-qdoc-commands-topical.html#namespace}{\\namespace}
+ \o \l {15-qdoc-commands-navigation.html#nextpage}{\\nextpage}
+ \o \l {06-qdoc-commands-verbatimcode.html#newcode}{\\newcode}
+ \o \l {17-qdoc-commands-thread.html#nonreentrant}{\\nonreentrant}
+ \o \l {10-qdoc-commands-container.html#o}{\\o}
+ \o \l {16-qdoc-commands-status.html#obsolete}{\\obsolete}
+ \o \l {06-qdoc-commands-verbatimcode.html#oldcode}{\\oldcode}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#omit}{\\omit}
+ \o \l {10-qdoc-commands-container.html#omitvalue}{\\omitvalue}
+ \o \l {18-qdoc-commands-relating.html#overload}{\\overload}
+ \o \l {13-qdoc-commands-topical.html#page}{\\page}
+ \o \l {05-qdoc-commands-documentstructuring.html#part}{\\part}
+ \o \l {16-qdoc-commands-status.html#preliminary}{\\preliminary}
+ \o \l {15-qdoc-commands-navigation.html#previouspage}{\\previouspage}
+ \o \l {07-0-qdoc-commands-quoting.html#printline}{\\printline}
+ \o \l {07-0-qdoc-commands-quoting.html#printto}{\\printto}
+ \o \l {07-0-qdoc-commands-quoting.html#printuntil}{\\printuntil}
+ \o \l {13-qdoc-commands-topical.html#property}{\\property}
+ \o \l {11-qdoc-commands-documentcontents.html#quotation}{\\quotation}
+ \o \l {07-0-qdoc-commands-quoting.html#quotefile}{\\quotefile}
+ \o \l {07-0-qdoc-commands-quoting.html#quotefromfile}{\\quotefromfile}
+ \o \l {12-0-qdoc-commands-miscellaneous.html#raw}{\\raw}
+ \o \l {17-qdoc-commands-thread.html#reentrant}{\\reentrant}
+ \o \l {18-qdoc-commands-relating.html#reimp}{\\reimp}
+ \o \l {18-qdoc-commands-relating.html#relates}{\\relates}
+ \o \l {10-qdoc-commands-container.html#row}{\\row}
+ \o \l {08-qdoc-commands-linking.html#sa}{\\sa}
+ \o \l {05-qdoc-commands-documentstructuring.html#sectionOne}{\\section1}
+ \o \l {05-qdoc-commands-documentstructuring.html#sectionTwo}{\\section2}
+ \o \l {05-qdoc-commands-documentstructuring.html#sectionThree}{\\section3}
+ \o \l {05-qdoc-commands-documentstructuring.html#sectionFour}{\\section4}
+ \o \l {13-qdoc-commands-topical.html#service}{\\service}
+ \o \l {16-qdoc-commands-status.html#since}{\\since}
+ \o \l {07-0-qdoc-commands-quoting.html#skipline}{\\skipline}
+ \o \l {07-0-qdoc-commands-quoting.html#skipto}{\\skipto}
+ \o \l {07-0-qdoc-commands-quoting.html#skipuntil}{\\skipuntil}
+ \o \l {07-0-qdoc-commands-quoting.html#snippet}{\\snippet},
+ \o \l {15-qdoc-commands-navigation.html#startpage}{\\startpage}
+ \o \l {04-qdoc-commands-textformatting.html#sub}{\\sub}
+ \o \l {20-qdoc-commands-title.html#subtitle}{\\subtitle}
+ \o \l {04-qdoc-commands-textformatting.html#sup}{\\sup}
+ \o \l {10-qdoc-commands-container.html#table}{\\table}
+ \o \l {11-qdoc-commands-documentcontents.html#tableofcontents}
+ {\\tableofcontents}
+ \o \l {08-qdoc-commands-linking.html#target}{\\target}
+ \o \l {17-qdoc-commands-thread.html#threadsafe}{\\threadsafe}
+ \o \l {20-qdoc-commands-title.html#title}{\\title}
+ \o \l {04-qdoc-commands-textformatting.html#tt}{\\tt}
+ \o \l {13-qdoc-commands-topical.html#typedef}{\\typedef}
+ \o \l {04-qdoc-commands-textformatting.html#underline}{\\underline}
+ \o \l {13-qdoc-commands-topical.html#variable}{\\variable}
+ \o \l {10-qdoc-commands-container.html#value}{\\value}
+ \o \l {11-qdoc-commands-documentcontents.html#warning}{\\warning}
+ \endlist
+*/
+
+/*!
+ \externalpage http://qt.nokia.com/about
+ \title About Qt
+*/
diff --git a/tools/qdoc3/doc/qdoc-manual.qdocconf b/tools/qdoc3/doc/qdoc-manual.qdocconf
new file mode 100644
index 0000000..1e7ff01
--- /dev/null
+++ b/tools/qdoc3/doc/qdoc-manual.qdocconf
@@ -0,0 +1,234 @@
+project = QDoc
+description = QDoc3 Manual
+
+indexes = ../../../doc/html/qt.index
+
+outputdir = html
+
+sources = qdoc-manual.qdoc
+sourcedirs = $PWD
+
+exampledirs += $PWD \
+ ../../../examples
+
+imagedirs += images
+
+extraimages.HTML = qt-logo
+
+HTML.stylesheets = style/style.css \
+ style/OfflineStyle.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style_ie6.css
+
+HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \
+ " <div class=\"content\"> \n" \
+ " <div id=\"nav-logo\">\n" \
+ " <a href=\"index.html\">Home</a></div>\n" \
+ " <a href=\"index.html\" class=\"qtref\"><span>Qt Reference Documentation</span></a>\n" \
+ " <div id=\"narrowsearch\"></div>\n" \
+ " <div id=\"nav-topright\">\n" \
+ " <ul>\n" \
+ " <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \
+ " <li class=\"nav-topright-dev\"><a href=\"http://developer.qt.nokia.com/\">DEV</a></li>\n" \
+ " <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \
+ " <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \
+ " DOC</a></li>\n" \
+ " <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <div id=\"shortCut\">\n" \
+ " <ul>\n" \
+ " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \
+ " <li class=\"shortCut-topleft-active\"><a href=\"http://doc.qt.nokia.com\">ALL VERSIONS" \
+ " </a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <ul class=\"sf-menu\" id=\"narrowmenu\"> \n" \
+ " <li><a href=\"#\">API Lookup</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"classes.html\">Class index</a></li> \n" \
+ " <li><a href=\"functions.html\">Function index</a></li> \n" \
+ " <li><a href=\"modules.html\">Modules</a></li> \n" \
+ " <li><a href=\"namespaces.html\">Namespaces</a></li> \n" \
+ " <li><a href=\"qtglobal.html\">Global Declarations</a></li> \n" \
+ " <li><a href=\"qdeclarativeelements.html\">QML elements</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Qt Topics</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"qt-basic-concepts.html\">Programming with Qt</a></li> \n" \
+ " <li><a href=\"qtquick.html\">Device UIs &amp; Qt Quick</a></li> \n" \
+ " <li><a href=\"qt-gui-concepts.html\">UI Design with Qt</a></li> \n" \
+ " <li><a href=\"developing-with-qt.html\">Cross-platform and Platform-specific</a></li> \n" \
+ " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " <li><a href=\"technology-apis.html\">Qt and Key Technologies</a></li> \n" \
+ " <li><a href=\"best-practices.html\">How-To's and Best Practices</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Examples</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"all-examples.html\">Examples</a></li> \n" \
+ " <li><a href=\"tutorials.html\">Tutorials</a></li> \n" \
+ " <li><a href=\"demos.html\">Demos</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html\">QML Examples</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrapper\">\n" \
+ " <div class=\"hd\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " <div class=\"bd group\">\n" \
+ " <div class=\"sidebar\">\n" \
+ " <div class=\"searchlabel\">\n" \
+ " Search index:</div>\n" \
+ " <div class=\"search\" id=\"sidebarsearch\">\n" \
+ " <form id=\"qtdocsearch\" action=\"\" onsubmit=\"return false;\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" name=\"searchstring\" id=\"pageType\" value=\"\" />\n" \
+ " <div id=\"resultdialog\"> \n" \
+ " <a href=\"#\" id=\"resultclose\">Close</a> \n" \
+ " <p id=\"resultlinks\" class=\"all\"><a href=\"#\" id=\"showallresults\">All</a> | <a href=\"#\" id=\"showapiresults\">API</a> | <a href=\"#\" id=\"showarticleresults\">Articles</a> | <a href=\"#\" id=\"showexampleresults\">Examples</a></p> \n" \
+ " <p id=\"searchcount\" class=\"all\"><span id=\"resultcount\"></span><span id=\"apicount\"></span><span id=\"articlecount\"></span><span id=\"examplecount\"></span>&nbsp;results:</p> \n" \
+ " <ul id=\"resultlist\" class=\"all\"> \n" \
+ " </ul> \n" \
+ " </div> \n" \
+ " </fieldset>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div class=\"box first bottombar\" id=\"lookup\">\n" \
+ " <h2 title=\"API Lookup\"><span></span>\n" \
+ " API Lookup</h2>\n" \
+ " <div id=\"list001\" class=\"list\">\n" \
+ " <ul id=\"ul001\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"classes.html\">Class index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"functions.html\">Function index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"modules.html\">Modules</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"namespaces.html\">Namespaces</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qtglobal.html\">Global Declarations</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeelements.html\">QML elements</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box bottombar\" id=\"topics\">\n" \
+ " <h2 title=\"Qt Topics\"><span></span>\n" \
+ " Qt Topics</h2>\n" \
+ " <div id=\"list002\" class=\"list\">\n" \
+ " <ul id=\"ul002\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Programming with Qt</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"qtquick.html\">Device UIs &amp; Qt Quick</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">UI Design with Qt</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"developing-with-qt.html\">Cross-platform and Platform-specific</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"technology-apis.html\">Qt and Key Technologies</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"best-practices.html\">How-To's and Best Practices</a></li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box\" id=\"examples\">\n" \
+ " <h2 title=\"Examples\"><span></span>\n" \
+ " Examples</h2>\n" \
+ " <div id=\"list003\" class=\"list\">\n" \
+ " <ul id=\"ul003\">\n" \
+ " <li class=\"defaultLink\"><a href=\"all-examples.html\">Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"tutorials.html\">Tutorials</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"demos.html\">Demos</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html\">QML Examples</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrap\">\n" \
+ " <div class=\"toolbar\">\n" \
+ " <div class=\"breadcrumb toolblock\">\n" \
+ " <ul>\n" \
+ " <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
+ " <!-- Bread crumbs goes here -->\n"
+
+HTML.postpostheader = " </ul>\n" \
+ " </div>\n" \
+ " <div class=\"toolbuttons toolblock\">\n" \
+ " <ul>\n" \
+ " <li id=\"smallA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"medA\" class=\"t_button active\">A</li>\n" \
+ " <li id=\"bigA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \
+ " <span>Print</span></a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"content mainContent\">\n"
+
+HTML.footer = "" \
+ " <div class=\"feedback t_button\">\n" \
+ " [+] Documentation Feedback</div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"ft\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"footer\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2008-2010 Nokia Corporation and/or its\n" \
+ " subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
+ " in Finland and/or other countries worldwide.</p>\n" \
+ " <p>\n" \
+ " All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
+ " href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
+ " <br />\n" \
+ " <p>\n" \
+ " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
+ " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
+ " with the terms contained in a written agreement between you and Nokia.</p>\n" \
+ " <p>\n" \
+ " Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
+ " Free Documentation License version 1.3</a>\n" \
+ " as published by the Free Software Foundation.</p>\n" \
+ " </div>\n" \
+ " <div id=\"feedbackBox\">\n" \
+ " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \
+ " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \
+ " <p id=\"noteHead\">Thank you for giving your feedback.</p> <p class=\"note\">Make sure it is related to this specific page. For more general bugs and \n" \
+ " requests, please use the <a href=\"http://bugreports.qt.nokia.com/secure/Dashboard.jspa\">Qt Bug Tracker</a>.</p>\n" \
+ " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\"></textarea></p>\n" \
+ " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div id=\"blurpage\">\n" \
+ " </div>\n"
+
+# This stuff is used by the Qt 4.7 doc format.
+scriptdirs = ../../../doc/src/template/scripts
+styledirs = ../../../doc/src/template/style
+
+scripts.HTML = functions.js \
+ narrow.js \
+ superfish.js \
+ jquery.js
+
+styles.HTML = style.css \
+ narrow.css \
+ superfish.css \
+ superfish_skin.css \
+ style_ie6.css \
+ style_ie7.css \
+ style_ie8.css
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index 9b58d7f..f1eaddc 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -42,7 +42,6 @@
/*
generator.cpp
*/
-#include <QtCore>
#include <qdir.h>
#include <qdebug.h>
#include "codemarker.h"
@@ -67,6 +66,10 @@ QStringList Generator::imageFiles;
QStringList Generator::imageDirs;
QStringList Generator::exampleDirs;
QStringList Generator::exampleImgExts;
+QStringList Generator::scriptFiles;
+QStringList Generator::scriptDirs;
+QStringList Generator::styleFiles;
+QStringList Generator::styleDirs;
QString Generator::outDir;
QString Generator::project;
@@ -125,10 +128,20 @@ void Generator::initialize(const Config &config)
if (!dirInfo.mkdir(outDir + "/images/used-in-examples"))
config.lastLocation().fatal(tr("Cannot create output directory '%1'")
.arg(outDir + "/images/used-in-examples"));
+ if (!dirInfo.mkdir(outDir + "/scripts"))
+ config.lastLocation().fatal(tr("Cannot create output directory '%1'")
+ .arg(outDir + "/scripts"));
+ if (!dirInfo.mkdir(outDir + "/style"))
+ config.lastLocation().fatal(tr("Cannot create output directory '%1'")
+ .arg(outDir + "/style"));
}
imageFiles = config.getStringList(CONFIG_IMAGES);
imageDirs = config.getStringList(CONFIG_IMAGEDIRS);
+ scriptFiles = config.getStringList(CONFIG_SCRIPTS);
+ scriptDirs = config.getStringList(CONFIG_SCRIPTDIRS);
+ styleFiles = config.getStringList(CONFIG_STYLES);
+ styleDirs = config.getStringList(CONFIG_STYLEDIRS);
exampleDirs = config.getStringList(CONFIG_EXAMPLEDIRS);
exampleImgExts = config.getStringList(CONFIG_EXAMPLES + Config::dot +
CONFIG_IMAGEEXTENSIONS);
@@ -166,6 +179,47 @@ void Generator::initialize(const Config &config)
"/images");
++e;
}
+
+ QStringList noExts;
+ QStringList scripts =
+ config.getStringList(CONFIG_SCRIPTS+Config::dot+(*g)->format());
+ e = scripts.begin();
+ while (e != scripts.end()) {
+ QString userFriendlyFilePath;
+ QString filePath = Config::findFile(config.lastLocation(),
+ scriptFiles,
+ scriptDirs,
+ *e,
+ noExts,
+ userFriendlyFilePath);
+ if (!filePath.isEmpty())
+ Config::copyFile(config.lastLocation(),
+ filePath,
+ userFriendlyFilePath,
+ (*g)->outputDir() +
+ "/scripts");
+ ++e;
+ }
+
+ QStringList styles =
+ config.getStringList(CONFIG_STYLES+Config::dot+(*g)->format());
+ e = styles.begin();
+ while (e != styles.end()) {
+ QString userFriendlyFilePath;
+ QString filePath = Config::findFile(config.lastLocation(),
+ styleFiles,
+ styleDirs,
+ *e,
+ noExts,
+ userFriendlyFilePath);
+ if (!filePath.isEmpty())
+ Config::copyFile(config.lastLocation(),
+ filePath,
+ userFriendlyFilePath,
+ (*g)->outputDir() +
+ "/style");
+ ++e;
+ }
}
++g;
}
@@ -227,6 +281,7 @@ void Generator::terminate()
imageFiles.clear();
imageDirs.clear();
outDir = "";
+ QmlClassNode::clear();
}
Generator *Generator::generatorForFormat(const QString& format)
@@ -322,11 +377,11 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
bool quiet = false;
if (node->type() == Node::Function) {
-#if 0
+#if 0
const FunctionNode *func = (const FunctionNode *) node;
if (func->isOverload() && func->metaness() != FunctionNode::Ctor)
generateOverload(node, marker);
-#endif
+#endif
}
else if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
@@ -347,7 +402,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
if (func->reimplementedFrom() != 0)
generateReimplementedFrom(func, marker);
}
-
+
if (!generateText(node->doc().body(), node, marker))
if (node->isReimp())
return;
@@ -452,7 +507,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
// Now we put this at the top, before the other text.
if (func->reimplementedFrom() != 0)
generateReimplementedFrom(func, marker);
-#endif
+#endif
}
}
@@ -544,7 +599,7 @@ void Generator::generateInheritedBy(const ClassNode *classe,
example is being formatted. It outputs the list of source
files comprising the example, and the list of images used
by the example. The images are copied into a subtree of
- \c{...doc/html/images/used-in-examples/...}
+ \c{...doc/html/images/used-in-examples/...}
*/
void Generator::generateFileList(const FakeNode* fake,
CodeMarker* marker,
@@ -641,33 +696,6 @@ void Generator::generateExampleFiles(const FakeNode *fake, CodeMarker *marker)
}
#endif
-void Generator::generateModuleWarning(const ClassNode *classe,
- CodeMarker *marker)
-{
- QString module = classe->moduleName();
- if (!module.isEmpty()) {
- Text text;
- if (!editionModuleMap["DesktopLight"].contains(module)) {
- text << Atom::ParaLeft
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
- << "This class is not part of the Qt GUI Framework Edition."
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
- << Atom::ParaRight;
- }
- else if (module == "Qt3Support") {
- text << Atom::ParaLeft
- << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD)
- << "Note to Qt GUI Framework Edition users:"
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD)
- << " This class is only available in the "
- << Atom(Atom::AutoLink, "Qt Full Framework Edition")
- << "." << Atom::ParaRight;
- }
-
- generateText(text, classe, marker);
- }
-}
-
QString Generator::indent(int level, const QString& markedCode)
{
if (level == 0)
@@ -953,27 +981,30 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
NodeList nonreentrant;
NodeList::ConstIterator c = innerNode->childNodes().begin();
while (c != innerNode->childNodes().end()) {
- switch ((*c)->threadSafeness()) {
- case Node::Reentrant:
- reentrant.append(*c);
- if (threadSafeness == Node::ThreadSafe)
- exceptions = true;
- break;
- case Node::ThreadSafe:
- threadsafe.append(*c);
- if (threadSafeness == Node::Reentrant)
+
+ if ((*c)->status() != Node::Obsolete){
+ switch ((*c)->threadSafeness()) {
+ case Node::Reentrant:
+ reentrant.append(*c);
+ if (threadSafeness == Node::ThreadSafe)
+ exceptions = true;
+ break;
+ case Node::ThreadSafe:
+ threadsafe.append(*c);
+ if (threadSafeness == Node::Reentrant)
+ exceptions = true;
+ break;
+ case Node::NonReentrant:
+ nonreentrant.append(*c);
exceptions = true;
- break;
- case Node::NonReentrant:
- nonreentrant.append(*c);
- exceptions = true;
- break;
- default:
- break;
+ break;
+ default:
+ break;
+ }
}
++c;
}
- if (!exceptions)
+ if (!exceptions)
text << ".";
else if (threadSafeness == Node::Reentrant) {
if (nonreentrant.isEmpty()) {
@@ -1040,8 +1071,11 @@ void Generator::generateSince(const Node *node, CodeMarker *marker)
Text text;
text << Atom::ParaLeft
<< "This "
- << typeString(node)
- << " was introduced in ";
+ << typeString(node);
+ if (node->type() == Node::Enum)
+ text << " was introduced or modified in ";
+ else
+ text << " was introduced in ";
if (project.isEmpty())
text << "version";
else
@@ -1060,7 +1094,7 @@ void Generator::generateOverload(const Node *node, CodeMarker *marker)
text << Atom::ParaLeft
<< "This function overloads ";
QString t = node->name() + "()";
- text << Atom::AutoLink << t
+ text << Atom::AutoLink << t
<< Atom::ParaRight;
generateText(text, node, marker);
}
@@ -1213,6 +1247,35 @@ void Generator::appendSortedNames(Text& text,
}
}
+void Generator::appendSortedQmlNames(Text& text,
+ const Node* base,
+ const NodeList& subs,
+ CodeMarker *marker)
+{
+ QMap<QString,Text> classMap;
+ int index = 0;
+
+#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
+ qDebug() << "Generator::appendSortedQmlNames():" << base->name() << "is inherited by...";
+#endif
+ for (int i = 0; i < subs.size(); ++i) {
+ Text t;
+#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
+ qDebug() << " " << subs[i]->name();
+#endif
+ appendFullName(t, subs[i], base, marker);
+ classMap[t.toString().toLower()] = t;
+ }
+
+ QStringList names = classMap.keys();
+ names.sort();
+
+ foreach (const QString &name, names) {
+ text << classMap[name];
+ text << separator(index++, names.count());
+ }
+}
+
int Generator::skipAtoms(const Atom *atom, Atom::Type type) const
{
int skipAhead = 0;
diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h
index 06f7f88..326a247 100644
--- a/tools/qdoc3/generator.h
+++ b/tools/qdoc3/generator.h
@@ -124,7 +124,6 @@ class Generator
Node::SubType subtype,
const QString& tag);
void generateExampleFiles(const FakeNode *fake, CodeMarker *marker);
- void generateModuleWarning(const ClassNode *classe, CodeMarker *marker);
virtual int skipAtoms(const Atom *atom, Atom::Type type) const;
virtual QString fullName(const Node *node,
@@ -170,6 +169,13 @@ class Generator
const QList<RelatedClass> &classes,
CodeMarker *marker);
+ protected:
+ void appendSortedQmlNames(Text& text,
+ const Node* base,
+ const NodeList& subs,
+ CodeMarker *marker);
+
+ private:
QString amp;
QString lt;
QString gt;
@@ -185,6 +191,10 @@ class Generator
static QStringList imageDirs;
static QStringList exampleDirs;
static QStringList exampleImgExts;
+ static QStringList scriptFiles;
+ static QStringList scriptDirs;
+ static QStringList styleFiles;
+ static QStringList styleDirs;
static QString outDir;
static QString project;
};
diff --git a/tools/qdoc3/helpprojectwriter.cpp b/tools/qdoc3/helpprojectwriter.cpp
index 2189e02..63e8df7 100644
--- a/tools/qdoc3/helpprojectwriter.cpp
+++ b/tools/qdoc3/helpprojectwriter.cpp
@@ -39,9 +39,9 @@
**
****************************************************************************/
-#include <QtXml>
#include <QHash>
#include <QMap>
+//#include <qdebug.h>
#include "atom.h"
#include "helpprojectwriter.h"
@@ -49,6 +49,7 @@
#include "config.h"
#include "node.h"
#include "tree.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -91,6 +92,7 @@ HelpProjectWriter::HelpProjectWriter(const Config &config, const QString &defaul
subproject.title = config.getString(subprefix + "title");
subproject.indexTitle = config.getString(subprefix + "indexTitle");
subproject.sortPages = config.getBool(subprefix + "sortPages");
+ subproject.type = config.getString(subprefix + "type");
readSelectors(subproject, config.getStringList(subprefix + "selectors"));
project.subprojects[name] = subproject;
}
@@ -117,6 +119,11 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
typeHash["property"] = Node::Property;
typeHash["variable"] = Node::Variable;
typeHash["target"] = Node::Target;
+#ifdef QDOC_QML
+ typeHash["qmlproperty"] = Node::QmlProperty;
+ typeHash["qmlsignal"] = Node::QmlSignal;
+ typeHash["qmlmethod"] = Node::QmlMethod;
+#endif
QHash<QString, Node::SubType> subTypeHash;
subTypeHash["example"] = Node::Example;
@@ -128,6 +135,8 @@ void HelpProjectWriter::readSelectors(SubProject &subproject, const QStringList
subTypeHash["externalpage"] = Node::ExternalPage;
#ifdef QDOC_QML
subTypeHash["qmlclass"] = Node::QmlClass;
+ subTypeHash["qmlpropertygroup"] = Node::QmlPropertyGroup;
+ subTypeHash["qmlbasictype"] = Node::QmlBasicType;
#endif
QSet<Node::SubType> allSubTypes = QSet<Node::SubType>::fromList(subTypeHash.values());
@@ -177,7 +186,13 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
{
QStringList details;
- if (node->parent() && !node->parent()->name().isEmpty()) {
+ if (node->type() == Node::QmlProperty) {
+ // "name"
+ details << node->name();
+ // "id"
+ details << node->parent()->parent()->name()+"::"+node->name();
+ }
+ else if (node->parent() && !node->parent()->name().isEmpty()) {
// "name"
if (node->type() == Node::Enum || node->type() == Node::Typedef)
details << node->parent()->name()+"::"+node->name();
@@ -185,29 +200,29 @@ QStringList HelpProjectWriter::keywordDetails(const Node *node) const
details << node->name();
// "id"
details << node->parent()->name()+"::"+node->name();
- } else if (node->type() == Node::Fake) {
+ }
+ else if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
-#ifdef QDOC_QML
if (fake->subType() == Node::QmlClass) {
details << (QmlClassNode::qmlOnly ? fake->name() : fake->fullTitle());
details << "QML." + fake->name();
- } else
-#endif
- {
+ }
+ else {
details << fake->fullTitle();
details << fake->fullTitle();
}
- } else {
+ }
+ else {
details << node->name();
details << node->name();
}
details << tree->fullDocumentLocation(node);
-
return details;
}
bool HelpProjectWriter::generateSection(HelpProject &project,
- QXmlStreamWriter & /* writer */, const Node *node)
+ QXmlStreamWriter & /* writer */,
+ const Node *node)
{
if (!node->url().isEmpty())
return false;
@@ -226,17 +241,19 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
if (node->type() == Node::Fake) {
const FakeNode *fake = static_cast<const FakeNode *>(node);
objName = fake->fullTitle();
- } else
+ }
+ else
objName = tree->fullDocumentName(node);
-
+
// Only add nodes to the set for each subproject if they match a selector.
// Those that match will be listed in the table of contents.
foreach (const QString &name, project.subprojects.keys()) {
SubProject subproject = project.subprojects[name];
// No selectors: accept all nodes.
- if (subproject.selectors.isEmpty())
+ if (subproject.selectors.isEmpty()) {
project.subprojects[name].nodes[objName] = node;
+ }
else if (subproject.selectors.contains(node->type())) {
// Accept only the node types in the selectors hash.
if (node->type() != Node::Fake)
@@ -247,9 +264,10 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
if (subproject.selectors[node->type()].contains(fakeNode->subType()) &&
fakeNode->subType() != Node::ExternalPage &&
- !fakeNode->fullTitle().isEmpty())
+ !fakeNode->fullTitle().isEmpty()) {
project.subprojects[name].nodes[objName] = node;
+ }
}
}
}
@@ -290,6 +308,9 @@ bool HelpProjectWriter::generateSection(HelpProject &project,
break;
case Node::Property:
+ case Node::QmlProperty:
+ case Node::QmlSignal:
+ case Node::QmlMethod:
project.keywords.append(keywordDetails(node));
break;
@@ -400,7 +421,7 @@ void HelpProjectWriter::generateSections(HelpProject &project,
{
if (!generateSection(project, writer, node))
return;
-
+
if (node->isInnerNode()) {
const InnerNode *inner = static_cast<const InnerNode *>(node);
@@ -409,8 +430,23 @@ void HelpProjectWriter::generateSections(HelpProject &project,
foreach (const Node *node, inner->childNodes()) {
if (node->access() == Node::Private)
continue;
- if (node->type() == Node::Fake)
- childMap[static_cast<const FakeNode *>(node)->fullTitle()] = node;
+ if (node->type() == Node::Fake) {
+ /*
+ Don't visit QML property group nodes,
+ but visit their children, which are all
+ QML property nodes.
+ */
+ if (node->subType() == Node::QmlPropertyGroup) {
+ const InnerNode* inner = static_cast<const InnerNode*>(node);
+ foreach (const Node* n, inner->childNodes()) {
+ if (n->access() == Node::Private)
+ continue;
+ childMap[tree->fullDocumentName(n)] = n;
+ }
+ }
+ else
+ childMap[static_cast<const FakeNode *>(node)->fullTitle()] = node;
+ }
else {
if (node->type() == Node::Function) {
const FunctionNode *funcNode = static_cast<const FunctionNode *>(node);
@@ -494,13 +530,11 @@ void HelpProjectWriter::writeNode(HelpProject &project, QXmlStreamWriter &writer
writer.writeStartElement("section");
writer.writeAttribute("ref", href);
writer.writeAttribute("title", fakeNode->fullTitle());
- // qDebug() << "Title:" << fakeNode->fullTitle();
- if (fakeNode->subType() == Node::HeaderFile) {
-
+ if ((fakeNode->subType() == Node::HeaderFile) || (fakeNode->subType() == Node::QmlClass)) {
// Write subsections for all members, obsolete members and Qt 3
// members.
- if (!project.memberStatus[node].isEmpty()) {
+ if (!project.memberStatus[node].isEmpty() || (fakeNode->subType() == Node::QmlClass)) {
QString membersPath = href.left(href.size()-5) + "-members.html";
writer.writeStartElement("section");
writer.writeAttribute("ref", membersPath);
@@ -593,44 +627,100 @@ void HelpProjectWriter::generateProject(HelpProject &project)
foreach (const QString &name, project.subprojects.keys()) {
SubProject subproject = project.subprojects[name];
- if (!name.isEmpty()) {
- writer.writeStartElement("section");
- QString indexPath = tree->fullDocumentLocation(tree->findFakeNodeByTitle(subproject.indexTitle));
- writer.writeAttribute("ref", HtmlGenerator::cleanRef(indexPath));
- writer.writeAttribute("title", subproject.title);
- project.files.insert(indexPath);
- }
- if (subproject.sortPages) {
- QStringList titles = subproject.nodes.keys();
- titles.sort();
- foreach (const QString &title, titles)
- writeNode(project, writer, subproject.nodes[title]);
+ if (subproject.type == QLatin1String("manual")) {
+
+ const FakeNode *indexPage = tree->findFakeNodeByTitle(subproject.indexTitle);
+ if (indexPage) {
+ Text indexBody = indexPage->doc().body();
+ const Atom *atom = indexBody.firstAtom();
+ QStack<int> sectionStack;
+ bool inItem = false;
+
+ while (atom) {
+ switch (atom->type()) {
+ case Atom::ListLeft:
+ sectionStack.push(0);
+ break;
+ case Atom::ListRight:
+ if (sectionStack.pop() > 0)
+ writer.writeEndElement(); // section
+ break;
+ case Atom::ListItemLeft:
+ inItem = true;
+ break;
+ case Atom::ListItemRight:
+ inItem = false;
+ break;
+ case Atom::Link:
+ if (inItem) {
+ if (sectionStack.top() > 0)
+ writer.writeEndElement(); // section
+
+ const FakeNode *page = tree->findFakeNodeByTitle(atom->string());
+ writer.writeStartElement("section");
+ QString indexPath = tree->fullDocumentLocation(page);
+ writer.writeAttribute("ref", HtmlGenerator::cleanRef(indexPath));
+ writer.writeAttribute("title", atom->string());
+ project.files.insert(indexPath);
+
+ sectionStack.top() += 1;
+ }
+ break;
+ default:
+ ;
+ }
+
+ if (atom == indexBody.lastAtom())
+ break;
+ atom = atom->next();
+ }
+ } else
+ rootNode->doc().location().warning(
+ tr("Failed to find index: %1").arg(subproject.indexTitle)
+ );
+
} else {
- // Find a contents node and navigate from there, using the NextLink values.
- foreach (const Node *node, subproject.nodes) {
- QString nextTitle = node->links().value(Node::NextLink).first;
- if (!nextTitle.isEmpty() &&
- node->links().value(Node::ContentsLink).first.isEmpty()) {
-
- FakeNode *nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
-
- // Write the contents node.
- writeNode(project, writer, node);
-
- while (nextPage) {
- writeNode(project, writer, nextPage);
- nextTitle = nextPage->links().value(Node::NextLink).first;
- if(nextTitle.isEmpty())
- break;
- nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
+
+ if (!name.isEmpty()) {
+ writer.writeStartElement("section");
+ QString indexPath = tree->fullDocumentLocation(tree->findFakeNodeByTitle(subproject.indexTitle));
+ writer.writeAttribute("ref", HtmlGenerator::cleanRef(indexPath));
+ writer.writeAttribute("title", subproject.title);
+ project.files.insert(indexPath);
+ }
+ if (subproject.sortPages) {
+ QStringList titles = subproject.nodes.keys();
+ titles.sort();
+ foreach (const QString &title, titles) {
+ writeNode(project, writer, subproject.nodes[title]);
+ }
+ } else {
+ // Find a contents node and navigate from there, using the NextLink values.
+ foreach (const Node *node, subproject.nodes) {
+ QString nextTitle = node->links().value(Node::NextLink).first;
+ if (!nextTitle.isEmpty() &&
+ node->links().value(Node::ContentsLink).first.isEmpty()) {
+
+ FakeNode *nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
+
+ // Write the contents node.
+ writeNode(project, writer, node);
+
+ while (nextPage) {
+ writeNode(project, writer, nextPage);
+ nextTitle = nextPage->links().value(Node::NextLink).first;
+ if(nextTitle.isEmpty())
+ break;
+ nextPage = const_cast<FakeNode *>(tree->findFakeNodeByTitle(nextTitle));
+ }
+ break;
}
- break;
}
}
- }
- if (!name.isEmpty())
- writer.writeEndElement(); // section
+ if (!name.isEmpty())
+ writer.writeEndElement(); // section
+ }
}
writer.writeEndElement(); // section
diff --git a/tools/qdoc3/helpprojectwriter.h b/tools/qdoc3/helpprojectwriter.h
index 511a9dd..7a67dff 100644
--- a/tools/qdoc3/helpprojectwriter.h
+++ b/tools/qdoc3/helpprojectwriter.h
@@ -60,6 +60,7 @@ struct SubProject
QString indexTitle;
QHash<Node::Type, QSet<FakeNode::SubType> > selectors;
bool sortPages;
+ QString type;
QHash<QString, const Node *> nodes;
};
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index a3cdae6..76ee4e8 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -44,6 +44,7 @@
*/
#include "codemarker.h"
+#include "codeparser.h"
#include "helpprojectwriter.h"
#include "htmlgenerator.h"
#include "node.h"
@@ -54,10 +55,19 @@
#include <qdebug.h>
#include <qlist.h>
#include <qiterator.h>
+#include <qtextcodec.h>
QT_BEGIN_NAMESPACE
#define COMMAND_VERSION Doc::alias("version")
+int HtmlGenerator::id = 0;
+bool HtmlGenerator::debugging_on = false;
+
+#if 0
+QString HtmlGenerator::divNavTop = "<div class=\"navTop\"><a href=\"#toc\"><img src=\"./images/bullet_up.png\"></a></div>";
+#endif
+
+QString HtmlGenerator::divNavTop = "";
QString HtmlGenerator::sinceTitles[] =
{
@@ -71,6 +81,7 @@ QString HtmlGenerator::sinceTitles[] =
" New Typedefs",
" New Properties",
" New Variables",
+ " New QML Elements",
" New Qml Properties",
" New Qml Signals",
" New Qml Methods",
@@ -201,10 +212,18 @@ static void addLink(const QString &linkTarget,
HtmlGenerator::HtmlGenerator()
- : helpProjectWriter(0), inLink(false), inContents(false),
- inSectionHeading(false), inTableHeader(false), numTableRows(0),
- threeColumnEnumValueTable(true), funcLeftParen("\\S(\\()"),
- myTree(0), slow(false), obsoleteLinks(false)
+ : helpProjectWriter(0),
+ inLink(false),
+ inContents(false),
+ inSectionHeading(false),
+ inTableHeader(false),
+ numTableRows(0),
+ threeColumnEnumValueTable(true),
+ application(Online),
+ funcLeftParen("\\S(\\()"),
+ myTree(0),
+ slow(false),
+ obsoleteLinks(false)
{
}
@@ -248,6 +267,15 @@ void HtmlGenerator::initializeGenerator(const Config &config)
postHeader = config.getString(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_POSTHEADER);
+ postPostHeader = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_POSTPOSTHEADER);
+ creatorPostHeader = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_CREATORPOSTHEADER);
+ creatorPostPostHeader = config.getString(HtmlGenerator::format() +
+ Config::dot +
+ HTMLGENERATOR_CREATORPOSTPOSTHEADER);
footer = config.getString(HtmlGenerator::format() +
Config::dot +
HTMLGENERATOR_FOOTER);
@@ -260,12 +288,29 @@ void HtmlGenerator::initializeGenerator(const Config &config)
project = config.getString(CONFIG_PROJECT);
+ QString app = config.getString(CONFIG_APPLICATION);
+ if (app == "online")
+ application = Online;
+ else if (app == "creator")
+ application = Creator;
+ else
+ application = Creator;
+
projectDescription = config.getString(CONFIG_DESCRIPTION);
if (projectDescription.isEmpty() && !project.isEmpty())
projectDescription = project + " Reference Documentation";
projectUrl = config.getString(CONFIG_URL);
+ outputEncoding = config.getString(CONFIG_OUTPUTENCODING);
+ if (outputEncoding.isEmpty())
+ outputEncoding = QLatin1String("ISO-8859-1");
+ outputCodec = QTextCodec::codecForName(outputEncoding.toLocal8Bit());
+
+ naturalLanguage = config.getString(CONFIG_NATURALLANGUAGE);
+ if (naturalLanguage.isEmpty())
+ naturalLanguage = QLatin1String("en");
+
QSet<QString> editionNames = config.subVars(CONFIG_EDITION);
QSet<QString>::ConstIterator edition = editionNames.begin();
while (edition != editionNames.end()) {
@@ -321,16 +366,6 @@ QString HtmlGenerator::format()
*/
void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
{
- // Copy the stylesheets from the directory containing the qdocconf file.
- // ### This should be changed to use a special directory in doc/src.
- QStringList::ConstIterator styleIter = stylesheets.begin();
- QDir configPath = QDir::current();
- while (styleIter != stylesheets.end()) {
- QString filePath = configPath.absoluteFilePath(*styleIter);
- Config::copyFile(Location(), filePath, filePath, outputDir());
- ++styleIter;
- }
-
myTree = tree;
nonCompatClasses.clear();
mainClasses.clear();
@@ -341,13 +376,11 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
funcIndex.clear();
legaleseTexts.clear();
serviceClasses.clear();
+ qmlClasses.clear();
findAllClasses(tree->root());
findAllFunctions(tree->root());
findAllLegaleseTexts(tree->root());
findAllNamespaces(tree->root());
-#ifdef ZZZ_QDOC_QML
- findAllQmlClasses(tree->root());
-#endif
findAllSince(tree->root());
PageGenerator::generateTree(tree, marker);
@@ -389,9 +422,9 @@ void HtmlGenerator::generateTree(const Tree *tree, CodeMarker *marker)
"qmake Manual",
dcfQmakeRoot);
- generateIndex(project.toLower().simplified().replace(" ", "-"),
- projectUrl,
- projectDescription);
+ QString fileBase = project.toLower().simplified().replace(" ", "-");
+ generateIndex(fileBase, projectUrl, projectDescription);
+ generatePageIndex(outputDir() + "/" + fileBase + ".pageindex", marker);
helpProjectWriter->generate(myTree);
}
@@ -409,6 +442,9 @@ void HtmlGenerator::startText(const Node * /* relative */,
sectionNumber.clear();
}
+/*!
+ Generate html from an instance of Atom.
+ */
int HtmlGenerator::generateAtom(const Atom *atom,
const Node *relative,
CodeMarker *marker)
@@ -431,11 +467,11 @@ int HtmlGenerator::generateAtom(const Atom *atom,
endLink();
}
else {
- out() << protect(atom->string());
+ out() << protectEnc(atom->string());
}
}
else {
- out() << protect(atom->string());
+ out() << protectEnc(atom->string());
}
break;
case Atom::BaseName:
@@ -483,7 +519,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::C:
out() << formattingLeftMap()[ATOM_FORMATTING_TELETYPE];
if (inLink) {
- out() << protect(plainCode(atom->string()));
+ out() << protectEnc(plainCode(atom->string()));
}
else {
out() << highlightedCode(atom->string(), marker, relative);
@@ -491,22 +527,22 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
break;
case Atom::Code:
- out() << "<pre>"
+ out() << "<pre class=\"highlightedCode brush: cpp\">"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "</pre>\n";
- break;
+ break;
#ifdef QDOC_QML
case Atom::Qml:
- out() << "<pre>"
+ out() << "<pre class=\"highlightedCode brush: cpp\">"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "</pre>\n";
- break;
+ break;
#endif
case Atom::CodeNew:
out() << "<p>you can rewrite it as</p>\n"
- << "<pre>"
+ << "<pre class=\"highlightedCode brush: cpp\">"
<< trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
marker,relative))
<< "</pre>\n";
@@ -515,10 +551,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << "<p>For example, if you have code like</p>\n";
// fallthrough
case Atom::CodeBad:
- out() << "<pre><font color=\"#404040\">"
- << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
- << "</font></pre>\n";
- break;
+ out() << "<pre class=\"highlightedCode brush: cpp\">"
+ << trimmedTrailing(protectEnc(plainCode(indent(codeIndent,atom->string()))))
+ << "</pre>\n";
+ break;
case Atom::FootnoteLeft:
// ### For now
if (in_para) {
@@ -574,7 +610,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
generateAnnotatedList(relative, marker, nonCompatClasses);
}
else if (atom->string() == "classes") {
- generateCompactList(relative, marker, nonCompatClasses);
+ generateCompactList(relative, marker, nonCompatClasses, true);
+ }
+ else if (atom->string() == "qmlclasses") {
+ generateCompactList(relative, marker, qmlClasses, true);
}
else if (atom->string().contains("classesbymodule")) {
QString arg = atom->string().trimmed();
@@ -622,10 +661,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
generateClassHierarchy(relative, marker, nonCompatClasses);
}
else if (atom->string() == "compatclasses") {
- generateCompactList(relative, marker, compatClasses);
+ generateCompactList(relative, marker, compatClasses, false);
}
else if (atom->string() == "obsoleteclasses") {
- generateCompactList(relative, marker, obsoleteClasses);
+ generateCompactList(relative, marker, obsoleteClasses, false);
}
else if (atom->string() == "functionindex") {
generateFunctionIndex(relative, marker);
@@ -634,10 +673,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
generateLegaleseList(relative, marker);
}
else if (atom->string() == "mainclasses") {
- generateCompactList(relative, marker, mainClasses);
+ generateCompactList(relative, marker, mainClasses, true);
}
else if (atom->string() == "services") {
- generateCompactList(relative, marker, serviceClasses);
+ generateCompactList(relative, marker, serviceClasses, false);
}
else if (atom->string() == "overviews") {
generateOverviewList(relative, marker);
@@ -676,16 +715,23 @@ int HtmlGenerator::generateAtom(const Atom *atom,
nsmap = newSinceMaps.find(atom->string());
NewClassMaps::const_iterator ncmap;
ncmap = newClassMaps.find(atom->string());
+ NewClassMaps::const_iterator nqcmap;
+ nqcmap = newQmlClassMaps.find(atom->string());
if ((nsmap != newSinceMaps.constEnd()) && !nsmap.value().isEmpty()) {
QList<Section> sections;
QList<Section>::ConstIterator s;
for (int i=0; i<LastSinceType; ++i)
- sections.append(Section(sinceTitle(i),QString(),QString()));
+ sections.append(Section(sinceTitle(i),QString(),QString(),QString()));
NodeMultiMap::const_iterator n = nsmap.value().constBegin();
while (n != nsmap.value().constEnd()) {
const Node* node = n.value();
switch (node->type()) {
+ case Node::Fake:
+ if (node->subType() == Node::QmlClass) {
+ sections[QmlClass].appendMember((Node*)node);
+ }
+ break;
case Node::Namespace:
sections[Namespace].appendMember((Node*)node);
break;
@@ -768,9 +814,11 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << "<a name=\""
<< Doc::canonicalTitle((*s).name)
<< "\"></a>\n";
- out() << "<h3>" << protect((*s).name) << "</h3>\n";
+ out() << "<h3>" << protectEnc((*s).name) << "</h3>\n";
if (idx == Class)
- generateCompactList(0, marker, ncmap.value(), QString("Q"));
+ generateCompactList(0, marker, ncmap.value(), false, QString("Q"));
+ else if (idx == QmlClass)
+ generateCompactList(0, marker, nqcmap.value(), false, QString("Q"));
else if (idx == MemberFunction) {
ParentMaps parentmaps;
ParentMaps::iterator pmap;
@@ -792,11 +840,11 @@ int HtmlGenerator::generateAtom(const Atom *atom,
<< linkForNode(pmap.key(), 0)
<< "\">";
QStringList pieces = fullName(pmap.key(), 0, marker).split("::");
- out() << protect(pieces.last());
+ out() << protectEnc(pieces.last());
out() << "</a>" << ":</p>\n";
generateSection(nlist, 0, marker, CodeMarker::Summary);
- out() << "<br />";
+ out() << "<br/>";
++pmap;
}
}
@@ -817,15 +865,15 @@ int HtmlGenerator::generateAtom(const Atom *atom,
if (atom->next() != 0)
text = atom->next()->string();
if (atom->type() == Atom::Image)
- out() << "<p align=\"center\">";
+ out() << "<p class=\"centerAlign\">";
if (fileName.isEmpty()) {
out() << "<font color=\"red\">[Missing image "
- << protect(atom->string()) << "]</font>";
+ << protectEnc(atom->string()) << "]</font>";
}
else {
- out() << "<img src=\"" << protect(fileName) << "\"";
+ out() << "<img src=\"" << protectEnc(fileName) << "\"";
if (!text.isEmpty())
- out() << " alt=\"" << protect(text) << "\"";
+ out() << " alt=\"" << protectEnc(text) << "\"";
out() << " />";
helpProjectWriter->addExtraFile(fileName);
}
@@ -836,13 +884,13 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::ImageText:
break;
case Atom::LegaleseLeft:
- out() << "<div style=\"padding: 0.5em; background: #e0e0e0; color: black\">";
+ out() << "<div class=\"LegaleseLeft\">";
break;
case Atom::LegaleseRight:
out() << "</div>";
break;
case Atom::LineBreak:
- out() << "<br />";
+ out() << "<br/>";
break;
case Atom::Link:
{
@@ -878,24 +926,26 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
- out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
- << "cellspacing=\"1\" width=\"100%\">\n"
- << "<tr><th width=\"25%\">Constant</th>"
- << "<th width=\"15%\">Value</th>"
- << "<th width=\"60%\">Description</th></tr>\n";
+ out() << "<table class=\"valuelist\">";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+
+ out() << "<th class=\"tblConst\">Constant</th>"
+ << "<th class=\"tblval\">Value</th>"
+ << "<th class=\"tbldscr\">Description</th></tr>\n";
}
else {
- out() << "<p><table class=\"valuelist\" border=\"1\" cellpadding=\"2\" "
- << "cellspacing=\"1\" width=\"40%\">\n"
- << "<tr><th width=\"60%\">Constant</th><th "
- << "width=\"40%\">Value</th></tr>\n";
+ out() << "<table class=\"valuelist\">"
+ << "<tr><th class=\"tblConst\">Constant</th><th class=\"tblVal\">Value</th></tr>\n";
}
}
else {
- out() << "<ol type=";
+ out() << "<ol class=";
if (atom->string() == ATOM_LIST_UPPERALPHA) {
out() << "\"A\"";
- }
+ } /* why type? changed to */
else if (atom->string() == ATOM_LIST_LOWERALPHA) {
out() << "\"a\"";
}
@@ -922,10 +972,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else { // (atom->string() == ATOM_LIST_VALUE)
// ### Trenton
- out() << "<tr><td valign=\"top\"><tt>"
- << protect(plainCode(marker->markedUpEnumValue(atom->next()->string(),
+ out() << "<tr><td class=\"topAlign\"><tt>"
+ << protectEnc(plainCode(marker->markedUpEnumValue(atom->next()->string(),
relative)))
- << "</tt></td><td align=\"center\" valign=\"top\">";
+ << "</tt></td><td class=\" topAlign\">";
QString itemValue;
if (relative->type() == Node::Enum) {
@@ -936,7 +986,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
if (itemValue.isEmpty())
out() << "?";
else
- out() << "<tt>" << protect(itemValue) << "</tt>";
+ out() << "<tt>" << protectEnc(itemValue) << "</tt>";
skipAhead = 1;
}
@@ -951,7 +1001,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
else if (atom->string() == ATOM_LIST_VALUE) {
if (threeColumnEnumValueTable) {
- out() << "</td><td valign=\"top\">";
+ out() << "</td><td class=\"topAlign\">";
if (matchAhead(atom, Atom::ListItemRight))
out() << "&nbsp;";
}
@@ -981,7 +1031,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << "</dl>\n";
}
else if (atom->string() == ATOM_LIST_VALUE) {
- out() << "</table></p>\n";
+ out() << "</table>\n";
}
else {
out() << "</ol>\n";
@@ -1026,11 +1076,11 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
}
- out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>\n";
+ out() << "<a name=\"sec-" << sectionNumber.join("-") << "\"></a>" << divNavTop << "\n";
}
#else
out() << "<a name=\"" << Doc::canonicalTitle(Text::sectionHeading(atom).toString())
- << "\"></a>\n";
+ << "\"></a>" << divNavTop << "\n";
#endif
break;
case Atom::SectionRight:
@@ -1052,7 +1102,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
generateLink(atom, relative, marker);
}
else {
- out() << protect(atom->string());
+ out() << protectEnc(atom->string());
}
break;
case Atom::TableLeft:
@@ -1062,32 +1112,28 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
if (!atom->string().isEmpty()) {
if (atom->string().contains("%"))
- out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
- << "align=\"center\" cellpadding=\"2\" "
- << "cellspacing=\"1\" border=\"0\">\n";
+ out() << "<table class=\"generic\">\n "; // width=\"" << atom->string() << "\">\n ";
else {
- out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
- << "cellspacing=\"1\" border=\"0\">\n";
+ out() << "<table class=\"generic\">\n";
}
}
else {
- out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
- << "cellspacing=\"1\" border=\"0\">\n";
+ out() << "<table class=\"generic\">\n";
}
numTableRows = 0;
break;
case Atom::TableRight:
- out() << "</table></p>\n";
+ out() << "</table>\n";
break;
case Atom::TableHeaderLeft:
- out() << "<thead><tr valign=\"top\" class=\"qt-style\">";
+ out() << "<thead><tr class=\"qt-style topAlign\">";
inTableHeader = true;
break;
case Atom::TableHeaderRight:
out() << "</tr>";
if (matchAhead(atom, Atom::TableHeaderLeft)) {
skipAhead = 1;
- out() << "\n<tr valign=\"top\" class=\"qt-style\">";
+ out() << "\n<tr class=\"qt-style topAlign\">";
}
else {
out() << "</thead>\n";
@@ -1096,9 +1142,9 @@ int HtmlGenerator::generateAtom(const Atom *atom,
break;
case Atom::TableRowLeft:
if (++numTableRows % 2 == 1)
- out() << "<tr valign=\"top\" class=\"odd\">";
+ out() << "<tr class=\"odd topAlign\">";
else
- out() << "<tr valign=\"top\" class=\"even\">";
+ out() << "<tr class=\"even topAlign\">";
break;
case Atom::TableRowRight:
out() << "</tr>\n";
@@ -1106,9 +1152,9 @@ int HtmlGenerator::generateAtom(const Atom *atom,
case Atom::TableItemLeft:
{
if (inTableHeader)
- out() << "<th";
+ out() << "<th ";
else
- out() << "<td";
+ out() << "<td ";
QStringList spans = atom->string().split(",");
if (spans.size() == 2) {
@@ -1116,7 +1162,10 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << " colspan=\"" << spans.at(0) << "\"";
if (spans.at(1) != "1")
out() << " rowspan=\"" << spans.at(1) << "\"";
+ if (inTableHeader)
out() << ">";
+ else
+ out() << "><p>";
}
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
@@ -1126,7 +1175,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
if (inTableHeader)
out() << "</th>";
else
- out() << "</td>";
+ out() << "</p></td>";
if (matchAhead(atom, Atom::ParaLeft))
skipAhead = 1;
break;
@@ -1163,11 +1212,11 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << "<a name=\"" << Doc::canonicalTitle(atom->string()) << "\"></a>";
break;
case Atom::UnhandledFormat:
- out() << "<font color=\"red\"><b>&lt;Missing HTML&gt;</b></font>";
+ out() << "<b class=\"redFont\">&lt;Missing HTML&gt;</b>";
break;
case Atom::UnknownCommand:
- out() << "<font color=\"red\"><b><code>\\" << protect(atom->string())
- << "</code></b></font>";
+ out() << "<b class=\"redFont\"><code>\\" << protectEnc(atom->string())
+ << "</code></b>";
break;
#ifdef QDOC_QML
case Atom::QmlText:
@@ -1181,6 +1230,9 @@ int HtmlGenerator::generateAtom(const Atom *atom,
return skipAhead;
}
+/*!
+ Generate a reference page for a C++ class.
+ */
void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
CodeMarker *marker)
{
@@ -1197,7 +1249,7 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
namespasse = static_cast<const NamespaceNode *>(inner);
rawTitle = marker->plainName(inner);
fullTitle = marker->plainFullName(inner);
- title = rawTitle + " Namespace Reference";
+ title = rawTitle + " Namespace";
}
else if (inner->type() == Node::Class) {
classe = static_cast<const ClassNode *>(inner);
@@ -1216,43 +1268,21 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
subtitleText << "(" << Atom(Atom::AutoLink, fullTitle) << ")"
<< Atom(Atom::LineBreak);
- QString fixedModule = inner->moduleName();
- if (fixedModule == "Qt3SupportLight")
- fixedModule = "Qt3Support";
- if (!fixedModule.isEmpty())
- subtitleText << "[" << Atom(Atom::AutoLink, fixedModule) << " module]";
-
- if (fixedModule.isEmpty()) {
- QMultiMap<QString, QString> publicGroups = myTree->publicGroups();
- QList<QString> groupNames = publicGroups.values(inner->name());
- if (!groupNames.isEmpty()) {
- qSort(groupNames.begin(), groupNames.end());
- subtitleText << "[";
- for (int j=0; j<groupNames.count(); j++) {
- subtitleText << Atom(Atom::AutoLink, groupNames[j]);
- if (j<groupNames.count()-1)
- subtitleText <<", ";
- }
- subtitleText << "]";
- }
- }
-
- generateHeader(title, inner, marker, true);
- generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
-
-#ifdef QDOC_QML
- if (classe && !classe->qmlElement().isEmpty()) {
- generateInstantiatedBy(classe,marker);
- }
-#endif
-
+ generateHeader(title, inner, marker);
+ sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
+ generateTableOfContents(inner,marker,&sections);
+ generateTitle(title, subtitleText, SmallSubTitle, inner, marker);
generateBrief(inner, marker);
generateIncludes(inner, marker);
generateStatus(inner, marker);
if (classe) {
- generateModuleWarning(classe, marker);
generateInherits(classe, marker);
generateInheritedBy(classe, marker);
+#ifdef QDOC_QML
+ if (!classe->qmlElement().isEmpty()) {
+ generateInstantiatedBy(classe,marker);
+ }
+#endif
}
generateThreadSafeness(inner, marker);
generateSince(inner, marker);
@@ -1282,7 +1312,9 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
bool needOtherSection = false;
- sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
+ /*
+ sections is built above for the call to generateTableOfContents().
+ */
s = sections.begin();
while (s != sections.end()) {
if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
@@ -1291,26 +1323,26 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
}
else {
if (!s->members.isEmpty()) {
- out() << "<hr />\n";
+ // out() << "<hr />\n";
out() << "<a name=\""
<< registerRef((*s).name.toLower())
- << "\"></a>\n";
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ << "\"></a>" << divNavTop << "\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
generateSection(s->members, inner, marker, CodeMarker::Summary);
}
if (!s->reimpMembers.isEmpty()) {
QString name = QString("Reimplemented ") + (*s).name;
- out() << "<hr />\n";
+ // out() << "<hr />\n";
out() << "<a name=\""
<< registerRef(name.toLower())
- << "\"></a>\n";
- out() << "<h2>" << protect(name) << "</h2>\n";
+ << "\"></a>" << divNavTop << "\n";
+ out() << "<h2>" << protectEnc(name) << "</h2>\n";
generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
}
if (!s->inherited.isEmpty()) {
out() << "<ul>\n";
- generateSectionInheritedList(*s, inner, marker, true);
+ generateSectionInheritedList(*s, inner, marker);
out() << "</ul>\n";
}
}
@@ -1330,20 +1362,26 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
out() << "</ul>\n";
}
- out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
if (!inner->doc().isEmpty()) {
- out() << "<hr />\n"
+ generateExtractionMark(inner, DetailedDescriptionMark);
+ //out() << "<hr />\n"
+ out() << "<div class=\"descr\">\n" // QTBUG-9504
<< "<h2>" << "Detailed Description" << "</h2>\n";
generateBody(inner, marker);
+ out() << "</div>\n"; // QTBUG-9504
generateAlsoList(inner, marker);
+ generateExtractionMark(inner, EndMark);
}
sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
- out() << "<hr />\n";
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ //out() << "<hr />\n";
+ if (!(*s).divClass.isEmpty())
+ out() << "<div class=\"" << (*s).divClass << "\">\n"; // QTBUG-9504
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
NodeList::ConstIterator m = (*s).members.begin();
while (m != (*s).members.end()) {
@@ -1392,6 +1430,8 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
}
++m;
}
+ if (!(*s).divClass.isEmpty())
+ out() << "</div>\n"; // QTBUG-9504
++s;
}
generateFooter(inner);
@@ -1418,6 +1458,10 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
appendDcfSubSection(&dcfClassesRoot, classSection);
}
+/*!
+ Generate the html page for a qdoc file that doesn't map
+ to an underlying c++ file.
+ */
void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
{
SubTitleSize subTitleSize = LargeSubTitle;
@@ -1428,14 +1472,33 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
QList<Section> sections;
QList<Section>::const_iterator s;
- QString htmlTitle = fake->fullTitle();
+ QString fullTitle = fake->fullTitle();
+ QString htmlTitle = fullTitle;
if (fake->subType() == Node::File && !fake->subTitle().isEmpty()) {
subTitleSize = SmallSubTitle;
htmlTitle += " (" + fake->subTitle() + ")";
}
+ else if (fake->subType() == Node::QmlBasicType) {
+ fullTitle = "QML Basic Type: " + fullTitle;
+ htmlTitle = fullTitle;
+ }
+
+ generateHeader(htmlTitle, fake, marker);
+
+ /*
+ Generate the TOC for the new doc format.
+ Don't generate a TOC for the home page.
+ */
+ const QmlClassNode* qml_cn = 0;
+ if (fake->subType() == Node::QmlClass) {
+ qml_cn = static_cast<const QmlClassNode*>(fake);
+ sections = marker->qmlSections(qml_cn,CodeMarker::Summary,0);
+ generateTableOfContents(fake,marker,&sections);
+ }
+ else if (fake->name() != QString("index.html"))
+ generateTableOfContents(fake,marker,0);
- generateHeader(htmlTitle, fake, marker, true);
- generateTitle(fake->fullTitle(),
+ generateTitle(fullTitle,
Text() << fake->subTitle(),
subTitleSize,
fake,
@@ -1447,10 +1510,12 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
generateStatus(fake, marker);
if (moduleNamespaceMap.contains(fake->name())) {
+ out() << "<a name=\"" << registerRef("namespaces") << "\"></a>" << divNavTop << "\n";
out() << "<h2>Namespaces</h2>\n";
generateAnnotatedList(fake, marker, moduleNamespaceMap[fake->name()]);
}
if (moduleClassMap.contains(fake->name())) {
+ out() << "<a name=\"" << registerRef("classes") << "\"></a>" << divNavTop << "\n";
out() << "<h2>Classes</h2>\n";
generateAnnotatedList(fake, marker, moduleClassMap[fake->name()]);
}
@@ -1504,36 +1569,45 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
}
#ifdef QDOC_QML
else if (fake->subType() == Node::QmlClass) {
- const QmlClassNode* qml_cn = static_cast<const QmlClassNode*>(fake);
const ClassNode* cn = qml_cn->classNode();
+ generateBrief(qml_cn, marker);
generateQmlInherits(qml_cn, marker);
+ generateQmlInheritedBy(qml_cn, marker);
generateQmlInstantiates(qml_cn, marker);
- generateBrief(qml_cn, marker);
- sections = marker->qmlSections(qml_cn,CodeMarker::Summary);
+
+ QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker);
+ if (!allQmlMembersLink.isEmpty()) {
+ out() << "<li><a href=\"" << allQmlMembersLink << "\">"
+ << "List of all members, including inherited members</a></li>\n";
+ }
+
s = sections.begin();
while (s != sections.end()) {
- out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ out() << "<a name=\"" << registerRef((*s).name.toLower())
+ << "\"></a>" << divNavTop << "\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
generateQmlSummary(*s,fake,marker);
++s;
}
- out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ generateExtractionMark(fake, DetailedDescriptionMark);
+ out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
out() << "<h2>" << "Detailed Description" << "</h2>\n";
generateBody(fake, marker);
if (cn)
generateQmlText(cn->doc().body(), cn, marker, fake->name());
generateAlsoList(fake, marker);
- out() << "<hr />\n";
+ generateExtractionMark(fake, EndMark);
+ //out() << "<hr />\n";
- sections = marker->qmlSections(qml_cn,CodeMarker::Detailed);
+ sections = marker->qmlSections(qml_cn,CodeMarker::Detailed,0);
s = sections.begin();
while (s != sections.end()) {
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
NodeList::ConstIterator m = (*s).members.begin();
while (m != (*s).members.end()) {
generateDetailedQmlMember(*m, fake, marker);
- out() << "<br />\n";
+ out() << "<br/>\n";
fakeSection.keywords += qMakePair((*m)->name(),
linkForNode(*m,0));
++m;
@@ -1548,20 +1622,28 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
sections = marker->sections(fake, CodeMarker::Summary, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
- out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ out() << "<a name=\"" << registerRef((*s).name) << "\"></a>" << divNavTop << "\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
generateSectionList(*s, fake, marker, CodeMarker::Summary);
++s;
}
Text brief = fake->doc().briefText();
if (fake->subType() == Node::Module && !brief.isEmpty()) {
- out() << "<a name=\"" << registerRef("details") << "\"></a>\n";
+ generateExtractionMark(fake, DetailedDescriptionMark);
+ out() << "<a name=\"" << registerRef("details") << "\"></a>" << divNavTop << "\n";
+ out() << "<div class=\"descr\">\n"; // QTBUG-9504
out() << "<h2>" << "Detailed Description" << "</h2>\n";
}
+ else {
+ generateExtractionMark(fake, DetailedDescriptionMark);
+ out() << "<div class=\"descr\"> <a name=\"" << registerRef("details") << "\"></a>\n"; // QTBUG-9504
+ }
generateBody(fake, marker);
+ out() << "</div>\n"; // QTBUG-9504
generateAlsoList(fake, marker);
+ generateExtractionMark(fake, EndMark);
if (!fake->groupMembers().isEmpty()) {
NodeMap groupMembersMap;
@@ -1577,8 +1659,8 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
sections = marker->sections(fake, CodeMarker::Detailed, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
- out() << "<hr />\n";
- out() << "<h2>" << protect((*s).name) << "</h2>\n";
+ //out() << "<hr />\n";
+ out() << "<h2>" << protectEnc((*s).name) << "</h2>\n";
NodeList::ConstIterator m = (*s).members.begin();
while (m != (*s).members.end()) {
@@ -1614,55 +1696,185 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
}
}
-QString HtmlGenerator::fileExtension(const Node * /* node */)
+/*!
+ Returns "html" for this subclass of Generator.
+ */
+QString HtmlGenerator::fileExtension(const Node * /* node */) const
{
return "html";
}
+/*!
+ Output breadcrumb list in the html file.
+ */
+void HtmlGenerator::generateBreadCrumbs(const QString& title,
+ const Node *node,
+ CodeMarker *marker)
+{
+ Text breadcrumb;
+ if (node->type() == Node::Class) {
+ const ClassNode* cn = static_cast<const ClassNode*>(node);
+ QString name = node->moduleName();
+ out() << " <li><a href=\"modules.html\">Modules</a></li>";
+ if (!name.isEmpty()) {
+ out() << " <li>";
+ breadcrumb << Atom(Atom::AutoLink,name);
+ generateText(breadcrumb, node, marker);
+ out() << "</li>\n";
+ }
+ if (!cn->name().isEmpty())
+ out() << " <li>" << protectEnc(cn->name()) << "</li>\n";
+ }
+ else if (node->type() == Node::Fake) {
+ const FakeNode* fn = static_cast<const FakeNode*>(node);
+ if (node->subType() == Node::Module) {
+ out() << " <li><a href=\"modules.html\">Modules</a></li>";
+ QString name = node->name();
+ if (!name.isEmpty())
+ out() << " <li>" << protectEnc(name) << "</li>\n";
+ }
+ else if (node->subType() == Node::Group) {
+ if (fn->name() == QString("modules"))
+ out() << " <li>Modules</li>";
+ else {
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+ }
+ else if (node->subType() == Node::Page) {
+ if (fn->name() == QString("qdeclarativeexamples.html")) {
+ out() << " <li><a href=\"all-examples.html\">Examples</a></li>";
+ out() << " <li>QML Examples &amp; Demos</li>";
+ }
+ else if (fn->name().startsWith("examples-")) {
+ out() << " <li><a href=\"all-examples.html\">Examples</a></li>";
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+ else if (fn->name() == QString("namespaces.html")) {
+ out() << " <li>Namespaces</li>";
+ }
+ else {
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+ }
+ else if (node->subType() == Node::QmlClass) {
+ out() << " <li><a href=\"qdeclarativeelements.html\">QML Elements</a></li>";
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+ else if (node->subType() == Node::Example) {
+ out() << " <li><a href=\"all-examples.html\">Examples</a></li>";
+ QStringList sl = fn->name().split('/');
+ if (sl.contains("declarative"))
+ out() << " <li><a href=\"qdeclarativeexamples.html\">QML Examples &amp; Demos</a></li>";
+ else {
+ QString name = protectEnc("examples-" + sl.at(0) + ".html"); // this generates an empty link
+ QString t = CodeParser::titleFromName(name);
+ }
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+ }
+ else if (node->type() == Node::Namespace) {
+ out() << " <li><a href=\"namespaces.html\">Namespaces</a></li>";
+ out() << " <li>" << protectEnc(title) << "</li>";
+ }
+}
+
void HtmlGenerator::generateHeader(const QString& title,
const Node *node,
- CodeMarker *marker,
- bool mainPage)
+ CodeMarker *marker)
{
- out() << "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>\n";
-
- out() << "<!DOCTYPE html\n"
- " PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"DTD/xhtml1-strict.dtd\">\n"
- "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n";
-
+ out() << QString("<?xml version=\"1.0\" encoding=\"%1\"?>\n").arg(outputEncoding);
+ out() << "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n";
+ out() << QString("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"%1\" lang=\"%1\">\n").arg(naturalLanguage);
+ out() << "<head>\n";
+ out() << " <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n";
QString shortVersion;
- if ((project != "Qtopia") && (project != "Qt Extended")) {
- shortVersion = project + " " + shortVersion + ": ";
- if (node && !node->doc().location().isEmpty())
- out() << "<!-- " << node->doc().location().fileName() << " -->\n";
-
- shortVersion = myTree->version();
- if (shortVersion.count(QChar('.')) == 2)
- shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
- if (!shortVersion.isEmpty()) {
- if (project == "QSA")
- shortVersion = "QSA " + shortVersion + ": ";
- else
- shortVersion = "Qt " + shortVersion + ": ";
- }
+ shortVersion = project + " " + shortVersion + ": ";
+ if (node && !node->doc().location().isEmpty())
+ out() << "<!-- " << node->doc().location().fileName() << " -->\n";
+
+ shortVersion = myTree->version();
+ if (shortVersion.count(QChar('.')) == 2)
+ shortVersion.truncate(shortVersion.lastIndexOf(QChar('.')));
+ if (!shortVersion.isEmpty()) {
+ if (project == "QSA")
+ shortVersion = "QSA " + shortVersion + ": ";
+ else
+ shortVersion = "Qt " + shortVersion + ": ";
+ }
+
+ // Generating page title
+ out() << " <title>" << shortVersion << protectEnc(title) << "</title>\n";
+ // Adding style sheet
+ out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/style.css\" />\n";
+ // Adding jquery and functions - providing online tools and search features
+ out() << " <script src=\"scripts/jquery.js\" type=\"text/javascript\"></script>\n";
+ out() << " <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
+
+
+ // Adding syntax highlighter // future release
+
+ // Setting some additional style sheet related details depending on configuration (e.g. Online/Creator)
+
+ switch (application) {
+ case Online:
+ // Adding style and js for small windows
+ out() << " <script src=\"./scripts/superfish.js\" type=\"text/javascript\"></script>\n";
+ out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/superfish.css\" />";
+ out() << " <script src=\"./scripts/narrow.js\" type=\"text/javascript\"></script>\n";
+ out() << " <link rel=\"stylesheet\" type=\"text/css\" href=\"style/narrow.css\" />\n";
+ // Browser spec styles
+ out() << " <!--[if IE]>\n";
+ out() << "<meta name=\"MSSmartTagsPreventParsing\" content=\"true\">\n";
+ out() << "<meta http-equiv=\"imagetoolbar\" content=\"no\">\n";
+ out() << "<![endif]-->\n";
+ out() << "<!--[if lt IE 7]>\n";
+ out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie6.css\">\n";
+ out() << "<![endif]-->\n";
+ out() << "<!--[if IE 7]>\n";
+ out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie7.css\">\n";
+ out() << "<![endif]-->\n";
+ out() << "<!--[if IE 8]>\n";
+ out() << "<link rel=\"stylesheet\" type=\"text/css\" href=\"style/style_ie8.css\">\n";
+ out() << "<![endif]-->\n";
+
+ out() << "</head>\n";
+ // CheckEmptyAndLoadList activating search
+ out() << "<body class=\"\" onload=\"CheckEmptyAndLoadList();\">\n";
+ break;
+ case Creator:
+ out() << "</head>\n";
+ out() << "<body class=\"offline narrow creator\">\n"; // offline narrow
+ break;
+ default:
+ out() << "</head>\n";
+ out() << "<body>\n";
+ break;
}
- out() << "<head>\n"
- " <title>" << shortVersion << protect(title) << "</title>\n";
- if (!style.isEmpty())
- out() << " <style type=\"text/css\">" << style << "</style>\n";
-
- const QMap<QString, QString> &metaMap = node->doc().metaTagMap();
- if (!metaMap.isEmpty()) {
- QMapIterator<QString, QString> i(metaMap);
- while (i.hasNext()) {
- i.next();
- out() << " <meta name=\"" << protect(i.key()) << "\" contents=\""
- << protect(i.value()) << "\" />\n";
- }
+#ifdef GENERATE_MAC_REFS
+ if (mainPage)
+ generateMacRef(node, marker);
+#endif
+
+ switch (application) {
+ case Online:
+ out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ generateBreadCrumbs(title,node,marker);
+ out() << QString(postPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ break;
+ case Creator:
+ out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ generateBreadCrumbs(title,node,marker);
+ out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ break;
+ default: // default -- not used except if one forgets to set any of the above settings to true
+ out() << QString(creatorPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ generateBreadCrumbs(title,node,marker);
+ out() << QString(creatorPostPostHeader).replace("\\" + COMMAND_VERSION, myTree->version());
+ break;
}
- navigationLinks.clear();
+ navigationLinks.clear();
if (node && !node->links().empty()) {
QPair<QString,QString> linkPair;
@@ -1687,24 +1899,6 @@ void HtmlGenerator::generateHeader(const QString& title,
navigationLinks += protect(linkPair.second);
navigationLinks += "</a>]\n";
}
- if (node->links().contains(Node::ContentsLink)) {
- linkPair = node->links()[Node::ContentsLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
- if (!linkNode || linkNode == node)
- anchorPair = linkPair;
- else
- anchorPair = anchorForNode(linkNode);
-
- out() << " <link rel=\"contents\" href=\""
- << anchorPair.first << "\" />\n";
-
- navigationLinks += "[<a href=\"" + anchorPair.first + "\">";
- if (linkPair.first == linkPair.second && !anchorPair.second.isEmpty())
- navigationLinks += protect(anchorPair.second);
- else
- navigationLinks += protect(linkPair.second);
- navigationLinks += "</a>]\n";
- }
if (node->links().contains(Node::NextLink)) {
linkPair = node->links()[Node::NextLink];
linkNode = findNodeForTarget(linkPair.first, node, marker);
@@ -1723,16 +1917,6 @@ void HtmlGenerator::generateHeader(const QString& title,
navigationLinks += protect(linkPair.second);
navigationLinks += "</a>]\n";
}
- if (node->links().contains(Node::IndexLink)) {
- linkPair = node->links()[Node::IndexLink];
- linkNode = findNodeForTarget(linkPair.first, node, marker);
- if (!linkNode || linkNode == node)
- anchorPair = linkPair;
- else
- anchorPair = anchorForNode(linkNode);
- out() << " <link rel=\"index\" href=\""
- << anchorPair.first << "\" />\n";
- }
if (node->links().contains(Node::StartLink)) {
linkPair = node->links()[Node::StartLink];
linkNode = findNodeForTarget(linkPair.first, node, marker);
@@ -1745,24 +1929,8 @@ void HtmlGenerator::generateHeader(const QString& title,
}
}
- foreach (const QString &stylesheet, stylesheets) {
- out() << " <link href=\"" << stylesheet << "\" rel=\"stylesheet\" "
- << "type=\"text/css\" />\n";
- }
-
- foreach (const QString &customHeadElement, customHeadElements) {
- out() << " " << customHeadElement << "\n";
- }
-
- out() << "</head>\n"
- "<body>\n";
- if (mainPage)
- generateMacRef(node, marker);
- out() << QString(postHeader).replace("\\" + COMMAND_VERSION, myTree->version());
-
-
if (node && !node->links().empty())
- out() << "<p>\n" << navigationLinks << "</p>\n";
+ out() << "<p class=\"naviNextPrevious headerNavi\">\n" << navigationLinks << "</p><p/>\n";
}
void HtmlGenerator::generateTitle(const QString& title,
@@ -1771,28 +1939,51 @@ void HtmlGenerator::generateTitle(const QString& title,
const Node *relative,
CodeMarker *marker)
{
- out() << "<h1 class=\"title\">" << protect(title);
+ if (!title.isEmpty())
+ out() << "<h1 class=\"title\">" << protectEnc(title) << "</h1>\n";
if (!subTitle.isEmpty()) {
- out() << "<br />";
+ out() << "<span";
if (subTitleSize == SmallSubTitle)
- out() << "<span class=\"small-subtitle\">";
+ out() << " class=\"small-subtitle\">";
else
- out() << "<span class=\"subtitle\">";
+ out() << " class=\"subtitle\">";
generateText(subTitle, relative, marker);
out() << "</span>\n";
}
- out() << "</h1>\n";
}
void HtmlGenerator::generateFooter(const Node *node)
{
if (node && !node->links().empty())
- out() << "<p>\n" << navigationLinks << "</p>\n";
+ out() << "<p class=\"naviNextPrevious footerNavi\">\n" << navigationLinks << "</p>\n";
out() << QString(footer).replace("\\" + COMMAND_VERSION, myTree->version())
- << QString(address).replace("\\" + COMMAND_VERSION, myTree->version())
- << "</body>\n"
- "</html>\n";
+ << QString(address).replace("\\" + COMMAND_VERSION, myTree->version());
+
+ switch (application) {
+ case Online:
+ out() << " <script src=\"scripts/functions.js\" type=\"text/javascript\"></script>\n";
+ out() << " <script type=\"text/javascript\">\n";
+ out() << " var _gaq = _gaq || [];\n";
+ out() << " _gaq.push(['_setAccount', 'UA-4457116-5']);\n";
+ out() << " _gaq.push(['_trackPageview']);\n";
+ out() << " (function() {\n";
+ out() << " var ga = document.createElement('script'); ";
+ out() << "ga.type = 'text/javascript'; ga.async = true;\n";
+ out() << " ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + ";
+ out() << "'.google-analytics.com/ga.js';\n";
+ out() << " var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n";
+ out() << " })();\n";
+ out() << " </script>\n";
+ out() << "</body>\n";
+ break;
+ case Creator:
+ out() << "</body>\n";
+ break;
+ default:
+ out() << "</body>\n";
+ }
+ out() << "</html>\n";
}
void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
@@ -1800,20 +1991,25 @@ void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
{
Text brief = node->doc().briefText();
if (!brief.isEmpty()) {
+ generateExtractionMark(node, BriefMark);
out() << "<p>";
generateText(brief, node, marker);
+
if (!relative || node == relative)
out() << " <a href=\"#";
else
out() << " <a href=\"" << linkForNode(node, relative) << "#";
out() << registerRef("details") << "\">More...</a></p>\n";
+
+
+ generateExtractionMark(node, EndMark);
}
}
void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
{
if (!inner->includes().isEmpty()) {
- out() << "<pre>"
+ out() << "<pre class=\"highlightedCode brush: cpp\">"
<< trimmedTrailing(highlightedCode(indent(codeIndent,
marker->markedUpIncludes(inner->includes())),
marker,inner))
@@ -1821,6 +2017,9 @@ void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
}
}
+/*!
+ Generates a table of contents beginning at \a node.
+ */
void HtmlGenerator::generateTableOfContents(const Node *node,
CodeMarker *marker,
Doc::SectioningUnit sectioningUnit,
@@ -1828,6 +2027,7 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
const Node *relative)
{
+ return;
if (!node->doc().hasTableOfContents())
return;
QList<Atom *> toc = node->doc().tableOfContents();
@@ -1843,8 +2043,8 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
QString tdTag;
if (numColumns > 1) {
- tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
- out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
+ tdTag = "<td>"; /* width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";*/
+ out() << "<table class=\"toc\">\n<tr class=\"topAlign\">"
<< tdTag << "\n";
}
@@ -1896,8 +2096,125 @@ void HtmlGenerator::generateTableOfContents(const Node *node,
}
if (numColumns > 1)
- out() << "</td></tr></table></p>\n";
+ out() << "</td></tr></table>\n";
+
+ inContents = false;
+ inLink = false;
+}
+
+/*!
+ Revised for the new doc format.
+ Generates a table of contents beginning at \a node.
+ */
+void HtmlGenerator::generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ QList<Section>* sections)
+{
+ QList<Atom*> toc;
+ if (node->doc().hasTableOfContents())
+ toc = node->doc().tableOfContents();
+ if (toc.isEmpty() && !sections && (node->subType() != Node::Module))
+ return;
+
+ QStringList sectionNumber;
+ int detailsBase = 0;
+
+ // disable nested links in table of contents
+ inContents = true;
+ inLink = true;
+
+ out() << "<div class=\"toc\">\n";
+ out() << "<h3><a name=\"toc\">Contents</a></h3>\n";
+ sectionNumber.append("1");
+ out() << "<ul>\n";
+
+ if (node->subType() == Node::Module) {
+ if (moduleNamespaceMap.contains(node->name())) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><a href=\"#"
+ << registerRef("namespaces")
+ << "\">Namespaces</a></li>\n";
+ }
+ if (moduleClassMap.contains(node->name())) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><a href=\"#"
+ << registerRef("classes")
+ << "\">Classes</a></li>\n";
+ }
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><a href=\"#"
+ << registerRef("details")
+ << "\">Detailed Description</a></li>\n";
+ for (int i = 0; i < toc.size(); ++i) {
+ if (toc.at(i)->string().toInt() == 1) {
+ detailsBase = 1;
+ break;
+ }
+ }
+ }
+ else if (sections && ((node->type() == Node::Class) ||
+ (node->type() == Node::Namespace) ||
+ (node->subType() == Node::QmlClass))) {
+ QList<Section>::ConstIterator s = sections->begin();
+ while (s != sections->end()) {
+ if (!s->members.isEmpty() || !s->reimpMembers.isEmpty()) {
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><a href=\"#"
+ << registerRef((*s).pluralMember)
+ << "\">" << (*s).name
+ << "</a></li>\n";
+ }
+ ++s;
+ }
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\"><a href=\"#"
+ << registerRef("details")
+ << "\">Detailed Description</a></li>\n";
+ for (int i = 0; i < toc.size(); ++i) {
+ if (toc.at(i)->string().toInt() == 1) {
+ detailsBase = 1;
+ break;
+ }
+ }
+ }
+ for (int i = 0; i < toc.size(); ++i) {
+ Atom *atom = toc.at(i);
+ int nextLevel = atom->string().toInt() + detailsBase;
+ if (sectionNumber.size() < nextLevel) {
+ do {
+ sectionNumber.append("1");
+ } while (sectionNumber.size() < nextLevel);
+ }
+ else {
+ while (sectionNumber.size() > nextLevel) {
+ sectionNumber.removeLast();
+ }
+ sectionNumber.last() = QString::number(sectionNumber.last().toInt() + 1);
+ }
+ int numAtoms;
+ Text headingText = Text::sectionHeading(atom);
+ QString s = headingText.toString();
+ out() << "<li class=\"level"
+ << sectionNumber.size()
+ << "\">";
+ out() << "<a href=\""
+ << "#"
+ << Doc::canonicalTitle(s)
+ << "\">";
+ generateAtomList(headingText.firstAtom(), node, marker, true, numAtoms);
+ out() << "</a></li>\n";
+ }
+ while (!sectionNumber.isEmpty()) {
+ sectionNumber.removeLast();
+ }
+ out() << "</ul>\n";
+ out() << "</div>\n";
inContents = false;
inLink = false;
}
@@ -1909,7 +2226,7 @@ void HtmlGenerator::generateNavigationBar(const NavigationBar& bar,
{
if (bar.prev.begin() != 0 || bar.current.begin() != 0 ||
bar.next.begin() != 0) {
- out() << "<p align=\"right\">";
+ out() << "<p class=\"rightAlign\">";
if (bar.prev.begin() != 0) {
#if 0
out() << "[<a href=\"" << section.previousBaseName()
@@ -1918,17 +2235,19 @@ void HtmlGenerator::generateNavigationBar(const NavigationBar& bar,
out() << "</a>]\n";
#endif
}
- if (bar.current.begin() != 0) {
- out() << "[<a href=\"" << "home"
- << ".html\">Home</a>]\n";
- }
- if (bar.next.begin() != 0) {
- out() << "[<a href=\"" << fileBase(node, bar.next)
- << ".html\">Next: ";
- generateText(Text::sectionHeading(bar.next.begin()), node, marker);
- out() << "</a>]\n";
+ if (fake->name() != QString("index.html")) {
+ if (bar.current.begin() != 0) {
+ out() << "[<a href=\"" << "home"
+ << ".html\">Home</a>]\n";
+ }
+ if (bar.next.begin() != 0) {
+ out() << "[<a href=\"" << fileBase(node, bar.next)
+ << ".html\">Next: ";
+ generateText(Text::sectionHeading(bar.next.begin()), node, marker);
+ out() << "</a>]\n";
+ }
+ out() << "</p>\n";
}
- out() << "</p>\n";
}
}
#endif
@@ -1948,7 +2267,7 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
QString fileName = fileBase(inner) + "-members." + fileExtension(inner);
beginSubPage(inner->location(), fileName);
QString title = "List of All Members for " + inner->name();
- generateHeader(title, inner, marker, false);
+ generateHeader(title, inner, marker);
generateTitle(title, Text(), SmallSubTitle, inner, marker);
out() << "<p>This is the complete list of members for ";
generateFullName(inner, 0, marker);
@@ -1962,6 +2281,38 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner,
return fileName;
}
+/*!
+ This function creates an html page on which are listed all
+ the members of QML class \a qml_cn, including the inherited
+ members. The \a marker is used for formatting stuff.
+ */
+QString HtmlGenerator::generateAllQmlMembersFile(const QmlClassNode* qml_cn,
+ CodeMarker* marker)
+{
+ QList<Section> sections;
+ QList<Section>::ConstIterator s;
+
+ sections = marker->qmlSections(qml_cn,CodeMarker::SeparateList,myTree);
+ if (sections.isEmpty())
+ return QString();
+
+ QString fileName = fileBase(qml_cn) + "-members." + fileExtension(qml_cn);
+ beginSubPage(qml_cn->location(), fileName);
+ QString title = "List of All Members for " + qml_cn->name();
+ generateHeader(title, qml_cn, marker);
+ generateTitle(title, Text(), SmallSubTitle, qml_cn, marker);
+ out() << "<p>This is the complete list of members for ";
+ generateFullName(qml_cn, 0, marker);
+ out() << ", including inherited members.</p>\n";
+
+ Section section = sections.first();
+ generateSectionList(section, 0, marker, CodeMarker::SeparateList);
+
+ generateFooter();
+ endSubPage();
+ return fileName;
+}
+
QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
CodeMarker *marker,
CodeMarker::Status status)
@@ -1992,7 +2343,7 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
}
beginSubPage(inner->location(), fileName);
- generateHeader(title, inner, marker, false);
+ generateHeader(title, inner, marker);
generateTitle(title, Text(), SmallSubTitle, inner, marker);
if (status == CodeMarker::Compat) {
@@ -2009,18 +2360,18 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
out() << "<p><ul><li><a href=\""
<< linkForNode(inner, 0) << "\">"
- << protect(inner->name())
+ << protectEnc(inner->name())
<< " class reference</a></li></ul></p>\n";
for (i = 0; i < sections.size(); ++i) {
- out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
+ out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
}
sections = marker->sections(inner, CodeMarker::Detailed, status);
for (i = 0; i < sections.size(); ++i) {
- out() << "<hr />\n";
- out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
+ //out() << "<hr />\n";
+ out() << "<h2>" << protectEnc(sections.at(i).name) << "</h2>\n";
NodeList::ConstIterator m = sections.at(i).members.begin();
while (m != sections.at(i).members.end()) {
@@ -2085,8 +2436,7 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
CodeMarker *marker,
const NodeMap &nodeMap)
{
- out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
- << "cellspacing=\"1\" border=\"0\">\n";
+ out() << "<table class=\"annotated\">\n";
int row = 0;
foreach (const QString &name, nodeMap.keys()) {
@@ -2096,29 +2446,29 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
continue;
if (++row % 2 == 1)
- out() << "<tr valign=\"top\" class=\"odd\">";
+ out() << "<tr class=\"odd topAlign\">";
else
- out() << "<tr valign=\"top\" class=\"even\">";
- out() << "<th>";
+ out() << "<tr class=\"even topAlign\">";
+ out() << "<td class=\"tblName\"><p>";
generateFullName(node, relative, marker);
- out() << "</th>";
+ out() << "</p></td>";
if (!(node->type() == Node::Fake)) {
Text brief = node->doc().trimmedBriefText(name);
if (!brief.isEmpty()) {
- out() << "<td>";
+ out() << "<td class=\"tblDescr\"><p>";
generateText(brief, node, marker);
- out() << "</td>";
+ out() << "</p></td>";
}
}
else {
- out() << "<td>";
- out() << protect(node->doc().briefText().toString());
- out() << "</td>";
+ out() << "<td class=\"tblDescr\"><p>";
+ out() << protectEnc(node->doc().briefText().toString());
+ out() << "</p></td>";
}
out() << "</tr>\n";
}
- out() << "</table></p>\n";
+ out() << "</table>\n";
}
/*!
@@ -2133,10 +2483,10 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative,
void HtmlGenerator::generateCompactList(const Node *relative,
CodeMarker *marker,
const NodeMap &classMap,
+ bool includeAlphabet,
QString commonPrefix)
{
const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
- const int NumColumns = 4; // number of columns in the result
if (classMap.isEmpty())
return;
@@ -2205,6 +2555,7 @@ void HtmlGenerator::generateCompactList(const Node *relative,
*/
NodeMap paragraph[NumParagraphs+1];
QString paragraphName[NumParagraphs+1];
+ QSet<char> usedParagraphNames;
NodeMap::ConstIterator c = classMap.begin();
while (c != classMap.end()) {
@@ -2218,17 +2569,18 @@ void HtmlGenerator::generateCompactList(const Node *relative,
else
key = pieces.last().toLower();
- int paragraphNo = NumParagraphs - 1;
+ int paragraphNr = NumParagraphs - 1;
if (key[0].digitValue() != -1) {
- paragraphNo = key[0].digitValue();
+ paragraphNr = key[0].digitValue();
}
else if (key[0] >= QLatin1Char('a') && key[0] <= QLatin1Char('z')) {
- paragraphNo = 10 + key[0].unicode() - 'a';
+ paragraphNr = 10 + key[0].unicode() - 'a';
}
- paragraphName[paragraphNo] = key[0].toUpper();
- paragraph[paragraphNo].insert(key, c.value());
+ paragraphName[paragraphNr] = key[0].toUpper();
+ usedParagraphNames.insert(key[0].toLower().cell());
+ paragraph[paragraphNr].insert(key, c.value());
++c;
}
@@ -2241,108 +2593,105 @@ void HtmlGenerator::generateCompactList(const Node *relative,
start at offsets 0, 3, 4, 8, 9, 14, 23.
*/
int paragraphOffset[NumParagraphs + 1]; // 37 + 1
- int i, j, k;
-
paragraphOffset[0] = 0;
- for (j = 0; j < NumParagraphs; j++) // j = 0..36
- paragraphOffset[j + 1] = paragraphOffset[j] + paragraph[j].count();
+ for (int i=0; i<NumParagraphs; i++) // i = 0..36
+ paragraphOffset[i+1] = paragraphOffset[i] + paragraph[i].count();
- int firstOffset[NumColumns + 1]; // 4 + 1
- int currentOffset[NumColumns]; // 4
- int currentParagraphNo[NumColumns]; // 4
- int currentOffsetInParagraph[NumColumns]; // 4
+ int curParNr = 0;
+ int curParOffset = 0;
- int numRows = (classMap.count() + NumColumns - 1) / NumColumns;
- int curParagNo = 0;
+ /*
+ Output the alphabet as a row of links.
+ */
+ if (includeAlphabet) {
+ out() << "<p class=\"centerAlign functionIndex\"><b>";
+ for (int i = 0; i < 26; i++) {
+ QChar ch('a' + i);
+ if (usedParagraphNames.contains(char('a' + i)))
+ out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
+ }
+ out() << "</b></p>\n";
+ }
+
+ /*
+ Output a <div> element to contain all the <dl> elements.
+ */
+ out() << "<div class=\"flowListDiv\">\n";
- for (i = 0; i < NumColumns; i++) { // i = 0..3
- firstOffset[i] = qMin(i * numRows, classMap.size());
- currentOffset[i] = firstOffset[i];
+ for (int i=0; i<classMap.count()-1; i++) {
+ while ((curParNr < NumParagraphs) &&
+ (curParOffset == paragraph[curParNr].count())) {
+ ++curParNr;
+ curParOffset = 0;
+ }
- for (j = curParagNo; j < NumParagraphs; j++) {
- if (paragraphOffset[j] > firstOffset[i])
- break;
- if (paragraphOffset[j] <= firstOffset[i])
- curParagNo = j;
- }
- currentParagraphNo[i] = curParagNo;
- currentOffsetInParagraph[i] = firstOffset[i] -
- paragraphOffset[curParagNo];
- }
- firstOffset[NumColumns] = classMap.count();
-
- out() << "<p><table class=\"generic\" width=\"100%\">\n";
- for (k = 0; k < numRows; k++) {
- out() << "<tr>\n";
- for (i = 0; i < NumColumns; i++) {
- if (currentOffset[i] >= firstOffset[i + 1]) {
- // this column is finished
- out() << "<td>\n</td>\n";
+ /*
+ Starting a new paragraph means starting a new <dl>.
+ */
+ if (curParOffset == 0) {
+ if (i > 0)
+ out() << "</dl>\n";
+ if (++numTableRows % 2 == 1)
+ out() << "<dl class=\"flowList odd\">";
+ else
+ out() << "<dl class=\"flowList even\">";
+ out() << "<dt class=\"alphaChar\">";
+ if (includeAlphabet) {
+ QChar c = paragraphName[curParNr][0].toLower();
+ out() << QString("<a name=\"%1\"></a>").arg(c);
}
- else {
- while ((currentParagraphNo[i] < NumParagraphs) &&
- (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count())) {
- ++currentParagraphNo[i];
- currentOffsetInParagraph[i] = 0;
- }
-#if 0
- if (currentParagraphNo[i] >= NumParagraphs) {
- qDebug() << "### Internal error ###" << __FILE__ << __LINE__
- << currentParagraphNo[i] << NumParagraphs;
- currentParagraphNo[i] = NumParagraphs - 1;
- }
-#endif
- out() << "<td align=\"right\">";
- if (currentOffsetInParagraph[i] == 0) {
- // start a new paragraph
- out() << "<b>"
- << paragraphName[currentParagraphNo[i]]
- << "&nbsp;</b>";
- }
- out() << "</td>\n";
-
- out() << "<td>";
- if ((currentParagraphNo[i] < NumParagraphs) &&
- !paragraphName[currentParagraphNo[i]].isEmpty()) {
- NodeMap::Iterator it;
- it = paragraph[currentParagraphNo[i]].begin();
- for (j = 0; j < currentOffsetInParagraph[i]; j++)
- ++it;
-
- // Previously, we used generateFullName() for this, but we
- // require some special formatting.
- out() << "<a href=\""
- << linkForNode(it.value(), relative)
- << "\">";
- QStringList pieces = fullName(it.value(), relative, marker).split("::");
- out() << protect(pieces.last());
- out() << "</a>";
- if (pieces.size() > 1) {
- out() << " (";
- generateFullName(it.value()->parent(), relative, marker);
- out() << ")";
- }
- }
- out() << "</td>\n";
+ out() << "<b>"
+ << paragraphName[curParNr]
+ << "</b>";
+ out() << "</dt>\n";
+ }
- currentOffset[i]++;
- currentOffsetInParagraph[i]++;
+ /*
+ Output a <dd> for the current offset in the current paragraph.
+ */
+ out() << "<dd>";
+ if ((curParNr < NumParagraphs) &&
+ !paragraphName[curParNr].isEmpty()) {
+ NodeMap::Iterator it;
+ it = paragraph[curParNr].begin();
+ for (int i=0; i<curParOffset; i++)
+ ++it;
+
+ /*
+ Previously, we used generateFullName() for this, but we
+ require some special formatting.
+ */
+ out() << "<a href=\"" << linkForNode(it.value(), relative) << "\">";
+
+ QStringList pieces;
+ if (it.value()->subType() == Node::QmlClass)
+ pieces << it.value()->name();
+ else
+ pieces = fullName(it.value(), relative, marker).split("::");
+ out() << protectEnc(pieces.last());
+ out() << "</a>";
+ if (pieces.size() > 1) {
+ out() << " (";
+ generateFullName(it.value()->parent(), relative, marker);
+ out() << ")";
}
}
- out() << "</tr>\n";
+ out() << "</dd>\n";
+ curParOffset++;
}
- out() << "</table></p>\n";
+ out() << "</dl>\n";
+ out() << "</div>\n";
}
void HtmlGenerator::generateFunctionIndex(const Node *relative,
CodeMarker *marker)
{
- out() << "<p align=\"center\"><font size=\"+1\"><b>";
+ out() << "<p class=\"centerAlign functionIndex\"><b>";
for (int i = 0; i < 26; i++) {
QChar ch('a' + i);
out() << QString("<a href=\"#%1\">%2</a>&nbsp;").arg(ch).arg(ch.toUpper());
}
- out() << "</b></font></p>\n";
+ out() << "</b></p>\n";
char nextLetter = 'a';
char currentLetter;
@@ -2357,7 +2706,7 @@ void HtmlGenerator::generateFunctionIndex(const Node *relative,
#else
out() << "<p>";
#endif
- out() << protect(f.key()) << ":";
+ out() << protectEnc(f.key()) << ":";
currentLetter = f.key()[0].unicode();
while (islower(currentLetter) && currentLetter >= nextLetter) {
@@ -2390,7 +2739,7 @@ void HtmlGenerator::generateLegaleseList(const Node *relative,
QMap<Text, const Node *>::ConstIterator it = legaleseTexts.begin();
while (it != legaleseTexts.end()) {
Text text = it.key();
- out() << "<hr />\n";
+ //out() << "<hr />\n";
generateText(text, relative, marker);
out() << "<ul>\n";
do {
@@ -2403,44 +2752,6 @@ void HtmlGenerator::generateLegaleseList(const Node *relative,
}
}
-/*void HtmlGenerator::generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style)
-{
- QString marked = marker->markedUpSynopsis(node, relative, style);
- QRegExp templateTag("(<[^@>]*>)");
- if (marked.indexOf(templateTag) != -1) {
- QString contents = protect(marked.mid(templateTag.pos(1),
- templateTag.cap(1).length()));
- marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
- contents);
- }
- marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
- "<i>\\1<sub>\\2</sub></i>");
- marked.replace("<@param>", "<i>");
- marked.replace("</@param>", "</i>");
-
- if (style == CodeMarker::Summary)
- marked.replace("@name>", "b>");
-
- if (style == CodeMarker::SeparateList) {
- QRegExp extraRegExp("<@extra>.*</@extra>");
- extraRegExp.setMinimal(true);
- marked.replace(extraRegExp, "");
- }
- else {
- marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
- marked.replace("</@extra>", "</tt>");
- }
-
- if (style != CodeMarker::Detailed) {
- marked.replace("<@type>", "");
- marked.replace("</@type>", "");
- }
- out() << highlightedCode(marked, marker, relative);
-}*/
-
#ifdef QDOC_QML
void HtmlGenerator::generateQmlItem(const Node *node,
const Node *relative,
@@ -2450,7 +2761,7 @@ void HtmlGenerator::generateQmlItem(const Node *node,
QString marked = marker->markedUpQmlItem(node,summary);
QRegExp templateTag("(<[^@>]*>)");
if (marked.indexOf(templateTag) != -1) {
- QString contents = protect(marked.mid(templateTag.pos(1),
+ QString contents = protectEnc(marked.mid(templateTag.pos(1),
templateTag.cap(1).length()));
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
@@ -2463,14 +2774,14 @@ void HtmlGenerator::generateQmlItem(const Node *node,
if (summary)
marked.replace("@name>", "b>");
- marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("<@extra>", "<tt>");
marked.replace("</@extra>", "</tt>");
if (summary) {
marked.replace("<@type>", "");
marked.replace("</@type>", "");
}
- out() << highlightedCode(marked, marker, relative);
+ out() << highlightedCode(marked, marker, relative, false, node);
}
#endif
@@ -2556,7 +2867,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
const FakeNode *groupNode = groupTitlesMap[groupTitle];
out() << QString("<h3><a href=\"%1\">%2</a></h3>\n").arg(
linkForNode(groupNode, relative)).arg(
- protect(groupNode->fullTitle()));
+ protectEnc(groupNode->fullTitle()));
if (fakeNodeMap[groupNode].count() == 0)
continue;
@@ -2568,7 +2879,7 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
if (title.startsWith("The "))
title.remove(0, 4);
out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
- << protect(title) << "</a></li>\n";
+ << protectEnc(title) << "</a></li>\n";
}
out() << "</ul>\n";
}
@@ -2582,39 +2893,35 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
if (title.startsWith("The "))
title.remove(0, 4);
out() << "<li><a href=\"" << linkForNode(fakeNode, relative) << "\">"
- << protect(title) << "</a></li>\n";
+ << protectEnc(title) << "</a></li>\n";
}
out() << "</ul>\n";
}
}
-#ifdef QDOC_NAME_ALIGNMENT
void HtmlGenerator::generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style)
{
- bool name_alignment = true;
+ bool alignNames = true;
if (!nl.isEmpty()) {
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
- name_alignment = false;
+ alignNames = false;
twoColumn = (nl.count() >= 16);
}
else if (nl.first()->type() == Node::Property) {
twoColumn = (nl.count() >= 5);
- name_alignment = false;
+ alignNames = false;
}
- if (name_alignment) {
- out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
- << "cellspacing=\"0\" width=\"100%\">\n";
+ if (alignNames) {
+ out() << "<table class=\"alignedsummary\">\n";
}
else {
if (twoColumn)
- out() << "<p><table class=\"propsummary\" width=\"100%\" "
- << "border=\"0\" cellpadding=\"0\""
- << " cellspacing=\"0\">\n"
- << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<table class=\"propsummary\">\n"
+ << "<tr><td class=\"topAlign\">";
out() << "<ul>\n";
}
@@ -2626,30 +2933,29 @@ void HtmlGenerator::generateSection(const NodeList& nl,
continue;
}
- if (name_alignment) {
- out() << "<tr><td class=\"memItemLeft\" "
- << "align=\"right\" valign=\"top\">";
+ if (alignNames) {
+ out() << "<tr><td class=\"memItemLeft rightAlign topAlign\"> ";
}
else {
if (twoColumn && i == (int) (nl.count() + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
- out() << "<li><div class=\"fn\">";
+ out() << "</ul></td><td class=\"topAlign\"><ul>\n";
+ out() << "<li class=\"fn\">";
}
- generateSynopsis(*m, relative, marker, style, name_alignment);
- if (name_alignment)
+ generateSynopsis(*m, relative, marker, style, alignNames);
+ if (alignNames)
out() << "</td></tr>\n";
else
- out() << "</div></li>\n";
+ out() << "</li>\n";
i++;
++m;
}
- if (name_alignment)
+ if (alignNames)
out() << "</table>\n";
else {
out() << "</ul>\n";
if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
+ out() << "</td></tr>\n</table>\n";
}
}
}
@@ -2659,27 +2965,24 @@ void HtmlGenerator::generateSectionList(const Section& section,
CodeMarker *marker,
CodeMarker::SynopsisStyle style)
{
- bool name_alignment = true;
+ bool alignNames = true;
if (!section.members.isEmpty()) {
bool twoColumn = false;
if (style == CodeMarker::SeparateList) {
- name_alignment = false;
+ alignNames = false;
twoColumn = (section.members.count() >= 16);
}
else if (section.members.first()->type() == Node::Property) {
twoColumn = (section.members.count() >= 5);
- name_alignment = false;
+ alignNames = false;
}
- if (name_alignment) {
- out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
- << "cellspacing=\"0\" width=\"100%\">\n";
+ if (alignNames) {
+ out() << "<table class=\"alignedsummary\">\n";
}
else {
if (twoColumn)
- out() << "<p><table class=\"propsummary\" width=\"100%\" "
- << "border=\"0\" cellpadding=\"0\""
- << " cellspacing=\"0\">\n"
- << "<tr><td width=\"45%\" valign=\"top\">";
+ out() << "<table class=\"propsummary\">\n"
+ << "<tr><td class=\"topAlign\">";
out() << "<ul>\n";
}
@@ -2691,51 +2994,46 @@ void HtmlGenerator::generateSectionList(const Section& section,
continue;
}
- if (name_alignment) {
- out() << "<tr><td class=\"memItemLeft\" "
- << "align=\"right\" valign=\"top\">";
+ if (alignNames) {
+ out() << "<tr><td class=\"memItemLeft topAlign rightAlign\"> ";
}
else {
if (twoColumn && i == (int) (section.members.count() + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
- out() << "<li><div class=\"fn\">";
+ out() << "</ul></td><td class=\"topAlign\"><ul>\n";
+ out() << "<li class=\"fn\">";
}
- generateSynopsis(*m, relative, marker, style, name_alignment);
- if (name_alignment)
+ generateSynopsis(*m, relative, marker, style, alignNames);
+ if (alignNames)
out() << "</td></tr>\n";
else
- out() << "</div></li>\n";
+ out() << "</li>\n";
i++;
++m;
}
- if (name_alignment)
+ if (alignNames)
out() << "</table>\n";
else {
out() << "</ul>\n";
if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
+ out() << "</td></tr>\n</table>\n";
}
}
if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
out() << "<ul>\n";
- generateSectionInheritedList(section, relative, marker, name_alignment);
+ generateSectionInheritedList(section, relative, marker);
out() << "</ul>\n";
}
}
void HtmlGenerator::generateSectionInheritedList(const Section& section,
const Node *relative,
- CodeMarker *marker,
- bool nameAlignment)
+ CodeMarker *marker)
{
QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
while (p != section.inherited.end()) {
- if (nameAlignment)
- out() << "<li><div bar=\"2\" class=\"fn\"></div>";
- else
- out() << "<li><div class=\"fn\"></div>";
+ out() << "<li class=\"fn\">";
out() << (*p).second << " ";
if ((*p).second == 1) {
out() << section.singularMember;
@@ -2745,7 +3043,7 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section,
}
out() << " inherited from <a href=\"" << fileName((*p).first)
<< "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
- << protect(marker->plainFullName((*p).first, relative))
+ << protectEnc(marker->plainFullName((*p).first, relative))
<< "</a></li>\n";
++p;
}
@@ -2755,12 +3053,12 @@ void HtmlGenerator::generateSynopsis(const Node *node,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style,
- bool nameAlignment)
+ bool alignNames)
{
QString marked = marker->markedUpSynopsis(node, relative, style);
QRegExp templateTag("(<[^@>]*>)");
if (marked.indexOf(templateTag) != -1) {
- QString contents = protect(marked.mid(templateTag.pos(1),
+ QString contents = protectEnc(marked.mid(templateTag.pos(1),
templateTag.cap(1).length()));
marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
contents);
@@ -2780,7 +3078,7 @@ void HtmlGenerator::generateSynopsis(const Node *node,
extraRegExp.setMinimal(true);
marked.replace(extraRegExp, "");
} else {
- marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("<@extra>", "<tt>");
marked.replace("</@extra>", "</tt>");
}
@@ -2788,14 +3086,14 @@ void HtmlGenerator::generateSynopsis(const Node *node,
marked.replace("<@type>", "");
marked.replace("</@type>", "");
}
- out() << highlightedCode(marked, marker, relative, style, nameAlignment);
+ out() << highlightedCode(marked, marker, relative, alignNames);
}
QString HtmlGenerator::highlightedCode(const QString& markedCode,
- CodeMarker *marker,
- const Node *relative,
- CodeMarker::SynopsisStyle ,
- bool nameAlignment)
+ CodeMarker* marker,
+ const Node* relative,
+ bool alignNames,
+ const Node* self)
{
QString src = markedCode;
QString html;
@@ -2805,20 +3103,24 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
const QChar charLangle = '<';
const QChar charAt = '@';
- // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
+ static const QString typeTag("type");
+ static const QString headerTag("headerfile");
+ static const QString funcTag("func");
static const QString linkTag("link");
+
+ // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
bool done = false;
- for (int i = 0, n = src.size(); i < n;) {
+ for (int i = 0, srcSize = src.size(); i < srcSize;) {
if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
- if (nameAlignment && !done) {// && (i != 0)) Why was this here?
- html += "</td><td class=\"memItemRight\" valign=\"bottom\">";
+ if (alignNames && !done) {// && (i != 0)) Why was this here?
+ html += "</td><td class=\"memItemRight bottomAlign\">";
done = true;
}
i += 2;
- if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
+ if (parseArg(src, linkTag, &i, srcSize, &arg, &par1)) {
html += "<b>";
- QString link = linkForNode(
- CodeMarker::nodeForString(par1.toString()), relative);
+ const Node* n = CodeMarker::nodeForString(par1.toString());
+ QString link = linkForNode(n, relative);
addLink(link, arg, &html);
html += "</b>";
}
@@ -2838,16 +3140,14 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
// replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
src = html;
html = QString();
- static const QString funcTag("func");
- for (int i = 0, n = src.size(); i < n;) {
+ for (int i = 0, srcSize = src.size(); i < srcSize;) {
if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
i += 2;
- if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
- QString link = linkForNode(
- marker->resolveTarget(par1.toString(),
- myTree,
- relative),
- relative);
+ if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
+ const Node* n = marker->resolveTarget(par1.toString(),
+ myTree,
+ relative);
+ QString link = linkForNode(n, relative);
addLink(link, arg, &html);
par1 = QStringRef();
}
@@ -2865,292 +3165,37 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
// replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
src = html;
html = QString();
- static const QString typeTags[] = { "type", "headerfile", "func" };
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- bool handled = false;
- for (int k = 0; k != 3; ++k) {
- if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
- par1 = QStringRef();
- QString link = linkForNode(
- marker->resolveTarget(arg.toString(), myTree, relative),
- relative);
- addLink(link, arg, &html);
- handled = true;
- break;
- }
- }
- if (!handled) {
- html += charLangle;
- html += charAt;
- }
- }
- else {
- html += src.at(i++);
- }
- }
- // replace all
- // "<@comment>" -> "<span class=\"comment\">";
- // "<@preprocessor>" -> "<span class=\"preprocessor\">";
- // "<@string>" -> "<span class=\"string\">";
- // "<@char>" -> "<span class=\"char\">";
- // "</@(?:comment|preprocessor|string|char)>" -> "</span>"
- src = html;
- html = QString();
- static const QString spanTags[] = {
- "<@comment>", "<span class=\"comment\">",
- "<@preprocessor>", "<span class=\"preprocessor\">",
- "<@string>", "<span class=\"string\">",
- "<@char>", "<span class=\"char\">",
- "</@comment>", "</span>",
- "</@preprocessor>","</span>",
- "</@string>", "</span>",
- "</@char>", "</span>"
- // "<@char>", "<font color=blue>",
- // "</@char>", "</font>",
- // "<@func>", "<font color=green>",
- // "</@func>", "</font>",
- // "<@id>", "<i>",
- // "</@id>", "</i>",
- // "<@keyword>", "<b>",
- // "</@keyword>", "</b>",
- // "<@number>", "<font color=yellow>",
- // "</@number>", "</font>",
- // "<@op>", "<b>",
- // "</@op>", "</b>",
- // "<@param>", "<i>",
- // "</@param>", "</i>",
- // "<@string>", "<font color=green>",
- // "</@string>", "</font>",
- };
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle) {
+ for (int i=0, srcSize=src.size(); i<srcSize;) {
+ if (src.at(i) == charLangle && src.at(i+1) == charAt) {
+ i += 2;
bool handled = false;
- for (int k = 0; k != 8; ++k) {
- const QString & tag = spanTags[2 * k];
- if (tag == QStringRef(&src, i, tag.length())) {
- html += spanTags[2 * k + 1];
- i += tag.length();
- handled = true;
- break;
+ if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) {
+ par1 = QStringRef();
+ const Node* n = marker->resolveTarget(arg.toString(), myTree, relative, self);
+ if (n && n->subType() == Node::QmlBasicType) {
+ if (relative && relative->subType() == Node::QmlClass)
+ addLink(linkForNode(n,relative), arg, &html);
+ else
+ html += arg.toString();
}
+ else
+ addLink(linkForNode(n,relative), arg, &html);
+ handled = true;
}
- if (!handled) {
- ++i;
- if (src.at(i) == charAt ||
- (src.at(i) == QLatin1Char('/') && src.at(i + 1) == charAt)) {
- // drop 'our' unknown tags (the ones still containing '@')
- while (i < n && src.at(i) != QLatin1Char('>'))
- ++i;
- ++i;
- }
- else {
- // retain all others
- html += charLangle;
- }
- }
- }
- else {
- html += src.at(i);
- ++i;
- }
- }
-
- return html;
-}
-
-#else
-void HtmlGenerator::generateSectionList(const Section& section,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style)
-{
- if (!section.members.isEmpty()) {
- bool twoColumn = false;
- if (style == CodeMarker::SeparateList) {
- twoColumn = (section.members.count() >= 16);
- }
- else if (section.members.first()->type() == Node::Property) {
- twoColumn = (section.members.count() >= 5);
- }
- if (twoColumn)
- out() << "<p><table class=\"generic\" width=\"100%\" border=\"0\" "
- << "cellpadding=\"0\" cellspacing=\"0\">\n"
- << "<tr><td width=\"45%\" valign=\"top\">";
- out() << "<ul>\n";
-
- int i = 0;
- NodeList::ConstIterator m = section.members.begin();
- while (m != section.members.end()) {
- if ((*m)->access() == Node::Private) {
- ++m;
- continue;
- }
-
- if (twoColumn && i == (int) (section.members.count() + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
-
- out() << "<li><div class=\"fn\"></div>";
- if (style == CodeMarker::Accessors)
- out() << "<b>";
- generateSynopsis(*m, relative, marker, style);
- if (style == CodeMarker::Accessors)
- out() << "</b>";
- out() << "</li>\n";
- i++;
- ++m;
- }
- out() << "</ul>\n";
- if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
- }
-
- if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
- out() << "<ul>\n";
- generateSectionInheritedList(section, relative, marker);
- out() << "</ul>\n";
- }
-}
-
-void HtmlGenerator::generateSectionInheritedList(const Section& section,
- const Node *relative,
- CodeMarker *marker)
-{
- QList<QPair<ClassNode *, int> >::ConstIterator p = section.inherited.begin();
- while (p != section.inherited.end()) {
- out() << "<li><div bar=\"2\" class=\"fn\"></div>";
- out() << (*p).second << " ";
- if ((*p).second == 1) {
- out() << section.singularMember;
- } else {
- out() << section.pluralMember;
- }
- out() << " inherited from <a href=\"" << fileName((*p).first)
- << "#" << HtmlGenerator::cleanRef(section.name.toLower()) << "\">"
- << protect(marker->plainFullName((*p).first, relative))
- << "</a></li>\n";
- ++p;
- }
-}
-
-void HtmlGenerator::generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style)
-{
- QString marked = marker->markedUpSynopsis(node, relative, style);
- QRegExp templateTag("(<[^@>]*>)");
- if (marked.indexOf(templateTag) != -1) {
- QString contents = protect(marked.mid(templateTag.pos(1),
- templateTag.cap(1).length()));
- marked.replace(templateTag.pos(1), templateTag.cap(1).length(),
- contents);
- }
- marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"), "<i>\\1<sub>\\2</sub></i>");
- marked.replace("<@param>", "<i>");
- marked.replace("</@param>", "</i>");
-
- if (style == CodeMarker::Summary)
- marked.replace("@name>", "b>");
-
- if (style == CodeMarker::SeparateList) {
- QRegExp extraRegExp("<@extra>.*</@extra>");
- extraRegExp.setMinimal(true);
- marked.replace(extraRegExp, "");
- } else {
- marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
- marked.replace("</@extra>", "</tt>");
- }
-
- if (style != CodeMarker::Detailed) {
- marked.replace("<@type>", "");
- marked.replace("</@type>", "");
- }
- out() << highlightedCode(marked, marker, relative);
-}
-
-QString HtmlGenerator::highlightedCode(const QString& markedCode,
- CodeMarker *marker,
- const Node *relative)
-{
- QString src = markedCode;
- QString html;
- QStringRef arg;
- QStringRef par1;
-
- const QChar charLangle = '<';
- const QChar charAt = '@';
-
- // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)"
- static const QString linkTag("link");
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
- const Node* node = CodeMarker::nodeForString(par1.toString());
- QString link = linkForNode(node, relative);
- addLink(link, arg, &html);
- }
- else {
- html += charLangle;
- html += charAt;
- }
- }
- else {
- html += src.at(i++);
- }
- }
-
- if (slow) {
- // is this block ever used at all?
- // replace all <@func> tags: "(<@func target=\"([^\"]*)\">)(.*)(</@func>)"
- src = html;
- html = QString();
- static const QString funcTag("func");
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- if (parseArg(src, funcTag, &i, n, &arg, &par1)) {
- QString link = linkForNode(
- marker->resolveTarget(par1.toString(),
- myTree,
- relative),
- relative);
- addLink(link, arg, &html);
- par1 = QStringRef();
- }
- else {
- html += charLangle;
- html += charAt;
- }
+ else if (parseArg(src, headerTag, &i, srcSize, &arg, &par1)) {
+ par1 = QStringRef();
+ const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
+ addLink(linkForNode(n,relative), arg, &html);
+ handled = true;
}
- else {
- html += src.at(i++);
+ else if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) {
+ par1 = QStringRef();
+ const Node* n = marker->resolveTarget(arg.toString(), myTree, relative);
+ addLink(linkForNode(n,relative), arg, &html);
+ handled = true;
}
- }
- }
- // replace all "(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)" tags
- src = html;
- html = QString();
- static const QString typeTags[] = { "type", "headerfile", "func" };
- for (int i = 0, n = src.size(); i < n;) {
- if (src.at(i) == charLangle && src.at(i + 1) == charAt) {
- i += 2;
- bool handled = false;
- for (int k = 0; k != 3; ++k) {
- if (parseArg(src, typeTags[k], &i, n, &arg, &par1)) {
- par1 = QStringRef();
- QString link = linkForNode(
- marker->resolveTarget(arg.toString(), myTree, relative),
- relative);
- addLink(link, arg, &html);
- handled = true;
- break;
- }
- }
if (!handled) {
html += charLangle;
html += charAt;
@@ -3178,22 +3223,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
"</@preprocessor>","</span>",
"</@string>", "</span>",
"</@char>", "</span>"
- // "<@char>", "<font color=blue>",
- // "</@char>", "</font>",
- // "<@func>", "<font color=green>",
- // "</@func>", "</font>",
- // "<@id>", "<i>",
- // "</@id>", "</i>",
- // "<@keyword>", "<b>",
- // "</@keyword>", "</b>",
- // "<@number>", "<font color=yellow>",
- // "</@number>", "</font>",
- // "<@op>", "<b>",
- // "</@op>", "</b>",
- // "<@param>", "<i>",
- // "</@param>", "</i>",
- // "<@string>", "<font color=green>",
- // "</@string>", "</font>",
};
for (int i = 0, n = src.size(); i < n;) {
if (src.at(i) == charLangle) {
@@ -3230,7 +3259,6 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
return html;
}
-#endif
void HtmlGenerator::generateLink(const Atom* atom,
const Node* /* relative */,
@@ -3241,7 +3269,7 @@ void HtmlGenerator::generateLink(const Atom* atom,
if (funcLeftParen.indexIn(atom->string()) != -1 && marker->recognizeLanguage("Cpp")) {
// hack for C++: move () outside of link
int k = funcLeftParen.pos(1);
- out() << protect(atom->string().left(k));
+ out() << protectEnc(atom->string().left(k));
if (link.isEmpty()) {
if (showBrokenLinks)
out() << "</i>";
@@ -3249,21 +3277,21 @@ void HtmlGenerator::generateLink(const Atom* atom,
out() << "</a>";
}
inLink = false;
- out() << protect(atom->string().mid(k));
+ out() << protectEnc(atom->string().mid(k));
} else if (marker->recognizeLanguage("Java")) {
- // hack for Java: remove () and use <tt> when appropriate
+ // hack for Java: remove () and use <tt> when appropriate
bool func = atom->string().endsWith("()");
bool tt = (func || atom->string().contains(camelCase));
if (tt)
out() << "<tt>";
if (func) {
- out() << protect(atom->string().left(atom->string().length() - 2));
+ out() << protectEnc(atom->string().left(atom->string().length() - 2));
} else {
- out() << protect(atom->string());
+ out() << protectEnc(atom->string());
}
out() << "</tt>";
} else {
- out() << protect(atom->string());
+ out() << protectEnc(atom->string());
}
}
@@ -3337,7 +3365,12 @@ QString HtmlGenerator::registerRef(const QString& ref)
return clean;
}
-QString HtmlGenerator::protect(const QString& string)
+QString HtmlGenerator::protectEnc(const QString &string)
+{
+ return protect(string, outputEncoding);
+}
+
+QString HtmlGenerator::protect(const QString &string, const QString &outputEncoding)
{
#define APPEND(x) \
if (html.isEmpty()) { \
@@ -3360,7 +3393,7 @@ QString HtmlGenerator::protect(const QString& string)
APPEND("&gt;");
} else if (ch == QLatin1Char('"')) {
APPEND("&quot;");
- } else if (ch.unicode() > 0x007F
+ } else if ((outputEncoding == "ISO-8859-1" && ch.unicode() > 0x007F)
|| (ch == QLatin1Char('*') && i + 1 < n && string.at(i) == QLatin1Char('/'))
|| (ch == QLatin1Char('.') && i > 2 && string.at(i - 2) == QLatin1Char('.'))) {
// we escape '*/' and the last dot in 'e.g.' and 'i.e.' for the Javadoc generator
@@ -3380,7 +3413,7 @@ QString HtmlGenerator::protect(const QString& string)
#undef APPEND
}
-QString HtmlGenerator::fileBase(const Node *node)
+QString HtmlGenerator::fileBase(const Node *node) const
{
QString result;
@@ -3490,7 +3523,7 @@ QString HtmlGenerator::refForNode(const Node *node)
ref = node->name() + "-var";
break;
case Node::Target:
- return protect(node->name());
+ return protectEnc(node->name());
}
return registerRef(ref);
}
@@ -3509,10 +3542,13 @@ QString HtmlGenerator::linkForNode(const Node *node, const Node *relative)
return QString();
if (node->access() == Node::Private)
return QString();
-
+
fn = fileName(node);
-/* if (!node->url().isEmpty())
- return fn;*/
+#if 0
+ if (!node->url().isEmpty())
+ return fn;
+#endif
+
#if 0
// ### reintroduce this test, without breaking .dcf files
if (fn != outFileName())
@@ -3564,7 +3600,7 @@ void HtmlGenerator::generateFullName(const Node *apparentNode,
}
}
out() << "\">";
- out() << protect(fullName(apparentNode, relative, marker));
+ out() << protectEnc(fullName(apparentNode, relative, marker));
out() << "</a>";
}
@@ -3574,14 +3610,19 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
{
const EnumNode *enume;
+#ifdef GENERATE_MAC_REFS
generateMacRef(node, marker);
+#endif
+ generateExtractionMark(node, MemberMark);
if (node->type() == Node::Enum
&& (enume = static_cast<const EnumNode *>(node))->flagsType()) {
+#ifdef GENERATE_MAC_REFS
generateMacRef(enume->flagsType(), marker);
+#endif
out() << "<h3 class=\"flags\">";
out() << "<a name=\"" + refForNode(node) + "\"></a>";
generateSynopsis(enume, relative, marker, CodeMarker::Detailed);
- out() << "<br />";
+ out() << "<br/>";
generateSynopsis(enume->flagsType(),
relative,
marker,
@@ -3592,7 +3633,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
out() << "<h3 class=\"fn\">";
out() << "<a name=\"" + refForNode(node) + "\"></a>";
generateSynopsis(node, relative, marker, CodeMarker::Detailed);
- out() << "</h3>\n";
+ out() << "</h3>" << divNavTop << "\n";
}
generateStatus(node, marker);
@@ -3625,16 +3666,17 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
else if (node->type() == Node::Enum) {
const EnumNode *enume = static_cast<const EnumNode *>(node);
if (enume->flagsType()) {
- out() << "<p>The " << protect(enume->flagsType()->name())
+ out() << "<p>The " << protectEnc(enume->flagsType()->name())
<< " type is a typedef for "
<< "<a href=\"qflags.html\">QFlags</a>&lt;"
- << protect(enume->name())
+ << protectEnc(enume->name())
<< "&gt;. It stores an OR combination of "
- << protect(enume->name())
+ << protectEnc(enume->name())
<< " values.</p>\n";
}
}
generateAlsoList(node, marker);
+ generateExtractionMark(node, EndMark);
}
void HtmlGenerator::findAllClasses(const InnerNode *node)
@@ -3676,6 +3718,16 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
if (!serviceName.isEmpty())
serviceClasses.insert(serviceName, *c);
}
+ else if ((*c)->type() == Node::Fake &&
+ (*c)->subType() == Node::QmlClass &&
+ !(*c)->doc().isEmpty()) {
+ QString qmlClassName = (*c)->name();
+ // Remove the "QML:" prefix if present.
+ if (qmlClassName.startsWith(QLatin1String("QML:")))
+ qmlClasses.insert(qmlClassName.mid(4),*c);
+ else
+ qmlClasses.insert(qmlClassName,*c);
+ }
else if ((*c)->isInnerNode()) {
findAllClasses(static_cast<InnerNode *>(*c));
}
@@ -3700,6 +3752,9 @@ void HtmlGenerator::findAllSince(const InnerNode *node)
NewClassMaps::iterator ncmap = newClassMaps.find(sinceVersion);
if (ncmap == newClassMaps.end())
ncmap = newClassMaps.insert(sinceVersion,NodeMap());
+ NewClassMaps::iterator nqcmap = newQmlClassMaps.find(sinceVersion);
+ if (nqcmap == newQmlClassMaps.end())
+ nqcmap = newQmlClassMaps.insert(sinceVersion,NodeMap());
if ((*child)->type() == Node::Function) {
FunctionNode *func = static_cast<FunctionNode *>(*child);
@@ -3719,6 +3774,15 @@ void HtmlGenerator::findAllSince(const InnerNode *node)
nsmap.value().insert(className,(*child));
ncmap.value().insert(className,(*child));
}
+ else if ((*child)->subType() == Node::QmlClass) {
+ QString className = (*child)->name();
+ if ((*child)->parent() &&
+ (*child)->parent()->type() == Node::Namespace &&
+ !(*child)->parent()->name().isEmpty())
+ className = (*child)->parent()->name()+"::"+className;
+ nsmap.value().insert(className,(*child));
+ nqcmap.value().insert(className,(*child));
+ }
}
else {
QString name = (*child)->name();
@@ -3736,13 +3800,6 @@ void HtmlGenerator::findAllSince(const InnerNode *node)
}
}
-#if 0
- const QRegExp versionSeparator("[\\-\\.]");
- const int minorIndex = version.indexOf(versionSeparator);
- const int patchIndex = version.indexOf(versionSeparator, minorIndex+1);
- version = version.left(patchIndex);
-#endif
-
void HtmlGenerator::findAllFunctions(const InnerNode *node)
{
NodeList::ConstIterator c = node->childNodes().begin();
@@ -3806,29 +3863,6 @@ void HtmlGenerator::findAllNamespaces(const InnerNode *node)
}
}
-#ifdef ZZZ_QDOC_QML
-/*!
- This function finds all the qml element nodes and
- stores them in a map for later use.
- */
-void HtmlGenerator::findAllQmlClasses(const InnerNode *node)
-{
- NodeList::const_iterator c = node->childNodes().constBegin();
- while (c != node->childNodes().constEnd()) {
- if ((*c)->type() == Node::Fake) {
- const FakeNode* fakeNode = static_cast<const FakeNode *>(*c);
- if (fakeNode->subType() == Node::QmlClass) {
- const QmlClassNode* qmlNode =
- static_cast<const QmlClassNode*>(fakeNode);
- const Node* n = qmlNode->classNode();
- }
- qmlClasses.insert(fakeNode->name(),*c);
- }
- ++c;
- }
-}
-#endif
-
int HtmlGenerator::hOffset(const Node *node)
{
switch (node->type()) {
@@ -3836,10 +3870,7 @@ int HtmlGenerator::hOffset(const Node *node)
case Node::Class:
return 2;
case Node::Fake:
- if (node->doc().briefText().isEmpty())
- return 1;
- else
- return 2;
+ return 1;
case Node::Enum:
case Node::Typedef:
case Node::Function:
@@ -3939,10 +3970,12 @@ QString HtmlGenerator::getLink(const Atom *atom,
}
else {
*node = marker->resolveTarget(first, myTree, relative);
- if (!*node)
+ if (!*node) {
*node = myTree->findFakeNodeByTitle(first);
- if (!*node)
+ }
+ if (!*node) {
*node = myTree->findUnambiguousTarget(first, targetAtom);
+ }
}
if (*node) {
@@ -4035,7 +4068,7 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
switch (node->status()) {
case Node::Obsolete:
if (node->isInnerNode())
- Generator::generateStatus(node, marker);
+ Generator::generateStatus(node, marker);
break;
case Node::Compat:
if (node->isInnerNode()) {
@@ -4077,6 +4110,10 @@ void HtmlGenerator::generateStatus(const Node *node, CodeMarker *marker)
}
}
+#ifdef GENERATE_MAC_REFS
+/*
+ No longer valid.
+ */
void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
{
if (!pleaseGenerateMacRef || marker == 0)
@@ -4086,6 +4123,7 @@ void HtmlGenerator::generateMacRef(const Node *node, CodeMarker *marker)
foreach (const QString &macRef, macRefs)
out() << "<a name=\"" << "//apple_ref/" << macRef << "\"></a>\n";
}
+#endif
void HtmlGenerator::beginLink(const QString &link,
const Node *node,
@@ -4137,12 +4175,10 @@ void HtmlGenerator::endLink()
inObsoleteLink = false;
}
-QT_END_NAMESPACE
-
#ifdef QDOC_QML
/*!
- Generates the summary for for the \a section. Only used for
+ Generates the summary for the \a section. Only used for
sections of QML element documentation.
Currently handles only the QML property group.
@@ -4152,32 +4188,16 @@ void HtmlGenerator::generateQmlSummary(const Section& section,
CodeMarker *marker)
{
if (!section.members.isEmpty()) {
- NodeList::ConstIterator m;
- int count = section.members.size();
- bool twoColumn = false;
- if (section.members.first()->type() == Node::QmlProperty) {
- twoColumn = (count >= 5);
- }
- if (twoColumn)
- out() << "<p><table width=\"100%\" border=\"0\" cellpadding=\"0\""
- " cellspacing=\"0\">\n"
- << "<tr><td width=\"45%\" valign=\"top\">";
out() << "<ul>\n";
-
- int row = 0;
+ NodeList::ConstIterator m;
m = section.members.begin();
while (m != section.members.end()) {
- if (twoColumn && row == (int) (count + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
- out() << "<li><div class=\"fn\"></div>";
+ out() << "<li class=\"fn\">";
generateQmlItem(*m,relative,marker,true);
out() << "</li>\n";
- row++;
++m;
}
out() << "</ul>\n";
- if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
}
}
@@ -4190,32 +4210,36 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
CodeMarker *marker)
{
const QmlPropertyNode* qpn = 0;
+#ifdef GENERATE_MAC_REFS
generateMacRef(node, marker);
+#endif
+ generateExtractionMark(node, MemberMark);
out() << "<div class=\"qmlitem\">";
if (node->subType() == Node::QmlPropertyGroup) {
const QmlPropGroupNode* qpgn = static_cast<const QmlPropGroupNode*>(node);
NodeList::ConstIterator p = qpgn->childNodes().begin();
out() << "<div class=\"qmlproto\">";
- out() << "<table width=\"100%\" class=\"qmlname\">";
+ out() << "<table class=\"qmlname\">";
while (p != qpgn->childNodes().end()) {
if ((*p)->type() == Node::QmlProperty) {
qpn = static_cast<const QmlPropertyNode*>(*p);
- out() << "<tr><td>";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+
+ out() << "<td class=\"tblQmlPropNode\"><p>";
+
out() << "<a name=\"" + refForNode(qpn) + "\"></a>";
- if (!qpn->isWritable())
+
+ if (!qpn->isWritable(myTree)) {
out() << "<span class=\"qmlreadonly\">read-only</span>";
- generateQmlItem(qpn, relative, marker, false);
- out() << "</td></tr>";
- if (qpgn->isDefault()) {
- out() << "</table>"
- << "</div></div>"
- << "<div class=\"qmlitem\">"
- << "<div class=\"qmlproto\">"
- << "<table class=\"qmlname\">"
- << "<tr><td><font color=\"green\">"
- << "default</font></td></tr>";
}
+ if (qpgn->isDefault())
+ out() << "<span class=\"qmldefault\">default</span>";
+ generateQmlItem(qpn, relative, marker, false);
+ out() << "</p></td></tr>";
}
++p;
}
@@ -4226,11 +4250,16 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
const FunctionNode* qsn = static_cast<const FunctionNode*>(node);
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
- out() << "<tr><td>";
+ //out() << "<tr>";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+ out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qsn) + "\"></a>";
generateSynopsis(qsn,relative,marker,CodeMarker::Detailed,false);
//generateQmlItem(qsn,relative,marker,false);
- out() << "</td></tr>";
+ out() << "</p></td></tr>";
out() << "</table>";
out() << "</div>";
}
@@ -4238,10 +4267,15 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
const FunctionNode* qmn = static_cast<const FunctionNode*>(node);
out() << "<div class=\"qmlproto\">";
out() << "<table class=\"qmlname\">";
- out() << "<tr><td>";
+ //out() << "<tr>";
+ if (++numTableRows % 2 == 1)
+ out() << "<tr class=\"odd\">";
+ else
+ out() << "<tr class=\"even\">";
+ out() << "<td class=\"tblQmlFuncNode\"><p>";
out() << "<a name=\"" + refForNode(qmn) + "\"></a>";
generateSynopsis(qmn,relative,marker,CodeMarker::Detailed,false);
- out() << "</td></tr>";
+ out() << "</p></td></tr>";
out() << "</table>";
out() << "</div>";
}
@@ -4253,6 +4287,7 @@ void HtmlGenerator::generateDetailedQmlMember(const Node *node,
generateAlsoList(node, marker);
out() << "</div>";
out() << "</div>";
+ generateExtractionMark(node, EndMark);
}
/*!
@@ -4270,22 +4305,40 @@ void HtmlGenerator::generateQmlInherits(const QmlClassNode* cn,
const Node* n = myTree->findNode(strList,Node::Fake);
if (n && n->subType() == Node::QmlClass) {
const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
- out() << "<p style=\"text-align: center\">";
Text text;
- text << "[Inherits ";
+ text << Atom::ParaLeft << "Inherits ";
text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, linkPair.second);
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- text << "]";
+ text << Atom::ParaRight;
generateText(text, cn, marker);
- out() << "</p>";
}
}
}
}
/*!
+ Output the "Inherit by" list for the QML element,
+ if it is inherited by any other elements.
+ */
+void HtmlGenerator::generateQmlInheritedBy(const QmlClassNode* cn,
+ CodeMarker* marker)
+{
+ if (cn) {
+ NodeList subs;
+ QmlClassNode::subclasses(cn->name(),subs);
+ if (!subs.isEmpty()) {
+ Text text;
+ text << Atom::ParaLeft << "Inherited by ";
+ appendSortedQmlNames(text,cn,subs,marker);
+ text << Atom::ParaRight;
+ generateText(text, cn, marker);
+ }
+ }
+}
+
+/*!
Output the "[Xxx instantiates the C++ class QmlGraphicsXxx]"
line for the QML element, if there should be one.
@@ -4297,21 +4350,22 @@ void HtmlGenerator::generateQmlInstantiates(const QmlClassNode* qcn,
{
const ClassNode* cn = qcn->classNode();
if (cn && (cn->status() != Node::Internal)) {
- out() << "<p style=\"text-align: center\">";
Text text;
- text << "[";
+ text << Atom::ParaLeft;
text << Atom(Atom::LinkNode,CodeMarker::stringForNode(qcn));
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
- text << Atom(Atom::String, qcn->name());
+ QString name = qcn->name();
+ if (name.startsWith(QLatin1String("QML:")))
+ name = name.mid(4); // remove the "QML:" prefix
+ text << Atom(Atom::String, name);
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
text << " instantiates the C++ class ";
text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, cn->name());
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- text << "]";
+ text << Atom::ParaRight;
generateText(text, qcn, marker);
- out() << "</p>";
}
}
@@ -4328,9 +4382,8 @@ void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn,
if (cn && cn->status() != Node::Internal && !cn->qmlElement().isEmpty()) {
const Node* n = myTree->root()->findNode(cn->qmlElement(),Node::Fake);
if (n && n->subType() == Node::QmlClass) {
- out() << "<p style=\"text-align: center\">";
Text text;
- text << "[";
+ text << Atom::ParaLeft;
text << Atom(Atom::LinkNode,CodeMarker::stringForNode(cn));
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, cn->name());
@@ -4340,11 +4393,249 @@ void HtmlGenerator::generateInstantiatedBy(const ClassNode* cn,
text << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK);
text << Atom(Atom::String, n->name());
text << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- text << "]";
+ text << Atom::ParaRight;
generateText(text, cn, marker);
- out() << "</p>";
}
}
}
+/*!
+ Generate the <page> element for the given \a node using the \a writer.
+ Return true if a <page> element was written; otherwise return false.
+ */
+bool HtmlGenerator::generatePageElement(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const
+{
+ if (node->pageType() == Node::NoPageType)
+ return false;
+ if (node->name().isEmpty())
+ return true;
+ if (node->access() == Node::Private)
+ return false;
+
+ QString guid = QUuid::createUuid().toString();
+ QString url = PageGenerator::fileName(node);
+ QString title;
+ QString rawTitle;
+ QString fullTitle;
+ QStringList pageWords;
+ QXmlStreamAttributes attributes;
+
+ writer.writeStartElement("page");
+
+ if (node->isInnerNode()) {
+ const InnerNode* inner = static_cast<const InnerNode*>(node);
+ if (!inner->pageKeywords().isEmpty())
+ pageWords << inner->pageKeywords();
+
+ switch (node->type()) {
+ case Node::Fake:
+ {
+ const FakeNode* fake = static_cast<const FakeNode*>(node);
+ title = fake->fullTitle();
+ pageWords << title;
+ break;
+ }
+ case Node::Class:
+ {
+ title = node->name() + " Class Reference";
+ pageWords << node->name() << "class" << "reference";
+ break;
+ }
+ case Node::Namespace:
+ {
+ rawTitle = marker->plainName(inner);
+ fullTitle = marker->plainFullName(inner);
+ title = rawTitle + " Namespace Reference";
+ pageWords << rawTitle << "namespace" << "reference";
+ break;
+ }
+ default:
+ title = node->name();
+ pageWords << title;
+ break;
+ }
+ }
+ else {
+ switch (node->type()) {
+ case Node::Enum:
+ {
+ title = node->name() + " Enum Reference";
+ pageWords << node->name() << "enum" << "type";
+ url += "#" + node->name() + "-enum";
+ break;
+ }
+ case Node::Function:
+ {
+ title = node->name() + " Function Reference";
+ pageWords << node->name() << "function";
+ url += "#" + node->name();
+ break;
+ }
+ case Node::Property:
+ {
+ title = node->name() + " Property Reference";
+ pageWords << node->name() << "property";
+ url += "#" + node->name() + "-prop";
+ break;
+ }
+ case Node::Typedef:
+ {
+ title = node->name() + " Type Reference";
+ pageWords << node->name() << "typedef" << "type";
+ url += "#" + node->name();
+ break;
+ }
+ default:
+ title = node->name();
+ pageWords << title;
+ break;
+ }
+
+ Node* parent = node->parent();
+ if (parent && ((parent->type() == Node::Class) ||
+ (parent->type() == Node::Namespace))) {
+ pageWords << parent->name();
+ }
+ }
+
+ writer.writeAttribute("id",guid);
+ writer.writeStartElement("pageWords");
+ writer.writeCharacters(pageWords.join(" "));
+
+ writer.writeEndElement();
+ writer.writeStartElement("pageTitle");
+ writer.writeCharacters(title);
+ writer.writeEndElement();
+ writer.writeStartElement("pageUrl");
+ writer.writeCharacters(url);
+ writer.writeEndElement();
+ writer.writeStartElement("pageType");
+ switch (node->pageType()) {
+ case Node::ApiPage:
+ writer.writeCharacters("APIPage");
+ break;
+ case Node::ArticlePage:
+ writer.writeCharacters("Article");
+ break;
+ case Node::ExamplePage:
+ writer.writeCharacters("Example");
+ break;
+ default:
+ break;
+ }
+ writer.writeEndElement();
+ writer.writeEndElement();
+
+ if (node->type() == Node::Fake && node->doc().hasTableOfContents()) {
+ QList<Atom*> toc = node->doc().tableOfContents();
+ if (!toc.isEmpty()) {
+ for (int i = 0; i < toc.size(); ++i) {
+ Text headingText = Text::sectionHeading(toc.at(i));
+ QString s = headingText.toString();
+ writer.writeStartElement("page");
+ guid = QUuid::createUuid().toString();
+ QString internalUrl = url + "#" + Doc::canonicalTitle(s);
+ writer.writeAttribute("id",guid);
+ writer.writeStartElement("pageWords");
+ writer.writeCharacters(pageWords.join(" "));
+ writer.writeCharacters(" ");
+ writer.writeCharacters(s);
+ writer.writeEndElement();
+ writer.writeStartElement("pageTitle");
+ writer.writeCharacters(s);
+ writer.writeEndElement();
+ writer.writeStartElement("pageUrl");
+ writer.writeCharacters(internalUrl);
+ writer.writeEndElement();
+ writer.writeStartElement("pageType");
+ writer.writeCharacters("Article");
+ writer.writeEndElement();
+ writer.writeEndElement();
+ }
+ }
+ }
+ return true;
+}
+
+/*!
+ Traverse the tree recursively and generate the <keyword>
+ elements.
+ */
+void HtmlGenerator::generatePageElements(QXmlStreamWriter& writer, const Node* node, CodeMarker* marker) const
+{
+ if (generatePageElement(writer, node, marker)) {
+
+ if (node->isInnerNode()) {
+ const InnerNode *inner = static_cast<const InnerNode *>(node);
+
+ // Recurse to write an element for this child node and all its children.
+ foreach (const Node *child, inner->childNodes())
+ generatePageElements(writer, child, marker);
+ }
+ }
+}
+
+/*!
+ Outputs the file containing the index used for searching the html docs.
+ */
+void HtmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* marker) const
+{
+ QFile file(fileName);
+ if (!file.open(QFile::WriteOnly | QFile::Text))
+ return ;
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.writeStartDocument();
+ writer.writeStartElement("qtPageIndex");
+
+ generatePageElements(writer, myTree->root(), marker);
+
+ writer.writeEndElement(); // qtPageIndex
+ writer.writeEndDocument();
+ file.close();
+}
+
+void HtmlGenerator::generateExtractionMark(const Node *node, ExtractionMarkType markType)
+{
+ if (markType != EndMark) {
+ out() << "<!-- $$$" + node->name();
+ if (markType == MemberMark) {
+ if (node->type() == Node::Function) {
+ const FunctionNode *func = static_cast<const FunctionNode *>(node);
+ if (!func->associatedProperty()) {
+ if (func->overloadNumber() == 1)
+ out() << "[overload1]";
+ out() << "$$$" + func->name() + func->rawParameters().remove(' ');
+ }
+ } else if (node->type() == Node::Property) {
+ out() << "-prop";
+ const PropertyNode *prop = static_cast<const PropertyNode *>(node);
+ const NodeList &list = prop->functions();
+ foreach (const Node *propFuncNode, list) {
+ if (propFuncNode->type() == Node::Function) {
+ const FunctionNode *func = static_cast<const FunctionNode *>(propFuncNode);
+ out() << "$$$" + func->name() + func->rawParameters().remove(' ');
+ }
+ }
+ } else if (node->type() == Node::Enum) {
+ const EnumNode *enumNode = static_cast<const EnumNode *>(node);
+ foreach (const EnumItem &item, enumNode->items())
+ out() << "$$$" + item.name();
+ }
+ } else if (markType == BriefMark) {
+ out() << "-brief";
+ } else if (markType == DetailedDescriptionMark) {
+ out() << "-description";
+ }
+ out() << " -->\n";
+ } else {
+ out() << "<!-- @@@" + node->name() + " -->\n";
+ }
+}
+
#endif
+
+ QT_END_NAMESPACE
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index 19a7c78..b96d737 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -46,10 +46,9 @@
#ifndef HTMLGENERATOR_H
#define HTMLGENERATOR_H
-#define QDOC_NAME_ALIGNMENT
-
#include <qmap.h>
#include <qregexp.h>
+#include <QXmlStreamWriter>
#include "codemarker.h"
#include "config.h"
@@ -89,12 +88,17 @@ class HtmlGenerator : public PageGenerator
Typedef,
Property,
Variable,
+ QmlClass,
QmlProperty,
QmlSignal,
QmlMethod,
LastSinceType
};
+ enum Application {
+ Online,
+ Creator};
+
public:
HtmlGenerator();
~HtmlGenerator();
@@ -104,7 +108,8 @@ class HtmlGenerator : public PageGenerator
virtual QString format();
virtual void generateTree(const Tree *tree, CodeMarker *marker);
- static QString protect(const QString& string);
+ QString protectEnc(const QString &string);
+ static QString protect(const QString &string, const QString &encoding = "ISO-8859-1");
static QString cleanRef(const QString& ref);
static QString sinceTitle(int i) { return sinceTitles[i]; }
@@ -115,21 +120,31 @@ class HtmlGenerator : public PageGenerator
CodeMarker *marker);
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
- virtual QString fileExtension(const Node *node);
+ virtual QString fileExtension(const Node *node) const;
virtual QString refForNode(const Node *node);
virtual QString linkForNode(const Node *node, const Node *relative);
virtual QString refForAtom(Atom *atom, const Node *node);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
+ enum ExtractionMarkType {
+ BriefMark,
+ DetailedDescriptionMark,
+ MemberMark,
+ EndMark
+ };
const QPair<QString,QString> anchorForNode(const Node *node);
const Node *findNodeForTarget(const QString &target,
const Node *relative,
CodeMarker *marker,
const Atom *atom = 0);
- void generateHeader(const QString& title, const Node *node = 0,
- CodeMarker *marker = 0, bool mainPage = true);
+ void generateBreadCrumbs(const QString& title,
+ const Node *node,
+ CodeMarker *marker);
+ void generateHeader(const QString& title,
+ const Node *node = 0,
+ CodeMarker *marker = 0);
void generateTitle(const QString& title,
const Text &subTitle,
SubTitleSize subTitleSize,
@@ -150,7 +165,13 @@ class HtmlGenerator : public PageGenerator
Doc::SectioningUnit sectioningUnit,
int numColumns,
const Node *relative = 0);
- QString generateListOfAllMemberFile(const InnerNode *inner, CodeMarker *marker);
+ void generateTableOfContents(const Node *node,
+ CodeMarker *marker,
+ QList<Section>* sections = 0);
+ QString generateListOfAllMemberFile(const InnerNode *inner,
+ CodeMarker *marker);
+ QString generateAllQmlMembersFile(const QmlClassNode* qml_cn,
+ CodeMarker* marker);
QString generateLowStatusMemberFile(const InnerNode *inner,
CodeMarker *marker,
CodeMarker::Status status);
@@ -163,6 +184,7 @@ class HtmlGenerator : public PageGenerator
void generateCompactList(const Node *relative,
CodeMarker *marker,
const NodeMap &classMap,
+ bool includeAlphabet,
QString commonPrefix = QString());
void generateFunctionIndex(const Node *relative, CodeMarker *marker);
void generateLegaleseList(const Node *relative, CodeMarker *marker);
@@ -183,10 +205,11 @@ class HtmlGenerator : public PageGenerator
const InnerNode *relative,
CodeMarker *marker);
void generateQmlInherits(const QmlClassNode* cn, CodeMarker* marker);
+ void generateQmlInheritedBy(const QmlClassNode* cn, CodeMarker* marker);
void generateQmlInstantiates(const QmlClassNode* qcn, CodeMarker* marker);
void generateInstantiatedBy(const ClassNode* cn, CodeMarker* marker);
#endif
-#ifdef QDOC_NAME_ALIGNMENT
+
void generateSection(const NodeList& nl,
const Node *relative,
CodeMarker *marker,
@@ -195,28 +218,16 @@ class HtmlGenerator : public PageGenerator
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style,
- bool nameAlignment = false);
- void generateSectionInheritedList(const Section& section,
- const Node *relative,
- CodeMarker *marker,
- bool nameAlignment = false);
- QString highlightedCode(const QString& markedCode,
- CodeMarker *marker,
- const Node *relative,
- CodeMarker::SynopsisStyle style = CodeMarker::Accessors,
- bool nameAlignment = false);
-#else
- void generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style);
+ bool alignNames = false);
void generateSectionInheritedList(const Section& section,
const Node *relative,
CodeMarker *marker);
QString highlightedCode(const QString& markedCode,
- CodeMarker *marker,
- const Node *relative);
-#endif
+ CodeMarker* marker,
+ const Node* relative,
+ bool alignNames = false,
+ const Node* self = 0);
+
void generateFullName(const Node *apparentNode,
const Node *relative,
CodeMarker *marker,
@@ -230,7 +241,7 @@ class HtmlGenerator : public PageGenerator
void generateStatus(const Node *node, CodeMarker *marker);
QString registerRef(const QString& ref);
- QString fileBase(const Node *node);
+ virtual QString fileBase(const Node *node) const;
#if 0
QString fileBase(const Node *node, const SectionIterator& section);
#endif
@@ -239,9 +250,6 @@ class HtmlGenerator : public PageGenerator
void findAllFunctions(const InnerNode *node);
void findAllLegaleseTexts(const InnerNode *node);
void findAllNamespaces(const InnerNode *node);
-#ifdef ZZZ_QDOC_QML
- void findAllQmlClasses(const InnerNode *node);
-#endif
void findAllSince(const InnerNode *node);
static int hOffset(const Node *node);
static bool isThreeColumnEnumValueTable(const Atom *atom);
@@ -255,12 +263,23 @@ class HtmlGenerator : public PageGenerator
virtual void generateIndex(const QString &fileBase,
const QString &url,
const QString &title);
+#ifdef GENERATE_MAC_REFS
void generateMacRef(const Node *node, CodeMarker *marker);
+#endif
void beginLink(const QString &link,
const Node *node,
const Node *relative,
CodeMarker *marker);
void endLink();
+ bool generatePageElement(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const;
+ void generatePageElements(QXmlStreamWriter& writer,
+ const Node* node,
+ CodeMarker* marker) const;
+ void generatePageIndex(const QString& fileName,
+ CodeMarker* marker) const;
+ void generateExtractionMark(const Node *node, ExtractionMarkType markType);
#if 0
NavigationBar currentNavigationBar;
@@ -282,11 +301,15 @@ class HtmlGenerator : public PageGenerator
bool inTableHeader;
int numTableRows;
bool threeColumnEnumValueTable;
+ Application application;
QString link;
QStringList sectionNumber;
QRegExp funcLeftParen;
QString style;
QString postHeader;
+ QString postPostHeader;
+ QString creatorPostHeader;
+ QString creatorPostPostHeader;
QString footer;
QString address;
bool pleaseGenerateMacRef;
@@ -307,20 +330,26 @@ class HtmlGenerator : public PageGenerator
NodeMap obsoleteClasses;
NodeMap namespaceIndex;
NodeMap serviceClasses;
-#ifdef QDOC_QML
NodeMap qmlClasses;
-#endif
QMap<QString, NodeMap > funcIndex;
QMap<Text, const Node *> legaleseTexts;
NewSinceMaps newSinceMaps;
static QString sinceTitles[];
NewClassMaps newClassMaps;
+ NewClassMaps newQmlClassMaps;
+ static int id;
+ public:
+ static bool debugging_on;
+ static QString divNavTop;
};
#define HTMLGENERATOR_ADDRESS "address"
#define HTMLGENERATOR_FOOTER "footer"
-#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
+#define HTMLGENERATOR_GENERATEMACREFS "generatemacrefs" // ### document me
#define HTMLGENERATOR_POSTHEADER "postheader"
+#define HTMLGENERATOR_POSTPOSTHEADER "postpostheader"
+#define HTMLGENERATOR_CREATORPOSTHEADER "postheader"
+#define HTMLGENERATOR_CREATORPOSTPOSTHEADER "postpostheader"
#define HTMLGENERATOR_STYLE "style"
#define HTMLGENERATOR_STYLESHEETS "stylesheets"
#define HTMLGENERATOR_CUSTOMHEADELEMENTS "customheadelements"
diff --git a/tools/qdoc3/jambiapiparser.cpp b/tools/qdoc3/jambiapiparser.cpp
index 3aba1b0..23f2716 100644
--- a/tools/qdoc3/jambiapiparser.cpp
+++ b/tools/qdoc3/jambiapiparser.cpp
@@ -43,8 +43,6 @@
jambiapiparser.cpp
*/
-#include <QtXml>
-
#include "cppcodeparser.h"
#include "jambiapiparser.h"
#include "node.h"
diff --git a/tools/qdoc3/javacodemarker.cpp b/tools/qdoc3/javacodemarker.cpp
index 1918cd8..c9a8f60 100644
--- a/tools/qdoc3/javacodemarker.cpp
+++ b/tools/qdoc3/javacodemarker.cpp
@@ -155,8 +155,10 @@ QList<Section> JavaCodeMarker::sections(const InnerNode * /* inner */, SynopsisS
return QList<Section>();
}
-const Node *JavaCodeMarker::resolveTarget(const QString &target, const Tree *tree,
- const Node *relative)
+const Node *JavaCodeMarker::resolveTarget(const QString &target,
+ const Tree *tree,
+ const Node *relative,
+ const Node* /* self */)
{
if (target.endsWith("()")) {
const FunctionNode *func;
diff --git a/tools/qdoc3/javacodemarker.h b/tools/qdoc3/javacodemarker.h
index a2d04dd..c2aabc0 100644
--- a/tools/qdoc3/javacodemarker.h
+++ b/tools/qdoc3/javacodemarker.h
@@ -72,7 +72,10 @@ public:
QList<Section> sections(const InnerNode *innerNode, SynopsisStyle style, Status status);
QString functionBeginRegExp( const QString& funcName );
QString functionEndRegExp( const QString& funcName );
- const Node *resolveTarget( const QString& target, const Tree *tree, const Node *relative );
+ const Node* resolveTarget( const QString& target,
+ const Tree* tree,
+ const Node* relative,
+ const Node* self = 0 );
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp
index 001bd27..eb9c1c9 100644
--- a/tools/qdoc3/javadocgenerator.cpp
+++ b/tools/qdoc3/javadocgenerator.cpp
@@ -145,7 +145,7 @@ void JavadocGenerator::generateTree(const Tree *tree, CodeMarker *marker)
HtmlGenerator::generateTree(tree, marker);
}
-QString JavadocGenerator::fileExtension(const Node *node)
+QString JavadocGenerator::fileExtension(const Node *node) const
{
if (node->type() == Node::Fake) {
return "html";
diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h
index 73452cf..b485502 100644
--- a/tools/qdoc3/javadocgenerator.h
+++ b/tools/qdoc3/javadocgenerator.h
@@ -61,7 +61,7 @@ public:
QString imageFileName(const Node *relative, const QString &fileBase);
protected:
- QString fileExtension(const Node *node);
+ QString fileExtension(const Node *node) const;
void startText( const Node *relative, CodeMarker *marker );
void endText( const Node *relative, CodeMarker *marker );
int generateAtom( const Atom *atom, const Node *relative, CodeMarker *marker );
diff --git a/tools/qdoc3/linguistgenerator.cpp b/tools/qdoc3/linguistgenerator.cpp
index d1bd22d..702f0fb 100644
--- a/tools/qdoc3/linguistgenerator.cpp
+++ b/tools/qdoc3/linguistgenerator.cpp
@@ -82,14 +82,14 @@ QString LinguistGenerator::format()
return "Linguist";
}
-QString LinguistGenerator::fileExtension(const Node * /* node */)
+QString LinguistGenerator::fileExtension(const Node * /* node */) const
{
return "ts";
}
void LinguistGenerator::generateClassLikeNode(const InnerNode *inner, CodeMarker *marker)
{
- out().setCodec("utf-8");
+ out().setCodec("UTF-8");
QDomDocument document("TS");
QDomElement documentElement = document.createElement("TS");
@@ -100,7 +100,7 @@ void LinguistGenerator::generateClassLikeNode(const InnerNode *inner, CodeMarker
documentElement.appendChild(element);
QDomProcessingInstruction process = document.createProcessingInstruction(
- "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("utf-8"));
+ "xml", QString("version=\"1.0\" encoding=\"%1\"").arg("UTF-8"));
document.appendChild(process);
document.appendChild(documentElement);
diff --git a/tools/qdoc3/linguistgenerator.h b/tools/qdoc3/linguistgenerator.h
index f7f0606..979db02 100644
--- a/tools/qdoc3/linguistgenerator.h
+++ b/tools/qdoc3/linguistgenerator.h
@@ -70,7 +70,7 @@ protected:
virtual void generateClassLikeNode(const InnerNode *inner,
CodeMarker *marker);
virtual void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
- virtual QString fileExtension(const Node *node);
+ virtual QString fileExtension(const Node *node) const;
QList<QDomElement> generateIndexSections(QDomDocument &document,
const Node *node, CodeMarker *marker);
diff --git a/tools/qdoc3/location.cpp b/tools/qdoc3/location.cpp
index 19625da..dee87d1 100644
--- a/tools/qdoc3/location.cpp
+++ b/tools/qdoc3/location.cpp
@@ -265,6 +265,8 @@ void Location::error(const QString& message, const QString& details) const
void Location::fatal(const QString& message, const QString& details) const
{
emitMessage(Error, message, details);
+ information(message);
+ information(details);
information("Aborting");
exit(EXIT_FAILURE);
}
diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp
index 3d0106d..2bfe38e 100644
--- a/tools/qdoc3/main.cpp
+++ b/tools/qdoc3/main.cpp
@@ -44,7 +44,6 @@
*/
#include <qglobal.h>
-#include <QtCore>
#include <stdlib.h>
#include "apigenerator.h"
#include "codemarker.h"
@@ -69,8 +68,15 @@
#include "qscodeparser.h"
#include "sgmlgenerator.h"
#include "webxmlgenerator.h"
+#include "ditaxmlgenerator.h"
#include "tokenizer.h"
#include "tree.h"
+#include <qdebug.h>
+
+#include "qtranslator.h"
+#ifndef QT_BOOTSTRAPPED
+# include "qcoreapplication.h"
+#endif
QT_BEGIN_NAMESPACE
@@ -99,6 +105,7 @@ static bool showInternal = false;
static bool obsoleteLinks = false;
static QStringList defines;
static QHash<QString, Tree *> trees;
+static QString appArg; // application
/*!
Find the Tree for language \a lang and return a pointer to it.
@@ -141,7 +148,7 @@ static void printHelp()
*/
static void printVersion()
{
- QString s = QString(tr("qdoc version ")) + QString(QT_VERSION_STR);
+ QString s = tr("qdoc version %1").arg(QT_VERSION_STR);
Location::information(s);
}
@@ -151,7 +158,9 @@ static void printVersion()
*/
static void processQdocconfFile(const QString &fileName)
{
+#ifndef QT_NO_TRANSLATION
QList<QTranslator *> translators;
+#endif
/*
The Config instance represents the configuration data for qdoc.
@@ -184,6 +193,24 @@ static void processQdocconfFile(const QString &fileName)
config.load(fileName);
/*
+ Set the application to which qdoc will create the output.
+ The two applications are:
+
+ creator: additional formatting for viewing in
+ the Creator application.
+
+ online: full-featured online version with search and
+ links to Qt topics
+ */
+ if (appArg.isEmpty()) {
+ qDebug() << "Warning: Application flag not specified on"
+ << "command line. Options are -creator (default)"
+ << "and -online.";
+ appArg = "creator";
+ }
+ config.setStringList(CONFIG_APPLICATION, QStringList(appArg));
+
+ /*
Add the defines to the configuration variables.
*/
QStringList defs = defines + config.getStringList(CONFIG_DEFINES);
@@ -207,6 +234,7 @@ static void processQdocconfFile(const QString &fileName)
CodeParser::initialize(config);
Generator::initialize(config);
+#ifndef QT_NO_TRANSLATION
/*
Load the language translators, if the configuration specifies any.
*/
@@ -221,6 +249,7 @@ static void processQdocconfFile(const QString &fileName)
translators.append(translator);
++fn;
}
+#endif
//QSet<QString> outputLanguages = config.getStringSet(CONFIG_OUTPUTLANGUAGES);
@@ -337,8 +366,9 @@ static void processQdocconfFile(const QString &fileName)
Generate the XML tag file, if it was requested.
*/
QString tagFile = config.getString(CONFIG_TAGFILE);
- if (!tagFile.isEmpty())
+ if (!tagFile.isEmpty()) {
tree->generateTagFile(tagFile);
+ }
tree->setVersion("");
Generator::terminate();
@@ -350,9 +380,16 @@ static void processQdocconfFile(const QString &fileName)
Location::terminate();
QDir::setCurrent(prevCurrentDir);
- foreach (QTranslator *translator, translators)
- delete translator;
+#ifndef QT_NO_TRANSLATION
+ qDeleteAll(translators);
+#endif
+#ifdef DEBUG_SHUTDOWN_CRASH
+ qDebug() << "main(): Delete tree";
+#endif
delete tree;
+#ifdef DEBUG_SHUTDOWN_CRASH
+ qDebug() << "main(): Tree deleted";
+#endif
}
QT_END_NAMESPACE
@@ -361,7 +398,9 @@ int main(int argc, char **argv)
{
QT_USE_NAMESPACE
+#ifndef QT_BOOTSTRAPPED
QCoreApplication app(argc, argv);
+#endif
QString cf = "qsauncompress \1 \2";
PolyArchiveExtractor qsaExtractor(QStringList() << "qsa",cf);
cf = "tar -C \2 -xf \1";
@@ -408,6 +447,7 @@ int main(int argc, char **argv)
ManGenerator manGenerator;
SgmlGenerator smglGenerator;
WebXMLGenerator webxmlGenerator;
+ DitaXmlGenerator ditaxmlGenerator;
QStringList qdocFiles;
QString opt;
@@ -441,12 +481,16 @@ int main(int argc, char **argv)
else if (opt == "-obsoletelinks") {
obsoleteLinks = true;
}
+ else if (opt == "-creator")
+ appArg = "creator";
+ else if (opt == "-online")
+ appArg = "online";
else {
qdocFiles.append(opt);
}
}
- if (qdocFiles.isEmpty()) {
+ if (qdocFiles.isEmpty()) {
printHelp();
return EXIT_FAILURE;
}
@@ -454,8 +498,10 @@ int main(int argc, char **argv)
/*
Main loop.
*/
- foreach (QString qf, qdocFiles)
+ foreach (QString qf, qdocFiles) {
+ //qDebug() << "PROCESSING:" << qf;
processQdocconfFile(qf);
+ }
qDeleteAll(trees);
return EXIT_SUCCESS;
diff --git a/tools/qdoc3/mangenerator.cpp b/tools/qdoc3/mangenerator.cpp
index c3b7780..1e85b73 100644
--- a/tools/qdoc3/mangenerator.cpp
+++ b/tools/qdoc3/mangenerator.cpp
@@ -187,7 +187,7 @@ void ManGenerator::generateFakeNode( const FakeNode *fake, CodeMarker *marker )
generateFooter();
}
-QString ManGenerator::fileExtension(const Node * /* node */)
+QString ManGenerator::fileExtension(const Node * /* node */) const
{
return "3qt";
}
diff --git a/tools/qdoc3/mangenerator.h b/tools/qdoc3/mangenerator.h
index 284517e..0fca342 100644
--- a/tools/qdoc3/mangenerator.h
+++ b/tools/qdoc3/mangenerator.h
@@ -63,7 +63,7 @@ protected:
CodeMarker *marker );
virtual void generateClassLikeNode(const InnerNode *node, CodeMarker *marker);
virtual void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
- virtual QString fileExtension(const Node *node);
+ virtual QString fileExtension(const Node *node) const;
private:
void generateHeader( const QString& name );
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 5796ea4..41f90d5 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -43,8 +43,10 @@
node.cpp
*/
-#include <QtCore>
#include "node.h"
+#include "tree.h"
+#include "codemarker.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -85,21 +87,27 @@ void Node::setDoc(const Doc& doc, bool replace)
}
/*!
+ Construct a node with the given \a type and having the
+ given \a parent and \a name. The new node is added to the
+ parent's child list.
*/
Node::Node(Type type, InnerNode *parent, const QString& name)
: typ(type),
acc(Public),
- sta(Commendable),
saf(UnspecifiedSafeness),
+ pageTyp(NoPageType),
+ sta(Commendable),
par(parent),
rel(0),
nam(name)
{
if (par)
par->addChild(this);
+ //uuid = QUuid::createUuid();
}
/*!
+ Returns the node's URL.
*/
QString Node::url() const
{
@@ -107,13 +115,25 @@ QString Node::url() const
}
/*!
+ Sets the node's URL to \a url
*/
void Node::setUrl(const QString &url)
{
u = url;
}
+void Node::setPageType(const QString& t)
+{
+ if ((t == "API") || (t == "api"))
+ pageTyp = ApiPage;
+ else if (t == "article")
+ pageTyp = ArticlePage;
+ else if (t == "example")
+ pageTyp = ExamplePage;
+}
+
/*!
+ Sets the pointer to the node that this node relates to.
*/
void Node::setRelates(InnerNode *pseudoParent)
{
@@ -137,6 +157,67 @@ void Node::setLink(LinkType linkType, const QString &link, const QString &desc)
}
/*!
+ Returns a string representing the access specifier.
+ */
+QString Node::accessString() const
+{
+ switch (acc) {
+ case Protected:
+ return "protected";
+ case Private:
+ return "private";
+ case Public:
+ default:
+ break;
+ }
+ return "public";
+}
+
+/*!
+ Extract a class name from the type \a string and return it.
+ */
+QString Node::extractClassName(const QString &string) const
+{
+ QString result;
+ for (int i=0; i<=string.size(); ++i) {
+ QChar ch;
+ if (i != string.size())
+ ch = string.at(i);
+
+ QChar lower = ch.toLower();
+ if ((lower >= QLatin1Char('a') && lower <= QLatin1Char('z')) ||
+ ch.digitValue() >= 0 ||
+ ch == QLatin1Char('_') ||
+ ch == QLatin1Char(':')) {
+ result += ch;
+ }
+ else if (!result.isEmpty()) {
+ if (result != QLatin1String("const"))
+ return result;
+ result.clear();
+ }
+ }
+ return result;
+}
+
+/*!
+ Returns a string representing the access specifier.
+ */
+QString RelatedClass::accessString() const
+{
+ switch (access) {
+ case Node::Protected:
+ return "protected";
+ case Node::Private:
+ return "private";
+ case Node::Public:
+ default:
+ break;
+ }
+ return "public";
+}
+
+/*!
*/
Node::Status Node::inheritedStatus() const
{
@@ -147,6 +228,11 @@ Node::Status Node::inheritedStatus() const
}
/*!
+ Returns the thread safeness value for whatever this node
+ represents. But if this node has a parent and the thread
+ safeness value of the parent is the same as the thread
+ safeness value of this node, what is returned is the
+ value \c{UnspecifiedSafeness}. Why?
*/
Node::ThreadSafeness Node::threadSafeness() const
{
@@ -156,6 +242,9 @@ Node::ThreadSafeness Node::threadSafeness() const
}
/*!
+ If this node has a parent, the parent's thread safeness
+ value is returned. Otherwise, this node's thread safeness
+ value is returned. Why?
*/
Node::ThreadSafeness Node::inheritedThreadSafeness() const
{
@@ -165,6 +254,9 @@ Node::ThreadSafeness Node::inheritedThreadSafeness() const
}
/*!
+ Returns the sanitized file name without the path.
+ If the the file is an html file, the html suffix
+ is removed. Why?
*/
QString Node::fileBase() const
{
@@ -178,10 +270,47 @@ QString Node::fileBase() const
}
/*!
+ Returns this node's Universally Unique IDentifier.
+ If its UUID has not yet been created, it is created
+ first.
+ */
+QUuid Node::guid() const
+{
+ if (uuid.isNull())
+ uuid = QUuid::createUuid();
+ return uuid;
+}
+
+/*!
+ Composes a string to be used as an href attribute in DITA
+ XML. It is composed of the file name and the UUID separated
+ by a '#'. If this node is a class node, the file name is
+ taken from this node; if this node is a function node, the
+ file name is taken from the parent node of this node.
+ */
+QString Node::ditaXmlHref()
+{
+ QString href;
+ if ((type() == Function) ||
+ (type() == Property) ||
+ (type() == Variable)) {
+ href = parent()->fileBase();
+ }
+ else {
+ href = fileBase();
+ }
+ if (!href.endsWith(".xml"))
+ href += ".xml";
+ return href + "#" + guid();
+}
+
+/*!
\class InnerNode
*/
/*!
+ The inner node destructor deletes the children and removes
+ this node from its related nodes.
*/
InnerNode::~InnerNode()
{
@@ -190,16 +319,33 @@ InnerNode::~InnerNode()
}
/*!
+ Find the node in this node's children that has the
+ given \a name. If this node is a QML class node, be
+ sure to also look in the children of its property
+ group nodes. Return the matching node or 0.
*/
Node *InnerNode::findNode(const QString& name)
{
Node *node = childMap.value(name);
- if (node)
+ if (node && node->subType() != QmlPropertyGroup)
return node;
+ if ((type() == Fake) && (subType() == QmlClass)) {
+ for (int i=0; i<children.size(); ++i) {
+ Node* n = children.at(i);
+ if (n->subType() == QmlPropertyGroup) {
+ node = static_cast<InnerNode*>(n)->findNode(name);
+ if (node)
+ return node;
+ }
+ }
+ }
return primaryFunctionMap.value(name);
}
/*!
+ Same as the other findNode(), but if the node with the
+ specified \a name is not of the specified \a type, return
+ 0.
*/
Node *InnerNode::findNode(const QString& name, Type type)
{
@@ -308,6 +454,9 @@ void InnerNode::setOverload(const FunctionNode *func, bool overlode)
}
/*!
+ Mark all child nodes that have no documentation as having
+ private access and internal status. qdoc will then ignore
+ them for documentation purposes.
*/
void InnerNode::makeUndocumentedChildrenInternal()
{
@@ -381,7 +530,7 @@ void InnerNode::normalizeOverloads()
/*!
*/
-void InnerNode::removeFromRelated()
+void InnerNode::removeFromRelated()
{
while (!related.isEmpty()) {
Node *p = static_cast<Node *>(related.takeFirst());
@@ -398,7 +547,7 @@ void InnerNode::deleteChildren()
}
/*!
- Returns true.
+ Returns true because this is an inner node.
*/
bool InnerNode::isInnerNode() const
{
@@ -422,7 +571,7 @@ const Node *InnerNode::findNode(const QString& name, Type type) const
}
/*!
- Find the function node in this node that has the given \a name.
+ Find the function node in this node that has the given \a name.
*/
const FunctionNode *InnerNode::findFunctionNode(const QString& name) const
{
@@ -452,6 +601,9 @@ const EnumNode *InnerNode::findEnumNodeForValue(const QString &enumValue) const
}
/*!
+ Returnds the sequence number of the function node \a func
+ in the list of overloaded functions for a class, such that
+ all the functions have the same name as the \a func.
*/
int InnerNode::overloadNumber(const FunctionNode *func) const
{
@@ -465,6 +617,8 @@ int InnerNode::overloadNumber(const FunctionNode *func) const
}
/*!
+ Returns the number of member functions of a class such that
+ the functions are all named \a funcName.
*/
int InnerNode::numOverloads(const QString& funcName) const
{
@@ -477,6 +631,8 @@ int InnerNode::numOverloads(const QString& funcName) const
}
/*!
+ Returns a node list containing all the member functions of
+ some class such that the functions overload the name \a funcName.
*/
NodeList InnerNode::overloads(const QString &funcName) const
{
@@ -490,13 +646,24 @@ NodeList InnerNode::overloads(const QString &funcName) const
}
/*!
+ Construct an inner node (i.e., not a leaf node) of the
+ given \a type and having the given \a parent and \a name.
*/
InnerNode::InnerNode(Type type, InnerNode *parent, const QString& name)
: Node(type, parent, name)
{
+ switch (type) {
+ case Class:
+ case Namespace:
+ setPageType(ApiPage);
+ break;
+ default:
+ break;
+ }
}
/*!
+ Appends an \a include file to the list of include files.
*/
void InnerNode::addInclude(const QString& include)
{
@@ -504,6 +671,7 @@ void InnerNode::addInclude(const QString& include)
}
/*!
+ Sets the list of include files to \a includes.
*/
void InnerNode::setIncludes(const QStringList& includes)
{
@@ -547,6 +715,7 @@ bool InnerNode::isSameSignature(const FunctionNode *f1, const FunctionNode *f2)
}
/*!
+ Adds the \a child to this node's child list.
*/
void InnerNode::addChild(Node *child)
{
@@ -564,7 +733,7 @@ void InnerNode::addChild(Node *child)
else {
if (child->type() == Enum)
enumChildren.append(child);
- childMap.insert(child->name(), child);
+ childMap.insert(child->name(), child);
}
}
@@ -578,7 +747,7 @@ void InnerNode::removeChild(Node *child)
QMap<QString, Node *>::Iterator prim =
primaryFunctionMap.find(child->name());
NodeList& secs = secondaryFunctionMap[child->name()];
- if (*prim == child) {
+ if (prim != primaryFunctionMap.end() && *prim == child) {
if (secs.isEmpty()) {
primaryFunctionMap.remove(child->name());
}
@@ -590,12 +759,12 @@ void InnerNode::removeChild(Node *child)
secs.removeAll(child);
}
QMap<QString, Node *>::Iterator ent = childMap.find( child->name() );
- if ( *ent == child )
+ if (ent != childMap.end() && *ent == child)
childMap.erase( ent );
}
else {
QMap<QString, Node *>::Iterator ent = childMap.find(child->name());
- if (*ent == child)
+ if (ent != childMap.end() && *ent == child)
childMap.erase(ent);
}
}
@@ -676,10 +845,25 @@ bool LeafNode::isInnerNode() const
}
/*!
+ Constructs a leaf node named \a name of the specified
+ \a type. The new leaf node becomes a child of \a parent.
*/
LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
: Node(type, parent, name)
{
+ switch (type) {
+ case Enum:
+ case Function:
+ case Typedef:
+ case Variable:
+ case QmlProperty:
+ case QmlSignal:
+ case QmlMethod:
+ setPageType(ApiPage);
+ break;
+ default:
+ break;
+ }
}
/*!
@@ -687,22 +871,28 @@ LeafNode::LeafNode(Type type, InnerNode *parent, const QString& name)
*/
/*!
+ Constructs a namespace node.
*/
NamespaceNode::NamespaceNode(InnerNode *parent, const QString& name)
: InnerNode(Namespace, parent, name)
{
+ setPageType(ApiPage);
}
/*!
\class ClassNode
+ \brief This class represents a C++ class.
*/
/*!
+ Constructs a class node. A class node will generate an API page.
*/
ClassNode::ClassNode(InnerNode *parent, const QString& name)
: InnerNode(Class, parent, name)
{
hidden = false;
+ abstract = false;
+ setPageType(ApiPage);
}
/*!
@@ -711,8 +901,8 @@ void ClassNode::addBaseClass(Access access,
ClassNode *node,
const QString &dataTypeWithTemplateArgs)
{
- bas.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
- node->der.append(RelatedClass(access, this));
+ bases.append(RelatedClass(access, node, dataTypeWithTemplateArgs));
+ node->derived.append(RelatedClass(access, this));
}
/*!
@@ -720,16 +910,16 @@ void ClassNode::addBaseClass(Access access,
void ClassNode::fixBaseClasses()
{
int i;
-
i = 0;
- while (i < bas.size()) {
- ClassNode *baseClass = bas.at(i).node;
- if (baseClass->access() == Node::Private) {
- bas.removeAt(i);
-
- const QList<RelatedClass> &basesBases = baseClass->baseClasses();
- for (int j = basesBases.size() - 1; j >= 0; --j)
- bas.insert(i, basesBases.at(j));
+ while (i < bases.size()) {
+ ClassNode* bc = bases.at(i).node;
+ if (bc->access() == Node::Private) {
+ RelatedClass rc = bases.at(i);
+ bases.removeAt(i);
+ ignoredBases.append(rc);
+ const QList<RelatedClass> &bb = bc->baseClasses();
+ for (int j = bb.size() - 1; j >= 0; --j)
+ bases.insert(i, bb.at(j));
}
else {
++i;
@@ -737,15 +927,13 @@ void ClassNode::fixBaseClasses()
}
i = 0;
- while (i < der.size()) {
- ClassNode *derivedClass = der.at(i).node;
- if (derivedClass->access() == Node::Private) {
- der.removeAt(i);
-
- const QList<RelatedClass> &dersDers =
- derivedClass->derivedClasses();
- for (int j = dersDers.size() - 1; j >= 0; --j)
- der.insert(i, dersDers.at(j));
+ while (i < derived.size()) {
+ ClassNode* dc = derived.at(i).node;
+ if (dc->access() == Node::Private) {
+ derived.removeAt(i);
+ const QList<RelatedClass> &dd = dc->derivedClasses();
+ for (int j = dd.size() - 1; j >= 0; --j)
+ derived.insert(i, dd.at(j));
}
else {
++i;
@@ -754,16 +942,51 @@ void ClassNode::fixBaseClasses()
}
/*!
+ Search the child list to find the property node with the
+ specified \a name.
+ */
+const PropertyNode* ClassNode::findPropertyNode(const QString& name) const
+{
+ const Node* n = findNode(name,Node::Property);
+ return (n ? static_cast<const PropertyNode*>(n) : 0);
+}
+
+/*!
\class FakeNode
*/
/*!
The type of a FakeNode is Fake, and it has a \a subtype,
- which specifies the type of FakeNode.
+ which specifies the type of FakeNode. The page type for
+ the page index is set here.
*/
FakeNode::FakeNode(InnerNode *parent, const QString& name, SubType subtype)
: InnerNode(Fake, parent, name), sub(subtype)
{
+ switch (subtype) {
+ case Module:
+ case Page:
+ case Group:
+ setPageType(ArticlePage);
+ break;
+ case QmlClass:
+ case QmlBasicType:
+ setPageType(ApiPage);
+ break;
+ case Example:
+ setPageType(ExamplePage);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ Returns the fake node's title. This is used for the page title.
+*/
+QString FakeNode::title() const
+{
+ return tle;
}
/*!
@@ -816,6 +1039,8 @@ QString FakeNode::subTitle() const
*/
/*!
+ The constructor for the node representing an enum type
+ has a \a parent class and an enum type \a name.
*/
EnumNode::EnumNode(InnerNode *parent, const QString& name)
: LeafNode(Enum, parent, name), ft(0)
@@ -823,6 +1048,7 @@ EnumNode::EnumNode(InnerNode *parent, const QString& name)
}
/*!
+ Add \a item to the enum type's item list.
*/
void EnumNode::addItem(const EnumItem& item)
{
@@ -831,15 +1057,15 @@ void EnumNode::addItem(const EnumItem& item)
}
/*!
+ Returns the access level of the enumeration item named \a name.
+ Apparently it is private if it has been omitted by qdoc's
+ omitvalue command. Otherwise it is public.
*/
Node::Access EnumNode::itemAccess(const QString &name) const
{
- if (doc().omitEnumItemNames().contains(name)) {
+ if (doc().omitEnumItemNames().contains(name))
return Private;
- }
- else {
- return Public;
- }
+ return Public;
}
/*!
@@ -904,7 +1130,7 @@ Parameter::Parameter(const Parameter& p)
/*!
Assigning Parameter \a p to this Parameter copies the
- strings across.
+ strings across.
*/
Parameter& Parameter::operator=(const Parameter& p)
{
@@ -974,6 +1200,19 @@ FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bo
}
/*!
+ Sets the \a virtualness of this function. If the \a virtualness
+ is PureVirtual, and if the parent() is a ClassNode, set the parent's
+ \e abstract flag to true.
+ */
+void FunctionNode::setVirtualness(Virtualness virtualness)
+{
+ vir = virtualness;
+ if ((virtualness == PureVirtual) && parent() &&
+ (parent()->type() == Node::Class))
+ parent()->setAbstract(true);
+}
+
+/*!
*/
void FunctionNode::setOverload(bool overlode)
{
@@ -1066,6 +1305,24 @@ QStringList FunctionNode::parameterNames() const
}
/*!
+ Returns a raw list of parameters. If \a names is true, the
+ names are included. If \a values is true, the default values
+ are included, if any are present.
+ */
+QString FunctionNode::rawParameters(bool names, bool values) const
+{
+ QString raw;
+ foreach (const Parameter &parameter, parameters()) {
+ raw += parameter.leftType() + parameter.rightType();
+ if (names)
+ raw += parameter.name();
+ if (values)
+ raw += parameter.defaultValue();
+ }
+ return raw;
+}
+
+/*!
Returns the list of reconstructed parameters. If \a values
is true, the default values are included, if any are present.
*/
@@ -1109,26 +1366,45 @@ QString FunctionNode::signature(bool values) const
*/
void FunctionNode::debug() const
{
- qDebug() << "QML METHOD" << name() << "rt" << rt << "pp" << pp;
+ qDebug("QML METHOD %s rt %s pp %s",
+ qPrintable(name()), qPrintable(rt), qPrintable(pp.join(" ")));
}
/*!
\class PropertyNode
+
+ This class describes one instance of using the Q_PROPERTY macro.
*/
/*!
+ The constructor sets the \a parent and the \a name, but
+ everything else is set to default values.
*/
PropertyNode::PropertyNode(InnerNode *parent, const QString& name)
: LeafNode(Property, parent, name),
sto(Trool_Default),
des(Trool_Default),
+ scr(Trool_Default),
+ wri(Trool_Default),
+ usr(Trool_Default),
+ cst(false),
+ fnl(false),
overrides(0)
{
+ // nothing.
}
/*!
+ Sets this property's \e {overridden from} property to
+ \a baseProperty, which indicates that this property
+ overrides \a baseProperty. To begin with, all the values
+ in this property are set to the corresponding values in
+ \a baseProperty.
+
+ We probably should ensure that the constant and final
+ attributes are not being overridden improperly.
*/
-void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty)
+void PropertyNode::setOverriddenFrom(const PropertyNode* baseProperty)
{
for (int i = 0; i < NumFunctionRoles; ++i) {
if (funcs[i].isEmpty())
@@ -1138,6 +1414,12 @@ void PropertyNode::setOverriddenFrom(const PropertyNode *baseProperty)
sto = baseProperty->sto;
if (des == Trool_Default)
des = baseProperty->des;
+ if (scr == Trool_Default)
+ scr = baseProperty->scr;
+ if (wri == Trool_Default)
+ wri = baseProperty->wri;
+ if (usr == Trool_Default)
+ usr = baseProperty->usr;
overrides = baseProperty;
}
@@ -1163,7 +1445,9 @@ QString PropertyNode::qualifiedDataType() const
}
}
-/*!
+/*! Converts the \a boolean value to an enum representation
+ of the boolean type, which includes an enum value for the
+ \e {default value} of the item, i.e. true, false, or default.
*/
PropertyNode::Trool PropertyNode::toTrool(bool boolean)
{
@@ -1171,6 +1455,15 @@ PropertyNode::Trool PropertyNode::toTrool(bool boolean)
}
/*!
+ Converts the enum \a troolean back to a boolean value.
+ If \a troolean is neither the true enum value nor the
+ false enum value, the boolean value returned is
+ \a defaultValue.
+
+ Note that runtimeDesignabilityFunction() should be called
+ first. If that function returns the name of a function, it
+ means the function must be called at runtime to determine
+ whether the property is Designable.
*/
bool PropertyNode::fromTrool(Trool troolean, bool defaultValue)
{
@@ -1205,16 +1498,43 @@ bool TargetNode::isInnerNode() const
#ifdef QDOC_QML
bool QmlClassNode::qmlOnly = false;
+QMultiMap<QString,Node*> QmlClassNode::inheritedBy;
/*!
- Constructor for the Qml class node.
+ Constructs a Qml class node (i.e. a Fake node with the
+ subtype QmlClass. The new node has the given \a parent
+ and \a name and is associated with the C++ class node
+ specified by \a cn which may be null if the the Qml
+ class node is not associated with a C++ class node.
*/
QmlClassNode::QmlClassNode(InnerNode *parent,
const QString& name,
const ClassNode* cn)
: FakeNode(parent, name, QmlClass), cnode(cn)
{
- setTitle((qmlOnly ? "" : "QML ") + name + " Element Reference");
+ if (name.startsWith(QLatin1String("QML:")))
+ setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name.mid(4) + QLatin1String(" Element"));
+ else
+ setTitle((qmlOnly ? QLatin1String("") : QLatin1String("QML ")) + name + QLatin1String(" Element"));
+}
+
+/*!
+ I made this so I could print a debug message here.
+ */
+QmlClassNode::~QmlClassNode()
+{
+#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
+ qDebug() << "Deleting QmlClassNode:" << name();
+#endif
+}
+
+/*!
+ Clear the multimap so that subsequent runs don't try to use
+ nodes from a previous run.
+ */
+void QmlClassNode::clear()
+{
+ inheritedBy.clear();
}
/*!
@@ -1225,7 +1545,7 @@ QmlClassNode::QmlClassNode(InnerNode *parent,
*/
QString QmlClassNode::fileBase() const
{
-#if 0
+#if 0
if (Node::fileBase() == "item")
qDebug() << "FILEBASE: qmlitem" << name();
return "qml_" + Node::fileBase();
@@ -1234,8 +1554,47 @@ QString QmlClassNode::fileBase() const
}
/*!
+ Record the fact that QML class \a base is inherited by
+ QML class \a sub.
+ */
+void QmlClassNode::addInheritedBy(const QString& base, Node* sub)
+{
+ inheritedBy.insert(base,sub);
+#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
+ qDebug() << "QmlClassNode::addInheritedBy(): insert" << base << sub->name() << inheritedBy.size();
+#endif
+}
+
+/*!
+ Loads the list \a subs with the nodes of all the subclasses of \a base.
+ */
+void QmlClassNode::subclasses(const QString& base, NodeList& subs)
+{
+ subs.clear();
+ if (inheritedBy.count(base) > 0) {
+ subs = inheritedBy.values(base);
+#ifdef DEBUG_MULTIPLE_QDOCCONF_FILES
+ qDebug() << "QmlClassNode::subclasses():" << inheritedBy.count(base) << base
+ << "subs:" << subs.size() << "total size:" << inheritedBy.size();
+#endif
+ }
+}
+
+/*!
+ Constructs a Qml basic type node (i.e. a Fake node with
+ the subtype QmlBasicType. The new node has the given
+ \a parent and \a name.
+ */
+QmlBasicTypeNode::QmlBasicTypeNode(InnerNode *parent,
+ const QString& name)
+ : FakeNode(parent, name, QmlBasicType)
+{
+ setTitle(name);
+}
+
+/*!
Constructor for the Qml property group node. \a parent is
- always a QmlClassNode.
+ always a QmlClassNode.
*/
QmlPropGroupNode::QmlPropGroupNode(QmlClassNode* parent,
const QString& name,
@@ -1260,7 +1619,7 @@ QmlPropertyNode::QmlPropertyNode(QmlPropGroupNode *parent,
des(Trool_Default),
att(attached)
{
- // nothing.
+ setPageType(ApiPage);
}
/*!
@@ -1285,6 +1644,144 @@ bool QmlPropertyNode::fromTrool(Trool troolean, bool defaultValue)
return defaultValue;
}
}
+
+static QString valueType(const QString& n)
+{
+ if (n == "QPoint")
+ return "QDeclarativePointValueType";
+ if (n == "QPointF")
+ return "QDeclarativePointFValueType";
+ if (n == "QSize")
+ return "QDeclarativeSizeValueType";
+ if (n == "QSizeF")
+ return "QDeclarativeSizeFValueType";
+ if (n == "QRect")
+ return "QDeclarativeRectValueType";
+ if (n == "QRectF")
+ return "QDeclarativeRectFValueType";
+ if (n == "QVector2D")
+ return "QDeclarativeVector2DValueType";
+ if (n == "QVector3D")
+ return "QDeclarativeVector3DValueType";
+ if (n == "QVector4D")
+ return "QDeclarativeVector4DValueType";
+ if (n == "QQuaternion")
+ return "QDeclarativeQuaternionValueType";
+ if (n == "QMatrix4x4")
+ return "QDeclarativeMatrix4x4ValueType";
+ if (n == "QEasingCurve")
+ return "QDeclarativeEasingValueType";
+ if (n == "QFont")
+ return "QDeclarativeFontValueType";
+ return QString();
+}
+
+/*!
+ Returns true if a QML property or attached property is
+ read-only. The algorithm for figuring this out is long
+ amd tedious and almost certainly will break. It currently
+ doesn't work for qmlproperty bool PropertyChanges::explicit,
+ because the tokenized gets confused on "explicit" .
+ */
+bool QmlPropertyNode::isWritable(const Tree* tree) const
+{
+ Node* n = parent();
+ while (n && n->subType() != Node::QmlClass)
+ n = n->parent();
+ if (n) {
+ const QmlClassNode* qcn = static_cast<const QmlClassNode*>(n);
+ const ClassNode* cn = qcn->classNode();
+ if (cn) {
+ QStringList dotSplit = name().split(QChar('.'));
+ const PropertyNode* pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ if (dotSplit.size() > 1) {
+ QStringList path(extractClassName(pn->qualifiedDataType()));
+ const Node* nn = tree->findNode(path,Class);
+ if (nn) {
+ const ClassNode* cn = static_cast<const ClassNode*>(nn);
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ else {
+ const QList<RelatedClass>& bases = cn->baseClasses();
+ if (!bases.isEmpty()) {
+ for (int i=0; i<bases.size(); ++i) {
+ const ClassNode* cn = bases[i].node;
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
+ if (!ignoredBases.isEmpty()) {
+ for (int i=0; i<ignoredBases.size(); ++i) {
+ const ClassNode* cn = ignoredBases[i].node;
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ QString vt = valueType(cn->name());
+ if (!vt.isEmpty()) {
+ QStringList path(vt);
+ const Node* vtn = tree->findNode(path,Class);
+ if (vtn) {
+ const ClassNode* cn = static_cast<const ClassNode*>(vtn);
+ pn = cn->findPropertyNode(dotSplit[1]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ }
+ }
+ }
+ else {
+ return pn->isWritable();
+ }
+ }
+ else {
+ const QList<RelatedClass>& bases = cn->baseClasses();
+ if (!bases.isEmpty()) {
+ for (int i=0; i<bases.size(); ++i) {
+ const ClassNode* cn = bases[i].node;
+ pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ const QList<RelatedClass>& ignoredBases = cn->ignoredBaseClasses();
+ if (!ignoredBases.isEmpty()) {
+ for (int i=0; i<ignoredBases.size(); ++i) {
+ const ClassNode* cn = ignoredBases[i].node;
+ pn = cn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ if (isAttached()) {
+ QString classNameAttached = cn->name() + "Attached";
+ QStringList path(classNameAttached);
+ const Node* nn = tree->findNode(path,Class);
+ const ClassNode* acn = static_cast<const ClassNode*>(nn);
+ pn = acn->findPropertyNode(dotSplit[0]);
+ if (pn) {
+ return pn->isWritable();
+ }
+ }
+ }
+ }
+ }
+ location().warning(tr("Can't determine read-only status of QML property %1; writable assumed.").arg(name()));
+ return true;
+}
+
#endif
QT_END_NAMESPACE
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index c77fbeb..40b78ef 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -55,6 +55,7 @@
#include "doc.h"
#include "location.h"
#include "text.h"
+#include <QUuid>
QT_BEGIN_NAMESPACE
@@ -96,7 +97,8 @@ class Node
#ifdef QDOC_QML
ExternalPage,
QmlClass,
- QmlPropertyGroup
+ QmlPropertyGroup,
+ QmlBasicType
#else
ExternalPage
#endif
@@ -136,6 +138,13 @@ class Node
AppendixLink */
};
+ enum PageType {
+ NoPageType,
+ ApiPage,
+ ArticlePage,
+ ExamplePage
+ };
+
virtual ~Node();
void setAccess(Access access) { acc = access; }
@@ -144,19 +153,22 @@ class Node
void setStatus(Status status) { sta = status; }
void setThreadSafeness(ThreadSafeness safeness) { saf = safeness; }
void setSince(const QString &since) { sinc = since; }
- void setRelates(InnerNode *pseudoParent);
+ void setRelates(InnerNode* pseudoParent);
void setModuleName(const QString &module) { mod = module; }
void setLink(LinkType linkType, const QString &link, const QString &desc);
void setUrl(const QString &url);
void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; }
+ void setPageType(PageType t) { pageTyp = t; }
+ void setPageType(const QString& t);
virtual bool isInnerNode() const = 0;
virtual bool isReimp() const { return false; }
virtual bool isFunction() const { return false; }
+ virtual bool isQmlNode() const { return false; }
Type type() const { return typ; }
virtual SubType subType() const { return NoSubType; }
- InnerNode *parent() const { return par; }
- InnerNode *relates() const { return rel; }
+ InnerNode* parent() const { return par; }
+ InnerNode* relates() const { return rel; }
const QString& name() const { return nam; }
QMap<LinkType, QPair<QString,QString> > links() const { return linkMap; }
QString moduleName() const;
@@ -164,6 +176,7 @@ class Node
virtual QString nameForLists() const { return nam; }
Access access() const { return acc; }
+ QString accessString() const;
const Location& location() const { return loc; }
const Doc& doc() const { return d; }
Status status() const { return sta; }
@@ -172,29 +185,36 @@ class Node
ThreadSafeness inheritedThreadSafeness() const;
QString since() const { return sinc; }
QString templateStuff() const { return tpl; }
+ PageType pageType() const { return pageTyp; }
+ virtual void addPageKeywords(const QString& ) { }
void clearRelated() { rel = 0; }
virtual QString fileBase() const;
+ QUuid guid() const;
+ QString ditaXmlHref();
+ QString extractClassName(const QString &string) const;
protected:
- Node(Type type, InnerNode *parent, const QString& name);
+ Node(Type type, InnerNode* parent, const QString& name);
private:
#ifdef Q_WS_WIN
Type typ;
Access acc;
- Status sta;
ThreadSafeness saf;
+ PageType pageTyp;
+ Status sta;
#else
Type typ : 4;
Access acc : 2;
- Status sta : 3;
ThreadSafeness saf : 2;
+ PageType pageTyp : 4;
+ Status sta : 3;
#endif
- InnerNode *par;
- InnerNode *rel;
+ InnerNode* par;
+ InnerNode* rel;
QString nam;
Location loc;
Doc d;
@@ -203,64 +223,70 @@ class Node
QString u;
QString sinc;
QString tpl;
+ mutable QUuid uuid;
};
class FunctionNode;
class EnumNode;
-typedef QList<Node *> NodeList;
+typedef QList<Node*> NodeList;
class InnerNode : public Node
{
public:
virtual ~InnerNode();
- Node *findNode(const QString& name);
- Node *findNode(const QString& name, Type type);
- FunctionNode *findFunctionNode(const QString& name);
- FunctionNode *findFunctionNode(const FunctionNode *clone);
+ Node* findNode(const QString& name);
+ Node* findNode(const QString& name, Type type);
+ FunctionNode* findFunctionNode(const QString& name);
+ FunctionNode* findFunctionNode(const FunctionNode* clone);
void addInclude(const QString &include);
void setIncludes(const QStringList &includes);
- void setOverload(const FunctionNode *func, bool overlode);
+ void setOverload(const FunctionNode* func, bool overlode);
void normalizeOverloads();
void makeUndocumentedChildrenInternal();
void deleteChildren();
void removeFromRelated();
virtual bool isInnerNode() const;
- const Node *findNode(const QString& name) const;
- const Node *findNode(const QString& name, Type type) const;
- const FunctionNode *findFunctionNode(const QString& name) const;
- const FunctionNode *findFunctionNode(const FunctionNode *clone) const;
- const EnumNode *findEnumNodeForValue(const QString &enumValue) const;
+ const Node* findNode(const QString& name) const;
+ const Node* findNode(const QString& name, Type type) const;
+ const FunctionNode* findFunctionNode(const QString& name) const;
+ const FunctionNode* findFunctionNode(const FunctionNode* clone) const;
+ const EnumNode* findEnumNodeForValue(const QString &enumValue) const;
const NodeList & childNodes() const { return children; }
const NodeList & relatedNodes() const { return related; }
int count() const { return children.size(); }
- int overloadNumber(const FunctionNode *func) const;
+ int overloadNumber(const FunctionNode* func) const;
int numOverloads(const QString& funcName) const;
NodeList overloads(const QString &funcName) const;
const QStringList& includes() const { return inc; }
QStringList primaryKeys();
QStringList secondaryKeys();
+ const QStringList& pageKeywords() const { return pageKeywds; }
+ virtual void addPageKeywords(const QString& t) { pageKeywds << t; }
+ virtual bool isAbstract() const { return false; }
+ virtual void setAbstract(bool ) { }
protected:
- InnerNode(Type type, InnerNode *parent, const QString& name);
+ InnerNode(Type type, InnerNode* parent, const QString& name);
private:
friend class Node;
- static bool isSameSignature(const FunctionNode *f1, const FunctionNode *f2);
- void addChild(Node *child);
- void removeChild(Node *child);
- void removeRelated(Node *pseudoChild);
+ static bool isSameSignature(const FunctionNode* f1, const FunctionNode* f2);
+ void addChild(Node* child);
+ void removeChild(Node* child);
+ void removeRelated(Node* pseudoChild);
+ QStringList pageKeywds;
QStringList inc;
NodeList children;
NodeList enumChildren;
NodeList related;
- QMap<QString, Node *> childMap;
- QMap<QString, Node *> primaryFunctionMap;
+ QMap<QString, Node*> childMap;
+ QMap<QString, Node*> primaryFunctionMap;
QMap<QString, NodeList> secondaryFunctionMap;
};
@@ -279,7 +305,7 @@ class LeafNode : public Node
class NamespaceNode : public InnerNode
{
public:
- NamespaceNode(InnerNode *parent, const QString& name);
+ NamespaceNode(InnerNode* parent, const QString& name);
virtual ~NamespaceNode() { }
};
@@ -294,25 +320,29 @@ struct RelatedClass
: access(access0),
node(node0),
dataTypeWithTemplateArgs(dataTypeWithTemplateArgs0) { }
+ QString accessString() const;
Node::Access access;
ClassNode* node;
QString dataTypeWithTemplateArgs;
};
+class PropertyNode;
+
class ClassNode : public InnerNode
{
public:
- ClassNode(InnerNode *parent, const QString& name);
+ ClassNode(InnerNode* parent, const QString& name);
virtual ~ClassNode() { }
void addBaseClass(Access access,
- ClassNode *node,
+ ClassNode* node,
const QString &dataTypeWithTemplateArgs = "");
void fixBaseClasses();
- const QList<RelatedClass> &baseClasses() const { return bas; }
- const QList<RelatedClass> &derivedClasses() const { return der; }
+ const QList<RelatedClass> &baseClasses() const { return bases; }
+ const QList<RelatedClass> &derivedClasses() const { return derived; }
+ const QList<RelatedClass> &ignoredBaseClasses() const { return ignoredBases; }
bool hideFromMainList() const { return hidden; }
void setHideFromMainList(bool value) { hidden = value; }
@@ -321,11 +351,16 @@ class ClassNode : public InnerNode
void setServiceName(const QString& value) { sname = value; }
QString qmlElement() const { return qmlelement; }
void setQmlElement(const QString& value) { qmlelement = value; }
+ virtual bool isAbstract() const { return abstract; }
+ virtual void setAbstract(bool b) { abstract = b; }
+ const PropertyNode* findPropertyNode(const QString& name) const;
private:
- QList<RelatedClass> bas;
- QList<RelatedClass> der;
+ QList<RelatedClass> bases;
+ QList<RelatedClass> derived;
+ QList<RelatedClass> ignoredBases;
bool hidden;
+ bool abstract;
QString sname;
QString qmlelement;
};
@@ -334,17 +369,17 @@ class FakeNode : public InnerNode
{
public:
- FakeNode(InnerNode *parent, const QString& name, SubType subType);
+ FakeNode(InnerNode* parent, const QString& name, SubType subType);
virtual ~FakeNode() { }
void setTitle(const QString &title) { tle = title; }
void setSubTitle(const QString &subTitle) { stle = subTitle; }
- void addGroupMember(Node *node) { gr.append(node); }
+ void addGroupMember(Node* node) { gr.append(node); }
SubType subType() const { return sub; }
- QString title() const { return tle; }
- QString fullTitle() const;
- QString subTitle() const;
+ virtual QString title() const;
+ virtual QString fullTitle() const;
+ virtual QString subTitle() const;
const NodeList &groupMembers() const { return gr; }
virtual QString nameForLists() const { return title(); }
@@ -359,18 +394,33 @@ class FakeNode : public InnerNode
class QmlClassNode : public FakeNode
{
public:
- QmlClassNode(InnerNode *parent,
+ QmlClassNode(InnerNode* parent,
const QString& name,
const ClassNode* cn);
- virtual ~QmlClassNode() { }
+ virtual ~QmlClassNode();
+ virtual bool isQmlNode() const { return true; }
const ClassNode* classNode() const { return cnode; }
virtual QString fileBase() const;
+ static void addInheritedBy(const QString& base, Node* sub);
+ static void subclasses(const QString& base, NodeList& subs);
+ static void clear();
+ public:
static bool qmlOnly;
+ static QMultiMap<QString,Node*> inheritedBy;
private:
- const ClassNode* cnode;
+ const ClassNode* cnode;
+};
+
+class QmlBasicTypeNode : public FakeNode
+{
+ public:
+ QmlBasicTypeNode(InnerNode* parent,
+ const QString& name);
+ virtual ~QmlBasicTypeNode() { }
+ virtual bool isQmlNode() const { return true; }
};
class QmlPropGroupNode : public FakeNode
@@ -380,6 +430,7 @@ class QmlPropGroupNode : public FakeNode
const QString& name,
bool attached);
virtual ~QmlPropGroupNode() { }
+ virtual bool isQmlNode() const { return true; }
const QString& element() const { return parent()->name(); }
void setDefault() { isdefault = true; }
@@ -391,6 +442,8 @@ class QmlPropGroupNode : public FakeNode
bool att;
};
+class Tree;
+
class QmlPropertyNode : public LeafNode
{
public:
@@ -409,8 +462,9 @@ class QmlPropertyNode : public LeafNode
QString qualifiedDataType() const { return dt; }
bool isStored() const { return fromTrool(sto,true); }
bool isDesignable() const { return fromTrool(des,false); }
- bool isWritable() const { return fromTrool(wri,true); }
+ bool isWritable(const Tree* tree) const;
bool isAttached() const { return att; }
+ virtual bool isQmlNode() const { return true; }
const QString& element() const { return static_cast<QmlPropGroupNode*>(parent())->element(); }
@@ -452,41 +506,41 @@ class TypedefNode;
class EnumNode : public LeafNode
{
public:
- EnumNode(InnerNode *parent, const QString& name);
+ EnumNode(InnerNode* parent, const QString& name);
virtual ~EnumNode() { }
void addItem(const EnumItem& item);
- void setFlagsType(TypedefNode *typedeff);
+ void setFlagsType(TypedefNode* typedeff);
bool hasItem(const QString &name) const { return names.contains(name); }
const QList<EnumItem>& items() const { return itms; }
Access itemAccess(const QString& name) const;
- const TypedefNode *flagsType() const { return ft; }
+ const TypedefNode* flagsType() const { return ft; }
QString itemValue(const QString &name) const;
private:
QList<EnumItem> itms;
QSet<QString> names;
- const TypedefNode *ft;
+ const TypedefNode* ft;
};
class TypedefNode : public LeafNode
{
public:
- TypedefNode(InnerNode *parent, const QString& name);
+ TypedefNode(InnerNode* parent, const QString& name);
virtual ~TypedefNode() { }
- const EnumNode *associatedEnum() const { return ae; }
+ const EnumNode* associatedEnum() const { return ae; }
private:
- void setAssociatedEnum(const EnumNode *enume);
+ void setAssociatedEnum(const EnumNode* enume);
friend class EnumNode;
- const EnumNode *ae;
+ const EnumNode* ae;
};
-inline void EnumNode::setFlagsType(TypedefNode *typedeff)
+inline void EnumNode::setFlagsType(TypedefNode* typedeff)
{
ft = typedeff;
typedeff->setAssociatedEnum(this);
@@ -538,22 +592,22 @@ class FunctionNode : public LeafNode
Native };
enum Virtualness { NonVirtual, ImpureVirtual, PureVirtual };
- FunctionNode(InnerNode *parent, const QString &name);
- FunctionNode(Type type, InnerNode *parent, const QString &name, bool attached);
+ FunctionNode(InnerNode* parent, const QString &name);
+ FunctionNode(Type type, InnerNode* parent, const QString &name, bool attached);
virtual ~FunctionNode() { }
void setReturnType(const QString& returnType) { rt = returnType; }
void setParentPath(const QStringList& parentPath) { pp = parentPath; }
void setMetaness(Metaness metaness) { met = metaness; }
- void setVirtualness(Virtualness virtualness) { vir = virtualness; }
+ void setVirtualness(Virtualness virtualness);
void setConst(bool conste) { con = conste; }
void setStatic(bool statique) { sta = statique; }
void setOverload(bool overlode);
void setReimp(bool r);
void addParameter(const Parameter& parameter);
inline void setParameters(const QList<Parameter>& parameters);
- void borrowParameterNames(const FunctionNode *source);
- void setReimplementedFrom(FunctionNode *from);
+ void borrowParameterNames(const FunctionNode* source);
+ void setReimplementedFrom(FunctionNode* from);
const QString& returnType() const { return rt; }
Metaness metaness() const { return met; }
@@ -570,20 +624,24 @@ class FunctionNode : public LeafNode
int numOverloads() const;
const QList<Parameter>& parameters() const { return params; }
QStringList parameterNames() const;
- const FunctionNode *reimplementedFrom() const { return rf; }
- const QList<FunctionNode *> &reimplementedBy() const { return rb; }
- const PropertyNode *associatedProperty() const { return ap; }
+ QString rawParameters(bool names = false, bool values = false) const;
+ const FunctionNode* reimplementedFrom() const { return rf; }
+ const QList<FunctionNode*> &reimplementedBy() const { return rb; }
+ const PropertyNode* associatedProperty() const { return ap; }
const QStringList& parentPath() const { return pp; }
QStringList reconstructParams(bool values = false) const;
QString signature(bool values = false) const;
const QString& element() const { return parent()->name(); }
bool isAttached() const { return att; }
+ virtual bool isQmlNode() const {
+ return ((type() == QmlSignal) || (type() == QmlMethod));
+ }
void debug() const;
private:
- void setAssociatedProperty(PropertyNode *property);
+ void setAssociatedProperty(PropertyNode* property);
friend class InnerNode;
friend class PropertyNode;
@@ -603,9 +661,9 @@ class FunctionNode : public LeafNode
bool reimp: 1;
bool att: 1;
QList<Parameter> params;
- const FunctionNode *rf;
- const PropertyNode *ap;
- QList<FunctionNode *> rb;
+ const FunctionNode* rf;
+ const PropertyNode* ap;
+ QList<FunctionNode*> rb;
};
class PropertyNode : public LeafNode
@@ -614,16 +672,22 @@ class PropertyNode : public LeafNode
enum FunctionRole { Getter, Setter, Resetter, Notifier };
enum { NumFunctionRoles = Notifier + 1 };
- PropertyNode(InnerNode *parent, const QString& name);
+ PropertyNode(InnerNode* parent, const QString& name);
virtual ~PropertyNode() { }
void setDataType(const QString& dataType) { dt = dataType; }
- void addFunction(FunctionNode *function, FunctionRole role);
- void addSignal(FunctionNode *function, FunctionRole role);
+ void addFunction(FunctionNode* function, FunctionRole role);
+ void addSignal(FunctionNode* function, FunctionRole role);
void setStored(bool stored) { sto = toTrool(stored); }
void setDesignable(bool designable) { des = toTrool(designable); }
+ void setScriptable(bool scriptable) { scr = toTrool(scriptable); }
void setWritable(bool writable) { wri = toTrool(writable); }
- void setOverriddenFrom(const PropertyNode *baseProperty);
+ void setUser(bool user) { usr = toTrool(user); }
+ void setOverriddenFrom(const PropertyNode* baseProperty);
+ void setRuntimeDesFunc(const QString& rdf) { runtimeDesFunc = rdf; }
+ void setRuntimeScrFunc(const QString& scrf) { runtimeScrFunc = scrf; }
+ void setConstant() { cst = true; }
+ void setFinal() { fnl = true; }
const QString &dataType() const { return dt; }
QString qualifiedDataType() const;
@@ -635,8 +699,20 @@ class PropertyNode : public LeafNode
NodeList notifiers() const { return functions(Notifier); }
bool isStored() const { return fromTrool(sto, storedDefault()); }
bool isDesignable() const { return fromTrool(des, designableDefault()); }
+ bool isScriptable() const { return fromTrool(scr, scriptableDefault()); }
+ const QString& runtimeDesignabilityFunction() const { return runtimeDesFunc; }
+ const QString& runtimeScriptabilityFunction() const { return runtimeScrFunc; }
bool isWritable() const { return fromTrool(wri, writableDefault()); }
- const PropertyNode *overriddenFrom() const { return overrides; }
+ bool isUser() const { return fromTrool(usr, userDefault()); }
+ bool isConstant() const { return cst; }
+ bool isFinal() const { return fnl; }
+ const PropertyNode* overriddenFrom() const { return overrides; }
+
+ bool storedDefault() const { return true; }
+ bool userDefault() const { return false; }
+ bool designableDefault() const { return !setters().isEmpty(); }
+ bool scriptableDefault() const { return true; }
+ bool writableDefault() const { return !setters().isEmpty(); }
private:
enum Trool { Trool_True, Trool_False, Trool_Default };
@@ -644,16 +720,18 @@ class PropertyNode : public LeafNode
static Trool toTrool(bool boolean);
static bool fromTrool(Trool troolean, bool defaultValue);
- bool storedDefault() const { return true; }
- bool designableDefault() const { return !setters().isEmpty(); }
- bool writableDefault() const { return !setters().isEmpty(); }
-
QString dt;
+ QString runtimeDesFunc;
+ QString runtimeScrFunc;
NodeList funcs[NumFunctionRoles];
Trool sto;
Trool des;
+ Trool scr;
Trool wri;
- const PropertyNode *overrides;
+ Trool usr;
+ bool cst;
+ bool fnl;
+ const PropertyNode* overrides;
};
inline void FunctionNode::setParameters(const QList<Parameter> &parameters)
@@ -661,13 +739,13 @@ inline void FunctionNode::setParameters(const QList<Parameter> &parameters)
params = parameters;
}
-inline void PropertyNode::addFunction(FunctionNode *function, FunctionRole role)
+inline void PropertyNode::addFunction(FunctionNode* function, FunctionRole role)
{
funcs[(int)role].append(function);
function->setAssociatedProperty(this);
}
-inline void PropertyNode::addSignal(FunctionNode *function, FunctionRole role)
+inline void PropertyNode::addSignal(FunctionNode* function, FunctionRole role)
{
funcs[(int)role].append(function);
}
@@ -683,7 +761,7 @@ inline NodeList PropertyNode::functions() const
class VariableNode : public LeafNode
{
public:
- VariableNode(InnerNode *parent, const QString &name);
+ VariableNode(InnerNode* parent, const QString &name);
virtual ~VariableNode() { }
void setLeftType(const QString &leftType) { lt = leftType; }
@@ -701,15 +779,16 @@ class VariableNode : public LeafNode
bool sta;
};
-inline VariableNode::VariableNode(InnerNode *parent, const QString &name)
+inline VariableNode::VariableNode(InnerNode* parent, const QString &name)
: LeafNode(Variable, parent, name), sta(false)
{
+ // nothing.
}
class TargetNode : public LeafNode
{
public:
- TargetNode(InnerNode *parent, const QString& name);
+ TargetNode(InnerNode* parent, const QString& name);
virtual ~TargetNode() { }
virtual bool isInnerNode() const;
diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp
index a001c10..37dc191 100644
--- a/tools/qdoc3/pagegenerator.cpp
+++ b/tools/qdoc3/pagegenerator.cpp
@@ -43,10 +43,9 @@
pagegenerator.cpp
*/
-#include <QtCore>
#include <qfile.h>
#include <qfileinfo.h>
-
+#include <qdebug.h>
#include "pagegenerator.h"
#include "tree.h"
@@ -69,6 +68,110 @@ PageGenerator::~PageGenerator()
endSubPage();
}
+static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
+static QRegExp funcTag("(<@func target=\"([^\"]*)\">)(.*)(</@func>)");
+static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)");
+static QRegExp spanTag("</@(?:comment|preprocessor|string|char)>");
+static QRegExp unknownTag("</?@[^>]*>");
+
+bool PageGenerator::parseArg(const QString& src,
+ const QString& tag,
+ int* pos,
+ int n,
+ QStringRef* contents,
+ QStringRef* par1,
+ bool debug)
+{
+#define SKIP_CHAR(c) \
+ if (debug) \
+ qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \
+ if (i >= n || src[i] != c) { \
+ if (debug) \
+ qDebug() << " char '" << c << "' not found"; \
+ return false; \
+ } \
+ ++i;
+
+
+#define SKIP_SPACE \
+ while (i < n && src[i] == ' ') \
+ ++i;
+
+ int i = *pos;
+ int j = i;
+
+ // assume "<@" has been parsed outside
+ //SKIP_CHAR('<');
+ //SKIP_CHAR('@');
+
+ if (tag != QStringRef(&src, i, tag.length())) {
+ if (0 && debug)
+ qDebug() << "tag " << tag << " not found at " << i;
+ return false;
+ }
+
+ if (debug)
+ qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i;
+
+ // skip tag
+ i += tag.length();
+
+ // parse stuff like: linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)");
+ if (par1) {
+ SKIP_SPACE;
+ // read parameter name
+ j = i;
+ while (i < n && src[i].isLetter())
+ ++i;
+ if (src[i] == '=') {
+ if (debug)
+ qDebug() << "read parameter" << QString(src.data() + j, i - j);
+ SKIP_CHAR('=');
+ SKIP_CHAR('"');
+ // skip parameter name
+ j = i;
+ while (i < n && src[i] != '"')
+ ++i;
+ *par1 = QStringRef(&src, j, i - j);
+ SKIP_CHAR('"');
+ SKIP_SPACE;
+ } else {
+ if (debug)
+ qDebug() << "no optional parameter found";
+ }
+ }
+ SKIP_SPACE;
+ SKIP_CHAR('>');
+
+ // find contents up to closing "</@tag>
+ j = i;
+ for (; true; ++i) {
+ if (i + 4 + tag.length() > n)
+ return false;
+ if (src[i] != '<')
+ continue;
+ if (src[i + 1] != '/')
+ continue;
+ if (src[i + 2] != '@')
+ continue;
+ if (tag != QStringRef(&src, i + 3, tag.length()))
+ continue;
+ if (src[i + 3 + tag.length()] != '>')
+ continue;
+ break;
+ }
+
+ *contents = QStringRef(&src, j, i - j);
+
+ i += tag.length() + 4;
+
+ *pos = i;
+ if (debug)
+ qDebug() << " tag " << tag << " found: pos now: " << i;
+ return true;
+#undef SKIP_CHAR
+}
+
/*!
This function is recursive.
*/
@@ -77,7 +180,7 @@ void PageGenerator::generateTree(const Tree *tree, CodeMarker *marker)
generateInnerNode(tree->root(), marker);
}
-QString PageGenerator::fileBase(const Node *node)
+QString PageGenerator::fileBase(const Node *node) const
{
if (node->relates())
node = node->relates();
@@ -104,8 +207,10 @@ QString PageGenerator::fileBase(const Node *node)
we prepend "qml-" to the file name of QML element doc
files.
*/
- if (p->subType() == Node::QmlClass) {
- base.prepend("qml-");
+ if ((p->subType() == Node::QmlClass) ||
+ (p->subType() == Node::QmlBasicType)) {
+ if (!base.startsWith(QLatin1String("QML:")))
+ base.prepend("qml-");
}
#endif
if (!pp || pp->name().isEmpty() || pp->type() == Node::Fake)
@@ -152,7 +257,7 @@ QString PageGenerator::fileBase(const Node *node)
return res;
}
-QString PageGenerator::fileName(const Node *node)
+QString PageGenerator::fileName(const Node *node) const
{
if (!node->url().isEmpty())
return node->url();
@@ -176,7 +281,7 @@ void PageGenerator::beginSubPage(const Location& location,
location.fatal(tr("Cannot open output file '%1'")
.arg(outFile->fileName()));
QTextStream *out = new QTextStream(outFile);
- out->setCodec("ISO-8859-1");
+ out->setCodec(outputCodec);
outStreamStack.push(out);
}
@@ -195,8 +300,8 @@ QTextStream &PageGenerator::out()
/*!
Recursive writing of html files from the root \a node.
*/
-void PageGenerator::generateInnerNode(const InnerNode *node,
- CodeMarker *marker)
+void
+PageGenerator::generateInnerNode(const InnerNode* node, CodeMarker* marker)
{
if (!node->url().isNull())
return;
@@ -205,10 +310,14 @@ void PageGenerator::generateInnerNode(const InnerNode *node,
const FakeNode *fakeNode = static_cast<const FakeNode *>(node);
if (fakeNode->subType() == Node::ExternalPage)
return;
-#ifdef QDOC_QML
+ if (fakeNode->subType() == Node::Image)
+ return;
if (fakeNode->subType() == Node::QmlPropertyGroup)
return;
-#endif
+ if (fakeNode->subType() == Node::Page) {
+ if (node->count() > 0)
+ qDebug("PAGE %s HAS CHILDREN", qPrintable(fakeNode->title()));
+ }
}
if (node->parent() != 0) {
diff --git a/tools/qdoc3/pagegenerator.h b/tools/qdoc3/pagegenerator.h
index db24edd..1aa24a1 100644
--- a/tools/qdoc3/pagegenerator.h
+++ b/tools/qdoc3/pagegenerator.h
@@ -54,6 +54,8 @@
QT_BEGIN_NAMESPACE
+class QTextCodec;
+
class ClassNode;
class InnerNode;
class NamespaceNode;
@@ -67,17 +69,28 @@ class PageGenerator : public Generator
virtual void generateTree(const Tree *tree, CodeMarker *marker);
protected:
- virtual QString fileBase(const Node *node);
- virtual QString fileExtension(const Node *node) = 0;
- QString fileName(const Node *node);
+ virtual QString fileBase(const Node *node) const;
+ virtual QString fileExtension(const Node *node) const = 0;
+ QString fileName(const Node *node) const;
QString outFileName();
void beginSubPage(const Location& location, const QString& fileName);
void endSubPage();
virtual void generateInnerNode(const InnerNode *node, CodeMarker *marker);
QTextStream& out();
+ QString naturalLanguage;
+ QString outputEncoding;
+ QTextCodec* outputCodec;
+ bool parseArg(const QString& src,
+ const QString& tag,
+ int* pos,
+ int n,
+ QStringRef* contents,
+ QStringRef* par1 = 0,
+ bool debug = false);
+
private:
- QStack<QTextStream *> outStreamStack;
+ QStack<QTextStream*> outStreamStack;
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/plaincodemarker.cpp b/tools/qdoc3/plaincodemarker.cpp
index 4abfd2b..d825c13 100644
--- a/tools/qdoc3/plaincodemarker.cpp
+++ b/tools/qdoc3/plaincodemarker.cpp
@@ -129,11 +129,4 @@ QList<Section> PlainCodeMarker::sections(const InnerNode * /* innerNode */,
return QList<Section>();
}
-const Node *PlainCodeMarker::resolveTarget( const QString& /* target */,
- const Tree * /* tree */,
- const Node * /* relative */ )
-{
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/tools/qdoc3/plaincodemarker.h b/tools/qdoc3/plaincodemarker.h
index e9cc40d..7afb88e 100644
--- a/tools/qdoc3/plaincodemarker.h
+++ b/tools/qdoc3/plaincodemarker.h
@@ -71,7 +71,6 @@ public:
QString functionBeginRegExp( const QString& funcName );
QString functionEndRegExp( const QString& funcName );
QList<Section> sections(const InnerNode *innerNode, SynopsisStyle style, Status status);
- const Node *resolveTarget(const QString &target, const Tree *tree, const Node *relative);
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro
index 441bf39..d47e066 100644
--- a/tools/qdoc3/qdoc3.pro
+++ b/tools/qdoc3/qdoc3.pro
@@ -4,9 +4,17 @@ DEFINES += QT_NO_CAST_TO_ASCII
#DEFINES += QT_USE_FAST_OPERATOR_PLUS
#DEFINES += QT_USE_FAST_CONCATENATION
-QT = core xml
-CONFIG += console
-CONFIG -= debug_and_release_target
+qdoc_bootstrapped {
+ include(../../src/tools/bootstrap/bootstrap.pri)
+ SOURCES += ../../src/corelib/plugin/quuid.cpp
+ DEFINES -= QT_NO_CAST_FROM_ASCII
+ DEFINES += QT_NO_TRANSLATION
+} else {
+ QT = core xml
+ CONFIG += console
+ CONFIG -= debug_and_release_target
+}
+
!isEmpty(QT_BUILD_TREE):DESTDIR = $$QT_BUILD_TREE/bin
#CONFIG += debug
build_all:!build_pass {
@@ -14,7 +22,8 @@ build_all:!build_pass {
CONFIG += release
# CONFIG += debug
}
-mac:CONFIG -= app_bundle
+
+CONFIG -= app_bundle
HEADERS += apigenerator.h \
archiveextractor.h \
atom.h \
@@ -29,6 +38,7 @@ HEADERS += apigenerator.h \
cppcodeparser.h \
cpptoqsconverter.h \
dcfsection.h \
+ ditaxmlgenerator.h \
doc.h \
editdistance.h \
generator.h \
@@ -73,6 +83,7 @@ SOURCES += apigenerator.cpp \
cppcodeparser.cpp \
cpptoqsconverter.cpp \
dcfsection.cpp \
+ ditaxmlgenerator.cpp \
doc.cpp \
editdistance.cpp \
generator.cpp \
@@ -105,5 +116,13 @@ SOURCES += apigenerator.cpp \
webxmlgenerator.cpp \
yyindent.cpp
+### Documentation for qdoc3 ###
+
+qtPrepareTool(QDOC, qdoc3)
+
+html-docs.commands = cd \"$$PWD/doc\" && $$QDOC qdoc-manual.qdocconf
+
+QMAKE_EXTRA_TARGETS += html-docs
+
target.path = $$[QT_INSTALL_BINS]
INSTALLS += target
diff --git a/tools/qdoc3/qsakernelparser.cpp b/tools/qdoc3/qsakernelparser.cpp
index 9320a17..8f12eda 100644
--- a/tools/qdoc3/qsakernelparser.cpp
+++ b/tools/qdoc3/qsakernelparser.cpp
@@ -70,8 +70,8 @@ void QsaKernelParser::parseSourceFile( const Location& location,
const QString& filePath,
Tree * /* tree */ )
{
- FILE *in = fopen( QFile::encodeName(filePath), "r" );
- if ( in == 0 ) {
+ QFile in(filePath);
+ if (!in.open(QIODevice::ReadOnly)) {
location.error( tr("Cannot open QSA kernel file '%1'").arg(filePath) );
return;
}
@@ -171,7 +171,7 @@ void QsaKernelParser::parseSourceFile( const Location& location,
readToken();
}
}
- fclose( in );
+ in.close();
}
void QsaKernelParser::doneParsingSourceFiles( Tree * /* tree */ )
diff --git a/tools/qdoc3/qscodemarker.cpp b/tools/qdoc3/qscodemarker.cpp
index 89c9c5c..2ee5d99 100644
--- a/tools/qdoc3/qscodemarker.cpp
+++ b/tools/qdoc3/qscodemarker.cpp
@@ -279,11 +279,11 @@ QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty
const ClassNode *classe = static_cast<const ClassNode *>(inner);
if ( style == Summary ) {
- FastSection enums(classe, "Enums", "enum", "enums");
- FastSection functions(classe, "Functions", "function", "functions");
- FastSection readOnlyProperties(classe, "Read-Only Properties", "property", "properties");
- FastSection signalz(classe, "Signals", "signal", "signals");
- FastSection writableProperties(classe, "Writable Properties", "property", "properties");
+ FastSection enums(classe, "Enums", "", "enum", "enums");
+ FastSection functions(classe, "Functions", "", "function", "functions");
+ FastSection readOnlyProperties(classe, "", "Read-Only Properties", "property", "properties");
+ FastSection signalz(classe, "Signals", "", "signal", "signals");
+ FastSection writableProperties(classe, "", "Writable Properties", "property", "properties");
QStack<const ClassNode *> stack;
stack.push( classe );
@@ -328,9 +328,9 @@ QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty
append( sections, functions );
append( sections, signalz );
} else if ( style == Detailed ) {
- FastSection enums( classe, "Enum Documentation" );
- FastSection functionsAndSignals( classe, "Function and Signal Documentation" );
- FastSection properties( classe, "Property Documentation" );
+ FastSection enums( classe, "Enum Documentation", "", "member", "members");
+ FastSection functionsAndSignals( classe, "Function and Signal Documentation", "", "member", "members");
+ FastSection properties( classe, "Property Documentation", "", "member", "members");
NodeList::ConstIterator c = classe->childNodes().begin();
while ( c != classe->childNodes().end() ) {
@@ -349,7 +349,7 @@ QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty
append( sections, properties );
append( sections, functionsAndSignals );
} else { // ( style == SeparateList )
- FastSection all( classe );
+ FastSection all(classe, "", "", "member", "members");
QStack<const ClassNode *> stack;
stack.push( classe );
@@ -375,11 +375,4 @@ QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle sty
return sections;
}
-const Node *QsCodeMarker::resolveTarget( const QString& /* target */,
- const Tree * /* tree */,
- const Node * /* relative */ )
-{
- return 0;
-}
-
QT_END_NAMESPACE
diff --git a/tools/qdoc3/qscodemarker.h b/tools/qdoc3/qscodemarker.h
index 1590009..c6a177f 100644
--- a/tools/qdoc3/qscodemarker.h
+++ b/tools/qdoc3/qscodemarker.h
@@ -72,7 +72,6 @@ public:
QList<Section> sections(const InnerNode *innerNode, SynopsisStyle style, Status status);
QString functionBeginRegExp( const QString& funcName );
QString functionEndRegExp( const QString& funcName );
- const Node *resolveTarget( const QString& target, const Tree *tree, const Node *relative );
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/qscodeparser.cpp b/tools/qdoc3/qscodeparser.cpp
index 8b3bc98..3b8bc1a 100644
--- a/tools/qdoc3/qscodeparser.cpp
+++ b/tools/qdoc3/qscodeparser.cpp
@@ -151,8 +151,8 @@ void QsCodeParser::parseHeaderFile(const Location& location,
{
qsTre = tree;
- FILE *in = fopen(QFile::encodeName(filePath), "r");
- if (in == 0) {
+ QFile in(filePath);
+ if (!in.open(QIODevice::ReadOnly)) {
location.error(tr("Cannot open Qt Script class list '%1'")
.arg(filePath));
return;
@@ -175,7 +175,7 @@ void QsCodeParser::parseHeaderFile(const Location& location,
}
tok = fileTokenizer.getToken();
}
- fclose(in);
+ in.close();
}
void QsCodeParser::parseSourceFile(const Location& location,
diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf
index 91c7cd4..0e9a2a8 100644
--- a/tools/qdoc3/test/assistant.qdocconf
+++ b/tools/qdoc3/test/assistant.qdocconf
@@ -6,18 +6,51 @@ include(qt-defines.qdocconf)
project = Qt Assistant
description = Qt Assistant Manual
-url = http://qt.nokia.com/doc/4.6
+url = http://doc.qt.nokia.com/4.7/
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Assistant
qhp.Assistant.file = assistant.qhp
-qhp.Assistant.namespace = com.trolltech.assistant.460
+qhp.Assistant.namespace = com.trolltech.assistant.472
qhp.Assistant.virtualFolder = qdoc
qhp.Assistant.indexTitle = Qt Assistant Manual
-qhp.Assistant.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Assistant.filterAttributes = qt 4.6.4 tools assistant
+qhp.Assistant.extraFiles = images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+qhp.Assistant.filterAttributes = qt 4.7.2 tools assistant
qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual
qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant
qhp.Assistant.subprojects = manual examples
@@ -40,6 +73,7 @@ exampledirs = $QT_SOURCE_TREE \
$QT_SOURCE_TREE/examples \
$QT_SOURCE_TREE/doc/src
-imagedirs = $QT_SOURCE_TREE/doc/src/images
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/doc/src/template/images
outputdir = $QT_BUILD_TREE/doc-build/html-assistant
base = file:$QT_BUILD_TREE/doc-build/html-assistant
diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf
index 69024d1..637399b 100644
--- a/tools/qdoc3/test/designer.qdocconf
+++ b/tools/qdoc3/test/designer.qdocconf
@@ -6,18 +6,51 @@ include(qt-defines.qdocconf)
project = Qt Designer
description = Qt Designer Manual
-url = http://qt.nokia.com/doc/4.6
+url = http://doc.qt.nokia.com/4.7/
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Designer
qhp.Designer.file = designer.qhp
-qhp.Designer.namespace = com.trolltech.designer.460
+qhp.Designer.namespace = com.trolltech.designer.472
qhp.Designer.virtualFolder = qdoc
qhp.Designer.indexTitle = Qt Designer Manual
-qhp.Designer.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Designer.filterAttributes = qt 4.6.4 tools designer
+qhp.Designer.extraFiles = images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+qhp.Designer.filterAttributes = qt 4.7.2 tools designer
qhp.Designer.customFilters.Designer.name = Qt Designer Manual
qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer
qhp.Designer.subprojects = manual examples
@@ -46,6 +79,7 @@ exampledirs = $QT_SOURCE_TREE \
$QT_SOURCE_TREE/examples \
$QT_SOURCE_TREE/doc/src
-imagedirs = $QT_SOURCE_TREE/doc/src/images
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/doc/src/template/images
outputdir = $QT_BUILD_TREE/doc-build/html-designer
base = file:$QT_BUILD_TREE/doc-build/html-designer
diff --git a/tools/qdoc3/test/images/bg_l.png b/tools/qdoc3/test/images/bg_l.png
new file mode 100644
index 0000000..90b1da1
--- /dev/null
+++ b/tools/qdoc3/test/images/bg_l.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bg_l_blank.png b/tools/qdoc3/test/images/bg_l_blank.png
new file mode 100644
index 0000000..5a9673d
--- /dev/null
+++ b/tools/qdoc3/test/images/bg_l_blank.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bg_r.png b/tools/qdoc3/test/images/bg_r.png
new file mode 100644
index 0000000..f0fb121
--- /dev/null
+++ b/tools/qdoc3/test/images/bg_r.png
Binary files differ
diff --git a/tools/qdoc3/test/images/box_bg.png b/tools/qdoc3/test/images/box_bg.png
new file mode 100644
index 0000000..3322f92
--- /dev/null
+++ b/tools/qdoc3/test/images/box_bg.png
Binary files differ
diff --git a/tools/qdoc3/test/images/breadcrumb.png b/tools/qdoc3/test/images/breadcrumb.png
new file mode 100644
index 0000000..0ded551
--- /dev/null
+++ b/tools/qdoc3/test/images/breadcrumb.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bullet_dn.png b/tools/qdoc3/test/images/bullet_dn.png
new file mode 100644
index 0000000..f776247
--- /dev/null
+++ b/tools/qdoc3/test/images/bullet_dn.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bullet_gt.png b/tools/qdoc3/test/images/bullet_gt.png
new file mode 100644
index 0000000..7561b4e
--- /dev/null
+++ b/tools/qdoc3/test/images/bullet_gt.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bullet_sq.png b/tools/qdoc3/test/images/bullet_sq.png
new file mode 100644
index 0000000..a84845e
--- /dev/null
+++ b/tools/qdoc3/test/images/bullet_sq.png
Binary files differ
diff --git a/tools/qdoc3/test/images/bullet_up.png b/tools/qdoc3/test/images/bullet_up.png
new file mode 100644
index 0000000..285e741
--- /dev/null
+++ b/tools/qdoc3/test/images/bullet_up.png
Binary files differ
diff --git a/tools/qdoc3/test/images/feedbackground.png b/tools/qdoc3/test/images/feedbackground.png
new file mode 100644
index 0000000..3a38d99
--- /dev/null
+++ b/tools/qdoc3/test/images/feedbackground.png
Binary files differ
diff --git a/tools/qdoc3/test/images/horBar.png b/tools/qdoc3/test/images/horBar.png
new file mode 100644
index 0000000..100fe91
--- /dev/null
+++ b/tools/qdoc3/test/images/horBar.png
Binary files differ
diff --git a/tools/qdoc3/test/images/page.png b/tools/qdoc3/test/images/page.png
new file mode 100644
index 0000000..1db151b
--- /dev/null
+++ b/tools/qdoc3/test/images/page.png
Binary files differ
diff --git a/tools/qdoc3/test/images/page_bg.png b/tools/qdoc3/test/images/page_bg.png
new file mode 100644
index 0000000..9b3bd99
--- /dev/null
+++ b/tools/qdoc3/test/images/page_bg.png
Binary files differ
diff --git a/tools/qdoc3/test/images/sprites-combined.png b/tools/qdoc3/test/images/sprites-combined.png
new file mode 100644
index 0000000..3a48b21
--- /dev/null
+++ b/tools/qdoc3/test/images/sprites-combined.png
Binary files differ
diff --git a/tools/qdoc3/test/jambi.qdocconf b/tools/qdoc3/test/jambi.qdocconf
index 04bb51b..aa87826 100644
--- a/tools/qdoc3/test/jambi.qdocconf
+++ b/tools/qdoc3/test/jambi.qdocconf
@@ -16,7 +16,8 @@ outputdir = $JAMBI/doc/html/com/trolltech/qt
imagedirs = $QTDIR/doc/src/images \
$QTDIR/examples \
$JAMBI/doc/src/images \
- ../doc/src/images
+ ../doc/src/images \
+ $QTDIR/doc/src/template/images
extraimages.javadoc = qt-logo \
qt-logo.png
diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf
index d8b90a7..8ee298e 100644
--- a/tools/qdoc3/test/linguist.qdocconf
+++ b/tools/qdoc3/test/linguist.qdocconf
@@ -6,18 +6,51 @@ include(qt-defines.qdocconf)
project = Qt Linguist
description = Qt Linguist Manual
-url = http://qt.nokia.com/doc/4.6
+url = http://doc.qt.nokia.com/4.7/
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Linguist
qhp.Linguist.file = linguist.qhp
-qhp.Linguist.namespace = com.trolltech.linguist.460
+qhp.Linguist.namespace = com.trolltech.linguist.472
qhp.Linguist.virtualFolder = qdoc
qhp.Linguist.indexTitle = Qt Linguist Manual
-qhp.Linguist.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.Linguist.filterAttributes = qt 4.6.4 tools linguist
+qhp.Linguist.extraFiles = images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+qhp.Linguist.filterAttributes = qt 4.7.2 tools linguist
qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual
qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist
qhp.Linguist.subprojects = manual examples
@@ -42,6 +75,7 @@ exampledirs = $QT_SOURCE_TREE \
$QT_SOURCE_TREE/examples \
$QT_SOURCE_TREE/doc/src
-imagedirs = $QT_SOURCE_TREE/doc/src/images
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/doc/src/template/images
outputdir = $QT_BUILD_TREE/doc-build/html-linguist
base = file:$QT_BUILD_TREE/doc-build/html-linguist
diff --git a/tools/qdoc3/test/macros.qdocconf b/tools/qdoc3/test/macros.qdocconf
index 22db23e..510a8b3 100644
--- a/tools/qdoc3/test/macros.qdocconf
+++ b/tools/qdoc3/test/macros.qdocconf
@@ -18,6 +18,7 @@ macro.ouml.HTML = "&ouml;"
macro.QA = "\\e{Qt Assistant}"
macro.QD = "\\e{Qt Designer}"
macro.QL = "\\e{Qt Linguist}"
+macro.QQV = "\\e{Qt QML Viewer}"
macro.param = "\\e"
macro.raisedaster.HTML = "<sup>*</sup>"
macro.rarrow.HTML = "&rarr;"
diff --git a/tools/qdoc3/test/qdeclarative.qdocconf b/tools/qdoc3/test/qdeclarative.qdocconf
new file mode 100644
index 0000000..e68a935
--- /dev/null
+++ b/tools/qdoc3/test/qdeclarative.qdocconf
@@ -0,0 +1,96 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qml
+description = Qml Reference Documentation
+url = http://qt.nokia.com/doc/4.7/
+qmlonly = true
+
+edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \
+ QtXmlPatterns QtTest
+edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtSql QtSvg \
+ QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
+ QtDesigner QtAssistant QAxContainer Phonon \
+ QAxServer QtUiTools QtTest QtDBus
+edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest
+edition.DesktopLight.groups = -graphicsview-api
+
+qhp.projects = Qml
+
+qhp.Qml.file = qml.qhp
+qhp.Qml.namespace = com.trolltech.qml.472
+qhp.Qml.virtualFolder = qdoc
+qhp.Qml.indexTitle = Qml Reference
+
+# Files not referenced in any qdoc file
+# See also extraimages.HTML
+qhp.Qml.extraFiles = images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+qhp.Qml.filterAttributes = qt 4.7.2 qtrefdoc
+qhp.Qml.customFilters.Qt.name = Qt 4.7.2
+qhp.Qml.customFilters.Qt.filterAttributes = qt 4.7.2
+qhp.Qml.subprojects = classes
+qhp.Qml.subprojects.classes.title = Elements
+qhp.Qml.subprojects.classes.indexTitle = Qml Elements
+qhp.Qml.subprojects.classes.selectors = fake:qmlclass
+qhp.Qml.subprojects.classes.sortPages = true
+
+language = Cpp
+
+headerdirs = $QT_SOURCE_TREE/src/declarative
+sourcedirs = $QT_SOURCE_TREE/src/declarative \
+ $QT_SOURCE_TREE/doc/src/declarative
+
+sources += $QT_SOURCE_TREE/doc/src/tutorials/declarative.qdoc
+
+sources.fileextensions = "*.cpp *.qdoc"
+examples.fileextensions = "*.cpp *.h *.js *.qml"
+
+exampledirs = $QT_SOURCE_TREE/doc/src \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/examples/tutorials \
+ $QT_SOURCE_TREE \
+ $QT_SOURCE_TREE/qmake/examples \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/doc/src/declarative/pics \
+ $QT_SOURCE_TREE/doc/src/template/images
+outputdir = $QT_BUILD_TREE/doc-build/html-qml
+tagfile = $QT_BUILD_TREE/doc-build/html-qml/qt.tags
+base = file:$QT_BUILD_TREE/doc/html-qml
diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf
index 28fc49a..b5bc96c 100644
--- a/tools/qdoc3/test/qmake.qdocconf
+++ b/tools/qdoc3/test/qmake.qdocconf
@@ -6,18 +6,51 @@ include(qt-defines.qdocconf)
project = QMake
description = QMake Manual
-url = http://qt.nokia.com/doc/4.6
+url = http://qt.nokia.com/doc/4.7
indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = qmake
qhp.qmake.file = qmake.qhp
-qhp.qmake.namespace = com.trolltech.qmake.460
+qhp.qmake.namespace = com.trolltech.qmake.472
qhp.qmake.virtualFolder = qdoc
qhp.qmake.indexTitle = QMake Manual
-qhp.qmake.extraFiles = classic.css images/qt-logo.png images/trolltech-logo.png
-qhp.qmake.filterAttributes = qt 4.6.4 tools qmake
+qhp.qmake.extraFiles = images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+qhp.qmake.filterAttributes = qt 4.7.2 tools qmake
qhp.qmake.customFilters.qmake.name = qmake Manual
qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake
qhp.qmake.subprojects = manual
@@ -35,6 +68,7 @@ exampledirs = $QT_SOURCE_TREE \
$QT_SOURCE_TREE/examples \
$QT_SOURCE_TREE/doc/src
-imagedirs = $QT_SOURCE_TREE/doc/src/images
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/doc/src/template/images
outputdir = $QT_BUILD_TREE/doc-build/html-qmake
base = file:$QT_BUILD_TREE/doc-build/html-qmake
diff --git a/tools/qdoc3/test/qt-api-only.qdocconf b/tools/qdoc3/test/qt-api-only.qdocconf
index 10b7be5..cdd7a7c 100644
--- a/tools/qdoc3/test/qt-api-only.qdocconf
+++ b/tools/qdoc3/test/qt-api-only.qdocconf
@@ -25,6 +25,10 @@ qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \
$QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \
$QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc
+# Remove the QML documentation from the Qt-only documentation.
+
+excludedirs += $QT_SOURCE_TREE/src/imports
+
outputdir = $QT_BUILD_TREE/doc-build/html-qt
tagfile = $QT_BUILD_TREE/doc-build/html-qt/qt.tags
base = file:$QT_BUILD_TREE/doc-build/html-qt
diff --git a/tools/qdoc3/test/qt-api-only_ja_JP.qdocconf b/tools/qdoc3/test/qt-api-only_ja_JP.qdocconf
new file mode 100644
index 0000000..70e0235
--- /dev/null
+++ b/tools/qdoc3/test/qt-api-only_ja_JP.qdocconf
@@ -0,0 +1,37 @@
+include(qt-build-docs_ja_JP.qdocconf)
+
+# Ensures that the generated index contains a URL that can be used by the
+# tools documentation (assistant.qdocconf, designer.qdocconf, linguist.qdocconf,
+# qmake.qdocconf).
+
+url = ./
+
+# Ensures that the documentation for the tools is not included in the generated
+# .qhp file.
+
+qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \
+ $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/customwidgetplugin.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/taskmenuextension.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/containerextension.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/worldtimeclockbuilder.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/worldtimeclockplugin.qdoc \
+ $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \
+ $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc
+
+# Remove the QML documentation from the Qt-only documentation.
+
+excludedirs += $QT_SOURCE_TREE/src/declarative \
+ $QT_SOURCE_TREE/src/imports \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/declarative \
+ $QT_SOURCE_TREE/doc/src/declarative
+
+outputdir = $QT_BUILD_TREE/doc-build/html-qt_ja_JP
+tagfile = $QT_BUILD_TREE/doc-build/html-qt_ja_JP/qt.tags
+base = file:$QT_BUILD_TREE/doc-build/html-qt_ja_JP
diff --git a/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf b/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf
new file mode 100644
index 0000000..d6bf410
--- /dev/null
+++ b/tools/qdoc3/test/qt-api-only_zh_CN.qdocconf
@@ -0,0 +1,37 @@
+include(qt-build-docs_zh_CN.qdocconf)
+
+# Ensures that the generated index contains a URL that can be used by the
+# tools documentation (assistant.qdocconf, designer.qdocconf, linguist.qdocconf,
+# qmake.qdocconf).
+
+url = ./
+
+# Ensures that the documentation for the tools is not included in the generated
+# .qhp file.
+
+qhp.Qt.excluded += $QT_SOURCE_TREE/doc/src/development/assistant-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/simpletextviewer.qdoc \
+ $QT_SOURCE_TREE/doc/src/development/designer-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/calculatorbuilder.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/calculatorform.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/customwidgetplugin.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/taskmenuextension.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/containerextension.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/worldtimeclockbuilder.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/worldtimeclockplugin.qdoc \
+ $QT_SOURCE_TREE/doc/src/internationalization/linguist-manual.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/hellotr.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/arrowpad.qdoc \
+ $QT_SOURCE_TREE/doc/src/examples/trollprint.qdoc \
+ $QT_SOURCE_TREE/doc/src/development/qmake-manual.qdoc
+
+# Remove the QML documentation from the Qt-only documentation.
+
+excludedirs += $QT_SOURCE_TREE/src/declarative \
+ $QT_SOURCE_TREE/src/imports \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/declarative \
+ $QT_SOURCE_TREE/doc/src/declarative
+
+outputdir = $QT_BUILD_TREE/doc-build/html-qt_zh_CN
+tagfile = $QT_BUILD_TREE/doc-build/html-qt_zh_CN/qt.tags
+base = file:$QT_BUILD_TREE/doc-build/html-qt_zh_CN
diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf
index 3570816..12dac9c 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -6,40 +6,71 @@ include(qt-defines.qdocconf)
project = Qt
description = Qt Reference Documentation
-url = http://qt.nokia.com/doc/4.6
+url = http://qt.nokia.com/doc/4.7
-edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
- QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
- QtDesigner QtAssistant QAxContainer Phonon \
- QAxServer QtUiTools QtTest QtDBus
-edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest
-edition.DesktopLight.groups = -graphicsview-api
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = en_US
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.460
+qhp.Qt.namespace = com.trolltech.qt.472
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
# Files not referenced in any qdoc file (last four are needed by qtdemo)
# See also extraimages.HTML
-qhp.Qt.extraFiles = classic.css \
- images/qt-logo.png \
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
images/taskmenuextension-example.png \
images/coloreditorfactoryimage.png \
images/dynamiclayouts-example.png \
- images/stylesheet-coffee-plastique.png
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
-qhp.Qt.filterAttributes = qt 4.6.4 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.6.4
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.4
-qhp.Qt.subprojects = classes overviews examples
+
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+qhp.Qt.subprojects = classes qmlelements overviews examples
qhp.Qt.subprojects.classes.title = Classes
-qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
+qhp.Qt.subprojects.classes.indexTitle = All Classes
qhp.Qt.subprojects.classes.selectors = class fake:headerfile
qhp.Qt.subprojects.classes.sortPages = true
+qhp.Qt.subprojects.qmlelements.title = QML Elements
+qhp.Qt.subprojects.qmlelements.indexTitle = QML Elements
+qhp.Qt.subprojects.qmlelements.selectors = fake:qmlclass
+qhp.Qt.subprojects.qmlelements.sortPages = true
qhp.Qt.subprojects.overviews.title = Overviews
qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs
qhp.Qt.subprojects.overviews.selectors = fake:page,group,module
@@ -76,6 +107,7 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \
$QT_SOURCE_TREE/src/3rdparty/freetype \
$QT_SOURCE_TREE/src/3rdparty/harfbuzz \
$QT_SOURCE_TREE/src/3rdparty/kdebase \
+ $QT_SOURCE_TREE/src/3rdparty/libconninet \
$QT_SOURCE_TREE/src/3rdparty/libjpeg \
$QT_SOURCE_TREE/src/3rdparty/libmng \
$QT_SOURCE_TREE/src/3rdparty/libpng \
@@ -89,14 +121,17 @@ excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \
$QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \
$QT_SOURCE_TREE/src/3rdparty/wintab \
$QT_SOURCE_TREE/src/3rdparty/zlib \
- $QT_SOURCE_TREE/doc/src/snippets \
$QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \
$QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \
$QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \
- $QT_SOURCE_TREE/src/3rdparty/phonon/waveout
+ $QT_SOURCE_TREE/src/3rdparty/phonon/mmf \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/waveout \
+ $QT_SOURCE_TREE/doc/src/snippets \
+ $QT_SOURCE_TREE/doc/src/ja_JP \
+ $QT_SOURCE_TREE/doc/src/zh_CN
sources.fileextensions = "*.cpp *.qdoc *.mm"
-examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml"
examples.imageextensions = "*.png"
exampledirs = $QT_SOURCE_TREE/doc/src \
@@ -106,7 +141,9 @@ exampledirs = $QT_SOURCE_TREE/doc/src \
$QT_SOURCE_TREE/qmake/examples \
$QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs
imagedirs = $QT_SOURCE_TREE/doc/src/images \
- $QT_SOURCE_TREE/examples
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/doc/src/declarative/pics \
+ $QT_SOURCE_TREE/doc/src/template/images
outputdir = $QT_BUILD_TREE/doc/html
tagfile = $QT_BUILD_TREE/doc/html/qt.tags
base = file:$QT_BUILD_TREE/doc/html
diff --git a/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf b/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf
new file mode 100644
index 0000000..24696d5
--- /dev/null
+++ b/tools/qdoc3/test/qt-build-docs_ja_JP.qdocconf
@@ -0,0 +1,118 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates_ja_JP.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qt
+description = Qt リファレンスドキュメント
+url = http://qt.nokia.com/doc/ja_JP/4.7
+
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = ja
+
+indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
+
+qhp.projects = Qt
+
+qhp.Qt.file = qt.qhp
+qhp.Qt.namespace = com.trolltech.qt.472
+qhp.Qt.virtualFolder = qdoc
+qhp.Qt.title = Qt
+qhp.Qt.indexTitle = Qt
+qhp.Qt.selectors = fake:example
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc ja_JP
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+language = Cpp
+
+sourcedirs = $QT_SOURCE_TREE/doc/src/ja_JP
+
+excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \
+ $QT_SOURCE_TREE/src/3rdparty/des \
+ $QT_SOURCE_TREE/src/3rdparty/freetype \
+ $QT_SOURCE_TREE/src/3rdparty/harfbuzz \
+ $QT_SOURCE_TREE/src/3rdparty/kdebase \
+ $QT_SOURCE_TREE/src/3rdparty/libconninet \
+ $QT_SOURCE_TREE/src/3rdparty/libjpeg \
+ $QT_SOURCE_TREE/src/3rdparty/libmng \
+ $QT_SOURCE_TREE/src/3rdparty/libpng \
+ $QT_SOURCE_TREE/src/3rdparty/libtiff \
+ $QT_SOURCE_TREE/src/3rdparty/md4 \
+ $QT_SOURCE_TREE/src/3rdparty/md5 \
+ $QT_SOURCE_TREE/src/3rdparty/patches \
+ $QT_SOURCE_TREE/src/3rdparty/sha1 \
+ $QT_SOURCE_TREE/src/3rdparty/sqlite \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \
+ $QT_SOURCE_TREE/src/3rdparty/wintab \
+ $QT_SOURCE_TREE/src/3rdparty/zlib \
+ $QT_SOURCE_TREE/doc/src/snippets \
+ $QT_SOURCE_TREE/doc/src/zh_CN \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/mmf \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/waveout
+
+sources.fileextensions = "*.cpp *.qdoc *.mm"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.imageextensions = "*.png"
+
+exampledirs = $QT_SOURCE_TREE/doc/src \
+ $QT_SOURCE_TREE/examples/ja_JP \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/examples/tutorials \
+ $QT_SOURCE_TREE \
+ $QT_SOURCE_TREE/qmake/examples \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QT_SOURCE_TREE/doc/src/ja_JP/images \
+ $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/doc/src/declarative/pics \
+ $QT_SOURCE_TREE/doc/src/template/images
+outputdir = $QT_BUILD_TREE/doc/html_ja_JP
+tagfile = $QT_BUILD_TREE/doc/html_ja_JP/qt.tags
+base = file:$QT_BUILD_TREE/doc/html_ja_JP
+
+HTML.generatemacrefs = "true"
diff --git a/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf
new file mode 100644
index 0000000..7789bf7
--- /dev/null
+++ b/tools/qdoc3/test/qt-build-docs_zh_CN.qdocconf
@@ -0,0 +1,116 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates_zh_CN.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qt
+description = Qt Reference Documentation
+url = http://qt.nokia.com/doc/zh_CN/4.7
+
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = zh-Hans
+
+indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
+
+qhp.projects = Qt
+
+qhp.Qt.file = qt.qhp
+qhp.Qt.namespace = com.trolltech.qt.472
+qhp.Qt.virtualFolder = qdoc
+qhp.Qt.title = 教程
+qhp.Qt.indexTitle = 教程
+qhp.Qt.selectors = fake:example
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc zh_CN
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+language = Cpp
+
+sourcedirs = $QT_SOURCE_TREE/doc/src/zh_CN
+
+excludedirs = $QT_SOURCE_TREE/src/3rdparty/clucene \
+ $QT_SOURCE_TREE/src/3rdparty/des \
+ $QT_SOURCE_TREE/src/3rdparty/freetype \
+ $QT_SOURCE_TREE/src/3rdparty/harfbuzz \
+ $QT_SOURCE_TREE/src/3rdparty/kdebase \
+ $QT_SOURCE_TREE/src/3rdparty/libconninet \
+ $QT_SOURCE_TREE/src/3rdparty/libjpeg \
+ $QT_SOURCE_TREE/src/3rdparty/libmng \
+ $QT_SOURCE_TREE/src/3rdparty/libpng \
+ $QT_SOURCE_TREE/src/3rdparty/libtiff \
+ $QT_SOURCE_TREE/src/3rdparty/md4 \
+ $QT_SOURCE_TREE/src/3rdparty/md5 \
+ $QT_SOURCE_TREE/src/3rdparty/patches \
+ $QT_SOURCE_TREE/src/3rdparty/sha1 \
+ $QT_SOURCE_TREE/src/3rdparty/sqlite \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebCore \
+ $QT_SOURCE_TREE/src/3rdparty/wintab \
+ $QT_SOURCE_TREE/src/3rdparty/zlib \
+ $QT_SOURCE_TREE/doc/src/snippets \
+ $QT_SOURCE_TREE/doc/src/ja_JP \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/gstreamer \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/ds9 \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/qt7 \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/mmf \
+ $QT_SOURCE_TREE/src/3rdparty/phonon/waveout
+
+sources.fileextensions = "*.cpp *.qdoc *.mm"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.imageextensions = "*.png"
+
+exampledirs = $QT_SOURCE_TREE/doc/src \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/examples/tutorials \
+ $QT_SOURCE_TREE \
+ $QT_SOURCE_TREE/qmake/examples \
+ $QT_SOURCE_TREE/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QT_SOURCE_TREE/doc/src/images \
+ $QT_SOURCE_TREE/examples \
+ $QT_SOURCE_TREE/doc/src/declarative/pics \
+ $QT_SOURCE_TREE/doc/src/template/images
+outputdir = $QT_BUILD_TREE/doc/html_zh_CN
+tagfile = $QT_BUILD_TREE/doc/html_zh_CN/qt.tags
+base = file:$QT_BUILD_TREE/doc/html_zh_CN
+
+HTML.generatemacrefs = "true"
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index dcf33dc..5d52a47 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -64,14 +64,16 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_XMLSTREAM_EXPORT \
Q_XMLPATTERNS_EXPORT \
QDBUS_EXPORT \
+ Q_DBUS_EXPORT \
QT_BEGIN_NAMESPACE \
QT_BEGIN_INCLUDE_NAMESPACE \
QT_END_NAMESPACE \
QT_END_INCLUDE_NAMESPACE \
PHONON_EXPORT \
Q_DECLARATIVE_EXPORT \
- Q_GADGET \
- QWEBKIT_EXPORT
+ Q_GADGET \
+ QWEBKIT_EXPORT \
+ Q_INVOKABLE
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
@@ -90,4 +92,7 @@ Cpp.ignoredirectives = Q_DECLARE_HANDLE \
__attribute__ \
K_DECLARE_PRIVATE \
PHONON_OBJECT \
- PHONON_HEIR
+ PHONON_HEIR \
+ Q_PRIVATE_PROPERTY \
+ Q_DECLARE_PRIVATE_D \
+ Q_CLASSINFO
diff --git a/tools/qdoc3/test/qt-defines.qdocconf b/tools/qdoc3/test/qt-defines.qdocconf
index b22727f..51ee0d3 100644
--- a/tools/qdoc3/test/qt-defines.qdocconf
+++ b/tools/qdoc3/test/qt-defines.qdocconf
@@ -3,6 +3,7 @@ defines = Q_QDOC \
QT_.*_LIB \
QT_COMPAT \
QT_KEYPAD_NAVIGATION \
+ QT_NO_EGL \
QT3_SUPPORT \
Q_WS_.* \
Q_OS_.* \
@@ -19,8 +20,43 @@ codeindent = 1
# See also qhp.Qt.extraFiles
extraimages.HTML = qt-logo \
trolltech-logo \
+ bg_l.png \
+ bg_l_blank.png \
+ bg_ll_blank.png \
+ bg_ul_blank.png \
+ header_bg.png \
+ bg_r.png \
+ box_bg.png \
+ breadcrumb.png \
+ bullet_gt.png \
+ bullet_dn.png \
+ bullet_sq.png \
+ bullet_up.png \
+ arrow_down.png \
+ feedbackground.png \
+ horBar.png \
+ page.png \
+ page_bg.png \
+ sprites-combined.png \
+ spinner.gif \
+ stylesheet-coffee-plastique.png \
taskmenuextension-example.png \
coloreditorfactoryimage.png \
- dynamiclayouts-example.png \
- stylesheet-coffee-plastique.png
- \ No newline at end of file
+ dynamiclayouts-example.png
+
+# This stuff is used by the new doc format.
+scriptdirs = $QT_SOURCE_TREE/doc/src/template/scripts
+styledirs = $QT_SOURCE_TREE/doc/src/template/style
+
+scripts.HTML = functions.js \
+ narrow.js \
+ superfish.js \
+ jquery.js
+
+styles.HTML = style.css \
+ narrow.css \
+ superfish.css \
+ superfish_skin.css \
+ style_ie6.css \
+ style_ie7.css \
+ style_ie8.css
diff --git a/tools/qdoc3/test/qt-ditaxml.qdocconf b/tools/qdoc3/test/qt-ditaxml.qdocconf
new file mode 100644
index 0000000..66f30e3
--- /dev/null
+++ b/tools/qdoc3/test/qt-ditaxml.qdocconf
@@ -0,0 +1,11 @@
+include(qt.qdocconf)
+
+imagedirs = $QTDIR/doc/src/images \
+ $QTDIR/examples \
+ $QTDIR/doc/src/template/images
+
+outputdir = $QTDIR/doc/ditaxml
+outputformats = DITAXML
+
+generateindex = true
+url = .
diff --git a/tools/qdoc3/test/qt-html-templates.qdocconf b/tools/qdoc3/test/qt-html-templates.qdocconf
index 60d6b61..698164d 100644
--- a/tools/qdoc3/test/qt-html-templates.qdocconf
+++ b/tools/qdoc3/test/qt-html-templates.qdocconf
@@ -1,25 +1,186 @@
-HTML.stylesheets = classic.css
-HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \
- "<tr>\n" \
- "<td align=\"left\" valign=\"top\" width=\"32\">" \
- "<a href=\"http://qt.nokia.com/\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \
- "</td>\n" \
- "<td width=\"1\">&nbsp;&nbsp;</td>" \
- "<td class=\"postheader\" valign=\"center\">" \
- "<a href=\"index.html\">" \
- "<font color=\"#004faf\">Home</font></a>&nbsp;&middot;" \
- " <a href=\"classes.html\">" \
- "<font color=\"#004faf\">All&nbsp;Classes</font></a>&nbsp;&middot;" \
- " <a href=\"functions.html\">" \
- "<font color=\"#004faf\">All&nbsp;Functions</font></a>&nbsp;&middot;" \
- " <a href=\"overviews.html\">" \
- "<font color=\"#004faf\">Overviews</font></a>" \
- "</td>" \
- "</tr></table>"
+HTML.stylesheets = style/style.css \
+ style/OfflineStyle.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style_ie6.css
-HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
- "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
- "<td width=\"40%\" align=\"left\">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>\n" \
- "<td width=\"20%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
- "<td width=\"40%\" align=\"right\"><div align=\"right\">Qt \\version</div></td>\n" \
- "</tr></table></div></address>"
+HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \
+ " <div class=\"content\"> \n" \
+ " <div id=\"nav-logo\">\n" \
+ " <a href=\"index.html\">Home</a></div>\n" \
+ " <a href=\"index.html\" class=\"qtref\"><span>Qt Reference Documentation</span></a>\n" \
+ " <div id=\"narrowsearch\"></div>\n" \
+ " <div id=\"nav-topright\">\n" \
+ " <ul>\n" \
+ " <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \
+ " <li class=\"nav-topright-dev\"><a href=\"http://developer.qt.nokia.com/\">DEV</a></li>\n" \
+ " <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \
+ " <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \
+ " DOC</a></li>\n" \
+ " <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <div id=\"shortCut\">\n" \
+ " <ul>\n" \
+ " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \
+ " <li class=\"shortCut-topleft-active\"><a href=\"http://doc.qt.nokia.com\">ALL VERSIONS" \
+ " </a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <ul class=\"sf-menu\" id=\"narrowmenu\"> \n" \
+ " <li><a href=\"#\">API Lookup</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"classes.html\">Class index</a></li> \n" \
+ " <li><a href=\"functions.html\">Function index</a></li> \n" \
+ " <li><a href=\"modules.html\">Modules</a></li> \n" \
+ " <li><a href=\"namespaces.html\">Namespaces</a></li> \n" \
+ " <li><a href=\"qtglobal.html\">Global Declarations</a></li> \n" \
+ " <li><a href=\"qdeclarativeelements.html\">QML elements</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Qt Topics</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"qt-basic-concepts.html\">Programming with Qt</a></li> \n" \
+ " <li><a href=\"qtquick.html\">Device UIs &amp; Qt Quick</a></li> \n" \
+ " <li><a href=\"qt-gui-concepts.html\">UI Design with Qt</a></li> \n" \
+ " <li><a href=\"developing-with-qt.html\">Cross-platform and Platform-specific</a></li> \n" \
+ " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " <li><a href=\"technology-apis.html\">Qt and Key Technologies</a></li> \n" \
+ " <li><a href=\"best-practices.html\">How-To's and Best Practices</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Examples</a> \n" \
+ " <ul> \n" \
+ " <li><a href=\"all-examples.html\">Examples</a></li> \n" \
+ " <li><a href=\"tutorials.html\">Tutorials</a></li> \n" \
+ " <li><a href=\"demos.html\">Demos</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html\">QML Examples</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrapper\">\n" \
+ " <div class=\"hd\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " <div class=\"bd group\">\n" \
+ " <div class=\"sidebar\">\n" \
+ " <div class=\"searchlabel\">\n" \
+ " Search index:</div>\n" \
+ " <div class=\"search\" id=\"sidebarsearch\">\n" \
+ " <form id=\"qtdocsearch\" action=\"\" onsubmit=\"return false;\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" name=\"searchstring\" id=\"pageType\" value=\"\" />\n" \
+ " <div id=\"resultdialog\"> \n" \
+ " <a href=\"#\" id=\"resultclose\">Close</a> \n" \
+ " <p id=\"resultlinks\" class=\"all\"><a href=\"#\" id=\"showallresults\">All</a> | <a href=\"#\" id=\"showapiresults\">API</a> | <a href=\"#\" id=\"showarticleresults\">Articles</a> | <a href=\"#\" id=\"showexampleresults\">Examples</a></p> \n" \
+ " <p id=\"searchcount\" class=\"all\"><span id=\"resultcount\"></span><span id=\"apicount\"></span><span id=\"articlecount\"></span><span id=\"examplecount\"></span>&nbsp;results:</p> \n" \
+ " <ul id=\"resultlist\" class=\"all\"> \n" \
+ " </ul> \n" \
+ " </div> \n" \
+ " </fieldset>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div class=\"box first bottombar\" id=\"lookup\">\n" \
+ " <h2 title=\"API Lookup\"><span></span>\n" \
+ " API Lookup</h2>\n" \
+ " <div id=\"list001\" class=\"list\">\n" \
+ " <ul id=\"ul001\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"classes.html\">Class index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"functions.html\">Function index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"modules.html\">Modules</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"namespaces.html\">Namespaces</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qtglobal.html\">Global Declarations</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeelements.html\">QML elements</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box bottombar\" id=\"topics\">\n" \
+ " <h2 title=\"Qt Topics\"><span></span>\n" \
+ " Qt Topics</h2>\n" \
+ " <div id=\"list002\" class=\"list\">\n" \
+ " <ul id=\"ul002\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Programming with Qt</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"qtquick.html\">Device UIs &amp; Qt Quick</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">UI Design with Qt</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"developing-with-qt.html\">Cross-platform and Platform-specific</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"technology-apis.html\">Qt and Key Technologies</a></li> \n" \
+ " <li class=\"defaultLink\"><a href=\"best-practices.html\">How-To's and Best Practices</a></li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box\" id=\"examples\">\n" \
+ " <h2 title=\"Examples\"><span></span>\n" \
+ " Examples</h2>\n" \
+ " <div id=\"list003\" class=\"list\">\n" \
+ " <ul id=\"ul003\">\n" \
+ " <li class=\"defaultLink\"><a href=\"all-examples.html\">Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"tutorials.html\">Tutorials</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"demos.html\">Demos</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html\">QML Examples</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrap\">\n" \
+ " <div class=\"toolbar\">\n" \
+ " <div class=\"breadcrumb toolblock\">\n" \
+ " <ul>\n" \
+ " <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
+ " <!-- Bread crumbs goes here -->\n"
+
+HTML.postpostheader = " </ul>\n" \
+ " </div>\n" \
+ " <div class=\"toolbuttons toolblock\">\n" \
+ " <ul>\n" \
+ " <li id=\"smallA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"medA\" class=\"t_button active\">A</li>\n" \
+ " <li id=\"bigA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \
+ " <span>Print</span></a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"content mainContent\">\n"
+
+HTML.footer = "" \
+ " <div class=\"feedback t_button\">\n" \
+ " [+] Documentation Feedback</div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"ft\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"footer\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2008-2010 Nokia Corporation and/or its\n" \
+ " subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
+ " in Finland and/or other countries worldwide.</p>\n" \
+ " <p>\n" \
+ " All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
+ " href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
+ " <br />\n" \
+ " <p>\n" \
+ " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
+ " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
+ " with the terms contained in a written agreement between you and Nokia.</p>\n" \
+ " <p>\n" \
+ " Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
+ " Free Documentation License version 1.3</a>\n" \
+ " as published by the Free Software Foundation.</p>\n" \
+ " </div>\n" \
+ " <div id=\"feedbackBox\">\n" \
+ " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \
+ " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \
+ " <p id=\"noteHead\">Thank you for giving your feedback.</p> <p class=\"note\">Make sure it is related to this specific page. For more general bugs and \n" \
+ " requests, please use the <a href=\"http://bugreports.qt.nokia.com/secure/Dashboard.jspa\">Qt Bug Tracker</a>.</p>\n" \
+ " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\"></textarea></p>\n" \
+ " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div id=\"blurpage\">\n" \
+ " </div>\n" \ No newline at end of file
diff --git a/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf b/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf
new file mode 100644
index 0000000..da20766
--- /dev/null
+++ b/tools/qdoc3/test/qt-html-templates_ja_JP.qdocconf
@@ -0,0 +1,177 @@
+HTML.stylesheets = style/style.css \
+ style/OfflineStyle.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style_ie6.css
+
+HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \
+ " <div class=\"content\"> \n" \
+ " <div id=\"nav-logo\">\n" \
+ " <a href=\"index.html\">Home</a></div>\n" \
+ " <a href=\"index.html\" class=\"qtref\"><span>Qt Reference Documentation</span></a>\n" \
+ " <div id=\"narrowsearch\"><form onsubmit=\"return false;\" action=\"\" id=\"qtdocsearch\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" value=\"\" id=\"pageType\" name=\"searchstring\">\n" \
+ " </fieldset>\n" \
+ " </form></div>\n" \
+ " <div id=\"nav-topright\">\n" \
+ " <ul>\n" \
+ " <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \
+ " <li class=\"nav-topright-dev\"><a href=\"http://qt.nokia.com/developer\">DEV</a></li>\n" \
+ " <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \
+ " <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \
+ " DOC</a></li>\n" \
+ " <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \
+ " <li class=\"nav-topright-shop\"><a title=\"SHOP\" href=\"http://shop.qt.nokia.com\">SHOP</a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <div id=\"shortCut\">\n" \
+ " <ul>\n" \
+ " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \
+ " <li class=\"shortCut-topleft-active\"><a href=\"http://qt.nokia.com/doc/\">ALL VERSIONS" \
+ " </a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <ul class=\"sf-menu sf-js-enabled sf-shadow\" id=\"narrowmenu\"> \n" \
+ " <li><a href=\"#\">API Lookup</a> \n" \
+ " <ul id=\"topmenuLook\"> \n" \
+ " <li><a href=\"classes.html\">Class index</a></li> \n" \
+ " <li><a href=\"functions.html\">Function index</a></li> \n" \
+ " <li><a href=\"modules.html\">Modules</a></li> \n" \
+ " <li><a href=\"namespaces.html\">Namespaces</a></li> \n" \
+ " <li><a href=\"qtglobal.html\">Global stuff</a></li> \n" \
+ " <li><a href=\"qdeclarativeelements.html\">QML elements</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Qt Topics</a> \n" \
+ " <ul id=\"topmenuTopic\"> \n" \
+ " <li><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li> \n" \
+ " <li><a href=\"declarativeui.html\">Device UI's &amp; Qt Quick</a></li> \n" \
+ " <li><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li> \n" \
+ " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Examples</a> \n" \
+ " <ul id=\"topmenuexample\"> \n" \
+ " <li><a href=\"all-examples.html\">Examples</a></li> \n" \
+ " <li><a href=\"tutorials.html\">チュートリアル</a></li> \n" \
+ " <li><a href=\"demos.html\">Demos</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html\">QML Examples</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrapper\">\n" \
+ " <div class=\"hd\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " <div class=\"bd group\">\n" \
+ " <div class=\"sidebar\">\n" \
+ " <div class=\"searchlabel\">\n" \
+ " Search index:</div>\n" \
+ " <div class=\"search\">\n" \
+ " <form id=\"qtdocsearch\" action=\"\" onsubmit=\"return false;\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" name=\"searchstring\" id=\"pageType\" value=\"\" />\n" \
+ " </fieldset>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div class=\"box first bottombar\" id=\"lookup\">\n" \
+ " <h2 title=\"API Lookup\"><span></span>\n" \
+ " API Lookup</h2>\n" \
+ " <div id=\"list001\" class=\"list\">\n" \
+ " <ul id=\"ul001\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"classes.html\">Class index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"functions.html\">Function index</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"modules.html\">Modules</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"namespaces.html\">Namespaces</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qtglobal.html\">Global stuff</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeelements.html\">QML elements</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box bottombar\" id=\"topics\">\n" \
+ " <h2 title=\"Qt Topics\"><span></span>\n" \
+ " Qt Topics</h2>\n" \
+ " <div id=\"list002\" class=\"list\">\n" \
+ " <ul id=\"ul002\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"declarativeui.html\">Device UI's &amp; Qt Quick</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box\" id=\"examples\">\n" \
+ " <h2 title=\"Examples\"><span></span>\n" \
+ " Examples</h2>\n" \
+ " <div id=\"list003\" class=\"list\">\n" \
+ " <ul id=\"ul003\">\n" \
+ " <li class=\"defaultLink\"><a href=\"all-examples.html\">Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"tutorials.html\">チュートリアル</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"demos.html\">Demos</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html\">QML Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrap\">\n" \
+ " <div class=\"toolbar\">\n" \
+ " <div class=\"breadcrumb toolblock\">\n" \
+ " <ul>\n" \
+ " <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
+ " <!-- Bread crumbs goes here -->\n"
+
+HTML.postpostheader = " </ul>\n" \
+ " </div>\n" \
+ " <div class=\"toolbuttons toolblock\">\n" \
+ " <ul>\n" \
+ " <li id=\"smallA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"medA\" class=\"t_button active\">A</li>\n" \
+ " <li id=\"bigA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \
+ " <span>Print</span></a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"content\">\n"
+
+HTML.footer = " <!-- /div -->\n" \
+ " <div class=\"feedback t_button\">\n" \
+ " [+] Documentation Feedback</div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"ft\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"footer\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2008-2010 Nokia Corporation and/or its\n" \
+ " subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
+ " in Finland and/or other countries worldwide.</p>\n" \
+ " <p>\n" \
+ " All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
+ " href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
+ " <br />\n" \
+ " <p>\n" \
+ " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
+ " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
+ " with the terms contained in a written agreement between you and Nokia.</p>\n" \
+ " <p>\n" \
+ " Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
+ " Free Documentation License version 1.3</a>\n" \
+ " as published by the Free Software Foundation.</p>\n" \
+ " </div>\n" \
+ " <div id=\"feedbackBox\">\n" \
+ " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \
+ " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \
+ " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\">Please submit your feedback...</textarea></p>\n" \
+ " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div id=\"blurpage\">\n" \
+ " </div>\n"
diff --git a/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf
new file mode 100644
index 0000000..5c4bfa9
--- /dev/null
+++ b/tools/qdoc3/test/qt-html-templates_zh_CN.qdocconf
@@ -0,0 +1,177 @@
+HTML.stylesheets = style/style.css \
+ style/OfflineStyle.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style_ie6.css
+
+HTML.postheader = " <div class=\"header\" id=\"qtdocheader\">\n" \
+ " <div class=\"content\"> \n" \
+ " <div id=\"nav-logo\">\n" \
+ " <a href=\"index.html\">Home</a></div>\n" \
+ " <a href=\"index.html\" class=\"qtref\"><span>Qt Reference Documentation</span></a>\n" \
+ " <div id=\"narrowsearch\"><form onsubmit=\"return false;\" action=\"\" id=\"qtdocsearch\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" value=\"\" id=\"pageType\" name=\"searchstring\">\n" \
+ " </fieldset>\n" \
+ " </form></div>\n" \
+ " <div id=\"nav-topright\">\n" \
+ " <ul>\n" \
+ " <li class=\"nav-topright-home\"><a href=\"http://qt.nokia.com/\">Qt HOME</a></li>\n" \
+ " <li class=\"nav-topright-dev\"><a href=\"http://qt.nokia.com/developer\">DEV</a></li>\n" \
+ " <li class=\"nav-topright-labs\"><a href=\"http://labs.qt.nokia.com/blogs/\">LABS</a></li>\n" \
+ " <li class=\"nav-topright-doc nav-topright-doc-active\"><a href=\"http://doc.qt.nokia.com/\">\n" \
+ " DOC</a></li>\n" \
+ " <li class=\"nav-topright-blog\"><a href=\"http://blog.qt.nokia.com/\">BLOG</a></li>\n" \
+ " <li class=\"nav-topright-shop\"><a title=\"SHOP\" href=\"http://shop.qt.nokia.com\">SHOP</a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <div id=\"shortCut\">\n" \
+ " <ul>\n" \
+ " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \
+ " <li class=\"shortCut-topleft-active\"><a href=\"http://qt.nokia.com/doc/\">ALL VERSIONS" \
+ " </a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " <ul class=\"sf-menu sf-js-enabled sf-shadow\" id=\"narrowmenu\"> \n" \
+ " <li><a href=\"#\">API Lookup</a> \n" \
+ " <ul id=\"topmenuLook\"> \n" \
+ " <li><a href=\"classes.html\">所有类</a></li> \n" \
+ " <li><a href=\"functions.html\">所有函数</a></li> \n" \
+ " <li><a href=\"modules.html\">Modules</a></li> \n" \
+ " <li><a href=\"namespaces.html\">Namespaces</a></li> \n" \
+ " <li><a href=\"qtglobal.html\">Global stuff</a></li> \n" \
+ " <li><a href=\"qdeclarativeelements.html\">QML elements</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Qt Topics</a> \n" \
+ " <ul id=\"topmenuTopic\"> \n" \
+ " <li><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li> \n" \
+ " <li><a href=\"declarativeui.html\">Device UI's &amp; Qt Quick</a></li> \n" \
+ " <li><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li> \n" \
+ " <li><a href=\"platform-specific.html\">Platform-specific info</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " <li><a href=\"#\">Examples</a> \n" \
+ " <ul id=\"topmenuexample\"> \n" \
+ " <li><a href=\"all-examples.html\">Examples</a></li> \n" \
+ " <li><a href=\"tutorials.html\">Tutorials</a></li> \n" \
+ " <li><a href=\"demos.html\">Demos</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html\">QML Examples</a></li> \n" \
+ " <li><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li> \n" \
+ " </ul> \n" \
+ " </li> \n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrapper\">\n" \
+ " <div class=\"hd\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " <div class=\"bd group\">\n" \
+ " <div class=\"sidebar\">\n" \
+ " <div class=\"searchlabel\">\n" \
+ " Search index:</div>\n" \
+ " <div class=\"search\">\n" \
+ " <form id=\"qtdocsearch\" action=\"\" onsubmit=\"return false;\">\n" \
+ " <fieldset>\n" \
+ " <input type=\"text\" name=\"searchstring\" id=\"pageType\" value=\"\" />\n" \
+ " </fieldset>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div class=\"box first bottombar\" id=\"lookup\">\n" \
+ " <h2 title=\"API Lookup\"><span></span>\n" \
+ " API Lookup</h2>\n" \
+ " <div id=\"list001\" class=\"list\">\n" \
+ " <ul id=\"ul001\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"classes.html\">所有类</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"functions.html\">所有函数</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"modules.html\">Modules</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"namespaces.html\">Namespaces</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qtglobal.html\">Global stuff</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeelements.html\">QML elements</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box bottombar\" id=\"topics\">\n" \
+ " <h2 title=\"Qt Topics\"><span></span>\n" \
+ " Qt Topics</h2>\n" \
+ " <div id=\"list002\" class=\"list\">\n" \
+ " <ul id=\"ul002\" >\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-basic-concepts.html\">Basic Qt architecture</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"declarativeui.html\">Device UI's &amp; Qt Quick</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qt-gui-concepts.html\">Desktop UI components</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"platform-specific.html\">Platform-specific info</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"box\" id=\"examples\">\n" \
+ " <h2 title=\"Examples\"><span></span>\n" \
+ " Examples</h2>\n" \
+ " <div id=\"list003\" class=\"list\">\n" \
+ " <ul id=\"ul003\">\n" \
+ " <li class=\"defaultLink\"><a href=\"all-examples.html\">Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"tutorials.html\">Tutorials</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"demos.html\">Demos</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html\">QML Examples</a></li>\n" \
+ " <li class=\"defaultLink\"><a href=\"qdeclarativeexamples.html#Demos\">QML Demos</a></li>\n" \
+ " </ul> \n" \
+ " </div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"wrap\">\n" \
+ " <div class=\"toolbar\">\n" \
+ " <div class=\"breadcrumb toolblock\">\n" \
+ " <ul>\n" \
+ " <li class=\"first\"><a href=\"index.html\">Home</a></li>\n" \
+ " <!-- Bread crumbs goes here -->\n"
+
+HTML.postpostheader = " </ul>\n" \
+ " </div>\n" \
+ " <div class=\"toolbuttons toolblock\">\n" \
+ " <ul>\n" \
+ " <li id=\"smallA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"medA\" class=\"t_button active\">A</li>\n" \
+ " <li id=\"bigA\" class=\"t_button\">A</li>\n" \
+ " <li id=\"print\" class=\"t_button\"><a href=\"javascript:this.print();\">\n" \
+ " <span>Print</span></a></li>\n" \
+ " </ul>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"content\">\n"
+
+HTML.footer = " <!-- /div -->\n" \
+ " <div class=\"feedback t_button\">\n" \
+ " [+] Documentation Feedback</div>\n" \
+ " </div>\n" \
+ " </div>\n" \
+ " <div class=\"ft\">\n" \
+ " <span></span>\n" \
+ " </div>\n" \
+ " </div> \n" \
+ " <div class=\"footer\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2008-2010 Nokia Corporation and/or its\n" \
+ " subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation \n" \
+ " in Finland and/or other countries worldwide.</p>\n" \
+ " <p>\n" \
+ " All other trademarks are property of their respective owners. <a title=\"Privacy Policy\"\n" \
+ " href=\"http://qt.nokia.com/about/privacy-policy\">Privacy Policy</a></p>\n" \
+ " <br />\n" \
+ " <p>\n" \
+ " Licensees holding valid Qt Commercial licenses may use this document in accordance with the" \
+ " Qt Commercial License Agreement provided with the Software or, alternatively, in accordance" \
+ " with the terms contained in a written agreement between you and Nokia.</p>\n" \
+ " <p>\n" \
+ " Alternatively, this document may be used under the terms of the <a href=\"http://www.gnu.org/licenses/fdl.html\">GNU\n" \
+ " Free Documentation License version 1.3</a>\n" \
+ " as published by the Free Software Foundation.</p>\n" \
+ " </div>\n" \
+ " <div id=\"feedbackBox\">\n" \
+ " <div id=\"feedcloseX\" class=\"feedclose t_button\">X</div>\n" \
+ " <form id=\"feedform\" action=\"http://doc.qt.nokia.com/docFeedbck/feedback.php\" method=\"get\">\n" \
+ " <p><textarea id=\"feedbox\" name=\"feedText\" rows=\"5\" cols=\"40\">Please submit your feedback...</textarea></p>\n" \
+ " <p><input id=\"feedsubmit\" class=\"feedclose\" type=\"submit\" name=\"feedback\" /></p>\n" \
+ " </form>\n" \
+ " </div>\n" \
+ " <div id=\"blurpage\">\n" \
+ " </div>\n"
diff --git a/tools/qdoc3/test/qt-webxml.qdocconf b/tools/qdoc3/test/qt-webxml.qdocconf
index 3ad0457..80ced42 100644
--- a/tools/qdoc3/test/qt-webxml.qdocconf
+++ b/tools/qdoc3/test/qt-webxml.qdocconf
@@ -2,7 +2,8 @@ include(qt.qdocconf)
quotinginformation = true
imagedirs = $QTDIR/doc/src/images \
- $QTDIR/examples
+ $QTDIR/examples \
+ $QTDIR/doc/src/template/images
outputdir = $QTDIR/doc/webxml
outputformats = WebXML
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index b8dbcd1..66f62ad 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -8,40 +8,69 @@ project = Qt
versionsym =
version = %VERSION%
description = Qt Reference Documentation
-url = http://qt.nokia.com/doc/4.6
+url = http://qt.nokia.com/doc/4.7
-edition.Desktop.modules = QtCore QtDBus QtGui QtNetwork QtOpenGL QtScript QtScriptTools QtSql QtSvg \
- QtWebKit QtXml QtXmlPatterns Qt3Support QtHelp \
- QtDesigner QtAssistant QAxContainer Phonon \
- QAxServer QtUiTools QtTest QtDBus
-edition.DesktopLight.modules = QtCore QtDBus QtGui Qt3SupportLight QtTest
-edition.DesktopLight.groups = -graphicsview-api
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = en_US
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.460
+qhp.Qt.namespace = com.trolltech.qt.472
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
# Files not referenced in any qdoc file (last four are needed by qtdemo)
# See also extraimages.HTML
-qhp.Qt.extraFiles = classic.css \
- images/qt-logo.png \
- images/taskmenuextension-example.png \
- images/coloreditorfactoryimage.png \
- images/dynamiclayouts-example.png \
- images/stylesheet-coffee-plastique.png
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
-qhp.Qt.filterAttributes = qt 4.6.4 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.6.4
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.4
-qhp.Qt.subprojects = classes overviews examples
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+qhp.Qt.subprojects = classes qmlelements overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
qhp.Qt.subprojects.classes.selectors = class fake:headerfile
qhp.Qt.subprojects.classes.sortPages = true
+qhp.Qt.subprojects.qmlelements.title = QML Elements
+qhp.Qt.subprojects.qmlelements.indexTitle = QML Elements
+qhp.Qt.subprojects.qmlelements.selectors = fake:qmlclass
+qhp.Qt.subprojects.qmlelements.sortPages = true
qhp.Qt.subprojects.overviews.title = Overviews
qhp.Qt.subprojects.overviews.indexTitle = All Overviews and HOWTOs
qhp.Qt.subprojects.overviews.selectors = fake:page,group,module
@@ -78,6 +107,7 @@ excludedirs = $QTDIR/src/3rdparty/clucene \
$QTDIR/src/3rdparty/freetype \
$QTDIR/src/3rdparty/harfbuzz \
$QTDIR/src/3rdparty/kdebase \
+ $QTDIR/src/3rdparty/libconninet \
$QTDIR/src/3rdparty/libjpeg \
$QTDIR/src/3rdparty/libmng \
$QTDIR/src/3rdparty/libpng \
@@ -91,15 +121,17 @@ excludedirs = $QTDIR/src/3rdparty/clucene \
$QTDIR/src/3rdparty/webkit/WebCore \
$QTDIR/src/3rdparty/wintab \
$QTDIR/src/3rdparty/zlib \
- $QTDIR/doc/src/snippets \
$QTDIR/src/3rdparty/phonon/gstreamer \
$QTDIR/src/3rdparty/phonon/ds9 \
$QTDIR/src/3rdparty/phonon/qt7 \
$QTDIR/src/3rdparty/phonon/mmf \
- $QTDIR/src/3rdparty/phonon/waveout
+ $QTDIR/src/3rdparty/phonon/waveout \
+ $QTDIR/doc/src/snippets \
+ $QTDIR/doc/src/ja_JP \
+ $QTDIR/doc/src/zh_CN
sources.fileextensions = "*.cpp *.qdoc *.mm"
-examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp *.qml"
examples.imageextensions = "*.png"
exampledirs = $QTDIR/doc/src \
@@ -109,7 +141,9 @@ exampledirs = $QTDIR/doc/src \
$QTDIR/qmake/examples \
$QTDIR/src/3rdparty/webkit/WebKit/qt/docs
imagedirs = $QTDIR/doc/src/images \
- $QTDIR/examples
+ $QTDIR/examples \
+ $QTDIR/doc/src/declarative/pics \
+ $QTDIR/doc/src/template/images
outputdir = $QTDIR/doc/html
tagfile = $QTDIR/doc/html/qt.tags
base = file:$QTDIR/doc/html
diff --git a/tools/qdoc3/test/qt_ja_JP.qdocconf b/tools/qdoc3/test/qt_ja_JP.qdocconf
new file mode 100644
index 0000000..a5c348c
--- /dev/null
+++ b/tools/qdoc3/test/qt_ja_JP.qdocconf
@@ -0,0 +1,118 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates_ja_JP.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qt
+versionsym =
+version = %VERSION%
+description = Qt リファレンスドキュメント
+url = http://qt.nokia.com/doc/ja_JP/4.7
+
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = ja
+
+indexes = $QTDIR/doc/html/qt.index
+
+qhp.projects = Qt
+
+qhp.Qt.file = qt.qhp
+qhp.Qt.namespace = com.trolltech.qt.472
+qhp.Qt.virtualFolder = qdoc
+qhp.Qt.title = Qt
+qhp.Qt.indexTitle = Qt
+qhp.Qt.selectors = fake:example
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc ja_JP
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+language = Cpp
+
+sourcedirs = $QTDIR/doc/src/ja_JP
+
+excludedirs = $QTDIR/src/3rdparty/clucene \
+ $QTDIR/src/3rdparty/des \
+ $QTDIR/src/3rdparty/freetype \
+ $QTDIR/src/3rdparty/harfbuzz \
+ $QTDIR/src/3rdparty/kdebase \
+ $QTDIR/src/3rdparty/libjpeg \
+ $QTDIR/src/3rdparty/libmng \
+ $QTDIR/src/3rdparty/libpng \
+ $QTDIR/src/3rdparty/libtiff \
+ $QTDIR/src/3rdparty/md4 \
+ $QTDIR/src/3rdparty/md5 \
+ $QTDIR/src/3rdparty/patches \
+ $QTDIR/src/3rdparty/sha1 \
+ $QTDIR/src/3rdparty/sqlite \
+ $QTDIR/src/3rdparty/webkit/JavaScriptCore \
+ $QTDIR/src/3rdparty/webkit/WebCore \
+ $QTDIR/src/3rdparty/wintab \
+ $QTDIR/src/3rdparty/zlib \
+ $QTDIR/doc/src/snippets \
+ $QTDIR/doc/src/zh_CN \
+ $QTDIR/src/3rdparty/phonon/gstreamer \
+ $QTDIR/src/3rdparty/phonon/ds9 \
+ $QTDIR/src/3rdparty/phonon/qt7 \
+ $QTDIR/src/3rdparty/phonon/mmf \
+ $QTDIR/src/3rdparty/phonon/waveout
+
+sources.fileextensions = "*.cpp *.qdoc *.mm"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.imageextensions = "*.png"
+
+exampledirs = $QTDIR/doc/src \
+ $QTDIR/examples/ja_JP \
+ $QTDIR/examples \
+ $QTDIR/examples/tutorials \
+ $QTDIR \
+ $QTDIR/qmake/examples \
+ $QTDIR/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QTDIR/doc/src/ja_JP/images \
+ $QTDIR/doc/src/images \
+ $QTDIR/examples \
+ $QTDIR/doc/src/template/images
+outputdir = $QTDIR/doc/html_ja_JP
+tagfile = $QTDIR/doc/html_ja_JP/qt.tags
+base = file:$QTDIR/doc/html_ja_JP
+
+HTML.generatemacrefs = "true"
diff --git a/tools/qdoc3/test/qt_zh_CN.qdocconf b/tools/qdoc3/test/qt_zh_CN.qdocconf
new file mode 100644
index 0000000..25f96b8
--- /dev/null
+++ b/tools/qdoc3/test/qt_zh_CN.qdocconf
@@ -0,0 +1,116 @@
+include(compat.qdocconf)
+include(macros.qdocconf)
+include(qt-cpp-ignore.qdocconf)
+include(qt-html-templates_zh_CN.qdocconf)
+include(qt-defines.qdocconf)
+
+project = Qt
+versionsym =
+version = %VERSION%
+description = Qt Reference Documentation
+url = http://qt.nokia.com/doc/zh_CN/4.7
+
+sourceencoding = UTF-8
+outputencoding = UTF-8
+naturallanguage = zh-Hans
+
+indexes = $QTDIR/doc/html/qt.index
+
+qhp.projects = Qt
+
+qhp.Qt.file = qt.qhp
+qhp.Qt.namespace = com.trolltech.qt.472
+qhp.Qt.virtualFolder = qdoc
+qhp.Qt.title = 教程
+qhp.Qt.indexTitle = 教程
+qhp.Qt.selectors = fake:example
+
+qhp.Qt.filterAttributes = qt 4.7.2 qtrefdoc zh_CN
+qhp.Qt.customFilters.Qt.name = Qt 4.7.2
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.2
+
+# Files not referenced in any qdoc file (last four are needed by qtdemo)
+# See also extraimages.HTML
+qhp.Qt.extraFiles = index.html \
+ images/bg_l.png \
+ images/bg_l_blank.png \
+ images/bg_ll_blank.png \
+ images/bg_ul_blank.png \
+ images/header_bg.png \
+ images/bg_r.png \
+ images/box_bg.png \
+ images/breadcrumb.png \
+ images/bullet_gt.png \
+ images/bullet_dn.png \
+ images/bullet_sq.png \
+ images/bullet_up.png \
+ images/arrow_down.png \
+ images/feedbackground.png \
+ images/horBar.png \
+ images/page.png \
+ images/page_bg.png \
+ images/sprites-combined.png \
+ images/spinner.gif \
+ images/stylesheet-coffee-plastique.png \
+ images/taskmenuextension-example.png \
+ images/coloreditorfactoryimage.png \
+ images/dynamiclayouts-example.png \
+ scripts/functions.js \
+ scripts/jquery.js \
+ scripts/narrow.js \
+ scripts/superfish.js \
+ style/narrow.css \
+ style/superfish.css \
+ style/style_ie6.css \
+ style/style_ie7.css \
+ style/style_ie8.css \
+ style/style.css
+
+language = Cpp
+
+sourcedirs = $QTDIR/doc/src/zh_CN
+
+excludedirs = $QTDIR/src/3rdparty/clucene \
+ $QTDIR/src/3rdparty/des \
+ $QTDIR/src/3rdparty/freetype \
+ $QTDIR/src/3rdparty/harfbuzz \
+ $QTDIR/src/3rdparty/kdebase \
+ $QTDIR/src/3rdparty/libjpeg \
+ $QTDIR/src/3rdparty/libmng \
+ $QTDIR/src/3rdparty/libpng \
+ $QTDIR/src/3rdparty/libtiff \
+ $QTDIR/src/3rdparty/md4 \
+ $QTDIR/src/3rdparty/md5 \
+ $QTDIR/src/3rdparty/patches \
+ $QTDIR/src/3rdparty/sha1 \
+ $QTDIR/src/3rdparty/sqlite \
+ $QTDIR/src/3rdparty/webkit/JavaScriptCore \
+ $QTDIR/src/3rdparty/webkit/WebCore \
+ $QTDIR/src/3rdparty/wintab \
+ $QTDIR/src/3rdparty/zlib \
+ $QTDIR/doc/src/snippets \
+ $QTDIR/doc/src/ja_JP \
+ $QTDIR/src/3rdparty/phonon/gstreamer \
+ $QTDIR/src/3rdparty/phonon/ds9 \
+ $QTDIR/src/3rdparty/phonon/qt7 \
+ $QTDIR/src/3rdparty/phonon/mmf \
+ $QTDIR/src/3rdparty/phonon/waveout
+
+sources.fileextensions = "*.cpp *.qdoc *.mm"
+examples.fileextensions = "*.cpp *.h *.js *.xq *.svg *.xml *.ui *.qhp *.qhcp"
+examples.imageextensions = "*.png"
+
+exampledirs = $QTDIR/doc/src \
+ $QTDIR/examples \
+ $QTDIR/examples/tutorials \
+ $QTDIR \
+ $QTDIR/qmake/examples \
+ $QTDIR/src/3rdparty/webkit/WebKit/qt/docs
+imagedirs = $QTDIR/doc/src/images \
+ $QTDIR/examples \
+ $QTDIR/doc/src/template/images
+outputdir = $QTDIR/doc/html_zh_CN
+tagfile = $QTDIR/doc/html_zh_CN/qt.tags
+base = file:$QTDIR/doc/html_zh_CN
+
+HTML.generatemacrefs = "true"
diff --git a/tools/qdoc3/test/scripts/functions.js b/tools/qdoc3/test/scripts/functions.js
new file mode 100644
index 0000000..0135427
--- /dev/null
+++ b/tools/qdoc3/test/scripts/functions.js
@@ -0,0 +1,60 @@
+
+/* START non link areas where cursor should change to pointing hand */
+$('.t_button').mouseover(function() {
+ $('.t_button').css('cursor','pointer');
+ /*document.getElementById(this.id).style.cursor='pointer';*/
+});
+
+/* END non link areas */
+$('#smallA').click(function() {
+ $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('font-size','smaller');
+ $('.t_button').removeClass('active')
+ $(this).addClass('active')
+});
+
+$('#medA').click(function() {
+ $('.content .heading').css('font','600 16px/1 Arial');
+ $('.content h1').css('font','600 18px/1.2 Arial');
+ $('.content h2').css('font','600 16px/1.2 Arial');
+ $('.content h3').css('font','600 14px/1.2 Arial');
+ $('.content p').css('font','13px/20px Verdana');
+ $('.content li').css('font','400 13px/1 Verdana');
+ $('.content li').css('line-height','14px');
+ $('.content table').css('font','13px/1.2 Verdana');
+ $('.content .heading').css('font','600 16px/1 Arial');
+ $('.content .indexboxcont li').css('font','600 13px/1 Verdana');
+ $('.t_button').removeClass('active')
+ $(this).addClass('active')
+});
+
+$('#bigA').click(function() {
+ $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('font-size','large');
+ $('.content .heading,.content h1, .content h2, .content h3, .content p, .content li, .content table').css('line-height','25px');
+ $('.t_button').removeClass('active')
+ $(this).addClass('active')
+});
+
+function doSearch(str){
+
+if (str.length>3)
+ {
+ alert('start search');
+ // document.getElementById("refWrapper").innerHTML="";
+ return;
+ }
+ else
+ return;
+
+// var url="indexSearch.php";
+// url=url+"?q="+str;
+ // url=url+"&sid="+Math.random();
+ // var url="http://localhost:8983/solr/select?";
+ // url=url+"&q="+str;
+ // url=url+"&fq=&start=0&rows=10&fl=&qt=&wt=&explainOther=&hl.fl=";
+
+ // $.get(url, function(data){
+ // alert(data);
+ // document.getElementById("refWrapper").innerHTML=data;
+ //});
+
+} \ No newline at end of file
diff --git a/tools/qdoc3/test/scripts/jquery.js b/tools/qdoc3/test/scripts/jquery.js
new file mode 100644
index 0000000..0c7294c
--- /dev/null
+++ b/tools/qdoc3/test/scripts/jquery.js
@@ -0,0 +1,152 @@
+/*!
+ * jQuery JavaScript Library v1.4.1
+ * http://jquery.com/
+ *
+ * Copyright 2010, John Resig
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ * http://jquery.org/license
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ * Copyright 2010, The Dojo Foundation
+ * Released under the MIT, BSD, and GPL Licenses.
+ *
+ * Date: Mon Jan 25 19:43:33 2010 -0500
+ */
+(function(z,v){function la(){if(!c.isReady){try{r.documentElement.doScroll("left")}catch(a){setTimeout(la,1);return}c.ready()}}function Ma(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,i){var j=a.length;if(typeof b==="object"){for(var n in b)X(a,n,b[n],f,e,d);return a}if(d!==v){f=!i&&f&&c.isFunction(d);for(n=0;n<j;n++)e(a[n],b,f?d.call(a[n],n,e(a[n],b)):d,i);return a}return j?
+e(a[0],b):null}function J(){return(new Date).getTime()}function Y(){return false}function Z(){return true}function ma(a,b,d){d[0].type=a;return c.event.handle.apply(b,d)}function na(a){var b,d=[],f=[],e=arguments,i,j,n,o,m,s,x=c.extend({},c.data(this,"events").live);if(!(a.button&&a.type==="click")){for(o in x){j=x[o];if(j.live===a.type||j.altLive&&c.inArray(a.type,j.altLive)>-1){i=j.data;i.beforeFilter&&i.beforeFilter[a.type]&&!i.beforeFilter[a.type](a)||f.push(j.selector)}else delete x[o]}i=c(a.target).closest(f,
+a.currentTarget);m=0;for(s=i.length;m<s;m++)for(o in x){j=x[o];n=i[m].elem;f=null;if(i[m].selector===j.selector){if(j.live==="mouseenter"||j.live==="mouseleave")f=c(a.relatedTarget).closest(j.selector)[0];if(!f||f!==n)d.push({elem:n,fn:j})}}m=0;for(s=d.length;m<s;m++){i=d[m];a.currentTarget=i.elem;a.data=i.fn.data;if(i.fn.apply(i.elem,e)===false){b=false;break}}return b}}function oa(a,b){return"live."+(a?a+".":"")+b.replace(/\./g,"`").replace(/ /g,"&")}function pa(a){return!a||!a.parentNode||a.parentNode.nodeType===
+11}function qa(a,b){var d=0;b.each(function(){if(this.nodeName===(a[d]&&a[d].nodeName)){var f=c.data(a[d++]),e=c.data(this,f);if(f=f&&f.events){delete e.handle;e.events={};for(var i in f)for(var j in f[i])c.event.add(this,i,f[i][j],f[i][j].data)}}})}function ra(a,b,d){var f,e,i;if(a.length===1&&typeof a[0]==="string"&&a[0].length<512&&a[0].indexOf("<option")<0&&(c.support.checkClone||!sa.test(a[0]))){e=true;if(i=c.fragments[a[0]])if(i!==1)f=i}if(!f){b=b&&b[0]?b[0].ownerDocument||b[0]:r;f=b.createDocumentFragment();
+c.clean(a,b,f,d)}if(e)c.fragments[a[0]]=i?f:1;return{fragment:f,cacheable:e}}function K(a,b){var d={};c.each(ta.concat.apply([],ta.slice(0,b)),function(){d[this]=a});return d}function ua(a){return"scrollTo"in a&&a.document?a:a.nodeType===9?a.defaultView||a.parentWindow:false}var c=function(a,b){return new c.fn.init(a,b)},Na=z.jQuery,Oa=z.$,r=z.document,S,Pa=/^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,Qa=/^.[^:#\[\.,]*$/,Ra=/\S/,Sa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Ta=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,O=navigator.userAgent,
+va=false,P=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,Q=Array.prototype.slice,wa=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(typeof a==="string")if((d=Pa.exec(a))&&(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:r;if(a=Ta.exec(a))if(c.isPlainObject(b)){a=[r.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=ra([d[1]],
+[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}}else{if(b=r.getElementById(d[2])){if(b.id!==d[2])return S.find(a);this.length=1;this[0]=b}this.context=r;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=r;a=r.getElementsByTagName(a)}else return!b||b.jquery?(b||S).find(a):c(b).find(a);else if(c.isFunction(a))return S.ready(a);if(a.selector!==v){this.selector=a.selector;this.context=a.context}return c.isArray(a)?this.setArray(a):c.makeArray(a,
+this)},selector:"",jquery:"1.4.1",length:0,size:function(){return this.length},toArray:function(){return Q.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){a=c(a||null);a.prevObject=this;a.context=this.context;if(b==="find")a.selector=this.selector+(this.selector?" ":"")+d;else if(b)a.selector=this.selector+"."+b+"("+d+")";return a},setArray:function(a){this.length=0;ba.apply(this,a);return this},each:function(a,b){return c.each(this,
+a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(r,c);else P&&P.push(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(Q.apply(this,arguments),"slice",Q.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this,function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};
+c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,i,j,n;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b<d;b++)if((e=arguments[b])!=null)for(i in e){j=a[i];n=e[i];if(a!==n)if(f&&n&&(c.isPlainObject(n)||c.isArray(n))){j=j&&(c.isPlainObject(j)||c.isArray(j))?j:c.isArray(n)?[]:{};a[i]=c.extend(f,j,n)}else if(n!==v)a[i]=n}return a};c.extend({noConflict:function(a){z.$=
+Oa;if(a)z.jQuery=Na;return c},isReady:false,ready:function(){if(!c.isReady){if(!r.body)return setTimeout(c.ready,13);c.isReady=true;if(P){for(var a,b=0;a=P[b++];)a.call(r,c);P=null}c.fn.triggerHandler&&c(r).triggerHandler("ready")}},bindReady:function(){if(!va){va=true;if(r.readyState==="complete")return c.ready();if(r.addEventListener){r.addEventListener("DOMContentLoaded",L,false);z.addEventListener("load",c.ready,false)}else if(r.attachEvent){r.attachEvent("onreadystatechange",L);z.attachEvent("onload",
+c.ready);var a=false;try{a=z.frameElement==null}catch(b){}r.documentElement.doScroll&&a&&la()}}},isFunction:function(a){return $.call(a)==="[object Function]"},isArray:function(a){return $.call(a)==="[object Array]"},isPlainObject:function(a){if(!a||$.call(a)!=="[object Object]"||a.nodeType||a.setInterval)return false;if(a.constructor&&!aa.call(a,"constructor")&&!aa.call(a.constructor.prototype,"isPrototypeOf"))return false;var b;for(b in a);return b===v||aa.call(a,b)},isEmptyObject:function(a){for(var b in a)return false;
+return true},error:function(a){throw a;},parseJSON:function(a){if(typeof a!=="string"||!a)return null;if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))return z.JSON&&z.JSON.parse?z.JSON.parse(a):(new Function("return "+a))();else c.error("Invalid JSON: "+a)},noop:function(){},globalEval:function(a){if(a&&Ra.test(a)){var b=r.getElementsByTagName("head")[0]||
+r.documentElement,d=r.createElement("script");d.type="text/javascript";if(c.support.scriptEval)d.appendChild(r.createTextNode(a));else d.text=a;b.insertBefore(d,b.firstChild);b.removeChild(d)}},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,b,d){var f,e=0,i=a.length,j=i===v||c.isFunction(a);if(d)if(j)for(f in a){if(b.apply(a[f],d)===false)break}else for(;e<i;){if(b.apply(a[e++],d)===false)break}else if(j)for(f in a){if(b.call(a[f],f,a[f])===false)break}else for(d=
+a[0];e<i&&b.call(d,e,d)!==false;d=a[++e]);return a},trim:function(a){return(a||"").replace(Sa,"")},makeArray:function(a,b){b=b||[];if(a!=null)a.length==null||typeof a==="string"||c.isFunction(a)||typeof a!=="function"&&a.setInterval?ba.call(b,a):c.merge(b,a);return b},inArray:function(a,b){if(b.indexOf)return b.indexOf(a);for(var d=0,f=b.length;d<f;d++)if(b[d]===a)return d;return-1},merge:function(a,b){var d=a.length,f=0;if(typeof b.length==="number")for(var e=b.length;f<e;f++)a[d++]=b[f];else for(;b[f]!==
+v;)a[d++]=b[f++];a.length=d;return a},grep:function(a,b,d){for(var f=[],e=0,i=a.length;e<i;e++)!d!==!b(a[e],e)&&f.push(a[e]);return f},map:function(a,b,d){for(var f=[],e,i=0,j=a.length;i<j;i++){e=b(a[i],i,d);if(e!=null)f[f.length]=e}return f.concat.apply([],f)},guid:1,proxy:function(a,b,d){if(arguments.length===2)if(typeof b==="string"){d=a;a=d[b];b=v}else if(b&&!c.isFunction(b)){d=b;b=v}if(!b&&a)b=function(){return a.apply(d||this,arguments)};if(a)b.guid=a.guid=a.guid||b.guid||c.guid++;return b},
+uaMatch:function(a){a=a.toLowerCase();a=/(webkit)[ \/]([\w.]+)/.exec(a)||/(opera)(?:.*version)?[ \/]([\w.]+)/.exec(a)||/(msie) ([\w.]+)/.exec(a)||!/compatible/.test(a)&&/(mozilla)(?:.*? rv:([\w.]+))?/.exec(a)||[];return{browser:a[1]||"",version:a[2]||"0"}},browser:{}});O=c.uaMatch(O);if(O.browser){c.browser[O.browser]=true;c.browser.version=O.version}if(c.browser.webkit)c.browser.safari=true;if(wa)c.inArray=function(a,b){return wa.call(b,a)};S=c(r);if(r.addEventListener)L=function(){r.removeEventListener("DOMContentLoaded",
+L,false);c.ready()};else if(r.attachEvent)L=function(){if(r.readyState==="complete"){r.detachEvent("onreadystatechange",L);c.ready()}};(function(){c.support={};var a=r.documentElement,b=r.createElement("script"),d=r.createElement("div"),f="script"+J();d.style.display="none";d.innerHTML=" <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";var e=d.getElementsByTagName("*"),i=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!i)){c.support=
+{leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(i.getAttribute("style")),hrefNormalized:i.getAttribute("href")==="/a",opacity:/^0.55$/.test(i.style.opacity),cssFloat:!!i.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:r.createElement("select").appendChild(r.createElement("option")).selected,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};
+b.type="text/javascript";try{b.appendChild(r.createTextNode("window."+f+"=1;"))}catch(j){}a.insertBefore(b,a.firstChild);if(z[f]){c.support.scriptEval=true;delete z[f]}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function n(){c.support.noCloneEvent=false;d.detachEvent("onclick",n)});d.cloneNode(true).fireEvent("onclick")}d=r.createElement("div");d.innerHTML="<input type='radio' name='radiotest' checked='checked'/>";a=r.createDocumentFragment();a.appendChild(d.firstChild);
+c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var n=r.createElement("div");n.style.width=n.style.paddingLeft="1px";r.body.appendChild(n);c.boxModel=c.support.boxModel=n.offsetWidth===2;r.body.removeChild(n).style.display="none"});a=function(n){var o=r.createElement("div");n="on"+n;var m=n in o;if(!m){o.setAttribute(n,"return;");m=typeof o[n]==="function"}return m};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=i=null}})();c.props=
+{"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ua=0,xa={},Va={};c.extend({cache:{},expando:G,noData:{embed:true,object:true,applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var f=a[G],e=c.cache;if(!b&&!f)return null;f||(f=++Ua);if(typeof b==="object"){a[G]=f;e=e[f]=c.extend(true,
+{},b)}else e=e[f]?e[f]:typeof d==="undefined"?Va:(e[f]={});if(d!==v){a[G]=f;e[b]=d}return typeof b==="string"?e[b]:e}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==z?xa:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{try{delete a[G]}catch(i){a.removeAttribute&&a.removeAttribute(G)}delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,
+a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===v){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===v&&this.length)f=c.data(this[0],a);return f===v&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this,a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);
+return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b===v)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||
+a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var ya=/[\n\t]/g,ca=/\s+/,Wa=/\r/g,Xa=/href|src|style/,Ya=/(button|input)/i,Za=/(button|input|object|select|textarea)/i,$a=/^(a|area)$/i,za=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=
+c(this);m.addClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1)if(e.className)for(var i=" "+e.className+" ",j=0,n=b.length;j<n;j++){if(i.indexOf(" "+b[j]+" ")<0)e.className+=" "+b[j]}else e.className=a}return this},removeClass:function(a){if(c.isFunction(a))return this.each(function(o){var m=c(this);m.removeClass(a.call(this,o,m.attr("class")))});if(a&&typeof a==="string"||a===v)for(var b=(a||"").split(ca),
+d=0,f=this.length;d<f;d++){var e=this[d];if(e.nodeType===1&&e.className)if(a){for(var i=(" "+e.className+" ").replace(ya," "),j=0,n=b.length;j<n;j++)i=i.replace(" "+b[j]+" "," ");e.className=i.substring(1,i.length-1)}else e.className=""}return this},toggleClass:function(a,b){var d=typeof a,f=typeof b==="boolean";if(c.isFunction(a))return this.each(function(e){var i=c(this);i.toggleClass(a.call(this,e,i.attr("class"),b),b)});return this.each(function(){if(d==="string")for(var e,i=0,j=c(this),n=b,o=
+a.split(ca);e=o[i++];){n=f?n:!j.hasClass(e);j[n?"addClass":"removeClass"](e)}else if(d==="undefined"||d==="boolean"){this.className&&c.data(this,"__className__",this.className);this.className=this.className||a===false?"":c.data(this,"__className__")||""}})},hasClass:function(a){a=" "+a+" ";for(var b=0,d=this.length;b<d;b++)if((" "+this[b].className+" ").replace(ya," ").indexOf(a)>-1)return true;return false},val:function(a){if(a===v){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||
+{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var i=b?d:0;for(d=b?d+1:e.length;i<d;i++){var j=e[i];if(j.selected){a=c(j).val();if(b)return a;f.push(a)}}return f}if(za.test(b.type)&&!c.support.checkOn)return b.getAttribute("value")===null?"on":b.value;return(b.value||"").replace(Wa,"")}return v}var n=c.isFunction(a);return this.each(function(o){var m=c(this),s=a;if(this.nodeType===1){if(n)s=a.call(this,o,m.val());
+if(typeof s==="number")s+="";if(c.isArray(s)&&za.test(this.type))this.checked=c.inArray(m.val(),s)>=0;else if(c.nodeName(this,"select")){var x=c.makeArray(s);c("option",this).each(function(){this.selected=c.inArray(c(this).val(),x)>=0});if(!x.length)this.selectedIndex=-1}else this.value=s}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return v;if(f&&b in c.attrFn)return c(a)[b](d);
+f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==v;b=f&&c.props[b]||b;if(a.nodeType===1){var i=Xa.test(b);if(b in a&&f&&!i){if(e){b==="type"&&Ya.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed");a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:Za.test(a.nodeName)||$a.test(a.nodeName)&&a.href?0:v;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=
+""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&i?a.getAttribute(b,2):a.getAttribute(b);return a===null?v:a}return c.style(a,b,d)}});var ab=function(a){return a.replace(/[^\w\s\.\|`]/g,function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==z&&!a.frameElement)a=z;if(!d.guid)d.guid=c.guid++;if(f!==v){d=c.proxy(d);d.data=f}var e=c.data(a,"events")||c.data(a,"events",{}),i=c.data(a,"handle"),j;if(!i){j=
+function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(j.elem,arguments):v};i=c.data(a,"handle",j)}if(i){i.elem=a;b=b.split(/\s+/);for(var n,o=0;n=b[o++];){var m=n.split(".");n=m.shift();if(o>1){d=c.proxy(d);if(f!==v)d.data=f}d.type=m.slice(0).sort().join(".");var s=e[n],x=this.special[n]||{};if(!s){s=e[n]={};if(!x.setup||x.setup.call(a,f,m,d)===false)if(a.addEventListener)a.addEventListener(n,i,false);else a.attachEvent&&a.attachEvent("on"+n,i)}if(x.add)if((m=x.add.call(a,
+d,f,m,s))&&c.isFunction(m)){m.guid=m.guid||d.guid;m.data=m.data||d.data;m.type=m.type||d.type;d=m}s[d.guid]=d;this.global[n]=true}a=null}}},global:{},remove:function(a,b,d){if(!(a.nodeType===3||a.nodeType===8)){var f=c.data(a,"events"),e,i,j;if(f){if(b===v||typeof b==="string"&&b.charAt(0)===".")for(i in f)this.remove(a,i+(b||""));else{if(b.type){d=b.handler;b=b.type}b=b.split(/\s+/);for(var n=0;i=b[n++];){var o=i.split(".");i=o.shift();var m=!o.length,s=c.map(o.slice(0).sort(),ab);s=new RegExp("(^|\\.)"+
+s.join("\\.(?:.*\\.)?")+"(\\.|$)");var x=this.special[i]||{};if(f[i]){if(d){j=f[i][d.guid];delete f[i][d.guid]}else for(var A in f[i])if(m||s.test(f[i][A].type))delete f[i][A];x.remove&&x.remove.call(a,o,j);for(e in f[i])break;if(!e){if(!x.teardown||x.teardown.call(a,o)===false)if(a.removeEventListener)a.removeEventListener(i,c.data(a,"handle"),false);else a.detachEvent&&a.detachEvent("on"+i,c.data(a,"handle"));e=null;delete f[i]}}}}for(e in f)break;if(!e){if(A=c.data(a,"handle"))A.elem=null;c.removeData(a,
+"events");c.removeData(a,"handle")}}}},trigger:function(a,b,d,f){var e=a.type||a;if(!f){a=typeof a==="object"?a[G]?a:c.extend(c.Event(e),a):c.Event(e);if(e.indexOf("!")>=0){a.type=e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();this.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return v;a.result=v;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,
+b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(i){}if(!a.isPropagationStopped()&&f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){d=a.target;var j;if(!(c.nodeName(d,"a")&&e==="click")&&!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()])){try{if(d[e]){if(j=d["on"+e])d["on"+e]=null;this.triggered=true;d[e]()}}catch(n){}if(j)d["on"+e]=j;this.triggered=false}}},handle:function(a){var b,
+d;a=arguments[0]=c.event.fix(a||z.event);a.currentTarget=this;d=a.type.split(".");a.type=d.shift();b=!d.length&&!a.exclusive;var f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)");d=(c.data(this,"events")||{})[a.type];for(var e in d){var i=d[e];if(b||f.test(i.type)){a.handler=i;a.data=i.data;i=i.apply(this,arguments);if(i!==v){a.result=i;if(i===false){a.preventDefault();a.stopPropagation()}}if(a.isImmediatePropagationStopped())break}}return a.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
+fix:function(a){if(a[G])return a;var b=a;a=c.Event(b);for(var d=this.props.length,f;d;){f=this.props[--d];a[f]=b[f]}if(!a.target)a.target=a.srcElement||r;if(a.target.nodeType===3)a.target=a.target.parentNode;if(!a.relatedTarget&&a.fromElement)a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;if(a.pageX==null&&a.clientX!=null){b=r.documentElement;d=r.body;a.pageX=a.clientX+(b&&b.scrollLeft||d&&d.scrollLeft||0)-(b&&b.clientLeft||d&&d.clientLeft||0);a.pageY=a.clientY+(b&&b.scrollTop||
+d&&d.scrollTop||0)-(b&&b.clientTop||d&&d.clientTop||0)}if(!a.which&&(a.charCode||a.charCode===0?a.charCode:a.keyCode))a.which=a.charCode||a.keyCode;if(!a.metaKey&&a.ctrlKey)a.metaKey=a.ctrlKey;if(!a.which&&a.button!==v)a.which=a.button&1?1:a.button&2?3:a.button&4?2:0;return a},guid:1E8,proxy:c.proxy,special:{ready:{setup:c.bindReady,teardown:c.noop},live:{add:function(a,b){c.extend(a,b||{});a.guid+=b.selector+b.live;b.liveProxy=a;c.event.add(this,b.live,na,b)},remove:function(a){if(a.length){var b=
+0,d=new RegExp("(^|\\.)"+a[0]+"(\\.|$)");c.each(c.data(this,"events").live||{},function(){d.test(this.type)&&b++});b<1&&c.event.remove(this,a[0],na)}},special:{}},beforeunload:{setup:function(a,b,d){if(this.setInterval)this.onbeforeunload=d;return false},teardown:function(a,b){if(this.onbeforeunload===b)this.onbeforeunload=null}}}};c.Event=function(a){if(!this.preventDefault)return new c.Event(a);if(a&&a.type){this.originalEvent=a;this.type=a.type}else this.type=a;this.timeStamp=J();this[G]=true};
+c.Event.prototype={preventDefault:function(){this.isDefaultPrevented=Z;var a=this.originalEvent;if(a){a.preventDefault&&a.preventDefault();a.returnValue=false}},stopPropagation:function(){this.isPropagationStopped=Z;var a=this.originalEvent;if(a){a.stopPropagation&&a.stopPropagation();a.cancelBubble=true}},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=Z;this.stopPropagation()},isDefaultPrevented:Y,isPropagationStopped:Y,isImmediatePropagationStopped:Y};var Aa=function(a){for(var b=
+a.relatedTarget;b&&b!==this;)try{b=b.parentNode}catch(d){break}if(b!==this){a.type=a.data;c.event.handle.apply(this,arguments)}},Ba=function(a){a.type=a.data;c.event.handle.apply(this,arguments)};c.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){c.event.special[a]={setup:function(d){c.event.add(this,b,d&&d.selector?Ba:Aa,a)},teardown:function(d){c.event.remove(this,b,d&&d.selector?Ba:Aa)}}});if(!c.support.submitBubbles)c.event.special.submit={setup:function(a,b,d){if(this.nodeName.toLowerCase()!==
+"form"){c.event.add(this,"click.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="submit"||i==="image")&&c(e).closest("form").length)return ma("submit",this,arguments)});c.event.add(this,"keypress.specialSubmit."+d.guid,function(f){var e=f.target,i=e.type;if((i==="text"||i==="password")&&c(e).closest("form").length&&f.keyCode===13)return ma("submit",this,arguments)})}else return false},remove:function(a,b){c.event.remove(this,"click.specialSubmit"+(b?"."+b.guid:""));c.event.remove(this,
+"keypress.specialSubmit"+(b?"."+b.guid:""))}};if(!c.support.changeBubbles){var da=/textarea|input|select/i;function Ca(a){var b=a.type,d=a.value;if(b==="radio"||b==="checkbox")d=a.checked;else if(b==="select-multiple")d=a.selectedIndex>-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d}function ea(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Ca(d);if(a.type!=="focusout"||
+d.type!=="radio")c.data(d,"_change_data",e);if(!(f===v||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}}c.event.special.change={filters:{focusout:ea,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return ea.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return ea.call(this,a)},beforeactivate:function(a){a=
+a.target;a.nodeName.toLowerCase()==="input"&&a.type==="radio"&&c.data(a,"_change_data",Ca(a))}},setup:function(a,b,d){for(var f in T)c.event.add(this,f+".specialChange."+d.guid,T[f]);return da.test(this.nodeName)},remove:function(a,b){for(var d in T)c.event.remove(this,d+".specialChange"+(b?"."+b.guid:""),T[d]);return da.test(this.nodeName)}};var T=c.event.special.change.filters}r.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,
+f)}c.event.special[b]={setup:function(){this.addEventListener(a,d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var i in d)this[b](i,f,d[i],e);return this}if(c.isFunction(f)){e=f;f=v}var j=b==="one"?c.proxy(e,function(n){c(this).unbind(n,j);return e.apply(this,arguments)}):e;return d==="unload"&&b!=="one"?this.one(d,f,e):this.each(function(){c.event.add(this,d,j,f)})}});c.fn.extend({unbind:function(a,
+b){if(typeof a==="object"&&!a.preventDefault){for(var d in a)this.unbind(d,a[d]);return this}return this.each(function(){c.event.remove(this,a,b)})},trigger:function(a,b){return this.each(function(){c.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0]){a=c.Event(a);a.preventDefault();a.stopPropagation();c.event.trigger(a,b,this[0]);return a.result}},toggle:function(a){for(var b=arguments,d=1;d<b.length;)c.proxy(a,b[d++]);return this.click(c.proxy(a,function(f){var e=(c.data(this,"lastToggle"+
+a.guid)||0)%d;c.data(this,"lastToggle"+a.guid,e+1);f.preventDefault();return b[e].apply(this,arguments)||false}))},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});c.each(["live","die"],function(a,b){c.fn[b]=function(d,f,e){var i,j=0;if(c.isFunction(f)){e=f;f=v}for(d=(d||"").split(/\s+/);(i=d[j++])!=null;){i=i==="focus"?"focusin":i==="blur"?"focusout":i==="hover"?d.push("mouseleave")&&"mouseenter":i;b==="live"?c(this.context).bind(oa(i,this.selector),{data:f,selector:this.selector,
+live:i},e):c(this.context).unbind(oa(i,this.selector),e?{guid:e.guid+this.selector+i}:null)}return this}});c.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){c.fn[b]=function(d){return d?this.bind(b,d):this.trigger(b)};if(c.attrFn)c.attrFn[b]=true});z.attachEvent&&!z.addEventListener&&z.attachEvent("onunload",function(){for(var a in c.cache)if(c.cache[a].handle)try{c.event.remove(c.cache[a].handle.elem)}catch(b){}});
+(function(){function a(g){for(var h="",k,l=0;g[l];l++){k=g[l];if(k.nodeType===3||k.nodeType===4)h+=k.nodeValue;else if(k.nodeType!==8)h+=a(k.childNodes)}return h}function b(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===k){y=l[t.sizset];break}if(t.nodeType===1&&!p){t.sizcache=k;t.sizset=q}if(t.nodeName.toLowerCase()===h){y=t;break}t=t[g]}l[q]=y}}}function d(g,h,k,l,q,p){q=0;for(var u=l.length;q<u;q++){var t=l[q];if(t){t=t[g];for(var y=false;t;){if(t.sizcache===
+k){y=l[t.sizset];break}if(t.nodeType===1){if(!p){t.sizcache=k;t.sizset=q}if(typeof h!=="string"){if(t===h){y=true;break}}else if(o.filter(h,[t]).length>0){y=t;break}}t=t[g]}l[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,e=0,i=Object.prototype.toString,j=false,n=true;[0,0].sort(function(){n=false;return 0});var o=function(g,h,k,l){k=k||[];var q=h=h||r;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||
+typeof g!=="string")return k;for(var p=[],u,t,y,R,H=true,M=w(h),I=g;(f.exec(""),u=f.exec(I))!==null;){I=u[3];p.push(u[1]);if(u[2]){R=u[3];break}}if(p.length>1&&s.exec(g))if(p.length===2&&m.relative[p[0]])t=fa(p[0]+p[1],h);else for(t=m.relative[p[0]]?[h]:o(p.shift(),h);p.length;){g=p.shift();if(m.relative[g])g+=p.shift();t=fa(g,t)}else{if(!l&&p.length>1&&h.nodeType===9&&!M&&m.match.ID.test(p[0])&&!m.match.ID.test(p[p.length-1])){u=o.find(p.shift(),h,M);h=u.expr?o.filter(u.expr,u.set)[0]:u.set[0]}if(h){u=
+l?{expr:p.pop(),set:A(l)}:o.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=u.expr?o.filter(u.expr,u.set):u.set;if(p.length>0)y=A(t);else H=false;for(;p.length;){var D=p.pop();u=D;if(m.relative[D])u=p.pop();else D="";if(u==null)u=h;m.relative[D](y,u,M)}}else y=[]}y||(y=t);y||o.error(D||g);if(i.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))k.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&
+y[g].nodeType===1&&k.push(t[g]);else k.push.apply(k,y);else A(y,k);if(R){o(R,q,k,l);o.uniqueSort(k)}return k};o.uniqueSort=function(g){if(C){j=n;g.sort(C);if(j)for(var h=1;h<g.length;h++)g[h]===g[h-1]&&g.splice(h--,1)}return g};o.matches=function(g,h){return o(g,null,null,h)};o.find=function(g,h,k){var l,q;if(!g)return[];for(var p=0,u=m.order.length;p<u;p++){var t=m.order[p];if(q=m.leftMatch[t].exec(g)){var y=q[1];q.splice(1,1);if(y.substr(y.length-1)!=="\\"){q[1]=(q[1]||"").replace(/\\/g,"");l=m.find[t](q,
+h,k);if(l!=null){g=g.replace(m.match[t],"");break}}}}l||(l=h.getElementsByTagName("*"));return{set:l,expr:g}};o.filter=function(g,h,k,l){for(var q=g,p=[],u=h,t,y,R=h&&h[0]&&w(h[0]);g&&h.length;){for(var H in m.filter)if((t=m.leftMatch[H].exec(g))!=null&&t[2]){var M=m.filter[H],I,D;D=t[1];y=false;t.splice(1,1);if(D.substr(D.length-1)!=="\\"){if(u===p)p=[];if(m.preFilter[H])if(t=m.preFilter[H](t,u,k,p,l,R)){if(t===true)continue}else y=I=true;if(t)for(var U=0;(D=u[U])!=null;U++)if(D){I=M(D,t,U,u);var Da=
+l^!!I;if(k&&I!=null)if(Da)y=true;else u[U]=false;else if(Da){p.push(D);y=true}}if(I!==v){k||(u=p);g=g.replace(m.match[H],"");if(!y)return[];break}}}if(g===q)if(y==null)o.error(g);else break;q=g}return u};o.error=function(g){throw"Syntax error, unrecognized expression: "+g;};var m=o.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
+TAG:/^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(g){return g.getAttribute("href")}},relative:{"+":function(g,h){var k=typeof h==="string",l=k&&!/\W/.test(h);k=k&&!l;if(l)h=h.toLowerCase();l=0;for(var q=g.length,
+p;l<q;l++)if(p=g[l]){for(;(p=p.previousSibling)&&p.nodeType!==1;);g[l]=k||p&&p.nodeName.toLowerCase()===h?p||false:p===h}k&&o.filter(h,g,true)},">":function(g,h){var k=typeof h==="string";if(k&&!/\W/.test(h)){h=h.toLowerCase();for(var l=0,q=g.length;l<q;l++){var p=g[l];if(p){k=p.parentNode;g[l]=k.nodeName.toLowerCase()===h?k:false}}}else{l=0;for(q=g.length;l<q;l++)if(p=g[l])g[l]=k?p.parentNode:p.parentNode===h;k&&o.filter(h,g,true)}},"":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=
+h=h.toLowerCase();q=b}q("parentNode",h,l,g,p,k)},"~":function(g,h,k){var l=e++,q=d;if(typeof h==="string"&&!/\W/.test(h)){var p=h=h.toLowerCase();q=b}q("previousSibling",h,l,g,p,k)}},find:{ID:function(g,h,k){if(typeof h.getElementById!=="undefined"&&!k)return(g=h.getElementById(g[1]))?[g]:[]},NAME:function(g,h){if(typeof h.getElementsByName!=="undefined"){var k=[];h=h.getElementsByName(g[1]);for(var l=0,q=h.length;l<q;l++)h[l].getAttribute("name")===g[1]&&k.push(h[l]);return k.length===0?null:k}},
+TAG:function(g,h){return h.getElementsByTagName(g[1])}},preFilter:{CLASS:function(g,h,k,l,q,p){g=" "+g[1].replace(/\\/g,"")+" ";if(p)return g;p=0;for(var u;(u=h[p])!=null;p++)if(u)if(q^(u.className&&(" "+u.className+" ").replace(/[\t\n]/g," ").indexOf(g)>=0))k||l.push(u);else if(k)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()},CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&
+"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,k,l,q,p){h=g[1].replace(/\\/g,"");if(!p&&m.attrMap[h])g[1]=m.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,k,l,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=o(g[3],null,null,h);else{g=o.filter(g[3],h,k,true^q);k||l.push.apply(l,g);return false}else if(m.match.POS.test(g[0])||m.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);
+return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,k){return!!o(k[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)},text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===
+g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}},setFilters:{first:function(g,h){return h===0},last:function(g,h,k,l){return h===l.length-1},even:function(g,h){return h%2===
+0},odd:function(g,h){return h%2===1},lt:function(g,h,k){return h<k[3]-0},gt:function(g,h,k){return h>k[3]-0},nth:function(g,h,k){return k[3]-0===h},eq:function(g,h,k){return k[3]-0===h}},filter:{PSEUDO:function(g,h,k,l){var q=h[1],p=m.filters[q];if(p)return p(g,k,h,l);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h=h[3];k=0;for(l=h.length;k<l;k++)if(h[k]===g)return false;return true}else o.error("Syntax error, unrecognized expression: "+
+q)},CHILD:function(g,h){var k=h[1],l=g;switch(k){case "only":case "first":for(;l=l.previousSibling;)if(l.nodeType===1)return false;if(k==="first")return true;l=g;case "last":for(;l=l.nextSibling;)if(l.nodeType===1)return false;return true;case "nth":k=h[2];var q=h[3];if(k===1&&q===0)return true;h=h[0];var p=g.parentNode;if(p&&(p.sizcache!==h||!g.nodeIndex)){var u=0;for(l=p.firstChild;l;l=l.nextSibling)if(l.nodeType===1)l.nodeIndex=++u;p.sizcache=h}g=g.nodeIndex-q;return k===0?g===0:g%k===0&&g/k>=
+0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var k=h[1];g=m.attrHandle[k]?m.attrHandle[k](g):g[k]!=null?g[k]:g.getAttribute(k);k=g+"";var l=h[2];h=h[4];return g==null?l==="!=":l==="="?k===h:l==="*="?k.indexOf(h)>=0:l==="~="?(" "+k+" ").indexOf(h)>=0:!h?k&&g!==false:l==="!="?k!==h:l==="^="?
+k.indexOf(h)===0:l==="$="?k.substr(k.length-h.length)===h:l==="|="?k===h||k.substr(0,h.length+1)===h+"-":false},POS:function(g,h,k,l){var q=m.setFilters[h[2]];if(q)return q(g,k,h,l)}}},s=m.match.POS;for(var x in m.match){m.match[x]=new RegExp(m.match[x].source+/(?![^\[]*\])(?![^\(]*\))/.source);m.leftMatch[x]=new RegExp(/(^(?:.|\r|\n)*?)/.source+m.match[x].source.replace(/\\(\d+)/g,function(g,h){return"\\"+(h-0+1)}))}var A=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};
+try{Array.prototype.slice.call(r.documentElement.childNodes,0)}catch(B){A=function(g,h){h=h||[];if(i.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var k=0,l=g.length;k<l;k++)h.push(g[k]);else for(k=0;g[k];k++)h.push(g[k]);return h}}var C;if(r.documentElement.compareDocumentPosition)C=function(g,h){if(!g.compareDocumentPosition||!h.compareDocumentPosition){if(g==h)j=true;return g.compareDocumentPosition?-1:1}g=g.compareDocumentPosition(h)&4?-1:g===
+h?0:1;if(g===0)j=true;return g};else if("sourceIndex"in r.documentElement)C=function(g,h){if(!g.sourceIndex||!h.sourceIndex){if(g==h)j=true;return g.sourceIndex?-1:1}g=g.sourceIndex-h.sourceIndex;if(g===0)j=true;return g};else if(r.createRange)C=function(g,h){if(!g.ownerDocument||!h.ownerDocument){if(g==h)j=true;return g.ownerDocument?-1:1}var k=g.ownerDocument.createRange(),l=h.ownerDocument.createRange();k.setStart(g,0);k.setEnd(g,0);l.setStart(h,0);l.setEnd(h,0);g=k.compareBoundaryPoints(Range.START_TO_END,
+l);if(g===0)j=true;return g};(function(){var g=r.createElement("div"),h="script"+(new Date).getTime();g.innerHTML="<a name='"+h+"'/>";var k=r.documentElement;k.insertBefore(g,k.firstChild);if(r.getElementById(h)){m.find.ID=function(l,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(l[1]))?q.id===l[1]||typeof q.getAttributeNode!=="undefined"&&q.getAttributeNode("id").nodeValue===l[1]?[q]:v:[]};m.filter.ID=function(l,q){var p=typeof l.getAttributeNode!=="undefined"&&l.getAttributeNode("id");
+return l.nodeType===1&&p&&p.nodeValue===q}}k.removeChild(g);k=g=null})();(function(){var g=r.createElement("div");g.appendChild(r.createComment(""));if(g.getElementsByTagName("*").length>0)m.find.TAG=function(h,k){k=k.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var l=0;k[l];l++)k[l].nodeType===1&&h.push(k[l]);k=h}return k};g.innerHTML="<a href='#'></a>";if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")m.attrHandle.href=function(h){return h.getAttribute("href",
+2)};g=null})();r.querySelectorAll&&function(){var g=o,h=r.createElement("div");h.innerHTML="<p class='TEST'></p>";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){o=function(l,q,p,u){q=q||r;if(!u&&q.nodeType===9&&!w(q))try{return A(q.querySelectorAll(l),p)}catch(t){}return g(l,q,p,u)};for(var k in g)o[k]=g[k];h=null}}();(function(){var g=r.createElement("div");g.innerHTML="<div class='test e'></div><div class='test'></div>";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===
+0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){m.order.splice(1,0,"CLASS");m.find.CLASS=function(h,k,l){if(typeof k.getElementsByClassName!=="undefined"&&!l)return k.getElementsByClassName(h[1])};g=null}}})();var E=r.compareDocumentPosition?function(g,h){return g.compareDocumentPosition(h)&16}:function(g,h){return g!==h&&(g.contains?g.contains(h):true)},w=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},fa=function(g,h){var k=[],
+l="",q;for(h=h.nodeType?[h]:h;q=m.match.PSEUDO.exec(g);){l+=q[0];g=g.replace(m.match.PSEUDO,"")}g=m.relative[g]?g+"*":g;q=0;for(var p=h.length;q<p;q++)o(g,h[q],k);return o.filter(l,k)};c.find=o;c.expr=o.selectors;c.expr[":"]=c.expr.filters;c.unique=o.uniqueSort;c.getText=a;c.isXMLDoc=w;c.contains=E})();var bb=/Until$/,cb=/^(?:parents|prevUntil|prevAll)/,db=/,/;Q=Array.prototype.slice;var Ea=function(a,b,d){if(c.isFunction(b))return c.grep(a,function(e,i){return!!b.call(e,i,e)===d});else if(b.nodeType)return c.grep(a,
+function(e){return e===b===d});else if(typeof b==="string"){var f=c.grep(a,function(e){return e.nodeType===1});if(Qa.test(b))return c.filter(b,f,!d);else b=c.filter(b,f)}return c.grep(a,function(e){return c.inArray(e,b)>=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f<e;f++){d=b.length;c.find(a,this[f],b);if(f>0)for(var i=d;i<b.length;i++)for(var j=0;j<d;j++)if(b[j]===b[i]){b.splice(i--,1);break}}return b},has:function(a){var b=c(a);return this.filter(function(){for(var d=
+0,f=b.length;d<f;d++)if(c.contains(this,b[d]))return true})},not:function(a){return this.pushStack(Ea(this,a,false),"not",a)},filter:function(a){return this.pushStack(Ea(this,a,true),"filter",a)},is:function(a){return!!a&&c.filter(a,this).length>0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,i={},j;if(f&&a.length){e=0;for(var n=a.length;e<n;e++){j=a[e];i[j]||(i[j]=c.expr.match.POS.test(j)?c(j,b||this.context):j)}for(;f&&f.ownerDocument&&f!==b;){for(j in i){e=i[j];if(e.jquery?e.index(f)>
+-1:c(f).is(e)){d.push({selector:j,elem:f});delete i[j]}}f=f.parentNode}}return d}var o=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(m,s){for(;s&&s.ownerDocument&&s!==b;){if(o?o.index(s)>-1:c(s).is(a))return s;s=s.parentNode}return null})},index:function(a){if(!a||typeof a==="string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),
+a);return this.pushStack(pa(a[0])||pa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode",d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},
+nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);bb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):
+e;if((this.length>1||db.test(f))&&cb.test(a))e=e.reverse();return this.pushStack(e,a,Q.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===v||a.nodeType!==1||!c(a).is(d));){a.nodeType===1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==
+b&&d.push(a);return d}});var Fa=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ga=/(<([\w:]+)[^>]*?)\/>/g,eb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,Ha=/<([\w:]+)/,fb=/<tbody/i,gb=/<|&\w+;/,sa=/checked\s*(?:[^=]|=\s*.checked.)/i,Ia=function(a,b,d){return eb.test(d)?a:b+"></"+d+">"},F={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],
+col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div<div>","</div>"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d=c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==v)return this.empty().append((this[0]&&this[0].ownerDocument||r).createTextNode(a));return c.getText(this)},
+wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this},wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?
+d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,
+false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&
+!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Fa,"").replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){qa(this,b);qa(this.find("*"),b.find("*"))}return b},html:function(a){if(a===v)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Fa,""):null;else if(typeof a==="string"&&!/<script/i.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(Ha.exec(a)||
+["",""])[1].toLowerCase()]){a=a.replace(Ga,Ia);try{for(var b=0,d=this.length;b<d;b++)if(this[b].nodeType===1){c.cleanData(this[b].getElementsByTagName("*"));this[b].innerHTML=a}}catch(f){this.empty().append(a)}}else c.isFunction(a)?this.each(function(e){var i=c(this),j=i.html();i.empty().append(function(){return a.call(this,e,j)})}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(c.isFunction(a))return this.each(function(b){var d=c(this),f=d.html();d.replaceWith(a.call(this,
+b,f))});else a=c(a).detach();return this.each(function(){var b=this.nextSibling,d=this.parentNode;c(this).remove();b?c(b).before(a):c(d).append(a)})}else return this.pushStack(c(c.isFunction(a)?a():a),"replaceWith",a)},detach:function(a){return this.remove(a,true)},domManip:function(a,b,d){function f(s){return c.nodeName(s,"table")?s.getElementsByTagName("tbody")[0]||s.appendChild(s.ownerDocument.createElement("tbody")):s}var e,i,j=a[0],n=[];if(!c.support.checkClone&&arguments.length===3&&typeof j===
+"string"&&sa.test(j))return this.each(function(){c(this).domManip(a,b,d,true)});if(c.isFunction(j))return this.each(function(s){var x=c(this);a[0]=j.call(this,s,b?x.html():v);x.domManip(a,b,d)});if(this[0]){e=a[0]&&a[0].parentNode&&a[0].parentNode.nodeType===11?{fragment:a[0].parentNode}:ra(a,this,n);if(i=e.fragment.firstChild){b=b&&c.nodeName(i,"tr");for(var o=0,m=this.length;o<m;o++)d.call(b?f(this[o],i):this[o],e.cacheable||this.length>1||o>0?e.fragment.cloneNode(true):e.fragment)}n&&c.each(n,
+Ma)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);for(var e=0,i=d.length;e<i;e++){var j=(e>0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),j);f=f.concat(j)}return this.pushStack(f,a,d.selector)}});c.each({remove:function(a,b){if(!a||c.filter(a,[this]).length){if(!b&&this.nodeType===1){c.cleanData(this.getElementsByTagName("*"));c.cleanData([this])}this.parentNode&&
+this.parentNode.removeChild(this)}},empty:function(){for(this.nodeType===1&&c.cleanData(this.getElementsByTagName("*"));this.firstChild;)this.removeChild(this.firstChild)}},function(a,b){c.fn[a]=function(){return this.each(b,arguments)}});c.extend({clean:function(a,b,d,f){b=b||r;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||r;var e=[];c.each(a,function(i,j){if(typeof j==="number")j+="";if(j){if(typeof j==="string"&&!gb.test(j))j=b.createTextNode(j);else if(typeof j===
+"string"){j=j.replace(Ga,Ia);var n=(Ha.exec(j)||["",""])[1].toLowerCase(),o=F[n]||F._default,m=o[0];i=b.createElement("div");for(i.innerHTML=o[1]+j+o[2];m--;)i=i.lastChild;if(!c.support.tbody){m=fb.test(j);n=n==="table"&&!m?i.firstChild&&i.firstChild.childNodes:o[1]==="<table>"&&!m?i.childNodes:[];for(o=n.length-1;o>=0;--o)c.nodeName(n[o],"tbody")&&!n[o].childNodes.length&&n[o].parentNode.removeChild(n[o])}!c.support.leadingWhitespace&&V.test(j)&&i.insertBefore(b.createTextNode(V.exec(j)[0]),i.firstChild);
+j=c.makeArray(i.childNodes)}if(j.nodeType)e.push(j);else e=c.merge(e,j)}});if(d)for(a=0;e[a];a++)if(f&&c.nodeName(e[a],"script")&&(!e[a].type||e[a].type.toLowerCase()==="text/javascript"))f.push(e[a].parentNode?e[a].parentNode.removeChild(e[a]):e[a]);else{e[a].nodeType===1&&e.splice.apply(e,[a+1,0].concat(c.makeArray(e[a].getElementsByTagName("script"))));d.appendChild(e[a])}return e},cleanData:function(a){for(var b=0,d;(d=a[b])!=null;b++){c.event.remove(d);c.removeData(d)}}});var hb=/z-?index|font-?weight|opacity|zoom|line-?height/i,
+Ja=/alpha\([^)]*\)/,Ka=/opacity=([^)]*)/,ga=/float/i,ha=/-([a-z])/ig,ib=/([A-Z])/g,jb=/^-?\d+(?:px)?$/i,kb=/^-?\d/,lb={position:"absolute",visibility:"hidden",display:"block"},mb=["Left","Right"],nb=["Top","Bottom"],ob=r.defaultView&&r.defaultView.getComputedStyle,La=c.support.cssFloat?"cssFloat":"styleFloat",ia=function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===v)return c.curCSS(d,f);if(typeof e==="number"&&!hb.test(f))e+="px";c.style(d,f,e)})};
+c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return v;if((b==="width"||b==="height")&&parseFloat(d)<0)d=v;var f=a.style||a,e=d!==v;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter=Ja.test(a)?a.replace(Ja,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Ka.exec(f.filter)[1])/100+"":""}if(ga.test(b))b=La;b=b.replace(ha,ia);if(e)f[b]=d;return f[b]},css:function(a,
+b,d,f){if(b==="width"||b==="height"){var e,i=b==="width"?mb:nb;function j(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(i,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a,"border"+this+"Width",true))||0})}a.offsetWidth!==0?j():c.swap(a,lb,j);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&
+a.currentStyle){f=Ka.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ga.test(b))b=La;if(!d&&e&&e[b])f=e[b];else if(ob){if(ga.test(b))b="float";b=b.replace(ib,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f=a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ha,ia);f=a.currentStyle[b]||a.currentStyle[d];if(!jb.test(f)&&kb.test(f)){b=e.left;var i=a.runtimeStyle.left;a.runtimeStyle.left=
+a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=i}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b=a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var pb=
+J(),qb=/<script(.|\s)*?\/script>/gi,rb=/select|textarea/i,sb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ja=/\?/,tb=/(\?|&)_=.*?(&|$)/,ub=/^(\w+:)?\/\/([^\/?#]+)/,vb=/%20/g;c.fn.extend({_load:c.fn.load,load:function(a,b,d){if(typeof a!=="string")return this._load(a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=
+c.param(b,c.ajaxSettings.traditional);f="POST"}var i=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(j,n){if(n==="success"||n==="notmodified")i.html(e?c("<div />").append(j.responseText.replace(qb,"")).find(e):j.responseText);d&&i.each(d,[j.responseText,n,j])}});return this},serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&
+(this.checked||rb.test(this.nodeName)||sb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,
+b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:z.XMLHttpRequest&&(z.location.protocol!=="file:"||!z.ActiveXObject)?function(){return new z.XMLHttpRequest}:
+function(){try{return new z.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&&e.success.call(o,n,j,w);e.global&&f("ajaxSuccess",[w,e])}function d(){e.complete&&e.complete.call(o,w,j);e.global&&f("ajaxComplete",[w,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}
+function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),i,j,n,o=a&&a.context||e,m=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(m==="GET")N.test(e.url)||(e.url+=(ja.test(e.url)?"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||
+N.test(e.url))){i=e.jsonpCallback||"jsonp"+pb++;if(e.data)e.data=(e.data+"").replace(N,"="+i+"$1");e.url=e.url.replace(N,"="+i+"$1");e.dataType="script";z[i]=z[i]||function(q){n=q;b();d();z[i]=v;try{delete z[i]}catch(p){}A&&A.removeChild(B)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache===false&&m==="GET"){var s=J(),x=e.url.replace(tb,"$1_="+s+"$2");e.url=x+(x===e.url?(ja.test(e.url)?"&":"?")+"_="+s:"")}if(e.data&&m==="GET")e.url+=(ja.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&
+c.event.trigger("ajaxStart");s=(s=ub.exec(e.url))&&(s[1]&&s[1]!==location.protocol||s[2]!==location.host);if(e.dataType==="script"&&m==="GET"&&s){var A=r.getElementsByTagName("head")[0]||r.documentElement,B=r.createElement("script");B.src=e.url;if(e.scriptCharset)B.charset=e.scriptCharset;if(!i){var C=false;B.onload=B.onreadystatechange=function(){if(!C&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){C=true;b();d();B.onload=B.onreadystatechange=null;A&&B.parentNode&&
+A.removeChild(B)}}}A.insertBefore(B,A.firstChild);return v}var E=false,w=e.xhr();if(w){e.username?w.open(m,e.url,e.async,e.username,e.password):w.open(m,e.url,e.async);try{if(e.data||a&&a.contentType)w.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&w.setRequestHeader("If-Modified-Since",c.lastModified[e.url]);c.etag[e.url]&&w.setRequestHeader("If-None-Match",c.etag[e.url])}s||w.setRequestHeader("X-Requested-With","XMLHttpRequest");w.setRequestHeader("Accept",
+e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(fa){}if(e.beforeSend&&e.beforeSend.call(o,w,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");w.abort();return false}e.global&&f("ajaxSend",[w,e]);var g=w.onreadystatechange=function(q){if(!w||w.readyState===0||q==="abort"){E||d();E=true;if(w)w.onreadystatechange=c.noop}else if(!E&&w&&(w.readyState===4||q==="timeout")){E=true;w.onreadystatechange=c.noop;j=q==="timeout"?"timeout":!c.httpSuccess(w)?
+"error":e.ifModified&&c.httpNotModified(w,e.url)?"notmodified":"success";var p;if(j==="success")try{n=c.httpData(w,e.dataType,e)}catch(u){j="parsererror";p=u}if(j==="success"||j==="notmodified")i||b();else c.handleError(e,w,j,p);d();q==="timeout"&&w.abort();if(e.async)w=null}};try{var h=w.abort;w.abort=function(){w&&h.call(w);g("abort")}}catch(k){}e.async&&e.timeout>0&&setTimeout(function(){w&&!E&&g("timeout")},e.timeout);try{w.send(m==="POST"||m==="PUT"||m==="DELETE"?e.data:null)}catch(l){c.handleError(e,
+w,null,l);d()}e.async||g();return w}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status===1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=
+f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b==="json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(j,n){if(c.isArray(n))c.each(n,
+function(o,m){b?f(j,m):d(j+"["+(typeof m==="object"||c.isArray(m)?o:"")+"]",m)});else!b&&n!=null&&typeof n==="object"?c.each(n,function(o,m){d(j+"["+o+"]",m)}):f(j,n)}function f(j,n){n=c.isFunction(n)?n():n;e[e.length]=encodeURIComponent(j)+"="+encodeURIComponent(n)}var e=[];if(b===v)b=c.ajaxSettings.traditional;if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var i in a)d(i,a[i]);return e.join("&").replace(vb,"+")}});var ka={},wb=/toggle|show|hide/,xb=/^([+-]=)?([\d+-.]+)(.*)$/,
+W,ta=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");this[a].style.display=d||"";if(c.css(this[a],"display")==="none"){d=this[a].nodeName;var f;if(ka[d])f=ka[d];else{var e=c("<"+d+" />").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();
+ka[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a<b;a++)this[a].style.display=c.data(this[a],"olddisplay")||"";return this}},hide:function(a,b){if(a||a===0)return this.animate(K("hide",3),a,b);else{a=0;for(b=this.length;a<b;a++){var d=c.data(this[a],"olddisplay");!d&&d!=="none"&&c.data(this[a],"olddisplay",c.css(this[a],"display"))}a=0;for(b=this.length;a<b;a++)this[a].style.display="none";return this}},_toggle:c.fn.toggle,toggle:function(a,b){var d=typeof a==="boolean";if(c.isFunction(a)&&
+c.isFunction(b))this._toggle.apply(this,arguments);else a==null||d?this.each(function(){var f=d?a:c(this).is(":hidden");c(this)[f?"show":"hide"]()}):this.animate(K("toggle",3),a,b);return this},fadeTo:function(a,b,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,d)},animate:function(a,b,d,f){var e=c.speed(b,d,f);if(c.isEmptyObject(a))return this.each(e.complete);return this[e.queue===false?"each":"queue"](function(){var i=c.extend({},e),j,n=this.nodeType===1&&c(this).is(":hidden"),
+o=this;for(j in a){var m=j.replace(ha,ia);if(j!==m){a[m]=a[j];delete a[j];j=m}if(a[j]==="hide"&&n||a[j]==="show"&&!n)return i.complete.call(this);if((j==="height"||j==="width")&&this.style){i.display=c.css(this,"display");i.overflow=this.style.overflow}if(c.isArray(a[j])){(i.specialEasing=i.specialEasing||{})[j]=a[j][1];a[j]=a[j][0]}}if(i.overflow!=null)this.style.overflow="hidden";i.curAnim=c.extend({},a);c.each(a,function(s,x){var A=new c.fx(o,i,s);if(wb.test(x))A[x==="toggle"?n?"show":"hide":x](a);
+else{var B=xb.exec(x),C=A.cur(true)||0;if(B){x=parseFloat(B[2]);var E=B[3]||"px";if(E!=="px"){o.style[s]=(x||1)+E;C=(x||1)/A.cur(true)*C;o.style[s]=C+E}if(B[1])x=(B[1]==="-="?-1:1)*x+C;A.custom(C,x,E)}else A.custom(C,x,"")}});return true})},stop:function(a,b){var d=c.timers;a&&this.queue([]);this.each(function(){for(var f=d.length-1;f>=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",
+1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration==="number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,
+b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]||c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==
+null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(i){return e.step(i)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start;this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop===
+"width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=
+this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem,e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=
+c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b<a.length;b++)a[b]()||a.splice(b--,1);a.length||c.fx.stop()},stop:function(){clearInterval(W);W=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){c.style(a.elem,"opacity",a.now)},_default:function(a){if(a.elem.style&&a.elem.style[a.prop]!=
+null)a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit;else a.elem[a.prop]=a.now}}});if(c.expr&&c.expr.filters)c.expr.filters.animated=function(a){return c.grep(c.timers,function(b){return a===b.elem}).length};c.fn.offset="getBoundingClientRect"in r.documentElement?function(a){var b=this[0];if(a)return this.each(function(e){c.offset.setOffset(this,a,e)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);var d=b.getBoundingClientRect(),
+f=b.ownerDocument;b=f.body;f=f.documentElement;return{top:d.top+(self.pageYOffset||c.support.boxModel&&f.scrollTop||b.scrollTop)-(f.clientTop||b.clientTop||0),left:d.left+(self.pageXOffset||c.support.boxModel&&f.scrollLeft||b.scrollLeft)-(f.clientLeft||b.clientLeft||0)}}:function(a){var b=this[0];if(a)return this.each(function(s){c.offset.setOffset(this,a,s)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return c.offset.bodyOffset(b);c.offset.initialize();var d=b.offsetParent,f=
+b,e=b.ownerDocument,i,j=e.documentElement,n=e.body;f=(e=e.defaultView)?e.getComputedStyle(b,null):b.currentStyle;for(var o=b.offsetTop,m=b.offsetLeft;(b=b.parentNode)&&b!==n&&b!==j;){if(c.offset.supportsFixedPosition&&f.position==="fixed")break;i=e?e.getComputedStyle(b,null):b.currentStyle;o-=b.scrollTop;m-=b.scrollLeft;if(b===d){o+=b.offsetTop;m+=b.offsetLeft;if(c.offset.doesNotAddBorder&&!(c.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(b.nodeName))){o+=parseFloat(i.borderTopWidth)||
+0;m+=parseFloat(i.borderLeftWidth)||0}f=d;d=b.offsetParent}if(c.offset.subtractsBorderForOverflowNotVisible&&i.overflow!=="visible"){o+=parseFloat(i.borderTopWidth)||0;m+=parseFloat(i.borderLeftWidth)||0}f=i}if(f.position==="relative"||f.position==="static"){o+=n.offsetTop;m+=n.offsetLeft}if(c.offset.supportsFixedPosition&&f.position==="fixed"){o+=Math.max(j.scrollTop,n.scrollTop);m+=Math.max(j.scrollLeft,n.scrollLeft)}return{top:o,left:m}};c.offset={initialize:function(){var a=r.body,b=r.createElement("div"),
+d,f,e,i=parseFloat(c.curCSS(a,"marginTop",true))||0;c.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"});b.innerHTML="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";a.insertBefore(b,a.firstChild);
+d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i;a.removeChild(b);c.offset.initialize=c.noop},
+bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),i=parseInt(c.curCSS(a,"top",true),10)||0,j=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a,d,e);d={top:b.top-e.top+i,left:b.left-
+e.left+j};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top-f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=
+this.offsetParent||r.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],i;if(!e)return null;if(f!==v)return this.each(function(){if(i=ua(this))i.scrollTo(!a?f:c(i).scrollLeft(),a?f:c(i).scrollTop());else this[d]=f});else return(i=ua(e))?"pageXOffset"in i?i[a?"pageYOffset":"pageXOffset"]:c.support.boxModel&&i.document.documentElement[d]||i.document.body[d]:e[d]}});
+c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(i){var j=c(this);j[d](f.call(this,i,j[d]()))});return"scrollTo"in e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||
+e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===v?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});z.jQuery=z.$=c})(window);
diff --git a/tools/qdoc3/test/style/style.css b/tools/qdoc3/test/style/style.css
new file mode 100644
index 0000000..dff0772
--- /dev/null
+++ b/tools/qdoc3/test/style/style.css
@@ -0,0 +1,1051 @@
+@media screen
+{
+ html
+ {
+ color: #000000;
+ background: #FFFFFF;
+ }
+ body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, button, textarea, p, blockquote, th, td
+ {
+ margin: 0;
+ padding: 0;
+ }
+ table
+ {
+ border-collapse: collapse;
+ border-spacing: 0;
+ }
+ fieldset, img
+ {
+ border: 0;
+ }
+ address, caption, cite, code, dfn, em, strong, th, var, optgroup
+ {
+ font-style: inherit;
+ font-weight: inherit;
+ }
+ del, ins
+ {
+ text-decoration: none;
+ }
+ li
+ {
+ list-style: none;
+ }
+ caption, th
+ {
+ text-align: left;
+ }
+ h1, h2, h3, h4, h5, h6
+ {
+ font-size: 100%;
+ font-weight: normal;
+ }
+ q:before, q:after
+ {
+ content: '';
+ }
+ abbr, acronym
+ {
+ border: 0;
+ font-variant: normal;
+ }
+ sup
+ {
+ vertical-align: baseline;
+ }
+ sub
+ {
+ vertical-align: baseline;
+ }
+ .heading
+ {
+ font: normal 600 16px/1.0 Arial;
+ padding-bottom: 15px;
+ }
+ .subtitle
+ {
+ font-size: 13px;
+ }
+ .small-subtitle
+ {
+ font-size: 13px;
+ }
+ legend
+ {
+ color: #000000;
+ }
+ input, button, textarea, select, optgroup, option
+ {
+ font-family: inherit;
+ font-size: inherit;
+ font-style: inherit;
+ font-weight: inherit;
+ }
+ input, button, textarea, select
+ {
+ font-size: 100%;
+ }
+ html
+ {
+ background-color: #e5e5e5;
+ }
+ body
+ {
+ background: #e6e7e8 url(../images/page_bg.png) repeat-x 0 0;
+ font: normal 13px/1.2 Verdana;
+ color: #363534;
+ }
+ strong
+ {
+ font-weight: bold;
+ }
+ em
+ {
+ font-style: italic;
+ }
+ a
+ {
+ color: #00732f;
+ text-decoration: none;
+ }
+ .header, .footer, .wrapper
+ {
+ min-width: 600px;
+ max-width: 1500px;
+ margin: 0 30px;
+ }
+ .wrapper
+ {
+ background: url(../images/bg_r.png) repeat-y 100% 0;
+ }
+ .wrapper .hd
+ {
+ padding-left: 216px;
+ height: 15px;
+ background: url(../images/page.png) no-repeat 0 0;
+ overflow: hidden;
+ }
+ .offline .wrapper .hd
+ {
+ background: url(../images/page.png) no-repeat 0 -15px;
+ }
+ .wrapper .hd span
+ {
+ height: 15px;
+ display: block;
+ overflow: hidden;
+ background: url(../images/page.png) no-repeat 100% -30px;
+ }
+ .wrapper .bd
+ {
+ background: url(../images/bg_l.png) repeat-y 0 0;
+ position: relative;
+ }
+ .offline .wrapper .bd
+ {
+ background: url(../images/bg_l_blank.png) repeat-y 0 0;
+ }
+ .wrapper .ft
+ {
+ padding-left: 216px;
+ height: 15px;
+ background: url(../images/page.png) no-repeat 0 -75px;
+ overflow: hidden;
+ }
+ .offline .wrapper .ft
+ {
+ background: url(../images/page.png) no-repeat 0 -90px;
+ }
+ .wrapper .ft span
+ {
+ height: 15px;
+ display: block;
+ background: url(../images/page.png) no-repeat 100% -60px;
+ overflow: hidden;
+ }
+ .header, .footer
+ {
+ display: block;
+ clear: both;
+ overflow: hidden;
+ }
+ .header
+ {
+ height: 115px;
+ position: relative;
+ }
+ .header .icon
+ {
+ position: absolute;
+ top: 13px;
+ left: 0;
+ }
+ .header .qtref
+ {
+ position: absolute;
+ top: 28px;
+ left: 88px;
+ width: 302px;
+ height: 22px;
+ }
+ .header .qtref span
+ {
+ display: block;
+ width: 302px;
+ height: 22px;
+ text-indent: -999em;
+ background: url(../images/sprites-combined.png) no-repeat -78px -235px;
+ }
+
+ .sidebar
+ {
+ float: left;
+ margin-left: 5px;
+ width: 200px;
+ font-size: 11px;
+ }
+
+ .offline .sidebar, .offline .feedback, .offline .t_button
+ {
+ display: none;
+ }
+
+ .sidebar .searchlabel
+ {
+ padding: 0 0 2px 17px;
+ font: normal bold 11px/1.2 Verdana;
+ }
+
+ .sidebar .search
+ {
+ padding: 0 15px 0 16px;
+ }
+
+ .sidebar .search form
+ {
+ background: url(../images/sprites-combined.png) no-repeat -6px -348px;
+ height:21px;
+ padding:2px 0 0 5px;
+ width:167px;
+ }
+
+ .sidebar .search form input#pageType
+ {
+ width: 158px;
+ height: 19px;
+ padding: 0;
+ border: none;
+ outline: none;
+ font: 13px/1.2 Verdana;
+ }
+
+ .sidebar .box
+ {
+ padding: 17px 15px 5px 16px;
+ }
+
+ .sidebar .box .first
+ {
+ background-image: none;
+ }
+
+ .sidebar .box h2
+ {
+ font: normal 18px/1.2 Arial;
+ padding: 0;
+ min-height: 32px;
+ }
+ .sidebar .box h2 span
+ {
+ overflow: hidden;
+ display: inline-block;
+ }
+ .sidebar .box#lookup h2
+ {
+ background-image: none;
+ }
+ .sidebar #lookup.box h2 span
+ {
+ background: url(../images/sprites-combined.png) no-repeat -6px -311px;
+ width: 27px;
+ height: 35px;
+ margin-right: 13px;
+ }
+ .sidebar .box#topics h2
+ {
+ background-image: none;
+ }
+ .sidebar #topics.box h2 span
+ {
+ background: url(../images/sprites-combined.png) no-repeat -94px -311px;
+ width: 27px;
+ height: 32px;
+ margin-right: 13px;
+ }
+ .sidebar .box#examples h2
+ {
+ background-image: none;
+ }
+ .sidebar #examples.box h2 span
+ {
+ background: url(../images/sprites-combined.png) no-repeat -48px -311px;
+ width: 30px;
+ height: 31px;
+ margin-right: 9px;
+ }
+
+ .sidebar .box .list
+ {
+ display: block;
+ }
+ .sidebar .box .live
+ {
+ display: none;
+ height: 100px;
+ overflow: auto;
+ }
+ .list li a:hover, .live li a:hover
+ {
+ text-decoration: underline;
+ }
+ .sidebar .box ul
+ {
+ }
+ .sidebar .box ul li
+ {
+ padding-left: 12px;
+ background: url(../images/bullet_gt.png) no-repeat 0 5px;
+ margin-bottom: 15px;
+ }
+ .sidebar .bottombar
+ {
+ background: url(../images/box_bg.png) repeat-x 0 bottom;
+ }
+ .wrap
+ {
+ margin: 0 5px 0 208px;
+ overflow: visible;
+ }
+ .offline .wrap
+ {
+ margin: 0 5px 0 5px;
+ }
+ .wrap .toolbar
+ {
+ background-color: #fafafa;
+ border-bottom: 1px solid #d1d1d1;
+ height: 20px;
+ position: relative;
+ }
+ .wrap .toolbar .toolblock
+ {
+ position: absolute;
+ }
+ .wrap .toolbar .breadcrumb
+ {
+ font-size: 11px;
+ line-height: 1;
+ padding: 0 0 10px 21px;
+ height: 10px;
+ }
+ .wrap .toolbar .toolbuttons
+ {
+ padding: 0 0 10px 21px;
+ right: 5px;
+ vertical-align: middle;
+ overflow: hidden;
+ }
+ .wrap .toolbar .toolbuttons .active
+ {
+ color: #00732F;
+ }
+ .wrap .toolbar .toolbuttons ul
+ {
+ float: right;
+ }
+ .wrap .toolbar .toolbuttons li
+ {
+ float: left;
+ text-indent: -10px;
+ margin-top: -5px;
+ margin-right: 15px;
+ font-weight: bold;
+ color: #B0ADAB;
+ }
+
+ .toolbuttons #print
+ {
+ border-left: 1px solid #c5c4c4;
+ margin-top: 0;
+ padding-left: 7px;
+ text-indent: 0;
+ }
+ .toolbuttons #print a
+ {
+ width: 16px;
+ height: 16px;
+ }
+
+ .toolbuttons #print a span
+ {
+ width: 16px;
+ height: 16px;
+ text-indent: -999em;
+ display: block;
+ overflow: hidden;
+ background: url(../images/sprites-combined.png) no-repeat -137px -311px;
+ }
+
+ .toolbuttons #smallA
+ {
+ font-size: 10pt;
+ }
+ .toolbuttons #medA
+ {
+ font-size: 12pt;
+ }
+ .toolbuttons #bigA
+ {
+ font-size: 14pt;
+ margin-right: 7px;
+ }
+
+ #smallA:hover, #medA:hover, #bigA:hover
+ {
+ color: #00732F;
+ }
+
+ .offline .wrap .breadcrumb
+ {
+ }
+
+ .wrap .breadcrumb ul
+ {
+ }
+ .wrap .breadcrumb ul li
+ {
+ float: left;
+ background: url(../images/breadcrumb.png) no-repeat 0 3px;
+ padding-left: 15px;
+ margin-left: 15px;
+ font-weight: bold;
+ }
+ .wrap .breadcrumb ul li.last
+ {
+ font-weight: normal;
+ }
+ .wrap .breadcrumb ul li a
+ {
+ color: #363534;
+ }
+ .wrap .breadcrumb ul li.first
+ {
+ background-image: none;
+ padding-left: 0;
+ margin-left: 0;
+ }
+ .wrap .content
+ {
+ padding: 30px;
+ }
+
+ .wrap .content li
+ {
+ padding-left: 12px;
+ background: url(../images/bullet_sq.png) no-repeat 0 5px;
+ font: normal 400 10pt/1 Verdana;
+ color: #44a51c;
+ margin-bottom: 10px;
+ }
+ .content li:hover
+ {
+ text-decoration: underline;
+ }
+
+ .offline .wrap .content
+ {
+ padding-top: 15px;
+ }
+
+ .wrap .content h1
+ {
+ font: 600 18px/1.2 Arial;
+ }
+ .wrap .content h2
+ {
+ font: 600 16px/1.2 Arial;
+ }
+ .wrap .content h3
+ {
+ font: 600 14px/1.2 Arial;
+ }
+ .wrap .content p
+ {
+ line-height: 20px;
+ padding: 10px 5px 10px 5px;
+ }
+ .wrap .content ul
+ {
+ padding-left: 25px;
+ }
+ a:hover
+ {
+ color: #4c0033;
+ text-decoration: underline;
+ }
+ .content a:visited
+ {
+ color: #4c0033;
+ text-decoration: none;
+ }
+ .footer
+ {
+ min-height: 100px;
+ color: #797775;
+ font: normal 9px/1 Verdana;
+ text-align: center;
+ padding-top: 40px;
+ background-color: #E6E7E8;
+ margin: 0;
+ }
+ .feedback
+ {
+ float: none;
+ position: absolute;
+ right: 15px;
+ bottom: 10px;
+ font: normal 8px/1 Verdana;
+ color: #B0ADAB;
+ }
+ .feedback:hover
+ {
+ float: right;
+ font: normal 8px/1 Verdana;
+ color: #00732F;
+ text-decoration: underline;
+ }
+ .header:after, .footer:after, .breadcrumb:after, .wrap .content:after, .group:after
+ {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+ #nav-topright
+ {
+ height: 70px;
+ }
+
+ #nav-topright ul
+ {
+ list-style-type: none;
+ float: right;
+ width: 370px;
+ margin-top: 11px;
+ }
+
+ #nav-topright li
+ {
+ display: inline-block;
+ margin-right: 20px;
+ float: left;
+ }
+
+ #nav-topright li.nav-topright-last
+ {
+ margin-right: 0;
+ }
+
+ #nav-topright li a
+ {
+ background: transparent url(../images/sprites-combined.png) no-repeat;
+ height: 18px;
+ display: block;
+ overflow: hidden;
+ text-indent: -9999px;
+ }
+
+ #nav-topright li.nav-topright-home a
+ {
+ width: 65px;
+ background-position: -2px -91px;
+ }
+
+ #nav-topright li.nav-topright-home a:hover
+ {
+ background-position: -2px -117px;
+ }
+
+
+ #nav-topright li.nav-topright-dev a
+ {
+ width: 30px;
+ background-position: -76px -91px;
+ }
+
+ #nav-topright li.nav-topright-dev a:hover
+ {
+ background-position: -76px -117px;
+ }
+
+
+ #nav-topright li.nav-topright-labs a
+ {
+ width: 40px;
+ background-position: -114px -91px;
+ }
+
+ #nav-topright li.nav-topright-labs a:hover
+ {
+ background-position: -114px -117px;
+ }
+
+ #nav-topright li.nav-topright-doc a
+ {
+ width: 32px;
+ background-position: -162px -91px;
+ }
+
+ #nav-topright li.nav-topright-doc a:hover, #nav-topright li.nav-topright-doc-active a
+ {
+ background-position: -162px -117px;
+ }
+
+ #nav-topright li.nav-topright-blog a
+ {
+ width: 40px;
+ background-position: -203px -91px;
+ }
+
+ #nav-topright li.nav-topright-blog a:hover, #nav-topright li.nav-topright-blog-active a
+ {
+ background-position: -203px -117px;
+ }
+
+ #nav-topright li.nav-topright-shop a
+ {
+ width: 40px;
+ background-position: -252px -91px;
+ }
+
+ #nav-topright li.nav-topright-shop a:hover, #nav-topright li.nav-topright-shop-active a
+ {
+ background-position: -252px -117px;
+ }
+
+ #nav-logo
+ {
+ background: transparent url(../images/sprites-combined.png ) no-repeat 0 -225px;
+ left: -3px;
+ position: absolute;
+ width: 75px;
+ height: 75px;
+ top: 13px;
+ }
+ #nav-logo a
+ {
+ width: 75px;
+ height: 75px;
+ display: block;
+ text-indent: -9999px;
+ overflow: hidden;
+ }
+
+
+ .shortCut-topleft-inactive
+ {
+ padding-left: 3px;
+ background: transparent url( ../images/sprites-combined.png) no-repeat 0px -58px;
+ height: 20px;
+ width: 47px;
+ }
+ .shortCut-topleft-inactive span
+ {
+ font-variant: normal;
+ }
+ #shortCut
+ {
+ padding-top: 10px;
+ font-weight: bolder;
+ color: #b0adab;
+ }
+ #shortCut ul
+ {
+ list-style-type: none;
+ float: left;
+ width: 347px;
+ margin-left: 100px;
+ }
+ #shortCut li
+ {
+ display: inline-block;
+ margin-right: 25px;
+ float: left;
+ white-space: nowrap;
+ }
+ #shortCut li a
+ {
+ color: #b0adab;
+ }
+ #shortCut li a:hover
+ {
+ color: #44a51c;
+ }
+
+ hr
+ {
+ background-color: #E6E6E6;
+ border: 1px solid #E6E6E6;
+ height: 1px;
+ width: 100%;
+ text-align: left;
+ margin: 15px 0px 15px 0px;
+ }
+
+ .content .alignedsummary
+ {
+ margin: 15px;
+ }
+ pre
+ {
+ border: 1px solid #DDDDDD;
+ margin: 0 20px 10px 10px;
+ padding: 20px 15px 20px 20px;
+ overflow-x: auto;
+ }
+ table, pre
+ {
+ -moz-border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #E6E6E6;
+ border-collapse: separate;
+ font-size: 11px;
+ /*min-width: 395px;*/
+ margin-bottom: 25px;
+ display: inline-block;
+ }
+ thead
+ {
+ margin-top: 5px;
+ }
+ th
+ {
+ padding: 3px 15px 3px 15px;
+ }
+ td
+ {
+ padding: 3px 15px 3px 20px;
+ }
+ table tr.odd
+ {
+ border-left: 1px solid #E6E6E6;
+ background-color: #F6F6F6;
+ color: #66666E;
+ }
+ table tr.even
+ {
+ border-left: 1px solid #E6E6E6;
+ background-color: #ffffff;
+ color: #66666E;
+ }
+ table tr.odd:hover
+ {
+ background-color: #E6E6E6;
+ }
+ table tr.even:hover
+ {
+ background-color: #E6E6E6;
+ }
+
+ span.comment
+ {
+ color: #8B0000;
+ font-style: italic;
+ }
+ span.string, span.char
+ {
+ color: #254117;
+ }
+
+ .qmltype
+ {
+ text-align: center;
+ font-size: 160%;
+ }
+ .qmlreadonly
+ {
+ padding-left: 3px;
+ float: right;
+ color: #254117;
+ }
+
+ .qmldefault
+ {
+ padding-left: 3px;
+ float: right;
+ color: red;
+ }
+
+ .qmldoc
+ {
+ }
+
+ *.qmlitem p
+ {
+ }
+
+ #feedbackBox
+ {
+ display: none;
+ -moz-border-radius: 7px 7px 7px 7px;
+ border: 1px solid #DDDDDD;
+ position: fixed;
+ top: 100px;
+ left: 33%;
+ height: 190px;
+ width: 400px;
+ padding: 5px;
+ background-color: #e6e7e8;
+ z-index: 4;
+ }
+ #feedcloseX a
+ {
+ display: inline;
+ padding: 5px 5px 0 0;
+ margin-bottom: 3px;
+ color: #363534;
+ font-weight: 600;
+ float: right;
+ text-decoration: none;
+ }
+
+ #feedbox
+ {
+ display: inline;
+ width: 370px;
+ height: 120px;
+ margin: 0px 25px 10px 15px;
+ }
+ #feedsubmit
+ {
+ display: inline;
+ float: right;
+ margin: 4px 32px 0 0;
+ }
+ #blurpage
+ {
+ display: none;
+ position: fixed;
+ float: none;
+ top: 0px;
+ left: 0px;
+ right: 0px;
+ bottom: 0px;
+ background: transparent url(../images/feedbackground.png) 0 0;
+ z-index: 3;
+ }
+ .toc
+ {
+ float: right;
+ -moz-border-radius: 7px 7px 7px 7px;
+ background-color: #F6F6F6;
+ border: 1px solid #DDDDDD;
+ margin: 0 20px 10px 10px;
+ padding: 20px 15px 20px 20px;
+ height: auto;
+ width: 200px;
+ }
+
+ .toc h3
+ {
+ font: 600 12px/1.2 Arial;
+ }
+
+ .wrap .content .toc ul
+ {
+ padding-left: 0px;
+ }
+
+
+ .wrap .content .toc .level2
+ {
+ margin-left: 15px;
+ }
+
+ .content .toc li
+ {
+ font: normal 10px/1.2 Verdana;
+ background: url(../images/bullet_dn.png) no-repeat 0 5px;
+ }
+
+ .relpage
+ {
+ -moz-border-radius: 7px 7px 7px 7px;
+ border: 1px solid #DDDDDD;
+ padding: 25px 25px;
+ clear: both;
+ }
+ .relpage ul
+ {
+ float: none;
+ padding: 15px;
+ }
+ .content .relpage li
+ {
+ font: normal 11px/1.2 Verdana;
+ }
+ h3.fn, span.fn
+ {
+ background-color: #F6F6F6;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #E6E6E6;
+ font-weight: bold;
+ }
+
+
+ /* start index box */
+ .indexbox
+ {
+ width: 100%;
+ display:inline-block;
+ }
+
+ .indexboxcont
+ {
+ display: block;
+ /* overflow: hidden;*/
+ }
+
+ .indexboxbar
+ {
+ background: transparent url(../images/horBar.png ) repeat-x left bottom;
+ margin-bottom: 25px;
+ /* background-image: none;
+ border-bottom: 1px solid #e2e2e2;*/
+ }
+
+ .indexboxcont .section
+ {
+ display: inline-block;
+ width: 49%;
+ *width:42%;
+ _width:42%;
+ padding:0 2% 0 1%;
+ vertical-align:top;
+
+}
+
+ .indexboxcont .indexIcon
+ {
+ width: 11%;
+ *width:18%;
+ _width:18%;
+ overflow:hidden;
+
+}
+ .indexboxcont .section p
+ {
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+ .indexboxcont .sectionlist
+ {
+ display: inline-block;
+ width: 33%;
+ padding: 0;
+ }
+ .indexboxcont .sectionlist ul
+ {
+ margin-bottom: 20px;
+ }
+
+ .indexboxcont .sectionlist ul li
+ {
+ line-height: 12px;
+ }
+
+ .content .indexboxcont li
+ {
+ font: normal 600 13px/1 Verdana;
+ }
+
+ .indexbox a:hover, .indexbox a:visited:hover
+ {
+ color: #4c0033;
+ text-decoration: underline;
+ }
+
+ .indexbox a:visited
+ {
+ color: #00732f;
+ text-decoration: none;
+ }
+
+ .indexboxcont:after
+ {
+ content: ".";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+
+ .indexbox .indexIcon span
+ {
+ display: block;
+ }
+
+ .indexbox.guide .indexIcon span
+ {
+ width: 96px;
+ height: 137px;
+ background: url(../images/sprites-combined.png) no-repeat -5px -376px;
+ padding: 0;
+ }
+
+ .indexbox.tools .indexIcon span
+ {
+ width: 115px;
+ height: 137px;
+ background: url(../images/sprites-combined.png) no-repeat -111px -376px;
+ padding: 0;
+ }
+
+ .lastcol
+ {
+ display: inline-block;
+ vertical-align: top;
+ padding: 0;
+ max-width: 25%;
+ }
+
+ .tricol .lastcol
+ {
+ margin-left: -6px;
+ }
+ /* end indexbox */
+}
+/* end of screen media */
+
+/* start of print media */
+
+@media print
+{
+ input, textarea, .header, .footer, .toolbar, .feedback, .wrapper .hd, .wrapper .bd .sidebar, .wrapper .ft
+ {
+ display: none;
+ background: none;
+ }
+ .content
+ {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ background: none;
+ display: block;
+ }
+}
+/* end of print media */
diff --git a/tools/qdoc3/test/style/style_ie6.css b/tools/qdoc3/test/style/style_ie6.css
new file mode 100644
index 0000000..16fb850
--- /dev/null
+++ b/tools/qdoc3/test/style/style_ie6.css
@@ -0,0 +1,54 @@
+.indexbox, .indexboxcont, .group {
+ zoom: 1;
+ height: 1%;
+}
+
+.sidebar {
+ margin-left: 3px;
+ width: 199px;
+ overflow: hidden;
+}
+
+.sidebar .search form {
+ position: relative;
+}
+
+.sidebar .search form fieldset {
+ position: absolute;
+ margin-top: -1px;
+}
+
+.sidebar .search form input#searchstring {
+ border: 1px solid #fff;
+ height: 18px;
+}
+
+.wrap {
+ zoom: 1;
+}
+
+.content,
+.toolbar {
+ zoom: 1;
+ margin-left: -3px;
+ position: relative;
+}
+
+.indexbox {
+ clear: both;
+}
+
+.indexboxcont .section {
+ zoom: 1;
+ float: left;
+}
+
+.indexboxcont .sectionlist {
+ zoom: 1;
+ float: left;
+}
+
+.wrap .toolbar .toolbuttons li {
+ text-indent: 0;
+ margin-right: 8px;
+} \ No newline at end of file
diff --git a/tools/qdoc3/test/style/style_ie7.css b/tools/qdoc3/test/style/style_ie7.css
new file mode 100644
index 0000000..afbff5f
--- /dev/null
+++ b/tools/qdoc3/test/style/style_ie7.css
@@ -0,0 +1,19 @@
+.indexbox, .indexboxcont, .group {
+ min-height: 1px;
+}
+
+.sidebar .search form input#searchstring {
+ border: 1px solid #fff;
+ height: 17px;
+}
+
+
+.indexboxcont .section {
+ zoom: 1;
+ float: left;
+}
+
+.indexboxcont .sectionlist {
+ zoom: 1;
+ float: left;
+}
diff --git a/tools/qdoc3/test/style/style_ie8.css b/tools/qdoc3/test/style/style_ie8.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tools/qdoc3/test/style/style_ie8.css
diff --git a/tools/qdoc3/text.h b/tools/qdoc3/text.h
index fa3ecda..879f6da 100644
--- a/tools/qdoc3/text.h
+++ b/tools/qdoc3/text.h
@@ -75,6 +75,7 @@ class Text
const Atom *lastAtom() const { return last; }
Text subText(Atom::Type left, Atom::Type right, const Atom *from = 0) const;
void dump() const;
+ void clear();
static Text subText(const Atom *begin, const Atom *end = 0);
static Text sectionHeading(const Atom *sectionBegin);
@@ -82,7 +83,6 @@ class Text
static int compare(const Text &text1, const Text &text2);
private:
- void clear();
Atom *first;
Atom *last;
diff --git a/tools/qdoc3/tokenizer.cpp b/tools/qdoc3/tokenizer.cpp
index b391759..05ad5ee 100644
--- a/tools/qdoc3/tokenizer.cpp
+++ b/tools/qdoc3/tokenizer.cpp
@@ -47,6 +47,7 @@
#include <qhash.h>
#include <qregexp.h>
#include <qstring.h>
+#include <qtextcodec.h>
#include <ctype.h>
#include <string.h>
@@ -66,7 +67,11 @@ static const char *kwords[] = {
"private", "protected", "public", "short", "signals", "signed",
"slots", "static", "struct", "template", "typedef", "typename",
"union", "unsigned", "using", "virtual", "void", "volatile",
- "__int64", "Q_OBJECT", "Q_OVERRIDE", "Q_PROPERTY",
+ "__int64",
+ "Q_OBJECT",
+ "Q_OVERRIDE",
+ "Q_PROPERTY",
+ "Q_PRIVATE_PROPERTY",
"Q_DECLARE_SEQUENTIAL_ITERATOR",
"Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR",
"Q_DECLARE_ASSOCIATIVE_ITERATOR",
@@ -97,6 +102,8 @@ static QRegExp *definedX = 0;
static QRegExp *defines = 0;
static QRegExp *falsehoods = 0;
+static QTextCodec *sourceCodec = 0;
+
/*
This function is a perfect hash function for the 37 keywords of C99
(with a hash table size of 512). It should perform well on our
@@ -118,13 +125,10 @@ static void insertKwordIntoHash(const char *s, int number)
kwordHashTable[k] = number;
}
-Tokenizer::Tokenizer(const Location& loc, FILE *in)
+Tokenizer::Tokenizer(const Location& loc, QFile &in)
{
init();
- QFile file;
- file.open(in, QIODevice::ReadOnly);
- yyIn = file.readAll();
- file.close();
+ yyIn = in.readAll();
yyPos = 0;
start(loc);
}
@@ -483,6 +487,11 @@ void Tokenizer::initialize(const Config &config)
{
QString versionSym = config.getString(CONFIG_VERSIONSYM);
+ QString sourceEncoding = config.getString(CONFIG_SOURCEENCODING);
+ if (sourceEncoding.isEmpty())
+ sourceEncoding = QLatin1String("ISO-8859-1");
+ sourceCodec = QTextCodec::codecForName(sourceEncoding.toLocal8Bit());
+
comment = new QRegExp("/(?:\\*.*\\*/|/.*\n|/[^\n]*$)");
comment->setMinimal(true);
versionX = new QRegExp("$cannot possibly match^");
@@ -750,4 +759,14 @@ bool Tokenizer::isTrue(const QString &condition)
return !falsehoods->exactMatch(t);
}
+QString Tokenizer::lexeme() const
+{
+ return sourceCodec->toUnicode(yyLex);
+}
+
+QString Tokenizer::previousLexeme() const
+{
+ return sourceCodec->toUnicode(yyPrevLex);
+}
+
QT_END_NAMESPACE
diff --git a/tools/qdoc3/tokenizer.h b/tools/qdoc3/tokenizer.h
index 519cffb..1b33f6f 100644
--- a/tools/qdoc3/tokenizer.h
+++ b/tools/qdoc3/tokenizer.h
@@ -46,11 +46,10 @@
#ifndef TOKENIZER_H
#define TOKENIZER_H
+#include <qfile.h>
#include <qstack.h>
#include <qstring.h>
-#include <stdio.h>
-
#include "location.h"
QT_BEGIN_NAMESPACE
@@ -76,7 +75,7 @@ enum { Tok_Eoi, Tok_Ampersand, Tok_Aster, Tok_Caret, Tok_LeftParen,
Tok_static, Tok_struct, Tok_template, Tok_typedef,
Tok_typename, Tok_union, Tok_unsigned, Tok_using, Tok_virtual,
Tok_void, Tok_volatile, Tok_int64, Tok_Q_OBJECT, Tok_Q_OVERRIDE,
- Tok_Q_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR,
+ Tok_Q_PROPERTY, Tok_Q_PRIVATE_PROPERTY, Tok_Q_DECLARE_SEQUENTIAL_ITERATOR,
Tok_Q_DECLARE_MUTABLE_SEQUENTIAL_ITERATOR,
Tok_Q_DECLARE_ASSOCIATIVE_ITERATOR,
Tok_Q_DECLARE_MUTABLE_ASSOCIATIVE_ITERATOR,
@@ -99,7 +98,7 @@ class Tokenizer
{
public:
Tokenizer(const Location& loc, const QByteArray &in);
- Tokenizer(const Location& loc, FILE *in);
+ Tokenizer(const Location& loc, QFile &file);
~Tokenizer();
@@ -108,8 +107,8 @@ class Tokenizer
bool parsingFnOrMacro() const { return parsingMacro; }
const Location &location() const { return yyTokLoc; }
- QString previousLexeme() const { return QString(yyPrevLex); }
- QString lexeme() const { return QString(yyLex); }
+ QString previousLexeme() const;
+ QString lexeme() const;
QString version() const { return yyVersion; }
int braceDepth() const { return yyBraceDepth; }
int parenDepth() const { return yyParenDepth; }
@@ -146,7 +145,7 @@ class Tokenizer
int ch = getch();
if (ch == EOF)
return EOF;
- // cast explicitely to make sure the value of ch
+ // cast explicitly to make sure the value of ch
// is in range [0..255] to avoid assert messages
// when using debug CRT that checks its input.
return int(uint(uchar(ch)));
diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp
index d46da95..540ffa9 100644
--- a/tools/qdoc3/tree.cpp
+++ b/tools/qdoc3/tree.cpp
@@ -43,7 +43,6 @@
tree.cpp
*/
-#include <QtCore>
#include <QDomDocument>
#include "atom.h"
@@ -54,6 +53,9 @@
#include "text.h"
#include "tree.h"
+#include <limits.h>
+#include <qdebug.h>
+
QT_BEGIN_NAMESPACE
struct InheritanceBound
@@ -123,24 +125,27 @@ Tree::~Tree()
/*!
*/
-Node *Tree::findNode(const QStringList &path, Node *relative, int findFlags)
+Node *Tree::findNode(const QStringList &path, Node *relative, int findFlags, const Node* self)
{
return const_cast<Node*>(const_cast<const Tree*>(this)->findNode(path,
relative,
- findFlags));
+ findFlags,
+ self));
}
/*!
*/
-const Node *Tree::findNode(const QStringList &path,
- const Node *relative,
- int findFlags) const
+const Node* Tree::findNode(const QStringList &path,
+ const Node* start,
+ int findFlags,
+ const Node* self) const
{
- if (!relative)
- relative = root();
+ const Node* current = start;
+ if (!current)
+ current = root();
do {
- const Node *node = relative;
+ const Node *node = current;
int i;
for (i = 0; i < path.size(); ++i) {
@@ -149,6 +154,7 @@ const Node *Tree::findNode(const QStringList &path,
const Node *next =
static_cast<const InnerNode*>(node)->findNode(path.at(i));
+
if (!next && (findFlags & SearchEnumValues) && i == path.size()-1)
next = static_cast<const InnerNode*>(node)->findEnumNodeForValue(path.at(i));
@@ -167,10 +173,13 @@ const Node *Tree::findNode(const QStringList &path,
}
if (node && i == path.size()
&& (!(findFlags & NonFunction) || node->type() != Node::Function
- || ((FunctionNode *)node)->metaness() == FunctionNode::MacroWithoutParams))
- return node;
- relative = relative->parent();
- } while (relative);
+ || ((FunctionNode *)node)->metaness() == FunctionNode::MacroWithoutParams)) {
+ if ((node != self) && (node->subType() != Node::QmlPropertyGroup)) {
+ return node;
+ }
+ }
+ current = current->parent();
+ } while (current);
return 0;
}
@@ -460,8 +469,9 @@ void Tree::resolveInheritance(NamespaceNode *rootNode)
for (int pass = 0; pass < 2; pass++) {
NodeList::ConstIterator c = rootNode->childNodes().begin();
while (c != rootNode->childNodes().end()) {
- if ((*c)->type() == Node::Class)
+ if ((*c)->type() == Node::Class) {
resolveInheritance(pass, (ClassNode *) *c);
+ }
else if ((*c)->type() == Node::Namespace) {
NamespaceNode *ns = static_cast<NamespaceNode*>(*c);
resolveInheritance(ns);
@@ -533,14 +543,16 @@ void Tree::resolveInheritance(int pass, ClassNode *classe)
while (b != bounds.end()) {
ClassNode *baseClass = (ClassNode*)findNode((*b).basePath,
Node::Class);
- if (!baseClass && (*b).parent)
+ if (!baseClass && (*b).parent) {
baseClass = (ClassNode*)findNode((*b).basePath,
Node::Class,
(*b).parent);
- if (baseClass)
+ }
+ if (baseClass) {
classe->addBaseClass((*b).access,
baseClass,
(*b).dataTypeWithTemplateArgs);
+ }
++b;
}
}
@@ -1118,6 +1130,15 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
case Node::Target:
nodeName = "target";
break;
+ case Node::QmlProperty:
+ nodeName = "qmlproperty";
+ break;
+ case Node::QmlSignal:
+ nodeName = "qmlsignal";
+ break;
+ case Node::QmlMethod:
+ nodeName = "qmlmethod";
+ break;
default:
return false;
}
@@ -1207,7 +1228,7 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
if (fullName != objName)
writer.writeAttribute("fullname", fullName);
writer.writeAttribute("href", fullDocumentLocation(node));
- if (node->type() != Node::Fake)
+ if ((node->type() != Node::Fake) && (!node->isQmlNode()))
writer.writeAttribute("location", node->location().fileName());
switch (node->type()) {
@@ -1262,6 +1283,12 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
case Node::ExternalPage:
writer.writeAttribute("subtype", "externalpage");
break;
+ case Node::QmlClass:
+ writer.writeAttribute("subtype", "qmlclass");
+ break;
+ case Node::QmlBasicType:
+ writer.writeAttribute("subtype", "qmlbasictype");
+ break;
default:
break;
}
@@ -1334,6 +1361,12 @@ bool Tree::generateIndexSection(QXmlStreamWriter &writer,
}
break;
+ case Node::QmlProperty:
+ {
+ const QmlPropertyNode *qpn = static_cast<const QmlPropertyNode*>(node);
+ writer.writeAttribute("type", qpn->dataType());
+ }
+ break;
case Node::Property:
{
const PropertyNode *propertyNode = static_cast<const PropertyNode*>(node);
@@ -1521,9 +1554,22 @@ void Tree::generateIndexSections(QXmlStreamWriter &writer,
if (node->isInnerNode()) {
const InnerNode *inner = static_cast<const InnerNode *>(node);
- // Recurse to write an element for this child node and all its children.
- foreach (const Node *child, inner->childNodes())
- generateIndexSections(writer, child, generateInternalNodes);
+ foreach (const Node *child, inner->childNodes()) {
+ /*
+ Don't generate anything for a QML property group node.
+ It is just a place holder for a collection of QML property
+ nodes. Recurse to its children, which are the QML property
+ nodes.
+ */
+ if (child->subType() == Node::QmlPropertyGroup) {
+ const InnerNode *pgn = static_cast<const InnerNode*>(child);
+ foreach (const Node *c, pgn->childNodes()) {
+ generateIndexSections(writer, c, generateInternalNodes);
+ }
+ }
+ else
+ generateIndexSections(writer, child, generateInternalNodes);
+ }
/*
foreach (const Node *child, inner->relatedNodes()) {
@@ -1914,9 +1960,14 @@ QString Tree::fullDocumentLocation(const Node *node) const
}
else if (node->type() == Node::Fake) {
#ifdef QDOC_QML
- if (node->subType() == Node::QmlClass)
- return "qml-" + node->fileBase() + ".html";
- else
+ if ((node->subType() == Node::QmlClass) ||
+ (node->subType() == Node::QmlBasicType)) {
+ QString fb = node->fileBase();
+ if (fb.startsWith(QLatin1String("qml-")))
+ return fb + ".html";
+ else
+ return "qml-" + node->fileBase() + ".html";
+ } else
#endif
parentName = node->fileBase() + ".html";
}
@@ -1927,9 +1978,23 @@ QString Tree::fullDocumentLocation(const Node *node) const
if ((parentNode = node->relates()))
parentName = fullDocumentLocation(node->relates());
- else if ((parentNode = node->parent()))
- parentName = fullDocumentLocation(node->parent());
-
+ else if ((parentNode = node->parent())) {
+ if (parentNode->subType() == Node::QmlPropertyGroup) {
+ parentNode = parentNode->parent();
+ parentName = fullDocumentLocation(parentNode);
+ }
+ else
+ parentName = fullDocumentLocation(node->parent());
+ }
+#if 0
+ if (node->type() == Node::QmlProperty) {
+ qDebug() << "Node::QmlProperty:" << node->name()
+ << "parentName:" << parentName;
+ if (parentNode)
+ qDebug() << "PARENT NODE" << parentNode->type()
+ << parentNode->subType() << parentNode->name();
+ }
+#endif
switch (node->type()) {
case Node::Class:
case Node::Namespace:
@@ -1976,6 +2041,15 @@ QString Tree::fullDocumentLocation(const Node *node) const
case Node::Property:
anchorRef = "#" + node->name() + "-prop";
break;
+ case Node::QmlProperty:
+ anchorRef = "#" + node->name() + "-prop";
+ break;
+ case Node::QmlSignal:
+ anchorRef = "#" + node->name() + "-signal";
+ break;
+ case Node::QmlMethod:
+ anchorRef = "#" + node->name() + "-method";
+ break;
case Node::Variable:
anchorRef = "#" + node->name() + "-var";
break;
@@ -2015,6 +2089,8 @@ QString Tree::fullDocumentLocation(const Node *node) const
}
/*!
+ Construct the full document name for \a node and return the
+ name.
*/
QString Tree::fullDocumentName(const Node *node) const
{
@@ -2025,10 +2101,11 @@ QString Tree::fullDocumentName(const Node *node) const
const Node *n = node;
do {
- if (!n->name().isEmpty())
+ if (!n->name().isEmpty() &&
+ ((n->type() != Node::Fake) || (n->subType() != Node::QmlPropertyGroup)))
pieces.insert(0, n->name());
- if (n->type() == Node::Fake)
+ if ((n->type() == Node::Fake) && (n->subType() != Node::QmlPropertyGroup))
break;
// Examine the parent node if one exists.
diff --git a/tools/qdoc3/tree.h b/tools/qdoc3/tree.h
index 0865847..b34c3a8 100644
--- a/tools/qdoc3/tree.h
+++ b/tools/qdoc3/tree.h
@@ -65,10 +65,13 @@ class Tree
Tree();
~Tree();
- Node *findNode(const QStringList &path, Node *relative=0, int findFlags=0);
- Node *findNode(const QStringList &path,
+ Node* findNode(const QStringList &path,
+ Node* relative=0,
+ int findFlags=0,
+ const Node* self=0);
+ Node* findNode(const QStringList &path,
Node::Type type,
- Node *relative = 0,
+ Node* relative = 0,
int findFlags = 0);
FunctionNode *findFunctionNode(const QStringList &path,
Node *relative = 0,
@@ -98,12 +101,13 @@ class Tree
NamespaceNode *root() { return &roo; }
QString version() const { return vers; }
- const Node *findNode(const QStringList &path,
- const Node *relative = 0,
- int findFlags = 0) const;
- const Node *findNode(const QStringList &path,
+ const Node* findNode(const QStringList &path,
+ const Node* relative = 0,
+ int findFlags = 0,
+ const Node* self=0) const;
+ const Node* findNode(const QStringList &path,
Node::Type type, const
- Node *relative = 0,
+ Node* relative = 0,
int findFlags = 0) const;
const FunctionNode *findFunctionNode(const QStringList &path,
const Node *relative = 0,
diff --git a/tools/qdoc3/webxmlgenerator.cpp b/tools/qdoc3/webxmlgenerator.cpp
index a3c92ce..6020b1b 100644
--- a/tools/qdoc3/webxmlgenerator.cpp
+++ b/tools/qdoc3/webxmlgenerator.cpp
@@ -43,8 +43,6 @@
webxmlgenerator.cpp
*/
-#include <QtXml>
-
#include "codemarker.h"
#include "pagegenerator.h"
#include "webxmlgenerator.h"
@@ -52,6 +50,8 @@
#include "separator.h"
#include "tree.h"
+#include <QtCore/qxmlstream.h>
+
QT_BEGIN_NAMESPACE
#define COMMAND_VERSION Doc::alias("version")
@@ -90,7 +90,7 @@ QString WebXMLGenerator::format()
return "WebXML";
}
-QString WebXMLGenerator::fileExtension(const Node * /* node */)
+QString WebXMLGenerator::fileExtension(const Node * /* node */) const
{
return "xml";
}
diff --git a/tools/qdoc3/webxmlgenerator.h b/tools/qdoc3/webxmlgenerator.h
index 3145d50..071896a 100644
--- a/tools/qdoc3/webxmlgenerator.h
+++ b/tools/qdoc3/webxmlgenerator.h
@@ -46,12 +46,17 @@
#ifndef WEBXMLGENERATOR_H
#define WEBXMLGENERATOR_H
+#include <QtCore/qxmlstream.h>
+
#include "codemarker.h"
#include "config.h"
#include "pagegenerator.h"
QT_BEGIN_NAMESPACE
+class QXmlStreamReader;
+class QXmlStreamWriter;
+
class WebXMLGenerator : public PageGenerator
{
public:
@@ -69,7 +74,7 @@ protected:
const Node *relative, CodeMarker *marker );
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
- virtual QString fileExtension(const Node *node);
+ virtual QString fileExtension(const Node *node) const;
virtual const Atom *addAtomElements(QXmlStreamWriter &writer, const Atom *atom,
const Node *relative, CodeMarker *marker);
diff --git a/tools/qev/qev.pro b/tools/qev/qev.pro
index 28383c6..962b9fa 100644
--- a/tools/qev/qev.pro
+++ b/tools/qev/qev.pro
@@ -9,5 +9,3 @@ INCLUDEPATH += .
# Input
SOURCES += qev.cpp
CONFIG += qt warn_on create_prl link_prl
-OBJECTS_DIR=.obj/debug-shared
-MOC_DIR=.moc/debug-shared
diff --git a/tools/qmeegographicssystemhelper/qmeegofencesync.cpp b/tools/qmeegographicssystemhelper/qmeegofencesync.cpp
new file mode 100644
index 0000000..499e102
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegofencesync.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegofencesync.h"
+#include "qmeegofencesync_p.h"
+#include "qmeegoruntime.h"
+
+/* QMeeGoFenceSyncPrivate */
+
+QMeeGoFenceSyncPrivate::QMeeGoFenceSyncPrivate() : syncObject(NULL)
+{
+}
+
+QMeeGoFenceSyncPrivate::~QMeeGoFenceSyncPrivate()
+{
+ if (syncObject) {
+ QMeeGoRuntime::destroyFenceSync(syncObject);
+ syncObject = NULL;
+ }
+}
+
+/* QMeeGoFenceSync */
+
+QMeeGoFenceSync::QMeeGoFenceSync(QWidget *parent) : QObject(parent), d_ptr(new QMeeGoFenceSyncPrivate())
+{
+ Q_D(QMeeGoFenceSync);
+ d->q_ptr = this;
+}
+
+QMeeGoFenceSync::~QMeeGoFenceSync()
+{
+}
+
+void QMeeGoFenceSync::setSyncPoint()
+{
+ Q_D(QMeeGoFenceSync);
+ if (d->syncObject)
+ QMeeGoRuntime::destroyFenceSync(d->syncObject);
+
+ d->syncObject = QMeeGoRuntime::createFenceSync();
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegofencesync.h b/tools/qmeegographicssystemhelper/qmeegofencesync.h
new file mode 100644
index 0000000..2d3f5c5
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegofencesync.h
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOFENCESYNC_H
+#define QMEEGOFENCESYNC_H
+
+#include <QWidget>
+
+class QMeeGoFenceSyncPrivate;
+
+//! A synchronization helper for GL pipeline.
+/*!
+ Fence syncs provide a mechanism for synchronizing access to certain GL primitives
+ and make it possible for the application developer to be sure that a certain point
+ in the GL processing pipeline has been already executed before continuing operation.
+
+ Currently fence syncs are only useful in conjunction with QMeeGoLivePixmaps.
+ \code
+ ...
+ // In your paint/expose event:
+ QImage *image = livePixmap->lock(&someGlobalFenceSync);
+ // Modify the image...
+ livePixmap->release(image);
+
+ painter->drawPixmap(0, 0, *livePixmap);
+ someGlobalFenceSync.setSyncPoint();
+ ...
+ \endcode
+
+ Assuming the paint/expose events come repeatedly, the lock operation
+ will block till the previous event completed painting the livePixmap.
+*/
+
+class Q_DECL_EXPORT QMeeGoFenceSync : public QObject
+{
+public:
+ //! Constructs a new fence sync.
+ /*!
+ The fence sync is created without a sync point. You need to set the sync point manually.
+ */
+ QMeeGoFenceSync(QWidget *parent = 0);
+
+ //! Destructor for the fence sync.
+ virtual ~QMeeGoFenceSync();
+
+ //! Sets the fence sync.
+ /*!
+ The fence sync synchronization point should be set after all drawing has been scheduled.
+ Setting a synchronization point always overrides the previous point -- whetver is was
+ used (waited upon) or not.
+ */
+ void setSyncPoint();
+
+private:
+ Q_DISABLE_COPY(QMeeGoFenceSync)
+ Q_DECLARE_PRIVATE(QMeeGoFenceSync)
+
+protected:
+ QScopedPointer<QMeeGoFenceSyncPrivate> d_ptr; //! Private bits.
+ friend class QMeeGoLivePixmap;
+};
+
+#endif
diff --git a/tools/designer/src/components/propertyeditor/defs.h b/tools/qmeegographicssystemhelper/qmeegofencesync_p.h
index 28e39fc..8a5d26e 100644
--- a/tools/designer/src/components/propertyeditor/defs.h
+++ b/tools/qmeegographicssystemhelper/qmeegofencesync_p.h
@@ -4,7 +4,7 @@
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
-** This file is part of the Qt Designer of the Qt Toolkit.
+** This file is part of the plugins of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
@@ -39,22 +39,22 @@
**
****************************************************************************/
-#ifndef DEFS_H
-#define DEFS_H
+#include "qmeegofencesync.h"
-#include <QtGui/QSizePolicy>
-#include <QtCore/QString>
+#ifndef QMEEGOFENCESYNC_P_H
+#define QMEEGOFENCESYNC_P_H
-QT_BEGIN_NAMESPACE
+class QMeeGoFenceSyncPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QMeeGoFenceSync);
+ QMeeGoFenceSyncPrivate();
-namespace qdesigner_internal {
+ virtual ~QMeeGoFenceSyncPrivate();
-int size_type_to_int(QSizePolicy::Policy t);
-QString size_type_to_string(QSizePolicy::Policy t);
-QSizePolicy::Policy int_to_size_type(int i);
+ void* syncObject;
-} // namespace qdesigner_internal
+ QMeeGoFenceSync *q_ptr;
+};
-QT_END_NAMESPACE
-
-#endif // DEFS_H
+#endif
diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
new file mode 100644
index 0000000..d348e70
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.cpp
@@ -0,0 +1,138 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#define ENSURE_RUNNING_MEEGO {if (! QMeeGoGraphicsSystemHelper::isRunningMeeGo()) { qFatal("Using meego functionality but not running meego graphics system!"); }}
+
+#include "qmeegographicssystemhelper.h"
+#include <private/qapplication_p.h>
+#include <private/qgraphicssystem_runtime_p.h>
+#include <private/qpixmap_raster_p.h>
+#include "qmeegoruntime.h"
+
+QString QMeeGoGraphicsSystemHelper::runningGraphicsSystemName()
+{
+ if (! QApplicationPrivate::instance()) {
+ qWarning("Querying graphics system but application not running yet!");
+ return QString();
+ }
+
+ QString name = QApplicationPrivate::instance()->graphics_system_name;
+ if (name == QLatin1String("runtime")) {
+ QRuntimeGraphicsSystem *rsystem = (QRuntimeGraphicsSystem *) QApplicationPrivate::instance()->graphics_system;
+ name = rsystem->graphicsSystemName();
+ }
+
+ return name;
+}
+
+bool QMeeGoGraphicsSystemHelper::isRunningMeeGo()
+{
+ return (runningGraphicsSystemName() == QLatin1String("meego"));
+}
+
+bool QMeeGoGraphicsSystemHelper::isRunningRuntime()
+{
+ return (QApplicationPrivate::instance()->graphics_system_name == QLatin1String("runtime"));
+}
+
+void QMeeGoGraphicsSystemHelper::switchToMeeGo()
+{
+ if (isRunningMeeGo())
+ return;
+
+ if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
+ qWarning("Can't switch to meego - switching only supported with 'runtime' graphics system.");
+ else {
+ QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
+ app->setGraphicsSystem(QLatin1String("meego"));
+ }
+}
+
+void QMeeGoGraphicsSystemHelper::switchToRaster()
+{
+ if (runningGraphicsSystemName() == QLatin1String("raster"))
+ return;
+
+ if (QApplicationPrivate::instance()->graphics_system_name != QLatin1String("runtime"))
+ qWarning("Can't switch to raster - switching only supported with 'runtime' graphics system.");
+ else {
+ QApplication *app = static_cast<QApplication *>(QCoreApplication::instance());
+ app->setGraphicsSystem(QLatin1String("raster"));
+ }
+}
+
+Qt::HANDLE QMeeGoGraphicsSystemHelper::imageToEGLSharedImage(const QImage &image)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::imageToEGLSharedImage(image);
+}
+
+QPixmap QMeeGoGraphicsSystemHelper::pixmapFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
+{
+ // This function is supported when not running meego too. A raster-backed
+ // pixmap will be created... but when you switch back to 'meego', it'll
+ // be replaced with a EGL shared image backing.
+ return QPixmap(QMeeGoRuntime::pixmapDataFromEGLSharedImage(handle, softImage));
+}
+
+QPixmap QMeeGoGraphicsSystemHelper::pixmapWithGLTexture(int w, int h)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QPixmap(QMeeGoRuntime::pixmapDataWithGLTexture(w, h));
+}
+
+bool QMeeGoGraphicsSystemHelper::destroyEGLSharedImage(Qt::HANDLE handle)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::destroyEGLSharedImage(handle);
+}
+
+void QMeeGoGraphicsSystemHelper::updateEGLSharedImagePixmap(QPixmap *p)
+{
+ ENSURE_RUNNING_MEEGO;
+ return QMeeGoRuntime::updateEGLSharedImagePixmap(p);
+}
+
+void QMeeGoGraphicsSystemHelper::setTranslucent(bool translucent)
+{
+ ENSURE_RUNNING_MEEGO;
+ QMeeGoRuntime::setTranslucent(translucent);
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h
new file mode 100644
index 0000000..2baacbb
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.h
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOGRAPHICSSYSTEMHELPER_H
+#define QMEEGOGRAPHICSSYSTEMHELPER_H
+
+#include <QPixmap>
+#include <QImage>
+#include "qmeegolivepixmap.h"
+
+class QLibrary;
+
+//! The base class for accressing special meego graphics system features.
+/*!
+ This class is a helper class with static-only methods for accessing various
+ meego graphics system functionalities. The way it works is that the helper
+ dynamically calls-in to the loaded graphicssystem plugin... therefore, you're
+ expected to make sure that you're indeed running with 'meego' before using any
+ of the specialized methods.
+
+ In example:
+
+ \code
+ QPixmap p;
+ if (QMeeGoGraphicsSystemHelper::isRunningMeeGo()) {
+ p = QMeeGoGraphicsSystemHelper::pixmapWithGLTexture(64, 64);
+ } else {
+ p = QPixmap(64, 64);
+ }
+ \endcode
+
+ Calling any of the meego-specific features while not running meego might
+ give unpredictable results. The only functions safe to call at all times are:
+
+ \code
+ QMeeGoGraphicsSystemHelper::isRunningMeeGo();
+ QMeeGoGraphicsSystemHelper::runningGraphicsSystemName();
+ QMeeGoGraphicsSystemHelper::switchToMeeGo();
+ QMeeGoGraphicsSystemHelper::switchToRaster();
+ \endcode
+*/
+
+class Q_DECL_EXPORT QMeeGoGraphicsSystemHelper
+{
+public:
+ //! Returns true if running meego.
+ /*!
+ Returns true if the currently active (running) system is 'meego' with OpenGL.
+ This returns both true if the app was started with 'meego' or was started with
+ 'runtime' graphics system and the currently active system through the runtime
+ switching is 'meego'.
+ */
+ static bool isRunningMeeGo();
+
+ //! Returns true if running with a 'runtime' graphicssystem.
+ /*!
+ This function can be used in combination with ::runningGraphicsSystemName to figure out
+ the existing situation.
+ */
+ static bool isRunningRuntime();
+
+ //! Switches to meego graphics system.
+ /*!
+ When running with the 'runtime' graphics system, sets the currently active
+ system to 'meego'. The window surface and all the resources are automatically
+ migrated to OpenGL. Will fail if the active graphics system is not 'runtime'.
+ */
+ static void switchToMeeGo();
+
+ //! Switches to raster graphics system
+ /*!
+ When running with the 'runtime' graphics system, sets the currently active
+ system to 'raster'. The window surface and the graphics resources (including the
+ EGL shared image resources) are automatically migrated back to the CPU. All OpenGL
+ resources (surface, context, cache, font cache) are automaticall anihilated.
+ */
+ static void switchToRaster();
+
+ //! Returns the name of the active graphics system
+ /*!
+ Returns the name of the currently active system. If running with 'runtime' graphics
+ system, returns the name of the active system inside the runtime graphics system
+ */
+ static QString runningGraphicsSystemName();
+
+ //! Creates a new EGL shared image.
+ /*!
+ Creates a new EGL shared image from the given image. The EGL shared image wraps
+ a GL texture in the native format and can be easily accessed from other processes.
+ */
+ static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
+
+ //! Creates a QPixmap from an EGL shared image
+ /*!
+ Creates a new QPixmap from the given EGL shared image handle. The QPixmap can be
+ used for painting like any other pixmap. The softImage should point to an alternative,
+ software version of the graphical resource -- ie. obtained from theme daemon. The
+ softImage can be allocated on a QSharedMemory slice for easy sharing across processes
+ too. When the application is migrated ToRaster, this softImage will replace the
+ contents of the sharedImage.
+
+ It's ok to call this function too when not running 'meego' graphics system. In this
+ case it'll create a QPixmap backed with a raster data (from softImage)... but when
+ the system is switched back to 'meego', the QPixmap will be migrated to a EGL-shared image
+ backed storage (handle).
+ */
+ static QPixmap pixmapFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+
+ //! Destroys an EGL shared image.
+ /*!
+ Destroys an EGLSharedImage previously created with an ::imageToEGLSharedImage call.
+ Returns true if the image was found and the destruction was successful. Notice that
+ this destroys the image for all processes using it.
+ */
+ static bool destroyEGLSharedImage(Qt::HANDLE handle);
+
+ //! Updates the QPixmap backed with an EGLShared image.
+ /*!
+ This function re-reads the softImage that was specified when creating the pixmap with
+ ::pixmapFromEGLSharedImage and updates the EGL Shared image contents. It can be used
+ to share cross-proccess mutable EGLShared images.
+ */
+ static void updateEGLSharedImagePixmap(QPixmap *p);
+
+ //! Create a new QPixmap with a GL texture.
+ /*!
+ Creates a new QPixmap which is backed by an OpenGL local texture. Drawing to this
+ QPixmap will be accelerated by hardware -- unlike the normal (new QPixmap()) pixmaps,
+ which are backed by a software engine and only migrated to GPU when used. Migrating those
+ GL-backed pixmaps when going ToRaster is expsensive (they need to be downloaded from
+ GPU to CPU) so use wisely.
+ */
+ static QPixmap pixmapWithGLTexture(int w, int h);
+
+ //! Sets translucency (alpha) on the base window surface.
+ /*!
+ This function needs to be called *before* any widget/content is created.
+ When called with true, the base window surface will be translucent and initialized
+ with QGLFormat.alpha == true.
+ */
+ static void setTranslucent(bool translucent);
+};
+
+#endif
diff --git a/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.pro b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.pro
new file mode 100644
index 0000000..161a31b
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegographicssystemhelper.pro
@@ -0,0 +1,10 @@
+TEMPLATE = lib
+TARGET = QtMeeGoGraphicsSystemHelper
+
+include(../../src/qbase.pri)
+
+QT += gui
+INCLUDEPATH += '../../src/plugins/graphicssystems/meego'
+
+HEADERS = qmeegographicssystemhelper.h qmeegooverlaywidget.h qmeegolivepixmap.h qmeegoruntime.h qmeegolivepixmap_p.h qmeegofencesync.h qmeegofencesync_p.h
+SOURCES = qmeegographicssystemhelper.cpp qmeegooverlaywidget.cpp qmeegoruntime.cpp qmeegolivepixmap.cpp qmeegographicssystemhelper.h qmeegooverlaywidget.h qmeegolivepixmap.h qmeegoruntime.h qmeegolivepixmap_p.h qmeegofencesync.h qmeegofencesync_p.h qmeegofencesync.cpp
diff --git a/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp b/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp
new file mode 100644
index 0000000..9700581f
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegolivepixmap.cpp
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegolivepixmap.h"
+#include "qmeegolivepixmap_p.h"
+#include "qmeegofencesync_p.h"
+#include "qmeegoruntime.h"
+
+/* QMeeGoLivePixmapPrivate */
+
+QMeeGoLivePixmapPrivate::QMeeGoLivePixmapPrivate()
+{
+}
+
+QMeeGoLivePixmapPrivate::~QMeeGoLivePixmapPrivate()
+{
+}
+
+/* QMeeGoLivePixmap */
+
+QMeeGoLivePixmap* QMeeGoLivePixmap::livePixmapWithSize(int w, int h, Format format)
+{
+ QImage::Format qtFormat;
+ if (format == Format_RGB16)
+ qtFormat = QImage::Format_RGB16;
+ else if (format == Format_ARGB32_Premultiplied)
+ qtFormat = QImage::Format_ARGB32_Premultiplied;
+ else {
+ qWarning("Unsupported live pixmap format!");
+ return 0;
+ }
+
+ QPixmapData *pmd = QMeeGoRuntime::pixmapDataWithNewLiveTexture(w, h, qtFormat);
+ if (! pmd) {
+ qWarning("Failed to create a live texture with given size!");
+ return NULL;
+ }
+
+ return new QMeeGoLivePixmap(pmd);
+}
+
+QMeeGoLivePixmap::QMeeGoLivePixmap(QPixmapData *p) : QPixmap(p), d_ptr(new QMeeGoLivePixmapPrivate())
+{
+ Q_D(QMeeGoLivePixmap);
+ d->q_ptr = this;
+}
+
+QMeeGoLivePixmap* QMeeGoLivePixmap::fromHandle(Qt::HANDLE liveTextureHandle)
+{
+ QPixmapData *pmd = QMeeGoRuntime::pixmapDataFromLiveTextureHandle(liveTextureHandle);
+ if (! pmd) {
+ qWarning("Failed to create a live texture from given handle!");
+ return NULL;
+ }
+
+ return new QMeeGoLivePixmap(pmd);
+}
+
+Qt::HANDLE QMeeGoLivePixmap::handle()
+{
+ return QMeeGoRuntime::getLiveTextureHandle(this);
+}
+
+QMeeGoLivePixmap::~QMeeGoLivePixmap()
+{
+}
+
+QImage* QMeeGoLivePixmap::lock(QMeeGoFenceSync *fenceSync)
+{
+ if (fenceSync)
+ return QMeeGoRuntime::lockLiveTexture(this, fenceSync->d_func()->syncObject);
+ else
+ return QMeeGoRuntime::lockLiveTexture(this, NULL);
+}
+
+void QMeeGoLivePixmap::release(QImage *img)
+{
+ QMeeGoRuntime::releaseLiveTexture(this, img);
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegolivepixmap.h b/tools/qmeegographicssystemhelper/qmeegolivepixmap.h
new file mode 100644
index 0000000..51b5976
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegolivepixmap.h
@@ -0,0 +1,112 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOLIVEPIXMAP_H
+#define QMEEGOLIVEPIXMAP_H
+
+#include <QPixmap>
+#include "qmeegofencesync.h"
+
+class QMeeGoLivePixmapPrivate;
+class QSharedMemory;
+class QImage;
+
+//! A pixmap representing streamed content.
+/*!
+*/
+
+class Q_DECL_EXPORT QMeeGoLivePixmap : public QPixmap
+{
+public:
+ enum Format {
+ Format_RGB16, //! 16bit, 5-6-5 RGB format.
+ Format_ARGB32_Premultiplied //! 32bit, AARRGGBB format. The typical Qt format.
+ };
+
+ //! Creates and returns a new live pixmap with the given parameters.
+ /*!
+ The new pixmap is created with the given width w and the given height h.
+ The format specifies the color format used by the pixmap.
+ */
+ static QMeeGoLivePixmap* livePixmapWithSize(int w, int h, Format format);
+
+ //! Creates a new QMeeGoLivePixmap from the specified handle.
+ /*!
+ The handle can be used to share QMeeGoLivePixmap cross-process.
+ */
+ static QMeeGoLivePixmap* fromHandle(Qt::HANDLE handle);
+
+ //! Returns the handle for this QMeeGoLivePixmap.
+ /*!
+ The handle can be used to share QMeeGoLivePixmap cross-process.
+ */
+ Qt::HANDLE handle();
+
+ //! Locks the access to the pixmap.
+ /*!
+ The returned image can be used for direct access.
+ You can optionally specify a fence sync to wait upon before unlocking. When
+ you specify a fence sync, you can be sure that this function will return only
+ when the previsouly set QMeeGoFenceSync synchronization point has been executed/passed
+ by the GL processing pipeline.
+ */
+ QImage* lock(QMeeGoFenceSync *fenceSync = NULL);
+
+ //! Unlocks the access to the pixmap.
+ /*!
+ */
+ void release(QImage *img);
+
+ //! Destroys the QMeeGoLivePixmap.
+ /*!
+ */
+ virtual ~QMeeGoLivePixmap();
+
+private:
+ QMeeGoLivePixmap(QPixmapData *p);
+ Q_DISABLE_COPY(QMeeGoLivePixmap)
+ Q_DECLARE_PRIVATE(QMeeGoLivePixmap)
+
+protected:
+ QScopedPointer<QMeeGoLivePixmapPrivate> d_ptr; //! Private bits.
+};
+
+#endif
diff --git a/tools/qmeegographicssystemhelper/qmeegolivepixmap_p.h b/tools/qmeegographicssystemhelper/qmeegolivepixmap_p.h
new file mode 100644
index 0000000..78d9553
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegolivepixmap_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegolivepixmap.h"
+
+#ifndef QMEEGOLIVEPIXMAP_P_H
+#define QMEEGOLIVEPIXMAP_P_H
+
+class QMeeGoLivePixmapPrivate
+{
+public:
+ Q_DECLARE_PUBLIC(QMeeGoLivePixmap);
+ QMeeGoLivePixmapPrivate();
+ virtual ~QMeeGoLivePixmapPrivate();
+
+ QMeeGoLivePixmap *q_ptr;
+};
+
+#endif
diff --git a/tools/qmeegographicssystemhelper/qmeegooverlaywidget.cpp b/tools/qmeegographicssystemhelper/qmeegooverlaywidget.cpp
new file mode 100644
index 0000000..b42a7ea
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegooverlaywidget.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QDebug>
+#include <QEvent>
+#include <QMouseEvent>
+#include <QApplication>
+#include <QDesktopWidget>
+#include "qmeegooverlaywidget.h"
+#include "qmeegographicssystemhelper.h"
+#include "qmeegoruntime.h"
+
+QMeeGoOverlayWidget::QMeeGoOverlayWidget(int surfaceWidth, int surfaceHeight, QWidget *parent) : QWidget(parent, 0),
+ sw(surfaceWidth),
+ sh(surfaceHeight)
+{
+ if (! QMeeGoGraphicsSystemHelper::isRunningMeeGo())
+ qFatal("QMeeGoOverlayWidget can only be used when running with 'meego' graphics system!");
+
+ const QRect desktop = QApplication::desktop()->screenGeometry(parent);
+
+ QMeeGoRuntime::setSurfaceFixedSize(surfaceWidth, surfaceHeight);
+
+ scaleW = sw / desktop.width();
+ scaleH = sh / desktop.height();
+ installEventFilter(this);
+}
+
+QPoint QMeeGoOverlayWidget::convertPoint(const QPoint &p)
+{
+ int x = p.x() * scaleW;
+ int y = p.y() * scaleH;
+ return QPoint(x, y);
+}
+
+void QMeeGoOverlayWidget::showEvent(QShowEvent *)
+{
+ QMeeGoRuntime::setSurfaceScaling(0, 0, width(), height());
+}
+
+bool QMeeGoOverlayWidget::eventFilter(QObject *, QEvent *event)
+{
+ if (event->spontaneous() == false)
+ return false;
+
+ switch(event->type()) {
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ {
+ QMouseEvent *e = static_cast <QMouseEvent *>(event);
+ QMouseEvent newEvent = QMouseEvent(e->type(),
+ convertPoint(e->pos()),
+ convertPoint(e->globalPos()),
+ e->button(),
+ e->buttons(),
+ e->modifiers());
+ QCoreApplication::sendEvent(this, &newEvent);
+ return true;
+ }
+
+ default:
+ return false;
+ }
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegooverlaywidget.h b/tools/qmeegographicssystemhelper/qmeegooverlaywidget.h
new file mode 100644
index 0000000..e67f59b
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegooverlaywidget.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QMEEGOOVERLAYWIDGET_H
+#define QMEEGOOVERLAYWIDGET_H
+
+#include <QWidget>
+
+//! A widget automatically scaling it's content.
+/*!
+*/
+
+class Q_DECL_EXPORT QMeeGoOverlayWidget : public QWidget
+{
+public:
+ //! Constructs a new scaling widget.
+ /*!
+ The real surface used for this widget will have the specified
+ width and height.
+ */
+ QMeeGoOverlayWidget(int surfaceWidth, int surfaceHeight, QWidget *parent = 0);
+
+
+ //! Event filtering function.
+ /*!
+ Converts coordinates for mouse/touch event. Do not
+ call manually.
+ */
+ bool eventFilter(QObject *obj, QEvent *event);
+
+ //! Standard override.
+ /*!
+ The surface scaling on the target paint device is being
+ set when the widget is displayed for the first time.
+ */
+ virtual void showEvent(QShowEvent *event);
+
+private:
+ //! Converts coordinates between real & virtual area of the widget.
+ QPoint convertPoint(const QPoint &p);
+
+ int sw; /// Surface real width.
+ int sh; /// Surface real height.
+ float scaleW; /// Width scaling factor.
+ float scaleH; /// Height scaling factor.
+};
+
+#endif
diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.cpp b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp
new file mode 100644
index 0000000..2d3ee3c
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegoruntime.cpp
@@ -0,0 +1,234 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmeegoruntime.h"
+
+#include <private/qlibrary_p.h>
+#include <private/qfactoryloader_p.h>
+#include <private/qgraphicssystemplugin_p.h>
+#include <stdio.h>
+
+#define ENSURE_INITIALIZED {if (!initialized) initialize();}
+
+bool QMeeGoRuntime::initialized = false;
+
+typedef int (*QMeeGoImageToEglSharedImageFunc) (const QImage&);
+typedef QPixmapData* (*QMeeGoPixmapDataFromEglSharedImageFunc) (Qt::HANDLE handle, const QImage&);
+typedef QPixmapData* (*QMeeGoPixmapDataWithGLTextureFunc) (int w, int h);
+typedef bool (*QMeeGoDestroyEGLSharedImageFunc) (Qt::HANDLE handle);
+typedef void (*QMeeGoUpdateEglSharedImagePixmapFunc) (QPixmap*);
+typedef void (*QMeeGoSetSurfaceFixedSizeFunc) (int w, int h);
+typedef void (*QMeeGoSetSurfaceScalingFunc) (int x, int y, int w, int h);
+typedef void (*QMeeGoSetTranslucentFunc) (bool translucent);
+typedef QPixmapData* (*QMeeGoPixmapDataWithNewLiveTextureFunc) (int w, int h, QImage::Format format);
+typedef QPixmapData* (*QMeeGoPixmapDataFromLiveTextureHandleFunc) (Qt::HANDLE h);
+typedef QImage* (*QMeeGoLiveTextureLockFunc) (QPixmap*, void* fenceSync);
+typedef bool (*QMeeGoLiveTextureReleaseFunc) (QPixmap*, QImage *i);
+typedef Qt::HANDLE (*QMeeGoLiveTextureGetHandleFunc) (QPixmap*);
+typedef void* (*QMeeGoCreateFenceSyncFunc) (void);
+typedef void (*QMeeGoDestroyFenceSyncFunc) (void *fs);
+
+static QMeeGoImageToEglSharedImageFunc qt_meego_image_to_egl_shared_image = NULL;
+static QMeeGoPixmapDataFromEglSharedImageFunc qt_meego_pixmapdata_from_egl_shared_image = NULL;
+static QMeeGoPixmapDataWithGLTextureFunc qt_meego_pixmapdata_with_gl_texture = NULL;
+static QMeeGoDestroyEGLSharedImageFunc qt_meego_destroy_egl_shared_image = NULL;
+static QMeeGoUpdateEglSharedImagePixmapFunc qt_meego_update_egl_shared_image_pixmap = NULL;
+static QMeeGoSetSurfaceFixedSizeFunc qt_meego_set_surface_fixed_size = NULL;
+static QMeeGoSetSurfaceScalingFunc qt_meego_set_surface_scaling = NULL;
+static QMeeGoSetTranslucentFunc qt_meego_set_translucent = NULL;
+static QMeeGoPixmapDataWithNewLiveTextureFunc qt_meego_pixmapdata_with_new_live_texture = NULL;
+static QMeeGoPixmapDataFromLiveTextureHandleFunc qt_meego_pixmapdata_from_live_texture_handle = NULL;
+static QMeeGoLiveTextureLockFunc qt_meego_live_texture_lock = NULL;
+static QMeeGoLiveTextureReleaseFunc qt_meego_live_texture_release = NULL;
+static QMeeGoLiveTextureGetHandleFunc qt_meego_live_texture_get_handle = NULL;
+static QMeeGoCreateFenceSyncFunc qt_meego_create_fence_sync = NULL;
+static QMeeGoDestroyFenceSyncFunc qt_meego_destroy_fence_sync = NULL;
+
+void QMeeGoRuntime::initialize()
+{
+ QFactoryLoader loader(QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive);
+
+ QLibraryPrivate *libraryPrivate = loader.library(QLatin1String("meego"));
+ Q_ASSERT(libraryPrivate);
+
+ QLibrary library(libraryPrivate->fileName, libraryPrivate->fullVersion);
+
+ bool success = library.load();
+
+ if (success) {
+ qt_meego_image_to_egl_shared_image = (QMeeGoImageToEglSharedImageFunc) library.resolve("qt_meego_image_to_egl_shared_image");
+ qt_meego_pixmapdata_from_egl_shared_image = (QMeeGoPixmapDataFromEglSharedImageFunc) library.resolve("qt_meego_pixmapdata_from_egl_shared_image");
+ qt_meego_pixmapdata_with_gl_texture = (QMeeGoPixmapDataWithGLTextureFunc) library.resolve("qt_meego_pixmapdata_with_gl_texture");
+ qt_meego_destroy_egl_shared_image = (QMeeGoDestroyEGLSharedImageFunc) library.resolve("qt_meego_destroy_egl_shared_image");
+ qt_meego_update_egl_shared_image_pixmap = (QMeeGoUpdateEglSharedImagePixmapFunc) library.resolve("qt_meego_update_egl_shared_image_pixmap");
+ qt_meego_set_surface_fixed_size = (QMeeGoSetSurfaceFixedSizeFunc) library.resolve("qt_meego_set_surface_fixed_size");
+ qt_meego_set_surface_scaling = (QMeeGoSetSurfaceScalingFunc) library.resolve("qt_meego_set_surface_scaling");
+ qt_meego_set_translucent = (QMeeGoSetTranslucentFunc) library.resolve("qt_meego_set_translucent");
+ qt_meego_pixmapdata_with_new_live_texture = (QMeeGoPixmapDataWithNewLiveTextureFunc) library.resolve("qt_meego_pixmapdata_with_new_live_texture");
+ qt_meego_pixmapdata_from_live_texture_handle = (QMeeGoPixmapDataFromLiveTextureHandleFunc) library.resolve("qt_meego_pixmapdata_from_live_texture_handle");
+ qt_meego_live_texture_lock = (QMeeGoLiveTextureLockFunc) library.resolve("qt_meego_live_texture_lock");
+ qt_meego_live_texture_release = (QMeeGoLiveTextureReleaseFunc) library.resolve("qt_meego_live_texture_release");
+ qt_meego_live_texture_get_handle = (QMeeGoLiveTextureGetHandleFunc) library.resolve("qt_meego_live_texture_get_handle");
+ qt_meego_create_fence_sync = (QMeeGoCreateFenceSyncFunc) library.resolve("qt_meego_create_fence_sync");
+ qt_meego_destroy_fence_sync = (QMeeGoDestroyFenceSyncFunc) library.resolve("qt_meego_destroy_fence_sync");
+
+ if (qt_meego_image_to_egl_shared_image && qt_meego_pixmapdata_from_egl_shared_image &&
+ qt_meego_pixmapdata_with_gl_texture && qt_meego_destroy_egl_shared_image && qt_meego_update_egl_shared_image_pixmap &&
+ qt_meego_set_surface_fixed_size && qt_meego_set_surface_scaling && qt_meego_set_translucent &&
+ qt_meego_pixmapdata_with_new_live_texture && qt_meego_pixmapdata_from_live_texture_handle &&
+ qt_meego_live_texture_lock && qt_meego_live_texture_release && qt_meego_live_texture_get_handle &&
+ qt_meego_create_fence_sync && qt_meego_destroy_fence_sync)
+ {
+ qDebug("Successfully resolved MeeGo graphics system: %s %s\n", qPrintable(libraryPrivate->fileName), qPrintable(libraryPrivate->fullVersion));
+ } else {
+ Q_ASSERT(false);
+ }
+ } else {
+ Q_ASSERT(false);
+ }
+
+ initialized = true;
+}
+
+Qt::HANDLE QMeeGoRuntime::imageToEGLSharedImage(const QImage &image)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_image_to_egl_shared_image);
+ return qt_meego_image_to_egl_shared_image(image);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_from_egl_shared_image);
+ return qt_meego_pixmapdata_from_egl_shared_image(handle, softImage);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataWithGLTexture(int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_with_gl_texture);
+ return qt_meego_pixmapdata_with_gl_texture(w, h);
+}
+
+bool QMeeGoRuntime::destroyEGLSharedImage(Qt::HANDLE handle)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_destroy_egl_shared_image);
+ return qt_meego_destroy_egl_shared_image(handle);
+}
+
+void QMeeGoRuntime::updateEGLSharedImagePixmap(QPixmap *p)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_update_egl_shared_image_pixmap);
+ return qt_meego_update_egl_shared_image_pixmap(p);
+}
+
+void QMeeGoRuntime::setSurfaceFixedSize(int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_surface_fixed_size);
+ qt_meego_set_surface_fixed_size(w, h);
+}
+
+void QMeeGoRuntime::setSurfaceScaling(int x, int y, int w, int h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_surface_scaling);
+ qt_meego_set_surface_scaling(x, y, w, h);
+}
+
+void QMeeGoRuntime::setTranslucent(bool translucent)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_set_translucent);
+ qt_meego_set_translucent(translucent);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_with_new_live_texture);
+ return qt_meego_pixmapdata_with_new_live_texture(w, h, format);
+}
+
+QPixmapData* QMeeGoRuntime::pixmapDataFromLiveTextureHandle(Qt::HANDLE h)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_pixmapdata_from_live_texture_handle);
+ return qt_meego_pixmapdata_from_live_texture_handle(h);
+}
+
+QImage* QMeeGoRuntime::lockLiveTexture(QPixmap *p, void* fenceSync)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_lock);
+ return qt_meego_live_texture_lock(p, fenceSync);
+}
+
+bool QMeeGoRuntime::releaseLiveTexture(QPixmap *p, QImage *i)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_release);
+ return qt_meego_live_texture_release(p, i);
+}
+
+Qt::HANDLE QMeeGoRuntime::getLiveTextureHandle(QPixmap *pixmap)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_live_texture_get_handle);
+ return qt_meego_live_texture_get_handle(pixmap);
+}
+
+void* QMeeGoRuntime::createFenceSync()
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_create_fence_sync);
+ return qt_meego_create_fence_sync();
+}
+
+void QMeeGoRuntime::destroyFenceSync(void *fs)
+{
+ ENSURE_INITIALIZED;
+ Q_ASSERT(qt_meego_destroy_fence_sync);
+ qt_meego_destroy_fence_sync(fs);
+}
diff --git a/tools/qmeegographicssystemhelper/qmeegoruntime.h b/tools/qmeegographicssystemhelper/qmeegoruntime.h
new file mode 100644
index 0000000..be6ff6b
--- /dev/null
+++ b/tools/qmeegographicssystemhelper/qmeegoruntime.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the plugins 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QPixmap>
+#include <QImage>
+
+class QMeeGoRuntime
+{
+public:
+ static void initialize();
+
+ static Qt::HANDLE imageToEGLSharedImage(const QImage &image);
+ static QPixmapData* pixmapDataFromEGLSharedImage(Qt::HANDLE handle, const QImage &softImage);
+ static QPixmapData* pixmapDataWithGLTexture(int w, int h);
+ static bool destroyEGLSharedImage(Qt::HANDLE handle);
+ static void updateEGLSharedImagePixmap(QPixmap *p);
+ static void setSurfaceFixedSize(int w, int h);
+ static void setSurfaceScaling(int x, int y, int w, int h);
+ static void setTranslucent(bool translucent);
+ static QPixmapData* pixmapDataWithNewLiveTexture(int w, int h, QImage::Format format);
+ static QPixmapData* pixmapDataFromLiveTextureHandle(Qt::HANDLE h);
+ static QImage* lockLiveTexture(QPixmap *pixmap, void *fenceSync);
+ static bool releaseLiveTexture(QPixmap *pixmap, QImage *image);
+ static Qt::HANDLE getLiveTextureHandle(QPixmap *pixmap);
+ static void* createFenceSync();
+ static void destroyFenceSync(void *fs);
+
+private:
+ static bool initialized;
+};
diff --git a/tools/qml/Info_mac.plist b/tools/qml/Info_mac.plist
new file mode 100644
index 0000000..0877547
--- /dev/null
+++ b/tools/qml/Info_mac.plist
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.1">
+<dict>
+ <key>CFBundleIconFile</key>
+ <string>@ICON@</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.nokia.qt.qml</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Created by Qt/QMake</string>
+ <key>CFBundleSignature</key>
+ <string>@TYPEINFO@</string>
+ <key>CFBundleExecutable</key>
+ <string>@EXECUTABLE@</string>
+ <key>UTExportedTypeDeclarations</key>
+ <array>
+ <dict>
+ <key>UTTypeIdentifier</key>
+ <string>com.nokia.qt.qml</string>
+ <key>UTTypeDescription</key>
+ <string>Qt Markup Language</string>
+ <key>UTTypeConformsTo</key>
+ <array>
+ <string>public.plain-text</string>
+ </array>
+ <key>UTTypeTagSpecification</key>
+ <dict>
+ <key>public.filename-extension</key>
+ <array>
+ <string>qml</string>
+ </array>
+ </dict>
+ </dict>
+ </array>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>LSItemContentTypes</key>
+ <array>
+ <string>com.nokia.qt.qml</string>
+ </array>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ </dict>
+ </array>
+</dict>
+</plist>
diff --git a/tools/qml/browser/Browser.qml b/tools/qml/browser/Browser.qml
new file mode 100644
index 0000000..ebed72f
--- /dev/null
+++ b/tools/qml/browser/Browser.qml
@@ -0,0 +1,318 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+import Qt.labs.folderlistmodel 1.0
+
+Rectangle {
+ id: root
+ property bool showFocusHighlight: false
+ property variant folders: folders1
+ property variant view: view1
+ width: 320
+ height: 480
+ color: palette.window
+
+ FolderListModel {
+ id: folders1
+ nameFilters: [ "*.qml" ]
+ folder: qmlViewerFolder
+ }
+ FolderListModel {
+ id: folders2
+ nameFilters: [ "*.qml" ]
+ folder: qmlViewerFolder
+ }
+
+ SystemPalette { id: palette }
+
+ function down(path) {
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitLeft";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitLeft";
+ }
+ view.x = root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+ function up() {
+ var path = folders.parentFolder;
+ if (folders == folders1) {
+ view = view2
+ folders = folders2;
+ view1.state = "exitRight";
+ } else {
+ view = view1
+ folders = folders1;
+ view2.state = "exitRight";
+ }
+ view.x = -root.width;
+ view.state = "current";
+ view.focus = true;
+ folders.folder = path;
+ }
+ function keyPressed(key) {
+ switch (key) {
+ case Qt.Key_Up:
+ case Qt.Key_Down:
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.showFocusHighlight = true;
+ break;
+ default:
+ // do nothing
+ break;
+ }
+ }
+
+ Component {
+ id: folderDelegate
+ Rectangle {
+ id: wrapper
+ function launch() {
+ if (folders.isFolder(index)) {
+ down(filePath);
+ } else {
+ qmlViewer.launch(filePath);
+ }
+ }
+ width: root.width
+ height: 52
+ color: "transparent"
+ Rectangle {
+ id: highlight; visible: false
+ anchors.fill: parent
+ color: palette.highlight
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ }
+ Item {
+ width: 48; height: 48
+ Image { source: "images/folder.png"; anchors.centerIn: parent; visible: folders.isFolder(index)}
+ }
+ Text {
+ id: nameText
+ anchors.fill: parent; verticalAlignment: Text.AlignVCenter
+ text: fileName
+ anchors.leftMargin: 54
+ font.pixelSize: 32
+ color: (wrapper.ListView.isCurrentItem && root.showFocusHighlight) ? palette.highlightedText : palette.windowText
+ elide: Text.ElideRight
+ }
+ MouseArea {
+ id: mouseRegion
+ anchors.fill: parent
+ onPressed: {
+ root.showFocusHighlight = false;
+ wrapper.ListView.view.currentIndex = index;
+ }
+ onClicked: { if (folders == wrapper.ListView.view.model) launch() }
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: mouseRegion.pressed
+ PropertyChanges { target: highlight; visible: true }
+ PropertyChanges { target: nameText; color: palette.highlightedText }
+ }
+ ]
+ }
+ }
+
+ ListView {
+ id: view1
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: 0
+ width: parent.width
+ model: folders1
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view1.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem.width
+ }
+ highlightMoveSpeed: 1000
+ pressDelay: 100
+ focus: true
+ state: "current"
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view1; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view1; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view1; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ ListView {
+ id: view2
+ anchors.top: titleBar.bottom
+ anchors.bottom: parent.bottom
+ x: parent.width
+ width: parent.width
+ model: folders2
+ delegate: folderDelegate
+ highlight: Rectangle {
+ color: palette.highlight
+ visible: root.showFocusHighlight && view2.count != 0
+ gradient: Gradient {
+ GradientStop { id: t1; position: 0.0; color: palette.highlight }
+ GradientStop { id: t2; position: 1.0; color: Qt.lighter(palette.highlight) }
+ }
+ width: view1.currentItem.width
+ }
+ highlightMoveSpeed: 1000
+ pressDelay: 100
+ states: [
+ State {
+ name: "current"
+ PropertyChanges { target: view2; x: 0 }
+ },
+ State {
+ name: "exitLeft"
+ PropertyChanges { target: view2; x: -root.width }
+ },
+ State {
+ name: "exitRight"
+ PropertyChanges { target: view2; x: root.width }
+ }
+ ]
+ transitions: [
+ Transition {
+ to: "current"
+ SequentialAnimation {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ },
+ Transition {
+ NumberAnimation { properties: "x"; duration: 250 }
+ }
+ ]
+ Keys.onPressed: root.keyPressed(event.key)
+ }
+
+ Keys.onPressed: {
+ root.keyPressed(event.key);
+ if (event.key == Qt.Key_Return || event.key == Qt.Key_Select || event.key == Qt.Key_Right) {
+ view.currentItem.launch();
+ event.accepted = true;
+ } else if (event.key == Qt.Key_Left) {
+ up();
+ }
+ }
+
+ BorderImage {
+ source: "images/titlebar.sci";
+ width: parent.width;
+ height: 52
+ y: -7
+ id: titleBar
+
+ Rectangle {
+ id: upButton
+ width: 48
+ height: titleBar.height - 7
+ color: "transparent"
+
+ Image { anchors.centerIn: parent; source: "images/up.png" }
+ MouseArea { id: upRegion; anchors.centerIn: parent
+ width: 56
+ height: 56
+ onClicked: if (folders.parentFolder != "") up()
+ }
+ states: [
+ State {
+ name: "pressed"
+ when: upRegion.pressed
+ PropertyChanges { target: upButton; color: palette.highlight }
+ }
+ ]
+ }
+ Rectangle {
+ color: "gray"
+ x: 48
+ width: 1
+ height: 44
+ }
+
+ Text {
+ anchors.left: upButton.right; anchors.right: parent.right; height: parent.height
+ anchors.leftMargin: 4; anchors.rightMargin: 4
+ text: folders.folder
+ color: "white"
+ elide: Text.ElideLeft; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignVCenter
+ font.pixelSize: 32
+ }
+ }
+}
diff --git a/tools/qml/browser/browser.qrc b/tools/qml/browser/browser.qrc
new file mode 100644
index 0000000..9c688e7
--- /dev/null
+++ b/tools/qml/browser/browser.qrc
@@ -0,0 +1,9 @@
+<RCC>
+ <qresource prefix="/browser">
+ <file>Browser.qml</file>
+ <file>images/up.png</file>
+ <file>images/folder.png</file>
+ <file>images/titlebar.sci</file>
+ <file>images/titlebar.png</file>
+ </qresource>
+</RCC>
diff --git a/tools/qml/browser/images/folder.png b/tools/qml/browser/images/folder.png
new file mode 100644
index 0000000..e53e2ad
--- /dev/null
+++ b/tools/qml/browser/images/folder.png
Binary files differ
diff --git a/tools/qml/browser/images/titlebar.png b/tools/qml/browser/images/titlebar.png
new file mode 100644
index 0000000..51c9008
--- /dev/null
+++ b/tools/qml/browser/images/titlebar.png
Binary files differ
diff --git a/tools/qml/browser/images/titlebar.sci b/tools/qml/browser/images/titlebar.sci
new file mode 100644
index 0000000..0418d94
--- /dev/null
+++ b/tools/qml/browser/images/titlebar.sci
@@ -0,0 +1,5 @@
+border.left: 10
+border.top: 12
+border.bottom: 12
+border.right: 10
+source: titlebar.png
diff --git a/tools/qml/browser/images/up.png b/tools/qml/browser/images/up.png
new file mode 100644
index 0000000..b05f802
--- /dev/null
+++ b/tools/qml/browser/images/up.png
Binary files differ
diff --git a/tools/qml/deviceorientation.cpp b/tools/qml/deviceorientation.cpp
new file mode 100644
index 0000000..d3014ad
--- /dev/null
+++ b/tools/qml/deviceorientation.cpp
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+
+QT_USE_NAMESPACE
+
+class DefaultDeviceOrientation : public DeviceOrientation
+{
+ Q_OBJECT
+public:
+ DefaultDeviceOrientation() : DeviceOrientation(), m_orientation(DeviceOrientation::Portrait) {}
+
+ Orientation orientation() const {
+ return m_orientation;
+ }
+
+ void pauseListening() {
+ }
+ void resumeListening() {
+ }
+
+ void setOrientation(Orientation o) {
+ if (o != m_orientation) {
+ m_orientation = o;
+ emit orientationChanged();
+ }
+ }
+
+ Orientation m_orientation;
+};
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static DefaultDeviceOrientation *o = 0;
+ if (!o)
+ o = new DefaultDeviceOrientation;
+ return o;
+}
+
+#include "deviceorientation.moc"
+
diff --git a/tools/qml/deviceorientation.h b/tools/qml/deviceorientation.h
new file mode 100644
index 0000000..487ebd4
--- /dev/null
+++ b/tools/qml/deviceorientation.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef ORIENTATION_H
+#define ORIENTATION_H
+
+#include <QObject>
+
+QT_BEGIN_NAMESPACE
+
+class DeviceOrientationPrivate;
+class DeviceOrientation : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(Orientation)
+public:
+ enum Orientation {
+ UnknownOrientation,
+ Portrait,
+ Landscape,
+ PortraitInverted,
+ LandscapeInverted
+ };
+
+ virtual Orientation orientation() const = 0;
+ virtual void setOrientation(Orientation) = 0;
+
+ virtual void pauseListening() = 0;
+ virtual void resumeListening() = 0;
+
+ static DeviceOrientation *instance();
+
+signals:
+ void orientationChanged();
+
+protected:
+ DeviceOrientation() {}
+
+private:
+ DeviceOrientationPrivate *d_ptr;
+ friend class DeviceOrientationPrivate;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qml/deviceorientation_harmattan.cpp b/tools/qml/deviceorientation_harmattan.cpp
new file mode 100644
index 0000000..22f9f4c
--- /dev/null
+++ b/tools/qml/deviceorientation_harmattan.cpp
@@ -0,0 +1,161 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+#include <QtDBus>
+#include <QDebug>
+
+#define ORIENTATION_SERVICE "com.nokia.SensorService"
+#define ORIENTATION_PATH "/org/maemo/contextkit/Screen/TopEdge"
+#define CONTEXT_INTERFACE "org.maemo.contextkit.Property"
+#define CONTEXT_CHANGED "ValueChanged"
+#define CONTEXT_SUBSCRIBE "Subscribe"
+#define CONTEXT_UNSUBSCRIBE "Unsubscribe"
+#define CONTEXT_GET "Get"
+
+
+class HarmattanOrientation : public DeviceOrientation
+{
+ Q_OBJECT
+public:
+ HarmattanOrientation()
+ : o(UnknownOrientation), sensorEnabled(false)
+ {
+ resumeListening();
+ // connect to the orientation change signal
+ bool ok = QDBusConnection::systemBus().connect(ORIENTATION_SERVICE, ORIENTATION_PATH,
+ CONTEXT_INTERFACE,
+ CONTEXT_CHANGED,
+ this,
+ SLOT(deviceOrientationChanged(QList<QVariant>,quint64)));
+// qDebug() << "connection OK" << ok;
+ QDBusMessage reply = QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(ORIENTATION_SERVICE, ORIENTATION_PATH,
+ CONTEXT_INTERFACE, CONTEXT_GET));
+ if (reply.type() != QDBusMessage::ErrorMessage) {
+ QList<QVariant> args;
+ qvariant_cast<QDBusArgument>(reply.arguments().at(0)) >> args;
+ deviceOrientationChanged(args, 0);
+ }
+ }
+
+ ~HarmattanOrientation()
+ {
+ // unsubscribe from the orientation sensor
+ if (sensorEnabled)
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(ORIENTATION_SERVICE, ORIENTATION_PATH,
+ CONTEXT_INTERFACE, CONTEXT_UNSUBSCRIBE));
+ }
+
+ inline Orientation orientation() const
+ {
+ return o;
+ }
+
+ void setOrientation(Orientation)
+ {
+ }
+
+ void pauseListening() {
+ if (sensorEnabled) {
+ // unsubscribe from the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(ORIENTATION_SERVICE, ORIENTATION_PATH,
+ CONTEXT_INTERFACE, CONTEXT_UNSUBSCRIBE));
+ sensorEnabled = false;
+ }
+ }
+
+ void resumeListening() {
+ if (!sensorEnabled) {
+ // subscribe to the orientation sensor
+ QDBusMessage reply = QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(ORIENTATION_SERVICE, ORIENTATION_PATH,
+ CONTEXT_INTERFACE, CONTEXT_SUBSCRIBE));
+
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage()));
+ } else {
+ sensorEnabled = true;
+ }
+ }
+ }
+
+private Q_SLOTS:
+ void deviceOrientationChanged(QList<QVariant> args,quint64)
+ {
+ if (args.count() == 0)
+ return;
+ Orientation newOrientation = toOrientation(args.at(0).toString());
+ if (newOrientation != o) {
+ o = newOrientation;
+ emit orientationChanged();
+ }
+// qDebug() << "orientation" << args.at(0).toString();
+ }
+
+private:
+ static Orientation toOrientation(const QString &nativeOrientation)
+ {
+ if (nativeOrientation == "top")
+ return Landscape;
+ else if (nativeOrientation == "left")
+ return Portrait;
+ else if (nativeOrientation == "bottom")
+ return LandscapeInverted;
+ else if (nativeOrientation == "right")
+ return PortraitInverted;
+ return UnknownOrientation;
+ }
+
+private:
+ Orientation o;
+ bool sensorEnabled;
+};
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static HarmattanOrientation *o = new HarmattanOrientation;
+ return o;
+}
+
+#include "deviceorientation_harmattan.moc"
diff --git a/tools/qml/deviceorientation_maemo5.cpp b/tools/qml/deviceorientation_maemo5.cpp
new file mode 100644
index 0000000..a324820
--- /dev/null
+++ b/tools/qml/deviceorientation_maemo5.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+#include <QtDBus>
+
+#include <mce/mode-names.h>
+#include <mce/dbus-names.h>
+
+class MaemoOrientation : public DeviceOrientation
+{
+ Q_OBJECT
+public:
+ MaemoOrientation()
+ : o(UnknownOrientation), sensorEnabled(false)
+ {
+ resumeListening();
+ // connect to the orientation change signal
+ QDBusConnection::systemBus().connect(QString(), MCE_SIGNAL_PATH, MCE_SIGNAL_IF,
+ MCE_DEVICE_ORIENTATION_SIG,
+ this,
+ SLOT(deviceOrientationChanged(QString)));
+ }
+
+ ~MaemoOrientation()
+ {
+ // disable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_DISABLE_REQ));
+ }
+
+ inline Orientation orientation() const
+ {
+ return o;
+ }
+
+ void setOrientation(Orientation o)
+ {
+ }
+
+ void pauseListening() {
+ if (sensorEnabled) {
+ // disable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_DISABLE_REQ));
+ sensorEnabled = false;
+ }
+ }
+
+ void resumeListening() {
+ if (!sensorEnabled) {
+ // enable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_ENABLE_REQ));
+
+ QDBusMessage reply = QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET));
+
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage()));
+ } else {
+ Orientation orientation = toOrientation(reply.arguments().value(0).toString());
+ if (o != orientation) {
+ o = orientation;
+ emit orientationChanged();
+ }
+ sensorEnabled = true;
+ }
+ }
+ }
+
+private Q_SLOTS:
+ void deviceOrientationChanged(const QString &newOrientation)
+ {
+ o = toOrientation(newOrientation);
+
+ emit orientationChanged();
+// printf("%d\n", o);
+ }
+
+private:
+ static Orientation toOrientation(const QString &nativeOrientation)
+ {
+ if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE)
+ return Landscape;
+ else if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE_INVERTED)
+ return LandscapeInverted;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT)
+ return Portrait;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT_INVERTED)
+ return PortraitInverted;
+ return UnknownOrientation;
+ }
+
+private:
+ Orientation o;
+ bool sensorEnabled;
+};
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static MaemoOrientation *o = new MaemoOrientation;
+ return o;
+}
+
+#include "deviceorientation_maemo5.moc"
diff --git a/tools/qml/deviceorientation_symbian.cpp b/tools/qml/deviceorientation_symbian.cpp
new file mode 100644
index 0000000..7710cf9
--- /dev/null
+++ b/tools/qml/deviceorientation_symbian.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deviceorientation.h"
+
+#include <e32base.h>
+#include <sensrvchannelfinder.h>
+#include <sensrvdatalistener.h>
+#include <sensrvchannel.h>
+#include <sensrvorientationsensor.h>
+
+class SymbianOrientation : public DeviceOrientation, public MSensrvDataListener
+{
+ Q_OBJECT
+public:
+ SymbianOrientation()
+ : DeviceOrientation(), m_current(UnknownOrientation), m_sensorChannel(0), m_channelOpen(false)
+ {
+ TRAP_IGNORE(initL());
+ if (!m_sensorChannel)
+ qWarning("No valid sensors found.");
+ }
+
+ ~SymbianOrientation()
+ {
+ if (m_sensorChannel) {
+ m_sensorChannel->StopDataListening();
+ m_sensorChannel->CloseChannel();
+ delete m_sensorChannel;
+ }
+ }
+
+ void initL()
+ {
+ CSensrvChannelFinder *channelFinder = CSensrvChannelFinder::NewLC();
+ RSensrvChannelInfoList channelInfoList;
+ CleanupClosePushL(channelInfoList);
+
+ TSensrvChannelInfo searchConditions;
+ searchConditions.iChannelType = KSensrvChannelTypeIdOrientationData;
+ channelFinder->FindChannelsL(channelInfoList, searchConditions);
+
+ for (int i = 0; i < channelInfoList.Count(); ++i) {
+ TRAPD(error, m_sensorChannel = CSensrvChannel::NewL(channelInfoList[i]));
+ if (!error)
+ TRAP(error, m_sensorChannel->OpenChannelL());
+ if (!error) {
+ TRAP(error, m_sensorChannel->StartDataListeningL(this, 1, 1, 0));
+ m_channelOpen = true;
+ break;
+ }
+ if (error) {
+ delete m_sensorChannel;
+ m_sensorChannel = 0;
+ }
+ }
+
+ channelInfoList.Close();
+ CleanupStack::Pop(&channelInfoList);
+ CleanupStack::PopAndDestroy(channelFinder);
+ }
+
+ Orientation orientation() const
+ {
+ return m_current;
+ }
+
+ void setOrientation(Orientation) { }
+
+private:
+ DeviceOrientation::Orientation m_current;
+ CSensrvChannel *m_sensorChannel;
+ bool m_channelOpen;
+ void pauseListening() {
+ if (m_sensorChannel && m_channelOpen) {
+ m_sensorChannel->StopDataListening();
+ m_sensorChannel->CloseChannel();
+ m_channelOpen = false;
+ }
+ }
+
+ void resumeListening() {
+ if (m_sensorChannel && !m_channelOpen) {
+ TRAPD(error, m_sensorChannel->OpenChannelL());
+ if (!error) {
+ TRAP(error, m_sensorChannel->StartDataListeningL(this, 1, 1, 0));
+ if (!error) {
+ m_channelOpen = true;
+ }
+ }
+ if (error) {
+ delete m_sensorChannel;
+ m_sensorChannel = 0;
+ }
+ }
+ }
+
+ void DataReceived(CSensrvChannel &channel, TInt count, TInt dataLost)
+ {
+ Q_UNUSED(dataLost)
+ if (channel.GetChannelInfo().iChannelType == KSensrvChannelTypeIdOrientationData) {
+ TSensrvOrientationData data;
+ for (int i = 0; i < count; ++i) {
+ TPckgBuf<TSensrvOrientationData> dataBuf;
+ channel.GetData(dataBuf);
+ data = dataBuf();
+ Orientation orientation = UnknownOrientation;
+ switch (data.iDeviceOrientation) {
+ case TSensrvOrientationData::EOrientationDisplayUp:
+ orientation = Portrait;
+ break;
+ case TSensrvOrientationData::EOrientationDisplayRightUp:
+ orientation = Landscape;
+ break;
+ case TSensrvOrientationData::EOrientationDisplayLeftUp:
+ orientation = LandscapeInverted;
+ break;
+ case TSensrvOrientationData::EOrientationDisplayDown:
+ orientation = PortraitInverted;
+ break;
+ case TSensrvOrientationData::EOrientationUndefined:
+ case TSensrvOrientationData::EOrientationDisplayUpwards:
+ case TSensrvOrientationData::EOrientationDisplayDownwards:
+ default:
+ break;
+ }
+
+ if (m_current != orientation && orientation != UnknownOrientation) {
+ m_current = orientation;
+ emit orientationChanged();
+ }
+ }
+ }
+ }
+
+ void DataError(CSensrvChannel& /* channel */, TSensrvErrorSeverity /* error */)
+ {
+ }
+
+ void GetDataListenerInterfaceL(TUid /* interfaceUid */, TAny*& /* interface */)
+ {
+ }
+};
+
+
+DeviceOrientation* DeviceOrientation::instance()
+{
+ static SymbianOrientation *o = 0;
+ if (!o)
+ o = new SymbianOrientation;
+ return o;
+}
+
+#include "deviceorientation_symbian.moc"
diff --git a/tools/qml/loggerwidget.cpp b/tools/qml/loggerwidget.cpp
new file mode 100644
index 0000000..8aa029f
--- /dev/null
+++ b/tools/qml/loggerwidget.cpp
@@ -0,0 +1,201 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qglobal.h>
+#include <QDebug>
+#include <QSettings>
+#include <QActionGroup>
+#include <QMenu>
+#include <QPlainTextEdit>
+#ifdef Q_WS_MAEMO_5
+# include <QScrollArea>
+# include <QVBoxLayout>
+# include "texteditautoresizer_maemo5.h"
+#endif
+
+#include "loggerwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+LoggerWidget::LoggerWidget(QWidget *parent) :
+ QMainWindow(parent),
+ m_visibilityOrigin(SettingsOrigin)
+{
+ setAttribute(Qt::WA_QuitOnClose, false);
+ setWindowTitle(tr("Warnings"));
+
+ m_plainTextEdit = new QPlainTextEdit();
+
+#ifdef Q_WS_MAEMO_5
+ new TextEditAutoResizer(m_plainTextEdit);
+ setAttribute(Qt::WA_Maemo5StackedWindow);
+ QScrollArea *area = new QScrollArea();
+ area->setWidget(m_plainTextEdit);
+ area->setWidgetResizable(true);
+ setCentralWidget(area);
+#else
+ setCentralWidget(m_plainTextEdit);
+#endif
+ readSettings();
+ setupPreferencesMenu();
+}
+
+void LoggerWidget::append(const QString &msg)
+{
+ m_plainTextEdit->appendPlainText(msg);
+
+ if (!isVisible() && (defaultVisibility() == AutoShowWarnings))
+ setVisible(true);
+}
+
+LoggerWidget::Visibility LoggerWidget::defaultVisibility() const
+{
+ return m_visibility;
+}
+
+void LoggerWidget::setDefaultVisibility(LoggerWidget::Visibility visibility)
+{
+ if (m_visibility == visibility)
+ return;
+
+ m_visibility = visibility;
+ m_visibilityOrigin = CommandLineOrigin;
+
+ m_preferencesMenu->setEnabled(m_visibilityOrigin == SettingsOrigin);
+}
+
+QMenu *LoggerWidget::preferencesMenu()
+{
+ return m_preferencesMenu;
+}
+
+QAction *LoggerWidget::showAction()
+{
+ return m_showWidgetAction;
+}
+
+void LoggerWidget::readSettings()
+{
+ QSettings settings;
+ QString warningsPreferences = settings.value("warnings", "hide").toString();
+ if (warningsPreferences == "show") {
+ m_visibility = ShowWarnings;
+ } else if (warningsPreferences == "hide") {
+ m_visibility = HideWarnings;
+ } else {
+ m_visibility = AutoShowWarnings;
+ }
+}
+
+void LoggerWidget::saveSettings()
+{
+ if (m_visibilityOrigin != SettingsOrigin)
+ return;
+
+ QString value = "autoShow";
+ if (defaultVisibility() == ShowWarnings) {
+ value = "show";
+ } else if (defaultVisibility() == HideWarnings) {
+ value = "hide";
+ }
+
+ QSettings settings;
+ settings.setValue("warnings", value);
+}
+
+void LoggerWidget::warningsPreferenceChanged(QAction *action)
+{
+ Visibility newSetting = static_cast<Visibility>(action->data().toInt());
+ m_visibility = newSetting;
+ saveSettings();
+}
+
+void LoggerWidget::showEvent(QShowEvent *event)
+{
+ QWidget::showEvent(event);
+ emit opened();
+}
+
+void LoggerWidget::closeEvent(QCloseEvent *event)
+{
+ QWidget::closeEvent(event);
+ emit closed();
+}
+
+void LoggerWidget::setupPreferencesMenu()
+{
+ m_preferencesMenu = new QMenu(tr("Warnings"));
+ QActionGroup *warnings = new QActionGroup(m_preferencesMenu);
+ warnings->setExclusive(true);
+
+ connect(warnings, SIGNAL(triggered(QAction*)), this, SLOT(warningsPreferenceChanged(QAction*)));
+
+ QAction *showWarningsPreference = new QAction(tr("Show by default"), m_preferencesMenu);
+ showWarningsPreference->setCheckable(true);
+ showWarningsPreference->setData(LoggerWidget::ShowWarnings);
+ warnings->addAction(showWarningsPreference);
+ m_preferencesMenu->addAction(showWarningsPreference);
+
+ QAction *hideWarningsPreference = new QAction(tr("Hide by default"), m_preferencesMenu);
+ hideWarningsPreference->setCheckable(true);
+ hideWarningsPreference->setData(LoggerWidget::HideWarnings);
+ warnings->addAction(hideWarningsPreference);
+ m_preferencesMenu->addAction(hideWarningsPreference);
+
+ QAction *autoWarningsPreference = new QAction(tr("Show for first warning"), m_preferencesMenu);
+ autoWarningsPreference->setCheckable(true);
+ autoWarningsPreference->setData(LoggerWidget::AutoShowWarnings);
+ warnings->addAction(autoWarningsPreference);
+ m_preferencesMenu->addAction(autoWarningsPreference);
+
+ switch (defaultVisibility()) {
+ case LoggerWidget::ShowWarnings:
+ showWarningsPreference->setChecked(true);
+ break;
+ case LoggerWidget::HideWarnings:
+ hideWarningsPreference->setChecked(true);
+ break;
+ default:
+ autoWarningsPreference->setChecked(true);
+ }
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qml/loggerwidget.h b/tools/qml/loggerwidget.h
new file mode 100644
index 0000000..13c319f
--- /dev/null
+++ b/tools/qml/loggerwidget.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef LOGGERWIDGET_H
+#define LOGGERWIDGET_H
+
+#include <QMainWindow>
+#include <QMetaType>
+
+QT_BEGIN_NAMESPACE
+
+class QPlainTextEdit;
+class QMenu;
+class QAction;
+
+class LoggerWidget : public QMainWindow {
+ Q_OBJECT
+public:
+ LoggerWidget(QWidget *parent=0);
+
+ enum Visibility { ShowWarnings, HideWarnings, AutoShowWarnings };
+
+ Visibility defaultVisibility() const;
+ void setDefaultVisibility(Visibility visibility);
+
+ QMenu *preferencesMenu();
+ QAction *showAction();
+
+public slots:
+ void append(const QString &msg);
+
+private slots:
+ void warningsPreferenceChanged(QAction *action);
+ void readSettings();
+ void saveSettings();
+
+protected:
+ void showEvent(QShowEvent *event);
+ void closeEvent(QCloseEvent *event);
+
+signals:
+ void opened();
+ void closed();
+
+private:
+ void setupPreferencesMenu();
+
+ QMenu *m_preferencesMenu;
+ QAction *m_showWidgetAction;
+ QPlainTextEdit *m_plainTextEdit;
+
+ enum ConfigOrigin { CommandLineOrigin, SettingsOrigin };
+ ConfigOrigin m_visibilityOrigin;
+ Visibility m_visibility;
+};
+
+QT_END_NAMESPACE
+
+Q_DECLARE_METATYPE(LoggerWidget::Visibility)
+
+#endif // LOGGERWIDGET_H
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
new file mode 100644
index 0000000..579f1ab
--- /dev/null
+++ b/tools/qml/main.cpp
@@ -0,0 +1,594 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qdeclarative.h"
+#include "qmlruntime.h"
+#include "qdeclarativeengine.h"
+#include "loggerwidget.h"
+#include <QWidget>
+#include <QDir>
+#include <QApplication>
+#include <QTranslator>
+#include <QDebug>
+#include <QMessageBox>
+#include <QAtomicInt>
+#include "qdeclarativetester.h"
+
+QT_USE_NAMESPACE
+
+QtMsgHandler systemMsgOutput = 0;
+
+static QDeclarativeViewer *openFile(const QString &fileName);
+static void showViewer(QDeclarativeViewer *viewer);
+
+#if defined (Q_OS_SYMBIAN)
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+void myMessageOutput(QtMsgType type, const char *msg)
+{
+ static int fd = -1;
+ if (fd == -1)
+ fd = ::open("E:\\qml.log", O_WRONLY | O_CREAT);
+
+ ::write(fd, msg, strlen(msg));
+ ::write(fd, "\n", 1);
+ ::fsync(fd);
+
+ switch (type) {
+ case QtFatalMsg:
+ abort();
+ }
+}
+
+#else // !defined (Q_OS_SYMBIAN)
+
+QWeakPointer<LoggerWidget> logger;
+
+QString warnings;
+void showWarnings()
+{
+ if (!warnings.isEmpty()) {
+ int argc = 0; char **argv = 0;
+ QApplication application(argc, argv); // QApplication() in main has been destroyed already.
+ Q_UNUSED(application)
+ QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings);
+ }
+}
+
+static QAtomicInt recursiveLock(0);
+
+void myMessageOutput(QtMsgType type, const char *msg)
+{
+ QString strMsg = QString::fromLatin1(msg);
+
+ if (!logger.isNull() && !QCoreApplication::closingDown()) {
+ if (recursiveLock.testAndSetOrdered(0, 1)) {
+ QMetaObject::invokeMethod(logger.data(), "append", Q_ARG(QString, strMsg));
+ recursiveLock = 0;
+ }
+ } else {
+ warnings += strMsg;
+ warnings += QLatin1Char('\n');
+ }
+ if (systemMsgOutput) { // Windows
+ systemMsgOutput(type, msg);
+ } else { // Unix
+ fprintf(stderr, "%s\n", msg);
+ fflush(stderr);
+ }
+}
+
+#endif
+
+static QDeclarativeViewer* globalViewer = 0;
+
+// The qml file that is shown if the user didn't specify a QML file
+QString initialFile = "qrc:/startup/startup.qml";
+
+void usage()
+{
+ qWarning("Usage: qmlviewer [options] <filename>");
+ qWarning(" ");
+ qWarning(" options:");
+ qWarning(" -v, -version ............................. display version");
+ qWarning(" -frameless ............................... run with no window frame");
+ qWarning(" -maximized................................ run maximized");
+ qWarning(" -fullscreen............................... run fullscreen");
+ qWarning(" -stayontop................................ keep viewer window on top");
+ qWarning(" -sizeviewtorootobject .................... the view resizes to the changes in the content");
+ qWarning(" -sizerootobjecttoview .................... the content resizes to the changes in the view (default)");
+ qWarning(" -qmlbrowser .............................. use a QML-based file browser");
+ qWarning(" -warnings [show|hide]..................... show warnings in a separate log window");
+ qWarning(" -recordfile <output> ..................... set video recording file");
+ qWarning(" - ImageMagick 'convert' for GIF)");
+ qWarning(" - png file for raw frames");
+ qWarning(" - 'ffmpeg' for other formats");
+ qWarning(" -recorddither ordered|threshold|floyd .... set GIF dither recording mode");
+ qWarning(" -recordrate <fps> ........................ set recording frame rate");
+ qWarning(" -record arg .............................. add a recording process argument");
+ qWarning(" -autorecord [from-]<tomilliseconds> ...... set recording to start and stop");
+ qWarning(" -devicekeys .............................. use numeric keys (see F1)");
+ qWarning(" -dragthreshold <size> .................... set mouse drag threshold size");
+ qWarning(" -netcache <size> ......................... set disk cache to size bytes");
+ qWarning(" -translation <translationfile> ........... set the language to run in");
+ qWarning(" -I <directory> ........................... prepend to the module import search path,");
+ qWarning(" display path if <directory> is empty");
+ qWarning(" -P <directory> ........................... prepend to the plugin search path");
+ qWarning(" -opengl .................................. use a QGLWidget for the viewport");
+ qWarning(" -script <path> ........................... set the script to use");
+ qWarning(" -scriptopts <options>|help ............... set the script options to use");
+
+ qWarning(" ");
+ qWarning(" Press F1 for interactive help");
+ exit(1);
+}
+
+void scriptOptsUsage()
+{
+ qWarning("Usage: qmlviewer -scriptopts <option>[,<option>...] ...");
+ qWarning(" options:");
+ qWarning(" record ................................... record a new script");
+ qWarning(" play ..................................... playback an existing script");
+ qWarning(" testimages ............................... record images or compare images on playback");
+ qWarning(" testerror ................................ test 'error' property of root item on playback");
+ qWarning(" testskip ................................ test 'skip' property of root item on playback");
+ qWarning(" snapshot ................................. file being recorded is static,");
+ qWarning(" only one frame will be recorded or tested");
+ qWarning(" exitoncomplete ........................... cleanly exit the viewer on script completion");
+ qWarning(" exitonfailure ............................ immediately exit the viewer on script failure");
+ qWarning(" saveonexit ............................... save recording on viewer exit");
+ qWarning(" ");
+ qWarning(" One of record, play or both must be specified.");
+ exit(1);
+}
+
+enum WarningsConfig { ShowWarnings, HideWarnings, DefaultWarnings };
+
+struct ViewerOptions
+{
+ ViewerOptions()
+ : frameless(false),
+ fps(0.0),
+ autorecord_from(0),
+ autorecord_to(0),
+ dither("none"),
+ runScript(false),
+ devkeys(false),
+ cache(0),
+ useGL(false),
+ fullScreen(false),
+ stayOnTop(false),
+ maximized(false),
+ useNativeFileBrowser(true),
+ experimentalGestures(false),
+ warningsConfig(DefaultWarnings),
+ sizeToView(true)
+ {
+#if defined(Q_OS_SYMBIAN)
+ maximized = true;
+ useNativeFileBrowser = false;
+#endif
+
+#if defined(Q_WS_MAC)
+ useGL = true;
+#endif
+ }
+
+ bool frameless;
+ double fps;
+ int autorecord_from;
+ int autorecord_to;
+ QString dither;
+ QString recordfile;
+ QStringList recordargs;
+ QStringList imports;
+ QStringList plugins;
+ QString script;
+ QString scriptopts;
+ bool runScript;
+ bool devkeys;
+ int cache;
+ QString translationFile;
+ bool useGL;
+ bool fullScreen;
+ bool stayOnTop;
+ bool maximized;
+ bool useNativeFileBrowser;
+ bool experimentalGestures;
+
+ WarningsConfig warningsConfig;
+ bool sizeToView;
+
+ QDeclarativeViewer::ScriptOptions scriptOptions;
+};
+
+static ViewerOptions opts;
+static QStringList fileNames;
+
+class Application : public QApplication
+{
+ Q_OBJECT
+public:
+ Application(int &argc, char **&argv)
+ : QApplication(argc, argv)
+ {}
+
+protected:
+ bool event(QEvent *ev)
+ {
+ if (ev->type() != QEvent::FileOpen)
+ return QApplication::event(ev);
+
+ QFileOpenEvent *fev = static_cast<QFileOpenEvent *>(ev);
+
+ globalViewer->open(fev->file());
+ if (!globalViewer->isVisible())
+ showViewer(globalViewer);
+
+ return true;
+ }
+
+private Q_SLOTS:
+ void showInitialViewer()
+ {
+ QApplication::processEvents();
+
+ QDeclarativeViewer *viewer = globalViewer;
+ if (!viewer)
+ return;
+ if (viewer->currentFile().isEmpty()) {
+ if(opts.useNativeFileBrowser)
+ viewer->open(initialFile);
+ else
+ viewer->openFile();
+ }
+ if (!viewer->isVisible())
+ showViewer(viewer);
+ }
+};
+
+static void parseScriptOptions()
+{
+ QStringList options =
+ opts.scriptopts.split(QLatin1Char(','), QString::SkipEmptyParts);
+
+ QDeclarativeViewer::ScriptOptions scriptOptions = 0;
+ for (int i = 0; i < options.count(); ++i) {
+ const QString &option = options.at(i);
+ if (option == QLatin1String("help")) {
+ scriptOptsUsage();
+ } else if (option == QLatin1String("play")) {
+ scriptOptions |= QDeclarativeViewer::Play;
+ } else if (option == QLatin1String("record")) {
+ scriptOptions |= QDeclarativeViewer::Record;
+ } else if (option == QLatin1String("testimages")) {
+ scriptOptions |= QDeclarativeViewer::TestImages;
+ } else if (option == QLatin1String("testerror")) {
+ scriptOptions |= QDeclarativeViewer::TestErrorProperty;
+ } else if (option == QLatin1String("testskip")) {
+ scriptOptions |= QDeclarativeViewer::TestSkipProperty;
+ } else if (option == QLatin1String("exitoncomplete")) {
+ scriptOptions |= QDeclarativeViewer::ExitOnComplete;
+ } else if (option == QLatin1String("exitonfailure")) {
+ scriptOptions |= QDeclarativeViewer::ExitOnFailure;
+ } else if (option == QLatin1String("saveonexit")) {
+ scriptOptions |= QDeclarativeViewer::SaveOnExit;
+ } else if (option == QLatin1String("snapshot")) {
+ scriptOptions |= QDeclarativeViewer::Snapshot;
+ } else {
+ scriptOptsUsage();
+ }
+ }
+
+ opts.scriptOptions = scriptOptions;
+}
+
+static void parseCommandLineOptions(const QStringList &arguments)
+{
+ for (int i = 1; i < arguments.count(); ++i) {
+ bool lastArg = (i == arguments.count() - 1);
+ QString arg = arguments.at(i);
+ if (arg == "-frameless") {
+ opts.frameless = true;
+ } else if (arg == "-maximized") {
+ opts.maximized = true;
+ } else if (arg == "-fullscreen") {
+ opts.fullScreen = true;
+ } else if (arg == "-stayontop") {
+ opts.stayOnTop = true;
+ } else if (arg == "-netcache") {
+ if (lastArg) usage();
+ opts.cache = arguments.at(++i).toInt();
+ } else if (arg == "-recordrate") {
+ if (lastArg) usage();
+ opts.fps = arguments.at(++i).toDouble();
+ } else if (arg == "-recordfile") {
+ if (lastArg) usage();
+ opts.recordfile = arguments.at(++i);
+ } else if (arg == "-record") {
+ if (lastArg) usage();
+ opts.recordargs << arguments.at(++i);
+ } else if (arg == "-recorddither") {
+ if (lastArg) usage();
+ opts.dither = arguments.at(++i);
+ } else if (arg == "-autorecord") {
+ if (lastArg) usage();
+ QString range = arguments.at(++i);
+ int dash = range.indexOf('-');
+ if (dash > 0)
+ opts.autorecord_from = range.left(dash).toInt();
+ opts.autorecord_to = range.mid(dash+1).toInt();
+ } else if (arg == "-devicekeys") {
+ opts.devkeys = true;
+ } else if (arg == "-dragthreshold") {
+ if (lastArg) usage();
+ qApp->setStartDragDistance(arguments.at(++i).toInt());
+ } else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) {
+ qWarning("Qt QML Viewer version %s", QT_VERSION_STR);
+ exit(0);
+ } else if (arg == "-translation") {
+ if (lastArg) usage();
+ opts.translationFile = arguments.at(++i);
+ } else if (arg == "-opengl") {
+ opts.useGL = true;
+ } else if (arg == "-qmlbrowser") {
+ opts.useNativeFileBrowser = false;
+ } else if (arg == "-warnings") {
+ if (lastArg) usage();
+ QString warningsStr = arguments.at(++i);
+ if (warningsStr == QLatin1String("show")) {
+ opts.warningsConfig = ShowWarnings;
+ } else if (warningsStr == QLatin1String("hide")) {
+ opts.warningsConfig = HideWarnings;
+ } else {
+ usage();
+ }
+ } else if (arg == "-I" || arg == "-L") {
+ if (arg == "-L")
+ qWarning("-L option provided for compatibility only, use -I instead");
+ if (lastArg) {
+ QDeclarativeEngine tmpEngine;
+ QString paths = tmpEngine.importPathList().join(QLatin1String(":"));
+ qWarning("Current search path: %s", paths.toLocal8Bit().constData());
+ exit(0);
+ }
+ opts.imports << arguments.at(++i);
+ } else if (arg == "-P") {
+ if (lastArg) usage();
+ opts.plugins << arguments.at(++i);
+ } else if (arg == "-script") {
+ if (lastArg) usage();
+ opts.script = arguments.at(++i);
+ } else if (arg == "-scriptopts") {
+ if (lastArg) usage();
+ opts.scriptopts = arguments.at(++i);
+ } else if (arg == "-savescript") {
+ if (lastArg) usage();
+ opts.script = arguments.at(++i);
+ opts.runScript = false;
+ } else if (arg == "-playscript") {
+ if (lastArg) usage();
+ opts.script = arguments.at(++i);
+ opts.runScript = true;
+ } else if (arg == "-sizeviewtorootobject") {
+ opts.sizeToView = false;
+ } else if (arg == "-sizerootobjecttoview") {
+ opts.sizeToView = true;
+ } else if (arg == "-experimentalgestures") {
+ opts.experimentalGestures = true;
+ } else if (!arg.startsWith('-')) {
+ fileNames.append(arg);
+ } else if (true || arg == "-help") {
+ usage();
+ }
+ }
+
+ if (!opts.scriptopts.isEmpty()) {
+
+ parseScriptOptions();
+
+ if (opts.script.isEmpty())
+ usage();
+
+ if (!(opts.scriptOptions & QDeclarativeViewer::Record) && !(opts.scriptOptions & QDeclarativeViewer::Play))
+ scriptOptsUsage();
+ } else if (!opts.script.isEmpty()) {
+ usage();
+ }
+
+}
+
+static QDeclarativeViewer *createViewer()
+{
+ Qt::WFlags wflags = (opts.frameless ? Qt::FramelessWindowHint : Qt::Widget);
+ if (opts.stayOnTop)
+ wflags |= Qt::WindowStaysOnTopHint;
+
+ QDeclarativeViewer *viewer = new QDeclarativeViewer(0, wflags);
+ viewer->setAttribute(Qt::WA_DeleteOnClose, true);
+ viewer->setUseGL(opts.useGL);
+
+ if (!opts.scriptopts.isEmpty()) {
+ viewer->setScriptOptions(opts.scriptOptions);
+ viewer->setScript(opts.script);
+ }
+
+#if !defined(Q_OS_SYMBIAN)
+ logger = viewer->warningsWidget();
+ if (opts.warningsConfig == ShowWarnings) {
+ logger.data()->setDefaultVisibility(LoggerWidget::ShowWarnings);
+ logger.data()->show();
+ } else if (opts.warningsConfig == HideWarnings){
+ logger.data()->setDefaultVisibility(LoggerWidget::HideWarnings);
+ }
+#endif
+
+ if (opts.experimentalGestures)
+ viewer->enableExperimentalGestures();
+
+ foreach (QString lib, opts.imports)
+ viewer->addLibraryPath(lib);
+
+ foreach (QString plugin, opts.plugins)
+ viewer->addPluginPath(plugin);
+
+ viewer->setNetworkCacheSize(opts.cache);
+ viewer->setRecordFile(opts.recordfile);
+ viewer->setSizeToView(opts.sizeToView);
+ if (opts.fps > 0)
+ viewer->setRecordRate(opts.fps);
+ if (opts.autorecord_to)
+ viewer->setAutoRecord(opts.autorecord_from, opts.autorecord_to);
+ if (opts.devkeys)
+ viewer->setDeviceKeys(true);
+ viewer->setRecordDither(opts.dither);
+ if (opts.recordargs.count())
+ viewer->setRecordArgs(opts.recordargs);
+
+ viewer->setUseNativeFileBrowser(opts.useNativeFileBrowser);
+
+ return viewer;
+}
+
+void showViewer(QDeclarativeViewer *viewer)
+{
+ if (opts.fullScreen)
+ viewer->showFullScreen();
+ else if (opts.maximized)
+ viewer->showMaximized();
+ else
+ viewer->show();
+ viewer->raise();
+}
+
+QDeclarativeViewer *openFile(const QString &fileName)
+{
+ QDeclarativeViewer *viewer = globalViewer;
+
+ viewer->open(fileName);
+ showViewer(viewer);
+
+ return viewer;
+}
+
+int main(int argc, char ** argv)
+{
+#if defined (Q_OS_SYMBIAN)
+ qInstallMsgHandler(myMessageOutput);
+#else
+ systemMsgOutput = qInstallMsgHandler(myMessageOutput);
+#endif
+
+#if defined (Q_OS_WIN)
+ // Debugging output is not visible by default on Windows -
+ // therefore show modal dialog with errors instead.
+ atexit(showWarnings);
+#endif
+
+#if defined (Q_WS_X11) || defined (Q_WS_MAC)
+ //### default to using raster graphics backend for now
+ bool gsSpecified = false;
+ for (int i = 0; i < argc; ++i) {
+ QString arg = argv[i];
+ if (arg == "-graphicssystem") {
+ gsSpecified = true;
+ break;
+ }
+ }
+
+ if (!gsSpecified)
+ QApplication::setGraphicsSystem("raster");
+#endif
+
+ Application app(argc, argv);
+ app.setApplicationName("QtQmlViewer");
+ app.setOrganizationName("Nokia");
+ app.setOrganizationDomain("nokia.com");
+
+ QDeclarativeViewer::registerTypes();
+ QDeclarativeTester::registerTypes();
+
+ parseCommandLineOptions(app.arguments());
+
+ QTranslator qmlTranslator;
+ if (!opts.translationFile.isEmpty()) {
+ qmlTranslator.load(opts.translationFile);
+ app.installTranslator(&qmlTranslator);
+ }
+
+ if (opts.fullScreen && opts.maximized)
+ qWarning() << "Both -fullscreen and -maximized specified. Using -fullscreen.";
+
+ if (fileNames.isEmpty()) {
+ QFile qmlapp(QLatin1String("qmlapp"));
+ if (qmlapp.exists() && qmlapp.open(QFile::ReadOnly)) {
+ QString content = QString::fromUtf8(qmlapp.readAll());
+ qmlapp.close();
+
+ int newline = content.indexOf(QLatin1Char('\n'));
+ if (newline >= 0)
+ fileNames += content.left(newline);
+ else
+ fileNames += content;
+ }
+ }
+
+ globalViewer = createViewer();
+
+ if (fileNames.isEmpty()) {
+ // show the initial viewer delayed.
+ // This prevents an initial viewer popping up while there
+ // are FileOpen events coming through the event queue
+ QTimer::singleShot(1, &app, SLOT(showInitialViewer()));
+ } else {
+ foreach (const QString &fileName, fileNames)
+ openFile(fileName);
+ }
+
+ QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit()));
+
+ return app.exec();
+}
+
+#include "main.moc"
diff --git a/tools/qml/proxysettings.cpp b/tools/qml/proxysettings.cpp
new file mode 100644
index 0000000..ffaa4c0
--- /dev/null
+++ b/tools/qml/proxysettings.cpp
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+
+#include <QIntValidator>
+#include <QSettings>
+
+#include "proxysettings.h"
+
+QT_BEGIN_NAMESPACE
+
+ProxySettings::ProxySettings (QWidget * parent)
+ : QDialog (parent), Ui::ProxySettings()
+{
+ setupUi (this);
+
+#if !defined Q_WS_MAEMO_5
+ // the onscreen keyboard can't cope with masks
+ proxyServerEdit->setInputMask ("000.000.000.000;_");
+#endif
+ QIntValidator *validator = new QIntValidator (0, 9999, this);
+ proxyPortEdit->setValidator (validator);
+
+ QSettings settings;
+ proxyCheckBox->setChecked (settings.value ("http_proxy/use", 0).toBool ());
+ proxyServerEdit->insert (settings.value ("http_proxy/hostname", "").toString ());
+ proxyPortEdit->insert (settings.value ("http_proxy/port", "80").toString ());
+ usernameEdit->insert (settings.value ("http_proxy/username", "").toString ());
+ passwordEdit->insert (settings.value ("http_proxy/password", "").toString ());
+}
+
+ProxySettings::~ProxySettings()
+{
+}
+
+void ProxySettings::accept ()
+{
+ QSettings settings;
+
+ settings.setValue ("http_proxy/use", proxyCheckBox->isChecked ());
+ settings.setValue ("http_proxy/hostname", proxyServerEdit->text ());
+ settings.setValue ("http_proxy/port", proxyPortEdit->text ());
+ settings.setValue ("http_proxy/username", usernameEdit->text ());
+ settings.setValue ("http_proxy/password", passwordEdit->text ());
+
+ QDialog::accept ();
+}
+
+QNetworkProxy ProxySettings::httpProxy ()
+{
+ QSettings settings;
+ QNetworkProxy proxy;
+
+ bool proxyInUse = settings.value ("http_proxy/use", 0).toBool ();
+ if (proxyInUse) {
+ proxy.setType (QNetworkProxy::HttpProxy);
+ proxy.setHostName (settings.value ("http_proxy/hostname", "").toString ());// "192.168.220.5"
+ proxy.setPort (settings.value ("http_proxy/port", 80).toInt ()); // 8080
+ proxy.setUser (settings.value ("http_proxy/username", "").toString ());
+ proxy.setPassword (settings.value ("http_proxy/password", "").toString ());
+ //QNetworkProxy::setApplicationProxy (proxy);
+ }
+ else {
+ proxy.setType (QNetworkProxy::NoProxy);
+ }
+ return proxy;
+}
+
+bool ProxySettings::httpProxyInUse()
+{
+ QSettings settings;
+ return settings.value ("http_proxy/use", 0).toBool ();
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qml/proxysettings.h b/tools/qml/proxysettings.h
new file mode 100644
index 0000000..5d4d137
--- /dev/null
+++ b/tools/qml/proxysettings.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef PROXYSETTINGS_H
+#define PROXYSETTINGS_H
+
+#include <QDialog>
+#include <QNetworkProxy>
+#ifdef Q_WS_MAEMO_5
+#include "ui_proxysettings_maemo5.h"
+#else
+#include "ui_proxysettings.h"
+#endif
+
+QT_BEGIN_NAMESPACE
+/**
+*/
+class ProxySettings : public QDialog, public Ui::ProxySettings
+{
+
+Q_OBJECT
+
+public:
+ ProxySettings(QWidget * parent = 0);
+
+ ~ProxySettings();
+
+ static QNetworkProxy httpProxy ();
+ static bool httpProxyInUse ();
+
+public slots:
+ virtual void accept ();
+};
+
+QT_END_NAMESPACE
+
+#endif // PROXYSETTINGS_H
diff --git a/tools/qml/proxysettings.ui b/tools/qml/proxysettings.ui
new file mode 100644
index 0000000..84e39fe
--- /dev/null
+++ b/tools/qml/proxysettings.ui
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProxySettings</class>
+ <widget class="QDialog" name="ProxySettings">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>318</width>
+ <height>199</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Dialog</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0" colspan="2">
+ <widget class="QCheckBox" name="proxyCheckBox">
+ <property name="text">
+ <string>Use http proxy</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="serverAddressLabel">
+ <property name="text">
+ <string>Server Address:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxyServerEdit"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Port:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="proxyPortEdit"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="usernameLabel">
+ <property name="text">
+ <string>Username:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="usernameEdit"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="1">
+ <widget class="QLineEdit" name="passwordEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <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>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ProxySettings</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>ProxySettings</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/qml/proxysettings_maemo5.ui b/tools/qml/proxysettings_maemo5.ui
new file mode 100644
index 0000000..83f0c2a
--- /dev/null
+++ b/tools/qml/proxysettings_maemo5.ui
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProxySettings</class>
+ <widget class="QDialog" name="ProxySettings">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>449</width>
+ <height>164</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>HTTP Proxy</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <property name="leftMargin">
+ <number>16</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>16</number>
+ </property>
+ <property name="bottomMargin">
+ <number>8</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>16</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QCheckBox" name="proxyCheckBox">
+ <property name="text">
+ <string>Use HTTP Proxy</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" rowspan="2">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" rowspan="2">
+ <widget class="QWidget" name="widget" native="true">
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="horizontalSpacing">
+ <number>16</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="serverAddressLabel">
+ <property name="text">
+ <string>Server</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="proxyServerEdit">
+ <property name="placeholderText">
+ <string>Name or IP</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Port</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="proxyPortEdit">
+ <property name="text">
+ <string>8080</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="usernameLabel">
+ <property name="text">
+ <string>Username</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="usernameEdit"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="passwordLabel">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="passwordEdit">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>proxyCheckBox</tabstop>
+ <tabstop>proxyServerEdit</tabstop>
+ <tabstop>proxyPortEdit</tabstop>
+ <tabstop>usernameEdit</tabstop>
+ <tabstop>passwordEdit</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ProxySettings</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>318</x>
+ <y>100</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>116</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ProxySettings</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>318</x>
+ <y>100</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>116</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp
new file mode 100644
index 0000000..a516fd7
--- /dev/null
+++ b/tools/qml/qdeclarativetester.cpp
@@ -0,0 +1,439 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qdeclarativetester.h>
+#include <QDebug>
+#include <QApplication>
+#include <qdeclarativeview.h>
+#include <QFile>
+#include <QDeclarativeComponent>
+#include <QDir>
+#include <QCryptographicHash>
+#include <private/qabstractanimation_p.h>
+#include <private/qdeclarativeitem_p.h>
+
+QT_BEGIN_NAMESPACE
+
+extern Q_GUI_EXPORT bool qt_applefontsmoothing_enabled;
+
+QDeclarativeTester::QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions opts,
+ QDeclarativeView *parent)
+: QAbstractAnimation(parent), m_script(script), m_view(parent), filterEvents(true), options(opts),
+ testscript(0), hasCompleted(false), hasFailed(false)
+{
+ parent->viewport()->installEventFilter(this);
+ parent->installEventFilter(this);
+ QUnifiedTimer::instance()->setConsistentTiming(true);
+
+ //Font antialiasing makes tests system-specific, so disable it
+ QFont noAA = QApplication::font();
+ noAA.setStyleStrategy(QFont::NoAntialias);
+ QApplication::setFont(noAA);
+
+ if (options & QDeclarativeViewer::Play)
+ this->run();
+ start();
+}
+
+QDeclarativeTester::~QDeclarativeTester()
+{
+ if (!hasFailed &&
+ options & QDeclarativeViewer::Record &&
+ options & QDeclarativeViewer::SaveOnExit)
+ save();
+}
+
+int QDeclarativeTester::duration() const
+{
+ return -1;
+}
+
+void QDeclarativeTester::addMouseEvent(Destination dest, QMouseEvent *me)
+{
+ MouseEvent e(me);
+ e.destination = dest;
+ m_mouseEvents << e;
+}
+
+void QDeclarativeTester::addKeyEvent(Destination dest, QKeyEvent *ke)
+{
+ KeyEvent e(ke);
+ e.destination = dest;
+ m_keyEvents << e;
+}
+
+bool QDeclarativeTester::eventFilter(QObject *o, QEvent *e)
+{
+ if (!filterEvents)
+ return false;
+
+ Destination destination;
+ if (o == m_view) {
+ destination = View;
+ } else if (o == m_view->viewport()) {
+ destination = ViewPort;
+ } else {
+ return false;
+ }
+
+ switch (e->type()) {
+ case QEvent::KeyPress:
+ case QEvent::KeyRelease:
+ addKeyEvent(destination, (QKeyEvent *)e);
+ return true;
+ case QEvent::MouseButtonPress:
+ case QEvent::MouseButtonRelease:
+ case QEvent::MouseMove:
+ case QEvent::MouseButtonDblClick:
+ addMouseEvent(destination, (QMouseEvent *)e);
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
+void QDeclarativeTester::executefailure()
+{
+ hasFailed = true;
+
+ if (options & QDeclarativeViewer::ExitOnFailure)
+ exit(-1);
+}
+
+void QDeclarativeTester::imagefailure()
+{
+ hasFailed = true;
+
+ if (options & QDeclarativeViewer::ExitOnFailure){
+ testSkip();
+ exit(hasFailed?-1:0);
+ }
+}
+
+void QDeclarativeTester::testSkip()
+{
+ if (options & QDeclarativeViewer::TestSkipProperty){
+ QString e = m_view->rootObject()->property("skip").toString();
+ if (!e.isEmpty()) {
+ if(hasFailed){
+ qWarning() << "Test failed, but skipping it: " << e;
+ }else{
+ qWarning() << "Test skipped: " << e;
+ }
+ hasFailed = 0;
+ }
+ }
+}
+
+void QDeclarativeTester::complete()
+{
+ if ((options & QDeclarativeViewer::TestErrorProperty) && !hasFailed) {
+ QString e = m_view->rootObject()->property("error").toString();
+ if (!e.isEmpty()) {
+ qWarning() << "Test failed:" << e;
+ hasFailed = true;
+ }
+ }
+
+
+ testSkip();
+ if (options & QDeclarativeViewer::ExitOnComplete)
+ QApplication::exit(hasFailed?-1:0);
+
+ if (hasCompleted)
+ return;
+ hasCompleted = true;
+
+ if (options & QDeclarativeViewer::Play)
+ qWarning("Script playback complete");
+}
+
+void QDeclarativeTester::run()
+{
+ QDeclarativeComponent c(m_view->engine(), m_script + QLatin1String(".qml"));
+
+ testscript = qobject_cast<QDeclarativeVisualTest *>(c.create());
+ if (testscript) testscript->setParent(this);
+ else { executefailure(); exit(-1); }
+ testscriptidx = 0;
+}
+
+void QDeclarativeTester::save()
+{
+ QString filename = m_script + QLatin1String(".qml");
+ QFileInfo filenameInfo(filename);
+ QDir saveDir = filenameInfo.absoluteDir();
+ saveDir.mkpath(".");
+
+ QFile file(filename);
+ file.open(QIODevice::WriteOnly);
+ QTextStream ts(&file);
+
+ ts << "import Qt.VisualTest 4.7\n\n";
+ ts << "VisualTest {\n";
+
+ int imgCount = 0;
+ QList<KeyEvent> keyevents = m_savedKeyEvents;
+ QList<MouseEvent> mouseevents = m_savedMouseEvents;
+ for (int ii = 0; ii < m_savedFrameEvents.count(); ++ii) {
+ const FrameEvent &fe = m_savedFrameEvents.at(ii);
+ ts << " Frame {\n";
+ ts << " msec: " << fe.msec << "\n";
+ if (!fe.hash.isEmpty()) {
+ ts << " hash: \"" << fe.hash.toHex() << "\"\n";
+ } else if (!fe.image.isNull()) {
+ QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png";
+ fe.image.save(m_script + "." + QString::number(imgCount) + ".png");
+ imgCount++;
+ ts << " image: \"" << filename << "\"\n";
+ }
+ ts << " }\n";
+
+ while (!mouseevents.isEmpty() &&
+ mouseevents.first().msec == fe.msec) {
+ MouseEvent me = mouseevents.takeFirst();
+
+ ts << " Mouse {\n";
+ ts << " type: " << me.type << "\n";
+ ts << " button: " << me.button << "\n";
+ ts << " buttons: " << me.buttons << "\n";
+ ts << " x: " << me.pos.x() << "; y: " << me.pos.y() << "\n";
+ ts << " modifiers: " << me.modifiers << "\n";
+ if (me.destination == ViewPort)
+ ts << " sendToViewport: true\n";
+ ts << " }\n";
+ }
+
+ while (!keyevents.isEmpty() &&
+ keyevents.first().msec == fe.msec) {
+ KeyEvent ke = keyevents.takeFirst();
+
+ ts << " Key {\n";
+ ts << " type: " << ke.type << "\n";
+ ts << " key: " << ke.key << "\n";
+ ts << " modifiers: " << ke.modifiers << "\n";
+ ts << " text: \"" << ke.text.toUtf8().toHex() << "\"\n";
+ ts << " autorep: " << (ke.autorep?"true":"false") << "\n";
+ ts << " count: " << ke.count << "\n";
+ if (ke.destination == ViewPort)
+ ts << " sendToViewport: true\n";
+ ts << " }\n";
+ }
+ }
+
+ ts << "}\n";
+ file.close();
+}
+
+void QDeclarativeTester::updateCurrentTime(int msec)
+{
+ QDeclarativeItemPrivate::setConsistentTime(msec);
+ if (!testscript && msec > 16 && options & QDeclarativeViewer::Snapshot)
+ return;
+
+ QImage img(m_view->width(), m_view->height(), QImage::Format_RGB32);
+
+ if (options & QDeclarativeViewer::TestImages) {
+ img.fill(qRgb(255,255,255));
+ QPainter p(&img);
+ m_view->render(&p);
+ }
+
+ bool snapshot = msec == 16 && (options & QDeclarativeViewer::Snapshot
+ || (testscript && testscript->count() == 2));
+
+ FrameEvent fe;
+ fe.msec = msec;
+ if (msec == 0 || !(options & QDeclarativeViewer::TestImages)) {
+ // Skip first frame, skip if not doing images
+ } else if (0 == ((m_savedFrameEvents.count()-1) % 60) || snapshot) {
+ fe.image = img;
+ } else {
+ QCryptographicHash hash(QCryptographicHash::Md5);
+ hash.addData((const char *)img.bits(), img.bytesPerLine() * img.height());
+ fe.hash = hash.result();
+ }
+ m_savedFrameEvents.append(fe);
+
+ // Deliver mouse events
+ filterEvents = false;
+
+ if (!testscript) {
+ for (int ii = 0; ii < m_mouseEvents.count(); ++ii) {
+ MouseEvent &me = m_mouseEvents[ii];
+ me.msec = msec;
+ QMouseEvent event(me.type, me.pos, me.button, me.buttons, me.modifiers);
+
+ if (me.destination == View) {
+ QCoreApplication::sendEvent(m_view, &event);
+ } else {
+ QCoreApplication::sendEvent(m_view->viewport(), &event);
+ }
+ }
+
+ for (int ii = 0; ii < m_keyEvents.count(); ++ii) {
+ KeyEvent &ke = m_keyEvents[ii];
+ ke.msec = msec;
+ QKeyEvent event(ke.type, ke.key, ke.modifiers, ke.text, ke.autorep, ke.count);
+
+ if (ke.destination == View) {
+ QCoreApplication::sendEvent(m_view, &event);
+ } else {
+ QCoreApplication::sendEvent(m_view->viewport(), &event);
+ }
+ }
+ m_savedMouseEvents.append(m_mouseEvents);
+ m_savedKeyEvents.append(m_keyEvents);
+ }
+
+ m_mouseEvents.clear();
+ m_keyEvents.clear();
+
+ // Advance test script
+ while (testscript && testscript->count() > testscriptidx) {
+
+ QObject *event = testscript->event(testscriptidx);
+
+ if (QDeclarativeVisualTestFrame *frame = qobject_cast<QDeclarativeVisualTestFrame *>(event)) {
+ if (frame->msec() < msec) {
+ if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) {
+ qWarning() << "QDeclarativeTester(" << m_script << "): Extra frame. Seen:"
+ << msec << "Expected:" << frame->msec();
+ imagefailure();
+ }
+ } else if (frame->msec() == msec) {
+ if (!frame->hash().isEmpty() && frame->hash().toUtf8() != fe.hash.toHex()) {
+ if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record)) {
+ qWarning() << "QDeclarativeTester(" << m_script << "): Mismatched frame hash at" << msec
+ << ". Seen:" << fe.hash.toHex()
+ << "Expected:" << frame->hash().toUtf8();
+ imagefailure();
+ }
+ }
+ } else if (frame->msec() > msec) {
+ break;
+ }
+
+ if (options & QDeclarativeViewer::TestImages && !(options & QDeclarativeViewer::Record) && !frame->image().isEmpty()) {
+ QImage goodImage(frame->image().toLocalFile());
+ if (frame->msec() == 16 && goodImage.size() != img.size()){
+ //Also an image mismatch, but this warning is more informative. Only checked at start though.
+ qWarning() << "QDeclarativeTester(" << m_script << "): Size mismatch. This test must be run at " << goodImage.size();
+ imagefailure();
+ }
+ if (goodImage != img) {
+ QString reject(frame->image().toLocalFile() + ".reject.png");
+ qWarning() << "QDeclarativeTester(" << m_script << "): Image mismatch. Reject saved to:"
+ << reject;
+ img.save(reject);
+ bool doDiff = (goodImage.size() == img.size());
+ if (doDiff) {
+ QImage diffimg(m_view->width(), m_view->height(), QImage::Format_RGB32);
+ diffimg.fill(qRgb(255,255,255));
+ QPainter p(&diffimg);
+ int diffCount = 0;
+ for (int x = 0; x < img.width(); ++x) {
+ for (int y = 0; y < img.height(); ++y) {
+ if (goodImage.pixel(x,y) != img.pixel(x,y)) {
+ ++diffCount;
+ p.drawPoint(x,y);
+ }
+ }
+ }
+ QString diff(frame->image().toLocalFile() + ".diff.png");
+ diffimg.save(diff);
+ qWarning().nospace() << " Diff (" << diffCount << " pixels differed) saved to: " << diff;
+ }
+ imagefailure();
+ }
+ }
+ } else if (QDeclarativeVisualTestMouse *mouse = qobject_cast<QDeclarativeVisualTestMouse *>(event)) {
+ QPoint pos(mouse->x(), mouse->y());
+ QPoint globalPos = m_view->mapToGlobal(QPoint(0, 0)) + pos;
+ QMouseEvent event((QEvent::Type)mouse->type(), pos, globalPos, (Qt::MouseButton)mouse->button(), (Qt::MouseButtons)mouse->buttons(), (Qt::KeyboardModifiers)mouse->modifiers());
+
+ MouseEvent me(&event);
+ me.msec = msec;
+ if (!mouse->sendToViewport()) {
+ QCoreApplication::sendEvent(m_view, &event);
+ me.destination = View;
+ } else {
+ QCoreApplication::sendEvent(m_view->viewport(), &event);
+ me.destination = ViewPort;
+ }
+ m_savedMouseEvents.append(me);
+ } else if (QDeclarativeVisualTestKey *key = qobject_cast<QDeclarativeVisualTestKey *>(event)) {
+
+ QKeyEvent event((QEvent::Type)key->type(), key->key(), (Qt::KeyboardModifiers)key->modifiers(), QString::fromUtf8(QByteArray::fromHex(key->text().toUtf8())), key->autorep(), key->count());
+
+ KeyEvent ke(&event);
+ ke.msec = msec;
+ if (!key->sendToViewport()) {
+ QCoreApplication::sendEvent(m_view, &event);
+ ke.destination = View;
+ } else {
+ QCoreApplication::sendEvent(m_view->viewport(), &event);
+ ke.destination = ViewPort;
+ }
+ m_savedKeyEvents.append(ke);
+ }
+ testscriptidx++;
+ }
+
+ filterEvents = true;
+
+ if (testscript && testscript->count() <= testscriptidx) {
+ //if (msec == 16) //for a snapshot, leave it up long enough to see
+ // (void)::sleep(1);
+ complete();
+ }
+}
+
+void QDeclarativeTester::registerTypes()
+{
+ qmlRegisterType<QDeclarativeVisualTest>("Qt.VisualTest", 4,7, "VisualTest");
+ qmlRegisterType<QDeclarativeVisualTestFrame>("Qt.VisualTest", 4,7, "Frame");
+ qmlRegisterType<QDeclarativeVisualTestMouse>("Qt.VisualTest", 4,7, "Mouse");
+ qmlRegisterType<QDeclarativeVisualTestKey>("Qt.VisualTest", 4,7, "Key");
+}
+
+QT_END_NAMESPACE
diff --git a/tools/qml/qdeclarativetester.h b/tools/qml/qdeclarativetester.h
new file mode 100644
index 0000000..0cf508a
--- /dev/null
+++ b/tools/qml/qdeclarativetester.h
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVETESTER_H
+#define QDECLARATIVETESTER_H
+
+#include <QEvent>
+#include <QMouseEvent>
+#include <QKeyEvent>
+#include <QImage>
+#include <QUrl>
+#include <qmlruntime.h>
+#include <qdeclarativelist.h>
+#include <qdeclarative.h>
+#include <QAbstractAnimation>
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeVisualTest : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QDeclarativeListProperty<QObject> events READ events CONSTANT)
+ Q_CLASSINFO("DefaultProperty", "events")
+public:
+ QDeclarativeVisualTest() {}
+
+ QDeclarativeListProperty<QObject> events() { return QDeclarativeListProperty<QObject>(this, m_events); }
+
+ int count() const { return m_events.count(); }
+ QObject *event(int idx) { return m_events.at(idx); }
+
+private:
+ QList<QObject *> m_events;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeVisualTest)
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeVisualTestFrame : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int msec READ msec WRITE setMsec)
+ Q_PROPERTY(QString hash READ hash WRITE setHash)
+ Q_PROPERTY(QUrl image READ image WRITE setImage)
+public:
+ QDeclarativeVisualTestFrame() : m_msec(-1) {}
+
+ int msec() const { return m_msec; }
+ void setMsec(int m) { m_msec = m; }
+
+ QString hash() const { return m_hash; }
+ void setHash(const QString &hash) { m_hash = hash; }
+
+ QUrl image() const { return m_image; }
+ void setImage(const QUrl &image) { m_image = image; }
+
+private:
+ int m_msec;
+ QString m_hash;
+ QUrl m_image;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeVisualTestFrame)
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeVisualTestMouse : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int type READ type WRITE setType)
+ Q_PROPERTY(int button READ button WRITE setButton)
+ Q_PROPERTY(int buttons READ buttons WRITE setButtons)
+ Q_PROPERTY(int x READ x WRITE setX)
+ Q_PROPERTY(int y READ y WRITE setY)
+ Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers)
+ Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport)
+public:
+ QDeclarativeVisualTestMouse() : m_type(0), m_button(0), m_buttons(0), m_x(0), m_y(0), m_modifiers(0), m_viewport(false) {}
+
+ int type() const { return m_type; }
+ void setType(int t) { m_type = t; }
+
+ int button() const { return m_button; }
+ void setButton(int b) { m_button = b; }
+
+ int buttons() const { return m_buttons; }
+ void setButtons(int b) { m_buttons = b; }
+
+ int x() const { return m_x; }
+ void setX(int x) { m_x = x; }
+
+ int y() const { return m_y; }
+ void setY(int y) { m_y = y; }
+
+ int modifiers() const { return m_modifiers; }
+ void setModifiers(int modifiers) { m_modifiers = modifiers; }
+
+ bool sendToViewport() const { return m_viewport; }
+ void setSendToViewport(bool v) { m_viewport = v; }
+private:
+ int m_type;
+ int m_button;
+ int m_buttons;
+ int m_x;
+ int m_y;
+ int m_modifiers;
+ bool m_viewport;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeVisualTestMouse)
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeVisualTestKey : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int type READ type WRITE setType)
+ Q_PROPERTY(int key READ key WRITE setKey)
+ Q_PROPERTY(int modifiers READ modifiers WRITE setModifiers)
+ Q_PROPERTY(QString text READ text WRITE setText)
+ Q_PROPERTY(bool autorep READ autorep WRITE setAutorep)
+ Q_PROPERTY(int count READ count WRITE setCount)
+ Q_PROPERTY(bool sendToViewport READ sendToViewport WRITE setSendToViewport)
+public:
+ QDeclarativeVisualTestKey() : m_type(0), m_key(0), m_modifiers(0), m_autorep(false), m_count(0), m_viewport(false) {}
+
+ int type() const { return m_type; }
+ void setType(int t) { m_type = t; }
+
+ int key() const { return m_key; }
+ void setKey(int k) { m_key = k; }
+
+ int modifiers() const { return m_modifiers; }
+ void setModifiers(int m) { m_modifiers = m; }
+
+ QString text() const { return m_text; }
+ void setText(const QString &t) { m_text = t; }
+
+ bool autorep() const { return m_autorep; }
+ void setAutorep(bool a) { m_autorep = a; }
+
+ int count() const { return m_count; }
+ void setCount(int c) { m_count = c; }
+
+ bool sendToViewport() const { return m_viewport; }
+ void setSendToViewport(bool v) { m_viewport = v; }
+private:
+ int m_type;
+ int m_key;
+ int m_modifiers;
+ QString m_text;
+ bool m_autorep;
+ int m_count;
+ bool m_viewport;
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QDeclarativeVisualTestKey)
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeTester : public QAbstractAnimation
+{
+public:
+ QDeclarativeTester(const QString &script, QDeclarativeViewer::ScriptOptions options, QDeclarativeView *parent);
+ ~QDeclarativeTester();
+
+ static void registerTypes();
+
+ virtual int duration() const;
+
+ void run();
+ void save();
+
+ void executefailure();
+protected:
+ virtual void updateCurrentTime(int msecs);
+ virtual bool eventFilter(QObject *, QEvent *);
+
+private:
+ QString m_script;
+
+ void imagefailure();
+ void complete();
+ void testSkip();
+
+ enum Destination { View, ViewPort };
+ void addKeyEvent(Destination, QKeyEvent *);
+ void addMouseEvent(Destination, QMouseEvent *);
+ QDeclarativeView *m_view;
+
+ struct MouseEvent {
+ MouseEvent(QMouseEvent *e)
+ : type(e->type()), button(e->button()), buttons(e->buttons()),
+ pos(e->pos()), modifiers(e->modifiers()), destination(View) {}
+
+ QEvent::Type type;
+ Qt::MouseButton button;
+ Qt::MouseButtons buttons;
+ QPoint pos;
+ Qt::KeyboardModifiers modifiers;
+ Destination destination;
+
+ int msec;
+ };
+ struct KeyEvent {
+ KeyEvent(QKeyEvent *e)
+ : type(e->type()), key(e->key()), modifiers(e->modifiers()), text(e->text()),
+ autorep(e->isAutoRepeat()), count(e->count()), destination(View) {}
+ QEvent::Type type;
+ int key;
+ Qt::KeyboardModifiers modifiers;
+ QString text;
+ bool autorep;
+ ushort count;
+ Destination destination;
+
+ int msec;
+ };
+ struct FrameEvent {
+ QImage image;
+ QByteArray hash;
+ int msec;
+ };
+ QList<MouseEvent> m_mouseEvents;
+ QList<KeyEvent> m_keyEvents;
+
+ QList<MouseEvent> m_savedMouseEvents;
+ QList<KeyEvent> m_savedKeyEvents;
+ QList<FrameEvent> m_savedFrameEvents;
+ bool filterEvents;
+
+ QDeclarativeViewer::ScriptOptions options;
+ int testscriptidx;
+ QDeclarativeVisualTest *testscript;
+
+ bool hasCompleted;
+ bool hasFailed;
+};
+
+
+QT_END_NAMESPACE
+
+#endif // QDECLARATIVETESTER_H
diff --git a/tools/qml/qml.icns b/tools/qml/qml.icns
new file mode 100644
index 0000000..c760516
--- /dev/null
+++ b/tools/qml/qml.icns
Binary files differ
diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri
new file mode 100644
index 0000000..5db7678
--- /dev/null
+++ b/tools/qml/qml.pri
@@ -0,0 +1,41 @@
+QT += declarative script network sql
+contains(QT_CONFIG, opengl) {
+ QT += opengl
+ DEFINES += GL_SUPPORTED
+}
+
+INCLUDEPATH += $$PWD
+
+HEADERS += $$PWD/qmlruntime.h \
+ $$PWD/proxysettings.h \
+ $$PWD/qdeclarativetester.h \
+ $$PWD/deviceorientation.h \
+ $$PWD/loggerwidget.h
+SOURCES += $$PWD/qmlruntime.cpp \
+ $$PWD/proxysettings.cpp \
+ $$PWD/qdeclarativetester.cpp \
+ $$PWD/loggerwidget.cpp
+
+RESOURCES = $$PWD/browser/browser.qrc \
+ $$PWD/startup/startup.qrc
+
+symbian:!contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
+ SOURCES += $$PWD/deviceorientation_symbian.cpp
+ FORMS = $$PWD/recopts.ui \
+ $$PWD/proxysettings.ui
+} else:maemo5 {
+ QT += dbus
+ HEADERS += $$PWD/texteditautoresizer_maemo5.h
+ SOURCES += $$PWD/deviceorientation_maemo5.cpp
+ FORMS = $$PWD/recopts_maemo5.ui \
+ $$PWD/proxysettings_maemo5.ui
+} else:linux-g++-maemo {
+ QT += dbus
+ SOURCES += $$PWD/deviceorientation_harmattan.cpp
+ FORMS = $$PWD/recopts.ui \
+ $$PWD/proxysettings.ui
+} else {
+ SOURCES += $$PWD/deviceorientation.cpp
+ FORMS = $$PWD/recopts.ui \
+ $$PWD/proxysettings.ui
+}
diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro
new file mode 100644
index 0000000..3927dd6
--- /dev/null
+++ b/tools/qml/qml.pro
@@ -0,0 +1,53 @@
+TEMPLATE = app
+CONFIG += qt uic
+DESTDIR = ../../bin
+
+include(qml.pri)
+
+SOURCES += main.cpp
+
+INCLUDEPATH += ../../include/QtDeclarative
+INCLUDEPATH += ../../src/declarative/util
+INCLUDEPATH += ../../src/declarative/graphicsitems
+
+target.path = $$[QT_INSTALL_BINS]
+INSTALLS += target
+
+wince* {
+ QT += xml
+
+ contains(QT_CONFIG, scripttools) {
+ QT += scripttools
+ }
+ contains(QT_CONFIG, phonon) {
+ QT += phonon
+ }
+ contains(QT_CONFIG, xmlpatterns) {
+ QT += xmlpatterns
+ }
+ contains(QT_CONFIG, webkit) {
+ QT += webkit
+ }
+}
+maemo5 {
+ QT += maemo5
+}
+symbian {
+ TARGET.UID3 = 0x20021317
+ include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri)
+ TARGET.EPOCHEAPSIZE = 0x20000 0x4000000
+ TARGET.CAPABILITY = NetworkServices ReadUserData
+ !contains(S60_VERSION, 3.1):!contains(S60_VERSION, 3.2) {
+ LIBS += -lsensrvclient -lsensrvutil
+ }
+ contains(QT_CONFIG, s60): {
+ LIBS += -lavkon -lcone
+ }
+}
+mac {
+ QMAKE_INFO_PLIST=Info_mac.plist
+ TARGET=QMLViewer
+ ICON=qml.icns
+} else {
+ TARGET=qmlviewer
+}
diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp
new file mode 100644
index 0000000..78bc409
--- /dev/null
+++ b/tools/qml/qmlruntime.cpp
@@ -0,0 +1,1545 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qdeclarativeview.h>
+
+#ifdef hz
+#undef hz
+#endif
+#ifdef Q_WS_MAEMO_5
+# include <QMaemo5ValueButton>
+# include <QMaemo5ListPickSelector>
+# include <QWidgetAction>
+# include <QStringListModel>
+# include "ui_recopts_maemo5.h"
+#else
+# include "ui_recopts.h"
+#endif
+
+#include "qmlruntime.h"
+#include <qdeclarativecontext.h>
+#include <qdeclarativeengine.h>
+#include <qdeclarativenetworkaccessmanagerfactory.h>
+#include "qdeclarative.h"
+#include <QAbstractAnimation>
+#include <private/qabstractanimation_p.h>
+
+#include <QSettings>
+#include <QXmlStreamReader>
+#include <QBuffer>
+#include <QNetworkReply>
+#include <QNetworkCookieJar>
+#include <QNetworkDiskCache>
+#include <QNetworkAccessManager>
+#include <QSignalMapper>
+#include <QDeclarativeComponent>
+#include <QWidget>
+#include <QApplication>
+#include <QTranslator>
+#include <QDir>
+#include <QTextBrowser>
+#include <QFile>
+#include <QFileInfo>
+#include <QVBoxLayout>
+#include <QProgressDialog>
+#include <QProcess>
+#include <QMenuBar>
+#include <QMenu>
+#include <QAction>
+#include <QFileDialog>
+#include <QInputDialog>
+#include <QTimer>
+#include <QGraphicsObject>
+#include <QNetworkProxyFactory>
+#include <QKeyEvent>
+#include <QMutex>
+#include <QMutexLocker>
+#include "proxysettings.h"
+#include "deviceorientation.h"
+
+#ifdef GL_SUPPORTED
+#include <QGLWidget>
+#endif
+
+#if defined(Q_WS_S60)
+#include <aknappui.h> // For locking app orientation
+#endif
+
+#include <qdeclarativetester.h>
+
+QT_BEGIN_NAMESPACE
+
+class DragAndDropView : public QDeclarativeView
+{
+ Q_OBJECT
+public:
+ DragAndDropView(QDeclarativeViewer *parent = 0)
+ : QDeclarativeView(parent)
+ {
+ setAcceptDrops(true);
+ }
+
+ void dragEnterEvent(QDragEnterEvent *event)
+ {
+ const QMimeData *mimeData = event->mimeData();
+ if (mimeData->hasUrls())
+ event->acceptProposedAction();
+ }
+
+ void dragMoveEvent(QDragMoveEvent *event)
+ {
+ event->acceptProposedAction();
+ }
+
+ void dragLeaveEvent(QDragLeaveEvent *event)
+ {
+ event->accept();
+ }
+
+ void dropEvent(QDropEvent *event)
+ {
+ const QMimeData *mimeData = event->mimeData();
+ if (!mimeData->hasUrls())
+ return;
+ const QList<QUrl> urlList = mimeData->urls();
+ foreach (const QUrl &url, urlList) {
+ if (url.scheme() == QLatin1String("file")) {
+ static_cast<QDeclarativeViewer *>(parent())->open(url.toLocalFile());
+ event->accept();
+ return;
+ }
+ }
+ }
+};
+
+class Runtime : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(bool isActiveWindow READ isActiveWindow NOTIFY isActiveWindowChanged)
+ Q_PROPERTY(DeviceOrientation::Orientation orientation READ orientation NOTIFY orientationChanged)
+
+public:
+ static Runtime* instance()
+ {
+ static Runtime *instance = 0;
+ if (!instance)
+ instance = new Runtime;
+ return instance;
+ }
+
+ bool isActiveWindow() const { return activeWindow; }
+ void setActiveWindow(bool active)
+ {
+ if (active == activeWindow)
+ return;
+ activeWindow = active;
+ emit isActiveWindowChanged();
+ }
+
+ DeviceOrientation::Orientation orientation() const { return DeviceOrientation::instance()->orientation(); }
+
+Q_SIGNALS:
+ void isActiveWindowChanged();
+ void orientationChanged();
+
+private:
+ Runtime(QObject *parent=0) : QObject(parent), activeWindow(false)
+ {
+ connect(DeviceOrientation::instance(), SIGNAL(orientationChanged()),
+ this, SIGNAL(orientationChanged()));
+ }
+
+ bool activeWindow;
+};
+
+
+
+#if defined(Q_WS_MAEMO_5)
+
+class Maemo5PickerAction : public QWidgetAction {
+ Q_OBJECT
+public:
+ Maemo5PickerAction(const QString &text, QActionGroup *actions, QObject *parent)
+ : QWidgetAction(parent), m_text(text), m_actions(actions)
+ { }
+
+ QWidget *createWidget(QWidget *parent)
+ {
+ QMaemo5ValueButton *button = new QMaemo5ValueButton(m_text, parent);
+ button->setValueLayout(QMaemo5ValueButton::ValueUnderTextCentered);
+ QMaemo5ListPickSelector *pick = new QMaemo5ListPickSelector(button);
+ button->setPickSelector(pick);
+ if (m_actions) {
+ QStringList sl;
+ int curIdx = -1, idx = 0;
+ foreach (QAction *a, m_actions->actions()) {
+ sl << a->text();
+ if (a->isChecked())
+ curIdx = idx;
+ idx++;
+ }
+ pick->setModel(new QStringListModel(sl));
+ pick->setCurrentIndex(curIdx);
+ } else {
+ button->setEnabled(false);
+ }
+ connect(pick, SIGNAL(selected(QString)), this, SLOT(emitTriggered()));
+ return button;
+ }
+
+private slots:
+ void emitTriggered()
+ {
+ QMaemo5ListPickSelector *pick = qobject_cast<QMaemo5ListPickSelector *>(sender());
+ if (!pick)
+ return;
+ int idx = pick->currentIndex();
+
+ if (m_actions && idx >= 0 && idx < m_actions->actions().count())
+ m_actions->actions().at(idx)->trigger();
+ }
+
+private:
+ QString m_text;
+ QPointer<QActionGroup> m_actions;
+};
+
+#endif // Q_WS_MAEMO_5
+
+static struct { const char *name, *args; } ffmpegprofiles[] = {
+ {"Maximum Quality", "-sameq"},
+ {"High Quality", "-qmax 2"},
+ {"Medium Quality", "-qmax 6"},
+ {"Low Quality", "-qmax 16"},
+ {"Custom ffmpeg arguments", ""},
+ {0,0}
+};
+
+class RecordingDialog : public QDialog, public Ui::RecordingOptions {
+ Q_OBJECT
+
+public:
+ RecordingDialog(QWidget *parent) : QDialog(parent)
+ {
+ setupUi(this);
+#ifndef Q_WS_MAEMO_5
+ hz->setValidator(new QDoubleValidator(hz));
+#endif
+ for (int i=0; ffmpegprofiles[i].name; ++i) {
+ profile->addItem(ffmpegprofiles[i].name);
+ }
+ }
+
+ void setArguments(QString a)
+ {
+ int i;
+ for (i=0; ffmpegprofiles[i].args[0]; ++i) {
+ if (ffmpegprofiles[i].args == a) {
+ profile->setCurrentIndex(i);
+ args->setText(QLatin1String(ffmpegprofiles[i].args));
+ return;
+ }
+ }
+ customargs = a;
+ args->setText(a);
+ profile->setCurrentIndex(i);
+ }
+
+ QString arguments() const
+ {
+ int i = profile->currentIndex();
+ return ffmpegprofiles[i].args[0] ? QLatin1String(ffmpegprofiles[i].args) : customargs;
+ }
+
+ void setOriginalSize(const QSize &s)
+ {
+ QString str = tr("Original (%1x%2)").arg(s.width()).arg(s.height());
+
+#ifdef Q_WS_MAEMO_5
+ sizeCombo->setItemText(0, str);
+#else
+ sizeOriginal->setText(str);
+ if (sizeWidth->value()<=1) {
+ sizeWidth->setValue(s.width());
+ sizeHeight->setValue(s.height());
+ }
+#endif
+ }
+
+ void showffmpegOptions(bool b)
+ {
+#ifdef Q_WS_MAEMO_5
+ profileLabel->setVisible(b);
+ profile->setVisible(b);
+ ffmpegHelp->setVisible(b);
+ args->setVisible(b);
+#else
+ ffmpegOptions->setVisible(b);
+#endif
+ }
+
+ void showRateOptions(bool b)
+ {
+#ifdef Q_WS_MAEMO_5
+ rateLabel->setVisible(b);
+ rateCombo->setVisible(b);
+#else
+ rateOptions->setVisible(b);
+#endif
+ }
+
+ void setVideoRate(int rate)
+ {
+#ifdef Q_WS_MAEMO_5
+ int idx;
+ if (rate >= 60)
+ idx = 0;
+ else if (rate >= 50)
+ idx = 2;
+ else if (rate >= 25)
+ idx = 3;
+ else if (rate >= 24)
+ idx = 4;
+ else if (rate >= 20)
+ idx = 5;
+ else if (rate >= 15)
+ idx = 6;
+ else
+ idx = 7;
+ rateCombo->setCurrentIndex(idx);
+#else
+ if (rate == 24)
+ hz24->setChecked(true);
+ else if (rate == 25)
+ hz25->setChecked(true);
+ else if (rate == 50)
+ hz50->setChecked(true);
+ else if (rate == 60)
+ hz60->setChecked(true);
+ else {
+ hzCustom->setChecked(true);
+ hz->setText(QString::number(rate));
+ }
+#endif
+ }
+
+ int videoRate() const
+ {
+#ifdef Q_WS_MAEMO_5
+ switch (rateCombo->currentIndex()) {
+ case 0: return 60;
+ case 1: return 50;
+ case 2: return 25;
+ case 3: return 24;
+ case 4: return 20;
+ case 5: return 15;
+ case 7: return 10;
+ default: return 60;
+ }
+#else
+ if (hz24->isChecked())
+ return 24;
+ else if (hz25->isChecked())
+ return 25;
+ else if (hz50->isChecked())
+ return 50;
+ else if (hz60->isChecked())
+ return 60;
+ else {
+ return hz->text().toInt();
+ }
+#endif
+ }
+
+ QSize videoSize() const
+ {
+#ifdef Q_WS_MAEMO_5
+ switch (sizeCombo->currentIndex()) {
+ case 0: return QSize();
+ case 1: return QSize(640,480);
+ case 2: return QSize(320,240);
+ case 3: return QSize(1280,720);
+ default: return QSize();
+ }
+#else
+ if (sizeOriginal->isChecked())
+ return QSize();
+ else if (size720p->isChecked())
+ return QSize(1280,720);
+ else if (sizeVGA->isChecked())
+ return QSize(640,480);
+ else if (sizeQVGA->isChecked())
+ return QSize(320,240);
+ else
+ return QSize(sizeWidth->value(), sizeHeight->value());
+#endif
+ }
+
+
+
+private slots:
+ void pickProfile(int i)
+ {
+ if (ffmpegprofiles[i].args[0]) {
+ args->setText(QLatin1String(ffmpegprofiles[i].args));
+ } else {
+ args->setText(customargs);
+ }
+ }
+
+ void storeCustomArgs(QString s)
+ {
+ setArguments(s);
+ }
+
+private:
+ QString customargs;
+};
+
+class PersistentCookieJar : public QNetworkCookieJar {
+public:
+ PersistentCookieJar(QObject *parent) : QNetworkCookieJar(parent) { load(); }
+ ~PersistentCookieJar() { save(); }
+
+ virtual QList<QNetworkCookie> cookiesForUrl(const QUrl &url) const
+ {
+ QMutexLocker lock(&mutex);
+ return QNetworkCookieJar::cookiesForUrl(url);
+ }
+
+ virtual bool setCookiesFromUrl(const QList<QNetworkCookie> &cookieList, const QUrl &url)
+ {
+ QMutexLocker lock(&mutex);
+ return QNetworkCookieJar::setCookiesFromUrl(cookieList, url);
+ }
+
+private:
+ void save()
+ {
+ QMutexLocker lock(&mutex);
+ QList<QNetworkCookie> list = allCookies();
+ QByteArray data;
+ foreach (QNetworkCookie cookie, list) {
+ if (!cookie.isSessionCookie()) {
+ data.append(cookie.toRawForm());
+ data.append("\n");
+ }
+ }
+ QSettings settings;
+ settings.setValue("Cookies",data);
+ }
+
+ void load()
+ {
+ QMutexLocker lock(&mutex);
+ QSettings settings;
+ QByteArray data = settings.value("Cookies").toByteArray();
+ setAllCookies(QNetworkCookie::parseCookies(data));
+ }
+
+ mutable QMutex mutex;
+};
+
+class SystemProxyFactory : public QNetworkProxyFactory
+{
+public:
+ SystemProxyFactory() : proxyDirty(true), httpProxyInUse(false) {
+ }
+
+ virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query)
+ {
+ if (proxyDirty)
+ setupProxy();
+ QString protocolTag = query.protocolTag();
+ if (httpProxyInUse && (protocolTag == "http" || protocolTag == "https")) {
+ QList<QNetworkProxy> ret;
+ ret << httpProxy;
+ return ret;
+ }
+#ifdef Q_OS_WIN
+ // systemProxyForQuery can take insanely long on Windows (QTBUG-10106)
+ return QNetworkProxyFactory::proxyForQuery(query);
+#else
+ return QNetworkProxyFactory::systemProxyForQuery(query);
+#endif
+ }
+
+ void setupProxy() {
+ // Don't bother locking because we know that the proxy only
+ // changes in response to the settings dialog and that
+ // the view will be reloaded.
+ proxyDirty = false;
+ httpProxyInUse = ProxySettings::httpProxyInUse();
+ if (httpProxyInUse)
+ httpProxy = ProxySettings::httpProxy();
+ }
+
+ void proxyChanged() {
+ proxyDirty = true;
+ }
+
+private:
+ volatile bool proxyDirty;
+ bool httpProxyInUse;
+ QNetworkProxy httpProxy;
+};
+
+class NetworkAccessManagerFactory : public QObject, public QDeclarativeNetworkAccessManagerFactory
+{
+ Q_OBJECT
+public:
+ NetworkAccessManagerFactory() : cacheSize(0) {}
+ ~NetworkAccessManagerFactory() {}
+
+ QNetworkAccessManager *create(QObject *parent);
+
+ void setCacheSize(int size) {
+ if (size != cacheSize) {
+ cacheSize = size;
+ }
+ }
+
+ void proxyChanged() {
+ foreach (QNetworkAccessManager *nam, namList) {
+ static_cast<SystemProxyFactory*>(nam->proxyFactory())->proxyChanged();
+ }
+ }
+
+ static PersistentCookieJar *cookieJar;
+
+private slots:
+ void managerDestroyed(QObject *obj) {
+ namList.removeOne(static_cast<QNetworkAccessManager*>(obj));
+ }
+
+private:
+ QMutex mutex;
+ int cacheSize;
+ QList<QNetworkAccessManager*> namList;
+};
+
+PersistentCookieJar *NetworkAccessManagerFactory::cookieJar = 0;
+
+static void cleanup_cookieJar()
+{
+ delete NetworkAccessManagerFactory::cookieJar;
+ NetworkAccessManagerFactory::cookieJar = 0;
+}
+
+QNetworkAccessManager *NetworkAccessManagerFactory::create(QObject *parent)
+{
+ QMutexLocker lock(&mutex);
+ QNetworkAccessManager *manager = new QNetworkAccessManager(parent);
+ if (!cookieJar) {
+ qAddPostRoutine(cleanup_cookieJar);
+ cookieJar = new PersistentCookieJar(0);
+ }
+ manager->setCookieJar(cookieJar);
+ cookieJar->setParent(0);
+ manager->setProxyFactory(new SystemProxyFactory);
+ if (cacheSize > 0) {
+ QNetworkDiskCache *cache = new QNetworkDiskCache;
+ cache->setCacheDirectory(QDir::tempPath()+QLatin1String("/qml-viewer-network-cache"));
+ cache->setMaximumCacheSize(cacheSize);
+ manager->setCache(cache);
+ } else {
+ manager->setCache(0);
+ }
+ connect(manager, SIGNAL(destroyed(QObject*)), this, SLOT(managerDestroyed(QObject*)));
+ namList.append(manager);
+ qDebug() << "created new network access manager for" << parent;
+ return manager;
+}
+
+QString QDeclarativeViewer::getVideoFileName()
+{
+ QString title = convertAvailable || ffmpegAvailable ? tr("Save Video File") : tr("Save PNG Frames");
+ QStringList types;
+ if (ffmpegAvailable) types += tr("Common Video files")+QLatin1String(" (*.avi *.mpeg *.mov)");
+ if (convertAvailable) types += tr("GIF Animation")+QLatin1String(" (*.gif)");
+ types += tr("Individual PNG frames")+QLatin1String(" (*.png)");
+ if (ffmpegAvailable) types += tr("All ffmpeg formats (*.*)");
+ return QFileDialog::getSaveFileName(this, title, "", types.join(";; "));
+}
+
+QDeclarativeViewer::QDeclarativeViewer(QWidget *parent, Qt::WindowFlags flags)
+ : QMainWindow(parent, flags)
+ , loggerWindow(new LoggerWidget(this))
+ , frame_stream(0)
+ , rotateAction(0)
+ , orientation(0)
+ , showWarningsWindow(0)
+ , m_scriptOptions(0)
+ , tester(0)
+ , useQmlFileBrowser(true)
+ , translator(0)
+{
+ QDeclarativeViewer::registerTypes();
+ setWindowTitle(tr("Qt QML Viewer"));
+#ifdef Q_WS_MAEMO_5
+ setAttribute(Qt::WA_Maemo5StackedWindow);
+// setPalette(QApplication::palette("QLabel"));
+#endif
+
+ devicemode = false;
+ canvas = 0;
+ record_autotime = 0;
+ record_rate = 50;
+ record_args += QLatin1String("-sameq");
+
+ recdlg = new RecordingDialog(this);
+ connect(recdlg->pickfile, SIGNAL(clicked()), this, SLOT(pickRecordingFile()));
+ senseFfmpeg();
+ senseImageMagick();
+ if (!ffmpegAvailable)
+ recdlg->showffmpegOptions(false);
+ if (!ffmpegAvailable && !convertAvailable)
+ recdlg->showRateOptions(false);
+ QString warn;
+ if (!ffmpegAvailable) {
+ if (!convertAvailable)
+ warn = tr("ffmpeg and ImageMagick not available - no video output");
+ else
+ warn = tr("ffmpeg not available - GIF and PNG outputs only");
+ recdlg->warning->setText(warn);
+ } else {
+ recdlg->warning->hide();
+ }
+
+ canvas = new DragAndDropView(this);
+
+ canvas->setAttribute(Qt::WA_OpaquePaintEvent);
+ canvas->setAttribute(Qt::WA_NoSystemBackground);
+
+ canvas->setFocus();
+
+ QObject::connect(canvas, SIGNAL(sceneResized(QSize)), this, SLOT(sceneResized(QSize)));
+ QObject::connect(canvas, SIGNAL(statusChanged(QDeclarativeView::Status)), this, SLOT(statusChanged()));
+ QObject::connect(canvas->engine(), SIGNAL(quit()), this, SLOT(close()));
+
+ QObject::connect(warningsWidget(), SIGNAL(opened()), this, SLOT(warningsWidgetOpened()));
+ QObject::connect(warningsWidget(), SIGNAL(closed()), this, SLOT(warningsWidgetClosed()));
+
+ if (!(flags & Qt::FramelessWindowHint)) {
+ createMenu();
+ changeOrientation(orientation->actions().value(0));
+ } else {
+ setMenuBar(0);
+ }
+
+ setCentralWidget(canvas);
+
+ namFactory = new NetworkAccessManagerFactory;
+ canvas->engine()->setNetworkAccessManagerFactory(namFactory);
+
+ connect(&autoStartTimer, SIGNAL(timeout()), this, SLOT(autoStartRecording()));
+ connect(&autoStopTimer, SIGNAL(timeout()), this, SLOT(autoStopRecording()));
+ connect(&recordTimer, SIGNAL(timeout()), this, SLOT(recordFrame()));
+ connect(DeviceOrientation::instance(), SIGNAL(orientationChanged()),
+ this, SLOT(orientationChanged()), Qt::QueuedConnection);
+ autoStartTimer.setSingleShot(true);
+ autoStopTimer.setSingleShot(true);
+ recordTimer.setSingleShot(false);
+
+ QObject::connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(appAboutToQuit()));
+}
+
+QDeclarativeViewer::~QDeclarativeViewer()
+{
+ delete loggerWindow;
+ canvas->engine()->setNetworkAccessManagerFactory(0);
+ delete namFactory;
+}
+
+void QDeclarativeViewer::enableExperimentalGestures()
+{
+#ifndef QT_NO_GESTURES
+ canvas->viewport()->grabGesture(Qt::TapGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent);
+ canvas->viewport()->grabGesture(Qt::TapAndHoldGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent);
+ canvas->viewport()->grabGesture(Qt::PanGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent);
+ canvas->viewport()->grabGesture(Qt::PinchGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent);
+ canvas->viewport()->grabGesture(Qt::SwipeGesture,Qt::DontStartGestureOnChildren|Qt::ReceivePartialGestures|Qt::IgnoredGesturesPropagateToParent);
+ canvas->viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
+#endif
+}
+
+QDeclarativeView *QDeclarativeViewer::view() const
+{
+ return canvas;
+}
+
+LoggerWidget *QDeclarativeViewer::warningsWidget() const
+{
+ return loggerWindow;
+}
+
+void QDeclarativeViewer::createMenu()
+{
+ QAction *openAction = new QAction(tr("&Open..."), this);
+ openAction->setShortcuts(QKeySequence::Open);
+ connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
+
+ QAction *openUrlAction = new QAction(tr("Open &URL..."), this);
+ connect(openUrlAction, SIGNAL(triggered()), this, SLOT(openUrl()));
+
+ QAction *reloadAction = new QAction(tr("&Reload"), this);
+ reloadAction->setShortcuts(QKeySequence::Refresh);
+ connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload()));
+
+ QAction *snapshotAction = new QAction(tr("&Take Snapshot"), this);
+ snapshotAction->setShortcut(QKeySequence("F3"));
+ connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot()));
+
+ recordAction = new QAction(tr("Start Recording &Video"), this);
+ recordAction->setShortcut(QKeySequence("F9"));
+ connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecordingWithSelection()));
+
+ QAction *recordOptions = new QAction(tr("Video &Options..."), this);
+ connect(recordOptions, SIGNAL(triggered()), this, SLOT(chooseRecordingOptions()));
+
+ QAction *slowAction = new QAction(tr("&Slow Down Animations"), this);
+ slowAction->setShortcut(QKeySequence("Ctrl+."));
+ slowAction->setCheckable(true);
+ connect(slowAction, SIGNAL(triggered(bool)), this, SLOT(setSlowMode(bool)));
+
+ showWarningsWindow = new QAction(tr("Show Warnings"), this);
+ showWarningsWindow->setCheckable((true));
+ showWarningsWindow->setChecked(loggerWindow->isVisible());
+ connect(showWarningsWindow, SIGNAL(triggered(bool)), this, SLOT(showWarnings(bool)));
+
+ QAction *proxyAction = new QAction(tr("HTTP &Proxy..."), this);
+ connect(proxyAction, SIGNAL(triggered()), this, SLOT(showProxySettings()));
+
+ QAction *fullscreenAction = new QAction(tr("Full Screen"), this);
+ fullscreenAction->setCheckable(true);
+ connect(fullscreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen()));
+
+ rotateAction = new QAction(tr("Rotate orientation"), this);
+ rotateAction->setShortcut(QKeySequence("Ctrl+T"));
+ connect(rotateAction, SIGNAL(triggered()), this, SLOT(rotateOrientation()));
+
+ orientation = new QActionGroup(this);
+ orientation->setExclusive(true);
+ connect(orientation, SIGNAL(triggered(QAction*)), this, SLOT(changeOrientation(QAction*)));
+
+#if defined(Q_OS_SYMBIAN)
+ QAction *autoOrientationAction = new QAction(tr("Auto-orientation"), this);
+ autoOrientationAction->setCheckable(true);
+#endif
+ QAction *portraitAction = new QAction(tr("Portrait"), this);
+ portraitAction->setCheckable(true);
+ QAction *landscapeAction = new QAction(tr("Landscape"), this);
+ landscapeAction->setCheckable(true);
+#if !defined(Q_OS_SYMBIAN)
+ QAction *portraitInvAction = new QAction(tr("Portrait (inverted)"), this);
+ portraitInvAction->setCheckable(true);
+ QAction *landscapeInvAction = new QAction(tr("Landscape (inverted)"), this);
+ landscapeInvAction->setCheckable(true);
+#endif
+
+ QAction *aboutAction = new QAction(tr("&About Qt..."), this);
+ aboutAction->setMenuRole(QAction::AboutQtRole);
+ connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+
+ QAction *closeAction = new QAction(tr("&Close"), this);
+ closeAction->setShortcuts(QKeySequence::Close);
+ connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
+
+ QAction *quitAction = new QAction(tr("&Quit"), this);
+ quitAction->setMenuRole(QAction::QuitRole);
+ quitAction->setShortcuts(QKeySequence::Quit);
+ connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
+
+ QMenuBar *menu = menuBar();
+ if (!menu)
+ return;
+
+#if defined(Q_WS_MAEMO_5)
+ menu->addAction(openAction);
+ menu->addAction(openUrlAction);
+ menu->addAction(reloadAction);
+
+ menu->addAction(snapshotAction);
+ menu->addAction(recordAction);
+
+ menu->addAction(recordOptions);
+ menu->addAction(proxyAction);
+
+ menu->addAction(slowAction);
+ menu->addAction(showWarningsWindow);
+
+ orientation->addAction(landscapeAction);
+ orientation->addAction(portraitAction);
+ menu->addAction(new Maemo5PickerAction(tr("Set orientation"), orientation, this));
+ menu->addAction(fullscreenAction);
+ return;
+#endif // Q_WS_MAEMO_5
+
+ QMenu *fileMenu = menu->addMenu(tr("&File"));
+ fileMenu->addAction(openAction);
+ fileMenu->addAction(openUrlAction);
+ fileMenu->addAction(reloadAction);
+ fileMenu->addSeparator();
+ fileMenu->addAction(closeAction);
+#if !defined(Q_OS_SYMBIAN)
+ fileMenu->addAction(quitAction);
+
+ QMenu *recordMenu = menu->addMenu(tr("&Recording"));
+ recordMenu->addAction(snapshotAction);
+ recordMenu->addAction(recordAction);
+
+ QMenu *debugMenu = menu->addMenu(tr("&Debugging"));
+ debugMenu->addAction(slowAction);
+ debugMenu->addAction(showWarningsWindow);
+#endif // ! Q_OS_SYMBIAN
+
+ QMenu *settingsMenu = menu->addMenu(tr("&Settings"));
+ settingsMenu->addAction(proxyAction);
+#if defined(Q_OS_SYMBIAN)
+ settingsMenu->addAction(fullscreenAction);
+#else
+ settingsMenu->addAction(recordOptions);
+ settingsMenu->addMenu(loggerWindow->preferencesMenu());
+#endif // !Q_OS_SYMBIAN
+ settingsMenu->addAction(rotateAction);
+
+ QMenu *propertiesMenu = settingsMenu->addMenu(tr("Properties"));
+
+#if defined(Q_OS_SYMBIAN)
+ orientation->addAction(autoOrientationAction);
+#endif
+ orientation->addAction(portraitAction);
+ orientation->addAction(landscapeAction);
+#if !defined(Q_OS_SYMBIAN)
+ orientation->addAction(portraitInvAction);
+ orientation->addAction(landscapeInvAction);
+#endif
+ propertiesMenu->addActions(orientation->actions());
+
+ QMenu *helpMenu = menu->addMenu(tr("&Help"));
+ helpMenu->addAction(aboutAction);
+}
+
+void QDeclarativeViewer::showProxySettings()
+{
+ ProxySettings settingsDlg (this);
+
+ connect (&settingsDlg, SIGNAL (accepted()), this, SLOT (proxySettingsChanged ()));
+
+ settingsDlg.exec();
+}
+
+void QDeclarativeViewer::proxySettingsChanged()
+{
+ namFactory->proxyChanged();
+ reload ();
+}
+
+void QDeclarativeViewer::rotateOrientation()
+{
+#if defined(Q_WS_S60)
+ CAknAppUi *appUi = static_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
+ if (appUi) {
+ CAknAppUi::TAppUiOrientation oldOrientation = appUi->Orientation();
+ QString newOrientation;
+ if (oldOrientation == CAknAppUi::EAppUiOrientationPortrait) {
+ newOrientation = QLatin1String("Landscape");
+ } else {
+ newOrientation = QLatin1String("Portrait");
+ }
+ foreach (QAction *action, orientation->actions()) {
+ if (action->text() == newOrientation) {
+ changeOrientation(action);
+ }
+ }
+ }
+#else
+ QAction *current = orientation->checkedAction();
+ QList<QAction *> actions = orientation->actions();
+ int index = actions.indexOf(current);
+ if (index < 0)
+ return;
+
+ QAction *newOrientation = actions[(index + 1) % actions.count()];
+ changeOrientation(newOrientation);
+#endif
+}
+
+void QDeclarativeViewer::toggleFullScreen()
+{
+ if (isFullScreen())
+ showMaximized();
+ else
+ showFullScreen();
+}
+
+void QDeclarativeViewer::showWarnings(bool show)
+{
+ loggerWindow->setVisible(show);
+}
+
+void QDeclarativeViewer::warningsWidgetOpened()
+{
+ showWarningsWindow->setChecked(true);
+}
+
+void QDeclarativeViewer::warningsWidgetClosed()
+{
+ showWarningsWindow->setChecked(false);
+}
+
+void QDeclarativeViewer::takeSnapShot()
+{
+ static int snapshotcount = 1;
+ QString snapFileName = QString(QLatin1String("snapshot%1.png")).arg(snapshotcount);
+ QPixmap::grabWidget(canvas).save(snapFileName);
+ qDebug() << "Wrote" << snapFileName;
+ ++snapshotcount;
+}
+
+void QDeclarativeViewer::pickRecordingFile()
+{
+ QString fileName = getVideoFileName();
+ if (!fileName.isEmpty())
+ recdlg->file->setText(fileName);
+}
+
+void QDeclarativeViewer::chooseRecordingOptions()
+{
+ // File
+ recdlg->file->setText(record_file);
+
+ // Size
+ recdlg->setOriginalSize(canvas->size());
+
+ // Rate
+ recdlg->setVideoRate(record_rate);
+
+
+ // Profile
+ recdlg->setArguments(record_args.join(" "));
+ if (recdlg->exec()) {
+ // File
+ record_file = recdlg->file->text();
+ // Size
+ record_outsize = recdlg->videoSize();
+ // Rate
+ record_rate = recdlg->videoRate();
+ // Profile
+ record_args = recdlg->arguments().split(" ",QString::SkipEmptyParts);
+ }
+}
+
+void QDeclarativeViewer::toggleRecordingWithSelection()
+{
+ if (!recordTimer.isActive()) {
+ if (record_file.isEmpty()) {
+ QString fileName = getVideoFileName();
+ if (fileName.isEmpty())
+ return;
+ if (!fileName.contains(QRegExp(".[^\\/]*$")))
+ fileName += ".avi";
+ setRecordFile(fileName);
+ }
+ }
+ toggleRecording();
+}
+
+void QDeclarativeViewer::toggleRecording()
+{
+ if (record_file.isEmpty()) {
+ toggleRecordingWithSelection();
+ return;
+ }
+ bool recording = !recordTimer.isActive();
+ recordAction->setText(recording ? tr("&Stop Recording Video\tF9") : tr("&Start Recording Video\tF9"));
+ setRecording(recording);
+}
+
+void QDeclarativeViewer::setSlowMode(bool enable)
+{
+ QUnifiedTimer::instance()->setSlowModeEnabled(enable);
+}
+
+void QDeclarativeViewer::addLibraryPath(const QString& lib)
+{
+ canvas->engine()->addImportPath(lib);
+}
+
+void QDeclarativeViewer::addPluginPath(const QString& plugin)
+{
+ canvas->engine()->addPluginPath(plugin);
+}
+
+void QDeclarativeViewer::reload()
+{
+ open(currentFileOrUrl);
+}
+
+void QDeclarativeViewer::openFile()
+{
+ QString cur = canvas->source().toLocalFile();
+ if (useQmlFileBrowser) {
+ open("qrc:/browser/Browser.qml");
+ } else {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open QML file"), cur, tr("QML Files (*.qml)"));
+ if (!fileName.isEmpty()) {
+ QFileInfo fi(fileName);
+ open(fi.absoluteFilePath());
+ }
+ }
+}
+
+void QDeclarativeViewer::openUrl()
+{
+ QString cur = canvas->source().toLocalFile();
+ QString url= QInputDialog::getText(this, tr("Open QML file"), tr("URL of main QML file:"), QLineEdit::Normal, cur);
+ if (!url.isEmpty())
+ open(url);
+}
+
+void QDeclarativeViewer::statusChanged()
+{
+ if (canvas->status() == QDeclarativeView::Error && tester)
+ tester->executefailure();
+
+ if (canvas->status() == QDeclarativeView::Ready) {
+ initialSize = canvas->initialSize();
+ updateSizeHints(true);
+ }
+}
+
+void QDeclarativeViewer::launch(const QString& file_or_url)
+{
+ QMetaObject::invokeMethod(this, "open", Qt::QueuedConnection, Q_ARG(QString, file_or_url));
+}
+
+void QDeclarativeViewer::loadTranslationFile(const QString& directory)
+{
+ if (!translator) {
+ translator = new QTranslator(this);
+ QApplication::installTranslator(translator);
+ }
+
+ translator->load(QLatin1String("qml_" )+QLocale::system().name(), directory + QLatin1String("/i18n"));
+}
+
+void QDeclarativeViewer::loadDummyDataFiles(const QString& directory)
+{
+ QDir dir(directory+"/dummydata", "*.qml");
+ QStringList list = dir.entryList();
+ for (int i = 0; i < list.size(); ++i) {
+ QString qml = list.at(i);
+ QDeclarativeComponent comp(canvas->engine(), dir.filePath(qml));
+ QObject *dummyData = comp.create();
+
+ if(comp.isError()) {
+ QList<QDeclarativeError> errors = comp.errors();
+ foreach (const QDeclarativeError &error, errors) {
+ qWarning() << error;
+ }
+ if (tester) tester->executefailure();
+ }
+
+ if (dummyData) {
+ qWarning() << "Loaded dummy data:" << dir.filePath(qml);
+ qml.truncate(qml.length()-4);
+ canvas->rootContext()->setContextProperty(qml, dummyData);
+ dummyData->setParent(this);
+ }
+ }
+}
+
+bool QDeclarativeViewer::open(const QString& file_or_url)
+{
+ currentFileOrUrl = file_or_url;
+
+ QUrl url;
+ QFileInfo fi(file_or_url);
+ if (fi.exists())
+ url = QUrl::fromLocalFile(fi.absoluteFilePath());
+ else
+ url = QUrl(file_or_url);
+ setWindowTitle(tr("%1 - Qt QML Viewer").arg(file_or_url));
+
+ if (!m_script.isEmpty())
+ tester = new QDeclarativeTester(m_script, m_scriptOptions, canvas);
+
+ delete canvas->rootObject();
+ canvas->engine()->clearComponentCache();
+ QDeclarativeContext *ctxt = canvas->rootContext();
+ ctxt->setContextProperty("qmlViewer", this);
+#ifdef Q_OS_SYMBIAN
+ ctxt->setContextProperty("qmlViewerFolder", "E:\\"); // Documents on your S60 phone
+#else
+ ctxt->setContextProperty("qmlViewerFolder", QDir::currentPath());
+#endif
+
+ ctxt->setContextProperty("runtime", Runtime::instance());
+
+ QString fileName = url.toLocalFile();
+ if (!fileName.isEmpty()) {
+ fi.setFile(fileName);
+ if (fi.exists()) {
+ if (fi.suffix().toLower() != QLatin1String("qml")) {
+ qWarning() << "qml cannot open non-QML file" << fileName;
+ return false;
+ }
+
+ QFileInfo fi(fileName);
+ loadTranslationFile(fi.path());
+ loadDummyDataFiles(fi.path());
+ } else {
+ qWarning() << "qml cannot find file:" << fileName;
+ return false;
+ }
+ }
+
+ QTime t;
+ t.start();
+
+ canvas->setSource(url);
+
+ return true;
+}
+
+void QDeclarativeViewer::setAutoRecord(int from, int to)
+{
+ if (from==0) from=1; // ensure resized
+ record_autotime = to-from;
+ autoStartTimer.setInterval(from);
+ autoStartTimer.start();
+}
+
+void QDeclarativeViewer::setRecordArgs(const QStringList& a)
+{
+ record_args = a;
+}
+
+void QDeclarativeViewer::setRecordFile(const QString& f)
+{
+ record_file = f;
+}
+
+void QDeclarativeViewer::setRecordRate(int fps)
+{
+ record_rate = fps;
+}
+
+void QDeclarativeViewer::sceneResized(QSize)
+{
+ updateSizeHints();
+}
+
+void QDeclarativeViewer::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_0 && devicemode)
+ exit(0);
+ else if (event->key() == Qt::Key_F1 || (event->key() == Qt::Key_1 && devicemode)) {
+ qDebug() << "F1 - help\n"
+ << "F2 - save test script\n"
+ << "F3 - take PNG snapshot\n"
+ << "F4 - show items and state\n"
+ << "F5 - reload QML\n"
+ << "F6 - show object tree\n"
+ << "F7 - show timing\n"
+ << "F9 - toggle video recording\n"
+ << "F10 - toggle orientation\n"
+ << "device keys: 0=quit, 1..8=F1..F8"
+ ;
+ } else if (event->key() == Qt::Key_F2 || (event->key() == Qt::Key_2 && devicemode)) {
+ if (tester && m_scriptOptions & Record)
+ tester->save();
+ } else if (event->key() == Qt::Key_F3 || (event->key() == Qt::Key_3 && devicemode)) {
+ takeSnapShot();
+ } else if (event->key() == Qt::Key_F5 || (event->key() == Qt::Key_5 && devicemode)) {
+ reload();
+ } else if (event->key() == Qt::Key_F9 || (event->key() == Qt::Key_9 && devicemode)) {
+ toggleRecording();
+ } else if (event->key() == Qt::Key_F10) {
+ rotateOrientation();
+ }
+
+ QWidget::keyPressEvent(event);
+}
+
+bool QDeclarativeViewer::event(QEvent *event)
+{
+ if (event->type() == QEvent::WindowActivate) {
+ Runtime::instance()->setActiveWindow(true);
+ DeviceOrientation::instance()->resumeListening();
+ } else if (event->type() == QEvent::WindowDeactivate) {
+ Runtime::instance()->setActiveWindow(false);
+ DeviceOrientation::instance()->pauseListening();
+ }
+ return QWidget::event(event);
+}
+
+void QDeclarativeViewer::senseImageMagick()
+{
+ QProcess proc;
+ proc.start("convert", QStringList() << "-h");
+ proc.waitForFinished(2000);
+ QString help = proc.readAllStandardOutput();
+ convertAvailable = help.contains("ImageMagick");
+}
+
+void QDeclarativeViewer::senseFfmpeg()
+{
+ QProcess proc;
+ proc.start("ffmpeg", QStringList() << "-h");
+ proc.waitForFinished(2000);
+ QString ffmpegHelp = proc.readAllStandardOutput();
+ ffmpegAvailable = ffmpegHelp.contains("-s ");
+ ffmpegHelp = tr("Video recording uses ffmpeg:")+"\n\n"+ffmpegHelp;
+
+ QDialog *d = new QDialog(recdlg);
+ QVBoxLayout *l = new QVBoxLayout(d);
+ QTextBrowser *b = new QTextBrowser(d);
+ QFont f = b->font();
+ f.setFamily("courier");
+ b->setFont(f);
+ b->setText(ffmpegHelp);
+ l->addWidget(b);
+ d->setLayout(l);
+ ffmpegHelpWindow = d;
+ connect(recdlg->ffmpegHelp,SIGNAL(clicked()), ffmpegHelpWindow, SLOT(show()));
+}
+
+void QDeclarativeViewer::setRecording(bool on)
+{
+ if (on == recordTimer.isActive())
+ return;
+
+ int period = int(1000/record_rate+0.5);
+ QUnifiedTimer::instance()->setTimingInterval(on ? period:16);
+ QUnifiedTimer::instance()->setConsistentTiming(on);
+ if (on) {
+ canvas->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
+ recordTimer.setInterval(period);
+ recordTimer.start();
+ frame_fmt = record_file.right(4).toLower();
+ frame = QImage(canvas->width(),canvas->height(),QImage::Format_RGB32);
+ if (frame_fmt != ".png" && (!convertAvailable || frame_fmt != ".gif")) {
+ // Stream video to ffmpeg
+
+ QProcess *proc = new QProcess(this);
+ connect(proc, SIGNAL(finished(int)), this, SLOT(ffmpegFinished(int)));
+ frame_stream = proc;
+
+ QStringList args;
+ args << "-y";
+ args << "-r" << QString::number(record_rate);
+ args << "-f" << "rawvideo";
+ args << "-pix_fmt" << (frame_fmt == ".gif" ? "rgb24" : "rgb32");
+ args << "-s" << QString("%1x%2").arg(canvas->width()).arg(canvas->height());
+ args << "-i" << "-";
+ if (record_outsize.isValid()) {
+ args << "-s" << QString("%1x%2").arg(record_outsize.width()).arg(record_outsize.height());
+ args << "-aspect" << QString::number(double(canvas->width())/canvas->height());
+ }
+ args += record_args;
+ args << record_file;
+ proc->start("ffmpeg",args);
+
+ } else {
+ // Store frames, save to GIF/PNG
+ frame_stream = 0;
+ }
+ } else {
+ canvas->setViewportUpdateMode(QGraphicsView::MinimalViewportUpdate);
+ recordTimer.stop();
+ if (frame_stream) {
+ qDebug() << "Saving video...";
+ frame_stream->close();
+ qDebug() << "Wrote" << record_file;
+ } else {
+ QProgressDialog progress(tr("Saving frames..."), tr("Cancel"), 0, frames.count()+10, this);
+ progress.setWindowModality(Qt::WindowModal);
+
+ int frame=0;
+ QStringList inputs;
+ qDebug() << "Saving frames...";
+
+ QString framename;
+ bool png_output = false;
+ if (record_file.right(4).toLower()==".png") {
+ if (record_file.contains('%'))
+ framename = record_file;
+ else
+ framename = record_file.left(record_file.length()-4)+"%04d"+record_file.right(4);
+ png_output = true;
+ } else {
+ framename = "tmp-frame%04d.png";
+ png_output = false;
+ }
+ foreach (QImage* img, frames) {
+ progress.setValue(progress.value()+1);
+ if (progress.wasCanceled())
+ break;
+ QString name;
+ name.sprintf(framename.toLocal8Bit(),frame++);
+ if (record_outsize.isValid())
+ *img = img->scaled(record_outsize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation);
+ if (record_dither=="ordered")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::OrderedDither).save(name);
+ else if (record_dither=="threshold")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::ThresholdDither).save(name);
+ else if (record_dither=="floyd")
+ img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither).save(name);
+ else
+ img->save(name);
+ inputs << name;
+ delete img;
+ }
+
+ if (!progress.wasCanceled()) {
+ if (png_output) {
+ framename.replace(QRegExp("%\\d*."),"*");
+ qDebug() << "Wrote frames" << framename;
+ inputs.clear(); // don't remove them
+ } else {
+ // ImageMagick and gifsicle for GIF encoding
+ progress.setLabelText(tr("Converting frames to GIF file..."));
+ QStringList args;
+ args << "-delay" << QString::number(period/10);
+ args << inputs;
+ args << record_file;
+ qDebug() << "Converting..." << record_file << "(this may take a while)";
+ if (0!=QProcess::execute("convert", args)) {
+ qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted";
+ inputs.clear(); // don't remove them
+ qDebug() << "Wrote frames tmp-frame*.png";
+ } else {
+ if (record_file.right(4).toLower() == ".gif") {
+ qDebug() << "Compressing..." << record_file;
+ if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file))
+ qWarning() << "Cannot run 'gifsicle' - not compressed";
+ }
+ qDebug() << "Wrote" << record_file;
+ }
+ }
+ }
+
+ progress.setValue(progress.maximum()-1);
+ foreach (QString name, inputs)
+ QFile::remove(name);
+
+ frames.clear();
+ }
+ }
+ qDebug() << "Recording: " << (recordTimer.isActive()?"ON":"OFF");
+}
+
+void QDeclarativeViewer::ffmpegFinished(int code)
+{
+ qDebug() << "ffmpeg returned" << code << frame_stream->readAllStandardError();
+}
+
+void QDeclarativeViewer::appAboutToQuit()
+{
+ // avoid QGLContext errors about invalid contexts on exit
+ canvas->setViewport(0);
+
+ // avoid crashes if messages are received after app has closed
+ delete loggerWindow;
+ loggerWindow = 0;
+ delete tester;
+ tester = 0;
+}
+
+void QDeclarativeViewer::autoStartRecording()
+{
+ setRecording(true);
+ autoStopTimer.setInterval(record_autotime);
+ autoStopTimer.start();
+}
+
+void QDeclarativeViewer::autoStopRecording()
+{
+ setRecording(false);
+}
+
+void QDeclarativeViewer::recordFrame()
+{
+ canvas->QWidget::render(&frame);
+ if (frame_stream) {
+ if (frame_fmt == ".gif") {
+ // ffmpeg can't do 32bpp with gif
+ QImage rgb24 = frame.convertToFormat(QImage::Format_RGB888);
+ frame_stream->write((char*)rgb24.bits(),rgb24.numBytes());
+ } else {
+ frame_stream->write((char*)frame.bits(),frame.numBytes());
+ }
+ } else {
+ frames.append(new QImage(frame));
+ }
+}
+
+void QDeclarativeViewer::changeOrientation(QAction *action)
+{
+ if (!action)
+ return;
+ QString o = action->text();
+ action->setChecked(true);
+#if defined(Q_WS_S60)
+ CAknAppUi *appUi = static_cast<CAknAppUi *>(CEikonEnv::Static()->AppUi());
+ if (appUi) {
+ CAknAppUi::TAppUiOrientation orientation = appUi->Orientation();
+ if (o == QLatin1String("Auto-orientation")) {
+ appUi->SetOrientationL(CAknAppUi::EAppUiOrientationAutomatic);
+ rotateAction->setVisible(false);
+ } else if (o == QLatin1String("Portrait")) {
+ appUi->SetOrientationL(CAknAppUi::EAppUiOrientationPortrait);
+ rotateAction->setVisible(true);
+ } else if (o == QLatin1String("Landscape")) {
+ appUi->SetOrientationL(CAknAppUi::EAppUiOrientationLandscape);
+ rotateAction->setVisible(true);
+ }
+ }
+#else
+ if (o == QLatin1String("Portrait"))
+ DeviceOrientation::instance()->setOrientation(DeviceOrientation::Portrait);
+ else if (o == QLatin1String("Landscape"))
+ DeviceOrientation::instance()->setOrientation(DeviceOrientation::Landscape);
+ else if (o == QLatin1String("Portrait (inverted)"))
+ DeviceOrientation::instance()->setOrientation(DeviceOrientation::PortraitInverted);
+ else if (o == QLatin1String("Landscape (inverted)"))
+ DeviceOrientation::instance()->setOrientation(DeviceOrientation::LandscapeInverted);
+#endif
+}
+
+void QDeclarativeViewer::orientationChanged()
+{
+ updateSizeHints();
+}
+
+void QDeclarativeViewer::setDeviceKeys(bool on)
+{
+ devicemode = on;
+}
+
+void QDeclarativeViewer::setNetworkCacheSize(int size)
+{
+ namFactory->setCacheSize(size);
+}
+
+void QDeclarativeViewer::setUseGL(bool useGL)
+{
+#ifdef GL_SUPPORTED
+ if (useGL) {
+ QGLFormat format = QGLFormat::defaultFormat();
+#ifdef Q_WS_MAC
+ format.setSampleBuffers(true);
+#else
+ format.setSampleBuffers(false);
+#endif
+
+ QGLWidget *glWidget = new QGLWidget(format);
+ //### potentially faster, but causes junk to appear if top-level is Item, not Rectangle
+ //glWidget->setAutoFillBackground(false);
+
+ canvas->setViewport(glWidget);
+ }
+#else
+ Q_UNUSED(useGL)
+#endif
+}
+
+void QDeclarativeViewer::setUseNativeFileBrowser(bool use)
+{
+ useQmlFileBrowser = !use;
+}
+
+void QDeclarativeViewer::setSizeToView(bool sizeToView)
+{
+ QDeclarativeView::ResizeMode resizeMode = sizeToView ? QDeclarativeView::SizeRootObjectToView : QDeclarativeView::SizeViewToRootObject;
+ if (resizeMode != canvas->resizeMode()) {
+ canvas->setResizeMode(resizeMode);
+ updateSizeHints();
+ }
+}
+
+void QDeclarativeViewer::updateSizeHints(bool initial)
+{
+ static bool isRecursive = false;
+
+ if (isRecursive)
+ return;
+ isRecursive = true;
+
+ if (initial || (canvas->resizeMode() == QDeclarativeView::SizeViewToRootObject)) {
+ QSize newWindowSize = initial ? initialSize : canvas->sizeHint();
+ //qWarning() << "USH:" << (initial ? "INIT:" : "V2R:") << "setting fixed size " << newWindowSize;
+ if (!isFullScreen() && !isMaximized()) {
+ canvas->setFixedSize(newWindowSize);
+ resize(1, 1);
+ layout()->setSizeConstraint(QLayout::SetFixedSize);
+ layout()->activate();
+ }
+ }
+ //qWarning() << "USH: R2V: setting free size ";
+ layout()->setSizeConstraint(QLayout::SetNoConstraint);
+ layout()->activate();
+ setMinimumSize(QSize(1,1));
+ setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
+ canvas->setMinimumSize(QSize(0,0));
+ canvas->setMaximumSize(QSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX));
+
+ isRecursive = false;
+}
+
+void QDeclarativeViewer::registerTypes()
+{
+ static bool registered = false;
+
+ if (!registered) {
+ // registering only for exposing the DeviceOrientation::Orientation enum
+ qmlRegisterUncreatableType<DeviceOrientation>("Qt",4,7,"Orientation","");
+ qmlRegisterUncreatableType<DeviceOrientation>("QtQuick",1,0,"Orientation","");
+ registered = true;
+ }
+}
+
+QT_END_NAMESPACE
+
+#include "qmlruntime.moc"
diff --git a/tools/qml/qmlruntime.h b/tools/qml/qmlruntime.h
new file mode 100644
index 0000000..b43aa54
--- /dev/null
+++ b/tools/qml/qmlruntime.h
@@ -0,0 +1,206 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDECLARATIVEVIEWER_H
+#define QDECLARATIVEVIEWER_H
+
+#include <QMainWindow>
+#include <QTimer>
+#include <QTime>
+#include <QList>
+
+#include "loggerwidget.h"
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeView;
+class PreviewDeviceSkin;
+class QDeclarativeTestEngine;
+class QProcess;
+class RecordingDialog;
+class QDeclarativeTester;
+class QNetworkReply;
+class QNetworkCookieJar;
+class NetworkAccessManagerFactory;
+class QTranslator;
+class QActionGroup;
+class QMenuBar;
+
+class QDeclarativeViewer
+ : public QMainWindow
+{
+ Q_OBJECT
+
+public:
+ QDeclarativeViewer(QWidget *parent = 0, Qt::WindowFlags flags = 0);
+ ~QDeclarativeViewer();
+
+ static void registerTypes();
+
+ enum ScriptOption {
+ Play = 0x00000001,
+ Record = 0x00000002,
+ TestImages = 0x00000004,
+ TestErrorProperty = 0x00000008,
+ SaveOnExit = 0x00000010,
+ ExitOnComplete = 0x00000020,
+ ExitOnFailure = 0x00000040,
+ Snapshot = 0x00000080,
+ TestSkipProperty = 0x00000100
+ };
+ Q_DECLARE_FLAGS(ScriptOptions, ScriptOption)
+ void setScript(const QString &s) { m_script = s; }
+ void setScriptOptions(ScriptOptions opt) { m_scriptOptions = opt; }
+ void setRecordDither(const QString& s) { record_dither = s; }
+ void setRecordRate(int fps);
+ void setRecordFile(const QString&);
+ void setRecordArgs(const QStringList&);
+ void setRecording(bool on);
+ bool isRecording() const { return recordTimer.isActive(); }
+ void setAutoRecord(int from, int to);
+ void setDeviceKeys(bool);
+ void setNetworkCacheSize(int size);
+ void addLibraryPath(const QString& lib);
+ void addPluginPath(const QString& plugin);
+ void setUseGL(bool use);
+ void setUseNativeFileBrowser(bool);
+ void setSizeToView(bool sizeToView);
+
+ QDeclarativeView *view() const;
+ LoggerWidget *warningsWidget() const;
+ QString currentFile() const { return currentFileOrUrl; }
+
+ void enableExperimentalGestures();
+
+public slots:
+ void sceneResized(QSize size);
+ bool open(const QString&);
+ void openFile();
+ void openUrl();
+ void reload();
+ void takeSnapShot();
+ void toggleRecording();
+ void toggleRecordingWithSelection();
+ void ffmpegFinished(int code);
+ void showProxySettings ();
+ void proxySettingsChanged ();
+ void rotateOrientation();
+ void statusChanged();
+ void setSlowMode(bool);
+ void launch(const QString &);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent *);
+ virtual bool event(QEvent *);
+ void createMenu();
+
+private slots:
+ void appAboutToQuit();
+
+ void autoStartRecording();
+ void autoStopRecording();
+ void recordFrame();
+ void chooseRecordingOptions();
+ void pickRecordingFile();
+ void toggleFullScreen();
+ void changeOrientation(QAction*);
+ void orientationChanged();
+
+ void showWarnings(bool show);
+ void warningsWidgetOpened();
+ void warningsWidgetClosed();
+
+private:
+ void updateSizeHints(bool initial = false);
+
+ QString getVideoFileName();
+
+ LoggerWidget *loggerWindow;
+ QDeclarativeView *canvas;
+ QSize initialSize;
+ QString currentFileOrUrl;
+ QTimer recordTimer;
+ QString frame_fmt;
+ QImage frame;
+ QList<QImage*> frames;
+ QProcess* frame_stream;
+ QTimer autoStartTimer;
+ QTimer autoStopTimer;
+ QString record_dither;
+ QString record_file;
+ QSize record_outsize;
+ QStringList record_args;
+ int record_rate;
+ int record_autotime;
+ bool devicemode;
+ QAction *recordAction;
+ RecordingDialog *recdlg;
+
+ void senseImageMagick();
+ void senseFfmpeg();
+ QWidget *ffmpegHelpWindow;
+ bool ffmpegAvailable;
+ bool convertAvailable;
+
+ QAction *rotateAction;
+ QActionGroup *orientation;
+ QAction *showWarningsWindow;
+
+ QString m_script;
+ ScriptOptions m_scriptOptions;
+ QDeclarativeTester *tester;
+
+ QNetworkReply *wgtreply;
+ QString wgtdir;
+ NetworkAccessManagerFactory *namFactory;
+
+ bool useQmlFileBrowser;
+
+ QTranslator *translator;
+ void loadTranslationFile(const QString& directory);
+
+ void loadDummyDataFiles(const QString& directory);
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QDeclarativeViewer::ScriptOptions)
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/tools/qml/recopts.ui b/tools/qml/recopts.ui
new file mode 100644
index 0000000..ce2da30
--- /dev/null
+++ b/tools/qml/recopts.ui
@@ -0,0 +1,513 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RecordingOptions</class>
+ <widget class="QDialog" name="RecordingOptions">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>316</width>
+ <height>436</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Video options</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="label">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>File:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="file"/>
+ </item>
+ <item>
+ <widget class="QToolButton" name="pickfile">
+ <property name="text">
+ <string>...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Size</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="sizeOriginal">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QRadioButton" name="sizeVGA">
+ <property name="text">
+ <string>VGA</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QRadioButton" name="size720p">
+ <property name="text">
+ <string>720p</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QRadioButton" name="sizeQVGA">
+ <property name="text">
+ <string>QVGA</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="3">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QRadioButton" name="sizeCustom">
+ <property name="text">
+ <string>Width:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sizeWidth">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Height:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="sizeHeight">
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>9999</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="2">
+ <spacer name="horizontalSpacer_4">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="rateOptions">
+ <property name="title">
+ <string>Rate</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_4">
+ <item row="0" column="0">
+ <widget class="QRadioButton" name="hz60">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>60Hz</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QRadioButton" name="hz50">
+ <property name="text">
+ <string>50Hz</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="2">
+ <widget class="QRadioButton" name="hz25">
+ <property name="text">
+ <string>25Hz</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0" colspan="4">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QRadioButton" name="hzCustom">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="hz">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>60</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>16777215</height>
+ </size>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Hz</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="2">
+ <widget class="QRadioButton" name="hz24">
+ <property name="text">
+ <string>24Hz</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::MinimumExpanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="1">
+ <spacer name="horizontalSpacer_5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="ffmpegOptions">
+ <property name="title">
+ <string>Profile</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0" colspan="3">
+ <widget class="QComboBox" name="profile"/>
+ </item>
+ <item row="1" column="0" colspan="2">
+ <widget class="QLineEdit" name="args"/>
+ </item>
+ <item row="1" column="2">
+ <widget class="QToolButton" name="ffmpegHelp">
+ <property name="text">
+ <string>Help</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="warning">
+ <property name="text">
+ <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>
+ </widget>
+ <tabstops>
+ <tabstop>file</tabstop>
+ <tabstop>pickfile</tabstop>
+ <tabstop>sizeOriginal</tabstop>
+ <tabstop>sizeVGA</tabstop>
+ <tabstop>size720p</tabstop>
+ <tabstop>sizeQVGA</tabstop>
+ <tabstop>sizeCustom</tabstop>
+ <tabstop>sizeWidth</tabstop>
+ <tabstop>sizeHeight</tabstop>
+ <tabstop>hz60</tabstop>
+ <tabstop>hz25</tabstop>
+ <tabstop>hz50</tabstop>
+ <tabstop>hz24</tabstop>
+ <tabstop>hzCustom</tabstop>
+ <tabstop>hz</tabstop>
+ <tabstop>profile</tabstop>
+ <tabstop>args</tabstop>
+ <tabstop>ffmpegHelp</tabstop>
+ <tabstop>buttonBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>hzCustom</sender>
+ <signal>clicked()</signal>
+ <receiver>hz</receiver>
+ <slot>setFocus()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>43</x>
+ <y>257</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>129</x>
+ <y>262</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>hz</sender>
+ <signal>textChanged(QString)</signal>
+ <receiver>hzCustom</receiver>
+ <slot>toggle()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>143</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>43</x>
+ <y>257</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>hz</sender>
+ <signal>selectionChanged()</signal>
+ <receiver>hzCustom</receiver>
+ <slot>toggle()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>143</x>
+ <y>262</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>43</x>
+ <y>257</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>258</x>
+ <y>424</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>60</x>
+ <y>219</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>258</x>
+ <y>424</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>92</x>
+ <y>219</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>profile</sender>
+ <signal>activated(int)</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>pickProfile(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>92</x>
+ <y>329</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>48</x>
+ <y>194</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>args</sender>
+ <signal>textEdited(QString)</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>storeCustomArgs(QString)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>128</x>
+ <y>357</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>102</x>
+ <y>189</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sizeWidth</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>sizeCustom</receiver>
+ <slot>toggle()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>108</x>
+ <y>133</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>48</x>
+ <y>133</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>sizeHeight</sender>
+ <signal>valueChanged(int)</signal>
+ <receiver>sizeCustom</receiver>
+ <slot>toggle()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>212</x>
+ <y>133</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>64</x>
+ <y>129</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <signal>filePicked(QString)</signal>
+ <signal>argumentsPicked(QString)</signal>
+ <slot>pickFile()</slot>
+ <slot>pickProfile(int)</slot>
+ <slot>storeCustomArgs(QString)</slot>
+ </slots>
+</ui>
diff --git a/tools/qml/recopts_maemo5.ui b/tools/qml/recopts_maemo5.ui
new file mode 100644
index 0000000..3bb5eca
--- /dev/null
+++ b/tools/qml/recopts_maemo5.ui
@@ -0,0 +1,254 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>RecordingOptions</class>
+ <widget class="QDialog" name="RecordingOptions">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>469</width>
+ <height>142</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Video options</string>
+ </property>
+ <layout class="QGridLayout" name="gridLayout" columnstretch="0,2,0">
+ <property name="sizeConstraint">
+ <enum>QLayout::SetMinAndMaxSize</enum>
+ </property>
+ <property name="leftMargin">
+ <number>16</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>16</number>
+ </property>
+ <property name="bottomMargin">
+ <number>8</number>
+ </property>
+ <property name="horizontalSpacing">
+ <number>16</number>
+ </property>
+ <property name="verticalSpacing">
+ <number>0</number>
+ </property>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="file"/>
+ </item>
+ <item row="0" column="2" rowspan="3">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>72</width>
+ <height>56</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Size</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="sizeCombo">
+ <item>
+ <property name="text">
+ <string/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>VGA</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>QVGA</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>720p</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="2" column="0" rowspan="2">
+ <widget class="QLabel" name="rateLabel">
+ <property name="text">
+ <string>Rate</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" rowspan="2">
+ <widget class="QComboBox" name="rateCombo">
+ <item>
+ <property name="text">
+ <string>60 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>50 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>25 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>24 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>20 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>15 Hz</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>10 Hz</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item row="5" column="1">
+ <widget class="QLineEdit" name="args"/>
+ </item>
+ <item row="4" column="1">
+ <widget class="QComboBox" name="profile"/>
+ </item>
+ <item row="4" column="0">
+ <widget class="QLabel" name="profileLabel">
+ <property name="text">
+ <string>Profile</string>
+ </property>
+ </widget>
+ </item>
+ <item row="6" column="0" colspan="2">
+ <widget class="QLabel" name="warning">
+ <property name="text">
+ <string notr="true">warning</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="4" column="2" rowspan="3">
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0">
+ <widget class="QPushButton" name="pickfile">
+ <property name="text">
+ <string>File</string>
+ </property>
+ </widget>
+ </item>
+ <item row="5" column="0">
+ <widget class="QPushButton" name="ffmpegHelp">
+ <property name="text">
+ <string>Options</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>258</x>
+ <y>424</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>60</x>
+ <y>219</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>258</x>
+ <y>424</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>92</x>
+ <y>219</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>profile</sender>
+ <signal>activated(int)</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>pickProfile(int)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>92</x>
+ <y>329</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>48</x>
+ <y>194</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>args</sender>
+ <signal>textEdited(QString)</signal>
+ <receiver>RecordingOptions</receiver>
+ <slot>storeCustomArgs(QString)</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>128</x>
+ <y>357</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>102</x>
+ <y>189</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+ <slots>
+ <signal>filePicked(QString)</signal>
+ <signal>argumentsPicked(QString)</signal>
+ <slot>pickFile()</slot>
+ <slot>pickProfile(int)</slot>
+ <slot>storeCustomArgs(QString)</slot>
+ </slots>
+</ui>
diff --git a/tools/qml/startup/Logo.qml b/tools/qml/startup/Logo.qml
new file mode 100644
index 0000000..aa5648f
--- /dev/null
+++ b/tools/qml/startup/Logo.qml
@@ -0,0 +1,179 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+Rectangle {
+ id: myApp
+ width: 411
+ height: 411
+ color: "transparent"
+ property alias logoState : myApp.state
+ signal animationFinished
+
+ Item {
+ id: sketchBlueHolder
+ width: sketchLogo.width
+ height: sketchLogo.height
+ Image {
+ id: image1
+ x: -44
+ y: -45
+ smooth: true
+ source: "shadow.png"
+ }
+ Item {
+ clip: true
+ width: sketchLogo.width
+ height: sketchLogo.height
+ Image {
+ id: sketchLogo
+ smooth: true
+ source: "qt-sketch.jpg"
+ }
+ Image {
+ id: blueLogo
+ y: -420
+ smooth: true
+ source: "qt-blue.jpg"
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "showBlueprint"
+ PropertyChanges {
+ target: blueLogo
+ y: 0
+ }
+ PropertyChanges {
+ target: sketchLogo
+ opacity: 0
+ }
+ },
+ State {
+ extend: "showBlueprint"
+ name: "finale"
+ PropertyChanges {
+ target: fullLogo
+ opacity: 1
+ }
+ PropertyChanges {
+ target: backLogo
+ opacity: 1
+ scale: 1
+ }
+ PropertyChanges {
+ target: frontLogo
+ opacity: 1
+ scale: 1
+ }
+ PropertyChanges {
+ target: qtText
+ opacity: 1
+ scale: 1
+ }
+ PropertyChanges {
+ target: sketchBlueHolder
+ opacity: 0
+ scale: 1.4
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ to: "showBlueprint"
+ SequentialAnimation {
+ NumberAnimation { property: "y"; duration: 600; easing.type: "OutBounce" }
+ PropertyAction { target: sketchLogo; property: "opacity" }
+ }
+ },
+ Transition {
+ to: "finale"
+ PropertyAction { target: fullLogo; property: "opacity" }
+ SequentialAnimation {
+ NumberAnimation { target: backLogo; properties: "scale, opacity"; duration: 300 }
+ NumberAnimation { target: frontLogo; properties: "scale, opacity"; duration: 300 }
+ ParallelAnimation {
+ NumberAnimation { target: qtText; properties: "opacity, scale"; duration: 400; easing.type: "OutQuad" }
+ NumberAnimation { target: sketchBlueHolder; property: "opacity"; duration: 300; easing.type: "OutQuad" }
+ NumberAnimation { target: sketchBlueHolder; property: "scale"; duration: 320; easing.type: "OutQuad" }
+ }
+ PauseAnimation { duration: 1000 }
+ ScriptAction { script: myApp.animationFinished() }
+ }
+ }
+ ]
+
+ Item {
+ id: fullLogo
+ opacity: 0
+ Image {
+ id: backLogo
+ x: -16
+ y: -41
+ opacity: 0
+ scale: 0.7
+ smooth: true
+ source: "qt-back.png"
+ }
+ Image {
+ id: frontLogo
+ x: -17
+ y: -41
+ opacity: 0
+ scale: 1.2
+ smooth: true
+ source: "qt-front.png"
+ }
+ Image {
+ id: qtText
+ x: -10
+ y: -41
+ opacity: 0
+ scale: 1.2
+ smooth: true
+ source: "qt-text.png"
+ }
+ }
+}
diff --git a/tools/qml/startup/qt-back.png b/tools/qml/startup/qt-back.png
new file mode 100644
index 0000000..077215f
--- /dev/null
+++ b/tools/qml/startup/qt-back.png
Binary files differ
diff --git a/tools/qml/startup/qt-blue.jpg b/tools/qml/startup/qt-blue.jpg
new file mode 100644
index 0000000..b204896
--- /dev/null
+++ b/tools/qml/startup/qt-blue.jpg
Binary files differ
diff --git a/tools/qml/startup/qt-front.png b/tools/qml/startup/qt-front.png
new file mode 100644
index 0000000..dbfb43e
--- /dev/null
+++ b/tools/qml/startup/qt-front.png
Binary files differ
diff --git a/tools/qml/startup/qt-sketch.jpg b/tools/qml/startup/qt-sketch.jpg
new file mode 100644
index 0000000..1ede6f0
--- /dev/null
+++ b/tools/qml/startup/qt-sketch.jpg
Binary files differ
diff --git a/tools/qml/startup/qt-text.png b/tools/qml/startup/qt-text.png
new file mode 100644
index 0000000..d44995c
--- /dev/null
+++ b/tools/qml/startup/qt-text.png
Binary files differ
diff --git a/tools/qml/startup/quick-blur.png b/tools/qml/startup/quick-blur.png
new file mode 100644
index 0000000..29ec243
--- /dev/null
+++ b/tools/qml/startup/quick-blur.png
Binary files differ
diff --git a/tools/qml/startup/quick-regular.png b/tools/qml/startup/quick-regular.png
new file mode 100644
index 0000000..38321cb
--- /dev/null
+++ b/tools/qml/startup/quick-regular.png
Binary files differ
diff --git a/tools/qml/startup/shadow.png b/tools/qml/startup/shadow.png
new file mode 100644
index 0000000..44f92fe
--- /dev/null
+++ b/tools/qml/startup/shadow.png
Binary files differ
diff --git a/tools/qml/startup/startup.qml b/tools/qml/startup/startup.qml
new file mode 100644
index 0000000..9ca50a3
--- /dev/null
+++ b/tools/qml/startup/startup.qml
@@ -0,0 +1,173 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.0
+
+Rectangle {
+ id: treatsApp
+ width: 800
+ height: 480
+ color: "darkgrey"
+ Component.onCompleted: treatsApp.state = "part1"
+ signal animationFinished
+
+ Item {
+ width: 800
+ height: 480
+ anchors.centerIn: parent
+ clip: true
+
+ Logo {
+ id: logo
+ x: 165
+ y: 35
+ rotation: -15
+ scale: 0.6
+ opacity: 0
+ onAnimationFinished: treatsApp.animationFinished();
+ }
+
+ Item {
+ id: quickblur
+ x: 800//325
+ y: 344
+ Image {
+ id: blurText
+ source: "quick-blur.png"
+ }
+ Image {
+ id: quickregular
+ x: -1
+ y: 0
+ opacity: 0
+ source: "quick-regular.png"
+ }
+ Image {
+ id: star
+ x: -1
+ y: 0
+ opacity: 0
+ source: "white-star.png"
+ smooth: true
+ NumberAnimation on rotation {
+ from: 0
+ to: 360
+ loops: NumberAnimation.Infinite
+ running: true
+ duration: 2000
+ }
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "part1"
+ PropertyChanges {
+ target: logo
+ scale: 0.8
+ opacity: 1
+ rotation: 0
+ }
+ PropertyChanges {
+ target: treatsApp
+ color: "black"
+ }
+ PropertyChanges {
+ target: logo
+ y: 10
+ }
+ PropertyChanges {
+ target: quickblur
+ x: logo.x + 145
+ }
+ PropertyChanges {
+ target: blurText
+ opacity: 0
+ }
+ PropertyChanges {
+ target: quickregular
+ opacity: 1
+ }
+ PropertyChanges {
+ target: star
+ x: -7
+ y: -37
+ }
+ }
+ ]
+
+ transitions: [
+ Transition {
+ ParallelAnimation {
+ NumberAnimation { target: logo; property: "opacity"; duration: 500 }
+ NumberAnimation { target: logo; property: "scale"; duration: 4000; }
+ NumberAnimation { target: logo; property: "rotation"; duration: 2000; easing.type: "OutBack"}
+ ColorAnimation { duration: 3000}
+ SequentialAnimation {
+ PauseAnimation { duration: 1000 }
+ ScriptAction { script: logo.logoState = "showBlueprint" }
+ PauseAnimation { duration: 800 }
+ ScriptAction { script: logo.logoState = "finale" }
+ PauseAnimation { duration: 800 }
+ ParallelAnimation {
+ NumberAnimation { target: quickblur; property: "x"; duration: 200;}
+ SequentialAnimation {
+ PauseAnimation { duration: 200}
+ ParallelAnimation {
+ NumberAnimation { target: blurText; property: "opacity"; duration: 300;}
+ NumberAnimation { target: quickregular; property: "opacity"; duration: 300;}
+ }
+ NumberAnimation { target: star; property: "opacity"; from: 0; to: 1; duration: 500 }
+ PauseAnimation { duration: 200 }
+ NumberAnimation { target: star; property: "opacity"; from: 1; to: 0; duration: 500 }
+ }
+ SequentialAnimation {
+ PauseAnimation { duration: 150}
+ NumberAnimation { target: logo; property: "y"; duration: 300; easing.type: "OutBounce" }
+ }
+ }
+ }
+ }
+ }
+ ]
+
+} // treatsApp
diff --git a/tools/qml/startup/startup.qrc b/tools/qml/startup/startup.qrc
new file mode 100644
index 0000000..52e6705
--- /dev/null
+++ b/tools/qml/startup/startup.qrc
@@ -0,0 +1,16 @@
+<RCC>
+ <qresource prefix="/startup">
+ <file>Logo.qml</file>
+ <file>qt-back.png</file>
+ <file>qt-blue.jpg</file>
+ <file>qt-front.png</file>
+ <file>qt-sketch.jpg</file>
+ <file>qt-text.png</file>
+ <file>quick-blur.png</file>
+ <file>quick-regular.png</file>
+ <file>shadow.png</file>
+ <file>startup.qml</file>
+ <file>startup.qrc</file>
+ <file>white-star.png</file>
+ </qresource>
+</RCC>
diff --git a/tools/qml/startup/white-star.png b/tools/qml/startup/white-star.png
new file mode 100644
index 0000000..f467c94
--- /dev/null
+++ b/tools/qml/startup/white-star.png
Binary files differ
diff --git a/tools/qml/texteditautoresizer_maemo5.h b/tools/qml/texteditautoresizer_maemo5.h
new file mode 100644
index 0000000..bb5567a
--- /dev/null
+++ b/tools/qml/texteditautoresizer_maemo5.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the examples 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qplaintextedit.h>
+#include <QtGui/qtextedit.h>
+#include <QtGui/qabstractkineticscroller.h>
+#include <QtGui/qscrollarea.h>
+#include <QtDebug>
+
+#ifndef TEXTEDITAUTORESIZER_H
+#define TEXTEDITAUTORESIZER_H
+
+class TextEditAutoResizer : public QObject
+{
+ Q_OBJECT
+public:
+ TextEditAutoResizer(QWidget *parent)
+ : QObject(parent), plainTextEdit(qobject_cast<QPlainTextEdit *>(parent)),
+ textEdit(qobject_cast<QTextEdit *>(parent)), edit(qobject_cast<QFrame *>(parent))
+ {
+ // parent must either inherit QPlainTextEdit or QTextEdit!
+ Q_ASSERT(plainTextEdit || textEdit);
+
+ connect(parent, SIGNAL(textChanged()), this, SLOT(textEditChanged()));
+ connect(parent, SIGNAL(cursorPositionChanged()), this, SLOT(textEditChanged()));
+
+ textEditChanged();
+ }
+
+private Q_SLOTS:
+ inline void textEditChanged();
+
+private:
+ QPlainTextEdit *plainTextEdit;
+ QTextEdit *textEdit;
+ QFrame *edit;
+};
+
+void TextEditAutoResizer::textEditChanged()
+{
+ QTextDocument *doc = textEdit ? textEdit->document() : plainTextEdit->document();
+ QRect cursor = textEdit ? textEdit->cursorRect() : plainTextEdit->cursorRect();
+
+ QSize s = doc->size().toSize();
+ if (plainTextEdit)
+ s.setHeight((s.height() + 2) * edit->fontMetrics().lineSpacing());
+
+ const QRect fr = edit->frameRect();
+ const QRect cr = edit->contentsRect();
+
+ edit->setMinimumHeight(qMax(70, s.height() + (fr.height() - cr.height() - 1)));
+
+ // make sure the cursor is visible in case we have a QAbstractScrollArea parent
+ QPoint pos = edit->pos();
+ QWidget *pw = edit->parentWidget();
+ while (pw) {
+ if (qobject_cast<QScrollArea *>(pw))
+ break;
+ pw = pw->parentWidget();
+ }
+
+ if (pw) {
+ QScrollArea *area = static_cast<QScrollArea *>(pw);
+ QPoint scrollto = area->widget()->mapFrom(edit, cursor.center());
+ QPoint margin(10 + cursor.width(), 2 * cursor.height());
+
+ if (QAbstractKineticScroller *scroller = area->property("kineticScroller").value<QAbstractKineticScroller *>()) {
+ scroller->ensureVisible(scrollto, margin.x(), margin.y());
+ } else {
+ area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y());
+ }
+ }
+}
+
+#endif
diff --git a/tools/qtconfig/main.cpp b/tools/qtconfig/main.cpp
index 24d044f..928cf01 100644
--- a/tools/qtconfig/main.cpp
+++ b/tools/qtconfig/main.cpp
@@ -42,6 +42,9 @@
#include "ui_previewwidgetbase.h"
#include "mainwindow.h"
#include <QApplication>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QTranslator>
QT_USE_NAMESPACE
@@ -50,6 +53,17 @@ int main(int argc, char **argv)
Q_INIT_RESOURCE(qtconfig);
QApplication app(argc, argv);
+
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("qtconfig_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+
MainWindow mw;
mw.show();
return app.exec();
diff --git a/tools/qtconfig/mainwindow.cpp b/tools/qtconfig/mainwindow.cpp
index 604b1f4..4fe2868 100644
--- a/tools/qtconfig/mainwindow.cpp
+++ b/tools/qtconfig/mainwindow.cpp
@@ -68,6 +68,8 @@
#ifndef QT_NO_GSTREAMER
#include <gst/gst.h>
+#endif
+#ifdef HAVE_PHONON
#include <phonon/phononnamespace.h>
#endif
@@ -79,7 +81,7 @@ QT_BEGIN_NAMESPACE
// external use ignore them
// extern bool Q_CORE_EXPORT qt_resolve_symlinks;
-static const char *appearance_text =
+static const char *appearance_text = QT_TRANSLATE_NOOP("MainWindow",
"<p><b><font size+=2>Appearance</font></b></p>"
"<hr>"
"<p>Use this tab to customize the appearance of your Qt applications.</p>"
@@ -93,9 +95,9 @@ static const char *appearance_text =
"To customize colors further, press the Tune Palette button to open "
"the advanced palette editor."
"<p>The Preview Window shows what the selected Style and colors look "
-"like.";
+"like.");
-static const char *font_text =
+static const char *font_text = QT_TRANSLATE_NOOP("MainWindow",
"<p><b><font size+=2>Fonts</font></b></p>"
"<hr>"
"<p>Use this tab to select the default font for your Qt applications. "
@@ -112,9 +114,9 @@ static const char *font_text =
"Korean characters that are not found in the Lucida font will be taken "
"from the Mincho font. Because the font substitutions are "
"lists, you can also select multiple families, such as Song Ti (for "
-"use with Chinese text).";
+"use with Chinese text).");
-static const char *interface_text =
+static const char *interface_text = QT_TRANSLATE_NOOP("MainWindow",
"<p><b><font size+=2>Interface</font></b></p>"
"<hr>"
"<p>Use this tab to customize the feel of your Qt applications.</p>"
@@ -129,10 +131,10 @@ static const char *interface_text =
"at 0 will disable the Global Strut feature</p>"
"<p>XIM (Extended Input Methods) are used for entering characters in "
"languages that have large character sets, for example, Chinese and "
-"Japanese.";
+"Japanese.");
// ### What does the 'Enhanced support for languages written R2L do?
-static const char *printer_text =
+static const char *printer_text = QT_TRANSLATE_NOOP("MainWindow",
"<p><b><font size+=2>Printer</font></b></p>"
"<hr>"
"<p>Use this tab to configure the way Qt generates output for the printer."
@@ -143,14 +145,14 @@ static const char *printer_text =
"size will be bigger."
"<p>When using font embedding you can select additional directories where "
"Qt should search for embeddable font files. By default, the X "
-"server font path is used.";
+"server font path is used.");
-static const char *phonon_text =
+static const char *phonon_text = QT_TRANSLATE_NOOP("MainWindow",
"<p><b><font size+=2>Phonon</font></b></p>"
"<hr>"
"<p>Use this tab to configure the Phonon GStreamer multimedia backend. "
"<p>It is reccommended to leave all settings on \"Auto\" to let "
-"Phonon determine your settings automatically.";
+"Phonon determine your settings automatically.");
static QColorGroup::ColorRole centralFromItem( int item )
{
@@ -387,8 +389,10 @@ MainWindow::MainWindow()
audiosinkCombo->addItem(tr("aRts"), QLatin1String("artssink"));
audiosinkCombo->setItemData(audiosinkCombo->findText(tr("aRts")),
tr("Experimental aRts support for GStreamer."), Qt::ToolTipRole);
-#ifndef QT_NO_GSTREAMER
+#ifdef HAVE_PHONON
phononVersionLabel->setText(QLatin1String(Phonon::phononVersion()));
+#endif
+#ifndef QT_NO_GSTREAMER
if (gst_init_check(0, 0, 0)) {
gchar *versionString = gst_version_string();
gstversionLabel->setText(QLatin1String(versionString));
@@ -428,7 +432,7 @@ MainWindow::MainWindow()
#endif
#ifndef QT_NO_OPENGL
videomodeCombo->addItem(tr("OpenGL"), QLatin1String("OpenGL"));
- videomodeCombo->setItemData(videomodeCombo->findText(tr("OpenGL")), tr("Use OpenGL if avaiable"), Qt::ToolTipRole);
+ videomodeCombo->setItemData(videomodeCombo->findText(tr("OpenGL")), tr("Use OpenGL if available"), Qt::ToolTipRole);
#endif
videomodeCombo->addItem(tr("Software"), QLatin1String("Software"));
videomodeCombo->setItemData(videomodeCombo->findText(tr("Software")), tr("Use simple software rendering"), Qt::ToolTipRole);
diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp
index 2728557..f59584e 100644
--- a/tools/qtconfig/paletteeditoradvanced.cpp
+++ b/tools/qtconfig/paletteeditoradvanced.cpp
@@ -182,6 +182,7 @@ QColorGroup::ColorRole PaletteEditorAdvanced::centralFromItem( int item )
}
QColorGroup::ColorRole PaletteEditorAdvanced::effectFromItem( int item )
+
{
switch( item ) {
case 0:
diff --git a/tools/qtconfig/qtconfig.pro b/tools/qtconfig/qtconfig.pro
index 8ab3f03..d1fd320 100644
--- a/tools/qtconfig/qtconfig.pro
+++ b/tools/qtconfig/qtconfig.pro
@@ -9,7 +9,10 @@ QT += qt3support
contains(QT_CONFIG, gstreamer):LIBS += $$QT_LIBS_GSTREAMER -lgstinterfaces-0.10 -lgstvideo-0.10 -lgstbase-0.10
contains(QT_CONFIG, gstreamer):QMAKE_CXXFLAGS += $$QT_CFLAGS_GSTREAMER
-contains(QT_CONFIG, gstreamer):QT += phonon
+contains(QT_CONFIG, phonon) {
+ QT += phonon
+ DEFINES += HAVE_PHONON
+}
SOURCES += colorbutton.cpp main.cpp previewframe.cpp previewwidget.cpp mainwindow.cpp paletteeditoradvanced.cpp \
mainwindowbase.cpp paletteeditoradvancedbase.cpp previewwidgetbase.cpp
HEADERS += colorbutton.h previewframe.h previewwidget.h mainwindow.h paletteeditoradvanced.h \
diff --git a/tools/qtconfig/translations/translations.pro b/tools/qtconfig/translations/translations.pro
deleted file mode 100644
index bf8a1da..0000000
--- a/tools/qtconfig/translations/translations.pro
+++ /dev/null
@@ -1,15 +0,0 @@
-# Include those manually as they do not contain any directory specification
-
-SOURCES += ../colorbutton.cpp ../main.cpp ../previewframe.cpp ../previewwidget.cpp ../mainwindow.cpp ../paletteeditoradvanced.cpp \
- ../mainwindowbase.cpp ../paletteeditoradvancedbase.cpp ../previewwidgetbase.cpp
-HEADERS += ../colorbutton.h ../previewframe.h ../previewwidget.h ../mainwindow.h ../paletteeditoradvanced.h \
- ../mainwindowbase.h ../paletteeditoradvancedbase.h ../previewwidgetbase.h
-
-FORMS = ../mainwindowbase.ui ../paletteeditoradvancedbase.ui ../previewwidgetbase.ui
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/qtconfig_pl.ts \
- $$TR_DIR/qtconfig_ru.ts \
- $$TR_DIR/qtconfig_zh_CN.ts \
- $$TR_DIR/qtconfig_zh_TW.ts
diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
index 98062ed..812ed47 100644
--- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp
+++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
@@ -247,7 +247,7 @@ bool ActiveSyncConnection::copyFileFromDevice(const QString &deviceSource, const
wprintf(L"\n");
if (!readUntilEnd) {
- debugOutput(QString::fromLatin1(" an error occured during copy"), 2);
+ debugOutput(QString::fromLatin1(" an error occurred during copy"), 2);
return false;
}
diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp
index 99219f3..5494194 100644
--- a/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp
+++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.cpp
@@ -198,3 +198,24 @@ bool CeTcpSyncConnection::fileCreationTime(const QString &fileName, FILETIME* de
file.remove();
return result;
}
+
+bool CeTcpSyncConnection::resetDevice()
+{
+ qWarning("CeTcpSyncConnection::resetDevice not implemented");
+ return false;
+}
+
+bool CeTcpSyncConnection::toggleDevicePower(int *returnValue)
+{
+ Q_UNUSED(returnValue);
+ qWarning("CeTcpSyncConnection::toggleDevicePower not implemented");
+ return false;
+}
+
+bool CeTcpSyncConnection::setDeviceAwake(bool activate, int *returnValue)
+{
+ Q_UNUSED(activate);
+ Q_UNUSED(returnValue);
+ qWarning("CeTcpSyncConnection::setDeviceAwake not implemented");
+ return false;
+}
diff --git a/tools/qtestlib/wince/cetest/cetcpsyncconnection.h b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h
index 77539cc..e603efc 100644
--- a/tools/qtestlib/wince/cetest/cetcpsyncconnection.h
+++ b/tools/qtestlib/wince/cetest/cetcpsyncconnection.h
@@ -75,6 +75,9 @@ public:
bool createDirectory(const QString&, bool deleteBefore=false);
bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL);
+ bool resetDevice();
+ bool toggleDevicePower(int *returnValue = NULL);
+ bool setDeviceAwake(bool activate, int *returnValue = NULL);
private:
bool connected;
};
diff --git a/tools/qtestlib/wince/cetest/cetest.pro b/tools/qtestlib/wince/cetest/cetest.pro
index 2773fe4..82747da 100644
--- a/tools/qtestlib/wince/cetest/cetest.pro
+++ b/tools/qtestlib/wince/cetest/cetest.pro
@@ -36,8 +36,6 @@ HEADERS += \
SOURCES += \
remoteconnection.cpp \
deployment.cpp \
- symbian/epocroot.cpp \
- windows/registry.cpp \
main.cpp
LIBS += ole32.lib advapi32.lib
diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp
index 9fe5f02..ec62af1 100644
--- a/tools/qtestlib/wince/cetest/main.cpp
+++ b/tools/qtestlib/wince/cetest/main.cpp
@@ -283,12 +283,16 @@ int main(int argc, char **argv)
cout << "Error: Can only test executables!" << endl;
return -1;
}
- // Check wether the project is still in debug/release mode after reading
+ // Check whether the project is still in debug/release mode after reading
// If .pro specifies to be one mode only, we need to accept this
- if (project.isActiveConfig("debug"))
+ if (project.isActiveConfig("debug") && !project.isActiveConfig("release")) {
TestConfiguration::testDebug = true;
- else
+ debugOutput("ActiveConfig: debug only in .pro.", 1);
+ }
+ if (!project.isActiveConfig("debug") && project.isActiveConfig("release")) {
TestConfiguration::testDebug = false;
+ debugOutput("ActiveConfig: release only in .pro.", 1);
+ }
// determine what is the real mkspec to use if the default mkspec is being used
if (Option::mkfile::qmakespec.endsWith("/default"))
diff --git a/tools/qtestlib/wince/cetest/qmake_include.pri b/tools/qtestlib/wince/cetest/qmake_include.pri
index 8b415b0..35fbc64 100644
--- a/tools/qtestlib/wince/cetest/qmake_include.pri
+++ b/tools/qtestlib/wince/cetest/qmake_include.pri
@@ -5,7 +5,9 @@ SOURCES += \
$$QT_SOURCE_TREE/qmake/option.cpp \
$$QT_SOURCE_TREE/qmake/project.cpp \
$$QT_SOURCE_TREE/qmake/property.cpp \
+ $$QT_SOURCE_TREE/qmake/generators/metamakefile.cpp \
$$QT_SOURCE_TREE/qmake/generators/symbian/initprojectdeploy_symbian.cpp \
$$QT_SOURCE_TREE/tools/shared/symbian/epocroot.cpp \
$$QT_SOURCE_TREE/tools/shared/windows/registry.cpp
+DEFINES += QT_QMAKE_PARSER_ONLY
diff --git a/tools/qttracereplay/main.cpp b/tools/qttracereplay/main.cpp
index a932d72..101d512 100644
--- a/tools/qttracereplay/main.cpp
+++ b/tools/qttracereplay/main.cpp
@@ -49,7 +49,7 @@ class ReplayWidget : public QWidget
{
Q_OBJECT
public:
- ReplayWidget(const QString &filename);
+ ReplayWidget(const QString &filename, int from, int to, bool single, int frame);
void paintEvent(QPaintEvent *event);
void resizeEvent(QResizeEvent *event);
@@ -66,22 +66,96 @@ public:
QTime timer;
QList<uint> visibleUpdates;
- QList<uint> iterationTimes;
+
+ QVector<uint> iterationTimes;
QString filename;
+
+ int from;
+ int to;
+
+ bool single;
+
+ int frame;
+ int currentCommand;
};
void ReplayWidget::updateRect()
{
- if (!visibleUpdates.isEmpty())
+ if (frame >= 0 && !updates.isEmpty())
+ update(updates.at(frame));
+ else if (!visibleUpdates.isEmpty())
update(updates.at(visibleUpdates.at(currentFrame)));
}
+const int singleFrameRepeatsPerCommand = 100;
+const int singleFrameIterations = 4;
+
void ReplayWidget::paintEvent(QPaintEvent *)
{
QPainter p(this);
+ QTimer::singleShot(0, this, SLOT(updateRect()));
+
// p.setClipRegion(frames.at(currentFrame).updateRegion);
+ if (frame >= 0) {
+ int start = buffer.frameStartIndex(frame);
+ int end = buffer.frameEndIndex(frame);
+
+ iterationTimes.resize(end - start);
+
+ int saveRestoreStackDepth = buffer.processCommands(&p, start, start + currentCommand);
+
+ for (int i = 0; i < saveRestoreStackDepth; ++i)
+ p.restore();
+
+ const int repeats = currentIteration >= 3 ? singleFrameRepeatsPerCommand : 1;
+
+ ++currentFrame;
+ if (currentFrame == repeats) {
+ currentFrame = 0;
+ if (currentIteration >= 3) {
+ iterationTimes[currentCommand - 1] = qMin(iterationTimes[currentCommand - 1], uint(timer.elapsed()));
+ timer.restart();
+ }
+
+ if (currentIteration >= singleFrameIterations + 3) {
+ printf(" # | ms | description\n");
+ printf("------+---------+------------------------------------------------------------\n");
+
+ qSort(iterationTimes);
+
+ int sum = 0;
+ for (int i = 0; i < iterationTimes.size(); ++i) {
+ int delta = iterationTimes.at(i);
+ if (i > 0)
+ delta -= iterationTimes.at(i-1);
+ sum += delta;
+ qreal deltaF = delta / qreal(repeats);
+ printf("%.5d | %.5f | %s\n", i, deltaF, qPrintable(buffer.commandDescription(start + i)));
+ }
+ printf("Total | %.5f | Total frame time\n", sum / qreal(repeats));
+ deleteLater();
+ return;
+ }
+
+ if (start + currentCommand >= end) {
+ currentCommand = 1;
+ ++currentIteration;
+ if (currentIteration == 3) {
+ timer.start();
+ iterationTimes.fill(uint(-1));
+ }
+ if (currentIteration >= 3 && currentIteration < singleFrameIterations + 3)
+ printf("Profiling iteration %d of %d\n", currentIteration - 2, singleFrameIterations);
+ } else {
+ ++currentCommand;
+ }
+ }
+
+ return;
+ }
+
buffer.draw(&p, visibleUpdates.at(currentFrame));
++currentFrame;
@@ -89,6 +163,11 @@ void ReplayWidget::paintEvent(QPaintEvent *)
currentFrame = 0;
++currentIteration;
+ if (single) {
+ deleteLater();
+ return;
+ }
+
if (currentIteration == 3)
timer.start();
else if (currentIteration > 3) {
@@ -128,29 +207,37 @@ void ReplayWidget::paintEvent(QPaintEvent *)
}
}
}
-
- QTimer::singleShot(0, this, SLOT(updateRect()));
}
-void ReplayWidget::resizeEvent(QResizeEvent *event)
+void ReplayWidget::resizeEvent(QResizeEvent *)
{
visibleUpdates.clear();
QRect bounds = rect();
- for (int i = 0; i < updates.size(); ++i) {
+
+ int first = qMax(0, from);
+ int last = qMin(unsigned(to), unsigned(updates.size()));
+ for (int i = first; i < last; ++i) {
if (updates.at(i).intersects(bounds))
visibleUpdates << i;
}
- if (visibleUpdates.size() != updates.size())
- printf("Warning: skipped %d frames due to limited resolution\n", updates.size() - visibleUpdates.size());
+ int range = last - first;
+
+ if (visibleUpdates.size() != range)
+ printf("Warning: skipped %d frames due to limited resolution\n", range - visibleUpdates.size());
}
-ReplayWidget::ReplayWidget(const QString &filename_)
+ReplayWidget::ReplayWidget(const QString &filename_, int from_, int to_, bool single_, int frame_)
: currentFrame(0)
, currentIteration(0)
, filename(filename_)
+ , from(from_)
+ , to(to_)
+ , single(single_)
+ , frame(frame_)
+ , currentCommand(1)
{
setWindowTitle(filename);
QFile file(filename);
@@ -165,15 +252,21 @@ ReplayWidget::ReplayWidget(const QString &filename_)
char *data;
uint size;
in.readBytes(data, size);
- bool isTraceFile = size == 7 && qstrncmp(data, "qttrace", 7) == 0;
- delete [] data;
+ bool isTraceFile = size >= 7 && qstrncmp(data, "qttrace", 7) == 0;
+
+ uint version = 0;
+ if (size == 9 && qstrncmp(data, "qttraceV2", 9) == 0) {
+ in.setFloatingPointPrecision(QDataStream::SinglePrecision);
+ in >> version;
+ }
+
if (!isTraceFile) {
printf("File '%s' is not a trace file\n", qPrintable(filename_));
return;
}
in >> buffer >> updates;
- printf("Read paint buffer with %d frames\n", buffer.numFrames());
+ printf("Read paint buffer version %d with %d frames\n", version, buffer.numFrames());
resize(buffer.boundingRect().size().toSize());
@@ -189,17 +282,65 @@ int main(int argc, char **argv)
if (argc <= 1 || qstrcmp(argv[1], "-h") == 0 || qstrcmp(argv[1], "--help") == 0) {
printf("Replays a tracefile generated with '-graphicssystem trace'\n");
- printf("Usage:\n > %s [traceFile]\n", argv[0]);
+ printf("Usage:\n > %s [OPTIONS] [traceFile]\n", argv[0]);
+ printf("OPTIONS\n"
+ " --range=from-to to specify a frame range.\n"
+ " --singlerun to do only one run (without statistics)\n"
+ " --instrumentframe=frame to instrument a single frame\n");
return 1;
}
- QFile file(argv[1]);
+ QFile file(app.arguments().last());
if (!file.exists()) {
- printf("%s does not exist\n", argv[1]);
+ printf("%s does not exist\n", qPrintable(app.arguments().last()));
return 1;
}
- ReplayWidget *widget = new ReplayWidget(argv[1]);
+ bool single = false;
+
+ int frame = -1;
+
+ int from = 0;
+ int to = -1;
+ for (int i = 1; i < app.arguments().size() - 1; ++i) {
+ QString arg = app.arguments().at(i);
+ if (arg.startsWith(QLatin1String("--range="))) {
+ QString rest = arg.mid(8);
+ QStringList components = rest.split(QLatin1Char('-'));
+
+ bool ok1 = false;
+ bool ok2 = false;
+ int fromCandidate = 0;
+ int toCandidate = 0;
+ if (components.size() == 2) {
+ fromCandidate = components.first().toInt(&ok1);
+ toCandidate = components.last().toInt(&ok2);
+ }
+
+ if (ok1 && ok2) {
+ from = fromCandidate;
+ to = toCandidate;
+ } else {
+ printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg));
+ }
+ } else if (arg == QLatin1String("--singlerun")) {
+ single = true;
+ } else if (arg.startsWith(QLatin1String("--instrumentframe="))) {
+ QString rest = arg.mid(18);
+ bool ok = false;
+ int frameCandidate = rest.toInt(&ok);
+ if (ok) {
+ frame = frameCandidate;
+ } else {
+ printf("ERROR: malformed syntax in argument %s\n", qPrintable(arg));
+ }
+ } else {
+ printf("Unrecognized argument: %s\n", qPrintable(arg));
+ return 1;
+ }
+ }
+
+ ReplayWidget *widget = new ReplayWidget(app.arguments().last(), from, to, single, frame);
if (!widget->updates.isEmpty()) {
widget->show();
diff --git a/tools/qvfb/main.cpp b/tools/qvfb/main.cpp
index d96b255..28aa7d4 100644
--- a/tools/qvfb/main.cpp
+++ b/tools/qvfb/main.cpp
@@ -43,6 +43,9 @@
#include <QApplication>
#include <QRegExp>
+#include <QLibraryInfo>
+#include <QLocale>
+#include <QTranslator>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
@@ -73,6 +76,16 @@ int runQVfb( int argc, char *argv[] )
QApplication app( argc, argv );
+ QTranslator translator;
+ QTranslator qtTranslator;
+ QString sysLocale = QLocale::system().name();
+ QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath);
+ if (translator.load(QLatin1String("qvfb_") + sysLocale, resourceDir)
+ && qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ app.installTranslator(&qtTranslator);
+ }
+
int width = 0;
int height = 0;
int depth = -32; // default, but overridable by skin
diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp
index bc9e529..a3b1964 100644
--- a/tools/qvfb/qvfb.cpp
+++ b/tools/qvfb/qvfb.cpp
@@ -398,47 +398,47 @@ void QVFb::createMenu(T *menu)
QMenu* QVFb::createFileMenu()
{
- QMenu *file = new QMenu( "File", this );
- file->addAction( "Configure...", this, SLOT(configure()), 0 );
+ QMenu *file = new QMenu( tr("&File"), this );
+ file->addAction( tr("&Configure..."), this, SLOT(configure()), QKeySequence::Preferences );
file->addSeparator();
- file->addAction( "&Save image...", this, SLOT(saveImage()), 0 );
- file->addAction( "&Animation...", this, SLOT(toggleAnimation()), 0 );
+ file->addAction( tr("&Save image..."), this, SLOT(saveImage()), QKeySequence::Save );
+ file->addAction( tr("&Animation..."), this, SLOT(toggleAnimation()), 0 );
file->addSeparator();
- file->addAction( "&Quit", qApp, SLOT(quit()) );
+ file->addAction( tr("&Quit"), qApp, SLOT(quit()), QKeySequence::Quit );
return file;
}
QMenu* QVFb::createViewMenu()
{
- viewMenu = new QMenu( "View", this );
- cursorAction = viewMenu->addAction( "Show &Cursor", this,
+ viewMenu = new QMenu( tr("&View"), this );
+ cursorAction = viewMenu->addAction( tr("Show &Cursor"), this,
SLOT(toggleCursor()) );
cursorAction->setCheckable(true);
if ( view )
enableCursor(true);
- viewMenu->addAction( "&Refresh Rate...", this, SLOT(changeRate()) );
+ viewMenu->addAction( tr("&Refresh Rate..."), this, SLOT(changeRate()) );
viewMenu->addSeparator();
- viewMenu->addAction( "No rotation", this, SLOT(setRot0()) );
- viewMenu->addAction( "90\260 rotation", this, SLOT(setRot90()) );
- viewMenu->addAction( "180\260 rotation", this, SLOT(setRot180()) );
- viewMenu->addAction( "270\260 rotation", this, SLOT(setRot270()) );
+ viewMenu->addAction( tr("&No rotation"), this, SLOT(setRot0()) );
+ viewMenu->addAction( tr("&90\260 rotation"), this, SLOT(setRot90()) );
+ viewMenu->addAction( tr("1&80\260 rotation"), this, SLOT(setRot180()) );
+ viewMenu->addAction( tr("2&70\260 rotation"), this, SLOT(setRot270()) );
viewMenu->addSeparator();
- viewMenu->addAction( "Zoom scale &0.5", this, SLOT(setZoomHalf()) );
- viewMenu->addAction( "Zoom scale 0.75", this, SLOT(setZoom075()) );
- viewMenu->addAction( "Zoom scale &1", this, SLOT(setZoom1()) );
- viewMenu->addAction( "Zoom scale &2", this, SLOT(setZoom2()) );
- viewMenu->addAction( "Zoom scale &3", this, SLOT(setZoom3()) );
- viewMenu->addAction( "Zoom scale &4", this, SLOT(setZoom4()) );
+ viewMenu->addAction( tr("Zoom scale &0.5"), this, SLOT(setZoomHalf()) );
+ viewMenu->addAction( tr("Zoom scale 0.7&5"), this, SLOT(setZoom075()) );
+ viewMenu->addAction( tr("Zoom scale &1"), this, SLOT(setZoom1()) );
+ viewMenu->addAction( tr("Zoom scale &2"), this, SLOT(setZoom2()) );
+ viewMenu->addAction( tr("Zoom scale &3"), this, SLOT(setZoom3()) );
+ viewMenu->addAction( tr("Zoom scale &4"), this, SLOT(setZoom4()) );
viewMenu->addSeparator();
- viewMenu->addAction( "Zoom scale...", this, SLOT(setZoom()) );
+ viewMenu->addAction( tr("Zoom &scale..."), this, SLOT(setZoom()) );
return viewMenu;
}
QMenu* QVFb::createHelpMenu()
{
- QMenu *help = new QMenu( "Help", this );
- help->addAction("About...", this, SLOT(about()));
+ QMenu *help = new QMenu( tr("&Help"), this );
+ help->addAction(tr("&About..."), this, SLOT(about()));
return help;
}
@@ -525,17 +525,17 @@ void QVFb::setZoom4()
void QVFb::saveImage()
{
QImage img = view->image();
- QString filename = QFileDialog::getSaveFileName(this, "Save Main Screen image", "snapshot.png", "Portable Network Graphics (*.png)");
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save Main Screen image"), tr("snapshot.png"), tr("Portable Network Graphics (*.png)"));
if (!filename.isEmpty()){
if(!img.save(filename,"PNG"))
- QMessageBox::critical(this, "Save Main Screen Image", "Save failed. Check that you have permission to write to the target directory.");
+ QMessageBox::critical(this, tr("Save Main Screen Image"), tr("Save failed. Check that you have permission to write to the target directory."));
}
if (secondaryView) {
QImage img = view->image();
- QString filename = QFileDialog::getSaveFileName(this, "Save Second Screen image", "snapshot.png", "Portable Network Graphics (*.png)");
+ QString filename = QFileDialog::getSaveFileName(this, tr("Save Second Screen image"), tr("snapshot.png"), tr("Portable Network Graphics (*.png)"));
if (!filename.isEmpty()) {
if(!img.save(filename,"PNG"))
- QMessageBox::critical(this, "Save Second Screen Image", "Save failed. Check that you have permission to write to the target directory.");
+ QMessageBox::critical(this, tr("Save Second Screen Image"), tr("Save failed. Check that you have permission to write to the target directory."));
}
}
}
@@ -577,7 +577,7 @@ void QVFb::setRate(int i)
void QVFb::about()
{
- QMessageBox::about(this, "About QVFB",
+ QMessageBox::about(this, tr("About QVFB"), tr(
"<h2>The Qt for Embedded Linux Virtual X11 Framebuffer</h2>"
"<p>This application runs under Qt for X11, emulating a simple framebuffer, "
"which the Qt for Embedded Linux server and clients can attach to just as if "
@@ -586,7 +586,7 @@ void QVFb::about()
"Linux applications under X11 without having to switch to a virtual console. "
"This means you can comfortably use your other development tools such "
"as GUI profilers and debuggers."
- );
+ ));
}
void QVFb::findSkins(const QString &currentSkin)
@@ -1038,7 +1038,7 @@ void AnimationSaveWidget::convertToMpeg(QString filename)
// ### can't use QProcess, not in Qt 2.3
// ### but it's certainly in Qt 4! use it?
- // Execute the ppmtompeg command as a seperate process to do the encoding
+ // Execute the ppmtompeg command as a separate process to do the encoding
pid_t pid = ::fork();
if ( !pid ) {
// Child process
diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro
index dde7e8d..c101d00 100644
--- a/tools/qvfb/qvfb.pro
+++ b/tools/qvfb/qvfb.pro
@@ -35,7 +35,7 @@ SOURCES = qvfb.cpp \
../../src/gui/embedded/qlock.cpp \
../../src/gui/embedded/qwssignalhandler.cpp
-include($$QT_SOURCE_TREE/tools/shared/deviceskin/deviceskin.pri)
+include(../shared/deviceskin/deviceskin.pri)
contains(QT_CONFIG, opengl) {
QT += opengl
diff --git a/tools/qvfb/qvfbratedlg.cpp b/tools/qvfb/qvfbratedlg.cpp
index e491bdf..a0cbb2f 100644
--- a/tools/qvfb/qvfbratedlg.cpp
+++ b/tools/qvfb/qvfbratedlg.cpp
@@ -55,7 +55,7 @@ QVFbRateDialog::QVFbRateDialog(int rate, QWidget *parent)
QVBoxLayout *tl = new QVBoxLayout(this);
tl->setMargin(5);
- QLabel *label = new QLabel("Target frame rate:", this);
+ QLabel *label = new QLabel(tr("Target frame rate:"), this);
tl->addWidget(label);
QHBoxLayout *hl = new QHBoxLayout();
@@ -67,15 +67,15 @@ QVFbRateDialog::QVFbRateDialog(int rate, QWidget *parent)
rateSlider->setValue(rate);
hl->addWidget(rateSlider);
connect(rateSlider, SIGNAL(valueChanged(int)), this, SLOT(rateChanged(int)));
- rateLabel = new QLabel(QString("%1fps").arg(rate), this);
+ rateLabel = new QLabel(tr("%1fps").arg(rate), this);
hl->addWidget(rateLabel);
hl = new QHBoxLayout();
tl->addItem(hl);
- QPushButton *pb = new QPushButton("OK", this);
+ QPushButton *pb = new QPushButton(tr("OK"), this);
connect(pb, SIGNAL(clicked()), this, SLOT(ok()));
hl->addWidget(pb);
- pb = new QPushButton("Cancel", this);
+ pb = new QPushButton(tr("Cancel"), this);
connect(pb, SIGNAL(clicked()), this, SLOT(cancel()));
hl->addWidget(pb);
}
@@ -84,7 +84,7 @@ void QVFbRateDialog::rateChanged(int r)
{
if (rateSlider->value() != r)
rateSlider->setValue(r);
- rateLabel->setText(QString("%1fps").arg(r));
+ rateLabel->setText(tr("%1fps").arg(r));
emit updateRate(r);
}
diff --git a/tools/qvfb/translations/translations.pro b/tools/qvfb/translations/translations.pro
deleted file mode 100644
index ef42063..0000000
--- a/tools/qvfb/translations/translations.pro
+++ /dev/null
@@ -1,34 +0,0 @@
-# Include those manually as they do not contain any directory specification
-
-FORMS = ../config.ui
-HEADERS = ../qvfb.h \
- ../qvfbview.h \
- ../qvfbratedlg.h \
- ../qanimationwriter.h \
- ../gammaview.h \
- ../qvfbprotocol.h \
- ../qvfbshmem.h \
- ../qvfbmmap.h \
- ../../../src/gui/embedded/qvfbhdr.h \
- ../../../src/gui/embedded/qlock_p.h \
- ../../../src/gui/embedded/qwssignalhandler_p.h \
- ../../shared/deviceskin/deviceskin.h
-
-SOURCES = ../qvfb.cpp \
- ../qvfbview.cpp \
- ../qvfbratedlg.cpp \
- ../main.cpp \
- ../qanimationwriter.cpp \
- ../qvfbprotocol.cpp \
- ../qvfbshmem.cpp \
- ../qvfbmmap.cpp \
- ../../../src/gui/embedded/qlock.cpp \
- ../../../src/gui/embedded/qwssignalhandler.cpp \
- ../../shared/deviceskin/deviceskin.cpp
-
-TR_DIR = $$PWD/../../../translations
-TRANSLATIONS = \
- $$TR_DIR/qvfb_pl.ts \
- $$TR_DIR/qvfb_ru.ts \
- $$TR_DIR/qvfb_zh_CN.ts \
- $$TR_DIR/qvfb_zh_TW.ts
diff --git a/tools/runonphone/main.cpp b/tools/runonphone/main.cpp
index 65085e0..93b087b 100644
--- a/tools/runonphone/main.cpp
+++ b/tools/runonphone/main.cpp
@@ -44,26 +44,34 @@
#include <QStringList>
#include <QScopedPointer>
#include <QTimer>
+#include <QFileInfo>
#include "symbianutils/trkutils.h"
#include "symbianutils/trkdevice.h"
#include "symbianutils/launcher.h"
#include "trksignalhandler.h"
#include "serenum.h"
+#include "ossignalconverter.h"
-void printUsage(QTextStream& outstream)
+void printUsage(QTextStream& outstream, QString exeName)
{
- outstream << "runtest [options] <program> [program arguments]" << endl
- << "-s, --sis <file> specify sis file to install" << endl
- << "-p, --portname <COMx> specify COM port to use by device name" << endl
- << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl
- << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl
- << "-v, --verbose show debugging output" << endl
- << "-q, --quiet hide progress messages" << endl
+ outstream << exeName << " [options] [program] [program arguments]" << endl
+ << "-s, --sis <file> specify sis file to install" << endl
+ << "-p, --portname <COMx> specify COM port to use by device name" << endl
+ << "-f, --portfriendlyname <substring> specify COM port to use by friendly name" << endl
+ << "-t, --timeout <milliseconds> terminate test if timeout occurs" << endl
+ << "-v, --verbose show debugging output" << endl
+ << "-q, --quiet hide progress messages" << endl
+ << "-d, --download <remote file> <local file> copy file from phone to PC after running test" << endl
+ << "--nocrashlog Don't capture call stack if test crashes" << endl
+ << "--crashlogpath <dir> Path to save crash logs (default=working dir)" << endl
<< endl
- << "USB COM ports can usually be autodetected" << endl;
+ << "USB COM ports can usually be autodetected, use -p or -f to force a specific port." << endl
+ << "If using System TRK, it is possible to copy the program directly to sys/bin on the phone." << endl
+ << "-s can be used with both System and Application TRK to install the program" << endl;
}
+#define CHECK_PARAMETER_EXISTS if(!it.hasNext()) { printUsage(outstream, args[0]); return 1; }
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
@@ -76,82 +84,94 @@ int main(int argc, char *argv[])
QStringList args = QCoreApplication::arguments();
QTextStream outstream(stdout);
QTextStream errstream(stderr);
+ QString downloadRemoteFile;
+ QString downloadLocalFile;
int loglevel=1;
int timeout=0;
- for (int i=1;i<args.size();i++) {
- QString arg = args.at(i);
+ bool crashlog = true;
+ QString crashlogpath;
+ QListIterator<QString> it(args);
+ it.next(); //skip name of program
+ while (it.hasNext()) {
+ QString arg = it.next();
+
if (arg.startsWith("-")) {
- if (args.size() < i+2) {
- errstream << "Command line missing argument parameters" << endl;
- return 1;
+ if (arg == "--portname" || arg == "-p") {
+ CHECK_PARAMETER_EXISTS
+ serialPortName = it.next();
}
- QString param = args.at(i+1);
- if(arg.compare("--portname", Qt::CaseSensitive) == 0
- || arg.compare("-p", Qt::CaseSensitive) == 0) {
- serialPortName = param;
- i++;
+ else if (arg == "--portfriendlyname" || arg == "-f") {
+ CHECK_PARAMETER_EXISTS
+ serialPortFriendlyName = it.next();
}
- else if(arg.compare("--portfriendlyname", Qt::CaseSensitive) == 0
- || arg.compare("-f", Qt::CaseSensitive) == 0) {
- serialPortFriendlyName = param;
- i++;
+ else if (arg == "--sis" || arg == "-s") {
+ CHECK_PARAMETER_EXISTS
+ sisFile = it.next();
+ if (!QFileInfo(sisFile).exists()) {
+ errstream << "Sis file (" << sisFile << ") doesn't exist" << endl;
+ return 1;
+ }
}
- else if(arg.compare("--sis", Qt::CaseSensitive) == 0
- || arg.compare("-s", Qt::CaseSensitive) == 0) {
- sisFile = param;
- i++;
+ else if (arg == "--download" || arg == "-d") {
+ CHECK_PARAMETER_EXISTS
+ downloadRemoteFile = it.next();
+ CHECK_PARAMETER_EXISTS
+ downloadLocalFile = it.next();
}
- else if(arg.compare("--timeout", Qt::CaseSensitive) == 0
- || arg.compare("-t", Qt::CaseSensitive) == 0) {
+ else if (arg == "--timeout" || arg == "-t") {
+ CHECK_PARAMETER_EXISTS
bool ok;
- timeout = param.toInt(&ok);
+ timeout = it.next().toInt(&ok);
if (!ok) {
errstream << "Timeout must be specified in milliseconds" << endl;
return 1;
}
- i++;
}
- else if(arg.compare("--verbose", Qt::CaseSensitive) == 0
- || arg.compare("-v", Qt::CaseSensitive) == 0)
+ else if (arg == "--verbose" || arg == "-v")
loglevel=2;
- else if(arg.compare("--quiet", Qt::CaseSensitive) == 0
- || arg.compare("-q", Qt::CaseSensitive) == 0)
+ else if (arg == "--quiet" || arg == "-q")
loglevel=0;
+ else if (arg == "--nocrashlog")
+ crashlog = false;
+ else if (arg == "--crashlogpath") {
+ CHECK_PARAMETER_EXISTS
+ crashlogpath = it.next();
+ }
else
errstream << "unknown command line option " << arg << endl;
} else {
exeFile = arg;
- i++;
- for(;i<args.size();i++) {
- cmdLine.append(args.at(i));
+ while(it.hasNext()) {
+ cmdLine.append(it.next());
}
}
}
- if(exeFile.isEmpty()) {
- printUsage(outstream);
+ if (exeFile.isEmpty() && sisFile.isEmpty() &&
+ (downloadLocalFile.isEmpty() || downloadRemoteFile.isEmpty())) {
+ printUsage(outstream, args[0]);
return 1;
}
if (serialPortName.isEmpty()) {
if (loglevel > 0)
outstream << "Detecting serial ports" << endl;
- QList <SerialPortId> ports = enumerateSerialPorts();
- foreach(SerialPortId id, ports) {
+ foreach (const SerialPortId &id, enumerateSerialPorts(loglevel)) {
if (loglevel > 0)
outstream << "Port Name: " << id.portName << ", "
<< "Friendly Name:" << id.friendlyName << endl;
- if (serialPortName.isEmpty()) {
- if (!id.friendlyName.isEmpty()
- && serialPortFriendlyName.isEmpty()
- && (id.friendlyName.contains("symbian", Qt::CaseInsensitive)
- || id.friendlyName.contains("s60", Qt::CaseInsensitive)
- || id.friendlyName.contains("nokia", Qt::CaseInsensitive)))
- serialPortName = id.portName;
- else if (!id.friendlyName.isEmpty()
- && !serialPortFriendlyName.isEmpty()
- && id.friendlyName.contains(serialPortFriendlyName))
- serialPortName = id.portName;
+ if (!id.friendlyName.isEmpty()
+ && serialPortFriendlyName.isEmpty()
+ && (id.friendlyName.contains("symbian", Qt::CaseInsensitive)
+ || id.friendlyName.contains("s60", Qt::CaseInsensitive)
+ || id.friendlyName.contains("nokia", Qt::CaseInsensitive))) {
+ serialPortName = id.portName;
+ break;
+ } else if (!id.friendlyName.isEmpty()
+ && !serialPortFriendlyName.isEmpty()
+ && id.friendlyName.contains(serialPortFriendlyName)) {
+ serialPortName = id.portName;
+ break;
}
}
if (serialPortName.isEmpty()) {
@@ -161,29 +181,37 @@ int main(int argc, char *argv[])
}
QScopedPointer<trk::Launcher> launcher;
-
- if (sisFile.isEmpty()) {
- launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyRun));
- launcher->setCopyFileName(exeFile, QString("c:\\sys\\bin\\") + exeFile);
- errstream << "System TRK required to copy EXE, use --sis if using Application TRK" << endl;
- } else {
- launcher.reset(new trk::Launcher(trk::Launcher::ActionCopyInstallRun));
- launcher->addStartupActions(trk::Launcher::ActionInstall);
+ launcher.reset(new trk::Launcher(trk::Launcher::ActionPingOnly));
+ QFileInfo info(exeFile);
+ if (!sisFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionCopyInstall);
launcher->setCopyFileName(sisFile, "c:\\data\\testtemp.sis");
launcher->setInstallFileName("c:\\data\\testtemp.sis");
}
+ else if (info.exists()) {
+ launcher->addStartupActions(trk::Launcher::ActionCopy);
+ launcher->setCopyFileName(exeFile, QString("c:\\sys\\bin\\") + info.fileName());
+ }
+ if (!exeFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionRun);
+ launcher->setFileName(QString("c:\\sys\\bin\\") + info.fileName());
+ launcher->setCommandLineArgs(cmdLine);
+ }
+ if (!downloadRemoteFile.isEmpty() && !downloadLocalFile.isEmpty()) {
+ launcher->addStartupActions(trk::Launcher::ActionDownload);
+ launcher->setDownloadFileName(downloadRemoteFile, downloadLocalFile);
+ }
if (loglevel > 0)
outstream << "Connecting to target via " << serialPortName << endl;
launcher->setTrkServerName(serialPortName);
- launcher->setFileName(QString("c:\\sys\\bin\\") + exeFile);
- launcher->setCommandLineArgs(cmdLine);
-
if (loglevel > 1)
launcher->setVerbose(1);
TrkSignalHandler handler;
handler.setLogLevel(loglevel);
+ handler.setCrashLogging(crashlog);
+ handler.setCrashLogPath(crashlogpath);
QObject::connect(launcher.data(), SIGNAL(copyingStarted()), &handler, SLOT(copyingStarted()));
QObject::connect(launcher.data(), SIGNAL(canNotConnect(const QString &)), &handler, SLOT(canNotConnect(const QString &)));
@@ -200,10 +228,16 @@ int main(int argc, char *argv[])
QObject::connect(launcher.data(), SIGNAL(copyProgress(int)), &handler, SLOT(copyProgress(int)));
QObject::connect(launcher.data(), SIGNAL(stateChanged(int)), &handler, SLOT(stateChanged(int)));
QObject::connect(launcher.data(), SIGNAL(processStopped(uint,uint,uint,QString)), &handler, SLOT(stopped(uint,uint,uint,QString)));
+ QObject::connect(launcher.data(), SIGNAL(libraryLoaded(trk::Library)), &handler, SLOT(libraryLoaded(trk::Library)));
+ QObject::connect(launcher.data(), SIGNAL(libraryUnloaded(trk::Library)), &handler, SLOT(libraryUnloaded(trk::Library)));
+ QObject::connect(launcher.data(), SIGNAL(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)), &handler, SLOT(registersAndCallStackReadComplete(const QList<uint> &,const QByteArray &)));
QObject::connect(&handler, SIGNAL(resume(uint,uint)), launcher.data(), SLOT(resumeProcess(uint,uint)));
QObject::connect(&handler, SIGNAL(terminate()), launcher.data(), SLOT(terminate()));
+ QObject::connect(&handler, SIGNAL(getRegistersAndCallStack(uint,uint)), launcher.data(), SLOT(getRegistersAndCallStack(uint,uint)));
QObject::connect(launcher.data(), SIGNAL(finished()), &handler, SLOT(finished()));
+ QObject::connect(OsSignalConverter::instance(), SIGNAL(terminate()), launcher.data(), SLOT(terminate()), Qt::QueuedConnection);
+
QTimer timer;
timer.setSingleShot(true);
QObject::connect(&timer, SIGNAL(timeout()), &handler, SLOT(timeout()));
diff --git a/tools/runonphone/ossignalconverter.cpp b/tools/runonphone/ossignalconverter.cpp
new file mode 100644
index 0000000..8566458
--- /dev/null
+++ b/tools/runonphone/ossignalconverter.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "ossignalconverter_p.h"
+#include <signal.h>
+#include <QTimer>
+#include <stdio.h>
+
+Q_GLOBAL_STATIC(OsSignalConverter, osSignalConverter);
+
+OsSignalConverter* OsSignalConverter::instance()
+{
+ return osSignalConverter();
+}
+
+OsSignalConverter::OsSignalConverter()
+: d(new OsSignalConverterPrivate(this))
+{
+};
+
+OsSignalConverter::~OsSignalConverter()
+{
+}
+
+OsSignalConverterPrivate::OsSignalConverterPrivate(OsSignalConverter* owner)
+: QObject(owner), q(owner), poller(new QTimer(this))
+{
+ trap();
+ connect(poller, SIGNAL(timeout()), this, SLOT(poll()));
+ poller->start(1000);
+}
+
+OsSignalConverterPrivate::~OsSignalConverterPrivate()
+{
+ untrap();
+}
+
+void OsSignalConverterPrivate::trap()
+{
+ signal(SIGINT, handler);
+ signal(SIGTERM, handler);
+#ifdef SIGBREAK
+ signal(SIGBREAK, handler);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, handler);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, handler);
+#endif
+}
+
+void OsSignalConverterPrivate::untrap()
+{
+ signal(SIGINT, SIG_DFL);
+ signal(SIGTERM, SIG_DFL);
+#ifdef SIGBREAK
+ signal(SIGBREAK, SIG_DFL);
+#endif
+#ifdef SIGHUP
+ signal(SIGHUP, SIG_DFL);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, SIG_DFL);
+#endif
+}
+
+void OsSignalConverterPrivate::handler(int sig)
+{
+ untrap(); //allow 2nd ctrl-c to really kill us
+ terminateRequest = sig;
+}
+
+void OsSignalConverterPrivate::poll()
+{
+ if (terminateRequest) {
+ fprintf(stderr, "\n*** caught signal %d, terminating ***\n", terminateRequest);
+ poller->stop();
+ emit q->terminate();
+ }
+}
+
+sig_atomic_t OsSignalConverterPrivate::terminateRequest;
diff --git a/tools/runonphone/ossignalconverter.h b/tools/runonphone/ossignalconverter.h
new file mode 100644
index 0000000..398d0f6
--- /dev/null
+++ b/tools/runonphone/ossignalconverter.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSSIGNALCONVERTER_H
+#define OSSIGNALCONVERTER_H
+#include <QObject>
+
+class OsSignalConverterPrivate;
+
+class OsSignalConverter : public QObject
+{
+ friend class OsSignalConverterPrivate;
+ Q_OBJECT
+public:
+ static OsSignalConverter* instance();
+ OsSignalConverter();
+ ~OsSignalConverter();
+signals:
+ //emitted when this process is asked to quit, e.g. by SIGINT
+ void terminate();
+private:
+ OsSignalConverterPrivate *d;
+};
+
+#endif // OSSIGNALCONVERTER_H
diff --git a/tools/runonphone/ossignalconverter_p.h b/tools/runonphone/ossignalconverter_p.h
new file mode 100644
index 0000000..dddc9ca
--- /dev/null
+++ b/tools/runonphone/ossignalconverter_p.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef OSSIGNALCONVERTER_P_H
+#define OSSIGNALCONVERTER_P_H
+#include "ossignalconverter.h"
+#include <signal.h>
+
+class QTimer;
+class OsSignalConverterPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ OsSignalConverterPrivate(OsSignalConverter* owner);
+ ~OsSignalConverterPrivate();
+private:
+
+ static void trap();
+ static void untrap();
+ static void handler(int signal);
+
+private slots:
+
+ void poll();
+
+private:
+
+ OsSignalConverter* q;
+ static sig_atomic_t terminateRequest;
+ QTimer *poller;
+};
+
+#endif // OSSIGNALCONVERTER_P_H
diff --git a/tools/runonphone/runonphone.pro b/tools/runonphone/runonphone.pro
index 7bed3e5..7ff361c 100644
--- a/tools/runonphone/runonphone.pro
+++ b/tools/runonphone/runonphone.pro
@@ -7,10 +7,13 @@ CONFIG -= app_bundle
include(symbianutils/symbianutils.pri)
SOURCES += main.cpp \
- trksignalhandler.cpp
+ trksignalhandler.cpp \
+ ossignalconverter.cpp
HEADERS += trksignalhandler.h \
- serenum.h
+ serenum.h \
+ ossignalconverter.h \
+ ossignalconverter_p.h
DEFINES += SYMBIANUTILS_INCLUDE_PRI
@@ -22,7 +25,11 @@ windows {
}
else:unix:!symbian {
SOURCES += serenum_unix.cpp
+ LIBS += -lusb
}
else {
SOURCES += serenum_stub.cpp
}
+
+target.path=$$[QT_INSTALL_BINS]
+INSTALLS += target
diff --git a/tools/runonphone/serenum.h b/tools/runonphone/serenum.h
index b794b97..a65c8cb 100644
--- a/tools/runonphone/serenum.h
+++ b/tools/runonphone/serenum.h
@@ -51,6 +51,6 @@ struct SerialPortId
QString friendlyName;
};
-QList<SerialPortId> enumerateSerialPorts();
+QList<SerialPortId> enumerateSerialPorts(int loglevel);
#endif // WIN32SERENUM_H
diff --git a/tools/runonphone/serenum_unix.cpp b/tools/runonphone/serenum_unix.cpp
index c8ec021..db6375e 100644
--- a/tools/runonphone/serenum_unix.cpp
+++ b/tools/runonphone/serenum_unix.cpp
@@ -46,19 +46,175 @@
#include <QFileInfo>
#include <QDir>
-QList<SerialPortId> enumerateSerialPorts()
+#include <usb.h>
+
+class InterfaceInfo
+{
+public:
+ InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid);
+ QString manufacturer;
+ QString product;
+ int manufacturerid;
+ int productid;
+};
+
+InterfaceInfo::InterfaceInfo(const QString &mf, const QString &pr, int mfid, int prid) :
+ manufacturer(mf),
+ product(pr),
+ manufacturerid(mfid),
+ productid(prid)
{
+ if(mf.isEmpty())
+ manufacturer = QString("[%1]").arg(mfid, 4, 16, QChar('0'));
+ if(pr.isEmpty())
+ product = QString("[%1]").arg(prid, 4, 16, QChar('0'));
+}
+
+QList<SerialPortId> enumerateSerialPorts(int loglevel)
+{
+ QList<QString> eligibleInterfaces;
+ QList<InterfaceInfo> eligibleInterfacesInfo;
QList<SerialPortId> list;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ for (struct usb_bus *bus = usb_get_busses(); bus; bus = bus->next) {
+ for (struct usb_device *device = bus->devices; device; device = device->next) {
+ for (int n = 0; n < device->descriptor.bNumConfigurations; ++n) {
+ struct usb_config_descriptor &usbConfig =device->config[n];
+ QList<int> usableInterfaces;
+ for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
+ for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
+ struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
+ if (descriptor.bInterfaceClass != 2 // "Communication"
+ || descriptor.bInterfaceSubClass != 2 // Abstract (modem)
+ || descriptor.bInterfaceProtocol != 255) // Vendor Specific
+ continue;
+
+ unsigned char *buf = descriptor.extra;
+ unsigned int size = descriptor.extralen;
+ while (size >= 2 * sizeof(u_int8_t)) {
+ // for Communication devices there is a slave interface for the actual
+ // data transmission.
+ // the extra info stores that as a index for the interface
+ if (buf[0] >= 5 && buf[1] == 36 && buf[2] == 6) { // CDC Union
+ for (int i = 4; i < buf[0]; i++)
+ usableInterfaces.append((int) buf[i]);
+ }
+ size -= buf[0];
+ buf += buf[0];
+ }
+ }
+ }
+
+ if (usableInterfaces.isEmpty())
+ continue;
+
+ QString manufacturerString;
+ QString productString;
+
+ usb_dev_handle *devh = usb_open(device);
+ if (devh) {
+ QByteArray buf;
+ buf.resize(256);
+ int err = usb_get_string_simple(devh, device->descriptor.iManufacturer, buf.data(), buf.size());
+ if (err < 0) {
+ if (loglevel > 1)
+ qDebug() << " can't read manufacturer name, error:" << err;
+ } else {
+ manufacturerString = QString::fromAscii(buf);
+ if (loglevel > 1)
+ qDebug() << " manufacturer:" << manufacturerString;
+ }
+
+ buf.resize(256);
+ err = usb_get_string_simple(devh, device->descriptor.iProduct, buf.data(), buf.size());
+ if (err < 0) {
+ if (loglevel > 1)
+ qDebug() << " can't read product name, error:" << err;
+ } else {
+ productString = QString::fromAscii(buf);
+ if (loglevel > 1)
+ qDebug() << " product:" << productString;
+ }
+ usb_close(devh);
+ } else if (loglevel > 0) {
+ qDebug() << " can't open usb device";
+ }
+
+ // second loop to find the actual data interface.
+ foreach (int i, usableInterfaces) {
+ for (int m = 0; m < usbConfig.bNumInterfaces; ++m) {
+ for (int o = 0; o < usbConfig.interface[m].num_altsetting; ++o) {
+ struct usb_interface_descriptor &descriptor = usbConfig.interface[m].altsetting[o];
+ if (descriptor.bInterfaceNumber != i)
+ continue;
+ if (descriptor.bInterfaceClass == 10) { // "CDC Data"
+ if (loglevel > 1) {
+ qDebug() << " found the data port"
+ << "bus:" << bus->dirname
+ << "device" << device->filename
+ << "interface" << descriptor.bInterfaceNumber;
+ }
+ // ### manufacturer and product strings are only readable as root :(
+ if (!manufacturerString.isEmpty() && !productString.isEmpty()) {
+ eligibleInterfaces << QString("usb-%1_%2-if%3")
+ .arg(manufacturerString.replace(QChar(' '), QChar('_')))
+ .arg(productString.replace(QChar(' '), QChar('_')))
+ .arg(i, 2, 16, QChar('0'));
+ } else {
+ eligibleInterfaces << QString("if%1").arg(i, 2, 16, QChar('0')); // fix!
+ }
+ eligibleInterfacesInfo << InterfaceInfo(manufacturerString, productString, device->descriptor.idVendor, device->descriptor.idProduct);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (loglevel > 1)
+ qDebug() << " searching for interfaces:" << eligibleInterfaces;
+
QDir dir("/dev/serial/by-id/");
- QFileInfoList ports(dir.entryInfoList());
- foreach (const QFileInfo &info, ports) {
+ foreach (const QFileInfo &info, dir.entryInfoList()) {
if (!info.isDir()) {
+ bool usable = eligibleInterfaces.isEmpty();
+ foreach (const QString &iface, eligibleInterfaces) {
+ if (info.fileName().contains(iface)) {
+ if (loglevel > 1)
+ qDebug() << " found device file:" << info.fileName() << endl;
+ usable = true;
+ break;
+ }
+ }
+ if (!usable)
+ continue;
+
SerialPortId id;
id.friendlyName = info.fileName();
id.portName = info.canonicalFilePath();
list << id;
}
}
+
+ if (list.isEmpty() && !eligibleInterfacesInfo.isEmpty() && loglevel > 0) {
+ qDebug() << "Possible USB devices found, but without serial drivers:";
+ foreach(const InterfaceInfo &iface, eligibleInterfacesInfo) {
+ qDebug() << " Manufacturer:"
+ << iface.manufacturer
+ << "Product:"
+ << iface.product
+ << endl
+ << " Load generic driver using:"
+ << QString("sudo modprobe usbserial vendor=0x%1 product=0x%2")
+ .arg(iface.manufacturerid, 4, 16, QChar('0'))
+ .arg(iface.productid, 4, 16, QChar('0'));
+ }
+ }
return list;
}
diff --git a/tools/runonphone/serenum_win.cpp b/tools/runonphone/serenum_win.cpp
index 572161c..070cac2 100644
--- a/tools/runonphone/serenum_win.cpp
+++ b/tools/runonphone/serenum_win.cpp
@@ -53,7 +53,7 @@
//{4d36e978-e325-11ce-bfc1-08002be10318}
//DEFINE_GUID(GUID_DEVCLASS_PORTS, 0x4D36E978, 0xE325, 0x11CE, 0xBF, 0xC1, 0x08, 0x00, 0x2B, 0xE1, 0x03, 0x18 );
-QList<SerialPortId> enumerateSerialPorts()
+QList<SerialPortId> enumerateSerialPorts(int)
{
DWORD index=0;
SP_DEVINFO_DATA info;
diff --git a/tools/runonphone/symbianutils/json.cpp b/tools/runonphone/symbianutils/json.cpp
new file mode 100644
index 0000000..2d58824
--- /dev/null
+++ b/tools/runonphone/symbianutils/json.cpp
@@ -0,0 +1,490 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "json.h"
+
+#ifdef TODO_USE_CREATOR
+#include <utils/qtcassert.h>
+#endif // TODO_USE_CREATOR
+
+#include <QtCore/QByteArray>
+#include <QtCore/QTextStream>
+#include <QtCore/QDebug>
+#include <QtCore/QStringList>
+
+#include <ctype.h>
+
+//#define DEBUG_JASON
+#ifdef DEBUG_JASON
+#define JDEBUG(s) qDebug() << s
+#else
+#define JDEBUG(s)
+#endif
+
+namespace tcftrk {
+
+static void skipSpaces(const char *&from, const char *to)
+{
+ while (from != to && isspace(*from))
+ ++from;
+}
+
+QTextStream &operator<<(QTextStream &os, const JsonValue &mi)
+{
+ return os << mi.toString();
+}
+
+void JsonValue::parsePair(const char *&from, const char *to)
+{
+ skipSpaces(from, to);
+ JDEBUG("parsePair: " << QByteArray(from, to - from));
+ m_name = parseCString(from, to);
+ skipSpaces(from, to);
+ while (from < to && *from != ':') {
+ JDEBUG("not a colon" << *from);
+ ++from;
+ }
+ ++from;
+ parseValue(from, to);
+ skipSpaces(from, to);
+}
+
+QByteArray JsonValue::parseNumber(const char *&from, const char *to)
+{
+ QByteArray result;
+ if (from < to && *from == '-') // Leading '-'.
+ result.append(*from++);
+ while (from < to && *from >= '0' && *from <= '9')
+ result.append(*from++);
+ return result;
+}
+
+QByteArray JsonValue::parseCString(const char *&from, const char *to)
+{
+ QByteArray result;
+ JDEBUG("parseCString: " << QByteArray(from, to - from));
+ if (*from != '"') {
+ qDebug() << "JSON Parse Error, double quote expected";
+ ++from; // So we don't hang
+ return QByteArray();
+ }
+ const char *ptr = from;
+ ++ptr;
+ while (ptr < to) {
+ if (*ptr == '"') {
+ ++ptr;
+ result = QByteArray(from + 1, ptr - from - 2);
+ break;
+ }
+ if (*ptr == '\\') {
+ ++ptr;
+ if (ptr == to) {
+ qDebug() << "JSON Parse Error, unterminated backslash escape";
+ from = ptr; // So we don't hang
+ return QByteArray();
+ }
+ }
+ ++ptr;
+ }
+ from = ptr;
+
+ int idx = result.indexOf('\\');
+ if (idx >= 0) {
+ char *dst = result.data() + idx;
+ const char *src = dst + 1, *end = result.data() + result.length();
+ do {
+ char c = *src++;
+ switch (c) {
+ case 'a': *dst++ = '\a'; break;
+ case 'b': *dst++ = '\b'; break;
+ case 'f': *dst++ = '\f'; break;
+ case 'n': *dst++ = '\n'; break;
+ case 'r': *dst++ = '\r'; break;
+ case 't': *dst++ = '\t'; break;
+ case 'v': *dst++ = '\v'; break;
+ case '"': *dst++ = '"'; break;
+ case '\\': *dst++ = '\\'; break;
+ default:
+ {
+ int chars = 0;
+ uchar prod = 0;
+ forever {
+ if (c < '0' || c > '7') {
+ --src;
+ break;
+ }
+ prod = prod * 8 + c - '0';
+ if (++chars == 3 || src == end)
+ break;
+ c = *src++;
+ }
+ if (!chars) {
+ qDebug() << "JSON Parse Error, unrecognized backslash escape";
+ return QByteArray();
+ }
+ *dst++ = prod;
+ }
+ }
+ while (src != end) {
+ char c = *src++;
+ if (c == '\\')
+ break;
+ *dst++ = c;
+ }
+ } while (src != end);
+ *dst = 0;
+ result.truncate(dst - result.data());
+ }
+
+ JDEBUG("parseCString, got " << result);
+ return result;
+}
+
+
+
+void JsonValue::parseValue(const char *&from, const char *to)
+{
+ JDEBUG("parseValue: " << QByteArray(from, to - from));
+ switch (*from) {
+ case '{':
+ parseObject(from, to);
+ break;
+ case 't':
+ if (to - from >= 4 && qstrncmp(from, "true", 4) == 0) {
+ m_data = QByteArray(from, 4);
+ from += m_data.size();
+ m_type = Boolean;
+ }
+ break;
+ case 'f':
+ if (to - from >= 5 && qstrncmp(from, "false", 5) == 0) {
+ m_data = QByteArray(from, 5);
+ from += m_data.size();
+ m_type = Boolean;
+ }
+ break;
+ case 'n':
+ if (to - from >= 4 && qstrncmp(from, "null", 4) == 0) {
+ m_data = QByteArray(from, 4);
+ from += m_data.size();
+ m_type = NullObject;
+ }
+ break;
+ case '[':
+ parseArray(from, to);
+ break;
+ case '"':
+ m_type = String;
+ m_data = parseCString(from, to);
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ case '-':
+ m_type = Number;
+ m_data = parseNumber(from, to);
+ default:
+ break;
+ }
+}
+
+void JsonValue::parseObject(const char *&from, const char *to)
+{
+ JDEBUG("parseObject: " << QByteArray(from, to - from));
+#ifdef TODO_USE_CREATOR
+ QTC_ASSERT(*from == '{', /**/);
+#endif
+ ++from;
+ m_type = Object;
+ while (from < to) {
+ if (*from == '}') {
+ ++from;
+ break;
+ }
+ JsonValue child;
+ child.parsePair(from, to);
+ if (!child.isValid())
+ return;
+ m_children += child;
+ if (*from == ',')
+ ++from;
+ }
+}
+
+void JsonValue::parseArray(const char *&from, const char *to)
+{
+ JDEBUG("parseArray: " << QByteArray(from, to - from));
+#ifdef TODO_USE_CREATOR
+ QTC_ASSERT(*from == '[', /**/);
+#endif
+ ++from;
+ m_type = Array;
+ while (from < to) {
+ if (*from == ']') {
+ ++from;
+ break;
+ }
+ JsonValue child;
+ child.parseValue(from, to);
+ if (child.isValid())
+ m_children += child;
+ if (*from == ',')
+ ++from;
+ }
+}
+
+void JsonValue::setStreamOutput(const QByteArray &name, const QByteArray &content)
+{
+ if (content.isEmpty())
+ return;
+ JsonValue child;
+ child.m_type = String;
+ child.m_name = name;
+ child.m_data = content;
+ m_children += child;
+ if (m_type == Invalid)
+ m_type = Object;
+}
+
+static QByteArray ind(int indent)
+{
+ return QByteArray(2 * indent, ' ');
+}
+
+void JsonValue::dumpChildren(QByteArray * str, bool multiline, int indent) const
+{
+ for (int i = 0; i < m_children.size(); ++i) {
+ if (i != 0) {
+ *str += ',';
+ if (multiline)
+ *str += '\n';
+ }
+ if (multiline)
+ *str += ind(indent);
+ *str += m_children.at(i).toString(multiline, indent);
+ }
+}
+
+class MyString : public QString {
+public:
+ ushort at(int i) const { return constData()[i].unicode(); }
+};
+
+template<class ST, typename CT>
+inline ST escapeCStringTpl(const ST &ba)
+{
+ ST ret;
+ ret.reserve(ba.length() * 2);
+ for (int i = 0; i < ba.length(); ++i) {
+ CT c = ba.at(i);
+ switch (c) {
+ case '\\': ret += "\\\\"; break;
+ case '\a': ret += "\\a"; break;
+ case '\b': ret += "\\b"; break;
+ case '\f': ret += "\\f"; break;
+ case '\n': ret += "\\n"; break;
+ case '\r': ret += "\\r"; break;
+ case '\t': ret += "\\t"; break;
+ case '\v': ret += "\\v"; break;
+ case '"': ret += "\\\""; break;
+ default:
+ if (c < 32 || c == 127) {
+ ret += '\\';
+ ret += '0' + (c >> 6);
+ ret += '0' + ((c >> 3) & 7);
+ ret += '0' + (c & 7);
+ } else {
+ ret += c;
+ }
+ }
+ }
+ return ret;
+}
+
+QString JsonValue::escapeCString(const QString &ba)
+{
+ return escapeCStringTpl<MyString, ushort>(static_cast<const MyString &>(ba));
+}
+
+QByteArray JsonValue::escapeCString(const QByteArray &ba)
+{
+ return escapeCStringTpl<QByteArray, uchar>(ba);
+}
+
+QByteArray JsonValue::toString(bool multiline, int indent) const
+{
+ QByteArray result;
+ switch (m_type) {
+ case Invalid:
+ if (multiline)
+ result += ind(indent) + "Invalid\n";
+ else
+ result += "Invalid";
+ break;
+ case String:
+ if (!m_name.isEmpty())
+ result += m_name + "=";
+ result += '"' + escapeCString(m_data) + '"';
+ break;
+ case Number:
+ if (!m_name.isEmpty())
+ result += '"' + m_name + "\":";
+ result += m_data;
+ break;
+ case Boolean:
+ case NullObject:
+ if (!m_name.isEmpty())
+ result += '"' + m_name + "\":";
+ result += m_data;
+ break;
+ case Object:
+ if (!m_name.isEmpty())
+ result += m_name + '=';
+ if (multiline) {
+ result += "{\n";
+ dumpChildren(&result, multiline, indent + 1);
+ result += '\n' + ind(indent) + "}";
+ } else {
+ result += "{";
+ dumpChildren(&result, multiline, indent + 1);
+ result += "}";
+ }
+ break;
+ case Array:
+ if (!m_name.isEmpty())
+ result += m_name + "=";
+ if (multiline) {
+ result += "[\n";
+ dumpChildren(&result, multiline, indent + 1);
+ result += '\n' + ind(indent) + "]";
+ } else {
+ result += "[";
+ dumpChildren(&result, multiline, indent + 1);
+ result += "]";
+ }
+ break;
+ }
+ return result;
+}
+
+void JsonValue::fromString(const QByteArray &ba)
+{
+ const char *from = ba.constBegin();
+ const char *to = ba.constEnd();
+ parseValue(from, to);
+}
+
+JsonValue JsonValue::findChild(const char *name) const
+{
+ for (int i = 0; i < m_children.size(); ++i)
+ if (m_children.at(i).m_name == name)
+ return m_children.at(i);
+ return JsonValue();
+}
+
+void JsonInputStream::appendCString(const char *s)
+{
+ m_target.append('"');
+ for (const char *p = s; *p; p++) {
+ if (*p == '"' || *p == '\\')
+ m_target.append('\\');
+ m_target.append(*p);
+ }
+ m_target.append('"');
+}
+
+void JsonInputStream::appendString(const QString &in)
+{
+ if (in.isEmpty()) {
+ m_target.append("\"\"");
+ return;
+ }
+
+ const QChar doubleQuote('"');
+ const QChar backSlash('\\');
+ QString rc;
+ const int inSize = in.size();
+ rc.reserve(in.size() + 5);
+ rc.append(doubleQuote);
+ for (int i = 0; i < inSize; i++) {
+ const QChar c = in.at(i);
+ if (c == doubleQuote || c == backSlash)
+ rc.append(backSlash);
+ rc.append(c);
+ }
+ rc.append(doubleQuote);
+ m_target.append(rc.toUtf8());
+ return;
+}
+
+JsonInputStream &JsonInputStream::operator<<(const QStringList &in)
+{
+ m_target.append('[');
+ const int count = in.size();
+ for (int i = 0 ; i < count; i++) {
+ if (i)
+ m_target.append(',');
+ appendString(in.at(i));
+ }
+ m_target.append(']');
+ return *this;
+}
+
+JsonInputStream &JsonInputStream::operator<<(const QVector<QByteArray> &ba)
+{
+ m_target.append('[');
+ const int count = ba.size();
+ for (int i = 0 ; i < count; i++) {
+ if (i)
+ m_target.append(',');
+ appendCString(ba.at(i).constData());
+ }
+ m_target.append(']');
+ return *this;
+}
+
+JsonInputStream &JsonInputStream::operator<<(bool b)
+{
+ m_target.append(b ? "true" : "false");
+ return *this;
+}
+
+} // namespace tcftrk
+
diff --git a/tools/runonphone/symbianutils/json.h b/tools/runonphone/symbianutils/json.h
new file mode 100644
index 0000000..ffcb7ab
--- /dev/null
+++ b/tools/runonphone/symbianutils/json.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SYMBIANUTILS_JSON_H
+#define SYMBIANUTILS_JSON_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QByteArray>
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+namespace tcftrk {
+
+class SYMBIANUTILS_EXPORT JsonValue
+{
+public:
+ JsonValue() : m_type(Invalid) {}
+ explicit JsonValue(const QByteArray &str) { fromString(str); }
+
+ QByteArray m_name;
+ QByteArray m_data;
+ QList<JsonValue> m_children;
+
+ enum Type {
+ Invalid,
+ String,
+ Number,
+ Boolean,
+ Object,
+ NullObject,
+ Array,
+ };
+
+ Type m_type;
+
+ inline Type type() const { return m_type; }
+ inline QByteArray name() const { return m_name; }
+ inline bool hasName(const char *name) const { return m_name == name; }
+
+ inline bool isValid() const { return m_type != Invalid; }
+ inline bool isNumber() const { return m_type == Number; }
+ inline bool isString() const { return m_type == String; }
+ inline bool isObject() const { return m_type == Object; }
+ inline bool isArray() const { return m_type == Array; }
+
+
+ inline QByteArray data() const { return m_data; }
+ inline const QList<JsonValue> &children() const { return m_children; }
+ inline int childCount() const { return m_children.size(); }
+
+ const JsonValue &childAt(int index) const { return m_children[index]; }
+ JsonValue &childAt(int index) { return m_children[index]; }
+ JsonValue findChild(const char *name) const;
+
+ QByteArray toString(bool multiline = false, int indent = 0) const;
+ void fromString(const QByteArray &str);
+ void setStreamOutput(const QByteArray &name, const QByteArray &content);
+
+private:
+ static QByteArray parseCString(const char *&from, const char *to);
+ static QByteArray parseNumber(const char *&from, const char *to);
+ static QByteArray escapeCString(const QByteArray &ba);
+ static QString escapeCString(const QString &ba);
+ void parsePair(const char *&from, const char *to);
+ void parseValue(const char *&from, const char *to);
+ void parseObject(const char *&from, const char *to);
+ void parseArray(const char *&from, const char *to);
+
+ void dumpChildren(QByteArray *str, bool multiline, int indent) const;
+};
+
+/* Thin wrapper around QByteArray for formatting JSON input. Use as in:
+ * JsonInputStream(byteArray) << '{' << "bla" << ':' << "blup" << '}';
+ * Note that strings get double quotes and JSON-escaping, characters should be
+ * used for the array/hash delimiters.
+ * */
+class SYMBIANUTILS_EXPORT JsonInputStream {
+public:
+ explicit JsonInputStream(QByteArray &a) : m_target(a) {}
+
+ JsonInputStream &operator<<(char c) { m_target.append(c); return *this; }
+ JsonInputStream &operator<<(const char *c) { appendCString(c); return *this; }
+ JsonInputStream &operator<<(const QByteArray &a) { appendCString(a.constData()); return *this; }
+ JsonInputStream &operator<<(const QString &c) { appendString(c); return *this; }
+
+ // Format as array
+ JsonInputStream &operator<<(const QStringList &c);
+
+ // Format as array
+ JsonInputStream &operator<<(const QVector<QByteArray> &ba);
+
+ JsonInputStream &operator<<(bool b);
+
+ JsonInputStream &operator<<(int i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+ JsonInputStream &operator<<(unsigned i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+ JsonInputStream &operator<<(quint64 i)
+ { m_target.append(QByteArray::number(i)); return *this; }
+
+private:
+ void appendString(const QString &);
+ void appendCString(const char *c);
+
+ QByteArray &m_target;
+};
+
+} // namespace tcftrk
+
+#endif // SYMBIANUTILS_JSON_H
diff --git a/tools/runonphone/symbianutils/launcher.cpp b/tools/runonphone/symbianutils/launcher.cpp
index 408829b..ee87480 100644
--- a/tools/runonphone/symbianutils/launcher.cpp
+++ b/tools/runonphone/symbianutils/launcher.cpp
@@ -44,6 +44,7 @@
#include "trkutils_p.h"
#include "trkdevice.h"
#include "bluetoothlistener.h"
+#include "symbiandevicemanager.h"
#include <QtCore/QTimer>
#include <QtCore/QDateTime>
@@ -53,15 +54,45 @@
#include <QtCore/QFile>
#include <QtCore/QScopedPointer>
+#include <cstdio>
+
namespace trk {
+struct CrashReportState {
+ CrashReportState();
+ void clear();
+
+ typedef uint Thread;
+ typedef QList<Thread> Threads;
+ Threads threads;
+
+ QList<uint> registers;
+ QByteArray stack;
+ uint sp;
+ uint fetchingStackPID;
+ uint fetchingStackTID;
+};
+
+CrashReportState::CrashReportState()
+{
+ clear();
+}
+
+void CrashReportState::clear()
+{
+ threads.clear();
+ stack.clear();
+ sp = fetchingStackPID = fetchingStackTID = 0;
+}
+
struct LauncherPrivate {
struct CopyState {
QString sourceFileName;
QString destinationFileName;
uint copyFileHandle;
QScopedPointer<QByteArray> data;
- int position;
+ qint64 position;
+ QScopedPointer<QFile> localFile;
};
explicit LauncherPrivate(const TrkDevicePtr &d);
@@ -75,12 +106,14 @@ struct LauncherPrivate {
Session m_session; // global-ish data (process id, target information)
CopyState m_copyState;
+ CopyState m_downloadState;
QString m_fileName;
QStringList m_commandLineArgs;
QString m_installFileName;
int m_verbose;
Launcher::Actions m_startupActions;
bool m_closeDevice;
+ CrashReportState m_crashReportState;
};
LauncherPrivate::LauncherPrivate(const TrkDevicePtr &d) :
@@ -100,12 +133,15 @@ Launcher::Launcher(Actions startupActions,
d(new LauncherPrivate(dev))
{
d->m_startupActions = startupActions;
- connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));
- connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
+ connect(d->m_device.data(), SIGNAL(messageReceived(trk::TrkResult)), this, SLOT(handleResult(trk::TrkResult)));
}
Launcher::~Launcher()
{
+ // Destroyed before protocol was through: Close
+ if (d->m_closeDevice && d->m_device->isOpen())
+ d->m_device->close();
+ emit destroyed(d->m_device->port());
logMessage("Shutting down.\n");
delete d;
}
@@ -154,6 +190,12 @@ void Launcher::setCopyFileName(const QString &srcName, const QString &dstName)
d->m_copyState.destinationFileName = dstName;
}
+void Launcher::setDownloadFileName(const QString &srcName, const QString &dstName)
+{
+ d->m_downloadState.sourceFileName = srcName;
+ d->m_downloadState.destinationFileName = dstName;
+}
+
void Launcher::setInstallFileName(const QString &name)
{
d->m_installFileName = name;
@@ -188,11 +230,28 @@ void Launcher::setCloseDevice(bool c)
bool Launcher::startServer(QString *errorMessage)
{
errorMessage->clear();
+ d->m_crashReportState.clear();
if (d->m_verbose) {
- const QString msg = QString::fromLatin1("Port=%1 Executable=%2 Arguments=%3 Package=%4 Remote Package=%5 Install file=%6")
- .arg(trkServerName(), d->m_fileName,
- d->m_commandLineArgs.join(QString(QLatin1Char(' '))),
- d->m_copyState.sourceFileName, d->m_copyState.destinationFileName, d->m_installFileName);
+ QString msg;
+ QTextStream str(&msg);
+ str.setIntegerBase(16);
+ str << "Actions=0x" << d->m_startupActions;
+ str.setIntegerBase(10);
+ str << " Port=" << trkServerName();
+ if (!d->m_fileName.isEmpty())
+ str << " Executable=" << d->m_fileName;
+ if (!d->m_commandLineArgs.isEmpty())
+ str << " Arguments= " << d->m_commandLineArgs.join(QString(QLatin1Char(' ')));
+ if (!d->m_copyState.sourceFileName.isEmpty())
+ str << " Package/Source=" << d->m_copyState.sourceFileName;
+ if (!d->m_copyState.destinationFileName.isEmpty())
+ str << " Remote Package/Destination=" << d->m_copyState.destinationFileName;
+ if (!d->m_downloadState.sourceFileName.isEmpty())
+ str << " Source=" << d->m_downloadState.sourceFileName;
+ if (!d->m_downloadState.destinationFileName.isEmpty())
+ str << " Destination=" << d->m_downloadState.destinationFileName;
+ if (!d->m_installFileName.isEmpty())
+ str << " Install file=" << d->m_installFileName;
logMessage(msg);
}
if (d->m_startupActions & ActionCopy) {
@@ -214,11 +273,6 @@ bool Launcher::startServer(QString *errorMessage)
}
if (!d->m_device->isOpen() && !d->m_device->open(errorMessage))
return false;
- if (d->m_closeDevice) {
- connect(this, SIGNAL(finished()), d->m_device.data(), SLOT(close()));
- } else {
- disconnect(this, SIGNAL(finished()), d->m_device.data(), 0);
- }
setState(Connecting);
// Set up the temporary 'waiting' state if we do not get immediate connection
QTimer::singleShot(1000, this, SLOT(slotWaitingForTrk()));
@@ -252,6 +306,8 @@ void Launcher::handleConnect(const TrkResult &result)
installRemotePackageSilently();
else if (d->m_startupActions & ActionRun)
startInferiorIfNeeded();
+ else if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
}
void Launcher::setVerbose(int v)
@@ -266,6 +322,13 @@ void Launcher::logMessage(const QString &msg)
qDebug() << "LAUNCHER: " << qPrintable(msg);
}
+void Launcher::handleFinished()
+{
+ if (d->m_closeDevice)
+ d->m_device->close();
+ emit finished();
+}
+
void Launcher::terminate()
{
switch (state()) {
@@ -287,7 +350,7 @@ void Launcher::terminate()
case Connecting:
case WaitingForTrk:
setState(Disconnected);
- emit finished();
+ handleFinished();
break;
}
}
@@ -331,8 +394,22 @@ void Launcher::handleResult(const TrkResult &result)
QByteArray prefix = "READ BUF: ";
QByteArray str = result.toString().toUtf8();
if (result.isDebugOutput) { // handle application output
- logMessage("APPLICATION OUTPUT: " + result.data);
- emit applicationOutputReceived(result.data);
+ QString msg;
+ if (result.multiplex == MuxTextTrace) {
+ if (result.data.length() > 8) {
+ quint64 timestamp = extractInt64(result.data) & 0x0FFFFFFFFFFFFFFFULL;
+ quint64 secs = timestamp / 1000000000;
+ quint64 ns = timestamp % 1000000000;
+ msg = QString("[%1.%2] %3").arg(secs).arg(ns).arg(QString(result.data.mid(8)));
+ logMessage("TEXT TRACE: " + msg);
+ }
+ } else {
+ logMessage("APPLICATION OUTPUT: " + stringFromArray(result.data));
+ msg = result.data;
+ }
+ msg.replace("\r\n", "\n");
+ if(!msg.endsWith('\n')) msg.append('\n');
+ emit applicationOutputReceived(msg);
return;
}
switch (result.code) {
@@ -368,49 +445,54 @@ void Launcher::handleResult(const TrkResult &result)
// target->host OS notification
case TrkNotifyCreated: { // Notify Created
- /*
- const char *data = result.data.data();
- byte error = result.data.at(0);
- byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
- uint pid = extractInt(data + 2); // ProcessID: 4 bytes;
- uint tid = extractInt(data + 6); //threadID: 4 bytes
- uint codeseg = extractInt(data + 10); //code address: 4 bytes; code base address for the library
- uint dataseg = extractInt(data + 14); //data address: 4 bytes; data base address for the library
- uint len = extractShort(data + 18); //length: 2 bytes; length of the library name string to follow
- QByteArray name = result.data.mid(20, len); // name: library name
-
- logMessage(prefix + "NOTE: LIBRARY LOAD: " + str);
- logMessage(prefix + "TOKEN: " + result.token);
- logMessage(prefix + "ERROR: " + int(error));
- logMessage(prefix + "TYPE: " + int(type));
- logMessage(prefix + "PID: " + pid);
- logMessage(prefix + "TID: " + tid);
- logMessage(prefix + "CODE: " + codeseg);
- logMessage(prefix + "DATA: " + dataseg);
- logMessage(prefix + "LEN: " + len);
- logMessage(prefix + "NAME: " + name);
- */
if (result.data.size() < 10)
break;
+ const char *data = result.data.constData();
+ const byte error = result.data.at(0);
+ Q_UNUSED(error)
+ const byte type = result.data.at(1); // type: 1 byte; for dll item, this value is 2.
+ const uint tid = extractInt(data + 6); //threadID: 4 bytes
+ Q_UNUSED(tid)
+ if (type == kDSOSDLLItem && result.data.size() >=20) {
+ const Library lib = Library(result);
+ d->m_session.libraries.push_back(lib);
+ emit libraryLoaded(lib);
+ }
QByteArray ba;
ba.append(result.data.mid(2, 8));
d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
- //d->m_device->sendTrkAck(result.token)
break;
}
case TrkNotifyDeleted: { // NotifyDeleted
const ushort itemType = (unsigned char)result.data.at(1);
- const ushort len = result.data.size() > 12 ? extractShort(result.data.data() + 10) : ushort(0);
+ const uint pid = result.data.size() >= 6 ? extractShort(result.data.constData() + 2) : 0;
+ const uint tid = result.data.size() >= 10 ? extractShort(result.data.constData() + 6) : 0;
+ Q_UNUSED(tid)
+ const ushort len = result.data.size() > 12 ? extractShort(result.data.constData() + 10) : ushort(0);
const QString name = len ? QString::fromAscii(result.data.mid(12, len)) : QString();
logMessage(QString::fromLatin1("%1 %2 UNLOAD: %3").
arg(QString::fromAscii(prefix)).arg(itemType ? QLatin1String("LIB") : QLatin1String("PROCESS")).
arg(name));
d->m_device->sendTrkAck(result.token);
- if (itemType == 0 // process
+ if (itemType == kDSOSProcessItem // process
&& result.data.size() >= 10
&& d->m_session.pid == extractInt(result.data.data() + 6)) {
- disconnectTrk();
+ if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
+ else
+ disconnectTrk();
+ }
+ else if (itemType == kDSOSDLLItem && len) {
+ // Remove libraries of process.
+ for (QList<Library>::iterator it = d->m_session.libraries.begin(); it != d->m_session.libraries.end(); ) {
+ if ((*it).pid == pid && (*it).name == name) {
+ emit libraryUnloaded(*it);
+ it = d->m_session.libraries.erase(it);
+ } else {
+ ++it;
+ }
+ }
}
break;
}
@@ -446,7 +528,7 @@ void Launcher::handleTrkVersion(const TrkResult &result)
if (result.errorCode() || result.data.size() < 5) {
if (d->m_startupActions == ActionPingOnly) {
setState(Disconnected);
- emit finished();
+ handleFinished();
}
return;
}
@@ -455,31 +537,109 @@ void Launcher::handleTrkVersion(const TrkResult &result)
d->m_session.trkAppVersion.protocolMajor = result.data.at(3);
d->m_session.trkAppVersion.protocolMinor = result.data.at(4);
setState(DeviceDescriptionReceived);
+ const QString msg = deviceDescription();
+ emit deviceDescriptionReceived(trkServerName(), msg);
// Ping mode: Log & Terminate
if (d->m_startupActions == ActionPingOnly) {
- qWarning("%s", qPrintable(deviceDescription()));
+ qWarning("%s", qPrintable(msg));
setState(Disconnected);
- emit finished();
+ handleFinished();
}
}
+static inline QString msgCannotOpenRemoteFile(const QString &fileName, const QString &message)
+{
+ return Launcher::tr("Cannot open remote file '%1': %2").arg(fileName, message);
+}
+
+static inline QString msgCannotOpenLocalFile(const QString &fileName, const QString &message)
+{
+ return Launcher::tr("Cannot open '%1': %2").arg(fileName, message);
+}
+
void Launcher::handleFileCreation(const TrkResult &result)
{
if (result.errorCode() || result.data.size() < 6) {
- emit canNotCreateFile(d->m_copyState.destinationFileName, result.errorString());
+ const QString msg = msgCannotOpenRemoteFile(d->m_copyState.destinationFileName, result.errorString());
+ logMessage(msg);
+ emit canNotCreateFile(d->m_copyState.destinationFileName, msg);
disconnectTrk();
return;
}
const char *data = result.data.data();
d->m_copyState.copyFileHandle = extractInt(data + 2);
- QFile file(d->m_copyState.sourceFileName);
- file.open(QIODevice::ReadOnly);
- d->m_copyState.data.reset(new QByteArray(file.readAll()));
+ const QString localFileName = d->m_copyState.sourceFileName;
+ QFile file(localFileName);
d->m_copyState.position = 0;
+ if (!file.open(QIODevice::ReadOnly)) {
+ const QString msg = msgCannotOpenLocalFile(localFileName, file.errorString());
+ logMessage(msg);
+ emit canNotOpenLocalFile(localFileName, msg);
+ closeRemoteFile(true);
+ disconnectTrk();
+ return;
+ }
+ d->m_copyState.data.reset(new QByteArray(file.readAll()));
file.close();
continueCopying();
}
+void Launcher::handleFileOpened(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 6) {
+ const QString msg = msgCannotOpenRemoteFile(d->m_downloadState.sourceFileName, result.errorString());
+ logMessage(msg);
+ emit canNotOpenFile(d->m_downloadState.sourceFileName, msg);
+ disconnectTrk();
+ return;
+ }
+ d->m_downloadState.position = 0;
+ const QString localFileName = d->m_downloadState.destinationFileName;
+ bool opened = false;
+ if (localFileName == QLatin1String("-")) {
+ d->m_downloadState.localFile.reset(new QFile);
+ opened = d->m_downloadState.localFile->open(stdout, QFile::WriteOnly);
+ } else {
+ d->m_downloadState.localFile.reset(new QFile(localFileName));
+ opened = d->m_downloadState.localFile->open(QFile::WriteOnly | QFile::Truncate);
+ }
+ if (!opened) {
+ const QString msg = msgCannotOpenLocalFile(localFileName, d->m_downloadState.localFile->errorString());
+ logMessage(msg);
+ emit canNotOpenLocalFile(localFileName, msg);
+ closeRemoteFile(true);
+ disconnectTrk();
+ }
+ continueReading();
+}
+
+void Launcher::continueReading()
+{
+ QByteArray ba;
+ appendInt(&ba, d->m_downloadState.copyFileHandle, TargetByteOrder);
+ appendShort(&ba, 2048, TargetByteOrder);
+ d->m_device->sendTrkMessage(TrkReadFile, TrkCallback(this, &Launcher::handleRead), ba);
+}
+
+void Launcher::handleRead(const TrkResult &result)
+{
+ if (result.errorCode() || result.data.size() < 4) {
+ d->m_downloadState.localFile->close();
+ closeRemoteFile(true);
+ disconnectTrk();
+ } else {
+ int length = extractShort(result.data.data() + 2);
+ //TRK doesn't tell us the file length, so we need to keep reading until it returns 0 length
+ if (length > 0) {
+ d->m_downloadState.localFile->write(result.data.data() + 4, length);
+ continueReading();
+ } else {
+ closeRemoteFile(true);
+ disconnectTrk();
+ }
+ }
+}
+
void Launcher::handleCopy(const TrkResult &result)
{
if (result.errorCode() || result.data.size() < 4) {
@@ -493,13 +653,14 @@ void Launcher::handleCopy(const TrkResult &result)
void Launcher::continueCopying(uint lastCopiedBlockSize)
{
- int size = d->m_copyState.data->length();
+ qint64 size = d->m_copyState.data->length();
d->m_copyState.position += lastCopiedBlockSize;
if (size == 0)
emit copyProgress(100);
else {
- int percent = qMin((d->m_copyState.position*100)/size, 100);
- emit copyProgress(percent);
+ const qint64 hundred = 100;
+ const qint64 percent = qMin( (d->m_copyState.position * hundred) / size, hundred);
+ emit copyProgress(static_cast<int>(percent));
}
if (d->m_copyState.position < size) {
QByteArray ba;
@@ -532,6 +693,8 @@ void Launcher::handleFileCopied(const TrkResult &result)
installRemotePackageSilently();
else if (d->m_startupActions & ActionRun)
startInferiorIfNeeded();
+ else if (d->m_startupActions & ActionDownload)
+ copyFileFromRemote();
else
disconnectTrk();
}
@@ -576,6 +739,15 @@ void Launcher::handleCreateProcess(const TrkResult &result)
logMessage(msg);
}
emit applicationRunning(d->m_session.pid);
+ //create a "library" entry for the executable which launched the process
+ Library lib;
+ lib.pid = d->m_session.pid;
+ lib.codeseg = d->m_session.codeseg;
+ lib.dataseg = d->m_session.dataseg;
+ lib.name = d->m_fileName.toUtf8();
+ d->m_session.libraries << lib;
+ emit libraryLoaded(lib);
+
QByteArray ba;
appendInt(&ba, d->m_session.pid);
appendInt(&ba, d->m_session.tid);
@@ -586,7 +758,7 @@ void Launcher::handleWaitForFinished(const TrkResult &result)
{
logMessage(" FINISHED: " + stringFromArray(result.data));
setState(Disconnected);
- emit finished();
+ handleFinished();
}
void Launcher::handleSupportMask(const TrkResult &result)
@@ -595,17 +767,18 @@ void Launcher::handleSupportMask(const TrkResult &result)
return;
const char *data = result.data.data() + 1;
- QString str = QLatin1String("SUPPORTED: ");
- for (int i = 0; i < 32; ++i) {
- //str.append(" [" + formatByte(data[i]) + "]: ");
- for (int j = 0; j < 8; ++j) {
- if (data[i] & (1 << j)) {
- str.append(QString::number(i * 8 + j, 16));
- str.append(QLatin1Char(' '));
+ if (d->m_verbose > 1) {
+ QString str = QLatin1String("SUPPORTED: ");
+ for (int i = 0; i < 32; ++i) {
+ for (int j = 0; j < 8; ++j) {
+ if (data[i] & (1 << j)) {
+ str.append(QString::number(i * 8 + j, 16));
+ str.append(QLatin1Char(' '));
+ }
}
}
+ logMessage(str);
}
- logMessage(str);
}
void Launcher::cleanUp()
@@ -669,11 +842,20 @@ void Launcher::copyFileToRemote()
{
emit copyingStarted();
QByteArray ba;
- ba.append(char(10));
+ ba.append(char(10)); //kDSFileOpenWrite | kDSFileOpenBinary
appendString(&ba, d->m_copyState.destinationFileName.toLocal8Bit(), TargetByteOrder, false);
d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileCreation), ba);
}
+void Launcher::copyFileFromRemote()
+{
+ emit copyingStarted();
+ QByteArray ba;
+ ba.append(char(9)); //kDSFileOpenRead | kDSFileOpenBinary
+ appendString(&ba, d->m_downloadState.sourceFileName.toLocal8Bit(), TargetByteOrder, false);
+ d->m_device->sendTrkMessage(TrkOpenFile, TrkCallback(this, &Launcher::handleFileOpened), ba);
+}
+
void Launcher::installRemotePackageSilently()
{
emit installingStarted();
@@ -694,6 +876,8 @@ void Launcher::handleInstallPackageFinished(const TrkResult &result)
}
if (d->m_startupActions & ActionRun) {
startInferiorIfNeeded();
+ } else if (d->m_startupActions & ActionDownload) {
+ copyFileFromRemote();
} else {
disconnectTrk();
}
@@ -704,18 +888,38 @@ QByteArray Launcher::startProcessMessage(const QString &executable,
{
// It's not started yet
QByteArray ba;
- appendShort(&ba, 0, TargetByteOrder); // create new process
+ appendShort(&ba, 0, TargetByteOrder); // create new process (kDSOSProcessItem)
ba.append(char(0)); // options - currently unused
- if(arguments.isEmpty()) {
- appendString(&ba, executable.toLocal8Bit(), TargetByteOrder);
- return ba;
- }
- // Append full command line as one string (leading length information).
- QByteArray commandLineBa;
- commandLineBa.append(executable.toLocal8Bit());
- commandLineBa.append('\0');
- commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
- appendString(&ba, commandLineBa, TargetByteOrder);
+ // One string consisting of binary terminated by '\0' and arguments terminated by '\0'
+ QByteArray commandLineBa = executable.toLocal8Bit();
+ commandLineBa.append(char(0));
+ if (!arguments.isEmpty())
+ commandLineBa.append(arguments.join(QString(QLatin1Char(' '))).toLocal8Bit());
+ appendString(&ba, commandLineBa, TargetByteOrder, true);
+ return ba;
+}
+
+QByteArray Launcher::readMemoryMessage(uint pid, uint tid, uint from, uint len)
+{
+ QByteArray ba;
+ ba.reserve(11);
+ ba.append(char(0x8)); // Options, FIXME: why?
+ appendShort(&ba, len);
+ appendInt(&ba, from);
+ appendInt(&ba, pid);
+ appendInt(&ba, tid);
+ return ba;
+}
+
+QByteArray Launcher::readRegistersMessage(uint pid, uint tid)
+{
+ QByteArray ba;
+ ba.reserve(15);
+ ba.append(char(0)); // Register set, only 0 supported
+ appendShort(&ba, 0); //R0
+ appendShort(&ba, 16); // last register CPSR
+ appendInt(&ba, pid);
+ appendInt(&ba, tid);
return ba;
}
@@ -737,4 +941,96 @@ void Launcher::resumeProcess(uint pid, uint tid)
appendInt(&ba, tid, BigEndian);
d->m_device->sendTrkMessage(TrkContinue, TrkCallback(), ba, "CONTINUE");
}
+
+// Acquire a device from SymbianDeviceManager, return 0 if not available.
+Launcher *Launcher::acquireFromDeviceManager(const QString &serverName,
+ QObject *parent,
+ QString *errorMessage)
+{
+ SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
+ const QSharedPointer<trk::TrkDevice> device = sdm->acquireDevice(serverName);
+ if (device.isNull()) {
+ *errorMessage = tr("Unable to acquire a device for port '%1'. It appears to be in use.").arg(serverName);
+ return 0;
+ }
+ // Wire release signal.
+ Launcher *rc = new Launcher(trk::Launcher::ActionPingOnly, device, parent);
+ connect(rc, SIGNAL(deviceDescriptionReceived(QString,QString)),
+ sdm, SLOT(setAdditionalInformation(QString,QString)));
+ connect(rc, SIGNAL(destroyed(QString)), sdm, SLOT(releaseDevice(QString)));
+ return rc;
+}
+
+// Preliminary release of device, disconnecting the signal.
+void Launcher::releaseToDeviceManager(Launcher *launcher)
+{
+ SymbianUtils::SymbianDeviceManager *sdm = SymbianUtils::SymbianDeviceManager::instance();
+ // Disentangle launcher and its device, remove connection from destroyed
+ launcher->setCloseDevice(false);
+ TrkDevice *device = launcher->trkDevice().data();
+ launcher->disconnect(device);
+ device->disconnect(launcher);
+ launcher->disconnect(sdm);
+ sdm->releaseDevice(launcher->trkServerName());
+}
+
+void Launcher::getRegistersAndCallStack(uint pid, uint tid)
+{
+ d->m_device->sendTrkMessage(TrkReadRegisters,
+ TrkCallback(this, &Launcher::handleReadRegisters),
+ Launcher::readRegistersMessage(pid, tid));
+ d->m_crashReportState.fetchingStackPID = pid;
+ d->m_crashReportState.fetchingStackTID = tid;
+}
+
+void Launcher::handleReadRegisters(const TrkResult &result)
+{
+ if(result.errorCode() || result.data.size() < (17*4)) {
+ terminate();
+ return;
+ }
+ const char* data = result.data.constData() + 1;
+ d->m_crashReportState.registers.clear();
+ d->m_crashReportState.stack.clear();
+ for (int i=0;i<17;i++) {
+ uint r = extractInt(data);
+ data += 4;
+ d->m_crashReportState.registers.append(r);
+ }
+ d->m_crashReportState.sp = d->m_crashReportState.registers.at(13);
+
+ const ushort len = 1024 - (d->m_crashReportState.sp % 1024); //read to 1k boundary first
+ const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
+ d->m_crashReportState.fetchingStackTID,
+ d->m_crashReportState.sp,
+ len);
+ d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
+ d->m_crashReportState.sp += len;
+}
+
+void Launcher::handleReadStack(const TrkResult &result)
+{
+ if (result.errorCode()) {
+ //error implies memory fault when reaching end of stack
+ emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
+ return;
+ }
+
+ const uint len = extractShort(result.data.constData() + 1);
+ d->m_crashReportState.stack.append(result.data.mid(3, len));
+
+ if (d->m_crashReportState.sp - d->m_crashReportState.registers.at(13) > 0x10000) {
+ //read enough stack, stop here
+ emit registersAndCallStackReadComplete(d->m_crashReportState.registers, d->m_crashReportState.stack);
+ return;
+ }
+ //read 1k more
+ const QByteArray ba = Launcher::readMemoryMessage(d->m_crashReportState.fetchingStackPID,
+ d->m_crashReportState.fetchingStackTID,
+ d->m_crashReportState.sp,
+ 1024);
+ d->m_device->sendTrkMessage(TrkReadMemory, TrkCallback(this, &Launcher::handleReadStack), ba);
+ d->m_crashReportState.sp += 1024;
+}
+
} // namespace trk
diff --git a/tools/runonphone/symbianutils/launcher.h b/tools/runonphone/symbianutils/launcher.h
index 2b23fd8..230a122 100644
--- a/tools/runonphone/symbianutils/launcher.h
+++ b/tools/runonphone/symbianutils/launcher.h
@@ -43,6 +43,7 @@
#define LAUNCHER_H
#include "trkdevice.h"
+#include "trkutils.h"
#include <QtCore/QObject>
#include <QtCore/QVariant>
@@ -69,6 +70,7 @@ public:
ActionInstall = 0x2,
ActionCopyInstall = ActionCopy | ActionInstall,
ActionRun = 0x4,
+ ActionDownload = 0x8,
ActionCopyRun = ActionCopy | ActionRun,
ActionInstallRun = ActionInstall | ActionRun,
ActionCopyInstallRun = ActionCopy | ActionInstall | ActionRun
@@ -94,10 +96,11 @@ public:
QString trkServerName() const;
void setFileName(const QString &name);
void setCopyFileName(const QString &srcName, const QString &dstName);
+ void setDownloadFileName(const QString &srcName, const QString &dstName);
void setInstallFileName(const QString &name);
void setCommandLineArgs(const QStringList &args);
bool startServer(QString *errorMessage);
- void setVerbose(int v);
+ void setVerbose(int v);
void setSerialFrame(bool b);
bool serialFrame() const;
// Close device or leave it open
@@ -109,8 +112,20 @@ public:
// becomes valid after successful execution of ActionPingOnly
QString deviceDescription(unsigned verbose = 0u) const;
+ // Acquire a device from SymbianDeviceManager, return 0 if not available.
+ // The device will be released on destruction.
+ static Launcher *acquireFromDeviceManager(const QString &serverName,
+ QObject *parent,
+ QString *errorMessage);
+ // Preliminary release of device, disconnecting the signal.
+ static void releaseToDeviceManager(Launcher *l);
+
+ // Create Trk message to start a process.
static QByteArray startProcessMessage(const QString &executable,
const QStringList &arguments);
+ // Create Trk message to read memory
+ static QByteArray readMemoryMessage(uint pid, uint tid, uint from, uint len);
+ static QByteArray readRegistersMessage(uint pid, uint tid);
// Parse a TrkNotifyStopped message
static bool parseNotifyStopped(const QByteArray &a,
uint *pid, uint *tid, uint *address,
@@ -119,9 +134,12 @@ public:
static QString msgStopped(uint pid, uint tid, uint address, const QString &why);
signals:
+ void deviceDescriptionReceived(const QString &port, const QString &description);
void copyingStarted();
void canNotConnect(const QString &errorMessage);
void canNotCreateFile(const QString &filename, const QString &errorMessage);
+ void canNotOpenFile(const QString &filename, const QString &errorMessage);
+ void canNotOpenLocalFile(const QString &filename, const QString &errorMessage);
void canNotWriteFile(const QString &filename, const QString &errorMessage);
void canNotCloseFile(const QString &filename, const QString &errorMessage);
void installingStarted();
@@ -135,10 +153,18 @@ signals:
void copyProgress(int percent);
void stateChanged(int);
void processStopped(uint pc, uint pid, uint tid, const QString& reason);
+ void processResumed(uint pid, uint tid);
+ void libraryLoaded(const trk::Library &lib);
+ void libraryUnloaded(const trk::Library &lib);
+ void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack);
+ // Emitted by the destructor, for releasing devices of SymbianDeviceManager by name
+ void destroyed(const QString &serverName);
public slots:
void terminate();
void resumeProcess(uint pid, uint tid);
+ //can be used to obtain traceback after a breakpoint / exception
+ void getRegistersAndCallStack(uint pid, uint tid);
private slots:
void handleResult(const trk::TrkResult &data);
@@ -152,8 +178,11 @@ private:
void handleRemoteProcessKilled(const TrkResult &result);
void handleConnect(const TrkResult &result);
void handleFileCreation(const TrkResult &result);
+ void handleFileOpened(const TrkResult &result);
void handleCopy(const TrkResult &result);
+ void handleRead(const TrkResult &result);
void continueCopying(uint lastCopiedBlockSize = 0);
+ void continueReading();
void closeRemoteFile(bool failed = false);
void handleFileCopied(const TrkResult &result);
void handleInstallPackageFinished(const TrkResult &result);
@@ -163,10 +192,14 @@ private:
void handleStop(const TrkResult &result);
void handleSupportMask(const TrkResult &result);
void handleTrkVersion(const TrkResult &result);
+ void handleReadRegisters(const TrkResult &result);
+ void handleReadStack(const TrkResult &result);
void copyFileToRemote();
+ void copyFileFromRemote();
void installRemotePackageSilently();
void startInferiorIfNeeded();
+ void handleFinished();
void logMessage(const QString &msg);
void setState(State s);
diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.cpp b/tools/runonphone/symbianutils/symbiandevicemanager.cpp
index f663816..8877ea1 100644
--- a/tools/runonphone/symbianutils/symbiandevicemanager.cpp
+++ b/tools/runonphone/symbianutils/symbiandevicemanager.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "symbiandevicemanager.h"
+#include "trkdevice.h"
#include <QtCore/QSettings>
#include <QtCore/QStringList>
@@ -48,6 +49,7 @@
#include <QtCore/QTextStream>
#include <QtCore/QSharedData>
#include <QtCore/QScopedPointer>
+#include <QtCore/QSignalMapper>
namespace SymbianUtils {
@@ -61,19 +63,51 @@ const char *SymbianDeviceManager::linuxBlueToothDeviceRootC = "/dev/rfcomm";
// ------------- SymbianDevice
class SymbianDeviceData : public QSharedData {
public:
- SymbianDeviceData() : type(SerialPortCommunication) {}
+ SymbianDeviceData();
+ ~SymbianDeviceData();
+
+ inline bool isOpen() const { return !device.isNull() && device->isOpen(); }
+ void forcedClose();
QString portName;
QString friendlyName;
QString deviceDesc;
QString manufacturer;
+ QString additionalInformation;
+
DeviceCommunicationType type;
+ QSharedPointer<trk::TrkDevice> device;
+ bool deviceAcquired;
};
+SymbianDeviceData::SymbianDeviceData() :
+ type(SerialPortCommunication),
+ deviceAcquired(false)
+{
+}
+
+SymbianDeviceData::~SymbianDeviceData()
+{
+ forcedClose();
+}
+
+void SymbianDeviceData::forcedClose()
+{
+ // Close the device when unplugging. Should devices be in 'acquired' state,
+ // their owners should hit on write failures.
+ // Apart from the <shared item> destructor, also called by the devicemanager
+ // to ensure it also happens if other shared instances are still around.
+ if (isOpen()) {
+ if (deviceAcquired)
+ qWarning("Device on '%s' unplugged while an operation is in progress.",
+ qPrintable(portName));
+ device->close();
+ }
+}
+
SymbianDevice::SymbianDevice(SymbianDeviceData *data) :
m_data(data)
{
-
}
SymbianDevice::SymbianDevice() :
@@ -96,6 +130,11 @@ SymbianDevice::~SymbianDevice()
{
}
+void SymbianDevice::forcedClose()
+{
+ m_data->forcedClose();
+}
+
QString SymbianDevice::portName() const
{
return m_data->portName;
@@ -106,6 +145,51 @@ QString SymbianDevice::friendlyName() const
return m_data->friendlyName;
}
+QString SymbianDevice::additionalInformation() const
+{
+ return m_data->additionalInformation;
+}
+
+void SymbianDevice::setAdditionalInformation(const QString &a)
+{
+ m_data->additionalInformation = a;
+}
+
+SymbianDevice::TrkDevicePtr SymbianDevice::acquireDevice()
+{
+ if (debug)
+ qDebug() << "SymbianDevice::acquireDevice" << m_data->portName
+ << "acquired: " << m_data->deviceAcquired << " open: " << isOpen();
+ if (isNull() || m_data->deviceAcquired)
+ return TrkDevicePtr();
+ if (m_data->device.isNull()) {
+ m_data->device = TrkDevicePtr(new trk::TrkDevice);
+ m_data->device->setPort(m_data->portName);
+ m_data->device->setSerialFrame(m_data->type == SerialPortCommunication);
+ }
+ m_data->deviceAcquired = true;
+ return m_data->device;
+}
+
+void SymbianDevice::releaseDevice(TrkDevicePtr *ptr /* = 0 */)
+{
+ if (debug)
+ qDebug() << "SymbianDevice::releaseDevice" << m_data->portName
+ << " open: " << isOpen();
+ if (m_data->deviceAcquired) {
+ if (m_data->device->isOpen())
+ m_data->device->clearWriteQueue();
+ // Release if a valid pointer was passed in.
+ if (ptr && !ptr->isNull()) {
+ ptr->data()->disconnect();
+ *ptr = TrkDevicePtr();
+ }
+ m_data->deviceAcquired = false;
+ } else {
+ qWarning("Internal error: Attempt to release device that is not acquired.");
+ }
+}
+
QString SymbianDevice::deviceDesc() const
{
return m_data->deviceDesc;
@@ -123,7 +207,12 @@ DeviceCommunicationType SymbianDevice::type() const
bool SymbianDevice::isNull() const
{
- return !m_data->portName.isEmpty();
+ return m_data->portName.isEmpty();
+}
+
+bool SymbianDevice::isOpen() const
+{
+ return m_data->isOpen();
}
QString SymbianDevice::toString() const
@@ -158,7 +247,7 @@ int SymbianDevice::compare(const SymbianDevice &rhs) const
return 0;
}
-QDebug operator<<(QDebug d, const SymbianDevice &cd)
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &cd)
{
d.nospace() << cd.toString();
return d;
@@ -166,10 +255,11 @@ QDebug operator<<(QDebug d, const SymbianDevice &cd)
// ------------- SymbianDeviceManagerPrivate
struct SymbianDeviceManagerPrivate {
- SymbianDeviceManagerPrivate() : m_initialized(false) {}
+ SymbianDeviceManagerPrivate() : m_initialized(false), m_destroyReleaseMapper(0) {}
bool m_initialized;
SymbianDeviceManager::SymbianDeviceList m_devices;
+ QSignalMapper *m_destroyReleaseMapper;
};
SymbianDeviceManager::SymbianDeviceManager(QObject *parent) :
@@ -185,8 +275,7 @@ SymbianDeviceManager::~SymbianDeviceManager()
SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::devices() const
{
- if (!d->m_initialized)
- const_cast<SymbianDeviceManager*>(this)->update(false);
+ ensureInitialized();
return d->m_devices;
}
@@ -194,6 +283,7 @@ QString SymbianDeviceManager::toString() const
{
QString rc;
QTextStream str(&rc);
+ str << d->m_devices.size() << " devices:\n";
const int count = d->m_devices.size();
for (int i = 0; i < count; i++) {
str << '#' << i << ' ';
@@ -203,13 +293,37 @@ QString SymbianDeviceManager::toString() const
return rc;
}
+int SymbianDeviceManager::findByPortName(const QString &p) const
+{
+ ensureInitialized();
+ const int count = d->m_devices.size();
+ for (int i = 0; i < count; i++)
+ if (d->m_devices.at(i).portName() == p)
+ return i;
+ return -1;
+}
+
QString SymbianDeviceManager::friendlyNameForPort(const QString &port) const
{
- foreach (const SymbianDevice &device, d->m_devices) {
- if (device.portName() == port)
- return device.friendlyName();
- }
- return QString();
+ const int idx = findByPortName(port);
+ return idx == -1 ? QString() : d->m_devices.at(idx).friendlyName();
+}
+
+SymbianDeviceManager::TrkDevicePtr
+ SymbianDeviceManager::acquireDevice(const QString &port)
+{
+ ensureInitialized();
+ const int idx = findByPortName(port);
+ if (idx == -1) {
+ qWarning("Attempt to acquire device '%s' that does not exist.", qPrintable(port));
+ if (debug)
+ qDebug() << *this;
+ return TrkDevicePtr();
+ }
+ const TrkDevicePtr rc = d->m_devices[idx].acquireDevice();
+ if (debug)
+ qDebug() << "SymbianDeviceManager::acquireDevice" << port << " returns " << !rc.isNull();
+ return rc;
}
void SymbianDeviceManager::update()
@@ -217,12 +331,38 @@ void SymbianDeviceManager::update()
update(true);
}
+void SymbianDeviceManager::releaseDevice(const QString &port)
+{
+ const int idx = findByPortName(port);
+ if (debug)
+ qDebug() << "SymbianDeviceManager::releaseDevice" << port << idx << sender();
+ if (idx != -1) {
+ d->m_devices[idx].releaseDevice();
+ } else {
+ qWarning("Attempt to release non-existing device %s.", qPrintable(port));
+ }
+}
+
+void SymbianDeviceManager::setAdditionalInformation(const QString &port, const QString &ai)
+{
+ const int idx = findByPortName(port);
+ if (idx != -1)
+ d->m_devices[idx].setAdditionalInformation(ai);
+}
+
+void SymbianDeviceManager::ensureInitialized() const
+{
+ if (!d->m_initialized) // Flag is set in update()
+ const_cast<SymbianDeviceManager*>(this)->update(false);
+}
+
void SymbianDeviceManager::update(bool emitSignals)
{
+ static int n = 0;
typedef SymbianDeviceList::iterator SymbianDeviceListIterator;
if (debug)
- qDebug(">SerialDeviceLister::update(%d)\n%s", int(emitSignals),
+ qDebug(">SerialDeviceLister::update(#%d, signals=%d)\n%s", n++, int(emitSignals),
qPrintable(toString()));
d->m_initialized = true;
@@ -230,8 +370,11 @@ void SymbianDeviceManager::update(bool emitSignals)
SymbianDeviceList newDevices = serialPorts() + blueToothDevices();
if (newDevices.size() > 1)
qStableSort(newDevices.begin(), newDevices.end());
- if (d->m_devices == newDevices) // Happy, nothing changed.
+ if (d->m_devices == newDevices) { // Happy, nothing changed.
+ if (debug)
+ qDebug("<SerialDeviceLister::update: unchanged\n");
return;
+ }
// Merge the lists and emit the respective added/removed signals, assuming
// no one can plug a different device on the same port at the speed of lightning
if (!d->m_devices.isEmpty()) {
@@ -240,7 +383,8 @@ void SymbianDeviceManager::update(bool emitSignals)
if (newDevices.contains(*oldIt)) {
++oldIt;
} else {
- const SymbianDevice toBeDeleted = *oldIt;
+ SymbianDevice toBeDeleted = *oldIt;
+ toBeDeleted.forcedClose();
oldIt = d->m_devices.erase(oldIt);
if (emitSignals)
emit deviceRemoved(toBeDeleted);
@@ -301,16 +445,30 @@ SymbianDeviceManager::SymbianDeviceList SymbianDeviceManager::blueToothDevices()
// Bluetooth devices are created on connection. List the existing ones
// or at least the first one.
const QString prefix = QLatin1String(linuxBlueToothDeviceRootC);
- const QString friendlyFormat = QLatin1String("Bluetooth device (%1)");
+ const QString blueToothfriendlyFormat = QLatin1String("Bluetooth device (%1)");
for (int d = 0; d < 4; d++) {
QScopedPointer<SymbianDeviceData> device(new SymbianDeviceData);
device->type = BlueToothCommunication;
device->portName = prefix + QString::number(d);
if (d == 0 || QFileInfo(device->portName).exists()) {
- device->friendlyName = friendlyFormat.arg(device->portName);
+ device->friendlyName = blueToothfriendlyFormat.arg(device->portName);
rc.push_back(SymbianDevice(device.take()));
}
}
+ // New kernel versions support /dev/ttyUSB0, /dev/ttyUSB1. Trk responds
+ // on the latter (usually), try first.
+ static const char *usbTtyDevices[] = { "/dev/ttyUSB1", "/dev/ttyUSB0" };
+ const int usbTtyCount = sizeof(usbTtyDevices)/sizeof(const char *);
+ for (int d = 0; d < usbTtyCount; d++) {
+ const QString ttyUSBDevice = QLatin1String(usbTtyDevices[d]);
+ if (QFileInfo(ttyUSBDevice).exists()) {
+ SymbianDeviceData *device = new SymbianDeviceData;
+ device->type = SerialPortCommunication;
+ device->portName = ttyUSBDevice;
+ device->friendlyName = QString::fromLatin1("USB/Serial device (%1)").arg(device->portName);
+ rc.push_back(SymbianDevice(device));
+ }
+ }
#endif
return rc;
}
@@ -322,7 +480,7 @@ SymbianDeviceManager *SymbianDeviceManager::instance()
return symbianDeviceManager();
}
-QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm)
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &sdm)
{
d.nospace() << sdm.toString();
return d;
diff --git a/tools/runonphone/symbianutils/symbiandevicemanager.h b/tools/runonphone/symbianutils/symbiandevicemanager.h
index dcf131a..180173d 100644
--- a/tools/runonphone/symbianutils/symbiandevicemanager.h
+++ b/tools/runonphone/symbianutils/symbiandevicemanager.h
@@ -46,12 +46,17 @@
#include <QtCore/QObject>
#include <QtCore/QExplicitlySharedDataPointer>
+#include <QtCore/QSharedPointer>
QT_BEGIN_NAMESPACE
class QDebug;
class QTextStream;
QT_END_NAMESPACE
+namespace trk {
+ class TrkDevice;
+}
+
namespace SymbianUtils {
struct SymbianDeviceManagerPrivate;
@@ -62,11 +67,16 @@ enum DeviceCommunicationType {
BlueToothCommunication = 1
};
-// SymbianDevice, explicitly shared.
+// SymbianDevice: Explicitly shared device data and a TrkDevice
+// instance that can be acquired (exclusively) for use.
+// A device removal from the manager will result in the
+// device being closed.
class SYMBIANUTILS_EXPORT SymbianDevice {
explicit SymbianDevice(SymbianDeviceData *data);
friend class SymbianDeviceManager;
public:
+ typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr;
+
SymbianDevice();
SymbianDevice(const SymbianDevice &rhs);
SymbianDevice &operator=(const SymbianDevice &rhs);
@@ -77,6 +87,17 @@ public:
bool isNull() const;
QString portName() const;
QString friendlyName() const;
+ QString additionalInformation() const;
+ void setAdditionalInformation(const QString &);
+
+ // Acquire: Mark the device as 'out' and return a shared pointer
+ // unless it is already in use by another owner. The result should not
+ // be passed on further.
+ TrkDevicePtr acquireDevice();
+ // Give back a device and mark it as 'free'.
+ void releaseDevice(TrkDevicePtr *ptr = 0);
+
+ bool isOpen() const;
// Windows only.
QString deviceDesc() const;
@@ -86,10 +107,12 @@ public:
QString toString() const;
private:
+ void forcedClose();
+
QExplicitlySharedDataPointer<SymbianDeviceData> m_data;
};
-QDebug operator<<(QDebug d, const SymbianDevice &);
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDevice &);
inline bool operator==(const SymbianDevice &d1, const SymbianDevice &d2)
{ return d1.compare(d2) == 0; }
@@ -100,13 +123,15 @@ inline bool operator<(const SymbianDevice &d1, const SymbianDevice &d2)
/* SymbianDeviceManager: Singleton that maintains a list of Symbian devices.
* and emits change signals.
- * On Windows, the update slot must be connected to a signal
- * emitted from an event handler listening for WM_DEVICECHANGE. */
+ * On Windows, the update slot must be connected to a [delayed] signal
+ * emitted from an event handler listening for WM_DEVICECHANGE.
+ * Device removal will result in the device being closed. */
class SYMBIANUTILS_EXPORT SymbianDeviceManager : public QObject
{
Q_OBJECT
public:
typedef QList<SymbianDevice> SymbianDeviceList;
+ typedef QSharedPointer<trk::TrkDevice> TrkDevicePtr;
static const char *linuxBlueToothDeviceRootC;
@@ -120,17 +145,25 @@ public:
SymbianDeviceList devices() const;
QString toString() const;
+ // Acquire a device for use. See releaseDevice().
+ TrkDevicePtr acquireDevice(const QString &port);
+
+ int findByPortName(const QString &p) const;
QString friendlyNameForPort(const QString &port) const;
public slots:
void update();
+ // Relase a device, make it available for further use.
+ void releaseDevice(const QString &port);
+ void setAdditionalInformation(const QString &port, const QString &ai);
signals:
- void deviceRemoved(const SymbianDevice &d);
- void deviceAdded(const SymbianDevice &d);
+ void deviceRemoved(const SymbianUtils::SymbianDevice &d);
+ void deviceAdded(const SymbianUtils::SymbianDevice &d);
void updated();
private:
+ void ensureInitialized() const;
void update(bool emitSignals);
SymbianDeviceList serialPorts() const;
SymbianDeviceList blueToothDevices() const;
@@ -138,7 +171,7 @@ private:
SymbianDeviceManagerPrivate *d;
};
-QDebug operator<<(QDebug d, const SymbianDeviceManager &);
+SYMBIANUTILS_EXPORT QDebug operator<<(QDebug d, const SymbianDeviceManager &);
} // namespace SymbianUtils
diff --git a/tools/runonphone/symbianutils/symbianutils.pri b/tools/runonphone/symbianutils/symbianutils.pri
index 6309517..f07e494 100644
--- a/tools/runonphone/symbianutils/symbianutils.pri
+++ b/tools/runonphone/symbianutils/symbianutils.pri
@@ -1,5 +1,7 @@
INCLUDEPATH *= $$PWD
+QT += network
+
# Input
HEADERS += $$PWD/symbianutils_global.h \
$$PWD/callback.h \
@@ -9,14 +11,20 @@ HEADERS += $$PWD/symbianutils_global.h \
$$PWD/launcher.h \
$$PWD/bluetoothlistener.h \
$$PWD/communicationstarter.h \
- $$PWD/symbiandevicemanager.h
+ $$PWD/symbiandevicemanager.h \
+ $$PWD/tcftrkdevice.h \
+ $$PWD/tcftrkmessage.h \
+ $$PWD/json.h
SOURCES += $$PWD/trkutils.cpp \
$$PWD/trkdevice.cpp \
$$PWD/launcher.cpp \
$$PWD/bluetoothlistener.cpp \
$$PWD/communicationstarter.cpp \
- $$PWD/symbiandevicemanager.cpp
+ $$PWD/symbiandevicemanager.cpp \
+ $$PWD/tcftrkdevice.cpp \
+ $$PWD/tcftrkmessage.cpp \
+ $$PWD/json.cpp
# Tests/trklauncher is a console application
contains(QT, gui) {
diff --git a/tools/runonphone/symbianutils/tcftrkdevice.cpp b/tools/runonphone/symbianutils/tcftrkdevice.cpp
new file mode 100644
index 0000000..50e3937
--- /dev/null
+++ b/tools/runonphone/symbianutils/tcftrkdevice.cpp
@@ -0,0 +1,929 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tcftrkdevice.h"
+#include "json.h"
+
+#include <QtNetwork/QAbstractSocket>
+#include <QtCore/QDebug>
+#include <QtCore/QVector>
+#include <QtCore/QQueue>
+#include <QtCore/QTextStream>
+#include <QtCore/QDateTime>
+#include <QtCore/QFileInfo>
+
+enum { debug = 0 };
+
+static const char messageTerminatorC[] = "\003\001";
+
+namespace tcftrk {
+// ------------- TcfTrkCommandError
+
+TcfTrkCommandError::TcfTrkCommandError() : timeMS(0), code(0), alternativeCode(0)
+{
+}
+
+void TcfTrkCommandError::clear()
+{
+ timeMS = 0;
+ code = alternativeCode = 0;
+ format.clear();
+ alternativeOrganization.clear();
+}
+
+void TcfTrkCommandError::write(QTextStream &str) const
+{
+ if (timeMS) {
+ const QDateTime time(QDate(1970, 1, 1));
+ str << time.addMSecs(timeMS).toString(Qt::ISODate) << ": Error code: " << code
+ << " '" << format << '\'';
+ if (!alternativeOrganization.isEmpty())
+ str << " ('" << alternativeOrganization << "', code: " << alternativeCode << ')';
+ } else{
+ str << "<No error>";
+ }
+}
+
+QString TcfTrkCommandError::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ write(str);
+ return rc;
+}
+
+/* {"Time":1277459762255,"Code":1,"AltCode":-6,"AltOrg":"POSIX","Format":"Unknown error: -6"} */
+bool TcfTrkCommandError::parse(const QVector<JsonValue> &values)
+{
+ // Parse an arbitrary hash (that could as well be a command response)
+ // and check for error elements.
+ unsigned errorKeyCount = 0;
+ clear();
+ do {
+ if (values.isEmpty() || values.front().type() != JsonValue::Object)
+ break;
+ foreach (const JsonValue &c, values.front().children()) {
+ if (c.name() == "Time") {
+ timeMS = c.data().toULongLong();
+ errorKeyCount++;
+ } else if (c.name() == "Code") {
+ code = c.data().toInt();
+ errorKeyCount++;
+ } else if (c.name() == "Format") {
+ format = c.data();
+ errorKeyCount++;
+ } else if (c.name() == "AltCode") {
+ alternativeCode = c.data().toInt();
+ errorKeyCount++;
+ } else if (c.name() == "AltOrg") {
+ alternativeOrganization = c.data();
+ errorKeyCount++;
+ }
+ }
+ } while (false);
+ const bool errorFound = errorKeyCount >= 2u; // Should be at least 'Time', 'Code'.
+ if (!errorFound)
+ clear();
+ if (debug) {
+ qDebug() << "TcfTrkCommandError::parse: Found error: " << errorFound;
+ if (!values.isEmpty())
+ qDebug() << values.front().toString();
+ }
+ return errorFound;
+}
+
+// ------------ TcfTrkCommandResult
+
+TcfTrkCommandResult::TcfTrkCommandResult(Type t) :
+ type(t), service(LocatorService)
+{
+}
+
+TcfTrkCommandResult::TcfTrkCommandResult(char typeChar, Services s,
+ const QByteArray &r,
+ const QVector<JsonValue> &v,
+ const QVariant &ck) :
+ type(FailReply), service(s), request(r), values(v), cookie(ck)
+{
+ switch (typeChar) {
+ case 'N':
+ type = FailReply;
+ break;
+ case 'P':
+ type = ProgressReply;
+ break;
+ case 'R':
+ type = commandError.parse(values) ? CommandErrorReply : SuccessReply;
+ break;
+ default:
+ qWarning("Unknown TCF reply type '%c'", typeChar);
+ }
+}
+
+QString TcfTrkCommandResult::errorString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+
+ switch (type) {
+ case SuccessReply:
+ case ProgressReply:
+ str << "<No error>";
+ return rc;
+ case FailReply:
+ str << "NAK";
+ case CommandErrorReply:
+ commandError.write(str);
+ break;
+ }
+ // Append the failed command for reference
+ str << " (Command was: '";
+ QByteArray printableRequest = request;
+ printableRequest.replace('\0', '|');
+ str << printableRequest << "')";
+ return rc;
+}
+
+QString TcfTrkCommandResult::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "Command answer ";
+ switch (type) {
+ case SuccessReply:
+ str << "[success]";
+ break;
+ case CommandErrorReply:
+ str << "[command error]";
+ break;
+ case FailReply:
+ str << "[fail (NAK)]";
+ break;
+ case ProgressReply:
+ str << "[progress]";
+ break;
+ }
+ str << ", " << values.size() << " values(s) to request: '";
+ QByteArray printableRequest = request;
+ printableRequest.replace('\0', '|');
+ str << printableRequest << "' ";
+ if (cookie.isValid())
+ str << " cookie: " << cookie.toString();
+ str << '\n';
+ for (int i = 0, count = values.size(); i < count; i++)
+ str << '#' << i << ' ' << values.at(i).toString() << '\n';
+ if (type == CommandErrorReply)
+ str << "Error: " << errorString();
+ return rc;
+}
+
+struct TcfTrkSendQueueEntry
+{
+ typedef TcfTrkDevice::MessageType MessageType;
+
+ explicit TcfTrkSendQueueEntry(MessageType mt,
+ int tok,
+ Services s,
+ const QByteArray &d,
+ const TcfTrkCallback &cb= TcfTrkCallback(),
+ const QVariant &ck = QVariant()) :
+ messageType(mt), service(s), data(d), token(tok), cookie(ck), callback(cb) {}
+
+ MessageType messageType;
+ Services service;
+ QByteArray data;
+ int token;
+ QVariant cookie;
+ TcfTrkCallback callback;
+};
+
+struct TcfTrkDevicePrivate {
+ typedef TcfTrkDevice::IODevicePtr IODevicePtr;
+ typedef QHash<int, TcfTrkSendQueueEntry> TokenWrittenMessageMap;
+
+ TcfTrkDevicePrivate();
+
+ const QByteArray m_messageTerminator;
+
+ IODevicePtr m_device;
+ unsigned m_verbose;
+ QByteArray m_readBuffer;
+ int m_token;
+ QQueue<TcfTrkSendQueueEntry> m_sendQueue;
+ TokenWrittenMessageMap m_writtenMessages;
+ QVector<QByteArray> m_registerNames;
+};
+
+TcfTrkDevicePrivate::TcfTrkDevicePrivate() :
+ m_messageTerminator(messageTerminatorC),
+ m_verbose(0), m_token(0)
+{
+}
+
+TcfTrkDevice::TcfTrkDevice(QObject *parent) :
+ QObject(parent), d(new TcfTrkDevicePrivate)
+{
+}
+
+TcfTrkDevice::~TcfTrkDevice()
+{
+ delete d;
+}
+
+QVector<QByteArray> TcfTrkDevice::registerNames() const
+{
+ return d->m_registerNames;
+}
+
+void TcfTrkDevice::setRegisterNames(const QVector<QByteArray>& n)
+{
+ d->m_registerNames = n;
+ if (d->m_verbose) {
+ QString msg;
+ QTextStream str(&msg);
+ const int count = n.size();
+ str << "Registers (" << count << "): ";
+ for (int i = 0; i < count; i++)
+ str << '#' << i << '=' << n.at(i) << ' ';
+ emitLogMessage(msg);
+ }
+}
+
+TcfTrkDevice::IODevicePtr TcfTrkDevice::device() const
+{
+ return d->m_device;
+}
+
+TcfTrkDevice::IODevicePtr TcfTrkDevice::takeDevice()
+{
+ const IODevicePtr old = d->m_device;
+ if (!old.isNull()) {
+ old.data()->disconnect(this);
+ d->m_device = IODevicePtr();
+ }
+ d->m_readBuffer.clear();
+ d->m_token = 0;
+ d->m_sendQueue.clear();
+ return old;
+}
+
+void TcfTrkDevice::setDevice(const IODevicePtr &dp)
+{
+ if (dp.data() == d->m_device.data())
+ return;
+ if (dp.isNull()) {
+ emitLogMessage(QLatin1String("Internal error: Attempt to set NULL device."));
+ return;
+ }
+ takeDevice();
+ d->m_device = dp;
+ connect(dp.data(), SIGNAL(readyRead()), this, SLOT(slotDeviceReadyRead()));
+ if (QAbstractSocket *s = qobject_cast<QAbstractSocket *>(dp.data())) {
+ connect(s, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(slotDeviceError()));
+ connect(s, SIGNAL(stateChanged(QAbstractSocket::SocketState)), this, SLOT(slotDeviceSocketStateChanged()));
+ }
+}
+
+void TcfTrkDevice::slotDeviceError()
+{
+ const QString message = d->m_device->errorString();
+ emitLogMessage(message);
+ emit error(message);
+}
+
+void TcfTrkDevice::slotDeviceSocketStateChanged()
+{
+ if (const QAbstractSocket *s = qobject_cast<const QAbstractSocket *>(d->m_device.data())) {
+ const QAbstractSocket::SocketState st = s->state();
+ switch (st) {
+ case QAbstractSocket::UnconnectedState:
+ emitLogMessage(QLatin1String("Unconnected"));
+ break;
+ case QAbstractSocket::HostLookupState:
+ emitLogMessage(QLatin1String("HostLookupState"));
+ break;
+ case QAbstractSocket::ConnectingState:
+ emitLogMessage(QLatin1String("Connecting"));
+ break;
+ case QAbstractSocket::ConnectedState:
+ emitLogMessage(QLatin1String("Connected"));
+ break;
+ case QAbstractSocket::ClosingState:
+ emitLogMessage(QLatin1String("Closing"));
+ break;
+ default:
+ emitLogMessage(QString::fromLatin1("State %1").arg(st));
+ break;
+ }
+ }
+}
+
+static inline QString debugMessage(QByteArray message, const char *prefix = 0)
+{
+ message.replace('\0', '|');
+ const QString messageS = QString::fromLatin1(message);
+ return prefix ?
+ (QLatin1String(prefix) + messageS) : messageS;
+}
+
+void TcfTrkDevice::slotDeviceReadyRead()
+{
+ d->m_readBuffer += d->m_device->readAll();
+ // Take complete message off front of readbuffer.
+ do {
+ const int messageEndPos = d->m_readBuffer.indexOf(d->m_messageTerminator);
+ if (messageEndPos == -1)
+ break;
+ const QByteArray message = d->m_readBuffer.left(messageEndPos);
+ if (debug)
+ qDebug("Read:\n%s", qPrintable(formatData(message)));
+ if (const int errorCode = parseMessage(message)) {
+ emitLogMessage(QString::fromLatin1("Parse error %1 for: %2").arg(errorCode).arg(debugMessage(message)));
+ }
+ d->m_readBuffer.remove(0, messageEndPos + d->m_messageTerminator.size());
+ } while (!d->m_readBuffer.isEmpty());
+ checkSendQueue(); // Send off further message
+}
+
+// Split \0-terminated message into tokens, skipping the initial type character
+static inline QVector<QByteArray> splitMessage(const QByteArray &message)
+{
+ QVector<QByteArray> tokens;
+ tokens.reserve(7);
+ const int messageSize = message.size();
+ for (int pos = 2; pos < messageSize; ) {
+ const int nextPos = message.indexOf('\0', pos);
+ if (nextPos == -1)
+ break;
+ tokens.push_back(message.mid(pos, nextPos - pos));
+ pos = nextPos + 1;
+ }
+ return tokens;
+}
+
+int TcfTrkDevice::parseMessage(const QByteArray &message)
+{
+ if (d->m_verbose)
+ emitLogMessage(debugMessage(message, "TCF ->"));
+ // Special JSON parse error message or protocol format error.
+ // The port is usually closed after receiving it.
+ // "\3\2{"Time":1276096098255,"Code":3,"Format": "Protocol format error"}"
+ if (message.startsWith("\003\002")) {
+ QByteArray text = message.mid(2);
+ const QString errorMessage = QString::fromLatin1("Parse error received: %1").arg(QString::fromAscii(text));
+ emit error(errorMessage);
+ return 0;
+ }
+ if (message.size() < 4 || message.at(1) != '\0')
+ return 1;
+ // Split into tokens
+ const char type = message.at(0);
+ const QVector<QByteArray> tokens = splitMessage(message);
+ switch (type) {
+ case 'E':
+ return parseTcfEvent(tokens);
+ case 'R': // Command replies
+ case 'N':
+ case 'P':
+ return parseTcfCommandReply(type, tokens);
+ default:
+ emitLogMessage(QString::fromLatin1("Unhandled message type: %1").arg(debugMessage(message)));
+ return 756;
+ }
+ return 0;
+}
+
+int TcfTrkDevice::parseTcfCommandReply(char type, const QVector<QByteArray> &tokens)
+{
+ typedef TcfTrkDevicePrivate::TokenWrittenMessageMap::iterator TokenWrittenMessageMapIterator;
+ // Find the corresponding entry in the written messages hash.
+ const int tokenCount = tokens.size();
+ if (tokenCount < 1)
+ return 234;
+ bool tokenOk;
+ const int token = tokens.at(0).toInt(&tokenOk);
+ if (!tokenOk)
+ return 235;
+ const TokenWrittenMessageMapIterator it = d->m_writtenMessages.find(token);
+ if (it == d->m_writtenMessages.end()) {
+ qWarning("TcfTrkDevice: Internal error: token %d not found for '%s'",
+ token, qPrintable(joinByteArrays(tokens)));
+ return 236;
+ }
+ // No callback: remove entry from map, happy
+ if (!it.value().callback) {
+ d->m_writtenMessages.erase(it);
+ return 0;
+ }
+ // Parse values into JSON
+ QVector<JsonValue> values;
+ values.reserve(tokenCount);
+ for (int i = 1; i < tokenCount; i++) {
+ if (!tokens.at(i).isEmpty()) { // Strange: Empty tokens occur.
+ const JsonValue value(tokens.at(i));
+ if (value.isValid()) {
+ values.push_back(value);
+ } else {
+ qWarning("JSON parse error for reply to command token %d: #%d '%s'",
+ token, i, tokens.at(i).constData());
+ d->m_writtenMessages.erase(it);
+ return -1;
+ }
+ }
+ }
+
+ // Construct result and invoke callback, remove entry from map.
+ TcfTrkCallback callback = it.value().callback;
+ TcfTrkCommandResult result(type, it.value().service, it.value().data,
+ values, it.value().cookie);
+ d->m_writtenMessages.erase(it);
+ callback(result);
+ return 0;
+}
+
+static const char locatorAnswerC[] = "E\0Locator\0Hello\0[\"Locator\"]";
+
+int TcfTrkDevice::parseTcfEvent(const QVector<QByteArray> &tokens)
+{
+ // Event: Ignore the periodical heartbeat event, answer 'Hello',
+ // emit signal for the rest
+ if (tokens.size() < 3)
+ return 433;
+ const Services service = serviceFromName(tokens.at(0).constData());
+ if (service == LocatorService && tokens.at(1) == "peerHeartBeat")
+ return 0;
+ QVector<JsonValue> values;
+ for (int i = 2; i < tokens.size(); i++) {
+ const JsonValue value(tokens.at(i));
+ if (!value.isValid())
+ return 434;
+ values.push_back(value);
+ }
+ // Parse known events, emit signals
+ QScopedPointer<TcfTrkEvent> knownEvent(TcfTrkEvent::parseEvent(service, tokens.at(1), values));
+ if (!knownEvent.isNull()) {
+ // Answer hello event.
+ if (knownEvent->type() == TcfTrkEvent::LocatorHello)
+ writeMessage(QByteArray(locatorAnswerC, sizeof(locatorAnswerC)));
+ emit tcfEvent(*knownEvent);
+ }
+ emit genericTcfEvent(service, tokens.at(1), values);
+
+ if (debug || d->m_verbose) {
+ QString msg;
+ QTextStream str(&msg);
+ if (knownEvent.isNull()) {
+ str << "Event: " << tokens.at(0) << ' ' << tokens.at(1) << '\n';
+ foreach(const JsonValue &val, values)
+ str << " " << val.toString() << '\n';
+ } else {
+ str << knownEvent->toString();
+ }
+ emitLogMessage(msg);
+ }
+
+ return 0;
+}
+
+unsigned TcfTrkDevice::verbose() const
+{
+ return d->m_verbose;
+}
+
+void TcfTrkDevice::setVerbose(unsigned v)
+{
+ d->m_verbose = v;
+}
+
+void TcfTrkDevice::emitLogMessage(const QString &m)
+{
+ if (debug)
+ qWarning("%s", qPrintable(m));
+ emit logMessage(m);
+}
+
+bool TcfTrkDevice::checkOpen()
+{
+ if (d->m_device.isNull()) {
+ emitLogMessage(QLatin1String("Internal error: No device set on TcfTrkDevice."));
+ return false;
+ }
+ if (!d->m_device->isOpen()) {
+ emitLogMessage(QLatin1String("Internal error: Device not open in TcfTrkDevice."));
+ return false;
+ }
+ return true;
+}
+
+void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const char *commandParameters, int commandParametersLength,
+ const TcfTrkCallback &callBack,
+ const QVariant &cookie)
+
+{
+ if (!checkOpen())
+ return;
+ // Format the message
+ const int token = d->m_token++;
+ QByteArray data;
+ data.reserve(30 + commandParametersLength);
+ data.append('C');
+ data.append('\0');
+ data.append(QByteArray::number(token));
+ data.append('\0');
+ data.append(serviceName(service));
+ data.append('\0');
+ data.append(command);
+ data.append('\0');
+ if (commandParametersLength)
+ data.append(commandParameters, commandParametersLength);
+ const TcfTrkSendQueueEntry entry(mt, token, service, data, callBack, cookie);
+ d->m_sendQueue.enqueue(entry);
+ checkSendQueue();
+}
+
+void TcfTrkDevice::sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const QByteArray &commandParameters,
+ const TcfTrkCallback &callBack,
+ const QVariant &cookie)
+{
+ sendTcfTrkMessage(mt, service, command, commandParameters.constData(), commandParameters.size(),
+ callBack, cookie);
+}
+
+// Enclose in message frame and write.
+void TcfTrkDevice::writeMessage(QByteArray data)
+{
+ if (!checkOpen())
+ return;
+
+ if (d->m_verbose)
+ emitLogMessage(debugMessage(data, "TCF <-"));
+
+ // Ensure \0-termination which easily gets lost in QByteArray CT.
+ if (!data.endsWith('\0'))
+ data.append('\0');
+ data += d->m_messageTerminator;
+
+ if (debug > 1)
+ qDebug("Writing:\n%s", qPrintable(formatData(data)));
+
+ d->m_device->write(data);
+ if (QAbstractSocket *as = qobject_cast<QAbstractSocket *>(d->m_device.data()))
+ as->flush();
+}
+
+void TcfTrkDevice::checkSendQueue()
+{
+ // Fire off messages or invoke noops until a message with reply is found
+ // and an entry to writtenMessages is made.
+ while (d->m_writtenMessages.empty()) {
+ if (d->m_sendQueue.isEmpty())
+ break;
+ TcfTrkSendQueueEntry entry = d->m_sendQueue.dequeue();
+ switch (entry.messageType) {
+ case MessageWithReply:
+ d->m_writtenMessages.insert(entry.token, entry);
+ writeMessage(entry.data);
+ break;
+ case MessageWithoutReply:
+ writeMessage(entry.data);
+ break;
+ case NoopMessage: // Invoke the noop-callback for synchronization
+ if (entry.callback) {
+ TcfTrkCommandResult noopResult(TcfTrkCommandResult::SuccessReply);
+ noopResult.cookie = entry.cookie;
+ entry.callback(noopResult);
+ }
+ break;
+ }
+ }
+}
+
+// Fix slashes
+static inline QString fixFileName(QString in)
+{
+ in.replace(QLatin1Char('/'), QLatin1Char('\\'));
+ return in;
+}
+
+// Start a process (consisting of a non-reply setSettings and start).
+void TcfTrkDevice::sendProcessStartCommand(const TcfTrkCallback &callBack,
+ const QString &binaryIn,
+ unsigned uid,
+ QStringList arguments,
+ QString workingDirectory,
+ bool debugControl,
+ const QStringList &additionalLibraries,
+ const QVariant &cookie)
+{
+ // Obtain the bin directory, expand by c:/sys/bin if missing
+ const QChar backSlash('\\');
+ int slashPos = binaryIn.lastIndexOf(QLatin1Char('/'));
+ if (slashPos == -1)
+ slashPos = binaryIn.lastIndexOf(backSlash);
+ const QString sysBin = QLatin1String("c:/sys/bin");
+ const QString binaryFileName = slashPos == -1 ? binaryIn : binaryIn.mid(slashPos + 1);
+ const QString binaryDirectory = slashPos == -1 ? sysBin : binaryIn.left(slashPos);
+ const QString binary = fixFileName(binaryDirectory + QLatin1Char('/') + binaryFileName);
+
+ // Fixup: Does argv[0] convention exist on Symbian?
+ arguments.push_front(binary);
+ if (workingDirectory.isEmpty())
+ workingDirectory = sysBin;
+
+ // Format settings with empty dummy parameter
+ QByteArray setData;
+ JsonInputStream setStr(setData);
+ setStr << "" << '\0'
+ << '[' << "exeToLaunch" << ',' << "addExecutables" << ',' << "addLibraries" << ']'
+ << '\0' << '['
+ << binary << ','
+ << '{' << binaryFileName << ':' << QString::number(uid, 16) << '}' << ','
+ << additionalLibraries
+ << ']';
+ sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData);
+
+ QByteArray startData;
+ JsonInputStream startStr(startData);
+ startStr << fixFileName(workingDirectory)
+ << '\0' << binary << '\0' << arguments << '\0'
+ << QStringList() << '\0' // Env is an array ["PATH=value"] (non-standard)
+ << debugControl;
+ sendTcfTrkMessage(MessageWithReply, ProcessesService, "start", startData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendProcessTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, ProcessesService, "terminate", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "terminate", data, callBack, cookie);
+}
+
+// Non-standard: Remove executable from settings
+void TcfTrkDevice::sendSettingsRemoveExecutableCommand(const QString &binaryIn,
+ unsigned uid,
+ const QStringList &additionalLibraries,
+ const QVariant &cookie)
+{
+ QByteArray setData;
+ JsonInputStream setStr(setData);
+ setStr << "" << '\0'
+ << '[' << "removedExecutables" << ',' << "removedLibraries" << ']'
+ << '\0' << '['
+ << '{' << QFileInfo(binaryIn).fileName() << ':' << QString::number(uid, 16) << '}' << ','
+ << additionalLibraries
+ << ']';
+ sendTcfTrkMessage(MessageWithoutReply, SettingsService, "set", setData, TcfTrkCallback(), cookie);
+}
+
+void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ RunControlResumeMode mode,
+ unsigned count,
+ quint64 rangeStart,
+ quint64 rangeEnd,
+ const QVariant &cookie)
+{
+ QByteArray resumeData;
+ JsonInputStream str(resumeData);
+ str << id << '\0' << int(mode) << '\0' << count;
+ switch (mode) {
+ case RM_STEP_OVER_RANGE:
+ case RM_STEP_INTO_RANGE:
+ case RM_REVERSE_STEP_OVER_RANGE:
+ case RM_REVERSE_STEP_INTO_RANGE:
+ str << '\0' << '{' << "RANGE_START" << ':' << rangeStart
+ << ',' << "RANGE_END" << ':' << rangeEnd << '}';
+ break;
+ default:
+ break;
+ }
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "resume", resumeData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlSuspendCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << id;
+ sendTcfTrkMessage(MessageWithReply, RunControlService, "suspend", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ sendRunControlResumeCommand(callBack, id, RM_RESUME, 1, 0, 0, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsAddCommand(const TcfTrkCallback &callBack,
+ const Breakpoint &bp,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << bp;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService, "add", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie)
+{
+ sendBreakpointsRemoveCommand(callBack, QVector<QByteArray>(1, id), cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << ids;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService, "remove", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ bool enable,
+ const QVariant &cookie)
+{
+ sendBreakpointsEnableCommand(callBack, QVector<QByteArray>(1, id), enable, cookie);
+}
+
+void TcfTrkDevice::sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &ids,
+ bool enable,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ str << ids;
+ sendTcfTrkMessage(MessageWithReply, BreakpointsService,
+ enable ? "enable" : "disable",
+ data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendMemorySetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, const QByteArray& data,
+ const QVariant &cookie)
+{
+ QByteArray getData;
+ JsonInputStream str(getData);
+ // start/word size/mode. Mode should ideally be 1 (continue on error?)
+ str << contextId << '\0' << start << '\0' << 1 << '\0' << data.size() << '\0' << 1
+ << '\0' << data.toBase64();
+ sendTcfTrkMessage(MessageWithReply, MemoryService, "set", getData, callBack, cookie);
+}
+
+void TcfTrkDevice::sendMemoryGetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, quint64 size,
+ const QVariant &cookie)
+{
+ QByteArray data;
+ JsonInputStream str(data);
+ // start/word size/mode. Mode should ideally be 1 (continue on error?)
+ str << contextId << '\0' << start << '\0' << 1 << '\0' << size << '\0' << 1;
+ sendTcfTrkMessage(MessageWithReply, MemoryService, "get", data, callBack, cookie);
+}
+
+QByteArray TcfTrkDevice::parseMemoryGet(const TcfTrkCommandResult &r)
+{
+ if (r.type != TcfTrkCommandResult::SuccessReply || r.values.size() < 1)
+ return QByteArray();
+ const JsonValue &memoryV = r.values.front();
+
+ if (memoryV.type() != JsonValue::String || memoryV.data().size() < 2
+ || !memoryV.data().endsWith('='))
+ return QByteArray();
+ // Catch errors reported as hash:
+ // R.4."TlVMTA==".{"Time":1276786871255,"Code":1,"AltCode":-38,"AltOrg":"POSIX","Format":"BadDescriptor"}
+ // Not sure what to make of it.
+ if (r.values.size() >= 2 && r.values.at(1).type() == JsonValue::Object)
+ qWarning("Error retrieving memory: %s", r.values.at(1).toString(false).constData());
+ // decode
+ const QByteArray memory = QByteArray::fromBase64(memoryV.data());
+ if (memory.isEmpty())
+ qWarning("Base64 decoding of %s failed.", memoryV.data().constData());
+ if (debug)
+ qDebug("TcfTrkDevice::parseMemoryGet: received %d bytes", memory.size());
+ return memory;
+}
+
+void TcfTrkDevice::sendRegistersGetMCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie)
+{
+ // TODO: use "Registers" (which uses base64-encoded values)
+ QByteArray data;
+ JsonInputStream str(data);
+ str << contextId << '\0' << ids;
+ sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "get", data, callBack, cookie);
+}
+
+void TcfTrkDevice::sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned start, unsigned count)
+{
+ const unsigned end = start + count;
+ if (end > (unsigned)d->m_registerNames.size()) {
+ qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", end, d->m_registerNames.size());
+ return;
+ }
+
+ QVector<QByteArray> ids;
+ ids.reserve(count);
+ for (unsigned i = start; i < end; i++)
+ ids.push_back(d->m_registerNames.at(i));
+ sendRegistersGetMCommand(callBack, contextId, ids, QVariant(start));
+}
+
+// Set register
+void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QByteArray &id,
+ unsigned value,
+ const QVariant &cookie)
+{
+ // TODO: use "Registers" (which uses base64-encoded values)
+ QByteArray data;
+ JsonInputStream str(data);
+ str << contextId << '\0' << QVector<QByteArray>(1, id)
+ << '\0' << QVector<QByteArray>(1, QByteArray::number(value, 16));
+ sendTcfTrkMessage(MessageWithReply, SimpleRegistersService, "set", data, callBack, cookie);
+}
+
+// Set register
+void TcfTrkDevice::sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned registerNumber,
+ unsigned value,
+ const QVariant &cookie)
+{
+ if (registerNumber >= (unsigned)d->m_registerNames.size()) {
+ qWarning("TcfTrkDevice: No register name set for index %u (size: %d).", registerNumber, d->m_registerNames.size());
+ return;
+ }
+ sendRegistersSetCommand(callBack, contextId,
+ d->m_registerNames[registerNumber],
+ value, cookie);
+}
+
+} // namespace tcftrk
diff --git a/tools/runonphone/symbianutils/tcftrkdevice.h b/tools/runonphone/symbianutils/tcftrkdevice.h
new file mode 100644
index 0000000..f56a86e
--- /dev/null
+++ b/tools/runonphone/symbianutils/tcftrkdevice.h
@@ -0,0 +1,295 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TCFTRKENGINE_H
+#define TCFTRKENGINE_H
+
+#include "symbianutils_global.h"
+#include "tcftrkmessage.h"
+#include "callback.h"
+#include "json.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
+#include <QtCore/QVector>
+#include <QtCore/QVariant>
+#include <QtCore/QStringList>
+
+QT_BEGIN_NAMESPACE
+class QIODevice;
+class QTextStream;
+QT_END_NAMESPACE
+
+namespace tcftrk {
+
+struct TcfTrkDevicePrivate;
+struct Breakpoint;
+
+/* Command error handling in TCF:
+ * 1) 'Severe' errors (JSON format, parameter format): Trk emits a
+ * nonstandard message (\3\2 error parameters) and closes the connection.
+ * 2) Protocol errors: 'N' without error message is returned.
+ * 3) Errors in command execution: 'R' with a TCF error hash is returned
+ * (see TcfTrkCommandError). */
+
+/* Error code return in 'R' reply to command
+ * (see top of 'Services' documentation). */
+struct SYMBIANUTILS_EXPORT TcfTrkCommandError {
+ TcfTrkCommandError();
+ void clear();
+ operator bool() const { return timeMS != 0; }
+ QString toString() const;
+ void write(QTextStream &str) const;
+ bool parse(const QVector<JsonValue> &values);
+
+ quint64 timeMS; // Since 1.1.1970
+ int code;
+ QByteArray format; // message
+ // 'Alternative' meaning, like altOrg="POSIX"/altCode=<some errno>
+ QByteArray alternativeOrganization;
+ int alternativeCode;
+};
+
+/* Answer to a Tcf command passed to the callback. */
+struct SYMBIANUTILS_EXPORT TcfTrkCommandResult {
+ enum Type {
+ SuccessReply, // 'R' and no error -> all happy.
+ CommandErrorReply, // 'R' with TcfTrkCommandError received
+ ProgressReply, // 'P', progress indicator
+ FailReply // 'N' Protocol NAK, severe error
+ };
+
+ explicit TcfTrkCommandResult(Type t = SuccessReply);
+ explicit TcfTrkCommandResult(char typeChar, Services service,
+ const QByteArray &request,
+ const QVector<JsonValue> &values,
+ const QVariant &cookie);
+
+ QString toString() const;
+ QString errorString() const;
+ operator bool() const { return type == SuccessReply || type == ProgressReply; }
+
+ Type type;
+ Services service;
+ QByteArray request;
+ TcfTrkCommandError commandError;
+ QVector<JsonValue> values;
+ QVariant cookie;
+};
+
+typedef trk::Callback<const TcfTrkCommandResult &> TcfTrkCallback;
+
+/* TcfTrkDevice: TCF communication helper using an asynchronous QIODevice
+ * implementing the TCF protocol according to:
+http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Specification.html
+http://dev.eclipse.org/svnroot/dsdp/org.eclipse.tm.tcf/trunk/docs/TCF%20Services.html
+ * Commands can be sent along with callbacks that are passed a
+ * TcfTrkCommandResult and an opaque QVariant cookie. In addition, events are emitted.
+*/
+
+class SYMBIANUTILS_EXPORT TcfTrkDevice : public QObject
+{
+ Q_PROPERTY(unsigned verbose READ verbose WRITE setVerbose)
+ Q_OBJECT
+public:
+ enum MessageType { MessageWithReply,
+ MessageWithoutReply, /* Non-standard: "Settings:set" command does not reply */
+ NoopMessage };
+
+ typedef QSharedPointer<QIODevice> IODevicePtr;
+
+ explicit TcfTrkDevice(QObject *parent = 0);
+ virtual ~TcfTrkDevice();
+
+ unsigned verbose() const;
+
+ // Mapping of register names for indices
+ QVector<QByteArray> registerNames() const;
+ void setRegisterNames(const QVector<QByteArray>& n);
+
+ IODevicePtr device() const;
+ IODevicePtr takeDevice();
+ void setDevice(const IODevicePtr &dp);
+
+ void sendTcfTrkMessage(MessageType mt, Services service,
+ const char *command,
+ const char *commandParameters, int commandParametersLength,
+ const TcfTrkCallback &callBack = TcfTrkCallback(),
+ const QVariant &cookie = QVariant());
+
+ void sendTcfTrkMessage(MessageType mt, Services service, const char *command,
+ const QByteArray &commandParameters,
+ const TcfTrkCallback &callBack = TcfTrkCallback(),
+ const QVariant &cookie = QVariant());
+
+ // Convenience messages: Start a process
+ void sendProcessStartCommand(const TcfTrkCallback &callBack,
+ const QString &binary,
+ unsigned uid,
+ QStringList arguments = QStringList(),
+ QString workingDirectory = QString(),
+ bool debugControl = true,
+ const QStringList &additionalLibraries = QStringList(),
+ const QVariant &cookie = QVariant());
+
+ // Preferred over Processes:Terminate by TCF TRK.
+ void sendRunControlTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendProcessTerminateCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ // Non-standard: Remove executable from settings.
+ // Probably needs to be called after stopping. This command has no response.
+ void sendSettingsRemoveExecutableCommand(const QString &binaryIn,
+ unsigned uid,
+ const QStringList &additionalLibraries = QStringList(),
+ const QVariant &cookie = QVariant());
+
+ void sendRunControlSuspendCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ // Resume / Step (see RunControlResumeMode).
+ void sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ RunControlResumeMode mode,
+ unsigned count /* = 1, currently ignored. */,
+ quint64 rangeStart, quint64 rangeEnd,
+ const QVariant &cookie = QVariant());
+
+ // Convenience to resume a suspended process
+ void sendRunControlResumeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsAddCommand(const TcfTrkCallback &callBack,
+ const Breakpoint &b,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsRemoveCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &id,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QByteArray &id,
+ bool enable,
+ const QVariant &cookie = QVariant());
+
+ void sendBreakpointsEnableCommand(const TcfTrkCallback &callBack,
+ const QVector<QByteArray> &id,
+ bool enable,
+ const QVariant &cookie = QVariant());
+
+
+ void sendMemoryGetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, quint64 size,
+ const QVariant &cookie = QVariant());
+
+ void sendMemorySetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ quint64 start, const QByteArray& data,
+ const QVariant &cookie = QVariant());
+
+ // Reply is an array of hexvalues
+ void sendRegistersGetMCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QVector<QByteArray> &ids,
+ const QVariant &cookie = QVariant());
+
+ // Convenience to get a range of register "R0" .. "R<n>".
+ // Cookie will be an int containing "start".
+ void sendRegistersGetMRangeCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned start, unsigned count);
+
+ // Set register
+ void sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ const QByteArray &ids,
+ unsigned value,
+ const QVariant &cookie = QVariant());
+ // Set register
+ void sendRegistersSetCommand(const TcfTrkCallback &callBack,
+ const QByteArray &contextId,
+ unsigned registerNumber,
+ unsigned value,
+ const QVariant &cookie = QVariant());
+
+ static QByteArray parseMemoryGet(const TcfTrkCommandResult &r);
+
+signals:
+ void genericTcfEvent(int service, const QByteArray &name, const QVector<tcftrk::JsonValue> &value);
+ void tcfEvent(const tcftrk::TcfTrkEvent &knownEvent);
+
+ void logMessage(const QString &);
+ void error(const QString &);
+
+public slots:
+ void setVerbose(unsigned v);
+
+private slots:
+ void slotDeviceError();
+ void slotDeviceSocketStateChanged();
+ void slotDeviceReadyRead();
+
+private:
+ bool checkOpen();
+ void checkSendQueue();
+ void writeMessage(QByteArray data);
+ void emitLogMessage(const QString &);
+ int parseMessage(const QByteArray &);
+ int parseTcfCommandReply(char type, const QVector<QByteArray> &tokens);
+ int parseTcfEvent(const QVector<QByteArray> &tokens);
+
+ TcfTrkDevicePrivate *d;
+};
+
+} // namespace tcftrk
+
+#endif // TCFTRKENGINE_H
diff --git a/tools/runonphone/symbianutils/tcftrkmessage.cpp b/tools/runonphone/symbianutils/tcftrkmessage.cpp
new file mode 100644
index 0000000..06035ab
--- /dev/null
+++ b/tools/runonphone/symbianutils/tcftrkmessage.cpp
@@ -0,0 +1,562 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "tcftrkmessage.h"
+#include "json.h"
+
+#include <QtCore/QString>
+#include <QtCore/QTextStream>
+
+// Names matching the enum
+static const char *serviceNamesC[] =
+{ "Locator", "RunControl", "Processes", "Memory", "Settings", "Breakpoints",
+ "Registers", "SimpleRegisters",
+ "UnknownService"};
+
+namespace tcftrk {
+
+SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep)
+{
+ QString rc;
+ const int count = a.size();
+ for (int i = 0; i < count; i++) {
+ if (i)
+ rc += QLatin1Char(sep);
+ rc += QString::fromUtf8(a.at(i));
+ }
+ return rc;
+}
+
+static inline bool jsonToBool(const JsonValue& js)
+{
+ return js.type() == JsonValue::Boolean && js.data() == "true";
+}
+
+SYMBIANUTILS_EXPORT const char *serviceName(Services s)
+{
+ return serviceNamesC[s];
+}
+
+SYMBIANUTILS_EXPORT Services serviceFromName(const char *n)
+{
+ const int count = sizeof(serviceNamesC)/sizeof(char *);
+ for (int i = 0; i < count; i++)
+ if (!qstrcmp(serviceNamesC[i], n))
+ return static_cast<Services>(i);
+ return UnknownService;
+}
+
+SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a)
+{
+ const int columns = 16;
+ QString rc;
+ QTextStream str(&rc);
+ str.setIntegerBase(16);
+ str.setPadChar(QLatin1Char('0'));
+ const unsigned char *start = reinterpret_cast<const unsigned char *>(a.constData());
+ const unsigned char *end = start + a.size();
+ for (const unsigned char *p = start; p < end ; ) {
+ str << "0x";
+ str.setFieldWidth(4);
+ str << (p - start);
+ str.setFieldWidth(0);
+ str << ' ';
+ QString asc;
+ int c = 0;
+ for ( ; c < columns && p < end; c++, p++) {
+ const unsigned u = *p;
+ str.setFieldWidth(2);
+ str << u;
+ str.setFieldWidth(0);
+ str << ' ';
+ switch (u) {
+ case '\n':
+ asc += QLatin1String("\\n");
+ break;
+ case '\r':
+ asc += QLatin1String("\\r");
+ break;
+ case '\t':
+ asc += QLatin1String("\\t");
+ break;
+ default:
+ if (u >= 32 && u < 128) {
+ asc += QLatin1Char(' ');
+ asc += QLatin1Char(u);
+ } else {
+ asc += QLatin1String(" .");
+ }
+ break;
+ }
+ }
+ if (const int remainder = columns - c)
+ str << QString(3 * remainder, QLatin1Char(' '));
+ str << ' ' << asc << '\n';
+ }
+ return rc;
+}
+
+// ----------- RunControlContext
+RunControlContext::RunControlContext() :
+ flags(0), resumeFlags(0)
+{
+}
+
+void RunControlContext::clear()
+{
+ flags =0;
+ resumeFlags = 0;
+ id.clear();
+ osid.clear();
+ parentId.clear();
+}
+
+RunControlContext::Type RunControlContext::typeFromTcfId(const QByteArray &id)
+{
+ // "p12" or "p12.t34"?
+ return id.contains(".t") ? Thread : Process;
+}
+
+unsigned RunControlContext::processId() const
+{
+ return processIdFromTcdfId(id);
+}
+
+unsigned RunControlContext::threadId() const
+{
+ return threadIdFromTcdfId(id);
+}
+
+unsigned RunControlContext::processIdFromTcdfId(const QByteArray &id)
+{
+ // Cut out process id from "p12" or "p12.t34"?
+ if (!id.startsWith('p'))
+ return 0;
+ const int dotPos = id.indexOf('.');
+ const int pLen = dotPos == -1 ? id.size() : dotPos;
+ return id.mid(1, pLen - 1).toUInt();
+}
+
+unsigned RunControlContext::threadIdFromTcdfId(const QByteArray &id)
+{
+ const int tPos = id.indexOf(".t");
+ return tPos != -1 ? id.mid(tPos + 2).toUInt() : uint(0);
+}
+
+QByteArray RunControlContext::tcfId(unsigned processId, unsigned threadId /* = 0 */)
+{
+ QByteArray rc("p");
+ rc += QByteArray::number(processId);
+ if (threadId) {
+ rc += ".t";
+ rc += QByteArray::number(threadId);
+ }
+ return rc;
+}
+
+RunControlContext::Type RunControlContext::type() const
+{
+ return RunControlContext::typeFromTcfId(id);
+}
+
+bool RunControlContext::parse(const JsonValue &val)
+{
+ clear();
+ if (val.type() != JsonValue::Object)
+ return false;
+ foreach(const JsonValue &c, val.children()) {
+ if (c.name() == "ID") {
+ id = c.data();
+ } else if (c.name() == "OSID") {
+ osid = c.data();
+ } else if (c.name() == "ParentID") {
+ parentId = c.data();
+ } else if (c.name() == "IsContainer") {
+ if (jsonToBool(c))
+ flags |= Container;
+ } else if (c.name() == "CanTerminate") {
+ if (jsonToBool(c))
+ flags |= CanTerminate;
+ } else if (c.name() == "CanResume") {
+ resumeFlags = c.data().toUInt();
+ } else if (c.name() == "HasState") {
+ if (jsonToBool(c))
+ flags |= HasState;
+ } else if (c.name() == "CanSuspend") {
+ if (jsonToBool(c))
+ flags |= CanSuspend;
+ }
+ }
+ return true;
+}
+
+QString RunControlContext::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ format(str);
+ return rc;
+}
+
+void RunControlContext::format(QTextStream &str) const
+{
+ str << " id='" << id << "' osid='" << osid
+ << "' parentId='" << parentId <<"' ";
+ if (flags & Container)
+ str << "[container] ";
+ if (flags & HasState)
+ str << "[has state] ";
+ if (flags & CanSuspend)
+ str << "[can suspend] ";
+ if (flags & CanSuspend)
+ str << "[can terminate] ";
+ str.setIntegerBase(16);
+ str << " resume_flags: 0x" << resumeFlags;
+ str.setIntegerBase(10);
+}
+
+// ------ ModuleLoadEventInfo
+ModuleLoadEventInfo::ModuleLoadEventInfo() :
+ loaded(false), codeAddress(0), dataAddress(0), requireResume(false)
+{
+}
+
+void ModuleLoadEventInfo::clear()
+{
+ loaded = requireResume = false;
+ codeAddress = dataAddress =0;
+}
+
+bool ModuleLoadEventInfo::parse(const JsonValue &val)
+{
+ clear();
+ if (val.type() != JsonValue::Object)
+ return false;
+ foreach(const JsonValue &c, val.children()) {
+ if (c.name() == "Name") {
+ name = c.data();
+ } else if (c.name() == "File") {
+ file = c.data();
+ } else if (c.name() == "CodeAddress") {
+ codeAddress = c.data().toULongLong();
+ } else if (c.name() == "DataAddress") {
+ dataAddress = c.data().toULongLong();
+ } else if (c.name() == "Loaded") {
+ loaded = jsonToBool(c);
+ } else if (c.name() == "RequireResume") {
+ requireResume =jsonToBool(c);
+ }
+ }
+ return true;
+}
+void ModuleLoadEventInfo::format(QTextStream &str) const
+{
+ str << "name='" << name << "' file='" << file << "' " <<
+ (loaded ? "[loaded] " : "[not loaded] ");
+ if (requireResume)
+ str << "[requires resume] ";
+ str.setIntegerBase(16);
+ str << " code: 0x" << codeAddress << " data: 0x" << dataAddress;
+ str.setIntegerBase(10);
+}
+
+// ---------------------- Breakpoint
+
+// Types matching enum
+static const char *breakPointTypesC[] = {"Software", "Hardware", "Auto"};
+
+Breakpoint::Breakpoint(quint64 loc) :
+ type(Auto), enabled(true), ignoreCount(0), location(loc), size(1), thumb(true)
+{
+ if (loc)
+ id = idFromLocation(location);
+}
+
+void Breakpoint::setContextId(unsigned processId, unsigned threadId)
+{
+ contextIds = QVector<QByteArray>(1, RunControlContext::tcfId(processId, threadId));
+}
+
+QByteArray Breakpoint::idFromLocation(quint64 loc)
+{
+ return QByteArray("BP_0x") + QByteArray::number(loc, 16);
+}
+
+QString Breakpoint::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str.setIntegerBase(16);
+ str << "Breakpoint '" << id << "' " << breakPointTypesC[type] << " for contexts '"
+ << joinByteArrays(contextIds, ',') << "' at 0x" << location;
+ str.setIntegerBase(10);
+ str << " size " << size;
+ if (enabled)
+ str << " [enabled]";
+ if (thumb)
+ str << " [thumb]";
+ if (ignoreCount)
+ str << " IgnoreCount " << ignoreCount;
+ return rc;
+}
+
+JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b)
+{
+ if (b.contextIds.isEmpty())
+ qWarning("tcftrk::Breakpoint: No context ids specified");
+
+ str << '{' << "ID" << ':' << QString::fromUtf8(b.id) << ','
+ << "BreakpointType" << ':' << breakPointTypesC[b.type] << ','
+ << "Enabled" << ':' << b.enabled << ','
+ << "IgnoreCount" << ':' << b.ignoreCount << ','
+ << "ContextIds" << ':' << b.contextIds << ','
+ << "Location" << ':' << QString::number(b.location) << ','
+ << "Size" << ':' << b.size << ','
+ << "THUMB_BREAKPOINT" << ':' << b.thumb
+ << '}';
+ return str;
+}
+
+// --- Events
+TcfTrkEvent::TcfTrkEvent(Type type) : m_type(type)
+{
+}
+
+TcfTrkEvent::~TcfTrkEvent()
+{
+}
+
+TcfTrkEvent::Type TcfTrkEvent::type() const
+{
+ return m_type;
+}
+
+QString TcfTrkEvent::toString() const
+{
+ return QString();
+}
+
+static const char sharedLibrarySuspendReasonC[] = "Shared Library";
+
+TcfTrkEvent *TcfTrkEvent::parseEvent(Services s, const QByteArray &nameBA, const QVector<JsonValue> &values)
+{
+ switch (s) {
+ case LocatorService:
+ if (nameBA == "Hello" && values.size() == 1 && values.front().type() == JsonValue::Array) {
+ QStringList services;
+ foreach (const JsonValue &jv, values.front().children())
+ services.push_back(QString::fromUtf8(jv.data()));
+ return new TcfTrkLocatorHelloEvent(services);
+ }
+ break;
+ case RunControlService:
+ if (values.empty())
+ return 0;
+ // "id/PC/Reason/Data"
+ if (nameBA == "contextSuspended" && values.size() == 4) {
+ const QByteArray idBA = values.at(0).data();
+ const quint64 pc = values.at(1).data().toULongLong();
+ const QByteArray reasonBA = values.at(2).data();
+ // Module load: Special
+ if (reasonBA == sharedLibrarySuspendReasonC) {
+ ModuleLoadEventInfo info;
+ if (!info.parse(values.at(3)))
+ return 0;
+ return new TcfTrkRunControlModuleLoadContextSuspendedEvent(idBA, reasonBA, pc, info);
+ }
+ return new TcfTrkRunControlContextSuspendedEvent(idBA, reasonBA, pc);
+ } // "contextSuspended"
+ if (nameBA == "contextAdded")
+ return TcfTrkRunControlContextAddedEvent::parseEvent(values);
+ if (nameBA == "contextRemoved" && values.front().type() == JsonValue::Array) {
+ QVector<QByteArray> ids;
+ foreach(const JsonValue &c, values.front().children())
+ ids.push_back(c.data());
+ return new TcfTrkRunControlContextRemovedEvent(ids);
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+// -------------- TcfTrkServiceHelloEvent
+TcfTrkLocatorHelloEvent::TcfTrkLocatorHelloEvent(const QStringList &s) :
+ TcfTrkEvent(LocatorHello),
+ m_services(s)
+{
+}
+
+QString TcfTrkLocatorHelloEvent::toString() const
+{
+ return QLatin1String("ServiceHello: ") + m_services.join(QLatin1String(", "));
+}
+
+// -------------- TcfTrkIdEvent
+TcfTrkIdEvent::TcfTrkIdEvent(Type t, const QByteArray &id) :
+ TcfTrkEvent(t), m_id(id)
+{
+}
+
+// ---------- TcfTrkIdsEvent
+TcfTrkIdsEvent::TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids) :
+ TcfTrkEvent(t), m_ids(ids)
+{
+}
+
+QString TcfTrkIdsEvent::joinedIdString(const char sep) const
+{
+ return joinByteArrays(m_ids, sep);
+}
+
+// ---------------- TcfTrkRunControlContextAddedEvent
+TcfTrkRunControlContextAddedEvent::TcfTrkRunControlContextAddedEvent(const RunControlContexts &c) :
+ TcfTrkEvent(RunControlContextAdded), m_contexts(c)
+{
+}
+
+TcfTrkRunControlContextAddedEvent
+ *TcfTrkRunControlContextAddedEvent::parseEvent(const QVector<JsonValue> &values)
+{
+ // Parse array of contexts
+ if (values.size() < 1 || values.front().type() != JsonValue::Array)
+ return 0;
+
+ RunControlContexts contexts;
+ foreach (const JsonValue &v, values.front().children()) {
+ RunControlContext context;
+ if (context.parse(v))
+ contexts.push_back(context);
+ }
+ return new TcfTrkRunControlContextAddedEvent(contexts);
+}
+
+QString TcfTrkRunControlContextAddedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "RunControl: " << m_contexts.size() << " context(s) "
+ << (type() == RunControlContextAdded ? "added" : "removed")
+ << '\n';
+ foreach (const RunControlContext &c, m_contexts) {
+ c.format(str);
+ str << '\n';
+ }
+ return rc;
+}
+
+// --------------- TcfTrkRunControlContextRemovedEvent
+TcfTrkRunControlContextRemovedEvent::TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &ids) :
+ TcfTrkIdsEvent(RunControlContextRemoved, ids)
+{
+}
+
+QString TcfTrkRunControlContextRemovedEvent::toString() const
+{
+ return QLatin1String("RunControl: Removed contexts '") + joinedIdString() + ("'.");
+}
+
+// --------------- TcfTrkRunControlContextSuspendedEvent
+TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc) :
+ TcfTrkIdEvent(RunControlSuspended, id), m_pc(pc), m_reason(reason)
+{
+}
+
+TcfTrkRunControlContextSuspendedEvent::TcfTrkRunControlContextSuspendedEvent(Type t,
+ const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc) :
+ TcfTrkIdEvent(t, id), m_pc(pc), m_reason(reason)
+{
+}
+
+void TcfTrkRunControlContextSuspendedEvent::format(QTextStream &str) const
+{
+ str.setIntegerBase(16);
+ str << "RunControl: '" << idString() << "' suspended at 0x"
+ << m_pc << ": '" << m_reason << "'.";
+ str.setIntegerBase(10);
+}
+
+QString TcfTrkRunControlContextSuspendedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ format(str);
+ return rc;
+}
+
+TcfTrkRunControlContextSuspendedEvent::Reason TcfTrkRunControlContextSuspendedEvent::reason() const
+{
+ if (m_reason == sharedLibrarySuspendReasonC)
+ return ModuleLoad;
+ if (m_reason == "Breakpoint")
+ return BreakPoint;
+ // 'Data abort exception'/'Thread has panicked' ... unfortunately somewhat unspecific.
+ if (m_reason.contains("exception") || m_reason.contains("panick"))
+ return Crash;
+ return Other;
+}
+
+TcfTrkRunControlModuleLoadContextSuspendedEvent::TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc,
+ const ModuleLoadEventInfo &mi) :
+ TcfTrkRunControlContextSuspendedEvent(RunControlModuleLoadSuspended, id, reason, pc),
+ m_mi(mi)
+{
+}
+
+QString TcfTrkRunControlModuleLoadContextSuspendedEvent::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ TcfTrkRunControlContextSuspendedEvent::format(str);
+ str << ' ';
+ m_mi.format(str);
+ return rc;
+}
+
+
+} // namespace tcftrk
diff --git a/tools/runonphone/symbianutils/tcftrkmessage.h b/tools/runonphone/symbianutils/tcftrkmessage.h
new file mode 100644
index 0000000..929a9e6
--- /dev/null
+++ b/tools/runonphone/symbianutils/tcftrkmessage.h
@@ -0,0 +1,296 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the tools applications 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 Technology Preview License Agreement accompanying
+** this package.
+**
+** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef TRCFTRKMESSAGE_H
+#define TRCFTRKMESSAGE_H
+
+#include "symbianutils_global.h"
+
+#include <QtCore/QStringList>
+#include <QtCore/QVector>
+
+QT_BEGIN_NAMESPACE
+class QTextStream;
+QT_END_NAMESPACE
+
+namespace tcftrk {
+
+class JsonValue;
+class JsonInputStream;
+
+enum Services {
+ LocatorService,
+ RunControlService,
+ ProcessesService,
+ MemoryService,
+ SettingsService, // non-standard, trk specific
+ BreakpointsService,
+ RegistersService,
+ SimpleRegistersService, // non-standard, trk specific
+ UnknownService
+}; // Note: Check string array 'serviceNamesC' of same size when modifying this.
+
+// Modes of RunControl/'Resume' (see EDF documentation).
+// As of 24.6.2010, RM_RESUME, RM_STEP_OVER, RM_STEP_INTO,
+// RM_STEP_OVER_RANGE, RM_STEP_INTO_RANGE are supported with
+// RANG_START/RANGE_END parameters.
+enum RunControlResumeMode {
+ RM_RESUME = 0,
+ RM_STEP_OVER = 1, RM_STEP_INTO = 2,
+ RM_STEP_OVER_LINE = 3, RM_STEP_INTO_LINE = 4,
+ RM_STEP_OUT = 5, RM_REVERSE_RESUME = 6,
+ RM_REVERSE_STEP_OVER = 7, RM_REVERSE_STEP_INTO = 8,
+ RM_REVERSE_STEP_OVER_LINE = 9, RM_REVERSE_STEP_INTO_LINE = 10,
+ RM_REVERSE_STEP_OUT = 11, RM_STEP_OVER_RANGE = 12,
+ RM_STEP_INTO_RANGE = 13, RM_REVERSE_STEP_OVER_RANGE = 14,
+ RM_REVERSE_STEP_INTO_RANGE = 15
+};
+
+SYMBIANUTILS_EXPORT const char *serviceName(Services s);
+SYMBIANUTILS_EXPORT Services serviceFromName(const char *);
+
+// Debug helpers
+SYMBIANUTILS_EXPORT QString formatData(const QByteArray &a);
+SYMBIANUTILS_EXPORT QString joinByteArrays(const QVector<QByteArray> &a, char sep = ',');
+
+// Context used in 'RunControl contextAdded' events and in reply
+// to 'Processes start'. Could be thread or process.
+struct SYMBIANUTILS_EXPORT RunControlContext {
+ enum Flags {
+ Container = 0x1, HasState = 0x2, CanSuspend = 0x4,
+ CanTerminate = 0x8
+ };
+ enum Type { Process, Thread };
+
+ RunControlContext();
+ Type type() const;
+ unsigned processId() const;
+ unsigned threadId() const;
+
+ void clear();
+ bool parse(const JsonValue &v);
+ void format(QTextStream &str) const;
+ QString toString() const;
+
+ // Helper for converting the TCF ids ("p12" or "p12.t34")
+ static Type typeFromTcfId(const QByteArray &id);
+ static unsigned processIdFromTcdfId(const QByteArray &id);
+ static unsigned threadIdFromTcdfId(const QByteArray &id);
+ static QByteArray tcfId(unsigned processId, unsigned threadId = 0);
+
+ unsigned flags;
+ unsigned resumeFlags;
+ QByteArray id; // "p434.t699"
+ QByteArray osid; // Non-standard: Process or thread id
+ QByteArray parentId; // Parent process id of a thread.
+};
+
+// Module load information occurring with 'RunControl contextSuspended' events
+struct SYMBIANUTILS_EXPORT ModuleLoadEventInfo {
+ ModuleLoadEventInfo();
+ void clear();
+ bool parse(const JsonValue &v);
+ void format(QTextStream &str) const;
+
+ QByteArray name;
+ QByteArray file;
+ bool loaded;
+ quint64 codeAddress;
+ quint64 dataAddress;
+ bool requireResume;
+};
+
+// Breakpoint as supported by TcfTrk source June 2010
+// TODO: Add watchpoints,etc once they are implemented
+struct SYMBIANUTILS_EXPORT Breakpoint {
+ enum Type { Software, Hardware, Auto };
+
+ explicit Breakpoint(quint64 loc = 0);
+ void setContextId(unsigned processId, unsigned threadId = 0);
+ QString toString() const;
+
+ static QByteArray idFromLocation(quint64 loc); // Automagically determine from location
+
+ Type type;
+ bool enabled;
+ int ignoreCount;
+ QVector<QByteArray> contextIds; // Process or thread ids.
+ QByteArray id; // Id of the breakpoint;
+ quint64 location;
+ unsigned size;
+ bool thumb;
+};
+
+SYMBIANUTILS_EXPORT JsonInputStream &operator<<(JsonInputStream &str, const Breakpoint &b);
+
+// Event hierarchy
+class SYMBIANUTILS_EXPORT TcfTrkEvent {
+ Q_DISABLE_COPY(TcfTrkEvent)
+public:
+ enum Type { None,
+ LocatorHello,
+ RunControlContextAdded,
+ RunControlContextRemoved,
+ RunControlSuspended,
+ RunControlBreakpointSuspended,
+ RunControlModuleLoadSuspended,
+ RunControlResumed
+ };
+
+ virtual ~TcfTrkEvent();
+
+ Type type() const;
+ virtual QString toString() const;
+
+ static TcfTrkEvent *parseEvent(Services s, const QByteArray &name, const QVector<JsonValue> &val);
+
+protected:
+ explicit TcfTrkEvent(Type type = None);
+
+private:
+ const Type m_type;
+};
+
+// ServiceHello
+class SYMBIANUTILS_EXPORT TcfTrkLocatorHelloEvent : public TcfTrkEvent {
+public:
+ explicit TcfTrkLocatorHelloEvent(const QStringList &);
+
+ const QStringList &services() { return m_services; }
+ virtual QString toString() const;
+
+private:
+ QStringList m_services;
+};
+
+// Base for events that just have one id as parameter
+// (simple suspend)
+class SYMBIANUTILS_EXPORT TcfTrkIdEvent : public TcfTrkEvent {
+protected:
+ explicit TcfTrkIdEvent(Type t, const QByteArray &id);
+public:
+ QByteArray id() const { return m_id; }
+ QString idString() const { return QString::fromUtf8(m_id); }
+
+private:
+ const QByteArray m_id;
+};
+
+// Base for events that just have some ids as parameter
+// (context removed)
+class SYMBIANUTILS_EXPORT TcfTrkIdsEvent : public TcfTrkEvent {
+protected:
+ explicit TcfTrkIdsEvent(Type t, const QVector<QByteArray> &ids);
+
+public:
+ QVector<QByteArray> ids() const { return m_ids; }
+ QString joinedIdString(const char sep = ',') const;
+
+private:
+ const QVector<QByteArray> m_ids;
+};
+
+// RunControlContextAdded
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextAddedEvent : public TcfTrkEvent {
+public:
+ typedef QVector<RunControlContext> RunControlContexts;
+
+ explicit TcfTrkRunControlContextAddedEvent(const RunControlContexts &c);
+
+ const RunControlContexts &contexts() const { return m_contexts; }
+ virtual QString toString() const;
+
+ static TcfTrkRunControlContextAddedEvent *parseEvent(const QVector<JsonValue> &val);
+
+private:
+ const RunControlContexts m_contexts;
+};
+
+// RunControlContextRemoved
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextRemovedEvent : public TcfTrkIdsEvent {
+public:
+ explicit TcfTrkRunControlContextRemovedEvent(const QVector<QByteArray> &id);
+ virtual QString toString() const;
+};
+
+// Simple RunControlContextSuspended (process/thread)
+class SYMBIANUTILS_EXPORT TcfTrkRunControlContextSuspendedEvent : public TcfTrkIdEvent {
+public:
+ enum Reason { BreakPoint, ModuleLoad, Crash, Other } ;
+
+ explicit TcfTrkRunControlContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc = 0);
+ virtual QString toString() const;
+
+ quint64 pc() const { return m_pc; }
+ QByteArray reasonID() const { return m_reason; }
+ Reason reason() const;
+
+protected:
+ explicit TcfTrkRunControlContextSuspendedEvent(Type t,
+ const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc = 0);
+ void format(QTextStream &str) const;
+
+private:
+ const quint64 m_pc;
+ const QByteArray m_reason;
+};
+
+// RunControlContextSuspended due to module load
+class SYMBIANUTILS_EXPORT TcfTrkRunControlModuleLoadContextSuspendedEvent : public TcfTrkRunControlContextSuspendedEvent {
+public:
+ explicit TcfTrkRunControlModuleLoadContextSuspendedEvent(const QByteArray &id,
+ const QByteArray &reason,
+ quint64 pc,
+ const ModuleLoadEventInfo &mi);
+
+ virtual QString toString() const;
+ const ModuleLoadEventInfo &info() const { return m_mi; }
+
+private:
+ const ModuleLoadEventInfo m_mi;
+};
+
+} // namespace tcftrk
+#endif // TRCFTRKMESSAGE_H
diff --git a/tools/runonphone/symbianutils/trkdevice.cpp b/tools/runonphone/symbianutils/trkdevice.cpp
index b327ab3..9039184 100644
--- a/tools/runonphone/symbianutils/trkdevice.cpp
+++ b/tools/runonphone/symbianutils/trkdevice.cpp
@@ -52,6 +52,7 @@
#include <QtCore/QMutex>
#include <QtCore/QWaitCondition>
#include <QtCore/QSharedPointer>
+#include <QtCore/QScopedPointer>
#include <QtCore/QMetaType>
#ifdef Q_OS_WIN
@@ -102,6 +103,11 @@ QString winErrorMessage(unsigned long error)
enum { verboseTrk = 0 };
+static inline QString msgAccessingClosedDevice(const QString &msg)
+{
+ return QString::fromLatin1("Error: Attempt to access device '%1', which is closed.").arg(msg);
+}
+
namespace trk {
///////////////////////////////////////////////////////////////////////
@@ -155,10 +161,11 @@ namespace trk {
///////////////////////////////////////////////////////////////////////
class TrkWriteQueue
-{
+{
Q_DISABLE_COPY(TrkWriteQueue)
public:
explicit TrkWriteQueue();
+ void clear();
// Enqueue messages.
void queueTrkMessage(byte code, TrkCallback callback,
@@ -208,13 +215,24 @@ TrkWriteQueue::TrkWriteQueue() :
{
}
+void TrkWriteQueue::clear()
+{
+ m_trkWriteToken = 0;
+ m_trkWriteBusy = false;
+ m_trkWriteQueue.clear();
+ const int discarded = m_writtenTrkMessages.size();
+ m_writtenTrkMessages.clear();
+ if (verboseTrk)
+ qDebug() << "TrkWriteQueue::clear: discarded " << discarded;
+}
+
byte TrkWriteQueue::nextTrkWriteToken()
{
++m_trkWriteToken;
if (m_trkWriteToken == 0)
++m_trkWriteToken;
if (verboseTrk)
- qDebug() << "Write token: " << m_trkWriteToken;
+ qDebug() << "nextTrkWriteToken:" << m_trkWriteToken;
return m_trkWriteToken;
}
@@ -349,7 +367,7 @@ class WriterThread : public QThread
{
Q_OBJECT
Q_DISABLE_COPY(WriterThread)
-public:
+public:
explicit WriterThread(const QSharedPointer<DeviceContext> &context);
// Enqueue messages.
@@ -357,6 +375,8 @@ public:
const QByteArray &data, const QVariant &cookie);
void queueTrkInitialPing();
+ void clearWriteQueue();
+
// Call this from the device read notification with the results.
void slotHandleResult(const TrkResult &result);
@@ -374,7 +394,7 @@ public slots:
private slots:
void invokeNoopMessage(const trk::TrkMessage &);
-private:
+private:
bool write(const QByteArray &data, QString *errorMessage);
inline int writePendingMessage();
@@ -462,6 +482,7 @@ void WriterThread::terminate()
m_waitCondition.wakeAll();
wait();
m_terminate = false;
+ m_queue.clear();
}
#ifdef Q_OS_WIN
@@ -561,6 +582,13 @@ void WriterThread::queueTrkMessage(byte code, TrkCallback callback,
tryWrite();
}
+void WriterThread::clearWriteQueue()
+{
+ m_dataMutex.lock();
+ m_queue.clear();
+ m_dataMutex.unlock();
+}
+
void WriterThread::queueTrkInitialPing()
{
m_dataMutex.lock();
@@ -592,6 +620,8 @@ class ReaderThreadBase : public QThread
Q_DISABLE_COPY(ReaderThreadBase)
public:
+ int bytesPending() const { return m_trkReadBuffer.size(); }
+
signals:
void messageReceived(const trk::TrkResult &result, const QByteArray &rawData);
@@ -606,10 +636,11 @@ private:
void readMessages();
QByteArray m_trkReadBuffer;
+ bool linkEstablishmentMode;
};
ReaderThreadBase::ReaderThreadBase(const QSharedPointer<DeviceContext> &context) :
- m_context(context)
+ m_context(context), linkEstablishmentMode(true)
{
static const int trkResultMetaId = qRegisterMetaType<trk::TrkResult>();
Q_UNUSED(trkResultMetaId)
@@ -632,7 +663,7 @@ void ReaderThreadBase::readMessages()
{
TrkResult r;
QByteArray rawData;
- while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, &rawData)) {
+ while (extractResult(&m_trkReadBuffer, m_context->serialFrame, &r, linkEstablishmentMode, &rawData)) {
emit messageReceived(r, rawData);
}
}
@@ -692,7 +723,7 @@ int WinReaderThread::tryRead()
if (!ClearCommError(m_context->device, NULL, &comStat)){
emit error(QString::fromLatin1("ClearCommError failed: %1").arg(winErrorMessage(GetLastError())));
return -7;
- }
+ }
const DWORD bytesToRead = qMax(DWORD(1), qMin(comStat.cbInQue, DWORD(BufSize)));
// Trigger read
DWORD bytesRead = 0;
@@ -708,7 +739,7 @@ int WinReaderThread::tryRead()
if (readError != ERROR_IO_PENDING) {
emit error(QString::fromLatin1("Read error: %1").arg(winErrorMessage(readError)));
return -1;
- }
+ }
// Wait for either termination or data
const DWORD wr = WaitForMultipleObjects(HandleCount, m_handles, false, INFINITE);
if (wr == WAIT_FAILED) {
@@ -783,7 +814,7 @@ private:
int m_terminatePipeFileDescriptors[2];
};
-UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) :
+UnixReaderThread::UnixReaderThread(const QSharedPointer<DeviceContext> &context) :
ReaderThreadBase(context)
{
m_terminatePipeFileDescriptors[0] = m_terminatePipeFileDescriptors[1] = -1;
@@ -877,8 +908,8 @@ struct TrkDevicePrivate
TrkDevicePrivate();
QSharedPointer<DeviceContext> deviceContext;
- QSharedPointer<WriterThread> writerThread;
- QSharedPointer<ReaderThread> readerThread;
+ QScopedPointer<WriterThread> writerThread;
+ QScopedPointer<ReaderThread> readerThread;
QByteArray trkReadBuffer;
int verbose;
@@ -917,14 +948,14 @@ TrkDevice::~TrkDevice()
bool TrkDevice::open(QString *errorMessage)
{
- if (d->verbose)
+ if (d->verbose || verboseTrk)
qDebug() << "Opening" << port() << "is open: " << isOpen() << " serialFrame=" << serialFrame();
+ if (isOpen())
+ return true;
if (d->port.isEmpty()) {
*errorMessage = QLatin1String("Internal error: No port set on TrkDevice");
return false;
}
-
- close();
#ifdef Q_OS_WIN
const QString fullPort = QLatin1String("\\\\.\\") + d->port;
d->deviceContext->device = CreateFile(reinterpret_cast<const WCHAR*>(fullPort.utf16()),
@@ -975,7 +1006,7 @@ bool TrkDevice::open(QString *errorMessage)
return false;
}
#endif
- d->readerThread = QSharedPointer<ReaderThread>(new ReaderThread(d->deviceContext));
+ d->readerThread.reset(new ReaderThread(d->deviceContext));
connect(d->readerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)),
Qt::QueuedConnection);
connect(d->readerThread.data(), SIGNAL(messageReceived(trk::TrkResult,QByteArray)),
@@ -983,18 +1014,22 @@ bool TrkDevice::open(QString *errorMessage)
Qt::QueuedConnection);
d->readerThread->start();
- d->writerThread = QSharedPointer<WriterThread>(new WriterThread(d->deviceContext));
+ d->writerThread.reset(new WriterThread(d->deviceContext));
connect(d->writerThread.data(), SIGNAL(error(QString)), this, SLOT(emitError(QString)),
- Qt::QueuedConnection);
- d->writerThread->start();
+ Qt::QueuedConnection);
+ d->writerThread->start();
- if (d->verbose)
- qDebug() << "Opened" << d->port;
+ if (d->verbose || verboseTrk)
+ qDebug() << "Opened" << d->port << d->readerThread.data() << d->writerThread.data();
return true;
}
void TrkDevice::close()
{
+ if (verboseTrk)
+ qDebug() << "close" << d->port << " is open: " << isOpen()
+ << " read pending " << (d->readerThread.isNull() ? 0 : d->readerThread->bytesPending())
+ << sender();
if (!isOpen())
return;
if (d->readerThread)
@@ -1010,6 +1045,7 @@ void TrkDevice::close()
#else
d->deviceContext->file.close();
#endif
+
if (d->verbose)
emitLogMessage("Close");
}
@@ -1030,6 +1066,8 @@ QString TrkDevice::port() const
void TrkDevice::setPort(const QString &p)
{
+ if (verboseTrk)
+ qDebug() << "setPort" << p;
d->port = p;
}
@@ -1045,6 +1083,8 @@ bool TrkDevice::serialFrame() const
void TrkDevice::setSerialFrame(bool f)
{
+ if (verboseTrk)
+ qDebug() << "setSerialFrame" << f;
d->deviceContext->serialFrame = f;
}
@@ -1060,12 +1100,14 @@ void TrkDevice::setVerbose(int b)
void TrkDevice::slotMessageReceived(const trk::TrkResult &result, const QByteArray &rawData)
{
- d->writerThread->slotHandleResult(result);
- if (d->verbose > 1)
- qDebug() << "Received: " << result.toString();
- emit messageReceived(result);
- if (!rawData.isEmpty())
- emit rawDataReceived(rawData);
+ if (isOpen()) { // Might receive bytes after closing due to queued connections.
+ d->writerThread->slotHandleResult(result);
+ if (d->verbose > 1)
+ qDebug() << "Received: " << result.toString();
+ emit messageReceived(result);
+ if (!rawData.isEmpty())
+ emit rawDataReceived(rawData);
+ }
}
void TrkDevice::emitError(const QString &s)
@@ -1075,15 +1117,27 @@ void TrkDevice::emitError(const QString &s)
emit error(s);
}
+void TrkDevice::clearWriteQueue()
+{
+ if (isOpen())
+ d->writerThread->clearWriteQueue();
+}
+
void TrkDevice::sendTrkMessage(byte code, TrkCallback callback,
const QByteArray &data, const QVariant &cookie)
{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return;
+ }
if (!d->writerThread.isNull()) {
if (d->verbose > 1) {
- QByteArray msg = "Sending: ";
+ QByteArray msg = "Sending: 0x";
msg += QByteArray::number(code, 16);
msg += ": ";
msg += stringFromArray(data).toLatin1();
+ if (cookie.isValid())
+ msg += " Cookie: " + cookie.toString().toLatin1();
qDebug("%s", msg.data());
}
d->writerThread->queueTrkMessage(code, callback, data, cookie);
@@ -1092,12 +1146,20 @@ void TrkDevice::sendTrkMessage(byte code, TrkCallback callback,
void TrkDevice::sendTrkInitialPing()
{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return;
+ }
if (!d->writerThread.isNull())
d->writerThread->queueTrkInitialPing();
}
bool TrkDevice::sendTrkAck(byte token)
{
+ if (!isOpen()) {
+ emitError(msgAccessingClosedDevice(d->port));
+ return false;
+ }
if (d->writerThread.isNull())
return false;
// The acknowledgement must not be queued!
diff --git a/tools/runonphone/symbianutils/trkdevice.h b/tools/runonphone/symbianutils/trkdevice.h
index 78012fd..1021a7d 100644
--- a/tools/runonphone/symbianutils/trkdevice.h
+++ b/tools/runonphone/symbianutils/trkdevice.h
@@ -64,12 +64,14 @@ struct TrkDevicePrivate;
* Trk communications. Provides synchronous write and asynchronous
* read operation.
* The serialFrames property specifies whether packets are encapsulated in
- * "0x90 <length>" frames, which is currently the case for serial ports.
+ * "0x90 <length>" frames, which is currently the case for serial ports.
* Contains a write message queue allowing
* for queueing messages with a notification callback. If the message receives
* an ACK, the callback is invoked.
- * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronisation.
- * The respective message will not be sent, the callback is just invoked. */
+ * The special message TRK_WRITE_QUEUE_NOOP_CODE code can be used for synchronization.
+ * The respective message will not be sent, the callback is just invoked.
+ * Note that calling open/close in quick succession can cause crashes
+ * due to the use of queused signals. */
enum { TRK_WRITE_QUEUE_NOOP_CODE = 0x7f };
@@ -111,6 +113,9 @@ public:
// Send an Ack synchronously, bypassing the queue
bool sendTrkAck(unsigned char token);
+public slots:
+ void clearWriteQueue();
+
signals:
void messageReceived(const trk::TrkResult &result);
// Emitted with the contents of messages enclosed in 07e, not for log output
diff --git a/tools/runonphone/symbianutils/trkutils.cpp b/tools/runonphone/symbianutils/trkutils.cpp
index 9b43c96..d89da20 100644
--- a/tools/runonphone/symbianutils/trkutils.cpp
+++ b/tools/runonphone/symbianutils/trkutils.cpp
@@ -52,6 +52,25 @@
namespace trk {
+Library::Library() : codeseg(0), dataseg(0), pid(0)
+{
+}
+
+Library::Library(const TrkResult &result) : codeseg(0), dataseg(0), pid(0)
+{
+ if (result.data.size() < 20) {
+ qWarning("Invalid trk creation notification received.");
+ return;
+ }
+
+ const char *data = result.data.constData();
+ pid = extractInt(data + 2);
+ codeseg = extractInt(data + 10);
+ dataseg = extractInt(data + 14);
+ const uint len = extractShort(data + 18);
+ name = result.data.mid(20, len);
+}
+
TrkAppVersion::TrkAppVersion()
{
reset();
@@ -77,11 +96,11 @@ void Session::reset()
extended1TypeSize = 0;
extended2TypeSize = 0;
pid = 0;
+ mainTid = 0;
tid = 0;
codeseg = 0;
dataseg = 0;
- currentThread = 0;
libraries.clear();
trkAppVersion.reset();
}
@@ -143,6 +162,90 @@ QString Session::deviceDescription(unsigned verbose) const
return msg.arg(formatTrkVersion(trkAppVersion));
}
+QByteArray Session::gdbLibraryList() const
+{
+ const int count = libraries.size();
+ QByteArray response = "l<library-list>";
+ for (int i = 0; i != count; ++i) {
+ const trk::Library &lib = libraries.at(i);
+ response += "<library name=\"";
+ response += lib.name;
+ response += "\">";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.codeseg);
+ response += "\"/>";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.dataseg);
+ response += "\"/>";
+ response += "<section address=\"0x";
+ response += trk::hexNumber(lib.dataseg);
+ response += "\"/>";
+ response += "</library>";
+ }
+ response += "</library-list>";
+ return response;
+}
+
+QByteArray Session::gdbQsDllInfo(int start, int count) const
+{
+ // Happens with gdb 6.4.50.20060226-cvs / CodeSourcery.
+ // Never made it into FSF gdb that got qXfer:libraries:read instead.
+ // http://sourceware.org/ml/gdb/2007-05/msg00038.html
+ // Name=hexname,TextSeg=textaddr[,DataSeg=dataaddr]
+ const int libraryCount = libraries.size();
+ const int end = count < 0 ? libraryCount : qMin(libraryCount, start + count);
+ QByteArray response(1, end == libraryCount ? 'l' : 'm');
+ for (int i = start; i < end; ++i) {
+ if (i != start)
+ response += ';';
+ const Library &lib = libraries.at(i);
+ response += "Name=";
+ response += lib.name.toHex();
+ response += ",TextSeg=";
+ response += hexNumber(lib.codeseg);
+ response += ",DataSeg=";
+ response += hexNumber(lib.dataseg);
+ }
+ return response;
+}
+
+QString Session::toString() const
+{
+ QString rc;
+ QTextStream str(&rc);
+ str << "Session: " << deviceDescription(false) << '\n'
+ << "pid: " << pid << "main thread: " << mainTid
+ << " current thread: " << tid << ' ';
+ str.setIntegerBase(16);
+ str << " code: 0x" << codeseg << " data: 0x" << dataseg << '\n';
+ if (const int libCount = libraries.size()) {
+ str << "Libraries:\n";
+ for (int i = 0; i < libCount; i++)
+ str << " #" << i << ' ' << libraries.at(i).name
+ << " code: 0x" << libraries.at(i).codeseg
+ << " data: 0x" << libraries.at(i).dataseg << '\n';
+ }
+ if (const int moduleCount = modules.size()) {
+ str << "Modules:\n";
+ for (int i = 0; i < moduleCount; i++)
+ str << " #" << i << ' ' << modules.at(i) << '\n';
+ }
+ str.setIntegerBase(10);
+ if (!addressToBP.isEmpty()) {
+ typedef QHash<uint, uint>::const_iterator BP_ConstIterator;
+ str << "Breakpoints:\n";
+ const BP_ConstIterator cend = addressToBP.constEnd();
+ for (BP_ConstIterator it = addressToBP.constBegin(); it != cend; ++it) {
+ str.setIntegerBase(16);
+ str << " 0x" << it.key();
+ str.setIntegerBase(10);
+ str << ' ' << it.value() << '\n';
+ }
+ }
+
+ return rc;
+}
+
// --------------
QByteArray decode7d(const QByteArray &ba)
@@ -188,18 +291,15 @@ SYMBIANUTILS_EXPORT QString stringFromArray(const QByteArray &ba, int maxLen)
QString ascii;
const int size = maxLen == -1 ? ba.size() : qMin(ba.size(), maxLen);
for (int i = 0; i < size; ++i) {
- //if (i == 5 || i == ba.size() - 2)
- // str += " ";
- int c = byte(ba.at(i));
- str += QString("%1 ").arg(c, 2, 16, QChar('0'));
- if (i >= 8 && i < ba.size() - 2)
- ascii += QChar(c).isPrint() ? QChar(c) : QChar('.');
+ const int c = byte(ba.at(i));
+ str += QString::fromAscii("%1 ").arg(c, 2, 16, QChar('0'));
+ ascii += QChar(c).isPrint() ? QChar(c) : QChar('.');
}
if (size != ba.size()) {
- str += "...";
- ascii += "...";
+ str += QLatin1String("...");
+ ascii += QLatin1String("...");
}
- return str + " " + ascii;
+ return str + QLatin1String(" ") + ascii;
}
SYMBIANUTILS_EXPORT QByteArray hexNumber(uint n, int digits)
@@ -276,14 +376,13 @@ QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool s
/* returns 0 if array doesn't represent a result,
otherwise returns the length of the result data */
-ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame)
+ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame, ushort& mux)
{
if (serialFrame) {
// Serial protocol with length info
if (buffer.length() < 4)
return 0;
- if (buffer.at(0) != 0x01 || byte(buffer.at(1)) != 0x90)
- return 0;
+ mux = extractShort(buffer.data());
const ushort len = extractShort(buffer.data() + 2);
return (buffer.size() >= len + 4) ? len : ushort(0);
}
@@ -292,6 +391,7 @@ ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame)
const int firstDelimiterPos = buffer.indexOf(delimiter);
// Regular message delimited by 0x7e..0x7e
if (firstDelimiterPos == 0) {
+ mux = MuxTrk;
const int endPos = buffer.indexOf(delimiter, firstDelimiterPos + 1);
return endPos != -1 ? endPos + 1 - firstDelimiterPos : 0;
}
@@ -299,21 +399,30 @@ ushort isValidTrkResult(const QByteArray &buffer, bool serialFrame)
return firstDelimiterPos != -1 ? firstDelimiterPos : buffer.size();
}
-bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByteArray *rawData)
+bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, bool &linkEstablishmentMode, QByteArray *rawData)
{
result->clear();
if(rawData)
rawData->clear();
- const ushort len = isValidTrkResult(*buffer, serialFrame);
- if (!len)
- return false;
+ ushort len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
// handle receiving application output, which is not a regular command
const int delimiterPos = serialFrame ? 4 : 0;
+ if (linkEstablishmentMode) {
+ //when "hot connecting" a device, we can receive partial frames.
+ //this code resyncs by discarding data until a TRK frame is found
+ while (buffer->length() > delimiterPos
+ && result->multiplex != MuxTextTrace
+ && !(result->multiplex == MuxTrk && buffer->at(delimiterPos) == 0x7e)) {
+ buffer->remove(0,1);
+ len = isValidTrkResult(*buffer, serialFrame, result->multiplex);
+ }
+ }
+ if (!len)
+ return false;
if (buffer->at(delimiterPos) != 0x7e) {
result->isDebugOutput = true;
result->data = buffer->mid(delimiterPos, len);
- result->data.replace("\r\n", "\n");
- *buffer->remove(0, delimiterPos + len);
+ buffer->remove(0, delimiterPos + len);
return true;
}
// FIXME: what happens if the length contains 0xfe?
@@ -321,7 +430,7 @@ bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByt
const QByteArray data = decode7d(buffer->mid(delimiterPos + 1, len - 2));
if(rawData)
*rawData = data;
- *buffer->remove(0, delimiterPos + len);
+ buffer->remove(0, delimiterPos + len);
byte sum = 0;
for (int i = 0; i < data.size(); ++i) // 3 = 2 * 0xfe + sum
@@ -336,6 +445,7 @@ bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *result, QByt
//logMessage(" CURR DATA: " << stringFromArray(data));
//QByteArray prefix = "READ BUF: ";
//logMessage((prefix + "HEADER: " + stringFromArray(header).toLatin1()).data());
+ linkEstablishmentMode = false; //have received a good TRK packet, therefore in sync
return true;
}
@@ -353,6 +463,19 @@ SYMBIANUTILS_EXPORT uint extractInt(const char *data)
return res;
}
+SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data)
+{
+ quint64 res = byte(data[0]);
+ res <<= 8; res += byte(data[1]);
+ res <<= 8; res += byte(data[2]);
+ res <<= 8; res += byte(data[3]);
+ res <<= 8; res += byte(data[4]);
+ res <<= 8; res += byte(data[5]);
+ res <<= 8; res += byte(data[6]);
+ res <<= 8; res += byte(data[7]);
+ return res;
+}
+
SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba)
{
QString res;
diff --git a/tools/runonphone/symbianutils/trkutils.h b/tools/runonphone/symbianutils/trkutils.h
index 3a485c7..d365f0d 100644
--- a/tools/runonphone/symbianutils/trkutils.h
+++ b/tools/runonphone/symbianutils/trkutils.h
@@ -43,6 +43,7 @@
#define DEBUGGER_TRK_UTILS
#include "symbianutils_global.h"
+
#include <QtCore/QByteArray>
#include <QtCore/QHash>
#include <QtCore/QStringList>
@@ -55,40 +56,110 @@ QT_END_NAMESPACE
namespace trk {
typedef unsigned char byte;
+struct TrkResult;
enum Command {
+ //meta commands
TrkPing = 0x00,
TrkConnect = 0x01,
TrkDisconnect = 0x02,
+ TrkReset = 0x03,
TrkVersions = 0x04,
TrkSupported = 0x05,
TrkCpuType = 0x06,
+ TrkConfigTransport = 0x07,
+ TrkVersions2 = 0x08,
TrkHostVersions = 0x09,
+
+ //state commands
+ TrkReadMemory = 0x10,
+ TrkWriteMemory = 0x11,
+ TrkReadRegisters = 0x12,
+ TrkWriteRegisters = 0x13,
+ TrkFillMemory = 0x14,
+ TrkCopyMemory = 0x15,
+ TrkFlushCache = 0x16,
+
+ //execution commands
TrkContinue = 0x18,
+ TrkStep = 0x19,
+ TrkStop = 0x1a,
+ TrkSetBreak = 0x1b,
+ TrkClearBreak = 0x1c,
+ TrkDownload = 0x1d,
+ TrkModifyBreakThread = 0x1e,
+
+ //host -> target IO management
+ TrkNotifyFileInput = 0x20,
+ TrkBlockFileIo = 0x21,
+
+ //host -> target os commands
TrkCreateItem = 0x40,
TrkDeleteItem = 0x41,
+ TrkReadInfo = 0x42,
+ TrkWriteInfo = 0x43,
TrkWriteFile = 0x48,
+ TrkReadFile = 0x49,
TrkOpenFile = 0x4a,
TrkCloseFile = 0x4b,
+ TrkPositionFile = 0x4c,
TrkInstallFile = 0x4d,
TrkInstallFile2 = 0x4e,
+ TrkPhoneSwVersion = 0x4f,
+ TrkPhoneName = 0x50,
+ TrkVersions3 = 0x51,
+
+ //replies
TrkNotifyAck = 0x80,
TrkNotifyNak = 0xff,
+
+ //target -> host notification
TrkNotifyStopped = 0x90,
TrkNotifyException = 0x91,
TrkNotifyInternalError = 0x92,
+ TrkNotifyStopped2 = 0x94,
+
+ //target -> host OS notification
TrkNotifyCreated = 0xa0,
TrkNotifyDeleted = 0xa1,
TrkNotifyProcessorStarted = 0xa2,
TrkNotifyProcessorStandBy = 0xa6,
- TrkNotifyProcessorReset = 0xa7
+ TrkNotifyProcessorReset = 0xa7,
+
+ //target -> host support commands (these are defined but not implemented in TRK)
+ TrkDSWriteFile = 0xd0,
+ TrkDSReadFile = 0xd1,
+ TrkDSOpenFile = 0xd2,
+ TrkDSCloseFile = 0xd3,
+ TrkDSPositionFile = 0xd4
+};
+
+enum DSOSItemTypes {
+ kDSOSProcessItem = 0x0000,
+ kDSOSThreadItem = 0x0001,
+ kDSOSDLLItem = 0x0002,
+ kDSOSAppItem = 0x0003,
+ kDSOSMemBlockItem = 0x0004,
+ kDSOSProcAttachItem = 0x0005,
+ kDSOSThreadAttachItem = 0x0006,
+ kDSOSProcAttach2Item = 0x0007,
+ kDSOSProcRunItem = 0x0008,
+ /* 0x0009 - 0x00ff reserved for general expansion */
+ /* 0x0100 - 0xffff available for target-specific use */
+};
+
+enum SerialMultiplexor {
+ MuxRaw = 0,
+ MuxTextTrace = 0x0102,
+ MuxTrk = 0x0190
};
inline byte extractByte(const char *data) { return *data; }
SYMBIANUTILS_EXPORT ushort extractShort(const char *data);
SYMBIANUTILS_EXPORT uint extractInt(const char *data);
+SYMBIANUTILS_EXPORT quint64 extractInt64(const char *data);
SYMBIANUTILS_EXPORT QString quoteUnprintableLatin1(const QByteArray &ba);
@@ -108,17 +179,20 @@ SYMBIANUTILS_EXPORT void appendString(QByteArray *ba, const QByteArray &str, End
struct SYMBIANUTILS_EXPORT Library
{
- Library() {}
+ Library();
+ explicit Library(const TrkResult &r);
QByteArray name;
uint codeseg;
uint dataseg;
+ //library addresses are valid for a given process (depending on memory model, they might be loaded at the same address in all processes or not)
+ uint pid;
};
struct SYMBIANUTILS_EXPORT TrkAppVersion
{
TrkAppVersion();
- void reset();
+ void reset();
int trkMajor;
int trkMinor;
@@ -131,6 +205,11 @@ struct SYMBIANUTILS_EXPORT Session
Session();
void reset();
QString deviceDescription(unsigned verbose) const;
+ QString toString() const;
+ // Answer to qXfer::libraries
+ QByteArray gdbLibraryList() const;
+ // Answer to qsDllInfo, can be sent chunk-wise.
+ QByteArray gdbQsDllInfo(int start = 0, int count = -1) const;
// Trk feedback
byte cpuMajor;
@@ -142,6 +221,7 @@ struct SYMBIANUTILS_EXPORT Session
byte extended2TypeSize;
TrkAppVersion trkAppVersion;
uint pid;
+ uint mainTid;
uint tid;
uint codeseg;
uint dataseg;
@@ -150,12 +230,7 @@ struct SYMBIANUTILS_EXPORT Session
typedef QList<Library> Libraries;
Libraries libraries;
- typedef uint Thread;
- typedef QList<Thread> Threads;
- Threads threads;
-
// Gdb request
- uint currentThread;
QStringList modules;
};
@@ -168,6 +243,7 @@ struct SYMBIANUTILS_EXPORT TrkResult
int errorCode() const;
QString errorString() const;
+ ushort multiplex;
byte code;
byte token;
QByteArray data;
diff --git a/tools/runonphone/symbianutils/trkutils_p.h b/tools/runonphone/symbianutils/trkutils_p.h
index 12b0109..05df83a 100644
--- a/tools/runonphone/symbianutils/trkutils_p.h
+++ b/tools/runonphone/symbianutils/trkutils_p.h
@@ -55,7 +55,7 @@ void appendDateTime(QByteArray *ba, QDateTime dateTime, Endianness = TargetByteO
// returns a QByteArray containing optionally
// the serial frame [0x01 0x90 <len>] and 0x7e encoded7d(ba) 0x7e
QByteArray frameMessage(byte command, byte token, const QByteArray &data, bool serialFrame);
-bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, QByteArray *rawData = 0);
+bool extractResult(QByteArray *buffer, bool serialFrame, TrkResult *r, bool& linkEstablishmentMode, QByteArray *rawData = 0);
} // namespace trk
diff --git a/tools/runonphone/trksignalhandler.cpp b/tools/runonphone/trksignalhandler.cpp
index 18a2c0c..898692a 100644
--- a/tools/runonphone/trksignalhandler.cpp
+++ b/tools/runonphone/trksignalhandler.cpp
@@ -42,7 +42,19 @@
#include <QDebug>
#include <QCoreApplication>
#include <QObject>
+#include <QFile>
+#include <QDir>
#include "trksignalhandler.h"
+#include "trkutils.h"
+
+class CrashState
+{
+public:
+ uint pid;
+ uint tid;
+ QString crashReason;
+ uint crashPC;
+};
class TrkSignalHandlerPrivate
{
@@ -54,6 +66,15 @@ private:
QTextStream out;
QTextStream err;
int loglevel;
+ int lastpercent;
+ QList<trk::Library> libraries;
+ QFile crashlogtextfile;
+ QFile crashstackfile;
+ QList<CrashState> queuedCrashes;
+ QList<int> dyingThreads;
+ QString crashlogPath;
+ bool crashlog;
+ bool terminateNeeded;
};
void TrkSignalHandler::copyingStarted()
@@ -107,6 +128,7 @@ void TrkSignalHandler::startingApplication()
void TrkSignalHandler::applicationRunning(uint pid)
{
+ Q_UNUSED(pid)
if (d->loglevel > 0)
d->out << "Running..." << endl;
}
@@ -131,7 +153,12 @@ void TrkSignalHandler::applicationOutputReceived(const QString &output)
void TrkSignalHandler::copyProgress(int percent)
{
if (d->loglevel > 0) {
- d->out << percent << "% ";
+ if (d->lastpercent == 0)
+ d->out << "[ ]\r[" << flush;
+ while (percent > d->lastpercent) {
+ d->out << QLatin1Char('#');
+ d->lastpercent+=2; //because typical console is 80 chars wide
+ }
d->out.flush();
if (percent==100)
d->out << endl;
@@ -149,13 +176,163 @@ void TrkSignalHandler::setLogLevel(int level)
d->loglevel = level;
}
+void TrkSignalHandler::setCrashLogging(bool enabled)
+{
+ d->crashlog = enabled;
+}
+
+void TrkSignalHandler::setCrashLogPath(QString path)
+{
+ d->crashlogPath = path;
+}
+
+bool lessThanCodeBase(const trk::Library& cs1, const trk::Library& cs2)
+{
+ return cs1.codeseg < cs2.codeseg;
+}
+
void TrkSignalHandler::stopped(uint pc, uint pid, uint tid, const QString& reason)
{
d->err << "STOPPED: pc=" << hex << pc << " pid=" << pid
<< " tid=" << tid << dec << " - " << reason << endl;
- // if it was a breakpoint, then we could continue with "emit resume(pid, tid);"
- // since we have set no breakpoints, it will be a just in time debug of a panic / exception
- emit terminate();
+
+ if (d->crashlog) {
+ CrashState cs;
+ cs.pid = pid;
+ cs.tid = tid;
+ cs.crashPC = pc;
+ cs.crashReason = reason;
+
+ if (d->dyingThreads.contains(tid)) {
+ if(d->queuedCrashes.isEmpty())
+ emit terminate();
+ else
+ d->terminateNeeded = true;
+ } else {
+ d->queuedCrashes.append(cs);
+ d->dyingThreads.append(tid);
+
+ if (d->queuedCrashes.count() == 1) {
+ d->err << "Fetching registers and stack..." << endl;
+ emit getRegistersAndCallStack(pid, tid);
+ }
+ }
+ }
+ else
+ emit terminate();
+}
+
+void TrkSignalHandler::registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack)
+{
+ CrashState cs = d->queuedCrashes.first();
+ QDir dir(d->crashlogPath);
+ d->crashlogtextfile.setFileName(dir.filePath(QString("d_exc_%1.txt").arg(cs.tid)));
+ d->crashstackfile.setFileName(dir.filePath(QString("d_exc_%1.stk").arg(cs.tid)));
+ d->crashlogtextfile.open(QIODevice::WriteOnly);
+ QTextStream crashlog(&d->crashlogtextfile);
+
+ crashlog << "-----------------------------------------------------------------------------" << endl;
+ crashlog << "EKA2 USER CRASH LOG" << endl;
+ crashlog << "Thread Name: " << QString("ProcessID-%1::ThreadID-%2").arg(cs.pid).arg(cs.tid) << endl;
+ crashlog << "Thread ID: " << cs.tid << endl;
+ //this is wrong, but TRK doesn't make stack limit available so we lie
+ crashlog << QString("User Stack %1-%2").arg(registers.at(13), 8, 16, QChar('0')).arg(registers.at(13) + stack.size(), 8, 16, QChar('0')) << endl;
+ //this is also wrong, but TRK doesn't give all information for exceptions
+ crashlog << QString("Panic: PC=%1 ").arg(cs.crashPC, 8, 16, QChar('0')) << cs.crashReason << endl;
+ crashlog << endl;
+ crashlog << "USER REGISTERS:" << endl;
+ crashlog << QString("CPSR=%1").arg(registers.at(16), 8, 16, QChar('0')) << endl;
+ for (int i=0;i<16;i+=4) {
+ crashlog << QString("r%1=%2 %3 %4 %5")
+ .arg(i, 2, 10, QChar('0'))
+ .arg(registers.at(i), 8, 16, QChar('0'))
+ .arg(registers.at(i+1), 8, 16, QChar('0'))
+ .arg(registers.at(i+2), 8, 16, QChar('0'))
+ .arg(registers.at(i+3), 8, 16, QChar('0')) << endl;
+ }
+ crashlog << endl;
+
+ //emit info for post mortem debug
+ qSort(d->libraries.begin(), d->libraries.end(), lessThanCodeBase);
+ d->err << "Code Segments:" << endl;
+ crashlog << "CODE SEGMENTS:" << endl;
+ for(int i=0; i<d->libraries.count(); i++) {
+ const trk::Library& seg = d->libraries.at(i);
+ if(seg.pid != cs.pid)
+ continue;
+ if (d->loglevel > 1) {
+ d->err << QString("Code: %1 Data: %2 Name: ")
+ .arg(seg.codeseg, 8, 16, QChar('0'))
+ .arg(seg.dataseg, 8, 16, QChar('0'))
+ << seg.name << endl;
+ }
+
+ //produce fake code segment end addresses since we don't get the real ones from TRK
+ uint end;
+ if (i+1 < d->libraries.count())
+ end = d->libraries.at(i+1).codeseg - 1;
+ else
+ end = 0xFFFFFFFF;
+
+ crashlog << QString("%1-%2 ")
+ .arg(seg.codeseg, 8, 16, QChar('0'))
+ .arg(end, 8, 16, QChar('0'))
+ << seg.name << endl;
+ }
+
+ d->crashlogtextfile.close();
+
+ if (d->loglevel > 1) {
+ d->err << "Registers:" << endl;
+ for (int i=0;i<16;i++) {
+ d->err << QString("R%1: %2 ").arg(i, 2, 10, QChar('0')).arg(registers.at(i), 8, 16, QChar('0'));
+ if (i % 4 == 3)
+ d->err << endl;
+ }
+ d->err << QString("CPSR: %1").arg(registers.at(16), 8, 16, QChar('0')) << endl;
+
+ d->err << "Stack:" << endl;
+ uint sp = registers.at(13);
+ for(int i=0; i<stack.size(); i+=16, sp+=16) {
+ d->err << QString("%1: ").arg(sp, 8, 16, QChar('0'));
+ d->err << trk::stringFromArray(stack.mid(i,16));
+ d->err << endl;
+ }
+ }
+ d->crashstackfile.open(QIODevice::WriteOnly);
+ d->crashstackfile.write(stack);
+ d->crashstackfile.close();
+
+ if (d->loglevel > 0)
+ d->err << "Crash logs saved to " << d->crashlogtextfile.fileName() << " & " << d->crashstackfile.fileName() << endl;
+
+ // resume the thread to allow Symbian OS to handle the panic normally.
+ // terminate when a non main thread is suspended reboots the phone (TRK bug)
+ emit resume(cs.pid, cs.tid);
+
+ //fetch next crashed thread
+ d->queuedCrashes.removeFirst();
+ if (d->queuedCrashes.count()) {
+ cs = d->queuedCrashes.first();
+ d->err << "Fetching registers and stack..." << endl;
+ emit getRegistersAndCallStack(cs.pid, cs.tid);
+ }
+ else if (d->terminateNeeded)
+ emit terminate();
+
+}
+
+void TrkSignalHandler::libraryLoaded(const trk::Library &lib)
+{
+ d->libraries << lib;
+}
+
+void TrkSignalHandler::libraryUnloaded(const trk::Library &lib)
+{
+ for (QList<trk::Library>::iterator i = d->libraries.begin(); i != d->libraries.end(); i++) {
+ if((*i).name == lib.name && (*i).pid == lib.pid)
+ i = d->libraries.erase(i);
+ }
}
void TrkSignalHandler::timeout()
@@ -167,7 +344,9 @@ void TrkSignalHandler::timeout()
TrkSignalHandlerPrivate::TrkSignalHandlerPrivate()
: out(stdout),
err(stderr),
- loglevel(0)
+ loglevel(0),
+ lastpercent(0),
+ terminateNeeded(false)
{
}
diff --git a/tools/runonphone/trksignalhandler.h b/tools/runonphone/trksignalhandler.h
index d31e46f..bfe2c3e 100644
--- a/tools/runonphone/trksignalhandler.h
+++ b/tools/runonphone/trksignalhandler.h
@@ -43,6 +43,7 @@
#define TRKSIGNALHANDLER_H
#include <QObject>
#include <QString>
+#include "symbianutils/trkutils.h"
class TrkSignalHandlerPrivate;
class TrkSignalHandler : public QObject
@@ -66,13 +67,20 @@ public slots:
void stateChanged(int);
void stopped(uint pc, uint pid, uint tid, const QString& reason);
void timeout();
+ void libraryLoaded(const trk::Library &lib);
+ void libraryUnloaded(const trk::Library &lib);
+ void registersAndCallStackReadComplete(const QList<uint>& registers, const QByteArray& stack);
signals:
void resume(uint pid, uint tid);
+ void stop(uint pid, uint tid);
void terminate();
+ void getRegistersAndCallStack(uint pid, uint tid);
public:
TrkSignalHandler();
~TrkSignalHandler();
void setLogLevel(int);
+ void setCrashLogging(bool);
+ void setCrashLogPath(QString);
private:
TrkSignalHandlerPrivate *d;
};
diff --git a/tools/shared/deviceskin/deviceskin.pri b/tools/shared/deviceskin/deviceskin.pri
index 2552c92..3e9935a 100644
--- a/tools/shared/deviceskin/deviceskin.pri
+++ b/tools/shared/deviceskin/deviceskin.pri
@@ -2,13 +2,10 @@ INCLUDEPATH += $$PWD
HEADERS += $$PWD/deviceskin.h
SOURCES += $$PWD/deviceskin.cpp
RESOURCES += $$PWD/skins/ClamshellPhone.qrc \
- $$PWD/skins/PDAPhone.qrc \
$$PWD/skins/SmartPhone2.qrc \
$$PWD/skins/SmartPhone.qrc \
$$PWD/skins/SmartPhoneWithButtons.qrc \
$$PWD/skins/TouchscreenPhone.qrc \
- $$PWD/skins/Trolltech-Keypad.qrc \
- $$PWD/skins/Trolltech-Touchscreen.qrc \
$$PWD/skins/PortableMedia.qrc \
$$PWD/skins/S60-QVGA-Candybar.qrc \
$$PWD/skins/S60-nHD-Touchscreen.qrc
diff --git a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png
deleted file mode 100644
index d62ef4a..0000000
--- a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png
deleted file mode 100644
index cb3d1a7..0000000
--- a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin
deleted file mode 100644
index a82ef23..0000000
--- a/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin
+++ /dev/null
@@ -1,29 +0,0 @@
-[SkinFile]
-Up=DualScreen.png
-Down=DualScreen-pressed.png
-Screen=128 155 176 208
-BackScreen=18 44 98 119
-Areas=21
-HasMouseHover=false
-
-"Context1" 0x1100000 144 368 189 368 168 396 176 427 150 398
-"Back" 0x1000061 245 365 291 366 283 398 258 424 265 394
-"Select" 0x1010000 202 401 210 389 224 388 233 402 224 415 208 415
-"Up" 0x1000013 202 381 196 374 218 363 239 373 229 382
-"Left" 0x1000012 199 385 189 375 176 403 185 426 197 415 194 401
-"Right" 0x1000014 235 390 248 379 253 402 246 421 238 413
-"Down" 0x1000015 204 421 233 422 241 432 214 443 191 430
-"Call" 0x1100004 163 452 137 450 125 465 136 484 159 485 169 467
-"Hangup" 0x1100005 266 475 279 448 295 447 309 460 301 480 289 487
-"1" 0x31 175 514 147 504 133 518 161 532 180 534
-"2" 0x32 199 515 229 519 238 533 222 540 195 538
-"2" 0x32 260 512 286 506 299 513 284 527 264 535 248 525
-"4" 0x34 164 541 177 546 182 560 164 565 146 560 135 545 154 539
-"5" 0x35 204 546 225 546 243 560 231 574 205 573 191 558
-"6" 0x36 257 547 281 537 294 540 287 555 274 566 254 561
-"7" 0x37 145 569 176 578 177 595 156 597 138 584
-"8" 0x38 197 582 229 584 241 593 226 604 201 603 189 594
-"9" 0x39 253 577 288 564 301 578 283 593 259 597 251 586
-"*" 0x2a 145 598 181 611 182 623 163 632 144 623 138 607
-"0" 0x30 196 611 233 613 240 630 220 642 193 637 191 622
-"#" 0x23 255 610 286 600 302 615 279 625 258 629 247 616
diff --git a/tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf
deleted file mode 100644
index 1103350..0000000
--- a/tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf
+++ /dev/null
@@ -1,78 +0,0 @@
-[Translation]
-File=QtopiaDefaults
-Context=Buttons
-[Menu]
-Rows=4
-Columns=3
-Map=123456789*0#
-Default=5
-1=Applications/camera.desktop
-2=Applications/datebook.desktop
-3=Applications
-4=Applications/qtmail.desktop
-5=Applications/addressbook.desktop
-6=Games
-7=Settings/Beaming.desktop
-8=Applications/simapp.desktop,Applications/calculator.desktop
-9=Settings
-*=Applications/mediarecorder.desktop
-0=Applications/todolist.desktop
-#=Documents
-Animator=Bounce
-AnimatorBackground=Radial
-[SoftKeys]
-Count=3
-Key0=Context1
-Key1=Select
-Key2=Back
-[SystemButtons]
-Count=5
-Key0=Context1
-Key1=Select
-Key2=Back
-Key3=Call
-Key4=Hangup
-[TextButtons]
-Buttons=0123456789*#
-Hold0='0
-Hold1='1
-Hold2='2
-Hold3='3
-Hold4='4
-Hold5='5
-Hold6='6
-Hold7='7
-Hold8='8
-Hold9='9
-Hold*=symbol
-Hold#=mode
-Tap0=space
-Tap1="\".,'?!-@:1"
-Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
-Tap3="\"de\xe8\xe9\xea\x66\x33"
-Tap4="\"ghi\xec\xed\xee\x34"
-Tap5="\"jkl5"
-Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
-Tap7="\"pqrs\xdf\x37"
-Tap8="\"tu\xfc\xf9\xfav8"
-Tap9="\"wxyz9"
-Tap*=modify
-Tap#=shift
-[LocaleTextButtons]
-Buttons=23456789
-Tap2[]='abc
-Tap3[]='def
-Tap4[]='ghi
-Tap5[]='jkl
-Tap6[]='mno
-Tap7[]='pqrs
-Tap8[]='tuv
-Tap9[]='wxyz
-[PhoneTextButtons]
-Buttons=*#
-Tap*='*+pw
-Hold*=+
-Tap#='#
-Hold#=mode
-[Device]
-PrimaryInput=Keypad
diff --git a/tools/shared/deviceskin/skins/PDAPhone.qrc b/tools/shared/deviceskin/skins/PDAPhone.qrc
deleted file mode 100644
index 1a1c35a..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/skins">
- <file>PDAPhone.skin</file>
-</qresource>
-</RCC>
diff --git a/tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin b/tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin
deleted file mode 100644
index d6a1966..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin
+++ /dev/null
@@ -1,18 +0,0 @@
-[SkinFile]
-Up=pda_up.png
-Down=pda_down.png
-Screen=42 59 176 220
-Cursor=finger.png 20 20
-Areas=10
-HasMouseHover=false
-
-"Power" 0x0100000a 117 21 141 42
-"Context1" 0x01100000 43 284 74 315
-"Call" 0x01100004 74 284 104 315
-"Hangup" 0x01100005 154 284 184 315
-"Back" 0x01000061 184 284 214 315
-"Left" 0x1000012 123 315 110 326 106 307 113 288 123 300 120 307
-"Down" 0x1000015 123 315 130 318 138 315 150 326 129 335 111 325
-"Right" 0x1000014 137 301 149 290 155 308 150 324 138 315 140 308
-"Up" 0x1000013 123 300 112 289 130 282 149 290 137 300 130 298
-"Select" 0x01010000 131 298 137 300 140 307 138 315 130 318 123 316 120 307 123 300
diff --git a/tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf
deleted file mode 100644
index e3ae813..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf
+++ /dev/null
@@ -1,36 +0,0 @@
-[Translation]
-File=QtopiaDefaults
-Context=Buttons
-[Menu]
-Rows=4
-Columns=3
-Map=123456789*0#
-Default=5
-1=Applications/camera.desktop
-2=Applications/datebook.desktop
-3=Applications
-4=Applications/qtmail.desktop
-5=Applications/addressbook.desktop
-6=Games
-7=Settings/Beaming.desktop
-8=Applications/simapp.desktop,Applications/calculator.desktop
-9=Settings
-*=Applications/mediarecorder.desktop
-0=Applications/todolist.desktop
-#=Documents
-Animator=Bounce
-AnimatorBackground=Radial
-[SoftKeys]
-Count=3
-Key0=Context1
-Key1=Select
-Key2=Back
-[SystemButtons]
-Count=5
-Key0=Context1
-Key1=Back
-Key2=Select
-Key3=Call
-Key4=Hangup
-[Device]
-PrimaryInput=Touchscreen
diff --git a/tools/shared/deviceskin/skins/PDAPhone.skin/finger.png b/tools/shared/deviceskin/skins/PDAPhone.skin/finger.png
deleted file mode 100644
index 24cf0cb..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.skin/finger.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png
deleted file mode 100644
index f65c059..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png
deleted file mode 100644
index 541e3c4..0000000
--- a/tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.qrc b/tools/shared/deviceskin/skins/Trolltech-Keypad.qrc
deleted file mode 100644
index 4775068..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/skins">
- <file>Trolltech-Keypad.skin</file>
-</qresource>
-</RCC>
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
deleted file mode 100644
index 8dd5719..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
deleted file mode 100644
index 5e1e6be..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png
deleted file mode 100644
index fb3d549..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin
deleted file mode 100644
index 4d90321..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin
+++ /dev/null
@@ -1,35 +0,0 @@
-[SkinFile]
-Up=Trolltech-Keypad.png
-Down=Trolltech-Keypad-down.png
-Closed=Trolltech-Keypad-closed.png
-ClosedAreas=F1 F2 F3 Flip
-ClosedScreen=95 456 128 96
-Screen=75 85 176 220
-Areas=25
-HasMouseHover=false
-"1" 0x0031 65 542 68 536 76 532 114 536 114 573 64 568
-"2" 0x0032 133 537 188 574
-"3" 0x0033 206 536 246 532 252 536 256 542 258 569 205 572
-"4" 0x0034 64 578 114 618
-"5" 0x0035 133 581 188 618
-"6" 0x0036 206 580 256 577 258 613 206 616
-"7" 0x0037 66 622 116 625 114 662 66 658
-"8" 0x0038 133 626 188 662
-"9" 0x0039 206 625 256 622 256 658 206 661
-"*" 0x002a 68 667 116 670 114 705 86 699 76 693 69 686
-"0" 0x0030 133 671 188 708
-"#" 0x0023 206 670 254 665 254 684 245 692 232 699 206 704
-"Context1" 0x01100000 69 420 75 410 85 404 101 404 102 458 69 458
-"Back" 0x01000061 218 404 234 404 240 408 248 418 248 456 218 457
-"Home" 0x1000010 140 494 180 514
-"Hangup" 0x01100005 218 457 248 456 248 496 243 507 230 514 194 514 194 494 206 492 213 486 218 478
-"Call" 0x01100004 68 458 102 460 102 479 108 487 118 492 126 494 126 514 86 514 77 507 72 496
-"Select" 0x01010000 138 426 182 458
-"Up" 0x1000013 118 406 201 402 184 423 134 422
-"Right" 0x1000014 184 424 201 402 202 476 184 460
-"Down" 0x1000015 135 462 184 461 199 477 118 477
-"Left" 0x1000012 118 406 134 424 134 461 117 476
-"F1" 0x1000030 0 408 45 456
-"F2" 0x1000031 0 456 45 509
-"F3" 0x1000032 0 545 45 582
-"Flip" 0x1100006 32 353 293 386
diff --git a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf
deleted file mode 100644
index 6a78e67..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf
+++ /dev/null
@@ -1,142 +0,0 @@
-[Translation]
-File=QtopiaDefaults
-Context=Buttons
-[Button]
-Count=8
-[Button7]
-Name[]=Home Down Button
-Key=Down
-Context=HomeScreen
-PressedActionMappable=0
-HeldActionService=Messaging
-HeldActionMessage=raise()
-[Button6]
-Name[]=Home Up Button
-Key=Up
-Context=HomeScreen
-PressedActionMappable=0
-HeldActionService=Contacts
-HeldActionMessage=raise()
-[Button5]
-Name[]=Home Right Button
-Key=Right
-Context=HomeScreen
-PressedActionMappable=0
-HeldActionService=mediaplayer
-HeldActionMessage=raise()
-[Button4]
-Name[]=Calender Button
-Key=Left
-Context=HomeScreen
-PressedActionMappable=0
-HeldActionService=Calendar
-HeldActionMessage=raiseToday()
-[Button3]
-Name[]=Left Soft Key
-Key=Context1
-HeldActionService=TaskManager
-HeldActionMessage=showRunningTasks()
-HeldActionMappable=0
-PressActionMappable=0
-[Button2]
-Name[]=VoiceNotes Button
-Key=F1
-PressedActionService=mediarecorder
-PressedActionMessage=raise()
-HeldActionService=mediarecorder
-HeldActionMessage=newEvent()
-[Button1]
-Name[]=Camera Button
-Key=F2
-PressedActionService=Camera
-PressedActionMessage=raise()
-HeldActionService=Tasks
-HeldActionMessage=newTask()
-[Button0]
-Name[]=Home Button
-Key=Home
-PressedActionMappable=0
-PressedActionService=TaskManager
-PressedActionMessage=multitask()
-HeldActionMappable=0
-HeldActionService=TaskManager
-HeldActionMessage=showRunningTasks()
-[Menu]
-Rows=4
-Columns=3
-Map=123456789*0#
-Default=5
-1=Applications/camera.desktop
-2=Applications/mediaplayer.desktop
-3=Applications/simapp.desktop,Applications/calculator.desktop
-4=Applications/qtmail.desktop
-5=Applications/addressbook.desktop
-6=Applications/datebook.desktop
-7=Games
-8=Settings/Beaming.desktop
-9=Applications/todolist.desktop
-*=Settings
-0=Applications
-#=Documents
-Animator=Bounce
-AnimatorBackground=Radial
-[SoftKeys]
-Count=3
-Key0=Context1
-Key1=Select
-Key2=Back
-[SystemButtons]
-Count=6
-Key0=Context1
-Key1=Select
-Key2=Back
-Key3=Call
-Key4=Hangup
-Key5=Flip
-[TextButtons]
-Buttons=0123456789*#
-Hold0='0
-Hold1='1
-Hold2='2
-Hold3='3
-Hold4='4
-Hold5='5
-Hold6='6
-Hold7='7
-Hold8='8
-Hold9='9
-Hold*=symbol
-Hold#=mode
-Tap0=space
-Tap0=space
-Tap1="\".,'?!-@:1"
-Tap2="\"a\xe4\xe5\xe6\xe0\xe1\xe2\x62\x63\xe7\x32"
-Tap3="\"de\xe8\xe9\xea\x66\x33"
-Tap4="\"ghi\xec\xed\xee\x34"
-Tap5="\"jkl5"
-Tap6="\"mn\xf1o\xf6\xf8\xf2\xf3\x36"
-Tap7="\"pqrs\xdf\x37"
-Tap8="\"tu\xfc\xf9\xfav8"
-Tap9="\"wxyz9"
-Tap*=modify
-Tap#=shift
-[LocaleTextButtons]
-Buttons=23456789
-Tap2[]='abc
-Tap3[]='def
-Tap4[]='ghi
-Tap5[]='jkl
-Tap6[]='mno
-Tap7[]='pqrs
-Tap8[]='tuv
-Tap9[]='wxyz
-[PhoneTextButtons]
-Buttons=*#
-Tap*='*+pw
-Hold*=+
-Tap#='#
-Hold#=mode
-[Device]
-PrimaryInput=Keypad
-[Environment]
-QWS_DISPLAY=Multi: LinuxFb:mmHeight57:0 LinuxFb:offset=0,320:1 :0
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc
deleted file mode 100644
index 40fafeb..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/skins">
- <file>Trolltech-Touchscreen.skin</file>
-</qresource>
-</RCC>
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
deleted file mode 100644
index c1a422f..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
deleted file mode 100644
index 544a425..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
+++ /dev/null
Binary files differ
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
deleted file mode 100644
index 5de882e..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
+++ /dev/null
@@ -1,17 +0,0 @@
-[SkinFile]
-Up=Trolltech-Touchscreen.png
-Down=Trolltech-Touchscreen-down.png
-Screen=40 109 176 220
-Areas=10
-HasMouseHover=false
-
-"Context1" 0x01100000 38 420 44 408 52 404 68 403 68 458 40 458
-"Back" 0x01000061 185 42 202 398 211 410 216 418 219 456 186 456
-"Call" 0x01100004 38 458 70 458 71 478 75 486 83 492 94 494 94 516 56 516 45 507 38 498
-"Hangup" 0x01100005 186 458 220 458 220 496 214 508 200 516 162 516 161 494 172 492 180 486 185 478
-"Left" 0x1000012 86 405 106 426 106 461 85 478
-"Down" 0x1000015 106 460 151 460 170 480 85 480
-"Right" 0x1000014 151 424 170 404 170 480 151 460
-"Up" 0x1000013 85 403 168 403 150 424 106 424
-"Select" 0x01010000 106 426 150 456
-"Home" 0x1000010 105 493 145 512
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf
deleted file mode 100644
index 6665125..0000000
--- a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf
+++ /dev/null
@@ -1,53 +0,0 @@
-[Translation]
-File=QtopiaDefaults
-Context=Buttons
-[Menu]
-Rows=4
-Columns=3
-Map=123456789*0#
-Default=5
-1=Applications/camera.desktop
-2=Applications/mediaplayer.desktop
-3=Applications/simapp.desktop,Applications/calculator.desktop
-4=Applications/qtmail.desktop
-5=Applications/addressbook.desktop
-6=Applications/datebook.desktop
-7=Games
-8=Settings/beaming.desktop
-9=Applications/todolist.desktop
-*=Settings
-0=Applications
-#=Documents
-Animator=Bounce
-AnimatorBackground=Radial
-[SoftKeys]
-Count=3
-Key0=Context1
-Key1=Select
-Key2=Back
-[SystemButtons]
-Count=5
-Key0=Context1
-Key1=Back
-Key2=Select
-Key3=Call
-Key4=Hangup
-[Device]
-PrimaryInput=Touchscreen
-[Button]
-Count=2
-[Button0]
-Name[]=Home Button
-Key=Home
-PressedActionMappable=0
-PressedActionService=TaskManager
-PressedActionMessage=multitask()
-HeldActionMappable=0
-HeldActionService=TaskManager
-HeldActionMessage=showRunningTasks()
-[Button1]
-Name=Power Button
-Key=Hangup
-HeldActionService=Launcher
-HeldActionMessage=execute(QString)
-HeldActionArgs=@ByteArray(\0\0\0\x1\0\0\0\n\0\0\0\0\x10\0s\0h\0u\0t\0\x64\0o\0w\0n)
diff --git a/tools/shared/fontpanel/fontpanel.cpp b/tools/shared/fontpanel/fontpanel.cpp
index ad297df..fe221fd 100644
--- a/tools/shared/fontpanel/fontpanel.cpp
+++ b/tools/shared/fontpanel/fontpanel.cpp
@@ -96,8 +96,12 @@ QFont FontPanel::selectedFont() const
const QString family = rc.family();
rc.setPointSize(pointSize());
const QString styleDescription = styleString();
- rc.setItalic(m_fontDatabase.italic(family, styleDescription));
-
+ if (styleDescription.contains(QLatin1String("Italic")))
+ rc.setStyle(QFont::StyleItalic);
+ else if (styleDescription.contains(QLatin1String("Oblique")))
+ rc.setStyle(QFont::StyleOblique);
+ else
+ rc.setStyle(QFont::StyleNormal);
rc.setBold(m_fontDatabase.bold(family, styleDescription));
// Weight < 0 asserts...
diff --git a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp
index d9ff10a..8c7835c 100644
--- a/tools/shared/qtpropertybrowser/qtpropertymanager.cpp
+++ b/tools/shared/qtpropertybrowser/qtpropertymanager.cpp
@@ -2399,15 +2399,23 @@ QString QtLocalePropertyManager::valueText(const QtProperty *property) const
if (it == d_ptr->m_values.constEnd())
return QString();
- QLocale loc = it.value();
+ const QLocale loc = it.value();
int langIdx = 0;
int countryIdx = 0;
- metaEnumProvider()->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx);
- QString str = tr("%1, %2")
- .arg(metaEnumProvider()->languageEnumNames().at(langIdx))
- .arg(metaEnumProvider()->countryEnumNames(loc.language()).at(countryIdx));
- return str;
+ const QtMetaEnumProvider *me = metaEnumProvider();
+ me->localeToIndex(loc.language(), loc.country(), &langIdx, &countryIdx);
+ if (langIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown language %d", loc.language());
+ return tr("<Invalid>");
+ }
+ const QString languageName = me->languageEnumNames().at(langIdx);
+ if (countryIdx < 0) {
+ qWarning("QtLocalePropertyManager::valueText: Unknown country %d for %s", loc.country(), qPrintable(languageName));
+ return languageName;
+ }
+ const QString countryName = me->countryEnumNames(loc.language()).at(countryIdx);
+ return tr("%1, %2").arg(languageName, countryName);
}
/*!
@@ -2635,8 +2643,8 @@ QString QtPointPropertyManager::valueText(const QtProperty *property) const
if (it == d_ptr->m_values.constEnd())
return QString();
const QPoint v = it.value();
- return QString(tr("(%1, %2)").arg(QString::number(v.x()))
- .arg(QString::number(v.y())));
+ return tr("(%1, %2)").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()));
}
/*!
@@ -2876,8 +2884,8 @@ QString QtPointFPropertyManager::valueText(const QtProperty *property) const
return QString();
const QPointF v = it.value().val;
const int dec = it.value().decimals;
- return QString(tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec))
- .arg(QString::number(v.y(), 'f', dec)));
+ return tr("(%1, %2)").arg(QString::number(v.x(), 'f', dec))
+ .arg(QString::number(v.y(), 'f', dec));
}
/*!
@@ -3196,8 +3204,8 @@ QString QtSizePropertyManager::valueText(const QtProperty *property) const
if (it == d_ptr->m_values.constEnd())
return QString();
const QSize v = it.value().val;
- return QString(tr("%1 x %2").arg(QString::number(v.width()))
- .arg(QString::number(v.height())));
+ return tr("%1 x %2").arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
}
/*!
@@ -3561,8 +3569,8 @@ QString QtSizeFPropertyManager::valueText(const QtProperty *property) const
return QString();
const QSizeF v = it.value().val;
const int dec = it.value().decimals;
- return QString(tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
- .arg(QString::number(v.height(), 'f', dec)));
+ return tr("%1 x %2").arg(QString::number(v.width(), 'f', dec))
+ .arg(QString::number(v.height(), 'f', dec));
}
/*!
@@ -3954,10 +3962,10 @@ QString QtRectPropertyManager::valueText(const QtProperty *property) const
if (it == d_ptr->m_values.constEnd())
return QString();
const QRect v = it.value().val;
- return QString(tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
- .arg(QString::number(v.y()))
- .arg(QString::number(v.width()))
- .arg(QString::number(v.height())));
+ return tr("[(%1, %2), %3 x %4]").arg(QString::number(v.x()))
+ .arg(QString::number(v.y()))
+ .arg(QString::number(v.width()))
+ .arg(QString::number(v.height()));
}
/*!
diff --git a/tools/shared/symbian/epocroot.cpp b/tools/shared/symbian/epocroot.cpp
index 071477d..eabae98 100644
--- a/tools/shared/symbian/epocroot.cpp
+++ b/tools/shared/symbian/epocroot.cpp
@@ -39,13 +39,13 @@
**
****************************************************************************/
-#include <iostream>
-
#include <QtCore/qdir.h>
#include <QtCore/qxmlstream.h>
-#include "epocroot.h"
-#include "../windows/registry.h"
+#include "epocroot_p.h"
+#include "../windows/registry_p.h"
+
+QT_BEGIN_NAMESPACE
// Registry key under which the location of the Symbian devices.xml file is
// stored.
@@ -64,35 +64,26 @@
// Stored as a static value in order to avoid unnecessary re-evaluation.
static QString epocRootValue;
-#ifdef QT_BUILD_QMAKE
-std::ostream &operator<<(std::ostream &s, const QString &val) {
- s << val.toLocal8Bit().data();
- return s;
-}
-#else
-// Operator implemented in configureapp.cpp
-std::ostream &operator<<(std::ostream &s, const QString &val);
-#endif
-
-QString getDevicesXmlPath()
+static QString getDevicesXmlPath()
{
// Note that the following call will return a null string on platforms other
// than Windows. If support is required on other platforms for devices.xml,
// an alternative mechanism for retrieving the location of this file will
// be required.
- return readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, SYMBIAN_SDKS_REG_SUBKEY);
+ return qt_readRegistryKey(SYMBIAN_SDKS_REG_HANDLE, QLatin1String(SYMBIAN_SDKS_REG_SUBKEY));
}
/**
* Checks whether epocRootValue points to an existent directory.
* If not, epocRootValue is set to an empty string and an error message is printed.
*/
-void checkEpocRootExists(const QString &source)
+static void checkEpocRootExists(const QString &source)
{
if (!epocRootValue.isEmpty()) {
QDir dir(epocRootValue);
if (!dir.exists()) {
- std::cerr << "Warning: " << source << " is set to an invalid path: " << epocRootValue << std::endl;
+ qWarning("Warning: %s is set to an invalid path: '%s'", qPrintable(source),
+ qPrintable(epocRootValue));
epocRootValue = QString();
}
}
@@ -103,36 +94,30 @@ void checkEpocRootExists(const QString &source)
*/
static void fixEpocRoot(QString &path)
{
- path.replace("\\", "/");
+ path.replace(QLatin1Char('\\'), QLatin1Char('/'));
- if (path.size() > 1 && path[1] == QChar(':')) {
- path = path.mid(2);
- }
-
- if (!path.size() || path[path.size()-1] != QChar('/')) {
- path += QChar('/');
+ if (!path.size() || path[path.size()-1] != QLatin1Char('/')) {
+ path += QLatin1Char('/');
}
}
/**
* Determine the epoc root for the currently active SDK.
*/
-QString epocRoot()
+QString qt_epocRoot()
{
if (epocRootValue.isEmpty()) {
// 1. If environment variable EPOCROOT is set and points to an existent
// directory, this is returned.
- epocRootValue = qgetenv("EPOCROOT");
- checkEpocRootExists("EPOCROOT");
+ epocRootValue = QString::fromLocal8Bit(qgetenv("EPOCROOT").constData());
+ checkEpocRootExists(QLatin1String("EPOCROOT environment variable"));
if (epocRootValue.isEmpty()) {
// 2. The location of devices.xml is specified by a registry key. If this
// file exists, it is parsed.
QString devicesXmlPath = getDevicesXmlPath();
- if (devicesXmlPath.isEmpty()) {
- std::cerr << "Error: Symbian SDK registry key not found" << std::endl;
- } else {
- devicesXmlPath += "/devices.xml";
+ if (!devicesXmlPath.isEmpty()) {
+ devicesXmlPath += QLatin1String("/devices.xml");
QFile devicesFile(devicesXmlPath);
if (devicesFile.open(QIODevice::ReadOnly)) {
@@ -142,84 +127,90 @@ QString epocRoot()
// 4. If a device element marked as default is found in devices.xml and its
// epocroot value points to an existent directory, this is returned.
- const QString epocDeviceValue = qgetenv("EPOCDEVICE");
+ const QString epocDeviceValue = QString::fromLocal8Bit(qgetenv("EPOCDEVICE").constData());
bool epocDeviceFound = false;
QXmlStreamReader xml(&devicesFile);
while (!xml.atEnd()) {
xml.readNext();
- if (xml.isStartElement() && xml.name() == "devices") {
- if (xml.attributes().value("version") == "1.0") {
- while (!(xml.isEndElement() && xml.name() == "devices") && !xml.atEnd()) {
+ if (xml.isStartElement() && xml.name() == QLatin1String("devices")) {
+ if (xml.attributes().value(QLatin1String("version")) == QLatin1String("1.0")) {
+ while (!(xml.isEndElement() && xml.name() == QLatin1String("devices")) && !xml.atEnd()) {
xml.readNext();
- if (xml.isStartElement() && xml.name() == "device") {
- const bool isDefault = xml.attributes().value("default") == "yes";
- const QString id = xml.attributes().value("id").toString();
- const QString name = xml.attributes().value("name").toString();
- const bool epocDeviceMatch = (id + ":" + name) == epocDeviceValue;
+ if (xml.isStartElement() && xml.name() == QLatin1String("device")) {
+ const bool isDefault = xml.attributes().value(QLatin1String("default")) == QLatin1String("yes");
+ const QString id = xml.attributes().value(QLatin1String("id")).toString();
+ const QString name = xml.attributes().value(QLatin1String("name")).toString();
+ const QString alias = xml.attributes().value(QLatin1String("alias")).toString();
+ bool epocDeviceMatch = QString(id + QLatin1String(":") + name) == epocDeviceValue;
+ if (!alias.isEmpty())
+ epocDeviceMatch |= alias == epocDeviceValue;
epocDeviceFound |= epocDeviceMatch;
if((epocDeviceValue.isEmpty() && isDefault) || epocDeviceMatch) {
// Found a matching device
- while (!(xml.isEndElement() && xml.name() == "device") && !xml.atEnd()) {
+ while (!(xml.isEndElement() && xml.name() == QLatin1String("device")) && !xml.atEnd()) {
xml.readNext();
- if (xml.isStartElement() && xml.name() == "epocroot") {
+ if (xml.isStartElement() && xml.name() == QLatin1String("epocroot")) {
epocRootValue = xml.readElementText();
const QString deviceSource = epocDeviceValue.isEmpty()
- ? "default device"
- : "EPOCDEVICE (" + epocDeviceValue + ")";
+ ? QLatin1String("default device")
+ : QString(QLatin1String("EPOCDEVICE (") + epocDeviceValue + QLatin1String(")"));
checkEpocRootExists(deviceSource);
}
}
if (epocRootValue.isEmpty())
- xml.raiseError("No epocroot element found");
+ xml.raiseError(QLatin1String("No epocroot element found"));
}
}
}
} else {
- xml.raiseError("Invalid 'devices' element version");
+ xml.raiseError(QLatin1String("Invalid 'devices' element version"));
}
}
}
if (xml.hasError()) {
- std::cerr << "Error: \"" << xml.errorString() << "\" when parsing devices.xml" << std::endl;
+ qWarning("Warning: Error \"%s\" when parsing devices.xml",
+ qPrintable(xml.errorString()));
} else {
if (epocRootValue.isEmpty()) {
if (!epocDeviceValue.isEmpty()) {
if (epocDeviceFound) {
- std::cerr << "Error: missing or invalid epocroot attribute "
- << "in device '" << epocDeviceValue << "'";
+ qWarning("Warning: Missing or invalid epocroot attribute in device '%s' in devices.xml.",
+ qPrintable(epocDeviceValue));
} else {
- std::cerr << "Error: no device matching EPOCDEVICE ("
- << epocDeviceValue << ")";
+ qWarning("Warning: No device matching EPOCDEVICE (%s) in devices.xml.",
+ qPrintable(epocDeviceValue));
}
} else {
if (epocDeviceFound) {
- std::cerr << "Error: missing or invalid epocroot attribute "
- << "in default device";
+ qWarning("Warning: Missing or invalid epocroot attribute in default device in devices.xml.");
} else {
- std::cerr << "Error: no default device";
+ qWarning("Warning: No default device set in devices.xml.");
}
}
- std::cerr << " found in devices.xml file." << std::endl;
}
}
} else {
- std::cerr << "Error: could not open file " << devicesXmlPath << std::endl;
+ qWarning("Warning: Could not open file: '%s'.", qPrintable(devicesXmlPath));
}
}
}
if (epocRootValue.isEmpty()) {
// 5. An empty string is returned.
- std::cerr << "Error: failed to find epoc root" << std::endl
- << "Either" << std::endl
- << " 1. Set EPOCROOT environment variable to a valid value" << std::endl
- << " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY
- " registry key is set, and then" << std::endl
- << " a. Set EPOCDEVICE environment variable to a valid device" << std::endl
- << " or b. Specify a default device in the devices.xml file." << std::endl;
+ qWarning("Warning: failed to resolve epocroot."
+#ifdef Q_OS_WIN32
+ "\nEither\n"
+ " 1. Set EPOCROOT environment variable to a valid value.\n"
+ " or 2. Ensure that the HKEY_LOCAL_MACHINE\\" SYMBIAN_SDKS_REG_SUBKEY
+ " registry key is set, and then\n"
+ " a. Set EPOCDEVICE environment variable to a valid device\n"
+ " or b. Specify a default device in the devices.xml file.");
+#else
+ " Set EPOCROOT environment variable to a valid value.");
+#endif
} else {
fixEpocRoot(epocRootValue);
}
@@ -228,3 +219,4 @@ QString epocRoot()
return epocRootValue;
}
+QT_END_NAMESPACE
diff --git a/tools/shared/symbian/epocroot.pri b/tools/shared/symbian/epocroot.pri
new file mode 100644
index 0000000..f0f0dab
--- /dev/null
+++ b/tools/shared/symbian/epocroot.pri
@@ -0,0 +1,11 @@
+# Epocroot resolving is only required for tools, so omit it from all mobile/embedded builds
+!symbian:!wince*:!embedded {
+HEADERS += \
+ $$QT_SOURCE_TREE/tools/shared/symbian/epocroot_p.h \
+ $$QT_SOURCE_TREE/tools/shared/windows/registry_p.h
+SOURCES += \
+ $$QT_SOURCE_TREE/tools/shared/symbian/epocroot.cpp \
+ $$QT_SOURCE_TREE/tools/shared/windows/registry.cpp
+INCLUDEPATH += $$QT_SOURCE_TREE/tools/shared
+DEFINES += QLIBRARYINFO_EPOCROOT
+}
diff --git a/tools/shared/symbian/epocroot.h b/tools/shared/symbian/epocroot_p.h
index 9846485..c97b593 100644
--- a/tools/shared/symbian/epocroot.h
+++ b/tools/shared/symbian/epocroot_p.h
@@ -39,11 +39,24 @@
**
****************************************************************************/
-#ifndef SYMBIAN_EPOCROOT_H
-#define SYMBIAN_EPOCROOT_H
+#ifndef QT_SYMBIAN_EPOCROOT_H
+#define QT_SYMBIAN_EPOCROOT_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
#include <QtCore/qstring.h>
+QT_BEGIN_NAMESPACE
+
/**
* Determine the epoc root for the currently active SDK.
*
@@ -62,6 +75,9 @@
* Any return value other than the empty string therefore is guaranteed to
* point to an existent directory.
*/
-QString epocRoot();
+QString qt_epocRoot();
+
+QT_END_NAMESPACE
+
+#endif // QT_SYMBIAN_EPOCROOT_H
-#endif // EPOCROOT_H
diff --git a/tools/shared/windows/registry.cpp b/tools/shared/windows/registry.cpp
index d342d78..48e9ae6 100644
--- a/tools/shared/windows/registry.cpp
+++ b/tools/shared/windows/registry.cpp
@@ -40,8 +40,11 @@
****************************************************************************/
#include <QtCore/qstringlist.h>
-#include "registry.h"
+#include "registry_p.h"
+QT_BEGIN_NAMESPACE
+
+#ifdef Q_OS_WIN32
/*!
Returns the path part of a registry key.
e.g.
@@ -73,12 +76,13 @@ static QString keyName(const QString &rKey)
return rKey;
QString res(rKey.mid(idx + 1));
- if (res == "Default" || res == ".")
- res = "";
+ if (res == QLatin1String("Default") || res == QLatin1String("."))
+ res = QString();
return res;
}
+#endif
-QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
+QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey)
{
QString result;
@@ -128,7 +132,7 @@ QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
break;
l.append(s);
}
- result = l.join(", ");
+ result = l.join(QLatin1String(", "));
break;
}
@@ -148,7 +152,7 @@ QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
}
default:
- qWarning("QSettings: unknown data %d type in windows registry", dataType);
+ qWarning("QSettings: unknown data %u type in windows registry", quint32(dataType));
break;
}
@@ -158,4 +162,5 @@ QString readRegistryKey(HKEY parentHandle, const QString &rSubkey)
return result;
}
+QT_END_NAMESPACE
diff --git a/tools/shared/windows/registry.h b/tools/shared/windows/registry_p.h
index 3896527..4aae5f9 100644
--- a/tools/shared/windows/registry.h
+++ b/tools/shared/windows/registry_p.h
@@ -39,8 +39,21 @@
**
****************************************************************************/
-#ifndef WINDOWS_REGISTRY_H
-#define WINDOWS_REGISTRY_H
+#ifndef QT_WINDOWS_REGISTRY_H
+#define QT_WINDOWS_REGISTRY_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+QT_BEGIN_NAMESPACE
#include <QtCore/qglobal.h>
@@ -59,6 +72,9 @@
* if this code is compiled for a platform other than Windows), a null
* string is returned.
*/
-QString readRegistryKey(HKEY parentHandle, const QString &rSubkey);
+QString qt_readRegistryKey(HKEY parentHandle, const QString &rSubkey);
+
+QT_END_NAMESPACE
+
+#endif // QT_WINDOWS_REGISTRY_H
-#endif // WINDOWS_REGISTRY_H
diff --git a/tools/tools.pro b/tools/tools.pro
index f6f2dcd..8f23fe4 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,32 +1,39 @@
TEMPLATE = subdirs
-no-png {
- message("Some graphics-related tools are unavailable without PNG support")
-} else {
- SUBDIRS += assistant \
- pixeltool \
- porting \
- qtestlib \
- qttracereplay
- contains(QT_EDITION, Console) {
- SUBDIRS += designer/src/uitools # Linguist depends on this
- } else {
- SUBDIRS += designer
- }
- SUBDIRS += linguist
- symbian: SUBDIRS = designer
- wince*: SUBDIRS = qtestlib designer
- unix:!mac:!embedded:contains(QT_CONFIG, qt3support):SUBDIRS += qtconfig
- win32:!wince*:SUBDIRS += activeqt
+!contains(QT_CONFIG, no-gui) {
+ no-png {
+ message("Some graphics-related tools are unavailable without PNG support")
+ } else {
+ symbian {
+ SUBDIRS = designer
+ } else:wince* {
+ SUBDIRS = qtestlib designer
+ } else {
+ SUBDIRS = assistant \
+ pixeltool \
+ porting \
+ qtestlib \
+ qttracereplay
+ contains(QT_EDITION, Console) {
+ SUBDIRS += designer/src/uitools # Linguist depends on this
+ } else {
+ SUBDIRS += designer
+ }
+ }
+ unix:!mac:!embedded:contains(QT_CONFIG, qt3support):SUBDIRS += qtconfig
+ win32:!wince*:SUBDIRS += activeqt
+ }
+ contains(QT_CONFIG, declarative):SUBDIRS += qml
}
+!wince*:!symbian:SUBDIRS += linguist
+
mac {
SUBDIRS += macdeployqt
}
embedded:SUBDIRS += kmap2qmap
-contains(QT_CONFIG, declarative):SUBDIRS += qmlviewer qmldebugger
contains(QT_CONFIG, dbus):SUBDIRS += qdbus
# We don't need these command line utilities on embedded platforms.
!wince*:!symbian:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns xmlpatternsvalidator
@@ -36,3 +43,7 @@ embedded: SUBDIRS += makeqpf
CONFIG+=ordered
QTDIR_build:REQUIRES = "contains(QT_CONFIG, full-config)"
+
+!win32:!embedded:!mac:!symbian:CONFIG += x11
+
+x11:contains(QT_CONFIG, opengles2):contains(QT_CONFIG, egl):SUBDIRS += qmeegographicssystemhelper