summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/activeqt/dumpcpp/main.cpp6
-rw-r--r--tools/assistant/compat/helpdialog.ui6
-rw-r--r--tools/assistant/compat/mainwindow.cpp11
-rw-r--r--tools/assistant/lib/qhelpprojectdata.cpp22
-rw-r--r--tools/assistant/tools/assistant/main.cpp2
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp15
-rw-r--r--tools/configure/configure.pro2
-rw-r--r--tools/configure/configureapp.cpp93
-rw-r--r--tools/configure/environment.cpp218
-rw-r--r--tools/configure/main.cpp6
-rw-r--r--tools/configure/tools.cpp4
-rw-r--r--tools/designer/data/generate_shared.xsl4
-rw-r--r--tools/designer/data/ui4.xsd13
-rw-r--r--tools/designer/src/components/buddyeditor/buddyeditor.cpp4
-rw-r--r--tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp4
-rw-r--r--tools/designer/src/components/buddyeditor/buddyeditor_tool.cpp4
-rw-r--r--tools/designer/src/components/formeditor/embeddedoptionspage.cpp4
-rw-r--r--tools/designer/src/components/formeditor/formwindow.cpp9
-rw-r--r--tools/designer/src/components/formeditor/formwindowcursor.cpp4
-rw-r--r--tools/designer/src/components/formeditor/formwindowmanager.cpp4
-rw-r--r--tools/designer/src/components/formeditor/qdesigner_resource.cpp127
-rw-r--r--tools/designer/src/components/formeditor/tool_widgeteditor.cpp4
-rw-r--r--tools/designer/src/components/objectinspector/objectinspector.cpp4
-rw-r--r--tools/designer/src/components/objectinspector/objectinspectormodel.cpp4
-rw-r--r--tools/designer/src/components/propertyeditor/designerpropertymanager.cpp3
-rw-r--r--tools/designer/src/components/propertyeditor/paletteeditor.cpp7
-rw-r--r--tools/designer/src/components/propertyeditor/paletteeditorbutton.cpp4
-rw-r--r--tools/designer/src/components/propertyeditor/previewframe.cpp4
-rw-r--r--tools/designer/src/components/propertyeditor/propertyeditor.cpp9
-rw-r--r--tools/designer/src/components/propertyeditor/stringlisteditorbutton.cpp4
-rw-r--r--tools/designer/src/components/signalsloteditor/connectdialog.ui8
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp4
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp4
-rw-r--r--tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp4
-rw-r--r--tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp4
-rw-r--r--tools/designer/src/components/tabordereditor/tabordereditor_tool.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/button_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/combobox_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/containerwidget_taskmenu.cpp5
-rw-r--r--tools/designer/src/components/taskmenu/groupbox_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/label_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/layouttaskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/lineedit_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/listwidget_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/listwidgeteditor.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/menutaskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/tablewidgeteditor.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/textedit_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/toolbar_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp4
-rw-r--r--tools/designer/src/components/taskmenu/treewidgeteditor.cpp4
-rw-r--r--tools/designer/src/components/widgetbox/widgetbox_dnditem.cpp10
-rw-r--r--tools/designer/src/designer/mainwindow.cpp2
-rw-r--r--tools/designer/src/designer/qdesigner_actions.cpp2
-rw-r--r--tools/designer/src/designer/qdesigner_workbench.cpp2
-rw-r--r--tools/designer/src/designer/versiondialog.cpp6
-rw-r--r--tools/designer/src/lib/sdk/abstractformeditor.cpp12
-rw-r--r--tools/designer/src/lib/sdk/abstractformwindow.cpp14
-rw-r--r--tools/designer/src/lib/sdk/script.cpp6
-rw-r--r--tools/designer/src/lib/shared/actioneditor.cpp4
-rw-r--r--tools/designer/src/lib/shared/codedialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/csshighlighter.cpp4
-rw-r--r--tools/designer/src/lib/shared/formwindowbase.cpp4
-rw-r--r--tools/designer/src/lib/shared/newformwidget.cpp5
-rw-r--r--tools/designer/src/lib/shared/orderdialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/plaintexteditor.cpp4
-rw-r--r--tools/designer/src/lib/shared/pluginmanager.cpp120
-rw-r--r--tools/designer/src/lib/shared/pluginmanager_p.h8
-rw-r--r--tools/designer/src/lib/shared/previewconfigurationwidget.cpp28
-rw-r--r--tools/designer/src/lib/shared/previewmanager.cpp171
-rw-r--r--tools/designer/src/lib/shared/promotionmodel.cpp4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_formbuilder.cpp14
-rw-r--r--tools/designer/src/lib/shared/qdesigner_formbuilder_p.h17
-rw-r--r--tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp104
-rw-r--r--tools/designer/src/lib/shared/qdesigner_stackedbox.cpp11
-rw-r--r--tools/designer/src/lib/shared/qdesigner_tabwidget.cpp12
-rw-r--r--tools/designer/src/lib/shared/qdesigner_taskmenu.cpp4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_toolbar.cpp17
-rw-r--r--tools/designer/src/lib/shared/qdesigner_widgetbox.cpp4
-rw-r--r--tools/designer/src/lib/shared/qsimpleresource.cpp133
-rw-r--r--tools/designer/src/lib/shared/qsimpleresource_p.h17
-rw-r--r--tools/designer/src/lib/shared/qtresourceview.cpp189
-rw-r--r--tools/designer/src/lib/shared/qtresourceview_p.h1
-rw-r--r--tools/designer/src/lib/shared/richtexteditor.cpp4
-rw-r--r--tools/designer/src/lib/shared/scriptdialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/scripterrordialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/stylesheeteditor.cpp4
-rw-r--r--tools/designer/src/lib/shared/widgetfactory.cpp4
-rw-r--r--tools/designer/src/lib/shared/zoomwidget.cpp22
-rw-r--r--tools/designer/src/lib/shared/zoomwidget_p.h9
-rw-r--r--tools/designer/src/lib/uilib/abstractformbuilder.cpp21
-rw-r--r--tools/designer/src/lib/uilib/formbuilder.cpp29
-rw-r--r--tools/designer/src/lib/uilib/formbuilderextra.cpp18
-rw-r--r--tools/designer/src/lib/uilib/formbuilderextra_p.h8
-rw-r--r--tools/designer/src/lib/uilib/ui4.cpp245
-rw-r--r--tools/designer/src/lib/uilib/ui4_p.h97
-rw-r--r--tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp2
-rw-r--r--tools/designer/src/uitools/quiloader.cpp11
-rw-r--r--tools/kmap2qmap/kmap2qmap.pro12
-rw-r--r--tools/kmap2qmap/main.cpp991
-rw-r--r--tools/linguist/lconvert/main.cpp47
-rw-r--r--tools/linguist/linguist/batchtranslation.ui4
-rw-r--r--tools/linguist/linguist/globals.cpp55
-rw-r--r--tools/linguist/linguist/globals.h50
-rw-r--r--tools/linguist/linguist/images/minus.pngbin0 -> 296 bytes
-rw-r--r--tools/linguist/linguist/images/plus.pngbin0 -> 383 bytes
-rw-r--r--tools/linguist/linguist/linguist.pro2
-rw-r--r--tools/linguist/linguist/linguist.qrc2
-rw-r--r--tools/linguist/linguist/main.cpp18
-rw-r--r--tools/linguist/linguist/mainwindow.cpp91
-rw-r--r--tools/linguist/linguist/mainwindow.h8
-rw-r--r--tools/linguist/linguist/mainwindow.ui33
-rw-r--r--tools/linguist/linguist/messageeditor.cpp331
-rw-r--r--tools/linguist/linguist/messageeditor.h39
-rw-r--r--tools/linguist/linguist/messageeditorwidgets.cpp259
-rw-r--r--tools/linguist/linguist/messageeditorwidgets.h58
-rw-r--r--tools/linguist/linguist/phrase.cpp12
-rw-r--r--tools/linguist/linguist/phrasebookbox.cpp6
-rw-r--r--tools/linguist/linguist/phraseview.cpp3
-rw-r--r--tools/linguist/linguist/recentfiles.cpp5
-rw-r--r--tools/linguist/lrelease/lrelease.112
-rw-r--r--tools/linguist/lrelease/main.cpp30
-rw-r--r--tools/linguist/lupdate/cpp.cpp1919
-rw-r--r--tools/linguist/lupdate/java.cpp (renamed from tools/linguist/shared/java.cpp)48
-rw-r--r--tools/linguist/lupdate/lupdate.114
-rw-r--r--tools/linguist/lupdate/lupdate.h (renamed from tools/linguist/shared/translatortools.h)8
-rw-r--r--tools/linguist/lupdate/lupdate.pro15
-rw-r--r--tools/linguist/lupdate/main.cpp119
-rw-r--r--tools/linguist/lupdate/merge.cpp (renamed from tools/linguist/shared/translatortools.cpp)8
-rw-r--r--tools/linguist/lupdate/qscript.cpp (renamed from tools/linguist/shared/qscript.cpp)39
-rw-r--r--tools/linguist/lupdate/qscript.g (renamed from tools/linguist/shared/qscript.g)43
-rw-r--r--tools/linguist/lupdate/ui.cpp (renamed from tools/linguist/shared/ui.cpp)55
-rw-r--r--tools/linguist/phrasebooks/french.qph227
-rw-r--r--tools/linguist/shared/cpp.cpp1098
-rw-r--r--tools/linguist/shared/formats.pri4
-rwxr-xr-xtools/linguist/shared/make-qscript.sh14
-rw-r--r--tools/linguist/shared/po.cpp10
-rw-r--r--tools/linguist/shared/profileevaluator.cpp987
-rw-r--r--tools/linguist/shared/profileevaluator.h5
-rw-r--r--tools/linguist/shared/proparserutils.h49
-rw-r--r--tools/linguist/shared/qm.cpp64
-rw-r--r--tools/linguist/shared/qph.cpp29
-rw-r--r--tools/linguist/shared/translator.cpp20
-rw-r--r--tools/linguist/shared/translator.h20
-rw-r--r--tools/linguist/shared/translatortools.pri11
-rw-r--r--tools/linguist/shared/ts.cpp6
-rw-r--r--tools/linguist/shared/ts.dtd8
-rw-r--r--tools/linguist/shared/xliff.cpp7
-rw-r--r--tools/macdeployqt/macchangeqt/main.cpp32
-rw-r--r--tools/macdeployqt/macdeployqt/main.cpp39
-rw-r--r--tools/macdeployqt/shared/shared.cpp249
-rw-r--r--tools/macdeployqt/shared/shared.h20
-rw-r--r--tools/pixeltool/qpixeltool.cpp4
-rw-r--r--tools/porting/src/logger.cpp6
-rw-r--r--tools/qdbus/qdbusviewer/qdbusviewer.cpp11
-rw-r--r--tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp11
-rw-r--r--tools/qdoc3/codemarker.cpp64
-rw-r--r--tools/qdoc3/codemarker.h8
-rw-r--r--tools/qdoc3/codeparser.cpp27
-rw-r--r--tools/qdoc3/codeparser.h1
-rw-r--r--tools/qdoc3/config.cpp2
-rw-r--r--tools/qdoc3/config.h1
-rw-r--r--tools/qdoc3/cppcodemarker.cpp77
-rw-r--r--tools/qdoc3/cppcodeparser.cpp26
-rw-r--r--tools/qdoc3/doc.cpp1983
-rw-r--r--tools/qdoc3/doc.h177
-rw-r--r--tools/qdoc3/generator.cpp241
-rw-r--r--tools/qdoc3/generator.h12
-rw-r--r--tools/qdoc3/htmlgenerator.cpp1188
-rw-r--r--tools/qdoc3/htmlgenerator.h35
-rw-r--r--tools/qdoc3/javadocgenerator.cpp3
-rw-r--r--tools/qdoc3/javadocgenerator.h2
-rw-r--r--tools/qdoc3/main.cpp70
-rw-r--r--tools/qdoc3/node.cpp12
-rw-r--r--tools/qdoc3/node.h4
-rw-r--r--tools/qdoc3/qdoc3.pro5
-rw-r--r--tools/qdoc3/separator.cpp36
-rw-r--r--tools/qdoc3/separator.h1
-rw-r--r--tools/qdoc3/test/assistant.qdocconf4
-rw-r--r--tools/qdoc3/test/classic.css110
-rw-r--r--tools/qdoc3/test/designer.qdocconf4
-rw-r--r--tools/qdoc3/test/linguist.qdocconf4
-rw-r--r--tools/qdoc3/test/qmake.qdocconf4
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf8
-rw-r--r--tools/qdoc3/test/qt-cpp-ignore.qdocconf6
-rw-r--r--tools/qdoc3/test/qt-inc.qdocconf4
-rw-r--r--tools/qdoc3/test/qt.qdocconf8
-rw-r--r--tools/qdoc3/tree.cpp80
-rw-r--r--tools/qtconfig/mainwindow.cpp4
-rw-r--r--tools/qtconfig/paletteeditoradvanced.cpp2
-rw-r--r--tools/qtestlib/chart/3rdparty/excanvas.js14
-rw-r--r--tools/qtestlib/chart/3rdparty/flotr.js2
-rw-r--r--tools/qtestlib/chart/3rdparty/prototype.js8
-rw-r--r--tools/qtestlib/chart/benchmark_template.html202
-rw-r--r--tools/qtestlib/chart/chart.pro16
-rw-r--r--tools/qtestlib/chart/chart.qrc9
-rw-r--r--tools/qtestlib/chart/chart_template.html110
-rw-r--r--tools/qtestlib/chart/database.cpp321
-rw-r--r--tools/qtestlib/chart/database.h99
-rw-r--r--tools/qtestlib/chart/main.cpp82
-rw-r--r--tools/qtestlib/chart/reportgenerator.cpp561
-rw-r--r--tools/qtestlib/chart/reportgenerator.h63
-rw-r--r--tools/qtestlib/qtestlib.pro2
-rw-r--r--tools/qtestlib/wince/cetest/activesyncconnection.cpp42
-rw-r--r--tools/qtestlib/wince/cetest/deployment.cpp34
-rw-r--r--tools/qtestlib/wince/cetest/main.cpp1
-rw-r--r--tools/qtestlib/wince/cetest/remoteconnection.cpp32
-rw-r--r--tools/qtestlib/wince/cetest/remoteconnection.h2
-rw-r--r--tools/qtestlib/wince/remotelib/commands.cpp10
-rw-r--r--tools/qtestlib/wince/remotelib/commands.h2
-rw-r--r--tools/qvfb/PDAPhone.skin/pda_up.pngbin100615 -> 0 bytes
-rw-r--r--tools/qvfb/config.ui1665
-rw-r--r--tools/qvfb/pda.qrc5
-rw-r--r--tools/qvfb/pda.skin14
-rw-r--r--tools/qvfb/pda_down.pngbin102655 -> 0 bytes
-rw-r--r--tools/qvfb/qvfb.cpp14
-rw-r--r--tools/qvfb/qvfb.pro12
-rw-r--r--tools/qvfb/qvfbview.cpp66
-rw-r--r--tools/qvfb/qvfbview.h5
-rw-r--r--tools/shared/deviceskin/deviceskin.pri12
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.qrc (renamed from tools/qvfb/ClamshellPhone.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin (renamed from tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin)0
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png (renamed from tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png)bin68200 -> 68200 bytes
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png (renamed from tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png)bin113907 -> 113907 bytes
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png (renamed from tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png)bin113450 -> 113450 bytes
-rw-r--r--tools/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf (renamed from tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png (renamed from tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png)bin115575 -> 115575 bytes
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png (renamed from tools/qvfb/DualScreenPhone.skin/DualScreen.png)bin104711 -> 104711 bytes
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin (renamed from tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin)0
-rw-r--r--tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf (renamed from tools/qvfb/SmartPhone.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.qrc (renamed from tools/qvfb/PDAPhone.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin (renamed from tools/qvfb/PDAPhone.skin/PDAPhone.skin)0
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf (renamed from tools/qvfb/PDAPhone.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/finger.png (renamed from tools/qvfb/PDAPhone.skin/finger.png)bin40343 -> 40343 bytes
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png (renamed from tools/qvfb/PDAPhone.skin/pda_down.png)bin52037 -> 52037 bytes
-rw-r--r--tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png (renamed from tools/qvfb/pda_up.png)bin100615 -> 100615 bytes
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.qrc (renamed from tools/qvfb/PortableMedia.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin (renamed from tools/qvfb/PortableMedia.skin/PortableMedia.skin)0
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf (renamed from tools/qvfb/PortableMedia.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png (renamed from tools/qvfb/PortableMedia.skin/portablemedia-pressed.png)bin6183 -> 6183 bytes
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png (renamed from tools/qvfb/PortableMedia.skin/portablemedia.png)bin6182 -> 6182 bytes
-rw-r--r--tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf (renamed from tools/qvfb/PortableMedia.skin/portablemedia.xcf)bin41592 -> 41592 bytes
-rw-r--r--tools/shared/deviceskin/skins/S60-QVGA-Candybar.qrc5
-rw-r--r--tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.pngbin0 -> 161184 bytes
-rw-r--r--tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.pngbin0 -> 156789 bytes
-rw-r--r--tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin15
-rw-r--r--tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf78
-rw-r--r--tools/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc5
-rw-r--r--tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.pngbin0 -> 241501 bytes
-rw-r--r--tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.pngbin0 -> 240615 bytes
-rw-r--r--tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin10
-rw-r--r--tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf (renamed from tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone.qrc (renamed from tools/qvfb/SmartPhone.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png (renamed from tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png)bin111515 -> 111515 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png (renamed from tools/qvfb/SmartPhone.skin/SmartPhone.png)bin101750 -> 101750 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin (renamed from tools/qvfb/SmartPhone.skin/SmartPhone.skin)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf (renamed from tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone2.qrc (renamed from tools/qvfb/SmartPhone2.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png (renamed from tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png)bin134749 -> 134749 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png (renamed from tools/qvfb/SmartPhone2.skin/SmartPhone2.png)bin121915 -> 121915 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin (renamed from tools/qvfb/SmartPhone2.skin/SmartPhone2.skin)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf (renamed from tools/qvfb/SmartPhone2.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhoneWithButtons.qrc (renamed from tools/qvfb/SmartPhoneWithButtons.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png (renamed from tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png)bin103838 -> 103838 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png (renamed from tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png)bin88470 -> 88470 bytes
-rw-r--r--tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin (renamed from tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin)0
-rw-r--r--tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf (renamed from tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/TouchscreenPhone.qrc (renamed from tools/qvfb/TouchscreenPhone.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png (renamed from tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png)bin88599 -> 88599 bytes
-rw-r--r--tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png (renamed from tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png)bin61809 -> 61809 bytes
-rw-r--r--tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin (renamed from tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin)0
-rw-r--r--tools/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf (renamed from tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.qrc (renamed from tools/qvfb/Trolltech-Keypad.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png (renamed from tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png)bin69447 -> 69447 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png (renamed from tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png)bin242107 -> 242107 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png (renamed from tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png)bin230638 -> 230638 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin (renamed from tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf (renamed from tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc (renamed from tools/qvfb/Trolltech-Touchscreen.qrc)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png (renamed from tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png)bin133117 -> 133117 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png (renamed from tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png)bin133180 -> 133180 bytes
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin (renamed from tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin)0
-rw-r--r--tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf53
-rw-r--r--tools/shared/qtgradienteditor/qtgradientdialog.cpp4
-rw-r--r--tools/shared/qtgradienteditor/qtgradienteditor.cpp4
-rw-r--r--tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp4
-rw-r--r--tools/shared/qttoolbardialog/qttoolbardialog.cpp6
-rw-r--r--tools/tools.pro2
-rw-r--r--tools/xmlpatterns/main.cpp2
291 files changed, 10615 insertions, 6579 deletions
diff --git a/tools/activeqt/dumpcpp/main.cpp b/tools/activeqt/dumpcpp/main.cpp
index 0a4aa06..de3ec57 100644
--- a/tools/activeqt/dumpcpp/main.cpp
+++ b/tools/activeqt/dumpcpp/main.cpp
@@ -969,7 +969,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
QString libName;
BSTR nameString;
typelib->GetDocumentation(-1, &nameString, 0, 0, 0);
- libName = QString::fromUtf16((const ushort *)nameString);
+ libName = QString::fromWCharArray(nameString);
SysFreeString(nameString);
if (!nameSpace.isEmpty())
libName = QString(nameSpace);
@@ -1086,7 +1086,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
BSTR bstr;
if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0))
break;
- className = QString::fromUtf16((const ushort *)bstr).toLatin1();
+ className = QString::fromWCharArray(bstr).toLatin1();
SysFreeString(bstr);
switch (typekind) {
case TKIND_RECORD:
@@ -1227,7 +1227,7 @@ bool generateTypeLibrary(const QByteArray &typeLib, const QByteArray &outname, O
BSTR bstr;
if (S_OK != typeinfo->GetDocumentation(-1, &bstr, 0, 0, 0))
break;
- className = QString::fromUtf16((const ushort *)bstr).toLatin1();
+ className = QString::fromWCharArray(bstr).toLatin1();
SysFreeString(bstr);
declOut << "// stub for vtable-only interface" << endl;
diff --git a/tools/assistant/compat/helpdialog.ui b/tools/assistant/compat/helpdialog.ui
index 54acc30..6c95418 100644
--- a/tools/assistant/compat/helpdialog.ui
+++ b/tools/assistant/compat/helpdialog.ui
@@ -269,7 +269,7 @@
<item row="1" column="0" >
<widget class="QLineEdit" name="termsEdit" >
<property name="toolTip" >
- <string>Enter searchword(s).</string>
+ <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>
@@ -307,7 +307,7 @@
<item>
<widget class="QPushButton" name="helpButton" >
<property name="toolTip" >
- <string>Display the help page.</string>
+ <string>Display the help page</string>
</property>
<property name="whatsThis" >
<string>Display the help page for the full text search.</string>
@@ -336,7 +336,7 @@
<item>
<widget class="QPushButton" name="searchButton" >
<property name="toolTip" >
- <string>Start searching.</string>
+ <string>Start searching</string>
</property>
<property name="whatsThis" >
<string>Pressing this button starts the search.</string>
diff --git a/tools/assistant/compat/mainwindow.cpp b/tools/assistant/compat/mainwindow.cpp
index d3e74fe..670b144 100644
--- a/tools/assistant/compat/mainwindow.cpp
+++ b/tools/assistant/compat/mainwindow.cpp
@@ -312,21 +312,14 @@ void MainWindow::about()
{
QMessageBox box(this);
- // TODO: Remove these variables for 4.6.0. Must keep this way for 4.5.x due to string freeze.
- QString edition;
- QString info;
- QString moreInfo;
-
box.setText(QString::fromLatin1("<center><img src=\":/trolltech/assistant/images/assistant-128.png\">"
"<h3>%1</h3>"
- "<p>Version %2 %3</p></center>"
- "<p>%4</p>"
- "<p>%5</p>"
+ "<p>Version %2</p></center>"
"<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p>"
"<p>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
" INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
" PARTICULAR PURPOSE.<p/>")
- .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)).arg(edition).arg(info).arg(moreInfo));
+ .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)));
box.setWindowTitle(tr("Qt Assistant"));
box.setIcon(QMessageBox::NoIcon);
box.exec();
diff --git a/tools/assistant/lib/qhelpprojectdata.cpp b/tools/assistant/lib/qhelpprojectdata.cpp
index 8947a36..55b4ea7 100644
--- a/tools/assistant/lib/qhelpprojectdata.cpp
+++ b/tools/assistant/lib/qhelpprojectdata.cpp
@@ -41,6 +41,7 @@
#include "qhelpprojectdata_p.h"
+#include <QtCore/QDir>
#include <QtCore/QFileInfo>
#include <QtCore/QStack>
#include <QtCore/QMap>
@@ -73,6 +74,7 @@ private:
void readKeywords();
void readFiles();
void raiseUnknownTokenError();
+ void addMatchingFiles(const QString &pattern);
};
void QHelpProjectDataPrivate::raiseUnknownTokenError()
@@ -161,7 +163,7 @@ void QHelpProjectDataPrivate::readFilterSection()
readNext();
if (isStartElement()) {
if (name() == QLatin1String("filterAttribute"))
- filterSectionList.last().addFilterAttribute(readElementText());
+ filterSectionList.last().addFilterAttribute(readElementText());
else if (name() == QLatin1String("toc"))
readTOC();
else if (name() == QLatin1String("keywords"))
@@ -244,7 +246,7 @@ void QHelpProjectDataPrivate::readFiles()
readNext();
if (isStartElement()) {
if (name() == QLatin1String("file"))
- filterSectionList.last().addFile(readElementText());
+ addMatchingFiles(readElementText());
else
raiseUnknownTokenError();
} else if (isEndElement()) {
@@ -258,7 +260,21 @@ void QHelpProjectDataPrivate::readFiles()
}
}
-
+// Expand file pattern and add matches into list. If the pattern does not match
+// any files, insert the pattern itself so the QHelpGenerator will emit a
+// meaningful warning later.
+void QHelpProjectDataPrivate::addMatchingFiles(const QString &pattern)
+{
+ QFileInfo fileInfo(rootPath + '/' + pattern);
+ const QStringList &matches =
+ fileInfo.dir().entryList(QStringList(fileInfo.fileName()));
+ for (QStringList::ConstIterator it = matches.constBegin();
+ it != matches.constEnd();
+ ++it)
+ filterSectionList.last().addFile(QFileInfo(pattern).dir().path() + '/' + *it);
+ if (matches.empty())
+ filterSectionList.last().addFile(pattern);
+}
/*!
\internal
diff --git a/tools/assistant/tools/assistant/main.cpp b/tools/assistant/tools/assistant/main.cpp
index 55e929a..05355d9 100644
--- a/tools/assistant/tools/assistant/main.cpp
+++ b/tools/assistant/tools/assistant/main.cpp
@@ -230,7 +230,7 @@ int main(int argc, char *argv[])
if (file.isEmpty())
file = MainWindow::defaultHelpCollectionFileName();
QString path = QFileInfo(file).path();
- path += QLatin1String("/") + indexFilesFolder(file);
+ path += QLatin1Char('/') + indexFilesFolder(file);
QLocalSocket localSocket;
localSocket.connectToServer(QString(QLatin1String("QtAssistant%1"))
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
index 0340297..617ac4d 100644
--- a/tools/assistant/tools/assistant/mainwindow.cpp
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -442,7 +442,7 @@ void MainWindow::setupActions()
m_closeTabAction->setShortcuts(QKeySequence::Close);
QAction *tmp = menu->addAction(tr("&Quit"), this, SLOT(close()));
- tmp->setShortcut(tr("CTRL+Q"));
+ tmp->setShortcut(QKeySequence::Quit);
tmp->setMenuRole(QAction::QuitRole);
menu = menuBar()->addMenu(tr("&Edit"));
@@ -828,23 +828,16 @@ void MainWindow::showAboutDialog()
aboutDia.setPixmap(pix);
aboutDia.setWindowTitle(aboutDia.documentTitle());
} else {
- // TODO: Remove these variables for 4.6.0. Must keep this way for 4.5.x due to string freeze.
- QString edition;
- QString info;
- QString moreInfo;
-
QByteArray resources;
aboutDia.setText(QString::fromLatin1("<center>"
"<h3>%1</h3>"
- "<p>Version %2 %3</p></center>"
- "<p>%4</p>"
- "<p>%5</p>"
+ "<p>Version %2</p></center>"
"<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)"
".</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
" INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
" PARTICULAR PURPOSE.<p/>")
- .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR))
- .arg(edition).arg(info).arg(moreInfo), resources);
+ .arg(tr("Qt Assistant")).arg(QLatin1String(QT_VERSION_STR)),
+ resources);
QLatin1String path(":/trolltech/assistant/images/assistant-128.png");
aboutDia.setPixmap(QString(path));
}
diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro
index 1ce9a1b..fdeab29 100644
--- a/tools/configure/configure.pro
+++ b/tools/configure/configure.pro
@@ -3,7 +3,7 @@ DESTDIR = ../..
CONFIG += console flat
CONFIG -= moc qt
-DEFINES = QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE
+DEFINES = UNICODE QT_NODLL QT_NO_CODECS QT_NO_TEXTCODEC QT_NO_UNICODETABLES QT_LITE_COMPONENT QT_NO_STL QT_NO_COMPRESS QT_BUILD_QMAKE QT_NO_THREAD QT_NO_QOBJECT _CRT_SECURE_NO_DEPRECATE
win32 : LIBS += -lole32 -ladvapi32
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 1e501c5..80cfc64 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -116,16 +116,9 @@ Configure::Configure( int& argc, char** argv )
// Get the path to the executable
- QFileInfo sourcePathInfo;
- QT_WA({
- unsigned short module_name[256];
- GetModuleFileNameW(0, reinterpret_cast<wchar_t *>(module_name), sizeof(module_name));
- sourcePathInfo = QString::fromUtf16(module_name);
- }, {
- char module_name[256];
- GetModuleFileNameA(0, module_name, sizeof(module_name));
- sourcePathInfo = QString::fromLocal8Bit(module_name);
- });
+ wchar_t module_name[MAX_PATH];
+ GetModuleFileName(0, module_name, sizeof(module_name) / sizeof(wchar_t));
+ QFileInfo sourcePathInfo = QString::fromWCharArray(module_name);
sourcePath = sourcePathInfo.absolutePath();
sourceDir = sourcePathInfo.dir();
buildPath = QDir::currentPath();
@@ -314,7 +307,6 @@ Configure::Configure( int& argc, char** argv )
dictionary[ "QT3SUPPORT" ] = "yes";
dictionary[ "ACCESSIBILITY" ] = "yes";
dictionary[ "OPENGL" ] = "yes";
- dictionary[ "DIRECT3D" ] = "auto";
dictionary[ "IPV6" ] = "yes"; // Always, dynamicly loaded
dictionary[ "OPENSSL" ] = "auto";
dictionary[ "DBUS" ] = "auto";
@@ -605,10 +597,13 @@ void Configure::parseCmdLine()
// cetest ---------------------------------------------------
else if (configCmdLine.at(i) == "-no-cetest") {
dictionary[ "CETEST" ] = "no";
+ dictionary[ "CETEST_REQUESTED" ] = "no";
} else if (configCmdLine.at(i) == "-cetest") {
// although specified to use it, we stay at "auto" state
// this is because checkAvailability() adds variables
- // we need for crosscompilation
+ // we need for crosscompilation; but remember if we asked
+ // for it.
+ dictionary[ "CETEST_REQUESTED" ] = "yes";
}
// Qt/CE - signing tool -------------------------------------
else if( configCmdLine.at(i) == "-signature") {
@@ -824,11 +819,7 @@ void Configure::parseCmdLine()
else if (configCmdLine.at(i) == "-iwmmxt")
dictionary[ "IWMMXT" ] = "yes";
- else if (configCmdLine.at(i) == "-no-direct3d") {
- dictionary["DIRECT3D"] = "no";
- }else if (configCmdLine.at(i) == "-direct3d") {
- dictionary["DIRECT3D"] = "auto"; // have to pass auto detection to enable Direct3D
- } else if( configCmdLine.at(i) == "-no-openssl" ) {
+ else if( configCmdLine.at(i) == "-no-openssl" ) {
dictionary[ "OPENSSL"] = "no";
} else if( configCmdLine.at(i) == "-openssl" ) {
dictionary[ "OPENSSL" ] = "yes";
@@ -1144,6 +1135,10 @@ void Configure::parseCmdLine()
useUnixSeparators = (dictionary["QMAKESPEC"] == "win32-g++");
+ // Allow tests for private classes to be compiled against internal builds
+ if (dictionary["BUILDDEV"] == "yes")
+ qtConfig += "private_tests";
+
#if !defined(EVAL)
for( QStringList::Iterator dis = disabledModules.begin(); dis != disabledModules.end(); ++dis ) {
@@ -1327,7 +1322,6 @@ void Configure::applySpecSpecifics()
dictionary[ "MMX" ] = "no";
dictionary[ "IWMMXT" ] = "no";
dictionary[ "CE_CRT" ] = "yes";
- dictionary[ "DIRECT3D" ] = "no";
dictionary[ "WEBKIT" ] = "no";
dictionary[ "PHONON" ] = "yes";
dictionary[ "DIRECTSHOW" ] = "no";
@@ -1427,7 +1421,7 @@ bool Configure::displayHelp()
"[-system-libtiff] [-no-libjpeg] [-qt-libjpeg] [-system-libjpeg]\n"
"[-no-libmng] [-qt-libmng] [-system-libmng] [-no-qt3support] [-mmx]\n"
"[-no-mmx] [-3dnow] [-no-3dnow] [-sse] [-no-sse] [-sse2] [-no-sse2]\n"
- "[-no-iwmmxt] [-iwmmxt] [-direct3d] [-openssl] [-openssl-linked]\n"
+ "[-no-iwmmxt] [-iwmmxt] [-openssl] [-openssl-linked]\n"
"[-no-openssl] [-no-dbus] [-dbus] [-dbus-linked] [-platform <spec>]\n"
"[-qtnamespace <namespace>] [-qtlibinfix <infix>] [-no-phonon]\n"
"[-phonon] [-no-phonon-backend] [-phonon-backend]\n"
@@ -1595,7 +1589,6 @@ bool Configure::displayHelp()
desc("SSE", "yes", "-sse", "Compile with use of SSE instructions");
desc("SSE2", "no", "-no-sse2", "Do not compile with use of SSE2 instructions");
desc("SSE2", "yes", "-sse2", "Compile with use of SSE2 instructions");
- desc("DIRECT3D", "yes", "-direct3d", "Compile in Direct3D support (experimental - see INSTALL for more info)");
desc("OPENSSL", "no", "-no-openssl", "Do not compile in OpenSSL support");
desc("OPENSSL", "yes", "-openssl", "Compile in run-time OpenSSL support");
desc("OPENSSL", "linked","-openssl-linked", "Compile in linked OpenSSL support");
@@ -1831,6 +1824,11 @@ bool Configure::checkAvailability(const QString &part)
dictionary[ "QT_CE_RAPI_INC" ] += QLatin1String("\"") + rapiHeader + QLatin1String("\"");
dictionary[ "QT_CE_RAPI_LIB" ] += QLatin1String("\"") + rapiLib + QLatin1String("\"");
}
+ else if (dictionary[ "CETEST_REQUESTED" ] == "yes") {
+ cout << "cetest could not be enabled: rapi.h and rapi.lib could not be found." << endl;
+ cout << "Make sure the environment is set up for compiling with ActiveSync." << endl;
+ dictionary[ "DONE" ] = "error";
+ }
}
else if (part == "INCREDIBUILD_XGE")
available = findFile("BuildConsole.exe") && findFile("xgConsole.exe");
@@ -1841,47 +1839,6 @@ bool Configure::checkAvailability(const QString &part)
&& dictionary.value("QMAKESPEC") != "win32-msvc.net" // Leave for now, since we can't be sure if they are using 2002 or 2003 with this spec
&& dictionary.value("QMAKESPEC") != "win32-msvc2002"
&& dictionary.value("EXCEPTIONS") == "yes";
- } else if (part == "DIRECT3D") {
- QString sdk_dir(QString::fromLocal8Bit(getenv("DXSDK_DIR")));
- QDir dir;
- bool has_d3d = false;
-
- if (!sdk_dir.isEmpty() && dir.exists(sdk_dir))
- has_d3d = true;
-
- if (has_d3d && !QFile::exists(sdk_dir + QLatin1String("\\include\\d3d9.h"))) {
- cout << "No Direct3D version 9 SDK found." << endl;
- has_d3d = false;
- }
-
- // find the first dxguid.lib in the current LIB paths, if it is NOT
- // the D3D SDK one, we're most likely in trouble..
- if (has_d3d) {
- has_d3d = false;
- QString env_lib(QString::fromLocal8Bit(getenv("LIB")));
- QStringList lib_paths = env_lib.split(';');
- for (int i=0; i<lib_paths.size(); ++i) {
- QString lib_path = lib_paths.at(i);
- if (QFile::exists(lib_path + QLatin1String("\\dxguid.lib")))
- {
- if (lib_path.startsWith(sdk_dir)) {
- has_d3d = true;
- } else {
- cout << "Your D3D/Platform SDK library paths seem to appear in the wrong order." << endl;
- }
- break;
- }
- }
- }
-
- available = has_d3d;
- if (!has_d3d) {
- cout << "Setting Direct3D to NO, since the proper Direct3D SDK was not detected." << endl
- << "Make sure you have the Direct3D SDK installed, and that you have run" << endl
- << "the <path to SDK>\\Utilities\\Bin\\dx_setenv.cmd script." << endl
- << "The D3D SDK library path *needs* to appear before the Platform SDK library" << endl
- << "path in your LIB environment variable." << endl;
- }
} else if (part == "PHONON") {
available = findFile("vmr9.h") && findFile("dshow.h") && findFile("strmiids.lib") &&
findFile("dmoguids.lib") && findFile("msdmo.lib") && findFile("d3d9.h");
@@ -1975,8 +1932,6 @@ void Configure::autoDetection()
dictionary["SCRIPTTOOLS"] = checkAvailability("SCRIPTTOOLS") ? "yes" : "no";
if (dictionary["XMLPATTERNS"] == "auto")
dictionary["XMLPATTERNS"] = checkAvailability("XMLPATTERNS") ? "yes" : "no";
- if (dictionary["DIRECT3D"] == "auto")
- dictionary["DIRECT3D"] = checkAvailability("DIRECT3D") ? "yes" : "no";
if (dictionary["PHONON"] == "auto")
dictionary["PHONON"] = checkAvailability("PHONON") ? "yes" : "no";
if (dictionary["WEBKIT"] == "auto")
@@ -2046,7 +2001,6 @@ bool Configure::verifyConfiguration()
no-gif gif
dll staticlib
- internal
nocrosscompiler
GNUmake
largefile
@@ -2301,9 +2255,6 @@ void Configure::generateOutputVars()
if ( dictionary["DIRECTSHOW"] == "yes" )
qtConfig += "directshow";
- if (dictionary[ "DIRECT3D" ] == "yes")
- qtConfig += "direct3d";
-
if (dictionary[ "OPENSSL" ] == "yes")
qtConfig += "openssl";
else if (dictionary[ "OPENSSL" ] == "linked")
@@ -2688,7 +2639,6 @@ void Configure::generateConfigfiles()
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["DIRECT3D"] == "no") qconfigList += "QT_NO_DIRECT3D";
if(dictionary["OPENSSL"] == "no") qconfigList += "QT_NO_OPENSSL";
if(dictionary["OPENSSL"] == "linked") qconfigList += "QT_LINKED_OPENSSL";
if(dictionary["DBUS"] == "no") qconfigList += "QT_NO_DBUS";
@@ -2779,7 +2729,7 @@ void Configure::generateConfigfiles()
tmpFile.flush();
// Replace old qconfig.h with new one
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL);
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL);
QFile::remove(outName);
tmpFile.copy(outName);
tmpFile.close();
@@ -2815,7 +2765,7 @@ void Configure::generateConfigfiles()
}
outName = defSpec + "/qmake.conf";
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
QFile qmakeConfFile(outName);
if (qmakeConfFile.open(QFile::Append | QFile::WriteOnly | QFile::Text)) {
QTextStream qmakeConfStream;
@@ -2883,7 +2833,7 @@ void Configure::generateConfigfiles()
tmpFile2.flush();
// Replace old qconfig.cpp with new one
- ::SetFileAttributesA(outName.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL );
+ ::SetFileAttributes((wchar_t*)outName.utf16(), FILE_ATTRIBUTE_NORMAL );
QFile::remove( outName );
tmpFile2.copy(outName);
tmpFile2.close();
@@ -2949,7 +2899,6 @@ void Configure::displayConfig()
cout << "SSE2 support................" << dictionary[ "SSE2" ] << endl;
cout << "IWMMXT support.............." << dictionary[ "IWMMXT" ] << endl;
cout << "OpenGL support.............." << dictionary[ "OPENGL" ] << endl;
- cout << "Direct3D support............" << dictionary[ "DIRECT3D" ] << endl;
cout << "OpenSSL support............." << dictionary[ "OPENSSL" ] << endl;
cout << "QtDBus support.............." << dictionary[ "DBUS" ] << endl;
cout << "QtXmlPatterns support......." << dictionary[ "XMLPATTERNS" ] << endl;
diff --git a/tools/configure/environment.cpp b/tools/configure/environment.cpp
index 6dc8940..b4c61f8 100644
--- a/tools/configure/environment.cpp
+++ b/tools/configure/environment.cpp
@@ -146,26 +146,14 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
QString rSubkeyPath = keyPath(rSubkey);
HKEY handle = 0;
- LONG res;
- QT_WA( {
- res = RegOpenKeyExW(parentHandle, (WCHAR*)rSubkeyPath.utf16(),
- 0, KEY_READ, &handle);
- } , {
- res = RegOpenKeyExA(parentHandle, rSubkeyPath.toLocal8Bit(),
- 0, KEY_READ, &handle);
- } );
-
+ LONG res = RegOpenKeyEx(parentHandle, (wchar_t*)rSubkeyPath.utf16(), 0, KEY_READ, &handle);
if (res != ERROR_SUCCESS)
return QString();
// get the size and type of the value
DWORD dataType;
DWORD dataSize;
- QT_WA( {
- res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
- }, {
- res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, &dataType, 0, &dataSize);
- } );
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, &dataType, 0, &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
return QString();
@@ -173,13 +161,8 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
// get the value
QByteArray data(dataSize, 0);
- QT_WA( {
- res = RegQueryValueExW(handle, (WCHAR*)rSubkeyName.utf16(), 0, 0,
- reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- }, {
- res = RegQueryValueExA(handle, rSubkeyName.toLocal8Bit(), 0, 0,
- reinterpret_cast<unsigned char*>(data.data()), &dataSize);
- } );
+ res = RegQueryValueEx(handle, (wchar_t*)rSubkeyName.utf16(), 0, 0,
+ reinterpret_cast<unsigned char*>(data.data()), &dataSize);
if (res != ERROR_SUCCESS) {
RegCloseKey(handle);
return QString();
@@ -189,11 +172,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
switch (dataType) {
case REG_EXPAND_SZ:
case REG_SZ: {
- QT_WA( {
- result = QString::fromUtf16(((const ushort*)data.constData()));
- }, {
- result = QString::fromLatin1(data.constData());
- } );
+ result = QString::fromWCharArray(((const wchar_t *)data.constData()));
break;
}
@@ -201,29 +180,20 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
QStringList l;
int i = 0;
for (;;) {
- QString s;
- QT_WA( {
- s = QString::fromUtf16((const ushort*)data.constData() + i);
- }, {
- s = QString::fromLatin1(data.constData() + i);
- } );
+ QString s = QString::fromWCharArray((const wchar_t *)data.constData() + i);
i += s.length() + 1;
if (s.isEmpty())
break;
l.append(s);
}
- result = l.join(", ");
+ result = l.join(", ");
break;
}
case REG_NONE:
case REG_BINARY: {
- QT_WA( {
- result = QString::fromUtf16((const ushort*)data.constData(), data.size()/2);
- }, {
- result = QString::fromLatin1(data.constData(), data.size());
- } );
+ result = QString::fromWCharArray((const wchar_t *)data.constData(), data.size() / 2);
break;
}
@@ -232,7 +202,7 @@ QString Environment::readRegistryKey(HKEY parentHandle, const QString &rSubkey)
Q_ASSERT(data.size() == sizeof(int));
int i;
memcpy((char*)&i, data.constData(), sizeof(int));
- result = QString::number(i);
+ result = QString::number(i);
break;
}
@@ -350,29 +320,14 @@ bool Environment::detectExecutable(const QString &executable)
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
- bool couldExecute;
- QT_WA({
- // Unicode version
- STARTUPINFOW startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
-
- couldExecute = CreateProcessW(0, (WCHAR*)executable.utf16(),
- 0, 0, false,
- CREATE_NO_WINDOW | CREATE_SUSPENDED,
- 0, 0, &startInfo, &procInfo);
-
- }, {
- // Ansi version
- STARTUPINFOA startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
+ STARTUPINFO startInfo;
+ memset(&startInfo, 0, sizeof(startInfo));
+ startInfo.cb = sizeof(startInfo);
- couldExecute = CreateProcessA(0, executable.toLocal8Bit().data(),
+ bool couldExecute = CreateProcess(0, (wchar_t*)executable.utf16(),
0, 0, false,
CREATE_NO_WINDOW | CREATE_SUSPENDED,
0, 0, &startInfo, &procInfo);
- })
if (couldExecute) {
CloseHandle(procInfo.hThread);
@@ -421,61 +376,38 @@ static QString qt_create_commandline(const QString &program, const QStringList &
}
/*!
- Creates a QByteArray of the \a environment in either UNICODE or
- ansi representation.
+ Creates a QByteArray of the \a environment.
*/
static QByteArray qt_create_environment(const QStringList &environment)
{
QByteArray envlist;
- if (!environment.isEmpty()) {
- int pos = 0;
- // add PATH if necessary (for DLL loading)
- QByteArray path = qgetenv("PATH");
- QT_WA({
- if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty()
- && !path.isNull()) {
- QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path));
- uint tmpSize = sizeof(TCHAR) * (tmp.length()+1);
- envlist.resize(envlist.size() + tmpSize );
- memcpy(envlist.data()+pos, tmp.utf16(), tmpSize);
- pos += tmpSize;
- }
- // add the user environment
- for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) {
- QString tmp = *it;
- uint tmpSize = sizeof(TCHAR) * (tmp.length()+1);
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.utf16(), tmpSize);
- pos += tmpSize;
- }
- // add the 2 terminating 0 (actually 4, just to be on the safe side)
- envlist.resize( envlist.size()+4 );
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- }, {
- if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) {
- QByteArray tmp = QString("PATH=%1").arg(QString::fromLocal8Bit(path)).toLocal8Bit();
- uint tmpSize = tmp.length() + 1;
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.data(), tmpSize);
- pos += tmpSize;
- }
- // add the user environment
- for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++) {
- QByteArray tmp = (*it).toLocal8Bit();
- uint tmpSize = tmp.length() + 1;
- envlist.resize(envlist.size() + tmpSize);
- memcpy(envlist.data()+pos, tmp.data(), tmpSize);
- pos += tmpSize;
- }
- // add the terminating 0 (actually 2, just to be on the safe side)
- envlist.resize(envlist.size()+2);
- envlist[pos++] = 0;
- envlist[pos++] = 0;
- })
+ if (environment.isEmpty())
+ return envlist;
+
+ int pos = 0;
+ // add PATH if necessary (for DLL loading)
+ QByteArray path = qgetenv("PATH");
+ if (environment.filter(QRegExp("^PATH=",Qt::CaseInsensitive)).isEmpty() && !path.isNull()) {
+ QString tmp = QString(QLatin1String("PATH=%1")).arg(QString::fromLocal8Bit(path));
+ uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
+ envlist.resize(envlist.size() + tmpSize);
+ memcpy(envlist.data() + pos, tmp.utf16(), tmpSize);
+ pos += tmpSize;
}
+ // add the user environment
+ for (QStringList::ConstIterator it = environment.begin(); it != environment.end(); it++ ) {
+ QString tmp = *it;
+ uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
+ envlist.resize(envlist.size() + tmpSize);
+ memcpy(envlist.data() + pos, tmp.utf16(), tmpSize);
+ pos += tmpSize;
+ }
+ // add the 2 terminating 0 (actually 4, just to be on the safe side)
+ envlist.resize(envlist.size() + 4);
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
+ envlist[pos++] = 0;
return envlist;
}
@@ -501,46 +433,24 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
qDebug() << " " << additionalEnv;
qDebug() << " " << removeEnv;
#endif
-// GetEnvironmentStrings is defined to GetEnvironmentStringsW when
-// UNICODE is defined. We cannot use that, since we need to
-// destinguish between unicode and ansi versions of the functions.
-#if defined(UNICODE) && defined(GetEnvironmentStrings)
-#undef GetEnvironmentStrings
-#endif
-
// Create the full environment from the current environment and
// the additionalEnv strings, then remove all variables defined
// in removeEnv
QMap<QString, QString> fullEnvMap;
- QT_WA({
- LPWSTR envStrings = GetEnvironmentStringsW();
- if (envStrings) {
- int strLen = 0;
- for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) {
- strLen = wcslen(envString);
- QString str = QString((const QChar*)envString, strLen);
- if (!str.startsWith("=")) { // These are added by the system
- int sepIndex = str.indexOf('=');
- fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
- }
- }
- }
- FreeEnvironmentStringsW(envStrings);
- }, {
- LPSTR envStrings = GetEnvironmentStrings();
- if (envStrings) {
- int strLen = 0;
- for (LPSTR envString = envStrings; *(envString); envString += strLen + 1) {
- strLen = strlen(envString);
- QString str = QLatin1String(envString);
- if (!str.startsWith("=")) { // These are added by the system
- int sepIndex = str.indexOf('=');
- fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
- }
+ LPWSTR envStrings = GetEnvironmentStrings();
+ if (envStrings) {
+ int strLen = 0;
+ for (LPWSTR envString = envStrings; *(envString); envString += strLen + 1) {
+ strLen = wcslen(envString);
+ QString str = QString((const QChar*)envString, strLen);
+ if (!str.startsWith("=")) { // These are added by the system
+ int sepIndex = str.indexOf('=');
+ fullEnvMap.insert(str.left(sepIndex).toUpper(), str.mid(sepIndex +1));
}
}
- FreeEnvironmentStringsA(envStrings);
- })
+ }
+ FreeEnvironmentStrings(envStrings);
+
// Add additionalEnv variables
for (int i = 0; i < additionalEnv.count(); ++i) {
const QString &str = additionalEnv.at(i);
@@ -569,28 +479,14 @@ int Environment::execute(QStringList arguments, const QStringList &additionalEnv
PROCESS_INFORMATION procInfo;
memset(&procInfo, 0, sizeof(procInfo));
- bool couldExecute;
- QT_WA({
- // Unicode version
- STARTUPINFOW startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
+ STARTUPINFO startInfo;
+ memset(&startInfo, 0, sizeof(startInfo));
+ startInfo.cb = sizeof(startInfo);
- couldExecute = CreateProcessW(0, (WCHAR*)args.utf16(),
+ bool couldExecute = CreateProcess(0, (wchar_t*)args.utf16(),
0, 0, true, CREATE_UNICODE_ENVIRONMENT,
envlist.isEmpty() ? 0 : envlist.data(),
0, &startInfo, &procInfo);
- }, {
- // Ansi version
- STARTUPINFOA startInfo;
- memset(&startInfo, 0, sizeof(startInfo));
- startInfo.cb = sizeof(startInfo);
-
- couldExecute = CreateProcessA(0, args.toLocal8Bit().data(),
- 0, 0, true, 0,
- envlist.isEmpty() ? 0 : envlist.data(),
- 0, &startInfo, &procInfo);
- })
if (couldExecute) {
WaitForSingleObject(procInfo.hProcess, INFINITE);
@@ -654,7 +550,7 @@ bool Environment::cpdir(const QString &srcDir, const QString &destDir)
#endif
QFile::remove(destFile);
intermediate = QFile::copy(entry.absoluteFilePath(), destFile);
- SetFileAttributesA(destFile.toLocal8Bit(), FILE_ATTRIBUTE_NORMAL);
+ SetFileAttributes((wchar_t*)destFile.utf16(), FILE_ATTRIBUTE_NORMAL);
}
if(!intermediate) {
qDebug() << "cpdir: Failure for " << entry.fileName() << entry.isDir();
diff --git a/tools/configure/main.cpp b/tools/configure/main.cpp
index 4f379d7..0e13c7a 100644
--- a/tools/configure/main.cpp
+++ b/tools/configure/main.cpp
@@ -92,15 +92,15 @@ int runConfigure( int argc, char** argv )
app.generateHeaders();
if( !app.isDone() )
app.buildQmake();
- if( !app.isOk() )
- return 2;
#endif
if( !app.isDone() )
app.generateMakefiles();
- if( app.isOk() )
+ if( !app.isDone() && app.isOk() )
app.buildHostTools();
if( !app.isDone() )
app.showSummary();
+ if( !app.isOk() )
+ return 2;
return 0;
}
diff --git a/tools/configure/tools.cpp b/tools/configure/tools.cpp
index f60f72c..708a537 100644
--- a/tools/configure/tools.cpp
+++ b/tools/configure/tools.cpp
@@ -201,8 +201,8 @@ void Tools::checkLicense(QMap<QString,QString> &dictionary, QMap<QString,QString
if (licenseFeatures == '5') //Floating
dictionary["METERED LICENSE"] = "true";
- if (!CopyFileA(QDir::toNativeSeparators(fromLicenseFile).toLocal8Bit(),
- QDir::toNativeSeparators(toLicenseFile).toLocal8Bit(), FALSE)) {
+ if (!CopyFile((wchar_t*)QDir::toNativeSeparators(fromLicenseFile).utf16(),
+ (wchar_t*)QDir::toNativeSeparators(toLicenseFile).utf16(), FALSE)) {
cout << "Failed to copy license file (" << fromLicenseFile << ")";
dictionary["DONE"] = "error";
return;
diff --git a/tools/designer/data/generate_shared.xsl b/tools/designer/data/generate_shared.xsl
index f7859cd..ec95fe2 100644
--- a/tools/designer/data/generate_shared.xsl
+++ b/tools/designer/data/generate_shared.xsl
@@ -6,8 +6,8 @@
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- Hack to make names camel case
- All names in ui files are lowercase, while the element names are
- capital case. To make the ui files conforming to the xsd file + keep
+ All names in UI files are lowercase, while the element names are
+ capital case. To make the UI files conforming to the XSD file + keep
the DOM interface we rename them here -->
<xsl:template name="camel-case">
<xsl:param name="text"/>
diff --git a/tools/designer/data/ui4.xsd b/tools/designer/data/ui4.xsd
index 703e497..de4253c 100644
--- a/tools/designer/data/ui4.xsd
+++ b/tools/designer/data/ui4.xsd
@@ -143,6 +143,7 @@
<xs:element name="script" type="Script" minOccurs="0" />
<xs:element name="properties" type="Properties" minOccurs="0" />
<xs:element name="slots" type="Slots" minOccurs="0" />
+ <xs:element name="propertyspecifications" type="PropertySpecifications" minOccurs="0" />
</xs:all>
</xs:complexType>
@@ -571,4 +572,16 @@
</xs:sequence>
</xs:complexType>
+ <xs:complexType name="PropertySpecifications">
+ <xs:sequence maxOccurs="unbounded">
+ <xs:element name="stringpropertyspecification" type="StringPropertySpecification" minOccurs="0" maxOccurs="unbounded" />
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="StringPropertySpecification">
+ <xs:attribute name="name" type="xs:string" use="required" />
+ <xs:attribute name="type" type="xs:string" use="required" />
+ <xs:attribute name="notr" type="xs:string"/>
+ </xs:complexType>
+
</xs:schema>
diff --git a/tools/designer/src/components/buddyeditor/buddyeditor.cpp b/tools/designer/src/components/buddyeditor/buddyeditor.cpp
index 295b37f..9984b0d 100644
--- a/tools/designer/src/components/buddyeditor/buddyeditor.cpp
+++ b/tools/designer/src/components/buddyeditor/buddyeditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::BuddyEditor
-*/
-
#include "buddyeditor.h"
#include <QtDesigner/QDesignerFormWindowInterface>
diff --git a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
index e79e4f2..ff0c3c6 100644
--- a/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
+++ b/tools/designer/src/components/buddyeditor/buddyeditor_plugin.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::BuddyEditorPlugin
-*/
-
#include <QtGui/QAction>
#include "buddyeditor_plugin.h"
diff --git a/tools/designer/src/components/buddyeditor/buddyeditor_tool.cpp b/tools/designer/src/components/buddyeditor/buddyeditor_tool.cpp
index 75669aa..3cc63f7 100644
--- a/tools/designer/src/components/buddyeditor/buddyeditor_tool.cpp
+++ b/tools/designer/src/components/buddyeditor/buddyeditor_tool.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::BuddyEditorTool
-*/
-
#include "buddyeditor_tool.h"
#include "buddyeditor.h"
diff --git a/tools/designer/src/components/formeditor/embeddedoptionspage.cpp b/tools/designer/src/components/formeditor/embeddedoptionspage.cpp
index b11c4b2..7b66d8c 100644
--- a/tools/designer/src/components/formeditor/embeddedoptionspage.cpp
+++ b/tools/designer/src/components/formeditor/embeddedoptionspage.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::EmbeddedOptionsControl
-*/
-
#include "embeddedoptionspage.h"
#include "deviceprofiledialog.h"
#include "widgetfactory_p.h"
diff --git a/tools/designer/src/components/formeditor/formwindow.cpp b/tools/designer/src/components/formeditor/formwindow.cpp
index 06fa40e..d556030 100644
--- a/tools/designer/src/components/formeditor/formwindow.cpp
+++ b/tools/designer/src/components/formeditor/formwindow.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::FormWindow
-*/
-
#include "formwindow.h"
#include "formeditor.h"
#include "formwindow_dnditem.h"
@@ -2140,7 +2136,10 @@ void FormWindow::layoutContainer(QWidget *w, int type)
bool FormWindow::hasInsertedChildren(QWidget *widget) const // ### move
{
if (QDesignerContainerExtension *container = qt_extension<QDesignerContainerExtension*>(core()->extensionManager(), widget)) {
- widget = container->widget(container->currentIndex());
+ const int index = container->currentIndex();
+ if (index < 0)
+ return false;
+ widget = container->widget(index);
}
const QWidgetList l = widgets(widget);
diff --git a/tools/designer/src/components/formeditor/formwindowcursor.cpp b/tools/designer/src/components/formeditor/formwindowcursor.cpp
index e8480bc..717b679 100644
--- a/tools/designer/src/components/formeditor/formwindowcursor.cpp
+++ b/tools/designer/src/components/formeditor/formwindowcursor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::FormWindowCursor
-*/
-
#include "formwindowcursor.h"
#include "formwindow.h"
diff --git a/tools/designer/src/components/formeditor/formwindowmanager.cpp b/tools/designer/src/components/formeditor/formwindowmanager.cpp
index 1d48bad..993bae9 100644
--- a/tools/designer/src/components/formeditor/formwindowmanager.cpp
+++ b/tools/designer/src/components/formeditor/formwindowmanager.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::FormWindowManager
-*/
-
// components/formeditor
#include "formwindowmanager.h"
#include "formwindow_dnditem.h"
diff --git a/tools/designer/src/components/formeditor/qdesigner_resource.cpp b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
index f4f961a..ac03909 100644
--- a/tools/designer/src/components/formeditor/qdesigner_resource.cpp
+++ b/tools/designer/src/components/formeditor/qdesigner_resource.cpp
@@ -631,13 +631,13 @@ static bool readUiAttributes(QIODevice *dev, QString *errorMessage,
*language = attributes.value(languageAttribute).toString();
return true;
} else {
- *errorMessage = QCoreApplication::translate("Designer", "Invalid ui file: The root element <ui> is missing.");
+ *errorMessage = QCoreApplication::translate("Designer", "Invalid UI file: The root element <ui> is missing.");
return false;
}
}
}
- *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the ui file at line %1, column %2: %3")
+ *errorMessage = QCoreApplication::translate("Designer", "An error has occurred while reading the UI file at line %1, column %2: %3")
.arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString());
return false;
}
@@ -753,30 +753,10 @@ void QDesignerResource::setSaveRelative(bool relative)
m_resourceBuilder->setSaveRelative(relative);
}
-static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals)
-{
- if (!domSlots)
- return false;
-
- bool rc = false;
- foreach (const QString &fakeSlot, domSlots->elementSlot())
- if (fakeSlots.indexOf(fakeSlot) == -1) {
- fakeSlots += fakeSlot;
- rc = true;
- }
-
- foreach (const QString &fakeSignal, domSlots->elementSignal())
- if (fakeSignals.indexOf(fakeSignal) == -1) {
- fakeSignals += fakeSignal;
- rc = true;
- }
- return rc;
-}
-
QWidget *QDesignerResource::create(DomUI *ui, QWidget *parentWidget)
{
// Load extra info extension. This is used by Jambi for preventing
- // C++ ui files from being loaded
+ // C++ UI files from being loaded
if (QDesignerExtraInfoExtension *extra = qt_extension<QDesignerExtraInfoExtension*>(core()->extensionManager(), core())) {
if (!extra->loadUiExtraInfo(ui)) {
const QString errorMessage = QApplication::translate("Designer", "This file cannot be read because the extra info extension failed to load.");
@@ -1435,108 +1415,9 @@ DomLayoutItem *QDesignerResource::createDom(QLayoutItem *item, DomLayout *ui_lay
return ui_item;
}
-static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item)
-{
- const DomSlots *domSlots = domCustomWidget->elementSlots();
- if (!domSlots)
- return;
-
- // Merge in new slots, signals
- QStringList fakeSlots = item->fakeSlots();
- QStringList fakeSignals = item->fakeSignals();
- if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
- item->setFakeSlots(fakeSlots);
- item->setFakeSignals(fakeSignals);
- }
-}
-
-void QDesignerResource::addCustomWidgetsToWidgetDatabase(DomCustomWidgetList& custom_widget_list)
-{
- // Perform one iteration of adding the custom widgets to the database,
- // looking up the base class and inheriting its data.
- // Remove the succeeded custom widgets from the list.
- // Classes whose base class could not be found are left in the list.
- QDesignerWidgetDataBaseInterface *db = m_formWindow->core()->widgetDataBase();
- for (int i=0; i < custom_widget_list.size(); ) {
- bool classInserted = false;
- DomCustomWidget *custom_widget = custom_widget_list[i];
- const QString customClassName = custom_widget->elementClass();
- const QString base_class = custom_widget->elementExtends();
- QString includeFile;
- IncludeType includeType = IncludeLocal;
- if (const DomHeader *header = custom_widget->elementHeader()) {
- includeFile = header->text();
- if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global"))
- includeType = IncludeGlobal;
- }
- const bool domIsContainer = custom_widget->elementContainer();
- // Append a new item
- if (base_class.isEmpty()) {
- WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName);
- item->setPromoted(false);
- item->setGroup(QApplication::translate("Designer", "Custom Widgets"));
- item->setIncludeFile(buildIncludeFile(includeFile, includeType));
- item->setContainer(domIsContainer);
- item->setCustom(true);
- addFakeMethodsToWidgetDataBase(custom_widget, item);
- db->append(item);
- custom_widget_list.removeAt(i);
- classInserted = true;
- } else {
- // Create a new entry cloned from base class. Note that this will ignore existing
- // classes, eg, plugin custom widgets.
- QDesignerWidgetDataBaseItemInterface *item =
- appendDerived(db, customClassName, QApplication::translate("Designer", "Promoted Widgets"),
- base_class,
- buildIncludeFile(includeFile, includeType),
- true,true);
- // Ok, base class found.
- if (item) {
- // Hack to accommodate for old UI-files in which "contains" is not set properly:
- // Apply "contains" from DOM only if true (else, eg classes from QFrame might not accept
- // dropping child widgets on them as container=false). This also allows for
- // QWidget-derived stacked pages.
- if (domIsContainer)
- item->setContainer(domIsContainer);
-
- addFakeMethodsToWidgetDataBase(custom_widget, static_cast<WidgetDataBaseItem*>(item));
- custom_widget_list.removeAt(i);
- classInserted = true;
- }
- }
- // Skip failed item.
- if (!classInserted)
- i++;
- }
-
-}
void QDesignerResource::createCustomWidgets(DomCustomWidgets *dom_custom_widgets)
{
- if (dom_custom_widgets == 0)
- return;
- DomCustomWidgetList custom_widget_list = dom_custom_widgets->elementCustomWidget();
- // Attempt to insert each item derived from its base class.
- // This should at most require two iterations in the event that the classes are out of order
- // (derived first, max depth: promoted custom plugin = 2)
- for (int iteration = 0; iteration < 2; iteration++) {
- addCustomWidgetsToWidgetDatabase(custom_widget_list);
- if (custom_widget_list.empty())
- return;
- }
- // Oops, there are classes left whose base class could not be found.
- // Default them to QWidget with warnings.
- const QString fallBackBaseClass = QLatin1String("QWidget");
- for (int i=0; i < custom_widget_list.size(); i++ ) {
- DomCustomWidget *custom_widget = custom_widget_list[i];
- const QString customClassName = custom_widget->elementClass();
- const QString base_class = custom_widget->elementExtends();
- qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName
- << " could not be found. Defaulting to " << fallBackBaseClass << '.';
- custom_widget->setElementExtends(fallBackBaseClass);
- }
- // One more pass.
- addCustomWidgetsToWidgetDatabase(custom_widget_list);
- Q_ASSERT(custom_widget_list.empty());
+ QSimpleResource::handleDomCustomWidgets(core(), dom_custom_widgets);
}
DomTabStops *QDesignerResource::saveTabStops()
diff --git a/tools/designer/src/components/formeditor/tool_widgeteditor.cpp b/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
index b4e52f5..967c6b7 100644
--- a/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
+++ b/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::WidgetEditorTool
-*/
-
#include "tool_widgeteditor.h"
#include "formwindow.h"
diff --git a/tools/designer/src/components/objectinspector/objectinspector.cpp b/tools/designer/src/components/objectinspector/objectinspector.cpp
index a356d9b..c36a629 100644
--- a/tools/designer/src/components/objectinspector/objectinspector.cpp
+++ b/tools/designer/src/components/objectinspector/objectinspector.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ObjectInspector
-*/
-
#include "objectinspector.h"
#include "objectinspectormodel_p.h"
#include "formwindow.h"
diff --git a/tools/designer/src/components/objectinspector/objectinspectormodel.cpp b/tools/designer/src/components/objectinspector/objectinspectormodel.cpp
index a86d4e8..c265539 100644
--- a/tools/designer/src/components/objectinspector/objectinspectormodel.cpp
+++ b/tools/designer/src/components/objectinspector/objectinspectormodel.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ObjectInspector
-*/
-
#include "objectinspectormodel_p.h"
#include <qlayout_widget_p.h>
diff --git a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
index 2f6a51e..fb1a5bb 100644
--- a/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
+++ b/tools/designer/src/components/propertyeditor/designerpropertymanager.cpp
@@ -2455,6 +2455,9 @@ void DesignerEditorFactory::slotStringTextChanged(const QString &value)
if (val.userType() == DesignerPropertyManager::designerStringTypeId()) {
PropertySheetStringValue strVal = qVariantValue<PropertySheetStringValue>(val);
strVal.setValue(value);
+ // Disable translation if no translation subproperties exist.
+ if (varProp->subProperties().empty())
+ strVal.setTranslatable(false);
val = qVariantFromValue(strVal);
} else {
val = QVariant(value);
diff --git a/tools/designer/src/components/propertyeditor/paletteeditor.cpp b/tools/designer/src/components/propertyeditor/paletteeditor.cpp
index c44b514..ab105b3 100644
--- a/tools/designer/src/components/propertyeditor/paletteeditor.cpp
+++ b/tools/designer/src/components/propertyeditor/paletteeditor.cpp
@@ -39,13 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::PaletteEditor
-*/
-/*
-TRANSLATOR qdesigner_internal::PaletteModel
-*/
-
#include "paletteeditor.h"
#include <iconloader_p.h>
diff --git a/tools/designer/src/components/propertyeditor/paletteeditorbutton.cpp b/tools/designer/src/components/propertyeditor/paletteeditorbutton.cpp
index 2ac1c3f..de96fea 100644
--- a/tools/designer/src/components/propertyeditor/paletteeditorbutton.cpp
+++ b/tools/designer/src/components/propertyeditor/paletteeditorbutton.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::PaletteEditorButton
-*/
-
#include "paletteeditorbutton.h"
#include "paletteeditor.h"
diff --git a/tools/designer/src/components/propertyeditor/previewframe.cpp b/tools/designer/src/components/propertyeditor/previewframe.cpp
index 8416a4e..33073e2 100644
--- a/tools/designer/src/components/propertyeditor/previewframe.cpp
+++ b/tools/designer/src/components/propertyeditor/previewframe.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::PreviewWorkspace
-*/
-
#include "previewframe.h"
#include "previewwidget.h"
diff --git a/tools/designer/src/components/propertyeditor/propertyeditor.cpp b/tools/designer/src/components/propertyeditor/propertyeditor.cpp
index 4c0565d..b20a5a8 100644
--- a/tools/designer/src/components/propertyeditor/propertyeditor.cpp
+++ b/tools/designer/src/components/propertyeditor/propertyeditor.cpp
@@ -137,13 +137,8 @@ void PropertyEditor::setupStringProperty(QtVariantProperty *property, bool isMai
const bool hasComment = params.second;
property->setAttribute(m_strings.m_validationModeAttribute, params.first);
// assuming comment cannot appear or disappear for the same property in different object instance
- if (!hasComment) {
- QList<QtProperty *> commentProperties = property->subProperties();
- if (commentProperties.count() > 0)
- delete commentProperties.at(0);
- if (commentProperties.count() > 1)
- delete commentProperties.at(1);
- }
+ if (!hasComment)
+ qDeleteAll(property->subProperties());
}
void PropertyEditor::setupPaletteProperty(QtVariantProperty *property)
diff --git a/tools/designer/src/components/propertyeditor/stringlisteditorbutton.cpp b/tools/designer/src/components/propertyeditor/stringlisteditorbutton.cpp
index d4bebb9..1b51376 100644
--- a/tools/designer/src/components/propertyeditor/stringlisteditorbutton.cpp
+++ b/tools/designer/src/components/propertyeditor/stringlisteditorbutton.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::StringListEditorButton
-*/
-
#include "stringlisteditorbutton.h"
#include "stringlisteditor.h"
diff --git a/tools/designer/src/components/signalsloteditor/connectdialog.ui b/tools/designer/src/components/signalsloteditor/connectdialog.ui
index bd062eb..568516a 100644
--- a/tools/designer/src/components/signalsloteditor/connectdialog.ui
+++ b/tools/designer/src/components/signalsloteditor/connectdialog.ui
@@ -13,7 +13,7 @@
<string>Configure Connection</string>
</property>
<layout class="QGridLayout" >
- <item row="0" column="0" colspan="2" >
+ <item row="0" column="0" >
<widget class="QGroupBox" name="signalGroupBox" >
<property name="title" >
<string>GroupBox</string>
@@ -53,7 +53,7 @@
</layout>
</widget>
</item>
- <item row="0" column="2" >
+ <item row="0" column="1" >
<widget class="QGroupBox" name="slotGroupBox" >
<property name="title" >
<string>GroupBox</string>
@@ -93,14 +93,14 @@
</layout>
</widget>
</item>
- <item row="1" column="0" >
+ <item row="1" column="0" colspan="2" >
<widget class="QCheckBox" name="showAllCheckBox" >
<property name="text" >
<string>Show signals and slots inherited from QWidget</string>
</property>
</widget>
</item>
- <item row="2" column="1" colspan="2" >
+ <item row="2" column="0" colspan="2" >
<widget class="QDialogButtonBox" name="buttonBox" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
index fd90e67..e664ae7 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::SignalSlotEditorPlugin
-*/
-
#include "signalsloteditor_plugin.h"
#include "signalsloteditor_tool.h"
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp
index d743d21..8b0dd7c 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditor_tool.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::SignalSlotEditorTool
-*/
-
#include "signalsloteditor_tool.h"
#include "signalsloteditor.h"
#include "ui4_p.h"
diff --git a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
index e1126bd..9f27923 100644
--- a/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
+++ b/tools/designer/src/components/signalsloteditor/signalsloteditorwindow.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ConnectionModel
-*/
-
#include "signalsloteditorwindow.h"
#include "signalsloteditor_p.h"
#include "signalsloteditor.h"
diff --git a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
index b6b93a9..9b051c9 100644
--- a/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
+++ b/tools/designer/src/components/tabordereditor/tabordereditor_plugin.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TabOrderEditorPlugin
-*/
-
#include <QtGui/QAction>
#include "tabordereditor_plugin.h"
diff --git a/tools/designer/src/components/tabordereditor/tabordereditor_tool.cpp b/tools/designer/src/components/tabordereditor/tabordereditor_tool.cpp
index 23e2f47..b94f7ff 100644
--- a/tools/designer/src/components/tabordereditor/tabordereditor_tool.cpp
+++ b/tools/designer/src/components/tabordereditor/tabordereditor_tool.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TabOrderEditorTool
-*/
-
#include "tabordereditor_tool.h"
#include "tabordereditor.h"
diff --git a/tools/designer/src/components/taskmenu/button_taskmenu.cpp b/tools/designer/src/components/taskmenu/button_taskmenu.cpp
index c431024..5eb74cc 100644
--- a/tools/designer/src/components/taskmenu/button_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/button_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ButtonTaskMenu
-*/
-
#include "button_taskmenu.h"
#include "inplace_editor.h"
#include <qdesigner_formwindowcommand_p.h>
diff --git a/tools/designer/src/components/taskmenu/combobox_taskmenu.cpp b/tools/designer/src/components/taskmenu/combobox_taskmenu.cpp
index 600e9e4..f1d16a3 100644
--- a/tools/designer/src/components/taskmenu/combobox_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/combobox_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ComboBoxTaskMenu
-*/
-
#include "combobox_taskmenu.h"
#include "listwidgeteditor.h"
#include "qdesigner_utils_p.h"
diff --git a/tools/designer/src/components/taskmenu/containerwidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
index 84d964b..14385ba 100644
--- a/tools/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/containerwidget_taskmenu.cpp
@@ -39,13 +39,8 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ContainerWidgetTaskMenu
-*/
-
#include "containerwidget_taskmenu.h"
-
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowInterface>
#include <QtDesigner/QExtensionManager>
diff --git a/tools/designer/src/components/taskmenu/groupbox_taskmenu.cpp b/tools/designer/src/components/taskmenu/groupbox_taskmenu.cpp
index ce6b4ab..ba9651a 100644
--- a/tools/designer/src/components/taskmenu/groupbox_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/groupbox_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::GroupBoxTaskMenu
-*/
-
#include "groupbox_taskmenu.h"
#include "inplace_editor.h"
diff --git a/tools/designer/src/components/taskmenu/label_taskmenu.cpp b/tools/designer/src/components/taskmenu/label_taskmenu.cpp
index 6a555c8..c7e8d72 100644
--- a/tools/designer/src/components/taskmenu/label_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/label_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::LabelTaskMenu
-*/
-
#include "label_taskmenu.h"
#include "inplace_editor.h"
diff --git a/tools/designer/src/components/taskmenu/layouttaskmenu.cpp b/tools/designer/src/components/taskmenu/layouttaskmenu.cpp
index d7e5365..46d3497 100644
--- a/tools/designer/src/components/taskmenu/layouttaskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/layouttaskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::LayoutWidgetTaskMenu
-*/
-
#include "layouttaskmenu.h"
#include <formlayoutmenu_p.h>
#include <morphmenu_p.h>
diff --git a/tools/designer/src/components/taskmenu/lineedit_taskmenu.cpp b/tools/designer/src/components/taskmenu/lineedit_taskmenu.cpp
index db7327b..f2915ec 100644
--- a/tools/designer/src/components/taskmenu/lineedit_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/lineedit_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::LineEditTaskMenu
-*/
-
#include "lineedit_taskmenu.h"
#include "inplace_editor.h"
diff --git a/tools/designer/src/components/taskmenu/listwidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/listwidget_taskmenu.cpp
index 984fc8a..e70d985 100644
--- a/tools/designer/src/components/taskmenu/listwidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/listwidget_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ListWidgetTaskMenu
-*/
-
#include "listwidget_taskmenu.h"
#include "listwidgeteditor.h"
#include "qdesigner_utils_p.h"
diff --git a/tools/designer/src/components/taskmenu/listwidgeteditor.cpp b/tools/designer/src/components/taskmenu/listwidgeteditor.cpp
index 8edad6d..a40a345 100644
--- a/tools/designer/src/components/taskmenu/listwidgeteditor.cpp
+++ b/tools/designer/src/components/taskmenu/listwidgeteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ListWidgetEditor
-*/
-
#include "listwidgeteditor.h"
#include <designerpropertymanager.h>
#include <abstractformbuilder.h>
diff --git a/tools/designer/src/components/taskmenu/menutaskmenu.cpp b/tools/designer/src/components/taskmenu/menutaskmenu.cpp
index 346a07f..3546cd1 100644
--- a/tools/designer/src/components/taskmenu/menutaskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/menutaskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::MenuTaskMenu
-*/
-
#include "menutaskmenu.h"
#include <promotiontaskmenu_p.h>
diff --git a/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
index f0fa680..c187a69 100644
--- a/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/tablewidget_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TableWidgetTaskMenu
-*/
-
#include "tablewidget_taskmenu.h"
#include "tablewidgeteditor.h"
diff --git a/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp b/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
index 6115998..587e7d3 100644
--- a/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
+++ b/tools/designer/src/components/taskmenu/tablewidgeteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TableWidgetEditor
-*/
-
#include "tablewidgeteditor.h"
#include <abstractformbuilder.h>
#include <iconloader_p.h>
diff --git a/tools/designer/src/components/taskmenu/textedit_taskmenu.cpp b/tools/designer/src/components/taskmenu/textedit_taskmenu.cpp
index 55cd105..d052ced 100644
--- a/tools/designer/src/components/taskmenu/textedit_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/textedit_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TextEditTaskMenu
-*/
-
#include "textedit_taskmenu.h"
#include <QtDesigner/QDesignerFormWindowInterface>
diff --git a/tools/designer/src/components/taskmenu/toolbar_taskmenu.cpp b/tools/designer/src/components/taskmenu/toolbar_taskmenu.cpp
index 7c4c07d..a64de13 100644
--- a/tools/designer/src/components/taskmenu/toolbar_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/toolbar_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ToolBarTaskMenu
-*/
-
#include "toolbar_taskmenu.h"
#include "qdesigner_toolbar_p.h"
diff --git a/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp b/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
index 3784957..6643141 100644
--- a/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
+++ b/tools/designer/src/components/taskmenu/treewidget_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TreeWidgetTaskMenu
-*/
-
#include "treewidget_taskmenu.h"
#include "treewidgeteditor.h"
diff --git a/tools/designer/src/components/taskmenu/treewidgeteditor.cpp b/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
index d0b6283..458eadb 100644
--- a/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
+++ b/tools/designer/src/components/taskmenu/treewidgeteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::TreeWidgetEditor
-*/
-
#include "treewidgeteditor.h"
#include <formwindowbase_p.h>
#include <iconloader_p.h>
diff --git a/tools/designer/src/components/widgetbox/widgetbox_dnditem.cpp b/tools/designer/src/components/widgetbox/widgetbox_dnditem.cpp
index 67e1184..045bfca 100644
--- a/tools/designer/src/components/widgetbox/widgetbox_dnditem.cpp
+++ b/tools/designer/src/components/widgetbox/widgetbox_dnditem.cpp
@@ -50,6 +50,7 @@
#include <formwindowbase_p.h>
#include <qdesigner_utils_p.h>
#include <qdesigner_dockwidget_p.h>
+#include <qsimpleresource_p.h>
#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerFormWindowManagerInterface>
@@ -84,6 +85,7 @@ protected:
virtual QWidget *create(DomWidget *ui_widget, QWidget *parents);
virtual QWidget *createWidget(const QString &widgetName, QWidget *parentWidget, const QString &name);
+ virtual void createCustomWidgets(DomCustomWidgets *);
};
WidgetBoxResource::WidgetBoxResource(QDesignerFormEditorInterface *core) :
@@ -120,6 +122,14 @@ QWidget *WidgetBoxResource::create(DomWidget *ui_widget, QWidget *parent)
return result;
}
+void WidgetBoxResource::createCustomWidgets(DomCustomWidgets *dc)
+{
+ // Make a promotion entry in case someone has a promoted widget
+ // in the scratchpad.
+ QSimpleResource::handleDomCustomWidgets(core(), dc);
+
+}
+
/*******************************************************************************
** WidgetBoxResource
*/
diff --git a/tools/designer/src/designer/mainwindow.cpp b/tools/designer/src/designer/mainwindow.cpp
index b72a790..a3ca234 100644
--- a/tools/designer/src/designer/mainwindow.cpp
+++ b/tools/designer/src/designer/mainwindow.cpp
@@ -155,7 +155,7 @@ DockedMdiArea::DockedMdiArea(const QString &extension, QWidget *parent) :
QStringList DockedMdiArea::uiFiles(const QMimeData *d) const
{
- // Extract dropped ui files from Mime data.
+ // Extract dropped UI files from Mime data.
QStringList rc;
if (!d->hasFormat(QLatin1String(uriListMimeFormatC)))
return rc;
diff --git a/tools/designer/src/designer/qdesigner_actions.cpp b/tools/designer/src/designer/qdesigner_actions.cpp
index 5151044..c671386 100644
--- a/tools/designer/src/designer/qdesigner_actions.cpp
+++ b/tools/designer/src/designer/qdesigner_actions.cpp
@@ -280,7 +280,7 @@ QDesignerActions::QDesignerActions(QDesignerWorkbench *workbench)
m_fileActions->addAction(createSeparator(this));
- m_quitAction->setShortcut(tr("CTRL+Q"));
+ m_quitAction->setShortcuts(QKeySequence::Quit);
m_quitAction->setMenuRole(QAction::QuitRole);
connect(m_quitAction, SIGNAL(triggered()), this, SLOT(shutdown()));
m_fileActions->addAction(m_quitAction);
diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp
index c9d9fc4..2ac9e1f 100644
--- a/tools/designer/src/designer/qdesigner_workbench.cpp
+++ b/tools/designer/src/designer/qdesigner_workbench.cpp
@@ -961,7 +961,7 @@ QDesignerFormWindow * QDesignerWorkbench::loadForm(const QString &fileName,
removeFormWindow(formWindow);
formWindowManager->removeFormWindow(editor);
m_core->metaDataBase()->remove(editor);
- *errorMessage = tr("The file <b>%1</b> is not a valid Designer ui file.").arg(file.fileName());
+ *errorMessage = tr("The file <b>%1</b> is not a valid Designer UI file.").arg(file.fileName());
return 0;
}
*uic3Converted = editor->fileName().isEmpty();
diff --git a/tools/designer/src/designer/versiondialog.cpp b/tools/designer/src/designer/versiondialog.cpp
index 101a3f3..388fb27 100644
--- a/tools/designer/src/designer/versiondialog.cpp
+++ b/tools/designer/src/designer/versiondialog.cpp
@@ -172,15 +172,11 @@ VersionDialog::VersionDialog(QWidget *parent)
version = version.arg(tr("Qt Designer")).arg(QLatin1String(QT_VERSION_STR));
version.append(tr("<br/>Qt Designer is a graphical user interface designer for Qt applications.<br/>"));
- // TODO: Remove this variable for 4.6.0. Must keep this way for 4.5.x due to string freeze
- QString edition;
-
lbl->setText(tr("%1"
- "<br/>%2"
"<br/>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)."
"<br/><br/>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
" INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
- " PARTICULAR PURPOSE.<br/> ").arg(version).arg(edition));
+ " PARTICULAR PURPOSE.<br/> ").arg(version));
lbl->setWordWrap(true);
lbl->setOpenExternalLinks(true);
diff --git a/tools/designer/src/lib/sdk/abstractformeditor.cpp b/tools/designer/src/lib/sdk/abstractformeditor.cpp
index 52f1ef1..48772b8 100644
--- a/tools/designer/src/lib/sdk/abstractformeditor.cpp
+++ b/tools/designer/src/lib/sdk/abstractformeditor.cpp
@@ -66,9 +66,21 @@
#include <grid_p.h>
#include <QtDesigner/QDesignerPromotionInterface>
+// Must be done outside of the Qt namespace
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);
+ Q_INIT_RESOURCE(SmartPhone2);
+ 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/abstractformwindow.cpp b/tools/designer/src/lib/sdk/abstractformwindow.cpp
index 89c1015..313b324 100644
--- a/tools/designer/src/lib/sdk/abstractformwindow.cpp
+++ b/tools/designer/src/lib/sdk/abstractformwindow.cpp
@@ -247,7 +247,7 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
/*!
\fn virtual QString QDesignerFormWindowInterface::fileName() const
- Returns the file name of the .ui file that describes the form
+ Returns the file name of the UI file that describes the form
currently being shown.
\sa setFileName()
@@ -399,11 +399,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
\fn virtual QStringList QDesignerFormWindowInterface::includeHints() const
Returns a list of the header files that will be included in the
- form window's associated \c .ui file.
+ form window's associated UI file.
Header files may be local, i.e. relative to the project's
- directory,\c "mywidget.h", or global, i.e. part of Qt or the
- compilers standard libraries:\c <QtGui/QWidget>.
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
\sa setIncludeHints()
*/
@@ -412,11 +412,11 @@ QDesignerFormWindowInterface *QDesignerFormWindowInterface::findFormWindow(QObje
\fn virtual void QDesignerFormWindowInterface::setIncludeHints(const QStringList &includeHints)
Sets the header files that will be included in the form window's
- associated \c .ui file to the specified \a includeHints.
+ associated UI file to the specified \a includeHints.
Header files may be local, i.e. relative to the project's
- directory,\c "mywidget.h", or global, i.e. part of Qt or the
- compilers standard libraries:\c <QtGui/QWidget>.
+ directory, \c "mywidget.h", or global, i.e. part of Qt or the
+ compilers standard libraries: \c <QtGui/QWidget>.
\sa includeHints()
*/
diff --git a/tools/designer/src/lib/sdk/script.cpp b/tools/designer/src/lib/sdk/script.cpp
index 90b4c73..2eda3d1 100644
--- a/tools/designer/src/lib/sdk/script.cpp
+++ b/tools/designer/src/lib/sdk/script.cpp
@@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE
\since 4.3
On saving the form, the extension is queried for a script snippet
- to be associated with the widget while saving the \c .ui file.
+ to be associated with the widget while saving the UI file.
This script is then run after creating the widget by \l uic or
QUiLoader.
@@ -66,7 +66,7 @@ QT_BEGIN_NAMESPACE
for which an editor is provided by the QDesignerTaskMenuExtension.
While saving the form, the state is serialized as a QVariantMap of
- \QD-supported properties, which is stored in the \c .ui file. This is
+ \QD-supported properties, which is stored in the UI file. This is
handled by data() and setData().
For item view contents, there might be for example a key that determines
@@ -97,7 +97,7 @@ QDesignerScriptExtension::~QDesignerScriptExtension()
\fn virtual QVariantMap QDesignerScriptExtension::data() const
Returns a map of variants describing the internal state to be
- stored in the \c .ui file.
+ stored in the UI file.
*/
/*!
diff --git a/tools/designer/src/lib/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp
index a89e47c..1a236d6 100644
--- a/tools/designer/src/lib/shared/actioneditor.cpp
+++ b/tools/designer/src/lib/shared/actioneditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ActionEditor
-*/
-
#include "actioneditor_p.h"
#include "filterwidget_p.h"
#include "actionrepository_p.h"
diff --git a/tools/designer/src/lib/shared/codedialog.cpp b/tools/designer/src/lib/shared/codedialog.cpp
index f379970..380566c 100644
--- a/tools/designer/src/lib/shared/codedialog.cpp
+++ b/tools/designer/src/lib/shared/codedialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::CodeDialog
-*/
-
#include "codedialog_p.h"
#include "qdesigner_utils_p.h"
#include "iconloader_p.h"
diff --git a/tools/designer/src/lib/shared/csshighlighter.cpp b/tools/designer/src/lib/shared/csshighlighter.cpp
index d871d4d..cb7a78e 100644
--- a/tools/designer/src/lib/shared/csshighlighter.cpp
+++ b/tools/designer/src/lib/shared/csshighlighter.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::StyleSheetEditorDialog
-*/
-
#include "csshighlighter_p.h"
QT_BEGIN_NAMESPACE
diff --git a/tools/designer/src/lib/shared/formwindowbase.cpp b/tools/designer/src/lib/shared/formwindowbase.cpp
index ab96809..1d79ac4 100644
--- a/tools/designer/src/lib/shared/formwindowbase.cpp
+++ b/tools/designer/src/lib/shared/formwindowbase.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::FormWindowBase
-*/
-
#include "formwindowbase_p.h"
#include "connectionedit_p.h"
#include "qdesigner_command_p.h"
diff --git a/tools/designer/src/lib/shared/newformwidget.cpp b/tools/designer/src/lib/shared/newformwidget.cpp
index e351ef0..c4d202e 100644
--- a/tools/designer/src/lib/shared/newformwidget.cpp
+++ b/tools/designer/src/lib/shared/newformwidget.cpp
@@ -310,9 +310,8 @@ QImage NewFormWidget::grabForm(QDesignerFormEditorInterface *core,
const QString &workingDir,
const qdesigner_internal::DeviceProfile &dp)
{
- qdesigner_internal::QDesignerFormBuilder formBuilder(core,
- qdesigner_internal::QDesignerFormBuilder::DisableScripts,
- dp);
+ qdesigner_internal::NewFormWidgetFormBuilder
+ formBuilder(core, qdesigner_internal::QDesignerFormBuilder::DisableScripts, dp);
if (!workingDir.isEmpty())
formBuilder.setWorkingDirectory(workingDir);
diff --git a/tools/designer/src/lib/shared/orderdialog.cpp b/tools/designer/src/lib/shared/orderdialog.cpp
index 96963db..d7da5f2 100644
--- a/tools/designer/src/lib/shared/orderdialog.cpp
+++ b/tools/designer/src/lib/shared/orderdialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::OrderDialog
-*/
-
#include "orderdialog_p.h"
#include "iconloader_p.h"
#include "ui_orderdialog.h"
diff --git a/tools/designer/src/lib/shared/plaintexteditor.cpp b/tools/designer/src/lib/shared/plaintexteditor.cpp
index 9b74ffd..3f9c5ed 100644
--- a/tools/designer/src/lib/shared/plaintexteditor.cpp
+++ b/tools/designer/src/lib/shared/plaintexteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::PlainTextEditorDialog
-*/
-
#include "plaintexteditor_p.h"
#include "abstractsettings_p.h"
diff --git a/tools/designer/src/lib/shared/pluginmanager.cpp b/tools/designer/src/lib/shared/pluginmanager.cpp
index d74f477..b8c1c40 100644
--- a/tools/designer/src/lib/shared/pluginmanager.cpp
+++ b/tools/designer/src/lib/shared/pluginmanager.cpp
@@ -72,6 +72,11 @@ static const char *classAttributeC = "class";
static const char *customwidgetElementC = "customwidget";
static const char *extendsElementC = "extends";
static const char *addPageMethodC = "addpagemethod";
+static const char *propertySpecsC = "propertyspecifications";
+static const char *stringPropertySpecC = "stringpropertyspecification";
+static const char *stringPropertyNameAttrC = "name";
+static const char *stringPropertyTypeAttrC = "type";
+static const char *stringPropertyNoTrAttrC = "notr";
static const char *jambiLanguageC = "jambi";
enum { debugPluginManager = 0 };
@@ -141,6 +146,10 @@ static inline QString getDesignerLanguage(QDesignerFormEditorInterface *core)
class QDesignerCustomWidgetSharedData : public QSharedData {
public:
+ // Type of a string property
+ typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
+ typedef QHash<QString, StringPropertyType> StringPropertyTypeMap;
+
explicit QDesignerCustomWidgetSharedData(const QString &thePluginPath) : pluginPath(thePluginPath) {}
void clearXML();
@@ -152,6 +161,7 @@ public:
QString xmlAddPageMethod;
QString xmlExtends;
+ StringPropertyTypeMap xmlStringPropertyTypeMap;
};
void QDesignerCustomWidgetSharedData::clearXML()
@@ -161,6 +171,7 @@ void QDesignerCustomWidgetSharedData::clearXML()
xmlLanguage.clear();
xmlAddPageMethod.clear();
xmlExtends.clear();
+ xmlStringPropertyTypeMap.clear();
}
// ---------------- QDesignerCustomWidgetData
@@ -220,6 +231,17 @@ QString QDesignerCustomWidgetData::pluginPath() const
return m_d->pluginPath;
}
+bool QDesignerCustomWidgetData::xmlStringPropertyType(const QString &name, StringPropertyType *type) const
+{
+ QDesignerCustomWidgetSharedData::StringPropertyTypeMap::const_iterator it = m_d->xmlStringPropertyTypeMap.constFind(name);
+ if (it == m_d->xmlStringPropertyTypeMap.constEnd()) {
+ *type = StringPropertyType(qdesigner_internal::ValidationRichText, true);
+ return false;
+ }
+ *type = it.value();
+ return true;
+}
+
// Wind a QXmlStreamReader until it finds an element. Returns index or one of FindResult
enum FindResult { FindError = -2, ElementNotFound = -1 };
@@ -249,6 +271,82 @@ static inline QString msgXmlError(const QString &name, const QString &errorMessa
return QDesignerPluginManager::tr("An XML error was encountered when parsing the XML of the custom widget %1: %2").arg(name, errorMessage);
}
+static inline QString msgAttributeMissing(const QString &name)
+{
+ return QDesignerPluginManager::tr("A required attribute ('%1') is missing.").arg(name);
+}
+
+static qdesigner_internal::TextPropertyValidationMode typeStringToType(const QString &v, bool *ok)
+{
+ *ok = true;
+ if (v == QLatin1String("multiline"))
+ return qdesigner_internal::ValidationMultiLine;
+ if (v == QLatin1String("richtext"))
+ return qdesigner_internal::ValidationRichText;
+ if (v == QLatin1String("stylesheet"))
+ return qdesigner_internal::ValidationStyleSheet;
+ if (v == QLatin1String("singleline"))
+ return qdesigner_internal::ValidationSingleLine;
+ if (v == QLatin1String("objectname"))
+ return qdesigner_internal::ValidationObjectName;
+ if (v == QLatin1String("objectnamescope"))
+ return qdesigner_internal::ValidationObjectNameScope;
+ if (v == QLatin1String("url"))
+ return qdesigner_internal::ValidationURL;
+ *ok = false;
+ return qdesigner_internal::ValidationRichText;
+}
+
+static bool parsePropertySpecs(QXmlStreamReader &sr,
+ QDesignerCustomWidgetSharedData::StringPropertyTypeMap *rc,
+ QString *errorMessage)
+{
+ const QString propertySpecs = QLatin1String(propertySpecsC);
+ const QString stringPropertySpec = QLatin1String(stringPropertySpecC);
+ const QString stringPropertyTypeAttr = QLatin1String(stringPropertyTypeAttrC);
+ const QString stringPropertyNoTrAttr = QLatin1String(stringPropertyNoTrAttrC);
+ const QString stringPropertyNameAttr = QLatin1String(stringPropertyNameAttrC);
+
+ while (!sr.atEnd()) {
+ switch(sr.readNext()) {
+ case QXmlStreamReader::StartElement: {
+ if (sr.name() != stringPropertySpec) {
+ *errorMessage = QDesignerPluginManager::tr("An invalid property specification ('%1') was encountered. Supported types: %2").arg(sr.name().toString(), stringPropertySpec);
+ return false;
+ }
+ const QXmlStreamAttributes atts = sr.attributes();
+ const QString name = atts.value(stringPropertyNameAttr).toString();
+ const QString type = atts.value(stringPropertyTypeAttr).toString();
+ const QString notrS = atts.value(stringPropertyNoTrAttr).toString(); //Optional
+
+ if (type.isEmpty()) {
+ *errorMessage = msgAttributeMissing(stringPropertyTypeAttr);
+ return false;
+ }
+ if (name.isEmpty()) {
+ *errorMessage = msgAttributeMissing(stringPropertyNameAttr);
+ return false;
+ }
+ bool typeOk;
+ const bool noTr = notrS == QLatin1String("true") || notrS == QLatin1String("1");
+ QDesignerCustomWidgetSharedData::StringPropertyType v(typeStringToType(type, &typeOk), !noTr);
+ if (!typeOk) {
+ *errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification!").arg(type);
+ return false;
+ }
+ rc->insert(name, v);
+ }
+ break;
+ case QXmlStreamReader::EndElement: // Outer </stringproperties>
+ if (sr.name() == propertySpecs)
+ return true;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
QDesignerCustomWidgetData::ParseResult
QDesignerCustomWidgetData::parseXml(const QString &xml, const QString &name, QString *errorMessage)
{
@@ -311,10 +409,11 @@ QDesignerCustomWidgetData::ParseResult
default:
break;
}
- // Find <extends>, <addPageMethod>
+ // Find <extends>, <addPageMethod>, <stringproperties>
elements.clear();
elements.push_back(QLatin1String(extendsElementC));
elements.push_back(QLatin1String(addPageMethodC));
+ elements.push_back(QLatin1String(propertySpecsC));
while (true) {
switch (findElement(elements, sr)) {
case FindError:
@@ -336,6 +435,12 @@ QDesignerCustomWidgetData::ParseResult
return ParseError;
}
break;
+ case 2: // <stringproperties>
+ if (!parsePropertySpecs(sr, &m_d->xmlStringPropertyTypeMap, errorMessage)) {
+ *errorMessage = msgXmlError(name, *errorMessage);
+ return ParseError;
+ }
+ break;
}
}
return rc;
@@ -345,6 +450,8 @@ QDesignerCustomWidgetData::ParseResult
class QDesignerPluginManagerPrivate {
public:
+ typedef QPair<QString, QString> ClassNamePropertyNameKey;
+
QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core);
void clearCustomWidgets();
@@ -562,7 +669,7 @@ bool QDesignerPluginManager::registerNewPlugins()
const int before = m_d->m_registeredPlugins.size();
foreach (const QString &path, m_d->m_pluginPaths)
- registerPath(path);
+ registerPath(path);
const bool newPluginsFound = m_d->m_registeredPlugins.size() > before;
// We force a re-initialize as Jambi collection might return
// different widget lists when switching projects.
@@ -654,6 +761,15 @@ QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(QDesignerCust
return m_d->m_customWidgetData.at(index);
}
+QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(const QString &name) const
+{
+ const int count = m_d->m_customWidgets.size();
+ for (int i = 0; i < count; i++)
+ if (m_d->m_customWidgets.at(i)->name() == name)
+ return m_d->m_customWidgetData.at(i);
+ return QDesignerCustomWidgetData();
+}
+
QObjectList QDesignerPluginManager::instances() const
{
QStringList plugins = registeredPlugins();
diff --git a/tools/designer/src/lib/shared/pluginmanager_p.h b/tools/designer/src/lib/shared/pluginmanager_p.h
index 479e94d..4654280 100644
--- a/tools/designer/src/lib/shared/pluginmanager_p.h
+++ b/tools/designer/src/lib/shared/pluginmanager_p.h
@@ -54,9 +54,11 @@
#define PLUGINMANAGER_H
#include "shared_global_p.h"
+#include "shared_enums_p.h"
#include <QtCore/QSharedDataPointer>
#include <QtCore/QMap>
+#include <QtCore/QPair>
#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
@@ -70,6 +72,9 @@ class QDesignerCustomWidgetSharedData;
/* Information contained in the Dom XML of a custom widget. */
class QDESIGNER_SHARED_EXPORT QDesignerCustomWidgetData {
public:
+ // StringPropertyType: validation mode and translatable flag.
+ typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
+
explicit QDesignerCustomWidgetData(const QString &pluginPath = QString());
enum ParseResult { ParseOk, ParseWarning, ParseError };
@@ -93,6 +98,8 @@ public:
QString xmlExtends() const;
// Optional. The name to be used in the widget box.
QString xmlDisplayName() const;
+ // Type of a string property
+ bool xmlStringPropertyType(const QString &name, StringPropertyType *type) const;
private:
QSharedDataPointer<QDesignerCustomWidgetSharedData> m_d;
@@ -128,6 +135,7 @@ public:
CustomWidgetList registeredCustomWidgets() const;
QDesignerCustomWidgetData customWidgetData(QDesignerCustomWidgetInterface *w) const;
+ QDesignerCustomWidgetData customWidgetData(const QString &className) const;
bool registerNewPlugins();
diff --git a/tools/designer/src/lib/shared/previewconfigurationwidget.cpp b/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
index 54a5c20..0134788 100644
--- a/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
+++ b/tools/designer/src/lib/shared/previewconfigurationwidget.cpp
@@ -65,43 +65,27 @@
#include <QtCore/QFileInfo>
#include <QtCore/QSharedData>
-// #define DEFAULT_SKINS_FROM_RESOURCE
-#ifdef DEFAULT_SKINS_FROM_RESOURCE
-QT_BEGIN_NAMESPACE
+
static const char *skinResourcePathC = ":/skins/";
-QT_END_NAMESPACE
-#else
-# include <QtCore/QLibraryInfo>
-#endif
QT_BEGIN_NAMESPACE
static const char *skinExtensionC = "skin";
-namespace {
- // Pair of skin name, path
- typedef QPair<QString, QString> SkinNamePath;
- typedef QList<SkinNamePath> Skins;
- enum { SkinComboNoneIndex = 0 };
-}
+// Pair of skin name, path
+typedef QPair<QString, QString> SkinNamePath;
+typedef QList<SkinNamePath> Skins;
+enum { SkinComboNoneIndex = 0 };
// find default skins (resources)
static const Skins &defaultSkins() {
static Skins rc;
if (rc.empty()) {
-#ifdef DEFAULT_SKINS_FROM_RESOURCE
const QString skinPath = QLatin1String(skinResourcePathC);
-#else
- QString skinPath = QLibraryInfo::location(QLibraryInfo::PrefixPath);
- skinPath += QDir::separator();
- skinPath += QLatin1String("tools");
- skinPath += QDir::separator();
- skinPath += QLatin1String("qvfb");
-#endif
QString pattern = QLatin1String("*.");
pattern += QLatin1String(skinExtensionC);
const QDir dir(skinPath, pattern);
- const QFileInfoList list = dir.entryInfoList();
+ const QFileInfoList list = dir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name);
if (list.empty())
return rc;
const QFileInfoList::const_iterator lcend = list.constEnd();
diff --git a/tools/designer/src/lib/shared/previewmanager.cpp b/tools/designer/src/lib/shared/previewmanager.cpp
index f972ffe..890bfc1 100644
--- a/tools/designer/src/lib/shared/previewmanager.cpp
+++ b/tools/designer/src/lib/shared/previewmanager.cpp
@@ -67,6 +67,7 @@
#include <QtGui/QAction>
#include <QtGui/QActionGroup>
#include <QtGui/QCursor>
+#include <QtGui/QMatrix>
#include <QtCore/QMap>
#include <QtCore/QDebug>
@@ -149,11 +150,16 @@ QGraphicsProxyWidget *DesignerZoomWidget::createProxyWidget(QGraphicsItem *paren
return new DesignerZoomProxyWidget(parent, wFlags);
}
-// --------- Widget Preview skin: Forward the key events to the window
+// PreviewDeviceSkin: Forwards the key events to the window and
+// provides context menu with rotation options. Derived class
+// can apply additional transformations to the skin.
+
class PreviewDeviceSkin : public DeviceSkin
{
Q_OBJECT
public:
+ enum Direction { DirectionUp, DirectionLeft, DirectionRight };
+
explicit PreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent);
virtual void setPreview(QWidget *w);
QSize screenSize() const { return m_screenSize; }
@@ -164,15 +170,36 @@ private slots:
void slotPopupMenu();
protected:
- virtual void populateContextMenu(QMenu *m);
+ virtual void populateContextMenu(QMenu *) {}
+
+private slots:
+ void slotDirection(QAction *);
+
+protected:
+ // Fit the widget in case the orientation changes (transposing screensize)
+ virtual void fitWidget(const QSize &size);
+ // Calculate the complete transformation for the skin
+ // (base class implementation provides rotation).
+ virtual QMatrix skinTransform() const;
private:
const QSize m_screenSize;
+ Direction m_direction;
+
+ QAction *m_directionUpAction;
+ QAction *m_directionLeftAction;
+ QAction *m_directionRightAction;
+ QAction *m_closeAction;
};
PreviewDeviceSkin::PreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent) :
- DeviceSkin(parameters, parent),
- m_screenSize(parameters.screenSize())
+ DeviceSkin(parameters, parent),
+ m_screenSize(parameters.screenSize()),
+ m_direction(DirectionUp),
+ m_directionUpAction(0),
+ m_directionLeftAction(0),
+ m_directionRightAction(0),
+ m_closeAction(0)
{
connect(this, SIGNAL(skinKeyPressEvent(int,QString,bool)),
this, SLOT(slotSkinKeyPressEvent(int,QString,bool)));
@@ -195,7 +222,6 @@ void PreviewDeviceSkin::slotSkinKeyPressEvent(int code, const QString& text, boo
QKeyEvent e(QEvent::KeyPress,code,0,text,autorep);
QApplication::sendEvent(focusWidget, &e);
}
-
}
void PreviewDeviceSkin::slotSkinKeyReleaseEvent(int code, const QString& text, bool autorep)
@@ -206,16 +232,83 @@ void PreviewDeviceSkin::slotSkinKeyReleaseEvent(int code, const QString& text, b
}
}
+// Create a checkable action with integer data and
+// set it checked if it matches the currentState.
+static inline QAction
+ *createCheckableActionIntData(const QString &label,
+ int actionValue, int currentState,
+ QActionGroup *ag, QObject *parent)
+{
+ QAction *a = new QAction(label, parent);
+ a->setData(actionValue);
+ a->setCheckable(true);
+ if (actionValue == currentState)
+ a->setChecked(true);
+ ag->addAction(a);
+ return a;
+}
+
void PreviewDeviceSkin::slotPopupMenu()
{
QMenu menu(this);
+ // Create actions
+ if (!m_directionUpAction) {
+ QActionGroup *directionGroup = new QActionGroup(this);
+ connect(directionGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotDirection(QAction*)));
+ directionGroup->setExclusive(true);
+ m_directionUpAction = createCheckableActionIntData(tr("&Portrait"), DirectionUp, m_direction, directionGroup, this);
+ m_directionLeftAction = createCheckableActionIntData(tr("Landscape (&CCW)"), DirectionLeft, m_direction, directionGroup, this);
+ m_directionRightAction = createCheckableActionIntData(tr("&Landscape (CW)"), DirectionRight, m_direction, directionGroup, this);
+ m_closeAction = new QAction(tr("&Close"), this);
+ connect(m_closeAction, SIGNAL(triggered()), parentWidget(), SLOT(close()));
+ }
+ menu.addAction(m_directionUpAction);
+ menu.addAction(m_directionLeftAction);
+ menu.addAction(m_directionRightAction);
+ menu.addSeparator();
populateContextMenu(&menu);
+ menu.addAction(m_closeAction);
menu.exec(QCursor::pos());
}
-void PreviewDeviceSkin::populateContextMenu(QMenu *menu)
+void PreviewDeviceSkin::slotDirection(QAction *a)
+{
+ const Direction newDirection = static_cast<Direction>(a->data().toInt());
+ if (m_direction == newDirection)
+ return;
+ const Qt::Orientation newOrientation = newDirection == DirectionUp ? Qt::Vertical : Qt::Horizontal;
+ const Qt::Orientation oldOrientation = m_direction == DirectionUp ? Qt::Vertical : Qt::Horizontal;
+ m_direction = newDirection;
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ if (oldOrientation != newOrientation) {
+ QSize size = screenSize();
+ if (newOrientation == Qt::Horizontal)
+ size.transpose();
+ fitWidget(size);
+ }
+ setTransform(skinTransform());
+ QApplication::restoreOverrideCursor();
+}
+
+void PreviewDeviceSkin::fitWidget(const QSize &size)
+{
+ view()->setFixedSize(size);
+}
+
+QMatrix PreviewDeviceSkin::skinTransform() const
{
- connect(menu->addAction(tr("&Close")), SIGNAL(triggered()), parentWidget(), SLOT(close()));
+ QMatrix newTransform;
+ switch (m_direction) {
+ case DirectionUp:
+ break;
+ case DirectionLeft:
+ newTransform.rotate(270.0);
+ break;
+ case DirectionRight:
+ newTransform.rotate(90.0);
+ break;
+ }
+ return newTransform;
}
// ------------ PreviewConfigurationPrivate
@@ -257,16 +350,20 @@ signals:
void zoomPercentChanged(int);
protected:
- virtual void populateContextMenu(QMenu *m);
+ virtual void populateContextMenu(QMenu *m);
+ virtual QMatrix skinTransform() const;
+ virtual void fitWidget(const QSize &size);
private:
ZoomMenu *m_zoomMenu;
+ QAction *m_zoomSubMenuAction;
ZoomWidget *m_zoomWidget;
};
ZoomablePreviewDeviceSkin::ZoomablePreviewDeviceSkin(const DeviceSkinParameters &parameters, QWidget *parent) :
PreviewDeviceSkin(parameters, parent),
m_zoomMenu(new ZoomMenu(this)),
+ m_zoomSubMenuAction(0),
m_zoomWidget(new DesignerZoomWidget)
{
connect(m_zoomMenu, SIGNAL(zoomChanged(int)), this, SLOT(setZoomPercent(int)));
@@ -279,10 +376,20 @@ ZoomablePreviewDeviceSkin::ZoomablePreviewDeviceSkin(const DeviceSkinParameters
setView(m_zoomWidget);
}
-void ZoomablePreviewDeviceSkin::setPreview(QWidget *formWidget)
+static inline qreal zoomFactor(int percent)
{
- formWidget->setFixedSize(screenSize());
+ return qreal(percent) / 100.0;
+}
+
+static inline QSize scaleSize(int zoomPercent, const QSize &size)
+{
+ return zoomPercent == 100 ? size : (QSizeF(size) * zoomFactor(zoomPercent)).toSize();
+}
+
+void ZoomablePreviewDeviceSkin::setPreview(QWidget *formWidget)
+{
m_zoomWidget->setWidget(formWidget);
+ m_zoomWidget->resize(scaleSize(zoomPercent(), screenSize()));
}
int ZoomablePreviewDeviceSkin::zoomPercent() const
@@ -290,32 +397,50 @@ int ZoomablePreviewDeviceSkin::zoomPercent() const
return m_zoomWidget->zoom();
}
-void ZoomablePreviewDeviceSkin::setZoomPercent(int z)
+void ZoomablePreviewDeviceSkin::setZoomPercent(int zp)
{
- if (z == zoomPercent())
+ if (zp == zoomPercent())
return;
// If not triggered by the menu itself: Update it
- if (m_zoomMenu->zoom() != z)
- m_zoomMenu->setZoom(z);
+ if (m_zoomMenu->zoom() != zp)
+ m_zoomMenu->setZoom(zp);
- const QCursor oldCursor = cursor();
- QApplication::setOverrideCursor(Qt::WaitCursor);
- // DeviceSkin has double, not qreal.
- const double hundred = 100.0;
- setZoom(static_cast<double>(z) / hundred);
- m_zoomWidget->setZoom(z);
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+ m_zoomWidget->setZoom(zp);
+ setTransform(skinTransform());
QApplication::restoreOverrideCursor();
}
void ZoomablePreviewDeviceSkin::populateContextMenu(QMenu *menu)
{
- m_zoomMenu->addActions(menu);
- menu->addSeparator();
- PreviewDeviceSkin::populateContextMenu(menu);
+ if (!m_zoomSubMenuAction) {
+ m_zoomSubMenuAction = new QAction(tr("&Zoom"), this);
+ QMenu *zoomSubMenu = new QMenu;
+ m_zoomSubMenuAction->setMenu(zoomSubMenu);
+ m_zoomMenu->addActions(zoomSubMenu);
+ }
+ menu->addAction(m_zoomSubMenuAction);
menu->addSeparator();
}
+QMatrix ZoomablePreviewDeviceSkin::skinTransform() const
+{
+ // Complete transformation consisting of base class rotation and zoom.
+ QMatrix rc = PreviewDeviceSkin::skinTransform();
+ const int zp = zoomPercent();
+ if (zp != 100) {
+ const qreal factor = zoomFactor(zp);
+ rc.scale(factor, factor);
+ }
+ return rc;
+}
+
+void ZoomablePreviewDeviceSkin::fitWidget(const QSize &size)
+{
+ m_zoomWidget->resize(scaleSize(zoomPercent(), size));
+}
+
// ------------- PreviewConfiguration
static const char *styleKey = "Style";
diff --git a/tools/designer/src/lib/shared/promotionmodel.cpp b/tools/designer/src/lib/shared/promotionmodel.cpp
index 7276195..4b4bc04 100644
--- a/tools/designer/src/lib/shared/promotionmodel.cpp
+++ b/tools/designer/src/lib/shared/promotionmodel.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::PromotionModel
-*/
-
#include "promotionmodel_p.h"
#include "widgetdatabase_p.h"
diff --git a/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp b/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp
index c4cdd9d..20e94dc 100644
--- a/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_formbuilder.cpp
@@ -473,6 +473,20 @@ QPixmap QDesignerFormBuilder::createPreviewPixmap(const QDesignerFormWindowInter
return rc;
}
+// ---------- NewFormWidgetFormBuilder
+
+NewFormWidgetFormBuilder::NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile) :
+ QDesignerFormBuilder(core, mode, deviceProfile)
+{
+}
+
+void NewFormWidgetFormBuilder::createCustomWidgets(DomCustomWidgets *dc)
+{
+ QSimpleResource::handleDomCustomWidgets(core(), dc);
+}
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h b/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h
index 9564c55..f026ac5 100644
--- a/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h
+++ b/tools/designer/src/lib/shared/qdesigner_formbuilder_p.h
@@ -75,7 +75,7 @@ namespace qdesigner_internal {
class DesignerPixmapCache;
class DesignerIconCache;
-/* Form builder used for previewing forms, widget box and new form dialog.
+/* Form builder used for previewing forms and widget box.
* It applies the system settings to its toplevel window. */
class QDESIGNER_SHARED_EXPORT QDesignerFormBuilder: public QFormBuilder
@@ -159,6 +159,21 @@ private:
bool m_mainWidget;
};
+// Form builder for a new form widget (preview). To allow for promoted
+// widgets in the template, it implements the handling of custom widgets
+// (adding of them to the widget database).
+
+class QDESIGNER_SHARED_EXPORT NewFormWidgetFormBuilder: public QDesignerFormBuilder {
+public:
+ NewFormWidgetFormBuilder(QDesignerFormEditorInterface *core,
+ Mode mode,
+ const DeviceProfile &deviceProfile = DeviceProfile());
+
+protected:
+ virtual void createCustomWidgets(DomCustomWidgets *);
+};
+
+
} // namespace qdesigner_internal
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp b/tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp
index caa3ef2..010cc17 100644
--- a/tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QDesignerPromotionDialog
-*/
-
#include "qdesigner_promotiondialog_p.h"
#include "promotionmodel_p.h"
#include "iconloader_p.h"
diff --git a/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp b/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
index 5a435ba..96b51f0 100644
--- a/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp
@@ -40,16 +40,56 @@
****************************************************************************/
#include "qdesigner_propertyeditor_p.h"
-#ifdef Q_OS_WIN
-# include <widgetfactory_p.h>
-#endif
-#include <QAction>
-#include <QLineEdit>
-#include <QAbstractButton>
+#include "pluginmanager_p.h"
+
+#include <QtDesigner/QDesignerFormEditorInterface>
+#include <widgetfactory_p.h>
+#include <QtGui/QAction>
+#include <QtGui/QLineEdit>
+#include <QtGui/QAbstractButton>
QT_BEGIN_NAMESPACE
namespace qdesigner_internal {
+typedef QDesignerPropertyEditor::StringPropertyParameters StringPropertyParameters;
+// A map of property name to type
+typedef QHash<QString, StringPropertyParameters> PropertyNameTypeMap;
+
+// Compile a map of hard-coded string property types
+static const PropertyNameTypeMap &stringPropertyTypes()
+{
+ static PropertyNameTypeMap propertyNameTypeMap;
+ if (propertyNameTypeMap.empty()) {
+ const StringPropertyParameters richtext(ValidationRichText, true);
+ // Accessibility. Both are texts the narrator reads
+ propertyNameTypeMap.insert(QLatin1String("accessibleDescription"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("accessibleName"), richtext);
+ // object names
+ const StringPropertyParameters objectName(ValidationObjectName, false);
+ propertyNameTypeMap.insert(QLatin1String("buddy"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentItemName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentPageName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("currentTabName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("layoutName"), objectName);
+ propertyNameTypeMap.insert(QLatin1String("spacerName"), objectName);
+ // Style sheet
+ propertyNameTypeMap.insert(QLatin1String("styleSheet"), StringPropertyParameters(ValidationStyleSheet, false));
+ // Buttons/ QCommandLinkButton
+ const StringPropertyParameters multiline(ValidationMultiLine, true);
+ propertyNameTypeMap.insert(QLatin1String("description"), multiline);
+ propertyNameTypeMap.insert(QLatin1String("iconText"), multiline);
+ // Tooltips, etc.
+ propertyNameTypeMap.insert(QLatin1String("toolTip"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("whatsThis"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("windowIconText"), richtext);
+ propertyNameTypeMap.insert(QLatin1String("html"), richtext);
+ // A QWizard page id
+ propertyNameTypeMap.insert(QLatin1String("pageId"), StringPropertyParameters(ValidationSingleLine, false));
+ // QPlainTextEdit
+ propertyNameTypeMap.insert(QLatin1String("plainText"), StringPropertyParameters(ValidationMultiLine, true));
+ }
+ return propertyNameTypeMap;
+}
QDesignerPropertyEditor::QDesignerPropertyEditor(QWidget *parent, Qt::WindowFlags flags) :
QDesignerPropertyEditorInterface(parent, flags)
@@ -68,33 +108,19 @@ QDesignerPropertyEditor::StringPropertyParameters QDesignerPropertyEditor::textP
return StringPropertyParameters(vm, false);
}
- // Accessibility. Both are texts the narrator reads
- if (propertyName == QLatin1String("accessibleDescription") || propertyName == QLatin1String("accessibleName"))
- return StringPropertyParameters(ValidationRichText, true);
-
- // Names
- if (propertyName == QLatin1String("buddy")
- || propertyName == QLatin1String("currentItemName")
- || propertyName == QLatin1String("currentPageName")
- || propertyName == QLatin1String("currentTabName")
- || propertyName == QLatin1String("layoutName")
- || propertyName == QLatin1String("spacerName"))
- return StringPropertyParameters(ValidationObjectName, false);
-
- if (propertyName.endsWith(QLatin1String("Name")))
- return StringPropertyParameters(ValidationSingleLine, true);
-
- // Multi line?
- if (propertyName == QLatin1String("styleSheet"))
- return StringPropertyParameters(ValidationStyleSheet, false);
-
- if (propertyName == QLatin1String("description") || propertyName == QLatin1String("iconText")) // QCommandLinkButton
- return StringPropertyParameters(ValidationMultiLine, true);
+ // Check custom widgets by class.
+ const QString className = WidgetFactory::classNameOf(core, object);
+ const QDesignerCustomWidgetData customData = core->pluginManager()->customWidgetData(className);
+ if (!customData.isNull()) {
+ StringPropertyParameters customType;
+ if (customData.xmlStringPropertyType(propertyName, &customType))
+ return customType;
+ }
- if (propertyName == QLatin1String("toolTip") || propertyName.endsWith(QLatin1String("ToolTip")) ||
- propertyName == QLatin1String("whatsThis") ||
- propertyName == QLatin1String("windowIconText") || propertyName == QLatin1String("html"))
- return StringPropertyParameters(ValidationRichText, true);
+ // Check hardcoded property ames
+ const PropertyNameTypeMap::const_iterator hit = stringPropertyTypes().constFind(propertyName);
+ if (hit != stringPropertyTypes().constEnd())
+ return hit.value();
// text: Check according to widget type.
if (propertyName == QLatin1String("text")) {
@@ -104,17 +130,17 @@ QDesignerPropertyEditor::StringPropertyParameters QDesignerPropertyEditor::textP
return StringPropertyParameters(ValidationMultiLine, true);
return StringPropertyParameters(ValidationRichText, true);
}
- if (propertyName == QLatin1String("pageId")) // A QWizard page id
- return StringPropertyParameters(ValidationSingleLine, false);
- if (propertyName == QLatin1String("plainText")) // QPlainTextEdit
- return StringPropertyParameters(ValidationMultiLine, true);
+ // Fuzzy matching
+ if (propertyName.endsWith(QLatin1String("Name")))
+ return StringPropertyParameters(ValidationSingleLine, true);
+
+ if (propertyName.endsWith(QLatin1String("ToolTip")))
+ return StringPropertyParameters(ValidationRichText, true);
#ifdef Q_OS_WIN // No translation for the active X "control" property
- if (propertyName == QLatin1String("control") && WidgetFactory::classNameOf(core, object) == QLatin1String("QAxWidget"))
+ if (propertyName == QLatin1String("control") && className == QLatin1String("QAxWidget"))
return StringPropertyParameters(ValidationSingleLine, false);
-#else
- Q_UNUSED(core);
#endif
// default to single
diff --git a/tools/designer/src/lib/shared/qdesigner_stackedbox.cpp b/tools/designer/src/lib/shared/qdesigner_stackedbox.cpp
index 38b1d7c..0b45b7b 100644
--- a/tools/designer/src/lib/shared/qdesigner_stackedbox.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_stackedbox.cpp
@@ -315,7 +315,7 @@ QMenu *QStackedWidgetEventFilter::addContextMenuActions(QMenu *popup)
QMenu *pageMenu = 0;
const int count = stackedWidget()->count();
const bool hasSeveralPages = count > 1;
- m_actionDeletePage->setEnabled(hasSeveralPages);
+ m_actionDeletePage->setEnabled(count);
if (count) {
const QString pageSubMenuLabel = tr("Page %1 of %2").arg(stackedWidget()->currentIndex() + 1).arg(count);
pageMenu = popup->addMenu(pageSubMenuLabel);
@@ -327,10 +327,13 @@ QMenu *QStackedWidgetEventFilter::addContextMenuActions(QMenu *popup)
qdesigner_internal::PromotionTaskMenu::SuppressGlobalEdit,
pageMenu);
}
+ QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
+ insertPageMenu->addAction(m_actionInsertPageAfter);
+ insertPageMenu->addAction(m_actionInsertPage);
+ } else {
+ QAction *insertPageAction = popup->addAction(tr("Insert Page"));
+ connect(insertPageAction, SIGNAL(triggered()), this, SLOT(addPage()));
}
- QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
- insertPageMenu->addAction(m_actionInsertPageAfter);
- insertPageMenu->addAction(m_actionInsertPage);
popup->addAction(m_actionNextPage);
m_actionNextPage->setEnabled(hasSeveralPages);
popup->addAction(m_actionPreviousPage);
diff --git a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp
index 22833b3..eb4dfa2 100644
--- a/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_tabwidget.cpp
@@ -368,7 +368,7 @@ QMenu *QTabWidgetEventFilter::addContextMenuActions(QMenu *popup)
{
QMenu *pageMenu = 0;
const int count = m_tabWidget->count();
- m_actionDeletePage->setEnabled(count > 1);
+ m_actionDeletePage->setEnabled(count);
if (count) {
const int currentIndex = m_tabWidget->currentIndex();
const QString pageSubMenuLabel = tr("Page %1 of %2").arg(currentIndex + 1).arg(count);
@@ -381,11 +381,13 @@ QMenu *QTabWidgetEventFilter::addContextMenuActions(QMenu *popup)
qdesigner_internal::PromotionTaskMenu::SuppressGlobalEdit,
pageMenu);
}
+ QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
+ insertPageMenu->addAction(m_actionInsertPageAfter);
+ insertPageMenu->addAction(m_actionInsertPage);
+ } else {
+ QAction *insertPageAction = popup->addAction(tr("Insert Page"));
+ connect(insertPageAction, SIGNAL(triggered()), this, SLOT(addPage()));
}
-
- QMenu *insertPageMenu = popup->addMenu(tr("Insert Page"));
- insertPageMenu->addAction(m_actionInsertPageAfter);
- insertPageMenu->addAction(m_actionInsertPage);
popup->addSeparator();
return pageMenu;
}
diff --git a/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp b/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
index 93b1fa6..ae31c33 100644
--- a/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QDesignerTaskMenu
-*/
-
#include "qdesigner_taskmenu_p.h"
#include "qdesigner_command_p.h"
#include "richtexteditor_p.h"
diff --git a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
index f0e51de..2693452 100644
--- a/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_toolbar.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::Sentinel
-*/
-
#include "qdesigner_toolbar_p.h"
#include "qdesigner_command_p.h"
#include "actionrepository_p.h"
@@ -65,7 +61,6 @@ TRANSLATOR qdesigner_internal::Sentinel
#include <QtGui/QMenu>
#include <QtGui/qevent.h>
#include <QtGui/QApplication>
-#include <QtGui/private/qtoolbarlayout_p.h>
#include <QtCore/QDebug>
Q_DECLARE_METATYPE(QAction*)
@@ -445,11 +440,17 @@ QAction *ToolBarEventFilter::actionAt(const QToolBar *tb, const QPoint &pos)
return tb->actions().at(index);
}
+//that's a trick to get acces to the initStyleOption which is a protected member
+class FriendlyToolBar : public QToolBar {
+public:
+ friend class ToolBarEventFilter;
+};
+
QRect ToolBarEventFilter::handleArea(const QToolBar *tb)
{
- const QToolBarLayout *tbl = qobject_cast<QToolBarLayout *>(tb->layout());
- Q_ASSERT(tbl);
- return tbl->handleRect();
+ QStyleOptionToolBar opt;
+ static_cast<const FriendlyToolBar*>(tb)->initStyleOption(&opt);
+ return tb->style()->subElementRect(QStyle::SE_ToolBarHandle, &opt, tb);
}
bool ToolBarEventFilter::withinHandleArea(const QToolBar *tb, const QPoint &pos)
diff --git a/tools/designer/src/lib/shared/qdesigner_widgetbox.cpp b/tools/designer/src/lib/shared/qdesigner_widgetbox.cpp
index 34f7016..e25b880 100644
--- a/tools/designer/src/lib/shared/qdesigner_widgetbox.cpp
+++ b/tools/designer/src/lib/shared/qdesigner_widgetbox.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QDesignerWidgetBox
-*/
-
#include "qdesigner_widgetbox_p.h"
#include "qdesigner_utils_p.h"
diff --git a/tools/designer/src/lib/shared/qsimpleresource.cpp b/tools/designer/src/lib/shared/qsimpleresource.cpp
index 4a9c7fe..63dfb03 100644
--- a/tools/designer/src/lib/shared/qsimpleresource.cpp
+++ b/tools/designer/src/lib/shared/qsimpleresource.cpp
@@ -41,6 +41,7 @@
#include "qsimpleresource_p.h"
#include "widgetfactory_p.h"
+#include "widgetdatabase_p.h"
#include <formscriptrunner_p.h>
#include <properties_p.h>
@@ -57,6 +58,8 @@
#include <QtGui/QWidget>
#include <QtGui/QAction>
#include <QtCore/QDebug>
+#include <QtCore/QCoreApplication>
+
QT_BEGIN_NAMESPACE
@@ -267,6 +270,136 @@ bool QSimpleResource::warningsEnabled()
return m_warningsEnabled;
}
+// Custom widgets handling helpers
+
+// Add unique fake slots and signals to lists
+bool QSimpleResource::addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals)
+{
+ if (!domSlots)
+ return false;
+
+ bool rc = false;
+ foreach (const QString &fakeSlot, domSlots->elementSlot())
+ if (fakeSlots.indexOf(fakeSlot) == -1) {
+ fakeSlots += fakeSlot;
+ rc = true;
+ }
+
+ foreach (const QString &fakeSignal, domSlots->elementSignal())
+ if (fakeSignals.indexOf(fakeSignal) == -1) {
+ fakeSignals += fakeSignal;
+ rc = true;
+ }
+ return rc;
+}
+
+void QSimpleResource::addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item)
+{
+ const DomSlots *domSlots = domCustomWidget->elementSlots();
+ if (!domSlots)
+ return;
+
+ // Merge in new slots, signals
+ QStringList fakeSlots = item->fakeSlots();
+ QStringList fakeSignals = item->fakeSignals();
+ if (addFakeMethods(domSlots, fakeSlots, fakeSignals)) {
+ item->setFakeSlots(fakeSlots);
+ item->setFakeSignals(fakeSignals);
+ }
+}
+
+// Perform one iteration of adding the custom widgets to the database,
+// looking up the base class and inheriting its data.
+// Remove the succeeded custom widgets from the list.
+// Classes whose base class could not be found are left in the list.
+
+void QSimpleResource::addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core,
+ QList<DomCustomWidget*>& custom_widget_list)
+{
+ QDesignerWidgetDataBaseInterface *db = core->widgetDataBase();
+ for (int i=0; i < custom_widget_list.size(); ) {
+ bool classInserted = false;
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ QString includeFile;
+ IncludeType includeType = IncludeLocal;
+ if (const DomHeader *header = custom_widget->elementHeader()) {
+ includeFile = header->text();
+ if (header->hasAttributeLocation() && header->attributeLocation() == QLatin1String("global"))
+ includeType = IncludeGlobal;
+ }
+ const bool domIsContainer = custom_widget->elementContainer();
+ // Append a new item
+ if (base_class.isEmpty()) {
+ WidgetDataBaseItem *item = new WidgetDataBaseItem(customClassName);
+ item->setPromoted(false);
+ item->setGroup(QCoreApplication::translate("Designer", "Custom Widgets"));
+ item->setIncludeFile(buildIncludeFile(includeFile, includeType));
+ item->setContainer(domIsContainer);
+ item->setCustom(true);
+ addFakeMethodsToWidgetDataBase(custom_widget, item);
+ db->append(item);
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ } else {
+ // Create a new entry cloned from base class. Note that this will ignore existing
+ // classes, eg, plugin custom widgets.
+ QDesignerWidgetDataBaseItemInterface *item =
+ appendDerived(db, customClassName, QCoreApplication::translate("Designer", "Promoted Widgets"),
+ base_class,
+ buildIncludeFile(includeFile, includeType),
+ true,true);
+ // Ok, base class found.
+ if (item) {
+ // Hack to accommodate for old UI-files in which "container" is not set properly:
+ // Apply "container" from DOM only if true (else, eg classes from QFrame might not accept
+ // dropping child widgets on them as container=false). This also allows for
+ // QWidget-derived stacked pages.
+ if (domIsContainer)
+ item->setContainer(domIsContainer);
+
+ addFakeMethodsToWidgetDataBase(custom_widget, static_cast<WidgetDataBaseItem*>(item));
+ custom_widget_list.removeAt(i);
+ classInserted = true;
+ }
+ }
+ // Skip failed item.
+ if (!classInserted)
+ i++;
+ }
+
+}
+
+void QSimpleResource::handleDomCustomWidgets(const QDesignerFormEditorInterface *core,
+ const DomCustomWidgets *dom_custom_widgets)
+{
+ if (dom_custom_widgets == 0)
+ return;
+ QList<DomCustomWidget*> custom_widget_list = dom_custom_widgets->elementCustomWidget();
+ // Attempt to insert each item derived from its base class.
+ // This should at most require two iterations in the event that the classes are out of order
+ // (derived first, max depth: promoted custom plugin = 2)
+ for (int iteration = 0; iteration < 2; iteration++) {
+ addCustomWidgetsToWidgetDatabase(core, custom_widget_list);
+ if (custom_widget_list.empty())
+ return;
+ }
+ // Oops, there are classes left whose base class could not be found.
+ // Default them to QWidget with warnings.
+ const QString fallBackBaseClass = QLatin1String("QWidget");
+ for (int i=0; i < custom_widget_list.size(); i++ ) {
+ DomCustomWidget *custom_widget = custom_widget_list[i];
+ const QString customClassName = custom_widget->elementClass();
+ const QString base_class = custom_widget->elementExtends();
+ qDebug() << "** WARNING The base class " << base_class << " of the custom widget class " << customClassName
+ << " could not be found. Defaulting to " << fallBackBaseClass << '.';
+ custom_widget->setElementExtends(fallBackBaseClass);
+ }
+ // One more pass.
+ addCustomWidgetsToWidgetDatabase(core, custom_widget_list);
+}
+
// ------------ FormBuilderClipboard
FormBuilderClipboard::FormBuilderClipboard(QWidget *w)
diff --git a/tools/designer/src/lib/shared/qsimpleresource_p.h b/tools/designer/src/lib/shared/qsimpleresource_p.h
index 2608160..8569ef2 100644
--- a/tools/designer/src/lib/shared/qsimpleresource_p.h
+++ b/tools/designer/src/lib/shared/qsimpleresource_p.h
@@ -55,15 +55,21 @@
#include "shared_global_p.h"
#include "abstractformbuilder.h"
+#include <QtCore/QStringList>
QT_BEGIN_NAMESPACE
class DomScript;
+class DomCustomWidgets;
+class DomCustomWidget;
+class DomSlots;
class QDesignerFormEditorInterface;
namespace qdesigner_internal {
+class WidgetDataBaseItem;
+
class QDESIGNER_SHARED_EXPORT QSimpleResource : public QAbstractFormBuilder
{
public:
@@ -92,6 +98,11 @@ public:
static QString customWidgetScript(QDesignerFormEditorInterface *core, const QString &className);
static bool hasCustomWidgetScript(QDesignerFormEditorInterface *core, QObject *object);
+ // Implementation for FormBuilder::createDomCustomWidgets() that adds
+ // the custom widgets to the widget database
+ static void handleDomCustomWidgets(const QDesignerFormEditorInterface *core,
+ const DomCustomWidgets *dom_custom_widgets);
+
protected:
virtual QIcon nameToIcon(const QString &filePath, const QString &qrcPath);
virtual QString iconToFilePath(const QIcon &pm) const;
@@ -105,7 +116,13 @@ protected:
typedef QList<DomScript*> DomScripts;
static void addScript(const QString &script, ScriptSource source, DomScripts &domScripts);
+ static bool addFakeMethods(const DomSlots *domSlots, QStringList &fakeSlots, QStringList &fakeSignals);
+
private:
+ static void addCustomWidgetsToWidgetDatabase(const QDesignerFormEditorInterface *core,
+ QList<DomCustomWidget*>& custom_widget_list);
+ static void addFakeMethodsToWidgetDataBase(const DomCustomWidget *domCustomWidget, WidgetDataBaseItem *item);
+
static bool m_warningsEnabled;
QDesignerFormEditorInterface *m_core;
};
diff --git a/tools/designer/src/lib/shared/qtresourceview.cpp b/tools/designer/src/lib/shared/qtresourceview.cpp
index b6c3612..40be3e6 100644
--- a/tools/designer/src/lib/shared/qtresourceview.cpp
+++ b/tools/designer/src/lib/shared/qtresourceview.cpp
@@ -44,6 +44,7 @@
#include "qtresourcemodel_p.h"
#include "qtresourceeditordialog_p.h"
#include "iconloader_p.h"
+#include "filterwidget_p.h" // For FilterWidget
#include <QtDesigner/QDesignerFormEditorInterface>
@@ -144,6 +145,7 @@ public:
void slotReloadResources();
void slotCopyResourcePath();
void slotListWidgetContextMenuRequested(const QPoint &pos);
+ void slotFilterChanged(const QString &pattern);
void createPaths();
QTreeWidgetItem *createPath(const QString &path, QTreeWidgetItem *parent);
void createResources(const QString &path);
@@ -152,16 +154,20 @@ public:
void restoreSettings();
void saveSettings();
void updateActions();
+ void filterOutResources();
QPixmap makeThumbnail(const QPixmap &pix) const;
QDesignerFormEditorInterface *m_core;
QtResourceModel *m_resourceModel;
QToolBar *m_toolBar;
+ qdesigner_internal::FilterWidget *m_filterWidget;
QTreeWidget *m_treeWidget;
QListWidget *m_listWidget;
QSplitter *m_splitter;
- QMap<QString, QStringList> m_pathToContents; // full path to contents file names
+ QMap<QString, QStringList> m_pathToContents; // full path to contents file names (full path to its resource filenames)
+ QMap<QString, QString> m_pathToParentPath; // full path to full parent path
+ QMap<QString, QStringList> m_pathToSubPaths; // full path to full sub paths
QMap<QString, QTreeWidgetItem *> m_pathToItem;
QMap<QTreeWidgetItem *, QString> m_itemToPath;
QMap<QString, QListWidgetItem *> m_resourceToItem;
@@ -175,6 +181,7 @@ public:
bool m_ignoreGuiSignals;
QString m_settingsKey;
bool m_resourceEditingEnabled;
+ QString m_filterPattern;
};
QtResourceViewPrivate::QtResourceViewPrivate(QDesignerFormEditorInterface *core) :
@@ -251,6 +258,12 @@ void QtResourceViewPrivate::slotListWidgetContextMenuRequested(const QPoint &pos
menu.exec(m_listWidget->mapToGlobal(pos));
}
+void QtResourceViewPrivate::slotFilterChanged(const QString &pattern)
+{
+ m_filterPattern = pattern;
+ filterOutResources();
+}
+
void QtResourceViewPrivate::storeExpansionState()
{
QMapIterator<QString, QTreeWidgetItem *> it(m_pathToItem);
@@ -294,6 +307,7 @@ void QtResourceViewPrivate::updateActions()
m_editResourcesAction->setVisible(m_resourceEditingEnabled);
m_editResourcesAction->setEnabled(resourceActive);
m_reloadResourcesAction->setEnabled(resourceActive);
+ m_filterWidget->setEnabled(resourceActive);
}
void QtResourceViewPrivate::slotResourceSetActivated(QtResourceSet *resourceSet)
@@ -307,6 +321,8 @@ void QtResourceViewPrivate::slotResourceSetActivated(QtResourceSet *resourceSet)
const QString currentResource = m_itemToResource.value(m_listWidget->currentItem());
m_treeWidget->clear();
m_pathToContents.clear();
+ m_pathToParentPath.clear();
+ m_pathToSubPaths.clear();
m_pathToItem.clear();
m_itemToPath.clear();
m_listWidget->clear();
@@ -320,6 +336,7 @@ void QtResourceViewPrivate::slotResourceSetActivated(QtResourceSet *resourceSet)
q_ptr->selectResource(currentResource);
else if (!currentPath.isEmpty())
q_ptr->selectResource(currentPath);
+ filterOutResources();
}
void QtResourceViewPrivate::slotCurrentPathChanged(QTreeWidgetItem *item)
@@ -362,9 +379,6 @@ void QtResourceViewPrivate::createPaths()
const QString root(QLatin1Char(':'));
- QMap<QString, QString> pathToParentPath; // full path to full parent path
- QMap<QString, QStringList> pathToSubPaths; // full path to full sub paths
-
QMap<QString, QString> contents = m_resourceModel->contents();
QMapIterator<QString, QString> itContents(contents);
while (itContents.hasNext()) {
@@ -372,11 +386,11 @@ void QtResourceViewPrivate::createPaths()
const QFileInfo fi(filePath);
QString dirPath = fi.absolutePath();
m_pathToContents[dirPath].append(fi.fileName());
- while (!pathToParentPath.contains(dirPath) && dirPath != root) {
+ while (!m_pathToParentPath.contains(dirPath) && dirPath != root) { // create all parent paths
const QFileInfo fd(dirPath);
const QString parentDirPath = fd.absolutePath();
- pathToParentPath[dirPath] = parentDirPath;
- pathToSubPaths[parentDirPath].append(dirPath);
+ m_pathToParentPath[dirPath] = parentDirPath;
+ m_pathToSubPaths[parentDirPath].append(dirPath);
dirPath = parentDirPath;
}
}
@@ -387,13 +401,126 @@ void QtResourceViewPrivate::createPaths()
QPair<QString, QTreeWidgetItem *> pathToParentItem = pathToParentItemQueue.dequeue();
const QString path = pathToParentItem.first;
QTreeWidgetItem *item = createPath(path, pathToParentItem.second);
- QStringList subPaths = pathToSubPaths.value(path);
+ QStringList subPaths = m_pathToSubPaths.value(path);
QStringListIterator itSubPaths(subPaths);
while (itSubPaths.hasNext())
pathToParentItemQueue.enqueue(qMakePair(itSubPaths.next(), item));
}
}
+void QtResourceViewPrivate::filterOutResources()
+{
+ QMap<QString, bool> pathToMatchingContents; // true means the path has any matching contents
+ QMap<QString, bool> pathToVisible; // true means the path has to be shown
+
+ // 1) we go from root path recursively.
+ // 2) we check every path if it contains at least one matching resource - if empty we add it
+ // to pathToMatchingContents and pathToVisible with false, if non empty
+ // we add it with true and change every parent path in pathToVisible to true.
+ // 3) we hide these items which has pathToVisible value false.
+
+ const bool matchAll = m_filterPattern.isEmpty();
+ const QString root(QLatin1Char(':'));
+
+ QQueue<QString> pathQueue;
+ pathQueue.enqueue(root);
+ while (!pathQueue.isEmpty()) {
+ const QString path = pathQueue.dequeue();
+
+ QStringList fileNames = m_pathToContents.value(path);
+ QStringListIterator it(fileNames);
+ bool hasContents = matchAll;
+ if (!matchAll) { // the case filter is not empty - we check if the path contains anything
+ while (it.hasNext()) {
+ QString fileName = it.next();
+ hasContents = fileName.contains(m_filterPattern, Qt::CaseInsensitive);
+ if (hasContents) // the path contains at least one resource which matches the filter
+ break;
+ }
+ }
+
+ pathToMatchingContents[path] = hasContents;
+ pathToVisible[path] = hasContents;
+
+ if (hasContents) { // if the path is going to be shown we need to show all its parent paths
+ QString parentPath = m_pathToParentPath.value(path);
+ while (!parentPath.isEmpty()) {
+ QString p = parentPath;
+ if (pathToVisible.value(p)) // parent path is already shown, we break the loop
+ break;
+ pathToVisible[p] = true;
+ parentPath = m_pathToParentPath.value(p);
+ }
+ }
+
+ QStringList subPaths = m_pathToSubPaths.value(path); // we do the same for children paths
+ QStringListIterator itSubPaths(subPaths);
+ while (itSubPaths.hasNext())
+ pathQueue.enqueue(itSubPaths.next());
+ }
+
+ // we setup here new path and resource to be activated
+ const QString currentPath = m_itemToPath.value(m_treeWidget->currentItem());
+ QString newCurrentPath = currentPath;
+ QString currentResource = m_itemToResource.value(m_listWidget->currentItem());
+ if (!matchAll) {
+ bool searchForNewPathWithContents = true;
+
+ if (!currentPath.isEmpty()) { // if the currentPath is empty we will search for a new path too
+ QMap<QString, bool>::ConstIterator it = pathToMatchingContents.constFind(currentPath);
+ if (it != pathToMatchingContents.constEnd() && it.value()) // the current item has contents, we don't need to search for another path
+ searchForNewPathWithContents = false;
+ }
+
+ if (searchForNewPathWithContents) {
+ // we find the first path with the matching contents
+ QMap<QString, bool>::ConstIterator itContents = pathToMatchingContents.constBegin();
+ while (itContents != pathToMatchingContents.constEnd()) {
+ if (itContents.value()) {
+ newCurrentPath = itContents.key(); // the new path will be activated
+ break;
+ }
+
+ itContents++;
+ }
+ }
+
+ QFileInfo fi(currentResource);
+ if (!fi.fileName().contains(m_filterPattern, Qt::CaseInsensitive)) { // the case when the current resource is filtered out
+ const QStringList fileNames = m_pathToContents.value(newCurrentPath);
+ QStringListIterator it(fileNames);
+ while (it.hasNext()) { // we try to select the first matching resource from the newCurrentPath
+ QString fileName = it.next();
+ if (fileName.contains(m_filterPattern, Qt::CaseInsensitive)) {
+ QDir dirPath(newCurrentPath);
+ currentResource = dirPath.absoluteFilePath(fileName); // the new resource inside newCurrentPath will be activated
+ break;
+ }
+ }
+ }
+ }
+
+ QTreeWidgetItem *newCurrentItem = m_pathToItem.value(newCurrentPath);
+ if (currentPath != newCurrentPath)
+ m_treeWidget->setCurrentItem(newCurrentItem);
+ else
+ slotCurrentPathChanged(newCurrentItem); // trigger filtering on the current path
+
+ QListWidgetItem *currentResourceItem = m_resourceToItem.value(currentResource);
+ if (currentResourceItem) {
+ m_listWidget->setCurrentItem(currentResourceItem);
+ m_listWidget->scrollToItem(currentResourceItem);
+ }
+
+ QMapIterator<QString, bool> it(pathToVisible); // hide all paths filtered out
+ while (it.hasNext()) {
+ const QString path = it.next().key();
+ QTreeWidgetItem *item = m_pathToItem.value(path);
+ if (item)
+ item->setHidden(!it.value());
+ }
+}
+
QTreeWidgetItem *QtResourceViewPrivate::createPath(const QString &path, QTreeWidgetItem *parent)
{
QTreeWidgetItem *item = 0;
@@ -417,27 +544,32 @@ QTreeWidgetItem *QtResourceViewPrivate::createPath(const QString &path, QTreeWid
void QtResourceViewPrivate::createResources(const QString &path)
{
+ const bool matchAll = m_filterPattern.isEmpty();
+
QDir dir(path);
- QStringList files = m_pathToContents.value(path);
- QStringListIterator it(files);
+ QStringList fileNames = m_pathToContents.value(path);
+ QStringListIterator it(fileNames);
while (it.hasNext()) {
- QString file = it.next();
- QString filePath = dir.absoluteFilePath(file);
- QFileInfo fi(filePath);
- if (fi.isFile()) {
- QListWidgetItem *item = new QListWidgetItem(fi.fileName(), m_listWidget);
- const QPixmap pix = QPixmap(filePath);
- if (pix.isNull()) {
- item->setToolTip(filePath);
- } else {
- item->setIcon(QIcon(makeThumbnail(pix)));
- const QSize size = pix.size();
- item->setToolTip(QtResourceView::tr("Size: %1 x %2\n%3").arg(size.width()).arg(size.height()).arg(filePath));
+ QString fileName = it.next();
+ const bool showProperty = matchAll || fileName.contains(m_filterPattern, Qt::CaseInsensitive);
+ if (showProperty) {
+ QString filePath = dir.absoluteFilePath(fileName);
+ QFileInfo fi(filePath);
+ if (fi.isFile()) {
+ QListWidgetItem *item = new QListWidgetItem(fi.fileName(), m_listWidget);
+ const QPixmap pix = QPixmap(filePath);
+ if (pix.isNull()) {
+ item->setToolTip(filePath);
+ } else {
+ item->setIcon(QIcon(makeThumbnail(pix)));
+ const QSize size = pix.size();
+ item->setToolTip(QtResourceView::tr("Size: %1 x %2\n%3").arg(size.width()).arg(size.height()).arg(filePath));
+ }
+ item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
+ item->setData(Qt::UserRole, filePath);
+ m_itemToResource[item] = filePath;
+ m_resourceToItem[filePath] = item;
}
- item->setFlags(item->flags() | Qt::ItemIsDragEnabled);
- item->setData(Qt::UserRole, filePath);
- m_itemToResource[item] = filePath;
- m_resourceToItem[filePath] = item;
}
}
}
@@ -464,6 +596,11 @@ QtResourceView::QtResourceView(QDesignerFormEditorInterface *core, QWidget *pare
connect(d_ptr->m_copyResourcePathAction, SIGNAL(triggered()), this, SLOT(slotCopyResourcePath()));
d_ptr->m_copyResourcePathAction->setEnabled(false);
+ //d_ptr->m_filterWidget = new qdesigner_internal::FilterWidget(0, qdesigner_internal::FilterWidget::LayoutAlignNone);
+ d_ptr->m_filterWidget = new qdesigner_internal::FilterWidget(d_ptr->m_toolBar);
+ d_ptr->m_toolBar->addWidget(d_ptr->m_filterWidget);
+ connect(d_ptr->m_filterWidget, SIGNAL(filterChanged(QString)), this, SLOT(slotFilterChanged(QString)));
+
d_ptr->m_splitter = new QSplitter;
d_ptr->m_splitter->setChildrenCollapsible(false);
d_ptr->m_splitter->addWidget(d_ptr->m_treeWidget);
diff --git a/tools/designer/src/lib/shared/qtresourceview_p.h b/tools/designer/src/lib/shared/qtresourceview_p.h
index 51a6353..fb8fb83 100644
--- a/tools/designer/src/lib/shared/qtresourceview_p.h
+++ b/tools/designer/src/lib/shared/qtresourceview_p.h
@@ -113,6 +113,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void slotReloadResources())
Q_PRIVATE_SLOT(d_func(), void slotCopyResourcePath())
Q_PRIVATE_SLOT(d_func(), void slotListWidgetContextMenuRequested(const QPoint &pos))
+ Q_PRIVATE_SLOT(d_func(), void slotFilterChanged(const QString &pattern))
};
class QDESIGNER_SHARED_EXPORT QtResourceViewDialog : public QDialog
diff --git a/tools/designer/src/lib/shared/richtexteditor.cpp b/tools/designer/src/lib/shared/richtexteditor.cpp
index 6563358..a4df04f 100644
--- a/tools/designer/src/lib/shared/richtexteditor.cpp
+++ b/tools/designer/src/lib/shared/richtexteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::RichTextEditorDialog
-*/
-
#include "richtexteditor_p.h"
#include "htmlhighlighter_p.h"
#include "iconselector_p.h"
diff --git a/tools/designer/src/lib/shared/scriptdialog.cpp b/tools/designer/src/lib/shared/scriptdialog.cpp
index 3cdf083..847afa3 100644
--- a/tools/designer/src/lib/shared/scriptdialog.cpp
+++ b/tools/designer/src/lib/shared/scriptdialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ScriptDialog
-*/
-
#include "scriptdialog_p.h"
#include "qscripthighlighter_p.h"
diff --git a/tools/designer/src/lib/shared/scripterrordialog.cpp b/tools/designer/src/lib/shared/scripterrordialog.cpp
index f41b444..629fc4e 100644
--- a/tools/designer/src/lib/shared/scripterrordialog.cpp
+++ b/tools/designer/src/lib/shared/scripterrordialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::ScriptErrorDialog
-*/
-
#include "scripterrordialog_p.h"
#include <QtGui/QTextEdit>
diff --git a/tools/designer/src/lib/shared/stylesheeteditor.cpp b/tools/designer/src/lib/shared/stylesheeteditor.cpp
index c4e54aa..2066ad8 100644
--- a/tools/designer/src/lib/shared/stylesheeteditor.cpp
+++ b/tools/designer/src/lib/shared/stylesheeteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::StyleSheetEditorDialog
-*/
-
#include "stylesheeteditor_p.h"
#include "csshighlighter_p.h"
#include "iconselector_p.h"
diff --git a/tools/designer/src/lib/shared/widgetfactory.cpp b/tools/designer/src/lib/shared/widgetfactory.cpp
index 6fabe18..6c45daf 100644
--- a/tools/designer/src/lib/shared/widgetfactory.cpp
+++ b/tools/designer/src/lib/shared/widgetfactory.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::WidgetFactory
-*/
-
#include "widgetfactory_p.h"
#include "widgetdatabase_p.h"
#include "metadatabase_p.h"
diff --git a/tools/designer/src/lib/shared/zoomwidget.cpp b/tools/designer/src/lib/shared/zoomwidget.cpp
index d37e814..08d6082 100644
--- a/tools/designer/src/lib/shared/zoomwidget.cpp
+++ b/tools/designer/src/lib/shared/zoomwidget.cpp
@@ -143,9 +143,10 @@ ZoomView::ZoomView(QWidget *parent) :
m_zoom(100),
m_zoomFactor(1.0),
m_zoomContextMenuEnabled(false),
- m_autoScrollSuppressed(true),
m_zoomMenu(0)
{
+ setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setFrameShape(QFrame::NoFrame);
setScene(m_scene);
if (debugZoomWidget)
@@ -187,8 +188,6 @@ void ZoomView::setZoom(int percent)
resetTransform();
scale(m_zoomFactor, m_zoomFactor);
- if (m_autoScrollSuppressed)
- scrollToOrigin();
}
void ZoomView::applyZoom()
@@ -210,16 +209,6 @@ void ZoomView::setZoomContextMenuEnabled(bool e)
m_zoomContextMenuEnabled = e;
}
-bool ZoomView::isAutoScrollSuppressed() const
-{
- return m_autoScrollSuppressed;
-}
-
-void ZoomView::setAutoScrollSuppressed(bool s)
-{
- m_autoScrollSuppressed = s;
-}
-
ZoomMenu *ZoomView::zoomMenu()
{
if (!m_zoomMenu) {
@@ -469,13 +458,16 @@ void ZoomWidget::resizeEvent(QResizeEvent *event)
* and the use the size ZoomView::resizeEvent(event); */
if (m_proxy && !m_viewResizeBlocked) {
if (debugZoomWidget > 1)
- qDebug() << ">ZoomWidget (" << size() << ")::resizeEvent from " << event->oldSize() << " to " << event->size();
+ qDebug() << '>' << Q_FUNC_INFO << size() << ")::resizeEvent from " << event->oldSize() << " to " << event->size();
const QSizeF newViewPortSize = size() - viewPortMargin();
const QSizeF widgetSizeF = newViewPortSize / zoomFactor() - widgetDecorationSizeF();
m_widgetResizeBlocked = true;
m_proxy->widget()->resize(widgetSizeF.toSize());
+ setSceneRect(QRectF(QPointF(0, 0), widgetSizeF));
scrollToOrigin();
m_widgetResizeBlocked = false;
+ if (debugZoomWidget > 1)
+ qDebug() << '<' << Q_FUNC_INFO << widgetSizeF << m_proxy->widget()->size() << m_proxy->size();
}
}
@@ -559,7 +551,7 @@ QGraphicsProxyWidget *ZoomWidget::createProxyWidget(QGraphicsItem *parent, Qt::W
void ZoomWidget::dump() const
{
- qDebug() << "ZoomWidget " << geometry() << " Viewport " << viewport()->geometry()
+ qDebug() << "ZoomWidget::dump " << geometry() << " Viewport " << viewport()->geometry()
<< "Scroll: " << scrollPosition() << "Matrix: " << matrix() << " SceneRect: " << sceneRect();
if (m_proxy) {
qDebug() << "Proxy Pos: " << m_proxy->pos() << "Proxy " << m_proxy->size()
diff --git a/tools/designer/src/lib/shared/zoomwidget_p.h b/tools/designer/src/lib/shared/zoomwidget_p.h
index 83b2972..8d5e07c 100644
--- a/tools/designer/src/lib/shared/zoomwidget_p.h
+++ b/tools/designer/src/lib/shared/zoomwidget_p.h
@@ -104,8 +104,6 @@ class QDESIGNER_SHARED_EXPORT ZoomView : public QGraphicsView
{
Q_PROPERTY(int zoom READ zoom WRITE setZoom DESIGNABLE true SCRIPTABLE true)
Q_PROPERTY(bool zoomContextMenuEnabled READ isZoomContextMenuEnabled WRITE setZoomContextMenuEnabled DESIGNABLE true SCRIPTABLE true)
- Q_PROPERTY(bool autoScrollSuppressed READ isAutoScrollSuppressed WRITE setAutoScrollSuppressed DESIGNABLE true SCRIPTABLE true)
-
Q_OBJECT
Q_DISABLE_COPY(ZoomView)
public:
@@ -120,10 +118,6 @@ public:
bool isZoomContextMenuEnabled() const;
void setZoomContextMenuEnabled(bool e);
- // Suppress scrolling when changing zoom. Default: on
- bool isAutoScrollSuppressed() const;
- void setAutoScrollSuppressed(bool s);
-
QGraphicsScene &scene() { return *m_scene; }
const QGraphicsScene &scene() const { return *m_scene; }
@@ -149,8 +143,7 @@ private:
int m_zoom;
qreal m_zoomFactor;
- bool m_zoomContextMenuEnabled;
- bool m_autoScrollSuppressed;
+ bool m_zoomContextMenuEnabled;
bool m_resizeBlocked;
ZoomMenu *m_zoomMenu;
};
diff --git a/tools/designer/src/lib/uilib/abstractformbuilder.cpp b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
index e15e5ac..05e05c1 100644
--- a/tools/designer/src/lib/uilib/abstractformbuilder.cpp
+++ b/tools/designer/src/lib/uilib/abstractformbuilder.cpp
@@ -135,7 +135,7 @@ public:
QAbstractFormBuilder provides a standard interface and a default
implementation for constructing forms from user interface
files. It is not intended to be instantiated directly. Use the
- QFormBuilder class to create user interfaces from \c{.ui} files at
+ QFormBuilder class to create user interfaces from UI files at
run-time. For example:
\snippet doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp 0
@@ -145,10 +145,10 @@ public:
functions:
\list
- \o load() handles reading of \c{.ui} format files from arbitrary
+ \o load() handles reading of UI format files from arbitrary
QIODevices, and construction of widgets from the XML data
that they contain.
- \o save() handles saving of widget details in \c{.ui} format to
+ \o save() handles saving of widget details in UI format to
arbitrary QIODevices.
\o workingDirectory() and setWorkingDirectory() control the
directory in which forms are held. The form builder looks for
@@ -208,13 +208,13 @@ QWidget *QAbstractFormBuilder::load(QIODevice *dev, QWidget *parentWidget)
}
}
if (reader.hasError()) {
- uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the ui file at line %1, column %2: %3")
+ uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "An error has occurred while reading the UI file at line %1, column %2: %3")
.arg(reader.lineNumber()).arg(reader.columnNumber())
.arg(reader.errorString()));
return 0;
}
if (!initialized) {
- uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid ui file: The root element <ui> is missing."));
+ uiLibWarning(QCoreApplication::translate("QAbstractFormBuilder", "Invalid UI file: The root element <ui> is missing."));
return 0;
}
@@ -403,6 +403,7 @@ QAction *QAbstractFormBuilder::create(DomAction *ui_action, QObject *parent)
if (!a)
return 0;
+ m_actions.insert(ui_action->attributeName(), a);
applyProperties(a, ui_action->elementProperty());
return a;
}
@@ -415,7 +416,7 @@ QActionGroup *QAbstractFormBuilder::create(DomActionGroup *ui_action_group, QObj
QActionGroup *a = createActionGroup(parent, ui_action_group->attributeName());
if (!a)
return 0;
-
+ m_actionGroups.insert(ui_action_group->attributeName(), a);
applyProperties(a, ui_action_group->elementProperty());
foreach (DomAction *ui_action, ui_action_group->elementAction()) {
@@ -656,7 +657,7 @@ void QAbstractFormBuilder::layoutInfo(DomLayout *ui_layout, QObject *parent, int
spac = p->elementNumber();
#ifdef Q_OS_MAC
- // here we recognize ui file < 4.3 (no we don't store margin property)
+ // here we recognize UI file < 4.3 (no we don't store margin property)
if (mar != INT_MIN) {
const int defaultMargin = parent->inherits("QLayoutWidget") ? 0 : 9;
if (mar == defaultMargin)
@@ -1184,8 +1185,6 @@ QAction *QAbstractFormBuilder::createAction(QObject *parent, const QString &name
{
QAction *action = new QAction(parent);
action->setObjectName(name);
- m_actions.insert(name, action);
-
return action;
}
@@ -1196,8 +1195,6 @@ QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QSt
{
QActionGroup *g = new QActionGroup(parent);
g->setObjectName(name);
- m_actionGroups.insert(name, g);
-
return g;
}
@@ -1205,7 +1202,7 @@ QActionGroup *QAbstractFormBuilder::createActionGroup(QObject *parent, const QSt
\fn void QAbstractFormBuilder::save(QIODevice *device, QWidget *widget)
Saves an XML representation of the given \a widget to the
- specified \a device in the standard \c{.ui} file format.
+ specified \a device in the standard UI file format.
\sa load()*/
void QAbstractFormBuilder::save(QIODevice *dev, QWidget *widget)
diff --git a/tools/designer/src/lib/uilib/formbuilder.cpp b/tools/designer/src/lib/uilib/formbuilder.cpp
index a627e74..f737311 100644
--- a/tools/designer/src/lib/uilib/formbuilder.cpp
+++ b/tools/designer/src/lib/uilib/formbuilder.cpp
@@ -57,12 +57,12 @@ namespace QFormInternal {
\class QFormBuilder
\brief The QFormBuilder class is used to dynamically construct
- user interfaces from .ui files at run-time.
+ user interfaces from UI files at run-time.
\inmodule QtDesigner
The QFormBuilder class provides a mechanism for dynamically
- creating user interfaces at run-time, based on \c{.ui} files
+ creating user interfaces at run-time, based on UI files
created with \QD. For example:
\snippet doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp 0
@@ -120,7 +120,10 @@ QFormBuilder::~QFormBuilder()
*/
QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget)
{
- QFormBuilderExtra::instance(this)->setProcessingLayoutWidget(false);
+ QFormBuilderExtra *fb = QFormBuilderExtra::instance(this);
+ if (!fb->parentWidgetIsSet())
+ fb->setParentWidget(parentWidget);
+ fb->setProcessingLayoutWidget(false);
if (ui_widget->attributeClass() == QFormBuilderStrings::instance().qWidgetClass && !ui_widget->hasAttributeNative()
&& parentWidget
#ifndef QT_NO_MAINWINDOW
@@ -145,7 +148,7 @@ QWidget *QFormBuilder::create(DomWidget *ui_widget, QWidget *parentWidget)
&& !qobject_cast<QDockWidget *>(parentWidget)
#endif
)
- QFormBuilderExtra::instance(this)->setProcessingLayoutWidget(true);
+ fb->setProcessingLayoutWidget(true);
return QAbstractFormBuilder::create(ui_widget, parentWidget);
}
@@ -228,9 +231,6 @@ QWidget *QFormBuilder::createWidget(const QString &widgetName, QWidget *parentWi
if (qobject_cast<QDialog *>(w))
w->setParent(parentWidget);
- if (!fb->rootWidget())
- fb->setRootWidget(w);
-
return w;
}
@@ -369,9 +369,10 @@ QWidget *QFormBuilder::create(DomUI *ui, QWidget *parentWidget)
*/
QLayout *QFormBuilder::create(DomLayout *ui_layout, QLayout *layout, QWidget *parentWidget)
{
+ QFormBuilderExtra *fb = QFormBuilderExtra::instance(this);
// Is this a temporary layout widget used to represent QLayout hierarchies in Designer?
// Set its margins to 0.
- bool layoutWidget = QFormBuilderExtra::instance(this)->processingLayoutWidget();
+ bool layoutWidget = fb->processingLayoutWidget();
QLayout *l = QAbstractFormBuilder::create(ui_layout, layout, parentWidget);
if (layoutWidget) {
const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
@@ -392,7 +393,7 @@ QLayout *QFormBuilder::create(DomLayout *ui_layout, QLayout *layout, QWidget *pa
bottom = prop->elementNumber();
l->setContentsMargins(left, top, right, bottom);
- QFormBuilderExtra::instance(this)->setProcessingLayoutWidget(false);
+ fb->setProcessingLayoutWidget(false);
}
return l;
}
@@ -525,6 +526,7 @@ QList<QDesignerCustomWidgetInterface*> QFormBuilder::customWidgets() const
/*!
\internal
*/
+
void QFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &properties)
{
typedef QList<DomProperty*> DomPropertyList;
@@ -542,11 +544,12 @@ void QFormBuilder::applyProperties(QObject *o, const QList<DomProperty*> &proper
continue;
const QString attributeName = (*it)->attributeName();
- if (o == fb->rootWidget() && attributeName == strings.geometryProperty) {
- // apply only the size for the rootWidget
- fb->rootWidget()->resize(qvariant_cast<QRect>(v).size());
+ const bool isWidget = o->isWidgetType();
+ if (isWidget && o->parent() == fb->parentWidget() && attributeName == strings.geometryProperty) {
+ // apply only the size part of a geometry for the root widget
+ static_cast<QWidget*>(o)->resize(qvariant_cast<QRect>(v).size());
} else if (fb->applyPropertyInternally(o, attributeName, v)) {
- } else if (!qstrcmp("QFrame", o->metaObject()->className ()) && attributeName == strings.orientationProperty) {
+ } else if (isWidget && !qstrcmp("QFrame", o->metaObject()->className ()) && attributeName == strings.orientationProperty) {
// ### special-casing for Line (QFrame) -- try to fix me
o->setProperty("frameShape", v); // v is of QFrame::Shape enum
} else {
diff --git a/tools/designer/src/lib/uilib/formbuilderextra.cpp b/tools/designer/src/lib/uilib/formbuilderextra.cpp
index 87491b7..c07d253 100644
--- a/tools/designer/src/lib/uilib/formbuilderextra.cpp
+++ b/tools/designer/src/lib/uilib/formbuilderextra.cpp
@@ -81,7 +81,8 @@ QFormBuilderExtra::~QFormBuilderExtra()
void QFormBuilderExtra::clear()
{
m_buddies.clear();
- m_rootWidget = 0;
+ m_parentWidget = 0;
+ m_parentWidgetIsSet = false;
#ifndef QT_FORMBUILDER_NO_SCRIPT
m_FormScriptRunner.clearErrors();
m_customWidgetScriptHash.clear();
@@ -136,14 +137,21 @@ bool QFormBuilderExtra::applyBuddy(const QString &buddyName, BuddyMode applyMode
return false;
}
-const QPointer<QWidget> &QFormBuilderExtra::rootWidget() const
+const QPointer<QWidget> &QFormBuilderExtra::parentWidget() const
{
- return m_rootWidget;
+ return m_parentWidget;
}
-void QFormBuilderExtra::setRootWidget(const QPointer<QWidget> &w)
+bool QFormBuilderExtra::parentWidgetIsSet() const
{
- m_rootWidget = w;
+ return m_parentWidgetIsSet;
+}
+
+void QFormBuilderExtra::setParentWidget(const QPointer<QWidget> &w)
+{
+ // Parent widget requires special handling of the geometry property.
+ m_parentWidget = w;
+ m_parentWidgetIsSet = true;
}
#ifndef QT_FORMBUILDER_NO_SCRIPT
diff --git a/tools/designer/src/lib/uilib/formbuilderextra_p.h b/tools/designer/src/lib/uilib/formbuilderextra_p.h
index ec06050..418c70c 100644
--- a/tools/designer/src/lib/uilib/formbuilderextra_p.h
+++ b/tools/designer/src/lib/uilib/formbuilderextra_p.h
@@ -101,8 +101,9 @@ public:
void applyInternalProperties() const;
static bool applyBuddy(const QString &buddyName, BuddyMode applyMode, QLabel *label);
- const QPointer<QWidget> &rootWidget() const;
- void setRootWidget(const QPointer<QWidget> &w);
+ const QPointer<QWidget> &parentWidget() const;
+ bool parentWidgetIsSet() const;
+ void setParentWidget(const QPointer<QWidget> &w);
#ifndef QT_FORMBUILDER_NO_SCRIPT
QFormScriptRunner &formScriptRunner();
@@ -182,7 +183,8 @@ private:
QResourceBuilder *m_resourceBuilder;
QTextBuilder *m_textBuilder;
- QPointer<QWidget> m_rootWidget;
+ QPointer<QWidget> m_parentWidget;
+ bool m_parentWidgetIsSet;
};
void uiLibWarning(const QString &message);
diff --git a/tools/designer/src/lib/uilib/ui4.cpp b/tools/designer/src/lib/uilib/ui4.cpp
index 7faee24..1578155 100644
--- a/tools/designer/src/lib/uilib/ui4.cpp
+++ b/tools/designer/src/lib/uilib/ui4.cpp
@@ -2368,6 +2368,7 @@ void DomCustomWidget::clear(bool clear_all)
delete m_script;
delete m_properties;
delete m_slots;
+ delete m_propertyspecifications;
if (clear_all) {
m_text.clear();
@@ -2381,6 +2382,7 @@ void DomCustomWidget::clear(bool clear_all)
m_script = 0;
m_properties = 0;
m_slots = 0;
+ m_propertyspecifications = 0;
}
DomCustomWidget::DomCustomWidget()
@@ -2393,6 +2395,7 @@ DomCustomWidget::DomCustomWidget()
m_script = 0;
m_properties = 0;
m_slots = 0;
+ m_propertyspecifications = 0;
}
DomCustomWidget::~DomCustomWidget()
@@ -2403,6 +2406,7 @@ DomCustomWidget::~DomCustomWidget()
delete m_script;
delete m_properties;
delete m_slots;
+ delete m_propertyspecifications;
}
void DomCustomWidget::read(QXmlStreamReader &reader)
@@ -2468,6 +2472,12 @@ void DomCustomWidget::read(QXmlStreamReader &reader)
setElementSlots(v);
continue;
}
+ if (tag == QLatin1String("propertyspecifications")) {
+ DomPropertySpecifications *v = new DomPropertySpecifications();
+ v->read(reader);
+ setElementPropertyspecifications(v);
+ continue;
+ }
reader.raiseError(QLatin1String("Unexpected element ") + tag);
}
break;
@@ -2548,6 +2558,12 @@ void DomCustomWidget::read(const QDomElement &node)
setElementSlots(v);
continue;
}
+ if (tag == QLatin1String("propertyspecifications")) {
+ DomPropertySpecifications *v = new DomPropertySpecifications();
+ v->read(e);
+ setElementPropertyspecifications(v);
+ continue;
+ }
}
m_text.clear();
for (QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {
@@ -2605,6 +2621,10 @@ void DomCustomWidget::write(QXmlStreamWriter &writer, const QString &tagName) co
m_slots->write(writer, QLatin1String("slots"));
}
+ if (m_children & Propertyspecifications) {
+ m_propertyspecifications->write(writer, QLatin1String("propertyspecifications"));
+ }
+
if (!m_text.isEmpty())
writer.writeCharacters(m_text);
@@ -2731,6 +2751,21 @@ void DomCustomWidget::setElementSlots(DomSlots* a)
m_slots = a;
}
+DomPropertySpecifications* DomCustomWidget::takeElementPropertyspecifications()
+{
+ DomPropertySpecifications* a = m_propertyspecifications;
+ m_propertyspecifications = 0;
+ m_children ^= Propertyspecifications;
+ return a;
+}
+
+void DomCustomWidget::setElementPropertyspecifications(DomPropertySpecifications* a)
+{
+ delete m_propertyspecifications;
+ m_children |= Propertyspecifications;
+ m_propertyspecifications = a;
+}
+
void DomCustomWidget::clearElementClass()
{
m_children &= ~Class;
@@ -2798,6 +2833,13 @@ void DomCustomWidget::clearElementSlots()
m_children &= ~Slots;
}
+void DomCustomWidget::clearElementPropertyspecifications()
+{
+ delete m_propertyspecifications;
+ m_propertyspecifications = 0;
+ m_children &= ~Propertyspecifications;
+}
+
void DomProperties::clear(bool clear_all)
{
qDeleteAll(m_property);
@@ -10883,5 +10925,208 @@ void DomSlots::setElementSlot(const QStringList& a)
m_slot = a;
}
+void DomPropertySpecifications::clear(bool clear_all)
+{
+ qDeleteAll(m_stringpropertyspecification);
+ m_stringpropertyspecification.clear();
+
+ if (clear_all) {
+ m_text.clear();
+ }
+
+ m_children = 0;
+}
+
+DomPropertySpecifications::DomPropertySpecifications()
+{
+ m_children = 0;
+}
+
+DomPropertySpecifications::~DomPropertySpecifications()
+{
+ qDeleteAll(m_stringpropertyspecification);
+ m_stringpropertyspecification.clear();
+}
+
+void DomPropertySpecifications::read(QXmlStreamReader &reader)
+{
+
+ for (bool finished = false; !finished && !reader.hasError();) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement : {
+ const QString tag = reader.name().toString().toLower();
+ if (tag == QLatin1String("stringpropertyspecification")) {
+ DomStringPropertySpecification *v = new DomStringPropertySpecification();
+ v->read(reader);
+ m_stringpropertyspecification.append(v);
+ continue;
+ }
+ reader.raiseError(QLatin1String("Unexpected element ") + tag);
+ }
+ break;
+ case QXmlStreamReader::EndElement :
+ finished = true;
+ break;
+ case QXmlStreamReader::Characters :
+ if (!reader.isWhitespace())
+ m_text.append(reader.text().toString());
+ break;
+ default :
+ break;
+ }
+ }
+}
+
+#ifdef QUILOADER_QDOM_READ
+void DomPropertySpecifications::read(const QDomElement &node)
+{
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if (!n.isElement())
+ continue;
+ QDomElement e = n.toElement();
+ QString tag = e.tagName().toLower();
+ if (tag == QLatin1String("stringpropertyspecification")) {
+ DomStringPropertySpecification *v = new DomStringPropertySpecification();
+ v->read(e);
+ m_stringpropertyspecification.append(v);
+ continue;
+ }
+ }
+ m_text.clear();
+ for (QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {
+ if (child.isText())
+ m_text.append(child.nodeValue());
+ }
+}
+#endif
+
+void DomPropertySpecifications::write(QXmlStreamWriter &writer, const QString &tagName) const
+{
+ writer.writeStartElement(tagName.isEmpty() ? QString::fromUtf8("propertyspecifications") : tagName.toLower());
+
+ for (int i = 0; i < m_stringpropertyspecification.size(); ++i) {
+ DomStringPropertySpecification* v = m_stringpropertyspecification[i];
+ v->write(writer, QLatin1String("stringpropertyspecification"));
+ }
+ if (!m_text.isEmpty())
+ writer.writeCharacters(m_text);
+
+ writer.writeEndElement();
+}
+
+void DomPropertySpecifications::setElementStringpropertyspecification(const QList<DomStringPropertySpecification*>& a)
+{
+ m_children |= Stringpropertyspecification;
+ m_stringpropertyspecification = a;
+}
+
+void DomStringPropertySpecification::clear(bool clear_all)
+{
+
+ if (clear_all) {
+ m_text.clear();
+ m_has_attr_name = false;
+ m_has_attr_type = false;
+ m_has_attr_notr = false;
+ }
+
+ m_children = 0;
+}
+
+DomStringPropertySpecification::DomStringPropertySpecification()
+{
+ m_children = 0;
+ m_has_attr_name = false;
+ m_has_attr_type = false;
+ m_has_attr_notr = false;
+}
+
+DomStringPropertySpecification::~DomStringPropertySpecification()
+{
+}
+
+void DomStringPropertySpecification::read(QXmlStreamReader &reader)
+{
+
+ foreach (const QXmlStreamAttribute &attribute, reader.attributes()) {
+ QStringRef name = attribute.name();
+ if (name == QLatin1String("name")) {
+ setAttributeName(attribute.value().toString());
+ continue;
+ }
+ if (name == QLatin1String("type")) {
+ setAttributeType(attribute.value().toString());
+ continue;
+ }
+ if (name == QLatin1String("notr")) {
+ setAttributeNotr(attribute.value().toString());
+ continue;
+ }
+ reader.raiseError(QLatin1String("Unexpected attribute ") + name.toString());
+ }
+
+ for (bool finished = false; !finished && !reader.hasError();) {
+ switch (reader.readNext()) {
+ case QXmlStreamReader::StartElement : {
+ const QString tag = reader.name().toString().toLower();
+ reader.raiseError(QLatin1String("Unexpected element ") + tag);
+ }
+ break;
+ case QXmlStreamReader::EndElement :
+ finished = true;
+ break;
+ case QXmlStreamReader::Characters :
+ if (!reader.isWhitespace())
+ m_text.append(reader.text().toString());
+ break;
+ default :
+ break;
+ }
+ }
+}
+
+#ifdef QUILOADER_QDOM_READ
+void DomStringPropertySpecification::read(const QDomElement &node)
+{
+ if (node.hasAttribute(QLatin1String("name")))
+ setAttributeName(node.attribute(QLatin1String("name")));
+ if (node.hasAttribute(QLatin1String("type")))
+ setAttributeType(node.attribute(QLatin1String("type")));
+ if (node.hasAttribute(QLatin1String("notr")))
+ setAttributeNotr(node.attribute(QLatin1String("notr")));
+
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ if (!n.isElement())
+ continue;
+ QDomElement e = n.toElement();
+ QString tag = e.tagName().toLower();
+ }
+ m_text.clear();
+ for (QDomNode child = node.firstChild(); !child.isNull(); child = child.nextSibling()) {
+ if (child.isText())
+ m_text.append(child.nodeValue());
+ }
+}
+#endif
+
+void DomStringPropertySpecification::write(QXmlStreamWriter &writer, const QString &tagName) const
+{
+ writer.writeStartElement(tagName.isEmpty() ? QString::fromUtf8("stringpropertyspecification") : tagName.toLower());
+
+ if (hasAttributeName())
+ writer.writeAttribute(QLatin1String("name"), attributeName());
+
+ if (hasAttributeType())
+ writer.writeAttribute(QLatin1String("type"), attributeType());
+
+ if (hasAttributeNotr())
+ writer.writeAttribute(QLatin1String("notr"), attributeNotr());
+
+ if (!m_text.isEmpty())
+ writer.writeCharacters(m_text);
+
+ writer.writeEndElement();
+}
+
QT_END_NAMESPACE
diff --git a/tools/designer/src/lib/uilib/ui4_p.h b/tools/designer/src/lib/uilib/ui4_p.h
index 505c61b..3c53d13 100644
--- a/tools/designer/src/lib/uilib/ui4_p.h
+++ b/tools/designer/src/lib/uilib/ui4_p.h
@@ -161,6 +161,8 @@ class DomScript;
class DomWidgetData;
class DomDesignerData;
class DomSlots;
+class DomPropertySpecifications;
+class DomStringPropertySpecification;
/*******************************************************************************
** Declarations
@@ -1015,6 +1017,12 @@ public:
inline bool hasElementSlots() const { return m_children & Slots; }
void clearElementSlots();
+ inline DomPropertySpecifications* elementPropertyspecifications() const { return m_propertyspecifications; }
+ DomPropertySpecifications* takeElementPropertyspecifications();
+ void setElementPropertyspecifications(DomPropertySpecifications* a);
+ inline bool hasElementPropertyspecifications() const { return m_children & Propertyspecifications; }
+ void clearElementPropertyspecifications();
+
private:
QString m_text;
void clear(bool clear_all = true);
@@ -1033,6 +1041,7 @@ private:
DomScript* m_script;
DomProperties* m_properties;
DomSlots* m_slots;
+ DomPropertySpecifications* m_propertyspecifications;
enum Child {
Class = 1,
Extends = 2,
@@ -1044,7 +1053,8 @@ private:
Pixmap = 128,
Script = 256,
Properties = 512,
- Slots = 1024
+ Slots = 1024,
+ Propertyspecifications = 2048
};
DomCustomWidget(const DomCustomWidget &other);
@@ -3686,6 +3696,91 @@ private:
void operator = (const DomSlots&other);
};
+class QDESIGNER_UILIB_EXPORT DomPropertySpecifications {
+public:
+ DomPropertySpecifications();
+ ~DomPropertySpecifications();
+
+ void read(QXmlStreamReader &reader);
+#ifdef QUILOADER_QDOM_READ
+ void read(const QDomElement &node);
+#endif
+ void write(QXmlStreamWriter &writer, const QString &tagName = QString()) const;
+ inline QString text() const { return m_text; }
+ inline void setText(const QString &s) { m_text = s; }
+
+ // attribute accessors
+ // child element accessors
+ inline QList<DomStringPropertySpecification*> elementStringpropertyspecification() const { return m_stringpropertyspecification; }
+ void setElementStringpropertyspecification(const QList<DomStringPropertySpecification*>& a);
+
+private:
+ QString m_text;
+ void clear(bool clear_all = true);
+
+ // attribute data
+ // child element data
+ uint m_children;
+ QList<DomStringPropertySpecification*> m_stringpropertyspecification;
+ enum Child {
+ Stringpropertyspecification = 1
+ };
+
+ DomPropertySpecifications(const DomPropertySpecifications &other);
+ void operator = (const DomPropertySpecifications&other);
+};
+
+class QDESIGNER_UILIB_EXPORT DomStringPropertySpecification {
+public:
+ DomStringPropertySpecification();
+ ~DomStringPropertySpecification();
+
+ void read(QXmlStreamReader &reader);
+#ifdef QUILOADER_QDOM_READ
+ void read(const QDomElement &node);
+#endif
+ void write(QXmlStreamWriter &writer, const QString &tagName = QString()) const;
+ inline QString text() const { return m_text; }
+ inline void setText(const QString &s) { m_text = s; }
+
+ // attribute accessors
+ inline bool hasAttributeName() const { return m_has_attr_name; }
+ inline QString attributeName() const { return m_attr_name; }
+ inline void setAttributeName(const QString& a) { m_attr_name = a; m_has_attr_name = true; }
+ inline void clearAttributeName() { m_has_attr_name = false; }
+
+ inline bool hasAttributeType() const { return m_has_attr_type; }
+ inline QString attributeType() const { return m_attr_type; }
+ inline void setAttributeType(const QString& a) { m_attr_type = a; m_has_attr_type = true; }
+ inline void clearAttributeType() { m_has_attr_type = false; }
+
+ inline bool hasAttributeNotr() const { return m_has_attr_notr; }
+ inline QString attributeNotr() const { return m_attr_notr; }
+ inline void setAttributeNotr(const QString& a) { m_attr_notr = a; m_has_attr_notr = true; }
+ inline void clearAttributeNotr() { m_has_attr_notr = false; }
+
+ // child element accessors
+private:
+ QString m_text;
+ void clear(bool clear_all = true);
+
+ // attribute data
+ QString m_attr_name;
+ bool m_has_attr_name;
+
+ QString m_attr_type;
+ bool m_has_attr_type;
+
+ QString m_attr_notr;
+ bool m_has_attr_notr;
+
+ // child element data
+ uint m_children;
+
+ DomStringPropertySpecification(const DomStringPropertySpecification &other);
+ void operator = (const DomStringPropertySpecification&other);
+};
+
#ifdef QFORMINTERNAL_NAMESPACE
}
diff --git a/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp b/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
index 1158e35..1cbf1c1 100644
--- a/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
+++ b/tools/designer/src/plugins/activeqt/qaxwidgettaskmenu.cpp
@@ -162,7 +162,7 @@ void QAxWidgetTaskMenu::setActiveXControl()
tr("The control requires a design-time license"));
clsid = QUuid();
} else {
- key = QString::fromUtf16((ushort *)bKey);
+ key = QString::fromWCharArray(bKey);
}
cf2->Release();
diff --git a/tools/designer/src/uitools/quiloader.cpp b/tools/designer/src/uitools/quiloader.cpp
index 48e142b..1c7d1cc 100644
--- a/tools/designer/src/uitools/quiloader.cpp
+++ b/tools/designer/src/uitools/quiloader.cpp
@@ -574,20 +574,20 @@ void QUiLoaderPrivate::setupWidgetMap() const
\brief The QUiLoader class enables standalone applications to
dynamically create user interfaces at run-time using the
- information stored in .ui files or specified in plugin paths.
+ information stored in UI files or specified in plugin paths.
In addition, you can customize or create your own user interface by
deriving your own loader class.
If you have a custom component or an application that embeds \QD, you can
also use the QFormBuilder class provided by the QtDesigner module to create
- user interfaces from \c{.ui} files.
+ user interfaces from UI files.
The QUiLoader class provides a collection of functions allowing you to
- create widgets based on the information stored in \c .ui files (created
+ create widgets based on the information stored in UI files (created
with \QD) or available in the specified plugin paths. The specified plugin
paths can be retrieved using the pluginPaths() function. Similarly, the
- contents of a \c{.ui} file can be retrieved using the load() function. For
+ contents of a UI file can be retrieved using the load() function. For
example:
\snippet doc/src/snippets/quiloader/mywidget.cpp 0
@@ -613,8 +613,7 @@ void QUiLoaderPrivate::setupWidgetMap() const
reason, you can subclass the QUiLoader class and reimplement these
functions to intervene the process of constructing a user interface. For
example, you might want to have a list of the actions created when loading
- a form or creating a custom widget. However, in your reimplementation, you
- must call QUiLoader's original implementation of these functions first.
+ a form or creating a custom widget.
For a complete example using the QUiLoader class, see the
\l{Calculator Builder Example}.
diff --git a/tools/kmap2qmap/kmap2qmap.pro b/tools/kmap2qmap/kmap2qmap.pro
new file mode 100644
index 0000000..cc8200b
--- /dev/null
+++ b/tools/kmap2qmap/kmap2qmap.pro
@@ -0,0 +1,12 @@
+
+TEMPLATE = app
+DESTDIR = ../../bin
+QT = core
+CONFIG += console
+CONFIG -= app_bundle
+
+DEPENDPATH += $$QT_SOURCE_TREE/src/gui/embedded
+INCLUDEPATH += $$QT_SOURCE_TREE/src/gui/embedded
+
+# Input
+SOURCES += main.cpp
diff --git a/tools/kmap2qmap/main.cpp b/tools/kmap2qmap/main.cpp
new file mode 100644
index 0000000..b438a05
--- /dev/null
+++ b/tools/kmap2qmap/main.cpp
@@ -0,0 +1,991 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <cstdio>
+
+#include <QFile>
+#include <QFileInfo>
+#include <QDir>
+#include <QTextCodec>
+#include <QList>
+#include <QVector>
+#include <QByteArray>
+#include <QStringList>
+#include <QTextStream>
+
+#include "qkbd_qws_p.h"
+
+using namespace std;
+
+
+struct modifier_map_t {
+ const char *symbol;
+ quint8 modifier;
+ quint32 qtmodifier;
+};
+
+static const struct modifier_map_t modifier_map[] = {
+ { "plain", QWSKeyboard::ModPlain, Qt::NoModifier },
+ { "shift", QWSKeyboard::ModShift, Qt::ShiftModifier },
+ { "altgr", QWSKeyboard::ModAltGr, Qt::AltModifier },
+ { "control", QWSKeyboard::ModControl, Qt::ControlModifier },
+ { "alt", QWSKeyboard::ModAlt, Qt::AltModifier },
+ { "meta", QWSKeyboard::ModAlt, Qt::AltModifier },
+ { "shiftl", QWSKeyboard::ModShiftL, Qt::ShiftModifier },
+ { "shiftr", QWSKeyboard::ModShiftR, Qt::ShiftModifier },
+ { "ctrll", QWSKeyboard::ModCtrlL, Qt::ControlModifier },
+ { "ctrlr", QWSKeyboard::ModCtrlR, Qt::ControlModifier },
+};
+
+static const int modifier_map_size = sizeof(modifier_map)/sizeof(modifier_map_t);
+
+
+struct symbol_map_t {
+ const char *symbol;
+ quint32 qtcode;
+};
+
+static const struct symbol_map_t symbol_map[] = {
+ { "space", Qt::Key_Space },
+ { "exclam", Qt::Key_Exclam },
+ { "quotedbl", Qt::Key_QuoteDbl },
+ { "numbersign", Qt::Key_NumberSign },
+ { "dollar", Qt::Key_Dollar },
+ { "percent", Qt::Key_Percent },
+ { "ampersand", Qt::Key_Ampersand },
+ { "apostrophe", Qt::Key_Apostrophe },
+ { "parenleft", Qt::Key_ParenLeft },
+ { "parenright", Qt::Key_ParenRight },
+ { "asterisk", Qt::Key_Asterisk },
+ { "plus", Qt::Key_Plus },
+ { "comma", Qt::Key_Comma },
+ { "minus", Qt::Key_Minus },
+ { "period", Qt::Key_Period },
+ { "slash", Qt::Key_Slash },
+ { "zero", Qt::Key_0 },
+ { "one", Qt::Key_1 },
+ { "two", Qt::Key_2 },
+ { "three", Qt::Key_3 },
+ { "four", Qt::Key_4 },
+ { "five", Qt::Key_5 },
+ { "six", Qt::Key_6 },
+ { "seven", Qt::Key_7 },
+ { "eight", Qt::Key_8 },
+ { "nine", Qt::Key_9 },
+ { "colon", Qt::Key_Colon },
+ { "semicolon", Qt::Key_Semicolon },
+ { "less", Qt::Key_Less },
+ { "equal", Qt::Key_Equal },
+ { "greater", Qt::Key_Greater },
+ { "question", Qt::Key_Question },
+ { "at", Qt::Key_At },
+ { "bracketleft", Qt::Key_BracketLeft },
+ { "backslash", Qt::Key_Backslash },
+ { "bracketright", Qt::Key_BracketRight },
+ { "asciicircum", Qt::Key_AsciiCircum },
+ { "underscore", Qt::Key_Underscore },
+ { "grave", Qt::Key_QuoteLeft },
+ { "braceleft", Qt::Key_BraceLeft },
+ { "bar", Qt::Key_Bar },
+ { "braceright", Qt::Key_BraceRight },
+ { "asciitilde", Qt::Key_AsciiTilde },
+ { "nobreakspace", Qt::Key_nobreakspace },
+ { "exclamdown", Qt::Key_exclamdown },
+ { "cent", Qt::Key_cent },
+ { "sterling", Qt::Key_sterling },
+ { "currency", Qt::Key_currency },
+ { "yen", Qt::Key_yen },
+ { "brokenbar", Qt::Key_brokenbar },
+ { "section", Qt::Key_section },
+ { "diaeresis", Qt::Key_diaeresis },
+ { "copyright", Qt::Key_copyright },
+ { "ordfeminine", Qt::Key_ordfeminine },
+ { "guillemotleft", Qt::Key_guillemotleft },
+ { "notsign", Qt::Key_notsign },
+ { "hyphen", Qt::Key_hyphen },
+ { "registered", Qt::Key_registered },
+ { "macron", Qt::Key_macron },
+ { "degree", Qt::Key_degree },
+ { "plusminus", Qt::Key_plusminus },
+ { "twosuperior", Qt::Key_twosuperior },
+ { "threesuperior", Qt::Key_threesuperior },
+ { "acute", Qt::Key_acute },
+ { "mu", Qt::Key_mu },
+ { "paragraph", Qt::Key_paragraph },
+ { "periodcentered", Qt::Key_periodcentered },
+ { "cedilla", Qt::Key_cedilla },
+ { "onesuperior", Qt::Key_onesuperior },
+ { "masculine", Qt::Key_masculine },
+ { "guillemotright", Qt::Key_guillemotright },
+ { "onequarter", Qt::Key_onequarter },
+ { "onehalf", Qt::Key_onehalf },
+ { "threequarters", Qt::Key_threequarters },
+ { "questiondown", Qt::Key_questiondown },
+ { "Agrave", Qt::Key_Agrave },
+ { "Aacute", Qt::Key_Aacute },
+ { "Acircumflex", Qt::Key_Acircumflex },
+ { "Atilde", Qt::Key_Atilde },
+ { "Adiaeresis", Qt::Key_Adiaeresis },
+ { "Aring", Qt::Key_Aring },
+ { "AE", Qt::Key_AE },
+ { "Ccedilla", Qt::Key_Ccedilla },
+ { "Egrave", Qt::Key_Egrave },
+ { "Eacute", Qt::Key_Eacute },
+ { "Ecircumflex", Qt::Key_Ecircumflex },
+ { "Ediaeresis", Qt::Key_Ediaeresis },
+ { "Igrave", Qt::Key_Igrave },
+ { "Iacute", Qt::Key_Iacute },
+ { "Icircumflex", Qt::Key_Icircumflex },
+ { "Idiaeresis", Qt::Key_Idiaeresis },
+ { "ETH", Qt::Key_ETH },
+ { "Ntilde", Qt::Key_Ntilde },
+ { "Ograve", Qt::Key_Ograve },
+ { "Oacute", Qt::Key_Oacute },
+ { "Ocircumflex", Qt::Key_Ocircumflex },
+ { "Otilde", Qt::Key_Otilde },
+ { "Odiaeresis", Qt::Key_Odiaeresis },
+ { "multiply", Qt::Key_multiply },
+ { "Ooblique", Qt::Key_Ooblique },
+ { "Ugrave", Qt::Key_Ugrave },
+ { "Uacute", Qt::Key_Uacute },
+ { "Ucircumflex", Qt::Key_Ucircumflex },
+ { "Udiaeresis", Qt::Key_Udiaeresis },
+ { "Yacute", Qt::Key_Yacute },
+ { "THORN", Qt::Key_THORN },
+ { "ssharp", Qt::Key_ssharp },
+
+ { "agrave", 0xe0 /*Qt::Key_agrave*/ },
+ { "aacute", 0xe1 /*Qt::Key_aacute*/ },
+ { "acircumflex", 0xe2 /*Qt::Key_acircumflex*/ },
+ { "atilde", 0xe3 /*Qt::Key_atilde*/ },
+ { "adiaeresis", 0xe4 /*Qt::Key_adiaeresis*/ },
+ { "aring", 0xe5 /*Qt::Key_aring*/ },
+ { "ae", 0xe6 /*Qt::Key_ae*/ },
+ { "ccedilla", 0xe7 /*Qt::Key_ccedilla*/ },
+ { "egrave", 0xe8 /*Qt::Key_egrave*/ },
+ { "eacute", 0xe9 /*Qt::Key_eacute*/ },
+ { "ecircumflex", 0xea /*Qt::Key_ecircumflex*/ },
+ { "ediaeresis", 0xeb /*Qt::Key_ediaeresis*/ },
+ { "igrave", 0xec /*Qt::Key_igrave*/ },
+ { "iacute", 0xed /*Qt::Key_iacute*/ },
+ { "icircumflex", 0xee /*Qt::Key_icircumflex*/ },
+ { "idiaeresis", 0xef /*Qt::Key_idiaeresis*/ },
+ { "eth", 0xf0 /*Qt::Key_eth*/ },
+ { "ntilde", 0xf1 /*Qt::Key_ntilde*/ },
+ { "ograve", 0xf2 /*Qt::Key_ograve*/ },
+ { "oacute", 0xf3 /*Qt::Key_oacute*/ },
+ { "ocircumflex", 0xf4 /*Qt::Key_ocircumflex*/ },
+ { "otilde", 0xf5 /*Qt::Key_otilde*/ },
+ { "odiaeresis", 0xf6 /*Qt::Key_odiaeresis*/ },
+ { "division", Qt::Key_division },
+ { "oslash", 0xf8 /*Qt::Key_oslash*/ },
+ { "ugrave", 0xf9 /*Qt::Key_ugrave*/ },
+ { "uacute", 0xfa /*Qt::Key_uacute*/ },
+ { "ucircumflex", 0xfb /*Qt::Key_ucircumflex*/ },
+ { "udiaeresis", 0xfc /*Qt::Key_udiaeresis*/ },
+ { "yacute", 0xfd /*Qt::Key_yacute*/ },
+ { "thorn", 0xfe /*Qt::Key_thorn*/ },
+ { "ydiaeresis", Qt::Key_ydiaeresis },
+
+ { "F1", Qt::Key_F1 },
+ { "F2", Qt::Key_F2 },
+ { "F3", Qt::Key_F3 },
+ { "F4", Qt::Key_F4 },
+ { "F5", Qt::Key_F5 },
+ { "F6", Qt::Key_F6 },
+ { "F7", Qt::Key_F7 },
+ { "F8", Qt::Key_F8 },
+ { "F9", Qt::Key_F9 },
+ { "F10", Qt::Key_F10 },
+ { "F11", Qt::Key_F11 },
+ { "F12", Qt::Key_F12 },
+ { "F13", Qt::Key_F13 },
+ { "F14", Qt::Key_F14 },
+ { "F15", Qt::Key_F15 },
+ { "F16", Qt::Key_F16 },
+ { "F17", Qt::Key_F17 },
+ { "F18", Qt::Key_F18 },
+ { "F19", Qt::Key_F19 },
+ { "F20", Qt::Key_F20 },
+ { "F21", Qt::Key_F21 },
+ { "F22", Qt::Key_F22 },
+ { "F23", Qt::Key_F23 },
+ { "F24", Qt::Key_F24 },
+ { "F25", Qt::Key_F25 },
+ { "F26", Qt::Key_F26 },
+ { "F27", Qt::Key_F27 },
+ { "F28", Qt::Key_F28 },
+ { "F29", Qt::Key_F29 },
+ { "F30", Qt::Key_F30 },
+ { "F31", Qt::Key_F31 },
+ { "F32", Qt::Key_F32 },
+ { "F33", Qt::Key_F33 },
+ { "F34", Qt::Key_F34 },
+ { "F35", Qt::Key_F35 },
+
+ { "BackSpace", Qt::Key_Backspace },
+ { "Tab", Qt::Key_Tab },
+ { "Escape", Qt::Key_Escape },
+ { "Delete", Qt::Key_Backspace }, // what's the difference between "Delete" and "BackSpace"??
+ { "Return", Qt::Key_Return },
+ { "Break", Qt::Key_unknown }, //TODO: why doesn't Qt support the 'Break' key?
+ { "Caps_Lock", Qt::Key_CapsLock },
+ { "Num_Lock", Qt::Key_NumLock },
+ { "Scroll_Lock", Qt::Key_ScrollLock },
+ { "Caps_On", Qt::Key_CapsLock },
+ { "Compose", Qt::Key_Multi_key },
+ { "Bare_Num_Lock", Qt::Key_NumLock },
+ { "Find", Qt::Key_Home },
+ { "Insert", Qt::Key_Insert },
+ { "Remove", Qt::Key_Delete },
+ { "Select", Qt::Key_End },
+ { "Prior", Qt::Key_PageUp },
+ { "Next", Qt::Key_PageDown },
+ { "Help", Qt::Key_Help },
+ { "Pause", Qt::Key_Pause },
+
+ { "KP_0", Qt::Key_0 | Qt::KeypadModifier },
+ { "KP_1", Qt::Key_1 | Qt::KeypadModifier },
+ { "KP_2", Qt::Key_2 | Qt::KeypadModifier },
+ { "KP_3", Qt::Key_3 | Qt::KeypadModifier },
+ { "KP_4", Qt::Key_4 | Qt::KeypadModifier },
+ { "KP_5", Qt::Key_5 | Qt::KeypadModifier },
+ { "KP_6", Qt::Key_6 | Qt::KeypadModifier },
+ { "KP_7", Qt::Key_7 | Qt::KeypadModifier },
+ { "KP_8", Qt::Key_8 | Qt::KeypadModifier },
+ { "KP_9", Qt::Key_9 | Qt::KeypadModifier },
+ { "KP_Add", Qt::Key_Plus | Qt::KeypadModifier },
+ { "KP_Subtract", Qt::Key_Minus | Qt::KeypadModifier },
+ { "KP_Multiply", Qt::Key_Asterisk | Qt::KeypadModifier },
+ { "KP_Divide", Qt::Key_Slash | Qt::KeypadModifier },
+ { "KP_Enter", Qt::Key_Enter | Qt::KeypadModifier },
+ { "KP_Comma", Qt::Key_Comma | Qt::KeypadModifier },
+ { "KP_Period", Qt::Key_Period | Qt::KeypadModifier },
+ { "KP_MinPlus", Qt::Key_plusminus | Qt::KeypadModifier },
+
+ { "dead_grave", Qt::Key_Dead_Grave },
+ { "dead_acute", Qt::Key_Dead_Acute },
+ { "dead_circumflex", Qt::Key_Dead_Circumflex },
+ { "dead_tilde", Qt::Key_Dead_Tilde },
+ { "dead_diaeresis", Qt::Key_Dead_Diaeresis },
+ { "dead_cedilla", Qt::Key_Dead_Cedilla },
+
+ { "Down", Qt::Key_Down },
+ { "Left", Qt::Key_Left },
+ { "Right", Qt::Key_Right },
+ { "Up", Qt::Key_Up },
+ { "Shift", Qt::Key_Shift },
+ { "AltGr", Qt::Key_AltGr },
+ { "Control", Qt::Key_Control },
+ { "Alt", Qt::Key_Alt },
+ { "ShiftL", Qt::Key_Shift },
+ { "ShiftR", Qt::Key_Shift },
+ { "CtrlL", Qt::Key_Control },
+ { "CtrlR", Qt::Key_Control },
+};
+
+static const int symbol_map_size = sizeof(symbol_map)/sizeof(symbol_map_t);
+
+
+struct symbol_dead_unicode_t {
+ quint32 dead;
+ quint16 unicode;
+};
+
+static const symbol_dead_unicode_t symbol_dead_unicode[] = {
+ { Qt::Key_Dead_Grave, '`' },
+ { Qt::Key_Dead_Acute, '\'' },
+ { Qt::Key_Dead_Circumflex, '^' },
+ { Qt::Key_Dead_Tilde, '~' },
+ { Qt::Key_Dead_Diaeresis, '"' },
+ { Qt::Key_Dead_Cedilla, ',' },
+};
+
+static const int symbol_dead_unicode_size = sizeof(symbol_dead_unicode)/sizeof(symbol_dead_unicode_t);
+
+
+struct symbol_synonyms_t {
+ const char *from;
+ const char *to;
+};
+
+static const symbol_synonyms_t symbol_synonyms[] = {
+ { "Control_h", "BackSpace" },
+ { "Control_i", "Tab" },
+ { "Control_j", "Linefeed" },
+ { "Home", "Find" },
+ { "End", "Select" },
+ { "PageUp", "Prior" },
+ { "PageDown", "Next" },
+ { "multiplication", "multiply" },
+ { "pound", "sterling" },
+ { "pilcrow", "paragraph" },
+ { "Oslash", "Ooblique" },
+ { "Shift_L", "ShiftL" },
+ { "Shift_R", "ShiftR" },
+ { "Control_L", "CtrlL" },
+ { "Control_R", "CtrlR" },
+ { "AltL", "Alt" },
+ { "AltR", "AltGr" },
+ { "Alt_L", "Alt" },
+ { "Alt_R", "AltGr" },
+ { "AltGr_L", "Alt" },
+ { "AltGr_R", "AltGr" },
+ { "tilde", "asciitilde" },
+ { "circumflex", "asciicircum" },
+ { "dead_ogonek", "dead_cedilla" },
+ { "dead_caron", "dead_circumflex" },
+ { "dead_breve", "dead_tilde" },
+ { "dead_doubleacute", "dead_tilde" },
+ { "no-break_space", "nobreakspace" },
+ { "paragraph_sign", "section" },
+ { "soft_hyphen", "hyphen" },
+ { "rightanglequote", "guillemotright" },
+};
+
+static const int symbol_synonyms_size = sizeof(symbol_synonyms)/sizeof(symbol_synonyms_t);
+
+// makes the generated array in --header mode a bit more human readable
+QT_BEGIN_NAMESPACE
+static bool operator<(const QWSKeyboard::Mapping &m1, const QWSKeyboard::Mapping &m2)
+{
+ return m1.keycode != m2.keycode ? m1.keycode < m2.keycode : m1.modifiers < m2.modifiers;
+}
+QT_END_NAMESPACE
+
+class KeymapParser {
+public:
+ KeymapParser();
+ ~KeymapParser();
+
+ bool parseKmap(QFile *kmap);
+ bool generateQmap(QFile *qmap);
+ bool generateHeader(QFile *qmap);
+
+ int parseWarningCount() const { return m_warning_count; }
+
+private:
+ bool parseSymbol(const QByteArray &str, const QTextCodec *codec, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special);
+ bool parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode);
+ bool parseModifier(const QByteArray &str, quint8 &modifier);
+
+ void updateMapping(quint16 keycode = 0, quint8 modifiers = 0, quint16 unicode = 0xffff, quint32 qtcode = Qt::Key_unknown, quint8 flags = 0, quint16 = 0);
+
+ static quint32 toQtModifiers(quint8 modifiers);
+ static QList<QByteArray> tokenize(const QByteArray &line);
+
+
+private:
+ QList<QWSKeyboard::Mapping> m_keymap;
+ QList<QWSKeyboard::Composing> m_keycompose;
+
+ int m_warning_count;
+};
+
+
+
+int main(int argc, char **argv)
+{
+ int header = 0;
+ if (argc >= 2 && !qstrcmp(argv[1], "--header"))
+ header = 1;
+
+ if (argc < (3 + header)) {
+ fprintf(stderr, "Usage: kmap2qmap [--header] <kmap> [<additional kmaps> ...] <qmap>\n");
+ fprintf(stderr, " --header can be used to generate Qt's default compiled in qmap.\n");
+ return 1;
+ }
+
+ QVector<QFile *> kmaps(argc - header - 2);
+ for (int i = 0; i < kmaps.size(); ++i) {
+ kmaps [i] = new QFile(QString::fromLocal8Bit(argv[i + 1 + header]));
+
+ if (!kmaps[i]->open(QIODevice::ReadOnly)) {
+ fprintf(stderr, "Could not read from '%s'.\n", argv[i + 1 + header]);
+ return 2;
+ }
+ }
+ QFile *qmap = new QFile(QString::fromLocal8Bit(argv[argc - 1]));
+
+ if (!qmap->open(QIODevice::WriteOnly)) {
+ fprintf(stderr, "Could not write to '%s'.\n", argv[argc - 1]);
+ return 3;
+ }
+
+ KeymapParser p;
+
+ for (int i = 0; i < kmaps.size(); ++i) {
+ if (!p.parseKmap(kmaps[i])) {
+ fprintf(stderr, "Parsing kmap '%s' failed.\n", qPrintable(kmaps[i]->fileName()));
+ return 4;
+ }
+ }
+
+ if (p.parseWarningCount()) {
+ fprintf(stderr, "\nParsing the specified keymap(s) produced %d warning(s).\n" \
+ "Your generated qmap might not be complete.\n", \
+ p.parseWarningCount());
+ }
+ if (!(header ? p.generateHeader(qmap) : p.generateQmap(qmap))) {
+ fprintf(stderr, "Generating the qmap failed.\n");
+ return 5;
+ }
+
+ qDeleteAll(kmaps);
+ delete qmap;
+
+ return 0;
+}
+
+
+KeymapParser::KeymapParser()
+ : m_warning_count(0)
+{ }
+
+
+KeymapParser::~KeymapParser()
+{ }
+
+
+bool KeymapParser::generateHeader(QFile *f)
+{
+ QTextStream ts(f);
+
+ ts << "#ifndef QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl;
+ ts << "#define QWSKEYBOARDHANDLER_DEFAULTMAP_H" << endl << endl;
+
+ ts << "const QWSKeyboard::Mapping QWSKbPrivate::s_keymap_default[] = {" << endl;
+
+ for (int i = 0; i < m_keymap.size(); ++i) {
+ const QWSKeyboard::Mapping &m = m_keymap.at(i);
+ QString s;
+ s.sprintf(" { %3d, 0x%04x, 0x%08x, 0x%02x, 0x%02x, 0x%04x },\n", m.keycode, m.unicode, m.qtcode, m.modifiers, m.flags, m.special);
+ ts << s;
+ }
+
+ ts << "};" << endl << endl;
+
+ ts << "const QWSKeyboard::Composing QWSKbPrivate::s_keycompose_default[] = {" << endl;
+
+ for (int i = 0; i < m_keycompose.size(); ++i) {
+ const QWSKeyboard::Composing &c = m_keycompose.at(i);
+ QString s;
+ s.sprintf(" { 0x%04x, 0x%04x, 0x%04x },\n", c.first, c.second, c.result);
+ ts << s;
+ }
+ ts << "};" << endl << endl;
+
+ ts << "#endif" << endl;
+
+ return (ts.status() == QTextStream::Ok);
+}
+
+
+bool KeymapParser::generateQmap(QFile *f)
+{
+ QDataStream ds(f);
+
+ ds << quint32(QWSKeyboard::FileMagic) << quint32(1 /* version */) << quint32(m_keymap.size()) << quint32(m_keycompose.size());
+
+ if (ds.status() != QDataStream::Ok)
+ return false;
+
+ for (int i = 0; i < m_keymap.size(); ++i)
+ ds << m_keymap[i];
+
+ for (int i = 0; i < m_keycompose.size(); ++i)
+ ds << m_keycompose[i];
+
+ return (ds.status() == QDataStream::Ok);
+}
+
+
+QList<QByteArray> KeymapParser::tokenize(const QByteArray &line)
+{
+ bool quoted = false, separator = true;
+ QList<QByteArray> result;
+ QByteArray token;
+
+ for (int i = 0; i < line.length(); ++i) {
+ QChar c = line.at(i);
+
+ if (!quoted && c == '#' && separator)
+ break;
+ else if (!quoted && c == '"' && separator)
+ quoted = true;
+ else if (quoted && c == '"')
+ quoted = false;
+ else if (!quoted && c.isSpace()) {
+ separator = true;
+ if (!token.isEmpty()) {
+ result.append(token);
+ token.truncate(0);
+ }
+ }
+ else {
+ separator = false;
+ token.append(c);
+ }
+ }
+ if (!token.isEmpty())
+ result.append(token);
+ return result;
+}
+
+
+#define parseWarning(s) do { qWarning("Warning: keymap file '%s', line %d: %s", qPrintable(f->fileName()), lineno, s); ++m_warning_count; } while (false)
+
+bool KeymapParser::parseKmap(QFile *f)
+{
+ QByteArray line;
+ int lineno = 0;
+ QList<int> keymaps;
+ QTextCodec *codec = QTextCodec::codecForName("iso8859-1");
+
+ for (int i = 0; i <= 256; ++i)
+ keymaps << i;
+
+ while (!f->atEnd() && !f->error()) {
+ line = f->readLine();
+ lineno++;
+
+ QList<QByteArray> tokens = tokenize(line);
+
+ if (tokens.isEmpty())
+ continue;
+
+ if (tokens[0] == "keymaps") {
+ keymaps.clear();
+
+ if (tokens.count() > 1) {
+ foreach (const QByteArray &section, tokens[1].split(',')) {
+ int dashpos = section.indexOf('-');
+
+ //qWarning("Section %s", section.constData());
+ int end = section.mid(dashpos + 1).toInt();
+ int start = end;
+ if (dashpos > 0)
+ start = section.left(dashpos).toInt();
+
+ if (start <= end && start >=0 && end <= 256) {
+ for (int i = start; i <= end; ++i) {
+ //qWarning("appending keymap %d", i);
+ keymaps.append(i);
+ }
+ }
+ else
+ parseWarning("keymaps has an invalid range");
+ }
+ qSort(keymaps);
+ }
+ else
+ parseWarning("keymaps with more than one argument");
+ }
+ else if (tokens[0] == "alt_is_meta") {
+ // simply ignore it for now
+ }
+ else if (tokens[0] == "include") {
+ if (tokens.count() == 2) {
+ QString incname = QString::fromLocal8Bit(tokens[1]);
+ bool found = false;
+ QList<QDir> searchpath;
+ QFileInfo fi(*f);
+
+ if (!incname.endsWith(QLatin1String(".kmap")) && !incname.endsWith(QLatin1String(".inc")))
+ incname.append(QLatin1String(".inc"));
+
+ QDir d = fi.dir();
+ searchpath << d;
+ if (d.cdUp() && d.cd(QLatin1String("include")))
+ searchpath << d;
+ searchpath << QDir::current();
+
+ foreach (const QDir &path, searchpath) {
+ QFile f2(path.filePath(incname));
+ //qWarning(" -- trying to include %s", qPrintable(f2.fileName()));
+ if (f2.open(QIODevice::ReadOnly)) {
+ if (!parseKmap(&f2))
+ parseWarning("could not parse keymap include");
+ found = true;
+ }
+ }
+
+ if (!found)
+ parseWarning("could not locate keymap include");
+ } else
+ parseWarning("include doesn't have exactly one argument");
+ }
+ else if (tokens[0] == "charset") {
+ if (tokens.count() == 2) {
+ codec = QTextCodec::codecForName(tokens[1]);
+ if (!codec) {
+ parseWarning("could not parse codec definition");
+ codec = QTextCodec::codecForName("iso8859-1");
+ }
+ } else
+ parseWarning("codec doesn't habe exactly one argument");
+ }
+ else if (tokens[0] == "strings") {
+ // simply ignore those - they have no meaning for QWS
+ }
+ else if (tokens[0] == "compose") {
+ if (tokens.count() == 5 && tokens[3] == "to") {
+ QWSKeyboard::Composing c = { 0xffff, 0xffff, 0xffff };
+
+ if (!parseCompose(tokens[1], codec, c.first))
+ parseWarning("could not parse first compose symbol");
+ if (!parseCompose(tokens[2], codec, c.second))
+ parseWarning("could not parse second compose symbol");
+ if (!parseCompose(tokens[4], codec, c.result))
+ parseWarning("could not parse resulting compose symbol");
+
+ if (c.first != 0xffff && c.second != 0xffff && c.result != 0xffff) {
+ m_keycompose << c;
+ }
+ } else
+ parseWarning("non-standard compose line");
+ }
+ else {
+ int kcpos = tokens.indexOf("keycode");
+
+ if (kcpos >= 0 && kcpos < (tokens.count()-3) && tokens[kcpos+2] == "=") {
+ quint16 keycode = tokens[kcpos+1].toInt();
+
+ if (keycode <= 0 || keycode > 0x1ff /* KEY_MAX */) {
+ parseWarning("keycode out of range [0..0x1ff]");
+ break;
+ }
+
+ bool line_modifiers = (kcpos > 0);
+
+ quint8 modifiers = 0; //, modifiers_mask = 0xff;
+ for (int i = 0; i < kcpos; ++i) {
+ quint8 mod;
+ if (!parseModifier(tokens[i], mod)) {
+ parseWarning("unknown modifier prefix for keycode");
+ continue;
+ }
+ modifiers |= mod;
+ }
+
+ int kccount = tokens.count() - kcpos - 3; // 3 : 'keycode' 'X' '='
+
+ if (line_modifiers && kccount > 1) {
+ parseWarning("line has modifiers, but more than one keycode");
+ break;
+ }
+
+ // only process one symbol when a prefix modifer was specified
+ for (int i = 0; i < (line_modifiers ? 1 : kccount); ++i) {
+ if (!line_modifiers)
+ modifiers = keymaps[i];
+
+ quint32 qtcode;
+ quint16 unicode;
+ quint16 special;
+ quint8 flags;
+ if (!parseSymbol(tokens[i + kcpos + 3], codec, unicode, qtcode, flags, special)) {
+ parseWarning((QByteArray("symbol could not be parsed: ") + tokens[i + kcpos + 3]).constData());
+ break;
+ }
+
+ if (qtcode == Qt::Key_unknown && unicode == 0xffff) // VoidSymbol
+ continue;
+
+ if (!line_modifiers && kccount == 1) {
+ if ((unicode >= 'A' && unicode <= 'Z') || (unicode >= 'a' && unicode <= 'z')) {
+ quint16 other_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode - 'a' + 'A';
+ quint16 lower_unicode = (unicode >= 'A' && unicode <= 'Z') ? unicode - 'A' + 'a' : unicode;
+
+ // a single a-z|A-Z value results in a very flags mapping: see below
+
+ updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAltGr, unicode, qtcode, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, other_unicode, qtcode, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAlt, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr, unicode, qtcode | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, unicode, qtcode | Qt::AltModifier, flags, 0);
+
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ updateMapping(keycode, QWSKeyboard::ModAlt | QWSKeyboard::ModControl | QWSKeyboard::ModAltGr | QWSKeyboard::ModShift, lower_unicode, qtcode | Qt::ControlModifier | Qt::AltModifier, flags, 0);
+ }
+ else {
+ // a single value results in that mapping regardless of the modifier
+ //for (int mod = 0; mod <= 255; ++mod)
+ // updateMapping(keycode, quint8(mod), unicode, qtcode | toQtModifiers(mod), flags, special);
+
+ // we can save a lot of space in the qmap, since we do that anyway in the kbd handler:
+ updateMapping(keycode, QWSKeyboard::ModPlain, unicode, qtcode, flags, special);
+ }
+ }
+ else {
+ // "normal" mapping
+ updateMapping(keycode, modifiers, unicode, qtcode, flags, special);
+ }
+ }
+ }
+ }
+ }
+ qSort(m_keymap);
+ return !m_keymap.isEmpty();
+}
+
+
+
+void KeymapParser::updateMapping(quint16 keycode, quint8 modifiers, quint16 unicode, quint32 qtcode, quint8 flags, quint16 special)
+{
+ for (int i = 0; i < m_keymap.size(); ++i) {
+ QWSKeyboard::Mapping &m = m_keymap[i];
+
+ if (m.keycode == keycode && m.modifiers == modifiers) {
+ m.unicode = unicode;
+ m.qtcode = qtcode;
+ m.flags = flags;
+ m.special = special;
+ return;
+ }
+ }
+ QWSKeyboard::Mapping m = { keycode, unicode, qtcode, modifiers, flags, special };
+ m_keymap << m;
+}
+
+
+quint32 KeymapParser::toQtModifiers(quint8 modifiers)
+{
+ quint32 qtmodifiers = Qt::NoModifier;
+
+ for (int i = 0; i < modifier_map_size; ++i) {
+ if (modifiers & modifier_map[i].modifier)
+ qtmodifiers |= modifier_map[i].qtmodifier;
+ }
+ return qtmodifiers;
+}
+
+
+bool KeymapParser::parseModifier(const QByteArray &str, quint8 &modifier)
+{
+ QByteArray lstr = str.toLower();
+
+ for (int i = 0; i < modifier_map_size; ++i) {
+ if (lstr == modifier_map[i].symbol) {
+ modifier = modifier_map[i].modifier;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+bool KeymapParser::parseCompose(const QByteArray &str, const QTextCodec *codec, quint16 &unicode)
+{
+ if (str == "'\\''") {
+ unicode = '\'';
+ return true;
+ } else if (str.length() == 3 && str.startsWith('\'') && str.endsWith('\'')) {
+ QString temp = codec->toUnicode(str.constData() + 1, str.length() - 2);
+ if (temp.length() != 1)
+ return false;
+ unicode = temp[0].unicode();
+ return true;
+ } else {
+ quint32 code = str.toUInt();
+ if (code > 255)
+ return false;
+ char c[2];
+ c[0] = char(code);
+ c[1] = 0;
+ QString temp = codec->toUnicode(c);
+ if (temp.length() != 1)
+ return false;
+ unicode = temp[0].unicode();
+ return true;
+ }
+}
+
+
+bool KeymapParser::parseSymbol(const QByteArray &str, const QTextCodec * /*codec*/, quint16 &unicode, quint32 &qtcode, quint8 &flags, quint16 &special)
+{
+ flags = (str[0] == '+') ? QWSKeyboard::IsLetter : 0;
+ QByteArray sym = (flags & QWSKeyboard::IsLetter) ? str.right(str.length() - 1) : str;
+
+ special = 0;
+ qtcode = Qt::Key_unknown;
+ unicode = 0xffff;
+
+ if (sym == "VoidSymbol" || sym == "nul")
+ return true;
+
+ bool try_to_find_qtcode = false;
+
+ if (sym[0] >= '0' && sym[0] <= '9') { // kernel internal action number
+ return false;
+ } else if (sym.length() == 6 && sym[1] == '+' && (sym[0] == 'U' || sym[0] == 'u')) { // unicode
+ bool ok;
+ unicode = sym.mid(2).toUInt(&ok, 16);
+ if (!ok)
+ return false;
+ try_to_find_qtcode = true;
+ } else { // symbolic
+ for (int i = 0; i < symbol_synonyms_size; ++i) {
+ if (sym == symbol_synonyms[i].from) {
+ sym = symbol_synonyms[i].to;
+ break;
+ }
+ }
+
+ quint32 qtmod = 0;
+
+ // parse prepended modifiers
+ forever {
+ int underpos = sym.indexOf('_');
+
+ if (underpos <= 0)
+ break;
+ QByteArray modsym = sym.left(underpos);
+ QByteArray nomodsym = sym.mid(underpos + 1);
+ quint8 modifier = 0;
+
+ if (!parseModifier(modsym, modifier))
+ break;
+
+ qtmod |= toQtModifiers(modifier);
+ sym = nomodsym;
+ }
+
+ if (qtcode == Qt::Key_unknown) {
+ quint8 modcode;
+ // check if symbol is a modifier
+ if (parseModifier(sym, modcode)) {
+ special = modcode;
+ flags |= QWSKeyboard::IsModifier;
+ }
+
+ // map symbol to Qt key code
+ for (int i = 0; i < symbol_map_size; ++i) {
+ if (sym == symbol_map[i].symbol) {
+ qtcode = symbol_map[i].qtcode;
+ break;
+ }
+ }
+
+ // a-zA-Z is not in the table to save space
+ if (qtcode == Qt::Key_unknown && sym.length() == 1) {
+ char letter = sym.at(0);
+
+ if (letter >= 'a' && letter <= 'z') {
+ qtcode = Qt::Key_A + letter - 'a';
+ unicode = letter;
+ }
+ else if (letter >= 'A' && letter <= 'Z') {
+ qtcode = Qt::Key_A + letter - 'A';
+ unicode = letter;
+ }
+ }
+ // System keys
+ if (qtcode == Qt::Key_unknown) {
+ quint16 sys = 0;
+
+ if (sym == "Decr_Console") {
+ sys = QWSKeyboard::SystemConsolePrevious;
+ } else if (sym == "Incr_Console") {
+ sys = QWSKeyboard::SystemConsoleNext;
+ } else if (sym.startsWith("Console_")) {
+ int console = sym.mid(8).toInt() - 1;
+ if (console >= 0 && console <= (QWSKeyboard::SystemConsoleLast - QWSKeyboard::SystemConsoleFirst)) {
+ sys = QWSKeyboard::SystemConsoleFirst + console;
+ }
+ } else if (sym == "Boot") {
+ sys = QWSKeyboard::SystemReboot;
+ } else if (sym == "QtZap") {
+ sys = QWSKeyboard::SystemZap;
+ }
+
+ if (sys) {
+ flags |= QWSKeyboard::IsSystem;
+ special = sys;
+ qtcode = Qt::Key_Escape; // just a dummy
+ }
+ }
+
+ // map Qt key codes in the iso-8859-1 range to unicode
+ if (qtcode != Qt::Key_unknown && unicode == 0xffff) {
+ quint32 qtcode_no_mod = qtcode & ~(Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier | Qt::KeypadModifier);
+ if (qtcode_no_mod <= 0x000000ff) // iso-8859-1
+ unicode = quint16(qtcode_no_mod);
+ }
+
+ // flag dead keys
+ if (qtcode >= Qt::Key_Dead_Grave && qtcode <= Qt::Key_Dead_Horn) {
+ flags = QWSKeyboard::IsDead;
+
+ for (int i = 0; i < symbol_dead_unicode_size; ++i) {
+ if (symbol_dead_unicode[i].dead == qtcode) {
+ unicode = symbol_dead_unicode[i].unicode;
+ break;
+ }
+ }
+ }
+ }
+ if ((qtcode == Qt::Key_unknown) && (unicode == 0xffff))
+ return false;
+
+ qtcode |= qtmod;
+ }
+
+ // map unicode in the iso-8859-1 range to Qt key codes
+ if (unicode >= 0x0020 && unicode <= 0x00ff && qtcode == Qt::Key_unknown)
+ qtcode = unicode; // iso-8859-1
+
+ return true;
+}
+
diff --git a/tools/linguist/lconvert/main.cpp b/tools/linguist/lconvert/main.cpp
index ddde578..4bed02f 100644
--- a/tools/linguist/lconvert/main.cpp
+++ b/tools/linguist/lconvert/main.cpp
@@ -51,21 +51,16 @@ static int usage(const QStringList &args)
Q_UNUSED(args);
QString loaders;
- QString savers;
- QString line = QString(QLatin1String(" %1 - %2\n"));
- foreach (Translator::FileFormat format, Translator::registeredFileFormats()) {
+ QString line(QLatin1String(" %1 - %2\n"));
+ foreach (Translator::FileFormat format, Translator::registeredFileFormats())
loaders += line.arg(format.extension, -5).arg(format.description);
- if (format.fileType != Translator::FileFormat::SourceCode)
- savers += line.arg(format.extension, -5).arg(format.description);
- }
qWarning("%s", qPrintable(QString(QLatin1String("\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 translation data files from one of the\n"
- "following input formats\n\n%1\n"
- "to one of the following output formats\n\n%2\n"
- "If multiple input files are specified the translations are merged with\n"
+ "stand-alone tool to convert and filter translation data files.\n"
+ "The following file formats are supported:\n\n%1\n"
+ "If multiple input files are specified, they are merged with\n"
"translations from later files taking precedence.\n\n"
"Options:\n"
" -h\n"
@@ -86,17 +81,17 @@ static int usage(const QStringList &args)
" --output-format <outformat>\n"
" Specify output format. See -if.\n\n"
" --input-codec <codec>\n"
- " Specify encoding for .qm input files. Default is 'Latin1'.\n"
+ " Specify encoding for QM input files. Default is 'Latin1'.\n"
" UTF-8 is always tried as well, corresponding to the trUtf8() function.\n\n"
" --drop-tags <regexp>\n"
- " Drop named extra tags when writing 'ts' or 'xlf' files.\n"
+ " Drop named extra tags when writing TS or XLIFF files.\n"
" May be specified repeatedly.\n\n"
" --drop-translations\n"
" Drop existing translations and reset the status to 'unfinished'.\n"
" Note: this implies --no-obsolete.\n\n"
" --source-language <language>[_<region>]\n"
" Specify/override the language of the source strings. Defaults to\n"
- " POSIX if not specified and the file does not name it yet.\n"
+ " POSIX if not specified and the file does not name it yet.\n\n"
" --target-language <language>[_<region>]\n"
" Specify/override the language of the translation.\n"
" The target language is guessed from the file name if this option\n"
@@ -105,6 +100,11 @@ static int usage(const QStringList &args)
" Drop obsolete messages.\n\n"
" --no-finished\n"
" Drop finished messages.\n\n"
+ " --locations {absolute|relative|none}\n"
+ " Override how source code references are saved in TS files.\n"
+ " Default is absolute.\n\n"
+ " --no-ui-lines\n"
+ " Drop line numbers from references to UI files.\n\n"
" --verbose\n"
" be a bit more verbose\n\n"
"Long options can be specified with only one leading dash, too.\n\n"
@@ -112,7 +112,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).arg(savers)));
+ " 3 on write failures\n")).arg(loaders)));
return 1;
}
@@ -137,6 +137,8 @@ int main(int argc, char *argv[])
bool noObsolete = false;
bool noFinished = false;
bool verbose = false;
+ bool noUiLines = false;
+ Translator::LocationsType locations = Translator::DefaultLocations;
ConversionData cd;
cd.m_codecForSource = "Latin1";
@@ -193,6 +195,19 @@ int main(int argc, char *argv[])
noObsolete = true;
} else if (args[i] == QLatin1String("-no-finished")) {
noFinished = true;
+ } else if (args[i] == QLatin1String("-locations")) {
+ if (++i >= args.size())
+ return usage(args);
+ if (args[i] == QLatin1String("none"))
+ locations = Translator::NoLocations;
+ else if (args[i] == QLatin1String("relative"))
+ locations = Translator::RelativeLocations;
+ else if (args[i] == QLatin1String("absolute"))
+ locations = Translator::AbsoluteLocations;
+ else
+ return usage(args);
+ } else if (args[i] == QLatin1String("-no-ui-lines")) {
+ noUiLines = true;
} else if (args[i] == QLatin1String("-verbose")) {
verbose = true;
} else if (args[i].startsWith(QLatin1Char('-'))) {
@@ -237,6 +252,10 @@ int main(int argc, char *argv[])
tr.stripFinishedMessages();
if (dropTranslations)
tr.dropTranslations();
+ if (noUiLines)
+ tr.dropUiLines();
+ if (locations != Translator::DefaultLocations)
+ tr.setLocationsType(locations);
if (!tr.save(outFileName, cd, outFormat)) {
qWarning("%s", qPrintable(cd.error()));
diff --git a/tools/linguist/linguist/batchtranslation.ui b/tools/linguist/linguist/batchtranslation.ui
index 88b55e2..0f7fe4b 100644
--- a/tools/linguist/linguist/batchtranslation.ui
+++ b/tools/linguist/linguist/batchtranslation.ui
@@ -104,7 +104,7 @@
<item>
<widget class="QCheckBox" name="ckTranslateFinished">
<property name="toolTip">
- <string>Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked.</string>
+ <string>Note that the modified entries will be reset to unfinished if 'Set translated entries to finished' above is unchecked</string>
</property>
<property name="text">
<string>Translate also finished entries</string>
@@ -189,7 +189,7 @@
<item>
<widget class="QLabel" name="label">
<property name="text">
- <string>The batch translator will search through the selected phrase books in the order given above.</string>
+ <string>The batch translator will search through the selected phrase books in the order given above</string>
</property>
<property name="wordWrap">
<bool>true</bool>
diff --git a/tools/linguist/linguist/globals.cpp b/tools/linguist/linguist/globals.cpp
new file mode 100644
index 0000000..03062ba
--- /dev/null
+++ b/tools/linguist/linguist/globals.cpp
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "globals.h"
+
+const QString &settingsPrefix()
+{
+ static QString prefix = QString(QLatin1String("%1.%2/"))
+ .arg((QT_VERSION >> 16) & 0xff)
+ .arg((QT_VERSION >> 8) & 0xff);
+ return prefix;
+}
+
+QString settingPath(const char *path)
+{
+ return settingsPrefix() + QLatin1String(path);
+}
diff --git a/tools/linguist/linguist/globals.h b/tools/linguist/linguist/globals.h
new file mode 100644
index 0000000..b4bfb9c
--- /dev/null
+++ b/tools/linguist/linguist/globals.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef GLOBALS_H
+#define GLOBALS_H
+
+#include <QString>
+
+const QString &settingsPrefix();
+QString settingPath(const char *path);
+
+#endif // GLOBALS_H
diff --git a/tools/linguist/linguist/images/minus.png b/tools/linguist/linguist/images/minus.png
new file mode 100644
index 0000000..745b445
--- /dev/null
+++ b/tools/linguist/linguist/images/minus.png
Binary files differ
diff --git a/tools/linguist/linguist/images/plus.png b/tools/linguist/linguist/images/plus.png
new file mode 100644
index 0000000..ef43788
--- /dev/null
+++ b/tools/linguist/linguist/images/plus.png
Binary files differ
diff --git a/tools/linguist/linguist/linguist.pro b/tools/linguist/linguist/linguist.pro
index 9f16ced..890b252 100644
--- a/tools/linguist/linguist/linguist.pro
+++ b/tools/linguist/linguist/linguist.pro
@@ -26,6 +26,7 @@ SOURCES += \
errorsview.cpp \
finddialog.cpp \
formpreviewview.cpp \
+ globals.cpp \
main.cpp \
mainwindow.cpp \
messageeditor.cpp \
@@ -49,6 +50,7 @@ HEADERS += \
errorsview.h \
finddialog.h \
formpreviewview.h \
+ globals.h \
mainwindow.h \
messageeditor.h \
messageeditorwidgets.h \
diff --git a/tools/linguist/linguist/linguist.qrc b/tools/linguist/linguist/linguist.qrc
index 42cf6e3..a43f0ce 100644
--- a/tools/linguist/linguist/linguist.qrc
+++ b/tools/linguist/linguist/linguist.qrc
@@ -32,6 +32,8 @@
<file>images/up.png</file>
<file>images/down.png</file>
<file>images/editdelete.png</file>
+ <file>images/minus.png</file>
+ <file>images/plus.png</file>
<file>images/win/accelerator.png</file>
<file>images/win/book.png</file>
<file>images/win/doneandnext.png</file>
diff --git a/tools/linguist/linguist/main.cpp b/tools/linguist/linguist/main.cpp
index 865f0b7..e276ff1 100644
--- a/tools/linguist/linguist/main.cpp
+++ b/tools/linguist/linguist/main.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "mainwindow.h"
+#include "globals.h"
#include <QtCore/QFile>
#include <QtCore/QLibraryInfo>
@@ -80,22 +81,23 @@ int main(int argc, char **argv)
}
QTranslator translator;
- translator.load(QLatin1String("linguist_") + QLocale::system().name(), resourceDir);
- app.installTranslator(&translator);
-
QTranslator qtTranslator;
- qtTranslator.load(QLatin1String("qt_") + QLocale::system().name(), resourceDir);
- app.installTranslator(&qtTranslator);
+ QString sysLocale = QLocale::system().name();
+ if (translator.load(QLatin1String("linguist_") + sysLocale, resourceDir)) {
+ app.installTranslator(&translator);
+ if (qtTranslator.load(QLatin1String("qt_") + sysLocale, resourceDir))
+ app.installTranslator(&qtTranslator);
+ else
+ app.removeTranslator(&translator);
+ }
app.setOrganizationName(QLatin1String("Trolltech"));
app.setApplicationName(QLatin1String("Linguist"));
- QString keybase(QString::number( (QT_VERSION >> 16) & 0xff ) +
- QLatin1Char('.') + QString::number( (QT_VERSION >> 8) & 0xff ) + QLatin1Char('/') );
QSettings config;
QWidget tmp;
- tmp.restoreGeometry(config.value(keybase + QLatin1String("Geometry/WindowGeometry")).toByteArray());
+ tmp.restoreGeometry(config.value(settingPath("Geometry/WindowGeometry")).toByteArray());
QSplashScreen *splash = 0;
int screenId = QApplication::desktop()->screenNumber(tmp.geometry().center());
diff --git a/tools/linguist/linguist/mainwindow.cpp b/tools/linguist/linguist/mainwindow.cpp
index a6ef7c7..bb79b19 100644
--- a/tools/linguist/linguist/mainwindow.cpp
+++ b/tools/linguist/linguist/mainwindow.cpp
@@ -50,6 +50,7 @@
#include "errorsview.h"
#include "finddialog.h"
#include "formpreviewview.h"
+#include "globals.h"
#include "messageeditor.h"
#include "messagemodel.h"
#include "phrasebookbox.h"
@@ -81,6 +82,7 @@
#include <QMenuBar>
#include <QMessageBox>
#include <QPrintDialog>
+#include <QPrinter>
#include <QProcess>
#include <QRegExp>
#include <QSettings>
@@ -96,14 +98,6 @@ QT_BEGIN_NAMESPACE
static const int MessageMS = 2500;
-const QString &settingsPrefix()
-{
- static QString prefix = QString(QLatin1String("%1.%2/"))
- .arg((QT_VERSION >> 16) & 0xff)
- .arg((QT_VERSION >> 8) & 0xff);
- return prefix;
-}
-
enum Ending {
End_None,
End_FullStop,
@@ -121,13 +115,12 @@ static bool hasFormPreview(const QString &fileName)
static Ending ending(QString str, QLocale::Language lang)
{
str = str.simplified();
- int ch = 0;
- if (!str.isEmpty())
- ch = str.right(1)[0].unicode();
+ if (str.isEmpty())
+ return End_None;
- switch (ch) {
+ switch (str.at(str.length() - 1).unicode()) {
case 0x002e: // full stop
- if (str.endsWith(QString(QLatin1String("..."))))
+ if (str.endsWith(QLatin1String("...")))
return End_Ellipsis;
else
return End_FullStop;
@@ -265,6 +258,7 @@ bool FocusWatcher::eventFilter(QObject *, QEvent *event)
MainWindow::MainWindow()
: QMainWindow(0, Qt::Window),
m_assistantProcess(0),
+ m_printer(0),
m_findMatchCase(Qt::CaseInsensitive),
m_findIgnoreAccelerators(true),
m_findWhere(DataModel::NoLocation),
@@ -488,6 +482,10 @@ MainWindow::MainWindow()
readConfig();
m_statistics = 0;
+ connect(m_ui.actionLenghtVariants, SIGNAL(toggled(bool)),
+ m_messageEditor, SLOT(setLenghtVariants(bool)));
+ m_messageEditor->setLenghtVariants(m_ui.actionLenghtVariants->isChecked());
+
m_focusWatcher = new FocusWatcher(m_messageEditor, this);
m_contextView->installEventFilter(m_focusWatcher);
m_messageView->installEventFilter(m_focusWatcher);
@@ -507,6 +505,7 @@ MainWindow::~MainWindow()
qDeleteAll(m_phraseBooks);
delete m_dataModel;
delete m_statistics;
+ delete m_printer;
}
void MainWindow::modelCountChanged()
@@ -874,15 +873,22 @@ void MainWindow::releaseAll()
releaseInternal(i);
}
+QPrinter *MainWindow::printer()
+{
+ if (!m_printer)
+ m_printer = new QPrinter;
+ return m_printer;
+}
+
void MainWindow::print()
{
int pageNum = 0;
- QPrintDialog dlg(&m_printer, this);
+ QPrintDialog dlg(printer(), this);
if (dlg.exec()) {
QApplication::setOverrideCursor(Qt::WaitCursor);
- m_printer.setDocName(m_dataModel->condensedSrcFileNames(true));
+ printer()->setDocName(m_dataModel->condensedSrcFileNames(true));
statusBar()->showMessage(tr("Printing..."));
- PrintOut pout(&m_printer);
+ PrintOut pout(printer());
for (int i = 0; i < m_dataModel->contextCount(); ++i) {
MultiContextItem *mc = m_dataModel->multiContextItem(i);
@@ -1233,11 +1239,11 @@ void MainWindow::printPhraseBook(QAction *action)
int pageNum = 0;
- QPrintDialog dlg(&m_printer, this);
+ QPrintDialog dlg(printer(), this);
if (dlg.exec()) {
- m_printer.setDocName(phraseBook->fileName());
+ printer()->setDocName(phraseBook->fileName());
statusBar()->showMessage(tr("Printing..."));
- PrintOut pout(&m_printer);
+ PrintOut pout(printer());
pout.setRule(PrintOut::ThinRule);
foreach (const Phrase *p, phraseBook->phrases()) {
pout.setGuide(p->source());
@@ -1342,17 +1348,13 @@ void MainWindow::about()
QString version = tr("Version %1");
version = version.arg(QLatin1String(QT_VERSION_STR));
- // TODO: Remove this variable for 4.6.0. Must keep this way for 4.5.x due to string freeze.
- QString edition;
-
box.setText(tr("<center><img src=\":/images/splash.png\"/></img><p>%1</p></center>"
"<p>Qt Linguist is a tool for adding translations to Qt "
"applications.</p>"
- "<p>%2</p>"
"<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)."
"</p><p>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
" INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
- " PARTICULAR PURPOSE.</p>").arg(version).arg(edition));
+ " PARTICULAR PURPOSE.</p>").arg(version));
box.setWindowTitle(QApplication::translate("AboutDialog", "Qt Linguist"));
box.setIcon(QMessageBox::NoIcon);
@@ -2370,6 +2372,13 @@ void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose)
}
QStringList translations = m->translations();
+ // Truncated variants are permitted to be "denormalized"
+ for (int i = 0; i < translations.count(); ++i) {
+ int sep = translations.at(i).indexOf(QChar(Translator::BinaryVariantSeparator));
+ if (sep >= 0)
+ translations[i].truncate(sep);
+ }
+
if (m_ui.actionAccelerators->isChecked()) {
bool sk = !QKeySequence::mnemonic(source).isEmpty();
bool tk = true;
@@ -2498,25 +2507,26 @@ void MainWindow::updateDanger(const MultiDataIndex &index, bool verbose)
void MainWindow::readConfig()
{
- QString keybase = settingsPrefix();
QSettings config;
QRect r(pos(), size());
- restoreGeometry(config.value(keybase + QLatin1String("Geometry/WindowGeometry")).toByteArray());
- restoreState(config.value(keybase + QLatin1String("MainWindowState")).toByteArray());
+ restoreGeometry(config.value(settingPath("Geometry/WindowGeometry")).toByteArray());
+ restoreState(config.value(settingPath("MainWindowState")).toByteArray());
m_ui.actionAccelerators->setChecked(
- config.value(keybase + QLatin1String("Validators/Accelerator"), true).toBool());
+ config.value(settingPath("Validators/Accelerator"), true).toBool());
m_ui.actionEndingPunctuation->setChecked(
- config.value(keybase + QLatin1String("Validators/EndingPunctuation"), true).toBool());
+ config.value(settingPath("Validators/EndingPunctuation"), true).toBool());
m_ui.actionPhraseMatches->setChecked(
- config.value(keybase + QLatin1String("Validators/PhraseMatch"), true).toBool());
+ config.value(settingPath("Validators/PhraseMatch"), true).toBool());
m_ui.actionPlaceMarkerMatches->setChecked(
- config.value(keybase + QLatin1String("Validators/PlaceMarkers"), true).toBool());
+ config.value(settingPath("Validators/PlaceMarkers"), true).toBool());
+ m_ui.actionLenghtVariants->setChecked(
+ config.value(settingPath("Options/LengthVariants"), false).toBool());
recentFiles().readConfig();
- int size = config.beginReadArray(keybase + QLatin1String("OpenedPhraseBooks"));
+ int size = config.beginReadArray(settingPath("OpenedPhraseBooks"));
for (int i = 0; i < size; ++i) {
config.setArrayIndex(i);
openPhraseBook(config.value(QLatin1String("FileName")).toString());
@@ -2526,23 +2536,24 @@ void MainWindow::readConfig()
void MainWindow::writeConfig()
{
- QString keybase = settingsPrefix();
QSettings config;
- config.setValue(keybase + QLatin1String("Geometry/WindowGeometry"),
+ config.setValue(settingPath("Geometry/WindowGeometry"),
saveGeometry());
- config.setValue(keybase + QLatin1String("Validators/Accelerator"),
+ config.setValue(settingPath("Validators/Accelerator"),
m_ui.actionAccelerators->isChecked());
- config.setValue(keybase + QLatin1String("Validators/EndingPunctuation"),
+ config.setValue(settingPath("Validators/EndingPunctuation"),
m_ui.actionEndingPunctuation->isChecked());
- config.setValue(keybase + QLatin1String("Validators/PhraseMatch"),
+ config.setValue(settingPath("Validators/PhraseMatch"),
m_ui.actionPhraseMatches->isChecked());
- config.setValue(keybase + QLatin1String("Validators/PlaceMarkers"),
+ config.setValue(settingPath("Validators/PlaceMarkers"),
m_ui.actionPlaceMarkerMatches->isChecked());
- config.setValue(keybase + QLatin1String("MainWindowState"),
+ config.setValue(settingPath("Options/LengthVariants"),
+ m_ui.actionLenghtVariants->isChecked());
+ config.setValue(settingPath("MainWindowState"),
saveState());
recentFiles().writeConfig();
- config.beginWriteArray(keybase + QLatin1String("OpenedPhraseBooks"),
+ config.beginWriteArray(settingPath("OpenedPhraseBooks"),
m_phraseBooks.size());
for (int i = 0; i < m_phraseBooks.size(); ++i) {
config.setArrayIndex(i);
diff --git a/tools/linguist/linguist/mainwindow.h b/tools/linguist/linguist/mainwindow.h
index e7ec79b..3dedcb5 100644
--- a/tools/linguist/linguist/mainwindow.h
+++ b/tools/linguist/linguist/mainwindow.h
@@ -51,7 +51,6 @@
#include <QtCore/QLocale>
#include <QtGui/QMainWindow>
-#include <QtGui/QPrinter>
QT_BEGIN_NAMESPACE
@@ -60,6 +59,7 @@ class QAction;
class QDialog;
class QLabel;
class QMenu;
+class QPrinter;
class QProcess;
class QIcon;
class QSortFilterProxyModel;
@@ -79,8 +79,6 @@ class Statistics;
class TranslateDialog;
class TranslationSettingsDialog;
-const QString &settingsPrefix();
-
class MainWindow : public QMainWindow
{
Q_OBJECT
@@ -202,6 +200,8 @@ private:
void releaseInternal(int model);
void saveInternal(int model);
+ QPrinter *printer();
+
// FIXME: move to DataModel
void updateDanger(const MultiDataIndex &index, bool verbose);
@@ -228,7 +228,7 @@ private:
QList<QHash<QString, QList<Phrase *> > > m_phraseDict;
QList<PhraseBook *> m_phraseBooks;
QMap<QAction *, PhraseBook *> m_phraseBookMenu[3];
- QPrinter m_printer;
+ QPrinter *m_printer;
FindDialog *m_findDialog;
QString m_findText;
diff --git a/tools/linguist/linguist/mainwindow.ui b/tools/linguist/linguist/mainwindow.ui
index 6d42db0..613241b 100644
--- a/tools/linguist/linguist/mainwindow.ui
+++ b/tools/linguist/linguist/mainwindow.ui
@@ -60,7 +60,7 @@
<x>0</x>
<y>0</y>
<width>673</width>
- <height>30</height>
+ <height>28</height>
</rect>
</property>
<widget class="QMenu" name="menuPhrases">
@@ -116,6 +116,7 @@
<addaction name="actionResetSorting"/>
<addaction name="actionDisplayGuesses"/>
<addaction name="actionStatistics"/>
+ <addaction name="actionLenghtVariants"/>
<addaction name="separator"/>
<addaction name="menuToolbars"/>
<addaction name="menuViewViews"/>
@@ -401,7 +402,7 @@
<string>&amp;Prev Unfinished</string>
</property>
<property name="toolTip">
- <string>Previous unfinished item.</string>
+ <string>Previous unfinished item</string>
</property>
<property name="whatsThis">
<string>Move to the previous unfinished item.</string>
@@ -418,7 +419,7 @@
<string>&amp;Next Unfinished</string>
</property>
<property name="toolTip">
- <string>Next unfinished item.</string>
+ <string>Next unfinished item</string>
</property>
<property name="whatsThis">
<string>Move to the next unfinished item.</string>
@@ -435,7 +436,7 @@
<string>P&amp;rev</string>
</property>
<property name="toolTip">
- <string>Move to previous item.</string>
+ <string>Move to previous item</string>
</property>
<property name="whatsThis">
<string>Move to the previous item.</string>
@@ -452,7 +453,7 @@
<string>Ne&amp;xt</string>
</property>
<property name="toolTip">
- <string>Next item.</string>
+ <string>Next item</string>
</property>
<property name="whatsThis">
<string>Move to the next item.</string>
@@ -472,7 +473,7 @@
<string>&amp;Done and Next</string>
</property>
<property name="toolTip">
- <string>Mark item as done and move to the next unfinished item.</string>
+ <string>Mark item as done and move to the next unfinished item</string>
</property>
<property name="whatsThis">
<string>Mark this item as done and move to the next unfinished item.</string>
@@ -492,7 +493,7 @@
<string>Copy from source text</string>
</property>
<property name="toolTip">
- <string>Copies the source text into the translation field.</string>
+ <string>Copies the source text into the translation field</string>
</property>
<property name="whatsThis">
<string>Copies the source text into the translation field.</string>
@@ -512,7 +513,7 @@
<string>&amp;Accelerators</string>
</property>
<property name="toolTip">
- <string>Toggle the validity check of accelerators.</string>
+ <string>Toggle the validity check of accelerators</string>
</property>
<property name="whatsThis">
<string>Toggle the validity check of accelerators, i.e. whether the number of ampersands in the source and translation text is the same. If the check fails, a message is shown in the warnings window.</string>
@@ -529,7 +530,7 @@
<string>&amp;Ending Punctuation</string>
</property>
<property name="toolTip">
- <string>Toggle the validity check of ending punctuation.</string>
+ <string>Toggle the validity check of ending punctuation</string>
</property>
<property name="whatsThis">
<string>Toggle the validity check of ending punctuation. If the check fails, a message is shown in the warnings window.</string>
@@ -546,7 +547,7 @@
<string>&amp;Phrase matches</string>
</property>
<property name="toolTip">
- <string>Toggle checking that phrase suggestions are used.</string>
+ <string>Toggle checking that phrase suggestions are used</string>
</property>
<property name="whatsThis">
<string>Toggle checking that phrase suggestions are used. If the check fails, a message is shown in the warnings window.</string>
@@ -563,7 +564,7 @@
<string>Place &amp;Marker Matches</string>
</property>
<property name="toolTip">
- <string>Toggle the validity check of place markers.</string>
+ <string>Toggle the validity check of place markers</string>
</property>
<property name="whatsThis">
<string>Toggle the validity check of place markers, i.e. whether %1, %2, ... are used consistently in the source text and translation text. If the check fails, a message is shown in the warnings window.</string>
@@ -746,7 +747,7 @@
<string>Release As...</string>
</property>
<property name="whatsThis">
- <string>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the .ts file.</string>
+ <string>Create a Qt message file suitable for released applications from the current message file. The filename will automatically be determined from the name of the TS file.</string>
</property>
</action>
<action name="actionFile">
@@ -877,6 +878,14 @@
<string>Ctrl+W</string>
</property>
</action>
+ <action name="actionLenghtVariants">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Lenght Variants</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections/>
diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp
index 67fe651..9e598a8 100644
--- a/tools/linguist/linguist/messageeditor.cpp
+++ b/tools/linguist/linguist/messageeditor.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-/* TRANSLATOR MsgEdit
+/* TRANSLATOR MessageEditor
This is the right panel of the main window.
*/
@@ -88,13 +88,13 @@ MessageEditor::MessageEditor(MultiDataModel *dataModel, QMainWindow *parent)
m_dataModel(dataModel),
m_currentModel(-1),
m_currentNumerus(-1),
+ m_lengthVariants(false),
m_undoAvail(false),
m_redoAvail(false),
m_cutAvail(false),
m_copyAvail(false),
- m_sourceSelected(false),
- m_pluralSourceSelected(false),
- m_currentSelected(false)
+ m_selectionHolder(0),
+ m_focusWidget(0)
{
setObjectName(QLatin1String("scroll area"));
@@ -122,6 +122,9 @@ MessageEditor::MessageEditor(MultiDataModel *dataModel, QMainWindow *parent)
connect(m_dataModel, SIGNAL(languageChanged(int)),
SLOT(setTargetLanguage(int)));
+ m_tabOrderTimer.setSingleShot(true);
+ connect(&m_tabOrderTimer, SIGNAL(timeout()), SLOT(reallyFixTabOrder()));
+
clipboardChanged();
setWhatsThis(tr("This whole panel allows you to view and edit "
@@ -145,12 +148,14 @@ void MessageEditor::setupEditorPage()
m_source = new FormWidget(tr("Source text"), false);
m_source->setHideWhenEmpty(true);
m_source->setWhatsThis(tr("This area shows the source text."));
- connect(m_source, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+ connect(m_source, SIGNAL(selectionChanged(QTextEdit *)),
+ SLOT(selectionChanged(QTextEdit *)));
m_pluralSource = new FormWidget(tr("Source text (Plural)"), false);
m_pluralSource->setHideWhenEmpty(true);
m_pluralSource->setWhatsThis(tr("This area shows the plural form of the source text."));
- connect(m_pluralSource, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
+ connect(m_pluralSource, SIGNAL(selectionChanged(QTextEdit *)),
+ SLOT(selectionChanged(QTextEdit *)));
m_commentText = new FormWidget(tr("Developer comments"), false);
m_commentText->setHideWhenEmpty(true);
@@ -217,10 +222,13 @@ void MessageEditor::messageModelAppended()
ed.transCommentText->setWhatsThis(tr("Here you can enter comments for your own use."
" They have no effect on the translated applications.") );
ed.transCommentText->getEditor()->installEventFilter(this);
- connect(ed.transCommentText, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
- connect(ed.transCommentText, SIGNAL(textChanged()), SLOT(emitTranslatorCommentChanged()));
- connect(ed.transCommentText, SIGNAL(textChanged()), SLOT(resetHoverSelection()));
+ connect(ed.transCommentText, SIGNAL(selectionChanged(QTextEdit *)),
+ SLOT(selectionChanged(QTextEdit *)));
+ connect(ed.transCommentText, SIGNAL(textChanged(QTextEdit *)),
+ SLOT(emitTranslatorCommentChanged(QTextEdit *)));
+ connect(ed.transCommentText, SIGNAL(textChanged(QTextEdit *)), SLOT(resetHoverSelection()));
connect(ed.transCommentText, SIGNAL(cursorPositionChanged()), SLOT(resetHoverSelection()));
+ fixTabOrder();
QBoxLayout *box = new QVBoxLayout(ed.container);
box->setMargin(5);
box->addWidget(ed.transCommentText);
@@ -251,7 +259,7 @@ void MessageEditor::messageModelDeleted(int model)
if (m_currentModel >= 0) {
if (m_currentNumerus >= m_editors[m_currentModel].transTexts.size())
m_currentNumerus = m_editors[m_currentModel].transTexts.size() - 1;
- activeEditor()->getEditor()->setFocus();
+ activeEditor()->setFocus();
} else {
m_currentNumerus = -1;
}
@@ -266,26 +274,64 @@ void MessageEditor::messageModelDeleted(int model)
void MessageEditor::addPluralForm(int model, const QString &label, bool writable)
{
- FormWidget *transEditor = new FormWidget(label, true);
- QFont font;
- font.setPointSize(static_cast<int>(m_editors[model].fontSize));
- transEditor->getEditor()->setFont(font);
+ FormMultiWidget *transEditor = new FormMultiWidget(label);
+ connect(transEditor, SIGNAL(editorCreated(QTextEdit *)), SLOT(editorCreated(QTextEdit *)));
transEditor->setEditingEnabled(writable);
transEditor->setHideWhenEmpty(!writable);
if (!m_editors[model].transTexts.isEmpty())
transEditor->setVisible(false);
+ transEditor->setMultiEnabled(m_lengthVariants);
static_cast<QBoxLayout *>(m_editors[model].container->layout())->insertWidget(
m_editors[model].transTexts.count(), transEditor);
- transEditor->getEditor()->installEventFilter(this);
- connect(transEditor, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
- connect(transEditor, SIGNAL(textChanged()), SLOT(emitTranslationChanged()));
- connect(transEditor, SIGNAL(textChanged()), SLOT(resetHoverSelection()));
+ connect(transEditor, SIGNAL(selectionChanged(QTextEdit *)),
+ SLOT(selectionChanged(QTextEdit *)));
+ connect(transEditor, SIGNAL(textChanged(QTextEdit *)),
+ SLOT(emitTranslationChanged(QTextEdit *)));
+ connect(transEditor, SIGNAL(textChanged(QTextEdit *)), SLOT(resetHoverSelection()));
connect(transEditor, SIGNAL(cursorPositionChanged()), SLOT(resetHoverSelection()));
m_editors[model].transTexts << transEditor;
}
+void MessageEditor::editorCreated(QTextEdit *te)
+{
+ FormMultiWidget *snd = static_cast<FormMultiWidget *>(sender());
+ for (int model = 0; ; ++model) {
+ MessageEditorData med = m_editors.at(model);
+ if (med.transTexts.contains(snd)) {
+ QFont font;
+ font.setPointSize(static_cast<int>(med.fontSize));
+ te->setFont(font);
+
+ te->installEventFilter(this);
+
+ fixTabOrder();
+ return;
+ }
+ }
+}
+
+void MessageEditor::fixTabOrder()
+{
+ m_tabOrderTimer.start(0);
+}
+
+void MessageEditor::reallyFixTabOrder()
+{
+ QWidget *prev = this;
+ foreach (const MessageEditorData &med, m_editors) {
+ foreach (FormMultiWidget *fmw, med.transTexts)
+ foreach (QTextEdit *te, fmw->getEditors()) {
+ setTabOrder(prev, te);
+ prev = te;
+ }
+ QTextEdit *te = med.transCommentText->getEditor();
+ setTabOrder(prev, te);
+ prev = te;
+ }
+}
+
/*! internal
Returns all translations for an item.
The number of translations is dependent on if we have a plural form or not.
@@ -301,69 +347,53 @@ QStringList MessageEditor::translations(int model) const
return translations;
}
-static bool clearFormSelection(FormWidget *fw, FormWidget *te)
+static void clearSelection(QTextEdit *t)
{
- if (fw != te) {
- QTextEdit *t = fw->getEditor();
- bool oldBlockState = t->blockSignals(true);
- QTextCursor c = t->textCursor();
- c.clearSelection();
- t->setTextCursor(c);
- t->blockSignals(oldBlockState);
- return true;
- }
- return false;
+ bool oldBlockState = t->blockSignals(true);
+ QTextCursor c = t->textCursor();
+ c.clearSelection();
+ t->setTextCursor(c);
+ t->blockSignals(oldBlockState);
}
-// Clear the selection for all textedits except the sender
-void MessageEditor::selectionChanged()
+void MessageEditor::selectionChanged(QTextEdit *te)
{
- if (!resetSelection(qobject_cast<FormWidget *>(sender())))
+ if (te != m_selectionHolder) {
+ if (m_selectionHolder)
+ clearSelection(m_selectionHolder);
+ m_selectionHolder = (te->textCursor().hasSelection() ? te : 0);
updateCanCutCopy();
+ }
}
-bool MessageEditor::resetHoverSelection(FormWidget *fw)
+void MessageEditor::resetHoverSelection()
{
- if (m_sourceSelected) {
- if (clearFormSelection(m_source, fw)) {
- updateCanCutCopy();
- return true;
- }
- } else if (m_pluralSourceSelected) {
- if (clearFormSelection(m_pluralSource, fw)) {
- updateCanCutCopy();
- return true;
- }
- }
- return false;
+ if (m_selectionHolder &&
+ (m_selectionHolder == m_source->getEditor()
+ || m_selectionHolder == m_pluralSource->getEditor()))
+ resetSelection();
}
-bool MessageEditor::resetSelection(FormWidget *fw)
+void MessageEditor::resetSelection()
{
- if (resetHoverSelection(fw))
- return true;
- if (m_currentSelected) {
- MessageEditorData &ed = m_editors[m_currentModel];
- FormWidget *cfw = (m_currentNumerus < 0) ? ed.transCommentText
- : ed.transTexts[m_currentNumerus];
- if (clearFormSelection(cfw, fw)) {
- updateCanCutCopy();
- return true;
- }
+ if (m_selectionHolder) {
+ clearSelection(m_selectionHolder);
+ m_selectionHolder = 0;
+ updateCanCutCopy();
}
- return false;
}
void MessageEditor::activeModelAndNumerus(int *model, int *numerus) const
{
for (int j = 0; j < m_editors.count(); ++j) {
for (int i = 0; i < m_editors[j].transTexts.count(); ++i)
- if (m_editors[j].transTexts[i]->getEditor()->hasFocus()) {
- *model = j;
- *numerus = i;
- return;
- }
- if (m_editors[j].transCommentText->getEditor()->hasFocus()) {
+ foreach (QTextEdit *te, m_editors[j].transTexts[i]->getEditors())
+ if (m_focusWidget == te) {
+ *model = j;
+ *numerus = i;
+ return;
+ }
+ if (m_focusWidget == m_editors[j].transCommentText->getEditor()) {
*model = j;
*numerus = -1;
return;
@@ -373,43 +403,46 @@ void MessageEditor::activeModelAndNumerus(int *model, int *numerus) const
*numerus = -1;
}
-FormWidget *MessageEditor::activeTranslation() const
+QTextEdit *MessageEditor::activeTranslation() const
{
if (m_currentNumerus < 0)
return 0;
- return m_editors[m_currentModel].transTexts[m_currentNumerus];
+ foreach (QTextEdit *te, m_editors[m_currentModel].transTexts[m_currentNumerus]->getEditors())
+ if (te->hasFocus())
+ return te;
+ return 0; // This cannot happen
}
-FormWidget *MessageEditor::activeOr1stTranslation() const
+QTextEdit *MessageEditor::activeOr1stTranslation() const
{
if (m_currentNumerus < 0) {
for (int i = 0; i < m_editors.size(); ++i)
if (m_editors[i].container->isVisible()
- && !m_editors[i].transTexts[0]->getEditor()->isReadOnly())
- return m_editors[i].transTexts[0];
+ && !m_editors[i].transTexts.first()->getEditors().first()->isReadOnly())
+ return m_editors[i].transTexts.first()->getEditors().first();
return 0;
}
- return m_editors[m_currentModel].transTexts[m_currentNumerus];
+ return activeTranslation();
}
-FormWidget *MessageEditor::activeTransComment() const
+QTextEdit *MessageEditor::activeTransComment() const
{
if (m_currentModel < 0 || m_currentNumerus >= 0)
return 0;
- return m_editors[m_currentModel].transCommentText;
+ return m_editors[m_currentModel].transCommentText->getEditor();
}
-FormWidget *MessageEditor::activeEditor() const
+QTextEdit *MessageEditor::activeEditor() const
{
- if (FormWidget *fw = activeTransComment())
- return fw;
+ if (QTextEdit *te = activeTransComment())
+ return te;
return activeTranslation();
}
-FormWidget *MessageEditor::activeOr1stEditor() const
+QTextEdit *MessageEditor::activeOr1stEditor() const
{
- if (FormWidget *fw = activeTransComment())
- return fw;
+ if (QTextEdit *te = activeTransComment())
+ return te;
return activeOr1stTranslation();
}
@@ -417,25 +450,14 @@ void MessageEditor::setTargetLanguage(int model)
{
const QStringList &numerusForms = m_dataModel->model(model)->numerusForms();
const QString &langLocalized = m_dataModel->model(model)->localizedLanguage();
- bool added = false;
for (int i = 0; i < numerusForms.count(); ++i) {
const QString &label = tr("%1 translation (%2)").arg(langLocalized, numerusForms[i]);
if (!i)
m_editors[model].firstForm = label;
- if (i >= m_editors[model].transTexts.count()) {
+ if (i >= m_editors[model].transTexts.count())
addPluralForm(model, label, m_dataModel->isModelWritable(model));
- QWidget *prev;
- if (i > 0)
- prev = m_editors[model].transTexts[i - 1]->getEditor();
- else if (model)
- prev = m_editors[model - 1].transCommentText->getEditor();
- else
- prev = this;
- setTabOrder(prev, m_editors[model].transTexts[i]->getEditor());
- added = true;
- } else {
+ else
m_editors[model].transTexts[i]->setLabel(label);
- }
m_editors[model].transTexts[i]->setVisible(!i || m_editors[model].pluralEditMode);
m_editors[model].transTexts[i]->setWhatsThis(
tr("This is where you can enter or modify"
@@ -445,16 +467,15 @@ void MessageEditor::setTargetLanguage(int model)
delete m_editors[model].transTexts.takeLast();
m_editors[model].invariantForm = tr("%1 translation").arg(langLocalized);
m_editors[model].transCommentText->setLabel(tr("%1 translator comments").arg(langLocalized));
- if (added)
- setTabOrder(m_editors[model].transTexts.last()->getEditor(), m_editors[model].transCommentText->getEditor());
}
MessageEditorData *MessageEditor::modelForWidget(const QObject *o)
{
for (int j = 0; j < m_editors.count(); ++j) {
for (int i = 0; i < m_editors[j].transTexts.count(); ++i)
- if (m_editors[j].transTexts[i]->getEditor() == o)
- return &m_editors[j];
+ foreach (QTextEdit *te, m_editors[j].transTexts[i]->getEditors())
+ if (te == o)
+ return &m_editors[j];
if (m_editors[j].transCommentText->getEditor() == o)
return &m_editors[j];
}
@@ -466,7 +487,8 @@ static bool applyFont(MessageEditorData *med)
QFont font;
font.setPointSize(static_cast<int>(med->fontSize));
for (int i = 0; i < med->transTexts.count(); ++i)
- med->transTexts[i]->getEditor()->setFont(font);
+ foreach (QTextEdit *te, med->transTexts[i]->getEditors())
+ te->setFont(font);
med->transCommentText->getEditor()->setFont(font);
return true;
}
@@ -529,22 +551,39 @@ bool MessageEditor::eventFilter(QObject *o, QEvent *e)
return decFont(modelForWidget(o));
}
} else if (e->type() == QEvent::FocusIn) {
- int model, numerus;
- activeModelAndNumerus(&model, &numerus);
- if (model != m_currentModel || numerus != m_currentNumerus) {
- resetSelection();
- m_currentModel = model;
- m_currentNumerus = numerus;
- emit activeModelChanged(activeModel());
- updateBeginFromSource();
- updateUndoRedo();
- updateCanPaste();
- }
+ QWidget *widget = static_cast<QWidget *>(o);
+ if (widget != m_focusWidget)
+ trackFocus(widget);
}
return QScrollArea::eventFilter(o, e);
}
+void MessageEditor::grabFocus(QWidget *widget)
+{
+ if (widget != m_focusWidget) {
+ widget->setFocus();
+ trackFocus(widget);
+ }
+}
+
+void MessageEditor::trackFocus(QWidget *widget)
+{
+ m_focusWidget = widget;
+
+ int model, numerus;
+ activeModelAndNumerus(&model, &numerus);
+ if (model != m_currentModel || numerus != m_currentNumerus) {
+ resetSelection();
+ m_currentModel = model;
+ m_currentNumerus = numerus;
+ emit activeModelChanged(activeModel());
+ updateBeginFromSource();
+ updateUndoRedo();
+ updateCanPaste();
+ }
+}
+
void MessageEditor::showNothing()
{
m_source->clearTranslation();
@@ -552,7 +591,7 @@ void MessageEditor::showNothing()
m_commentText->clearTranslation();
for (int j = 0; j < m_editors.count(); ++j) {
setEditingEnabled(j, false);
- foreach (FormWidget *widget, m_editors[j].transTexts)
+ foreach (FormMultiWidget *widget, m_editors[j].transTexts)
widget->clearTranslation();
m_editors[j].transCommentText->clearTranslation();
}
@@ -639,7 +678,7 @@ void MessageEditor::setTranslation(int model, const QString &translation, int nu
MessageEditorData &ed = m_editors[model];
if (numerus >= ed.transTexts.count())
numerus = 0;
- FormWidget *transForm = ed.transTexts[numerus];
+ FormMultiWidget *transForm = ed.transTexts[numerus];
transForm->setTranslation(translation, false);
updateBeginFromSource();
@@ -654,8 +693,8 @@ void MessageEditor::setTranslation(int latestModel, const QString &translation)
latestModel = m_currentModel;
numerus = m_currentNumerus;
}
- FormWidget *transForm = m_editors[latestModel].transTexts[numerus];
- transForm->getEditor()->setFocus();
+ FormMultiWidget *transForm = m_editors[latestModel].transTexts[numerus];
+ transForm->getEditors().first()->setFocus();
transForm->setTranslation(translation, true);
updateBeginFromSource();
@@ -664,29 +703,37 @@ void MessageEditor::setTranslation(int latestModel, const QString &translation)
void MessageEditor::setEditingEnabled(int model, bool enabled)
{
MessageEditorData &ed = m_editors[model];
- foreach (FormWidget *widget, ed.transTexts)
+ foreach (FormMultiWidget *widget, ed.transTexts)
widget->setEditingEnabled(enabled);
ed.transCommentText->setEditingEnabled(enabled);
updateCanPaste();
}
+void MessageEditor::setLenghtVariants(bool on)
+{
+ m_lengthVariants = on;
+ foreach (const MessageEditorData &ed, m_editors)
+ foreach (FormMultiWidget *widget, ed.transTexts)
+ widget->setMultiEnabled(on);
+}
+
void MessageEditor::undo()
{
- activeEditor()->getEditor()->document()->undo();
+ activeEditor()->document()->undo();
}
void MessageEditor::redo()
{
- activeEditor()->getEditor()->document()->redo();
+ activeEditor()->document()->redo();
}
void MessageEditor::updateUndoRedo()
{
bool newUndoAvail = false;
bool newRedoAvail = false;
- if (FormWidget *fw = activeEditor()) {
- QTextDocument *doc = fw->getEditor()->document();
+ if (QTextEdit *te = activeEditor()) {
+ QTextDocument *doc = te->document();
newUndoAvail = doc->isUndoAvailable();
newRedoAvail = doc->isRedoAvailable();
}
@@ -704,18 +751,12 @@ void MessageEditor::updateUndoRedo()
void MessageEditor::cut()
{
- QTextEdit *editor = activeEditor()->getEditor();
- if (editor->textCursor().hasSelection())
- editor->cut();
+ m_selectionHolder->cut();
}
void MessageEditor::copy()
{
- QTextEdit *te;
- if ((te = m_source->getEditor())->textCursor().hasSelection()
- || (te = m_pluralSource->getEditor())->textCursor().hasSelection()
- || (te = activeEditor()->getEditor())->textCursor().hasSelection())
- te->copy();
+ m_selectionHolder->copy();
}
void MessageEditor::updateCanCutCopy()
@@ -723,19 +764,9 @@ void MessageEditor::updateCanCutCopy()
bool newCopyState = false;
bool newCutState = false;
- m_sourceSelected = m_source->getEditor()->textCursor().hasSelection();
- m_pluralSourceSelected = m_pluralSource->getEditor()->textCursor().hasSelection();
- m_currentSelected = false;
-
- if (m_sourceSelected || m_pluralSourceSelected) {
+ if (m_selectionHolder) {
newCopyState = true;
- } else if (FormWidget *fw = activeEditor()) {
- QTextEdit *te = fw->getEditor();
- if (te->textCursor().hasSelection()) {
- m_currentSelected = true;
- newCopyState = true;
- newCutState = !te->isReadOnly();
- }
+ newCutState = !m_selectionHolder->isReadOnly();
}
if (newCopyState != m_copyAvail) {
@@ -751,14 +782,14 @@ void MessageEditor::updateCanCutCopy()
void MessageEditor::paste()
{
- activeEditor()->getEditor()->paste();
+ activeEditor()->paste();
}
void MessageEditor::updateCanPaste()
{
- FormWidget *fw;
+ QTextEdit *te;
emit pasteAvailable(!m_clipboardEmpty
- && (fw = activeEditor()) && !fw->getEditor()->isReadOnly());
+ && (te = activeEditor()) && !te->isReadOnly());
}
void MessageEditor::clipboardChanged()
@@ -773,24 +804,23 @@ void MessageEditor::selectAll()
// make sure we don't select the selection of a translator textedit,
// if we really want the source text editor to be selected.
QTextEdit *te;
- FormWidget *fw;
if ((te = m_source->getEditor())->underMouse()
|| (te = m_pluralSource->getEditor())->underMouse()
- || ((fw = activeEditor()) && (te = fw->getEditor())->hasFocus()))
+ || ((te = activeEditor()) && te->hasFocus()))
te->selectAll();
}
-void MessageEditor::emitTranslationChanged()
+void MessageEditor::emitTranslationChanged(QTextEdit *widget)
{
- static_cast<FormWidget *>(sender())->getEditor()->setFocus(); // DND proofness
+ grabFocus(widget); // DND proofness
updateBeginFromSource();
updateUndoRedo();
emit translationChanged(translations(m_currentModel));
}
-void MessageEditor::emitTranslatorCommentChanged()
+void MessageEditor::emitTranslatorCommentChanged(QTextEdit *widget)
{
- static_cast<FormWidget *>(sender())->getEditor()->setFocus(); // DND proofness
+ grabFocus(widget); // DND proofness
updateUndoRedo();
emit translatorCommentChanged(m_editors[m_currentModel].transCommentText->getTranslation());
}
@@ -798,11 +828,9 @@ void MessageEditor::emitTranslatorCommentChanged()
void MessageEditor::updateBeginFromSource()
{
bool overwrite = false;
- if (FormWidget *transForm = activeTranslation()) {
- QTextEdit *activeEditor = transForm->getEditor();
+ if (QTextEdit *activeEditor = activeTranslation())
overwrite = !activeEditor->isReadOnly()
&& activeEditor->toPlainText().trimmed().isEmpty();
- }
emit beginFromSourceAvailable(overwrite);
}
@@ -817,8 +845,8 @@ void MessageEditor::beginFromSource()
void MessageEditor::setEditorFocus()
{
if (!widget()->hasFocus())
- if (FormWidget *transForm = activeOr1stEditor())
- transForm->getEditor()->setFocus();
+ if (QTextEdit *activeEditor = activeOr1stEditor())
+ activeEditor->setFocus();
}
void MessageEditor::setEditorFocus(int model)
@@ -828,12 +856,13 @@ void MessageEditor::setEditorFocus(int model)
resetSelection();
m_currentNumerus = -1;
m_currentModel = -1;
+ m_focusWidget = 0;
emit activeModelChanged(activeModel());
updateBeginFromSource();
updateUndoRedo();
updateCanPaste();
} else {
- m_editors[model].transTexts[0]->getEditor()->setFocus();
+ m_editors[model].transTexts.first()->getEditors().first()->setFocus();
}
}
}
@@ -844,7 +873,7 @@ bool MessageEditor::focusNextUnfinished(int start)
if (m_dataModel->isModelWritable(j))
if (MessageItem *item = m_dataModel->messageItem(m_currentIndex, j))
if (item->type() == TranslatorMessage::Unfinished) {
- m_editors[j].transTexts[0]->getEditor()->setFocus();
+ m_editors[j].transTexts.first()->getEditors().first()->setFocus();
return true;
}
return false;
diff --git a/tools/linguist/linguist/messageeditor.h b/tools/linguist/linguist/messageeditor.h
index 8b0c45b..4106036 100644
--- a/tools/linguist/linguist/messageeditor.h
+++ b/tools/linguist/linguist/messageeditor.h
@@ -45,6 +45,7 @@
#include "messagemodel.h"
#include <QtCore/QLocale>
+#include <QtCore/QTimer>
#include <QtGui/QFrame>
#include <QtGui/QScrollArea>
@@ -58,11 +59,12 @@ class QTextEdit;
class MessageEditor;
class FormatTextEdit;
class FormWidget;
+class FormMultiWidget;
struct MessageEditorData {
QWidget *container;
FormWidget *transCommentText;
- QList<FormWidget*> transTexts;
+ QList<FormMultiWidget *> transTexts;
QString invariantForm;
QString firstForm;
float fontSize;
@@ -108,30 +110,35 @@ public slots:
void beginFromSource();
void setEditorFocus();
void setTranslation(int latestModel, const QString &translation);
+ void setLenghtVariants(bool on);
private slots:
- void selectionChanged();
- bool resetHoverSelection(FormWidget *fw = 0);
- void emitTranslationChanged();
- void emitTranslatorCommentChanged();
+ void editorCreated(QTextEdit *);
+ void selectionChanged(QTextEdit *);
+ void resetHoverSelection();
+ void emitTranslationChanged(QTextEdit *);
+ void emitTranslatorCommentChanged(QTextEdit *);
void updateCanPaste();
void clipboardChanged();
void messageModelAppended();
void messageModelDeleted(int model);
void allModelsDeleted();
void setTargetLanguage(int model);
+ void reallyFixTabOrder();
private:
void setupEditorPage();
void setEditingEnabled(int model, bool enabled);
bool focusNextUnfinished(int start);
- bool resetSelection(FormWidget *fw = 0);
+ void resetSelection();
+ void grabFocus(QWidget *widget);
+ void trackFocus(QWidget *widget);
void activeModelAndNumerus(int *model, int *numerus) const;
- FormWidget *activeTranslation() const;
- FormWidget *activeOr1stTranslation() const;
- FormWidget *activeTransComment() const;
- FormWidget *activeEditor() const;
- FormWidget *activeOr1stEditor() const;
+ QTextEdit *activeTranslation() const;
+ QTextEdit *activeOr1stTranslation() const;
+ QTextEdit *activeTransComment() const;
+ QTextEdit *activeEditor() const;
+ QTextEdit *activeOr1stEditor() const;
MessageEditorData *modelForWidget(const QObject *o);
int activeTranslationNumerus() const;
QStringList translations(int model) const;
@@ -139,6 +146,7 @@ private:
void updateUndoRedo();
void updateCanCutCopy();
void addPluralForm(int model, const QString &label, bool writable);
+ void fixTabOrder();
QPalette paletteForModel(int model) const;
MultiDataModel *m_dataModel;
@@ -147,21 +155,24 @@ private:
int m_currentModel;
int m_currentNumerus;
+ bool m_lengthVariants;
+
bool m_undoAvail;
bool m_redoAvail;
bool m_cutAvail;
bool m_copyAvail;
- bool m_sourceSelected;
- bool m_pluralSourceSelected;
- bool m_currentSelected;
bool m_clipboardEmpty;
+ QTextEdit *m_selectionHolder;
+ QWidget *m_focusWidget;
QBoxLayout *m_layout;
FormWidget *m_source;
FormWidget *m_pluralSource;
FormWidget *m_commentText;
QList<MessageEditorData> m_editors;
+
+ QTimer m_tabOrderTimer;
};
QT_END_NAMESPACE
diff --git a/tools/linguist/linguist/messageeditorwidgets.cpp b/tools/linguist/linguist/messageeditorwidgets.cpp
index b1eede2..f8e2dc2 100644
--- a/tools/linguist/linguist/messageeditorwidgets.cpp
+++ b/tools/linguist/linguist/messageeditorwidgets.cpp
@@ -42,6 +42,8 @@
#include "messageeditorwidgets.h"
#include "messagehighlighter.h"
+#include <translator.h>
+
#include <QAbstractTextDocumentLayout>
#include <QAction>
#include <QApplication>
@@ -49,10 +51,12 @@
#include <QDebug>
#include <QLayout>
#include <QMenu>
+#include <QMessageBox>
#include <QPainter>
#include <QScrollArea>
#include <QTextBlock>
#include <QTextDocumentFragment>
+#include <QToolButton>
#include <QVBoxLayout>
QT_BEGIN_NAMESPACE
@@ -145,16 +149,15 @@ void FormatTextEdit::setEditable(bool editable)
void FormatTextEdit::setPlainText(const QString &text, bool userAction)
{
- bool oldBlockState = false;
if (!userAction) {
// Prevent contentsChanged signal
- oldBlockState = document()->blockSignals(true);
+ bool oldBlockState = blockSignals(true);
document()->setUndoRedoEnabled(false);
ExpandingTextEdit::setPlainText(text);
// highlighter is out of sync because of blocked signals
m_highlighter->rehighlight();
document()->setUndoRedoEnabled(true);
- document()->blockSignals(oldBlockState);
+ blockSignals(oldBlockState);
} else {
ExpandingTextEdit::setPlainText(text);
}
@@ -178,11 +181,21 @@ FormWidget::FormWidget(const QString &label, bool isEditable, QWidget *parent)
setLayout(layout);
- connect(m_editor->document(), SIGNAL(contentsChanged()), SIGNAL(textChanged()));
- connect(m_editor, SIGNAL(selectionChanged()), SIGNAL(selectionChanged()));
+ connect(m_editor, SIGNAL(textChanged()), SLOT(slotTextChanged()));
+ connect(m_editor, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
connect(m_editor, SIGNAL(cursorPositionChanged()), SIGNAL(cursorPositionChanged()));
}
+void FormWidget::slotTextChanged()
+{
+ emit textChanged(m_editor);
+}
+
+void FormWidget::slotSelectionChanged()
+{
+ emit selectionChanged(m_editor);
+}
+
void FormWidget::setTranslation(const QString &text, bool userAction)
{
m_editor->setPlainText(text, userAction);
@@ -198,4 +211,240 @@ void FormWidget::setEditingEnabled(bool enable)
}
+class ButtonWrapper : public QWidget
+{
+ // no Q_OBJECT: no need to, and don't want the useless moc file
+
+public:
+ ButtonWrapper(QWidget *wrapee, QWidget *relator) : m_wrapee(wrapee)
+ {
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored);
+ QBoxLayout *box = new QVBoxLayout;
+ box->setMargin(0);
+ setLayout(box);
+ box->addWidget(wrapee, 0, Qt::AlignBottom);
+ if (relator)
+ relator->installEventFilter(this);
+ }
+
+protected:
+ virtual bool eventFilter(QObject *object, QEvent *event)
+ {
+ if (event->type() == QEvent::Resize) {
+ QWidget *relator = static_cast<QWidget *>(object);
+ setFixedHeight((relator->height() + layout()->spacing() + m_wrapee->height()) / 2);
+ }
+ return false;
+ }
+
+private:
+ QWidget *m_wrapee;
+};
+
+FormMultiWidget::FormMultiWidget(const QString &label, QWidget *parent)
+ : QWidget(parent),
+ m_hideWhenEmpty(false),
+ m_multiEnabled(false),
+ m_plusIcon(QIcon(QLatin1String(":/images/plus.png"))), // make static
+ m_minusIcon(QIcon(QLatin1String(":/images/minus.png")))
+{
+ m_label = new QLabel(this);
+ m_label->setText(label);
+
+ m_plusButtons.append(
+ new ButtonWrapper(makeButton(m_plusIcon, SLOT(plusButtonClicked())), 0));
+}
+
+QAbstractButton *FormMultiWidget::makeButton(const QIcon &icon, const char *slot)
+{
+ QAbstractButton *btn = new QToolButton(this);
+ btn->setIcon(icon);
+ btn->setFixedSize(icon.availableSizes().first() /* + something */);
+ btn->setFocusPolicy(Qt::NoFocus);
+ connect(btn, SIGNAL(clicked()), slot);
+ return btn;
+}
+
+void FormMultiWidget::addEditor(int idx)
+{
+ FormatTextEdit *editor = new FormatTextEdit(this);
+ m_editors.insert(idx, editor);
+
+ m_minusButtons.insert(idx, makeButton(m_minusIcon, SLOT(minusButtonClicked())));
+ m_plusButtons.insert(idx + 1,
+ new ButtonWrapper(makeButton(m_plusIcon, SLOT(plusButtonClicked())), editor));
+
+ connect(editor, SIGNAL(textChanged()), SLOT(slotTextChanged()));
+ connect(editor, SIGNAL(selectionChanged()), SLOT(slotSelectionChanged()));
+ connect(editor, SIGNAL(cursorPositionChanged()), SIGNAL(cursorPositionChanged()));
+ editor->installEventFilter(this);
+
+ emit editorCreated(editor);
+}
+
+bool FormMultiWidget::eventFilter(QObject *watched, QEvent *event)
+{
+ int i = 0;
+ while (m_editors.at(i) != watched)
+ if (++i >= m_editors.count()) // Happens when deleting an editor
+ return false;
+ if (event->type() == QEvent::FocusOut) {
+ m_minusButtons.at(i)->setToolTip(QString());
+ m_plusButtons.at(i)->setToolTip(QString());
+ m_plusButtons.at(i + 1)->setToolTip(QString());
+ } else if (event->type() == QEvent::FocusIn) {
+ m_minusButtons.at(i)->setToolTip(/*: translate, but don't change */ tr("Alt+Delete"));
+ m_plusButtons.at(i)->setToolTip(/*: translate, but don't change */ tr("Shift+Alt+Insert"));
+ m_plusButtons.at(i + 1)->setToolTip(/*: translate, but don't change */ tr("Alt+Insert"));
+ } else if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->modifiers() & Qt::AltModifier) {
+ if (ke->key() == Qt::Key_Delete) {
+ deleteEditor(i);
+ return true;
+ } else if (ke->key() == Qt::Key_Insert) {
+ if (!(ke->modifiers() & Qt::ShiftModifier))
+ ++i;
+ insertEditor(i);
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void FormMultiWidget::updateLayout()
+{
+ delete layout();
+
+ QGridLayout *layout = new QGridLayout;
+ layout->setMargin(0);
+ setLayout(layout);
+
+ bool variants = m_multiEnabled && m_label->isEnabled();
+
+ layout->addWidget(m_label, 0, 0, 1, variants ? 3 : 1);
+
+ for (int i = 0; i < m_plusButtons.count(); ++i) {
+ if (variants)
+ layout->addWidget(m_plusButtons.at(i), 1 + i * 2, 0, 2, 1, Qt::AlignTop);
+ m_plusButtons.at(i)->setVisible(variants);
+ }
+ for (int j = 0; j < m_minusButtons.count(); ++j) {
+ if (variants)
+ layout->addWidget(m_minusButtons.at(j), 2 + j * 2, 2, 2, 1, Qt::AlignVCenter);
+ m_minusButtons.at(j)->setVisible(variants);
+ }
+ for (int k = 0; k < m_editors.count(); ++k)
+ layout->addWidget(m_editors.at(k), 2 + k * 2, variants ? 1 : 0, 2, 1, Qt::AlignVCenter);
+
+ updateGeometry();
+}
+
+void FormMultiWidget::slotTextChanged()
+{
+ emit textChanged(static_cast<QTextEdit *>(sender()));
+}
+
+void FormMultiWidget::slotSelectionChanged()
+{
+ emit selectionChanged(static_cast<QTextEdit *>(sender()));
+}
+
+void FormMultiWidget::setTranslation(const QString &text, bool userAction)
+{
+ QStringList texts = text.split(QChar(Translator::BinaryVariantSeparator), QString::KeepEmptyParts);
+
+ while (m_editors.count() > texts.count()) {
+ delete m_minusButtons.takeLast();
+ delete m_plusButtons.takeLast();
+ delete m_editors.takeLast();
+ }
+ while (m_editors.count() < texts.count())
+ addEditor(m_editors.count());
+ updateLayout();
+
+ for (int i = 0; i < texts.count(); ++i)
+ // XXX this will emit n textChanged signals
+ m_editors.at(i)->setPlainText(texts.at(i), userAction);
+
+ if (m_hideWhenEmpty)
+ setHidden(text.isEmpty());
+}
+
+QString FormMultiWidget::getTranslation() const
+{
+ QString ret;
+ for (int i = 0; i < m_editors.count(); ++i) {
+ if (i)
+ ret += QChar(Translator::BinaryVariantSeparator);
+ ret += m_editors.at(i)->toPlainText();
+ }
+ return ret;
+}
+
+void FormMultiWidget::setEditingEnabled(bool enable)
+{
+ // Use read-only state so that the text can still be copied
+ for (int i = 0; i < m_editors.count(); ++i)
+ m_editors.at(i)->setReadOnly(!enable);
+ m_label->setEnabled(enable);
+ if (m_multiEnabled)
+ updateLayout();
+}
+
+void FormMultiWidget::setMultiEnabled(bool enable)
+{
+ m_multiEnabled = enable;
+ if (m_label->isEnabled())
+ updateLayout();
+}
+
+void FormMultiWidget::minusButtonClicked()
+{
+ int i = 0;
+ while (m_minusButtons.at(i) != sender())
+ ++i;
+ deleteEditor(i);
+}
+
+void FormMultiWidget::plusButtonClicked()
+{
+ QWidget *btn = static_cast<QAbstractButton *>(sender())->parentWidget();
+ int i = 0;
+ while (m_plusButtons.at(i) != btn)
+ ++i;
+ insertEditor(i);
+}
+
+void FormMultiWidget::deleteEditor(int idx)
+{
+ if (m_editors.count() == 1) {
+ // Don't just clear(), so the undo history is not lost
+ QTextCursor c = m_editors.first()->textCursor();
+ c.select(QTextCursor::Document);
+ c.removeSelectedText();
+ } else {
+ if (!m_editors.at(idx)->toPlainText().isEmpty()) {
+ if (QMessageBox::question(topLevelWidget(), tr("Confirmation - Qt Linguist"),
+ tr("Delete non-empty length variant?"),
+ QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes)
+ != QMessageBox::Yes)
+ return;
+ }
+ delete m_editors.takeAt(idx);
+ delete m_minusButtons.takeAt(idx);
+ delete m_plusButtons.takeAt(idx + 1);
+ updateLayout();
+ emit textChanged(m_editors.at((m_editors.count() == idx) ? idx - 1 : idx));
+ }
+}
+
+void FormMultiWidget::insertEditor(int idx)
+{
+ addEditor(idx);
+ updateLayout();
+ emit textChanged(m_editors.at(idx));
+}
+
QT_END_NAMESPACE
diff --git a/tools/linguist/linguist/messageeditorwidgets.h b/tools/linguist/linguist/messageeditorwidgets.h
index 3c54d73..c0b445c 100644
--- a/tools/linguist/linguist/messageeditorwidgets.h
+++ b/tools/linguist/linguist/messageeditorwidgets.h
@@ -42,6 +42,7 @@
#ifndef MESSAGEEDITORWIDGETS_H
#define MESSAGEEDITORWIDGETS_H
+#include <QIcon>
#include <QImage>
#include <QLabel>
#include <QMap>
@@ -51,6 +52,7 @@
QT_BEGIN_NAMESPACE
+class QAbstractButton;
class QAction;
class QContextMenuEvent;
class QKeyEvent;
@@ -115,16 +117,68 @@ public:
FormatTextEdit *getEditor() { return m_editor; }
signals:
- void textChanged();
- void selectionChanged();
+ void textChanged(QTextEdit *);
+ void selectionChanged(QTextEdit *);
void cursorPositionChanged();
+private slots:
+ void slotSelectionChanged();
+ void slotTextChanged();
+
private:
QLabel *m_label;
FormatTextEdit *m_editor;
bool m_hideWhenEmpty;
};
+/*
+ Displays text fields & associated label
+*/
+class FormMultiWidget : public QWidget
+{
+ Q_OBJECT
+public:
+ FormMultiWidget(const QString &label, QWidget *parent = 0);
+ void setLabel(const QString &label) { m_label->setText(label); }
+ void setTranslation(const QString &text, bool userAction = false);
+ void clearTranslation() { setTranslation(QString(), false); }
+ QString getTranslation() const;
+ void setEditingEnabled(bool enable);
+ void setMultiEnabled(bool enable);
+ void setHideWhenEmpty(bool optional) { m_hideWhenEmpty = optional; }
+ const QList<FormatTextEdit *> &getEditors() const { return m_editors; }
+
+signals:
+ void editorCreated(QTextEdit *);
+ void textChanged(QTextEdit *);
+ void selectionChanged(QTextEdit *);
+ void cursorPositionChanged();
+
+protected:
+ bool eventFilter(QObject *watched, QEvent *event);
+
+private slots:
+ void slotTextChanged();
+ void slotSelectionChanged();
+ void minusButtonClicked();
+ void plusButtonClicked();
+
+private:
+ void addEditor(int idx);
+ void updateLayout();
+ QAbstractButton *makeButton(const QIcon &icon, const char *slot);
+ void insertEditor(int idx);
+ void deleteEditor(int idx);
+
+ QLabel *m_label;
+ QList<FormatTextEdit *> m_editors;
+ QList<QWidget *> m_plusButtons;
+ QList<QAbstractButton *> m_minusButtons;
+ bool m_hideWhenEmpty;
+ bool m_multiEnabled;
+ QIcon m_plusIcon, m_minusIcon;
+};
+
QT_END_NAMESPACE
#endif // MESSAGEEDITORWIDGETS_H
diff --git a/tools/linguist/linguist/phrase.cpp b/tools/linguist/linguist/phrase.cpp
index 0c21cce..463e699 100644
--- a/tools/linguist/linguist/phrase.cpp
+++ b/tools/linguist/linguist/phrase.cpp
@@ -152,10 +152,10 @@ bool QphHandler::startElement(const QString & /* namespaceURI */,
const QString &qName,
const QXmlAttributes &atts)
{
- if (qName == QString(QLatin1String("QPH"))) {
+ if (qName == QLatin1String("QPH")) {
m_language = atts.value(QLatin1String("language"));
m_sourceLanguage = atts.value(QLatin1String("sourcelanguage"));
- } else if (qName == QString(QLatin1String("phrase"))) {
+ } else if (qName == QLatin1String("phrase")) {
source.truncate(0);
target.truncate(0);
definition.truncate(0);
@@ -168,13 +168,13 @@ bool QphHandler::endElement(const QString & /* namespaceURI */,
const QString & /* localName */,
const QString &qName)
{
- if (qName == QString(QLatin1String("source")))
+ if (qName == QLatin1String("source"))
source = accum;
- else if (qName == QString(QLatin1String("target")))
+ else if (qName == QLatin1String("target"))
target = accum;
- else if (qName == QString(QLatin1String("definition")))
+ else if (qName == QLatin1String("definition"))
definition = accum;
- else if (qName == QString(QLatin1String("phrase")))
+ else if (qName == QLatin1String("phrase"))
pb->m_phrases.append(new Phrase(source, target, definition, pb));
return true;
}
diff --git a/tools/linguist/linguist/phrasebookbox.cpp b/tools/linguist/linguist/phrasebookbox.cpp
index 67d996b..9a6819b 100644
--- a/tools/linguist/linguist/phrasebookbox.cpp
+++ b/tools/linguist/linguist/phrasebookbox.cpp
@@ -56,13 +56,15 @@
QT_BEGIN_NAMESPACE
-#define NewPhrase tr("(New Entry)")
-
PhraseBookBox::PhraseBookBox(PhraseBook *phraseBook, QWidget *parent)
: QDialog(parent),
m_phraseBook(phraseBook),
m_translationSettingsDialog(0)
{
+
+// This definition needs to be within class context for lupdate to find it
+#define NewPhrase tr("(New Entry)")
+
setupUi(this);
setWindowTitle(tr("%1[*] - Qt Linguist").arg(m_phraseBook->friendlyPhraseBookName()));
setWindowModified(m_phraseBook->isModified());
diff --git a/tools/linguist/linguist/phraseview.cpp b/tools/linguist/linguist/phraseview.cpp
index 649b24d..a959b66 100644
--- a/tools/linguist/linguist/phraseview.cpp
+++ b/tools/linguist/linguist/phraseview.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "globals.h"
#include "mainwindow.h"
#include "messagemodel.h"
#include "phrase.h"
@@ -61,7 +62,7 @@ static const int MaxCandidates = 5;
static QString phraseViewHeaderKey()
{
- return settingsPrefix() + QLatin1String("PhraseViewHeader");
+ return settingPath("PhraseViewHeader");
}
PhraseView::PhraseView(MultiDataModel *model, QList<QHash<QString, QList<Phrase *> > > *phraseDict, QWidget *parent)
diff --git a/tools/linguist/linguist/recentfiles.cpp b/tools/linguist/linguist/recentfiles.cpp
index 6e13b78..0dc14a4 100644
--- a/tools/linguist/linguist/recentfiles.cpp
+++ b/tools/linguist/linguist/recentfiles.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "recentfiles.h"
+#include "globals.h"
#include <QtCore/QDebug>
#include <QtCore/QFileInfo>
@@ -49,11 +50,9 @@
QT_BEGIN_NAMESPACE
-const QString &settingsPrefix();
-
static QString configKey()
{
- return settingsPrefix() + QLatin1String("RecentlyOpenedFiles");
+ return settingPath("RecentlyOpenedFiles");
}
diff --git a/tools/linguist/lrelease/lrelease.1 b/tools/linguist/lrelease/lrelease.1
index 9e77504..8dd14b2 100644
--- a/tools/linguist/lrelease/lrelease.1
+++ b/tools/linguist/lrelease/lrelease.1
@@ -51,10 +51,10 @@ This page documents the
tool for the Qt GUI toolkit.
.B Lrelease
reads a qmake/tmake project file (.pro file) and converts the
-translation files (.ts files) specified in it into Qt message files
-(.qm files) used by the application to translate.
+translation files (TS files) specified in it into Qt message files
+(QM files) used by the application to translate.
.PP
-The .qm file format is a compact binary format that provides
+The QM file format is a compact binary format that provides
extremely fast lookups for translations and that is used by Qt.
.SH OPTIONS
.TP
@@ -62,7 +62,7 @@ extremely fast lookups for translations and that is used by Qt.
Display the usage and exit.
.TP
.I "-compress"
-Compress the .qm files.
+Compress the QM files.
.TP
.I "-nounfinished"
Do not include unfinished translations.
@@ -72,7 +72,7 @@ If the translated text is the same as
the source text, do not include the message.
.TP
.I "-silent"
-Don't explain what is being done.
+Do not explain what is being done.
.TP
.I "-version"
Display the version of
@@ -105,7 +105,7 @@ generated from gnomovision_dk.ts, gnomovision_fi.ts,
gnomovision_no.ts and gnomovision_se.ts, respectively.
.PP
.B Lrelease
-can also be invoked with a list of .ts files to convert:
+can also be invoked with a list of TS files to convert:
.PP
.in +4
.nf
diff --git a/tools/linguist/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 905a399..aeed1f2 100644
--- a/tools/linguist/lrelease/main.cpp
+++ b/tools/linguist/lrelease/main.cpp
@@ -40,7 +40,6 @@
****************************************************************************/
#include "translator.h"
-#include "translatortools.h"
#include "profileevaluator.h"
#include <QtCore/QCoreApplication>
@@ -67,19 +66,21 @@ static void printUsage()
" lrelease [options] project-file\n"
" lrelease [options] ts-files [-qm qm-file]\n\n"
"lrelease is part of Qt's Linguist tool chain. It can be used as a\n"
- "stand-alone tool to convert XML based translations files in the .ts\n"
- "format into the 'compiled' .qm format used by QTranslator objects.\n\n"
+ "stand-alone tool to convert XML-based translations files in the TS\n"
+ "format into the 'compiled' QM format used by QTranslator objects.\n\n"
"Options:\n"
" -help Display this information and exit\n"
+ " -idbased\n"
+ " Use IDs instead of source strings for message keying\n"
" -compress\n"
- " Compress the .qm files\n"
+ " Compress the QM files\n"
" -nounfinished\n"
" Do not include unfinished translations\n"
" -removeidentical\n"
" If the translated text is the same as\n"
" the source text, do not include the message\n"
" -silent\n"
- " Don't explain what is being done\n"
+ " Do not explain what is being done\n"
" -version\n"
" Display the version of lrelease and exit\n"
));
@@ -100,7 +101,7 @@ static bool loadTsFile(Translator &tor, const QString &tsFileName, bool /* verbo
static bool releaseTranslator(Translator &tor, const QString &qmFileName,
bool verbose, bool ignoreUnfinished,
- bool removeIdentical, TranslatorSaveMode mode)
+ bool removeIdentical, bool idBased, TranslatorSaveMode mode)
{
Translator::reportDuplicates(tor.resolveDuplicates(), qmFileName, verbose);
@@ -122,6 +123,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
ConversionData cd;
cd.m_verbose = verbose;
cd.m_ignoreUnfinished = ignoreUnfinished;
+ cd.m_idBased = idBased;
cd.m_saveMode = mode;
bool ok = tor.release(&file, cd);
file.close();
@@ -137,7 +139,7 @@ static bool releaseTranslator(Translator &tor, const QString &qmFileName,
}
static bool releaseTsFile(const QString& tsFileName, bool verbose,
- bool ignoreUnfinished, bool removeIdentical, TranslatorSaveMode mode)
+ bool ignoreUnfinished, bool removeIdentical, bool idBased, TranslatorSaveMode mode)
{
Translator tor;
if (!loadTsFile(tor, tsFileName, verbose))
@@ -152,7 +154,7 @@ static bool releaseTsFile(const QString& tsFileName, bool verbose,
}
qmFileName += QLatin1String(".qm");
- return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, mode);
+ return releaseTranslator(tor, qmFileName, verbose, ignoreUnfinished, removeIdentical, idBased, mode);
}
int main(int argc, char **argv)
@@ -165,6 +167,7 @@ int main(int argc, char **argv)
bool verbose = true; // the default is true starting with Qt 4.2
bool ignoreUnfinished = false;
+ bool idBased = false;
// the default mode is SaveEverything starting with Qt 4.2
TranslatorSaveMode mode = SaveEverything;
bool removeIdentical = false;
@@ -176,6 +179,9 @@ int main(int argc, char **argv)
if (args[i] == QLatin1String("-compress")) {
mode = SaveStripped;
continue;
+ } else if (args[i] == QLatin1String("-idbased")) {
+ idBased = true;
+ continue;
} else if (args[i] == QLatin1String("-nocompress")) {
mode = SaveEverything;
continue;
@@ -233,18 +239,18 @@ int main(int argc, char **argv)
qPrintable(args[i]));
} else {
foreach (const QString &trans, translations)
- if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, mode))
+ if (!releaseTsFile(trans, verbose, ignoreUnfinished, removeIdentical, idBased, mode))
return 1;
}
} else {
qWarning("error: lrelease encountered project file functionality that is currently not supported.\n"
- "You might want to consider using .ts files as input instead of a project file.\n"
+ "You might want to consider using TS files as input instead of a project file.\n"
"Try the following syntax:\n"
" lrelease [options] ts-files [-qm qm-file]\n");
}
} else {
if (outputFile.isEmpty()) {
- if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, mode))
+ if (!releaseTsFile(args[i], verbose, ignoreUnfinished, removeIdentical, idBased, mode))
return 1;
} else {
if (!loadTsFile(tor, args[i], verbose))
@@ -255,7 +261,7 @@ int main(int argc, char **argv)
if (!outputFile.isEmpty())
return releaseTranslator(tor, outputFile, verbose, ignoreUnfinished,
- removeIdentical, mode) ? 0 : 1;
+ removeIdentical, idBased, mode) ? 0 : 1;
return 0;
}
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
new file mode 100644
index 0000000..58e094b
--- /dev/null
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -0,0 +1,1919 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "lupdate.h"
+
+#include <translator.h>
+
+#include <QtCore/QDebug>
+#include <QtCore/QFileInfo>
+#include <QtCore/QStack>
+#include <QtCore/QString>
+#include <QtCore/QTextCodec>
+#include <QtCore/QTextStream>
+
+#include <ctype.h> // for isXXX()
+
+QT_BEGIN_NAMESPACE
+
+/* qmake ignore Q_OBJECT */
+
+static const char MagicComment[] = "TRANSLATOR ";
+
+#define STRINGIFY_INTERNAL(x) #x
+#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
+#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s)))
+
+//#define DIAGNOSE_RETRANSLATABILITY // FIXME: should make a runtime option of this
+
+uint qHash(const QStringList &qsl)
+{
+ uint hash = 0;
+ foreach (const QString &qs, qsl) {
+ hash ^= qHash(qs) ^ 0xa09df22f;
+ hash = (hash << 13) | (hash >> 19);
+ }
+ return hash;
+}
+
+struct Namespace {
+
+ Namespace() :
+ isClass(false),
+ hasTrFunctions(false), needsTrFunctions(false), complained(false)
+ {}
+
+ QString name;
+ QMap<QString, Namespace *> children;
+ QMap<QString, QStringList> aliases;
+ QSet<QStringList> usings;
+
+ int fileId;
+
+ bool isClass;
+
+ bool hasTrFunctions;
+ bool needsTrFunctions;
+ bool complained; // ... that tr functions are missing.
+};
+
+typedef QList<Namespace *> NamespaceList;
+
+struct ParseResults {
+
+ ParseResults()
+ {
+ static int nextFileId;
+ rootNamespace.fileId = nextFileId++;
+ tor = 0;
+ }
+ bool detachNamespace(Namespace **that);
+ Namespace *include(Namespace *that, const Namespace *other);
+ void unite(const ParseResults *other);
+
+ Namespace rootNamespace;
+ Translator *tor;
+ QSet<QString> allIncludes;
+};
+
+typedef QHash<QString, const ParseResults *> ParseResultHash;
+
+class CppFiles {
+
+public:
+ static const ParseResults *getResults(const QString &cleanFile);
+ static void setResults(const QString &cleanFile, const ParseResults *results);
+ static bool isBlacklisted(const QString &cleanFile);
+ static void setBlacklisted(const QString &cleanFile);
+
+private:
+ static ParseResultHash &parsedFiles();
+ static QSet<QString> &blacklistedFiles();
+};
+
+class CppParser {
+
+public:
+ CppParser(ParseResults *results = 0);
+ void setInput(const QString &in);
+ void setInput(QTextStream &ts, const QString &fileName);
+ void setTranslator(Translator *tor) { results->tor = tor; }
+ void parse(const QString &initialContext, ConversionData &cd, QSet<QString> &inclusions);
+ void parseInternal(ConversionData &cd, QSet<QString> &inclusions);
+ const ParseResults *getResults() const { return results; }
+ void deleteResults() { delete results; }
+
+ struct SavedState {
+ QStringList namespaces;
+ QStack<int> namespaceDepths;
+ QStringList functionContext;
+ QString functionContextUnresolved;
+ QString pendingContext;
+ };
+
+private:
+ struct IfdefState {
+ IfdefState() {}
+ IfdefState(int _braceDepth, int _parenDepth) :
+ braceDepth(_braceDepth),
+ parenDepth(_parenDepth),
+ elseLine(-1)
+ {}
+
+ SavedState state;
+ int braceDepth, braceDepth1st;
+ int parenDepth, parenDepth1st;
+ int elseLine;
+ };
+
+ uint getChar();
+ uint getToken();
+ bool match(uint t);
+ bool matchString(QString *s);
+ bool matchEncoding(bool *utf8);
+ bool matchInteger(qlonglong *number);
+ bool matchStringOrNull(QString *s);
+ bool matchExpression();
+
+ QString transcode(const QString &str, bool utf8);
+ void recordMessage(
+ int line, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural);
+
+ void processInclude(const QString &file, ConversionData &cd,
+ QSet<QString> &inclusions);
+
+ void saveState(SavedState *state);
+ void loadState(const SavedState *state);
+
+ static QString stringifyNamespace(const NamespaceList &namespaces);
+ static QStringList stringListifyNamespace(const NamespaceList &namespaces);
+ void modifyNamespace(NamespaceList *namespaces);
+ NamespaceList resolveNamespaces(const QStringList &segments);
+ bool qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment,
+ NamespaceList *resolved);
+ bool fullyQualify(const NamespaceList &namespaces, const QStringList &segments,
+ bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved);
+ void enterNamespace(NamespaceList *namespaces, const QString &name);
+ void truncateNamespaces(NamespaceList *namespaces, int lenght);
+
+ enum {
+ Tok_Eof, Tok_class, Tok_friend, Tok_namespace, Tok_using, Tok_return,
+ Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8, Tok_trid,
+ Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS,
+ Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
+ Tok_Equals,
+ Tok_LeftBrace = 30, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
+ Tok_Integer = 40,
+ Tok_QuotedInclude = 50, Tok_AngledInclude,
+ Tok_Other = 99
+ };
+
+ // Tokenizer state
+ QString yyFileName;
+ int yyCh;
+ bool yyAtNewline;
+ bool yyCodecIsUtf8;
+ bool yyForceUtf8;
+ QString yyIdent;
+ QString yyComment;
+ QString yyString;
+ qlonglong yyInteger;
+ QStack<IfdefState> yyIfdefStack;
+ int yyBraceDepth;
+ int yyParenDepth;
+ int yyLineNo;
+ int yyCurLineNo;
+ int yyBraceLineNo;
+ int yyParenLineNo;
+
+ // the string to read from and current position in the string
+ QTextCodec *yySourceCodec;
+ bool yySourceIsUnicode;
+ QString yyInStr;
+ int yyInPos;
+
+ // Parser state
+ uint yyTok;
+
+ NamespaceList namespaces;
+ QStack<int> namespaceDepths;
+ NamespaceList functionContext;
+ QString functionContextUnresolved;
+ QString prospectiveContext;
+ QString pendingContext;
+ ParseResults *results;
+ bool directInclude;
+
+ SavedState savedState;
+ int yyMinBraceDepth;
+ bool inDefine;
+};
+
+CppParser::CppParser(ParseResults *_results)
+{
+ if (_results) {
+ results = _results;
+ directInclude = true;
+ } else {
+ results = new ParseResults;
+ directInclude = false;
+ }
+ yyInPos = 0;
+ yyBraceDepth = 0;
+ yyParenDepth = 0;
+ yyCurLineNo = 1;
+ yyBraceLineNo = 1;
+ yyParenLineNo = 1;
+ yyAtNewline = true;
+ yyMinBraceDepth = 0;
+ inDefine = false;
+}
+
+void CppParser::setInput(const QString &in)
+{
+ yyInStr = in;
+ yyFileName = QString();
+ yySourceCodec = 0;
+ yySourceIsUnicode = true;
+ yyForceUtf8 = true;
+}
+
+void CppParser::setInput(QTextStream &ts, const QString &fileName)
+{
+ yyInStr = ts.readAll();
+ yyFileName = fileName;
+ yySourceCodec = ts.codec();
+ yySourceIsUnicode = yySourceCodec->name().startsWith("UTF-");
+ yyForceUtf8 = false;
+}
+
+/*
+ The first part of this source file is the C++ tokenizer. We skip
+ most of C++; the only tokens that interest us are defined here.
+ Thus, the code fragment
+
+ int main()
+ {
+ printf("Hello, world!\n");
+ return 0;
+ }
+
+ is broken down into the following tokens (Tok_ omitted):
+
+ Ident Ident LeftParen RightParen
+ LeftBrace
+ Ident LeftParen String RightParen Semicolon
+ return Semicolon
+ RightBrace.
+
+ The 0 doesn't produce any token.
+*/
+
+uint CppParser::getChar()
+{
+ forever {
+ if (yyInPos >= yyInStr.size())
+ return EOF;
+ uint c = yyInStr[yyInPos++].unicode();
+ if (c == '\\' && yyInPos < yyInStr.size()) {
+ if (yyInStr[yyInPos].unicode() == '\n') {
+ ++yyCurLineNo;
+ ++yyInPos;
+ continue;
+ }
+ if (yyInStr[yyInPos].unicode() == '\r') {
+ ++yyCurLineNo;
+ ++yyInPos;
+ if (yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n')
+ ++yyInPos;
+ continue;
+ }
+ }
+ if (c == '\r') {
+ if (yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n')
+ ++yyInPos;
+ c = '\n';
+ ++yyCurLineNo;
+ yyAtNewline = true;
+ } else if (c == '\n') {
+ ++yyCurLineNo;
+ yyAtNewline = true;
+ } else if (c != ' ' && c != '\t' && c != '#') {
+ yyAtNewline = false;
+ }
+ return c;
+ }
+}
+
+uint CppParser::getToken()
+{
+ restart:
+ yyIdent.clear();
+ yyComment.clear();
+ yyString.clear();
+
+ while (yyCh != EOF) {
+ yyLineNo = yyCurLineNo;
+
+ if (yyCh == '#' && yyAtNewline) {
+ /*
+ Early versions of lupdate complained about
+ unbalanced braces in the following code:
+
+ #ifdef ALPHA
+ while (beta) {
+ #else
+ while (gamma) {
+ #endif
+ delta;
+ }
+
+ The code contains, indeed, two opening braces for
+ one closing brace; yet there's no reason to panic.
+
+ The solution is to remember yyBraceDepth as it was
+ when #if, #ifdef or #ifndef was met, and to set
+ yyBraceDepth to that value when meeting #elif or
+ #else.
+ */
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh) && yyCh != '\n');
+
+ switch (yyCh) {
+ case 'd': // define
+ // Skip over the name of the define to avoid it being interpreted as c++ code
+ do { // Rest of "define"
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (!isspace(yyCh));
+ do { // Space beween "define" and macro name
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (isspace(yyCh));
+ do { // Macro name
+ if (yyCh == '(') {
+ // Argument list. Follows the name without a space, and no
+ // paren nesting is possible.
+ do {
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (yyCh != ')');
+ break;
+ }
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (!isspace(yyCh));
+ do { // Shortcut the immediate newline case if no comments follow.
+ yyCh = getChar();
+ if (yyCh == EOF)
+ return Tok_Eof;
+ if (yyCh == '\n')
+ goto restart;
+ } while (isspace(yyCh));
+
+ saveState(&savedState);
+ yyMinBraceDepth = yyBraceDepth;
+ inDefine = true;
+ goto restart;
+ case 'i':
+ yyCh = getChar();
+ if (yyCh == 'f') {
+ // if, ifdef, ifndef
+ yyIfdefStack.push(IfdefState(yyBraceDepth, yyParenDepth));
+ yyCh = getChar();
+ } else if (yyCh == 'n') {
+ // include
+ do {
+ yyCh = getChar();
+ } while (yyCh != EOF && !isspace(yyCh));
+ do {
+ yyCh = getChar();
+ } while (isspace(yyCh));
+ int tChar;
+ if (yyCh == '"')
+ tChar = '"';
+ else if (yyCh == '<')
+ tChar = '>';
+ else
+ break;
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF || yyCh == '\n')
+ break;
+ if (yyCh == tChar) {
+ yyCh = getChar();
+ break;
+ }
+ yyString += yyCh;
+ }
+ return (tChar == '"') ? Tok_QuotedInclude : Tok_AngledInclude;
+ }
+ break;
+ case 'e':
+ yyCh = getChar();
+ if (yyCh == 'l') {
+ // elif, else
+ if (!yyIfdefStack.isEmpty()) {
+ IfdefState &is = yyIfdefStack.top();
+ if (is.elseLine != -1) {
+ if (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);
+ } else {
+ is.braceDepth1st = yyBraceDepth;
+ is.parenDepth1st = yyParenDepth;
+ saveState(&is.state);
+ }
+ is.elseLine = yyLineNo;
+ yyBraceDepth = is.braceDepth;
+ yyParenDepth = is.parenDepth;
+ }
+ yyCh = getChar();
+ } else if (yyCh == 'n') {
+ // endif
+ if (!yyIfdefStack.isEmpty()) {
+ IfdefState is = yyIfdefStack.pop();
+ if (is.elseLine != -1) {
+ if (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);
+ yyBraceDepth = is.braceDepth1st;
+ yyParenDepth = is.parenDepth1st;
+ loadState(&is.state);
+ }
+ }
+ yyCh = getChar();
+ }
+ break;
+ }
+ // Optimization: skip over rest of preprocessor directive
+ do {
+ if (yyCh == '/') {
+ yyCh = getChar();
+ if (yyCh == '/') {
+ do {
+ yyCh = getChar();
+ } while (yyCh != EOF && yyCh != '\n');
+ break;
+ } else if (yyCh == '*') {
+ bool metAster = false;
+
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF) {
+ qWarning("%s:%d: Unterminated C++ comment\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+
+ if (yyCh == '*') {
+ metAster = true;
+ } else if (metAster && yyCh == '/') {
+ yyCh = getChar();
+ break;
+ } else {
+ metAster = false;
+ }
+ }
+ }
+ } else {
+ yyCh = getChar();
+ }
+ } while (yyCh != '\n' && yyCh != EOF);
+ yyCh = getChar();
+ } else if (isalpha(yyCh) || yyCh == '_') {
+ do {
+ yyIdent += yyCh;
+ yyCh = getChar();
+ } while (isalnum(yyCh) || yyCh == '_');
+
+ //qDebug() << "IDENT: " << yyIdent;
+
+ switch (yyIdent.at(0).unicode()) {
+ case 'Q':
+ if (yyIdent == QLatin1String("Q_OBJECT"))
+ return Tok_Q_OBJECT;
+ if (yyIdent == QLatin1String("Q_DECLARE_TR_FUNCTIONS"))
+ return Tok_Q_DECLARE_TR_FUNCTIONS;
+ if (yyIdent == QLatin1String("QT_TR_NOOP"))
+ return Tok_tr;
+ if (yyIdent == QLatin1String("QT_TRID_NOOP"))
+ return Tok_trid;
+ if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP"))
+ return Tok_translate;
+ if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3"))
+ return Tok_translate;
+ if (yyIdent == QLatin1String("QT_TR_NOOP_UTF8"))
+ return Tok_trUtf8;
+ if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP_UTF8"))
+ return Tok_translateUtf8;
+ if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3_UTF8"))
+ return Tok_translateUtf8;
+ break;
+ case 'T':
+ // TR() for when all else fails
+ if (yyIdent.compare(QLatin1String("TR"), Qt::CaseInsensitive) == 0) {
+ return Tok_tr;
+ }
+ break;
+ case 'c':
+ if (yyIdent == QLatin1String("class"))
+ return Tok_class;
+ break;
+ case 'f':
+ /*
+ QTranslator::findMessage() has the same parameters as
+ QApplication::translate().
+ */
+ if (yyIdent == QLatin1String("findMessage"))
+ return Tok_translate;
+ if (yyIdent == QLatin1String("friend"))
+ return Tok_friend;
+ break;
+ case 'n':
+ if (yyIdent == QLatin1String("namespace"))
+ return Tok_namespace;
+ break;
+ case 'q':
+ if (yyIdent == QLatin1String("qtTrId"))
+ return Tok_trid;
+ break;
+ case 'r':
+ if (yyIdent == QLatin1String("return"))
+ return Tok_return;
+ break;
+ case 's':
+ if (yyIdent == QLatin1String("struct"))
+ return Tok_class;
+ break;
+ case 't':
+ if (yyIdent == QLatin1String("tr")) {
+ return Tok_tr;
+ }
+ if (yyIdent == QLatin1String("trUtf8")) {
+ return Tok_trUtf8;
+ }
+ if (yyIdent == QLatin1String("translate")) {
+ return Tok_translate;
+ }
+ break;
+ case 'u':
+ if (yyIdent == QLatin1String("using"))
+ return Tok_using;
+ break;
+ }
+ return Tok_Ident;
+ } else {
+ switch (yyCh) {
+ case '\n':
+ if (inDefine) {
+ loadState(&savedState);
+ prospectiveContext.clear();
+ yyBraceDepth = yyMinBraceDepth;
+ yyMinBraceDepth = 0;
+ inDefine = false;
+ }
+ yyCh = getChar();
+ break;
+ case '/':
+ yyCh = getChar();
+ if (yyCh == '/') {
+ do {
+ yyCh = getChar();
+ if (yyCh == EOF)
+ break;
+ yyComment.append(yyCh);
+ } while (yyCh != '\n');
+ } else if (yyCh == '*') {
+ bool metAster = false;
+
+ forever {
+ yyCh = getChar();
+ if (yyCh == EOF) {
+ qWarning("%s:%d: Unterminated C++ comment\n",
+ qPrintable(yyFileName), yyLineNo);
+ return Tok_Comment;
+ }
+ yyComment.append(yyCh);
+
+ if (yyCh == '*')
+ metAster = true;
+ else if (metAster && yyCh == '/')
+ break;
+ else
+ metAster = false;
+ }
+ yyCh = getChar();
+ yyComment.chop(2);
+ }
+ return Tok_Comment;
+ case '"':
+ yyCh = getChar();
+ while (yyCh != EOF && yyCh != '\n' && yyCh != '"') {
+ if (yyCh == '\\') {
+ yyCh = getChar();
+ if (yyCh == EOF || yyCh == '\n')
+ break;
+ yyString.append(QLatin1Char('\\'));
+ }
+ yyString.append(yyCh);
+ yyCh = getChar();
+ }
+
+ if (yyCh != '"')
+ qWarning("%s:%d: Unterminated C++ string\n",
+ qPrintable(yyFileName), yyLineNo);
+ else
+ yyCh = getChar();
+ return Tok_String;
+ case '-':
+ yyCh = getChar();
+ if (yyCh == '>') {
+ yyCh = getChar();
+ return Tok_Arrow;
+ }
+ break;
+ case ':':
+ yyCh = getChar();
+ if (yyCh == ':') {
+ yyCh = getChar();
+ return Tok_ColonColon;
+ }
+ return Tok_Colon;
+ // Incomplete: '<' might be part of '<=' or of template syntax.
+ // The main intent of not completely ignoring it is to break
+ // parsing of things like std::cout << QObject::tr() as
+ // context std::cout::QObject (see Task 161106)
+ case '=':
+ yyCh = getChar();
+ return Tok_Equals;
+ case '>':
+ case '<':
+ yyCh = getChar();
+ return Tok_Other;
+ case '\'':
+ yyCh = getChar();
+ if (yyCh == '\\')
+ yyCh = getChar();
+
+ forever {
+ if (yyCh == EOF || yyCh == '\n') {
+ qWarning("%s:%d: Unterminated C++ character\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ yyCh = getChar();
+ if (yyCh == '\'') {
+ yyCh = getChar();
+ break;
+ }
+ }
+ break;
+ case '{':
+ if (yyBraceDepth == 0)
+ yyBraceLineNo = yyCurLineNo;
+ yyBraceDepth++;
+ yyCh = getChar();
+ return Tok_LeftBrace;
+ 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);
+ // Avoid things getting messed up even more
+ yyCh = getChar();
+ return Tok_Semicolon;
+ }
+ yyBraceDepth--;
+ yyCh = getChar();
+ return Tok_RightBrace;
+ case '(':
+ if (yyParenDepth == 0)
+ yyParenLineNo = yyCurLineNo;
+ yyParenDepth++;
+ yyCh = getChar();
+ 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);
+ else
+ yyParenDepth--;
+ yyCh = getChar();
+ return Tok_RightParen;
+ case ',':
+ yyCh = getChar();
+ return Tok_Comma;
+ case ';':
+ yyCh = getChar();
+ return Tok_Semicolon;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ {
+ QByteArray ba;
+ ba += yyCh;
+ yyCh = getChar();
+ bool hex = yyCh == 'x';
+ if (hex) {
+ ba += yyCh;
+ yyCh = getChar();
+ }
+ while (hex ? isxdigit(yyCh) : isdigit(yyCh)) {
+ ba += yyCh;
+ yyCh = getChar();
+ }
+ bool ok;
+ yyInteger = ba.toLongLong(&ok);
+ if (ok)
+ return Tok_Integer;
+ break;
+ }
+ default:
+ yyCh = getChar();
+ break;
+ }
+ }
+ }
+ return Tok_Eof;
+}
+
+/*
+ The second part of this source file are namespace/class related
+ utilities for the third part.
+*/
+
+void CppParser::saveState(SavedState *state)
+{
+ state->namespaces = stringListifyNamespace(namespaces);
+ state->namespaceDepths = namespaceDepths;
+ state->functionContext = stringListifyNamespace(functionContext);
+ state->functionContextUnresolved = functionContextUnresolved;
+ state->pendingContext = pendingContext;
+}
+
+void CppParser::loadState(const SavedState *state)
+{
+ namespaces = resolveNamespaces(state->namespaces);
+ namespaceDepths = state->namespaceDepths;
+ functionContext = resolveNamespaces(state->functionContext);
+ functionContextUnresolved = state->functionContextUnresolved;
+ pendingContext = state->pendingContext;
+}
+
+bool ParseResults::detachNamespace(Namespace **that)
+{
+ if ((*that)->fileId != rootNamespace.fileId) {
+ Namespace *newThat = new Namespace;
+ *newThat = **that;
+ newThat->fileId = rootNamespace.fileId;
+ *that = newThat;
+ return true;
+ }
+ return false;
+}
+
+Namespace *ParseResults::include(Namespace *that, const Namespace *other)
+{
+ Namespace *origThat = that;
+ foreach (Namespace *otherSub, other->children) {
+ if (Namespace *thisSub = that->children.value(otherSub->name)) {
+ // Don't make these cause a detach - it's best
+ // (though not necessary) if they are shared
+ thisSub->isClass |= otherSub->isClass;
+ thisSub->hasTrFunctions |= otherSub->hasTrFunctions;
+ thisSub->needsTrFunctions |= otherSub->needsTrFunctions;
+ thisSub->complained |= otherSub->complained;
+
+ if (Namespace *newSub = include(thisSub, otherSub)) {
+ thisSub = newSub;
+ detachNamespace(&that);
+ that->children[thisSub->name] = thisSub;
+ }
+ } else {
+ detachNamespace(&that);
+ that->children[otherSub->name] = otherSub;
+ }
+ }
+ if ((that->aliases != other->aliases && !other->aliases.isEmpty())
+ || (that->usings != other->usings && !other->usings.isEmpty())) {
+ detachNamespace(&that);
+ that->aliases.unite(other->aliases);
+ that->usings.unite(other->usings);
+ }
+ return (that != origThat) ? that : 0;
+}
+
+void ParseResults::unite(const ParseResults *other)
+{
+ allIncludes.unite(other->allIncludes);
+ include(&rootNamespace, &other->rootNamespace);
+}
+
+void CppParser::modifyNamespace(NamespaceList *namespaces)
+{
+ Namespace *pns = 0;
+ int i = namespaces->count();
+ forever {
+ --i;
+ Namespace *ns = namespaces->at(i);
+ bool detached = results->detachNamespace(&ns);
+ if (pns)
+ ns->children[pns->name] = pns;
+ if (!detached) // Known to be true for root namespace
+ return;
+ pns = ns;
+ namespaces->replace(i, ns);
+ }
+}
+
+QString CppParser::stringifyNamespace(const NamespaceList &namespaces)
+{
+ QString ret;
+ for (int i = 1; i < namespaces.count(); ++i) {
+ if (i > 1)
+ ret += QLatin1String("::");
+ ret += namespaces.at(i)->name;
+ }
+ return ret;
+}
+
+QStringList CppParser::stringListifyNamespace(const NamespaceList &namespaces)
+{
+ QStringList ret;
+ for (int i = 1; i < namespaces.count(); ++i)
+ ret << namespaces.at(i)->name;
+ return ret;
+}
+
+// This function is called only with known-existing namespaces
+NamespaceList CppParser::resolveNamespaces(const QStringList &segments)
+{
+ NamespaceList ret;
+ Namespace *ns = &results->rootNamespace;
+ ret << ns;
+ foreach (const QString &seg, segments) {
+ ns = ns->children.value(seg);
+ ret << ns;
+ }
+ return ret;
+}
+
+bool CppParser::qualifyOne(const NamespaceList &namespaces, int nsIdx, const QString &segment,
+ NamespaceList *resolved)
+{
+ const Namespace *ns = namespaces.at(nsIdx);
+ QMap<QString, Namespace *>::ConstIterator cnsi = ns->children.constFind(segment);
+ if (cnsi != ns->children.constEnd()) {
+ *resolved = namespaces.mid(0, nsIdx + 1);
+ *resolved << *cnsi;
+ return true;
+ }
+ QMap<QString, QStringList>::ConstIterator nsai = ns->aliases.constFind(segment);
+ if (nsai != ns->aliases.constEnd()) {
+ *resolved = resolveNamespaces(*nsai);
+ return true;
+ }
+ foreach (const QStringList &use, ns->usings) {
+ NamespaceList usedNs = resolveNamespaces(use);
+ if (qualifyOne(usedNs, usedNs.count() - 1, segment, resolved))
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::fullyQualify(const NamespaceList &namespaces, const QStringList &segments,
+ bool isDeclaration,
+ NamespaceList *resolved, QStringList *unresolved)
+{
+ int nsIdx;
+ int initSegIdx;
+
+ if (segments.first().isEmpty()) {
+ // fully qualified
+ if (segments.count() == 1) {
+ resolved->clear();
+ *resolved << &results->rootNamespace;
+ return true;
+ }
+ initSegIdx = 1;
+ nsIdx = 0;
+ } else {
+ initSegIdx = 0;
+ nsIdx = namespaces.count() - 1;
+ }
+
+ do {
+ if (qualifyOne(namespaces, nsIdx, segments[initSegIdx], resolved)) {
+ int segIdx = initSegIdx;
+ while (++segIdx < segments.count()) {
+ if (!qualifyOne(*resolved, resolved->count() - 1, segments[segIdx], resolved)) {
+ if (unresolved)
+ *unresolved = segments.mid(segIdx);
+ return false;
+ }
+ }
+ return true;
+ }
+ } while (!isDeclaration && --nsIdx >= 0);
+ resolved->clear();
+ *resolved << &results->rootNamespace;
+ if (unresolved)
+ *unresolved = segments.mid(initSegIdx);
+ return false;
+}
+
+void CppParser::enterNamespace(NamespaceList *namespaces, const QString &name)
+{
+ Namespace *ns = namespaces->last()->children.value(name);
+ if (!ns) {
+ ns = new Namespace;
+ ns->fileId = results->rootNamespace.fileId;
+ ns->name = name;
+ modifyNamespace(namespaces);
+ namespaces->last()->children[name] = ns;
+ }
+ *namespaces << ns;
+}
+
+void CppParser::truncateNamespaces(NamespaceList *namespaces, int length)
+{
+ if (namespaces->count() > length)
+ namespaces->erase(namespaces->begin() + length, namespaces->end());
+}
+
+/*
+ Functions for processing include files.
+*/
+
+ParseResultHash &CppFiles::parsedFiles()
+{
+ static ParseResultHash parsed;
+
+ return parsed;
+}
+
+QSet<QString> &CppFiles::blacklistedFiles()
+{
+ static QSet<QString> blacklisted;
+
+ return blacklisted;
+}
+
+const ParseResults *CppFiles::getResults(const QString &cleanFile)
+{
+ ParseResultHash::ConstIterator it = parsedFiles().find(cleanFile);
+ if (it == parsedFiles().constEnd())
+ return 0;
+ return *it;
+}
+
+void CppFiles::setResults(const QString &cleanFile, const ParseResults *results)
+{
+ parsedFiles().insert(cleanFile, results);
+}
+
+bool CppFiles::isBlacklisted(const QString &cleanFile)
+{
+ return blacklistedFiles().contains(cleanFile);
+}
+
+void CppFiles::setBlacklisted(const QString &cleanFile)
+{
+ blacklistedFiles().insert(cleanFile);
+}
+
+void CppParser::processInclude(const QString &file, ConversionData &cd,
+ QSet<QString> &inclusions)
+{
+ QString cleanFile = QDir::cleanPath(file);
+
+ if (inclusions.contains(cleanFile)) {
+ qWarning("%s:%d: circular inclusion of %s\n",
+ qPrintable(yyFileName), yyLineNo, qPrintable(cleanFile));
+ return;
+ }
+
+ // If the #include is in any kind of namespace, has been blacklisted previously,
+ // or is not a header file (stdc++ extensionless or *.h*), then really include
+ // it. Otherwise it is safe to process it stand-alone and re-use the parsed
+ // namespace data for inclusion into other files.
+ bool isIndirect = false;
+ if (namespaces.count() == 1 && functionContext.count() == 1
+ && functionContextUnresolved.isEmpty() && pendingContext.isEmpty()
+ && !CppFiles::isBlacklisted(cleanFile)) {
+ QString fileExt = QFileInfo(cleanFile).suffix();
+ if (fileExt.isEmpty() || fileExt.startsWith(QLatin1Char('h'), Qt::CaseInsensitive)) {
+
+ if (results->allIncludes.contains(cleanFile))
+ return;
+ results->allIncludes.insert(cleanFile);
+
+ if (const ParseResults *res = CppFiles::getResults(cleanFile)) {
+ results->unite(res);
+ return;
+ }
+
+ isIndirect = true;
+ }
+ }
+
+ QFile f(cleanFile);
+ if (!f.open(QIODevice::ReadOnly)) {
+ qWarning("%s:%d: Cannot open %s: %s\n",
+ qPrintable(yyFileName), yyLineNo,
+ qPrintable(cleanFile), qPrintable(f.errorString()));
+ return;
+ }
+
+ QTextStream ts(&f);
+ ts.setCodec(yySourceCodec);
+ ts.setAutoDetectUnicode(true);
+
+ inclusions.insert(cleanFile);
+ if (isIndirect) {
+ CppParser parser;
+ foreach (const QString &projectRoot, cd.m_projectRoots)
+ if (cleanFile.startsWith(projectRoot)) {
+ parser.setTranslator(new Translator);
+ break;
+ }
+ parser.setInput(ts, cleanFile);
+ parser.parse(cd.m_defaultContext, cd, inclusions);
+ CppFiles::setResults(cleanFile, parser.getResults());
+ results->unite(parser.results);
+ } else {
+ CppParser parser(results);
+ parser.namespaces = namespaces;
+ parser.functionContext = functionContext;
+ parser.functionContextUnresolved = functionContextUnresolved;
+ parser.pendingContext = pendingContext;
+ parser.setInput(ts, cleanFile);
+ parser.parseInternal(cd, inclusions);
+ // Don't wreak havoc if not enough braces were found.
+ truncateNamespaces(&parser.namespaces, namespaces.count());
+ truncateNamespaces(&parser.functionContext, functionContext.count());
+ // Copy them back - the pointers might have changed.
+ namespaces = parser.namespaces;
+ functionContext = parser.functionContext;
+ // Avoid that messages obtained by direct scanning are used
+ CppFiles::setBlacklisted(cleanFile);
+ }
+ inclusions.remove(cleanFile);
+}
+
+/*
+ The third part of this source file is the parser. It accomplishes
+ a very easy task: It finds all strings inside a tr() or translate()
+ call, and possibly finds out the context of the call. It supports
+ three cases: (1) the context is specified, as in
+ FunnyDialog::tr("Hello") or translate("FunnyDialog", "Hello");
+ (2) the call appears within an inlined function; (3) the call
+ appears within a function defined outside the class definition.
+*/
+
+bool CppParser::match(uint t)
+{
+ bool matches = (yyTok == t);
+ if (matches)
+ yyTok = getToken();
+ return matches;
+}
+
+bool CppParser::matchString(QString *s)
+{
+ bool matches = (yyTok == Tok_String);
+ s->clear();
+ while (yyTok == Tok_String) {
+ *s += yyString;
+ do {
+ yyTok = getToken();
+ } while (yyTok == Tok_Comment);
+ }
+ return matches;
+}
+
+bool CppParser::matchEncoding(bool *utf8)
+{
+ STRING(QApplication);
+ STRING(QCoreApplication);
+ STRING(UnicodeUTF8);
+ STRING(DefaultCodec);
+ STRING(CodecForTr);
+
+ if (yyTok != Tok_Ident)
+ return false;
+ if (yyIdent == strQApplication || yyIdent == strQCoreApplication) {
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ yyTok = getToken();
+ }
+ if (yyIdent == strUnicodeUTF8) {
+ *utf8 = true;
+ yyTok = getToken();
+ return true;
+ }
+ if (yyIdent == strDefaultCodec || yyIdent == strCodecForTr) {
+ *utf8 = false;
+ yyTok = getToken();
+ return true;
+ }
+ return false;
+}
+
+bool CppParser::matchInteger(qlonglong *number)
+{
+ bool matches = (yyTok == Tok_Integer);
+ if (matches) {
+ yyTok = getToken();
+ *number = yyInteger;
+ }
+ return matches;
+}
+
+bool CppParser::matchStringOrNull(QString *s)
+{
+ bool matches = matchString(s);
+ qlonglong num = 0;
+ if (!matches)
+ matches = matchInteger(&num);
+ return matches && num == 0;
+}
+
+/*
+ * match any expression that can return a number, which can be
+ * 1. Literal number (e.g. '11')
+ * 2. simple identifier (e.g. 'm_count')
+ * 3. simple function call (e.g. 'size()' )
+ * 4. function call on an object (e.g. 'list.size()')
+ * 5. function call on an object (e.g. 'list->size()')
+ *
+ * Other cases:
+ * size(2,4)
+ * list().size()
+ * list(a,b).size(2,4)
+ * etc...
+ */
+bool CppParser::matchExpression()
+{
+ if (match(Tok_Integer))
+ return true;
+
+ int parenlevel = 0;
+ while (match(Tok_Ident) || parenlevel > 0) {
+ if (yyTok == Tok_RightParen) {
+ if (parenlevel == 0) break;
+ --parenlevel;
+ yyTok = getToken();
+ } else if (yyTok == Tok_LeftParen) {
+ yyTok = getToken();
+ if (yyTok == Tok_RightParen) {
+ yyTok = getToken();
+ } else {
+ ++parenlevel;
+ }
+ } else if (yyTok == Tok_Ident) {
+ continue;
+ } else if (yyTok == Tok_Arrow) {
+ yyTok = getToken();
+ } else if (parenlevel == 0) {
+ return false;
+ }
+ }
+ return true;
+}
+
+QString CppParser::transcode(const QString &str, bool utf8)
+{
+ static const char tab[] = "abfnrtv";
+ static const char backTab[] = "\a\b\f\n\r\t\v";
+ const QString in = (!utf8 || yySourceIsUnicode)
+ ? str : QString::fromUtf8(yySourceCodec->fromUnicode(str).data());
+ QString out;
+
+ out.reserve(in.length());
+ for (int i = 0; i < in.length();) {
+ ushort c = in[i++].unicode();
+ if (c == '\\') {
+ if (i >= in.length())
+ break;
+ c = in[i++].unicode();
+
+ if (c == '\n')
+ continue;
+
+ if (c == 'x') {
+ QByteArray hex;
+ while (i < in.length() && isxdigit((c = in[i].unicode()))) {
+ hex += c;
+ i++;
+ }
+ out += hex.toUInt(0, 16);
+ } else if (c >= '0' && c < '8') {
+ QByteArray oct;
+ int n = 0;
+ oct += c;
+ while (n < 2 && i < in.length() && (c = in[i].unicode()) >= '0' && c < '8') {
+ i++;
+ n++;
+ oct += c;
+ }
+ out += oct.toUInt(0, 8);
+ } else {
+ const char *p = strchr(tab, c);
+ out += QChar(QLatin1Char(!p ? c : backTab[p - tab]));
+ }
+ } else {
+ out += c;
+ }
+ }
+ return out;
+}
+
+void CppParser::recordMessage(
+ int line, const QString &context, const QString &text, const QString &comment,
+ const QString &extracomment, const QString &msgid, const TranslatorMessage::ExtraData &extra,
+ bool utf8, bool plural)
+{
+ TranslatorMessage msg(
+ transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(),
+ yyFileName, line, QStringList(),
+ TranslatorMessage::Unfinished, plural);
+ msg.setExtraComment(transcode(extracomment.simplified(), utf8));
+ msg.setId(msgid);
+ msg.setExtras(extra);
+ if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit())
+ msg.setUtf8(true);
+ results->tor->append(msg);
+}
+
+void CppParser::parse(const QString &initialContext, ConversionData &cd,
+ QSet<QString> &inclusions)
+{
+ if (results->tor)
+ yyCodecIsUtf8 = (results->tor->codecName() == "UTF-8");
+
+ namespaces << &results->rootNamespace;
+ functionContext = namespaces;
+ functionContextUnresolved = initialContext;
+
+ parseInternal(cd, inclusions);
+}
+
+void CppParser::parseInternal(ConversionData &cd, QSet<QString> &inclusions)
+{
+ static QString strColons(QLatin1String("::"));
+
+ QString context;
+ QString text;
+ QString comment;
+ QString extracomment;
+ QString msgid;
+ QString sourcetext;
+ TranslatorMessage::ExtraData extra;
+ QString prefix;
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ QString functionName;
+#endif
+ int line;
+ bool utf8;
+ bool yyTokColonSeen = false; // Start of c'tor's initializer list
+
+ yyCh = getChar();
+ yyTok = getToken();
+ while (yyTok != Tok_Eof) {
+ //qDebug() << "TOKEN: " << yyTok;
+ switch (yyTok) {
+ case Tok_QuotedInclude: {
+ text = QDir(QFileInfo(yyFileName).absolutePath()).absoluteFilePath(yyString);
+ if (QFileInfo(text).isFile()) {
+ processInclude(text, cd, inclusions);
+ yyTok = getToken();
+ break;
+ }
+ }
+ /* fall through */
+ case Tok_AngledInclude: {
+ QStringList cSources = cd.m_allCSources.values(yyString);
+ if (!cSources.isEmpty()) {
+ foreach (const QString &cSource, cSources)
+ processInclude(cSource, cd, inclusions);
+ goto incOk;
+ }
+ foreach (const QString &incPath, cd.m_includePath) {
+ text = QDir(incPath).absoluteFilePath(yyString);
+ if (QFileInfo(text).isFile()) {
+ processInclude(text, cd, inclusions);
+ goto incOk;
+ }
+ }
+ incOk:
+ yyTok = getToken();
+ break;
+ }
+ case Tok_friend:
+ yyTok = getToken();
+ // Ensure that these don't end up being interpreted as forward declarations
+ // (they are forwards, but with different namespacing).
+ if (yyTok == Tok_class)
+ yyTok = getToken();
+ break;
+ case Tok_class:
+ yyTokColonSeen = false;
+ /*
+ Partial support for inlined functions.
+ */
+ yyTok = getToken();
+ if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0) {
+ QStringList fct;
+ do {
+ /*
+ This code should execute only once, but we play
+ safe with impure definitions such as
+ 'class Q_EXPORT QMessageBox', in which case
+ 'QMessageBox' is the class name, not 'Q_EXPORT'.
+ */
+ fct = QStringList(yyIdent);
+ yyTok = getToken();
+ } while (yyTok == Tok_Ident);
+ while (yyTok == Tok_ColonColon) {
+ yyTok = getToken();
+ if (yyTok != Tok_Ident)
+ break; // Oops ...
+ fct += yyIdent;
+ yyTok = getToken();
+ }
+ if (fct.count() > 1) {
+ // Forward-declared class definitions can be namespaced
+ NamespaceList nsl;
+ if (!fullyQualify(namespaces, fct, true, &nsl, 0)) {
+ qWarning("%s:%d: Ignoring definition of undeclared qualified class\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ namespaceDepths.push(namespaces.count());
+ namespaces = nsl;
+ } else {
+ namespaceDepths.push(namespaces.count());
+ enterNamespace(&namespaces, fct.first());
+ }
+ namespaces.last()->isClass = true;
+
+ while (yyTok == Tok_Comment)
+ yyTok = getToken();
+ if (yyTok == Tok_Colon) {
+ // Skip any token until '{' since lupdate might do things wrong if it finds
+ // a '::' token here.
+ do {
+ yyTok = getToken();
+ } while (yyTok != Tok_LeftBrace && yyTok != Tok_Eof);
+ } else {
+ if (yyTok != Tok_LeftBrace) {
+ // Obviously a forward decl
+ truncateNamespaces(&namespaces, namespaceDepths.pop());
+ break;
+ }
+ }
+
+ functionContext = namespaces;
+ functionContextUnresolved.clear(); // Pointless
+ prospectiveContext.clear();
+ pendingContext.clear();
+ }
+ break;
+ case Tok_namespace:
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ if (yyTok == Tok_Ident) {
+ QString ns = yyIdent;
+ yyTok = getToken();
+ if (yyTok == Tok_LeftBrace) {
+ namespaceDepths.push(namespaces.count());
+ enterNamespace(&namespaces, ns);
+ yyTok = getToken();
+ } else if (yyTok == Tok_Equals) {
+ // e.g. namespace Is = OuterSpace::InnerSpace;
+ QStringList fullName;
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ fullName.append(QString());
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident)
+ fullName.append(yyIdent);
+ yyTok = getToken();
+ }
+ if (fullName.isEmpty())
+ break;
+ NamespaceList nsl;
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0)) {
+ modifyNamespace(&namespaces);
+ namespaces.last()->aliases.insert(ns, stringListifyNamespace(nsl));
+ }
+ }
+ } else if (yyTok == Tok_LeftBrace) {
+ // Anonymous namespace
+ namespaceDepths.push(namespaces.count());
+ yyTok = getToken();
+ }
+ break;
+ case Tok_using:
+ yyTok = getToken();
+ if (yyTok == Tok_namespace) {
+ QStringList fullName;
+ yyTok = getToken();
+ if (yyTok == Tok_ColonColon)
+ fullName.append(QString());
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident)
+ fullName.append(yyIdent);
+ yyTok = getToken();
+ }
+ NamespaceList nsl;
+ QStringList unresolved;
+ if (fullyQualify(namespaces, fullName, false, &nsl, &unresolved)) {
+ modifyNamespace(&namespaces);
+ namespaces.last()->usings.insert(stringListifyNamespace(nsl));
+ }
+ } else {
+ QStringList fullName;
+ if (yyTok == Tok_ColonColon)
+ fullName.append(QString());
+ while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
+ if (yyTok == Tok_Ident)
+ fullName.append(yyIdent);
+ yyTok = getToken();
+ }
+ if (fullName.isEmpty())
+ break;
+ NamespaceList nsl;
+ if (fullyQualify(namespaces, fullName, false, &nsl, 0)) {
+ modifyNamespace(&namespaces);
+ namespaces.last()->aliases.insert(nsl.last()->name, stringListifyNamespace(nsl));
+ }
+ }
+ break;
+ case Tok_tr:
+ case Tok_trUtf8:
+ if (!results->tor)
+ goto case_default;
+ if (!sourcetext.isEmpty())
+ qWarning("%s:%d: //%% cannot be used with tr() / QT_TR_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
+ utf8 = (yyTok == Tok_trUtf8);
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen) && matchString(&text) && !text.isEmpty()) {
+ comment.clear();
+ bool plural = false;
+
+ if (match(Tok_RightParen)) {
+ // no comment
+ } else if (match(Tok_Comma) && matchStringOrNull(&comment)) { //comment
+ if (match(Tok_RightParen)) {
+ // ok,
+ } else if (match(Tok_Comma)) {
+ plural = true;
+ }
+ }
+ if (!pendingContext.isEmpty()) {
+ QStringList unresolved;
+ if (!fullyQualify(namespaces, pendingContext.split(strColons), 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()));
+ }
+ pendingContext.clear();
+ }
+ if (prefix.isEmpty()) {
+ if (functionContextUnresolved.isEmpty()) {
+ int idx = functionContext.length();
+ if (idx < 2) {
+ qWarning("%s:%d: tr() cannot be called without context\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ while (!functionContext.at(idx - 1)->hasTrFunctions) {
+ if (idx == 1 || !functionContext.at(idx - 2)->isClass) {
+ idx = functionContext.length();
+ if (!functionContext.last()->complained) {
+ qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
+ qPrintable(yyFileName), yyLineNo,
+ qPrintable(stringifyNamespace(functionContext)));
+ functionContext.last()->complained = true;
+ }
+ break;
+ }
+ --idx;
+ }
+ context.clear();
+ for (int i = 1;;) {
+ context += functionContext.at(i)->name;
+ if (++i == idx)
+ break;
+ context += strColons;
+ }
+ } else {
+ context = (stringListifyNamespace(functionContext)
+ << functionContextUnresolved).join(strColons);
+ }
+ } else {
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ 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());
+ }
+#endif
+ prefix.chop(2);
+ NamespaceList nsl;
+ QStringList unresolved;
+ if (fullyQualify(functionContext, prefix.split(strColons), false, &nsl, &unresolved)) {
+ if (!nsl.last()->hasTrFunctions && !nsl.last()->complained) {
+ qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
+ qPrintable(yyFileName), yyLineNo,
+ qPrintable(stringifyNamespace(nsl)));
+ nsl.last()->complained = true;
+ }
+ context = stringifyNamespace(nsl);
+ } else {
+ context = (stringListifyNamespace(nsl) + unresolved).join(strColons);
+ }
+ prefix.clear();
+ }
+
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
+ }
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_translateUtf8:
+ case Tok_translate:
+ if (!results->tor)
+ goto case_default;
+ if (!sourcetext.isEmpty())
+ qWarning("%s:%d: //%% cannot be used with translate() / QT_TRANSLATE_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
+ utf8 = (yyTok == Tok_translateUtf8);
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen)
+ && matchString(&context)
+ && match(Tok_Comma)
+ && matchString(&text) && !text.isEmpty())
+ {
+ comment.clear();
+ bool plural = false;
+ if (!match(Tok_RightParen)) {
+ // look for comment
+ if (match(Tok_Comma) && matchStringOrNull(&comment)) {
+ if (!match(Tok_RightParen)) {
+ // look for encoding
+ if (match(Tok_Comma)) {
+ if (matchEncoding(&utf8)) {
+ if (!match(Tok_RightParen)) {
+ // look for the plural quantifier,
+ // this can be a number, an identifier or
+ // a function call,
+ // so for simplicity we mark it as plural if
+ // we know we have a comma instead of an
+ // right parentheses.
+ plural = match(Tok_Comma);
+ }
+ } else {
+ // This can be a QTranslator::translate("context",
+ // "source", "comment", n) plural translation
+ if (matchExpression() && match(Tok_RightParen)) {
+ plural = true;
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ } else {
+ break;
+ }
+ }
+ recordMessage(line, context, text, comment, extracomment, msgid, extra, utf8, plural);
+ }
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_trid:
+ if (!results->tor)
+ goto case_default;
+ if (!sourcetext.isEmpty()) {
+ if (!msgid.isEmpty())
+ qWarning("%s:%d: //= cannot be used with qtTrId() / QT_TRID_NOOP(). Ignoring\n",
+ qPrintable(yyFileName), yyLineNo);
+ //utf8 = false; // Maybe use //%% or something like that
+ line = yyLineNo;
+ yyTok = getToken();
+ if (match(Tok_LeftParen) && matchString(&msgid) && !msgid.isEmpty()) {
+ bool plural = match(Tok_Comma);
+ recordMessage(line, QString(), sourcetext, QString(), extracomment,
+ msgid, extra, false, plural);
+ }
+ sourcetext.clear();
+ }
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ break;
+ case Tok_Q_DECLARE_TR_FUNCTIONS:
+ case Tok_Q_OBJECT:
+ namespaces.last()->hasTrFunctions = true;
+ yyTok = getToken();
+ break;
+ case Tok_Ident:
+ prefix += yyIdent;
+ yyTok = getToken();
+ if (yyTok != Tok_ColonColon) {
+ prefix.clear();
+ if (yyTok == Tok_Ident && !yyParenDepth)
+ prospectiveContext.clear();
+ }
+ break;
+ case Tok_Comment:
+ if (!results->tor)
+ goto case_default;
+ if (yyComment.startsWith(QLatin1Char(':'))) {
+ yyComment.remove(0, 1);
+ extracomment.append(yyComment);
+ } else if (yyComment.startsWith(QLatin1Char('='))) {
+ yyComment.remove(0, 1);
+ msgid = yyComment.simplified();
+ } else if (yyComment.startsWith(QLatin1Char('~'))) {
+ yyComment.remove(0, 1);
+ yyComment = yyComment.trimmed();
+ int k = yyComment.indexOf(QLatin1Char(' '));
+ if (k > -1)
+ extra.insert(yyComment.left(k), yyComment.mid(k + 1).trimmed());
+ } else if (yyComment.startsWith(QLatin1Char('%'))) {
+ int p = 1, c;
+ forever {
+ if (p >= yyComment.length())
+ break;
+ c = yyComment.unicode()[p++].unicode();
+ if (isspace(c))
+ continue;
+ if (c != '"') {
+ qWarning("%s:%d: Unexpected character in meta string\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ forever {
+ if (p >= yyComment.length()) {
+ whoops:
+ qWarning("%s:%d: Unterminated meta string\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ }
+ c = yyComment.unicode()[p++].unicode();
+ if (c == '"')
+ break;
+ if (c == '\\') {
+ if (p >= yyComment.length())
+ goto whoops;
+ c = yyComment.unicode()[p++].unicode();
+ if (c == '\n')
+ goto whoops;
+ sourcetext.append(QLatin1Char('\\'));
+ }
+ sourcetext.append(c);
+ }
+ }
+ } else {
+ comment = yyComment.simplified();
+ if (comment.startsWith(QLatin1String(MagicComment))) {
+ comment.remove(0, sizeof(MagicComment) - 1);
+ int k = comment.indexOf(QLatin1Char(' '));
+ if (k == -1) {
+ context = comment;
+ } else {
+ context = comment.left(k);
+ comment.remove(0, k + 1);
+ recordMessage(yyLineNo, context, QString(), comment, extracomment,
+ QString(), TranslatorMessage::ExtraData(), false, false);
+ extracomment.clear();
+ results->tor->setExtras(extra);
+ extra.clear();
+ }
+ }
+ }
+ yyTok = getToken();
+ break;
+ case Tok_Arrow:
+ yyTok = getToken();
+ if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
+ qWarning("%s:%d: Cannot invoke tr() like this\n",
+ qPrintable(yyFileName), yyLineNo);
+ break;
+ case Tok_ColonColon:
+ if (yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0 && !yyTokColonSeen)
+ prospectiveContext = prefix;
+ prefix += strColons;
+ yyTok = getToken();
+#ifdef DIAGNOSE_RETRANSLATABILITY
+ if (yyTok == Tok_Ident && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0)
+ functionName = yyIdent;
+#endif
+ break;
+ case Tok_RightBrace:
+ if (yyBraceDepth + 1 == namespaceDepths.count()) {
+ // class or namespace
+ Namespace *ns = namespaces.last();
+ if (ns->needsTrFunctions && !ns->hasTrFunctions && !ns->complained) {
+ qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro\n",
+ qPrintable(yyFileName), yyLineNo,
+ qPrintable(stringifyNamespace(namespaces)));
+ ns->complained = true;
+ }
+ truncateNamespaces(&namespaces, namespaceDepths.pop());
+ }
+ if (yyBraceDepth == namespaceDepths.count()) {
+ // function, class or namespace
+ if (!yyBraceDepth && !directInclude) {
+ truncateNamespaces(&functionContext, 1);
+ functionContextUnresolved = cd.m_defaultContext;
+ } else {
+ functionContext = namespaces;
+ functionContextUnresolved.clear();
+ }
+ pendingContext.clear();
+ }
+ // fallthrough
+ case Tok_Semicolon:
+ prospectiveContext.clear();
+ prefix.clear();
+ extracomment.clear();
+ msgid.clear();
+ extra.clear();
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ break;
+ case Tok_Colon:
+ if (!prospectiveContext.isEmpty()
+ && yyBraceDepth == namespaceDepths.count() && yyParenDepth == 0)
+ pendingContext = prospectiveContext;
+ yyTokColonSeen = true;
+ yyTok = getToken();
+ break;
+ case Tok_LeftBrace:
+ if (!prospectiveContext.isEmpty()
+ && yyBraceDepth == namespaceDepths.count() + 1 && yyParenDepth == 0)
+ pendingContext = prospectiveContext;
+ // fallthrough
+ case Tok_LeftParen:
+ case Tok_RightParen:
+ yyTokColonSeen = false;
+ yyTok = getToken();
+ break;
+ default:
+ if (!yyParenDepth)
+ prospectiveContext.clear();
+ case_default:
+ yyTok = getToken();
+ break;
+ }
+ }
+
+ if (yyBraceDepth != 0)
+ qWarning("%s:%d: Unbalanced opening brace in C++ code"
+ " (or abuse of the C++ preprocessor)\n",
+ qPrintable(yyFileName), yyBraceLineNo);
+ else if (yyParenDepth != 0)
+ qWarning("%s:%d: Unbalanced opening parenthesis in C++ code"
+ " (or abuse of the C++ preprocessor)\n",
+ qPrintable(yyFileName), yyParenLineNo);
+}
+
+/*
+ Fetches tr() calls in C++ code in UI files (inside "<function>"
+ tag). This mechanism is obsolete.
+*/
+void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString &context)
+{
+ CppParser parser;
+ parser.setInput(in);
+ ConversionData cd;
+ QSet<QString> inclusions;
+ parser.setTranslator(&translator);
+ parser.parse(context, cd, inclusions);
+ parser.deleteResults();
+}
+
+void loadCPP(Translator &translator, const QStringList &filenames, ConversionData &cd)
+{
+ QByteArray codecName = cd.m_codecForSource.isEmpty()
+ ? translator.codecName() : cd.m_codecForSource;
+ QTextCodec *codec = QTextCodec::codecForName(codecName);
+
+ foreach (const QString &filename, filenames) {
+ if (CppFiles::getResults(filename) || CppFiles::isBlacklisted(filename))
+ continue;
+
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ continue;
+ }
+
+ CppParser parser;
+ QTextStream ts(&file);
+ ts.setCodec(codec);
+ ts.setAutoDetectUnicode(true);
+ if (ts.codec()->name() == "UTF-16")
+ translator.setCodecName("System");
+ parser.setInput(ts, filename);
+ Translator *tor = new Translator;
+ tor->setCodecName(translator.codecName());
+ parser.setTranslator(tor);
+ QSet<QString> inclusions;
+ parser.parse(cd.m_defaultContext, cd, inclusions);
+ CppFiles::setResults(filename, parser.getResults());
+ }
+
+ foreach (const QString filename, filenames)
+ if (!CppFiles::isBlacklisted(filename))
+ if (Translator *tor = CppFiles::getResults(filename)->tor)
+ foreach (const TranslatorMessage &msg, tor->messages())
+ translator.extend(msg);
+}
+
+QT_END_NAMESPACE
diff --git a/tools/linguist/shared/java.cpp b/tools/linguist/lupdate/java.cpp
index c91a55a..8a5d975 100644
--- a/tools/linguist/shared/java.cpp
+++ b/tools/linguist/lupdate/java.cpp
@@ -39,7 +39,9 @@
**
****************************************************************************/
-#include "translator.h"
+#include "lupdate.h"
+
+#include <translator.h>
#include <QtCore/QDebug>
#include <QtCore/QFile>
@@ -373,22 +375,13 @@ static bool matchString( QString &s )
return true;
}
-static bool matchInteger( qlonglong *number)
-{
- bool matches = (yyTok == Tok_Integer);
- if (matches) {
- yyTok = getToken();
- *number = yyInteger;
- }
- return matches;
-}
-
static bool matchStringOrNull(QString &s)
{
bool matches = matchString(s);
if (!matches) {
matches = (yyTok == Tok_null);
- if (matches) yyTok = getToken();
+ if (matches)
+ yyTok = getToken();
}
return matches;
}
@@ -606,14 +599,18 @@ static void parse( Translator *tor )
}
-bool loadJava(Translator &translator, QIODevice &dev, ConversionData &cd)
+bool loadJava(Translator &translator, const QString &filename, ConversionData &cd)
{
- //void LupdateApplication::fetchtr_java( const QString &fileName, Translator *tor,
- //const QString &defaultContext, bool mustExist, const QByteArray &codecForSource )
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
yyDefaultContext = cd.m_defaultContext;
yyInPos = -1;
- yyFileName = cd.m_sourceFileName;
+ yyFileName = filename;
yyPackage.clear();
yyScope.clear();
yyTok = -1;
@@ -621,7 +618,7 @@ bool loadJava(Translator &translator, QIODevice &dev, ConversionData &cd)
yyCurLineNo = 0;
yyParenLineNo = 1;
- QTextStream ts(&dev);
+ QTextStream ts(&file);
QByteArray codecName;
if (!cd.m_codecForSource.isEmpty())
codecName = cd.m_codecForSource;
@@ -631,7 +628,7 @@ bool loadJava(Translator &translator, QIODevice &dev, ConversionData &cd)
ts.setAutoDetectUnicode(true);
yyInStr = ts.readAll();
yyInPos = 0;
- yyFileName = cd.m_sourceFileName;
+ yyFileName = filename;
yyCurLineNo = 1;
yyParenLineNo = 1;
yyCh = getChar();
@@ -643,19 +640,4 @@ bool loadJava(Translator &translator, QIODevice &dev, ConversionData &cd)
return true;
}
-int initJava()
-{
- Translator::FileFormat format;
- format.extension = QLatin1String("java");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.description = QObject::tr("Java source files");
- format.loader = &loadJava;
- format.saver = 0;
- Translator::registerFileFormat(format);
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initJava)
-
QT_END_NAMESPACE
diff --git a/tools/linguist/lupdate/lupdate.1 b/tools/linguist/lupdate/lupdate.1
index 68958b9..b37e7b3 100644
--- a/tools/linguist/lupdate/lupdate.1
+++ b/tools/linguist/lupdate/lupdate.1
@@ -52,12 +52,12 @@ tool for the Qt GUI toolkit.
.B Lupdate
reads a qmake/tmake project file (.pro file), finds the translatable
strings in the specified source, header and interface files, and
-updates the translation files (.ts files) specified in it. The
+updates the translation files (TS files) specified in it. The
translation files are given to the translator who uses
.B Qt Linguist
to read the files and insert the translations.
.PP
-The .ts file format is a simple human-readable XML format that can be
+The TS file format is a simple human-readable XML format that can be
used with version control systems if required.
.PP
.SH OPTIONS
@@ -74,7 +74,7 @@ Default: 'ui,c,c++,cc,cpp,cxx,ch,h,h++,hh,hpp,hxx'.
Display the usage and exit.
.TP
.I "-locations {absolute|relative|none}"
-Specify/override how source code references are saved in ts files.
+Specify/override how source code references are saved in TS files.
Default is absolute.
.TP
.I "-no-obsolete"
@@ -84,7 +84,7 @@ Drop all obsolete strings.
Do not recursively scan the following directories.
.TP
.I "-no-sort"
-Do not sort contexts in .ts files.
+Do not sort contexts in TS files.
.TP
.I "-pluralonly"
Only include plural form messages.
@@ -97,7 +97,7 @@ file syntax but different file suffix
Recursively scan the following directories.
.TP
.I "-silent"
-Don't explain what is being done.
+Do not explain what is being done.
.TP
.I "-source-language <language>[_<region>]"
Specify/override the language of the source strings. Defaults to
@@ -139,8 +139,8 @@ translations will be reused as far as possible, and translated
strings that have vanished from the source files are marked obsolete.
.PP
.B lupdate
-can also be invoked with a list of C++ source files, .ui files
-and .ts files:
+can also be invoked with a list of C++ source files, UI files
+and TS files:
.PP
.in +4
.nf
diff --git a/tools/linguist/shared/translatortools.h b/tools/linguist/lupdate/lupdate.h
index 25ba612..7e28cf5 100644
--- a/tools/linguist/shared/translatortools.h
+++ b/tools/linguist/lupdate/lupdate.h
@@ -48,7 +48,9 @@
QT_BEGIN_NAMESPACE
+class ConversionData;
class QString;
+class QStringList;
class Translator;
class TranslatorMessage;
@@ -72,6 +74,12 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(UpdateOptions)
Translator merge(const Translator &tor, const Translator &virginTor,
UpdateOptions options, QString &err);
+void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString &context);
+void loadCPP(Translator &translator, const QStringList &filenames, ConversionData &cd);
+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);
+
QT_END_NAMESPACE
#endif
diff --git a/tools/linguist/lupdate/lupdate.pro b/tools/linguist/lupdate/lupdate.pro
index b05a4ef..ccc2d47 100644
--- a/tools/linguist/lupdate/lupdate.pro
+++ b/tools/linguist/lupdate/lupdate.pro
@@ -14,9 +14,20 @@ build_all:!build_pass {
include(../shared/formats.pri)
include(../shared/proparser.pri)
-include(../shared/translatortools.pri)
-SOURCES += main.cpp
+SOURCES += \
+ main.cpp \
+ merge.cpp \
+ ../shared/simtexth.cpp \
+ \
+ cpp.cpp \
+ java.cpp \
+ qscript.cpp \
+ ui.cpp
+
+HEADERS += \
+ lupdate.h \
+ ../shared/simtexth.h
DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp
index 52a57fb..a531af8 100644
--- a/tools/linguist/lupdate/main.cpp
+++ b/tools/linguist/lupdate/main.cpp
@@ -39,9 +39,10 @@
**
****************************************************************************/
-#include "translator.h"
-#include "translatortools.h"
-#include "profileevaluator.h"
+#include "lupdate.h"
+
+#include <translator.h>
+#include <profileevaluator.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
@@ -83,12 +84,12 @@ static void printUsage()
{
printOut(QObject::tr(
"Usage:\n"
- " lupdate [options] [project-file]\n"
+ " lupdate [options] [project-file]...\n"
" lupdate [options] [source-file|path]... -ts ts-files\n\n"
- "lupdate is part of Qt's Linguist tool chain. It can be used as a\n"
- "stand-alone tool to create XML based translations files in the .ts\n"
- "format from translatable messages in C++ and Java source code.\n\n"
- "lupdate can also merge such messages into existing .ts files.\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"
+ "Qt TS XML). New and modified messages can be merged into existing TS files.\n\n"
"Options:\n"
" -help Display this information and exit.\n"
" -no-obsolete\n"
@@ -102,16 +103,19 @@ static void printUsage()
" -silent\n"
" Do not explain what is being done.\n"
" -no-sort\n"
- " Do not sort contexts in .ts files.\n"
+ " Do not sort contexts in TS files.\n"
" -no-recursive\n"
" Do not recursively scan the following directories.\n"
" -recursive\n"
- " Recursively scan the following directories.\n"
+ " Recursively scan the following directories (default).\n"
+ " -I <includepath> or -I<includepath>\n"
+ " Additional location to look for include files.\n"
+ " May be specified multiple times.\n"
" -locations {absolute|relative|none}\n"
- " Specify/override how source code references are saved in ts files.\n"
+ " Specify/override how source code references are saved in TS files.\n"
" Default is absolute.\n"
" -no-ui-lines\n"
- " Do not record line numbers in references to .ui files.\n"
+ " Do not record line numbers in references to UI files.\n"
" -disable-heuristic {sametext|similartext|number}\n"
" Disable the named merge heuristic. Can be specified multiple times.\n"
" -pro <filename>\n"
@@ -217,7 +221,10 @@ int main(int argc, char **argv)
QByteArray codecForSource;
QStringList tsFileNames;
QStringList proFiles;
+ QMultiHash<QString, QString> allCSources;
+ QSet<QString> projectRoots;
QStringList sourceFiles;
+ QStringList includePath;
QString targetLanguage;
QString sourceLanguage;
@@ -344,6 +351,18 @@ int main(int argc, char **argv)
proFiles += args[i];
numFiles++;
continue;
+ } else if (arg.startsWith(QLatin1String("-I"))) {
+ if (arg.length() == 2) {
+ ++i;
+ if (i == argc) {
+ qWarning("The -I option should be followed by a path.");
+ return 1;
+ }
+ includePath += args[i];
+ } else {
+ includePath += args[i].mid(2);
+ }
+ continue;
} else if (arg.startsWith(QLatin1String("-")) && arg != QLatin1String("-")) {
qWarning("Unrecognized option '%s'", qPrintable(arg));
return 1;
@@ -388,33 +407,46 @@ int main(int argc, char **argv)
if (options & Verbose)
printOut(QObject::tr("Scanning directory '%1'...").arg(arg));
QDir dir = QDir(fi.filePath());
+ projectRoots.insert(dir.absolutePath() + QLatin1Char('/'));
if (extensionsNameFilters.isEmpty()) {
- extensions = extensions.trimmed();
- // Remove the potential dot in front of each extension
- if (extensions.startsWith(QLatin1Char('.')))
- extensions.remove(0,1);
- extensions.replace(QLatin1String(",."), QLatin1String(","));
-
- extensions.insert(0, QLatin1String("*."));
- extensions.replace(QLatin1Char(','), QLatin1String(",*."));
- extensionsNameFilters = extensions.split(QLatin1Char(','));
+ foreach (QString ext, extensions.split(QLatin1Char(','))) {
+ ext = ext.trimmed();
+ if (ext.startsWith(QLatin1Char('.')))
+ ext.remove(0,1);
+ ext.insert(0, QLatin1String("*."));
+ extensionsNameFilters << ext;
+ }
}
QDir::Filters filters = QDir::Files | QDir::NoSymLinks;
QFileInfoList fileinfolist;
recursiveFileInfoList(dir, extensionsNameFilters, filters,
recursiveScan, &fileinfolist);
- QFileInfoList::iterator ii;
- QString fn;
- for (ii = fileinfolist.begin(); ii != fileinfolist.end(); ++ii) {
- // Make sure the path separator is stored with '/' in the ts file
- sourceFiles << ii->canonicalFilePath().replace(QLatin1Char('\\'), QLatin1Char('/'));
+ 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);
+ }
}
} else {
- sourceFiles << fi.canonicalFilePath().replace(QLatin1Char('\\'), QLatin1Char('/'));
+ sourceFiles << QDir::cleanPath(fi.absoluteFilePath());;
}
}
} // for args
+ foreach (const QString &proFile, proFiles)
+ projectRoots.insert(QDir::cleanPath(QFileInfo(proFile).absolutePath()) + QLatin1Char('/'));
bool firstPass = true;
bool fail = false;
@@ -422,6 +454,9 @@ int main(int argc, char **argv)
ConversionData cd;
cd.m_defaultContext = defaultContext;
cd.m_noUiLines = options & NoUiLines;
+ cd.m_projectRoots = projectRoots;
+ cd.m_includePath = includePath;
+ cd.m_allCSources = allCSources;
QStringList tsFiles = tsFileNames;
if (proFiles.count() > 0) {
@@ -451,6 +486,8 @@ int main(int argc, char **argv)
continue;
}
+ cd.m_includePath += visitor.values(QLatin1String("INCLUDEPATH"));
+
evaluateProFile(visitor, &variables);
sourceFiles = variables.value("SOURCES");
@@ -473,27 +510,19 @@ int main(int argc, char **argv)
tsFiles += variables.value("TRANSLATIONS");
}
+ QStringList sourceFilesCpp;
for (QStringList::iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) {
- if (it->endsWith(QLatin1String(".java"), Qt::CaseInsensitive)) {
- cd.m_sourceFileName = *it;
- fetchedTor.load(*it, cd, QLatin1String("java"));
- //fetchtr_java(*it, &fetchedTor, defaultContext, true, codecForSource);
- }
- else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive)) {
- fetchedTor.load(*it, cd, QLatin1String("ui"));
- //fetchedTor.load(*it + QLatin1String(".h"), cd, QLatin1String("cpp"));
- //fetchtr_ui(*it, &fetchedTor, defaultContext, true);
- //fetchtr_cpp(*it + QLatin1String(".h"), &fetchedTor,
- // defaultContext, false, codecForSource);
- }
+ if (it->endsWith(QLatin1String(".java"), Qt::CaseInsensitive))
+ loadJava(fetchedTor, *it, cd);
+ else if (it->endsWith(QLatin1String(".ui"), Qt::CaseInsensitive))
+ loadUI(fetchedTor, *it, cd);
else if (it->endsWith(QLatin1String(".js"), Qt::CaseInsensitive)
- || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive)) {
- fetchedTor.load(*it, cd, QLatin1String("js"));
- } else {
- fetchedTor.load(*it, cd, QLatin1String("cpp"));
- //fetchtr_cpp(*it, &fetchedTor, defaultContext, true, codecForSource);
- }
+ || it->endsWith(QLatin1String(".qs"), Qt::CaseInsensitive))
+ loadQScript(fetchedTor, *it, cd);
+ else
+ sourceFilesCpp << *it;
}
+ loadCPP(fetchedTor, sourceFilesCpp, cd);
if (!cd.error().isEmpty())
printOut(cd.error());
diff --git a/tools/linguist/shared/translatortools.cpp b/tools/linguist/lupdate/merge.cpp
index 01a1f48..7925fb2 100644
--- a/tools/linguist/shared/translatortools.cpp
+++ b/tools/linguist/lupdate/merge.cpp
@@ -39,7 +39,7 @@
**
****************************************************************************/
-#include "translatortools.h"
+#include "lupdate.h"
#include "simtexth.h"
#include "translator.h"
@@ -193,7 +193,7 @@ static QString translationAttempt(const QString &oldTranslation,
*/
for (k = 0; k < p; k++) {
if (!met[k])
- attempt += QString(QLatin1String(" {")) + newNumbers[k] + QString(QLatin1String("?}"));
+ attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String("?}");
}
/*
@@ -205,8 +205,8 @@ static QString translationAttempt(const QString &oldTranslation,
for (ell = 0; ell < p; ell++) {
if (k != ell && oldNumbers[k] == oldNumbers[ell] &&
newNumbers[k] < newNumbers[ell])
- attempt += QString(QLatin1String(" {")) + newNumbers[k] + QString(QLatin1String(" or ")) +
- newNumbers[ell] + QString(QLatin1String("?}"));
+ attempt += QLatin1String(" {") + newNumbers[k] + QLatin1String(" or ") +
+ newNumbers[ell] + QLatin1String("?}");
}
}
return attempt;
diff --git a/tools/linguist/shared/qscript.cpp b/tools/linguist/lupdate/qscript.cpp
index bec1cf1..7a701ae 100644
--- a/tools/linguist/shared/qscript.cpp
+++ b/tools/linguist/lupdate/qscript.cpp
@@ -752,7 +752,7 @@ const int QScriptGrammar::action_check [] = {
#define Q_SCRIPT_REGEXPLITERAL_RULE2 8
-#include "translator.h"
+#include <translator.h>
#include <QtCore/qdebug.h>
#include <QtCore/qnumeric.h>
@@ -2356,9 +2356,15 @@ case 94: {
}
-bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
+bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
{
- QTextStream ts(&dev);
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
+ QTextStream ts(&file);
QByteArray codecName;
if (!cd.m_codecForSource.isEmpty())
codecName = cd.m_codecForSource;
@@ -2371,8 +2377,8 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
QScript::Lexer lexer;
lexer.setCode(code, /*lineNumber=*/1);
QScriptParser parser;
- if (!parser.parse(&lexer, cd.m_sourceFileName, &translator)) {
- qWarning("%s:%d: %s", qPrintable(cd.m_sourceFileName), parser.errorLineNumber(),
+ if (!parser.parse(&lexer, filename, &translator)) {
+ qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(),
qPrintable(parser.errorMessage()));
return false;
}
@@ -2382,27 +2388,4 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
return true;
}
-bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
- Q_UNUSED(dev);
- Q_UNUSED(translator);
- cd.appendError(QLatin1String("Cannot save .js files"));
- return false;
-}
-
-int initQScript()
-{
- Translator::FileFormat format;
- format.extension = QLatin1String("js");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.description = QObject::tr("Qt Script source files");
- format.loader = &loadQScript;
- format.saver = &saveQScript;
- Translator::registerFileFormat(format);
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initQScript)
-
QT_END_NAMESPACE
diff --git a/tools/linguist/shared/qscript.g b/tools/linguist/lupdate/qscript.g
index 128699d..4e36395 100644
--- a/tools/linguist/shared/qscript.g
+++ b/tools/linguist/lupdate/qscript.g
@@ -42,6 +42,10 @@
--
----------------------------------------------------------------------------
+--------------------------------------------------------------------------------
+-- Process with "qlalr --no-debug --no-lines qscript.g" to update qscript.cpp --
+--------------------------------------------------------------------------------
+
%parser QScriptGrammar
%merged_output qscript.cpp
%expect 3
@@ -81,7 +85,7 @@
%start Program
/.
-#include "translator.h"
+#include <translator.h>
#include <QtCore/qdebug.h>
#include <QtCore/qnumeric.h>
@@ -1986,9 +1990,15 @@ PropertyNameAndValueListOpt: PropertyNameAndValueList ;
}
-bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
+bool loadQScript(Translator &translator, const QString &filename, ConversionData &cd)
{
- QTextStream ts(&dev);
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
+ QTextStream ts(&file);
QByteArray codecName;
if (!cd.m_codecForSource.isEmpty())
codecName = cd.m_codecForSource;
@@ -2001,8 +2011,8 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
QScript::Lexer lexer;
lexer.setCode(code, /*lineNumber=*/1);
QScriptParser parser;
- if (!parser.parse(&lexer, cd.m_sourceFileName, &translator)) {
- qWarning("%s:%d: %s", qPrintable(cd.m_sourceFileName), parser.errorLineNumber(),
+ if (!parser.parse(&lexer, filename, &translator)) {
+ qWarning("%s:%d: %s", qPrintable(filename), parser.errorLineNumber(),
qPrintable(parser.errorMessage()));
return false;
}
@@ -2012,28 +2022,5 @@ bool loadQScript(Translator &translator, QIODevice &dev, ConversionData &cd)
return true;
}
-bool saveQScript(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
- Q_UNUSED(dev);
- Q_UNUSED(translator);
- cd.appendError(QLatin1String("Cannot save .js files"));
- return false;
-}
-
-int initQScript()
-{
- Translator::FileFormat format;
- format.extension = QLatin1String("js");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.description = QObject::tr("Qt Script source files");
- format.loader = &loadQScript;
- format.saver = &saveQScript;
- Translator::registerFileFormat(format);
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initQScript)
-
QT_END_NAMESPACE
./
diff --git a/tools/linguist/shared/ui.cpp b/tools/linguist/lupdate/ui.cpp
index cdecfd1..fb78b2a 100644
--- a/tools/linguist/shared/ui.cpp
+++ b/tools/linguist/lupdate/ui.cpp
@@ -39,7 +39,9 @@
**
****************************************************************************/
-#include "translator.h"
+#include "lupdate.h"
+
+#include <translator.h>
#include <QtCore/QDebug>
#include <QtCore/QFile>
@@ -53,9 +55,6 @@
QT_BEGIN_NAMESPACE
-// in cpp.cpp
-void fetchtrInlinedCpp(const QString &in, Translator &tor, const QString &context);
-
class UiReader : public QXmlDefaultHandler
{
public:
@@ -157,7 +156,7 @@ bool UiReader::fatalError(const QXmlParseException &exception)
msg.sprintf("XML error: Parse error at line %d, column %d (%s).",
exception.lineNumber(), exception.columnNumber(),
exception.message().toLatin1().data());
- m_cd.appendError(msg);
+ m_cd.appendError(msg);
return false;
}
@@ -177,9 +176,16 @@ void UiReader::flush()
m_extracomment.clear();
}
-bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd)
+bool loadUI(Translator &translator, const QString &filename, ConversionData &cd)
{
- QXmlInputSource in(&dev);
+ cd.m_sourceFileName = filename;
+ QFile file(filename);
+ if (!file.open(QIODevice::ReadOnly)) {
+ cd.appendError(QString::fromLatin1("Cannot open %1: %2")
+ .arg(filename, file.errorString()));
+ return false;
+ }
+ QXmlInputSource in(&file);
QXmlSimpleReader reader;
reader.setFeature(QLatin1String("http://xml.org/sax/features/namespaces"), false);
reader.setFeature(QLatin1String("http://xml.org/sax/features/namespace-prefixes"), true);
@@ -196,39 +202,4 @@ bool loadUI(Translator &translator, QIODevice &dev, ConversionData &cd)
return result;
}
-bool saveUI(const Translator &translator, QIODevice &dev, ConversionData &cd)
-{
- Q_UNUSED(dev);
- Q_UNUSED(translator);
- cd.appendError(QLatin1String("Cannot save .ui files"));
- return false;
-}
-
-int initUI()
-{
- Translator::FileFormat format;
-
- // "real" Qt Designer
- format.extension = QLatin1String("ui");
- format.description = QObject::tr("Qt Designer form files");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.loader = &loadUI;
- format.saver = &saveUI;
- Translator::registerFileFormat(format);
-
- // same for jambi
- format.extension = QLatin1String("jui");
- format.description = QObject::tr("Qt Jambi form files");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.loader = &loadUI;
- format.saver = &saveUI;
- Translator::registerFileFormat(format);
-
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initUI)
-
QT_END_NAMESPACE
diff --git a/tools/linguist/phrasebooks/french.qph b/tools/linguist/phrasebooks/french.qph
index f244013..d38da5a 100644
--- a/tools/linguist/phrasebooks/french.qph
+++ b/tools/linguist/phrasebooks/french.qph
@@ -1,4 +1,5 @@
-<!DOCTYPE QPH><QPH language="fr">
+<!DOCTYPE QPH>
+<QPH language="fr">
<phrase>
<source>About</source>
<target>A propos</target>
@@ -1101,4 +1102,228 @@
<source>Yes</source>
<target>Oui</target>
</phrase>
+<phrase>
+ <source>Split</source>
+ <target>Scinder</target>
+</phrase>
+<phrase>
+ <source>&amp;Edit</source>
+ <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>
+<phrase>
+ <source>Start Debugger</source>
+ <target>Lancer le débogueur</target>
+</phrase>
+<phrase>
+ <source>Executable:</source>
+ <target>Exécutable:</target>
+</phrase>
+<phrase>
+ <source>Filter:</source>
+ <target>Filtre:</target>
+</phrase>
+<phrase>
+ <source>Clear</source>
+ <target>Effacer</target>
+</phrase>
+<phrase>
+ <source>Host and port:</source>
+ <target>Hôte et port:</target>
+</phrase>
+<phrase>
+ <source>Architecture:</source>
+ <target>Architecture:</target>
+</phrase>
+<phrase>
+ <source>Server start script:</source>
+ <target>Script de démarrage du serveur:</target>
+</phrase>
+<phrase>
+ <source>&amp;Undo</source>
+ <target>Annu&amp;ler</target>
+</phrase>
+<phrase>
+ <source>Add Bookmark</source>
+ <target>Ajouter un signet</target>
+</phrase>
+<phrase>
+ <source>Bookmark:</source>
+ <target>Signet:</target>
+</phrase>
+<phrase>
+ <source>Add in Folder:</source>
+ <target>Ajouter dans le dossier:</target>
+</phrase>
+<phrase>
+ <source>+</source>
+ <target>+</target>
+</phrase>
+<phrase>
+ <source>New Folder</source>
+ <target>Nouveau dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmarks</source>
+ <target>Signets</target>
+</phrase>
+<phrase>
+ <source>Rename Folder</source>
+ <target>Renommer le dossier</target>
+</phrase>
+<phrase>
+ <source>Bookmark</source>
+ <target>Signet</target>
+</phrase>
+<phrase>
+ <source>Remove</source>
+ <target>Retirer</target>
+</phrase>
+<phrase>
+ <source>Delete Folder</source>
+ <target>Supprimer le dossier</target>
+</phrase>
+<phrase>
+ <source>Add</source>
+ <target>Ajouter</target>
+</phrase>
+<phrase>
+ <source>Move Up</source>
+ <target>Vers le Haut</target>
+</phrase>
+<phrase>
+ <source>Move Down</source>
+ <target>Vers le Bas</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark</source>
+ <target>Afficher le signet</target>
+</phrase>
+<phrase>
+ <source>Show Bookmark in New Tab</source>
+ <target>Afficher le signet dans un nouvel onglet</target>
+</phrase>
+<phrase>
+ <source>Delete Bookmark</source>
+ <target>Supprimer le signet</target>
+</phrase>
+<phrase>
+ <source>Rename Bookmark</source>
+ <target>Renommer le signet</target>
+</phrase>
+<phrase>
+ <source>Previous Bookmark</source>
+ <target>Signet précédent</target>
+</phrase>
+<phrase>
+ <source>Next Bookmark</source>
+ <target>Signet suivant</target>
+</phrase>
+<phrase>
+ <source>Condition:</source>
+ <target>Condition:</target>
+</phrase>
+<phrase>
+ <source>Working Directory:</source>
+ <target>Répertoire de travail:</target>
+</phrase>
+<phrase>
+ <source>Environment</source>
+ <target>Environnement</target>
+</phrase>
+<phrase>
+ <source>Arguments</source>
+ <target>Arguments</target>
+</phrase>
+<phrase>
+ <source>Build directory:</source>
+ <target>Répertoire de compilation:</target>
+</phrase>
+<phrase>
+ <source>Path:</source>
+ <target>Chemin:</target>
+</phrase>
+<phrase>
+ <source>General</source>
+ <target>Général</target>
+</phrase>
+<phrase>
+ <source>Username:</source>
+ <target>Nom d&apos;utilisateur:</target>
+</phrase>
+<phrase>
+ <source>User interface</source>
+ <target>Interface utilisateur</target>
+</phrase>
+<phrase>
+ <source>Open Link</source>
+ <target>Ouvrir le lien</target>
+</phrase>
+<phrase>
+ <source> [read only]</source>
+ <target> [lecture seule]</target>
+</phrase>
+<phrase>
+ <source> [directory]</source>
+ <target> [répertoire]</target>
+</phrase>
+<phrase>
+ <source>Close All</source>
+ <target>Fermer tout</target>
+</phrase>
+<phrase>
+ <source>Failed!</source>
+ <target>Échec!</target>
+</phrase>
+<phrase>
+ <source>Proceed</source>
+ <target>Continuer</target>
+</phrase>
+<phrase>
+ <source>Make writable</source>
+ <target>Rendre inscriptible</target>
+</phrase>
+<phrase>
+ <source>Qt Creator</source>
+ <target>Qt Creator</target>
+</phrase>
+<phrase>
+ <source>&amp;File</source>
+ <target>&amp;Fichier</target>
+</phrase>
+<phrase>
+ <source>Activate %1</source>
+ <target>Activer %1</target>
+</phrase>
+<phrase>
+ <source>New Project</source>
+ <target>Nouveau projet</target>
+</phrase>
+<phrase>
+ <source>Close %1</source>
+ <target>Fermer %1</target>
+</phrase>
+<phrase>
+ <source>*</source>
+ <target>*</target>
+</phrase>
+<phrase>
+ <source>&amp;Change</source>
+ <target>&amp;Modifier</target>
+</phrase>
+<phrase>
+ <source>Close Other Editors</source>
+ <target>Fermer les autres éditeurs</target>
+</phrase>
+<phrase>
+ <source>Close All Except %1</source>
+ <target>Fermer tout sauf %1</target>
+</phrase>
</QPH>
diff --git a/tools/linguist/shared/cpp.cpp b/tools/linguist/shared/cpp.cpp
deleted file mode 100644
index ac6bd33..0000000
--- a/tools/linguist/shared/cpp.cpp
+++ /dev/null
@@ -1,1098 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** 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 either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at http://www.qtsoftware.com/contact.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "translator.h"
-
-#include <QtCore/QDebug>
-#include <QtCore/QStack>
-#include <QtCore/QString>
-#include <QtCore/QTextCodec>
-#include <QtCore/QTextStream>
-
-#include <ctype.h> // for isXXX()
-
-QT_BEGIN_NAMESPACE
-
-/* qmake ignore Q_OBJECT */
-
-static const char MagicComment[] = "TRANSLATOR ";
-
-static QSet<QString> needs_Q_OBJECT;
-static QSet<QString> lacks_Q_OBJECT;
-
-static const int yyIdentMaxLen = 128;
-static const int yyCommentMaxLen = 65536;
-static const int yyStringMaxLen = 65536;
-
-#define STRINGIFY_INTERNAL(x) #x
-#define STRINGIFY(x) STRINGIFY_INTERNAL(x)
-#define STRING(s) static QString str##s(QLatin1String(STRINGIFY(s)))
-
-//#define DIAGNOSE_RETRANSLATABILITY
-/*
- The first part of this source file is the C++ tokenizer. We skip
- most of C++; the only tokens that interest us are defined here.
- Thus, the code fragment
-
- int main()
- {
- printf("Hello, world!\n");
- return 0;
- }
-
- is broken down into the following tokens (Tok_ omitted):
-
- Ident Ident LeftParen RightParen
- LeftBrace
- Ident LeftParen String RightParen Semicolon
- return Semicolon
- RightBrace.
-
- The 0 doesn't produce any token.
-*/
-
-enum {
- Tok_Eof, Tok_class, Tok_namespace, Tok_return,
- Tok_tr = 10, Tok_trUtf8, Tok_translate, Tok_translateUtf8,
- Tok_Q_OBJECT = 20, Tok_Q_DECLARE_TR_FUNCTIONS,
- Tok_Ident, Tok_Comment, Tok_String, Tok_Arrow, Tok_Colon, Tok_ColonColon,
- Tok_Equals,
- Tok_LeftBrace = 30, Tok_RightBrace, Tok_LeftParen, Tok_RightParen, Tok_Comma, Tok_Semicolon,
- Tok_Integer = 40,
- Tok_Other
-};
-
-/*
- The tokenizer maintains the following global variables. The names
- should be self-explanatory.
-*/
-static QString yyFileName;
-static int yyCh;
-static bool yyCodecIsUtf8;
-static bool yyForceUtf8;
-static QString yyIdent;
-static QString yyComment;
-static QString yyString;
-static qlonglong yyInteger;
-static QStack<int> yySavedBraceDepth;
-static QStack<int> yySavedParenDepth;
-static int yyBraceDepth;
-static int yyParenDepth;
-static int yyLineNo;
-static int yyCurLineNo;
-static int yyBraceLineNo;
-static int yyParenLineNo;
-static bool yyTokColonSeen = false;
-
-// the string to read from and current position in the string
-static QTextCodec *yySourceCodec;
-static bool yySourceIsUnicode;
-static QString yyInStr;
-static int yyInPos;
-
-static uint getChar()
-{
- forever {
- if (yyInPos >= yyInStr.size())
- return EOF;
- uint c = yyInStr[yyInPos++].unicode();
- if (c == '\\' && yyInPos < yyInStr.size()) {
- if (yyInStr[yyInPos].unicode() == '\n') {
- ++yyCurLineNo;
- ++yyInPos;
- continue;
- }
- if (yyInStr[yyInPos].unicode() == '\r') {
- ++yyCurLineNo;
- ++yyInPos;
- if (yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n')
- ++yyInPos;
- continue;
- }
- }
- if (c == '\r') {
- if (yyInPos < yyInStr.size() && yyInStr[yyInPos].unicode() == '\n')
- ++yyInPos;
- c = '\n';
- ++yyCurLineNo;
- } else if (c == '\n') {
- ++yyCurLineNo;
- }
- return c;
- }
-}
-
-static uint getToken()
-{
- yyIdent.clear();
- yyComment.clear();
- yyString.clear();
-
- while (yyCh != EOF) {
- yyLineNo = yyCurLineNo;
-
- if (isalpha(yyCh) || yyCh == '_') {
- do {
- yyIdent += yyCh;
- yyCh = getChar();
- } while (isalnum(yyCh) || yyCh == '_');
-
- //qDebug() << "IDENT: " << yyIdent;
-
- switch (yyIdent.at(0).unicode()) {
- case 'Q':
- if (yyIdent == QLatin1String("Q_OBJECT"))
- return Tok_Q_OBJECT;
- if (yyIdent == QLatin1String("Q_DECLARE_TR_FUNCTIONS"))
- return Tok_Q_DECLARE_TR_FUNCTIONS;
- if (yyIdent == QLatin1String("QT_TR_NOOP"))
- return Tok_tr;
- if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP"))
- return Tok_translate;
- if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3"))
- return Tok_translate;
- if (yyIdent == QLatin1String("QT_TR_NOOP_UTF8"))
- return Tok_trUtf8;
- if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP_UTF8"))
- return Tok_translateUtf8;
- if (yyIdent == QLatin1String("QT_TRANSLATE_NOOP3_UTF8"))
- return Tok_translateUtf8;
- break;
- case 'T':
- // TR() for when all else fails
- if (yyIdent.compare(QLatin1String("TR"), Qt::CaseInsensitive) == 0) {
- return Tok_tr;
- }
- break;
- case 'c':
- if (yyIdent == QLatin1String("class"))
- return Tok_class;
- break;
- case 'f':
- /*
- QTranslator::findMessage() has the same parameters as
- QApplication::translate().
- */
- if (yyIdent == QLatin1String("findMessage"))
- return Tok_translate;
- break;
- case 'n':
- if (yyIdent == QLatin1String("namespace"))
- return Tok_namespace;
- break;
- case 'r':
- if (yyIdent == QLatin1String("return"))
- return Tok_return;
- break;
- case 's':
- if (yyIdent == QLatin1String("struct"))
- return Tok_class;
- break;
- case 't':
- if (yyIdent == QLatin1String("tr")) {
- return Tok_tr;
- }
- if (yyIdent == QLatin1String("trUtf8")) {
- return Tok_trUtf8;
- }
- if (yyIdent == QLatin1String("translate")) {
- return Tok_translate;
- }
- }
- return Tok_Ident;
- } else {
- switch (yyCh) {
- case '#':
- /*
- Early versions of lupdate complained about
- unbalanced braces in the following code:
-
- #ifdef ALPHA
- while (beta) {
- #else
- while (gamma) {
- #endif
- delta;
- }
-
- The code contains, indeed, two opening braces for
- one closing brace; yet there's no reason to panic.
-
- The solution is to remember yyBraceDepth as it was
- when #if, #ifdef or #ifndef was met, and to set
- yyBraceDepth to that value when meeting #elif or
- #else.
- */
- do {
- yyCh = getChar();
- } while (isspace(yyCh) && yyCh != '\n');
-
- switch (yyCh) {
- case 'i':
- yyCh = getChar();
- if (yyCh == 'f') {
- // if, ifdef, ifndef
- yySavedBraceDepth.push(yyBraceDepth);
- yySavedParenDepth.push(yyParenDepth);
- }
- break;
- case 'e':
- yyCh = getChar();
- if (yyCh == 'l') {
- // elif, else
- if (!yySavedBraceDepth.isEmpty()) {
- yyBraceDepth = yySavedBraceDepth.top();
- yyParenDepth = yySavedParenDepth.top();
- }
- } else if (yyCh == 'n') {
- // endif
- if (!yySavedBraceDepth.isEmpty()) {
- yySavedBraceDepth.pop();
- yySavedParenDepth.pop();
- }
- }
- }
- while (isalnum(yyCh) || yyCh == '_')
- yyCh = getChar();
- break;
- case '/':
- yyCh = getChar();
- if (yyCh == '/') {
- do {
- yyCh = getChar();
- if (yyCh == EOF)
- break;
- yyComment.append(yyCh);
- } while (yyCh != '\n');
- } else if (yyCh == '*') {
- bool metAster = false;
- bool metAsterSlash = false;
-
- while (!metAsterSlash) {
- yyCh = getChar();
- if (yyCh == EOF) {
- qWarning("%s: Unterminated C++ comment starting at"
- " line %d\n",
- qPrintable(yyFileName), yyLineNo);
- return Tok_Comment;
- }
- yyComment.append(yyCh);
-
- if (yyCh == '*')
- metAster = true;
- else if (metAster && yyCh == '/')
- metAsterSlash = true;
- else
- metAster = false;
- }
- yyCh = getChar();
- yyComment.chop(2);
- }
- return Tok_Comment;
- case '"':
- yyCh = getChar();
- while (yyCh != EOF && yyCh != '\n' && yyCh != '"') {
- if (yyCh == '\\') {
- yyCh = getChar();
- if (yyString.size() < yyStringMaxLen) {
- yyString.append(QLatin1Char('\\'));
- yyString.append(yyCh);
- }
- } else {
- if (yyString.size() < yyStringMaxLen)
- yyString.append(yyCh);
- }
- yyCh = getChar();
- }
-
- if (yyCh != '"')
- qWarning("%s:%d: Unterminated C++ string",
- qPrintable(yyFileName), yyLineNo);
-
- if (yyCh == EOF)
- return Tok_Eof;
- yyCh = getChar();
- return Tok_String;
- case '-':
- yyCh = getChar();
- if (yyCh == '>') {
- yyCh = getChar();
- return Tok_Arrow;
- }
- break;
- case ':':
- yyCh = getChar();
- if (yyCh == ':') {
- yyCh = getChar();
- return Tok_ColonColon;
- }
- return Tok_Colon;
- // Incomplete: '<' might be part of '<=' or of template syntax.
- // The main intent of not completely ignoring it is to break
- // parsing of things like std::cout << QObject::tr() as
- // context std::cout::QObject (see Task 161106)
- case '=':
- yyCh = getChar();
- return Tok_Equals;
- case '>':
- case '<':
- yyCh = getChar();
- return Tok_Other;
- case '\'':
- yyCh = getChar();
- if (yyCh == '\\')
- yyCh = getChar();
-
- do {
- yyCh = getChar();
- } while (yyCh != EOF && yyCh != '\'');
- yyCh = getChar();
- break;
- case '{':
- if (yyBraceDepth == 0)
- yyBraceLineNo = yyCurLineNo;
- yyBraceDepth++;
- yyCh = getChar();
- return Tok_LeftBrace;
- case '}':
- if (yyBraceDepth == 0)
- yyBraceLineNo = yyCurLineNo;
- yyBraceDepth--;
- yyCh = getChar();
- return Tok_RightBrace;
- case '(':
- if (yyParenDepth == 0)
- yyParenLineNo = yyCurLineNo;
- yyParenDepth++;
- yyCh = getChar();
- return Tok_LeftParen;
- case ')':
- if (yyParenDepth == 0)
- yyParenLineNo = yyCurLineNo;
- yyParenDepth--;
- yyCh = getChar();
- return Tok_RightParen;
- case ',':
- yyCh = getChar();
- return Tok_Comma;
- case ';':
- yyCh = getChar();
- return Tok_Semicolon;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
- QByteArray ba;
- ba += yyCh;
- yyCh = getChar();
- bool hex = yyCh == 'x';
- if (hex) {
- ba += yyCh;
- yyCh = getChar();
- }
- while (hex ? isxdigit(yyCh) : isdigit(yyCh)) {
- ba += yyCh;
- yyCh = getChar();
- }
- bool ok;
- yyInteger = ba.toLongLong(&ok);
- if (ok)
- return Tok_Integer;
- break;
- }
- default:
- yyCh = getChar();
- break;
- }
- }
- }
- return Tok_Eof;
-}
-
-/*
- The second part of this source file is the parser. It accomplishes
- a very easy task: It finds all strings inside a tr() or translate()
- call, and possibly finds out the context of the call. It supports
- three cases: (1) the context is specified, as in
- FunnyDialog::tr("Hello") or translate("FunnyDialog", "Hello");
- (2) the call appears within an inlined function; (3) the call
- appears within a function defined outside the class definition.
-*/
-
-static uint yyTok;
-
-static bool match(uint t)
-{
- bool matches = (yyTok == t);
- if (matches)
- yyTok = getToken();
- return matches;
-}
-
-static bool matchString(QString *s)
-{
- bool matches = (yyTok == Tok_String);
- s->clear();
- while (yyTok == Tok_String) {
- *s += yyString;
- do {
- yyTok = getToken();
- } while (yyTok == Tok_Comment);
- }
- return matches;
-}
-
-static bool matchEncoding(bool *utf8)
-{
- STRING(QApplication);
- STRING(QCoreApplication);
- STRING(UnicodeUTF8);
- STRING(DefaultCodec);
- STRING(CodecForTr);
-
- if (yyTok != Tok_Ident)
- return false;
- if (yyIdent == strQApplication || yyIdent == strQCoreApplication) {
- yyTok = getToken();
- if (yyTok == Tok_ColonColon)
- yyTok = getToken();
- }
- if (yyIdent == strUnicodeUTF8) {
- *utf8 = true;
- yyTok = getToken();
- return true;
- }
- if (yyIdent == strDefaultCodec || yyIdent == strCodecForTr) {
- *utf8 = false;
- yyTok = getToken();
- return true;
- }
- return false;
-}
-
-static bool matchInteger(qlonglong *number)
-{
- bool matches = (yyTok == Tok_Integer);
- if (matches) {
- yyTok = getToken();
- *number = yyInteger;
- }
- return matches;
-}
-
-static bool matchStringOrNull(QString *s)
-{
- bool matches = matchString(s);
- qlonglong num = 0;
- if (!matches)
- matches = matchInteger(&num);
- return matches && num == 0;
-}
-
-/*
- * match any expression that can return a number, which can be
- * 1. Literal number (e.g. '11')
- * 2. simple identifier (e.g. 'm_count')
- * 3. simple function call (e.g. 'size()' )
- * 4. function call on an object (e.g. 'list.size()')
- * 5. function call on an object (e.g. 'list->size()')
- *
- * Other cases:
- * size(2,4)
- * list().size()
- * list(a,b).size(2,4)
- * etc...
- */
-static bool matchExpression()
-{
- if (match(Tok_Integer))
- return true;
-
- int parenlevel = 0;
- while (match(Tok_Ident) || parenlevel > 0) {
- if (yyTok == Tok_RightParen) {
- if (parenlevel == 0) break;
- --parenlevel;
- yyTok = getToken();
- } else if (yyTok == Tok_LeftParen) {
- yyTok = getToken();
- if (yyTok == Tok_RightParen) {
- yyTok = getToken();
- } else {
- ++parenlevel;
- }
- } else if (yyTok == Tok_Ident) {
- continue;
- } else if (yyTok == Tok_Arrow) {
- yyTok = getToken();
- } else if (parenlevel == 0) {
- return false;
- }
- }
- return true;
-}
-
-static QStringList resolveNamespaces(
- const QStringList &namespaces, const QHash<QString, QStringList> &namespaceAliases)
-{
- static QString strColons(QLatin1String("::"));
-
- QStringList ns;
- foreach (const QString &cns, namespaces) {
- ns << cns;
- ns = namespaceAliases.value(ns.join(strColons), ns);
- }
- return ns;
-}
-
-static QStringList getFullyQualifiedNamespaceName(
- const QSet<QString> &allNamespaces, const QStringList &namespaces,
- const QHash<QString, QStringList> &namespaceAliases,
- const QStringList &segments)
-{
- static QString strColons(QLatin1String("::"));
-
- if (segments.first().isEmpty()) {
- // fully qualified
- QStringList segs = segments;
- segs.removeFirst();
- return resolveNamespaces(segs, namespaceAliases);
- } else {
- for (int n = namespaces.count(); --n >= -1; ) {
- QStringList ns;
- for (int i = 0; i <= n; ++i) // Note: n == -1 possible
- ns << namespaces[i];
- foreach (const QString &cns, segments) {
- ns << cns;
- ns = namespaceAliases.value(ns.join(strColons), ns);
- }
- if (allNamespaces.contains(ns.join(strColons)))
- return ns;
- }
-
- // Fallback when the namespace was declared in a header, etc.
- QStringList ns = namespaces;
- ns += segments;
- return ns;
- }
-}
-
-static QString getFullyQualifiedClassName(
- const QSet<QString> &allClasses, const QStringList &namespaces,
- const QHash<QString, QStringList> &namespaceAliases,
- const QString &ident, bool hasPrefix)
-{
- static QString strColons(QLatin1String("::"));
-
- QString context = ident;
- QStringList segments = context.split(strColons);
- if (segments.first().isEmpty()) {
- // fully qualified
- segments.removeFirst();
- context = resolveNamespaces(segments, namespaceAliases).join(strColons);
- } else {
- for (int n = namespaces.count(); --n >= -1; ) {
- QStringList ns;
- for (int i = 0; i <= n; ++i) // Note: n == -1 possible
- ns.append(namespaces[i]);
- foreach (const QString &cns, segments) {
- ns.append(cns);
- ns = namespaceAliases.value(ns.join(strColons), ns);
- }
- QString nctx = ns.join(strColons);
- if (allClasses.contains(nctx)) {
- context = nctx;
- goto gotit;
- }
- }
-
- if (!hasPrefix && namespaces.count())
- context = namespaces.join(strColons) + strColons + context;
- }
-gotit:
- //qDebug() << "CLASSES:" << allClasses << "NAMEPACES:" << namespaces
- // << "IDENT:" << ident << "CONTEXT:" << context;
- return context;
-}
-
-
-static QString transcode(const QString &str, bool utf8)
-{
- static const char tab[] = "abfnrtv";
- static const char backTab[] = "\a\b\f\n\r\t\v";
- const QString in = (!utf8 || yySourceIsUnicode)
- ? str : QString::fromUtf8(yySourceCodec->fromUnicode(str).data());
- QString out;
-
- out.reserve(in.length());
- for (int i = 0; i < in.length();) {
- ushort c = in[i++].unicode();
- if (c == '\\') {
- if (i >= in.length())
- break;
- c = in[i++].unicode();
-
- if (c == '\n')
- continue;
-
- if (c == 'x') {
- QByteArray hex;
- while (i < in.length() && isxdigit((c = in[i].unicode()))) {
- hex += c;
- i++;
- }
- out += hex.toUInt(0, 16);
- } else if (c >= '0' && c < '8') {
- QByteArray oct;
- int n = 0;
- oct += c;
- while (n < 2 && i < in.length() && (c = in[i].unicode()) >= '0' && c < '8') {
- i++;
- n++;
- oct += c;
- }
- out += oct.toUInt(0, 8);
- } else {
- const char *p = strchr(tab, c);
- out += QChar(QLatin1Char(!p ? c : backTab[p - tab]));
- }
- } else {
- out += c;
- }
- }
- return out;
-}
-
-static void recordMessage(
- Translator *tor, int line, const QString &context, const QString &text, const QString &comment,
- const QString &extracomment, bool utf8, bool plural)
-{
- TranslatorMessage msg(
- transcode(context, utf8), transcode(text, utf8), transcode(comment, utf8), QString(),
- yyFileName, line, QStringList(),
- TranslatorMessage::Unfinished, plural);
- msg.setExtraComment(transcode(extracomment.simplified(), utf8));
- if ((utf8 || yyForceUtf8) && !yyCodecIsUtf8 && msg.needs8Bit())
- msg.setUtf8(true);
- tor->extend(msg);
-}
-
-static void parse(Translator *tor, const QString &initialContext, const QString &defaultContext)
-{
- static QString strColons(QLatin1String("::"));
-
- QMap<QString, QString> qualifiedContexts;
- QSet<QString> allClasses;
- QSet<QString> allNamespaces;
- QHash<QString, QStringList> namespaceAliases;
- QStringList namespaces;
- QString context;
- QString text;
- QString comment;
- QString extracomment;
- QString functionContext = initialContext;
- QString prefix;
-#ifdef DIAGNOSE_RETRANSLATABILITY
- QString functionName;
-#endif
- int line;
- bool utf8 = false;
- bool missing_Q_OBJECT = false;
-
- yyTok = getToken();
- while (yyTok != Tok_Eof) {
- //qDebug() << "TOKEN: " << yyTok;
- switch (yyTok) {
- case Tok_class:
- yyTokColonSeen = false;
- /*
- Partial support for inlined functions.
- */
- yyTok = getToken();
- if (yyBraceDepth == namespaces.count() && yyParenDepth == 0) {
- QStringList fct;
- do {
- /*
- This code should execute only once, but we play
- safe with impure definitions such as
- 'class Q_EXPORT QMessageBox', in which case
- 'QMessageBox' is the class name, not 'Q_EXPORT'.
- */
- fct = QStringList(yyIdent);
- yyTok = getToken();
- } while (yyTok == Tok_Ident);
- while (yyTok == Tok_ColonColon) {
- yyTok = getToken();
- if (yyTok != Tok_Ident)
- break; // Oops ...
- fct += yyIdent;
- yyTok = getToken();
- }
- functionContext = resolveNamespaces(namespaces + fct, namespaceAliases).join(strColons);
- allClasses.insert(functionContext);
-
- if (yyTok == Tok_Colon) {
- missing_Q_OBJECT = true;
- // Skip any token until '{' since lupdate might do things wrong if it finds
- // a '::' token here.
- do {
- yyTok = getToken();
- } while (yyTok != Tok_LeftBrace && yyTok != Tok_Eof);
- } else {
- //functionContext = defaultContext;
- }
- }
- break;
- case Tok_namespace:
- yyTokColonSeen = false;
- yyTok = getToken();
- if (yyTok == Tok_Ident) {
- QString ns = yyIdent;
- yyTok = getToken();
- if (yyTok == Tok_LeftBrace) {
- if (yyBraceDepth == namespaces.count() + 1) {
- namespaces.append(ns);
- allNamespaces.insert(namespaces.join(strColons));
- }
- } else if (yyTok == Tok_Equals) {
- // e.g. namespace Is = OuterSpace::InnerSpace;
- QStringList alias = namespaces;
- alias.append(ns);
- QStringList fullName;
- yyTok = getToken();
- if (yyTok == Tok_ColonColon)
- fullName.append(QString());
- while (yyTok == Tok_ColonColon || yyTok == Tok_Ident) {
- if (yyTok == Tok_Ident)
- fullName.append(yyIdent);
- yyTok = getToken();
- }
- namespaceAliases[alias.join(strColons)] =
- getFullyQualifiedNamespaceName(allNamespaces, namespaces, namespaceAliases, fullName);
- }
- }
- break;
- case Tok_tr:
- case Tok_trUtf8:
- utf8 = (yyTok == Tok_trUtf8);
- line = yyLineNo;
- yyTok = getToken();
- if (match(Tok_LeftParen) && matchString(&text) && !text.isEmpty()) {
- comment.clear();
- bool plural = false;
-
- if (match(Tok_RightParen)) {
- // no comment
- } else if (match(Tok_Comma) && matchStringOrNull(&comment)) { //comment
- if (match(Tok_RightParen)) {
- // ok,
- } else if (match(Tok_Comma)) {
- plural = true;
- }
- }
- if (prefix.isEmpty()) {
- context = functionContext;
- } else {
-#ifdef DIAGNOSE_RETRANSLATABILITY
- 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());
- }
-#endif
- prefix.chop(2);
- context = getFullyQualifiedClassName(allClasses, namespaces, namespaceAliases, prefix, true);
- }
- prefix.clear();
- if (qualifiedContexts.contains(context))
- context = qualifiedContexts[context];
-
- if (!text.isEmpty())
- recordMessage(tor, line, context, text, comment, extracomment, utf8, plural);
-
- if (lacks_Q_OBJECT.contains(context)) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(context));
- lacks_Q_OBJECT.remove(context);
- } else {
- needs_Q_OBJECT.insert(context);
- }
- }
- extracomment.clear();
- break;
- case Tok_translateUtf8:
- case Tok_translate:
- utf8 = (yyTok == Tok_translateUtf8);
- line = yyLineNo;
- yyTok = getToken();
- if (match(Tok_LeftParen)
- && matchString(&context)
- && match(Tok_Comma)
- && matchString(&text))
- {
- comment.clear();
- bool plural = false;
- if (!match(Tok_RightParen)) {
- // look for comment
- if (match(Tok_Comma) && matchStringOrNull(&comment)) {
- if (!match(Tok_RightParen)) {
- // look for encoding
- if (match(Tok_Comma)) {
- if (matchEncoding(&utf8)) {
- if (!match(Tok_RightParen)) {
- // look for the plural quantifier,
- // this can be a number, an identifier or
- // a function call,
- // so for simplicity we mark it as plural if
- // we know we have a comma instead of an
- // right parentheses.
- plural = match(Tok_Comma);
- }
- } else {
- // This can be a QTranslator::translate("context",
- // "source", "comment", n) plural translation
- if (matchExpression() && match(Tok_RightParen)) {
- plural = true;
- } else {
- break;
- }
- }
- } else {
- break;
- }
- }
- } else {
- break;
- }
- }
- if (!text.isEmpty())
- recordMessage(tor, line, context, text, comment, extracomment, utf8, plural);
- }
- extracomment.clear();
- break;
- case Tok_Q_DECLARE_TR_FUNCTIONS:
- case Tok_Q_OBJECT:
- missing_Q_OBJECT = false;
- yyTok = getToken();
- break;
- case Tok_Ident:
- prefix += yyIdent;
- yyTok = getToken();
- if (yyTok != Tok_ColonColon)
- prefix.clear();
- break;
- case Tok_Comment:
- if (yyComment.startsWith(QLatin1Char(':'))) {
- yyComment.remove(0, 1);
- extracomment.append(yyComment);
- } else {
- comment = yyComment.simplified();
- if (comment.startsWith(QLatin1String(MagicComment))) {
- comment.remove(0, sizeof(MagicComment) - 1);
- int k = comment.indexOf(QLatin1Char(' '));
- if (k == -1) {
- context = comment;
- } else {
- context = comment.left(k);
- comment.remove(0, k + 1);
- recordMessage(tor, yyLineNo, context, QString(), comment, extracomment, false, false);
- }
-
- /*
- Provide a backdoor for people using "using
- namespace". See the manual for details.
- */
- k = 0;
- while ((k = context.indexOf(strColons, k)) != -1) {
- qualifiedContexts.insert(context.mid(k + 2), context);
- k++;
- }
- }
- }
- yyTok = getToken();
- break;
- case Tok_Arrow:
- yyTok = getToken();
- if (yyTok == Tok_tr || yyTok == Tok_trUtf8)
- qWarning("%s:%d: Cannot invoke tr() like this",
- qPrintable(yyFileName), yyLineNo);
- break;
- case Tok_ColonColon:
- if (yyBraceDepth == namespaces.count() && yyParenDepth == 0 && !yyTokColonSeen)
- functionContext = getFullyQualifiedClassName(allClasses, namespaces, namespaceAliases, prefix, false);
- prefix += strColons;
- yyTok = getToken();
-#ifdef DIAGNOSE_RETRANSLATABILITY
- if (yyTok == Tok_Ident && yyBraceDepth == namespaces.count() && yyParenDepth == 0)
- functionName = yyIdent;
-#endif
- break;
- case Tok_RightBrace:
- case Tok_Semicolon:
- prefix.clear();
- extracomment.clear();
- yyTokColonSeen = false;
- if (yyBraceDepth >= 0 && yyBraceDepth + 1 == namespaces.count())
- namespaces.removeLast();
- if (yyBraceDepth == namespaces.count()) {
- if (missing_Q_OBJECT) {
- if (needs_Q_OBJECT.contains(functionContext)) {
- qWarning("%s:%d: Class '%s' lacks Q_OBJECT macro",
- qPrintable(yyFileName), yyLineNo,
- qPrintable(functionContext));
- } else {
- lacks_Q_OBJECT.insert(functionContext);
- }
- }
- functionContext = defaultContext;
- missing_Q_OBJECT = false;
- }
- yyTok = getToken();
- break;
- case Tok_Colon:
- yyTokColonSeen = true;
- yyTok = getToken();
- break;
- case Tok_LeftParen:
- case Tok_RightParen:
- case Tok_LeftBrace:
- yyTokColonSeen = false;
- yyTok = getToken();
- break;
- default:
- yyTok = getToken();
- break;
- }
- }
-
- if (yyBraceDepth != 0)
- qWarning("%s:%d: Unbalanced braces in C++ code (or abuse of the C++"
- " preprocessor)\n",
- qPrintable(yyFileName), yyBraceLineNo);
- else if (yyParenDepth != 0)
- qWarning("%s:%d: Unbalanced parentheses in C++ code (or abuse of the C++"
- " preprocessor)\n",
- qPrintable(yyFileName), yyParenLineNo);
-}
-
-/*
- Fetches tr() calls in C++ code in UI files (inside "<function>"
- tag). This mechanism is obsolete.
-*/
-void fetchtrInlinedCpp(const QString &in, Translator &translator, const QString &context)
-{
- yyInStr = in;
- yyInPos = 0;
- yyFileName = QString();
- yyCodecIsUtf8 = (translator.codecName() == "UTF-8");
- yyForceUtf8 = true;
- yySourceIsUnicode = true;
- yySavedBraceDepth.clear();
- yySavedParenDepth.clear();
- yyBraceDepth = 0;
- yyParenDepth = 0;
- yyCurLineNo = 1;
- yyBraceLineNo = 1;
- yyParenLineNo = 1;
- yyCh = getChar();
-
- parse(&translator, context, QString());
-}
-
-
-bool loadCPP(Translator &translator, QIODevice &dev, ConversionData &cd)
-{
- QString defaultContext = cd.m_defaultContext;
-
- yyCodecIsUtf8 = (translator.codecName() == "UTF-8");
- yyForceUtf8 = false;
- QTextStream ts(&dev);
- QByteArray codecName = cd.m_codecForSource.isEmpty()
- ? translator.codecName() : cd.m_codecForSource;
- ts.setCodec(QTextCodec::codecForName(codecName));
- ts.setAutoDetectUnicode(true);
- yySourceCodec = ts.codec();
- if (yySourceCodec->name() == "UTF-16")
- translator.setCodecName("System");
- yySourceIsUnicode = yySourceCodec->name().startsWith("UTF-");
- yyInStr = ts.readAll();
- yyInPos = 0;
- yyFileName = cd.m_sourceFileName;
- yySavedBraceDepth.clear();
- yySavedParenDepth.clear();
- yyBraceDepth = 0;
- yyParenDepth = 0;
- yyCurLineNo = 1;
- yyBraceLineNo = 1;
- yyParenLineNo = 1;
- yyCh = getChar();
-
- parse(&translator, defaultContext, defaultContext);
-
- return true;
-}
-
-int initCPP()
-{
- Translator::FileFormat format;
- format.extension = QLatin1String("cpp");
- format.fileType = Translator::FileFormat::SourceCode;
- format.priority = 0;
- format.description = QObject::tr("C++ source files");
- format.loader = &loadCPP;
- format.saver = 0;
- Translator::registerFileFormat(format);
- return 1;
-}
-
-Q_CONSTRUCTOR_FUNCTION(initCPP)
-
-QT_END_NAMESPACE
diff --git a/tools/linguist/shared/formats.pri b/tools/linguist/shared/formats.pri
index 9c8072b..985f6db 100644
--- a/tools/linguist/shared/formats.pri
+++ b/tools/linguist/shared/formats.pri
@@ -19,8 +19,4 @@ SOURCES += \
$$PWD/qph.cpp \
$$PWD/po.cpp \
$$PWD/ts.cpp \
- $$PWD/ui.cpp \
- $$PWD/cpp.cpp \
- $$PWD/java.cpp \
- $$PWD/qscript.cpp \
$$PWD/xliff.cpp
diff --git a/tools/linguist/shared/make-qscript.sh b/tools/linguist/shared/make-qscript.sh
deleted file mode 100755
index 42cab7a..0000000
--- a/tools/linguist/shared/make-qscript.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-
-me=$(dirname $0)
-mkdir -p $me/out
-(cd $me/out && ${QLALR-qlalr} --no-debug --troll --no-lines ../qscript.g)
-
-for f in $me/out/*.{h,cpp}; do
- n=$(basename $f)
- p4 open $me/../$n
- cp $f $me/../$n
-done
-
-p4 revert -a $me/../...
-p4 diff -du $me/../...
diff --git a/tools/linguist/shared/po.cpp b/tools/linguist/shared/po.cpp
index cb943be..e22aa7d 100644
--- a/tools/linguist/shared/po.cpp
+++ b/tools/linguist/shared/po.cpp
@@ -395,7 +395,10 @@ bool loadPO(Translator &translator, QIODevice &dev, ConversionData &cd)
const QString prefix = QLatin1String(isObsolete ? "#~ " : "");
while (true) {
int idx = line.indexOf(QLatin1Char(' '), prefix.length());
- item.msgStr.append(slurpEscapedString(lines, l, idx, prefix, cd));
+ QString str = slurpEscapedString(lines, l, idx, prefix, cd);
+ str.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
+ item.msgStr.append(str);
if (l + 1 >= lines.size() || !isTranslationLine(lines.at(l + 1)))
break;
++l;
@@ -635,8 +638,11 @@ bool savePO(const Translator &translator, QIODevice &dev, ConversionData &cd)
out << poEscapedString(prefix, QLatin1String("msgid_plural"), noWrap, plural);
QStringList translations = translator.normalizedTranslations(msg, cd, &ok);
for (int i = 0; i != translations.size(); ++i) {
+ QString str = translations.at(i);
+ str.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
out << poEscapedString(prefix, QString::fromLatin1("msgstr[%1]").arg(i), noWrap,
- translations.at(i));
+ str);
}
}
first = false;
diff --git a/tools/linguist/shared/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp
index 4ea9c10..a962152 100644
--- a/tools/linguist/shared/profileevaluator.cpp
+++ b/tools/linguist/shared/profileevaluator.cpp
@@ -44,6 +44,7 @@
#include "proitems.h"
#include <QtCore/QByteArray>
+#include <QtCore/QDateTime>
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QFile>
@@ -56,6 +57,15 @@
#include <QtCore/QStringList>
#include <QtCore/QTextStream>
+#ifdef Q_OS_UNIX
+#include <unistd.h>
+#include <sys/utsname.h>
+#elif defined(Q_OS_WIN32)
+#include <Windows.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+
#ifdef Q_OS_WIN32
#define QT_POPEN _popen
#define QT_PCLOSE _pclose
@@ -68,6 +78,58 @@ QT_BEGIN_NAMESPACE
///////////////////////////////////////////////////////////////////////
//
+// Option
+//
+///////////////////////////////////////////////////////////////////////
+
+QString
+Option::fixString(QString string, uchar flags)
+{
+ // XXX Ripped out caching, so this will be slow. Should not matter for current uses.
+
+ //fix the environment variables
+ if (flags & Option::FixEnvVars) {
+ int rep;
+ QRegExp reg_variableName(QLatin1String("\\$\\(.*\\)"));
+ reg_variableName.setMinimal(true);
+ while ((rep = reg_variableName.indexIn(string)) != -1)
+ string.replace(rep, reg_variableName.matchedLength(),
+ QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_variableName.matchedLength() - 3).toLatin1().constData()).constData()));
+ }
+
+ //canonicalize it (and treat as a path)
+ if (flags & Option::FixPathCanonicalize) {
+#if 0
+ string = QFileInfo(string).canonicalFilePath();
+#endif
+ string = QDir::cleanPath(string);
+ }
+
+ if (string.length() > 2 && string[0].isLetter() && string[1] == QLatin1Char(':'))
+ string[0] = string[0].toLower();
+
+ //fix separators
+ Q_ASSERT(!((flags & Option::FixPathToLocalSeparators) && (flags & Option::FixPathToTargetSeparators)));
+ if (flags & Option::FixPathToLocalSeparators) {
+#if defined(Q_OS_WIN32)
+ string = string.replace(QLatin1Char('/'), QLatin1Char('\\'));
+#else
+ string = string.replace(QLatin1Char('\\'), QLatin1Char('/'));
+#endif
+ } else if (flags & Option::FixPathToTargetSeparators) {
+ string = string.replace(QLatin1Char('/'), Option::dir_sep)
+ .replace(QLatin1Char('\\'), Option::dir_sep);
+ }
+
+ if ((string.startsWith(QLatin1Char('"')) && string.endsWith(QLatin1Char('"'))) ||
+ (string.startsWith(QLatin1Char('\'')) && string.endsWith(QLatin1Char('\''))))
+ string = string.mid(1, string.length() - 2);
+
+ return string;
+}
+
+///////////////////////////////////////////////////////////////////////
+//
// ProFileEvaluator::Private
//
///////////////////////////////////////////////////////////////////////
@@ -77,6 +139,12 @@ class ProFileEvaluator::Private : public AbstractProItemVisitor
public:
Private(ProFileEvaluator *q_);
+ ProFileEvaluator *q;
+ int m_lineNo; // Error reporting
+ bool m_verbose;
+
+ /////////////// Reading pro file
+
bool read(ProFile *pro);
ProBlock *currentBlock();
@@ -89,6 +157,19 @@ public:
void leaveScope();
void finalizeBlock();
+ QStack<ProBlock *> m_blockstack;
+ ProBlock *m_block;
+
+ ProItem *m_commentItem;
+ QString m_proitem;
+ QString m_pendingComment;
+ bool m_syntaxError;
+ bool m_contNextLine;
+ bool m_inQuote;
+ int m_parens;
+
+ /////////////// Evaluating pro file contents
+
// implementation of AbstractProItemVisitor
bool visitBeginProBlock(ProBlock *block);
bool visitEndProBlock(ProBlock *block);
@@ -104,6 +185,8 @@ public:
QStringList valuesDirect(const QString &variableName) const { return m_valuemap[variableName]; }
QStringList values(const QString &variableName) const;
QStringList values(const QString &variableName, const ProFile *pro) const;
+ QStringList values(const QString &variableName, const QHash<QString, QStringList> &place,
+ const ProFile *pro) const;
QString propertyValue(const QString &val) const;
bool isActiveConfig(const QString &config, bool regex = false);
@@ -115,7 +198,7 @@ public:
QString format(const char *format) const;
QString currentFileName() const;
- QString getcwd() const;
+ QString currentDirectory() const;
ProFile *currentProFile() const;
bool evaluateConditionalFunction(const QString &function, const QString &arguments, bool *result);
@@ -124,41 +207,51 @@ public:
QStringList qmakeFeaturePaths();
- ProFileEvaluator *q;
-
- QStack<ProBlock *> m_blockstack;
- ProBlock *m_block;
-
- ProItem *m_commentItem;
- QString m_proitem;
- QString m_pendingComment;
- bool m_syntaxError;
- bool m_contNextLine;
- bool m_condition;
+ enum { ConditionTrue, ConditionFalse, ConditionElse };
+ int m_condition;
+ int m_prevCondition;
+ bool m_updateCondition;
bool m_invertNext;
+ int m_skipLevel;
+ bool m_cumulative;
+ bool m_isFirstVariableValue;
QString m_lastVarName;
ProVariable::VariableOperator m_variableOperator;
- int m_lineNo; // Error reporting
+ QString m_origfile;
QString m_oldPath; // To restore the current path to the path
QStack<ProFile*> m_profileStack; // To handle 'include(a.pri), so we can track back to 'a.pro' when finished with 'a.pri'
+ // we need the following two variables for handling
+ // CONFIG = foo bar $$CONFIG
+ QHash<QString, QStringList> m_tempValuemap; // used while evaluating (variable operator value1 value2 ...)
+ QHash<const ProFile*, QHash<QString, QStringList> > m_tempFilevaluemap; // used while evaluating (variable operator value1 value2 ...)
+
QHash<QString, QStringList> m_valuemap; // VariableName must be us-ascii, the content however can be non-us-ascii.
QHash<const ProFile*, QHash<QString, QStringList> > m_filevaluemap; // Variables per include file
QHash<QString, QString> m_properties;
- QString m_origfile;
+ QString m_outputDir;
int m_prevLineNo; // Checking whether we're assigning the same TARGET
ProFile *m_prevProFile; // See m_prevLineNo
-
- bool m_verbose;
};
ProFileEvaluator::Private::Private(ProFileEvaluator *q_)
: q(q_)
{
+ // Global parser state
m_prevLineNo = 0;
m_prevProFile = 0;
+
+ // Configuration, more or less
m_verbose = true;
+ m_cumulative = true;
+
+ // Evaluator state
+ m_updateCondition = false;
+ m_condition = ConditionFalse;
+ m_invertNext = false;
+ m_skipLevel = 0;
+ m_isFirstVariableValue = true;
}
bool ProFileEvaluator::Private::read(ProFile *pro)
@@ -169,8 +262,11 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
return false;
}
+ // Parser state
m_block = 0;
m_commentItem = 0;
+ m_inQuote = false;
+ m_parens = 0;
m_contNextLine = false;
m_syntaxError = false;
m_lineNo = 1;
@@ -194,71 +290,84 @@ bool ProFileEvaluator::Private::parseLine(const QString &line0)
if (m_blockstack.isEmpty())
return false;
- ushort quote = 0;
- int parens = 0;
- bool contNextLine = false;
+ int parens = m_parens;
+ bool inQuote = m_inQuote;
+ bool escaped = false;
QString line = line0.simplified();
for (int i = 0; !m_syntaxError && i < line.length(); ++i) {
ushort c = line.at(i).unicode();
- if (quote && c == quote)
- quote = 0;
- else if (c == '(')
- ++parens;
- else if (c == ')')
- --parens;
- else if (c == '"' && (i == 0 || line.at(i - 1).unicode() != '\\'))
- quote = c;
- else if (!parens && !quote) {
- if (c == '#') {
- insertComment(line.mid(i + 1));
- contNextLine = m_contNextLine;
- break;
- }
- if (c == '\\' && i >= line.count() - 1) {
- updateItem();
- contNextLine = true;
- continue;
- }
- if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
- if (c == ' ')
- updateItem();
- else
- m_proitem += c;
- continue;
- }
- if (c == ':') {
- enterScope(false);
- continue;
- }
- if (c == '{') {
- enterScope(true);
- continue;
- }
- if (c == '}') {
- leaveScope();
+ if (c == '#') { // Yep - no escaping possible
+ insertComment(line.mid(i + 1));
+ escaped = m_contNextLine;
+ break;
+ }
+ if (!escaped) {
+ if (c == '\\') {
+ escaped = true;
+ m_proitem += c;
continue;
- }
- if (c == '=') {
- insertVariable(line, &i);
+ } else if (c == '"') {
+ inQuote = !inQuote;
+ m_proitem += c;
continue;
}
- if (c == '|' || c == '!') {
- insertOperator(c);
- continue;
+ } else {
+ escaped = false;
+ }
+ if (!inQuote) {
+ if (c == '(') {
+ ++parens;
+ } else if (c == ')') {
+ --parens;
+ } else if (!parens) {
+ if (m_block && (m_block->blockKind() & ProBlock::VariableKind)) {
+ if (c == ' ')
+ updateItem();
+ else
+ m_proitem += c;
+ continue;
+ }
+ if (c == ':') {
+ enterScope(false);
+ continue;
+ }
+ if (c == '{') {
+ enterScope(true);
+ continue;
+ }
+ if (c == '}') {
+ leaveScope();
+ continue;
+ }
+ if (c == '=') {
+ insertVariable(line, &i);
+ continue;
+ }
+ if (c == '|' || c == '!') {
+ insertOperator(c);
+ continue;
+ }
}
}
m_proitem += c;
}
- m_contNextLine = contNextLine;
-
- if (!m_syntaxError) {
+ m_inQuote = inQuote;
+ m_parens = parens;
+ m_contNextLine = escaped;
+ if (escaped) {
+ m_proitem.chop(1);
updateItem();
- if (!m_contNextLine)
+ return true;
+ } else {
+ if (!m_syntaxError) {
+ updateItem();
finalizeBlock();
+ return true;
+ }
+ return false;
}
- return !m_syntaxError;
}
void ProFileEvaluator::Private::finalizeBlock()
@@ -457,15 +566,35 @@ void ProFileEvaluator::Private::updateItem()
bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block)
{
if (block->blockKind() == ProBlock::ScopeKind) {
- m_invertNext = false;
- m_condition = false;
+ m_updateCondition = true;
+ if (!m_skipLevel) {
+ m_prevCondition = m_condition;
+ m_condition = ConditionFalse;
+ } else {
+ Q_ASSERT(m_condition != ConditionTrue);
+ }
+ } else if (block->blockKind() & ProBlock::ScopeContentsKind) {
+ m_updateCondition = false;
+ if (m_condition != ConditionTrue)
+ ++m_skipLevel;
+ else
+ Q_ASSERT(!m_skipLevel);
}
return true;
}
bool ProFileEvaluator::Private::visitEndProBlock(ProBlock *block)
{
- Q_UNUSED(block);
+ if (block->blockKind() & ProBlock::ScopeContentsKind) {
+ if (m_skipLevel) {
+ Q_ASSERT(m_condition != ConditionTrue);
+ --m_skipLevel;
+ } else {
+ // Conditionals contained inside this block may have changed the state.
+ // So we reset it here to make an else following us do the right thing.
+ m_condition = ConditionTrue;
+ }
+ }
return true;
}
@@ -473,12 +602,17 @@ bool ProFileEvaluator::Private::visitBeginProVariable(ProVariable *variable)
{
m_lastVarName = variable->variable();
m_variableOperator = variable->variableOperator();
+ m_isFirstVariableValue = true;
+ m_tempValuemap = m_valuemap;
+ m_tempFilevaluemap = m_filevaluemap;
return true;
}
bool ProFileEvaluator::Private::visitEndProVariable(ProVariable *variable)
{
Q_UNUSED(variable);
+ m_valuemap = m_tempValuemap;
+ m_filevaluemap = m_tempFilevaluemap;
m_lastVarName.clear();
return true;
}
@@ -491,12 +625,20 @@ bool ProFileEvaluator::Private::visitProOperator(ProOperator *oper)
bool ProFileEvaluator::Private::visitProCondition(ProCondition *cond)
{
- if (!m_condition) {
- if (m_invertNext)
- m_condition |= !isActiveConfig(cond->text(), true);
- else
- m_condition |= isActiveConfig(cond->text(), true);
+ if (!m_skipLevel) {
+ if (cond->text().toLower() == QLatin1String("else")) {
+ // The state ConditionElse makes sure that subsequential elses are ignored.
+ // That's braindead, but qmake is like that.
+ if (m_prevCondition == ConditionTrue)
+ m_condition = ConditionElse;
+ else if (m_prevCondition == ConditionFalse)
+ m_condition = ConditionTrue;
+ } else if (m_condition == ConditionFalse) {
+ if (isActiveConfig(cond->text(), true) ^ m_invertNext)
+ m_condition = ConditionTrue;
+ }
}
+ m_invertNext = false;
return true;
}
@@ -505,18 +647,32 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro)
PRE(pro);
bool ok = true;
m_lineNo = pro->lineNumber();
+
+ if (m_origfile.isEmpty())
+ m_origfile = pro->fileName();
if (m_oldPath.isEmpty()) {
// change the working directory for the initial profile we visit, since
// that is *the* profile. All the other times we reach this function will be due to
// include(file) or load(file)
+
m_oldPath = QDir::currentPath();
+
m_profileStack.push(pro);
+
+ const QString mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
+ if (!mkspecDirectory.isEmpty()) {
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+ // This is what qmake does, everything set in the mkspec is also set
+ // But this also creates a lot of problems
+ evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok);
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok);
+ m_cumulative = cumulative;
+ }
+
ok = QDir::setCurrent(pro->directoryName());
}
- if (m_origfile.isEmpty())
- m_origfile = pro->fileName();
-
return ok;
}
@@ -526,12 +682,60 @@ bool ProFileEvaluator::Private::visitEndProFile(ProFile * pro)
bool ok = true;
m_lineNo = pro->lineNumber();
if (m_profileStack.count() == 1 && !m_oldPath.isEmpty()) {
+ const QString &mkspecDirectory = propertyValue(QLatin1String("QMAKE_MKSPECS"));
+ if (!mkspecDirectory.isEmpty()) {
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+
+ evaluateFile(mkspecDirectory + QLatin1String("/features/default_post.prf"), &ok);
+
+ QSet<QString> processed;
+ forever {
+ bool finished = true;
+ QStringList configs = valuesDirect(QLatin1String("CONFIG"));
+ for (int i = configs.size() - 1; i >= 0; --i) {
+ const QString config = configs[i].toLower();
+ if (!processed.contains(config)) {
+ processed.insert(config);
+ evaluateFile(mkspecDirectory + QLatin1String("/features/")
+ + config + QLatin1String(".prf"), &ok);
+ if (ok) {
+ finished = false;
+ break;
+ }
+ }
+ }
+ if (finished)
+ break;
+ }
+
+ m_cumulative = cumulative;
+ }
+
m_profileStack.pop();
ok = QDir::setCurrent(m_oldPath);
}
return ok;
}
+static void replaceInList(QStringList *varlist,
+ const QRegExp &regexp, const QString &replace, bool global)
+{
+ for (QStringList::Iterator varit = varlist->begin(); varit != varlist->end(); ) {
+ if ((*varit).contains(regexp)) {
+ (*varit).replace(regexp, replace);
+ if ((*varit).isEmpty())
+ varit = varlist->erase(varit);
+ else
+ ++varit;
+ if(!global)
+ break;
+ } else {
+ ++varit;
+ }
+ }
+}
+
bool ProFileEvaluator::Private::visitProValue(ProValue *value)
{
PRE(value);
@@ -549,8 +753,8 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
if (varName == QLatin1String("TARGET")
&& m_lineNo == m_prevLineNo
&& currentProFile() == m_prevProFile) {
- QStringList targets = m_valuemap.value(QLatin1String("TARGET"));
- m_valuemap.remove(QLatin1String("TARGET"));
+ QStringList targets = m_tempValuemap.value(QLatin1String("TARGET"));
+ m_tempValuemap.remove(QLatin1String("TARGET"));
QStringList lastTarget(targets.takeLast());
lastTarget << v.join(QLatin1String(" "));
targets.push_back(lastTarget.join(QLatin1String(" ")));
@@ -583,37 +787,58 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
}
switch (m_variableOperator) {
- case ProVariable::UniqueAddOperator: // *
- insertUnique(&m_valuemap, varName, v, true);
- insertUnique(&m_filevaluemap[currentProFile()], varName, v, true);
- break;
case ProVariable::SetOperator: // =
- case ProVariable::AddOperator: // +
- insertUnique(&m_valuemap, varName, v, false);
- insertUnique(&m_filevaluemap[currentProFile()], varName, v, false);
+ if (!m_cumulative) {
+ if (!m_skipLevel) {
+ if (m_isFirstVariableValue) {
+ m_tempValuemap[varName] = v;
+ m_tempFilevaluemap[currentProFile()][varName] = v;
+ } else { // handle lines "CONFIG = foo bar"
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
+ }
+ } else {
+ // We are greedy for values.
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
break;
- case ProVariable::RemoveOperator: // -
- // fix me: interaction between AddOperator and RemoveOperator
- insertUnique(&m_valuemap, varName.prepend(QLatin1Char('-')), v, false);
- insertUnique(&m_filevaluemap[currentProFile()],
- varName.prepend(QLatin1Char('-')), v, false);
+ case ProVariable::UniqueAddOperator: // *=
+ if (!m_skipLevel || m_cumulative) {
+ insertUnique(&m_tempValuemap, varName, v);
+ insertUnique(&m_tempFilevaluemap[currentProFile()], varName, v);
+ }
+ break;
+ case ProVariable::AddOperator: // +=
+ if (!m_skipLevel || m_cumulative) {
+ m_tempValuemap[varName] += v;
+ m_tempFilevaluemap[currentProFile()][varName] += v;
+ }
+ break;
+ case ProVariable::RemoveOperator: // -=
+ if (!m_cumulative) {
+ if (!m_skipLevel) {
+ removeEach(&m_tempValuemap, varName, v);
+ removeEach(&m_tempFilevaluemap[currentProFile()], varName, v);
+ }
+ } else {
+ // We are stingy with our values, too.
+ }
break;
- case ProVariable::ReplaceOperator: // ~
+ case ProVariable::ReplaceOperator: // ~=
{
// DEFINES ~= s/a/b/?[gqi]
-/* Create a superset by executing replacement + adding items that have changed
- to original list. We're not sure if this is really the right approach, so for
- the time being we will just do nothing ...
-
+ // FIXME: qmake variable-expands val first.
+ if (val.length() < 4 || val[0] != QLatin1Char('s')) {
+ q->logMessage(format("the ~= operator can handle only the s/// function."));
+ return false;
+ }
QChar sep = val.at(1);
QStringList func = val.split(sep);
if (func.count() < 3 || func.count() > 4) {
- q->logMessage(format("'~= operator '(function s///) expects 3 or 4 arguments."));
- return false;
- }
- if (func[0] != QLatin1String("s")) {
- q->logMessage(format("~= operator can only handle s/// function."));
+ q->logMessage(format("the s/// function expects 3 or 4 arguments."));
return false;
}
@@ -630,40 +855,40 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value)
QRegExp regexp(pattern, case_sense ? Qt::CaseSensitive : Qt::CaseInsensitive);
- QStringList replaceList = replaceInList(m_valuemap.value(varName), regexp, replace,
- global);
- // Add changed entries to list
- foreach (const QString &entry, replaceList)
- if (!m_valuemap.value(varName).contains(entry))
- insertUnique(&m_valuemap, varName, QStringList() << entry, false);
-
- replaceList = replaceInList(m_filevaluemap[currentProFile()].value(varName), regexp,
- replace, global);
- foreach (const QString &entry, replaceList)
- if (!m_filevaluemap[currentProFile()].value(varName).contains(entry))
- insertUnique(&m_filevaluemap[currentProFile()], varName,
- QStringList() << entry, false); */
+ if (!m_skipLevel || m_cumulative) {
+ // We could make a union of modified and unmodified values,
+ // but this will break just as much as it fixes, so leave it as is.
+ replaceInList(&m_tempValuemap[varName], regexp, replace, global);
+ replaceInList(&m_tempFilevaluemap[currentProFile()][varName], regexp, replace, global);
+ }
}
break;
}
+ m_isFirstVariableValue = false;
return true;
}
bool ProFileEvaluator::Private::visitProFunction(ProFunction *func)
{
- m_lineNo = func->lineNumber();
- bool result = true;
- bool ok = true;
- QString text = func->text();
- int lparen = text.indexOf(QLatin1Char('('));
- int rparen = text.lastIndexOf(QLatin1Char(')'));
- Q_ASSERT(lparen < rparen);
-
- QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
- QString funcName = text.left(lparen);
- ok &= evaluateConditionalFunction(funcName.trimmed(), arguments, &result);
- return ok;
+ if (!m_updateCondition || m_condition == ConditionFalse) {
+ QString text = func->text();
+ int lparen = text.indexOf(QLatin1Char('('));
+ int rparen = text.lastIndexOf(QLatin1Char(')'));
+ Q_ASSERT(lparen < rparen);
+ QString arguments = text.mid(lparen + 1, rparen - lparen - 1);
+ QString funcName = text.left(lparen);
+ m_lineNo = func->lineNumber();
+ bool result;
+ if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result)) {
+ m_invertNext = false;
+ return false;
+ }
+ if (!m_skipLevel && (result ^ m_invertNext))
+ m_condition = ConditionTrue;
+ }
+ m_invertNext = false;
+ return true;
}
@@ -671,7 +896,7 @@ QStringList ProFileEvaluator::Private::qmakeFeaturePaths()
{
QStringList concat;
{
- const QString base_concat = QDir::separator() + QString(QLatin1String("features"));
+ const QString base_concat = QDir::separator() + QLatin1String("features");
concat << base_concat + QDir::separator() + QLatin1String("mac");
concat << base_concat + QDir::separator() + QLatin1String("macx");
concat << base_concat + QDir::separator() + QLatin1String("unix");
@@ -680,7 +905,7 @@ QStringList ProFileEvaluator::Private::qmakeFeaturePaths()
concat << base_concat + QDir::separator() + QLatin1String("qnx6");
concat << base_concat;
}
- const QString mkspecs_concat = QDir::separator() + QString(QLatin1String("mkspecs"));
+ const QString mkspecs_concat = QDir::separator() + QLatin1String("mkspecs");
QStringList feature_roots;
QByteArray mkspec_path = qgetenv("QMAKEFEATURES");
if (!mkspec_path.isNull())
@@ -783,7 +1008,7 @@ QString ProFileEvaluator::Private::currentFileName() const
return QString();
}
-QString ProFileEvaluator::Private::getcwd() const
+QString ProFileEvaluator::Private::currentDirectory() const
{
ProFile *cur = m_profileStack.top();
return cur->directoryName();
@@ -1020,29 +1245,29 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
static QHash<QString, int> *expands = 0;
if (!expands) {
expands = new QHash<QString, int>;
- expands->insert(QLatin1String("member"), E_MEMBER); //v (implemented)
- expands->insert(QLatin1String("first"), E_FIRST); //v
- expands->insert(QLatin1String("last"), E_LAST); //v
+ expands->insert(QLatin1String("member"), E_MEMBER);
+ expands->insert(QLatin1String("first"), E_FIRST);
+ expands->insert(QLatin1String("last"), E_LAST);
expands->insert(QLatin1String("cat"), E_CAT);
- expands->insert(QLatin1String("fromfile"), E_FROMFILE);
+ expands->insert(QLatin1String("fromfile"), E_FROMFILE); // implementation disabled (see comment below)
expands->insert(QLatin1String("eval"), E_EVAL);
expands->insert(QLatin1String("list"), E_LIST);
expands->insert(QLatin1String("sprintf"), E_SPRINTF);
- expands->insert(QLatin1String("join"), E_JOIN); //v
- expands->insert(QLatin1String("split"), E_SPLIT); //v
- expands->insert(QLatin1String("basename"), E_BASENAME); //v
- expands->insert(QLatin1String("dirname"), E_DIRNAME); //v
+ expands->insert(QLatin1String("join"), E_JOIN);
+ expands->insert(QLatin1String("split"), E_SPLIT);
+ expands->insert(QLatin1String("basename"), E_BASENAME);
+ expands->insert(QLatin1String("dirname"), E_DIRNAME);
expands->insert(QLatin1String("section"), E_SECTION);
expands->insert(QLatin1String("find"), E_FIND);
- expands->insert(QLatin1String("system"), E_SYSTEM); //v
+ expands->insert(QLatin1String("system"), E_SYSTEM);
expands->insert(QLatin1String("unique"), E_UNIQUE);
- expands->insert(QLatin1String("quote"), E_QUOTE); //v
+ expands->insert(QLatin1String("quote"), E_QUOTE);
expands->insert(QLatin1String("escape_expand"), E_ESCAPE_EXPAND);
expands->insert(QLatin1String("upper"), E_UPPER);
expands->insert(QLatin1String("lower"), E_LOWER);
expands->insert(QLatin1String("re_escape"), E_RE_ESCAPE);
expands->insert(QLatin1String("files"), E_FILES);
- expands->insert(QLatin1String("prompt"), E_PROMPT);
+ expands->insert(QLatin1String("prompt"), E_PROMPT); // interactive, so cannot be implemented
expands->insert(QLatin1String("replace"), E_REPLACE);
}
ExpandFunc func_t = ExpandFunc(expands->value(func.toLower()));
@@ -1091,6 +1316,16 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
}
break;
}
+ case E_SPRINTF:
+ if(args.count() < 1) {
+ q->logMessage(format("sprintf(format, ...) requires at least one argument"));
+ } else {
+ QString tmp = args.at(0);
+ for (int i = 1; i < args.count(); ++i)
+ tmp = tmp.arg(args.at(i));
+ ret = split_value_list(tmp);
+ }
+ break;
case E_JOIN: {
if (args.count() < 1 || args.count() > 4) {
q->logMessage(format("join(var, glue, before, after) requires one to four arguments."));
@@ -1110,9 +1345,9 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
}
case E_SPLIT: {
if (args.count() != 2) {
- q->logMessage(format("split(var, sep) requires two arguments"));
+ q->logMessage(format("split(var, sep) requires one or two arguments"));
} else {
- QString sep = args.at(1);
+ const QString &sep = (args.count() == 2) ? args[1] : QString(Option::field_sep);
foreach (const QString &var, values(args.first()))
foreach (const QString &splt, var.split(sep))
ret.append(splt);
@@ -1183,8 +1418,82 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
}
break;
}
- case E_SYSTEM: {
- if (m_condition) {
+ case E_CAT:
+ if (args.count() < 1 || args.count() > 2) {
+ q->logMessage(format("cat(file, singleline=true) requires one or two arguments."));
+ } else {
+ QString file = args[0];
+ file = Option::fixPathToLocalOS(file);
+
+ bool singleLine = true;
+ if (args.count() > 1)
+ singleLine = (args[1].toLower() == QLatin1String("true"));
+
+ QFile qfile(file);
+ if (qfile.open(QIODevice::ReadOnly)) {
+ QTextStream stream(&qfile);
+ while (!stream.atEnd()) {
+ ret += split_value_list(stream.readLine().trimmed());
+ if (!singleLine)
+ ret += QLatin1String("\n");
+ }
+ qfile.close();
+ }
+ }
+ break;
+#if 0 // Used only by Qt's configure for caching
+ case E_FROMFILE:
+ if (args.count() != 2) {
+ q->logMessage(format("fromfile(file, variable) requires two arguments."));
+ } else {
+ QString file = args[0], seek_variableName = args[1];
+
+ ProFile pro(Option::fixPathToLocalOS(file));
+
+ ProFileEvaluator visitor;
+ visitor.setVerbose(m_verbose);
+ visitor.setCumulative(m_cumulative);
+
+ if (!visitor.queryProFile(&pro))
+ break;
+
+ if (!visitor.accept(&pro))
+ break;
+
+ ret = visitor.values(seek_variableName);
+ }
+ break;
+#endif
+ case E_EVAL: {
+ if (args.count() != 1) {
+ q->logMessage(format("eval(variable) requires one argument"));
+
+ } else {
+ ret += values(args.at(0));
+ }
+ break; }
+ case E_LIST: {
+ static int x = 0;
+ QString tmp;
+ tmp.sprintf(".QMAKE_INTERNAL_TMP_variableName_%d", x++);
+ ret = QStringList(tmp);
+ QStringList lst;
+ foreach (const QString &arg, args)
+ lst += split_value_list(arg);
+ m_valuemap[tmp] = lst;
+ break; }
+ case E_FIND:
+ if (args.count() != 2) {
+ q->logMessage(format("find(var, str) requires two arguments."));
+ } else {
+ QRegExp regx(args[1]);
+ foreach (const QString &val, values(args.first()))
+ if (regx.indexIn(val) != -1)
+ ret += val;
+ }
+ break;
+ case E_SYSTEM:
+ if (!m_skipLevel) {
if (args.count() < 1 || args.count() > 2) {
q->logMessage(format("system(execute) requires one or two arguments."));
} else {
@@ -1210,13 +1519,114 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
QT_PCLOSE(proc);
}
}
- break; }
+ break;
+ case E_UNIQUE:
+ if(args.count() != 1) {
+ q->logMessage(format("unique(var) requires one argument."));
+ } else {
+ foreach (const QString &var, values(args.first()))
+ if (!ret.contains(var))
+ ret.append(var);
+ }
+ break;
case E_QUOTE:
for (int i = 0; i < args.count(); ++i)
ret += QStringList(args.at(i));
break;
+ case E_ESCAPE_EXPAND:
+ for (int i = 0; i < args.size(); ++i) {
+ QChar *i_data = args[i].data();
+ int i_len = args[i].length();
+ for (int x = 0; x < i_len; ++x) {
+ if (*(i_data+x) == QLatin1Char('\\') && x < i_len-1) {
+ if (*(i_data+x+1) == QLatin1Char('\\')) {
+ ++x;
+ } else {
+ struct {
+ char in, out;
+ } mapped_quotes[] = {
+ { 'n', '\n' },
+ { 't', '\t' },
+ { 'r', '\r' },
+ { 0, 0 }
+ };
+ for (int i = 0; mapped_quotes[i].in; ++i) {
+ if (*(i_data+x+1) == QLatin1Char(mapped_quotes[i].in)) {
+ *(i_data+x) = QLatin1Char(mapped_quotes[i].out);
+ if (x < i_len-2)
+ memmove(i_data+x+1, i_data+x+2, (i_len-x-2)*sizeof(QChar));
+ --i_len;
+ break;
+ }
+ }
+ }
+ }
+ }
+ ret.append(QString(i_data, i_len));
+ }
+ break;
+ case E_RE_ESCAPE:
+ for (int i = 0; i < args.size(); ++i)
+ ret += QRegExp::escape(args[i]);
+ break;
+ case E_UPPER:
+ case E_LOWER:
+ for (int i = 0; i < args.count(); ++i)
+ if (func_t == E_UPPER)
+ ret += args[i].toUpper();
+ else
+ ret += args[i].toLower();
+ break;
+ case E_FILES:
+ if (args.count() != 1 && args.count() != 2) {
+ q->logMessage(format("files(pattern, recursive=false) requires one or two arguments"));
+ } else {
+ bool recursive = false;
+ if (args.count() == 2)
+ recursive = (args[1].toLower() == QLatin1String("true") || args[1].toInt());
+ QStringList dirs;
+ QString r = Option::fixPathToLocalOS(args[0]);
+ int slash = r.lastIndexOf(QDir::separator());
+ if (slash != -1) {
+ dirs.append(r.left(slash));
+ r = r.mid(slash+1);
+ } else {
+ dirs.append(QString());
+ }
+
+ const QRegExp regex(r, Qt::CaseSensitive, QRegExp::Wildcard);
+ for (int d = 0; d < dirs.count(); d++) {
+ QString dir = dirs[d];
+ if (!dir.isEmpty() && !dir.endsWith(Option::dir_sep))
+ dir += QLatin1Char('/');
+
+ QDir qdir(dir);
+ for (int i = 0; i < (int)qdir.count(); ++i) {
+ if (qdir[i] == QLatin1String(".") || qdir[i] == QLatin1String(".."))
+ continue;
+ QString fname = dir + qdir[i];
+ if (QFileInfo(fname).isDir()) {
+ if (recursive)
+ dirs.append(fname);
+ }
+ if (regex.exactMatch(qdir[i]))
+ ret += fname;
+ }
+ }
+ }
+ break;
+ case E_REPLACE:
+ if(args.count() != 3 ) {
+ q->logMessage(format("replace(var, before, after) requires three arguments"));
+ } else {
+ const QRegExp before(args[1]);
+ const QString after(args[2]);
+ foreach (QString val, values(args.first()))
+ ret += val.replace(before, after);
+ }
+ break;
case 0:
- q->logMessage(format("'%1' is not a function").arg(func));
+ q->logMessage(format("'%1' is not a recognized replace function").arg(func));
break;
default:
q->logMessage(format("Function '%1' is not implemented").arg(func));
@@ -1237,26 +1647,67 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
for (int i = 0; i < argumentsList.count(); ++i)
args += expandVariableReferences(argumentsList[i]).join(sep);
- enum ConditionFunc { CF_CONFIG = 1, CF_CONTAINS, CF_COUNT, CF_EXISTS, CF_INCLUDE,
- CF_LOAD, CF_ISEMPTY, CF_SYSTEM, CF_MESSAGE};
+ enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS,
+ T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM,
+ T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE,
+ T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF };
static QHash<QString, int> *functions = 0;
if (!functions) {
functions = new QHash<QString, int>;
- functions->insert(QLatin1String("load"), CF_LOAD); //v
- functions->insert(QLatin1String("include"), CF_INCLUDE); //v
- functions->insert(QLatin1String("message"), CF_MESSAGE); //v
- functions->insert(QLatin1String("warning"), CF_MESSAGE); //v
- functions->insert(QLatin1String("error"), CF_MESSAGE); //v
+ functions->insert(QLatin1String("requires"), T_REQUIRES);
+ functions->insert(QLatin1String("greaterThan"), T_GREATERTHAN);
+ functions->insert(QLatin1String("lessThan"), T_LESSTHAN);
+ functions->insert(QLatin1String("equals"), T_EQUALS);
+ functions->insert(QLatin1String("isEqual"), T_EQUALS);
+ functions->insert(QLatin1String("exists"), T_EXISTS);
+ functions->insert(QLatin1String("export"), T_EXPORT);
+ functions->insert(QLatin1String("clear"), T_CLEAR);
+ functions->insert(QLatin1String("unset"), T_UNSET);
+ functions->insert(QLatin1String("eval"), T_EVAL);
+ functions->insert(QLatin1String("CONFIG"), T_CONFIG);
+ functions->insert(QLatin1String("if"), T_IF);
+ functions->insert(QLatin1String("isActiveConfig"), T_CONFIG);
+ functions->insert(QLatin1String("system"), T_SYSTEM);
+ functions->insert(QLatin1String("return"), T_RETURN);
+ functions->insert(QLatin1String("break"), T_BREAK);
+ functions->insert(QLatin1String("next"), T_NEXT);
+ functions->insert(QLatin1String("defined"), T_DEFINED);
+ functions->insert(QLatin1String("contains"), T_CONTAINS);
+ functions->insert(QLatin1String("infile"), T_INFILE);
+ functions->insert(QLatin1String("count"), T_COUNT);
+ functions->insert(QLatin1String("isEmpty"), T_ISEMPTY);
+ functions->insert(QLatin1String("load"), T_LOAD); //v
+ functions->insert(QLatin1String("include"), T_INCLUDE); //v
+ functions->insert(QLatin1String("debug"), T_DEBUG);
+ functions->insert(QLatin1String("message"), T_MESSAGE); //v
+ functions->insert(QLatin1String("warning"), T_MESSAGE); //v
+ functions->insert(QLatin1String("error"), T_MESSAGE); //v
}
bool cond = false;
bool ok = true;
- ConditionFunc func_t = (ConditionFunc)functions->value(function);
+ TestFunc func_t = (TestFunc)functions->value(function);
switch (func_t) {
- case CF_CONFIG: {
+#if 0
+ case T_INFILE:
+ case T_REQUIRES:
+ case T_GREATERTHAN:
+ case T_LESSTHAN:
+ case T_EQUALS:
+ case T_EXPORT:
+ case T_CLEAR:
+ case T_UNSET:
+ case T_EVAL:
+ case T_IF:
+ case T_RETURN:
+ case T_BREAK:
+ case T_NEXT:
+ case T_DEFINED:
+#endif
+ case T_CONFIG: {
if (args.count() < 1 || args.count() > 2) {
q->logMessage(format("CONFIG(config) requires one or two arguments."));
ok = false;
@@ -1268,7 +1719,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
const QStringList mutuals = args[1].split(QLatin1Char('|'));
const QStringList &configs = valuesDirect(QLatin1String("CONFIG"));
- for (int i = configs.size() - 1 && ok; i >= 0; i--) {
+ for (int i = configs.size() - 1; i >= 0; i--) {
for (int mut = 0; mut < mutuals.count(); mut++) {
if (configs[i] == mutuals[mut].trimmed()) {
cond = (configs[i] == args[0]);
@@ -1279,7 +1730,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
done_T_CONFIG:
break;
}
- case CF_CONTAINS: {
+ case T_CONTAINS: {
if (args.count() < 2 || args.count() > 3) {
q->logMessage(format("contains(var, val) requires two or three arguments."));
ok = false;
@@ -1311,9 +1762,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
done_T_CONTAINS:
break;
}
- case CF_COUNT: {
+ case T_COUNT: {
if (args.count() != 2 && args.count() != 3) {
- q->logMessage(format("count(var, count) requires two or three arguments."));
+ q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments."));
ok = false;
break;
}
@@ -1338,7 +1789,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
cond = values(args.first()).count() == args[1].toInt();
break;
}
- case CF_INCLUDE: {
+ case T_INCLUDE: {
+ if (m_skipLevel && !m_cumulative)
+ break;
QString parseInto;
if (args.count() == 2) {
parseInto = args[1];
@@ -1349,12 +1802,14 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
QString fileName = args.first();
// ### this breaks if we have include(c:/reallystupid.pri) but IMHO that's really bad style.
- QDir currentProPath(getcwd());
+ QDir currentProPath(currentDirectory());
fileName = QDir::cleanPath(currentProPath.absoluteFilePath(fileName));
ok = evaluateFile(fileName, &ok);
break;
}
- case CF_LOAD: {
+ case T_LOAD: {
+ if (m_skipLevel && !m_cumulative)
+ break;
QString parseInto;
bool ignore_error = false;
if (args.count() == 2) {
@@ -1368,13 +1823,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
ok = evaluateFeatureFile( args.first(), &cond);
break;
}
- case CF_MESSAGE: {
+ case T_DEBUG:
+ // Yup - do nothing. Nothing is going to enable debug output anyway.
+ break;
+ case T_MESSAGE: {
if (args.count() != 1) {
q->logMessage(format("%1(message) requires one argument.").arg(function));
ok = false;
break;
}
- QString msg = args.first();
+ QString msg = fixEnvVariables(args.first());
if (function == QLatin1String("error")) {
QStringList parents;
foreach (ProFile *proFile, m_profileStack)
@@ -1391,7 +1849,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
break;
}
- case CF_SYSTEM: {
+#if 0 // Way too dangerous to enable.
+ case T_SYSTEM: {
if (args.count() != 1) {
q->logMessage(format("system(exec) requires one argument."));
ok = false;
@@ -1400,7 +1859,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
ok = system(args.first().toLatin1().constData()) == 0;
break;
}
- case CF_ISEMPTY: {
+#endif
+ case T_ISEMPTY: {
if (args.count() != 1) {
q->logMessage(format("isEmpty(var) requires one argument."));
ok = false;
@@ -1415,31 +1875,38 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
}
break;
}
- case CF_EXISTS: {
+ case T_EXISTS: {
if (args.count() != 1) {
q->logMessage(format("exists(file) requires one argument."));
ok = false;
break;
}
QString file = args.first();
-
- file = QDir::cleanPath(file);
+ file = Option::fixPathToLocalOS(file);
if (QFile::exists(file)) {
cond = true;
break;
}
//regular expression I guess
- QString dirstr = getcwd();
+ QString dirstr = currentDirectory();
int slsh = file.lastIndexOf(Option::dir_sep);
if (slsh != -1) {
dirstr = file.left(slsh+1);
file = file.right(file.length() - slsh - 1);
}
- cond = QDir(dirstr).entryList(QStringList(file)).count();
+ if (file.contains(QLatin1Char('*')) || file.contains(QLatin1Char('?')))
+ cond = QDir(dirstr).entryList(QStringList(file)).count();
break;
}
+ case 0:
+ // This is too chatty currently (missing defineTest and defineReplace)
+ //q->logMessage(format("'%1' is not a recognized test function").arg(function));
+ break;
+ default:
+ q->logMessage(format("Function '%1' is not implemented").arg(function));
+ break;
}
if (result)
@@ -1448,32 +1915,131 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct
return ok;
}
-QStringList ProFileEvaluator::Private::values(const QString &variableName) const
+QStringList ProFileEvaluator::Private::values(const QString &variableName,
+ const QHash<QString, QStringList> &place,
+ const ProFile *pro) const
{
- if (variableName == QLatin1String("TARGET")) {
- QStringList list = m_valuemap.value(variableName);
- if (!m_origfile.isEmpty())
- list.append(QFileInfo(m_origfile).baseName());
- return list;
+ if (variableName == QLatin1String("LITERAL_WHITESPACE")) //a real space in a token
+ return QStringList(QLatin1String("\t"));
+ if (variableName == QLatin1String("LITERAL_DOLLAR")) //a real $
+ return QStringList(QLatin1String("$"));
+ if (variableName == QLatin1String("LITERAL_HASH")) //a real #
+ return QStringList(QLatin1String("#"));
+ if (variableName == QLatin1String("OUT_PWD")) //the out going dir
+ return QStringList(m_outputDir);
+ if (variableName == QLatin1String("PWD") || //current working dir (of _FILE_)
+ variableName == QLatin1String("IN_PWD"))
+ return QStringList(currentDirectory());
+ if (variableName == QLatin1String("DIR_SEPARATOR"))
+ return QStringList(Option::dir_sep);
+ if (variableName == QLatin1String("DIRLIST_SEPARATOR"))
+ return QStringList(Option::dirlist_sep);
+ if (variableName == QLatin1String("_LINE_")) //parser line number
+ return QStringList(QString::number(m_lineNo));
+ if (variableName == QLatin1String("_FILE_")) //parser file; qmake is a bit weird here
+ return QStringList(m_profileStack.size() == 1 ? pro->fileName() : QFileInfo(pro->fileName()).fileName());
+ if (variableName == QLatin1String("_DATE_")) //current date/time
+ return QStringList(QDateTime::currentDateTime().toString());
+ if (variableName == QLatin1String("_PRO_FILE_"))
+ return QStringList(m_origfile);
+ if (variableName == QLatin1String("_PRO_FILE_PWD_"))
+ return QStringList(QFileInfo(m_origfile).absolutePath());
+ if (variableName == QLatin1String("_QMAKE_CACHE_"))
+ return QStringList(); // FIXME?
+ if (variableName.startsWith(QLatin1String("QMAKE_HOST."))) {
+ QString ret, type = variableName.mid(11);
+#if defined(Q_OS_WIN32)
+ if (type == QLatin1String("os")) {
+ ret = QLatin1String("Windows");
+ } else if (type == QLatin1String("name")) {
+ DWORD name_length = 1024;
+ wchar_t name[1024];
+ if (GetComputerName(name, &name_length))
+ ret = QString::fromWCharArray(name);
+ } else if (type == QLatin1String("version") || type == QLatin1String("version_string")) {
+ QSysInfo::WinVersion ver = QSysInfo::WindowsVersion;
+ if (type == QLatin1String("version"))
+ ret = QString::number(ver);
+ else if (ver == QSysInfo::WV_Me)
+ ret = QLatin1String("WinMe");
+ else if (ver == QSysInfo::WV_95)
+ ret = QLatin1String("Win95");
+ else if (ver == QSysInfo::WV_98)
+ ret = QLatin1String("Win98");
+ else if (ver == QSysInfo::WV_NT)
+ ret = QLatin1String("WinNT");
+ else if (ver == QSysInfo::WV_2000)
+ ret = QLatin1String("Win2000");
+ else if (ver == QSysInfo::WV_2000)
+ ret = QLatin1String("Win2003");
+ else if (ver == QSysInfo::WV_XP)
+ ret = QLatin1String("WinXP");
+ else if (ver == QSysInfo::WV_VISTA)
+ ret = QLatin1String("WinVista");
+ else
+ ret = QLatin1String("Unknown");
+ } else if (type == QLatin1String("arch")) {
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ switch(info.wProcessorArchitecture) {
+#ifdef PROCESSOR_ARCHITECTURE_AMD64
+ case PROCESSOR_ARCHITECTURE_AMD64:
+ ret = QLatin1String("x86_64");
+ break;
+#endif
+ case PROCESSOR_ARCHITECTURE_INTEL:
+ ret = QLatin1String("x86");
+ break;
+ case PROCESSOR_ARCHITECTURE_IA64:
+#ifdef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+ case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+#endif
+ ret = QLatin1String("IA64");
+ break;
+ default:
+ ret = QLatin1String("Unknown");
+ break;
+ }
+ }
+#elif defined(Q_OS_UNIX)
+ struct utsname name;
+ if (!uname(&name)) {
+ if (type == QLatin1String("os"))
+ ret = QString::fromLatin1(name.sysname);
+ else if (type == QLatin1String("name"))
+ ret = QString::fromLatin1(name.nodename);
+ else if (type == QLatin1String("version"))
+ ret = QString::fromLatin1(name.release);
+ else if (type == QLatin1String("version_string"))
+ ret = QString::fromLatin1(name.version);
+ else if (type == QLatin1String("arch"))
+ ret = QString::fromLatin1(name.machine);
+ }
+#endif
+ return QStringList(ret);
}
- if (variableName == QLatin1String("PWD")) {
- return QStringList(getcwd());
+
+ QStringList result = place[variableName];
+ if (result.isEmpty()) {
+ if (variableName == QLatin1String("TARGET")) {
+ result.append(QFileInfo(m_origfile).baseName());
+ } else if (variableName == QLatin1String("TEMPLATE")) {
+ result.append(QLatin1String("app"));
+ } else if (variableName == QLatin1String("QMAKE_DIR_SEP")) {
+ result.append(Option::dirlist_sep);
+ }
}
- return m_valuemap.value(variableName);
+ return result;
+}
+
+QStringList ProFileEvaluator::Private::values(const QString &variableName) const
+{
+ return values(variableName, m_valuemap, currentProFile());
}
QStringList ProFileEvaluator::Private::values(const QString &variableName, const ProFile *pro) const
{
- if (variableName == QLatin1String("TARGET")) {
- QStringList list = m_filevaluemap[pro].value(variableName);
- if (!m_origfile.isEmpty())
- list.append(QFileInfo(m_origfile).baseName());
- return list;
- }
- if (variableName == QLatin1String("PWD")) {
- return QStringList(QFileInfo(pro->fileName()).absoluteFilePath());
- }
- return m_filevaluemap[pro].value(variableName);
+ return values(variableName, m_filevaluemap[pro], pro);
}
ProFile *ProFileEvaluator::parsedProFile(const QString &fileName)
@@ -1534,7 +2100,13 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, boo
break;
}
}
- return fn.isEmpty() ? false : evaluateFile(fn, result);
+ if (fn.isEmpty())
+ return false;
+ bool cumulative = m_cumulative;
+ m_cumulative = false;
+ bool ok = evaluateFile(fn, result);
+ m_cumulative = cumulative;
+ return ok;
}
void ProFileEvaluator::Private::expandPatternHelper(const QString &relName, const QString &absName,
@@ -1644,14 +2216,23 @@ bool ProFileEvaluator::contains(const QString &variableName) const
return d->m_valuemap.contains(variableName);
}
+inline QStringList fixEnvVariables(const QStringList &x)
+{
+ QStringList ret;
+ foreach (const QString &str, x)
+ ret << Option::fixString(str, Option::FixEnvVars);
+ return ret;
+}
+
+
QStringList ProFileEvaluator::values(const QString &variableName) const
{
- return d->values(variableName);
+ return fixEnvVariables(d->values(variableName));
}
QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const
{
- return d->values(variableName, pro);
+ return fixEnvVariables(d->values(variableName, pro));
}
ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
@@ -1663,6 +2244,8 @@ ProFileEvaluator::TemplateType ProFileEvaluator::templateType()
return TT_Application;
if (t == QLatin1String("lib"))
return TT_Library;
+ if (t == QLatin1String("script"))
+ return TT_Script;
if (t == QLatin1String("subdirs"))
return TT_Subdirs;
}
@@ -1707,18 +2290,20 @@ void ProFileEvaluator::addProperties(const QHash<QString, QString> &properties)
void ProFileEvaluator::logMessage(const QString &message)
{
- if (d->m_verbose)
+ if (d->m_verbose && !d->m_skipLevel)
qWarning("%s", qPrintable(message));
}
void ProFileEvaluator::fileMessage(const QString &message)
{
- qWarning("%s", qPrintable(message));
+ if (!d->m_skipLevel)
+ qWarning("%s", qPrintable(message));
}
void ProFileEvaluator::errorMessage(const QString &message)
{
- qWarning("%s", qPrintable(message));
+ if (!d->m_skipLevel)
+ qWarning("%s", qPrintable(message));
}
void ProFileEvaluator::setVerbose(bool on)
@@ -1726,6 +2311,16 @@ void ProFileEvaluator::setVerbose(bool on)
d->m_verbose = on;
}
+void ProFileEvaluator::setCumulative(bool on)
+{
+ d->m_cumulative = on;
+}
+
+void ProFileEvaluator::setOutputDir(const QString &dir)
+{
+ d->m_outputDir = dir;
+}
+
void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap)
{
QStringList sourceFiles;
diff --git a/tools/linguist/shared/profileevaluator.h b/tools/linguist/shared/profileevaluator.h
index 5f35ea8..69f47f5 100644
--- a/tools/linguist/shared/profileevaluator.h
+++ b/tools/linguist/shared/profileevaluator.h
@@ -65,6 +65,7 @@ public:
TT_Unknown = 0,
TT_Application,
TT_Library,
+ TT_Script,
TT_Subdirs
};
@@ -73,7 +74,9 @@ public:
ProFileEvaluator::TemplateType templateType();
virtual bool contains(const QString &variableName) const;
- void setVerbose(bool on);
+ void setVerbose(bool on); // Default is false
+ void setCumulative(bool on); // Default is true!
+ void setOutputDir(const QString &dir); // Default is empty
bool queryProFile(ProFile *pro);
bool accept(ProFile *pro);
diff --git a/tools/linguist/shared/proparserutils.h b/tools/linguist/shared/proparserutils.h
index 1134c0b..0ffe4d2 100644
--- a/tools/linguist/shared/proparserutils.h
+++ b/tools/linguist/shared/proparserutils.h
@@ -93,6 +93,25 @@ struct Option
Option::qmakespec = QString::fromLatin1(qgetenv("QMAKESPEC").data());
Option::field_sep = QLatin1Char(' ');
}
+
+ enum StringFixFlags {
+ FixNone = 0x00,
+ FixEnvVars = 0x01,
+ FixPathCanonicalize = 0x02,
+ FixPathToLocalSeparators = 0x04,
+ FixPathToTargetSeparators = 0x08
+ };
+ static QString fixString(QString string, uchar flags);
+
+ inline static QString fixPathToLocalOS(const QString &in, bool fix_env = true, bool canonical = true)
+ {
+ uchar flags = FixPathToLocalSeparators;
+ if (fix_env)
+ flags |= FixEnvVars;
+ if (canonical)
+ flags |= FixPathCanonicalize;
+ return fixString(in, flags);
+ }
};
#if defined(Q_OS_WIN32)
Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE;
@@ -110,17 +129,20 @@ QString Option::dir_sep;
QChar Option::field_sep;
static void insertUnique(QHash<QString, QStringList> *map,
- const QString &key, const QStringList &value, bool unique = true)
+ const QString &key, const QStringList &value)
{
QStringList &sl = (*map)[key];
- if (!unique) {
- sl += value;
- } else {
- for (int i = 0; i < value.count(); ++i) {
- if (!sl.contains(value.at(i)))
- sl.append(value.at(i));
- }
- }
+ foreach (const QString &str, value)
+ if (!sl.contains(str))
+ sl.append(str);
+}
+
+static void removeEach(QHash<QString, QStringList> *map,
+ const QString &key, const QStringList &value)
+{
+ QStringList &sl = (*map)[key];
+ foreach (const QString &str, value)
+ sl.removeAll(str);
}
/*
@@ -148,7 +170,12 @@ static QStringList replaceInList(const QStringList &varList, const QRegExp &rege
}
*/
-inline QStringList splitPathList(const QString paths)
+inline QString fixEnvVariables(const QString &x)
+{
+ return Option::fixString(x, Option::FixEnvVars);
+}
+
+inline QStringList splitPathList(const QString &paths)
{
return paths.split(Option::dirlist_sep);
}
@@ -255,7 +282,7 @@ static QStringList split_value_list(const QString &vals, bool do_semicolon=false
static QStringList qmake_mkspec_paths()
{
QStringList ret;
- const QString concat = QDir::separator() + QString(QLatin1String("mkspecs"));
+ const QString concat = QDir::separator() + QLatin1String("mkspecs");
QByteArray qmakepath = qgetenv("QMAKEPATH");
if (!qmakepath.isEmpty()) {
const QStringList lst = splitPathList(QString::fromLocal8Bit(qmakepath));
diff --git a/tools/linguist/shared/qm.cpp b/tools/linguist/shared/qm.cpp
index 323bd29..9523fde 100644
--- a/tools/linguist/shared/qm.cpp
+++ b/tools/linguist/shared/qm.cpp
@@ -173,6 +173,7 @@ public:
bool save(QIODevice *iod);
void insert(const TranslatorMessage &msg, bool forceComment);
+ void insertIdBased(const TranslatorMessage &message);
void squeeze(TranslatorSaveMode mode);
@@ -238,17 +239,13 @@ Prefix Releaser::commonPrefix(const ByteTranslatorMessage &m1, const ByteTransla
void Releaser::writeMessage(const ByteTranslatorMessage &msg, QDataStream &stream,
TranslatorSaveMode mode, Prefix prefix) const
{
- for (int i = 0; i < msg.translations().count(); ++i) {
- QString str = msg.translations().at(i);
- str.replace(QChar(Translator::DefaultVariantSeparator),
- QChar(Translator::InternalVariantSeparator));
- stream << quint8(Tag_Translation) << str;
- }
+ for (int i = 0; i < msg.translations().count(); ++i)
+ stream << quint8(Tag_Translation) << msg.translations().at(i);
if (mode == SaveEverything)
prefix = HashContextSourceTextComment;
- // lrelease produces "wrong" .qm files for QByteArrays that are .isNull().
+ // lrelease produces "wrong" QM files for QByteArrays that are .isNull().
switch (prefix) {
default:
case HashContextSourceTextComment:
@@ -440,6 +437,16 @@ void Releaser::insert(const TranslatorMessage &message, bool forceComment)
insertInternal(message, forceComment, false);
}
+void Releaser::insertIdBased(const TranslatorMessage &message)
+{
+ QStringList tlns = message.translations();
+ for (int i = 0; i < tlns.size(); ++i)
+ if (tlns.at(i).isEmpty())
+ tlns[i] = message.sourceText();
+ ByteTranslatorMessage bmsg("", originalBytes(message.id(), false), "", tlns);
+ m_messages.insert(bmsg, 0);
+}
+
void Releaser::setNumerusRules(const QByteArray &rules)
{
m_numerusRules = rules;
@@ -592,8 +599,6 @@ bool loadQM(Translator &translator, QIODevice &dev, ConversionData &cd)
str[i] = QChar((str.at(i).unicode() >> 8) +
((str.at(i).unicode() << 8) & 0xff00));
}
- str.replace(QChar(Translator::InternalVariantSeparator),
- QChar(Translator::DefaultVariantSeparator));
translations << str;
m += len;
break;
@@ -695,11 +700,17 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
int finished = 0;
int unfinished = 0;
int untranslated = 0;
+ int missingIds = 0;
+ int droppedData = 0;
for (int i = 0; i != translator.messageCount(); ++i) {
const TranslatorMessage &msg = translator.message(i);
TranslatorMessage::Type typ = msg.type();
if (typ != TranslatorMessage::Obsolete) {
+ if (cd.m_idBased && msg.id().isEmpty()) {
+ ++missingIds;
+ continue;
+ }
if (typ == TranslatorMessage::Unfinished) {
if (msg.translation().isEmpty()) {
++untranslated;
@@ -712,19 +723,34 @@ static bool saveQM(const Translator &translator, QIODevice &dev, ConversionData
} else {
++finished;
}
- // Drop the comment in (context, sourceText, comment),
- // unless the context is empty,
- // unless (context, sourceText, "") already exists or
- // unless we already dropped the comment of (context,
- // sourceText, comment0).
- bool forceComment =
- msg.comment().isEmpty()
- || msg.context().isEmpty()
- || translator.contains(msg.context(), msg.sourceText(), QString());
- releaser.insert(msg, forceComment);
+ if (cd.m_idBased) {
+ if (!msg.context().isEmpty() || !msg.comment().isEmpty())
+ ++droppedData;
+ releaser.insertIdBased(msg);
+ } else {
+ // Drop the comment in (context, sourceText, comment),
+ // unless the context is empty,
+ // unless (context, sourceText, "") already exists or
+ // unless we already dropped the comment of (context,
+ // sourceText, comment0).
+ bool forceComment =
+ msg.comment().isEmpty()
+ || msg.context().isEmpty()
+ || translator.contains(msg.context(), msg.sourceText(), QString());
+ releaser.insert(msg, forceComment);
+ }
}
}
+ if (missingIds)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Dropped %n message(s) which had no ID.", 0,
+ QCoreApplication::CodecForTr, missingIds));
+ if (droppedData)
+ cd.appendError(QCoreApplication::translate("LRelease",
+ "Excess context/disambiguation dropped from %n message(s).", 0,
+ QCoreApplication::CodecForTr, droppedData));
+
releaser.squeeze(cd.m_saveMode);
bool saved = releaser.save(&dev);
if (saved && cd.isVerbose()) {
diff --git a/tools/linguist/shared/qph.cpp b/tools/linguist/shared/qph.cpp
index 076194c..4a29e0f 100644
--- a/tools/linguist/shared/qph.cpp
+++ b/tools/linguist/shared/qph.cpp
@@ -54,33 +54,19 @@ QT_BEGIN_NAMESPACE
class QPHReader : public QXmlStreamReader
{
public:
- QPHReader(QIODevice &dev, ConversionData &cd)
- : QXmlStreamReader(&dev), m_cd(cd)
+ QPHReader(QIODevice &dev)
+ : QXmlStreamReader(&dev)
{}
// the "real thing"
bool read(Translator &translator);
private:
- bool elementStarts(const QString &str) const
- {
- return isStartElement() && name() == str;
- }
-
bool isWhiteSpace() const
{
return isCharacters() && text().toString().trimmed().isEmpty();
}
- // needed to expand <byte ... />
- QString readContents();
- // needed to join <lengthvariant>s
- QString readTransContents();
-
- void handleError();
-
- ConversionData &m_cd;
-
enum DataField { NoField, SourceField, TargetField, DefinitionField };
DataField m_currentField;
QString m_currentSource;
@@ -113,6 +99,8 @@ bool QPHReader::read(Translator &translator)
else if (m_currentField == DefinitionField)
m_currentDefinition += text();
} else if (isEndElement() && name() == QLatin1String("phrase")) {
+ m_currentTarget.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
TranslatorMessage msg;
msg.setSourceText(m_currentSource);
msg.setTranslation(m_currentTarget);
@@ -126,10 +114,10 @@ bool QPHReader::read(Translator &translator)
return true;
}
-static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &cd)
+static bool loadQPH(Translator &translator, QIODevice &dev, ConversionData &)
{
translator.setLocationsType(Translator::NoLocations);
- QPHReader reader(dev, cd);
+ QPHReader reader(dev);
return reader.read(translator);
}
@@ -173,7 +161,10 @@ static bool saveQPH(const Translator &translator, QIODevice &dev, ConversionData
foreach (const TranslatorMessage &msg, translator.messages()) {
t << "<phrase>\n";
t << " <source>" << protect(msg.sourceText()) << "</source>\n";
- t << " <target>" << protect(msg.translations().join(QLatin1String("@")))
+ QString str = msg.translations().join(QLatin1String("@"));
+ str.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
+ t << " <target>" << protect(str)
<< "</target>\n";
if (!msg.context().isEmpty() || !msg.comment().isEmpty())
t << " <definition>" << msg.context() << msg.comment()
diff --git a/tools/linguist/shared/translator.cpp b/tools/linguist/shared/translator.cpp
index b8d559f..305681d 100644
--- a/tools/linguist/shared/translator.cpp
+++ b/tools/linguist/shared/translator.cpp
@@ -415,6 +415,26 @@ void Translator::dropTranslations()
}
}
+void Translator::dropUiLines()
+{
+ QString uiXt = QLatin1String(".ui");
+ QString juiXt = QLatin1String(".jui");
+ for (TMM::Iterator it = m_messages.begin(); it != m_messages.end(); ++it) {
+ QHash<QString, int> have;
+ QList<TranslatorMessage::Reference> refs;
+ foreach (const TranslatorMessage::Reference &itref, it->allReferences()) {
+ const QString &fn = itref.fileName();
+ if (fn.endsWith(uiXt) || fn.endsWith(juiXt)) {
+ if (++have[fn] == 1)
+ refs.append(TranslatorMessage::Reference(fn, -1));
+ } else {
+ refs.append(itref);
+ }
+ }
+ it->setReferences(refs);
+ }
+}
+
QSet<TranslatorMessagePtr> Translator::resolveDuplicates()
{
QSet<TranslatorMessagePtr> dups;
diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h
index 77b515f..fb17fd1 100644
--- a/tools/linguist/shared/translator.h
+++ b/tools/linguist/shared/translator.h
@@ -47,7 +47,9 @@
#include <QDir>
#include <QList>
#include <QLocale>
+#include <QMultiHash>
#include <QString>
+#include <QSet>
QT_BEGIN_NAMESPACE
@@ -63,6 +65,7 @@ public:
m_ignoreUnfinished(false),
m_sortContexts(false),
m_noUiLines(false),
+ m_idBased(false),
m_saveMode(SaveEverything)
{}
@@ -85,13 +88,17 @@ public:
QString m_sourceFileName;
QString m_targetFileName;
QDir m_sourceDir;
- QDir m_targetDir; // FIXME: TS spefic
+ QDir m_targetDir; // FIXME: TS specific
+ QSet<QString> m_projectRoots;
+ QMultiHash<QString, QString> m_allCSources;
+ QStringList m_includePath;
QStringList m_dropTags; // tags to be dropped
QStringList m_errors;
bool m_verbose;
bool m_ignoreUnfinished;
bool m_sortContexts;
bool m_noUiLines;
+ bool m_idBased;
TranslatorSaveMode m_saveMode;
};
@@ -127,6 +134,7 @@ public:
void stripNonPluralForms();
void stripIdenticalSourceTranslations();
void dropTranslations();
+ void dropUiLines();
void makeFileNamesAbsolute(const QDir &originalPath);
QSet<TranslatorMessagePtr> resolveDuplicates();
static void reportDuplicates(const QSet<TranslatorMessagePtr> &dupes,
@@ -138,7 +146,7 @@ public:
QString languageCode() const { return m_language; }
QString sourceLanguageCode() const { return m_sourceLanguage; }
- enum LocationsType { NoLocations, RelativeLocations, AbsoluteLocations };
+ enum LocationsType { DefaultLocations, NoLocations, RelativeLocations, AbsoluteLocations };
void setLocationsType(LocationsType lt) { m_locationsType = lt; }
LocationsType locationsType() const { return m_locationsType; }
@@ -178,15 +186,15 @@ public:
QString description; // human-readable description
LoadFunction loader;
SaveFunction saver;
- enum FileType { SourceCode, TranslationSource, TranslationBinary } fileType;
+ enum FileType { TranslationSource, TranslationBinary } fileType;
int priority; // 0 = highest, -1 = invisible
};
static void registerFileFormat(const FileFormat &format);
static QList<FileFormat> &registeredFileFormats();
- enum VariantSeparators {
- DefaultVariantSeparator = 0x2762, // some weird character nobody ever heard of :-D
- InternalVariantSeparator = 0x9c // unicode "STRING TERMINATOR"
+ enum {
+ TextVariantSeparator = 0x2762, // some weird character nobody ever heard of :-D
+ BinaryVariantSeparator = 0x9c // unicode "STRING TERMINATOR"
};
private:
diff --git a/tools/linguist/shared/translatortools.pri b/tools/linguist/shared/translatortools.pri
deleted file mode 100644
index 2b6de8c..0000000
--- a/tools/linguist/shared/translatortools.pri
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-INCLUDEPATH *= $$PWD
-
-SOURCES += \
- $$PWD/translatortools.cpp \
- $$PWD/simtexth.cpp
-
-HEADERS += \
- $$PWD/translatortools.h
-
diff --git a/tools/linguist/shared/ts.cpp b/tools/linguist/shared/ts.cpp
index 6c95dbd..3efce15 100644
--- a/tools/linguist/shared/ts.cpp
+++ b/tools/linguist/shared/ts.cpp
@@ -197,7 +197,7 @@ QString TSReader::readTransContents()
// ignore these, just whitespace
} else if (elementStarts(strlengthvariant)) {
if (!result.isEmpty())
- result += QChar(Translator::DefaultVariantSeparator);
+ result += QChar(Translator::BinaryVariantSeparator);
result += readContents();
} else {
handleError();
@@ -514,7 +514,7 @@ static void writeExtras(QTextStream &t, const char *indent,
static void writeVariants(QTextStream &t, const char *indent, const QString &input)
{
int offset;
- if ((offset = input.indexOf(QChar(Translator::DefaultVariantSeparator))) >= 0) {
+ if ((offset = input.indexOf(QChar(Translator::BinaryVariantSeparator))) >= 0) {
t << " variants=\"yes\">";
int start = 0;
forever {
@@ -524,7 +524,7 @@ static void writeVariants(QTextStream &t, const char *indent, const QString &inp
if (offset == input.length())
break;
start = offset + 1;
- offset = input.indexOf(QChar(Translator::DefaultVariantSeparator), start);
+ offset = input.indexOf(QChar(Translator::BinaryVariantSeparator), start);
if (offset < 0)
offset = input.length();
}
diff --git a/tools/linguist/shared/ts.dtd b/tools/linguist/shared/ts.dtd
index ab77f64..4d2cdeb 100644
--- a/tools/linguist/shared/ts.dtd
+++ b/tools/linguist/shared/ts.dtd
@@ -34,7 +34,7 @@
version CDATA #IMPLIED
sourcelanguage CDATA #IMPLIED
language CDATA #IMPLIED>
-<!-- The encoding to use in the .qm file by default. Default is ISO-8859-1. -->
+<!-- The encoding to use in the QM file by default. Default is ISO-8859-1. -->
<!ELEMENT defaultcodec (#PCDATA) >
<!ELEMENT context (name?, comment?, (context|message)+) >
<!ATTLIST context
@@ -54,7 +54,7 @@
<!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.
+ ! in UTF-8 in the QM file.
-->
<!ATTLIST message
id CDATA #IMPLIED
@@ -70,7 +70,7 @@
! is omitted, the "current" one is used. For the 1st location in a message,
! "current" is the filename used for the 1st location of the previous message.
! For subsequent locations, it is the filename used for the previous location.
- ! A single .ts file has either all absolute or all relative locations.
+ ! A single TS file has either all absolute or all relative locations.
-->
<!ATTLIST location
filename CDATA #IMPLIED
@@ -106,7 +106,7 @@
<!--
! 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.
+ ! 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 61e4b9f..1313172 100644
--- a/tools/linguist/shared/xliff.cpp
+++ b/tools/linguist/shared/xliff.cpp
@@ -303,6 +303,8 @@ static void writeTransUnits(QTextStream &ts, const TranslatorMessage &msg, const
QString translation;
if (transit != transend) {
translation = *transit;
+ translation.replace(QChar(Translator::BinaryVariantSeparator),
+ QChar(Translator::TextVariantSeparator));
++transit;
puttrans = true;
}
@@ -598,8 +600,11 @@ bool XLIFFHandler::endElement(const QString &namespaceURI, const QString& localN
m_sources.append(accum);
}
} else if (localName == QLatin1String("target")) {
- if (popContext(XC_restype_translation))
+ if (popContext(XC_restype_translation)) {
+ accum.replace(QChar(Translator::TextVariantSeparator),
+ QChar(Translator::BinaryVariantSeparator));
m_translations.append(accum);
+ }
} else if (localName == QLatin1String("context-group")) {
if (popContext(XC_context_group)) {
m_refs.append(TranslatorMessage::Reference(
diff --git a/tools/macdeployqt/macchangeqt/main.cpp b/tools/macdeployqt/macchangeqt/main.cpp
index 36793c9..519aab0 100644
--- a/tools/macdeployqt/macchangeqt/main.cpp
+++ b/tools/macdeployqt/macchangeqt/main.cpp
@@ -42,13 +42,35 @@
int main(int argc, char **argv)
{
- if (argc != 3) {
- qDebug() << "Changeqt changes witch qt frameworks an application links against.";
- qDebug() << "Usage: changeqt app-bundle qt-dir";
+ // useDebugLibs should always be false because even if set all Qt
+ // libraries inside a binary to point to debug versions, as soon as
+ // one of them loads a Qt plugin, the plugin itself will load the
+ // release version of Qt, and as such, the app will crash.
+ bool useDebugLibs = false;
+
+ int optionsSpecified = 0;
+ for (int i = 2; i < argc; ++i) {
+ QByteArray argument = QByteArray(argv[i]);
+ if (argument.startsWith(QByteArray("-verbose="))) {
+ LogDebug() << "Argument found:" << argument;
+ optionsSpecified++;
+ int index = argument.indexOf("=");
+ bool ok = false;
+ int number = argument.mid(index+1).toInt(&ok);
+ if (!ok)
+ LogError() << "Could not parse verbose level";
+ else
+ logLevel = number;
+ }
+ }
+
+ if (argc != (3 + optionsSpecified)) {
+ qDebug() << "Changeqt: changes witch Qt frameworks an application links against.";
+ qDebug() << "Usage: changeqt app-bundle qt-dir <-verbose=[0-3]>";
return 0;
}
-
+
const QString appPath = QString::fromLocal8Bit(argv[1]);
const QString qtPath = QString::fromLocal8Bit(argv[2]);
- changeQtFrameworks(appPath, qtPath);
+ changeQtFrameworks(appPath, qtPath, useDebugLibs);
}
diff --git a/tools/macdeployqt/macdeployqt/main.cpp b/tools/macdeployqt/macdeployqt/main.cpp
index e5dde10..f57315b 100644
--- a/tools/macdeployqt/macdeployqt/main.cpp
+++ b/tools/macdeployqt/macdeployqt/main.cpp
@@ -51,9 +51,11 @@ int main(int argc, char **argv)
qDebug() << "Usage: macdeployqt app-bundle [options]";
qDebug() << "";
qDebug() << "Options:";
- qDebug() << " -no-plugins: Skip plugin deployment";
- qDebug() << " -dmg : Create a .dmg disk image";
- qDebug() << " -no-strip : Don't run 'strip' on the binaries";
+ qDebug() << " -verbose=<0-3> : 0 = no output, 1 = error/warning (default), 2 = normal, 3 = debug";
+ qDebug() << " -no-plugins : Skip plugin deployment";
+ qDebug() << " -dmg : Create a .dmg disk image";
+ qDebug() << " -no-strip : Don't run 'strip' on the binaries";
+ qDebug() << " -use-debug-libs : Deploy with debug versions of frameworks and plugins (implies -no-strip)";
qDebug() << "";
qDebug() << "macdeployqt takes an application bundle as input and makes it";
qDebug() << "self-contained by copying in the Qt frameworks and plugins that";
@@ -68,10 +70,10 @@ int main(int argc, char **argv)
return 0;
}
-
+
if (appBundlePath.endsWith("/"))
appBundlePath.chop(1);
-
+
if (QDir().exists(appBundlePath) == false) {
qDebug() << "Error: Could not find app bundle" << appBundlePath;
return 0;
@@ -79,23 +81,40 @@ int main(int argc, char **argv)
bool plugins = true;
bool dmg = false;
+ bool useDebugLibs = false;
extern bool runStripEnabled;
for (int i = 2; i < argc; ++i) {
QByteArray argument = QByteArray(argv[i]);
if (argument == QByteArray("-no-plugins")) {
+ LogDebug() << "Argument found:" << argument;
plugins = false;
} else if (argument == QByteArray("-dmg")) {
+ LogDebug() << "Argument found:" << argument;
dmg = true;
} else if (argument == QByteArray("-no-strip")) {
+ LogDebug() << "Argument found:" << argument;
runStripEnabled = false;
+ } else if (argument == QByteArray("-use-debug-libs")) {
+ LogDebug() << "Argument found:" << argument;
+ useDebugLibs = true;
+ runStripEnabled = false;
+ } else if (argument.startsWith(QByteArray("-verbose"))) {
+ LogDebug() << "Argument found:" << argument;
+ int index = argument.indexOf("=");
+ bool ok = false;
+ int number = argument.mid(index+1).toInt(&ok);
+ if (!ok)
+ LogError() << "Could not parse verbose level";
+ else
+ logLevel = number;
} else if (argument.startsWith("-")) {
- qDebug() << "Error: Unknown option" << argument << "\n";
+ LogError() << "Unknown argument" << argument << "\n";
return 0;
}
}
- DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath);
+ DeploymentInfo deploymentInfo = deployQtFrameworks(appBundlePath, useDebugLibs);
if (plugins) {
if (deploymentInfo.qtPath.isEmpty())
@@ -103,13 +122,13 @@ int main(int argc, char **argv)
else
deploymentInfo.pluginPath = deploymentInfo.qtPath + "/plugins";
- qDebug() << "";
- qDebug() << "Deploying plugins from" << deploymentInfo.pluginPath;
- deployPlugins(appBundlePath, deploymentInfo);
+ LogNormal();
+ deployPlugins(appBundlePath, deploymentInfo, useDebugLibs);
createQtConf(appBundlePath);
}
if (dmg) {
+ LogNormal();
createDiskImage(appBundlePath);
}
}
diff --git a/tools/macdeployqt/shared/shared.cpp b/tools/macdeployqt/shared/shared.cpp
index b14debe..3e8c667 100644
--- a/tools/macdeployqt/shared/shared.cpp
+++ b/tools/macdeployqt/shared/shared.cpp
@@ -50,6 +50,7 @@
#include "shared.h"
bool runStripEnabled = true;
+int logLevel = 1;
using std::cout;
using std::endl;
@@ -61,8 +62,8 @@ bool operator==(const FrameworkInfo &a, const FrameworkInfo &b)
QDebug operator<<(QDebug debug, const FrameworkInfo &info)
{
- debug << "Framework directory" << info.frameworkDirectory << "\n";
debug << "Framework name" << info.frameworkName << "\n";
+ debug << "Framework directory" << info.frameworkDirectory << "\n";
debug << "Framework path" << info.frameworkPath << "\n";
debug << "Binary directory" << info.binaryDirectory << "\n";
debug << "Binary name" << info.binaryName << "\n";
@@ -71,8 +72,8 @@ QDebug operator<<(QDebug debug, const FrameworkInfo &info)
debug << "Install name" << info.installName << "\n";
debug << "Deployed install name" << info.deployedInstallName << "\n";
debug << "Source file Path" << info.sourceFilePath << "\n";
- debug << "Deployed Directtory (relative to bundle)" << info.destinationDirectory << "\n";
-
+ debug << "Deployed Directory (relative to bundle)" << info.destinationDirectory << "\n";
+
return debug;
}
@@ -89,40 +90,41 @@ inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info)
bool copyFilePrintStatus(const QString &from, const QString &to)
{
if (QFile::copy(from, to)) {
- qDebug() << "copied" << from << "to" << to;
+ LogNormal() << " copied:" << from;
+ LogNormal() << " to" << to;
return true;
} else {
- qDebug() << "ERROR: file copy failed from" << from << "to" << to;
+ LogError() << "file copy failed from" << from;
+ LogError() << " to" << to;
return false;
}
}
-
-FrameworkInfo parseOtoolLibraryLine(const QString &line)
+FrameworkInfo parseOtoolLibraryLine(const QString &line, bool useDebugLibs)
{
FrameworkInfo info;
QString trimmed = line.trimmed();
if (trimmed.isEmpty())
return info;
-
+
// Don't deploy system libraries.
if (trimmed.startsWith("/System/Library/") ||
(trimmed.startsWith("/usr/lib/") && trimmed.contains("libQt") == false) // exception for libQtuitools and libQtlucene
|| trimmed.startsWith("@executable_path"))
return info;
-
+
enum State {QtPath, FrameworkName, DylibName, Version, End};
State state = QtPath;
int part = 0;
QString name;
QString qtPath;
+ QString suffix = useDebugLibs ? "_debug" : "";
// Split the line into [Qt-path]/lib/qt[Module].framework/Versions/[Version]/
QStringList parts = trimmed.split("/");
while (part < parts.count()) {
const QString currentPart = parts.at(part).simplified() ;
-// qDebug() << "currentPart" << currentPart;
++part;
if (currentPart == "")
continue;
@@ -148,13 +150,13 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line)
info.frameworkDirectory = "/usr/lib/";
state = DylibName;
}
-
+
--part;
continue;
}
qtPath += (currentPart + "/");
-
- } if (state == FrameworkName) {
+
+ } if (state == FrameworkName) {
// remove ".framework"
name = currentPart;
name.chop(QString(".framework").length());
@@ -163,28 +165,29 @@ FrameworkInfo parseOtoolLibraryLine(const QString &line)
++part;
continue;
} if (state == DylibName) {
- name = currentPart.split(" (compatibility").at(0);
+ name = currentPart.split(" (compatibility").at(0);
info.frameworkName = name;
- info.installName += info.frameworkName;
- info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName;
- info.binaryName = name;
- info.frameworkPath = info.frameworkDirectory + info.frameworkName;
+ info.binaryName = name.left(name.indexOf('.')) + suffix + name.mid(name.indexOf('.'));
+ info.installName += name;
+ info.deployedInstallName = "@executable_path/../Frameworks/" + info.binaryName;
+ info.frameworkPath = info.frameworkDirectory + info.binaryName;
info.sourceFilePath = info.frameworkPath;
info.destinationDirectory = bundleFrameworkDirectory + "/";
+ info.binaryDirectory = info.frameworkDirectory;
+ info.binaryPath = info.frameworkPath;
state = End;
++part;
continue;
} else if (state == Version) {
info.version = currentPart;
- info.binaryDirectory = "Versions/" + info.version;
- info.binaryName = name;
+ info.binaryDirectory = "Versions/" + info.version;
+ info.binaryName = name + suffix;
info.binaryPath = "/" + info.binaryDirectory + "/" + info.binaryName;
- info.installName += info.frameworkName + info.binaryPath;
+ info.installName += info.frameworkName + "/" + info.binaryDirectory + "/" + name;
info.deployedInstallName = "@executable_path/../Frameworks/" + info.frameworkName + info.binaryPath;
info.frameworkPath = info.frameworkDirectory + info.frameworkName;
info.sourceFilePath = info.frameworkPath + info.binaryPath;
info.destinationDirectory = bundleFrameworkDirectory + "/" + info.frameworkName + "/" + info.binaryDirectory;
-
state = End;
} else if (state == End) {
break;
@@ -198,42 +201,46 @@ QString findAppBinary(const QString &appBundlePath)
{
QString appName = QFileInfo(appBundlePath).completeBaseName();
QString binaryPath = appBundlePath + "/Contents/MacOS/" + appName;
-
+
if (QFile::exists(binaryPath))
return binaryPath;
- qDebug() << "Error: Could not find bundle binary for" << appBundlePath;
+ LogError() << "Could not find bundle binary for" << appBundlePath;
return QString();
}
-QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines)
+QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, bool useDebugLibs)
{
- QList<FrameworkInfo> libraries;
+ QList<FrameworkInfo> libraries;
foreach(const QString line, otoolLines) {
- FrameworkInfo info = parseOtoolLibraryLine(line);
+ FrameworkInfo info = parseOtoolLibraryLine(line, useDebugLibs);
if (info.frameworkName.isEmpty() == false) {
+ LogDebug() << "Adding framework:";
+ LogDebug() << info;
libraries.append(info);
}
}
return libraries;
}
-QList<FrameworkInfo> getQtFrameworks(const QString &path)
+QList<FrameworkInfo> getQtFrameworks(const QString &path, bool useDebugLibs)
{
+ LogDebug() << "Using otool:";
+ LogDebug() << " inspecting" << path;
QProcess otool;
otool.start("otool", QStringList() << "-L" << path);
otool.waitForFinished();
-
+
if (otool.exitCode() != 0) {
- qDebug() << otool.readAllStandardError();
+ LogError() << otool.readAllStandardError();
}
-
+
QString output = otool.readAllStandardOutput();
QStringList outputLines = output.split("\n");
outputLines.removeFirst(); // remove line containing the binary path
if (path.contains(".framework") || path.contains(".dylib"))
outputLines.removeFirst(); // frameworks and dylibs lists themselves as a dependency.
- return getQtFrameworks(outputLines);
+ return getQtFrameworks(outputLines, useDebugLibs);
}
// copies everything _inside_ sourcePath to destinationPath
@@ -256,32 +263,31 @@ void recursiveCopy(const QString &sourcePath, const QString &destinationPath)
QString copyFramework(const FrameworkInfo &framework, const QString path)
{
- const QString from = framework.sourceFilePath;
- const QString toDir = path + "/" + framework.destinationDirectory;
- const QString to = toDir + "/" + framework.binaryName;
+ QString from = framework.sourceFilePath;
+ QString toDir = path + "/" + framework.destinationDirectory;
+ QString to = toDir + "/" + framework.binaryName;
if (QFile::exists(from) == false) {
- qDebug() << "ERROR: no file at" << from;
+ LogError() << "no file at" << from;
return QString();
}
QDir dir;
if (dir.mkpath(toDir) == false) {
- qDebug() << "ERROR: could not create destination directory" << to;
+ LogError() << "could not create destination directory" << to;
return QString();
}
-
+
if (QFile::exists(to)) {
-// qDebug() << framework.frameworkName << "already deployed, skip";
return QString();
}
-
+
copyFilePrintStatus(from, to);
- const QString resourcesSourcePath = framework.frameworkPath + "/Resources";
- const QString resourcesDestianationPath = path + "/Contents/Frameworks/" + framework.frameworkName + "/Resources";
+ const QString resourcesSourcePath = framework.frameworkPath + "/Resources";
+ const QString resourcesDestianationPath = path + "/Contents/Frameworks/" + framework.frameworkName + "/Resources";
recursiveCopy(resourcesSourcePath, resourcesDestianationPath);
return to;
@@ -293,20 +299,25 @@ void runInstallNameTool(QStringList options)
installNametool.start("install_name_tool", options);
installNametool.waitForFinished();
if (installNametool.exitCode() != 0) {
- qDebug() << installNametool.readAllStandardError();
- qDebug() << installNametool.readAllStandardOutput();
+ LogError() << installNametool.readAllStandardError();
+ LogError() << installNametool.readAllStandardOutput();
}
}
void changeIdentification(const QString &id, const QString &binaryPath)
{
-// qDebug() << "change identification on" << binaryPath << id;
+ LogDebug() << "Using install_name_tool:";
+ LogDebug() << " change identification in" << binaryPath;
+ LogDebug() << " to" << id;
runInstallNameTool(QStringList() << "-id" << id << binaryPath);
}
void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath)
{
-// qDebug() << "change install name on" << binaryPath << oldName << newName;
+ LogDebug() << "Using install_name_tool:";
+ LogDebug() << " in" << binaryPath;
+ LogDebug() << " change reference" << oldName;
+ LogDebug() << " to" << newName;
runInstallNameTool(QStringList() << "-change" << oldName << newName << binaryPath);
}
@@ -315,14 +326,14 @@ void runStrip(const QString &binaryPath)
if (runStripEnabled == false)
return;
+ LogDebug() << "Using strip:";
+ LogDebug() << " stripped" << binaryPath;
QProcess strip;
strip.start("strip", QStringList() << "-x" << binaryPath);
strip.waitForFinished();
if (strip.exitCode() != 0) {
- qDebug() << strip.readAllStandardError();
- qDebug() << strip.readAllStandardOutput();
- } else {
- qDebug() << "stripped" << binaryPath;
+ LogError() << strip.readAllStandardError();
+ LogError() << strip.readAllStandardOutput();
}
}
@@ -333,15 +344,18 @@ void runStrip(const QString &binaryPath)
Returns a DeploymentInfo structure containing the Qt path used and a
a list of actually deployed frameworks.
*/
-DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString &bundlePath, const QString &binaryPath)
+DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks,
+ const QString &bundlePath, const QString &binaryPath, bool useDebugLibs)
{
+ LogNormal();
+ LogNormal() << "Deploying Qt frameworks found inside:" << binaryPath;
QStringList copiedFrameworks;
DeploymentInfo deploymenInfo;
-
+
while (frameworks.isEmpty() == false) {
const FrameworkInfo framework = frameworks.takeFirst();
copiedFrameworks.append(framework.frameworkName);
-
+
// Get the qt path from one of the Qt frameworks;
if (deploymenInfo.qtPath.isNull() && framework.frameworkName.contains("Qt")
&& framework.frameworkDirectory.contains("/lib"))
@@ -350,14 +364,11 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString
deploymenInfo.qtPath.chop(5); // remove "/lib/"
}
-// qDebug() << "";
-// qDebug() << "deploy" << framework.frameworkName;
-
if (framework.installName.startsWith("/@executable_path/")) {
- qDebug() << framework.frameworkName << "already deployed, skipping.";
+ LogError() << framework.frameworkName << "already deployed, skipping.";
continue;
}
-
+
// Install_name_tool the new id into the binary
changeInstallName(framework.installName, framework.deployedInstallName, binaryPath);
@@ -366,18 +377,17 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString
// Skip the rest if already was deployed.
if (deployedBinaryPath.isNull())
continue;
-
+
runStrip(deployedBinaryPath);
// Install_name_tool it a new id.
changeIdentification(framework.deployedInstallName, deployedBinaryPath);
// Check for framework dependencies
- QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath);
+ QList<FrameworkInfo> dependencies = getQtFrameworks(deployedBinaryPath, useDebugLibs);
foreach (FrameworkInfo dependency, dependencies) {
-// qDebug() << "dependent framework" << dependency.installName << deployedBinaryPath;
changeInstallName(dependency.installName, dependency.deployedInstallName, deployedBinaryPath);
-
+
// Deploy framework if neccesary.
if (copiedFrameworks.contains(dependency.frameworkName) == false && frameworks.contains(dependency) == false) {
frameworks.append(dependency);
@@ -388,28 +398,39 @@ DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString
return deploymenInfo;
}
-DeploymentInfo deployQtFrameworks(const QString &appBundlePath)
+DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs)
{
ApplicationBundleInfo applicationBundle;
applicationBundle.path = appBundlePath;
applicationBundle.binaryPath = findAppBinary(appBundlePath);
- return deployQtFrameworks(getQtFrameworks(applicationBundle.binaryPath), applicationBundle.path, applicationBundle.binaryPath);
+ QList<FrameworkInfo> frameworks = getQtFrameworks(applicationBundle.binaryPath, useDebugLibs);
+ if (frameworks.isEmpty()) {
+ LogWarning();
+ LogWarning() << "Could not find any external Qt frameworks to deploy in" << appBundlePath;
+ LogWarning() << "Perhaps macdeployqt was already used on" << appBundlePath << "?";
+ LogWarning() << "If so, you will need to rebuild" << appBundlePath << "before trying again.";
+ return DeploymentInfo();
+ } else {
+ return deployQtFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, useDebugLibs);
+ }
}
-void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath, const QString pluginDestinationPath, DeploymentInfo deploymentInfo)
+void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pluginSourcePath,
+ const QString pluginDestinationPath, DeploymentInfo deploymentInfo, bool useDebugLibs)
{
+ LogNormal() << "Deploying plugins from" << pluginSourcePath;
QStringList plugins = QDir(pluginSourcePath).entryList(QStringList() << "*.dylib");
foreach (QString pluginName, plugins) {
-
- // Skip some Qt plugins based on what frameworks were deployed:
- //qDebug() << pluginSourcePath << deploymentInfo.pluginPath;
-
if (pluginSourcePath.contains(deploymentInfo.pluginPath)) {
QStringList deployedFrameworks = deploymentInfo.deployedFrameworks;
- // Skip the debug versions of the plugins
- if (pluginName.endsWith("_debug.dylib"))
+ // Skip the debug versions of the plugins, unless specified otherwise.
+ if (!useDebugLibs && pluginName.endsWith("_debug.dylib"))
+ continue;
+
+ // Skip the release versions of the plugins, unless specified otherwise.
+ if (useDebugLibs && !pluginName.endsWith("_debug.dylib"))
continue;
// Skip the designer plugins
@@ -420,7 +441,7 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
// SKip the opengl graphicssystem plugin when not in use.
if (pluginName.contains("libqglgraphicssystem"))
continue;
-#endif
+#endif
// Deploy accessibility for Qt3Support only if the Qt3Support.framework is in use
if (deployedFrameworks.indexOf("Qt3Support.framework") == -1 && pluginName.contains("accessiblecompatwidgets"))
continue;
@@ -448,28 +469,25 @@ void deployPlugins(const ApplicationBundleInfo &appBundleInfo, const QString &pl
const QString sourcePath = pluginSourcePath + "/" + pluginName;
const QString destinationPath = pluginDestinationPath + "/" + pluginName;
if (copyFilePrintStatus(sourcePath, destinationPath)) {
-
- runStrip(destinationPath);
-
- // Special case for the phonon plugin: CoreVideo is not available as a separate framework
- // on panther, link against the QuartzCore framework instead. (QuartzCore contians CoreVideo.)
- if (pluginName.contains("libphonon_qt7")) {
- changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
- "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
- destinationPath);
- }
-// qDebug() << "deploy plugin depedencies:";
- QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath);
-// qDebug() << frameworks;
- deployQtFrameworks(frameworks, appBundleInfo.path, destinationPath);
-// qDebug() << "deploy plugin depedencies done";
+ runStrip(destinationPath);
+
+ // Special case for the phonon plugin: CoreVideo is not available as a separate framework
+ // on panther, link against the QuartzCore framework instead. (QuartzCore contians CoreVideo.)
+ if (pluginName.contains("libphonon_qt7")) {
+ changeInstallName("/System/Library/Frameworks/CoreVideo.framework/Versions/A/CoreVideo",
+ "/System/Library/Frameworks/QuartzCore.framework/Versions/A/QuartzCore",
+ destinationPath);
+ }
+
+ QList<FrameworkInfo> frameworks = getQtFrameworks(destinationPath, useDebugLibs);
+ deployQtFrameworks(frameworks, appBundleInfo.path, destinationPath, useDebugLibs);
}
} // foreach plugins
QStringList subdirs = QDir(pluginSourcePath).entryList(QStringList() << "*", QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &subdir, subdirs)
- deployPlugins(appBundleInfo, pluginSourcePath + "/" + subdir, pluginDestinationPath + "/" + subdir, deploymentInfo);
+ deployPlugins(appBundleInfo, pluginSourcePath + "/" + subdir, pluginDestinationPath + "/" + subdir, deploymentInfo, useDebugLibs);
}
void createQtConf(const QString &appBundlePath)
@@ -479,63 +497,64 @@ void createQtConf(const QString &appBundlePath)
QString fileName = filePath + "qt.conf";
QDir().mkpath(filePath);
-
+
QFile qtconf(fileName);
if (qtconf.exists()) {
- qDebug() << "";
- qDebug() << "Warning:" << fileName << "already exists, will not overwrite.";
- qDebug() << "To make sure the plugins are loaded from the correct location,";
- qDebug() << "please make sure qt.conf contains the following lines:";
- qDebug() << contents;
- qDebug() << "";
+ LogWarning();
+ LogWarning() << fileName << "already exists, will not overwrite.";
+ LogWarning() << "To make sure the plugins are loaded from the correct location,";
+ LogWarning() << "please make sure qt.conf contains the following lines:";
+ LogWarning() << "[Paths]";
+ LogWarning() << " Plugins = PlugIns";
return;
}
qtconf.open(QIODevice::WriteOnly);
if (qtconf.write(contents) != -1) {
- qDebug() << "";
- qDebug() << "Created configuration file:" << fileName;
- qDebug() << "This file sets the plugin search path to" << appBundlePath + "/Contents/PlugIns";
- qDebug() << "";
+ LogNormal() << "Created configuration file:" << fileName;
+ LogNormal() << "This file sets the plugin search path to" << appBundlePath + "/Contents/PlugIns";
}
}
-void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo)
+void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs)
{
ApplicationBundleInfo applicationBundle;
applicationBundle.path = appBundlePath;
applicationBundle.binaryPath = findAppBinary(appBundlePath);
-
+
const QString pluginDestinationPath = appBundlePath + "/" + "Contents/PlugIns";
-
-// qDebug() << "";
-// qDebug() << "recursively copying plugins from" << deploymentInfo.pluginPath << "to" << pluginDestinationPath;
- deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo);
+ deployPlugins(applicationBundle, deploymentInfo.pluginPath, pluginDestinationPath, deploymentInfo, useDebugLibs);
}
void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QString &appBinaryPath, const QString &absoluteQtPath)
{
- qDebug() << "Changing" << appBinaryPath << "to link against Qt in" << absoluteQtPath;
+ LogNormal() << "Changing" << appBinaryPath << "to link against";
+ LogNormal() << "Qt in" << absoluteQtPath;
QString finalQtPath = absoluteQtPath;
- if (absoluteQtPath.startsWith("/Library/Frameworks") == false)
+ if (!absoluteQtPath.startsWith("/Library/Frameworks"))
finalQtPath += "/lib/";
foreach (FrameworkInfo framework, frameworks) {
const QString oldBinaryId = framework.installName;
const QString newBinaryId = finalQtPath + framework.frameworkName + framework.binaryPath;
- qDebug() << "Changing" << oldBinaryId << "to" << newBinaryId;
changeInstallName(oldBinaryId, newBinaryId, appBinaryPath);
}
}
-void changeQtFrameworks(const QString appPath, const QString &qtPath)
+void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs)
{
const QString appBinaryPath = findAppBinary(appPath);
- const QList<FrameworkInfo> qtFrameworks = getQtFrameworks(appBinaryPath);
- const QString absoluteQtPath = QDir(qtPath).absolutePath();
- changeQtFrameworks(qtFrameworks, appBinaryPath, absoluteQtPath);
+ const QList<FrameworkInfo> frameworks = getQtFrameworks(appBinaryPath, useDebugLibs);
+ if (frameworks.isEmpty()) {
+ LogWarning();
+ LogWarning() << "Could not find any _external_ Qt frameworks to change in" << appPath;
+ return;
+ } else {
+ const QString absoluteQtPath = QDir(qtPath).absolutePath();
+ changeQtFrameworks(frameworks, appBinaryPath, absoluteQtPath);
+ }
}
@@ -543,15 +562,15 @@ void createDiskImage(const QString &appBundlePath)
{
QString appBaseName = appBundlePath;
appBaseName.chop(4); // remove ".app" from end
-
+
QString dmgName = appBaseName + ".dmg";
QFile dmg(dmgName);
if (dmg.exists()) {
- qDebug() << "Disk image already exists, skipping .dmg creation for" << dmg.fileName();
+ LogNormal() << "Disk image already exists, skipping .dmg creation for" << dmg.fileName();
} else {
- qDebug() << "Creating disk image (.dmg) for" << appBundlePath;
+ LogNormal() << "Creating disk image (.dmg) for" << appBundlePath;
}
// More dmg options can be found in the hdiutil man page.
diff --git a/tools/macdeployqt/shared/shared.h b/tools/macdeployqt/shared/shared.h
index ed44a64..a7a09e0 100644
--- a/tools/macdeployqt/shared/shared.h
+++ b/tools/macdeployqt/shared/shared.h
@@ -45,6 +45,12 @@
#include <QStringList>
#include <QDebug>
+extern int logLevel;
+#define LogError() if (logLevel < 1) {} else qDebug() << "ERROR:"
+#define LogWarning() if (logLevel < 1) {} else qDebug() << "WARNING:"
+#define LogNormal() if (logLevel < 2) {} else qDebug() << "Log:"
+#define LogDebug() if (logLevel < 3) {} else qDebug() << "Log:"
+
extern bool runStripEnabled;
class FrameworkInfo
@@ -68,7 +74,7 @@ QDebug operator<<(QDebug debug, const FrameworkInfo &info);
class ApplicationBundleInfo
{
-public:
+ public:
QString path;
QString binaryPath;
};
@@ -84,18 +90,18 @@ public:
inline QDebug operator<<(QDebug debug, const ApplicationBundleInfo &info);
-void changeQtFrameworks(const QString appPath, const QString &qtPath);
+void changeQtFrameworks(const QString appPath, const QString &qtPath, bool useDebugLibs);
void changeQtFrameworks(const QList<FrameworkInfo> frameworks, const QString &appBinaryPath, const QString &qtPath);
-FrameworkInfo parseOtoolLibraryLine(const QString &line);
+FrameworkInfo parseOtoolLibraryLine(const QString &line, bool useDebugLibs);
QString findAppBinary(const QString &appBundlePath);
-QList<FrameworkInfo> getQtFrameworks(const QString &path);
-QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines);
+QList<FrameworkInfo> getQtFrameworks(const QString &path, bool useDebugLibs);
+QList<FrameworkInfo> getQtFrameworks(const QStringList &otoolLines, bool useDebugLibs);
QString copyFramework(const FrameworkInfo &framework, const QString path);
-DeploymentInfo deployQtFrameworks(const QString &appBundlePath);
+DeploymentInfo deployQtFrameworks(const QString &appBundlePath, bool useDebugLibs);
DeploymentInfo deployQtFrameworks(QList<FrameworkInfo> frameworks, const QString &bundlePath, const QString &binaryPath);
void createQtConf(const QString &appBundlePath);
-void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo);
+void deployPlugins(const QString &appBundlePath, DeploymentInfo deploymentInfo, bool useDebugLibs);
void changeIdentification(const QString &id, const QString &binaryPath);
void changeInstallName(const QString &oldName, const QString &newName, const QString &binaryPath);
QString findAppBinary(const QString &appBundlePath);
diff --git a/tools/pixeltool/qpixeltool.cpp b/tools/pixeltool/qpixeltool.cpp
index 0e9416c..beea85a 100644
--- a/tools/pixeltool/qpixeltool.cpp
+++ b/tools/pixeltool/qpixeltool.cpp
@@ -179,13 +179,13 @@ void QPixelTool::paintEvent(QPaintEvent *)
if (m_displayZoom) {
render_string(&p, w, h,
- QString(QLatin1String("Zoom: x%1")).arg(m_zoom),
+ QString::fromLatin1("Zoom: x%1").arg(m_zoom),
Qt::AlignTop | Qt::AlignRight);
}
if (m_displayGridSize) {
render_string(&p, w, h,
- QString(QLatin1String("Grid size: %1")).arg(m_gridSize),
+ QString::fromLatin1("Grid size: %1").arg(m_gridSize),
Qt::AlignBottom | Qt::AlignLeft);
}
diff --git a/tools/porting/src/logger.cpp b/tools/porting/src/logger.cpp
index 8727d65..8a38dd2 100644
--- a/tools/porting/src/logger.cpp
+++ b/tools/porting/src/logger.cpp
@@ -60,8 +60,8 @@ SourcePointLogEntry::SourcePointLogEntry(QString type, QString location, QString
QString SourcePointLogEntry::description() const
{
return QLatin1String("In file ") + file +
- QLatin1String(" at line ") + QString(QLatin1String("%1")).arg(line + 1) + //line count is zero based, adjust here.
- QLatin1String(" column ") + QString(QLatin1String("%1")).arg(column) +
+ QLatin1String(" at line ") + QString::number(line + 1) + //line count is zero based, adjust here.
+ QLatin1String(" column ") + QString::number(column) +
QLatin1String(": ") + text ;
}
@@ -127,7 +127,7 @@ QStringList Logger::fullReport()
commitSection();
QStringList report;
report << QLatin1String("Log for qt3to4 on ") + QDateTime::currentDateTime().toString() +
- QLatin1String(". Number of log entries: ") + QString(QLatin1String("%1")).arg(logEntries.size());
+ QLatin1String(". Number of log entries: ") + QString::number(logEntries.size());
foreach(LogEntry *logEntry, logEntries) {
report << logEntry->description();
}
diff --git a/tools/qdbus/qdbusviewer/qdbusviewer.cpp b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
index ca747c2..af37596 100644
--- a/tools/qdbus/qdbusviewer/qdbusviewer.cpp
+++ b/tools/qdbus/qdbusviewer/qdbusviewer.cpp
@@ -441,21 +441,14 @@ void QDBusViewer::about()
{
QMessageBox box(this);
- // TODO: Remove these variables for 4.6.0. Must keep this way for 4.5.x due to string freeze.
- QString edition;
- QString info;
- QString moreInfo;
-
box.setText(QString::fromLatin1("<center><img src=\":/trolltech/qdbusviewer/images/qdbusviewer-128.png\">"
"<h3>%1</h3>"
- "<p>Version %2 %3</p></center>"
- "<p>%4</p>"
- "<p>%5</p>"
+ "<p>Version %2</p></center>"
"<p>Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).</p>"
"<p>The program is provided AS IS with NO WARRANTY OF ANY KIND,"
" INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A"
" PARTICULAR PURPOSE.<p/>")
- .arg(tr("D-Bus Viewer")).arg(QLatin1String(QT_VERSION_STR)).arg(edition).arg(info).arg(moreInfo));
+ .arg(tr("D-Bus Viewer")).arg(QLatin1String(QT_VERSION_STR)));
box.setWindowTitle(tr("D-Bus Viewer"));
box.exec();
}
diff --git a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
index 5d1ac32..b8b9338 100644
--- a/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/tools/qdbus/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -613,18 +613,15 @@ static void writeProxy(const QString &filename, const QDBusIntrospection::Interf
// getter:
if (property.access != QDBusIntrospection::Property::Write) {
- hs << " inline " << type << " " << getter << "() const" << endl;
- if (type != "QVariant")
- hs << " { return qvariant_cast< " << type << " >(internalPropGet(\""
- << property.name << "\")); }" << endl;
- else
- hs << " { return internalPropGet(\"" << property.name << "\"); }" << endl;
+ hs << " inline " << type << " " << getter << "() const" << endl
+ << " { return qvariant_cast< " << type << " >(property(\""
+ << property.name << "\")); }" << endl;
}
// setter:
if (property.access != QDBusIntrospection::Property::Read) {
hs << " inline void " << setter << "(" << constRefArg(type) << "value)" << endl
- << " { internalPropSet(\"" << property.name
+ << " { setProperty(\"" << property.name
<< "\", qVariantFromValue(value)); }" << endl;
}
diff --git a/tools/qdoc3/codemarker.cpp b/tools/qdoc3/codemarker.cpp
index 728f9fa..e95153d 100644
--- a/tools/qdoc3/codemarker.cpp
+++ b/tools/qdoc3/codemarker.cpp
@@ -331,7 +331,10 @@ QString CodeMarker::sortName(const Node *node)
return QLatin1Char('B') + nodeName;
}
-void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle style, Status status)
+void CodeMarker::insert(FastSection &fastSection,
+ Node *node,
+ SynopsisStyle style,
+ Status status)
{
bool inheritedMember = (!node->relates() &&
(node->parent() != (const InnerNode *)fastSection.innerNode));
@@ -339,12 +342,14 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
if (node->access() == Node::Private) {
irrelevant = true;
- } else if (node->type() == Node::Function) {
+ }
+ else if (node->type() == Node::Function) {
FunctionNode *func = (FunctionNode *) node;
irrelevant = (inheritedMember
&& (func->metaness() == FunctionNode::Ctor ||
func->metaness() == FunctionNode::Dtor));
- } else if (node->type() == Node::Class || node->type() == Node::Enum
+ }
+ else if (node->type() == Node::Class || node->type() == Node::Enum
|| node->type() == Node::Typedef) {
irrelevant = (inheritedMember && style != SeparateList);
if (!irrelevant && style == Detailed && node->type() == Node::Typedef) {
@@ -357,9 +362,11 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
if (!irrelevant) {
if (status == Compat) {
irrelevant = (node->status() != Node::Compat);
- } else if (status == Obsolete) {
+ }
+ else if (status == Obsolete) {
irrelevant = (node->status() != Node::Obsolete);
- } else {
+ }
+ else {
irrelevant = (node->status() == Node::Compat ||
node->status() == Node::Obsolete);
}
@@ -370,7 +377,8 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
QString key = sortName(node);
if (!fastSection.memberMap.contains(key))
fastSection.memberMap.insert(key, node);
- } else {
+ }
+ else {
if (node->parent()->type() == Node::Class) {
if (fastSection.inherited.isEmpty()
|| fastSection.inherited.last().first != node->parent()) {
@@ -383,16 +391,42 @@ void CodeMarker::insert(FastSection &fastSection, Node *node, SynopsisStyle styl
}
}
-void CodeMarker::append(QList<Section>& sectionList,
- const FastSection& fastSection)
+/*!
+ Returns true if \a node represents a reimplemented member function.
+ If it is, then it is inserted in the reimplemented member map in the
+ section \a fs. And, the test is only performed if \a status is \e OK.
+ Otherwise, false is returned.
+ */
+bool CodeMarker::insertReimpFunc(FastSection& fs, Node* node, Status status)
+{
+ if (node->access() == Node::Private)
+ return false;
+
+ const FunctionNode* fn = static_cast<const FunctionNode*>(node);
+ if ((fn->reimplementedFrom() != 0) && (status == Okay)) {
+ bool inherited = (!fn->relates() && (fn->parent() != (const InnerNode*)fs.innerNode));
+ if (!inherited) {
+ QString key = sortName(fn);
+ if (!fs.reimpMemberMap.contains(key)) {
+ fs.reimpMemberMap.insert(key,node);
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+/*!
+ If \a fs is not empty, convert it to a Section and append
+ the new Section to \a sectionList.
+ */
+void CodeMarker::append(QList<Section>& sectionList, const FastSection& fs)
{
- if (!fastSection.memberMap.isEmpty() ||
- !fastSection.inherited.isEmpty()) {
- Section section(fastSection.name,
- fastSection.singularMember,
- fastSection.pluralMember);
- section.members = fastSection.memberMap.values();
- section.inherited = fastSection.inherited;
+ if (!fs.isEmpty()) {
+ Section section(fs.name,fs.singularMember,fs.pluralMember);
+ section.members = fs.memberMap.values();
+ section.reimpMembers = fs.reimpMemberMap.values();
+ section.inherited = fs.inherited;
sectionList.append(section);
}
}
diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h
index 483dc4d..67b1064 100644
--- a/tools/qdoc3/codemarker.h
+++ b/tools/qdoc3/codemarker.h
@@ -61,6 +61,7 @@ struct Section
QString singularMember;
QString pluralMember;
NodeList members;
+ NodeList reimpMembers;
QList<QPair<ClassNode *, int> > inherited;
Section() { }
@@ -79,6 +80,7 @@ struct FastSection
QString singularMember;
QString pluralMember;
QMap<QString, Node *> memberMap;
+ QMap<QString, Node *> reimpMemberMap;
QList<QPair<ClassNode *, int> > inherited;
FastSection(const InnerNode *innerNode0,
@@ -89,6 +91,11 @@ struct FastSection
name(name0),
singularMember(singularMember0),
pluralMember(pluralMember0) { }
+ bool isEmpty() const {
+ return (memberMap.isEmpty() && inherited.isEmpty() &&
+ reimpMemberMap.isEmpty());
+ }
+
};
class CodeMarker
@@ -150,6 +157,7 @@ class CodeMarker
Node *node,
SynopsisStyle style,
Status status);
+ bool insertReimpFunc(FastSection& fs, Node* node, Status status);
void append(QList<Section>& sectionList, const FastSection& fastSection);
private:
diff --git a/tools/qdoc3/codeparser.cpp b/tools/qdoc3/codeparser.cpp
index 2fedd67..92243fa 100644
--- a/tools/qdoc3/codeparser.cpp
+++ b/tools/qdoc3/codeparser.cpp
@@ -47,6 +47,7 @@
#include "codeparser.h"
#include "node.h"
#include "tree.h"
+#include "config.h"
QT_BEGIN_NAMESPACE
@@ -67,6 +68,7 @@ QT_BEGIN_NAMESPACE
#define COMMAND_TITLE Doc::alias(QLatin1String("title"))
QList<CodeParser *> CodeParser::parsers;
+bool CodeParser::showInternal = false;
/*!
The constructor adds this code parser to the static
@@ -87,11 +89,11 @@ CodeParser::~CodeParser()
}
/*!
- Initializing a code parser is trivial.
+ Initialize the code parser base class.
*/
-void CodeParser::initializeParser(const Config & /* config */)
+void CodeParser::initializeParser(const Config& config)
{
- // nothing.
+ showInternal = config.getBool(QLatin1String(CONFIG_SHOWINTERNAL));
}
/*!
@@ -217,8 +219,10 @@ void CodeParser::processCommonMetaCommand(const Location &location,
node->setStatus(Node::Preliminary);
}
else if (command == COMMAND_INTERNAL) {
- node->setAccess(Node::Private);
- node->setStatus(Node::Internal);
+ if (!showInternal) {
+ node->setAccess(Node::Private);
+ node->setStatus(Node::Internal);
+ }
}
else if (command == COMMAND_REENTRANT) {
node->setThreadSafeness(Node::Reentrant);
@@ -241,19 +245,6 @@ void CodeParser::processCommonMetaCommand(const Location &location,
if (node->type() == Node::Fake) {
FakeNode *fake = static_cast<FakeNode *>(node);
fake->setTitle(arg);
-#ifdef QDOC2DOX
- /* qdoc -> doxygen.
- I think this must be done here, because there can be multiple
- "\externalpage" and "\title" metacommands in a single qdoc
- comment, which means, among other things, that the "\title"
- commands are not inserted into the metacommand map used by
- the Doc class. I'm sure there4 is a better way to do this in
- the DoxWriter class using the information in the FakeNode,
- but I don't have time to figure it out right now.
- */
- if (DoxWriter::isDoxPass(1))
- DoxWriter::insertTitle(fake,arg);
-#endif
}
else
location.warning(tr("Ignored '\\%1'").arg(COMMAND_TITLE));
diff --git a/tools/qdoc3/codeparser.h b/tools/qdoc3/codeparser.h
index 8f5bd87..06603a9 100644
--- a/tools/qdoc3/codeparser.h
+++ b/tools/qdoc3/codeparser.h
@@ -87,6 +87,7 @@ class CodeParser
private:
static QList<CodeParser *> parsers;
+ static bool showInternal;
};
QT_END_NAMESPACE
diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp
index 20b0aa7..ad993d9 100644
--- a/tools/qdoc3/config.cpp
+++ b/tools/qdoc3/config.cpp
@@ -751,7 +751,7 @@ void Config::load(Location location, const QString& fileName)
word += QChar(c.digitValue());
SKIP_CHAR();
}
- else if ((metaCharPos = QString(QLatin1String("abfnrtv")).indexOf(c)) != -1) {
+ else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
word += "\a\b\f\n\r\t\v"[metaCharPos];
SKIP_CHAR();
}
diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h
index 8f25340..4e97d9f 100644
--- a/tools/qdoc3/config.h
+++ b/tools/qdoc3/config.h
@@ -147,6 +147,7 @@ class Config
#define CONFIG_QHP "qhp"
#define CONFIG_QUOTINGINFORMATION "quotinginformation"
#define CONFIG_SLOW "slow"
+#define CONFIG_SHOWINTERNAL "showinternal"
#define CONFIG_SOURCEDIRS "sourcedirs"
#define CONFIG_SOURCES "sources"
#define CONFIG_SPURIOUS "spurious"
diff --git a/tools/qdoc3/cppcodemarker.cpp b/tools/qdoc3/cppcodemarker.cpp
index 6760c65..f807609 100644
--- a/tools/qdoc3/cppcodemarker.cpp
+++ b/tools/qdoc3/cppcodemarker.cpp
@@ -43,6 +43,7 @@
cppcodemarker.cpp
*/
+#include <qdebug.h>
#include "atom.h"
#include "cppcodemarker.h"
#include "node.h"
@@ -411,6 +412,21 @@ QString CppCodeMarker::functionEndRegExp(const QString& /* funcName */)
return "^\\}$";
}
+#if 0
+ FastSection privateReimpFuncs(classe,
+ "Private Reimplemented Functions",
+ "private reimplemented function",
+ "private reimplemented functions");
+ FastSection protectedReimpFuncs(classe,
+ "Protected Reimplemented Functions",
+ "protected reimplemented function",
+ "protected reimplemented functions");
+ FastSection publicReimpFuncs(classe,
+ "Public Reimplemented Functions",
+ "public reimplemented function",
+ "public reimplemented functions");
+#endif
+
QList<Section> CppCodeMarker::sections(const InnerNode *inner,
SynopsisStyle style,
Status status)
@@ -421,29 +437,55 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
const ClassNode *classe = static_cast<const ClassNode *>(inner);
if (style == Summary) {
- FastSection privateFunctions(classe, "Private Functions", "private function",
+ 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 protectedFunctions(classe, "Protected Functions", "protected function",
+ 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 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 publicVariables(classe, "Public Variables", "public type", "public variables");
+ FastSection publicVariables(classe,
+ "Public Variables",
+ "public type",
+ "public variables");
FastSection properties(classe, "Properties", "property", "properties");
- FastSection relatedNonMembers(classe, "Related Non-Members", "related non-member",
+ FastSection relatedNonMembers(classe,
+ "Related Non-Members",
+ "related non-member",
"related non-members");
- FastSection staticPrivateMembers(classe, "Static Private Members", "static private member",
+ 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",
+ 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");
@@ -505,7 +547,8 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
insert(publicVariables, *c, style, status);
}
else if ((*c)->type() == Node::Function) {
- insert(publicFunctions, *c, style, status);
+ if (!insertReimpFunc(publicFunctions,*c,status))
+ insert(publicFunctions, *c, style, status);
}
else {
insert(publicTypes, *c, style, status);
@@ -525,7 +568,8 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
insert(protectedVariables, *c, style, status);
}
else if ((*c)->type() == Node::Function) {
- insert(protectedFunctions, *c, style, status);
+ if (!insertReimpFunc(protectedFunctions,*c,status))
+ insert(protectedFunctions, *c, style, status);
}
else {
insert(protectedTypes, *c, style, status);
@@ -541,7 +585,8 @@ QList<Section> CppCodeMarker::sections(const InnerNode *inner,
insert(staticPrivateMembers, *c, style, status);
}
else if ((*c)->type() == Node::Function) {
- insert(privateFunctions, *c, style, status);
+ if (!insertReimpFunc(privateFunctions,*c,status))
+ insert(privateFunctions, *c, style, status);
}
else {
insert(privateTypes, *c, style, status);
diff --git a/tools/qdoc3/cppcodeparser.cpp b/tools/qdoc3/cppcodeparser.cpp
index 204c6e5..cb6caa9 100644
--- a/tools/qdoc3/cppcodeparser.cpp
+++ b/tools/qdoc3/cppcodeparser.cpp
@@ -589,22 +589,6 @@ Node *CppCodeParser::processTopicCommand(const Doc& doc,
// ### split(" ") hack is there to support header file syntax
QStringList paths = arg.split(" ");
QStringList path = paths[0].split("::");
-
-#if QDOC2DOX
- // qdoc -> doxygen.
- if (Doc::isDoxPass(1)) {
- if (command == COMMAND_PROPERTY) {
- Doc::insertProperty(path);
- }
- else if (command == COMMAND_VARIABLE) {
- Doc::insertVariable(path);
- }
- else if (command == COMMAND_ENUM) {
- // zzz
- }
- }
-#endif
-
Node *node = 0;
if (!usedNamespaces.isEmpty()) {
foreach (const QString &usedNamespace, usedNamespaces) {
@@ -755,8 +739,12 @@ void CppCodeParser::processOtherMetaCommand(const Doc& doc,
// Note: Setting the access to Private hides the documentation,
// but setting the status to Internal makes the node available
// in the XML output when the WebXMLGenerator is used.
+#if 0
+ // Reimplemented functions now reported in separate sections.
func->setAccess(Node::Private);
func->setStatus(Node::Internal);
+#endif
+ func->setReimp(true);
}
else {
doc.location().warning(tr("Ignored '\\%1' in %2")
@@ -1753,12 +1741,6 @@ bool CppCodeParser::matchDocsAndStuff()
readToken();
Doc::trimCStyleComment(start_loc,comment);
- /*
- qdoc --> doxygen
- We must also remember the location of the end
- of the comment, so we can construct a diff for
- it.
- */
Location end_loc(location());
/*
diff --git a/tools/qdoc3/doc.cpp b/tools/qdoc3/doc.cpp
index f7007a0..d5aca0e 100644
--- a/tools/qdoc3/doc.cpp
+++ b/tools/qdoc3/doc.cpp
@@ -515,14 +515,7 @@ void DocParser::parse(const QString& source,
break;
case CMD_BADCODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::CodeBad,getUnmarkedCode(CMD_BADCODE));
- else
- append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
-#else
append(Atom::CodeBad,getCode(CMD_BADCODE, marker));
-#endif
break;
case CMD_BASENAME:
leavePara();
@@ -538,17 +531,8 @@ void DocParser::parse(const QString& source,
case CMD_C:
enterPara();
x = untabifyEtc(getArgument(true));
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::C, x);
- else {
- marker = CodeMarker::markerForCode(x);
- append(Atom::C, marker->markedUpCode(x, 0, ""));
- }
-#else
marker = CodeMarker::markerForCode(x);
append(Atom::C, marker->markedUpCode(x, 0, ""));
-#endif
break;
case CMD_CAPTION:
leavePara();
@@ -559,14 +543,7 @@ void DocParser::parse(const QString& source,
break;
case CMD_CODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass())
- append(Atom::Code, getUnmarkedCode(CMD_CODE));
- else
- append(Atom::Code, getCode(CMD_CODE, marker));
-#else
append(Atom::Code, getCode(CMD_CODE, marker));
-#endif
break;
#ifdef QDOC_QML
case CMD_QML:
@@ -579,17 +556,6 @@ void DocParser::parse(const QString& source,
#endif
case CMD_CODELINE:
{
-#ifdef QDOC2DOX
- if (!quoting && !DoxWriter::isDoxPass()) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
- appendToCode("\n");
- } lse {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, " ");
- }
-#else
if (!quoting) {
if (priv->text.lastAtom()->type() == Atom::Code
&& priv->text.lastAtom()->string().endsWith("\n\n"))
@@ -600,37 +566,10 @@ void DocParser::parse(const QString& source,
append(Atom::CodeQuoteCommand, cmdStr);
append(Atom::CodeQuoteArgument, " ");
}
-#endif
}
break;
case CMD_DOTS:
{
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- append(Atom::CodeQuoteCommand, cmdStr);
- append(Atom::CodeQuoteArgument, " ...");
- }
- else if (!quoting) {
- if (priv->text.lastAtom()->type() == Atom::Code
- && priv->text.lastAtom()->string().endsWith("\n\n"))
- priv->text.lastAtom()->chopString();
-
- QString arg = getOptionalArgument();
- int indent = 4;
- if (!arg.isEmpty())
- indent = arg.toInt();
- for (int i = 0; i < indent; ++i)
- appendToCode(" ");
- appendToCode("...\n");
- }
- else {
- append(Atom::CodeQuoteCommand, cmdStr);
- QString arg = getOptionalArgument();
- if (arg.isEmpty())
- arg = "4";
- append(Atom::CodeQuoteArgument, arg);
- }
-#else
if (!quoting) {
if (priv->text.lastAtom()->type() == Atom::Code
&& priv->text.lastAtom()->string().endsWith("\n\n"))
@@ -651,7 +590,6 @@ void DocParser::parse(const QString& source,
arg = "4";
append(Atom::CodeQuoteArgument, arg);
}
-#endif
}
break;
case CMD_ELSE:
@@ -953,19 +891,8 @@ void DocParser::parse(const QString& source,
break;
case CMD_OLDCODE:
leavePara();
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- append(Atom::CodeOld, getUnmarkedCode(CMD_OLDCODE));
- append(Atom::CodeNew, getUnmarkedCode(CMD_NEWCODE));
- }
- else {
- append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
- append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
- }
-#else
append(Atom::CodeOld, getCode(CMD_OLDCODE, marker));
append(Atom::CodeNew, getCode(CMD_NEWCODE, marker));
-#endif
break;
case CMD_OMIT:
getUntilEnd(cmd);
@@ -1147,18 +1074,6 @@ void DocParser::parse(const QString& source,
{
QString snippet = getArgument();
QString identifier = getRestOfLine();
-#ifdef QDOC2DOX
- if (quoting || DoxWriter::isDoxPass()) {
- append(Atom::SnippetCommand, cmdStr);
- append(Atom::SnippetLocation, snippet);
- append(Atom::SnippetIdentifier, identifier);
- }
- else {
- Doc::quoteFromFile(location(),quoter,snippet);
- appendToCode(quoter.quoteSnippet(location(),
- identifier));
- }
-#else
if (quoting) {
append(Atom::SnippetCommand, cmdStr);
append(Atom::SnippetLocation, snippet);
@@ -1169,7 +1084,6 @@ void DocParser::parse(const QString& source,
appendToCode(quoter.quoteSnippet(location(),
identifier));
}
-#endif
}
break;
case CMD_SUB:
@@ -1251,7 +1165,7 @@ void DocParser::parse(const QString& source,
append(Atom::FormattingRight, ATOM_FORMATTING_BOLD);
append(Atom::String, " ");
break;
- case CMD_OVERLOAD: // qdoc --> doxygen
+ case CMD_OVERLOAD:
priv->metacommandsUsed.insert(cmdStr);
x.clear();
if (!isBlankLine())
@@ -1763,10 +1677,13 @@ void DocParser::startSection(Doc::SectioningUnit unit, int cmd)
leavePara();
if (currentSectioningUnit == Doc::Book) {
+#if 0
+ // mws didn't think this was necessary.
if (unit > Doc::Section1)
location().warning(tr("Unexpected '\\%1' without '\\%2'")
.arg(cmdName(cmd))
.arg(cmdName(CMD_SECTION1)));
+#endif
currentSectioningUnit = (Doc::SectioningUnit) (unit - 1);
priv->constructExtra();
priv->extra->sectioningUnit = currentSectioningUnit;
@@ -2343,7 +2260,7 @@ QString DocParser::getCode(int cmd, CodeMarker *marker)
}
/*!
- Used only for generating doxygen output.
+ Was used only for generating doxygen output.
*/
QString DocParser::getUnmarkedCode(int cmd)
{
@@ -2579,36 +2496,6 @@ QString DocParser::slashed(const QString& str)
#define COMMAND_QMLBRIEF Doc::alias("qmlbrief")
#endif
-#ifdef QDOC2DOX
-#define DOXYGEN_INDENT 2
-#define DOXYGEN_TAB_SIZE 4
-#define DOXYGEN_INDENT_STRING " "
-#define DOXYGEN_TAB_STRING " "
-
-static QRegExp ws_rx("\\s");
-static QRegExp not_ws_rx("\\S");
-
-int DoxWriter::doxPass = 0;
-QString DoxWriter::currentClass;
-QSet<QString> DoxWriter::anchors;
-QStringMap DoxWriter::exampleTitles;
-QStringMap DoxWriter::headerFileTitles;
-QStringMap DoxWriter::fileTitles;
-QStringMap DoxWriter::groupTitles;
-QStringMap DoxWriter::moduleTitles;
-QStringMap DoxWriter::pageTitles;
-QStringMap DoxWriter::externalPageTitles;
-QStringMap DoxWriter::exampleTitlesInverse;
-QStringMap DoxWriter::headerFileTitlesInverse;
-QStringMap DoxWriter::fileTitlesInverse;
-QStringMap DoxWriter::groupTitlesInverse;
-QStringMap DoxWriter::moduleTitlesInverse;
-QStringMap DoxWriter::pageTitlesInverse;
-QStringMap DoxWriter::externalPageTitlesInverse;
-QStringMultiMap DoxWriter::variables;
-QStringMultiMap DoxWriter::properties;
-QStringMultiMap DoxWriter::enums;
-#endif
Doc::Doc(const Location& start_loc,
const Location& end_loc,
@@ -2618,15 +2505,6 @@ Doc::Doc(const Location& start_loc,
priv = new DocPrivate(start_loc,end_loc,source);
DocParser parser;
parser.parse(source,priv,metaCommandSet);
-#ifdef QDOC2DOX
- if (DoxWriter::isDoxPass()) {
- DoxWriter doxWriter(source,priv);
- if (DoxWriter::isDoxPass(1))
- doxWriter.pass1();
- else
- doxWriter.pass2();
- }
-#endif
}
Doc::Doc(const Doc& doc)
@@ -3180,1855 +3058,4 @@ void Doc::detach()
priv = newPriv;
}
-#ifdef QDOC2DOX
-/*!
- Sets the doxygen writer pass to \a pass. You can use
- isDoxPass(), with or without a parameter, to test if
- you are in a doxygen writer run or in a specific pass
- of a doxygen writer run.
-
- This function is only called from main() if either the
- \e doxygen1 or \e doxygen2 flag is passed to qdoc3 on
- the command line.
- */
-void DoxWriter::setDoxPass(int pass)
-{
- qDebug() << "SETTING doxygen pass to " << pass
- << " in DoxWriter::setDoxPass()";
- doxPass = pass;
-}
-
-/*!
- Returns true if the doxygen pass is set to \a pass,
- which means we are in the specified \a pass of a doxygen
- writer run of qdoc3.
- */
-bool DoxWriter::isDoxPass(int pass) { return (doxPass == pass); }
-
-/*!
- Returns true if the doxygen pass is 1 or 2, which
- means this is a doxygen writer run to transform qdoc
- comments into doxygen comments.
- */
-bool DoxWriter::isDoxPass() { return (doxPass > 0); }
-
-bool DoxWriter::conversionRequired() const
-{
- /*
- Loop through all the topic commands searching for
- one that must be transformed to doxygen format. If
- one is found, return true.
- */
- QCommandMap::const_iterator i;
- i = priv->metaCommandMap.constBegin();
- while (i != priv->metaCommandMap.constEnd()) {
- QString s = i.key();
- if (s == "enum")
- return true;
- else if (s == "example")
- return true;
- else if (s == "externalpage")
- return true;
- else if (s == "group")
- return true;
- else if (s == "headerfile")
- return true;
- else if (s == "module")
- return true;
- else if (s == "page")
- return true;
- else if (s == "property")
- return true;
- else if (s == "typedef")
- return true;
- else if (s == "variable")
- return true;
- else if (s == "overload")
- return true;
- else if (s == "reimp")
- return true;
- else if (s == "relates")
- return true;
- else if (s == "macro")
- return true;
- else {
-#if 0
- if (s == "class")
- else if (s == "namespace")
- else if (s == "service")
- else if (s == "inheaderfile")
- else if (s == "file")
- else if (s == "fn")
- else if (s == "contentspage")
- else if (s == "nextpage")
- else if (s == "previous")
- else if (s == "indexpage")
- else if (s == "startpage")
-#endif
- }
- ++i;
- }
-
- /*
- Loop through all the qdoc atoms searching for one
- that must be transformed to doxygen format. If one
- is found, return true.
- */
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- Atom::Type atomType = next->type();
- switch (atomType) {
- case Atom::C:
- case Atom::CaptionLeft:
- case Atom::Code:
- case Atom::CodeBad:
- case Atom::CodeNew:
- case Atom::CodeOld:
- case Atom::CodeQuoteArgument:
- case Atom::CodeQuoteCommand:
- case Atom::FootnoteLeft:
- case Atom::FormatElse:
- case Atom::FormatEndif:
- case Atom::FormatIf:
- case Atom::GeneratedList:
- case Atom::Image:
- case Atom::ImageText:
- case Atom::InlineImage:
- case Atom::LegaleseLeft:
- case Atom::LineBreak:
- case Atom::Link:
- case Atom::LinkNode:
- case Atom::ListLeft:
- case Atom::ListItemNumber:
- case Atom::ListTagLeft:
- case Atom::ListItemLeft:
- case Atom::QuotationLeft:
- case Atom::RawString:
- case Atom::SectionLeft:
- case Atom::SectionHeadingLeft:
- case Atom::SidebarLeft:
- case Atom::SnippetCommand:
- case Atom::SnippetIdentifier:
- case Atom::SnippetLocation:
- case Atom::TableLeft:
- case Atom::TableHeaderLeft:
- case Atom::TableRowLeft:
- case Atom::TableItemLeft:
- case Atom::TableOfContents:
- case Atom::Target:
- return true;
- case Atom::AbstractLeft:
- case Atom::AbstractRight:
- case Atom::AutoLink:
- case Atom::BaseName:
- case Atom::BriefLeft:
- case Atom::BriefRight:
- case Atom::CaptionRight:
- case Atom::FormattingLeft:
- case Atom::FormattingRight:
- case Atom::Nop:
- case Atom::ParaLeft:
- case Atom::ParaRight:
- case Atom::FootnoteRight:
- case Atom::LegaleseRight:
- case Atom::ListTagRight:
- case Atom::ListItemRight:
- case Atom::ListRight:
- case Atom::QuotationRight:
- case Atom::SectionRight:
- case Atom::SectionHeadingRight:
- case Atom::SidebarRight:
- case Atom::String:
- case Atom::TableRight:
- case Atom::TableHeaderRight:
- case Atom::TableRowRight:
- case Atom::TableItemRight:
- default:
- break;
- }
- next = next->next();
- }
- return false;
-}
-
-/*!
- A convenience function to write a qdoc metacommand as a
- doxygen command, without conversion. i.e., some of the
- qdoc metacommands don't require conversion for doxygen.
- */
-void DoxWriter::writeCommand(QCommandMap::const_iterator cmd)
-{
- concatenate("\\" + cmd.key() + " " + cmd.value()[0]);
- newLine();
-}
-
-/*!
- Convert the qdoc commands in the metacommand map to
- doxygen format. This function is called only in pass2().
- The metacommand map contains all the metacommands that
- were found in the qdoc comment that is being converted.
- The metacommands are the ones that begin with the '\'.
- These are not considered part of the text of the comment.
- The text is converted by convertText().
- */
-void DoxWriter::convertMetaCommands()
-{
- QCommandMap& metaCmdMap = priv->metaCommandMap;
- QCommandMap::iterator cmd;
- int c;
-
- currentPage.clear();
- currentFn.clear();
- currentTitle.clear();
- currentEnum.clear();
- currentProperty.clear();
- currentVariable.clear();
- currentClass.clear();
- currentExample.clear();
- currentGroup.clear();
- currentModule.clear();
- currentMacro.clear();
- currentService.clear();
- currentTypedef.clear();
- currentHeaderFile.clear();
- commentType = OtherComment;
-
- if ((cmd = metaCmdMap.find("class")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.indexOf(' ')) > 0)
- currentClass = currentClass.left(c);
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = ClassComment;
- }
- else if ((cmd = metaCmdMap.find("fn")) != metaCmdMap.end()) {
- currentFn = cmd.value()[0];
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = FnComment;
- }
- else if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
- currentEnum = cmd.value()[0];
- if ((c = currentEnum.lastIndexOf("::")) > 0) {
- currentClass = currentEnum.left(c);
- currentEnum = currentEnum.right(currentEnum.size()-c-2);
- qDebug() << "currentEnum =" << currentEnum;
- qDebug() << "currentClass =" << currentClass;
- }
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = EnumComment;
- }
- else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentProperty = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentProperty =" << currentProperty;
- qDebug() << "currentClass =" << currentClass;
- }
- writeCommand(cmd);
- metaCmdMap.erase(cmd);
- commentType = PropertyComment;
- }
- else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentVariable = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentVariable =" << currentVariable;
- qDebug() << "currentClass =" << currentClass;
- }
- concatenate("\\var " + cmd.value()[0]);
- newLine();
- metaCmdMap.erase(cmd);
- commentType = VariableComment;
- }
-
- if ((cmd = metaCmdMap.find("page")) != metaCmdMap.end()) {
- currentPage = cmd.value()[0];
- QString htmlFile = currentPage;
- const QString* title = getPageTitle(htmlFile);
- QStringList parts = htmlFile.split('.');
- metaCmdMap.erase(cmd);
- if (title) {
- concatenate("\\page " + parts[0] + " " + *title);
- newLine();
- }
- commentType = PageComment;
- qDebug() << "currentPage =" << currentPage;
- }
-
- if ((cmd = metaCmdMap.find("example")) != metaCmdMap.end()) {
- currentExample = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = ExampleComment;
- qDebug() << "currentExample =" << currentExample;
- }
-
- if ((cmd = metaCmdMap.find("macro")) != metaCmdMap.end()) {
- currentMacro = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = MacroComment;
- qDebug() << "currentMacro =" << currentMacro;
- }
-
- if ((cmd = metaCmdMap.find("group")) != metaCmdMap.end()) {
- currentGroup = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = GroupComment;
- qDebug() << "currentGroup =" << currentGroup;
- }
-
- if ((cmd = metaCmdMap.find("module")) != metaCmdMap.end()) {
- currentModule = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = ModuleComment;
- qDebug() << "currentModule =" << currentModule;
- }
-
- if ((cmd = metaCmdMap.find("headerfile")) != metaCmdMap.end()) {
- currentHeaderFile = cmd.value()[0];
- metaCmdMap.erase(cmd);
- commentType = HeaderFileComment;
- qDebug() << "currentHeaderFile =" << currentHeaderFile;
- }
-
- if ((cmd = metaCmdMap.find("typedef")) != metaCmdMap.end()) {
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentTypedef = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- }
- metaCmdMap.erase(cmd);
- commentType = TypedefComment;
- qDebug() << "currentTypedef =" << currentTypedef;
- qDebug() << "currentClass =" << currentClass;
- }
-
- cmd = priv->metaCommandMap.begin();
- while (cmd != priv->metaCommandMap.end()) {
- for (int i=0; i<cmd.value().size(); i++) {
- concatenate("\\" + cmd.key() + " " + cmd.value()[i]);
- newLine();
- }
- //qDebug() << " " << cmd.key() << ": " << cmd.value();
- ++cmd;
- }
-}
-
-/*!
- Convert the qdoc text to doxygen format. The metacommands
- are converted by convertMetaCommands(). This function is
- called in pass2().
- */
-void DoxWriter::convertText()
-{
- const Atom* prev = 0;
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- next->dump();
- Atom::Type atomType = next->type();
- switch (atomType) {
- case Atom::AbstractLeft:
- break;
- case Atom::AbstractRight:
- break;
- case Atom::AutoLink:
- concatenate(next->string());
- break;
- case Atom::BaseName:
- break;
- case Atom::BriefLeft:
- concatenate("\\brief ");
- break;
- case Atom::BriefRight:
- newLine();
- break;
- case Atom::C:
- tt(next);
- break;
- case Atom::CaptionLeft:
- unhandled(next);
- break;
- case Atom::CaptionRight:
- unhandled(next);
- break;
- case Atom::Code:
- code(next);
- break;
- case Atom::CodeBad:
- code(next);
- break;
- case Atom::CodeNew:
- newLine();
- concatenate("you can rewrite it as");
- code(next);
- break;
- case Atom::CodeOld:
- newLine();
- concatenate("For example, if you have code like");
- code(next);
- break;
- case Atom::CodeQuoteArgument:
- unhandled(next);
- break;
- case Atom::CodeQuoteCommand:
- next = codeQuoteCommand(next);
- break;
- case Atom::FootnoteLeft:
- break;
- case Atom::FootnoteRight:
- break;
- case Atom::FormatElse:
- formatElse();
- break;
- case Atom::FormatEndif:
- formatEndif();
- break;
- case Atom::FormatIf:
- formatIf(next);
- break;
- case Atom::FormattingLeft:
- formattingLeft(next,next->next());
- break;
- case Atom::FormattingRight:
- formattingRight(next,prev);
- break;
- case Atom::GeneratedList:
- break;
- case Atom::Image:
- break;
- case Atom::ImageText:
- break;
- case Atom::InlineImage:
- break;
- case Atom::LegaleseLeft:
- break;
- case Atom::LegaleseRight:
- break;
- case Atom::LineBreak:
- break;
- case Atom::Link:
- next = link(next);
- break;
- case Atom::LinkNode:
- break;
- case Atom::ListLeft:
- {
- bool nested = false;
- if (structs.isEmpty()) {
- const Atom* i = next->next();
- while (i->type() != Atom::ListRight) {
- if ((i->type() == Atom::ListLeft) ||
- (i->type() == Atom::TableLeft)) {
- nested = true;
- break;
- }
- i = i->next();
- }
- }
- else
- nested = true;
- StructDesc d(BulletList,nested);
- if (next->string() == "numeric")
- d.structType = NumericList;
- else if (next->string() == "value") {
- d.structType = ValueList;
- }
- else if (next->string() != "bullet")
- qDebug() << "UNKNOWN LIST TYPE" << next->string();
- structs.push(d);
- if (nested || (d.structType != BulletList)) {
- if (d.structType == BulletList)
- concatenate("<ul>");
- else if (d.structType == NumericList)
- concatenate("<ol>");
- else if (d.structType == ValueList)
- concatenate("<dl>");
- newLine();
- }
- }
- break;
- case Atom::ListItemNumber:
- structs.top().count = next->string().toInt();
- break;
- case Atom::ListTagLeft:
- {
- structs.top().count++;
- concatenate("<dt>");
- const Atom* n = next->next();
- if (n->type() == Atom::String) {
- qDebug() << "ENUM VALUE" << n->string();
- }
- else
- qDebug() << "NOT EN ENUM";
- }
- break;
- case Atom::ListTagRight:
- concatenate("</dt>");
- break;
- case Atom::ListItemLeft:
- {
- newLine();
- const StructDesc& d = structs.top();
- if (d.structType == BulletList) {
- if (!d.nested)
- concatenate("\\arg ");
- else
- concatenate("<li>");
- }
- else if (d.structType == NumericList)
- concatenate("<li>");
- else if (d.structType == ValueList)
- concatenate("<dd>");
- }
- break;
- case Atom::ListItemRight:
- {
- const StructDesc& d = structs.top();
- if (d.structType == BulletList) {
- if (d.nested) {
- concatenate("</li>");
- newLine();
- }
- }
- else if (d.structType == NumericList) {
- concatenate("</li>");
- newLine();
- }
- else if (d.structType == ValueList) {
- concatenate("</dd>");
- newLine();
- }
- }
- break;
- case Atom::ListRight:
- {
- if (!structs.isEmpty()) {
- const StructDesc& d = structs.top();
- if (d.nested || (d.structType != BulletList)) {
- if (d.structType == BulletList)
- concatenate("</ul>");
- else if (d.structType == NumericList)
- concatenate("</ol>");
- else if (d.structType == ValueList)
- concatenate("</dl>");
- newLine();
- }
- structs.pop();
- }
- }
- break;
- case Atom::Nop:
- // nothing.
- break;
- case Atom::ParaLeft:
- if (structs.isEmpty())
- newLine();
- break;
- case Atom::ParaRight:
- {
- if (structs.isEmpty())
- newLine();
- else {
- const StructDesc& d = structs.top();
- if (d.nested || (d.structType != BulletList)) {
- Atom::Type t = next->next()->type();
- if ((t != Atom::ListItemRight) &&
- (t != Atom::TableItemRight))
- newLine();
- }
- else
- newLine();
- }
- }
- break;
- case Atom::QuotationLeft:
- break;
- case Atom::QuotationRight:
- break;
- case Atom::RawString:
- concatenate(next->string());
- break;
- case Atom::SectionLeft:
- // nothing.
- break;
- case Atom::SectionRight:
- // nothing.
- break;
- case Atom::SectionHeadingLeft:
- next = sectionHeading(next);
- break;
- case Atom::SectionHeadingRight:
- newLine();
- break;
- case Atom::SidebarLeft:
- break;
- case Atom::SidebarRight:
- break;
- case Atom::SnippetCommand:
- newLine();
- concatenate("\\snippet ");
- break;
- case Atom::SnippetIdentifier:
- newText += next->string();
- lineLength += next->string().size();
- newLine();
- break;
- case Atom::SnippetLocation:
- newText += next->string() + " ";
- lineLength += next->string().size() + 1;
- break;
- case Atom::String:
- wrap(next->string());
- break;
- case Atom::TableLeft:
- {
- bool nested = false;
- if (structs.isEmpty()) {
- const Atom* i = next->next();
- while (i->type() != Atom::TableRight) {
- if ((i->type() == Atom::ListLeft) ||
- (i->type() == Atom::TableLeft)) {
- nested = true;
- break;
- }
- i = i->next();
- }
- }
- else
- nested = true;
- StructDesc d(Table,nested);
- structs.push(d);
- if (next->string().isEmpty())
- concatenate("<table>");
- else {
- QString attrs = "width=\"" + next->string() + "\"";
- attrs += " align=\"center\"";
- concatenate("<table " + attrs + ">");
- }
- newLine();
- }
- break;
- case Atom::TableRight:
- concatenate("</table>");
- if (!structs.isEmpty())
- structs.pop();
- newLine();
- break;
- case Atom::TableHeaderLeft:
- concatenate("<tr>");
- if (!structs.isEmpty())
- structs.top().inTableHeader = true;
- newLine();
- break;
- case Atom::TableHeaderRight:
- concatenate("</tr>");
- if (!structs.isEmpty())
- structs.top().inTableHeader = false;
- newLine();
- break;
- case Atom::TableRowLeft:
- if (!structs.isEmpty()) {
- structs.top().inTableRow = true;
- concatenate("<tr valign=\"top\" class=\"");
- if (structs.top().odd)
- concatenate("odd\">");
- else
- concatenate("even\">");
- structs.top().odd = !structs.top().odd;
- }
- newLine();
- break;
- case Atom::TableRowRight:
- concatenate("</tr>");
- if (!structs.isEmpty())
- structs.top().inTableRow = false;
- newLine();
- break;
- case Atom::TableItemLeft:
- if (!structs.isEmpty()) {
- structs.top().inTableItem = true;
- concatenate("<td>");
- if (structs.top().inTableHeader)
- concatenate("<b> ");
- }
- break;
- case Atom::TableItemRight:
- if (!structs.isEmpty()) {
- structs.top().inTableItem = false;
- if (structs.top().inTableHeader)
- concatenate(" </b>");
- concatenate("</td>");
- }
- newLine();
- break;
- case Atom::TableOfContents:
- break;
- case Atom::Target:
- {
- QString text = next->string();
- text.remove(ws_rx);
- newLine();
- concatenate("\\anchor ");
- newText += text;
- lineLength += text.size();
- newLine();
- }
- break;
- case Atom::UnhandledFormat:
- unhandled(next);
- break;
- case Atom::UnknownCommand:
- unhandled(next);
- break;
- default:
- //next->dump();
- break;
- }
- prev = next;
- next = next->next();
- }
-}
-
-/*!
-
- Pass one looks for topic commands and target and section
- commands, and maybe other stuff. These are serialized to
- text files, which are read back in by pass2().
- */
-void DoxWriter::pass1()
-{
- QCommandMap& metaCmdMap = priv->metaCommandMap;
- if (!metaCmdMap.isEmpty()) {
- int c;
- QCommandMap::iterator cmd;
- if ((cmd = metaCmdMap.find("enum")) != metaCmdMap.end()) {
- commentType = EnumComment;
- currentEnum = cmd.value()[0];
- if ((c = currentEnum.lastIndexOf("::")) > 0) {
- currentClass = currentEnum.left(c);
- currentEnum = currentEnum.right(currentEnum.size()-c-2);
- qDebug() << "currentEnum =" << currentEnum;
- qDebug() << "currentClass =" << currentClass;
- if (enums.contains(currentEnum,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate enum:"
- << currentClass << currentEnum;
- }
- else
- enums.insert(currentEnum,currentClass);
- }
- }
- else if ((cmd = metaCmdMap.find("property")) != metaCmdMap.end()) {
- commentType = PropertyComment;
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentProperty = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentProperty =" << currentProperty;
- qDebug() << "currentClass =" << currentClass;
- if (properties.contains(currentProperty,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate property:"
- << currentClass << currentProperty;
- }
- else
- properties.insert(currentProperty,currentClass);
- }
- }
- else if ((cmd = metaCmdMap.find("variable")) != metaCmdMap.end()) {
- commentType = VariableComment;
- currentClass = cmd.value()[0];
- if ((c = currentClass.lastIndexOf("::")) > 0) {
- currentVariable = currentClass.right(currentClass.size()-c-2);
- currentClass = currentClass.left(c);
- qDebug() << "currentVariable =" << currentVariable;
- qDebug() << "currentClass =" << currentClass;
- if (variables.contains(currentVariable,currentClass)) {
- qWarning() << "DoxWriter::pass1():"
- << "Duplicate variable:"
- << currentClass << currentVariable;
- }
- else
- variables.insert(currentVariable,currentClass);
- }
- }
- }
-
- /*
- */
- const Atom* next = priv->text.firstAtom();
- while (next != 0) {
- switch (next->type()) {
- case Atom::SectionHeadingLeft:
- {
- QString text;
- next = next->next();
- while (next) {
- if (next->type() == Atom::SectionHeadingRight)
- break;
- else
- text += next->string();
- next = next->next();
- }
- //text.remove(ws_rx);
- insertAnchor(text);
- }
- break;
- case Atom::Target:
- {
- QString text = next->string();
- //text.remove(ws_rx);
- insertAnchor(text);
- }
- default:
- break;
- }
- next = next->next();
- }
-}
-
-/*!
- Output a parsed, tokenized qdoc comment as a doxygen
- comment in diff format for input to the patch command.
- */
-void DoxWriter::pass2()
-{
- if (!conversionRequired()) {
- qDebug() << "NO CONVERSION - FILE:" << priv->start_loc.fileName()
- << "START:" << priv->start_loc.lineNo()
- << "END:" << priv->end_loc.lineNo() - 1;
- return;
- }
-
- /*
- Transformation to doxygen required...
- */
- newText = "\n/*! \n";
- convertMetaCommands();
- convertText();
- if (newText[newText.size()-1] == ' ')
- newText.remove(newText.size()-1,1);
- newText += " */\n";
- qDebug() << "CONVERTED COMMENT - FILE:" << priv->start_loc.fileName()
- << "START:" << priv->start_loc.lineNo()
- << "END:" << priv->end_loc.lineNo() - 1;
- qDebug() << newText;
-}
-
-/*!
- Unparse the second parameter of a "\l" command.
- */
-const Atom* DoxWriter::link(const Atom* atom)
-{
- QString first_text = atom->string();
- QString second_text;
- const QString* value = 0;
-
- const Atom* next = atom->next(Atom::FormattingLeft,Atom::LINK_);
- if (next) {
- next->dump();
- while (1) {
- next = next->next();
- next->dump();
- if (next->type() == Atom::FormattingRight) {
- if (next->string() == Atom::LINK_)
- break;
- else {
- // ignore it.
- }
- }
- else
- second_text += next->string();
- }
- int i = first_text.indexOf('#');
- if (i >= 0)
- first_text = first_text.right(first_text.size() - i - 1);
- //newLine();
- if ((value = getExternalPage(first_text))) {
- //qDebug() << "USED AN EXTERNAL PAGE TITLE" << first_text;
- QString href = "<a href=\""+*value+"\">"+first_text+"</a>";
- concatenate(href);
- }
- else if (first_text.startsWith("http:",Qt::CaseInsensitive)) {
- if (first_text == second_text) {
- concatenate(first_text);
- }
- else {
- QString href = "<a href=\""+first_text+"\">"+second_text+"</a>";
- concatenate(href);
- }
- }
- else if ((value = getPageFile(first_text))) {
- //qDebug() << "USED A PAGE TITLE" << first_text;
- QStringList parts = (*value).split('.');
- QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getGroup(first_text))) {
- //qDebug() << "USED A GROUP TITLE" << first_text;
- concatenate("\\ref " + *value + " \"" + second_text + "\"");
- }
- else if ((value = getModule(first_text))) {
- //qDebug() << "USED A MODULE TITLE" << first_text;
- concatenate("\\ref " + *value + " \"" + second_text + "\"");
- }
- else if ((value = getExamplePath(first_text))) {
- //qDebug() << "USED AN EXAMPLE TITLE" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getFile(first_text))) {
- //qDebug() << "USED A FILE TITLE" << first_text;
- // I think this command is no longer available.
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getHeaderFile(first_text))) {
- //qDebug() << "USED A HEADER FILE TITLE" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if (isAnchor(first_text)) {
- //qDebug() << "USED AN ANCHOR" << first_text;
- first_text.remove(ws_rx);
- QString ref = "\\ref " + first_text + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getPageTitle(first_text))) {
- //qDebug() << "USED AN INVERSE PAGE TITLE" << first_text;
- QStringList parts = first_text.split('.');
- QString ref = "\\ref " + parts[0] + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getExampleTitle(first_text))) {
- //qDebug() << "USED AN INVERSE EXAMPLE TITLE" << first_text;
- QString title = *value;
- title.remove(ws_rx);
- QString ref = "\\ref " + title + " \"" + second_text + "\"";
- concatenate(ref);
- }
- else if ((value = getGroupTitle(first_text))) {
- //qDebug() << "USED AN INVERSE GROUP TITLE" << first_text;
- concatenate("\\ref " + first_text + " \"" + second_text + "\"");
- }
- else if ((value = getModuleTitle(first_text))) {
- //qDebug() << "USED AN INVERSE MODULE TITLE" << first_text;
- concatenate("\\ref " + first_text + " \"" + second_text + "\"");
- }
- else if ((value = getFileTitle(first_text))) {
- qDebug() << "USED AN INVERSE FILE TITLE" << first_text;
- }
- else if ((value = getHeaderFileTitle(first_text))) {
- qDebug() << "USED AN INVERSE HEADER FILE TITLE" << first_text;
- }
- else if ((first_text.indexOf("::") >= 0) ||
- (first_text.indexOf("()") >= 0) ||
- (first_text[0] == 'Q')) {
- //qDebug() << "AUTO-LINKABLE" << first_text;
- if (first_text == second_text)
- concatenate(first_text);
- else {
- QString link = first_text + " " + second_text;
- concatenate("\\link " + link + "\\endlink");
- }
- }
- else {
- QString link;
- QStringList propertyClasses;
- QStringList variableClasses;
- QStringList enumClasses;
- bool p = isProperty(first_text,propertyClasses);
- bool v = isVariable(first_text,variableClasses);
- bool e = isEnum(first_text,enumClasses);
- if (e) {
- if (enumClasses.size() == 1)
- link = enumClasses[0];
- else if (enumClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified enum name: " + first_text;
- QString details = "Classes: " + enumClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- if (!link.isEmpty())
- qDebug() << "FOUND ENUM" << link << first_text;
- }
- else if (p && v) {
- if (propertyClasses.size() == 1) {
- if (variableClasses.size() == 1) {
- if (propertyClasses[0] == variableClasses[0])
- link = propertyClasses[0];
- }
- }
- if (link.isEmpty()) {
- if (propertyClasses.contains(currentClass) ||
- variableClasses.contains(currentClass))
- link = currentClass;
- else {
- propertyClasses += variableClasses;
- QString msg = "Unqualified property or variable name: "
- + first_text;
- QString details = "Classes: " +
- propertyClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- }
- else if (p) {
- if (propertyClasses.size() == 1)
- link = propertyClasses[0];
- else if (propertyClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified property name: " + first_text;
- QString details = "Classes: " + propertyClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- else if (v) {
- if (variableClasses.size() == 1)
- link = variableClasses[0];
- else if (variableClasses.contains(currentClass))
- link = currentClass;
- else {
- QString msg = "Unqualified variable name: " + first_text;
- QString details = "Classes: " + variableClasses.join(", ");
- priv->start_loc.error(msg,details);
- }
- }
- else {
- qDebug() << "NOT AUTO-LINKABLE" << first_text;
- QString s = first_text + " " + second_text;
- concatenate("\\link " + s + "\\endlink");
- }
- if (!link.isEmpty()) {
- link += "::" + first_text + " " + second_text;
- concatenate("\\link " + link + "\\endlink");
- }
- }
- }
- else
- qDebug() << "LINK with no second parameter!!!!";
- return next? next : atom;
-}
-
-/*!
- If the current line length is 0, the current line is
- indented according to the context.
- */
-void DoxWriter::indentLine()
-{
- if (lineLength == 0) {
- newText += DOXYGEN_INDENT_STRING;
- lineLength = DOXYGEN_INDENT;
- if (!structs.isEmpty()) {
- for (int i=1; i<structs.size(); ++i) {
- newText += DOXYGEN_TAB_STRING;
- lineLength += DOXYGEN_TAB_SIZE;
- }
- }
- }
-}
-
-/*!
- Concatenates a newline to the doxygen text, increments the
- line count, and resets the line length to 0.
- */
-void DoxWriter::newLine()
-{
- newText += "\n";
- ++lineCount;
- lineLength = 0;
-}
-
-static const int maxLineLength = 70;
-
-/*!
- Concatenate the \a text to the doxygen comment currently
- under construction and increment the current line length
- by the size of the \a text.
-
- If incrementing the current line length by the \a text size
- would make the current line length longer than the maximum
- line length, then call newLine() and indentLine() \e before
- concatenating the \a text.
- */
-void DoxWriter::concatenate(QString text)
-{
- if ((lineLength + text.size()) > maxLineLength)
- newLine();
- indentLine();
- newText += text;
- lineLength += text.size();
-}
-
-static bool punctuation(QChar c)
-{
- switch (c.toAscii()) {
- case '.':
- case ',':
- case ':':
- case ';':
- case '/':
- case '+':
- case '-':
- case '?':
- case '!':
- case '\"':
- return true;
- default:
- break;
- }
- return false;
-}
-
-/*!
- Concatenate the \a text string to the doxygen text, doing
- line wrapping where necessary.
- */
-void DoxWriter::wrap(QString text)
-{
- int from = 0;
- int to = -1;
-
- if ((lineLength == 0) || (lineLength >= maxLineLength)) {
- if (!text.isEmpty() && (text[0] == ' '))
- text = text.right(text.size() - 1);
- }
-
- indentLine();
- while (text.size()) {
- int avail = maxLineLength - lineLength;
- from = text.indexOf(' ',from);
- if (from >= 0) {
- if (from < avail)
- to = from++;
- else if (from == 1 && punctuation(text[0]))
- to = from++;
- else {
- if (to >= 0) {
- newText += text.left(to+1);
- lineLength += to + 1;
- text = text.right(text.size() - to - 1);
- }
- else {
- newLine();
- indentLine();
- newText += text.left(from+1);
- lineLength += from + 1;
- text = text.right(text.size() - from - 1);
- }
- from = 0;
- to = -1;
- if (text.size() && (lineLength > maxLineLength)) {
- newLine();
- indentLine();
- }
- }
- }
- else
- break;
- }
- if (text.size()) {
- if (lineLength >= maxLineLength) {
- newLine();
- indentLine();
- }
- newText += text;
- lineLength += text.size();
- }
-}
-
-/*!
- This will output something, but it depends on what the
- \a atom string and the \a next atom string are.
- */
-void DoxWriter::formattingLeft(const Atom* atom, const Atom* next)
-{
- if (atom->string() == "parameter") {
- concatenate("\\a ");
- return;
- }
- else if (atom->string() == "underline") {
- concatenate("<u>");
- return;
- }
- else if (atom->string() == "superscript") {
- concatenate("<sup>");
- return;
- }
- else if (atom->string() == "subscript") {
- concatenate("<sub>");
- return;
- }
- int ws = -1;
- if (next)
- ws = next->string().indexOf(ws_rx);
- if (atom->string() == "bold") {
- if (ws < 0)
- concatenate("\\b ");
- else
- concatenate("<b>");
- }
- else if (atom->string() == "italic") {
- if (ws < 0)
- concatenate("\\e ");
- else
- concatenate("<i>");
- }
- else if (atom->string() == "teletype") {
- if (ws < 0)
- concatenate("\\c ");
- else
- concatenate("<tt>");
- }
- else
- qDebug() << "UNHANDLED FormattingLeft: " << atom->string();
-}
-
-/*!
- This will output something, but it depends on what the
- \a atom string and the \a prev atom string are.
- */
-void DoxWriter::formattingRight(const Atom* atom, const Atom* prev)
-{
- if (atom->string() == "parameter")
- return;
- else if (atom->string() == "underline") {
- concatenate("</u>");
- return;
- }
- else if (atom->string() == "superscript") {
- concatenate("</sup>");
- return;
- }
- else if (atom->string() == "subscript") {
- concatenate("</sub>");
- return;
- }
- int ws = -1;
- if (prev)
- ws = prev->string().indexOf(ws_rx);
- if (ws < 0)
- return;
- if (atom->string() == "bold")
- concatenate("</b>");
- else if (atom->string() == "italic")
- concatenate("</i>");
- else if (atom->string() == "teletype")
- concatenate("</tt>");
- else
- qDebug() << "UNHANDLED FormattingRight: " << atom->string();
-}
-
-/*!
- Output a \c or a <tt>...</tt>.
- */
-void DoxWriter::tt(const Atom* atom)
-{
- if (atom->string().indexOf(ws_rx) < 0) {
- concatenate("\\c ");
- concatenate(atom->string());
- }
- else {
- concatenate("<tt>");
- concatenate(atom->string());
- concatenate("</tt>");
- }
-}
-
-/*!
- */
-void DoxWriter::formatIf(const Atom* atom)
-{
- if (atom->string() == "HTML") {
- newLine();
- concatenate("\\htmlonly");
- newLine();
- }
-}
-
-/*!
- */
-void DoxWriter::formatEndif()
-{
- newLine();
- concatenate("\\endhtmlonly");
- newLine();
-}
-
-/*!
- */
-void DoxWriter::formatElse()
-{
- // nothing.
-}
-
-/*!
- Pass 1: Construct a section identifier and insert it into
- the anchor set.
-
- Pass 2: Convert section1, section2, and section3 commands
- to section, subsection, and subsubsection respectively.
- Warn if a section command higher than 3 is seen.
- */
-const Atom* DoxWriter::sectionHeading(const Atom* atom)
-{
- QString heading_level = atom->string();
- QString heading_text;
- const Atom* next = atom->next();
- while (next) {
- next->dump();
- if (next->type() == Atom::SectionHeadingRight) {
- if (next->string() == heading_level)
- break;
- else {
- qDebug() << "WRONG SectionHeading number!!!!";
- }
- }
- else
- heading_text += next->string();
- next = next->next();
- }
-
- QString heading_identifier = heading_text;
- heading_identifier.remove(ws_rx);
-
- newLine();
- if (heading_level == "1")
- heading_level = "\\section ";
- else if (heading_level == "2")
- heading_level = "\\subsection ";
- else if (heading_level == "3")
- heading_level = "\\subsubsection ";
- else if (heading_level == "4") {
- heading_level = "\\subsubsection ";
- qDebug() << "WARNING section4 converted to \\subsubsection";
- }
- else {
- heading_level = "\\subsubsection ";
- qDebug() << "WARNING section5 converted to \\subsubsection";
- }
- concatenate(heading_level);
- newText += heading_identifier + " ";
- lineLength += heading_identifier.size() + 1;
- newText += heading_text;
- lineLength += heading_text.size();
- newLine();
- return next? next : atom;
-}
-
-/*!
- Report an unhandled atom.
- */
-void DoxWriter::unhandled(const Atom* atom)
-{
- qDebug() << "UNHANDLED ATOM";
- atom->dump();
-}
-
-/*!
- Output a code/endcode block.
- */
-void DoxWriter::code(const Atom* atom)
-{
- newLine();
- concatenate("\\code");
- writeCode(atom->string());
- concatenate("\\endcode");
- newLine();
-}
-
-/*!
- Output a code/endcode block depending on the
- CodeQuote Command and CodeQuoteArgument parameters.
- */
-const Atom* DoxWriter::codeQuoteCommand(const Atom* atom)
-{
- QString command = atom->string();
- atom = atom->next();
- concatenate("\\code");
- if (command == "codeline") {
- newLine();
- concatenate(atom->string());
- newLine();
- }
- else if (command == "dots") {
- newLine();
- concatenate(atom->string());
- newLine();
- }
- else {
- writeCode(atom->string());
- }
- concatenate("\\endcode");
- return atom;
-}
-
-/*!
- Appends a block of code to the comment.
- */
-void DoxWriter::writeCode(QString text)
-{
- int cr_count = text.count('\n') - 1;
- if (cr_count >= 0) {
- int last_cr = text.lastIndexOf('\n');
- newText += text.left(last_cr);
- lineCount += cr_count;
- }
- else
- newText += text;
- newLine();
-}
-
-/*!
- Inserts \a text into the anchor set. This function is called
- during doxygen pass 1.
- */
-void DoxWriter::insertAnchor(const QString& text)
-{
- anchors.insert(text);
-}
-
-/*!
- Returns true if \a text identifies an anchor, section,
- subsection, subsubsection, or page.
- */
-bool DoxWriter::isAnchor(const QString& text)
-{
- return anchors.contains(text);
-}
-
-/*!
- Write the set of anchors to a file, one per line.
- */
-void DoxWriter::writeAnchors()
-{
- QFile file("anchors.txt");
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning("Unable to open anchors.txt for writing.");
- return;
- }
-
- QTextStream out(&file);
- QSet<QString>::const_iterator i = anchors.constBegin();
- while (i != anchors.constEnd()) {
- out << *i << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Read the set of anchors from the anchors file, one per line,
- and insert each one into the anchor set.
- */
-void DoxWriter::readAnchors()
-{
- QFile file("anchors.txt");
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning("Unable to open anchors.txt for reading.");
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString line = in.readLine();
- anchors.insert(line);
- }
- file.close();
-#if 0
- QSet<QString>::const_iterator i = anchors.constBegin();
- while (i != anchors.constEnd()) {
- qDebug() << *i;
- ++i;
- }
-#endif
-}
-
-/*!
- Inserts \a title into one of the title maps. \a title is
- mapped to the \a node name. This function is called during
- doxygen pass 1.
- */
-void DoxWriter::insertTitle(FakeNode* node, const QString& title)
-{
- switch (node->subType()) {
- case FakeNode::Example:
- if (exampleTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate example title:"
- << title;
- }
- else {
- exampleTitles[title] = node->name();
- exampleTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::HeaderFile:
- if (headerFileTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate header file title:"
- << title;
- }
- else {
- headerFileTitles[title] = node->name();
- headerFileTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::File:
- if (fileTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate file title:"
- << title;
- }
- else {
- fileTitles[title] = node->name();
- fileTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Group:
- if (groupTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate group title:"
- << title;
- }
- else {
- groupTitles[title] = node->name();
- groupTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Module:
- if (moduleTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate module title:"
- << title;
- }
- else {
- moduleTitles[title] = node->name();
- moduleTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::Page:
- if (pageTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate page title:"
- << title;
- }
- else {
- pageTitles[title] = node->name();
- pageTitlesInverse[node->name()] = title;
- }
- break;
- case FakeNode::ExternalPage:
- if (externalPageTitles.contains(title)) {
- qWarning() << "DoxWriter::insertTitle():"
- << "Duplicate external page title:"
- << title;
- }
- else {
- externalPageTitles[title] = node->name();
- externalPageTitlesInverse[node->name()] = title;
- }
- break;
- default:
- break;
- }
-}
-
-/*!
- */
-const QString* DoxWriter::getPageFile(const QString& title)
-{
- QStringMapEntry entry = pageTitles.find(title);
- return (entry == pageTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExamplePath(const QString& title)
-{
- QStringMapEntry entry = exampleTitles.find(title);
- return (entry == exampleTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getFile(const QString& title)
-{
- QStringMapEntry entry = fileTitles.find(title);
- return (entry == fileTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getHeaderFile(const QString& title)
-{
- QStringMapEntry entry = headerFileTitles.find(title);
- return (entry == headerFileTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getGroup(const QString& title)
-{
- QStringMapEntry entry = groupTitles.find(title);
- return (entry == groupTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getModule(const QString& title)
-{
- QStringMapEntry entry = moduleTitles.find(title);
- return (entry == moduleTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExternalPage(const QString& title)
-{
- QStringMapEntry entry = externalPageTitles.find(title);
- return (entry == externalPageTitles.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getPageTitle(const QString& text)
-{
- QStringMapEntry entry = pageTitlesInverse.find(text);
- return (entry == pageTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExampleTitle(const QString& text)
-{
- QStringMapEntry entry = exampleTitlesInverse.find(text);
- return (entry == exampleTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getFileTitle(const QString& text)
-{
- QStringMapEntry entry = fileTitlesInverse.find(text);
- return (entry == fileTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getHeaderFileTitle(const QString& text)
-{
- QStringMapEntry entry = headerFileTitlesInverse.find(text);
- return (entry == headerFileTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getGroupTitle(const QString& text)
-{
- QStringMapEntry entry = groupTitlesInverse.find(text);
- return (entry == groupTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getModuleTitle(const QString& text)
-{
- QStringMapEntry entry = moduleTitlesInverse.find(text);
- return (entry == moduleTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- */
-const QString* DoxWriter::getExternalPageTitle(const QString& text)
-{
- QStringMapEntry entry = externalPageTitlesInverse.find(text);
- return (entry == externalPageTitlesInverse.end()) ? 0 : &entry.value();
-}
-
-/*!
- Serialize \a map to file \a name.
- */
-void DoxWriter::writeMap(const QStringMap& map, const QString& name)
-{
-
- QFile file(name);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for writing.";
- return;
- }
-
- QTextStream out(&file);
- QStringMap::const_iterator i = map.constBegin();
- while (i != map.constEnd()) {
- out << i.key() << "\n";
- out << i.value() << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Read file \a name into the \a map.
- */
-void DoxWriter::readMap(QStringMap& map, QStringMap& inverseMap, const QString& name)
-{
- QFile file(name);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for reading.";
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString title = in.readLine();
- QString value = in.readLine();
- map[title] = value;
- inverseMap[value] = title;
- }
- file.close();
-}
-
-/*!
- Write the sets of titles to text files, one per line.
- */
-void DoxWriter::writeTitles()
-{
- if (!pageTitles.isEmpty())
- writeMap(pageTitles,"pagetitles.txt");
- if (!fileTitles.isEmpty())
- writeMap(fileTitles,"filetitles.txt");
- if (!headerFileTitles.isEmpty())
- writeMap(headerFileTitles,"headerfiletitles.txt");
- if (!exampleTitles.isEmpty())
- writeMap(exampleTitles,"exampletitles.txt");
- if (!moduleTitles.isEmpty())
- writeMap(moduleTitles,"moduletitles.txt");
- if (!groupTitles.isEmpty())
- writeMap(groupTitles,"grouptitles.txt");
- if (!externalPageTitles.isEmpty())
- writeMap(externalPageTitles,"externalpagetitles.txt");
-}
-
-/*!
- Read the sets of titles from the titles files, one per line,
- and insert each one into the appropriate title set.
- */
-void DoxWriter::readTitles()
-{
- readMap(pageTitles,pageTitlesInverse,"pagetitles.txt");
- readMap(fileTitles,fileTitlesInverse,"filetitles.txt");
- readMap(headerFileTitles,headerFileTitlesInverse,"headerfiletitles.txt");
- readMap(exampleTitles,exampleTitlesInverse,"exampletitles.txt");
- readMap(moduleTitles,moduleTitlesInverse,"moduletitles.txt");
- readMap(groupTitles,groupTitlesInverse,"grouptitles.txt");
- readMap(externalPageTitles,
- externalPageTitlesInverse,
- "externalpagetitles.txt");
-}
-
-/*!
- Serialize \a map to file \a name.
- */
-void DoxWriter::writeMultiMap(const QStringMultiMap& map, const QString& name)
-{
-
- QFile file(name);
- if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for writing.";
- return;
- }
-
- QTextStream out(&file);
- QStringMultiMap::const_iterator i = map.constBegin();
- while (i != map.constEnd()) {
- out << i.key() << "\n";
- out << i.value() << "\n";
- ++i;
- }
- file.close();
-}
-
-/*!
- Write the4 property names and variable names to text files.
- */
-void DoxWriter::writeMembers()
-{
- if (!variables.isEmpty())
- writeMultiMap(variables,"variables.txt");
- if (!properties.isEmpty())
- writeMultiMap(properties,"properties.txt");
- if (!enums.isEmpty())
- writeMultiMap(enums,"enums.txt");
-}
-
-/*!
- Read file \a name into the \a map.
- */
-void DoxWriter::readMultiMap(QStringMultiMap& map, const QString& name)
-{
- QFile file(name);
- if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
- qWarning() << "Unable to open" << name << "for reading.";
- return;
- }
-
- QTextStream in(&file);
- while (!in.atEnd()) {
- QString member = in.readLine();
- QString className = in.readLine();
- map.insert(member,className);
- }
- file.close();
-}
-
-/*!
- Read the property names and variable names from the test files.
- */
-void DoxWriter::readMembers()
-{
- readMultiMap(variables,"variables.txt");
- readMultiMap(properties,"properties.txt");
- readMultiMap(enums,"enums.txt");
-}
-
-/*!
- Return true if \a name is a property. Loads \a classes with
- the names of all the classes in which \a name is a property.
- */
-bool DoxWriter::isProperty(const QString& name, QStringList& classes)
-{
- classes = properties.values(name);
- return !classes.isEmpty();
-}
-
-/*!
- Return true if \a name is a variable. Loads \a classes with
- the names of all the classes in which \a name is a variable.
- */
-bool DoxWriter::isVariable(const QString& name, QStringList& classes)
-{
- classes = variables.values(name);
- return !classes.isEmpty();
-}
-
-/*!
- Return true if \a name is an enum type. Loads \a classes with
- the names of all the classes in which \a name is an enum type.
- */
-bool DoxWriter::isEnum(const QString& name, QStringList& classes)
-{
- classes = enums.values(name);
- return !classes.isEmpty();
-}
-#endif
-
QT_END_NAMESPACE
diff --git a/tools/qdoc3/doc.h b/tools/qdoc3/doc.h
index dbba6e4..d58167f 100644
--- a/tools/qdoc3/doc.h
+++ b/tools/qdoc3/doc.h
@@ -133,183 +133,6 @@ class Doc
DocPrivate *priv;
};
-#ifdef QDOC2DOX
-
-class DoxWriter
-{
- public:
- DoxWriter(const QString& source, DocPrivate* docPrivate)
- : commentType(OtherComment),
- lineLength(0),
- lineCount(0),
- priv(docPrivate),
- oldText(source) {}
- ~DoxWriter() {}
-
- void pass1();
- void pass2();
-
- static void setDoxPass(int pass);
- static bool isDoxPass(int pass);
- static bool isDoxPass();
- static void insertTitle(FakeNode* node, const QString& title);
- static void writeTitles();
- static void readTitles();
- static void writeMembers();
- static void readMembers();
- static void writeAnchors();
- static void readAnchors();
-
- private:
- void indentLine();
- void newLine();
- void concatenate(QString text);
- void wrap(QString text);
- bool conversionRequired() const;
- void convertMetaCommands();
- void convertText();
- const Atom* link(const Atom* atom);
- void formattingLeft(const Atom* atom, const Atom* next);
- void formattingRight(const Atom* atom, const Atom* prev);
- void tt(const Atom* atom);
- void formatIf(const Atom* atom);
- void formatEndif();
- void formatElse();
- const Atom* sectionHeading(const Atom* atom);
- void unhandled(const Atom* atom);
- void code(const Atom* atom);
- const Atom* codeQuoteCommand(const Atom* atom);
- void writeCode(QString text);
- void writeCommand(QCommandMap::const_iterator cmd);
-
- static void insertAnchor(const QString& text);
- static bool isAnchor(const QString& text);
-
- static const QString* getPageFile(const QString& title);
- static const QString* getFile(const QString& title);
- static const QString* getExamplePath(const QString& title);
- static const QString* getHeaderFile(const QString& title);
- static const QString* getGroup(const QString& title);
- static const QString* getModule(const QString& title);
- static const QString* getExternalPage(const QString& title);
- static const QString* getPageTitle(const QString& text);
- static const QString* getFileTitle(const QString& text);
- static const QString* getExampleTitle(const QString& text);
- static const QString* getHeaderFileTitle(const QString& text);
- static const QString* getGroupTitle(const QString& text);
- static const QString* getModuleTitle(const QString& text);
- static const QString* getExternalPageTitle(const QString& text);
-
- static bool isProperty(const QString& title, QStringList& classes);
- static bool isVariable(const QString& title, QStringList& classes);
- static bool isEnum(const QString& title, QStringList& classes);
-
- private:
- static void writeMap(const QStringMap& map, const QString& name);
- static void readMap(QStringMap& map,
- QStringMap& inverseMap,
- const QString& name);
- static void writeMultiMap(const QStringMultiMap& map, const QString& name);
- static void readMultiMap(QStringMultiMap& map, const QString& name);
-
- public: // VS 6, SunCC need this to be public
- enum StructType { BulletList, NumericList, ValueList, Table };
- private:
- struct StructDesc {
- StructType structType;
- int count;
- bool nested;
- bool inTableHeader;
- bool inTableRow;
- bool inTableItem;
- bool odd;
-
- StructDesc()
- : structType(BulletList),
- count(0),
- nested(false),
- inTableHeader(false),
- inTableRow(false),
- inTableItem(false),
- odd(true) { }
-
- StructDesc(StructType t, bool n)
- : structType(t),
- count(0),
- nested(n),
- inTableHeader(false),
- inTableRow(false),
- inTableItem(false),
- odd(true) { }
- };
-
- typedef QStack<StructDesc> StructStack;
-
- enum CommentType {
- ClassComment,
- EnumComment,
- ExampleComment,
- FnComment,
- GroupComment,
- HeaderFileComment,
- MacroComment,
- ModuleComment,
- PageComment,
- PropertyComment,
- ServiceComment,
- TypedefComment,
- VariableComment,
- OtherComment
- };
-
- private:
- CommentType commentType;
- int lineLength;
- int lineCount;
- DocPrivate* priv;
- QString oldText;
- QString newText;
- StructStack structs;
-
- QString currentPage;
- QString currentFn;
- QString currentTitle;
- QString currentEnum;
- QString currentProperty;
- QString currentVariable;
- QString currentExample;
- QString currentGroup;
- QString currentModule;
- QString currentMacro;
- QString currentService;
- QString currentTypedef;
- QString currentHeaderFile;
- static QString currentClass;
-
- static int doxPass;
- static QSet<QString> anchors;
- static QStringMap exampleTitles;
- static QStringMap headerFileTitles;
- static QStringMap fileTitles;
- static QStringMap groupTitles;
- static QStringMap moduleTitles;
- static QStringMap pageTitles;
- static QStringMap externalPageTitles;
- static QStringMap exampleTitlesInverse;
- static QStringMap headerFileTitlesInverse;
- static QStringMap fileTitlesInverse;
- static QStringMap groupTitlesInverse;
- static QStringMap moduleTitlesInverse;
- static QStringMap pageTitlesInverse;
- static QStringMap externalPageTitlesInverse;
-
- static QStringMultiMap variables;
- static QStringMultiMap properties;
- static QStringMultiMap enums;
-};
-
-#endif
-
QT_END_NAMESPACE
#endif
diff --git a/tools/qdoc3/generator.cpp b/tools/qdoc3/generator.cpp
index 3652071..e97b7f2 100644
--- a/tools/qdoc3/generator.cpp
+++ b/tools/qdoc3/generator.cpp
@@ -44,7 +44,7 @@
*/
#include <qdir.h>
-
+#include <qdebug.h>
#include "codemarker.h"
#include "config.h"
#include "doc.h"
@@ -68,10 +68,12 @@ QStringList Generator::imageDirs;
QString Generator::outDir;
QString Generator::project;
-static Text stockLink(const QString &target)
+static void singularPlural(Text& text, const NodeList& nodes)
{
- return Text() << Atom(Atom::Link, target) << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
- << target << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+ if (nodes.count() == 1)
+ text << " is";
+ else
+ text << " are";
}
Generator::Generator()
@@ -241,7 +243,7 @@ void Generator::generateFakeNode(const FakeNode * /* fake */,
{
}
-void Generator::generateText(const Text& text,
+bool Generator::generateText(const Text& text,
const Node *relative,
CodeMarker *marker)
{
@@ -254,31 +256,35 @@ void Generator::generateText(const Text& text,
true,
numAtoms);
endText(relative, marker);
+ return true;
}
+ return false;
}
#ifdef QDOC_QML
-void Generator::generateQmlText(const Text& text,
+bool Generator::generateQmlText(const Text& text,
const Node *relative,
CodeMarker *marker)
{
- if (text.firstAtom() != 0) {
- startText(relative, marker);
- const Atom *atom = text.firstAtom();
- while (atom) {
- if (atom->type() != Atom::QmlText)
- atom = atom->next();
- else {
- atom = atom->next();
- while (atom && (atom->type() != Atom::EndQmlText)) {
- int n = 1 + generateAtom(atom, relative, marker);
- while (n-- > 0)
- atom = atom->next();
- }
+ const Atom* atom = text.firstAtom();
+ if (atom == 0)
+ return false;
+
+ startText(relative, marker);
+ while (atom) {
+ if (atom->type() != Atom::QmlText)
+ atom = atom->next();
+ else {
+ atom = atom->next();
+ while (atom && (atom->type() != Atom::EndQmlText)) {
+ int n = 1 + generateAtom(atom, relative, marker);
+ while (n-- > 0)
+ atom = atom->next();
}
}
- endText(relative, marker);
}
+ endText(relative, marker);
+ return true;
}
#endif
@@ -302,12 +308,20 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
if (node->doc().isEmpty()) {
- if (!quiet) // ### might be unnecessary
+ if (!quiet && !node->isReimp()) // ### might be unnecessary
node->location().warning(tr("No documentation for '%1'")
.arg(marker->plainFullName(node)));
}
else {
- generateText(node->doc().body(), node, marker);
+ if (node->type() == Node::Function) {
+ const FunctionNode *func = static_cast<const FunctionNode *>(node);
+ if (func->reimplementedFrom() != 0)
+ generateReimplementedFrom(func, marker);
+ }
+
+ if (!generateText(node->doc().body(), node, marker))
+ if (node->isReimp())
+ return;
if (node->type() == Node::Enum) {
const EnumNode *enume = (const EnumNode *) node;
@@ -345,7 +359,6 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
else if (node->type() == Node::Function) {
const FunctionNode *func = static_cast<const FunctionNode *>(node);
-
QSet<QString> definedParams;
QList<Parameter>::ConstIterator p = func->parameters().begin();
while (p != func->parameters().end()) {
@@ -390,7 +403,7 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
}
}
}
- if (needWarning)
+ if (needWarning && !func->isReimp())
node->doc().location().warning(
tr("Undocumented parameter '%1' in %2").arg(*a).arg(marker->plainFullName(node)));
}
@@ -404,9 +417,11 @@ void Generator::generateBody(const Node *node, CodeMarker *marker)
if (!body.contains("return", Qt::CaseInsensitive))
node->doc().location().warning(tr("Undocumented return value"));
}
-
+#if 0
+ // Now we put this at the top, before the other text.
if (func->reimplementedFrom() != 0)
generateReimplementedFrom(func, marker);
+#endif
}
}
@@ -762,64 +777,138 @@ void Generator::generateThreadSafeness(const Node *node, CodeMarker *marker)
{
Text text;
Text theStockLink;
- Node::ThreadSafeness parent = node->parent()->inheritedThreadSafeness();
+ Node::ThreadSafeness threadSafeness = node->threadSafeness();
+
+ Text rlink;
+ rlink << Atom(Atom::Link,"reentrant")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "reentrant"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
- switch (node->threadSafeness()) {
+ Text tlink;
+ tlink << Atom(Atom::Link,"thread-safe")
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << "thread-safe"
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+
+ switch (threadSafeness) {
case Node::UnspecifiedSafeness:
break;
case Node::NonReentrant:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD) << "Warning:"
- << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " This "
- << typeString(node) << " is not " << stockLink("reentrant") << "." << Atom::ParaRight;
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Warning:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " This "
+ << typeString(node)
+ << " is not "
+ << rlink
+ << "."
+ << Atom::ParaRight;
break;
case Node::Reentrant:
case Node::ThreadSafe:
- text << Atom::ParaLeft << Atom(Atom::FormattingLeft, ATOM_FORMATTING_BOLD);
- if (parent == Node::ThreadSafe) {
- text << "Warning:";
- } else {
- text << "Note:";
- }
- text << Atom(Atom::FormattingRight, ATOM_FORMATTING_BOLD) << " ";
-
- if (node->threadSafeness() == Node::ThreadSafe)
- theStockLink = stockLink("thread-safe");
- else
- theStockLink = stockLink("reentrant");
+ text << Atom::ParaLeft
+ << Atom(Atom::FormattingLeft,ATOM_FORMATTING_BOLD)
+ << "Note:"
+ << Atom(Atom::FormattingRight,ATOM_FORMATTING_BOLD)
+ << " ";
if (node->isInnerNode()) {
- const InnerNode *innerNode = static_cast<const InnerNode *>(node);
- text << "All the functions in this " << typeString(node) << " are "
- << theStockLink;
-
- NodeList except;
+ const InnerNode* innerNode = static_cast<const InnerNode*>(node);
+ text << "All functions in this "
+ << typeString(node)
+ << " are ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+
+ bool exceptions = false;
+ NodeList reentrant;
+ NodeList threadsafe;
+ NodeList nonreentrant;
NodeList::ConstIterator c = innerNode->childNodes().begin();
while (c != innerNode->childNodes().end()) {
- if ((*c)->threadSafeness() != Node::UnspecifiedSafeness)
- except.append(*c);
+ 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;
+ default:
+ break;
+ }
++c;
}
- if (except.isEmpty()) {
+ if (!exceptions)
text << ".";
+ else if (threadSafeness == Node::Reentrant) {
+ if (nonreentrant.isEmpty()) {
+ if (!threadsafe.isEmpty()) {
+ text << ", but ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " also " << tlink << ".";
+ }
+ else
+ text << ".";
+ }
+ else {
+ text << ", except for ";
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ if (!threadsafe.isEmpty()) {
+ text << " ";
+ appendFullNames(text,threadsafe,innerNode,marker);
+ singularPlural(text,threadsafe);
+ text << " " << tlink << ".";
+ }
+ }
}
- else {
- text << ", except ";
-
- NodeList::ConstIterator e = except.begin();
- int index = 0;
- while (e != except.end()) {
- appendFullName(text, *e, innerNode, marker);
- text << separator(index++, except.count());
- ++e;
+ else { // thread-safe
+ if (!nonreentrant.isEmpty() || !reentrant.isEmpty()) {
+ text << ", except for ";
+ if (!reentrant.isEmpty()) {
+ appendFullNames(text,reentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,reentrant);
+ text << " only " << rlink;
+ if (!nonreentrant.isEmpty())
+ text << ", and ";
+ }
+ if (!nonreentrant.isEmpty()) {
+ appendFullNames(text,nonreentrant,innerNode,marker);
+ text << ", which";
+ singularPlural(text,nonreentrant);
+ text << " nonreentrant.";
+ }
+ text << ".";
}
}
}
else {
- text << "This " << typeString(node) << " is " << theStockLink << ".";
+ text << "This " << typeString(node) << " is ";
+ if (threadSafeness == Node::ThreadSafe)
+ text << tlink;
+ else
+ text << rlink;
+ text << ".";
}
text << Atom::ParaRight;
}
- generateText(text, node, marker);
+ generateText(text,node,marker);
}
void Generator::generateSince(const Node *node, CodeMarker *marker)
@@ -859,7 +948,8 @@ void Generator::generateReimplementedFrom(const FunctionNode *func,
if (from->access() != Node::Private && from->parent()->access() != Node::Private) {
Text text;
text << Atom::ParaLeft << "Reimplemented from ";
- appendFullName(text, from->parent(), func, marker, from);
+ QString fullName = from->parent()->name() + "::" + from->name() + "()";
+ appendFullName(text, from->parent(), fullName, from);
text << "." << Atom::ParaRight;
generateText(text, func, marker);
}
@@ -939,6 +1029,33 @@ void Generator::appendFullName(Text& text,
<< Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
}
+void Generator::appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode)
+{
+ if (actualNode == 0)
+ actualNode = apparentNode;
+ text << Atom(Atom::LinkNode, CodeMarker::stringForNode(actualNode))
+ << Atom(Atom::FormattingLeft, ATOM_FORMATTING_LINK)
+ << Atom(Atom::String, fullName)
+ << Atom(Atom::FormattingRight, ATOM_FORMATTING_LINK);
+}
+
+void Generator::appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator n = nodes.begin();
+ int index = 0;
+ while (n != nodes.end()) {
+ appendFullName(text,*n,relative,marker);
+ text << comma(index++,nodes.count());
+ ++n;
+ }
+}
+
void Generator::appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
diff --git a/tools/qdoc3/generator.h b/tools/qdoc3/generator.h
index d0909a6..cdc4c29 100644
--- a/tools/qdoc3/generator.h
+++ b/tools/qdoc3/generator.h
@@ -93,11 +93,11 @@ class Generator
virtual void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
virtual void generateFakeNode(const FakeNode *fake, CodeMarker *marker);
- virtual void generateText(const Text& text,
+ virtual bool generateText(const Text& text,
const Node *relative,
CodeMarker *marker);
#ifdef QDOC_QML
- virtual void generateQmlText(const Text& text,
+ virtual bool generateQmlText(const Text& text,
const Node *relative,
CodeMarker *marker);
#endif
@@ -150,6 +150,14 @@ class Generator
const Node *relative,
CodeMarker *marker,
const Node *actualNode = 0);
+ void appendFullName(Text& text,
+ const Node *apparentNode,
+ const QString& fullName,
+ const Node *actualNode);
+ void appendFullNames(Text& text,
+ const NodeList& nodes,
+ const Node* relative,
+ CodeMarker* marker);
void appendSortedNames(Text& text,
const ClassNode *classe,
const QList<RelatedClass> &classes,
diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index 543975e..c007b9b 100644
--- a/tools/qdoc3/htmlgenerator.cpp
+++ b/tools/qdoc3/htmlgenerator.cpp
@@ -61,6 +61,127 @@ QT_BEGIN_NAMESPACE
static bool showBrokenLinks = false;
+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 parseArg(const QString &src,
+ const QString &tag,
+ int *pos,
+ int n,
+ QStringRef *contents,
+ QStringRef *par1 = 0,
+ bool debug = false)
+{
+#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
+}
+
+static void addLink(const QString &linkTarget,
+ const QStringRef &nestedStuff,
+ QString *res)
+{
+ if (!linkTarget.isEmpty()) {
+ *res += "<a href=\"";
+ *res += linkTarget;
+ *res += "\">";
+ *res += nestedStuff;
+ *res += "</a>";
+ }
+ else {
+ *res += nestedStuff;
+ }
+}
+
+
HtmlGenerator::HtmlGenerator()
: helpProjectWriter(0), inLink(false), inContents(false),
inSectionHeading(false), inTableHeader(false), numTableRows(0),
@@ -326,21 +447,24 @@ int HtmlGenerator::generateAtom(const Atom *atom,
out() << formattingRightMap()[ATOM_FORMATTING_TELETYPE];
break;
case Atom::Code:
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
#ifdef QDOC_QML
case Atom::Qml:
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
#endif
case Atom::CodeNew:
out() << "<p>you can rewrite it as</p>\n"
- << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent, atom->string()),
- marker, relative))
+ << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,atom->string()),
+ marker,relative))
<< "</pre>\n";
break;
case Atom::CodeOld:
@@ -348,7 +472,7 @@ int HtmlGenerator::generateAtom(const Atom *atom,
// fallthrough
case Atom::CodeBad:
out() << "<pre><font color=\"#404040\">"
- << trimmedTrailing(protect(plainCode(indent(codeIndent, atom->string()))))
+ << trimmedTrailing(protect(plainCode(indent(codeIndent,atom->string()))))
<< "</font></pre>\n";
break;
case Atom::FootnoteLeft:
@@ -554,13 +678,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
else if (atom->string() == ATOM_LIST_VALUE) {
threeColumnEnumValueTable = isThreeColumnEnumValueTable(atom);
if (threeColumnEnumValueTable) {
- out() << "<p><table 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() << "<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";
}
else {
- out() << "<p><table border=\"1\" cellpadding=\"2\" cellspacing=\"1\" width=\"40%\">\n"
- << "<tr><th width=\"60%\">Constant</th><th width=\"40%\">Value</th></tr>\n";
+ 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";
}
}
else {
@@ -734,14 +862,17 @@ int HtmlGenerator::generateAtom(const Atom *atom,
}
if (!atom->string().isEmpty()) {
if (atom->string().contains("%"))
- out() << "<p><table width=\"" << atom->string() << "\" "
+ out() << "<p><table class=\"generic\" width=\"" << atom->string() << "\" "
<< "align=\"center\" cellpadding=\"2\" "
<< "cellspacing=\"1\" border=\"0\">\n";
- else
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ else {
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
+ }
}
else {
- out() << "<p><table align=\"center\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table class=\"generic\" align=\"center\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
}
numTableRows = 0;
break;
@@ -924,12 +1055,16 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
out() << "<li><a href=\"" << membersLink << "\">"
<< "List of all members, including inherited members</a></li>\n";
- QString obsoleteLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Obsolete);
+ QString obsoleteLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Obsolete);
if (!obsoleteLink.isEmpty())
out() << "<li><a href=\"" << obsoleteLink << "\">"
<< "Obsolete members</a></li>\n";
- QString compatLink = generateLowStatusMemberFile(inner, marker, CodeMarker::Compat);
+ QString compatLink = generateLowStatusMemberFile(inner,
+ marker,
+ CodeMarker::Compat);
if (!compatLink.isEmpty())
out() << "<li><a href=\"" << compatLink << "\">"
<< "Qt 3 support members</a></li>\n";
@@ -941,14 +1076,34 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
sections = marker->sections(inner, CodeMarker::Summary, CodeMarker::Okay);
s = sections.begin();
while (s != sections.end()) {
- if (s->members.isEmpty()) {
+ if (s->members.isEmpty() && s->reimpMembers.isEmpty()) {
if (!s->inherited.isEmpty())
needOtherSection = true;
- } else {
- out() << "<a name=\"" << registerRef((*s).name.toLower()) << "\"></a>\n";
- out() << "<h3>" << protect((*s).name) << "</h3>\n";
+ }
+ else {
+ if (!s->members.isEmpty()) {
+ out() << "<hr />\n";
+ out() << "<a name=\""
+ << registerRef((*s).name.toLower())
+ << "\"></a>\n";
+ out() << "<h2>" << protect((*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>" << protect(name) << "</h2>\n";
+ generateSection(s->reimpMembers, inner, marker, CodeMarker::Summary);
+ }
- generateSectionList(*s, inner, marker, CodeMarker::Summary);
+ if (!s->inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(*s, inner, marker, true);
+ out() << "</ul>\n";
+ }
}
++s;
}
@@ -997,29 +1152,34 @@ void HtmlGenerator::generateClassLikeNode(const InnerNode *inner,
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)
+ if (func->metaness() == FunctionNode::Ctor ||
+ func->metaness() == FunctionNode::Dtor ||
+ func->overloadNumber() != 1)
names.clear();
- } else if ((*m)->type() == Node::Property) {
+ }
+ else if ((*m)->type() == Node::Property) {
const PropertyNode *prop = reinterpret_cast<const PropertyNode *>(*m);
- if (!prop->getters().isEmpty() && !names.contains(prop->getters().first()->name()))
+ 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);
+ }
+ 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));
+ enume->doc().enumItemNames().toSet() -
+ enume->doc().omitEnumItemNames().toSet())
+ names << plainCode(marker->markedUpEnumValue(enumName,
+ enume));
}
foreach (const QString &name, names)
- classSection.keywords += qMakePair(name, linkForNode(*m, 0));
+ classSection.keywords += qMakePair(name,linkForNode(*m,0));
}
++m;
}
@@ -1095,12 +1255,16 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
out() << "<li><a href=\"" << membersLink << "\">"
<< "List of all members, including inherited members</a></li>\n";
- QString obsoleteLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Obsolete);
+ QString obsoleteLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Obsolete);
if (!obsoleteLink.isEmpty())
out() << "<li><a href=\"" << obsoleteLink << "\">"
<< "Obsolete members</a></li>\n";
- QString compatLink = generateLowStatusMemberFile(fake, marker, CodeMarker::Compat);
+ QString compatLink = generateLowStatusMemberFile(fake,
+ marker,
+ CodeMarker::Compat);
if (!compatLink.isEmpty())
out() << "<li><a href=\"" << compatLink << "\">"
<< "Qt 3 support members</a></li>\n";
@@ -1131,7 +1295,7 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker)
s = sections.begin();
while (s != sections.end()) {
out() << "<a name=\"" << registerRef((*s).name) << "\"></a>\n";
- out() << "<h3>" << protect((*s).name) << "</h3>\n";
+ out() << "<h2>" << protect((*s).name) << "</h2>\n";
generateSectionList(*s, fake, marker, CodeMarker::Summary);
++s;
}
@@ -1407,17 +1571,19 @@ void HtmlGenerator::generateBrief(const Node *node, CodeMarker *marker,
void HtmlGenerator::generateIncludes(const InnerNode *inner, CodeMarker *marker)
{
if (!inner->includes().isEmpty()) {
- out() << "<pre>" << trimmedTrailing(highlightedCode(indent(codeIndent,
- marker->markedUpIncludes(
- inner->includes())),
- marker, inner))
+ out() << "<pre>"
+ << trimmedTrailing(highlightedCode(indent(codeIndent,
+ marker->markedUpIncludes(inner->includes())),
+ marker,inner))
<< "</pre>";
}
}
-void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker,
+void HtmlGenerator::generateTableOfContents(const Node *node,
+ CodeMarker *marker,
Doc::SectioningUnit sectioningUnit,
- int numColumns, const Node *relative)
+ int numColumns,
+ const Node *relative)
{
if (!node->doc().hasTableOfContents())
@@ -1436,7 +1602,8 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
QString tdTag;
if (numColumns > 1) {
tdTag = "<td width=\"" + QString::number((100 + numColumns - 1) / numColumns) + "%\">";
- out() << "<p><table width=\"100%\">\n<tr valign=\"top\">" << tdTag << "\n";
+ out() << "<p><table class=\"toc\" width=\"100%\">\n<tr valign=\"top\">"
+ << tdTag << "\n";
}
// disable nested links in table of contents
@@ -1455,7 +1622,8 @@ void HtmlGenerator::generateTableOfContents(const Node *node, CodeMarker *marker
out() << "<ul>";
sectionNumber.append("1");
} while (sectionNumber.size() < nextLevel);
- } else {
+ }
+ else {
while (sectionNumber.size() > nextLevel) {
out() << "</ul>\n";
sectionNumber.removeLast();
@@ -1525,7 +1693,9 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeM
QList<Section> sections;
QList<Section>::ConstIterator s;
- sections = marker->sections(inner, CodeMarker::SeparateList, CodeMarker::Okay);
+ sections = marker->sections(inner,
+ CodeMarker::SeparateList,
+ CodeMarker::Okay);
if (sections.isEmpty())
return QString();
@@ -1546,10 +1716,13 @@ QString HtmlGenerator::generateListOfAllMemberFile(const InnerNode *inner, CodeM
return fileName;
}
-QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeMarker *marker,
+QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner,
+ CodeMarker *marker,
CodeMarker::Status status)
{
- QList<Section> sections = marker->sections(inner, CodeMarker::Summary, status);
+ QList<Section> sections = marker->sections(inner,
+ CodeMarker::Summary,
+ status);
QMutableListIterator<Section> j(sections);
while (j.hasNext()) {
if (j.next().members.size() == 0)
@@ -1586,12 +1759,13 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeM
"code.</p>\n";
}
- out() << "<p><ul><li><a href=\"" << linkForNode(inner, 0) << "\">" << protect(inner->name())
+ out() << "<p><ul><li><a href=\""
+ << linkForNode(inner, 0) << "\">"
+ << protect(inner->name())
<< " class reference</a></li></ul></p>\n";
for (i = 0; i < sections.size(); ++i) {
- out() << "<h3>" << protect(sections.at(i).name) << "</h3>\n";
-
+ out() << "<h2>" << protect(sections.at(i).name) << "</h2>\n";
generateSectionList(sections.at(i), inner, marker, CodeMarker::Summary);
}
@@ -1613,8 +1787,9 @@ QString HtmlGenerator::generateLowStatusMemberFile(const InnerNode *inner, CodeM
return fileName;
}
-void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *marker,
- const QMap<QString, const Node *> &classMap)
+void HtmlGenerator::generateClassHierarchy(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString,const Node*> &classMap)
{
if (classMap.isEmpty())
return;
@@ -1656,10 +1831,13 @@ void HtmlGenerator::generateClassHierarchy(const Node *relative, CodeMarker *mar
}
}
-void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *marker,
- const QMap<QString, const Node *> &nodeMap)
+void
+HtmlGenerator::generateAnnotatedList(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString,const Node *>&nodeMap)
{
- out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" cellspacing=\"1\" border=\"0\">\n";
+ out() << "<p><table width=\"100%\" class=\"annotated\" cellpadding=\"2\" "
+ << "cellspacing=\"1\" border=\"0\">\n";
int row = 0;
foreach (const QString &name, nodeMap.keys()) {
@@ -1690,8 +1868,10 @@ void HtmlGenerator::generateAnnotatedList(const Node *relative, CodeMarker *mark
out() << "</table></p>\n";
}
-void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker,
- const QMap<QString, const Node *> &classMap)
+void
+HtmlGenerator::generateCompactList(const Node *relative,
+ CodeMarker *marker,
+ const QMap<QString,const Node*> &classMap)
{
const int NumParagraphs = 37; // '0' to '9', 'A' to 'Z', '_'
const int NumColumns = 4; // number of columns in the result
@@ -1812,14 +1992,15 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
}
firstOffset[NumColumns] = classMap.count();
- out() << "<p><table width=\"100%\">\n";
+ 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";
- } else {
+ }
+ else {
while (currentOffsetInParagraph[i] == paragraph[currentParagraphNo[i]].count()) {
++currentParagraphNo[i];
currentOffsetInParagraph[i] = 0;
@@ -1828,29 +2009,34 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
out() << "<td align=\"right\">";
if (currentOffsetInParagraph[i] == 0) {
// start a new paragraph
- out() << "<b>" << paragraphName[currentParagraphNo[i]] << "&nbsp;</b>";
- }
- out() << "</td>\n";
-
- // bad loop
- QMap<QString, const Node *>::Iterator it;
- it = paragraph[currentParagraphNo[i]].begin();
- for (j = 0; j < currentOffsetInParagraph[i]; j++)
- ++it;
-
- out() << "<td>";
- // 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() << "<b>"
+ << paragraphName[currentParagraphNo[i]]
+ << "&nbsp;</b>";
}
out() << "</td>\n";
+
+ if (!paragraphName[currentParagraphNo[i]].isEmpty()) {
+ QMap<QString, const Node *>::Iterator it;
+ it = paragraph[currentParagraphNo[i]].begin();
+ for (j = 0; j < currentOffsetInParagraph[i]; j++)
+ ++it;
+
+ out() << "<td>";
+ // 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";
+ }
currentOffset[i]++;
currentOffsetInParagraph[i]++;
@@ -1861,7 +2047,8 @@ void HtmlGenerator::generateCompactList(const Node *relative, CodeMarker *marker
out() << "</table></p>\n";
}
-void HtmlGenerator::generateFunctionIndex(const Node *relative, CodeMarker *marker)
+void HtmlGenerator::generateFunctionIndex(const Node *relative,
+ CodeMarker *marker)
{
out() << "<p align=\"center\"><font size=\"+1\"><b>";
for (int i = 0; i < 26; i++) {
@@ -1928,40 +2115,6 @@ void HtmlGenerator::generateLegaleseList(const Node *relative, CodeMarker *marke
}
}
-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);
-}
-
void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* marker */)
{
QMap<const FakeNode *, QMap<QString, FakeNode *> > fakeNodeMap;
@@ -2075,21 +2228,100 @@ void HtmlGenerator::generateOverviewList(const Node *relative, CodeMarker * /* m
}
}
-void HtmlGenerator::generateSectionList(const Section& section, const Node *relative,
- CodeMarker *marker, CodeMarker::SynopsisStyle style)
+#ifdef QDOC_NAME_ALIGNMENT
+void HtmlGenerator::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\" border=\"0\" cellpadding=\"0\" "
+ << "cellspacing=\"0\" width=\"100%\">\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() << "<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\" "
+ << "align=\"right\" valign=\"top\">";
+ }
+ else {
+ if (twoColumn && i == (int) (nl.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
+ out() << "<li><div class=\"fn\">";
+ }
+
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</div></li>\n";
+ i++;
+ ++m;
+ }
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ out() << "</ul>\n";
+ if (twoColumn)
+ out() << "</td></tr>\n</table></p>\n";
+ }
+ }
+}
+
+void HtmlGenerator::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) {
+ }
+ else if (section.members.first()->type() == Node::Property) {
twoColumn = (section.members.count() >= 5);
+ name_alignment = false;
+ }
+ if (name_alignment) {
+ out() << "<table class=\"alignedsummary\" border=\"0\" cellpadding=\"0\" "
+ << "cellspacing=\"0\" width=\"100%\">\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() << "<ul>\n";
}
- if (twoColumn)
- out() << "<p><table 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();
@@ -2099,41 +2331,56 @@ void HtmlGenerator::generateSectionList(const Section& section, const Node *rela
continue;
}
- if (twoColumn && i == (int) (section.members.count() + 1) / 2)
- out() << "</ul></td><td valign=\"top\"><ul>\n";
+ if (name_alignment) {
+ out() << "<tr><td class=\"memItemLeft\" "
+ << "align=\"right\" valign=\"top\">";
+ }
+ else {
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
+ out() << "<li><div class=\"fn\">";
+ }
- 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";
+ generateSynopsis(*m, relative, marker, style, name_alignment);
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</div></li>\n";
i++;
++m;
}
- out() << "</ul>\n";
- if (twoColumn)
- out() << "</td></tr>\n</table></p>\n";
+ if (name_alignment)
+ out() << "</table>\n";
+ else {
+ 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);
+ generateSectionInheritedList(section, relative, marker, name_alignment);
out() << "</ul>\n";
}
}
-void HtmlGenerator::generateSectionInheritedList(const Section& section, const Node *relative,
- CodeMarker *marker)
+void HtmlGenerator::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()) {
- out() << "<li><div class=\"fn\"></div>";
+ if (nameAlignment)
+ out() << "<li><div bar=\"2\" class=\"fn\"></div>";
+ else
+ out() << "<li><div class=\"fn\"></div>";
out() << (*p).second << " ";
if ((*p).second == 1) {
out() << section.singularMember;
- } else {
+ }
+ else {
out() << section.pluralMember;
}
out() << " inherited from <a href=\"" << fileName((*p).first)
@@ -2144,270 +2391,324 @@ void HtmlGenerator::generateSectionInheritedList(const Section& section, const N
}
}
-void HtmlGenerator::generateLink(const Atom *atom, const Node * /* relative */, CodeMarker *marker)
+void HtmlGenerator::generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style,
+ bool nameAlignment)
{
- 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);
- out() << protect(atom->string().left(k));
- if (link.isEmpty()) {
- if (showBrokenLinks)
- out() << "</i>";
- } else {
- out() << "</a>";
- }
- inLink = false;
- out() << protect(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)
- out() << "<tt>";
- if (func) {
- out() << protect(atom->string().left(atom->string().length() - 2));
- } else {
- out() << protect(atom->string());
- }
- out() << "</tt>";
- } else {
- out() << protect(atom->string());
+ 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);
}
-}
-
-QString HtmlGenerator::cleanRef(const QString& ref)
-{
- QString clean;
-
- if (ref.isEmpty())
- return clean;
+ marked.replace(QRegExp("<@param>([a-z]+)_([1-9n])</@param>"),
+ "<i>\\1<sub>\\2</sub></i>");
+ marked.replace("<@param>", "<i>");
+ marked.replace("</@param>", "</i>");
- clean.reserve(ref.size() + 20);
- const QChar c = ref[0];
- const uint u = c.unicode();
+ if (style == CodeMarker::Summary) {
+ marked.replace("<@name>", ""); // was "<b>"
+ marked.replace("</@name>", ""); // was "</b>"
+ }
- 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.";
+ if (style == CodeMarker::SeparateList) {
+ QRegExp extraRegExp("<@extra>.*</@extra>");
+ extraRegExp.setMinimal(true);
+ marked.replace(extraRegExp, "");
} else {
- clean += "A";
+ marked.replace("<@extra>", "&nbsp;&nbsp;<tt>");
+ marked.replace("</@extra>", "</tt>");
}
- 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);
- }
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
}
- return clean;
+ out() << highlightedCode(marked, marker, relative, style, nameAlignment);
}
-QString HtmlGenerator::registerRef(const QString& ref)
+QString HtmlGenerator::highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ CodeMarker::SynopsisStyle ,
+ bool nameAlignment)
{
- QString clean = HtmlGenerator::cleanRef(ref);
+ QString src = markedCode;
+ QString html;
+ QStringRef arg;
+ QStringRef par1;
- for (;;) {
- QString& prevRef = refMap[clean.toLower()];
- if (prevRef.isEmpty()) {
- prevRef = ref;
- break;
- } else if (prevRef == ref) {
- break;
+ 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\" valign=\"bottom\">";
+ 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++);
}
- clean += "x";
}
- return clean;
-}
-
-QString HtmlGenerator::protect(const QString& string)
-{
-#define APPEND(x) \
- if (html.isEmpty()) { \
- html = string; \
- html.truncate(i); \
- } \
- html += (x);
- QString html;
- int n = string.length();
- for (int i = 0; i < n; ++i) {
- QChar ch = string.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(),
+ tre,
+ relative),
+ relative);
+ addLink(link, arg, &html);
+ par1 = QStringRef();
+ }
+ else {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.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 (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");
- html += QString::number(ch.unicode(), 16);
- html += QLatin1Char(';');
- } else {
- if (!html.isEmpty())
- html += ch;
+ // 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(), tre, relative),
+ relative);
+ addLink(link, arg, &html);
+ handled = true;
+ break;
+ }
+ }
+ if (!handled) {
+ html += charLangle;
+ html += charAt;
+ }
+ }
+ else {
+ html += src.at(i++);
}
}
- if (!html.isEmpty())
- return html;
- return string;
+ // 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;
+ }
+ }
-#undef APPEND
+ return html;
}
-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 parseArg(const QString &src,
- const QString &tag,
- int *pos,
- int n,
- QStringRef *contents,
- QStringRef *par1 = 0,
- bool debug = false)
+#else
+void HtmlGenerator::generateSectionList(const Section& section,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style)
{
-#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;
+ 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 = *pos;
- int j = i;
+ int i = 0;
+ NodeList::ConstIterator m = section.members.begin();
+ while (m != section.members.end()) {
+ if ((*m)->access() == Node::Private) {
+ ++m;
+ continue;
+ }
- // assume "<@" has been parsed outside
- //SKIP_CHAR('<');
- //SKIP_CHAR('@');
+ if (twoColumn && i == (int) (section.members.count() + 1) / 2)
+ out() << "</ul></td><td valign=\"top\"><ul>\n";
- if (tag != QStringRef(&src, i, tag.length())) {
- if (0 && debug)
- qDebug() << "tag " << tag << " not found at " << i;
- return false;
+ 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 (debug)
- qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i;
-
- // skip tag
- i += tag.length();
+ if (style == CodeMarker::Summary && !section.inherited.isEmpty()) {
+ out() << "<ul>\n";
+ generateSectionInheritedList(section, relative, marker);
+ out() << "</ul>\n";
+ }
+}
- // 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;
+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 {
- if (debug)
- qDebug() << "no optional parameter found";
+ 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;
}
- 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;
+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>");
- *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
-}
+ if (style == CodeMarker::Summary)
+ marked.replace("@name>", "b>");
-static void addLink(const QString &linkTarget,
- const QStringRef &nestedStuff,
- QString *res)
-{
- if (!linkTarget.isEmpty()) {
- *res += "<a href=\"";
- *res += linkTarget;
- *res += "\">";
- *res += nestedStuff;
- *res += "</a>";
+ 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>");
}
- else {
- *res += nestedStuff;
+
+ if (style != CodeMarker::Detailed) {
+ marked.replace("<@type>", "");
+ marked.replace("</@type>", "");
}
+ out() << highlightedCode(marked, marker, relative);
}
QString HtmlGenerator::highlightedCode(const QString& markedCode,
@@ -2570,6 +2871,153 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode,
return html;
}
+#endif
+
+void HtmlGenerator::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);
+ out() << protect(atom->string().left(k));
+ if (link.isEmpty()) {
+ if (showBrokenLinks)
+ out() << "</i>";
+ } else {
+ out() << "</a>";
+ }
+ inLink = false;
+ out() << protect(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)
+ out() << "<tt>";
+ if (func) {
+ out() << protect(atom->string().left(atom->string().length() - 2));
+ } else {
+ out() << protect(atom->string());
+ }
+ out() << "</tt>";
+ } else {
+ out() << protect(atom->string());
+ }
+}
+
+QString HtmlGenerator::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 HtmlGenerator::registerRef(const QString& ref)
+{
+ QString clean = HtmlGenerator::cleanRef(ref);
+
+ for (;;) {
+ QString& prevRef = refMap[clean.toLower()];
+ if (prevRef.isEmpty()) {
+ prevRef = ref;
+ break;
+ } else if (prevRef == ref) {
+ break;
+ }
+ clean += "x";
+ }
+ return clean;
+}
+
+QString HtmlGenerator::protect(const QString& string)
+{
+#define APPEND(x) \
+ if (html.isEmpty()) { \
+ html = string; \
+ html.truncate(i); \
+ } \
+ html += (x);
+
+ QString html;
+ 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 (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");
+ html += QString::number(ch.unicode(), 16);
+ html += QLatin1Char(';');
+ } else {
+ if (!html.isEmpty())
+ html += ch;
+ }
+ }
+
+ if (!html.isEmpty())
+ return html;
+ return string;
+
+#undef APPEND
+}
QString HtmlGenerator::fileBase(const Node *node)
{
@@ -2778,7 +3226,7 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
section.members += property->resetters();
if (!section.members.isEmpty()) {
- out() << "<p>Access functions:</p>\n";
+ out() << "<p><b>Access functions:</b></p>\n";
generateSectionList(section, node, marker, CodeMarker::Accessors);
}
}
@@ -2789,7 +3237,8 @@ void HtmlGenerator::generateDetailedMember(const Node *node,
<< " type is a typedef for "
<< "<a href=\"qflags.html\">QFlags</a>&lt;"
<< protect(enume->name())
- << "&gt;. It stores an OR combination of " << protect(enume->name())
+ << "&gt;. It stores an OR combination of "
+ << protect(enume->name())
<< " values.</p>\n";
}
}
@@ -2803,7 +3252,8 @@ void HtmlGenerator::findAllClasses(const InnerNode *node)
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 &&
+ if ((*c)->parent() &&
+ (*c)->parent()->type() == Node::Namespace &&
!(*c)->parent()->name().isEmpty())
className = (*c)->parent()->name()+"::"+className;
@@ -2851,7 +3301,7 @@ void HtmlGenerator::findAllFunctions(const InnerNode *node)
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((*c)->parent()->name(), *c);
+ funcIndex[(*c)->name()].insert(tre->fullDocumentName((*c)->parent()), *c);
}
}
}
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index 8ff32f8..dc5e5cf 100644
--- a/tools/qdoc3/htmlgenerator.h
+++ b/tools/qdoc3/htmlgenerator.h
@@ -46,6 +46,8 @@
#ifndef HTMLGENERATOR_H
#define HTMLGENERATOR_H
+#define QDOC_NAME_ALIGNMENT
+
#include <qmap.h>
#include <qregexp.h>
@@ -139,17 +141,41 @@ class HtmlGenerator : public PageGenerator
void generateFunctionIndex(const Node *relative, CodeMarker *marker);
void generateLegaleseList(const Node *relative, CodeMarker *marker);
void generateOverviewList(const Node *relative, CodeMarker *marker);
- void generateSynopsis(const Node *node,
- const Node *relative,
- CodeMarker *marker,
- CodeMarker::SynopsisStyle style);
void generateSectionList(const Section& section,
const Node *relative,
CodeMarker *marker,
CodeMarker::SynopsisStyle style);
+#ifdef QDOC_NAME_ALIGNMENT
+ 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);
+#else
+ void generateSynopsis(const Node *node,
+ const Node *relative,
+ CodeMarker *marker,
+ CodeMarker::SynopsisStyle style);
void generateSectionInheritedList(const Section& section,
const Node *relative,
CodeMarker *marker);
+ QString highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative);
+#endif
void generateFullName(const Node *apparentNode,
const Node *relative,
CodeMarker *marker,
@@ -159,7 +185,6 @@ class HtmlGenerator : public PageGenerator
void generateStatus(const Node *node, CodeMarker *marker);
QString registerRef(const QString& ref);
- QString highlightedCode(const QString& markedCode, CodeMarker *marker, const Node *relative);
QString fileBase(const Node *node);
#if 0
QString fileBase(const Node *node, const SectionIterator& section);
diff --git a/tools/qdoc3/javadocgenerator.cpp b/tools/qdoc3/javadocgenerator.cpp
index b32425c..294877b 100644
--- a/tools/qdoc3/javadocgenerator.cpp
+++ b/tools/qdoc3/javadocgenerator.cpp
@@ -272,9 +272,10 @@ void JavadocGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker
HtmlGenerator::generateFakeNode(fake, marker);
}
-void JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
+bool JavadocGenerator::generateText(const Text& text, const Node *relative, CodeMarker *marker)
{
HtmlGenerator::generateText(text, relative, marker);
+ return true;
}
void JavadocGenerator::generateBody(const Node *node, CodeMarker *marker)
diff --git a/tools/qdoc3/javadocgenerator.h b/tools/qdoc3/javadocgenerator.h
index ba9b15d..5431c38 100644
--- a/tools/qdoc3/javadocgenerator.h
+++ b/tools/qdoc3/javadocgenerator.h
@@ -68,7 +68,7 @@ protected:
void generateClassLikeNode(const InnerNode *inner, CodeMarker *marker);
void generateFakeNode( const FakeNode *fake, CodeMarker *marker );
- void generateText( const Text& text, const Node *relative, CodeMarker *marker );
+ bool generateText( const Text& text, const Node *relative, CodeMarker *marker );
void generateBody( const Node *node, CodeMarker *marker );
void generateAlsoList( const Node *node, CodeMarker *marker );
diff --git a/tools/qdoc3/main.cpp b/tools/qdoc3/main.cpp
index e3b2f08..6425765 100644
--- a/tools/qdoc3/main.cpp
+++ b/tools/qdoc3/main.cpp
@@ -95,11 +95,10 @@ static const struct {
};
static bool slow = false;
+static bool showInternal = false;
static QStringList defines;
static QHash<QString, Tree *> trees;
-//static int doxygen = 0;
-
/*!
Find the Tree for language \a lang and return a pointer to it.
If there is no Tree for language \a lang in the Tree table, add
@@ -122,14 +121,16 @@ static void printHelp()
{
Location::information(tr("Usage: qdoc [options] file1.qdocconf ...\n"
"Options:\n"
- " -help "
+ " -help "
"Display this information and exit\n"
- " -version "
+ " -version "
"Display version of qdoc and exit\n"
- " -D<name> "
+ " -D<name> "
"Define <name> as a macro while parsing sources\n"
- " -slow "
- "Turn on features that slow down qdoc") );
+ " -slow "
+ "Turn on features that slow down qdoc\n"
+ " -showinternal "
+ "Include stuff marked internal") );
}
/*!
@@ -162,6 +163,8 @@ static void processQdocconfFile(const QString &fileName)
++i;
}
config.setStringList(CONFIG_SLOW, QStringList(slow ? "true" : "false"));
+ config.setStringList(CONFIG_SHOWINTERNAL,
+ QStringList(showInternal ? "true" : "false"));
/*
With the default configuration values in place, load
@@ -224,18 +227,6 @@ static void processQdocconfFile(const QString &fileName)
QString lang = config.getString(CONFIG_LANGUAGE);
Location langLocation = config.lastLocation();
-#ifdef QDOC2DOX
- // qdoc -> doxygen
- if (doxygen == 2) {
- qDebug() << "READING anchors.txt";
- DoxWriter::readAnchors();
- qDebug() << "READING title maps";
- DoxWriter::readTitles();
- qDebug() << "READING member multimaps";
- DoxWriter::readMembers();
- }
-#endif
-
/*
Initialize the tree where all the parsed sources will be stored.
The tree gets built as the source files are parsed, and then the
@@ -322,17 +313,6 @@ static void processQdocconfFile(const QString &fileName)
tree->resolveGroups();
tree->resolveTargets();
-#ifdef QDOC2DOX
- // qdoc -> doxygen
- if (doxygen == 1) {
- DoxWriter::writeAnchors();
- DoxWriter::writeTitles();
- DoxWriter::writeMembers();
- }
-
- if (doxygen == 0) {
-#endif
-
/*
Now the tree has been built, and all the stuff that needed
resolving has been resolved. Now it is time to traverse
@@ -351,17 +331,13 @@ static void processQdocconfFile(const QString &fileName)
/*
Generate the XML tag file, if it was requested.
*/
+
QString tagFile = config.getString(CONFIG_TAGFILE);
if (!tagFile.isEmpty())
tree->generateTagFile(tagFile);
-
+
tree->setVersion("");
Generator::terminate();
-
-#ifdef QDOC2DOX
- }
-#endif
-
CodeParser::terminate();
CodeMarker::terminate();
CppToQsConverter::terminate();
@@ -372,7 +348,6 @@ static void processQdocconfFile(const QString &fileName)
foreach (QTranslator *translator, translators)
delete translator;
-
delete tree;
}
@@ -456,26 +431,9 @@ int main(int argc, char **argv)
else if (opt == "-slow") {
slow = true;
}
-
-#ifdef QDOC2DOX
- else if (opt == "-doxygen1") {
- // qdoc -> doxygen
- // Don't use this; it isn't ready yet.
- // Now it's a fossil.
- qDebug() << "doxygen pass 1";
- doxygen = 1;
- DoxWriter::setDoxPass(1);
- }
- else if (opt == "-doxygen2") {
- // qdoc -> doxygen
- // Don't use this; it isn't ready yet.
- // Now it's a fossil.
- qDebug() << "doxygen pass 2";
- doxygen = 2;
- DoxWriter::setDoxPass(2);
+ else if (opt == "-showinternal") {
+ showInternal = true;
}
-#endif
-
else {
qdocFiles.append(opt);
}
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 0f9468a..b2e53ab 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -868,6 +868,18 @@ void FunctionNode::setOverload(bool overlode)
}
/*!
+ Sets the function node's reimplementation flag to \a r.
+ When \a r is true, it is supposed to mean that this function
+ is a reimplementation of a virtual function in a base class,
+ but it really just means the \e reimp command was seen in the
+ qdoc comment.
+ */
+void FunctionNode::setReimp(bool r)
+{
+ reimp = r;
+}
+
+/*!
*/
void FunctionNode::addParameter(const Parameter& parameter)
{
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 0a671b37d..a35bc17 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -123,6 +123,7 @@ class Node
void setTemplateStuff(const QString &templateStuff) { tpl = templateStuff; }
virtual bool isInnerNode() const = 0;
+ virtual bool isReimp() const { return false; }
Type type() const { return typ; }
InnerNode *parent() const { return par; }
InnerNode *relates() const { return rel; }
@@ -444,6 +445,7 @@ class FunctionNode : public LeafNode
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);
@@ -458,6 +460,7 @@ class FunctionNode : public LeafNode
bool isConst() const { return con; }
bool isStatic() const { return sta; }
bool isOverload() const { return ove; }
+ bool isReimp() const { return reimp; }
int overloadNumber() const;
int numOverloads() const;
const QList<Parameter>& parameters() const { return params; }
@@ -483,6 +486,7 @@ class FunctionNode : public LeafNode
bool con : 1;
bool sta : 1;
bool ove : 1;
+ bool reimp: 1;
QList<Parameter> params;
const FunctionNode *rf;
const PropertyNode *ap;
diff --git a/tools/qdoc3/qdoc3.pro b/tools/qdoc3/qdoc3.pro
index 2bba8fb..6c1cfd2 100644
--- a/tools/qdoc3/qdoc3.pro
+++ b/tools/qdoc3/qdoc3.pro
@@ -1,9 +1,12 @@
DEFINES += QDOC2_COMPAT
-#DEFINES += QT_NO_CAST_TO_ASCII
+DEFINES += QT_NO_CAST_TO_ASCII
#DEFINES += QT_NO_CAST_FROM_ASCII
+#DEFINES += QT_USE_FAST_OPERATOR_PLUS
+#DEFINES += QT_USE_FAST_CONCATENATION
QT = core xml
CONFIG += console
+CONFIG -= debug_and_release_target
build_all:!build_pass {
CONFIG -= build_all
CONFIG += release
diff --git a/tools/qdoc3/separator.cpp b/tools/qdoc3/separator.cpp
index 8f27f90..60674be 100644
--- a/tools/qdoc3/separator.cpp
+++ b/tools/qdoc3/separator.cpp
@@ -48,22 +48,30 @@
QT_BEGIN_NAMESPACE
-QString separator( int index, int count )
+QString separator(int index, int count)
{
- if ( index == count - 1 )
- return tr( ".", "terminator" );
+ if (index == count - 1)
+ return tr(".", "terminator");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
+}
- if ( count == 2 ) {
- return tr( " and ", "separator when N = 2" );
- } else {
- if ( index == 0 ) {
- return tr( ", ", "first separator when N > 2" );
- } else if ( index < count - 2 ) {
- return tr( ", ", "general separator when N > 2" );
- } else {
- return tr( ", and ", "last separator when N > 2" );
- }
- }
+QString comma(int index, int count)
+{
+ if (index == count - 1)
+ return QString("");
+ if (count == 2)
+ return tr(" and ", "separator when N = 2");
+ if (index == 0)
+ return tr(", ", "first separator when N > 2");
+ if (index < count - 2)
+ return tr(", ", "general separator when N > 2");
+ return tr(", and ", "last separator when N > 2");
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/separator.h b/tools/qdoc3/separator.h
index 70ba624..2336d94 100644
--- a/tools/qdoc3/separator.h
+++ b/tools/qdoc3/separator.h
@@ -51,6 +51,7 @@
QT_BEGIN_NAMESPACE
QString separator( int index, int count );
+QString comma( int index, int count );
QT_END_NAMESPACE
diff --git a/tools/qdoc3/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf
index 71de998..b82507f 100644
--- a/tools/qdoc3/test/assistant.qdocconf
+++ b/tools/qdoc3/test/assistant.qdocconf
@@ -13,11 +13,11 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Assistant
qhp.Assistant.file = assistant.qhp
-qhp.Assistant.namespace = com.trolltech.assistant.453
+qhp.Assistant.namespace = com.trolltech.assistant.452
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.5.3 tools assistant
+qhp.Assistant.filterAttributes = qt 4.6.0 tools assistant
qhp.Assistant.customFilters.Assistant.name = Qt Assistant Manual
qhp.Assistant.customFilters.Assistant.filterAttributes = qt tools assistant
qhp.Assistant.subprojects = manual examples
diff --git a/tools/qdoc3/test/classic.css b/tools/qdoc3/test/classic.css
index f22a77a..7f22861 100644
--- a/tools/qdoc3/test/classic.css
+++ b/tools/qdoc3/test/classic.css
@@ -1,12 +1,82 @@
+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
{
- margin-left: 1cm;
- text-indent: -1cm;
+ 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-collapse: collapse;
+ background-color: #f0f0f0;
+ border-color:#555;
+}
+
+
+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: 4px;
+ border-style: solid;
+ border-color: #444;
+ color:white;
+ background-color:#555555;
+}
+
+p {
+
+ margin-left: 4px;
+ margin-top: 8px;
+ margin-bottom: 8px;
}
a:link
{
- color: #004faf;
+ color: #0046ad;
text-decoration: none
}
@@ -40,20 +110,38 @@ a.compat:visited
text-decoration: none
}
-td.postheader
+body
{
- font-family: sans-serif
+ background: #ffffff;
+ color: black
}
-tr.address
+table.generic, table.annotated
{
- font-family: sans-serif
+ border-width: 1px;
+ border-color:#bbb;
+ border-style:solid;
+ border-collapse:collapse;
}
-body
-{
- background: #ffffff;
- color: black
+table td.memItemLeft {
+ width: 160px;
+ 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 {
diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf
index 0c39bb8..9c0790e 100644
--- a/tools/qdoc3/test/designer.qdocconf
+++ b/tools/qdoc3/test/designer.qdocconf
@@ -13,11 +13,11 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Designer
qhp.Designer.file = designer.qhp
-qhp.Designer.namespace = com.trolltech.designer.453
+qhp.Designer.namespace = com.trolltech.designer.452
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.5.3 tools designer
+qhp.Designer.filterAttributes = qt 4.6.0 tools designer
qhp.Designer.customFilters.Designer.name = Qt Designer Manual
qhp.Designer.customFilters.Designer.filterAttributes = qt tools designer
qhp.Designer.subprojects = manual examples
diff --git a/tools/qdoc3/test/linguist.qdocconf b/tools/qdoc3/test/linguist.qdocconf
index b6bd375..da49abe 100644
--- a/tools/qdoc3/test/linguist.qdocconf
+++ b/tools/qdoc3/test/linguist.qdocconf
@@ -13,11 +13,11 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = Linguist
qhp.Linguist.file = linguist.qhp
-qhp.Linguist.namespace = com.trolltech.linguist.453
+qhp.Linguist.namespace = com.trolltech.linguist.452
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.5.3 tools linguist
+qhp.Linguist.filterAttributes = qt 4.6.0 tools linguist
qhp.Linguist.customFilters.Linguist.name = Qt Linguist Manual
qhp.Linguist.customFilters.Linguist.filterAttributes = qt tools linguist
qhp.Linguist.subprojects = manual examples
diff --git a/tools/qdoc3/test/qmake.qdocconf b/tools/qdoc3/test/qmake.qdocconf
index 83220ae..5e2cac7 100644
--- a/tools/qdoc3/test/qmake.qdocconf
+++ b/tools/qdoc3/test/qmake.qdocconf
@@ -13,11 +13,11 @@ indexes = $QT_BUILD_TREE/doc-build/html-qt/qt.index
qhp.projects = qmake
qhp.qmake.file = qmake.qhp
-qhp.qmake.namespace = com.trolltech.qmake.453
+qhp.qmake.namespace = com.trolltech.qmake.452
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.5.3 tools qmake
+qhp.qmake.filterAttributes = qt 4.6.0 tools qmake
qhp.qmake.customFilters.qmake.name = qmake Manual
qhp.qmake.customFilters.qmake.filterAttributes = qt tools qmake
qhp.qmake.subprojects = manual
diff --git a/tools/qdoc3/test/qt-build-docs.qdocconf b/tools/qdoc3/test/qt-build-docs.qdocconf
index 5169714..77b03d2 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -20,7 +20,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.453
+qhp.Qt.namespace = com.trolltech.qt.452
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
@@ -34,9 +34,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.3 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.3
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.3
+qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.6.0
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0
qhp.Qt.subprojects = classes overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
diff --git a/tools/qdoc3/test/qt-cpp-ignore.qdocconf b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
index 107c692..709e336 100644
--- a/tools/qdoc3/test/qt-cpp-ignore.qdocconf
+++ b/tools/qdoc3/test/qt-cpp-ignore.qdocconf
@@ -12,6 +12,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QM_EXPORT_ICONVIEW \
QM_EXPORT_NETWORK \
QM_EXPORT_OPENGL \
+ QM_EXPORT_OPENVG \
QM_EXPORT_SQL \
QM_EXPORT_TABLE \
QM_EXPORT_WORKSPACE \
@@ -50,6 +51,7 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_INTERNAL_WIN_NO_THROW \
Q_NETWORK_EXPORT \
Q_OPENGL_EXPORT \
+ Q_OPENVG_EXPORT \
Q_OUTOFLINE_TEMPLATE \
Q_SQL_EXPORT \
Q_SVG_EXPORT \
@@ -65,7 +67,9 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
QT_BEGIN_INCLUDE_NAMESPACE \
QT_END_NAMESPACE \
QT_END_INCLUDE_NAMESPACE \
- PHONON_EXPORT
+ PHONON_EXPORT \
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt-inc.qdocconf b/tools/qdoc3/test/qt-inc.qdocconf
index d6cb0e6..542c7ca 100644
--- a/tools/qdoc3/test/qt-inc.qdocconf
+++ b/tools/qdoc3/test/qt-inc.qdocconf
@@ -99,7 +99,9 @@ Cpp.ignoretokens = QAXFACTORY_EXPORT \
Q_TESTLIB_EXPORT \
Q_TYPENAME \
Q_XML_EXPORT \
- QDBUS_EXPORT
+ QDBUS_EXPORT \
+ Q_GADGET \
+ QWEBKIT_EXPORT
Cpp.ignoredirectives = Q_DECLARE_HANDLE \
Q_DECLARE_INTERFACE \
Q_DECLARE_METATYPE \
diff --git a/tools/qdoc3/test/qt.qdocconf b/tools/qdoc3/test/qt.qdocconf
index f1fd8a2..d154254 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -22,7 +22,7 @@ edition.DesktopLight.groups = -graphicsview-api
qhp.projects = Qt
qhp.Qt.file = qt.qhp
-qhp.Qt.namespace = com.trolltech.qt.453
+qhp.Qt.namespace = com.trolltech.qt.452
qhp.Qt.virtualFolder = qdoc
qhp.Qt.indexTitle = Qt Reference Documentation
qhp.Qt.indexRoot =
@@ -36,9 +36,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.3 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.3
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.3
+qhp.Qt.filterAttributes = qt 4.6.0 qtrefdoc
+qhp.Qt.customFilters.Qt.name = Qt 4.6.0
+qhp.Qt.customFilters.Qt.filterAttributes = qt 4.6.0
qhp.Qt.subprojects = classes overviews examples
qhp.Qt.subprojects.classes.title = Classes
qhp.Qt.subprojects.classes.indexTitle = Qt's Classes
diff --git a/tools/qdoc3/tree.cpp b/tools/qdoc3/tree.cpp
index c992688..308ba0e 100644
--- a/tools/qdoc3/tree.cpp
+++ b/tools/qdoc3/tree.cpp
@@ -1884,23 +1884,25 @@ QString Tree::fullDocumentLocation(const Node *node) const
if (!node->url().isEmpty())
return node->url();
+ QString parentName;
+ QString anchorRef;
+
if (node->type() == Node::Namespace) {
// The root namespace has no name - check for this before creating
// an attribute containing the location of any documentation.
if (!node->fileBase().isEmpty())
- return node->fileBase() + ".html";
+ parentName = node->fileBase() + ".html";
else
return "";
}
else if (node->type() == Node::Fake) {
- return node->fileBase() + ".html";
+ parentName = node->fileBase() + ".html";
}
else if (node->fileBase().isEmpty())
return "";
- QString parentName;
Node *parentNode = 0;
if ((parentNode = node->relates()))
@@ -1912,10 +1914,11 @@ QString Tree::fullDocumentLocation(const Node *node) const
case Node::Class:
case Node::Namespace:
if (parentNode && !parentNode->name().isEmpty())
- return parentName.replace(".html", "") + "-"
- + node->fileBase().toLower() + ".html";
+ parentName = parentName.replace(".html", "") + "-"
+ + node->fileBase().toLower() + ".html";
else
- return node->fileBase() + ".html";
+ parentName = node->fileBase() + ".html";
+ break;
case Node::Function:
{
/*
@@ -1925,29 +1928,17 @@ QString Tree::fullDocumentLocation(const Node *node) const
const FunctionNode *functionNode =
static_cast<const FunctionNode *>(node);
- // Functions can be compatibility functions or be obsolete.
- switch (node->status()) {
- case Node::Compat:
- parentName.replace(".html", "-qt3.html");
- break;
- case Node::Obsolete:
- parentName.replace(".html", "-obsolete.html");
- break;
- default:
- ;
- }
-
if (functionNode->metaness() == FunctionNode::Dtor)
- return parentName + "#dtor." + functionNode->name().mid(1);
+ anchorRef = "#dtor." + functionNode->name().mid(1);
- if (functionNode->associatedProperty())
+ else if (functionNode->associatedProperty())
return fullDocumentLocation(functionNode->associatedProperty());
- if (functionNode->overloadNumber() > 1)
- return parentName + "#" + functionNode->name()
- + "-" + QString::number(functionNode->overloadNumber());
+ else if (functionNode->overloadNumber() > 1)
+ anchorRef = "#" + functionNode->name()
+ + "-" + QString::number(functionNode->overloadNumber());
else
- return parentName + "#" + functionNode->name();
+ anchorRef = "#" + functionNode->name();
}
/*
@@ -1955,27 +1946,52 @@ QString Tree::fullDocumentLocation(const Node *node) const
the latter returns the name in lower-case. For
HTML anchors, we need to preserve the case.
*/
+ break;
case Node::Enum:
- return parentName + "#" + node->name() + "-enum";
+ anchorRef = "#" + node->name() + "-enum";
+ break;
case Node::Typedef:
- return parentName + "#" + node->name() + "-typedef";
+ anchorRef = "#" + node->name() + "-typedef";
+ break;
case Node::Property:
- return parentName + "#" + node->name() + "-prop";
+ anchorRef = "#" + node->name() + "-prop";
+ break;
case Node::Variable:
- return parentName + "#" + node->name() + "-var";
+ anchorRef = "#" + node->name() + "-var";
+ break;
case Node::Target:
- return parentName + "#" + Doc::canonicalTitle(node->name());
+ anchorRef = "#" + Doc::canonicalTitle(node->name());
+ break;
case Node::Fake:
{
- QString pageName = node->name();
- return pageName.replace("/", "-").replace(".", "-") + ".html";
+ /*
+ Use node->fileBase() for fake nodes because they are represented
+ by pages whose file names are lower-case.
+ */
+ parentName = node->fileBase();
+ parentName.replace("/", "-").replace(".", "-");
+ parentName += ".html";
}
break;
default:
break;
}
- return "";
+ // Various objects can be compat (deprecated) or obsolete.
+ if (node->type() != Node::Class && node->type() != Node::Namespace) {
+ switch (node->status()) {
+ case Node::Compat:
+ parentName.replace(".html", "-qt3.html");
+ break;
+ case Node::Obsolete:
+ parentName.replace(".html", "-obsolete.html");
+ break;
+ default:
+ ;
+ }
+ }
+
+ return parentName.toLower() + anchorRef;
}
/*!
diff --git a/tools/qtconfig/mainwindow.cpp b/tools/qtconfig/mainwindow.cpp
index eabaec6..a59f790 100644
--- a/tools/qtconfig/mainwindow.cpp
+++ b/tools/qtconfig/mainwindow.cpp
@@ -829,7 +829,7 @@ void MainWindow::removeSubstitute()
int item = sublistbox->currentItem();
QStringList subs = QFont::substitutes(familysubcombo->currentText());
- subs.remove(subs.at(sublistbox->currentItem()));
+ subs.removeAt(sublistbox->currentItem());
sublistbox->clear();
sublistbox->insertStringList(subs);
if (uint(item) > sublistbox->count())
@@ -909,7 +909,7 @@ void MainWindow::removeFontpath()
return;
int item = fontpathlistbox->currentItem();
- fontpaths.remove(fontpaths.at(fontpathlistbox->currentItem()));
+ fontpaths.removeAt(fontpathlistbox->currentItem());
fontpathlistbox->clear();
fontpathlistbox->insertStringList(fontpaths);
if (uint(item) > fontpathlistbox->count())
diff --git a/tools/qtconfig/paletteeditoradvanced.cpp b/tools/qtconfig/paletteeditoradvanced.cpp
index 45f6a45..36cbd89 100644
--- a/tools/qtconfig/paletteeditoradvanced.cpp
+++ b/tools/qtconfig/paletteeditoradvanced.cpp
@@ -55,7 +55,7 @@ PaletteEditorAdvanced::PaletteEditorAdvanced( QWidget * parent,
const char * name, bool modal, Qt::WindowFlags f )
: PaletteEditorAdvancedBase( parent, name, modal, f ), selectedPalette(0)
{
- // work around buggy ui file
+ // work around buggy UI file
comboEffect->setEnabled(false);
buttonEffect->setEnabled(false);
onToggleBuildEffects(true);
diff --git a/tools/qtestlib/chart/3rdparty/excanvas.js b/tools/qtestlib/chart/3rdparty/excanvas.js
new file mode 100644
index 0000000..e77763a
--- /dev/null
+++ b/tools/qtestlib/chart/3rdparty/excanvas.js
@@ -0,0 +1,14 @@
+// Copyright 2006 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+if(!window.CanvasRenderingContext2D){(function(){var N=Math;var O=N.round;var L=N.sin;var U=N.cos;var A=10;var I=A/2;var G={init:function(W){var X=W||document;if(/MSIE/.test(navigator.userAgent)&&!window.opera){var V=this;X.attachEvent("onreadystatechange",function(){V.init_(X)})}},init_:function(Y){if(Y.readyState=="complete"){if(!Y.namespaces.g_vml_){Y.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml")}var X=Y.createStyleSheet();X.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}";var W=Y.getElementsByTagName("canvas");for(var V=0;V<W.length;V++){if(!W[V].getContext){this.initElement(W[V])}}}},fixElement_:function(X){var Z=X.outerHTML;var Y=X.ownerDocument.createElement(Z);if(Z.slice(-2)!="/>"){var V="/"+X.tagName;var W;while((W=X.nextSibling)&&W.tagName!=V){W.removeNode()}if(W){W.removeNode()}}X.parentNode.replaceChild(Y,X);return Y},initElement:function(W){W=this.fixElement_(W);W.getContext=function(){if(this.context_){return this.context_}return this.context_=new J(this)};W.attachEvent("onpropertychange",T);W.attachEvent("onresize",B);var V=W.attributes;if(V.width&&V.width.specified){W.style.width=V.width.nodeValue+"px"}else{W.width=W.clientWidth}if(V.height&&V.height.specified){W.style.height=V.height.nodeValue+"px"}else{W.height=W.clientHeight}return W}};function T(W){var V=W.srcElement;switch(W.propertyName){case"width":V.style.width=V.attributes.width.nodeValue+"px";V.getContext().clearRect();break;case"height":V.style.height=V.attributes.height.nodeValue+"px";V.getContext().clearRect();break}}function B(W){var V=W.srcElement;if(V.firstChild){V.firstChild.style.width=V.clientWidth+"px";V.firstChild.style.height=V.clientHeight+"px"}}G.init();var D=[];for(var R=0;R<16;R++){for(var Q=0;Q<16;Q++){D[R*16+Q]=R.toString(16)+Q.toString(16)}}function K(){return[[1,0,0],[0,1,0],[0,0,1]]}function E(Y,X){var W=K();for(var V=0;V<3;V++){for(var b=0;b<3;b++){var Z=0;for(var a=0;a<3;a++){Z+=Y[V][a]*X[a][b]}W[V][b]=Z}}return W}function P(W,V){V.fillStyle=W.fillStyle;V.lineCap=W.lineCap;V.lineJoin=W.lineJoin;V.lineWidth=W.lineWidth;V.miterLimit=W.miterLimit;V.shadowBlur=W.shadowBlur;V.shadowColor=W.shadowColor;V.shadowOffsetX=W.shadowOffsetX;V.shadowOffsetY=W.shadowOffsetY;V.strokeStyle=W.strokeStyle;V.arcScaleX_=W.arcScaleX_;V.arcScaleY_=W.arcScaleY_}function C(W){var Z,Y=1;W=String(W);if(W.substring(0,3)=="rgb"){var b=W.indexOf("(",3);var V=W.indexOf(")",b+1);var a=W.substring(b+1,V).split(",");Z="#";for(var X=0;X<3;X++){Z+=D[Number(a[X])]}if((a.length==4)&&(W.substr(3,1)=="a")){Y=a[3]}}else{Z=W}return[Z,Y]}function M(V){switch(V){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function J(W){this.m_=K();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=A*1;this.globalAlpha=1;this.canvas=W;var V=W.ownerDocument.createElement("div");V.style.width=W.clientWidth+"px";V.style.height=W.clientHeight+"px";V.style.overflow="hidden";V.style.position="absolute";W.appendChild(V);this.element_=V;this.arcScaleX_=1;this.arcScaleY_=1}var H=J.prototype;H.clearRect=function(){this.element_.innerHTML="";this.currentPath_=[]};H.beginPath=function(){this.currentPath_=[]};H.moveTo=function(W,V){this.currentPath_.push({type:"moveTo",x:W,y:V});this.currentX_=W;this.currentY_=V};H.lineTo=function(W,V){this.currentPath_.push({type:"lineTo",x:W,y:V});this.currentX_=W;this.currentY_=V};H.bezierCurveTo=function(X,V,a,Z,Y,W){this.currentPath_.push({type:"bezierCurveTo",cp1x:X,cp1y:V,cp2x:a,cp2y:Z,x:Y,y:W});this.currentX_=Y;this.currentY_=W};H.quadraticCurveTo=function(c,b,a,Z){var W=this.currentX_+2/3*(c-this.currentX_);var V=this.currentY_+2/3*(b-this.currentY_);var Y=W+(a-this.currentX_)/3;var X=V+(Z-this.currentY_)/3;this.bezierCurveTo(W,V,Y,X,a,Z)};H.arc=function(b,Z,a,Y,W,X){a*=A;var f=X?"at":"wa";var c=b+(U(Y)*a)-I;var e=Z+(L(Y)*a)-I;var V=b+(U(W)*a)-I;var d=Z+(L(W)*a)-I;if(c==V&&!X){c+=0.125}this.currentPath_.push({type:f,x:b,y:Z,radius:a,xStart:c,yStart:e,xEnd:V,yEnd:d})};H.rect=function(X,W,V,Y){this.moveTo(X,W);this.lineTo(X+V,W);this.lineTo(X+V,W+Y);this.lineTo(X,W+Y);this.closePath()};H.strokeRect=function(X,W,V,Y){this.beginPath();this.moveTo(X,W);this.lineTo(X+V,W);this.lineTo(X+V,W+Y);this.lineTo(X,W+Y);this.closePath();this.stroke()};H.fillRect=function(X,W,V,Y){this.beginPath();this.moveTo(X,W);this.lineTo(X+V,W);this.lineTo(X+V,W+Y);this.lineTo(X,W+Y);this.closePath();this.fill()};H.createLinearGradient=function(W,Y,V,X){var Z=new S("gradient");return Z};H.createRadialGradient=function(Y,a,X,W,Z,V){var b=new S("gradientradial");b.radius1_=X;b.radius2_=V;b.focus_.x=Y;b.focus_.y=a;return b};H.drawImage=function(n,Y){var f,c,i,u,l,j,p,x;var g=n.runtimeStyle.width;var m=n.runtimeStyle.height;n.runtimeStyle.width="auto";n.runtimeStyle.height="auto";var e=n.width;var s=n.height;n.runtimeStyle.width=g;n.runtimeStyle.height=m;if(arguments.length==3){f=arguments[1];c=arguments[2];l=j=0;p=i=e;x=u=s}else{if(arguments.length==5){f=arguments[1];c=arguments[2];i=arguments[3];u=arguments[4];l=j=0;p=e;x=s}else{if(arguments.length==9){l=arguments[1];j=arguments[2];p=arguments[3];x=arguments[4];f=arguments[5];c=arguments[6];i=arguments[7];u=arguments[8]}else{throw"Invalid number of arguments"}}}var v=this.getCoords_(f,c);var Z=p/2;var X=x/2;var t=[];var V=10;var b=10;t.push(" <g_vml_:group",' coordsize="',A*V,",",A*b,'"',' coordorigin="0,0"',' style="width:',V,";height:",b,";position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var a=[];a.push("M11='",this.m_[0][0],"',","M12='",this.m_[1][0],"',","M21='",this.m_[0][1],"',","M22='",this.m_[1][1],"',","Dx='",O(v.x/A),"',","Dy='",O(v.y/A),"'");var r=v;var q=this.getCoords_(f+i,c);var o=this.getCoords_(f,c+u);var k=this.getCoords_(f+i,c+u);r.x=Math.max(r.x,q.x,o.x,k.x);r.y=Math.max(r.y,q.y,o.y,k.y);t.push("padding:0 ",O(r.x/A),"px ",O(r.y/A),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",a.join(""),", sizingmethod='clip');")}else{t.push("top:",O(v.y/A),"px;left:",O(v.x/A),"px;")}t.push(' ">','<g_vml_:image src="',n.src,'"',' style="width:',A*i,";"," height:",A*u,';"',' cropleft="',l/e,'"',' croptop="',j/s,'"',' cropright="',(e-l-p)/e,'"',' cropbottom="',(s-j-x)/s,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",t.join(""))};H.stroke=function(y){var e=[];var d=false;var AB=C(y?this.fillStyle:this.strokeStyle);var u=AB[0];var Y=AB[1]*this.globalAlpha;var X=10;var j=10;e.push("<g_vml_:shape",' fillcolor="',u,'"',' filled="',Boolean(y),'"',' style="position:absolute;width:',X,";height:",j,';"',' coordorigin="0 0" coordsize="',A*X," ",A*j,'"',' stroked="',!y,'"',' strokeweight="',this.lineWidth,'"',' strokecolor="',u,'"',' path="');var h=false;var t={x:null,y:null};var v={x:null,y:null};for(var w=0;w<this.currentPath_.length;w++){var o=this.currentPath_[w];if(o.type=="moveTo"){e.push(" m ");var AA=this.getCoords_(o.x,o.y);e.push(O(AA.x),",",O(AA.y))}else{if(o.type=="lineTo"){e.push(" l ");var AA=this.getCoords_(o.x,o.y);e.push(O(AA.x),",",O(AA.y))}else{if(o.type=="close"){e.push(" x ")}else{if(o.type=="bezierCurveTo"){e.push(" c ");var AA=this.getCoords_(o.x,o.y);var s=this.getCoords_(o.cp1x,o.cp1y);var q=this.getCoords_(o.cp2x,o.cp2y);e.push(O(s.x),",",O(s.y),",",O(q.x),",",O(q.y),",",O(AA.x),",",O(AA.y))}else{if(o.type=="at"||o.type=="wa"){e.push(" ",o.type," ");var AA=this.getCoords_(o.x,o.y);var k=this.getCoords_(o.xStart,o.yStart);var b=this.getCoords_(o.xEnd,o.yEnd);e.push(O(AA.x-this.arcScaleX_*o.radius),",",O(AA.y-this.arcScaleY_*o.radius)," ",O(AA.x+this.arcScaleX_*o.radius),",",O(AA.y+this.arcScaleY_*o.radius)," ",O(k.x),",",O(k.y)," ",O(b.x),",",O(b.y))}}}}}if(AA){if(t.x==null||AA.x<t.x){t.x=AA.x}if(v.x==null||AA.x>v.x){v.x=AA.x}if(t.y==null||AA.y<t.y){t.y=AA.y}if(v.y==null||AA.y>v.y){v.y=AA.y}}}e.push(' ">');if(typeof this.fillStyle=="object"){var n={x:"50%",y:"50%"};var r=(v.x-t.x);var l=(v.y-t.y);var z=(r>l)?r:l;n.x=O((this.fillStyle.focus_.x/r)*100+50)+"%";n.y=O((this.fillStyle.focus_.y/l)*100+50)+"%";var g=[];if(this.fillStyle.type_=="gradientradial"){var x=(this.fillStyle.radius1_/z*100);var m=(this.fillStyle.radius2_/z*100)-x}else{var x=0;var m=100}var V={offset:null,color:null};var Z={offset:null,color:null};this.fillStyle.colors_.sort(function(a,W){return a.offset-W.offset});for(var w=0;w<this.fillStyle.colors_.length;w++){var f=this.fillStyle.colors_[w];g.push((f.offset*m)+x,"% ",f.color,",");if(f.offset>V.offset||V.offset==null){V.offset=f.offset;V.color=f.color}if(f.offset<Z.offset||Z.offset==null){Z.offset=f.offset;Z.color=f.color}}g.pop();e.push("<g_vml_:fill",' color="',Z.color,'"',' color2="',V.color,'"',' type="',this.fillStyle.type_,'"',' focusposition="',n.x,", ",n.y,'"',' colors="',g.join(""),'"',' opacity="',Y,'" />')}else{if(y){e.push('<g_vml_:fill color="',u,'" opacity="',Y,'" />')}else{e.push("<g_vml_:stroke",' opacity="',Y,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',M(this.lineCap),'"',' weight="',this.lineWidth,'px"',' color="',u,'" />')}}e.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",e.join(""))};H.fill=function(){this.stroke(true)};H.closePath=function(){this.currentPath_.push({type:"close"})};H.getCoords_=function(W,V){return{x:A*(W*this.m_[0][0]+V*this.m_[1][0]+this.m_[2][0])-I,y:A*(W*this.m_[0][1]+V*this.m_[1][1]+this.m_[2][1])-I}};H.save=function(){var V={};P(this,V);this.aStack_.push(V);this.mStack_.push(this.m_);this.m_=E(K(),this.m_)};H.restore=function(){P(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};H.translate=function(X,W){var V=[[1,0,0],[0,1,0],[X,W,1]];this.m_=E(V,this.m_)};H.rotate=function(W){var Y=U(W);var X=L(W);var V=[[Y,X,0],[-X,Y,0],[0,0,1]];this.m_=E(V,this.m_)};H.scale=function(X,W){this.arcScaleX_*=X;this.arcScaleY_*=W;var V=[[X,0,0],[0,W,0],[0,0,1]];this.m_=E(V,this.m_)};H.clip=function(){};H.arcTo=function(){};H.createPattern=function(){return new F};function S(V){this.type_=V;this.radius1_=0;this.radius2_=0;this.colors_=[];this.focus_={x:0,y:0}}S.prototype.addColorStop=function(W,V){V=C(V);this.colors_.push({offset:1-W,color:V})};function F(){}G_vmlCanvasManager=G;CanvasRenderingContext2D=J;CanvasGradient=S;CanvasPattern=F})()}; \ No newline at end of file
diff --git a/tools/qtestlib/chart/3rdparty/flotr.js b/tools/qtestlib/chart/3rdparty/flotr.js
new file mode 100644
index 0000000..80bb506
--- /dev/null
+++ b/tools/qtestlib/chart/3rdparty/flotr.js
@@ -0,0 +1,2 @@
+//Flotr 0.1.0alpha Copyright (c) 2008 Bas Wenneker, <http://solutoire.com>, MIT License.
+var Flotr=(function(){var C=0;function L(M){return M.collect(function(N){return(N.data)?Object.clone(N):{data:N}})}function G(P,N){var M=N||{};for(var O in P){M[O]=(typeof (P[O])=="object"&&!(P[O].constructor==Array||P[O].constructor==RegExp))?G(P[O],N[O]):M[O]=P[O]}return M}function I(Q,P,M,N){var T=(M-P)/Q;var S=H(T);var O=T/S;var R=10;if(O<1.5){R=1}else{if(O<2.25){R=2}else{if(O<3){R=2.5}else{if(O<7.5){R=5}}}}if(R==2.5&&N==0){R=2}R*=S;return R}function E(M){return M.toString()}function F(M){return"("+M.x+", "+M.y+")"}function H(M){return Math.pow(10,Math.floor(Math.log(M)/Math.LN10))}function K(O){var M;if((M=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(O))){return new B(parseInt(M[1]),parseInt(M[2]),parseInt(M[3]))}if((M=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(O))){return new B(parseInt(M[1]),parseInt(M[2]),parseInt(M[3]),parseFloat(M[4]))}if((M=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(O))){return new B(parseFloat(M[1])*2.55,parseFloat(M[2])*2.55,parseFloat(M[3])*2.55)}if((M=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(O))){return new B(parseFloat(M[1])*2.55,parseFloat(M[2])*2.55,parseFloat(M[3])*2.55,parseFloat(M[4]))}if((M=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(O))){return new B(parseInt(M[1],16),parseInt(M[2],16),parseInt(M[3],16))}if((M=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(O))){return new B(parseInt(M[1]+M[1],16),parseInt(M[2]+M[2],16),parseInt(M[3]+M[3],16))}var N=O.strip().toLowerCase();if(N=="transparent"){return new B(255,255,255,0)}M=D[N];return new B(M[0],M[1],M[2])}function A(N){var M;do{M=N.getStyle("background-color").toLowerCase();if(M!=""&&M!="transparent"){break}N=N.up(0)}while(N.nodeName.toLowerCase()!="body");if(M=="rgba(0, 0, 0, 0)"){return"transparent"}return M}function B(S,R,N,P){var Q=["r","g","b","a"];var M=4;while(-1<--M){this[Q[M]]=arguments[M]||((M==3)?1:0)}this.toString=function(){return(this.a>=1)?"rgb("+[this.r,this.g,this.b].join(",")+")":"rgba("+[this.r,this.g,this.b,this.a].join(",")+")"};this.scale=function(V,U,W,T){M=4;while(-1<--M){if(arguments[M]!=null){this[Q[M]]*=arguments[M]}}return this.normalize()};this.adjust=function(V,U,W,T){M=4;while(-1<--M){if(arguments[M]!=null){this[Q[M]]+=arguments[M]}}return this.normalize()};this.clone=function(){return new B(this.r,this.b,this.g,this.a)};var O=function(U,T,V){return Math.max(Math.min(U,V),T)};this.normalize=function(){this.r=O(parseInt(this.r),0,255);this.g=O(parseInt(this.g),0,255);this.b=O(parseInt(this.b),0,255);this.a=O(this.a,0,1);return this};this.normalize()}var D={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]};function J(y,AO,p){var o,S,AL,h,AS;var z="flotr-"+C++;var R=L(AO);var N=y;var u={},c={};var l={left:0,right:0,top:0,bottom:0};var AA=0;var d=0;var AH=0;var U=0;var P=0;var AD=0;var AC=0;var AB=0;g(p);k();AN();q();AK(u,o.xaxis);Z();AK(c,o.yaxis);m(u,o.xaxis);m(c,o.yaxis);Y();AP();AQ();this.getCanvas=function(){return S};this.getPlotOffset=function(){return l};this.clearSelection=M;this.setSelection=AF;function g(AV){o=G(AV,{colors:["#00A8F0","#C0D800","#cb4b4b","#4da74d","#9440ed"],legend:{show:true,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:0.85},xaxis:{ticks:null,noTicks:5,tickFormatter:E,tickDecimals:null,min:null,max:null,autoscaleMargin:0},yaxis:{ticks:null,noTicks:5,tickFormatter:E,tickDecimals:null,min:null,max:null,autoscaleMargin:0},points:{show:false,radius:3,lineWidth:2,fill:true,fillColor:"#ffffff"},lines:{show:false,lineWidth:2,fill:false,fillColor:null},bars:{show:false,lineWidth:2,barWidth:1,fill:true,fillColor:null},grid:{color:"#545454",backgroundColor:null,tickColor:"#dddddd",labelMargin:3},selection:{mode:null,color:"#B6D9FF",fps:10},mouse:{track:null,position:"se",trackFormatter:F,margin:3,color:"#ff3f19",trackDecimals:1,sensibility:2,radius:3},shadowSize:4});var Ah=R.length;var AT=[];var AZ=[];for(var Ac=0;Ac<R.length;++Ac){var Ag=R[Ac].color;if(Ag!=null){--Ah;if(Object.isNumber(Ag)){AZ.push(Ag)}else{AT.push(K(R[Ac].color))}}}for(var Ab=0;Ab<AZ.length;++Ab){Ah=Math.max(Ah,AZ[Ab]+1)}var AU=[];var AY=0;var Aa=0;while(AU.length<Ah){var Af=(o.colors.length==Aa)?new B(100,100,100):K(o.colors[Aa]);var AW=AY%2==1?-1:1;var Ae=1+AW*Math.ceil(AY/2)*0.2;Af.scale(Ae,Ae,Ae);AU.push(Af);if(++Aa>=o.colors.length){Aa=0;++AY}}var Ad=0;for(var AX=0,Ai;AX<R.length;++AX){Ai=R[AX];if(Ai.color==null){Ai.color=AU[Ad].toString();++Ad}else{if(Object.isNumber(Ai.color)){Ai.color=AU[Ai.color].toString()}}Ai.lines=Object.extend(Object.clone(o.lines),Ai.lines);Ai.points=Object.extend(Object.clone(o.points),Ai.points);Ai.bars=Object.extend(Object.clone(o.bars),Ai.bars);Ai.mouse=Object.extend(Object.clone(o.mouse),Ai.mouse);if(Ai.shadowSize==null){Ai.shadowSize=o.shadowSize}}}function k(){AH=N.getWidth();U=N.getHeight();N.innerHTML="";N.setStyle({position:"relative"});if(AH<=0||U<=0){throw"Invalid dimensions for plot, width = "+AH+", height = "+U}S=$(document.createElement("canvas")).writeAttribute({width:AH,height:U});N.appendChild(S);if(Prototype.Browser.IE){S=$(window.G_vmlCanvasManager.initElement(S))}h=S.getContext("2d");AL=$(document.createElement("canvas")).writeAttribute({width:AH,height:U}).setStyle({position:"absolute",left:"0px",top:"0px"});N.setStyle({cursor:"default"}).appendChild(AL);if(Prototype.Browser.IE){AL=$(window.G_vmlCanvasManager.initElement(AL))}AS=AL.getContext("2d")}function AN(){if(o.selection.mode!=null){AL.observe("mousedown",r)}AL.observe("mousemove",e);AL.observe("click",f)}function q(){c.datamin=u.datamin=0;u.datamax=c.datamax=1;if(R.length==0){return }var AY=false;for(var AV=0;AV<R.length;++AV){if(R[AV].data.length>0){u.datamin=u.datamax=R[AV].data[0][0];c.datamin=c.datamax=R[AV].data[0][1];AY=true;break}}if(!AY){return }for(var AU=0;AU<R.length;++AU){var AX=R[AU].data;for(var AW=0;AW<AX.length;++AW){var AT=AX[AW][0];var AZ=AX[AW][1];if(AT<u.datamin){u.datamin=AT}else{if(AT>u.datamax){u.datamax=AT}}if(AZ<c.datamin){c.datamin=AZ}else{if(AZ>c.datamax){c.datamax=AZ}}}}}function AK(AW,AY){var AV=AY.min!=null?AY.min:AW.datamin;var AT=AY.max!=null?AY.max:AW.datamax;if(AT-AV==0){var AU=(AT==0)?1:0.01;AV-=AU;AT+=AU}AW.tickSize=I(AY.noTicks,AV,AT,AY.tickDecimals);var AX;if(AY.min==null){AX=AY.autoscaleMargin;if(AX!=0){AV-=AW.tickSize*AX;if(AV<0&&AW.datamin>=0){AV=0}AV=AW.tickSize*Math.floor(AV/AW.tickSize)}}if(AY.max==null){AX=AY.autoscaleMargin;if(AX!=0){AT+=AW.tickSize*AX;if(AT>0&&AW.datamax<=0){AT=0}AT=AW.tickSize*Math.ceil(AT/AW.tickSize)}}AW.min=AV;AW.max=AT}function Z(){if(o.xaxis.max==null){var AU=u.max;for(var AT=0;AT<R.length;++AT){if(R[AT].bars.show&&R[AT].bars.barWidth+u.datamax>AU){AU=u.max+R[AT].bars.barWidth}}u.max=AU}}function m(AV,AW){AV.ticks=[];if(AW.ticks){var AZ=AW.ticks;if(Object.isFunction(AZ)){AZ=AZ({min:AV.min,max:AV.max})}for(var AX=0,Aa,AY;AX<AZ.length;++AX){var Ab=AZ[AX];if(typeof (Ab)=="object"){Aa=Ab[0];AY=(Ab.length>1)?Ab[1]:AW.tickFormatter(Aa)}else{Aa=Ab;AY=AW.tickFormatter(Aa)}AV.ticks[AX]={v:Aa,label:AY}}}else{var AT=AV.tickSize*Math.ceil(AV.min/AV.tickSize);for(AX=0;AT+AX*AV.tickSize<=AV.max;++AX){Aa=AT+AX*AV.tickSize;var AU=AW.tickDecimals;if(AU==null){AU=1-Math.floor(Math.log(AV.tickSize)/Math.LN10)}if(AU<0){AU=0}Aa=Aa.toFixed(AU);AV.ticks.push({v:Aa,label:AW.tickFormatter(Aa)})}}}function Y(){var AX="";for(var AW=0;AW<c.ticks.length;++AW){var AU=c.ticks[AW].label.length;if(AU>AX.length){AX=c.ticks[AW].label}}var AT=N.insert('<div style="position:absolute;top:-10000px;font-size:smaller" class="flotr-grid-label">'+AX+"</div>").down(0).next(1);AA=AT.getWidth();d=AT.getHeight();AT.remove();var AY=2;if(o.points.show){AY=Math.max(AY,o.points.radius+o.points.lineWidth/2)}for(var AV=0;AV<R.length;++AV){if(R[AV].points.show){AY=Math.max(AY,R[AV].points.radius+R[AV].points.lineWidth/2)}}l.left=l.right=l.top=l.bottom=AY;l.left+=AA+o.grid.labelMargin;l.bottom+=d+o.grid.labelMargin;P=AH-l.left-l.right;AD=U-l.bottom-l.top;AC=P/(u.max-u.min);AB=AD/(c.max-c.min)}function AP(){V();AR();for(var AT=0;AT<R.length;AT++){AI(R[AT])}}function AE(AT){return(AT-u.min)*AC}function j(AT){return AD-(AT-c.min)*AB}function V(){h.save();h.translate(l.left,l.top);if(o.grid.backgroundColor!=null){h.fillStyle=o.grid.backgroundColor;h.fillRect(0,0,P,AD)}h.lineWidth=1;h.strokeStyle=o.grid.tickColor;h.beginPath();for(var AV=0,AT=null;AV<u.ticks.length;++AV){AT=u.ticks[AV].v;if(AT==u.min||AT==u.max){continue}h.moveTo(Math.floor(AE(AT))+h.lineWidth/2,0);h.lineTo(Math.floor(AE(AT))+h.lineWidth/2,AD)}for(var AU=0,AT=null;AU<c.ticks.length;++AU){AT=c.ticks[AU].v;if(AT==c.min||AT==c.max){continue}h.moveTo(0,Math.floor(j(AT))+h.lineWidth/2);h.lineTo(P,Math.floor(j(AT))+h.lineWidth/2)}h.stroke();h.lineWidth=2;h.strokeStyle=o.grid.color;h.lineJoin="round";h.strokeRect(0,0,P,AD);h.restore()}function AR(){var AZ=0;for(var AY=0;AY<u.ticks.length;++AY){if(u.ticks[AY].label){++AZ}}var AU=P/AZ;var AX='<div style="font-size:smaller;color:'+o.grid.color+'">';for(var AV=0,AW=null;AV<u.ticks.length;++AV){AW=u.ticks[AV];if(!AW.label){continue}AX+='<div style="position:absolute;top:'+(l.top+AD+o.grid.labelMargin)+"px;left:"+(l.left+AE(AW.v)-AU/2)+"px;width:"+AU+'px;text-align:center" class="flotr-grid-label">'+AW.label+"</div>"}for(var AT=0,AW=null;AT<c.ticks.length;++AT){AW=c.ticks[AT];if(!AW.label||AW.label.length==0){continue}AX+='<div style="position:absolute;top:'+(l.top+j(AW.v)-d/2)+"px;left:0;width:"+AA+'px;text-align:right" class="flotr-grid-label">'+AW.label+"</div>"}AX+="</div>";N.insert(AX)}function AI(AT){if(AT.lines.show||(!AT.bars.show&&!AT.points.show)){i(AT)}if(AT.bars.show){v(AT)}if(AT.points.show){w(AT)}}function i(AV){function AU(Ad,Ac){if(Ad.length<2){return }var Ab=AE(Ad[0][0]),Aa=j(Ad[0][1])+Ac;h.beginPath();h.moveTo(Ab,Aa);for(var Ae=0;Ae<Ad.length-1;++Ae){var AZ=Ad[Ae][0],Ag=Ad[Ae][1],AY=Ad[Ae+1][0],Af=Ad[Ae+1][1];if(Ag<=Af&&Ag<c.min){if(Af<c.min){continue}AZ=(c.min-Ag)/(Af-Ag)*(AY-AZ)+AZ;Ag=c.min}else{if(Af<=Ag&&Af<c.min){if(Ag<c.min){continue}AY=(c.min-Ag)/(Af-Ag)*(AY-AZ)+AZ;Af=c.min}}if(Ag>=Af&&Ag>c.max){if(Af>c.max){continue}AZ=(c.max-Ag)/(Af-Ag)*(AY-AZ)+AZ;Ag=c.max}else{if(Af>=Ag&&Af>c.max){if(Ag>c.max){continue}AY=(c.max-Ag)/(Af-Ag)*(AY-AZ)+AZ;Af=c.max}}if(AZ<=AY&&AZ<u.min){if(AY<u.min){continue}Ag=(u.min-AZ)/(AY-AZ)*(Af-Ag)+Ag;AZ=u.min}else{if(AY<=AZ&&AY<u.min){if(AZ<u.min){continue}Af=(u.min-AZ)/(AY-AZ)*(Af-Ag)+Ag;AY=u.min}}if(AZ>=AY&&AZ>u.max){if(AY>u.max){continue}Ag=(u.max-AZ)/(AY-AZ)*(Af-Ag)+Ag;AZ=u.max}else{if(AY>=AZ&&AY>u.max){if(AZ>u.max){continue}Af=(u.max-AZ)/(AY-AZ)*(Af-Ag)+Ag;AY=u.max}}if(Ab!=AE(AZ)||Aa!=j(Ag)+Ac){h.moveTo(AE(AZ),j(Ag)+Ac)}Ab=AE(AY);Aa=j(Af)+Ac;h.lineTo(Ab,Aa)}h.stroke()}function AW(Ac){if(Ac.length<2){return }var AY=Math.min(Math.max(0,c.min),c.max);var Ah,Aa=0;var Ae=true;h.beginPath();for(var Ad=0;Ad<Ac.length-1;++Ad){var Ab=Ac[Ad][0],Ai=Ac[Ad][1],AZ=Ac[Ad+1][0],Ag=Ac[Ad+1][1];if(Ab<=AZ&&Ab<u.min){if(AZ<u.min){continue}Ai=(u.min-Ab)/(AZ-Ab)*(Ag-Ai)+Ai;Ab=u.min}else{if(AZ<=Ab&&AZ<u.min){if(Ab<u.min){continue}Ag=(u.min-Ab)/(AZ-Ab)*(Ag-Ai)+Ai;AZ=u.min}}if(Ab>=AZ&&Ab>u.max){if(AZ>u.max){continue}Ai=(u.max-Ab)/(AZ-Ab)*(Ag-Ai)+Ai;Ab=u.max}else{if(AZ>=Ab&&AZ>u.max){if(Ab>u.max){continue}Ag=(u.max-Ab)/(AZ-Ab)*(Ag-Ai)+Ai;AZ=u.max}}if(Ae){h.moveTo(AE(Ab),j(AY));Ae=false}if(Ai>=c.max&&Ag>=c.max){h.lineTo(AE(Ab),j(c.max));h.lineTo(AE(AZ),j(c.max));continue}else{if(Ai<=c.min&&Ag<=c.min){h.lineTo(AE(Ab),j(c.min));h.lineTo(AE(AZ),j(c.min));continue}}var Aj=Ab,Af=AZ;if(Ai<=Ag&&Ai<c.min&&Ag>=c.min){Ab=(c.min-Ai)/(Ag-Ai)*(AZ-Ab)+Ab;Ai=c.min}else{if(Ag<=Ai&&Ag<c.min&&Ai>=c.min){AZ=(c.min-Ai)/(Ag-Ai)*(AZ-Ab)+Ab;Ag=c.min}}if(Ai>=Ag&&Ai>c.max&&Ag<=c.max){Ab=(c.max-Ai)/(Ag-Ai)*(AZ-Ab)+Ab;Ai=c.max}else{if(Ag>=Ai&&Ag>c.max&&Ai<=c.max){AZ=(c.max-Ai)/(Ag-Ai)*(AZ-Ab)+Ab;Ag=c.max}}if(Ab!=Aj){Ah=(Ai<=c.min)?Ah=c.min:c.max;h.lineTo(AE(Aj),j(Ah));h.lineTo(AE(Ab),j(Ah))}h.lineTo(AE(Ab),j(Ai));h.lineTo(AE(AZ),j(Ag));if(AZ!=Af){Ah=(Ag<=c.min)?c.min:c.max;h.lineTo(AE(Af),j(Ah));h.lineTo(AE(AZ),j(Ah))}Aa=Math.max(AZ,Af)}h.lineTo(AE(Aa),j(AY));h.closePath();h.fill()}h.save();h.translate(l.left,l.top);h.lineJoin="round";var AX=AV.lines.lineWidth;var AT=AV.shadowSize;if(AT>0){h.lineWidth=AT/2;h.strokeStyle="rgba(0,0,0,0.1)";AU(AV.data,AX/2+AT/2+h.lineWidth/2);h.lineWidth=AT/2;h.strokeStyle="rgba(0,0,0,0.2)";AU(AV.data,AX/2+h.lineWidth/2)}h.lineWidth=AX;h.strokeStyle=AV.color;if(AV.lines.fill){h.fillStyle=AV.lines.fillColor!=null?AV.lines.fillColor:K(AV.color).scale(null,null,null,0.4).toString();AW(AV.data,0)}AU(AV.data,0);h.restore()}function w(AU){function AX(Ab,AZ,Ac){for(var Aa=0;Aa<Ab.length;++Aa){var AY=Ab[Aa][0],Ad=Ab[Aa][1];if(AY<u.min||AY>u.max||Ad<c.min||Ad>c.max){continue}h.beginPath();h.arc(AE(AY),j(Ad),AZ,0,2*Math.PI,true);if(Ac){h.fill()}h.stroke()}}function AW(Ab,Ac,AZ){for(var Aa=0;Aa<Ab.length;++Aa){var AY=Ab[Aa][0],Ad=Ab[Aa][1];if(AY<u.min||AY>u.max||Ad<c.min||Ad>c.max){continue}h.beginPath();h.arc(AE(AY),j(Ad)+Ac,AZ,0,Math.PI,false);h.stroke()}}h.save();h.translate(l.left,l.top);var AV=AU.lines.lineWidth;var AT=AU.shadowSize;if(AT>0){h.lineWidth=AT/2;h.strokeStyle="rgba(0,0,0,0.1)";AW(AU.data,AT/2+h.lineWidth/2,AU.points.radius);h.lineWidth=AT/2;h.strokeStyle="rgba(0,0,0,0.2)";AW(AU.data,h.lineWidth/2,AU.points.radius)}h.lineWidth=AU.points.lineWidth;h.strokeStyle=AU.color;h.fillStyle=AU.points.fillColor!=null?AU.points.fillColor:AU.color;AX(AU.data,AU.points.radius,AU.points.fill);h.restore()}function v(AU){function AT(Ab,Ak,AZ,Aj){if(Ab.length<2){return }for(var Ac=0;Ac<Ab.length;Ac++){var Ag=Ab[Ac][0],Af=Ab[Ac][1];var Ai=true,Aa=true,Ad=true;var AY=Ag,Ah=Ag+Ak,AX=0,Ae=Af;if(Ah<u.min||AY>u.max||Ae<c.min||AX>c.max){continue}if(AY<u.min){AY=u.min;Ai=false}if(Ah>u.max){Ah=u.max;Ad=false}if(AX<c.min){AX=c.min}if(Ae>c.max){Ae=c.max;Aa=false}if(Aj){h.beginPath();h.moveTo(AE(AY),j(AX)+AZ);h.lineTo(AE(AY),j(Ae)+AZ);h.lineTo(AE(Ah),j(Ae)+AZ);h.lineTo(AE(Ah),j(AX)+AZ);h.fill()}if(Ai||Ad||Aa){h.beginPath();h.moveTo(AE(AY),j(AX)+AZ);if(Ai){h.lineTo(AE(AY),j(Ae)+AZ)}else{h.moveTo(AE(AY),j(Ae)+AZ)}if(Aa){h.lineTo(AE(Ah),j(Ae)+AZ)}else{h.moveTo(AE(Ah),j(Ae)+AZ)}if(Ad){h.lineTo(AE(Ah),j(AX)+AZ)}else{h.moveTo(AE(Ah),j(AX)+AZ)}h.stroke()}}}h.save();h.translate(l.left,l.top);h.lineJoin="round";var AW=AU.bars.barWidth;var AV=Math.min(AU.bars.lineWidth,AW);h.lineWidth=AV;h.strokeStyle=AU.color;if(AU.bars.fill){h.fillStyle=AU.bars.fillColor!=null?AU.bars.fillColor:K(AU.color).scale(null,null,null,0.4).toString()}AT(AU.data,AW,0,AU.bars.fill);h.restore()}function AQ(){if(!o.legend.show){return }var Aa=[];var AY=false;for(var AX=0;AX<R.length;++AX){if(!R[AX].label){continue}if(AX%o.legend.noColumns==0){Aa.push((AY)?"</tr><tr>":"<tr>");AY=true}var Ac=R[AX].label;if(o.legend.labelFormatter!=null){Ac=o.legend.labelFormatter(Ac)}Aa.push('<td class="flotr-legend-color-box"><div style="border:1px solid '+o.legend.labelBoxBorderColor+';padding:1px"><div style="width:14px;height:10px;background-color:'+R[AX].color+'"></div></div></td><td class="flotr-legend-label">'+Ac+"</td>")}if(AY){Aa.push("</tr>")}if(Aa.length>0){var Ad='<table style="font-size:smaller;color:'+o.grid.color+'">'+Aa.join("")+"</table>";if(o.legend.container!=null){o.legend.container.append(Ad)}else{var Ab="";var AU=o.legend.position,AV=o.legend.margin;if(AU.charAt(0)=="n"){Ab+="top:"+(AV+l.top)+"px;"}else{if(AU.charAt(0)=="s"){Ab+="bottom:"+(AV+l.bottom)+"px;"}}if(AU.charAt(1)=="e"){Ab+="right:"+(AV+l.right)+"px;"}else{if(AU.charAt(1)=="w"){Ab+="left:"+(AV+l.bottom)+"px;"}}var AT=N.insert('<div class="flotr-legend" style="position:absolute;z-index:2;'+Ab+'">'+Ad+"</div>").getElementsBySelector("div.flotr-legend").first();if(o.legend.backgroundOpacity!=0){var AZ=o.legend.backgroundColor;if(AZ==null){var AW=(o.grid.backgroundColor!=null)?o.grid.backgroundColor:A(AT);AZ=K(AW).adjust(null,null,null,1).toString()}N.insert('<div class="flotr-legend-bg" style="position:absolute;width:'+AT.getWidth()+"px;height:"+AT.getHeight()+"px;"+Ab+"background-color:"+AZ+';"> </div>').select("div.flotr-legend-bg").first().setStyle({opacity:o.legend.backgroundOpacity})}}}}var AG={pageX:null,pageY:null};var b={first:{x:-1,y:-1},second:{x:-1,y:-1}};var T=null;var x=null;var t=false;var Q=null;function f(AT){if(t){t=false;return }var AU=AL.cumulativeOffset();N.fire("flotr:click",[{x:u.min+(AT.pageX-AU.left-l.left)/AC,y:c.max-(AT.pageY-AU.top-l.top)/AB}])}function e(AU){if(AU.pageX==null&&AU.clientX!=null){var AX=document.documentElement,AT=document.body;AG.pageX=AU.clientX+(AX&&AX.scrollLeft||AT.scrollLeft||0);AG.pageY=AU.clientY+(AX&&AX.scrollTop||AT.scrollTop||0)}else{AG.pageX=AU.pageX;AG.pageY=AU.pageY}var AV=AL.cumulativeOffset();var AW={x:u.min+(AU.pageX-AV.left-l.left)/AC,y:c.max-(AU.pageY-AV.top-l.top)/AB};if(o.mouse.track&&x==null){n(AW)}N.fire("flotr:mousemove",[AU,AW])}function r(AT){if(!AT.isLeftClick()){return }AM(b.first,AT);if(x!=null){clearInterval(x)}AG.pageX=null;x=setInterval(AJ,1000/o.selection.fps);$(document).observe("mouseup",O)}function a(){var AU=(b.first.x<=b.second.x)?b.first.x:b.second.x;var AT=(b.first.x<=b.second.x)?b.second.x:b.first.x;var AW=(b.first.y>=b.second.y)?b.first.y:b.second.y;var AV=(b.first.y>=b.second.y)?b.second.y:b.first.y;AU=u.min+AU/AC;AT=u.min+AT/AC;AW=c.max-AW/AB;AV=c.max-AV/AB;N.fire("flotr:select",[{x1:AU,y1:AW,x2:AT,y2:AV}])}function O(AT){$(document).stopObserving("mouseup",O);if(x!=null){clearInterval(x);x=null}AM(b.second,AT);M();if(W()||AT.isLeftClick()){X();a();t=true}Event.stop(AT)}function AM(AV,AT){var AU=$(AL).cumulativeOffset();if(o.selection.mode=="y"){AV.x=(AV==b.first)?0:P}else{AV.x=AT.pageX-AU.left-l.left;AV.x=Math.min(Math.max(0,AV.x),P)}if(o.selection.mode=="x"){AV.y=(AV==b.first)?0:AD}else{AV.y=AT.pageY-AU.top-l.top;AV.y=Math.min(Math.max(0,AV.y),AD)}}function AJ(){if(AG.pageX==null){return }AM(b.second,AG);M();if(W()){X()}}function M(){if(T==null){return }var AT=Math.min(T.first.x,T.second.x),AW=Math.min(T.first.y,T.second.y),AU=Math.abs(T.second.x-T.first.x),AV=Math.abs(T.second.y-T.first.y);AS.clearRect(AT+l.left-AS.lineWidth,AW+l.top-AS.lineWidth,AU+AS.lineWidth*2,AV+AS.lineWidth*2);T=null}function AF(AT){M();b.first.y=(o.selection.mode=="x")?0:(c.max-AT.y1)*AB;b.second.y=(o.selection.mode=="x")?AD:(c.max-AT.y2)*AB;b.first.x=(o.selection.mode=="y")?0:(AT.x1-u.min)*AC;b.second.x=(o.selection.mode=="y")?P:(AT.x2-u.min)*AC;X();a()}function X(){if(T!=null&&b.first.x==T.first.x&&b.first.y==T.first.y&&b.second.x==T.second.x&&b.second.y==T.second.y){return }AS.strokeStyle=K(o.selection.color).scale(null,null,null,0.8).toString();AS.lineWidth=1;h.lineJoin="round";AS.fillStyle=K(o.selection.color).scale(null,null,null,0.4).toString();T={first:{x:b.first.x,y:b.first.y},second:{x:b.second.x,y:b.second.y}};var AT=Math.min(b.first.x,b.second.x),AW=Math.min(b.first.y,b.second.y),AU=Math.abs(b.second.x-b.first.x),AV=Math.abs(b.second.y-b.first.y);AS.fillRect(AT+l.left,AW+l.top,AU,AV);AS.strokeRect(AT+l.left,AW+l.top,AU,AV)}function W(){var AT=5;return Math.abs(b.second.x-b.first.x)>=AT&&Math.abs(b.second.y-b.first.y)>=AT}function s(){if(Q){AS.clearRect(AE(Q.x)+l.left-o.points.radius*2,j(Q.y)+l.top-o.points.radius*2,o.points.radius*3+o.points.lineWidth*3,o.points.radius*3+o.points.lineWidth*3);Q=null}}function n(Ae){var AX={dist:Number.MAX_VALUE,x:null,y:null,mouse:null};for(var Ad=0,Ac,AZ,AV;Ad<R.length;Ad++){if(!R[Ad].mouse.track){continue}Ac=R[Ad].data;AZ=(AC*R[Ad].mouse.sensibility);AV=(AB*R[Ad].mouse.sensibility);for(var Aa=0,Af,Ab;Aa<Ac.length;Aa++){Af=AC*Math.abs(Ac[Aa][0]-Ae.x);Ab=AB*Math.abs(Ac[Aa][1]-Ae.y);if(Af<AZ&&Ab<AV&&(Af+Ab)<AX.dist){AX.dist=(Af+Ab);AX.x=Ac[Aa][0];AX.y=Ac[Aa][1];AX.mouse=R[Ad].mouse}}}if(AX.mouse&&AX.mouse.track&&!Q||(Q&&AX.x!=Q.x&&AX.y!=Q.y)){var AU=N.select(".flotr-mouse-value").first();if(!AU){var Ag="",AT=o.mouse.position,AY=o.mouse.margin;if(AT.charAt(0)=="n"){Ag+="top:"+(AY+l.top)+"px;"}else{if(AT.charAt(0)=="s"){Ag+="bottom:"+(AY+l.bottom)+"px;"}}if(AT.charAt(1)=="e"){Ag+="right:"+(AY+l.right)+"px;"}else{if(AT.charAt(1)=="w"){Ag+="left:"+(AY+l.bottom)+"px;"}}N.insert('<div class="flotr-mouse-value" style="opacity:0.7;background-color:#000;color:#fff;display:none;position:absolute;'+Ag+'"></div>');return }if(AX.x!==null&&AX.y!==null){AU.setStyle({display:"block"});s();if(AX.mouse.lineColor!=null){AS.save();AS.translate(l.left,l.top);AS.lineWidth=o.points.lineWidth;AS.strokeStyle=AX.mouse.lineColor;AS.fillStyle="#ffffff";AS.beginPath();AS.arc(AE(AX.x),j(AX.y),o.points.radius,0,2*Math.PI,true);AS.fill();AS.stroke();AS.restore()}Q=AX;var AW=AX.mouse.trackDecimals;if(AW==null||AW<0){AW=0}AU.innerHTML=AX.mouse.trackFormatter({x:AX.x.toFixed(AW),y:AX.y.toFixed(AW)});N.fire("flotr:hit",[AX])}else{if(Q){AU.setStyle({display:"none"});s()}}}}}return{clean:function(M){M.innerHTML=""},draw:function(P,N,M){var O=new J(P,N,M);return O}}})(); \ No newline at end of file
diff --git a/tools/qtestlib/chart/3rdparty/prototype.js b/tools/qtestlib/chart/3rdparty/prototype.js
new file mode 100644
index 0000000..e580ae5
--- /dev/null
+++ b/tools/qtestlib/chart/3rdparty/prototype.js
@@ -0,0 +1,8 @@
+/* Prototype JavaScript framework, version 1.6.0.2
+ * (c) 2005-2008 Sam Stephenson
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ * For details, see the Prototype web site: http://www.prototypejs.org/
+ *
+ *--------------------------------------------------------------------------*/
+eval(function(p,a,c,k,e,d){e=function(c){return(c<a?"":e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('G 1g={9D:\'1.6.0.2\',1W:{3X:!!(1A.7b&&!1A.9e),58:!!1A.9e,4u:5e.5d.47(\'hE/\')>-1,7H:5e.5d.47(\'7H\')>-1&&5e.5d.47(\'ch\')==-1,d5:!!5e.5d.1f(/hD.*hC.*ci/)},3U:{72:!!1b.2S,6H:!!1A.6G,7x:1b.43(\'1T\').4U&&1b.43(\'1T\').4U!==1b.43(\'1x\').4U},84:\'<4S[^>]*>([\\\\S\\\\s]*?)<\\/4S>\',cM:/^\\/\\*-hB-([\\s\\S]*)\\*\\/\\s*$/,3q:q(){},K:q(x){o x}};E(1g.1W.d5)1g.3U.7x=1r;G 2b={2p:q(){G 2T=1k,3k=$A(1p);E(M.2w(3k[0]))2T=3k.5i();q 1N(){C.2I.3R(C,1p)}M.15(1N,2b.1d);1N.9Z=2T;1N.d4=[];E(2T){G a0=q(){};a0.1l=2T.1l;1N.1l=1s a0;2T.d4.1h(1N)}17(G i=0;i<3k.O;i++)1N.6a(3k[i]);E(!1N.1l.2I)1N.1l.2I=1g.3q;1N.1l.hA=1N;o 1N}};2b.1d={6a:q(22){G 3b=C.9Z&&C.9Z.1l;G 3k=M.4b(22);E(!M.4b({2H:1u}).O)3k.1h("2H","d3");17(G i=0,O=3k.O;i<O;i++){G 1y=3k[i],I=22[1y];E(3b&&M.2w(I)&&I.d1().3K()=="$4d"){G 1F=I,I=M.15((q(m){o q(){o 3b[m].3R(C,1p)}})(1y).5g(1F),{d3:q(){o 1F},2H:q(){o 1F.2H()}})}C.1l[1y]=I}o C}};G 4Y={};M.15=q(5L,22){17(G 1y 1Q 22)5L[1y]=22[1y];o 5L};M.15(M,{2C:q(Y){2s{E(M.2D(Y))o\'4z\';E(Y===1k)o\'1k\';o Y.2C?Y.2C():24(Y)}2E(e){E(e d2 hz)o\'...\';4q e}},3D:q(Y){G 1B=3Z Y;5y(1B){2r\'4z\':2r\'q\':2r\'hy\':o;2r\'hx\':o Y.2H()}E(Y===1k)o\'1k\';E(Y.3D)o Y.3D();E(M.4j(Y))o;G V=[];17(G 1y 1Q Y){G I=M.3D(Y[1y]);E(!M.2D(I))V.1h(1y.3D()+\': \'+I)}o\'{\'+V.2o(\', \')+\'}\'},4r:q(Y){o $H(Y).4r()},4i:q(Y){o Y&&Y.4i?Y.4i():24.62(Y)},4b:q(Y){G 4b=[];17(G 1y 1Q Y)4b.1h(1y);o 4b},1S:q(Y){G 1S=[];17(G 1y 1Q Y)1S.1h(Y[1y]);o 1S},2A:q(Y){o M.15({},Y)},4j:q(Y){o Y&&Y.3r==1},4x:q(Y){o Y!=1k&&3Z Y=="Y"&&\'hw\'1Q Y&&\'2o\'1Q Y},9G:q(Y){o Y d2 3V},2w:q(Y){o 3Z Y=="q"},3f:q(Y){o 3Z Y=="3h"},53:q(Y){o 3Z Y=="4M"},2D:q(Y){o 3Z Y=="4z"}});M.15(9X.1l,{d1:q(){G 3A=C.2H().1f(/^[\\s\\(]*q[^(]*\\((.*?)\\)/)[1].49(",").7k("3T");o 3A.O==1&&!3A[0]?[]:3A},1L:q(){E(1p.O<2&&M.2D(1p[0]))o C;G 3n=C,21=$A(1p),Y=21.5i();o q(){o 3n.3R(Y,21.20($A(1p)))}},hv:q(){G 3n=C,21=$A(1p),Y=21.5i();o q(1c){o 3n.3R(Y,[1c||1A.1c].20(21))}},7T:q(){E(!1p.O)o C;G 3n=C,21=$A(1p);o q(){o 3n.3R(C,21.20($A(1p)))}},9l:q(){G 3n=C,21=$A(1p),d0=21.5i()*cY;o 1A.hu(q(){o 3n.3R(3n,21)},d0)},5g:q(1K){G 3n=C;o q(){o 1K.3R(C,[3n.1L(C)].20($A(1p)))}},4v:q(){E(C.9Y)o C.9Y;G 3n=C;o C.9Y=q(){o 3n.3R(1k,[C].20($A(1p)))}}});9X.1l.4s=9X.1l.9l.7T(0.ht);hs.1l.3D=q(){o\'"\'+C.hr()+\'-\'+(C.hq()+1).4L(2)+\'-\'+C.hp().4L(2)+\'T\'+C.ho().4L(2)+\':\'+C.hn().4L(2)+\':\'+C.hm().4L(2)+\'Z"\'};G cp={co:q(){G 7d;17(G i=0,O=1p.O;i<O;i++){G cZ=1p[i];2s{7d=cZ();2d}2E(e){}}o 7d}};4k.1l.1f=4k.1l.2L;4k.c3=q(68){o 24(68).1Y(/([.*+?^=!:${}()|[\\]\\/\\\\])/g,\'\\\\$1\')};G aB=2b.2p({2I:q(2X,4c){C.2X=2X;C.4c=4c;C.85=1r;C.6s()},6s:q(){C.3W=ae(C.6N.1L(C),C.4c*cY)},8t:q(){C.2X(C)},8p:q(){E(!C.3W)o;af(C.3W);C.3W=1k},6N:q(){E(!C.85){2s{C.85=1u;C.8t()}hl{C.85=1r}}}});M.15(24,{62:q(I){o I==1k?\'\':24(I)},cQ:{\'\\b\':\'\\\\b\',\'\\t\':\'\\\\t\',\'\\n\':\'\\\\n\',\'\\f\':\'\\\\f\',\'\\r\':\'\\\\r\',\'\\\\\':\'\\\\\\\\\'}});M.15(24.1l,{3m:q(28,3F){G 1q=\'\',22=C,1f;3F=1p.5v.9S(3F);1P(22.O>0){E(1f=22.1f(28)){1q+=22.3B(0,1f.1i);1q+=24.62(3F(1f));22=22.3B(1f.1i+1f[0].O)}1m{1q+=22,22=\'\'}}o 1q},cN:q(28,3F,3x){3F=C.3m.9S(3F);3x=M.2D(3x)?1:3x;o C.3m(28,q(1f){E(--3x<0)o 1f[0];o 3F(1f)})},aN:q(28,W){C.3m(28,W);o 24(C)},hk:q(O,69){O=O||30;69=M.2D(69)?\'...\':69;o C.O>O?C.3B(0,O-69.O)+69:24(C)},3T:q(){o C.1Y(/^\\s+/,\'\').1Y(/\\s+$/,\'\')},cS:q(){o C.1Y(/<\\/?[^>]+>/gi,\'\')},4h:q(){o C.1Y(1s 4k(1g.84,\'cX\'),\'\')},cT:q(){G cW=1s 4k(1g.84,\'cX\');G cU=1s 4k(1g.84,\'hj\');o(C.1f(cW)||[]).2M(q(cV){o(cV.1f(cU)||[\'\',\'\'])[1]})},59:q(){o C.cT().2M(q(4S){o 7u(4S)})},82:q(){G 5J=1p.5v;5J.3Y.7n=C;o 5J.1T.4C},cJ:q(){G 1T=1s J(\'1T\');1T.4C=C.cS();o 1T.3g[0]?(1T.3g.O>1?$A(1T.3g).3H(\'\',q(2O,L){o 2O+L.4f}):1T.3g[0].4f):\'\'},7g:q(cR){G 1f=C.3T().1f(/([^?#]*)(#.*)?$/);E(!1f)o{};o 1f[1].49(cR||\'&\').3H({},q(3w,1H){E((1H=1H.49(\'=\'))[0]){G 1w=9p(1H.5i());G I=1H.O>1?1H.2o(\'=\'):1H[0];E(I!=4z)I=9p(I);E(1w 1Q 3w){E(!M.4x(3w[1w]))3w[1w]=[3w[1w]];3w[1w].1h(I)}1m 3w[1w]=I}o 3w})},3E:q(){o C.49(\'\')},9I:q(){o C.3B(0,C.O-1)+24.hi(C.cP(C.O-1)+1)},7E:q(3x){o 3x<1?\'\':1s 2m(3x+1).2o(C)},95:q(){G 4N=C.49(\'-\'),9W=4N.O;E(9W==1)o 4N[0];G 9V=C.83(0)==\'-\'?4N[0].83(0).2R()+4N[0].5H(1):4N[0];17(G i=1;i<9W;i++)9V+=4N[i].83(0).2R()+4N[i].5H(1);o 9V},6F:q(){o C.83(0).2R()+C.5H(1).2e()},hh:q(){o C.3m(/::/,\'/\').3m(/([A-Z]+)([A-Z][a-z])/,\'#{1}6T#{2}\').3m(/([a-z\\d])([A-Z])/,\'#{1}6T#{2}\').3m(/-/,\'6T\').2e()},hg:q(){o C.3m(/6T/,\'-\')},2C:q(cO){G 9T=C.3m(/[\\hf-\\he\\\\]/,q(1f){G 9U=24.cQ[1f[0]];o 9U?9U:\'\\\\hd\'+1f[0].cP().4L(2,16)});E(cO)o\'"\'+9T.1Y(/"/g,\'\\\\"\')+\'"\';o"\'"+9T.1Y(/\'/g,\'\\\\\\\'\')+"\'"},3D:q(){o C.2C(1u)},9w:q(2h){o C.cN(2h||1g.cM,\'#{1}\')},cK:q(){G 68=C;E(68.4O())o 1r;68=C.1Y(/\\\\./g,\'@\').1Y(/"[^"\\\\\\n\\r]*"/g,\'\');o(/^[,:{}\\[\\]0-9.\\-+hc-u \\n\\r\\t]*$/).2L(68)},60:q(cL){G 3l=C.9w();2s{E(!cL||3l.cK())o 7u(\'(\'+3l+\')\')}2E(e){}4q 1s hb(\'ha h9 c4 3h: \'+C.2C())},1J:q(28){o C.47(28)>-1},8F:q(28){o C.47(28)===0},aO:q(28){G d=C.O-28.O;o d>=0&&C.9L(28)===d},5E:q(){o C==\'\'},4O:q(){o/^\\s*$/.2L(C)},cb:q(Y,28){o 1s 32(C,28).2S(Y)}});E(1g.1W.4u||1g.1W.3X)M.15(24.1l,{82:q(){o C.1Y(/&/g,\'&cI;\').1Y(/</g,\'&cH;\').1Y(/>/g,\'&gt;\')},cJ:q(){o C.1Y(/&cI;/g,\'&\').1Y(/&cH;/g,\'<\').1Y(/&gt;/g,\'>\')}});24.1l.3m.9S=q(3F){E(M.2w(3F))o 3F;G 67=1s 32(3F);o q(1f){o 67.2S(1f)}};24.1l.h8=24.1l.7g;M.15(24.1l.82,{1T:1b.43(\'1T\'),3Y:1b.bm(\'\')});b0(24.1l.82)1T.5O(3Y);G 32=2b.2p({2I:q(67,28){C.67=67.2H();C.28=28||32.cE},2S:q(Y){E(M.2w(Y.9J))Y=Y.9J();o C.67.3m(C.28,q(1f){E(Y==1k)o\'\';G 4R=1f[1]||\'\';E(4R==\'\\\\\')o 1f[2];G 6X=Y,6Y=1f[3];G 28=/^([^.[]+|\\[((?:.*?[^\\\\])?)\\])(\\.|\\[|$)/;1f=28.cF(6Y);E(1f==1k)o 4R;1P(1f!=1k){G cG=1f[1].8F(\'[\')?1f[2].3m(\'\\\\\\\\]\',\']\'):1f[1];6X=6X[cG];E(1k==6X||\'\'==1f[3])2d;6Y=6Y.5H(\'[\'==1f[3]?1f[1].O:1f[0].O);1f=28.cF(6Y)}o 4R+24.62(6X)})}});32.cE=/(^|.|\\r|\\n)(#\\{(.*?)\\})/;G $2d={};G 2G={1E:q(W,1M){G 1i=0;W=W.1L(1M);2s{C.48(q(I){W(I,1i++)})}2E(e){E(e!=$2d)4q e}o C},cD:q(4M,W,1M){W=W?W.1L(1M):1g.K;G 1i=-4M,9R=[],2F=C.3E();1P((1i+=4M)<2F.O)9R.1h(2F.3B(1i,1i+4M));o 9R.9N(W,1M)},88:q(W,1M){W=W?W.1L(1M):1g.K;G 1q=1u;C.1E(q(I,1i){1q=1q&&!!W(I,1i);E(!1q)4q $2d});o 1q},cB:q(W,1M){W=W?W.1L(1M):1g.K;G 1q=1r;C.1E(q(I,1i){E(1q=!!W(I,1i))4q $2d});o 1q},9N:q(W,1M){W=W?W.1L(1M):1g.K;G V=[];C.1E(q(I,1i){V.1h(W(I,1i))});o V},81:q(W,1M){W=W.1L(1M);G 1q;C.1E(q(I,1i){E(W(I,1i)){1q=I;4q $2d}});o 1q},5C:q(W,1M){W=W.1L(1M);G V=[];C.1E(q(I,1i){E(W(I,1i))V.1h(I)});o V},h7:q(2h,W,1M){W=W?W.1L(1M):1g.K;G V=[];E(M.3f(2h))2h=1s 4k(2h);C.1E(q(I,1i){E(2h.1f(I))V.1h(W(I,1i))});o V},1J:q(Y){E(M.2w(C.47))E(C.47(Y)!=-1)o 1u;G 9Q=1r;C.1E(q(I){E(I==Y){9Q=1u;4q $2d}});o 9Q},h6:q(4M,6W){6W=M.2D(6W)?1k:6W;o C.cD(4M,q(3B){1P(3B.O<4M)3B.1h(6W);o 3B})},3H:q(2O,W,1M){W=W.1L(1M);C.1E(q(I,1i){2O=W(2O,I,1i)});o 2O},7k:q(1F){G 21=$A(1p).3B(1);o C.2M(q(I){o I[1F].3R(I,21)})},h5:q(W,1M){W=W?W.1L(1M):1g.K;G 1q;C.1E(q(I,1i){I=W(I,1i);E(1q==1k||I>=1q)1q=I});o 1q},h4:q(W,1M){W=W?W.1L(1M):1g.K;G 1q;C.1E(q(I,1i){I=W(I,1i);E(1q==1k||I<1q)1q=I});o 1q},h3:q(W,1M){W=W?W.1L(1M):1g.K;G 9P=[],9O=[];C.1E(q(I,1i){(W(I,1i)?9P:9O).1h(I)});o[9P,9O]},5u:q(1y){G V=[];C.1E(q(I){V.1h(I[1y])});o V},h2:q(W,1M){W=W.1L(1M);G V=[];C.1E(q(I,1i){E(!W(I,1i))V.1h(I)});o V},aK:q(W,1M){W=W.1L(1M);o C.2M(q(I,1i){o{I:I,6D:W(I,1i)}}).h1(q(2x,5U){G a=2x.6D,b=5U.6D;o a<b?-1:a>b?1:0}).5u(\'I\')},3E:q(){o C.2M()},h0:q(){G W=1g.K,21=$A(1p);E(M.2w(21.2u()))W=21.gZ();G cC=[C].20(21).2M($A);o C.2M(q(I,1i){o W(cC.5u(1i))})},cw:q(){o C.3E().O},2C:q(){o\'#<2G:\'+C.3E().2C()+\'>\'}};M.15(2G,{2M:2G.9N,8l:2G.81,2z:2G.5C,2h:2G.5C,gY:2G.1J,gX:2G.3E,gW:2G.88,gV:2G.cB});q $A(3d){E(!3d)o[];E(3d.3E)o 3d.3E();G O=3d.O||0,V=1s 2m(O);1P(O--)V[O]=3d[O];o V}E(1g.1W.4u){$A=q(3d){E(!3d)o[];E(!(M.2w(3d)&&3d==\'[Y gU]\')&&3d.3E)o 3d.3E();G O=3d.O||0,V=1s 2m(O);1P(O--)V[O]=3d[O];o V}}2m.cr=$A;M.15(2m.1l,2G);E(!2m.1l.9M)2m.1l.9M=2m.1l.4e;M.15(2m.1l,{48:q(W){17(G i=0,O=C.O;i<O;i++)W(C[i])},aH:q(){C.O=0;o C},3K:q(){o C[0]},2u:q(){o C[C.O-1]},gT:q(){o C.2z(q(I){o I!=1k})},cA:q(){o C.3H([],q(2F,I){o 2F.20(M.4x(I)?I.cA():[I])})},6b:q(){G 1S=$A(1p);o C.2z(q(I){o!1S.1J(I)})},4e:q(cz){o(cz!==1r?C:C.3E()).9M()},gS:q(){o C.O>1?C:C[0]},cx:q(cy){o C.3H([],q(2F,I,1i){E(0==1i||(cy?2F.2u()!=I:!2F.1J(I)))2F.1h(I);o 2F})},gR:q(2F){o C.cx().5C(q(66){o 2F.81(q(I){o 66===I})})},2A:q(){o[].20(C)},cw:q(){o C.O},2C:q(){o\'[\'+C.2M(M.2C).2o(\', \')+\']\'},3D:q(){G V=[];C.1E(q(Y){G I=M.3D(Y);E(!M.2D(I))V.1h(I)});o\'[\'+V.2o(\', \')+\']\'}});E(M.2w(2m.1l.cv))2m.1l.48=2m.1l.cv;E(!2m.1l.47)2m.1l.47=q(66,i){i||(i=0);G O=C.O;E(i<0)i=O+i;17(;i<O;i++)E(C[i]===66)o i;o-1};E(!2m.1l.9L)2m.1l.9L=q(66,i){i=gQ(i)?C.O:(i<0?C.O+i:i)+1;G n=C.3B(0,i).4e().47(66);o(n<0)?n:i-n-1};2m.1l.3E=2m.1l.2A;q $w(3h){E(!M.3f(3h))o[];3h=3h.3T();o 3h?3h.49(/\\s+/):[]}E(1g.1W.58){2m.1l.20=q(){G 2F=[];17(G i=0,O=C.O;i<O;i++)2F.1h(C[i]);17(G i=0,O=1p.O;i<O;i++){E(M.4x(1p[i])){17(G j=0,cu=1p[i].O;j<cu;j++)2F.1h(1p[i][j])}1m{2F.1h(1p[i])}}o 2F}}M.15(54.1l,{gP:q(){o C.4L(2,16)},9I:q(){o C+1},7E:q(W){$R(0,C,1u).1E(W);o C},4L:q(O,ct){G 3h=C.2H(ct||10);o\'0\'.7E(O-3h.O)+3h},3D:q(){o gO(C)?C.2H():\'1k\'}});$w(\'gN gM gL gK\').1E(q(1F){54.1l[1F]=gJ[1F].4v()});q $H(Y){o 1s 3V(Y)};G 3V=2b.2p(2G,(q(){q 9K(1w,I){E(M.2D(I))o 1w;o 1w+\'=\'+cs(24.62(I))}o{2I:q(Y){C.4K=M.9G(Y)?Y.6U():M.2A(Y)},48:q(W){17(G 1w 1Q C.4K){G I=C.4K[1w],1H=[1w,I];1H.1w=1w;1H.I=I;W(1H)}},6c:q(1w,I){o C.4K[1w]=I},9F:q(1w){o C.4K[1w]},gI:q(1w){G I=C.4K[1w];8R C.4K[1w];o I},6U:q(){o M.2A(C.4K)},4b:q(){o C.5u(\'1w\')},1S:q(){o C.5u(\'I\')},1i:q(I){G 1f=C.81(q(1H){o 1H.I===I});o 1f&&1f.1w},gH:q(Y){o C.2A().5a(Y)},5a:q(Y){o 1s 3V(Y).3H(C,q(1q,1H){1q.6c(1H.1w,1H.I);o 1q})},4r:q(){o C.2M(q(1H){G 1w=cs(1H.1w),1S=1H.I;E(1S&&3Z 1S==\'Y\'){E(M.4x(1S))o 1S.2M(9K.7T(1w)).2o(\'&\')}o 9K(1w,1S)}).2o(\'&\')},2C:q(){o\'#<3V:{\'+C.2M(q(1H){o 1H.2M(M.2C).2o(\': \')}).2o(\', \')+\'}>\'},3D:q(){o M.3D(C.6U())},2A:q(){o 1s 3V(C)}}})());3V.1l.9J=3V.1l.6U;3V.cr=$H;G cq=2b.2p(2G,{2I:q(4l,5o,65){C.4l=4l;C.5o=5o;C.65=65},48:q(W){G I=C.4l;1P(C.1J(I)){W(I);I=I.9I()}},1J:q(I){E(I<C.4l)o 1r;E(C.65)o I<C.5o;o I<=C.5o}});G $R=q(4l,5o,65){o 1s cq(4l,5o,65)};G 1R={cj:q(){o cp.co(q(){o 1s cf()},q(){o 1s cm(\'gG.cl\')},q(){o 1s cm(\'gF.cl\')})||1r},9H:0};1R.63={6V:[],48:q(W){C.6V.48(W)},ck:q(4m){E(!C.1J(4m))C.6V.1h(4m)},gE:q(4m){C.6V=C.6V.6b(4m)},7X:q(2X,2Q,1Z,3l){C.1E(q(4m){E(M.2w(4m[2X])){2s{4m[2X].3R(4m,[2Q,1Z,3l])}2E(e){}}})}};M.15(1R.63,2G);1R.63.ck({80:q(){1R.9H++},3S:q(){1R.9H--}});1R.9m=2b.2p({2I:q(U){C.U={1F:\'6S\',7Z:1u,6R:\'7V/x-gD-1x-gC\',9C:\'gB-8\',3v:\'\',60:1u,9z:1u};M.15(C.U,U||{});C.U.1F=C.U.1F.2e();E(M.3f(C.U.3v))C.U.3v=C.U.3v.7g();1m E(M.9G(C.U.3v))C.U.3v=C.U.3v.6U()}});1R.50=2b.2p(1R.9m,{9A:1r,2I:q($4d,2U,U){$4d(U);C.1Z=1R.cj();C.2Q(2U)},2Q:q(2U){C.2U=2U;C.1F=C.U.1F;G 2Y=M.2A(C.U.3v);E(![\'9F\',\'6S\'].1J(C.1F)){2Y[\'gA\']=C.1F;C.1F=\'6S\'}C.3v=2Y;E(2Y=M.4r(2Y)){E(C.1F==\'9F\')C.2U+=(C.2U.1J(\'?\')?\'&\':\'?\')+2Y;1m E(/gz|ci|ch/.2L(5e.5d))2Y+=\'&6T=\'}2s{G 2y=1s 1R.9t(C);E(C.U.80)C.U.80(2y);1R.63.7X(\'80\',C,2y);C.1Z.gy(C.1F.2R(),C.2U,C.U.7Z);E(C.U.7Z)C.9B.1L(C).4s(1);C.1Z.77=C.9E.1L(C);C.cg();C.2q=C.1F==\'6S\'?(C.U.gx||2Y):1k;C.1Z.gw(C.2q);E(!C.U.7Z&&C.1Z.ce)C.9E()}2E(e){C.5m(e)}},9E:q(){G 2N=C.1Z.2N;E(2N>1&&!((2N==4)&&C.9A))C.9B(C.1Z.2N)},cg:q(){G 5n={\'X-gv-gu\':\'cf\',\'X-1g-9D\':1g.9D,\'gs\':\'3Y/gr, 3Y/7D, 7V/6P, 3Y/6P, */*\'};E(C.1F==\'6S\'){5n[\'9o-1B\']=C.U.6R+(C.U.9C?\'; gq=\'+C.U.9C:\'\');E(C.1Z.ce&&(5e.5d.1f(/7H\\/(\\d{4})/)||[0,cd])[1]<cd)5n[\'gp\']=\'go\'}E(3Z C.U.cc==\'Y\'){G 64=C.U.cc;E(M.2w(64.1h))17(G i=0,O=64.O;i<O;i+=2)5n[64[i]]=64[i+1];1m $H(64).1E(q(1H){5n[1H.1w]=1H.I})}17(G 1e 1Q 5n)C.1Z.gn(1e,5n[1e])},5l:q(){G 4J=C.6O();o!4J||(4J>=gm&&4J<gl)},6O:q(){2s{o C.1Z.4J||0}2E(e){o 0}},9B:q(2N){G 6Q=1R.50.c8[2N],2y=1s 1R.9t(C);E(6Q==\'9u\'){2s{C.9A=1u;(C.U[\'5t\'+2y.4J]||C.U[\'5t\'+(C.5l()?\'gk\':\'gj\')]||1g.3q)(2y,2y.7W)}2E(e){C.5m(e)}G 6R=2y.61(\'9o-1B\');E(C.U.9z==\'c1\'||(C.U.9z&&C.7U()&&6R&&6R.1f(/^\\s*(3Y|7V)\\/(x-)?(gh|gg)4S(;.*)?\\s*$/i)))C.ca()}2s{(C.U[\'5t\'+6Q]||1g.3q)(2y,2y.7W);1R.63.7X(\'5t\'+6Q,C,2y,2y.7W)}2E(e){C.5m(e)}E(6Q==\'9u\'){C.1Z.77=1g.3q}},7U:q(){G m=C.2U.1f(/^\\s*gf?:\\/\\/[^\\/]*/);o!m||(m[0]==\'#{9y}//#{9x}#{7Y}\'.cb({9y:7h.9y,9x:1b.9x,7Y:7h.7Y?\':\'+7h.7Y:\'\'}))},61:q(1e){2s{o C.1Z.9r(1e)||1k}2E(e){o 1k}},ca:q(){2s{o 7u((C.1Z.3c||\'\').9w())}2E(e){C.5m(e)}},5m:q(9v){(C.U.c9||1g.3q)(C,9v);1R.63.7X(\'c9\',C,9v)}});1R.50.c8=[\'ge\',\'gd\',\'gc\',\'gb\',\'9u\'];1R.9t=2b.2p({2I:q(2Q){C.2Q=2Q;G 1Z=C.1Z=2Q.1Z,2N=C.2N=1Z.2N;E((2N>2&&!1g.1W.3X)||2N==4){C.4J=C.6O();C.9s=C.c6();C.3c=24.62(1Z.3c);C.7W=C.c5()}E(2N==4){G 6P=1Z.c7;C.c7=M.2D(6P)?1k:6P;C.ga=C.c2()}},4J:0,9s:\'\',6O:1R.50.1l.6O,c6:q(){2s{o C.1Z.9s||\'\'}2E(e){o\'\'}},61:1R.50.1l.61,g9:q(){2s{o C.9q()}2E(e){o 1k}},9r:q(1e){o C.1Z.9r(1e)},9q:q(){o C.1Z.9q()},c5:q(){G 3l=C.61(\'X-c4\');E(!3l)o 1k;3l=9p(c3(3l));2s{o 3l.60(C.2Q.U.c0||!C.2Q.7U())}2E(e){C.2Q.5m(e)}},c2:q(){G U=C.2Q.U;E(!U.60||(U.60!=\'c1\'&&!(C.61(\'9o-1B\')||\'\').1J(\'7V/3l\'))||C.3c.4O())o 1k;2s{o C.3c.60(U.c0||!C.2Q.7U())}2E(e){C.2Q.5m(e)}}});1R.bW=2b.2p(1R.50,{2I:q($4d,3C,2U,U){C.3C={5l:(3C.5l||3C),9n:(3C.9n||(3C.5l?1k:3C))};U=M.2A(U);G 3S=U.3S;U.3S=(q(2y,3l){C.bZ(2y.3c);E(M.2w(3S))3S(2y,3l)}).1L(C);$4d(2U,U)},bZ:q(3c){G 5Z=C.3C[C.5l()?\'5l\':\'9n\'],U=C.U;E(!U.59)3c=3c.4h();E(5Z=$(5Z)){E(U.5k){E(M.3f(U.5k)){G 5k={};5k[U.5k]=3c;5Z.3o(5k)}1m U.5k(5Z,3c)}1m 5Z.5a(3c)}}});1R.g8=2b.2p(1R.9m,{2I:q($4d,3C,2U,U){$4d(U);C.3S=C.U.3S;C.4c=(C.U.4c||2);C.5j=(C.U.5j||1);C.9k={};C.3C=3C;C.2U=2U;C.4l()},4l:q(){C.U.3S=C.bY.1L(C);C.6N()},8p:q(){C.9k.U.3S=4z;g7(C.3W);(C.3S||1g.3q).3R(C,1p)},bY:q(2y){E(C.U.5j){C.5j=(2y.3c==C.bX?C.5j*C.U.5j:1);C.bX=2y.3c}C.3W=C.6N.1L(C).9l(C.5j*C.4c)},6N:q(){C.9k=1s 1R.bW(C.3C,C.2U,C.U)}});q $(k){E(1p.O>1){17(G i=0,1V=[],O=1p.O;i<O;i++)1V.1h($(1p[i]));o 1V}E(M.3f(k))k=1b.g6(k);o J.15(k)}E(1g.3U.72){1b.8a=q(1t,71){G V=[];G 9j=1b.2S(1t,$(71)||1b,1k,g5.g4,1k);17(G i=0,O=9j.g3;i<O;i++)V.1h(J.15(9j.g2(i)));o V}}E(!1A.6o)G 6o={};E(!6o.bV){M.15(6o,{bV:1,g1:2,au:3,g0:4,fZ:5,fY:6,fX:7,fW:8,fV:9,fU:10,fT:11,fS:12})}(q(){G k=C.J;C.J=q(1a,2l){2l=2l||{};1a=1a.2e();G 2P=J.2P;E(1g.1W.3X&&2l.1e){1a=\'<\'+1a+\' 1e="\'+2l.1e+\'">\';8R 2l.1e;o J.6M(1b.43(1a),2l)}E(!2P[1a])2P[1a]=J.15(1b.43(1a));o J.6M(2P[1a].fR(1r),2l)};M.15(C.J,k||{})}).8m(1A);J.2P={};J.1d={99:q(k){o $(k).14.3p!=\'7L\'},aa:q(k){k=$(k);J[J.99(k)?\'bU\':\'bT\'](k);o k},bU:q(k){$(k).14.3p=\'7L\';o k},bT:q(k){$(k).14.3p=\'\';o k},a1:q(k){k=$(k);k.1O.6I(k);o k},5a:q(k,18){k=$(k);E(18&&18.3s)18=18.3s();E(M.4j(18))o k.5a().3o(18);18=M.4i(18);k.4C=18.4h();18.59.1L(18).4s();o k},1Y:q(k,18){k=$(k);E(18&&18.3s)18=18.3s();1m E(!M.4j(18)){18=M.4i(18);G 9i=k.fQ.fP();9i.fO(k);18.59.1L(18).4s();18=9i.fN(18.4h())}k.1O.8Z(18,k);o k},3o:q(k,3Q){k=$(k);E(M.3f(3Q)||M.53(3Q)||M.4j(3Q)||(3Q&&(3Q.3s||3Q.4i)))3Q={4Q:3Q};G 18,3o,1a,3g;17(G 1v 1Q 3Q){18=3Q[1v];1v=1v.2e();3o=J.5M[1v];E(18&&18.3s)18=18.3s();E(M.4j(18)){3o(k,18);3G}18=M.4i(18);1a=((1v==\'4R\'||1v==\'75\')?k.1O:k).1a.2R();3g=J.7F(1a,18.4h());E(1v==\'2i\'||1v==\'75\')3g.4e();3g.1E(3o.7T(k));18.59.1L(18).4s()}o k},5g:q(k,1K,2l){k=$(k);E(M.4j(1K))$(1K).6M(2l||{});1m E(M.3f(1K))1K=1s J(1K,2l);1m 1K=1s J(\'1T\',1K);E(k.1O)k.1O.8Z(1K,k);1K.5O(k);o 1K},2C:q(k){k=$(k);G 1q=\'<\'+k.1a.2e();$H({\'1o\':\'1o\',\'1j\':\'6e\'}).1E(q(1H){G 1y=1H.3K(),1U=1H.2u();G I=(k[1y]||\'\').2H();E(I)1q+=\' \'+1U+\'=\'+I.2C(1u)});o 1q+\'>\'},7S:q(k,1y){k=$(k);G 1V=[];1P(k=k[1y])E(k.3r==1)1V.1h(J.15(k));o 1V},5x:q(k){o $(k).7S(\'1O\')},bR:q(k){o $(k).2z("*")},bS:q(k){k=$(k).5D;1P(k&&k.3r!=1)k=k.3M;o $(k)},br:q(k){E(!(k=$(k).5D))o[];1P(k&&k.3r!=1)k=k.3M;E(k)o[k].20($(k).4E());o[]},5Y:q(k){o $(k).7S(\'aY\')},4E:q(k){o $(k).7S(\'3M\')},fM:q(k){k=$(k);o k.5Y().4e().20(k.4E())},1f:q(k,41){E(M.3f(41))41=1s 19(41);o 41.1f($(k))},fL:q(k,1t,1i){k=$(k);E(1p.O==1)o $(k.1O);G 5x=k.5x();o M.53(1t)?5x[1t]:19.5w(5x,1t,1i)},fK:q(k,1t,1i){k=$(k);E(1p.O==1)o k.bS();o M.53(1t)?k.bR()[1t]:k.2z(1t)[1i||0]},fJ:q(k,1t,1i){k=$(k);E(1p.O==1)o $(19.25.6x(k));G 5Y=k.5Y();o M.53(1t)?5Y[1t]:19.5w(5Y,1t,1i)},6B:q(k,1t,1i){k=$(k);E(1p.O==1)o $(19.25.6w(k));G 4E=k.4E();o M.53(1t)?4E[1t]:19.5w(4E,1t,1i)},2z:q(){G 21=$A(1p),k=$(21.5i());o 19.7o(k,21)},55:q(){G 21=$A(1p),k=$(21.5i());o 19.7o(k.1O,21).6b(k)},bt:q(k){k=$(k);G 1o=k.51(\'1o\'),5J=1p.5v;E(1o)o 1o;do{1o=\'fI\'+5J.bs++}1P($(1o));k.6M(\'1o\',1o);o 1o},51:q(k,1e){k=$(k);E(1g.1W.3X){G t=J.3O.7I;E(t.1S[1e])o t.1S[1e](k,1e);E(t.3A[1e])1e=t.3A[1e];E(1e.1J(\':\')){o(!k.2l||!k.2l[1e])?1k:k.2l[1e].I}}o k.91(1e)},6M:q(k,1e,I){k=$(k);G 2l={},t=J.3O.6l;E(3Z 1e==\'Y\')2l=1e;1m 2l[1e]=M.2D(I)?1u:I;17(G 29 1Q 2l){1e=t.3A[29]||29;I=2l[29];E(t.1S[29])1e=t.1S[29](k,I);E(I===1r||I===1k)k.8D(1e);1m E(I===1u)k.bQ(1e,1e);1m k.bQ(1e,I)}o k},b5:q(k){o $(k).5I().3a},b6:q(k){o $(k).5I().2g},6d:q(k){o 1s J.6Z(k)},7s:q(k,1j){E(!(k=$(k)))o;G 7R=k.1j;o(7R.O>0&&(7R==1j||1s 4k("(^|\\\\s)"+1j+"(\\\\s|$)").2L(7R)))},bO:q(k,1j){E(!(k=$(k)))o;E(!k.7s(1j))k.1j+=(k.1j?\' \':\'\')+1j;o k},bP:q(k,1j){E(!(k=$(k)))o;k.1j=k.1j.1Y(1s 4k("(^|\\\\s+)"+1j+"(\\\\s+|$)"),\' \').3T();o k},fH:q(k,1j){E(!(k=$(k)))o;o k[k.7s(1j)?\'bP\':\'bO\'](1j)},fG:q(k){k=$(k);G L=k.5D;1P(L){G bN=L.3M;E(L.3r==3&&!/\\S/.2L(L.4f))k.6I(L);L=bN}o k},5E:q(k){o $(k).4C.4O()},76:q(k,3b){k=$(k),3b=$(3b);G bL=3b;E(k.bM)o(k.bM(3b)&8)===8;E(k.6L&&!1g.1W.58){G e=k.6L,a=3b.6L,5X=3b.3M;E(!5X){do{3b=3b.1O}1P(!(5X=3b.3M)&&3b.1O)}E(5X&&5X.6L)o(e>a&&e<5X.6L)}1P(k=k.1O)E(k==bL)o 1u;o 1r},bK:q(k){k=$(k);G 5W=k.4P();1A.bK(5W[0],5W[1]);o k},2a:q(k,14){k=$(k);14=14==\'97\'?\'7N\':14.95();G I=k.14[14];E(!I){G 9h=1b.fF.fE(k,1k);I=9h?9h[14]:1k}E(14==\'3P\')o I?5R(I):1.0;o I==\'7M\'?1k:I},fD:q(k){o $(k).2a(\'3P\')},5S:q(k,4I){k=$(k);G 9g=k.14,1f;E(M.3f(4I)){k.14.90+=\';\'+4I;o 4I.1J(\'3P\')?k.5Q(4I.1f(/3P:\\s*(\\d?\\.?\\d*)/)[1]):k}17(G 1y 1Q 4I)E(1y==\'3P\')k.5Q(4I[1y]);1m 9g[(1y==\'97\'||1y==\'7N\')?(M.2D(9g.96)?\'7N\':\'96\'):1y]=4I[1y];o k},5Q:q(k,I){k=$(k);k.14.3P=(I==1||I===\'\')?\'\':(I<0.7G)?0:I;o k},5I:q(k){k=$(k);G 3p=$(k).2a(\'3p\');E(3p!=\'7L\'&&3p!=1k)o{2g:k.5q,3a:k.5r};G 44=k.14;G bH=44.9f;G bI=44.1v;G bJ=44.3p;44.9f=\'7j\';44.1v=\'5P\';44.3p=\'fC\';G bG=k.bE;G bF=k.bD;44.3p=bJ;44.1v=bI;44.9f=bH;o{2g:bG,3a:bF}},fB:q(k){k=$(k);G 5W=J.2a(k,\'1v\');E(5W==\'5T\'||!5W){k.9d=1u;k.14.1v=\'6K\';E(1A.9e){k.14.2i=0;k.14.2x=0}}o k},fA:q(k){k=$(k);E(k.9d){k.9d=4z;k.14.1v=k.14.2i=k.14.2x=k.14.4Q=k.14.5U=\'\'}o k},fz:q(k){k=$(k);E(k.5h)o k;k.5h=J.2a(k,\'9c\')||\'7M\';E(k.5h!==\'7j\')k.14.9c=\'7j\';o k},fy:q(k){k=$(k);E(!k.5h)o k;k.14.9c=k.5h==\'7M\'?\'\':k.5h;k.5h=1k;o k},4P:q(k){G 2J=0,2K=0;do{2J+=k.5c||0;2K+=k.5b||0;k=k.3e}1P(k);o J.57(2K,2J)},6h:q(k){G 2J=0,2K=0;do{2J+=k.5c||0;2K+=k.5b||0;k=k.3e;E(k){E(k.1a==\'by\')2d;G p=J.2a(k,\'1v\');E(p!==\'5T\')2d}}1P(k);o J.57(2K,2J)},8g:q(k){k=$(k);E(k.2a(\'1v\')==\'5P\')o;G 9b=k.6h();G 2i=9b[1];G 2x=9b[0];G 2g=k.bE;G 3a=k.bD;k.bB=2x-5R(k.14.2x||0);k.bC=2i-5R(k.14.2i||0);k.bz=k.14.2g;k.bA=k.14.3a;k.14.1v=\'5P\';k.14.2i=2i+\'3i\';k.14.2x=2x+\'3i\';k.14.2g=2g+\'3i\';k.14.3a=3a+\'3i\';o k},8d:q(k){k=$(k);E(k.2a(\'1v\')==\'6K\')o;k.14.1v=\'6K\';G 2i=5R(k.14.2i||0)-(k.bC||0);G 2x=5R(k.14.2x||0)-(k.bB||0);k.14.2i=2i+\'3i\';k.14.2x=2x+\'3i\';k.14.3a=k.bA;k.14.2g=k.bz;o k},8c:q(k){G 2J=0,2K=0;do{2J+=k.4n||0;2K+=k.4p||0;k=k.1O}1P(k);o J.57(2K,2J)},5p:q(k){E(k.3e)o $(k.3e);E(k==1b.2q)o $(k);1P((k=k.1O)&&k!=1b.2q)E(J.2a(k,\'1v\')!=\'5T\')o $(k);o $(1b.2q)},6g:q(9a){G 2J=0,2K=0;G k=9a;do{2J+=k.5c||0;2K+=k.5b||0;E(k.3e==1b.2q&&J.2a(k,\'1v\')==\'5P\')2d}1P(k=k.3e);k=9a;do{E(!1g.1W.58||k.1a==\'by\'){2J-=k.4n||0;2K-=k.4p||0}}1P(k=k.1O);o J.57(2K,2J)},a3:q(k,22){G U=M.15({bx:1u,bw:1u,bv:1u,bu:1u,5c:0,5b:0},1p[2]||{});22=$(22);G p=22.6g();k=$(k);G 5V=[0,0];G 2T=1k;E(J.2a(k,\'1v\')==\'5P\'){2T=k.5p();5V=2T.6g()}E(2T==1b.2q){5V[0]-=1b.2q.5b;5V[1]-=1b.2q.5c}E(U.bx)k.14.2x=(p[0]-5V[0]+U.5b)+\'3i\';E(U.bw)k.14.2i=(p[1]-5V[1]+U.5c)+\'3i\';E(U.bv)k.14.2g=22.5q+\'3i\';E(U.bu)k.14.3a=22.5r+\'3i\';o k}};J.1d.bt.bs=1;M.15(J.1d,{fx:J.1d.2z,fw:J.1d.br});J.3O={6l:{3A:{1j:\'6e\',bo:\'17\'},1S:{}}};E(1g.1W.58){J.1d.2a=J.1d.2a.5g(q(3j,k,14){5y(14){2r\'2x\':2r\'2i\':2r\'5U\':2r\'4Q\':E(3j(k,\'1v\')===\'5T\')o 1k;2r\'3a\':2r\'2g\':E(!J.99(k))o 1k;G 7O=bq(3j(k,14),10);E(7O!==k[\'2V\'+14.6F()])o 7O+\'3i\';G 3k;E(14===\'3a\'){3k=[\'7P-2i-2g\',\'7Q-2i\',\'7Q-4Q\',\'7P-4Q-2g\']}1m{3k=[\'7P-2x-2g\',\'7Q-2x\',\'7Q-5U\',\'7P-5U-2g\']}o 3k.3H(7O,q(2O,1y){G 98=3j(k,1y);o 98===1k?2O:2O-bq(98,10)})+\'3i\';6p:o 3j(k,14)}});J.1d.51=J.1d.51.5g(q(3j,k,1U){E(1U===\'7K\')o k.7K;o 3j(k,1U)})}1m E(1g.1W.3X){J.1d.5p=J.1d.5p.5g(q(3j,k){k=$(k);G 1v=k.2a(\'1v\');E(1v!==\'5T\')o 3j(k);k.5S({1v:\'6K\'});G I=3j(k);k.5S({1v:1v});o I});$w(\'6h 6g\').1E(q(1F){J.1d[1F]=J.1d[1F].5g(q(3j,k){k=$(k);G 1v=k.2a(\'1v\');E(1v!==\'5T\')o 3j(k);G 3e=k.5p();E(3e&&3e.2a(\'1v\')===\'fv\')3e.5S({94:1});k.5S({1v:\'6K\'});G I=3j(k);k.5S({1v:1v});o I})});J.1d.2a=q(k,14){k=$(k);14=(14==\'97\'||14==\'7N\')?\'96\':14.95();G I=k.14[14];E(!I&&k.5f)I=k.5f[14];E(14==\'3P\'){E(I=(k.2a(\'2h\')||\'\').1f(/92\\(3P=(.*)\\)/))E(I[1])o 5R(I[1])/bp;o 1.0}E(I==\'7M\'){E((14==\'2g\'||14==\'3a\')&&(k.2a(\'3p\')!=\'7L\'))o k[\'2V\'+14.6F()]+\'3i\';o 1k}o I};J.1d.5Q=q(k,I){q 93(2h){o 2h.1Y(/92\\([^\\)]*\\)/gi,\'\')}k=$(k);G 5f=k.5f;E((5f&&!5f.fu)||(!5f&&k.14.94==\'ft\'))k.14.94=1;G 2h=k.2a(\'2h\'),14=k.14;E(I==1||I===\'\'){(2h=93(2h))?14.2h=2h:14.8D(\'2h\');o k}1m E(I<0.7G)I=0;14.2h=93(2h)+\'92(3P=\'+(I*bp)+\')\';o k};J.3O={7I:{3A:{\'6e\':\'1j\',\'17\':\'bo\'},1S:{7J:q(k,1U){o k.91(1U,2)},bn:q(k,1U){G L=k.bj(1U);o L?L.I:""},2k:q(k,1U){1U=k.91(1U);o 1U?1U.2H().3B(23,-2):1k},6J:q(k,1U){o $(k).3I(1U)?1U:1k},14:q(k){o k.14.90.2e()},7K:q(k){o k.7K}}}};J.3O.6l={3A:M.15({fs:\'fr\',fq:\'fp\'},J.3O.7I.3A),1S:{3J:q(k,I){k.3J=!!I},14:q(k,I){k.14.90=I?I:\'\'}}};J.3O.8X={};$w(\'fo fn fm fl fk 7i \'+\'fj fi fh fg\').1E(q(29){J.3O.6l.3A[29.2e()]=29;J.3O.8X[29.2e()]=29});(q(v){M.15(v,{aI:v.7J,ad:v.7J,1B:v.7J,5B:v.bn,3u:v.6J,3J:v.6J,ff:v.6J,fe:v.6J,fd:v.2k,ao:v.2k,fc:v.2k,fb:v.2k,fa:v.2k,f9:v.2k,f8:v.2k,f7:v.2k,f6:v.2k,f5:v.2k,f4:v.2k,f3:v.2k,f2:v.2k,f1:v.2k,f0:v.2k,eZ:v.2k,eY:v.2k,eX:v.2k})})(J.3O.7I.1S)}1m E(1g.1W.7H&&/eW:1\\.8\\.0/.2L(5e.5d)){J.1d.5Q=q(k,I){k=$(k);k.14.3P=(I==1)?0.eV:(I===\'\')?\'\':(I<0.7G)?0:I;o k}}1m E(1g.1W.4u){J.1d.5Q=q(k,I){k=$(k);k.14.3P=(I==1||I===\'\')?\'\':(I<0.7G)?0:I;E(I==1)E(k.1a==\'bf\'&&k.2g){k.2g++;k.2g--}1m 2s{G n=1b.bm(\' \');k.5O(n);k.6I(n)}2E(e){}o k};J.1d.4P=q(k){G 2J=0,2K=0;do{2J+=k.5c||0;2K+=k.5b||0;E(k.3e==1b.2q)E(J.2a(k,\'1v\')==\'5P\')2d;k=k.3e}1P(k);o J.57(2K,2J)}}E(1g.1W.3X||1g.1W.58){J.1d.5a=q(k,18){k=$(k);E(18&&18.3s)18=18.3s();E(M.4j(18))o k.5a().3o(18);18=M.4i(18);G 1a=k.1a.2R();E(1a 1Q J.5M.4G){$A(k.3g).1E(q(L){k.6I(L)});J.7F(1a,18.4h()).1E(q(L){k.5O(L)})}1m k.4C=18.4h();18.59.1L(18).4s();o k}}E(\'bl\'1Q 1b.43(\'1T\')){J.1d.1Y=q(k,18){k=$(k);E(18&&18.3s)18=18.3s();E(M.4j(18)){k.1O.8Z(18,k);o k}18=M.4i(18);G 2T=k.1O,1a=2T.1a.2R();E(J.5M.4G[1a]){G 3M=k.6B();G 8Y=J.7F(1a,18.4h());2T.6I(k);E(3M)8Y.1E(q(L){2T.7C(L,3M)});1m 8Y.1E(q(L){2T.5O(L)})}1m k.bl=18.4h();18.59.1L(18).4s();o k}}J.57=q(l,t){G 1q=[l,t];1q.2x=l;1q.2i=t;o 1q};J.7F=q(1a,7D){G 1T=1s J(\'1T\'),t=J.5M.4G[1a];E(t){1T.4C=t[0]+7D+t[1];t[2].7E(q(){1T=1T.5D})}1m 1T.4C=7D;o $A(1T.3g)};J.5M={4R:q(k,L){k.1O.7C(L,k)},2i:q(k,L){k.7C(L,k.5D)},4Q:q(k,L){k.5O(L)},75:q(k,L){k.1O.7C(L,k.3M)},4G:{eU:[\'<4H>\',\'</4H>\',1],7z:[\'<4H><5N>\',\'</5N></4H>\',2],bb:[\'<4H><5N><7B>\',\'</7B></5N></4H>\',3],8V:[\'<4H><5N><7B><bk>\',\'</bk></7B></5N></4H>\',4],bi:[\'<2z>\',\'</2z>\',1]}};(q(){M.15(C.4G,{bd:C.4G.7z,bc:C.4G.7z,ba:C.4G.8V})}).8m(J.5M);J.1d.7y={3I:q(k,1U){1U=J.3O.8X[1U]||1U;G L=$(k).bj(1U);o L&&L.eT}};J.1d.3z={};M.15(J,J.1d);E(!1g.3U.6H&&1b.43(\'1T\').4U){1A.6G={};1A.6G.1l=1b.43(\'1T\').4U;1g.3U.6H=1u}J.15=(q(){E(1g.3U.7x)o 1g.K;G 1d={},3z=J.1d.3z;G 15=M.15(q(k){E(!k||k.7c||k.3r!=1||k==1A)o k;G 2B=M.2A(1d),1a=k.1a,1y,I;E(3z[1a])M.15(2B,3z[1a]);17(1y 1Q 2B){I=2B[1y];E(M.2w(I)&&!(1y 1Q k))k[1y]=I.4v()}k.7c=1g.3q;o k},{7v:q(){E(!1g.3U.6H){M.15(1d,J.1d);M.15(1d,J.1d.7y)}}});15.7v();o 15})();J.3I=q(k,1U){E(k.3I)o k.3I(1U);o J.1d.7y.3I(k,1U)};J.6a=q(2B){G F=1g.3U,T=J.1d.3z;E(!2B){M.15(1C,1C.1d);M.15(1C.J,1C.J.1d);M.15(J.1d.3z,{"eS":M.2A(1C.1d),"eR":M.2A(1C.J.1d),"bi":M.2A(1C.J.1d),"bh":M.2A(1C.J.1d)})}E(1p.O==2){G 1a=2B;2B=1p[1]}E(!1a)M.15(J.1d,2B||{});1m{E(M.4x(1a))1a.1E(15);1m 15(1a)}q 15(1a){1a=1a.2R();E(!J.1d.3z[1a])J.1d.3z[1a]={};M.15(J.1d.3z[1a],2B)}q 7w(2B,5L,7A){7A=7A||1r;17(G 1y 1Q 2B){G I=2B[1y];E(!M.2w(I))3G;E(!7A||!(1y 1Q 5L))5L[1y]=I.4v()}}q b8(1a){G 1N;G 8U={"eQ":"eP","bh":"eO","P":"eN","eM":"eL","eK":"eJ","eI":"eH","eG":"eF","eE":"eD","eC":"5K","eB":"5K","eA":"5K","ez":"5K","ey":"5K","ex":"5K","Q":"ew","ev":"bg","eu":"bg","A":"et","bf":"es","er":"eq","ep":"be","eo":"be","bd":"8W","bc":"8W","7z":"8W","bb":"em","ba":"b9","8V":"b9","el":"ek","ej":"ei"};E(8U[1a])1N=\'8T\'+8U[1a]+\'J\';E(1A[1N])o 1A[1N];1N=\'8T\'+1a+\'J\';E(1A[1N])o 1A[1N];1N=\'8T\'+1a.6F()+\'J\';E(1A[1N])o 1A[1N];1A[1N]={};1A[1N].1l=1b.43(1a).4U;o 1A[1N]}E(F.6H){7w(J.1d,6G.1l);7w(J.1d.7y,6G.1l,1u)}E(F.7x){17(G 8S 1Q J.1d.3z){G 1N=b8(8S);E(M.2D(1N))3G;7w(T[8S],1N.1l)}}M.15(J,J.1d);8R J.3z;E(J.15.7v)J.15.7v();J.2P={}};1b.eh={5I:q(){G 8Q={};G B=1g.1W;$w(\'2g 3a\').1E(q(d){G D=d.6F();8Q[d]=(B.4u&&!1b.2S)?5J[\'eg\'+D]:(B.58)?1b.2q[\'b7\'+D]:1b.4o[\'b7\'+D]});o 8Q},b6:q(){o C.5I().2g},b5:q(){o C.5I().3a},ef:q(){o J.57(1A.a9||1b.4o.4p||1b.2q.4p,1A.a8||1b.4o.4n||1b.2q.4n)}};G 19=2b.2p({2I:q(1t){C.1t=1t.3T();C.b4()},b3:q(){E(!1g.3U.72)o 1r;G e=C.1t;E(1g.1W.4u&&(e.1J("-2t-1B")||e.1J(":5E")))o 1r;E((/(\\[[\\w-]*?:|:3J)/).2L(C.1t))o 1r;o 1u},b4:q(){E(C.b3())o C.b2();G e=C.1t,4g=19.6C,h=19.25,c=19.6D,3y,p,m;E(19.56[e]){C.3N=19.56[e];o}C.3N=["C.3N = q(1n) {","G r = 1n, h = 19.25, c = 1r, n;"];1P(e&&3y!=e&&(/\\S/).2L(e)){3y=e;17(G i 1Q 4g){p=4g[i];E(m=e.1f(p)){C.3N.1h(M.2w(c[i])?c[i](m):1s 32(c[i]).2S(m));e=e.1Y(m[0],\'\');2d}}}C.3N.1h("o h.8E(n);\\n}");7u(C.3N.2o(\'\\n\'));19.56[C.1t]=C.3N},b2:q(){G e=C.1t,4g=19.6C,x=19.2v,3y,m;E(19.56[e]){C.2v=19.56[e];o}C.3N=[\'.//*\'];1P(e&&3y!=e&&(/\\S/).2L(e)){3y=e;17(G i 1Q 4g){E(m=e.1f(4g[i])){C.3N.1h(M.2w(x[i])?x[i](m):1s 32(x[i]).2S(m));e=e.1Y(m[0],\'\');2d}}}C.2v=C.3N.2o(\'\');19.56[C.1t]=C.2v},7p:q(1n){1n=1n||1b;E(C.2v)o 1b.8a(C.2v,1n);o C.3N(1n)},1f:q(k){C.8P=[];G e=C.1t,4g=19.6C,as=19.8J;G 3y,p,m;1P(e&&3y!==e&&(/\\S/).2L(e)){3y=e;17(G i 1Q 4g){p=4g[i];E(m=e.1f(p)){E(as[i]){C.8P.1h([i,M.2A(m)]);e=e.1Y(m[0],\'\')}1m{o C.7p(1b).1J(k)}}}}G 1f=1u,1e,2j;17(G i=0,7t;7t=C.8P[i];i++){1e=7t[0],2j=7t[1];E(!19.8J[1e](k,2j)){1f=1r;2d}}o 1f},2H:q(){o C.1t},2C:q(){o"#<19:"+C.1t.2C()+">"}});M.15(19,{56:{},2v:{4D:"//*",1G:"/*",55:"/6E-4F::*[1]",6A:\'/6E-4F::*\',1a:q(m){E(m[1]==\'*\')o\'\';o"[b1-1e()=\'"+m[1].2e()+"\' 8O b1-1e()=\'"+m[1].2R()+"\']"},1j:"[6f(20(\' \', @6e, \' \'), \' #{1} \')]",1o:"[@1o=\'#{1}\']",5F:q(m){m[1]=m[1].2e();o 1s 32("[@#{1}]").2S(m)},29:q(m){m[1]=m[1].2e();m[3]=m[5]||m[6];o 1s 32(19.2v.6t[m[2]]).2S(m)},6y:q(m){G h=19.2v.2f[m[1]];E(!h)o\'\';E(M.2w(h))o h(m);o 1s 32(19.2v.2f[m[1]]).2S(m)},6t:{\'=\':"[@#{1}=\'#{3}\']",\'!=\':"[@#{1}!=\'#{3}\']",\'^=\':"[ee-b0(@#{1}, \'#{3}\')]",\'$=\':"[5H(@#{1}, (3h-O(@#{1}) - 3h-O(\'#{3}\') + 1))=\'#{3}\']",\'*=\':"[6f(@#{1}, \'#{3}\')]",\'~=\':"[6f(20(\' \', @#{1}, \' \'), \' #{3} \')]",\'|=\':"[6f(20(\'-\', @#{1}, \'-\'), \'-#{3}-\')]"},2f:{\'3K-1G\':\'[4B(8M-4F::*)]\',\'2u-1G\':\'[4B(6E-4F::*)]\',\'6v-1G\':\'[4B(8M-4F::* 8O 6E-4F::*)]\',\'5E\':"[3x(*) = 0 8L (3x(3Y()) = 0 8O ed(3Y(), \' \\t\\r\\n\', \'\') = \'\')]",\'3J\':"[@3J]",\'3u\':"[@3u]",\'aP\':"[4B(@3u)]",\'4B\':q(m){G e=m[6],p=19.6C,x=19.2v,3y,v;G 8N=[];1P(e&&3y!=e&&(/\\S/).2L(e)){3y=e;17(G i 1Q p){E(m=e.1f(p[i])){v=M.2w(x[i])?x[i](m):1s 32(x[i]).2S(m);8N.1h("("+v.5H(1,v.O-1)+")");e=e.1Y(m[0],\'\');2d}}}o"[4B("+8N.2o(" 8L ")+")]"},\'1X-1G\':q(m){o 19.2v.2f.1X("(3x(./8M-4F::*) + 1) ",m)},\'1X-2u-1G\':q(m){o 19.2v.2f.1X("(3x(./6E-4F::*) + 1) ",m)},\'1X-2t-1B\':q(m){o 19.2v.2f.1X("1v() ",m)},\'1X-2u-2t-1B\':q(m){o 19.2v.2f.1X("(2u() + 1 - 1v()) ",m)},\'3K-2t-1B\':q(m){m[6]="1";o 19.2v.2f[\'1X-2t-1B\'](m)},\'2u-2t-1B\':q(m){m[6]="1";o 19.2v.2f[\'1X-2u-2t-1B\'](m)},\'6v-2t-1B\':q(m){G p=19.2v.2f;o p[\'3K-2t-1B\'](m)+p[\'2u-2t-1B\'](m)},1X:q(5G,m){G 42,1I=m[6],8K;E(1I==\'aS\')1I=\'2n+0\';E(1I==\'aR\')1I=\'2n+1\';E(42=1I.1f(/^(\\d+)$/))o\'[\'+5G+"= "+42[1]+\']\';E(42=1I.1f(/^(-?\\d*)?n(([+-])(\\d+))?/)){E(42[1]=="-")42[1]=-1;G a=42[1]?54(42[1]):1;G b=42[2]?54(42[2]):0;8K="[((#{5G} - #{b}) ec #{a} = 0) 8L "+"((#{5G} - #{b}) 1T #{a} >= 0)]";o 1s 32(8K).2S({5G:5G,a:a,b:b})}}}},6D:{1a:\'n = h.1a(n, r, "#{1}", c); c = 1r;\',1j:\'n = h.1j(n, r, "#{1}", c); c = 1r;\',1o:\'n = h.1o(n, r, "#{1}", c); c = 1r;\',5F:\'n = h.5F(n, r, "#{1}", c); c = 1r;\',29:q(m){m[3]=(m[5]||m[6]);o 1s 32(\'n = h.29(n, r, "#{1}", "#{3}", "#{2}", c); c = 1r;\').2S(m)},6y:q(m){E(m[6])m[6]=m[6].1Y(/"/g,\'\\\\"\');o 1s 32(\'n = h.6y(n, "#{1}", "#{6}", r, c); c = 1r;\').2S(m)},4D:\'c = "4D";\',1G:\'c = "1G";\',55:\'c = "55";\',6A:\'c = "6A";\'},6C:{6A:/^\\s*~\\s*/,1G:/^\\s*>\\s*/,55:/^\\s*\\+\\s*/,4D:/^\\s/,1a:/^\\s*(\\*|[\\w\\-]+)(\\b|$)?/,1o:/^#([\\w\\-\\*]+)(\\b|$)/,1j:/^\\.([\\w\\-\\*]+)(\\b|$)/,6y:/^:((3K|2u|1X|1X-2u|6v)(-1G|-2t-1B)|5E|3J|(en|eb)ea|4B)(\\((.*?)\\))?(\\b|$|(?=\\s|[:+~>]))/,5F:/^\\[([\\w]+)\\]/,29:/\\[((?:[\\w-]*:)?[\\w-]+)\\s*(?:([!^$*~|]?=)\\s*(([\'"])([^\\4]*?)\\4|([^\'"][^\\]]*?)))?\\]/},8J:{1a:q(k,2j){o 2j[1].2R()==k.1a.2R()},1j:q(k,2j){o J.7s(k,2j[1])},1o:q(k,2j){o k.1o===2j[1]},5F:q(k,2j){o J.3I(k,2j[1])},29:q(k,2j){G 4f=J.51(k,2j[1]);o 4f&&19.6t[2j[2]](4f,2j[5]||2j[6])}},25:{20:q(a,b){17(G i=0,L;L=b[i];i++)a.1h(L);o a},7q:q(N){G aZ=1g.3q;17(G i=0,L;L=N[i];i++)L.3L=aZ;o N},52:q(N){17(G i=0,L;L=N[i];i++)L.3L=4z;o N},1i:q(1O,4e,6u){1O.3L=1g.3q;E(4e){17(G N=1O.3g,i=N.O-1,j=1;i>=0;i--){G L=N[i];E(L.3r==1&&(!6u||L.3L))L.7r=j++}}1m{17(G i=0,j=1,N=1O.3g;L=N[i];i++)E(L.3r==1&&(!6u||L.3L))L.7r=j++}},8E:q(N){E(N.O==0)o N;G V=[],n;17(G i=0,l=N.O;i<l;i++)E(!(n=N[i]).3L){n.3L=1g.3q;V.1h(J.15(n))}o 19.25.52(V)},4D:q(N){G h=19.25;17(G i=0,V=[],L;L=N[i];i++)h.20(V,L.4a(\'*\'));o V},1G:q(N){G h=19.25;17(G i=0,V=[],L;L=N[i];i++){17(G j=0,1G;1G=L.3g[j];j++)E(1G.3r==1&&1G.1a!=\'!\')V.1h(1G)}o V},55:q(N){17(G i=0,V=[],L;L=N[i];i++){G 6B=C.6w(L);E(6B)V.1h(6B)}o V},6A:q(N){G h=19.25;17(G i=0,V=[],L;L=N[i];i++)h.20(V,J.4E(L));o V},6w:q(L){1P(L=L.3M)E(L.3r==1)o L;o 1k},6x:q(L){1P(L=L.aY)E(L.3r==1)o L;o 1k},1a:q(N,1n,1a,26){G aX=1a.2R();G V=[],h=19.25;E(N){E(26){E(26=="4D"){17(G i=0,L;L=N[i];i++)h.20(V,L.4a(1a));o V}1m N=C[26](N);E(1a=="*")o N}17(G i=0,L;L=N[i];i++)E(L.1a.2R()===aX)V.1h(L);o V}1m o 1n.4a(1a)},1o:q(N,1n,1o,26){G 31=$(1o),h=19.25;E(!31)o[];E(!N&&1n==1b)o[31];E(N){E(26){E(26==\'1G\'){17(G i=0,L;L=N[i];i++)E(31.1O==L)o[31]}1m E(26==\'4D\'){17(G i=0,L;L=N[i];i++)E(J.76(31,L))o[31]}1m E(26==\'55\'){17(G i=0,L;L=N[i];i++)E(19.25.6x(31)==L)o[31]}1m N=h[26](N)}17(G i=0,L;L=N[i];i++)E(L==31)o[31];o[]}o(31&&J.76(31,1n))?[31]:[]},1j:q(N,1n,1j,26){E(N&&26)N=C[26](N);o 19.25.aW(N,1n,1j)},aW:q(N,1n,1j){E(!N)N=19.25.4D([1n]);G aV=\' \'+1j+\' \';17(G i=0,V=[],L,6z;L=N[i];i++){6z=L.1j;E(6z.O==0)3G;E(6z==1j||(\' \'+6z+\' \').1J(aV))V.1h(L)}o V},5F:q(N,1n,29,26){E(!N)N=1n.4a("*");E(N&&26)N=C[26](N);G V=[];17(G i=0,L;L=N[i];i++)E(J.3I(L,29))V.1h(L);o V},29:q(N,1n,29,I,aU,26){E(!N)N=1n.4a("*");E(N&&26)N=C[26](N);G 2c=19.6t[aU],V=[];17(G i=0,L;L=N[i];i++){G 4f=J.51(L,29);E(4f===1k)3G;E(2c(4f,I))V.1h(L)}o V},6y:q(N,1e,I,1n,26){E(N&&26)N=C[26](N);E(!N)N=1n.4a("*");o 19.2f[1e](N,I,1n)}},2f:{\'3K-1G\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++){E(19.25.6x(L))3G;V.1h(L)}o V},\'2u-1G\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++){E(19.25.6w(L))3G;V.1h(L)}o V},\'6v-1G\':q(N,I,1n){G h=19.25;17(G i=0,V=[],L;L=N[i];i++)E(!h.6x(L)&&!h.6w(L))V.1h(L);o V},\'1X-1G\':q(N,1I,1n){o 19.2f.1X(N,1I,1n)},\'1X-2u-1G\':q(N,1I,1n){o 19.2f.1X(N,1I,1n,1u)},\'1X-2t-1B\':q(N,1I,1n){o 19.2f.1X(N,1I,1n,1r,1u)},\'1X-2u-2t-1B\':q(N,1I,1n){o 19.2f.1X(N,1I,1n,1u,1u)},\'3K-2t-1B\':q(N,1I,1n){o 19.2f.1X(N,"1",1n,1r,1u)},\'2u-2t-1B\':q(N,1I,1n){o 19.2f.1X(N,"1",1n,1u,1u)},\'6v-2t-1B\':q(N,1I,1n){G p=19.2f;o p[\'2u-2t-1B\'](p[\'3K-2t-1B\'](N,1I,1n),1I,1n)},aQ:q(a,b,aT){E(a==0)o b>0?[b]:[];o $R(1,aT).3H([],q(2O,i){E(0==(i-b)%a&&(i-b)/a>=0)2O.1h(i);o 2O})},1X:q(N,1I,1n,4e,6u){E(N.O==0)o[];E(1I==\'aS\')1I=\'2n+0\';E(1I==\'aR\')1I=\'2n+1\';G h=19.25,V=[],8H=[],m;h.7q(N);17(G i=0,L;L=N[i];i++){E(!L.1O.3L){h.1i(L.1O,4e,6u);8H.1h(L.1O)}}E(1I.1f(/^\\d+$/)){1I=54(1I);17(G i=0,L;L=N[i];i++)E(L.7r==1I)V.1h(L)}1m E(m=1I.1f(/^(-?\\d*)?n(([+-])(\\d+))?/)){E(m[1]=="-")m[1]=-1;G a=m[1]?54(m[1]):1;G b=m[2]?54(m[2]):0;G 8I=19.2f.aQ(a,b,N.O);17(G i=0,L,l=8I.O;L=N[i];i++){17(G j=0;j<l;j++)E(L.7r==8I[j])V.1h(L)}}h.52(N);h.52(8H);o V},\'5E\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++){E(L.1a==\'!\'||(L.5D&&!L.4C.1f(/^\\s*$/)))3G;V.1h(L)}o V},\'4B\':q(N,41,1n){G h=19.25,e9,m;G 8G=1s 19(41).7p(1n);h.7q(8G);17(G i=0,V=[],L;L=N[i];i++)E(!L.3L)V.1h(L);h.52(8G);o V},\'aP\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++)E(!L.3u)V.1h(L);o V},\'3u\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++)E(L.3u)V.1h(L);o V},\'3J\':q(N,I,1n){17(G i=0,V=[],L;L=N[i];i++)E(L.3J)V.1h(L);o V}},6t:{\'=\':q(2Z,v){o 2Z==v},\'!=\':q(2Z,v){o 2Z!=v},\'^=\':q(2Z,v){o 2Z.8F(v)},\'$=\':q(2Z,v){o 2Z.aO(v)},\'*=\':q(2Z,v){o 2Z.1J(v)},\'~=\':q(2Z,v){o(\' \'+2Z+\' \').1J(\' \'+v+\' \')},\'|=\':q(2Z,v){o(\'-\'+2Z.2R()+\'-\').1J(\'-\'+v.2R()+\'-\')}},49:q(1t){G 4A=[];1t.aN(/(([\\w#:.~>+()\\s-]+|\\*|\\[.*?\\])+)\\s*(,|$)/,q(m){4A.1h(m[1].3T())});o 4A},aM:q(1V,1t){G 2j=$$(1t),h=19.25;h.7q(2j);17(G i=0,V=[],k;k=1V[i];i++)E(k.3L)V.1h(k);h.52(2j);o V},5w:q(1V,1t,1i){E(M.53(1t)){1i=1t;1t=1r}o 19.aM(1V,1t||\'*\')[1i||0]},7o:q(k,4A){4A=19.49(4A.2o(\',\'));G V=[],h=19.25;17(G i=0,l=4A.O,41;i<l;i++){41=1s 19(4A[i].3T());h.20(V,41.7p(k))}o(l>1)?h.8E(V):V}});E(1g.1W.3X){M.15(19.25,{20:q(a,b){17(G i=0,L;L=b[i];i++)E(L.1a!=="!")a.1h(L);o a},52:q(N){17(G i=0,L;L=N[i];i++)L.8D(\'3L\');o N}})}q $$(){o 19.7o(1b,$A(1p))}G 1C={8y:q(1x){$(1x).8y();o 1x},aL:q(1V,U){E(3Z U!=\'Y\')U={3w:!!U};1m E(M.2D(U.3w))U.3w=1u;G 1w,I,8C=1r,4Z=U.4Z;G 7n=1V.3H({},q(1q,k){E(!k.3u&&k.1e){1w=k.1e;I=$(k).2W();E(I!=1k&&(k.1B!=\'4Z\'||(!8C&&4Z!==1r&&(!4Z||1w==4Z)&&(8C=1u)))){E(1w 1Q 1q){E(!M.4x(1q[1w]))1q[1w]=[1q[1w]];1q[1w].1h(I)}1m 1q[1w]=I}}o 1q});o U.3w?7n:M.4r(7n)}};1C.1d={6q:q(1x,U){o 1C.aL(1C.5z(1x),U)},5z:q(1x){o $A($(1x).4a(\'*\')).3H([],q(1V,1G){E(1C.J.5A[1G.1a.2e()])1V.1h(J.15(1G));o 1V})},e8:q(1x,7l,1e){1x=$(1x);G 7m=1x.4a(\'4y\');E(!7l&&!1e)o $A(7m).2M(J.15);17(G i=0,8B=[],O=7m.O;i<O;i++){G 4y=7m[i];E((7l&&4y.1B!=7l)||(1e&&4y.1e!=1e))3G;8B.1h(J.15(4y))}o 8B},8x:q(1x){1x=$(1x);1C.5z(1x).7k(\'8x\');o 1x},8w:q(1x){1x=$(1x);1C.5z(1x).7k(\'8w\');o 1x},aJ:q(1x){G 1V=$(1x).5z().5C(q(k){o\'7j\'!=k.1B&&!k.3u});G 8A=1V.5C(q(k){o k.3I(\'7i\')&&k.7i>=0}).aK(q(k){o k.7i}).3K();o 8A?8A:1V.8l(q(k){o[\'4y\',\'2z\',\'8v\'].1J(k.1a.2e())})},e7:q(1x){1x=$(1x);1x.aJ().aG();o 1x},2Q:q(1x,U){1x=$(1x),U=M.2A(U||{});G 2Y=U.3v,5B=1x.51(\'5B\')||\'\';E(5B.4O())5B=1A.7h.aI;U.3v=1x.6q(1u);E(2Y){E(M.3f(2Y))2Y=2Y.7g();M.15(U.3v,2Y)}E(1x.3I(\'1F\')&&!U.1F)U.1F=1x.1F;o 1s 1R.50(5B,U)}};1C.J={8z:q(k){$(k).8z();o k},2z:q(k){$(k).2z();o k}};1C.J.1d={6q:q(k){k=$(k);E(!k.3u&&k.1e){G I=k.2W();E(I!=4z){G 1H={};1H[k.1e]=I;o M.4r(1H)}}o\'\'},2W:q(k){k=$(k);G 1F=k.1a.2e();o 1C.J.5A[1F](k)},e6:q(k,I){k=$(k);G 1F=k.1a.2e();1C.J.5A[1F](k,I);o k},aH:q(k){$(k).I=\'\';o k},e5:q(k){o $(k).I!=\'\'},aG:q(k){k=$(k);2s{k.8z();E(k.2z&&(k.1a.2e()!=\'4y\'||![\'8q\',\'8y\',\'4Z\'].1J(k.1B)))k.2z()}2E(e){}o k},8x:q(k){k=$(k);k.e4();k.3u=1u;o k},8w:q(k){k=$(k);k.3u=1r;o k}};G e3=1C.J;G $F=1C.J.1d.2W;1C.J.5A={4y:q(k,I){5y(k.1B.2e()){2r\'ay\':2r\'ax\':o 1C.J.5A.aF(k,I);6p:o 1C.J.5A.8v(k,I)}},aF:q(k,I){E(M.2D(I))o k.3J?k.I:1k;1m k.3J=!!I},8v:q(k,I){E(M.2D(I))o k.I;1m k.I=I},2z:q(k,1i){E(M.2D(1i))o C[k.1B==\'2z-e2\'?\'aD\':\'aC\'](k);1m{G 3t,I,aE=!M.4x(1i);17(G i=0,O=k.O;i<O;i++){3t=k.U[i];I=C.7f(3t);E(aE){E(I==1i){3t.8u=1u;o}}1m 3t.8u=1i.1J(I)}}},aD:q(k){G 1i=k.e1;o 1i>=0?C.7f(k.U[1i]):1k},aC:q(k){G 1S,O=k.O;E(!O)o 1k;17(G i=0,1S=[];i<O;i++){G 3t=k.U[i];E(3t.8u)1S.1h(C.7f(3t))}o 1S},7f:q(3t){o J.15(3t).3I(\'I\')?3t.I:3t.3Y}};4Y.8s=2b.2p(aB,{2I:q($4d,k,4c,2X){$4d(2X,4c);C.k=$(k);C.4w=C.2W()},8t:q(){G I=C.2W();E(M.3f(C.4w)&&M.3f(I)?C.4w!=I:24(C.4w)!=24(I)){C.2X(C.k,I);C.4w=I}}});1C.J.aA=2b.2p(4Y.8s,{2W:q(){o 1C.J.2W(C.k)}});1C.aA=2b.2p(4Y.8s,{2W:q(){o 1C.6q(C.k)}});4Y.6r=2b.2p({2I:q(k,2X){C.k=$(k);C.2X=2X;C.4w=C.2W();E(C.k.1a.2e()==\'1x\')C.az();1m C.6s(C.k)},8r:q(){G I=C.2W();E(C.4w!=I){C.2X(C.k,I);C.4w=I}},az:q(){1C.5z(C.k).1E(C.6s,C)},6s:q(k){E(k.1B){5y(k.1B.2e()){2r\'ay\':2r\'ax\':1D.4t(k,\'e0\',C.8r.1L(C));2d;6p:1D.4t(k,\'dZ\',C.8r.1L(C));2d}}}});1C.J.6r=2b.2p(4Y.6r,{2W:q(){o 1C.J.2W(C.k)}});1C.6r=2b.2p(4Y.6r,{2W:q(){o 1C.6q(C.k)}});E(!1A.1D)G 1D={};M.15(1D,{dY:8,dX:9,dW:13,dV:27,dU:37,dT:38,dS:39,dR:40,dQ:46,dP:36,dO:35,dN:33,dM:34,dL:45,2P:{},8o:q(1c){G k;5y(1c.1B){2r\'dK\':k=1c.dJ;2d;2r\'dI\':k=1c.3s;2d;6p:o 1k}o J.15(k)}});1D.1d=(q(){G 4W;E(1g.1W.3X){G aw={0:1,1:4,2:2};4W=q(1c,4X){o 1c.8q==aw[4X]}}1m E(1g.1W.4u){4W=q(1c,4X){5y(4X){2r 0:o 1c.7e==1&&!1c.av;2r 1:o 1c.7e==1&&1c.av;6p:o 1r}}}1m{4W=q(1c,4X){o 1c.7e?(1c.7e===4X+1):(1c.8q===4X)}}o{dH:q(1c){o 4W(1c,0)},dG:q(1c){o 4W(1c,1)},dF:q(1c){o 4W(1c,2)},k:q(1c){G L=1D.15(1c).73;o J.15(L.3r==6o.au?L.1O:L)},5w:q(1c,1t){G k=1D.k(1c);E(!1t)o k;G 1V=[k].20(k.5x());o 19.5w(1V,1t,0)},4V:q(1c){o{x:1c.aq||(1c.dE+(1b.4o.4p||1b.2q.4p)),y:1c.ap||(1c.dD+(1b.4o.4n||1b.2q.4n))}},dC:q(1c){o 1D.4V(1c).x},dB:q(1c){o 1D.4V(1c).y},8p:q(1c){1D.15(1c);1c.ar();1c.at();1c.dA=1u}}})();1D.15=(q(){G 2B=M.4b(1D.1d).3H({},q(m,1e){m[1e]=1D.1d[1e].4v();o m});E(1g.1W.3X){M.15(2B,{at:q(){C.dz=1u},ar:q(){C.7d=1r},2C:q(){o"[Y 1D]"}});o q(1c){E(!1c)o 1r;E(1c.7c)o 1c;1c.7c=1g.3q;G 4V=1D.4V(1c);M.15(1c,{73:1c.dy,8o:1D.8o(1c),aq:4V.x,ap:4V.y});o M.15(1c,2B)}}1m{1D.1l=1D.1l||1b.6n("aj").4U;M.15(1D.1l,2B);o 1g.K}})();M.15(1D,(q(){G 2P=1D.2P;q 8k(k){E(k.8n)o k.8n[0];1p.5v.1o=1p.5v.1o||1;o k.8n=[++1p.5v.1o]}q 8j(1z){E(1z&&1z.1J(\':\'))o"ai";o 1z}q 79(1o){o 2P[1o]=2P[1o]||{}}q 7a(1o,1z){G c=79(1o);o c[1z]=c[1z]||[]}q am(k,1z,2c){G 1o=8k(k);G c=7a(1o,1z);E(c.5u("2c").1J(2c))o 1r;G 1K=q(1c){E(!1D||!1D.15||(1c.1z&&1c.1z!=1z))o 1r;1D.15(1c);2c.8m(k,1c)};1K.2c=2c;c.1h(1K);o 1K}q 8i(1o,1z,2c){G c=7a(1o,1z);o c.8l(q(1K){o 1K.2c==2c})}q ak(1o,1z,2c){G c=79(1o);E(!c[1z])o 1r;c[1z]=c[1z].6b(8i(1o,1z,2c))}q an(){17(G 1o 1Q 2P)17(G 1z 1Q 2P[1o])2P[1o][1z]=1k}E(1A.7b){1A.7b("ao",an)}o{4t:q(k,1z,2c){k=$(k);G 1e=8j(1z);G 1K=am(k,1z,2c);E(!1K)o k;E(k.78){k.78(1e,1K,1r)}1m{k.7b("5t"+1e,1K)}o k},4T:q(k,1z,2c){k=$(k);G 1o=8k(k),1e=8j(1z);E(!2c&&1z){7a(1o,1z).1E(q(1K){k.4T(1z,1K.2c)});o k}1m E(!1z){M.4b(79(1o)).1E(q(1z){k.4T(1z)});o k}G 1K=8i(1o,1z,2c);E(!1K)o k;E(k.al){k.al(1e,1K,1r)}1m{k.dx("5t"+1e,1K)}ak(1o,1z,2c);o k},5s:q(k,1z,2O){k=$(k);E(k==1b&&1b.6n&&!k.ah)k=1b.4o;G 1c;E(1b.6n){1c=1b.6n("aj");1c.dw("ai",1u,1u)}1m{1c=1b.dv();1c.ag="du"}1c.1z=1z;1c.2O=2O||{};E(1b.6n){k.ah(1c)}1m{k.dt(1c.ag,1c)}o 1D.15(1c)}}})());M.15(1D,1D.1d);J.6a({5s:1D.5s,4t:1D.4t,4T:1D.4T});M.15(1b,{5s:J.1d.5s.4v(),4t:J.1d.4t.4v(),4T:J.1d.4T.4v(),6m:1r});(q(){G 3W;q 6k(){E(1b.6m)o;E(3W)1A.af(3W);1b.5s("ds:6m");1b.6m=1u}E(1b.78){E(1g.1W.4u){3W=1A.ae(q(){E(/6m|ab/.2L(1b.2N))6k()},0);1D.4t(1A,"dr",6k)}1m{1b.78("dq",6k,1r)}}1m{1b.6l("<4S 1o=ac 4s ad=//:><\\/4S>");$("ac").77=q(){E(C.2N=="ab"){C.77=1k;6k()}}}})();3V.4r=M.4r;G dp={3p:J.aa};J.1d.dn=J.1d.76;G dm={dl:q(k,18){o J.3o(k,{4R:18})},dk:q(k,18){o J.3o(k,{2i:18})},dj:q(k,18){o J.3o(k,{4Q:18})},di:q(k,18){o J.3o(k,{75:18})}};G $3G=1s dh(\'"4q $3G" dg df, de "o" dd\');G 8f={a7:1r,8e:q(){C.a5=1A.a9||1b.4o.4p||1b.2q.4p||0;C.a4=1A.a8||1b.4o.4n||1b.2q.4n||0},dc:q(k,x,y){E(C.a7)o C.a6(k,x,y);C.6i=x;C.6j=y;C.2V=J.4P(k);o(y>=C.2V[1]&&y<C.2V[1]+k.5r&&x>=C.2V[0]&&x<C.2V[0]+k.5q)},a6:q(k,x,y){G 8h=J.8c(k);C.6i=x+8h[0]-C.a5;C.6j=y+8h[1]-C.a4;C.2V=J.4P(k);o(C.6j>=C.2V[1]&&C.6j<C.2V[1]+k.5r&&C.6i>=C.2V[0]&&C.6i<C.2V[0]+k.5q)},db:q(74,k){E(!74)o 0;E(74==\'da\')o((C.2V[1]+k.5r)-C.6j)/k.5r;E(74==\'d9\')o((C.2V[0]+k.5q)-C.6i)/k.5q},4P:J.1d.4P,6h:J.1d.6h,8g:q(k){8f.8e();o J.8g(k)},8d:q(k){8f.8e();o J.8d(k)},d8:J.1d.8c,3e:J.1d.5p,d7:J.1d.6g,2A:q(22,73,U){U=U||{};o J.a3(73,22,U)}};E(!1b.70)1b.70=q(a2){q 8b(1e){o 1e.4O()?1k:"[6f(20(\' \', @6e, \' \'), \' "+1e+" \')]"}a2.70=1g.3U.72?q(k,1j){1j=1j.2H().3T();G 89=/\\s/.2L(1j)?$w(1j).2M(8b).2o(\'\'):8b(1j);o 89?1b.8a(\'.//*\'+89,k):[]}:q(k,1j){1j=1j.2H().3T();G 1V=[],6d=(/\\s/.2L(1j)?$w(1j):1k);E(!6d&&!1j)o 1V;G N=$(k).4a(\'*\');1j=\' \'+1j+\' \';17(G i=0,1G,cn;1G=N[i];i++){E(1G.1j&&(cn=\' \'+1G.1j+\' \')&&(cn.1J(1j)||(6d&&6d.88(q(1e){o!1e.2H().4O()&&cn.1J(\' \'+1e+\' \')}))))1V.1h(J.15(1G))}o 1V};o q(1j,71){o $(71||1b.2q).70(1j)}}(J.1d);J.6Z=2b.2p();J.6Z.1l={2I:q(k){C.k=$(k)},48:q(W){C.k.1j.49(/\\s+/).2z(q(1e){o 1e.O>0}).48(W)},6c:q(1j){C.k.1j=1j},d6:q(87){E(C.1J(87))o;C.6c($A(C).20(87).2o(\' \'))},a1:q(86){E(!C.1J(86))o;C.6c($A(C).6b(86).2o(\' \'))},2H:q(){o $A(C).2o(\' \')}};M.15(J.6Z.1l,2G);J.6a();',62,1095,'||||||||||||||||||||element||||return||function||||||||||||this||if||var||value|Element||node|Object|nodes|length||||||options|results|iterator||object||||||style|extend||for|content|Selector|tagName|document|event|Methods|name|match|Prototype|push|index|className|null|prototype|else|root|id|arguments|result|false|new|expression|true|position|key|form|property|eventName|window|type|Form|Event|each|method|child|pair|formula|include|wrapper|bind|context|klass|parentNode|while|in|Ajax|values|div|attribute|elements|Browser|nth|replace|transport|concat|args|source||String|handlers|combinator||pattern|attr|getStyle|Class|handler|break|toLowerCase|pseudos|width|filter|top|matches|_getEv|attributes|Array||join|create|body|case|try|of|last|xpath|isFunction|left|response|select|clone|methods|inspect|isUndefined|catch|array|Enumerable|toString|initialize|valueT|valueL|test|map|readyState|memo|cache|request|toUpperCase|evaluate|parent|url|offset|getValue|callback|params|nv||targetNode|Template||||||||height|ancestor|responseText|iterable|offsetParent|isString|childNodes|string|px|proceed|properties|json|gsub|__method|insert|display|emptyFunction|nodeType|toElement|opt|disabled|parameters|hash|count|le|ByTag|names|slice|container|toJSON|toArray|replacement|continue|inject|hasAttribute|checked|first|_countedByPrototype|nextSibling|matcher|_attributeTranslations|opacity|insertions|apply|onComplete|strip|BrowserFeatures|Hash|timer|IE|text|typeof||selector|mm|createElement|els|||indexOf|_each|split|getElementsByTagName|keys|frequency|super|reverse|nodeValue|ps|stripScripts|toHTML|isElement|RegExp|start|responder|scrollTop|documentElement|scrollLeft|throw|toQueryString|defer|observe|WebKit|methodize|lastValue|isArray|input|undefined|expressions|not|innerHTML|descendant|nextSiblings|sibling|tags|table|styles|status|_object|toPaddedString|number|parts|blank|cumulativeOffset|bottom|before|script|stopObserving|__proto__|pointer|isButton|code|Abstract|submit|Request|readAttribute|unmark|isNumber|Number|adjacent|_cache|_returnOffset|Opera|evalScripts|update|offsetLeft|offsetTop|userAgent|navigator|currentStyle|wrap|_overflow|shift|decay|insertion|success|dispatchException|headers|end|getOffsetParent|offsetWidth|offsetHeight|fire|on|pluck|callee|findElement|ancestors|switch|getElements|Serializers|action|findAll|firstChild|empty|attrPresence|fragment|substring|getDimensions|self|Heading|destination|_insertionTranslations|tbody|appendChild|absolute|setOpacity|parseFloat|setStyle|static|right|delta|pos|nextAncestor|previousSiblings|receiver|evalJSON|getHeader|interpret|Responders|extras|exclusive|item|template|str|truncation|addMethods|without|set|classNames|class|contains|viewportOffset|positionedOffset|xcomp|ycomp|fireContentLoadedEvent|write|loaded|createEvent|Node|default|serialize|EventObserver|registerCallback|operators|ofType|only|nextElementSibling|previousElementSibling|pseudo|nodeClassName|laterSibling|next|patterns|criteria|following|capitalize|HTMLElement|ElementExtensions|removeChild|_flag|relative|sourceIndex|writeAttribute|onTimerEvent|getStatus|xml|state|contentType|post|_|toObject|responders|fillWith|ctx|expr|ClassNames|getElementsByClassName|parentElement|XPath|target|mode|after|descendantOf|onreadystatechange|addEventListener|getCacheForID|getWrappersForEventName|attachEvent|_extendedByPrototype|returnValue|which|optionValue|toQueryParams|location|tabIndex|hidden|invoke|typeName|inputs|data|findChildElements|findElements|mark|nodeIndex|hasClassName|token|eval|refresh|copy|SpecificElementExtensions|Simulated|TBODY|onlyIfAbsent|tr|insertBefore|html|times|_getContentFromAnonymousElement|00001|Gecko|read|_getAttr|title|none|auto|cssFloat|dim|border|padding|elementClassName|recursivelyCollect|curry|isSameOrigin|application|headerJSON|dispatch|port|asynchronous|onCreate|detect|escapeHTML|charAt|ScriptFragment|currentlyExecuting|classNameToRemove|classNameToAdd|all|cond|_getElementsByXPath|iter|cumulativeScrollOffset|relativize|prepare|Position|absolutize|offsetcache|findWrapper|getDOMEventName|getEventID|find|call|_prototypeEventID|relatedTarget|stop|button|onElementEvent|TimedObserver|execute|selected|textarea|enable|disable|reset|focus|firstByIndex|matchingInputs|submitted|removeAttribute|unique|startsWith|exclusions|indexed|indices|assertions|predicate|and|preceding|exclusion|or|tokens|dimensions|delete|tag|HTML|trans|TD|TableSection|has|fragments|replaceChild|cssText|getAttribute|alpha|stripAlpha|zoom|camelize|styleFloat|float|val|visible|forElement|offsets|overflow|_madePositioned|opera|visibility|elementStyle|css|range|query|updater|delay|Base|failure|Content|decodeURIComponent|getAllResponseHeaders|getResponseHeader|statusText|Response|Complete|exception|unfilterJSON|domain|protocol|evalJS|_complete|respondToReadyState|encoding|Version|onStateChange|get|isHash|activeRequestCount|succ|toTemplateReplacements|toQueryPair|lastIndexOf|_reverse|collect|falses|trues|found|slices|prepareReplacement|escapedString|character|camelized|len|Function|_methodized|superclass|subclass|remove|instanceMethods|clonePosition|deltaY|deltaX|withinIncludingScrolloffsets|includeScrollOffsets|pageYOffset|pageXOffset|toggle|complete|__onDOMContentLoaded|src|setInterval|clearInterval|eventType|dispatchEvent|dataavailable|HTMLEvents|destroyWrapper|removeEventListener|createWrapper|destroyCache|onunload|pageY|pageX|preventDefault||stopPropagation|TEXT_NODE|metaKey|buttonMap|radio|checkbox|registerFormCallbacks|Observer|PeriodicalExecuter|selectMany|selectOne|single|inputSelector|activate|clear|href|findFirstElement|sortBy|serializeElements|matchElements|scan|endsWith|enabled|getIndices|odd|even|total|operator|needle|byClassName|uTagName|previousSibling|_true|with|local|compileXPathMatcher|shouldUseXPath|compileMatcher|getHeight|getWidth|client|findDOMClass|TableCell|TH|TR|TFOOT|THEAD|TableCol|IMG|Mod|TEXTAREA|SELECT|getAttributeNode|td|outerHTML|createTextNode|_getAttrNode|htmlFor|100|parseInt|immediateDescendants|counter|identify|setHeight|setWidth|setTop|setLeft|BODY|_originalWidth|_originalHeight|_originalLeft|_originalTop|clientHeight|clientWidth|originalHeight|originalWidth|originalVisibility|originalPosition|originalDisplay|scrollTo|originalAncestor|compareDocumentPosition|nextNode|addClassName|removeClassName|setAttribute|descendants|firstDescendant|show|hide|ELEMENT_NODE|Updater|lastText|updateComplete|updateContent|sanitizeJSON|force|_getResponseJSON|escape|JSON|_getHeaderJSON|getStatusText|responseXML|Events|onException|evalResponse|interpolate|requestHeaders|2005|overrideMimeType|XMLHttpRequest|setRequestHeaders|KHTML|Safari|getTransport|register|XMLHTTP|ActiveXObject||these|Try|ObjectRange|from|encodeURIComponent|radix|arrayLength|forEach|size|uniq|sorted|inline|flatten|any|collections|eachSlice|Pattern|exec|comp|lt|amp|unescapeHTML|isJSON|sanitize|JSONFilter|sub|useDoubleQuotes|charCodeAt|specialChar|separator|stripTags|extractScripts|matchOne|scriptTag|matchAll|img|1000|lambda|timeout|argumentNames|instanceof|valueOf|subclasses|MobileSafari|add|page|realOffset|horizontal|vertical|overlap|within|instead|use|deprecated|is|Error|After|Bottom|Top|Before|Insertion|childOf||Toggle|DOMContentLoaded|load|dom|fireEvent|ondataavailable|createEventObject|initEvent|detachEvent|srcElement|cancelBubble|stopped|pointerY|pointerX|clientY|clientX|isRightClick|isMiddleClick|isLeftClick|mouseout|fromElement|mouseover|KEY_INSERT|KEY_PAGEDOWN|KEY_PAGEUP|KEY_END|KEY_HOME|KEY_DELETE|KEY_DOWN|KEY_RIGHT|KEY_UP|KEY_LEFT|KEY_ESC|KEY_RETURN|KEY_TAB|KEY_BACKSPACE|change|click|selectedIndex|one|Field|blur|present|setValue|focusFirstElement|getInputs|selectorType|abled|dis|mod|translate|starts|getScrollOffsets|inner|viewport|IFrame|IFRAME|FrameSet|FRAMESET|TableRow||COLGROUP|COL|TableCaption|CAPTION|Image|Anchor|DEL|INS|Quote|H6|H5|H4|H3|H2|H1|Directory|DIR|DList|DL|OList|OL|UList|UL|FieldSet|FIELDSET|Paragraph|TextArea|OptGroup|OPTGROUP|INPUT|FORM|specified|TABLE|999999|rv|onchange|onselect|onreset|onsubmit|onkeyup|onkeydown|onkeypress|onblur|onfocus|onmouseout|onmousemove|onmouseover|onmouseup|onmousedown|ondblclick|onclick|onload|multiple|readonly|longDesc|readOnly|maxLength|encType|accessKey|dateTime|vAlign|rowSpan|colSpan|cellSpacing|cellspacing|cellPadding|cellpadding|normal|hasLayout|fixed|childElements|getElementsBySelector|undoClipping|makeClipping|undoPositioned|makePositioned|block|getOpacity|getComputedStyle|defaultView|cleanWhitespace|toggleClassName|anonymous_element_|previous|down|up|siblings|createContextualFragment|selectNode|createRange|ownerDocument|cloneNode|NOTATION_NODE|DOCUMENT_FRAGMENT_NODE|DOCUMENT_TYPE_NODE|DOCUMENT_NODE|COMMENT_NODE|PROCESSING_INSTRUCTION_NODE|ENTITY_NODE|ENTITY_REFERENCE_NODE|CDATA_SECTION_NODE|ATTRIBUTE_NODE|snapshotItem|snapshotLength|ORDERED_NODE_SNAPSHOT_TYPE|XPathResult|getElementById|clearTimeout|PeriodicalUpdater|getAllHeaders|responseJSON|Interactive|Loaded|Loading|Uninitialized|https|ecma|java||Failure|Success|300|200|setRequestHeader|close|Connection|charset|javascript|Accept||With|Requested|send|postBody|open|Konqueror|_method|UTF|urlencoded|www|unregister|Microsoft|Msxml2|merge|unset|Math|floor|ceil|round|abs|isFinite|toColorPart|isNaN|intersect|reduce|compact|NodeList|some|every|entries|member|pop|zip|sort|reject|partition|min|max|inGroupsOf|grep|parseQuery|formed|Badly|SyntaxError|Eaeflnr|u00|x1f|x00|dasherize|underscore|fromCharCode|im|truncate|finally|getUTCSeconds|getUTCMinutes|getUTCHours|getUTCDate|getUTCMonth|getUTCFullYear|Date|01|setTimeout|bindAsEventListener|splice|boolean|unknown|RangeError|constructor|secure|Mobile|Apple|AppleWebKit'.split('|'),0,{})) \ No newline at end of file
diff --git a/tools/qtestlib/chart/benchmark_template.html b/tools/qtestlib/chart/benchmark_template.html
new file mode 100644
index 0000000..a7e48be
--- /dev/null
+++ b/tools/qtestlib/chart/benchmark_template.html
@@ -0,0 +1,202 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+ <title>Title</title>
+ <! Javascript Here>
+
+ <script type="text/javascript">
+
+function offsetLabels(labels, offset)
+{
+ var copy = new Array();
+ for (key in labels) {
+ copy[key] = new Array(labels[key][0] + 0.25, labels[key][1]);
+ }
+ return copy;
+}
+
+function createLogDataSet(inDataSet)
+{
+ var logDataSet = {};
+ logDataSet.label = inDataSet.label;
+ logDataSet.data = [];
+
+ if (!inDataSet.data)
+ return logDataSet;
+
+ var length = inDataSet.data.length;
+
+ for (var i = 0; i < length; i++) {
+ logDataSet.data[i] = [];
+ logDataSet.data[i][0] = inDataSet.data[i][0];
+ logDataSet.data[i][1] = Math.log(inDataSet.data[i][1]);
+ }
+ return logDataSet;
+}
+
+
+function createLogData(inData)
+{
+ var logData = [];
+
+ // foreach data set;
+ var length = inData.length;
+ for (var i = 0; i < length; ++i) {
+ logData[i] = createLogDataSet(inData[i]);
+ }
+ return logData;
+}
+
+function createChart() {
+// alert("create chart" + this.chartId)
+
+ var dataSet;
+
+ if (this.useLinearScale)
+ dataSet = this.selectedDataset;
+ else
+ dataSet = createLogData(this.selectedDataset);
+
+ if (this.useLineChart) {
+ var f = Flotr.draw($(this.chartId),
+ dataSet,
+ { legend:{ backgroundColor: '#D2E8FF' }
+ , xaxis: { ticks: this.labels, noTicks : 10 }
+ , mouse: {
+ track: true,
+ lineColor: 'purple',
+ sensibility: 1,
+ trackDecimals: 2,
+ trackFormatter: function(obj){ return 'x = ' + obj.x +', y = ' + obj.y; }
+ }
+ });
+
+ } else {
+ var f = Flotr.draw($(this.chartId),
+ dataSet,
+ { legend:{ backgroundColor: '#D2E8FF'}
+ , bars: { show: true, lineWidth: 1, barWidth: this.barWidth }
+ , xaxis: { ticks: offsetLabels(this.labels, chartOptions.tickOffset), noTicks : 10 }
+ });
+ }
+}
+
+function checkform()
+{
+// alert("check form " + this.form.id + " " + this.chartId);
+ var field = this.form.list
+
+ // Apparently list of lenght one is not a list...
+ // Display the entire chart if there is only one data series.
+ if (!field.length) {
+ this.createChart();
+ return;
+ }
+
+ this.selectedDataset = [];
+ var data = [];
+ var index = 0;
+
+ for (i = 0; i < field.length; i++) {
+ if (field[i].checked == true) {
+ this.selectedDataset[index++] = this.dataset[i];
+ } else {
+ this.selectedDataset[index++] = [];
+ }
+ }
+ this.createChart();
+}
+
+function createElement(nodeName, name) {
+ var node;
+ try {
+ node = document.createElement("<"+nodeName+" name="+name+">");
+ } catch (e) {
+ node = document.createElement(nodeName);
+ node.name = name;
+ }
+ return node;
+}
+
+function createFormSelector(form, value, text, type)
+{
+ var selector = createElement('input', 'list');
+ selector.type = type;
+ selector.defaultChecked = true;
+ selector.value = value;
+
+ form.appendChild(selector);
+ form.appendChild(document.createTextNode(text));
+ form.appendChild(document.createElement("BR"));
+}
+
+function createCheckBox(form, value, text)
+{
+ createFormSelector(form, value, text, "checkbox");
+}
+
+function createRadioButton(form, value, text)
+{
+ createFormSelector(form, value, text, "radio");
+}
+
+function buildSeriesSelector(form, chartOptions)
+{
+// alert("form" + form.id + " " + chartOptions.chartId);
+ var series = chartOptions.seriesLabels;
+ form.onclick = function() { /*alert("fn " + chartOptions.chartId);*/ chartOptions.checkform() };
+ for (s = 0; s < series.length; ++s) {
+ createCheckBox(form, s, series[s]);
+ }
+}
+
+function buildChartTypeSelector()
+{
+ createRadioButton(this.chartTypeForm, 0, "Bar Chart");
+ createRadioButton(this.chartTypeForm, 1, "Line Chart");
+
+ var field = this.chartTypeForm.list;
+ if (this.useLineChart)
+ field[1].checked = true;
+ else
+ field[0].checked = true;
+
+ var chartOptions = this;
+ this.chartTypeForm.onclick = function() {
+ var field = chartOptions.chartTypeForm.list;
+
+ chartOptions.useLineChart = (field[1].checked == true);
+ chartOptions.checkform();
+ };
+}
+
+function buildScaleSelector()
+{
+ createRadioButton(this.scaleForm, 0, "Linear Scale");
+ createRadioButton(this.scaleForm, 1, "Logarithmic Scale");
+
+ var field = this.scaleForm.list;
+ field[0].checked = true;
+ field[1].checked = false;
+
+ var chartOptions = this;
+ this.scaleForm.onclick = function() {
+ var field = chartOptions.scaleForm.list;
+
+ chartOptions.useLinearScale = (field[0].checked == true);
+ chartOptions.checkform();
+ };
+}
+
+
+ </script>
+ </head>
+ <body>
+ <h2>
+ <! Title Here>
+ </h2>
+ <! Description Here>
+ <! Chart Here>
+ </body>
+</html>
diff --git a/tools/qtestlib/chart/chart.pro b/tools/qtestlib/chart/chart.pro
new file mode 100644
index 0000000..7328e5d
--- /dev/null
+++ b/tools/qtestlib/chart/chart.pro
@@ -0,0 +1,16 @@
+HEADERS += $$PWD/database.h $$PWD/reportgenerator.h
+SOURCES += $$PWD/database.cpp $$PWD/reportgenerator.cpp
+SOURCES += main.cpp
+RESOURCES = $$PWD/chart.qrc
+
+QT += sql xml
+CONFIG += console
+CONFIG -= app_bundle
+
+
+TEMPLATE = app
+DEPENDPATH += .
+INCLUDEPATH += .
+TARGET = chart
+
+
diff --git a/tools/qtestlib/chart/chart.qrc b/tools/qtestlib/chart/chart.qrc
new file mode 100644
index 0000000..90f782e
--- /dev/null
+++ b/tools/qtestlib/chart/chart.qrc
@@ -0,0 +1,9 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+ <file>chart_template.html</file>
+ <file>benchmark_template.html</file>
+ <file>3rdparty/excanvas.js</file>
+ <file>3rdparty/flotr.js</file>
+ <file>3rdparty/prototype.js</file>
+ </qresource>
+ </RCC> \ No newline at end of file
diff --git a/tools/qtestlib/chart/chart_template.html b/tools/qtestlib/chart/chart_template.html
new file mode 100644
index 0000000..0a4b81a
--- /dev/null
+++ b/tools/qtestlib/chart/chart_template.html
@@ -0,0 +1,110 @@
+ <div>
+ <h3>
+ <! Test Name Here>
+ </h3>
+ <div id=
+ <! Chart ID Here>
+ style="width:900px;height:350px;"></div>
+
+ <table cellspacing = "10"><tr>
+
+ <td valign = "top">
+ <form id=
+ <! Form ID Here>
+ <b> Data series </b><br>
+ </form>
+ </td>
+
+ <td valign = "top">
+ <form id=
+ <! ChartTypeForm ID Here>
+ <b> Chart Type </b><br>
+ </form>
+ </td>
+
+ <td valign = "top">
+ <form id=
+ <! ScaleForm ID Here>
+ <b> Scale </b><br>
+ </form>
+ </td>
+
+ </tr></table>
+
+ </div>
+ <script type="text/javascript">
+ var chartId =
+ <! Chart ID Here>
+ ;
+
+ var chartType =
+ <! Chart Type Here>
+ ;
+
+ var seriesLabels =
+ <! Series Labels Here>
+
+ var dataset = [];
+ <! Data Goes Here>
+
+ var labels = [
+ <! Labels Go Here>
+ ];
+
+ var colors = new Hash({
+ <! ColorScheme Here>
+ });
+
+ var shouldFill =
+ <! Fill Setting Here>
+ ;
+
+ var form = document.getElementById(
+ <! Form ID Here>
+ );
+
+ var chartTypeForm = document.getElementById(
+ <! ChartTypeForm ID Here>
+ );
+
+ var scaleForm = document.getElementById(
+ <! ScaleForm ID Here>
+ );
+
+
+
+ var chartOptions = new Object();
+ chartOptions.chartId = chartId;
+ chartOptions.chartType = chartType;
+ chartOptions.dataset = dataset;
+ chartOptions.colors = colors;
+ chartOptions.shouldFill = shouldFill;
+ chartOptions.labels = labels;
+ chartOptions.seriesLabels = seriesLabels;
+ chartOptions.useLineChart = true;
+ chartOptions.useLinearScale = true;
+ chartOptions.createChart = createChart;
+
+ chartOptions.ticks = labels;
+ chartOptions.barWidth = 0.5;
+ chartOptions.tickOffset = 0.25;
+
+ chartOptions.useLineChart =
+ <! Use Line Chart Here>
+
+ chartOptions.chartTypeForm = chartTypeForm;
+ chartOptions.buildChartTypeSelector = buildChartTypeSelector;
+ chartOptions.buildChartTypeSelector();
+
+ chartOptions.scaleForm = scaleForm;
+ chartOptions.buildScaleSelector = buildScaleSelector;
+ chartOptions.buildScaleSelector();
+
+ chartOptions.selectedDataset = dataset;
+ chartOptions.checkform = checkform;
+ chartOptions.form = form;
+ chartOptions.buildSeriesSelector = buildSeriesSelector;
+ chartOptions.buildSeriesSelector(form, chartOptions);
+ chartOptions.checkform();
+ </script>
+
diff --git a/tools/qtestlib/chart/database.cpp b/tools/qtestlib/chart/database.cpp
new file mode 100644
index 0000000..ba0a31a
--- /dev/null
+++ b/tools/qtestlib/chart/database.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "database.h"
+#include <QtGui>
+#include <QtXml>
+
+// Database schema definition and open/create functions
+
+QString resultsTable = QString("(TestName varchar, TestCaseName varchar, Series varchar, Idx varchar, ") +
+ QString("Result varchar, ChartType varchar, Title varchar, ChartWidth varchar, ") +
+ QString("ChartHeight varchar, TestTitle varchar, QtVersion varchar, Iterations varchar") +
+ QString(")");
+
+void execQuery(QSqlQuery query, bool warnOnFail)
+{
+ bool ok = query.exec();
+ if (!ok && warnOnFail) {
+ qDebug() << "FAIL:" << query.lastQuery() << query.lastError().text();
+ }
+}
+
+void execQuery(const QString &spec, bool warnOnFail)
+{
+ QSqlQuery query;
+ query.prepare(spec);
+ execQuery(query, warnOnFail);
+}
+
+QSqlDatabase openDataBase(const QString &databaseFile)
+{
+// qDebug() << "open data base";
+ QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
+ db.setDatabaseName(databaseFile);
+ bool ok = db.open();
+ if (!ok)
+ qDebug() << "FAIL: could not open database";
+ return db;
+}
+
+QSqlDatabase createDataBase(const QString &databaseFile)
+{
+// qDebug() << "create data base";
+ QSqlDatabase db = openDataBase(databaseFile);
+
+ execQuery("DROP TABLE Results", false);
+ execQuery("CREATE TABLE Results " + resultsTable);
+
+ return db;
+}
+
+struct Tag
+{
+ Tag(QString key, QString value)
+ : key(key.trimmed()), value(value.trimmed())
+ {
+
+ }
+
+ QString key;
+ QString value;
+};
+
+QList<Tag> parseTag(const QString &tag)
+{
+ // Format: key1=value ; key2=value
+ // key1=value key2=value
+ // value--value
+
+ QList<Tag> keyValues;
+
+ QString keyValuePairSeparator("");
+ if (tag.contains(";"))
+ keyValuePairSeparator = ';';
+ if (tag.contains("--"))
+ keyValuePairSeparator = "--";
+
+ foreach (QString keyValue, tag.split(keyValuePairSeparator)) {
+ if (keyValue.contains("=")) {
+ QStringList parts = keyValue.split("=");
+ keyValues.append(Tag(parts.at(0), parts.at(1)));
+ } else {
+ keyValues.append(Tag(QString(), keyValue)); // no key, just a value.
+ }
+ }
+
+ return keyValues;
+}
+
+void loadXml(const QStringList &fileNames)
+{
+ foreach(const QString &fileName, fileNames) {
+ QFileInfo fi( fileName );
+ loadXml(fileName, fi.fileName());
+ }
+}
+
+void loadXml(const QString &fileName, const QString &context)
+{
+ QFile f(fileName);
+ f.open(QIODevice::ReadOnly);
+ loadXml(f.readAll(), context);
+}
+
+void loadXml(const QByteArray &xml, const QString& context)
+{
+ QDomDocument doc;
+
+ int line;
+ int col;
+ QString errorMsg;
+ if (doc.setContent(xml, &errorMsg, &line, &col) == false) {
+ qDebug() << "dom setContent failed" << line << col << errorMsg;
+ }
+
+ // Grab "Value" from <Environment><QtVersion>Value</QtVersion></Environment>
+ QString qtVersion = doc.elementsByTagName("Environment").at(0).toElement().elementsByTagName("QtVersion")
+ .at(0).toElement().childNodes().at(0).nodeValue();
+ QString testCase = doc.elementsByTagName("TestCase").at(0).toElement().attributeNode("name").value();
+
+// qDebug() << "qt version" << qtVersion;
+// qDebug() << "test case" << testCase;
+
+ DataBaseWriter writer;
+ writer.testName = testCase; // testCaseName and testName is mixed up in the database writer class
+ writer.qtVersion = qtVersion;
+
+ QDomNodeList testFunctions = doc.elementsByTagName("TestFunction");
+ for (int i = 0; i < testFunctions.count(); ++i) {
+ QDomElement function = testFunctions.at(i).toElement();
+ QString functionName = function.attributeNode("name").value();
+ writer.testCaseName = functionName; // testCaseName and testName is mixed up in the database writer class
+
+// qDebug() << "fn" << functionName;
+
+ QDomNodeList results = function.elementsByTagName("BenchmarkResult");
+ for (int j = 0; j < results.count(); ++j) {
+ QDomElement result = results.at(j).toElement();
+ QString tag = result.attributeNode("tag").value();
+
+ Q_UNUSED(context);
+// if (!context.isEmpty())
+// tag += QString(" (%1)").arg(context);
+
+ QString series;
+ QString index;
+
+ // By convention, "--" separates series and indexes in tags.
+ if (tag.contains("--")) {
+ QStringList parts = tag.split("--");
+ series = parts.at(0);
+ index = parts.at(1);
+ } else {
+ series = tag;
+ }
+
+ QString resultString = result.attributeNode("value").value();
+ QString iterationCount = result.attributeNode("iterations").value();
+ double resultNumber = resultString.toDouble() / iterationCount.toDouble();
+ writer.addResult(series, index, QString::number(resultNumber), iterationCount);
+// qDebug() << "result" << series << index << tag << resultString << iterationCount;
+ }
+ }
+}
+
+void displayTable(const QString &table)
+{
+ QSqlTableModel *model = new QSqlTableModel();
+ model->setTable(table);
+ model->select();
+ QTableView *view = new QTableView();
+ view->setModel(model);
+ view->show();
+}
+
+void printDataBase()
+{
+ QSqlQuery query;
+ query.prepare("SELECT TestName, TestCaseName, Result FROM Results;");
+ bool ok = query.exec();
+ qDebug() << "printDataBase ok?" << ok;
+
+ query.next();
+ qDebug() << "";
+ qDebug() << "Benchmark" << query.value(0).toString();
+ query.previous();
+
+ while (query.next()) {
+ // QString country = query.value(fieldNo).toString();
+ // doSomething(country);
+ qDebug() << "result for" << query.value(1).toString() << query.value(2).toString();
+ }
+}
+
+// TempTable implementation
+
+static int tempTableIdentifier = 0;
+TempTable::TempTable(const QString &spec)
+{
+ m_name = "TempTable" + QString::number(tempTableIdentifier++);
+ execQuery("CREATE TEMP TABLE " + m_name + " " + spec);
+}
+
+TempTable::~TempTable()
+{
+ // ref count and drop it?
+}
+
+QString TempTable::name()
+{
+ return m_name;
+}
+
+// DataBaseWriter implementation
+
+DataBaseWriter::DataBaseWriter()
+{
+ disable = false;
+ chartSize = QSize(800, 400);
+ databaseFileName = ":memory:";
+ qtVersion = QT_VERSION_STR;
+}
+
+void DataBaseWriter::openDatabase()
+{
+ db = openDataBase(databaseFileName);
+}
+
+void DataBaseWriter::createDatabase()
+{
+ db = createDataBase(databaseFileName);
+}
+
+void DataBaseWriter::beginTransaction()
+{
+ if (db.transaction() == false) {
+ qDebug() << db.lastError();
+ qFatal("no transaction support");
+ }
+}
+
+void DataBaseWriter::commitTransaction()
+{
+ db.commit();
+}
+
+void DataBaseWriter::rollbackTransaction()
+{
+ db.rollback();
+}
+
+void DataBaseWriter::addResult(const QString &result)
+{
+ return addResult(QString(), QString(), result);
+}
+
+void DataBaseWriter::addResult(const QString &series, const QString &index, const QString &result, const QString &iterations)
+{
+ if (disable)
+ return;
+
+ QSqlQuery query;
+
+ query.prepare("INSERT INTO Results (TestName, TestCaseName, Series, Idx, Result, ChartWidth, ChartHeight, Title, TestTitle, ChartType, QtVersion, Iterations) "
+ "VALUES (:TestName, :TestCaseName, :Series, :Idx, :Result, :ChartWidth, :ChartHeight, :Title, :TestTitle, :ChartType, :QtVersion, :Iterations)");
+ query.bindValue(":TestName", testName);
+ query.bindValue(":TestCaseName", testCaseName);
+ query.bindValue(":Series", series);
+ query.bindValue(":Idx", index);
+ query.bindValue(":Result", result);
+ query.bindValue(":ChartWidth", chartSize.width());
+ query.bindValue(":ChartHeight", chartSize.height());
+ query.bindValue(":Title", chartTitle);
+ query.bindValue(":TestTitle", testTitle);
+ query.bindValue(":QtVersion", qtVersion);
+ query.bindValue(":Iterations", iterations);
+
+
+ if (chartType == LineChart)
+ query.bindValue(":ChartType", "LineChart");
+ else
+ query.bindValue(":ChartType", "BarChart");
+ execQuery(query);
+}
diff --git a/tools/qtestlib/chart/database.h b/tools/qtestlib/chart/database.h
new file mode 100644
index 0000000..df3dde2
--- /dev/null
+++ b/tools/qtestlib/chart/database.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef DATABASE_H
+#define DATABASE_H
+
+#include <QtCore>
+#include <QtSql>
+
+extern QString resultsTable;
+QSqlDatabase openDataBase(const QString &databaseFile = "database");
+QSqlDatabase createDataBase(const QString &databaseFile = "database");
+
+void loadXml(const QStringList &fileNames);
+void loadXml(const QString &fileName, const QString &context=QString::null);
+void loadXml(const QByteArray &xml, const QString &context=QString::null);
+
+void execQuery(QSqlQuery query, bool warnOnFail = true);
+void execQuery(const QString &spec, bool warnOnFail = true);
+void printDataBase();
+void displayTable(const QString &table);
+
+class TempTable
+{
+public:
+ TempTable(const QString &spec);
+ ~TempTable();
+ QString name();
+private:
+ QString m_name;
+};
+
+enum ChartType { BarChart, LineChart };
+class DataBaseWriter
+{
+public:
+ DataBaseWriter();
+ QString databaseFileName;
+ QString testTitle;
+ QString testName;
+ QString testCaseName;
+ ChartType chartType;
+ QSize chartSize;
+ QString chartTitle;
+ QString qtVersion;
+ bool disable;
+
+ void openDatabase();
+ void createDatabase();
+
+ void beginTransaction();
+ void commitTransaction();
+ void rollbackTransaction();
+
+ void addResult(const QString &result);
+ void addResult(const QString &series , const QString &index, const QString &result, const QString &iterations = QLatin1String("1"));
+
+ QSqlDatabase db;
+};
+
+
+#endif
diff --git a/tools/qtestlib/chart/main.cpp b/tools/qtestlib/chart/main.cpp
new file mode 100644
index 0000000..7069330
--- /dev/null
+++ b/tools/qtestlib/chart/main.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <QtCore>
+#include <QtSql>
+#include <database.h>
+#include <reportgenerator.h>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QSqlDatabase db = createDataBase(":memory:");
+
+ if (argc < 2) {
+
+ // Try stdin
+ QFile in;
+ in.open(stdin, QIODevice::ReadOnly);
+ QByteArray xml = in.readAll();
+
+ if (xml.isEmpty()) {
+ qDebug() << "Usage: chart xml-file [xml-file2 xml-file3 ...]";
+ qDebug() << "See also QTestLib's \"-chart\" option";
+ return 0;
+ } else {
+ loadXml(xml, QString());
+ }
+ }
+
+ QStringList files;
+ for (int i = 1; i < argc; i++) {
+ QString file = QString::fromLocal8Bit(argv[i]);
+ files += file;
+ }
+
+ if (files.isEmpty() == false)
+ loadXml(files);
+
+ ReportGenerator reportGenerator;
+ reportGenerator.writeReports();
+
+ db.close();
+}
+
diff --git a/tools/qtestlib/chart/reportgenerator.cpp b/tools/qtestlib/chart/reportgenerator.cpp
new file mode 100644
index 0000000..0b5eb6f
--- /dev/null
+++ b/tools/qtestlib/chart/reportgenerator.cpp
@@ -0,0 +1,561 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "reportgenerator.h"
+
+// Report generator file utility functions
+
+QList<QByteArray> readLines(const QString &fileName)
+{
+ QList<QByteArray> lines;
+ QFile f(fileName);
+ f.open(QIODevice::ReadOnly | QIODevice::Text);
+ while(!f.atEnd())
+ lines.append(f.readLine());
+ return lines;
+}
+
+void writeLines(const QString &fileName, const QList<QByteArray> &lines)
+{
+ QFile f(fileName);
+ f.open(QIODevice::WriteOnly | QIODevice::Text);
+ foreach(const QByteArray line, lines)
+ f.write(line);
+}
+
+void writeFile(const QString &fileName, const QByteArray &contents)
+{
+ QFile f(fileName);
+ f.open(QIODevice::WriteOnly | QIODevice::Append);
+ f.write(contents);
+}
+
+// Report generator database utility functions
+
+QStringList select(const QString &field, const QString &tableName)
+{
+ QSqlQuery query;
+ query.prepare("SELECT DISTINCT " + field +" FROM " + tableName);
+ bool ok = query.exec();
+ Q_UNUSED(ok);
+// if (!ok)
+// qDebug() << "select unique ok" << ok;
+
+ QStringList values;
+ while (query.next()) {
+ values += query.value(0).toString();
+ }
+ return values;
+}
+
+QStringList selectUnique(const QString &field, const QString &tableName)
+{
+ QSqlQuery query;
+ query.prepare("SELECT DISTINCT " + field +" FROM " + tableName);
+ bool ok = query.exec();
+ Q_UNUSED(ok);
+// if (!ok)
+// qDebug() << "select unique ok" << ok;
+
+ QStringList values;
+ while (query.next()) {
+ values += query.value(0).toString();
+ }
+ return values;
+}
+
+QSqlQuery selectFromSeries(const QString &serie, const QString &column, const QString &tableName, const QString &seriesName)
+{
+ QSqlQuery query;
+ if (serie == QString())
+ query.prepare("SELECT " + column + " FROM " + tableName);
+ else
+ query.prepare("SELECT " + column + " FROM " + tableName + " WHERE " + seriesName + "='" + serie + "'");
+ /*bool ok =*/ query.exec();
+
+
+// qDebug() << "selectDataFromSeries ok?" << ok << query.size();
+ return query;
+}
+
+int countDataFromSeries(const QString &serie, const QString &tableName, const QString &seriesName)
+{
+// qDebug() << "count" << serie << "in" << tableName;
+ QSqlQuery query;
+ query.prepare("SELECT COUNT(Result) FROM " + tableName + " WHERE" + seriesName + "='" + serie + "'");
+ bool ok = query.exec();
+ if (!ok) {
+ qDebug() << "query fail" << query.lastError();
+ }
+
+ qDebug() << "countDataFromSeries ok?" << ok << query.size();
+ query.next();
+ return query.value(0).toInt();
+}
+
+// Report generator output utility functions
+
+QList<QByteArray> printData(const QString &tableName, const QString &seriesName, const QString &indexName)
+{
+ QList<QByteArray> output;
+ QStringList series = selectUnique(seriesName, tableName);
+// qDebug() << "series" << series;
+ if (series.isEmpty())
+ series+=QString();
+
+ foreach (QString serie, series) {
+ QSqlQuery data = selectFromSeries(serie, "Result", tableName, seriesName);
+ QSqlQuery labels = selectFromSeries(serie, indexName, tableName, seriesName);
+
+ QByteArray dataLine = "dataset.push({ data: [";
+ int i = 0;
+ while (data.next() && labels.next()) {
+ QString label = labels.value(0).toString();
+
+ QString labelString;
+ bool ok;
+ label.toInt(&ok);
+ if (ok)
+ labelString = label;
+ // else
+ labelString = QString::number(i);
+
+ dataLine += ("[" + labelString + ", " + data.value(0).toString() + "]");
+
+ ++i;
+ if (data.next()) {
+ dataLine += ", ";
+ data.previous();
+ }
+ }
+ dataLine += "], label : \"" + serie + "\" });\n";
+ output.append(dataLine);
+ }
+ return output;
+}
+
+// Determines if a line chart should be used. Returns true if the first label is numerical.
+bool useLineChart(const QString &tableName, const QString &seriesName, const QString &indexName)
+{
+ QList<QByteArray> output;
+ QStringList series = selectUnique(seriesName, tableName);
+ if (series.isEmpty())
+ return false;
+
+ QSqlQuery data = selectFromSeries(series[0], indexName, tableName, seriesName);
+
+ if (data.next()) {
+ QString label = data.value(0).toString();
+ bool ok;
+ label.toDouble(&ok);
+ return ok;
+ }
+
+ return false;
+}
+
+int countLabels(const QString &tableName, const QString &seriesName, const QString &indexName)
+{
+ QStringList series = selectUnique(seriesName, tableName);
+ if (series.isEmpty())
+ return 0;
+ QSqlQuery data = selectFromSeries(series[0], indexName, tableName, seriesName);
+ int count = 0;
+ while (data.next())
+ count++;
+
+ return count;
+}
+
+
+QList<QByteArray> printLabels(const QString &tableName, const QString &seriesName, const QString &indexName)
+{
+ QList<QByteArray> output;
+ QStringList series = selectUnique(seriesName, tableName);
+ if (series.isEmpty())
+ return QList<QByteArray>();
+
+ QSqlQuery data = selectFromSeries(series[0], indexName, tableName, seriesName);
+
+ int count = 0;
+ while (data.next())
+ count++;
+
+ data.first(); data.previous();
+
+ const int labelCount = 10;
+ int skip = count / labelCount;
+
+ QByteArray dataLine;
+ int i = 0;
+ while (data.next()) {
+ dataLine += ("[" + QByteArray::number(i) + ",\"" + data.value(0).toString() + "\"]");
+ ++i;
+ if (data.next()) {
+ dataLine += ", ";
+ data.previous();
+ }
+
+ // skip labels.
+ i += skip;
+ for (int j = 0; j < skip; ++j)
+ data.next();
+ }
+ dataLine += "\n";
+ output.append(dataLine);
+ return output;
+}
+
+QByteArray printSeriesLabels(const QString &tableName, const QString &seriesColumnName)
+{
+ QByteArray output;
+ QStringList series = selectUnique(seriesColumnName, tableName);
+ if (series.isEmpty())
+ return "[];\n";
+
+ output += "[";
+
+ foreach(const QString &serie, series) {
+ output += "\"" + serie.toLocal8Bit() + "\",";
+ }
+ output.chop(1); //remove last comma
+ output += "]\n";
+ return output;
+}
+
+void addJavascript(QList<QByteArray> *output, const QString &fileName)
+{
+ output->append("<script type=\"text/javascript\">\n");
+ (*output) += readLines(fileName);
+ output->append("</script>\n");
+}
+
+void addJavascript(QList<QByteArray> *output)
+{
+ addJavascript(output, ":3rdparty/prototype.js");
+ addJavascript(output, ":3rdparty/excanvas.js");
+ addJavascript(output, ":3rdparty/flotr.js");
+}
+
+TempTable selectRows(const QString &sourceTable, const QString &column, const QString &value)
+{
+ TempTable tempTable(resultsTable);
+
+ QSqlQuery query;
+ query.prepare("INSERT INTO " + tempTable.name() + " SELECT * FROM " + sourceTable +
+ " WHERE " + column + "='" + value + "'");
+ execQuery(query);
+
+// displayTable(tempTable.name());
+
+ return tempTable;
+}
+
+TempTable mergeVersions(const QString &)
+{
+
+// QtVersion - As series
+// Result - (free)
+// Idx - match
+// TestName - match
+// CaseName - match
+
+// (Series - average)
+/*
+ TempTable tempTable(resultsTable);
+ QStringlist versions = selectUnique("QtVersions", sourceTable);
+
+ QSqlQuery oneVersion = select(WHERE QtVersions = versions.at(0))
+ while (oneVersion.next) {
+ QSqlQuery otherversions = selectMatches(QStringList() << "TestName" << "TestCaseName" << "Idx")
+ while (otherversions.next) {
+ insert(temptable
+ }
+ }
+*/
+ return TempTable("");
+}
+
+QStringList fieldPriorityList = QStringList() << "Idx" << "Series" << "QtVersion";
+
+struct IndexSeriesFields
+{
+ QString index;
+ QString series;
+};
+
+IndexSeriesFields selectFields(const QString &table)
+{
+ IndexSeriesFields fields;
+ foreach (QString field, fieldPriorityList) {
+// qDebug() << "unique" << field << selectUnique(field, table).count();
+ QStringList rows = selectUnique(field, table);
+
+ if (rows.count() <= 1 && rows.join("") == QString(""))
+ continue;
+
+ if (fields.index.isEmpty()) {
+ fields.index = field;
+ continue;
+ }
+
+ if (fields.series.isEmpty()) {
+ fields.series = field;
+ break;
+ }
+ }
+ return fields;
+}
+
+TempTable selectTestCase(const QString &testCase, const QString &sourceTable)
+{
+ return selectRows(sourceTable, QLatin1String("TestCaseName"), testCase);
+}
+
+QString field(const QSqlQuery &query, const QString &name)
+{
+ return query.value(query.record().indexOf(name)).toString();
+}
+
+QSqlQuery selectAllResults(const QString &tableName)
+{
+ QSqlQuery query;
+ query.prepare("SELECT * FROM " + tableName);
+ execQuery(query);
+ return query;
+}
+
+void printTestCaseResults(const QString &testCaseName)
+{
+// QStringList testCases = selectUnique("TestCaseName", "Results");
+ qDebug() << "";
+ qDebug() << "Results for benchmark" << testCaseName;
+ TempTable temptable = selectTestCase(testCaseName, "Results");
+ QSqlQuery query = selectAllResults(temptable.name());
+ if (query.isActive() == false) {
+ qDebug() << "No results";
+ return;
+ }
+
+ query.next();
+
+ if (field(query, "Idx") == QString()) {
+ do {
+ qDebug() << "Result:" << field(query, "result");
+ } while (query.next());
+ } else if (field(query, "Series") == QString()) {
+ do {
+ qDebug() << field(query, "Idx") << " : " << field(query, "result");
+ } while (query.next());
+ } else {
+ do {
+ qDebug() << field(query, "Series") << " - " << field(query, "Idx") << " : " << field(query, "result");
+ } while (query.next());
+ }
+
+ qDebug() << "";
+}
+
+
+// ReportGenerator implementation
+
+ReportGenerator::ReportGenerator()
+{
+ m_colorScheme = QList<QByteArray>() << "#a03b3c" << "#3ba03a" << "#3a3ba0" << "#3aa09f" << "#39a06b" << "#a09f39";
+}
+
+
+void ReportGenerator::writeReport(const QString &tableName, const QString &fileName, bool combineQtVersions)
+{
+ QStringList testCases = selectUnique("TestCaseName", tableName);
+ QList<QByteArray> lines = readLines(":benchmark_template.html");
+ QList<QByteArray> output;
+
+ foreach(QByteArray line, lines) {
+ if (line.contains("<! Chart Here>")) {
+ foreach (const QString testCase, testCases) {
+ TempTable testCaseTable = selectTestCase(testCase, tableName);
+ output += writeChart(testCaseTable.name(), combineQtVersions);
+ }
+ } else if (line.contains("<! Title Here>")) {
+ QStringList name = selectUnique("TestName", tableName);
+ output += "Test: " + name.join("").toLocal8Bit();
+ } else if (line.contains("<! Description Here>")) {
+ output += selectUnique("TestTitle", tableName).join("").toLocal8Bit();
+ } else if (line.contains("<! Javascript Here>")){
+ addJavascript(&output);
+ } else {
+ output.append(line);
+ }
+ }
+
+ m_fileName = fileName;
+
+ writeLines(m_fileName, output);
+ qDebug() << "Wrote report to" << m_fileName;
+}
+
+void ReportGenerator::writeReports()
+{
+/*
+ QStringList versions = selectUnique("QtVersion", "Results");
+
+ // qDebug() << "versions" << versions;
+
+ foreach (QString version, versions) {
+ QString fileName = "results-" + version + ".html";
+ TempTable versionTable = selectRows("Results", "QtVersion", version);
+ writeReport(versionTable.name(), fileName, false);
+ }
+*/
+ writeReport("Results", "results.html", false);
+}
+
+QString ReportGenerator::fileName()
+{
+ return m_fileName;
+}
+
+QList<QByteArray> ReportGenerator::writeChart(const QString &tableName, bool combineQtVersions)
+{
+ QSqlQuery query;
+ query.prepare("SELECT TestName, Series, Idx, Result, ChartWidth, ChartHeight, Title, TestCaseName, ChartType, QtVersion FROM " + tableName);
+ execQuery(query);
+
+ QString seriesName;
+ QString indexName;
+
+ if (combineQtVersions) {
+ IndexSeriesFields fields = selectFields(tableName);
+ seriesName = fields.series;
+ indexName = fields.index;
+ } else {
+ seriesName = "Series";
+ indexName = "Idx";
+ }
+
+ QList<QByteArray> data = printData(tableName, seriesName, indexName);
+ QList<QByteArray> labels = printLabels(tableName, seriesName, indexName);
+ QByteArray seriesLabels = printSeriesLabels(tableName, seriesName);
+ QByteArray useLineChartString = useLineChart(tableName, seriesName, indexName) ? "true" : "false" ;
+
+ query.next();
+ QString testName = query.value(0).toString();
+ QSize size(query.value(4).toInt(), query.value(5).toInt());
+// QString title = "Test Function: " + query.value(7).toString() + " - " + query.value(6).toString();
+ QString title = "Test Function: " + query.value(7).toString();
+ QString chartId = "\"" + query.value(7).toString() + "\"";
+ QString formId = "\"" + query.value(7).toString() + "form\"";
+ QString chartTypeFormId = "\"" + query.value(7).toString() + "chartTypeform\"";
+ QString scaleFormId = "\"" + query.value(7).toString() + "scaleform\"";
+ QString type = query.value(8).toString();
+
+ // Skip chart generation if there isn't enough data.
+ if (countLabels(tableName, seriesName, indexName) < 2) {
+ qDebug() << title.toAscii() << "No chartable data. (See the \"series\" test function"
+ << "in examples/qtestlib/tutorial5 for an example.) ";
+ return QList<QByteArray>() << title.toAscii() << " (no chartable data)"; // TODO: genrate text table here.
+ }
+
+// QString qtVersion = query.value(9).toString();
+ query.previous();
+
+ QString sizeString = "height=\"" + QString::number(size.height()) + "\" width=\"" + QString::number(size.width()) + "\"";
+
+ QString fillString;
+ if (type == "LineChart")
+ fillString = "false";
+ else
+ fillString = "true";
+
+ QByteArray colors = printColors(tableName, seriesName);
+
+ QList<QByteArray> lines = readLines(":chart_template.html");
+ QList<QByteArray> output;
+
+ foreach(QByteArray line, lines) {
+ if (line.contains("<! Test Name Here>")) {
+ output.append(title.toLocal8Bit());
+ } else if (line.contains("<! Chart ID Here>")) {
+ output += chartId.toLocal8Bit();
+ } else if (line.contains("<! Form ID Here>")) {
+ output += formId.toLocal8Bit();
+ } else if (line.contains("<! ChartTypeForm ID Here>")) {
+ output += chartTypeFormId.toLocal8Bit();
+ } else if (line.contains("<! ScaleForm ID Here>")) {
+ output += scaleFormId.toLocal8Bit();
+ } else if (line.contains("<! Size>")) {
+ output += sizeString.toLocal8Bit();
+ } else if (line.contains("<! ColorScheme Here>")) {
+ output += colors;
+ } else if (line.contains("<! Data Goes Here>")) {
+ output += data;
+ } else if (line.contains("<! Labels Go Here>")) {
+ output += labels;
+ } else if (line.contains("<! Use Line Chart Here>")) {
+ output += useLineChartString + ";";
+ } else if (line.contains("<! Chart Type Here>")) {
+ output += "\"" + type.toLocal8Bit() + "\"";
+ } else if (line.contains("<! Fill Setting Here>")) {
+ output += fillString.toLocal8Bit();
+ } else if (line.contains("<! Series Labels Here>")) {
+ output += seriesLabels;
+ } else {
+ output.append(line);
+ }
+ }
+
+ return output;
+}
+
+QByteArray ReportGenerator::printColors(const QString &tableName, const QString &seriesName)
+{
+ QByteArray colors;
+ int i = 0;
+ QStringList series = selectUnique(seriesName, tableName);
+ foreach (const QString &serie, series) {
+ colors.append("'" + serie.toLocal8Bit() + "': '" + m_colorScheme.at(i % m_colorScheme.count()) + "',\n");
+ ++ i;
+ }
+ colors.chop(2); // remove last comma
+ colors.append("\n");
+ return colors;
+}
+
diff --git a/tools/qtestlib/chart/reportgenerator.h b/tools/qtestlib/chart/reportgenerator.h
new file mode 100644
index 0000000..bef9cdd
--- /dev/null
+++ b/tools/qtestlib/chart/reportgenerator.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** 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 either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef REPORTGENERATOR_H
+#define REPORTGENERATOR_H
+
+#include "database.h"
+
+class ReportGenerator
+{
+public:
+ ReportGenerator();
+ QByteArray printColors(const QString &tableName, const QString &seriesName);
+ QList<QByteArray> writeChart(const QString &tableName, bool combineVersions);
+ void writeReport(const QString &tableName, const QString &filename, bool combineVersions = false);
+ void writeReports();
+ QString fileName();
+private:
+ QList<QByteArray> m_colorScheme;
+ QString m_fileName;
+};
+
+void printTestCaseResults(const QString &testCaseName);
+
+#endif
+
diff --git a/tools/qtestlib/qtestlib.pro b/tools/qtestlib/qtestlib.pro
index da94e81..9ff7360 100644
--- a/tools/qtestlib/qtestlib.pro
+++ b/tools/qtestlib/qtestlib.pro
@@ -1,4 +1,4 @@
TEMPLATE = subdirs
-!wince*: SUBDIRS += updater
+!wince*: SUBDIRS += updater chart
wince*: contains(QT_CONFIG, cetest): SUBDIRS += wince
CONFIG += ordered
diff --git a/tools/qtestlib/wince/cetest/activesyncconnection.cpp b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
index f047b79..1080477 100644
--- a/tools/qtestlib/wince/cetest/activesyncconnection.cpp
+++ b/tools/qtestlib/wince/cetest/activesyncconnection.cpp
@@ -113,6 +113,8 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
CeCloseHandle(deviceHandle);
return true;
}
+ } else {
+ qWarning("Could not open %s: %s", qPrintable(localSource), qPrintable(file.errorString()));
}
return false;
}
@@ -120,7 +122,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
deleteFile(deviceDest);
HANDLE deviceHandle = CeCreateFile(deviceDest.utf16(), GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (deviceHandle == INVALID_HANDLE_VALUE) {
- debugOutput(QString::fromLatin1(" Could not create target file"), 2);
+ qWarning("Could not create %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
return false;
}
@@ -144,7 +146,7 @@ bool ActiveSyncConnection::copyFileToDevice(const QString &localSource, const QS
if (toWrite == 0)
break;
if (!CeWriteFile(deviceHandle, data.data() , toWrite, &written, NULL)) {
- debugOutput(QString::fromLatin1(" Could not write File"), 2);
+ qWarning("Could not write to %s: %s", qPrintable(deviceDest), strwinerror(CeGetLastError()).constData());
return false;
}
currentPos += written;
@@ -270,8 +272,8 @@ bool ActiveSyncConnection::copyDirectoryFromDevice(const QString &deviceSource,
}
do {
- QString srcFile = deviceSource + "\\" + QString::fromUtf16(data.cFileName);
- QString destFile = localDest + "\\" + QString::fromUtf16(data.cFileName);
+ QString srcFile = deviceSource + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = localDest + "\\" + QString::fromWCharArray(data.cFileName);
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive && !copyDirectoryFromDevice(srcFile, destFile, recursive)) {
wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
@@ -306,8 +308,8 @@ bool ActiveSyncConnection::copyDirectory(const QString &srcDirectory, const QStr
}
do {
- QString srcFile = srcDirectory + "\\" + QString::fromUtf16(data.cFileName);
- QString destFile = destDirectory + "\\" + QString::fromUtf16(data.cFileName);
+ QString srcFile = srcDirectory + "\\" + QString::fromWCharArray(data.cFileName);
+ QString destFile = destDirectory + "\\" + QString::fromWCharArray(data.cFileName);
if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive && !copyDirectory(srcFile, destFile, recursive)) {
wprintf(L"Copy of subdirectory(%s) failed\n", srcFile.utf16());
@@ -341,7 +343,7 @@ bool ActiveSyncConnection::deleteDirectory(const QString &directory, bool recurs
return false;
do {
- QString FileName = directory + "\\" + QString::fromUtf16(FindFileData.cFileName);
+ QString FileName = directory + "\\" + QString::fromWCharArray(FindFileData.cFileName);
if((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
if (recursive)
if (!deleteDirectory(FileName, recursive, failIfContentExists))
@@ -380,12 +382,17 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo
BYTE* output;
IRAPIStream *stream;
int returned = 0;
+ DWORD error = 0;
HRESULT res = CeRapiInvoke(dllLocation.utf16(), functionName.utf16(), 0, 0, &outputSize, &output, &stream, 0);
if (S_OK != res) {
- if (S_OK != CeGetLastError())
- debugOutput(QString::fromLatin1("Error: Could not invoke method on QtRemote"),1);
- else
- debugOutput(QString::fromLatin1("Error: QtRemote return unexpectedly with error Code %1").arg(res), 1);
+ DWORD ce_error = CeGetLastError();
+ if (S_OK != ce_error) {
+ qWarning("Error invoking %s on %s: %s", qPrintable(functionName),
+ qPrintable(dllLocation), strwinerror(ce_error).constData());
+ } else {
+ qWarning("Error: %s on %s unexpectedly returned %d", qPrintable(functionName),
+ qPrintable(dllLocation), res);
+ }
} else {
DWORD written;
int strSize = program.length();
@@ -414,9 +421,18 @@ bool ActiveSyncConnection::execute(QString program, QString arguments, int timeo
if (S_OK != stream->Read(&returned, sizeof(returned), &written)) {
qWarning(" Could not access return value of process");
}
- result = true;
- }
+ if (S_OK != stream->Read(&error, sizeof(error), &written)) {
+ qWarning(" Could not access error code");
+ }
+ if (error) {
+ qWarning("Error on target: %s", strwinerror(error).constData());
+ result = false;
+ }
+ else {
+ result = true;
+ }
+ }
if (returnValue)
*returnValue = returned;
diff --git a/tools/qtestlib/wince/cetest/deployment.cpp b/tools/qtestlib/wince/cetest/deployment.cpp
index fec2735..68f0197 100644
--- a/tools/qtestlib/wince/cetest/deployment.cpp
+++ b/tools/qtestlib/wince/cetest/deployment.cpp
@@ -125,13 +125,37 @@ void DeploymentHandler::initQtDeploy(QMakeProject *project, DeploymentList &depl
if (!project->values("QMAKE_QT_DLL").isEmpty() && !project->values("QMAKE_LIBDIR").isEmpty()) {
QStringList libs = project->values("LIBS");
QStringList qtLibs;
+ QStringList libPaths;
foreach (QString item, libs) {
- if (item.startsWith("-lQt")) {
- qtLibs += project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + item.mid(2) + QLatin1String("4.dll");
+
+ if (item.startsWith("-L")) {
+ // -L -> a directory containing DLLs
+ libPaths << item.mid(2);
+ continue;
+ }
+
+ QStringList libCandidates;
+
+ if (item.startsWith("-l")) {
+ // -l -> a library located within one of the standard library paths
+ QString lib = item.mid(2);
+
+ // Check if it's a Qt library first, then check in all paths given with -L.
+ // Note Qt libraries get a `4' appended to them, others don't.
+ libCandidates << project->values("QMAKE_LIBDIR").at(0) + QDir::separator() + lib + QLatin1String("4.dll");
+ foreach (QString const& libPath, libPaths) {
+ libCandidates << libPath + QDir::separator() + lib + QLatin1String(".dll");
+ }
} else {
- QFileInfo info(item);
- if (info.exists() && info.isAbsolute() && info.fileName().startsWith(QLatin1String("Qt")))
- qtLibs += info.dir().absoluteFilePath(info.fileName().replace(QLatin1String(".lib"), QLatin1String(".dll")));
+ libCandidates << item.replace(".lib",".dll");
+ }
+
+ foreach (QString const& file, libCandidates) {
+ QFileInfo info(file);
+ if (info.exists()) {
+ qtLibs += info.dir().absoluteFilePath(info.fileName());
+ break;
+ }
}
}
for (QStringList::ConstIterator it = qtLibs.constBegin(); it != qtLibs.constEnd(); ++it) {
diff --git a/tools/qtestlib/wince/cetest/main.cpp b/tools/qtestlib/wince/cetest/main.cpp
index ba3ef8d..782f6d9 100644
--- a/tools/qtestlib/wince/cetest/main.cpp
+++ b/tools/qtestlib/wince/cetest/main.cpp
@@ -320,6 +320,7 @@ int main(int argc, char **argv)
cout << endl << "Remote Launch:" << qPrintable(TestConfiguration::remoteExecutable) << " " << qPrintable(launchArguments.join(" ")) << endl;
if (!connection.execute(TestConfiguration::remoteExecutable, launchArguments.join(" "), timeout)) {
cout << "Error: Could not execute target file" << endl;
+ return -1;
}
diff --git a/tools/qtestlib/wince/cetest/remoteconnection.cpp b/tools/qtestlib/wince/cetest/remoteconnection.cpp
index 547b211..3d0c3f3 100644
--- a/tools/qtestlib/wince/cetest/remoteconnection.cpp
+++ b/tools/qtestlib/wince/cetest/remoteconnection.cpp
@@ -41,6 +41,38 @@
#include "remoteconnection.h"
+QByteArray strwinerror(DWORD errorcode)
+{
+ QByteArray out(512, 0);
+
+ DWORD ok = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ 0,
+ errorcode,
+ 0,
+ out.data(),
+ out.size(),
+ 0
+ );
+
+ if (!ok) {
+ qsnprintf(out.data(), out.size(),
+ "(error %d; additionally, error %d while looking up error string)",
+ (int)errorcode, (int)GetLastError());
+ }
+ else {
+ out.resize(qstrlen(out.constData()));
+ if (out.endsWith("\r\n"))
+ out.chop(2);
+
+ /* Append error number to error message for good measure */
+ out.append(" (0x");
+ out.append(QByteArray::number(uint(errorcode), 16).rightJustified(8, '0'));
+ out.append(")");
+ }
+ return out;
+}
+
AbstractRemoteConnection::AbstractRemoteConnection()
{
}
diff --git a/tools/qtestlib/wince/cetest/remoteconnection.h b/tools/qtestlib/wince/cetest/remoteconnection.h
index 9c3e63d..f517009 100644
--- a/tools/qtestlib/wince/cetest/remoteconnection.h
+++ b/tools/qtestlib/wince/cetest/remoteconnection.h
@@ -79,4 +79,6 @@ public:
virtual bool execute(QString program, QString arguments = QString(), int timeout = -1, int *returnValue = NULL) = 0;
};
+QByteArray strwinerror(DWORD);
+
#endif
diff --git a/tools/qtestlib/wince/remotelib/commands.cpp b/tools/qtestlib/wince/remotelib/commands.cpp
index 3aed2d6..f2176dd 100644
--- a/tools/qtestlib/wince/remotelib/commands.cpp
+++ b/tools/qtestlib/wince/remotelib/commands.cpp
@@ -56,6 +56,7 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
wchar_t* arguments = 0;
int timeout = -1;
int returnValue = -2;
+ DWORD error = 0;
if (S_OK != stream->Read(&appLength, sizeof(appLength), &bytesRead))
CLEAN_FAIL(-2);
@@ -74,11 +75,13 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
if (S_OK != stream->Read(&timeout, sizeof(timeout), &bytesRead))
CLEAN_FAIL(-2);
- bool result = qRemoteExecute(appName, arguments, &returnValue, timeout);
+ bool result = qRemoteExecute(appName, arguments, &returnValue, &error, timeout);
if (timeout != 0) {
if (S_OK != stream->Write(&returnValue, sizeof(returnValue), &bytesRead))
CLEAN_FAIL(-4);
+ if (S_OK != stream->Write(&error, sizeof(error), &bytesRead))
+ CLEAN_FAIL(-5);
}
delete appName;
delete arguments;
@@ -90,13 +93,16 @@ int qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream* stream)
}
-bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, int timeout)
+bool qRemoteExecute(const wchar_t* program, const wchar_t* arguments, int *returnValue, DWORD* error, int timeout)
{
+ *error = 0;
+
if (!program)
return false;
PROCESS_INFORMATION pid;
if (!CreateProcess(program, arguments, NULL, NULL, false, 0, NULL, NULL, NULL, &pid)) {
+ *error = GetLastError();
wprintf(L"Could not launch: %s\n", program);
return false;
}
diff --git a/tools/qtestlib/wince/remotelib/commands.h b/tools/qtestlib/wince/remotelib/commands.h
index 9f0b2e3..5275f2c 100644
--- a/tools/qtestlib/wince/remotelib/commands.h
+++ b/tools/qtestlib/wince/remotelib/commands.h
@@ -45,7 +45,7 @@
extern "C" {
int __declspec(dllexport) qRemoteLaunch(DWORD, BYTE*, DWORD*, BYTE**, IRAPIStream*);
- bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , int timeout = -1);
+ bool __declspec(dllexport) qRemoteExecute(const wchar_t* program, const wchar_t* arguments = NULL, int *returnValue = NULL , DWORD* error = NULL, int timeout = -1);
}
#endif
diff --git a/tools/qvfb/PDAPhone.skin/pda_up.png b/tools/qvfb/PDAPhone.skin/pda_up.png
deleted file mode 100644
index 541e3c4..0000000
--- a/tools/qvfb/PDAPhone.skin/pda_up.png
+++ /dev/null
Binary files differ
diff --git a/tools/qvfb/config.ui b/tools/qvfb/config.ui
index 5a2eca0..182682e 100644
--- a/tools/qvfb/config.ui
+++ b/tools/qvfb/config.ui
@@ -1,4 +1,5 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
<comment>*********************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
@@ -40,181 +41,145 @@
**
*********************************************************************</comment>
<class>Config</class>
- <widget class="QDialog" name="Config" >
- <property name="geometry" >
+ <widget class="QDialog" name="Config">
+ <property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
- <height>650</height>
+ <height>665</height>
</rect>
</property>
- <property name="windowTitle" >
+ <property name="windowTitle">
<string>Configure</string>
</property>
- <property name="sizeGripEnabled" >
+ <property name="sizeGripEnabled">
<bool>true</bool>
</property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <layout class="QVBoxLayout">
+ <property name="spacing">
<number>6</number>
</property>
- <property name="leftMargin" >
- <number>8</number>
- </property>
- <property name="topMargin" >
- <number>8</number>
- </property>
- <property name="rightMargin" >
- <number>8</number>
- </property>
- <property name="bottomMargin" >
+ <property name="margin">
<number>8</number>
</property>
<item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
+ <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" >
+ <property name="margin">
<number>0</number>
</property>
<item>
- <widget class="QGroupBox" name="ButtonGroup1" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <widget class="QGroupBox" name="ButtonGroup1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="title" >
+ <property name="title">
<string>Size</string>
</property>
- <layout class="QVBoxLayout" >
- <property name="spacing" >
+ <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" >
+ <property name="margin">
<number>11</number>
</property>
<item>
- <widget class="QRadioButton" name="size_176_220" >
- <property name="text" >
- <string>176x220 "SmartPhone"</string>
+ <widget class="QRadioButton" name="size_176_220">
+ <property name="text">
+ <string>176x220 &quot;SmartPhone&quot;</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="size_240_320" >
- <property name="text" >
- <string>240x320 "PDA"</string>
+ <widget class="QRadioButton" name="size_240_320">
+ <property name="text">
+ <string>240x320 &quot;PDA&quot;</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="size_320_240" >
- <property name="text" >
- <string>320x240 "TV" / "QVGA"</string>
+ <widget class="QRadioButton" name="size_320_240">
+ <property name="text">
+ <string>320x240 &quot;TV&quot; / &quot;QVGA&quot;</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="size_640_480" >
- <property name="text" >
- <string>640x480 "VGA"</string>
+ <widget class="QRadioButton" name="size_640_480">
+ <property name="text">
+ <string>640x480 &quot;VGA&quot;</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="size_800_600" >
- <property name="text" >
+ <widget class="QRadioButton" name="size_800_600">
+ <property name="text">
<string>800x600</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="size_1024_768" >
- <property name="text" >
+ <widget class="QRadioButton" name="size_1024_768">
+ <property name="text">
<string>1024x768</string>
</property>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
+ <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" >
+ <property name="margin">
<number>0</number>
</property>
<item>
- <widget class="QRadioButton" name="size_custom" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+ <widget class="QRadioButton" name="size_custom">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text" >
+ <property name="text">
<string>Custom</string>
</property>
</widget>
</item>
<item>
- <widget class="QSpinBox" name="size_width" >
- <property name="minimum" >
+ <widget class="QSpinBox" name="size_width">
+ <property name="minimum">
<number>1</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>1280</number>
</property>
- <property name="singleStep" >
+ <property name="singleStep">
<number>16</number>
</property>
- <property name="value" >
+ <property name="value">
<number>400</number>
</property>
</widget>
</item>
<item>
- <widget class="QSpinBox" name="size_height" >
- <property name="minimum" >
+ <widget class="QSpinBox" name="size_height">
+ <property name="minimum">
<number>1</number>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>1024</number>
</property>
- <property name="singleStep" >
+ <property name="singleStep">
<number>16</number>
</property>
- <property name="value" >
+ <property name="value">
<number>300</number>
</property>
</widget>
@@ -225,135 +190,128 @@
</widget>
</item>
<item>
- <widget class="QGroupBox" name="ButtonGroup2" >
- <property name="title" >
+ <widget class="QGroupBox" name="ButtonGroup2">
+ <property name="title">
<string>Depth</string>
</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>
+ <layout class="QVBoxLayout" name="verticalLayout">
<item>
- <widget class="QRadioButton" name="depth_1" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_1">
+ <property name="text">
<string>1 bit monochrome</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_4gray" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_2gray">
+ <property name="text">
+ <string>2 bit grayscale</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="depth_4gray">
+ <property name="text">
<string>4 bit grayscale</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_8" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_8">
+ <property name="text">
<string>8 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_12" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_12">
+ <property name="text">
<string>12 (16) bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_15" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_15">
+ <property name="text">
<string>15 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_16" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_16">
+ <property name="text">
<string>16 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_18" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_18">
+ <property name="text">
<string>18 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_24" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_24">
+ <property name="text">
<string>24 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_32" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_32">
+ <property name="text">
<string>32 bit</string>
</property>
</widget>
</item>
<item>
- <widget class="QRadioButton" name="depth_32_argb" >
- <property name="text" >
+ <widget class="QRadioButton" name="depth_32_argb">
+ <property name="text">
<string>32 bit ARGB</string>
</property>
</widget>
</item>
+ <item>
+ <widget class="QCheckBox" name="rgbSwapped">
+ <property name="toolTip">
+ <string>Swap red and blue channels</string>
+ </property>
+ <property name="text">
+ <string>BGR format</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
+ <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" >
+ <property name="margin">
<number>0</number>
</property>
<item>
- <widget class="QLabel" name="TextLabel1_3" >
- <property name="text" >
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
<string>Skin</string>
</property>
</widget>
</item>
<item>
- <widget class="QComboBox" name="skin" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Expanding" >
+ <widget class="QComboBox" name="skin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<item>
- <property name="text" >
+ <property name="text">
<string>None</string>
</property>
</item>
@@ -362,25 +320,25 @@
</layout>
</item>
<item>
- <widget class="QCheckBox" name="touchScreen" >
- <property name="text" >
+ <widget class="QCheckBox" name="touchScreen">
+ <property name="text">
<string>Emulate touch screen (no mouse move)</string>
</property>
</widget>
</item>
<item>
- <widget class="QCheckBox" name="lcdScreen" >
- <property name="text" >
+ <widget class="QCheckBox" name="lcdScreen">
+ <property name="text">
<string>Emulate LCD screen (Only with fixed zoom of 3.0 times magnification)</string>
</property>
</widget>
</item>
<item>
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Vertical</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
@@ -389,204 +347,192 @@
</spacer>
</item>
<item>
- <widget class="QLabel" name="TextLabel1" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <widget class="QLabel" name="TextLabel1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
- <property name="text" >
- <string>&lt;p>Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth &lt;i>above&lt;/i>. You may freely modify the Gamma &lt;i>below&lt;/i>.</string>
+ <property name="text">
+ <string>&lt;p&gt;Note that any applications using the virtual framebuffer will be terminated if you change the Size or Depth &lt;i&gt;above&lt;/i&gt;. You may freely modify the Gamma &lt;i&gt;below&lt;/i&gt;.</string>
</property>
- <property name="wordWrap" >
+ <property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <widget class="QGroupBox" name="GroupBox1" >
- <property name="title" >
+ <widget class="QGroupBox" name="GroupBox1">
+ <property name="title">
<string>Gamma</string>
</property>
- <layout class="QGridLayout" >
- <property name="leftMargin" >
- <number>11</number>
- </property>
- <property name="topMargin" >
- <number>11</number>
- </property>
- <property name="rightMargin" >
- <number>11</number>
- </property>
- <property name="bottomMargin" >
+ <layout class="QGridLayout">
+ <property name="margin">
<number>11</number>
</property>
- <property name="horizontalSpacing" >
+ <property name="spacing">
<number>6</number>
</property>
- <property name="verticalSpacing" >
- <number>6</number>
- </property>
- <item row="6" column="0" >
- <widget class="QLabel" name="TextLabel3" >
- <property name="text" >
+ <item row="6" column="0">
+ <widget class="QLabel" name="TextLabel3">
+ <property name="text">
<string>Blue</string>
</property>
</widget>
</item>
- <item row="6" column="1" >
- <widget class="QSlider" name="bslider" >
- <property name="palette" >
+ <item row="6" column="1">
+ <widget class="QSlider" name="bslider">
+ <property name="palette">
<palette>
<active>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>38</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -595,153 +541,153 @@
</colorrole>
</active>
<inactive>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>38</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -750,153 +696,153 @@
</colorrole>
</inactive>
<disabled>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>38</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -906,183 +852,183 @@
</disabled>
</palette>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>400</number>
</property>
- <property name="value" >
+ <property name="value">
<number>100</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="6" column="2" >
- <widget class="QLabel" name="blabel" >
- <property name="text" >
+ <item row="6" column="2">
+ <widget class="QLabel" name="blabel">
+ <property name="text">
<string>1.0</string>
</property>
</widget>
</item>
- <item row="4" column="0" >
- <widget class="QLabel" name="TextLabel2" >
- <property name="text" >
+ <item row="4" column="0">
+ <widget class="QLabel" name="TextLabel2">
+ <property name="text">
<string>Green</string>
</property>
</widget>
</item>
- <item row="4" column="1" >
- <widget class="QSlider" name="gslider" >
- <property name="palette" >
+ <item row="4" column="1">
+ <widget class="QSlider" name="gslider">
+ <property name="palette">
<palette>
<active>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>255</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>255</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>127</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>170</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1091,153 +1037,153 @@
</colorrole>
</active>
<inactive>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>255</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>255</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>127</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>170</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1246,153 +1192,153 @@
</colorrole>
</inactive>
<disabled>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>255</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>255</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>38</red>
<green>255</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>127</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>170</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1402,190 +1348,190 @@
</disabled>
</palette>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>400</number>
</property>
- <property name="value" >
+ <property name="value">
<number>100</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="4" column="2" >
- <widget class="QLabel" name="glabel" >
- <property name="text" >
+ <item row="4" column="2">
+ <widget class="QLabel" name="glabel">
+ <property name="text">
<string>1.0</string>
</property>
</widget>
</item>
- <item row="0" column="0" >
- <widget class="QLabel" name="TextLabel7" >
- <property name="text" >
+ <item row="0" column="0">
+ <widget class="QLabel" name="TextLabel7">
+ <property name="text">
<string>All</string>
</property>
</widget>
</item>
- <item row="0" column="2" >
- <widget class="QLabel" name="TextLabel8" >
- <property name="text" >
+ <item row="0" column="2">
+ <widget class="QLabel" name="TextLabel8">
+ <property name="text">
<string>1.0</string>
</property>
</widget>
</item>
- <item row="0" column="1" >
- <widget class="QSlider" name="gammaslider" >
- <property name="palette" >
+ <item row="0" column="1">
+ <widget class="QSlider" name="gammaslider">
+ <property name="palette">
<palette>
<active>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1594,153 +1540,153 @@
</colorrole>
</active>
<inactive>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1749,153 +1695,153 @@
</colorrole>
</inactive>
<disabled>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>170</green>
<blue>170</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -1905,183 +1851,183 @@
</disabled>
</palette>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>400</number>
</property>
- <property name="value" >
+ <property name="value">
<number>100</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="2" column="0" >
- <widget class="QLabel" name="TextLabel1_2" >
- <property name="text" >
+ <item row="2" column="0">
+ <widget class="QLabel" name="TextLabel1_2">
+ <property name="text">
<string>Red</string>
</property>
</widget>
</item>
- <item row="2" column="2" >
- <widget class="QLabel" name="rlabel" >
- <property name="text" >
+ <item row="2" column="2">
+ <widget class="QLabel" name="rlabel">
+ <property name="text">
<string>1.0</string>
</property>
</widget>
</item>
- <item row="2" column="1" >
- <widget class="QSlider" name="rslider" >
- <property name="palette" >
+ <item row="2" column="1">
+ <widget class="QSlider" name="rslider">
+ <property name="palette">
<palette>
<active>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>38</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -2090,153 +2036,153 @@
</colorrole>
</active>
<inactive>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>38</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -2245,153 +2191,153 @@
</colorrole>
</inactive>
<disabled>
- <colorrole role="WindowText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="WindowText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Button" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Button">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Light" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Light">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>127</green>
<blue>127</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Midlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Midlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>38</green>
<blue>38</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Dark" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Dark">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>127</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Mid" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Mid">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>170</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Text" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Text">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="BrightText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="BrightText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="ButtonText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="ButtonText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>128</red>
<green>128</green>
<blue>128</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Base" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Base">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Window" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Window">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>220</red>
<green>220</green>
<blue>220</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Shadow" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Shadow">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Highlight" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Highlight">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>10</red>
<green>95</green>
<blue>137</blue>
</color>
</brush>
</colorrole>
- <colorrole role="HighlightedText" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="HighlightedText">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
- <colorrole role="Link" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="Link">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="LinkVisited" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="LinkVisited">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
- <colorrole role="AlternateBase" >
- <brush brushstyle="SolidPattern" >
- <color alpha="255" >
+ <colorrole role="AlternateBase">
+ <brush brushstyle="SolidPattern">
+ <color alpha="255">
<red>232</red>
<green>232</green>
<blue>232</blue>
@@ -2401,53 +2347,44 @@
</disabled>
</palette>
</property>
- <property name="maximum" >
+ <property name="maximum">
<number>400</number>
</property>
- <property name="value" >
+ <property name="value">
<number>100</number>
</property>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
- <item row="8" column="0" colspan="3" >
- <widget class="QPushButton" name="PushButton3" >
- <property name="text" >
+ <item row="8" column="0" colspan="3">
+ <widget class="QPushButton" name="PushButton3">
+ <property name="text">
<string>Set all to 1.0</string>
</property>
</widget>
</item>
- <item rowspan="9" row="0" column="3" >
- <widget class="GammaView" native="1" name="MyCustomWidget1" />
+ <item row="0" column="3" rowspan="9">
+ <widget class="GammaView" name="MyCustomWidget1" native="true"/>
</item>
</layout>
</widget>
</item>
<item>
- <layout class="QHBoxLayout" >
- <property name="spacing" >
+ <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" >
+ <property name="margin">
<number>0</number>
</property>
<item>
<spacer>
- <property name="orientation" >
+ <property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
- <property name="sizeHint" >
+ <property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
@@ -2456,24 +2393,24 @@
</spacer>
</item>
<item>
- <widget class="QPushButton" name="buttonOk" >
- <property name="text" >
+ <widget class="QPushButton" name="buttonOk">
+ <property name="text">
<string>&amp;OK</string>
</property>
- <property name="autoDefault" >
+ <property name="autoDefault">
<bool>true</bool>
</property>
- <property name="default" >
+ <property name="default">
<bool>true</bool>
</property>
</widget>
</item>
<item>
- <widget class="QPushButton" name="buttonCancel" >
- <property name="text" >
+ <widget class="QPushButton" name="buttonCancel">
+ <property name="text">
<string>&amp;Cancel</string>
</property>
- <property name="autoDefault" >
+ <property name="autoDefault">
<bool>true</bool>
</property>
</widget>
@@ -2482,7 +2419,7 @@
</item>
</layout>
</widget>
- <layoutdefault spacing="6" margin="11" />
+ <layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>GammaView</class>
@@ -2498,11 +2435,11 @@
<receiver>size_custom</receiver>
<slot>click()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>152</x>
<y>193</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>94</x>
<y>199</y>
</hint>
@@ -2514,11 +2451,11 @@
<receiver>size_custom</receiver>
<slot>click()</slot>
<hints>
- <hint type="sourcelabel" >
+ <hint type="sourcelabel">
<x>259</x>
<y>196</y>
</hint>
- <hint type="destinationlabel" >
+ <hint type="destinationlabel">
<x>64</x>
<y>188</y>
</hint>
diff --git a/tools/qvfb/pda.qrc b/tools/qvfb/pda.qrc
deleted file mode 100644
index b14e7b3..0000000
--- a/tools/qvfb/pda.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource prefix="/skins">
- <file>pda.skin</file>
-</qresource>
-</RCC>
diff --git a/tools/qvfb/pda.skin b/tools/qvfb/pda.skin
deleted file mode 100644
index 037f750..0000000
--- a/tools/qvfb/pda.skin
+++ /dev/null
@@ -1,14 +0,0 @@
-pda_up.png pda_down.png
-57 81
-240 320
-11
-"Power" 0x0100000a 277 36 302 57
-"F1" 0x01000030 52 439 81 470
-"F2" 0x01000031 101 422 130 451
-"F3" 0x01000032 232 423 260 452
-"F4" 0x01000033 279 445 309 473
-"Left" 0x01000012 155 438 176 472
-"Down" 0x01000015 169 471 203 486
-"Right" 0x01000014 193 448 215 472
-"Up" 0x01000013 166 427 199 451
-"Enter" 0x01000005 177 448 193 468
diff --git a/tools/qvfb/pda_down.png b/tools/qvfb/pda_down.png
deleted file mode 100644
index 0ea157d..0000000
--- a/tools/qvfb/pda_down.png
+++ /dev/null
Binary files differ
diff --git a/tools/qvfb/qvfb.cpp b/tools/qvfb/qvfb.cpp
index 073124d..6f89ece 100644
--- a/tools/qvfb/qvfb.cpp
+++ b/tools/qvfb/qvfb.cpp
@@ -635,6 +635,7 @@ void QVFb::configure()
config->touchScreen->setChecked(view->touchScreenEmulation());
config->lcdScreen->setChecked(view->lcdScreenEmulation());
chooseDepth(view->displayDepth(), view->displayFormat());
+ config->rgbSwapped->setChecked(view->rgbSwapped());
connect(config->skin, SIGNAL(activated(int)), this, SLOT(skinConfigChosen(int)));
if ( view->gammaRed() == view->gammaGreen() && view->gammaGreen() == view->gammaBlue() ) {
config->gammaslider->setValue(int(view->gammaRed()*400));
@@ -678,6 +679,8 @@ void QVFb::configure()
int d;
if ( config->depth_1->isChecked() )
d=1;
+ else if ( config->depth_2gray->isChecked() )
+ d=2;
else if ( config->depth_4gray->isChecked() )
d=4;
else if ( config->depth_8->isChecked() )
@@ -708,6 +711,16 @@ void QVFb::configure()
}
view->setViewFormat(displayFormat);
view->setTouchscreenEmulation( config->touchScreen->isChecked() );
+ if (view->rgbSwapped() != config->rgbSwapped->isChecked()) {
+ //### the windowTitle logic is inside init(), and init isn't always invoked
+ QString caption = windowTitle();
+ if (!config->rgbSwapped->isChecked())
+ caption.replace(QLatin1String(" BGR"), QString());
+ else
+ caption.append(QLatin1String(" BGR"));
+ setWindowTitle(caption);
+ view->setRgbSwapped(config->rgbSwapped->isChecked());
+ }
bool lcdEmulation = config->lcdScreen->isChecked();
view->setLcdScreenEmulation( lcdEmulation );
if ( lcdEmulation )
@@ -741,6 +754,7 @@ void QVFb::chooseSize(const QSize& sz)
void QVFb::chooseDepth(int depth, QVFbView::PixelFormat displayFormat)
{
config->depth_1->setChecked(depth==1);
+ config->depth_2gray->setChecked(depth==2);
config->depth_4gray->setChecked(depth==4);
config->depth_8->setChecked(depth==8);
config->depth_12->setChecked(depth==12);
diff --git a/tools/qvfb/qvfb.pro b/tools/qvfb/qvfb.pro
index a3b55ab..247337a 100644
--- a/tools/qvfb/qvfb.pro
+++ b/tools/qvfb/qvfb.pro
@@ -60,14 +60,4 @@ unix:x11 {
LIBS += -lXtst
}
-RESOURCES += qvfb.qrc \
- ClamshellPhone.qrc \
- PDAPhone.qrc \
- SmartPhone2.qrc \
- SmartPhone.qrc \
- SmartPhoneWithButtons.qrc \
- TouchscreenPhone.qrc \
- Trolltech-Keypad.qrc \
- Trolltech-Touchscreen.qrc \
- PortableMedia.qrc
-
+RESOURCES += qvfb.qrc
diff --git a/tools/qvfb/qvfbview.cpp b/tools/qvfb/qvfbview.cpp
index 25e93e0..c00c554 100644
--- a/tools/qvfb/qvfbview.cpp
+++ b/tools/qvfb/qvfbview.cpp
@@ -89,7 +89,7 @@ QVFbAbstractView::~QVFbAbstractView()
QVFbView::QVFbView(int id, int w, int h, int d, Rotation r, QWidget *parent)
: QVFbAbstractView(parent),
- viewdepth(d), viewFormat(DefaultFormat), rsh(0), gsh(0), bsh(0), rmax(15), gmax(15), bmax(15),
+ viewdepth(d), viewFormat(DefaultFormat), rgb_swapped(0), rsh(0), gsh(0), bsh(0), rmax(15), gmax(15), bmax(15),
contentsWidth(w), contentsHeight(h), gred(1.0), ggreen(1.0), gblue(1.0),
gammatable(0), refreshRate(30), animation(0),
hzm(0.0), vzm(0.0), mView(0),
@@ -457,6 +457,67 @@ QImage QVFbView::getBuffer(const QRect &r, int &leading) const
}
break;
}
+
+ case 2: {
+ if (requiredSize > buffer.size())
+ buffer.resize(requiredSize);
+
+ // XXX: hw: replace by drawhelper functionality
+
+ const int pixelsPerByte = 4;
+ quint8 *src = reinterpret_cast<quint8*>(mView->data())
+ + r.y() * mView->linestep() + r.x() / pixelsPerByte;
+ const int align = qMin(r.width(), (4 - (r.x() & 3)) & 3);
+ const int doAlign = (align > 0 ? 1 : 0);
+ const int tail = qMin(r.width(), (r.width() - align) & 3);
+ const int doTail = (tail > 0 ? 1 : 0);
+ const int width8 = (r.width() - align) / pixelsPerByte;
+ const int stride = mView->linestep() - (width8 + doAlign);
+
+ uchar *b = reinterpret_cast<uchar*>(buffer.data());
+ img = QImage(b, r.width(), r.height(), QImage::Format_RGB32);
+ for (int y = 0; y < r.height(); ++y) {
+ quint32 *dest = reinterpret_cast<quint32*>(img.scanLine(y));
+ quint8 c;
+
+ if (doAlign) {
+ switch (align) {
+ case 3: c = ((*src & 0x30) >> 4) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ case 2: c = ((*src & 0x0c) >> 2) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ case 1: c = ((*src & 0x03)) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ }
+ ++src;
+ }
+ for (int i = 0; i < width8; ++i) {
+ c = ((*src & 0xc0) >> 6) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x30) >> 4) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x0c) >> 2) * 0x55;
+ *dest++ = qRgb(c, c, c);
+ c = ((*src & 0x03)) * 0x55;
+ *dest++ = qRgb(c, c, c);
+
+ ++src;
+ }
+ if (doTail) {
+ switch (tail) {
+ case 3: c = ((*src & 0x0c) >> 2) * 0x55;
+ dest[2] = qRgb(c, c, c);
+ case 2: c = ((*src & 0x30) >> 4) * 0x55;
+ dest[1] = qRgb(c, c, c);
+ case 1: c = ((*src & 0xc0) >> 6) * 0x55;
+ dest[0] = qRgb(c, c, c);
+ }
+ }
+ src += stride;
+ }
+ break;
+ }
+
case 4: {
if (requiredSize > buffer.size())
buffer.resize(requiredSize);
@@ -540,6 +601,9 @@ QImage QVFbView::getBuffer(const QRect &r, int &leading) const
break;
}
+ if (rgb_swapped)
+ img = img.rgbSwapped();
+
if ( brightness != 255 ) {
if (img.format() == QImage::Format_Indexed8) {
QVector<QRgb> c = img.colorTable();
diff --git a/tools/qvfb/qvfbview.h b/tools/qvfb/qvfbview.h
index 4893830..cd6fc89 100644
--- a/tools/qvfb/qvfbview.h
+++ b/tools/qvfb/qvfbview.h
@@ -77,6 +77,7 @@ public:
virtual int displayHeight() const = 0;
virtual int displayDepth() const = 0;
virtual PixelFormat displayFormat() const { return DefaultFormat; }
+ virtual bool rgbSwapped() const { return false; }
virtual Rotation displayRotation() const = 0;
virtual void setGamma(double gr, double gg, double gb) = 0;
@@ -105,6 +106,7 @@ public slots:
virtual void skinKeyPressEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
virtual void skinKeyReleaseEvent( int code, const QString& text, bool autorep=FALSE ) = 0;
virtual void setViewFormat(PixelFormat) {}
+ virtual void setRgbSwapped( bool ) {};
virtual void embedDisplay(WId) {}
};
@@ -120,6 +122,7 @@ public:
int displayHeight() const;
int displayDepth() const;
PixelFormat displayFormat() const;
+ bool rgbSwapped() const { return rgb_swapped; }
Rotation displayRotation() const;
bool touchScreenEmulation() const { return emulateTouchscreen; }
@@ -151,6 +154,7 @@ public slots:
void skinKeyPressEvent(int code, const QString& text, bool autorep=FALSE);
void skinKeyReleaseEvent(int code, const QString& text, bool autorep=FALSE);
void setViewFormat(PixelFormat);
+ void setRgbSwapped(bool b) { rgb_swapped = b; }
#ifdef Q_WS_X11
void embedDisplay(WId id);
#endif
@@ -180,6 +184,7 @@ private:
void setDirty(const QRect&);
int viewdepth; // "faked" depth
PixelFormat viewFormat;
+ bool rgb_swapped;
int rsh;
int gsh;
int bsh;
diff --git a/tools/shared/deviceskin/deviceskin.pri b/tools/shared/deviceskin/deviceskin.pri
index e4c9ef7..2552c92 100644
--- a/tools/shared/deviceskin/deviceskin.pri
+++ b/tools/shared/deviceskin/deviceskin.pri
@@ -1,3 +1,15 @@
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/qvfb/ClamshellPhone.qrc b/tools/shared/deviceskin/skins/ClamshellPhone.qrc
index 39cd422..39cd422 100644
--- a/tools/qvfb/ClamshellPhone.qrc
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.qrc
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
index cb24a8e..cb24a8e 100644
--- a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone.skin
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone.skin
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
index 88ba3a1..88ba3a1 100644
--- a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-closed.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
index 971cdef..971cdef 100644
--- a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5-pressed.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
index f3550ee..f3550ee 100644
--- a/tools/qvfb/ClamshellPhone.skin/ClamshellPhone1-5.png
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.skin/ClamshellPhone1-5.png
Binary files differ
diff --git a/tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
index e349dbc..e349dbc 100644
--- a/tools/qvfb/ClamshellPhone.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/ClamshellPhone.skin/defaultbuttons.conf
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png
index d62ef4a..d62ef4a 100644
--- a/tools/qvfb/DualScreenPhone.skin/DualScreen-pressed.png
+++ b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen-pressed.png
Binary files differ
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreen.png b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png
index cb3d1a7..cb3d1a7 100644
--- a/tools/qvfb/DualScreenPhone.skin/DualScreen.png
+++ b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreen.png
Binary files differ
diff --git a/tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin
index a82ef23..a82ef23 100644
--- a/tools/qvfb/DualScreenPhone.skin/DualScreenPhone.skin
+++ b/tools/shared/deviceskin/skins/DualScreenPhone.skin/DualScreenPhone.skin
diff --git a/tools/qvfb/SmartPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf
index 1103350..1103350 100644
--- a/tools/qvfb/SmartPhone.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/DualScreenPhone.skin/defaultbuttons.conf
diff --git a/tools/qvfb/PDAPhone.qrc b/tools/shared/deviceskin/skins/PDAPhone.qrc
index 1a1c35a..1a1c35a 100644
--- a/tools/qvfb/PDAPhone.qrc
+++ b/tools/shared/deviceskin/skins/PDAPhone.qrc
diff --git a/tools/qvfb/PDAPhone.skin/PDAPhone.skin b/tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin
index d6a1966..d6a1966 100644
--- a/tools/qvfb/PDAPhone.skin/PDAPhone.skin
+++ b/tools/shared/deviceskin/skins/PDAPhone.skin/PDAPhone.skin
diff --git a/tools/qvfb/PDAPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf
index e3ae813..e3ae813 100644
--- a/tools/qvfb/PDAPhone.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/PDAPhone.skin/defaultbuttons.conf
diff --git a/tools/qvfb/PDAPhone.skin/finger.png b/tools/shared/deviceskin/skins/PDAPhone.skin/finger.png
index 24cf0cb..24cf0cb 100644
--- a/tools/qvfb/PDAPhone.skin/finger.png
+++ b/tools/shared/deviceskin/skins/PDAPhone.skin/finger.png
Binary files differ
diff --git a/tools/qvfb/PDAPhone.skin/pda_down.png b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png
index f65c059..f65c059 100644
--- a/tools/qvfb/PDAPhone.skin/pda_down.png
+++ b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_down.png
Binary files differ
diff --git a/tools/qvfb/pda_up.png b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png
index 541e3c4..541e3c4 100644
--- a/tools/qvfb/pda_up.png
+++ b/tools/shared/deviceskin/skins/PDAPhone.skin/pda_up.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.qrc b/tools/shared/deviceskin/skins/PortableMedia.qrc
index a902f1a..a902f1a 100644
--- a/tools/qvfb/PortableMedia.qrc
+++ b/tools/shared/deviceskin/skins/PortableMedia.qrc
diff --git a/tools/qvfb/PortableMedia.skin/PortableMedia.skin b/tools/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
index b76e5cf..b76e5cf 100644
--- a/tools/qvfb/PortableMedia.skin/PortableMedia.skin
+++ b/tools/shared/deviceskin/skins/PortableMedia.skin/PortableMedia.skin
diff --git a/tools/qvfb/PortableMedia.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
index 514e881..514e881 100644
--- a/tools/qvfb/PortableMedia.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/PortableMedia.skin/defaultbuttons.conf
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia-pressed.png b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
index 730e762..730e762 100644
--- a/tools/qvfb/PortableMedia.skin/portablemedia-pressed.png
+++ b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia-pressed.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia.png b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
index e44cbe1..e44cbe1 100644
--- a/tools/qvfb/PortableMedia.skin/portablemedia.png
+++ b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.png
Binary files differ
diff --git a/tools/qvfb/PortableMedia.skin/portablemedia.xcf b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
index 127e07c..127e07c 100644
--- a/tools/qvfb/PortableMedia.skin/portablemedia.xcf
+++ b/tools/shared/deviceskin/skins/PortableMedia.skin/portablemedia.xcf
Binary files differ
diff --git a/tools/shared/deviceskin/skins/S60-QVGA-Candybar.qrc b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
new file mode 100644
index 0000000..8138484
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-QVGA-Candybar.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
new file mode 100644
index 0000000..89d40cb
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar-down.png
Binary files differ
diff --git a/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
new file mode 100644
index 0000000..0d0e598
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.png
Binary files differ
diff --git a/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
new file mode 100644
index 0000000..4f8fe5d
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/S60-QVGA-Candybar.skin
@@ -0,0 +1,15 @@
+[SkinFile]
+Up=S60-QVGA-Candybar.png
+Down=S60-QVGA-Candybar-down.png
+Screen=61 93 240 320
+Areas=7
+HasMouseHover=false
+
+
+"Context1" 0x01100000 54 469 151 469 140 483 88 485 81 496 54 498
+"Back" 0x01000061 211 468 307 467 307 498 278 497 219 486
+"Select" 0x01010000 165 491 196 522
+"Left" 0x1000012 149 474 166 492 163 519 143 538 142 481
+"Down" 0x1000015 164 521 195 522 212 539 204 545 154 544 145 536
+"Right" 0x1000014 214 475 219 487 219 528 212 539 196 522 197 492
+"Up" 0x1000013 150 474 156 467 209 467 213 476 197 489 165 489
diff --git a/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
new file mode 100644
index 0000000..e349dbc
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-QVGA-Candybar.skin/defaultbuttons.conf
@@ -0,0 +1,78 @@
+[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=Flip
+Key4=Backspace
+[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/S60-nHD-Touchscreen.qrc b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
new file mode 100644
index 0000000..daf0cc3
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.qrc
@@ -0,0 +1,5 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/skins">
+ <file>S60-nHD-Touchscreen.skin</file>
+</qresource>
+</RCC>
diff --git a/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
new file mode 100644
index 0000000..7253e38
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen-down.png
Binary files differ
diff --git a/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
new file mode 100644
index 0000000..675563e
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.png
Binary files differ
diff --git a/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
new file mode 100644
index 0000000..ed25d0e
--- /dev/null
+++ b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/S60-nHD-Touchscreen.skin
@@ -0,0 +1,10 @@
+[SkinFile]
+Up=S60-nHD-Touchscreen.png
+Down=S60-nHD-Touchscreen-down.png
+Screen=53 183 360 640
+Areas=3
+HasMouseHover=false
+
+"Call" 0x01100004 76 874 171 899
+"Hangup" 0x01100005 300 876 393 899
+"Home" 0x1000010 174 878 298 899
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
index 6665125..6665125 100644
--- a/tools/qvfb/Trolltech-Touchscreen.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/S60-nHD-Touchscreen.skin/defaultbuttons.conf
diff --git a/tools/qvfb/SmartPhone.qrc b/tools/shared/deviceskin/skins/SmartPhone.qrc
index 8bb5325..8bb5325 100644
--- a/tools/qvfb/SmartPhone.qrc
+++ b/tools/shared/deviceskin/skins/SmartPhone.qrc
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
index d0db2ed..d0db2ed 100644
--- a/tools/qvfb/SmartPhone.skin/SmartPhone-pressed.png
+++ b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone.png b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
index e6ac5a0..e6ac5a0 100644
--- a/tools/qvfb/SmartPhone.skin/SmartPhone.png
+++ b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone.skin/SmartPhone.skin b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
index 2f44c5a..2f44c5a 100644
--- a/tools/qvfb/SmartPhone.skin/SmartPhone.skin
+++ b/tools/shared/deviceskin/skins/SmartPhone.skin/SmartPhone.skin
diff --git a/tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
index 1103350..1103350 100644
--- a/tools/qvfb/DualScreenPhone.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/SmartPhone.skin/defaultbuttons.conf
diff --git a/tools/qvfb/SmartPhone2.qrc b/tools/shared/deviceskin/skins/SmartPhone2.qrc
index 751e985..751e985 100644
--- a/tools/qvfb/SmartPhone2.qrc
+++ b/tools/shared/deviceskin/skins/SmartPhone2.qrc
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
index d4eb5b0..d4eb5b0 100644
--- a/tools/qvfb/SmartPhone2.skin/SmartPhone2-pressed.png
+++ b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2.png b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
index 48ccc1c..48ccc1c 100644
--- a/tools/qvfb/SmartPhone2.skin/SmartPhone2.png
+++ b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.png
Binary files differ
diff --git a/tools/qvfb/SmartPhone2.skin/SmartPhone2.skin b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
index 16884bf..16884bf 100644
--- a/tools/qvfb/SmartPhone2.skin/SmartPhone2.skin
+++ b/tools/shared/deviceskin/skins/SmartPhone2.skin/SmartPhone2.skin
diff --git a/tools/qvfb/SmartPhone2.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
index b083203..b083203 100644
--- a/tools/qvfb/SmartPhone2.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/SmartPhone2.skin/defaultbuttons.conf
diff --git a/tools/qvfb/SmartPhoneWithButtons.qrc b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
index f3393ba..f3393ba 100644
--- a/tools/qvfb/SmartPhoneWithButtons.qrc
+++ b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.qrc
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
index 456a068..456a068 100644
--- a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
+++ b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons-pressed.png
Binary files differ
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
index 5ffbd6e..5ffbd6e 100644
--- a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
+++ b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.png
Binary files differ
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
index 9afa67f..9afa67f 100644
--- a/tools/qvfb/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
+++ b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/SmartPhoneWithButtons.skin
diff --git a/tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
index ebd6926..ebd6926 100644
--- a/tools/qvfb/SmartPhoneWithButtons.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/SmartPhoneWithButtons.skin/defaultbuttons.conf
diff --git a/tools/qvfb/TouchscreenPhone.qrc b/tools/shared/deviceskin/skins/TouchscreenPhone.qrc
index 023144d..023144d 100644
--- a/tools/qvfb/TouchscreenPhone.qrc
+++ b/tools/shared/deviceskin/skins/TouchscreenPhone.qrc
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
index 01acb86..01acb86 100644
--- a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
+++ b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone-pressed.png
Binary files differ
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
index e90de0d..e90de0d 100644
--- a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.png
+++ b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.png
Binary files differ
diff --git a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
index 24316a1..24316a1 100644
--- a/tools/qvfb/TouchscreenPhone.skin/TouchscreenPhone.skin
+++ b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/TouchscreenPhone.skin
diff --git a/tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
index a13dfdc..a13dfdc 100644
--- a/tools/qvfb/TouchscreenPhone.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/TouchscreenPhone.skin/defaultbuttons.conf
diff --git a/tools/qvfb/Trolltech-Keypad.qrc b/tools/shared/deviceskin/skins/Trolltech-Keypad.qrc
index 4775068..4775068 100644
--- a/tools/qvfb/Trolltech-Keypad.qrc
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.qrc
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
index 8dd5719..8dd5719 100644
--- a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-closed.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
index 5e1e6be..5e1e6be 100644
--- a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad-down.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png
index fb3d549..fb3d549 100644
--- a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.png
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin
index 4d90321..4d90321 100644
--- a/tools/qvfb/Trolltech-Keypad.skin/Trolltech-Keypad.skin
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/Trolltech-Keypad.skin
diff --git a/tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf
index 6a78e67..6a78e67 100644
--- a/tools/qvfb/Trolltech-Keypad.skin/defaultbuttons.conf
+++ b/tools/shared/deviceskin/skins/Trolltech-Keypad.skin/defaultbuttons.conf
diff --git a/tools/qvfb/Trolltech-Touchscreen.qrc b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc
index 40fafeb..40fafeb 100644
--- a/tools/qvfb/Trolltech-Touchscreen.qrc
+++ b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.qrc
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
index c1a422f..c1a422f 100644
--- a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
+++ b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen-down.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
index 544a425..544a425 100644
--- a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
+++ b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.png
Binary files differ
diff --git a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
index 5de882e..5de882e 100644
--- a/tools/qvfb/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
+++ b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/Trolltech-Touchscreen.skin
diff --git a/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf
new file mode 100644
index 0000000..6665125
--- /dev/null
+++ b/tools/shared/deviceskin/skins/Trolltech-Touchscreen.skin/defaultbuttons.conf
@@ -0,0 +1,53 @@
+[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/qtgradienteditor/qtgradientdialog.cpp b/tools/shared/qtgradienteditor/qtgradientdialog.cpp
index 9605403..6c2deff 100644
--- a/tools/shared/qtgradienteditor/qtgradientdialog.cpp
+++ b/tools/shared/qtgradienteditor/qtgradientdialog.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QtGradientDialog
-*/
-
#include "qtgradientdialog.h"
#include "ui_qtgradientdialog.h"
#include <QtGui/QPushButton>
diff --git a/tools/shared/qtgradienteditor/qtgradienteditor.cpp b/tools/shared/qtgradienteditor/qtgradienteditor.cpp
index 0671176..76562c4 100644
--- a/tools/shared/qtgradienteditor/qtgradienteditor.cpp
+++ b/tools/shared/qtgradienteditor/qtgradienteditor.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QtGradientEditor
-*/
-
#include "qtgradienteditor.h"
#include "qtgradientstopscontroller.h"
#include "ui_qtgradienteditor.h"
diff --git a/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp b/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp
index 35e77e8..4e6639a 100644
--- a/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp
+++ b/tools/shared/qtgradienteditor/qtgradientstopscontroller.cpp
@@ -39,10 +39,6 @@
**
****************************************************************************/
-/*
-TRANSLATOR qdesigner_internal::QtGradientStopsController
-*/
-
#include "qtgradientstopscontroller.h"
#include "ui_qtgradienteditor.h"
#include "qtgradientstopsmodel.h"
diff --git a/tools/shared/qttoolbardialog/qttoolbardialog.cpp b/tools/shared/qttoolbardialog/qttoolbardialog.cpp
index e1c92b8..c313709 100644
--- a/tools/shared/qttoolbardialog/qttoolbardialog.cpp
+++ b/tools/shared/qttoolbardialog/qttoolbardialog.cpp
@@ -637,10 +637,10 @@ QToolBar *QtFullToolBarManager::createToolBar(const QString &toolBarName)
return 0;
QToolBar *toolBar = new QToolBar(toolBarName, mainWindow());
int i = 1;
- const QString prefix = QLatin1String("_Custom_Toolbar_");
- QString name = QString(QLatin1String("%1%2")).arg(prefix).arg(i);
+ const QString prefix = QLatin1String("_Custom_Toolbar_%1");
+ QString name = prefix.arg(i);
while (d_ptr->toolBarByName(name))
- name = QString(QLatin1String("%1%2")).arg(prefix).arg(++i);
+ name = prefix.arg(++i);
toolBar->setObjectName(name);
mainWindow()->addToolBar(toolBar);
d_ptr->customToolBars.append(toolBar);
diff --git a/tools/tools.pro b/tools/tools.pro
index 3325a57..d034dcd 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -22,6 +22,8 @@ mac {
SUBDIRS += macdeployqt
}
+embedded:SUBDIRS += kmap2qmap
+
contains(QT_CONFIG, dbus):SUBDIRS += qdbus
!wince*:contains(QT_CONFIG, xmlpatterns): SUBDIRS += xmlpatterns
embedded: SUBDIRS += makeqpf
diff --git a/tools/xmlpatterns/main.cpp b/tools/xmlpatterns/main.cpp
index a5c2c41..2405d5d 100644
--- a/tools/xmlpatterns/main.cpp
+++ b/tools/xmlpatterns/main.cpp
@@ -194,7 +194,7 @@ protected:
/* If we don't open stdout in "binary" mode on Windows, it will translate
* 0xA into 0xD 0xA. See Trolltech task 173619, for an example. */
_setmode(_fileno(stdout), _O_BINARY);
- m_stdout = QT_WA_INLINE(_wfdopen(_fileno(stdout), L"wb"),_fdopen(_fileno(stdout), "wb"));
+ m_stdout = _wfdopen(_fileno(stdout), L"wb");
out->open(m_stdout, QIODevice::WriteOnly);
#else
out->open(stdout, QIODevice::WriteOnly);