summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/assistant/tools/assistant/mainwindow.cpp2
-rw-r--r--tools/configure/configureapp.cpp59
-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.cpp4
-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/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/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/designer/qdesigner_actions.cpp2
-rw-r--r--tools/designer/src/lib/sdk/abstractformeditor.cpp12
-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/orderdialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/plaintexteditor.cpp4
-rw-r--r--tools/designer/src/lib/shared/pluginmanager.cpp122
-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_promotiondialog.cpp4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_propertyeditor.cpp104
-rw-r--r--tools/designer/src/lib/shared/qdesigner_taskmenu.cpp4
-rw-r--r--tools/designer/src/lib/shared/qdesigner_toolbar.cpp21
-rw-r--r--tools/designer/src/lib/shared/qdesigner_widgetbox.cpp4
-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/ui4.cpp245
-rw-r--r--tools/designer/src/lib/uilib/ui4_p.h97
-rw-r--r--tools/kmap2qmap/kmap2qmap.pro12
-rw-r--r--tools/kmap2qmap/main.cpp991
-rw-r--r--tools/linguist/lconvert/main.cpp19
-rw-r--r--tools/linguist/linguist/main.cpp13
-rw-r--r--tools/linguist/linguist/messageeditor.cpp2
-rw-r--r--tools/linguist/linguist/phrasebookbox.cpp6
-rw-r--r--tools/linguist/lrelease/main.cpp1
-rw-r--r--tools/linguist/lupdate/cpp.cpp1818
-rw-r--r--tools/linguist/lupdate/java.cpp (renamed from tools/linguist/shared/java.cpp)35
-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.cpp113
-rw-r--r--tools/linguist/lupdate/merge.cpp (renamed from tools/linguist/shared/translatortools.cpp)2
-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/shared/cpp.cpp1081
-rw-r--r--tools/linguist/shared/formats.pri4
-rwxr-xr-xtools/linguist/shared/make-qscript.sh14
-rw-r--r--tools/linguist/shared/profileevaluator.cpp983
-rw-r--r--tools/linguist/shared/profileevaluator.h5
-rw-r--r--tools/linguist/shared/proparserutils.h47
-rw-r--r--tools/linguist/shared/translator.h9
-rw-r--r--tools/linguist/shared/translatortools.pri11
-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/qdoc3/htmlgenerator.cpp872
-rw-r--r--tools/qdoc3/htmlgenerator.h30
-rw-r--r--tools/qdoc3/test/assistant.qdocconf2
-rw-r--r--tools/qdoc3/test/classic.css64
-rw-r--r--tools/qdoc3/test/designer.qdocconf2
-rw-r--r--tools/qdoc3/test/linguist.qdocconf2
-rw-r--r--tools/qdoc3/test/qmake.qdocconf2
-rw-r--r--tools/qdoc3/test/qt-build-docs.qdocconf6
-rw-r--r--tools/qdoc3/test/qt.qdocconf6
-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/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/tools.pro2
196 files changed, 8176 insertions, 3259 deletions
diff --git a/tools/assistant/tools/assistant/mainwindow.cpp b/tools/assistant/tools/assistant/mainwindow.cpp
index 582eef3..1db3bc2 100644
--- a/tools/assistant/tools/assistant/mainwindow.cpp
+++ b/tools/assistant/tools/assistant/mainwindow.cpp
@@ -412,7 +412,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"));
diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp
index 91344c8..8fd8c0a 100644
--- a/tools/configure/configureapp.cpp
+++ b/tools/configure/configureapp.cpp
@@ -314,7 +314,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";
@@ -824,11 +823,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";
@@ -1322,7 +1317,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";
@@ -1421,7 +1415,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>] [-no-phonon] [-phonon]\n"
"[-no-phonon-backend] [-phonon-backend]\n"
@@ -1588,7 +1582,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");
@@ -1834,47 +1827,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");
@@ -1968,8 +1920,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")
@@ -2294,9 +2244,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")
@@ -2678,7 +2625,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";
@@ -2939,7 +2885,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/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 f5c93fa..43348d2 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 98fff8c..9319916 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 68a6030..cf7f250 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 bf3f3f1..1a41985 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 48efcde..07d785a 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"
diff --git a/tools/designer/src/components/formeditor/formwindowcursor.cpp b/tools/designer/src/components/formeditor/formwindowcursor.cpp
index 5b4aee1..fb30885 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 69fb4a3..ea8d128 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/tool_widgeteditor.cpp b/tools/designer/src/components/formeditor/tool_widgeteditor.cpp
index 3a59543..aed7e80 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 4e515be..cb90d2a 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 bc1ac0c..1e20ec3 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 346da18..1dd5bd6 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 b0dc82b..4c60941 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 d7a76b9..c425e18 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 95d533d..e94ace0 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 806e1dd..eab7a12 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 440015c..32a8c78 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/signalsloteditor_plugin.cpp b/tools/designer/src/components/signalsloteditor/signalsloteditor_plugin.cpp
index 311c843..a6f4969 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 973105c..311ec36 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 dc6b3c3..c916af8 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 46bf378..abe882b 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 4f291a1..75304ee 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 ced32ce..c2816a2 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 e3364cc..908cb61 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 b182ddf..c6673e3 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 bb97342..18b6612 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 77e5ed9..f85df33 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 4a3aeec..0bfe607 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 baf4785..a88246a 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 1a9ba36..10e004d 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 2a8de52..4c3ede9 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 52320ac..093a1fe 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 5ef1f9c..dce9f97 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 0863847..be1f89a 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 feaec2c..a9a2a96 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 a15cd8a..d841b87 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 b1c8c28..34d883a 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 faf00f2..e97ebde 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/designer/qdesigner_actions.cpp b/tools/designer/src/designer/qdesigner_actions.cpp
index 65e5937..d5d01f4 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/lib/sdk/abstractformeditor.cpp b/tools/designer/src/lib/sdk/abstractformeditor.cpp
index 17e93e7..09d6976 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/shared/actioneditor.cpp b/tools/designer/src/lib/shared/actioneditor.cpp
index 7f96a15..e60b212 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 5a2db33..0b18f5e 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 d5e045b..f7144c5 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 b569b51..377ae43 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/orderdialog.cpp b/tools/designer/src/lib/shared/orderdialog.cpp
index 3f14ca6..0df3866 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 ce5cd5b..f30df3d 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 9dc8c7b..100a088 100644
--- a/tools/designer/src/lib/shared/pluginmanager.cpp
+++ b/tools/designer/src/lib/shared/pluginmanager.cpp
@@ -16,6 +16,8 @@
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
+What usually causes this mess is specifying a Z-order (raise/lower) widget or changing the tab order and then deleting the widget. Designer did not delete the widget from those settings, causing uic to report this when applying them. I believe we fixed that 4.5.
+
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
@@ -72,6 +74,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 +148,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 +163,7 @@ public:
QString xmlAddPageMethod;
QString xmlExtends;
+ StringPropertyTypeMap xmlStringPropertyTypeMap;
};
void QDesignerCustomWidgetSharedData::clearXML()
@@ -161,6 +173,7 @@ void QDesignerCustomWidgetSharedData::clearXML()
xmlLanguage.clear();
xmlAddPageMethod.clear();
xmlExtends.clear();
+ xmlStringPropertyTypeMap.clear();
}
// ---------------- QDesignerCustomWidgetData
@@ -220,6 +233,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 +273,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 +411,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 +437,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 +452,8 @@ QDesignerCustomWidgetData::ParseResult
class QDesignerPluginManagerPrivate {
public:
+ typedef QPair<QString, QString> ClassNamePropertyNameKey;
+
QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core);
void clearCustomWidgets();
@@ -562,7 +671,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 +763,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 e374f42..f73bc74 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 2cf362f..2b45759 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 8ed1772..ac16741 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 77d0bbb..1df9cbe 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_promotiondialog.cpp b/tools/designer/src/lib/shared/qdesigner_promotiondialog.cpp
index 8453c16..a1c47d2 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 7c7d9d7..3875d0e 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_taskmenu.cpp b/tools/designer/src/lib/shared/qdesigner_taskmenu.cpp
index cce0528..d85e18f 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 cb77801..0bb91ee 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*)
@@ -447,9 +442,19 @@ QAction *ToolBarEventFilter::actionAt(const QToolBar *tb, const QPoint &pos)
QRect ToolBarEventFilter::handleArea(const QToolBar *tb)
{
- const QToolBarLayout *tbl = qobject_cast<QToolBarLayout *>(tb->layout());
- Q_ASSERT(tbl);
- return tbl->handleRect();
+ //that's a trick to get acces to the initStyleOption which is a protected member
+ class FriendlyToolBar : public QToolBar
+ {
+ public:
+#ifdef Q_NO_USING_KEYWORD
+ void initStyleOption(QStyleOptionToolBar *option) { QToolBar::initStyleOption(option); }
+#else
+ using QToolBar::initStyleOption;
+#endif
+ };
+ 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 5ba8ad7..d94a397 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/qtresourceview.cpp b/tools/designer/src/lib/shared/qtresourceview.cpp
index d956491..2b59605 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 33162c5..f78c5af 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 8aa036b..42cf449 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 616f0c9..ef4d08f 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 c4a7e07..326cba2 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 2056fcf..de64135 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 3822fec..56a1744 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 f4ab48e..a404dcb 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 fe850f7..92c857e 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/ui4.cpp b/tools/designer/src/lib/uilib/ui4.cpp
index 2047739..72c7f50 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 df02a39..fa70573 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/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..12d91c6
--- /dev/null
+++ b/tools/kmap2qmap/main.cpp
@@ -0,0 +1,991 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $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 9ccc60e..bdc6c9a 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"
@@ -93,7 +88,7 @@ static int usage(const QStringList &args)
" 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"
@@ -109,7 +104,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;
}
diff --git a/tools/linguist/linguist/main.cpp b/tools/linguist/linguist/main.cpp
index 018fbc5..a6a0d27 100644
--- a/tools/linguist/linguist/main.cpp
+++ b/tools/linguist/linguist/main.cpp
@@ -80,12 +80,15 @@ 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"));
diff --git a/tools/linguist/linguist/messageeditor.cpp b/tools/linguist/linguist/messageeditor.cpp
index 53cbbea..fb2fb1d 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.
*/
diff --git a/tools/linguist/linguist/phrasebookbox.cpp b/tools/linguist/linguist/phrasebookbox.cpp
index 50749d7..d3bb937 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/lrelease/main.cpp b/tools/linguist/lrelease/main.cpp
index 3bcc998..7d0452f 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>
diff --git a/tools/linguist/lupdate/cpp.cpp b/tools/linguist/lupdate/cpp.cpp
new file mode 100644
index 0000000..42aa2f0
--- /dev/null
+++ b/tools/linguist/lupdate/cpp.cpp
@@ -0,0 +1,1818 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Qt 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 qt-sales@nokia.com.
+** $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 ";
+
+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 // 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; }
+
+private:
+ struct SavedState {
+ QStringList namespaces;
+ QStack<int> namespaceDepths;
+ QStringList functionContext;
+ QString functionContextUnresolved;
+ QString pendingContext;
+ };
+
+ 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, 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_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() && yyInStr[yyInPos].unicode() == '\n') {
+ ++yyCurLineNo;
+ ++yyInPos;
+ continue;
+ }
+ 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_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 '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;
+ 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\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;
+ yyTok = getToken();
+ }
+ 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, 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);
+ 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 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;
+ 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, utf8, plural);
+ }
+ extracomment.clear();
+ break;
+ case Tok_translateUtf8:
+ case Tok_translate:
+ if (!results->tor)
+ goto case_default;
+ 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, utf8, plural);
+ }
+ extracomment.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 {
+ 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, false, false);
+ }
+ }
+ }
+ 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();
+ 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 912a8d7..c8dbe5b 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>
@@ -600,14 +602,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;
@@ -615,7 +621,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;
@@ -625,7 +631,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();
@@ -637,19 +643,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/shared/translatortools.h b/tools/linguist/lupdate/lupdate.h
index 9eaf024..2f98643 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 b537b6e..8a70b55 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"
@@ -106,7 +107,10 @@ static void printUsage()
" -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"
" Default is absolute.\n"
@@ -216,7 +220,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;
@@ -343,6 +350,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;
@@ -387,33 +406,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;
@@ -421,6 +453,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) {
@@ -450,6 +485,8 @@ int main(int argc, char **argv)
continue;
}
+ cd.m_includePath += visitor.values(QLatin1String("INCLUDEPATH"));
+
evaluateProFile(visitor, &variables);
sourceFiles = variables.value("SOURCES");
@@ -472,27 +509,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 96301d5..c4f4448 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"
diff --git a/tools/linguist/shared/qscript.cpp b/tools/linguist/lupdate/qscript.cpp
index 7377cba..64adde6 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 8d33277..563974a 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 ff98a90..935cac4 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/shared/cpp.cpp b/tools/linguist/shared/cpp.cpp
deleted file mode 100644
index 2e137cf..0000000
--- a/tools/linguist/shared/cpp.cpp
+++ /dev/null
@@ -1,1081 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the Qt 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 qt-sales@nokia.com.
-** $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() && yyInStr[yyInPos].unicode() == '\n') {
- ++yyCurLineNo;
- ++yyInPos;
- continue;
- }
- 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;
- yyTok = getToken();
- }
- 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/profileevaluator.cpp b/tools/linguist/shared/profileevaluator.cpp
index 5440752..0be6bec 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
#else
@@ -66,6 +76,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
//
///////////////////////////////////////////////////////////////////////
@@ -75,6 +137,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();
@@ -87,6 +155,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);
@@ -102,6 +183,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);
@@ -113,7 +196,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);
@@ -122,41 +205,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)
@@ -167,8 +260,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;
@@ -192,71 +288,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()
@@ -455,15 +564,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;
}
@@ -471,12 +600,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;
}
@@ -489,12 +623,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;
}
@@ -503,18 +645,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;
}
@@ -524,12 +680,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);
@@ -547,8 +751,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(" ")));
@@ -581,37 +785,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;
}
@@ -628,40 +853,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;
}
@@ -781,7 +1006,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();
@@ -1018,29 +1243,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()));
@@ -1089,6 +1314,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."));
@@ -1108,9 +1343,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);
@@ -1181,8 +1416,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 {
@@ -1206,13 +1515,114 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun
ret += split_value_list(output);
}
}
- 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));
@@ -1233,26 +1643,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;
@@ -1264,7 +1715,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]);
@@ -1275,7 +1726,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;
@@ -1307,9 +1758,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;
}
@@ -1334,7 +1785,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];
@@ -1345,12 +1798,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) {
@@ -1364,13 +1819,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)
@@ -1387,7 +1845,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;
@@ -1396,7 +1855,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;
@@ -1411,31 +1871,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)
@@ -1444,32 +1911,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;
+ TCHAR name[1024];
+ if (GetComputerName(name, &name_length))
+ ret = QString::fromUtf16((ushort*)name, name_length);
+ } 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)
@@ -1540,7 +2106,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,
@@ -1650,14 +2222,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()
@@ -1669,6 +2250,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;
}
@@ -1713,18 +2296,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)
@@ -1732,6 +2317,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 beb16ea..ae1422a 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 8914a8e..c27c3c0 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);
}
diff --git a/tools/linguist/shared/translator.h b/tools/linguist/shared/translator.h
index 6b88b23..4e97000 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
@@ -85,7 +87,10 @@ 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;
@@ -178,7 +183,7 @@ 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);
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/macdeployqt/macchangeqt/main.cpp b/tools/macdeployqt/macchangeqt/main.cpp
index e94e8a3..ebdfc14 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 0026c40..5353688 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 1faa63a..3b9ba73 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 5f30dad..637873e 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/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp
index 13d52bf..d7770bb 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),
@@ -1928,40 +2049,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 +2162,35 @@ 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::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 border=\"0\" cellpadding=\"0\" "
+ << "cellspacing=\"0\">\n";
+ }
+ else {
+ if (twoColumn)
+ out() << "<p><table 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 +2200,60 @@ 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\" "
+ << "nowrap 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\"></div>";
+ }
- out() << "<li><div class=\"fn\"></div>";
if (style == CodeMarker::Accessors)
out() << "<b>";
- generateSynopsis(*m, relative, marker, style);
+ generateSynopsis(*m, relative, marker, style, name_alignment);
if (style == CodeMarker::Accessors)
out() << "</b>";
- out() << "</li>\n";
+ if (name_alignment)
+ out() << "</td></tr>\n";
+ else
+ out() << "</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 +2264,315 @@ 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>", "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, nameAlignment);
}
-QString HtmlGenerator::registerRef(const QString& ref)
+QString HtmlGenerator::highlightedCode(const QString& markedCode,
+ CodeMarker *marker,
+ const Node *relative,
+ 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");
+ for (int i = 0, n = src.size(); i < n;) {
+ if (src.at(i) == charLangle && src.at(i + 1).unicode() == '@') {
+ if (nameAlignment && (i != 0))
+ html += "&nbsp;</td><td class=\"memItemRight\" valign=\"bottom\">";
+ i += 2;
+ if (parseArg(src, linkTag, &i, n, &arg, &par1)) {
+ QString link = linkForNode(
+ CodeMarker::nodeForString(par1.toString()), relative);
+ addLink(link, arg, &html);
+ }
+ 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 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 +2735,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)
{
diff --git a/tools/qdoc3/htmlgenerator.h b/tools/qdoc3/htmlgenerator.h
index de64190..ec9532f 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,36 @@ 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 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,
+ 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 +180,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/test/assistant.qdocconf b/tools/qdoc3/test/assistant.qdocconf
index b6313fa..b82507f 100644
--- a/tools/qdoc3/test/assistant.qdocconf
+++ b/tools/qdoc3/test/assistant.qdocconf
@@ -17,7 +17,7 @@ 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.2 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 6cf7377..e53ea29 100644
--- a/tools/qdoc3/test/classic.css
+++ b/tools/qdoc3/test/classic.css
@@ -1,7 +1,29 @@
+BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
+ font-family: Geneva, Arial, Helvetica, sans-serif;
+}
+BODY,TD {
+ font-size: 90%;
+}
+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: #d5e1d5;
+ border-width: 1px;
+ border-style: solid;
+ border-color: #84b0c7;
+ font-weight: bold;
+ -moz-border-radius: 8px 8px 8px 8px;
+ padding: 6px 0px 6px 10px;
}
a:link
@@ -56,6 +78,44 @@ body
color: black
}
+table td.memItemLeft {
+ width: 200px;
+ padding: 1px 0px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #FAFAFA;
+ font-size: 80%;
+}
+table td.memItemRight {
+ padding: 1px 8px 0px 8px;
+ margin: 4px;
+ border-top-width: 1px;
+ border-right-width: 1px;
+ border-bottom-width: 1px;
+ border-left-width: 1px;
+ border-top-color: #E0E0E0;
+ border-right-color: #E0E0E0;
+ border-bottom-color: #E0E0E0;
+ border-left-color: #E0E0E0;
+ border-top-style: solid;
+ border-right-style: none;
+ border-bottom-style: none;
+ border-left-style: none;
+ background-color: #d5e1d5;
+ font-size: 80%;
+}
+
table tr.odd {
background: #f0f0f0;
color: black;
diff --git a/tools/qdoc3/test/designer.qdocconf b/tools/qdoc3/test/designer.qdocconf
index 8d9a49e..9c0790e 100644
--- a/tools/qdoc3/test/designer.qdocconf
+++ b/tools/qdoc3/test/designer.qdocconf
@@ -17,7 +17,7 @@ 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.2 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 177a54c..da49abe 100644
--- a/tools/qdoc3/test/linguist.qdocconf
+++ b/tools/qdoc3/test/linguist.qdocconf
@@ -17,7 +17,7 @@ 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.2 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 20b0acf..5e2cac7 100644
--- a/tools/qdoc3/test/qmake.qdocconf
+++ b/tools/qdoc3/test/qmake.qdocconf
@@ -17,7 +17,7 @@ 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.2 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 a05786b..3fbeb44 100644
--- a/tools/qdoc3/test/qt-build-docs.qdocconf
+++ b/tools/qdoc3/test/qt-build-docs.qdocconf
@@ -35,9 +35,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.2 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.2
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.2
+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.qdocconf b/tools/qdoc3/test/qt.qdocconf
index 964869c..1ec9b72 100644
--- a/tools/qdoc3/test/qt.qdocconf
+++ b/tools/qdoc3/test/qt.qdocconf
@@ -37,9 +37,9 @@ qhp.Qt.extraFiles = classic.css \
images/dynamiclayouts-example.png \
images/stylesheet-coffee-plastique.png
-qhp.Qt.filterAttributes = qt 4.5.2 qtrefdoc
-qhp.Qt.customFilters.Qt.name = Qt 4.5.2
-qhp.Qt.customFilters.Qt.filterAttributes = qt 4.5.2
+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/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..5abfe50
--- /dev/null
+++ b/tools/qtestlib/chart/database.cpp
@@ -0,0 +1,321 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $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..448a44f
--- /dev/null
+++ b/tools/qtestlib/chart/database.h
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the 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 qt-sales@nokia.com.
+** $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..9bb937c
--- /dev/null
+++ b/tools/qtestlib/chart/main.cpp
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $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..94661ba
--- /dev/null
+++ b/tools/qtestlib/chart/reportgenerator.cpp
@@ -0,0 +1,561 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (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 qt-sales@nokia.com.
+** $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..bb69d1a
--- /dev/null
+++ b/tools/qtestlib/chart/reportgenerator.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the 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 qt-sales@nokia.com.
+** $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/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 7a45bfe..82a3d38 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 62149a1..510f0eb 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 53a5360..e7c99ed 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 d533613..1d43bdc 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 032cb16..950a1d2 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 9eca9d8..42d7767 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 cbc53db..c9ef03b 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/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