From 87ac3a9444d1ce924a4b94958ff878e33209822f Mon Sep 17 00:00:00 2001 From: Kurt Kremitzki Date: Sat, 19 Dec 2020 20:26:09 +0000 Subject: [PATCH 1/1] Import pyside2_5.15.2.orig.tar.gz [dgit import orig pyside2_5.15.2.orig.tar.gz] --- .gitattributes | 15 + .gitignore | 152 + .gitmodules | 3 + .travis.yml | 14 + CMakeLists.txt | 23 + LICENSE.COMMERCIAL | 914 + LICENSE.FDL | 450 + LICENSE.GPL2 | 339 + LICENSE.GPLv3 | 686 + LICENSE.GPLv3-EXCEPT | 704 + LICENSE.LGPLv3 | 177 + README.cmake.md | 39 + README.md | 9 + README.pyside2.md | 77 + README.shiboken2-generator.md | 37 + README.shiboken2.md | 13 + build_history/blacklist.txt | 98 + build_scripts/__init__.py | 38 + build_scripts/build_scripts.pyproject | 9 + build_scripts/config.py | 397 + build_scripts/main.py | 1255 + build_scripts/options.py | 340 + build_scripts/platforms/__init__.py | 38 + build_scripts/platforms/linux.py | 146 + build_scripts/platforms/macos.py | 211 + build_scripts/platforms/unix.py | 227 + build_scripts/platforms/windows_desktop.py | 478 + build_scripts/qp5_tool.py | 435 + build_scripts/qtinfo.py | 262 + build_scripts/setup_runner.py | 177 + build_scripts/utils.py | 1166 + build_scripts/wheel_override.py | 216 + build_scripts/wheel_utils.py | 162 + coin/instructions/common_environment.yaml | 117 + .../execute_build_instructions.yaml | 56 + coin/instructions/execute_license_check.yaml | 31 + .../execute_test_instructions.yaml | 39 + .../find_path_to_msvc_compiler.yaml | 28 + coin/instructions/relocate_pyside.yaml | 57 + coin/module_config.yaml | 68 + coin_build_instructions.py | 186 + coin_test_instructions.py | 126 + dist/changes-1.2.3 | 405 + dist/changes-5.12.1 | 45 + dist/changes-5.12.2 | 49 + dist/changes-5.12.3 | 35 + dist/changes-5.12.4 | 43 + dist/changes-5.12.5 | 40 + dist/changes-5.12.6 | 29 + dist/changes-5.13.0 | 33 + dist/changes-5.13.1 | 47 + dist/changes-5.13.2 | 37 + dist/changes-5.14.0 | 69 + dist/changes-5.14.1 | 35 + dist/changes-5.14.2 | 66 + dist/changes-5.14.2.2 | 38 + dist/changes-5.14.2.3 | 35 + dist/changes-5.15.0 | 49 + dist/changes-5.15.1 | 67 + dist/changes-5.15.2 | 70 + docs/.gitignore | 1 + examples/3d/3d.pyproject | 3 + examples/3d/simple3d.py | 162 + examples/axcontainer/axcontainer.pyproject | 3 + examples/axcontainer/axviewer.py | 82 + examples/charts/audio.py | 126 + examples/charts/callout.py | 257 + examples/charts/charts.pyproject | 5 + examples/charts/chartthemes/README.md | 9 + .../charts/chartthemes/chartthemes.pyproject | 3 + examples/charts/chartthemes/main.py | 396 + examples/charts/chartthemes/themewidget.ui | 103 + examples/charts/chartthemes/ui_themewidget.py | 84 + examples/charts/donutbreakdown.py | 181 + examples/charts/legend.py | 252 + examples/charts/lineandbar.py | 116 + examples/charts/linechart.py | 84 + examples/charts/logvalueaxis.py | 94 + examples/charts/memoryusage.py | 125 + examples/charts/modeldata.py | 182 + examples/charts/nesteddonuts.py | 136 + examples/charts/percentbarchart.py | 98 + examples/charts/piechart.py | 87 + examples/charts/qmlpolarchart/View1.qml | 78 + examples/charts/qmlpolarchart/View2.qml | 99 + examples/charts/qmlpolarchart/View3.qml | 86 + examples/charts/qmlpolarchart/main.qml | 89 + .../charts/qmlpolarchart/qmlpolarchart.py | 63 + .../qmlpolarchart/qmlpolarchart.pyproject | 3 + examples/charts/temperaturerecords.py | 95 + examples/corelib/threads/mandelbrot.py | 348 + examples/corelib/threads/threads.pyproject | 3 + examples/corelib/tools/codecs/codecs.py | 253 + .../corelib/tools/codecs/codecs.pyproject | 3 + examples/corelib/tools/regexp.py | 194 + .../tools/settingseditor/settingseditor.py | 770 + .../settingseditor/settingseditor.pyproject | 3 + examples/corelib/tools/tools.pyproject | 3 + examples/datavisualization/bars3d.py | 113 + .../datavisualization.pyproject | 3 + examples/declarative/declarative.pyproject | 3 + .../extending/chapter1-basics/app.qml | 64 + .../extending/chapter1-basics/basics.py | 99 + .../chapter1-basics/chapter1-basics.pyproject | 3 + .../extending/chapter2-methods/app.qml | 70 + .../chapter2-methods.pyproject | 3 + .../extending/chapter2-methods/methods.py | 104 + .../extending/chapter3-bindings/app.qml | 78 + .../extending/chapter3-bindings/bindings.py | 109 + .../chapter3-bindings.pyproject | 3 + .../chapter4-customPropertyTypes/app.qml | 60 + .../chapter4-customPropertyTypes.pyproject | 3 + .../customPropertyTypes.py | 115 + .../extending/chapter5-listproperties/app.qml | 70 + .../chapter5-listproperties.pyproject | 3 + .../chapter5-listproperties/listproperties.py | 127 + examples/declarative/scrolling.py | 71 + examples/declarative/signals/pytoqml1/main.py | 70 + .../signals/pytoqml1/pytoqml1.pyproject | 3 + .../declarative/signals/pytoqml1/view.qml | 73 + examples/declarative/signals/qmltopy1/main.py | 87 + .../signals/qmltopy1/qmltopy1.pyproject | 3 + .../declarative/signals/qmltopy1/view.qml | 85 + examples/declarative/signals/qmltopy2/main.py | 79 + .../signals/qmltopy2/qmltopy2.pyproject | 3 + .../declarative/signals/qmltopy2/view.qml | 80 + examples/declarative/signals/qmltopy3/main.py | 70 + .../signals/qmltopy3/qmltopy3.pyproject | 3 + .../declarative/signals/qmltopy3/view.qml | 103 + examples/declarative/signals/qmltopy4/main.py | 70 + .../signals/qmltopy4/qmltopy4.pyproject | 3 + .../declarative/signals/qmltopy4/view.qml | 68 + examples/declarative/textproperties/main.py | 113 + .../textproperties/textproperties.pyproject | 3 + examples/declarative/textproperties/view.qml | 191 + examples/declarative/usingmodel.py | 100 + examples/declarative/view.qml | 65 + examples/examples.pyproject | 106 + examples/external/matplotlib/requirements.txt | 1 + examples/external/matplotlib/widget_3dplot.py | 242 + examples/external/opencv/requirements.txt | 1 + .../opencv/webcam_pattern_detection.py | 207 + examples/external/scikit/requirements.txt | 1 + .../scikit/staining_colors_separation.py | 184 + examples/installer_test/hello.py | 104 + examples/installer_test/hello_app.spec | 93 + examples/macextras/macextras.pyproject | 3 + examples/macextras/macpasteboardmime.py | 125 + examples/multimedia/audiooutput.py | 300 + examples/multimedia/camera.py | 169 + examples/multimedia/multimedia.pyproject | 3 + examples/multimedia/player.py | 157 + examples/multimedia/shutter.svg | 21 + examples/network/blockingfortuneclient.py | 224 + examples/network/fortuneclient.py | 167 + examples/network/fortuneserver.py | 117 + examples/network/network.pyproject | 4 + examples/network/threadedfortuneserver.py | 152 + examples/opengl/2dpainting.py | 172 + examples/opengl/contextinfo.py | 283 + examples/opengl/grabber.py | 437 + examples/opengl/hellogl.py | 287 + examples/opengl/hellogl2.py | 472 + examples/opengl/opengl.pyproject | 5 + examples/opengl/overpainting.py | 385 + examples/opengl/samplebuffers.py | 192 + examples/opengl/textures/images/side1.png | Bin 0 -> 1044 bytes examples/opengl/textures/images/side2.png | Bin 0 -> 1768 bytes examples/opengl/textures/images/side3.png | Bin 0 -> 2323 bytes examples/opengl/textures/images/side4.png | Bin 0 -> 1342 bytes examples/opengl/textures/images/side5.png | Bin 0 -> 1959 bytes examples/opengl/textures/images/side6.png | Bin 0 -> 2446 bytes examples/opengl/textures/textures.py | 231 + examples/opengl/textures/textures.pyproject | 3 + examples/opengl/textures/textures.qrc | 10 + examples/opengl/textures/textures_rc.py | 762 + .../quick/customitems/painteditem/main.qml | 114 + .../customitems/painteditem/painteditem.py | 106 + .../painteditem/painteditem.pyproject | 3 + .../modelview/modelview.pyproject | 3 + .../modelview/modelviewclient.py | 61 + .../modelview/modelviewserver.py | 139 + examples/samplebinding/CMakeLists.txt | 231 + examples/samplebinding/README.md | 236 + examples/samplebinding/bindings.h | 57 + examples/samplebinding/bindings.xml | 81 + examples/samplebinding/icecream.cpp | 65 + examples/samplebinding/icecream.h | 71 + examples/samplebinding/macros.h | 68 + examples/samplebinding/main.py | 101 + examples/samplebinding/truck.cpp | 143 + examples/samplebinding/truck.h | 86 + examples/script/README.md | 9 + examples/script/helloscript.py | 60 + examples/script/script.pyproject | 3 + examples/scriptableapplication/CMakeLists.txt | 213 + examples/scriptableapplication/README.md | 170 + examples/scriptableapplication/main.cpp | 64 + examples/scriptableapplication/mainwindow.cpp | 142 + examples/scriptableapplication/mainwindow.h | 76 + examples/scriptableapplication/pyside2.pri | 52 + .../scriptableapplication/pythonutils.cpp | 192 + examples/scriptableapplication/pythonutils.h | 81 + .../scriptableapplication.pro | 85 + .../scriptableapplication.xml | 56 + .../scriptableapplication/wrappedclasses.h | 56 + examples/sql/books/bookdelegate.py | 133 + examples/sql/books/books.pyproject | 5 + examples/sql/books/books.qrc | 5 + examples/sql/books/bookwindow.py | 137 + examples/sql/books/bookwindow.ui | 164 + examples/sql/books/createdb.py | 130 + examples/sql/books/images/star.png | Bin 0 -> 782 bytes examples/sql/books/main.py | 53 + examples/sql/books/rc_books.py | 88 + examples/sql/books/ui_bookwindow.py | 129 + examples/texttospeech/texttospeech.py | 107 + examples/texttospeech/texttospeech.pyproject | 3 + examples/tutorial/t1.py | 56 + examples/tutorial/t10.py | 191 + examples/tutorial/t11.py | 263 + examples/tutorial/t12.py | 312 + examples/tutorial/t13.py | 395 + examples/tutorial/t14.py | 450 + examples/tutorial/t2.py | 59 + examples/tutorial/t3.py | 61 + examples/tutorial/t4.py | 66 + examples/tutorial/t5.py | 77 + examples/tutorial/t6.py | 90 + examples/tutorial/t7.py | 113 + examples/tutorial/t8.py | 152 + examples/tutorial/t9.py | 159 + examples/tutorial/tutorial.pyproject | 5 + examples/uiloader/uiloader.py | 71 + examples/utils/pyside2_config.py | 372 + examples/utils/utils.py | 48 + examples/webchannel/standalone/core.py | 62 + examples/webchannel/standalone/dialog.py | 68 + examples/webchannel/standalone/dialog.ui | 48 + examples/webchannel/standalone/index.html | 79 + examples/webchannel/standalone/main.py | 99 + .../standalone/standalone.pyproject | 4 + examples/webchannel/standalone/ui_dialog.py | 55 + .../standalone/websocketclientwrapper.py | 72 + .../standalone/websockettransport.py | 88 + examples/webenginequick/browser.qml | 53 + examples/webenginequick/quicknanobrowser.py | 59 + .../webenginequick/webenginequick.pyproject | 3 + examples/webenginewidgets/simplebrowser.py | 101 + .../tabbedbrowser/bookmarkwidget.py | 277 + .../tabbedbrowser/browsertabwidget.py | 244 + .../tabbedbrowser/downloadwidget.py | 146 + .../tabbedbrowser/findtoolbar.py | 99 + .../tabbedbrowser/historywindow.py | 103 + .../webenginewidgets/tabbedbrowser/main.py | 395 + .../tabbedbrowser/tabbedbrowser.pyproject | 5 + .../tabbedbrowser/webengineview.py | 91 + .../webenginewidgets.pyproject | 3 + examples/widgetbinding/CMakeLists.txt | 275 + examples/widgetbinding/README.md | 74 + examples/widgetbinding/bindings.h | 54 + examples/widgetbinding/bindings.xml | 56 + examples/widgetbinding/dialog.py | 77 + examples/widgetbinding/macros.h | 63 + examples/widgetbinding/main.py | 61 + examples/widgetbinding/wigglywidget.cpp | 111 + examples/widgetbinding/wigglywidget.h | 81 + examples/widgetbinding/wigglywidget.py | 97 + .../animation/animatedtiles/animatedtiles.py | 259 + .../animatedtiles/animatedtiles.pyproject | 4 + .../animation/animatedtiles/animatedtiles.qrc | 11 + .../animatedtiles/animatedtiles_rc.py | 6108 +++ .../animatedtiles/images/Time-For-Lunch-2.jpg | Bin 0 -> 32471 bytes .../animatedtiles/images/centered.png | Bin 0 -> 892 bytes .../animatedtiles/images/ellipse.png | Bin 0 -> 10767 bytes .../animatedtiles/images/figure8.png | Bin 0 -> 14050 bytes .../animatedtiles/images/kinetic.png | Bin 0 -> 6776 bytes .../animation/animatedtiles/images/random.png | Bin 0 -> 14969 bytes .../animation/animatedtiles/images/tile.png | Bin 0 -> 16337 bytes .../appchooser/accessories-dictionary.png | Bin 0 -> 5396 bytes .../animation/appchooser/akregator.png | Bin 0 -> 4873 bytes .../animation/appchooser/appchooser.py | 133 + .../animation/appchooser/appchooser.pyproject | 3 + .../animation/appchooser/appchooser.qrc | 8 + .../animation/appchooser/appchooser_rc.py | 1424 + .../widgets/animation/appchooser/digikam.png | Bin 0 -> 3334 bytes examples/widgets/animation/appchooser/k3b.png | Bin 0 -> 8220 bytes examples/widgets/animation/easing/easing.py | 259 + .../widgets/animation/easing/easing.pyproject | 4 + examples/widgets/animation/easing/easing.qrc | 5 + .../widgets/animation/easing/easing_rc.py | 361 + examples/widgets/animation/easing/form.ui | 205 + .../animation/easing/images/qt-logo.png | Bin 0 -> 5149 bytes examples/widgets/animation/easing/ui_form.py | 152 + examples/widgets/animation/states/states.py | 264 + .../widgets/animation/states/states.pyproject | 3 + .../widgets/animation/states/states_rc.py | 2221 + examples/widgets/codeeditor/codeeditor.py | 141 + examples/widgets/codeeditor/main.py | 52 + .../dialogs/classwizard/classwizard.py | 404 + .../dialogs/classwizard/classwizard.pyproject | 4 + .../dialogs/classwizard/classwizard.qrc | 11 + .../dialogs/classwizard/classwizard_rc.py | 3892 ++ .../dialogs/classwizard/images/background.png | Bin 0 -> 22578 bytes .../dialogs/classwizard/images/banner.png | Bin 0 -> 3947 bytes .../dialogs/classwizard/images/logo1.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/logo2.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/logo3.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/watermark1.png | Bin 0 -> 14516 bytes .../dialogs/classwizard/images/watermark2.png | Bin 0 -> 14912 bytes examples/widgets/dialogs/dialogs.pyproject | 4 + examples/widgets/dialogs/extension.py | 113 + examples/widgets/dialogs/findfiles.py | 210 + examples/widgets/dialogs/standarddialogs.py | 319 + examples/widgets/dialogs/trivialwizard.py | 112 + .../draggabletext/draggabletext.py | 155 + .../draggabletext/draggabletext.pyproject | 4 + .../draggabletext/draggabletext.qrc | 5 + .../draggabletext/draggabletext_rc.py | 55 + .../draganddrop/draggabletext/words.txt | 41 + examples/widgets/effects/effects.pyproject | 3 + examples/widgets/effects/lighting.py | 144 + examples/widgets/gallery/gallery.pyproject | 3 + examples/widgets/gallery/main.py | 56 + examples/widgets/gallery/widgetgallery.py | 429 + examples/widgets/graphicsview/anchorlayout.py | 125 + .../collidingmice/collidingmice.py | 218 + .../collidingmice/collidingmice.pyproject | 3 + .../graphicsview/collidingmice/mice_rc.py | 271 + .../graphicsview/diagramscene/diagramscene.py | 824 + .../diagramscene/diagramscene.pyproject | 3 + .../diagramscene/diagramscene.qrc | 19 + .../diagramscene/diagramscene_rc.py | 417 + .../diagramscene/images/background1.png | Bin 0 -> 112 bytes .../diagramscene/images/background2.png | Bin 0 -> 114 bytes .../diagramscene/images/background3.png | Bin 0 -> 116 bytes .../diagramscene/images/background4.png | Bin 0 -> 96 bytes .../graphicsview/diagramscene/images/bold.png | Bin 0 -> 274 bytes .../diagramscene/images/bringtofront.png | Bin 0 -> 293 bytes .../diagramscene/images/delete.png | Bin 0 -> 831 bytes .../diagramscene/images/floodfill.png | Bin 0 -> 282 bytes .../diagramscene/images/italic.png | Bin 0 -> 247 bytes .../diagramscene/images/linecolor.png | Bin 0 -> 145 bytes .../diagramscene/images/linepointer.png | Bin 0 -> 141 bytes .../diagramscene/images/pointer.png | Bin 0 -> 173 bytes .../diagramscene/images/sendtoback.png | Bin 0 -> 318 bytes .../diagramscene/images/textpointer.png | Bin 0 -> 753 bytes .../diagramscene/images/underline.png | Bin 0 -> 250 bytes .../dragdroprobot/dragdroprobot.py | 287 + .../dragdroprobot/dragdroprobot.pyproject | 3 + .../dragdroprobot/dragdroprobot.qrc | 5 + .../dragdroprobot/dragdroprobot_rc.py | 975 + .../dragdroprobot/images/head.png | Bin 0 -> 14972 bytes examples/widgets/graphicsview/elasticnodes.py | 416 + .../graphicsview/graphicsview.pyproject | 3 + .../itemviews/addressbook/adddialogwidget.py | 102 + .../itemviews/addressbook/addressbook.py | 130 + .../addressbook/addressbook.pyproject | 4 + .../itemviews/addressbook/addresswidget.py | 248 + .../itemviews/addressbook/newaddresstab.py | 93 + .../itemviews/addressbook/tablemodel.py | 146 + .../widgets/itemviews/basicsortfiltermodel.py | 213 + examples/widgets/itemviews/fetchmore.py | 147 + .../widgets/itemviews/itemviews.pyproject | 3 + .../itemviews/stardelegate/stardelegate.py | 173 + .../stardelegate/stardelegate.pyproject | 3 + .../itemviews/stardelegate/stareditor.py | 100 + .../itemviews/stardelegate/starrating.py | 100 + examples/widgets/layouts/basiclayouts.py | 134 + examples/widgets/layouts/dynamiclayouts.py | 170 + examples/widgets/layouts/flowlayout.py | 160 + examples/widgets/layouts/layouts.pyproject | 3 + .../mainwindows/application/application.py | 275 + .../application/application.pyproject | 3 + .../mainwindows/application/application.qrc | 10 + .../mainwindows/application/application_rc.py | 608 + .../mainwindows/application/images/copy.png | Bin 0 -> 1338 bytes .../mainwindows/application/images/cut.png | Bin 0 -> 1323 bytes .../mainwindows/application/images/new.png | Bin 0 -> 852 bytes .../mainwindows/application/images/open.png | Bin 0 -> 2073 bytes .../mainwindows/application/images/paste.png | Bin 0 -> 1645 bytes .../mainwindows/application/images/save.png | Bin 0 -> 1187 bytes .../mainwindows/dockwidgets/dockwidgets.py | 303 + .../dockwidgets/dockwidgets.pyproject | 3 + .../mainwindows/dockwidgets/dockwidgets.qrc | 8 + .../mainwindows/dockwidgets/dockwidgets_rc.py | 464 + .../mainwindows/dockwidgets/images/new.png | Bin 0 -> 977 bytes .../mainwindows/dockwidgets/images/print.png | Bin 0 -> 1732 bytes .../mainwindows/dockwidgets/images/save.png | Bin 0 -> 1894 bytes .../mainwindows/dockwidgets/images/undo.png | Bin 0 -> 1768 bytes .../widgets/mainwindows/mdi/images/copy.png | Bin 0 -> 1338 bytes .../widgets/mainwindows/mdi/images/cut.png | Bin 0 -> 1323 bytes .../widgets/mainwindows/mdi/images/new.png | Bin 0 -> 852 bytes .../widgets/mainwindows/mdi/images/open.png | Bin 0 -> 2073 bytes .../widgets/mainwindows/mdi/images/paste.png | Bin 0 -> 1645 bytes .../widgets/mainwindows/mdi/images/save.png | Bin 0 -> 1187 bytes examples/widgets/mainwindows/mdi/mdi.py | 451 + .../widgets/mainwindows/mdi/mdi.pyproject | 3 + examples/widgets/mainwindows/mdi/mdi.qrc | 10 + examples/widgets/mainwindows/mdi/mdi_rc.py | 608 + .../painting/basicdrawing/basicdrawing.py | 349 + .../basicdrawing/basicdrawing.pyproject | 3 + .../painting/basicdrawing/basicdrawing.qrc | 6 + .../painting/basicdrawing/basicdrawing_rc.py | 135 + .../painting/basicdrawing/images/brick.png | Bin 0 -> 856 bytes .../painting/basicdrawing/images/qt-logo.png | Bin 0 -> 533 bytes .../widgets/painting/concentriccircles.py | 146 + examples/widgets/painting/painting.pyproject | 3 + examples/widgets/richtext/orderform.py | 296 + examples/widgets/richtext/richtext.pyproject | 3 + .../widgets/richtext/syntaxhighlighter.py | 210 + .../syntaxhighlighter/examples/example | 79 + .../syntaxhighlighter/syntaxhighlighter.py | 154 + .../syntaxhighlighter.pyproject | 4 + .../syntaxhighlighter/syntaxhighlighter.qrc | 5 + .../syntaxhighlighter/syntaxhighlighter_rc.py | 143 + .../richtext/textobject/files/heart.svg | 55 + .../widgets/richtext/textobject/textobject.py | 129 + .../richtext/textobject/textobject.pyproject | 3 + examples/widgets/state-machine/eventtrans.py | 92 + examples/widgets/state-machine/factstates.py | 111 + examples/widgets/state-machine/pingpong.py | 96 + examples/widgets/state-machine/rogue.py | 202 + .../state-machine/state-machine.pyproject | 4 + .../widgets/state-machine/trafficlight.py | 139 + .../widgets/state-machine/twowaybutton.py | 70 + examples/widgets/systray/images/bad.png | Bin 0 -> 2496 bytes examples/widgets/systray/images/heart.png | Bin 0 -> 25780 bytes examples/widgets/systray/images/trash.png | Bin 0 -> 12128 bytes examples/widgets/systray/main.py | 58 + examples/widgets/systray/rc_systray.py | 2581 ++ examples/widgets/systray/systray.pyproject | 3 + examples/widgets/systray/systray.qrc | 7 + examples/widgets/systray/window.py | 273 + examples/widgets/threads/thread_signals.py | 100 + .../addressbook/addressbook.pyproject | 4 + .../widgets/tutorials/addressbook/part1.py | 74 + .../widgets/tutorials/addressbook/part2.py | 180 + .../widgets/tutorials/addressbook/part3.py | 245 + .../widgets/tutorials/addressbook/part4.py | 299 + .../widgets/tutorials/addressbook/part5.py | 359 + .../widgets/tutorials/addressbook/part6.py | 424 + .../widgets/tutorials/addressbook/part7.py | 476 + .../widgets/hellogl_openglwidget_legacy.py | 288 + examples/widgets/widgets/tetrix.py | 498 + examples/widgets/widgets/widgets.pyproject | 3 + examples/xml/dombookmarks/dombookmarks.py | 262 + .../xml/dombookmarks/dombookmarks.pyproject | 3 + examples/xml/dombookmarks/frank.xbel | 230 + examples/xml/dombookmarks/jennifer.xbel | 93 + examples/xmlpatterns/schema/files/contact.xsd | 25 + .../schema/files/invalid_contact.xml | 11 + .../schema/files/invalid_order.xml | 13 + .../schema/files/invalid_recipe.xml | 14 + examples/xmlpatterns/schema/files/order.xsd | 23 + examples/xmlpatterns/schema/files/recipe.xsd | 40 + .../schema/files/valid_contact.xml | 11 + .../xmlpatterns/schema/files/valid_order.xml | 18 + .../xmlpatterns/schema/files/valid_recipe.xml | 13 + examples/xmlpatterns/schema/schema.py | 286 + examples/xmlpatterns/schema/schema.pyproject | 4 + examples/xmlpatterns/schema/schema.qrc | 13 + examples/xmlpatterns/schema/schema.ui | 71 + examples/xmlpatterns/schema/schema_rc.py | 394 + examples/xmlpatterns/schema/ui_schema.py | 88 + ez_setup.py | 376 + header.BSD-OLD | 39 + keyword-errors.lst | 43 + product_dependencies.yaml | 3 + requirements.txt | 11 + setup.py | 296 + sources/cmake_helpers/helpers.cmake | 274 + sources/patchelf/COPYING | 674 + sources/patchelf/README | 107 + sources/patchelf/elf.h | 2674 ++ sources/patchelf/patchelf.cc | 1239 + sources/pyside2-tools/CMakeLists.txt | 127 + sources/pyside2-tools/LICENSE-lupdate | 339 + sources/pyside2-tools/LICENSE-rcc | 342 + sources/pyside2-tools/LICENSE-uic | 372 + sources/pyside2-tools/README.md | 21 + sources/pyside2-tools/cmake_uninstall.cmake | 21 + .../pyside2-tools/pylupdate/CMakeLists.txt | 44 + sources/pyside2-tools/pylupdate/fetchtr.cpp | 889 + sources/pyside2-tools/pylupdate/main.cpp | 256 + sources/pyside2-tools/pylupdate/merge.cpp | 199 + .../pylupdate/metatranslator.cpp | 766 + .../pyside2-tools/pylupdate/metatranslator.h | 144 + sources/pyside2-tools/pylupdate/numberh.cpp | 240 + sources/pyside2-tools/pylupdate/proparser.cpp | 209 + sources/pyside2-tools/pylupdate/proparser.h | 34 + .../pyside2-tools/pylupdate/pyside2-lupdate.1 | 27 + sources/pyside2-tools/pylupdate/sametexth.cpp | 87 + sources/pyside2-tools/pylupdate/simtexth.cpp | 256 + sources/pyside2-tools/pylupdate/simtexth.h | 77 + .../pyside2-tools/pylupdate/translator.cpp | 1184 + sources/pyside2-tools/pylupdate/translator.h | 387 + sources/pyside2-tools/pyside_tool.py | 89 + sources/pyside2-tools/qt_attribution.json | 16 + sources/pyside2-tools/tests/CMakeLists.txt | 4 + sources/pyside2-tools/tests/qwizard_test.ui | 67 + .../pyside2-tools/tests/rcc/CMakeLists.txt | 10 + .../tests/rcc/document-print-preview.png | Bin 0 -> 1719 bytes sources/pyside2-tools/tests/rcc/example.qrc | 7 + sources/pyside2-tools/tests/rcc/image.qrc | 5 + sources/pyside2-tools/tests/rcc/manychars.txt | 1 + .../pyside2-tools/tests/rcc/rcc_image_test.py | 16 + sources/pyside2-tools/tests/rcc/rcc_test.py | 31 + sources/pyside2-tools/tests/rcc/run_test.sh | 12 + sources/pyside2-tools/tests/rcc/shining.txt | 1 + sources/pyside2-tools/tests/rcc/words.txt | 1 + sources/pyside2/CMakeLists.txt | 284 + sources/pyside2/COPYING | 501 + sources/pyside2/PySide2/CMakeLists.txt | 108 + .../PySide2/Qt3DAnimation/CMakeLists.txt | 57 + .../Qt3DAnimation/typesystem_3danimation.xml | 83 + .../pyside2/PySide2/Qt3DCore/CMakeLists.txt | 69 + .../PySide2/Qt3DCore/typesystem_3dcore.xml | 114 + .../pyside2/PySide2/Qt3DExtras/CMakeLists.txt | 78 + .../Qt3DExtras/typesystem_3dextras.xml | 87 + .../pyside2/PySide2/Qt3DInput/CMakeLists.txt | 51 + .../PySide2/Qt3DInput/typesystem_3dinput.xml | 90 + .../pyside2/PySide2/Qt3DLogic/CMakeLists.txt | 32 + .../PySide2/Qt3DLogic/typesystem_3dlogic.xml | 49 + .../pyside2/PySide2/Qt3DRender/CMakeLists.txt | 173 + .../Qt3DRender/typesystem_3drender.xml | 277 + .../PySide2/QtAxContainer/CMakeLists.txt | 41 + .../QtAxContainer_global.post.h.in | 5 + .../QtAxContainer/typesystem_axcontainer.xml | 73 + .../pyside2/PySide2/QtCharts/CMakeLists.txt | 85 + .../PySide2/QtCharts/typesystem_charts.xml | 272 + .../PySide2/QtConcurrent/CMakeLists.txt | 31 + .../PySide2/QtConcurrent/curr_errors.txt | 21 + .../QtConcurrent/typesystem_concurrent.xml | 71 + sources/pyside2/PySide2/QtCore/CMakeLists.txt | 233 + .../PySide2/QtCore/glue/qeasingcurve_glue.cpp | 158 + .../PySide2/QtCore/glue/qeasingcurve_glue.h | 66 + .../PySide2/QtCore/typesystem_core.xml.in | 45 + .../PySide2/QtCore/typesystem_core_common.xml | 3394 ++ .../PySide2/QtCore/typesystem_core_mac.xml | 57 + .../PySide2/QtCore/typesystem_core_win.xml | 90 + .../PySide2/QtCore/typesystem_core_x11.xml | 61 + .../QtDataVisualization/CMakeLists.txt | 65 + .../typesystem_datavisualization.xml | 422 + sources/pyside2/PySide2/QtGui/CMakeLists.txt | 268 + .../PySide2/QtGui/QtGui_global.post.h.in | 1 + .../PySide2/QtGui/typesystem_gui.xml.in | 46 + .../PySide2/QtGui/typesystem_gui_common.xml | 3069 ++ .../PySide2/QtGui/typesystem_gui_mac.xml | 50 + .../PySide2/QtGui/typesystem_gui_win.xml | 42 + .../PySide2/QtGui/typesystem_gui_x11.xml | 42 + sources/pyside2/PySide2/QtHelp/CMakeLists.txt | 60 + .../PySide2/QtHelp/typesystem_help.xml | 71 + .../pyside2/PySide2/QtLocation/CMakeLists.txt | 75 + .../QtLocation/typesystem_location.xml | 116 + .../PySide2/QtMacExtras/CMakeLists.txt | 33 + .../QtMacExtras/typesystem_macextras.xml | 55 + .../PySide2/QtMultimedia/CMakeLists.txt | 130 + .../QtMultimedia/typesystem_multimedia.xml | 45 + .../typesystem_multimedia_common.xml | 372 + ...system_multimedia_forward_declarations.xml | 45 + .../QtMultimediaWidgets/CMakeLists.txt | 42 + .../typesystem_multimediawidgets.xml | 52 + .../pyside2/PySide2/QtNetwork/CMakeLists.txt | 121 + .../PySide2/QtNetwork/typesystem_network.xml | 325 + .../pyside2/PySide2/QtOpenGL/CMakeLists.txt | 42 + .../PySide2/QtOpenGL/typesystem_opengl.xml | 716 + .../PySide2/QtOpenGLFunctions/CMakeLists.txt | 73 + .../QtOpenGLFunctions_global.post.h.in | 61 + .../typesystem_openglfunctions.xml | 409 + ...ystem_openglfunctions_modifications1_0.xml | 51 + ...penglfunctions_modifications1_0_compat.xml | 103 + ...ystem_openglfunctions_modifications1_1.xml | 44 + ...penglfunctions_modifications1_1_compat.xml | 44 + ...penglfunctions_modifications1_2_compat.xml | 46 + ...penglfunctions_modifications1_3_compat.xml | 46 + ...ystem_openglfunctions_modifications1_4.xml | 47 + ...penglfunctions_modifications1_4_compat.xml | 49 + ...ystem_openglfunctions_modifications2_0.xml | 49 + ...penglfunctions_modifications2_0_compat.xml | 1 + ...ystem_openglfunctions_modifications2_1.xml | 43 + ...ystem_openglfunctions_modifications3_0.xml | 46 + ...ystem_openglfunctions_modifications3_3.xml | 46 + ...stem_openglfunctions_modifications3_3a.xml | 57 + ...ystem_openglfunctions_modifications4_0.xml | 46 + ...ystem_openglfunctions_modifications4_1.xml | 58 + ...ystem_openglfunctions_modifications4_3.xml | 43 + ...ystem_openglfunctions_modifications4_4.xml | 56 + ..._openglfunctions_modifications4_4_core.xml | 43 + ...ystem_openglfunctions_modifications4_5.xml | 57 + ..._openglfunctions_modifications4_5_core.xml | 41 + ...ystem_openglfunctions_modifications_va.xml | 43 + .../PySide2/QtPositioning/CMakeLists.txt | 50 + .../QtPositioning/typesystem_positioning.xml | 80 + .../PySide2/QtPrintSupport/CMakeLists.txt | 43 + .../typesystem_printsupport.xml.in | 45 + .../typesystem_printsupport_common.xml | 124 + sources/pyside2/PySide2/QtQml/CMakeLists.txt | 63 + .../PySide2/QtQml/pysideqmlregistertype.cpp | 506 + .../PySide2/QtQml/pysideqmlregistertype.h | 80 + .../pyside2/PySide2/QtQml/typesystem_qml.xml | 236 + .../pyside2/PySide2/QtQuick/CMakeLists.txt | 90 + .../QtQuick/pysidequickregistertype.cpp | 253 + .../PySide2/QtQuick/pysidequickregistertype.h | 52 + .../PySide2/QtQuick/typesystem_quick.xml | 175 + .../PySide2/QtQuickControls2/CMakeLists.txt | 41 + .../typesystem_quickcontrols2.xml | 47 + .../PySide2/QtQuickWidgets/CMakeLists.txt | 43 + .../typesystem_quickwidgets.xml | 54 + .../PySide2/QtRemoteObjects/CMakeLists.txt | 45 + .../typesystem_remoteobjects.xml | 75 + .../pyside2/PySide2/QtScript/CMakeLists.txt | 42 + .../QtScript/qscript_value_iterator_glue.cpp | 3 + .../PySide2/QtScript/typesystem_script.xml | 105 + .../PySide2/QtScriptTools/CMakeLists.txt | 37 + .../QtScriptTools/typesystem_scripttools.xml | 55 + .../pyside2/PySide2/QtScxml/CMakeLists.txt | 55 + .../PySide2/QtScxml/typesystem_scxml.xml | 86 + .../pyside2/PySide2/QtSensors/CMakeLists.txt | 100 + .../PySide2/QtSensors/typesystem_sensors.xml | 127 + .../PySide2/QtSerialPort/CMakeLists.txt | 31 + .../QtSerialPort/typesystem_serialport.xml | 56 + sources/pyside2/PySide2/QtSql/CMakeLists.txt | 49 + .../PySide2/QtSql/QtSql_global.pre.h.in | 5 + .../pyside2/PySide2/QtSql/typesystem_sql.xml | 194 + sources/pyside2/PySide2/QtSvg/CMakeLists.txt | 36 + .../pyside2/PySide2/QtSvg/typesystem_svg.xml | 74 + sources/pyside2/PySide2/QtTest/CMakeLists.txt | 40 + .../PySide2/QtTest/QtTest_global.post.h.in | 1 + .../PySide2/QtTest/QtTest_global.pre.h.in | 5 + .../PySide2/QtTest/typesystem_test.xml | 168 + .../PySide2/QtTextToSpeech/CMakeLists.txt | 30 + .../typesystem_texttospeech.xml | 53 + .../pyside2/PySide2/QtUiTools/CMakeLists.txt | 42 + .../pyside2/PySide2/QtUiTools/glue/plugins.h | 67 + .../PySide2/QtUiTools/typesystem_uitools.xml | 157 + .../PySide2/QtWebChannel/CMakeLists.txt | 28 + .../QtWebChannel/typesystem_webchannel.xml | 55 + .../PySide2/QtWebEngine/CMakeLists.txt | 27 + .../QtWebEngine/typesystem_webengine.xml | 45 + .../PySide2/QtWebEngineCore/CMakeLists.txt | 41 + .../typesystem_webenginecore.xml | 75 + .../PySide2/QtWebEngineWidgets/CMakeLists.txt | 55 + .../typesystem_webenginewidgets.xml | 130 + .../pyside2/PySide2/QtWebKit/CMakeLists.txt | 34 + .../PySide2/QtWebKit/typesystem_webkit.xml | 49 + .../PySide2/QtWebKitWidgets/CMakeLists.txt | 65 + .../typesystem_webkitwidgets.xml | 211 + .../PySide2/QtWebSockets/CMakeLists.txt | 36 + .../QtWebSockets/typesystem_websockets.xml | 78 + .../pyside2/PySide2/QtWidgets/CMakeLists.txt | 236 + .../QtWidgets/typesystem_widgets.xml.in | 46 + .../QtWidgets/typesystem_widgets_common.xml | 3486 ++ .../QtWidgets/typesystem_widgets_mac.xml | 55 + .../QtWidgets/typesystem_widgets_win.xml | 42 + .../QtWidgets/typesystem_widgets_x11.xml | 42 + .../PySide2/QtWinExtras/CMakeLists.txt | 48 + .../QtWinExtras/QtWinExtras_global.pre.h.in | 5 + .../QtWinExtras/typesystem_winextras.xml | 66 + .../PySide2/QtX11Extras/CMakeLists.txt | 33 + .../QtX11Extras/QtX11Extras_global.post.h.in | 1 + .../QtX11Extras/typesystem_x11extras.xml | 49 + sources/pyside2/PySide2/QtXml/CMakeLists.txt | 55 + .../pyside2/PySide2/QtXml/typesystem_xml.xml | 401 + .../PySide2/QtXmlPatterns/CMakeLists.txt | 41 + .../QtXmlPatterns/typesystem_xmlpatterns.xml | 122 + sources/pyside2/PySide2/__init__.py.in | 107 + sources/pyside2/PySide2/_config.py.in | 16 + sources/pyside2/PySide2/global.h.in | 64 + sources/pyside2/PySide2/glue/qtcharts.cpp | 42 + sources/pyside2/PySide2/glue/qtcore.cpp | 2034 + .../PySide2/glue/qtdatavisualization.cpp | 42 + sources/pyside2/PySide2/glue/qtgui.cpp | 547 + sources/pyside2/PySide2/glue/qtmultimedia.cpp | 53 + sources/pyside2/PySide2/glue/qtnetwork.cpp | 80 + sources/pyside2/PySide2/glue/qtopengl.cpp | 74 + .../pyside2/PySide2/glue/qtprintsupport.cpp | 43 + sources/pyside2/PySide2/glue/qtqml.cpp | 52 + sources/pyside2/PySide2/glue/qtquick.cpp | 42 + sources/pyside2/PySide2/glue/qtscript.cpp | 74 + sources/pyside2/PySide2/glue/qtuitools.cpp | 252 + .../PySide2/glue/qtwebenginewidgets.cpp | 157 + .../pyside2/PySide2/glue/qtwebkitwidgets.cpp | 92 + sources/pyside2/PySide2/glue/qtwidgets.cpp | 663 + sources/pyside2/PySide2/glue/qtxml.cpp | 63 + .../pyside2/PySide2/glue/qtxmlpatterns.cpp | 43 + sources/pyside2/PySide2/licensecomment.txt | 38 + sources/pyside2/PySide2/py.typed.in | 1 + sources/pyside2/PySide2/pysideqtesttouch.h | 227 + sources/pyside2/PySide2/pysidewtypes.h | 66 + sources/pyside2/PySide2/qpytextobject.cpp | 50 + sources/pyside2/PySide2/qpytextobject.h | 64 + sources/pyside2/PySide2/qt.conf.in | 2 + sources/pyside2/PySide2/support/__init__.py | 42 + sources/pyside2/PySide2/support/deprecated.py | 80 + .../pyside2/PySide2/support/generate_pyi.py | 327 + .../pyside2/PySide2/templates/core_common.xml | 393 + .../templates/datavisualization_common.xml | 76 + .../pyside2/PySide2/templates/gui_common.xml | 298 + .../PySide2/templates/opengl_common.xml | 61 + .../templates/openglfunctions_common.xml | 48 + .../templates/webkitwidgets_common.xml | 73 + .../PySide2/templates/widgets_common.xml | 91 + .../pyside2/PySide2/templates/xml_common.xml | 58 + .../pyside2/cmake/Macros/FindQt5Extra.cmake | 25 + .../pyside2/cmake/Macros/PySideModules.cmake | 253 + sources/pyside2/cmake/Macros/icecc.cmake | 11 + sources/pyside2/cmake_uninstall.cmake | 21 + sources/pyside2/doc/CMakeLists.txt | 188 + sources/pyside2/doc/_templates/layout.html | 40 + .../doc/_themes/pysidedocs/domainindex.html | 57 + .../doc/_themes/pysidedocs/searchbox.html | 12 + .../_themes/pysidedocs/static/bg_header.png | Bin 0 -> 36012 bytes .../doc/_themes/pysidedocs/static/bg_topo.jpg | Bin 0 -> 14237 bytes .../doc/_themes/pysidedocs/static/fakebar.png | Bin 0 -> 101 bytes .../_themes/pysidedocs/static/logo_python.jpg | Bin 0 -> 2660 bytes .../doc/_themes/pysidedocs/static/logo_qt.png | Bin 0 -> 1936 bytes .../doc/_themes/pysidedocs/static/minus.png | Bin 0 -> 199 bytes .../doc/_themes/pysidedocs/static/plus.png | Bin 0 -> 199 bytes .../doc/_themes/pysidedocs/static/pyside.css | 2076 + .../_themes/pysidedocs/static/pysidelogo.png | Bin 0 -> 4936 bytes .../_themes/pysidedocs/static/relbar_bg.png | Bin 0 -> 130 bytes .../pyside2/doc/_themes/pysidedocs/theme.conf | 7 + .../pysidedocs_qthelp/domainindex.html | 57 + .../pysidedocs_qthelp/static/fakebar.png | Bin 0 -> 101 bytes .../pysidedocs_qthelp/static/logo_python.jpg | Bin 0 -> 2660 bytes .../pysidedocs_qthelp/static/logo_qt.png | Bin 0 -> 1936 bytes .../pysidedocs_qthelp/static/minus.png | Bin 0 -> 199 bytes .../_themes/pysidedocs_qthelp/static/plus.png | Bin 0 -> 199 bytes .../pysidedocs_qthelp/static/pyside.css | 1943 + .../pysidedocs_qthelp/static/pysidelogo.png | Bin 0 -> 4936 bytes .../pysidedocs_qthelp/static/relbar_bg.png | Bin 0 -> 130 bytes .../doc/_themes/pysidedocs_qthelp/theme.conf | 7 + sources/pyside2/doc/additionaldocs.lst | 597 + sources/pyside2/doc/api.rst | 90 + .../snippets/accessibilityslidersnippet.cpp | 271 + .../doc/src/snippets/alphachannel.cpp | 64 + .../doc/src/snippets/audio/main.cpp | 104 + .../doc/src/snippets/brushstyles/qt-logo.png | Bin 0 -> 15518 bytes .../doc/src/snippets/brushstyles/renderarea.h | 71 + .../src/snippets/brushstyles/stylewidget.h | 108 + .../doc/src/snippets/clipboard/clipwindow.h | 82 + .../doc/src/snippets/clipboard/clipwindow.py | 105 + .../src/snippets/code/doc_src_qnamespace.qdoc | 67 + .../doc/src/snippets/code/doc_src_qtcore.py | 53 + .../src/snippets/code/doc_src_qtnetwork.py | 53 + .../doc/src/snippets/code/doc_src_qtopengl.py | 53 + .../snippets/code/doc_src_qtprintsupport.py | 53 + .../doc/src/snippets/code/doc_src_qtqml.py | 53 + .../doc/src/snippets/code/doc_src_qtquick.py | 53 + .../doc/src/snippets/code/doc_src_qtsql.py | 52 + .../doc/src/snippets/code/doc_src_qttest.py | 53 + .../src/snippets/code/doc_src_qtwidgets.py | 53 + .../doc/src/snippets/code/doc_src_qtxml.py | 53 + .../code/src.gui.text.qtextdocumentwriter.cpp | 55 + .../code/src.qdbus.qdbuspendingcall.cpp | 74 + .../code/src.qdbus.qdbuspendingreply.cpp | 73 + .../src.scripttools.qscriptenginedebugger.cpp | 59 + .../code/src_corelib_codecs_qtextcodec.cpp | 82 + .../src_corelib_codecs_qtextcodecplugin.cpp | 62 + .../code/src_corelib_concurrent_qfuture.cpp | 74 + ...corelib_concurrent_qfuturesynchronizer.cpp | 63 + .../src_corelib_concurrent_qfuturewatcher.cpp | 60 + ...relib_concurrent_qtconcurrentexception.cpp | 85 + ..._corelib_concurrent_qtconcurrentfilter.cpp | 181 + ...src_corelib_concurrent_qtconcurrentmap.cpp | 194 + ...src_corelib_concurrent_qtconcurrentrun.cpp | 110 + .../src_corelib_concurrent_qthreadpool.cpp | 59 + .../src_corelib_io_qabstractfileengine.cpp | 112 + .../code/src_corelib_io_qdatastream.cpp | 135 + .../src/snippets/code/src_corelib_io_qdir.cpp | 179 + .../code/src_corelib_io_qdiriterator.cpp | 62 + .../snippets/code/src_corelib_io_qfile.cpp | 82 + .../code/src_corelib_io_qfileinfo.cpp | 148 + .../code/src_corelib_io_qiodevice.cpp | 98 + .../snippets/code/src_corelib_io_qprocess.cpp | 132 + .../code/src_corelib_io_qsettings.cpp | 327 + .../code/src_corelib_io_qtemporaryfile.cpp | 62 + .../code/src_corelib_io_qtextstream.cpp | 140 + .../src/snippets/code/src_corelib_io_qurl.cpp | 96 + ...orelib_kernel_qabstracteventdispatcher.cpp | 3 + .../src_corelib_kernel_qabstractitemmodel.cpp | 98 + .../src_corelib_kernel_qcoreapplication.cpp | 128 + .../code/src_corelib_kernel_qmetaobject.cpp | 132 + .../code/src_corelib_kernel_qmetatype.cpp | 119 + .../code/src_corelib_kernel_qmimedata.cpp | 107 + .../code/src_corelib_kernel_qobject.py | 375 + .../src_corelib_kernel_qsystemsemaphore.cpp | 71 + .../code/src_corelib_kernel_qtimer.cpp | 60 + .../code/src_corelib_plugin_qlibrary.cpp | 94 + .../code/src_corelib_plugin_quuid.cpp | 54 + ...src_corelib_statemachine_qstatemachine.cpp | 65 + .../code/src_corelib_thread_qatomic.cpp | 108 + .../code/src_corelib_thread_qmutex.cpp | 165 + .../code/src_corelib_thread_qmutexpool.cpp | 62 + .../src_corelib_thread_qreadwritelock.cpp | 111 + .../code/src_corelib_thread_qsemaphore.cpp | 83 + .../code/src_corelib_thread_qthread.cpp | 59 + ...src_corelib_thread_qwaitcondition_unix.cpp | 95 + .../code/src_corelib_tools_qbitarray.cpp | 239 + .../code/src_corelib_tools_qbytearray.cpp | 402 + .../code/src_corelib_tools_qdatetime.cpp | 156 + .../snippets/code/src_corelib_tools_qhash.cpp | 309 + .../code/src_corelib_tools_qlinkedlist.cpp | 214 + .../code/src_corelib_tools_qlistdata.cpp | 277 + .../code/src_corelib_tools_qlocale.cpp | 101 + .../snippets/code/src_corelib_tools_qmap.cpp | 323 + .../code/src_corelib_tools_qpoint.cpp | 161 + .../code/src_corelib_tools_qqueue.cpp | 58 + .../snippets/code/src_corelib_tools_qrect.cpp | 60 + .../code/src_corelib_tools_qregexp.cpp | 225 + .../snippets/code/src_corelib_tools_qsize.cpp | 146 + .../code/src_corelib_tools_qstring.cpp | 95 + .../code/src_corelib_tools_qtimeline.cpp | 65 + .../code/src_corelib_tools_qvector.cpp | 193 + .../code/src_corelib_xml_qxmlstream.cpp | 77 + .../code/src_gui_accessible_qaccessible.cpp | 57 + .../src_gui_dialogs_qabstractprintdialog.cpp | 55 + .../code/src_gui_dialogs_qfiledialog.cpp | 136 + .../code/src_gui_dialogs_qfontdialog.cpp | 90 + .../snippets/code/src_gui_dialogs_qwizard.cpp | 81 + .../code/src_gui_effects_qgraphicseffect.cpp | 87 + ...c_gui_graphicsview_qgraphicsgridlayout.cpp | 63 + .../src_gui_graphicsview_qgraphicsitem.cpp | 249 + ...gui_graphicsview_qgraphicslinearlayout.cpp | 63 + ..._gui_graphicsview_qgraphicsproxywidget.cpp | 96 + .../src_gui_graphicsview_qgraphicsscene.cpp | 125 + ...c_gui_graphicsview_qgraphicssceneevent.cpp | 55 + .../src_gui_graphicsview_qgraphicsview.cpp | 136 + .../src_gui_graphicsview_qgraphicswidget.cpp | 75 + .../snippets/code/src_gui_image_qbitmap.cpp | 54 + .../src/snippets/code/src_gui_image_qicon.cpp | 82 + .../snippets/code/src_gui_image_qimage.cpp | 86 + .../code/src_gui_image_qimagereader.cpp | 75 + .../code/src_gui_image_qimagewriter.cpp | 69 + .../snippets/code/src_gui_image_qmovie.cpp | 63 + .../snippets/code/src_gui_image_qpixmap.cpp | 68 + .../code/src_gui_image_qpixmapcache.cpp | 66 + .../code/src_gui_image_qpixmapfilter.cpp | 72 + .../src_gui_itemviews_qabstractitemview.cpp | 67 + .../src_gui_itemviews_qdatawidgetmapper.cpp | 73 + .../src_gui_itemviews_qitemeditorfactory.cpp | 73 + .../src_gui_itemviews_qitemselectionmodel.cpp | 60 + .../src_gui_itemviews_qstandarditemmodel.cpp | 86 + .../code/src_gui_itemviews_qtablewidget.cpp | 55 + .../code/src_gui_itemviews_qtreewidget.cpp | 58 + .../snippets/code/src_gui_kernel_qaction.cpp | 59 + .../code/src_gui_kernel_qapplication.cpp | 167 + .../code/src_gui_kernel_qapplication_x11.cpp | 55 + .../code/src_gui_kernel_qclipboard.cpp | 63 + .../snippets/code/src_gui_kernel_qevent.cpp | 61 + .../code/src_gui_kernel_qformlayout.cpp | 86 + .../code/src_gui_kernel_qkeysequence.cpp | 69 + .../snippets/code/src_gui_kernel_qlayout.cpp | 75 + .../code/src_gui_kernel_qlayoutitem.cpp | 58 + .../code/src_gui_kernel_qshortcut.cpp | 65 + .../code/src_gui_kernel_qshortcutmap.cpp | 3 + .../snippets/code/src_gui_kernel_qsound.cpp | 59 + .../snippets/code/src_gui_kernel_qwidget.cpp | 150 + .../snippets/code/src_gui_painting_qbrush.cpp | 61 + .../snippets/code/src_gui_painting_qcolor.cpp | 59 + .../code/src_gui_painting_qdrawutil.cpp | 108 + .../code/src_gui_painting_qmatrix.cpp | 72 + .../code/src_gui_painting_qpainter.cpp | 261 + .../code/src_gui_painting_qpainterpath.cpp | 160 + .../snippets/code/src_gui_painting_qpen.cpp | 85 + .../code/src_gui_painting_qregion.cpp | 63 + .../code/src_gui_painting_qregion_unix.cpp | 68 + .../code/src_gui_painting_qtransform.cpp | 88 + .../snippets/code/src_gui_styles_qstyle.cpp | 58 + .../code/src_gui_styles_qstyleoption.cpp | 57 + .../src/snippets/code/src_gui_text_qfont.cpp | 77 + .../code/src_gui_text_qfontmetrics.cpp | 64 + .../code/src_gui_text_qsyntaxhighlighter.cpp | 124 + .../code/src_gui_text_qtextcursor.cpp | 90 + .../code/src_gui_text_qtextlayout.cpp | 73 + .../snippets/code/src_gui_util_qcompleter.cpp | 74 + .../code/src_gui_util_qdesktopservices.cpp | 65 + .../snippets/code/src_gui_util_qundostack.cpp | 120 + .../snippets/code/src_gui_util_qvalidator.cpp | 155 + .../code/src_gui_widgets_qabstractbutton.cpp | 69 + .../code/src_gui_widgets_qabstractspinbox.cpp | 58 + .../code/src_gui_widgets_qcalendarwidget.cpp | 83 + .../code/src_gui_widgets_qcheckbox.cpp | 3 + .../code/src_gui_widgets_qdatetimeedit.cpp | 89 + .../code/src_gui_widgets_qdockwidget.cpp | 57 + .../snippets/code/src_gui_widgets_qframe.cpp | 58 + .../code/src_gui_widgets_qgroupbox.cpp | 3 + .../snippets/code/src_gui_widgets_qlabel.cpp | 74 + .../code/src_gui_widgets_qlineedit.cpp | 57 + .../code/src_gui_widgets_qmainwindow.cpp | 65 + .../snippets/code/src_gui_widgets_qmenu.cpp | 87 + .../code/src_gui_widgets_qmenubar.cpp | 58 + .../code/src_gui_widgets_qplaintextedit.cpp | 64 + .../code/src_gui_widgets_qpushbutton.cpp | 3 + .../code/src_gui_widgets_qradiobutton.cpp | 3 + .../code/src_gui_widgets_qrubberband.cpp | 67 + .../code/src_gui_widgets_qscrollarea.cpp | 59 + .../code/src_gui_widgets_qspinbox.cpp | 90 + .../code/src_gui_widgets_qsplashscreen.cpp | 65 + .../code/src_gui_widgets_qsplitter.cpp | 57 + .../code/src_gui_widgets_qstatusbar.cpp | 3 + .../code/src_gui_widgets_qtextbrowser.cpp | 54 + .../code/src_gui_widgets_qtextedit.cpp | 69 + .../code/src_gui_widgets_qworkspace.cpp | 57 + .../snippets/code/src_network_access_qftp.cpp | 109 + .../code/src_network_access_qhttp.cpp | 132 + ...c_network_access_qnetworkaccessmanager.cpp | 86 + .../src_network_access_qnetworkdiskcache.cpp | 74 + .../src_network_access_qnetworkrequest.cpp | 3 + ...c_network_bearer_qnetworkconfigmanager.cpp | 58 + .../code/src_network_kernel_qhostaddress.cpp | 57 + .../code/src_network_kernel_qhostinfo.cpp | 92 + .../code/src_network_kernel_qnetworkproxy.cpp | 64 + .../src_network_socket_qabstractsocket.cpp | 78 + .../src_network_socket_qlocalsocket_unix.cpp | 62 + ...src_network_socket_qnativesocketengine.cpp | 71 + .../code/src_network_socket_qtcpserver.cpp | 3 + .../code/src_network_socket_qudpsocket.cpp | 67 + .../code/src_network_ssl_qsslcertificate.cpp | 54 + .../src_network_ssl_qsslconfiguration.cpp | 55 + .../code/src_network_ssl_qsslsocket.cpp | 100 + .../doc/src/snippets/code/src_opengl_qgl.cpp | 168 + .../snippets/code/src_opengl_qglcolormap.cpp | 74 + .../code/src_opengl_qglpixelbuffer.cpp | 69 + .../code/src_opengl_qglshaderprogram.cpp | 103 + .../snippets/code/src_qtestlib_qtestcase.cpp | 237 + .../snippets/code/src_script_qscriptable.cpp | 69 + .../snippets/code/src_script_qscriptclass.cpp | 59 + .../code/src_script_qscriptcontext.cpp | 73 + .../code/src_script_qscriptengine.cpp | 320 + .../code/src_script_qscriptengineagent.cpp | 62 + .../snippets/code/src_script_qscriptvalue.cpp | 91 + .../code/src_script_qscriptvalueiterator.cpp | 78 + .../code/src_sql_kernel_qsqldriver.cpp | 73 + .../code/src_sql_kernel_qsqlerror.cpp | 56 + .../code/src_sql_kernel_qsqlindex.cpp | 55 + .../code/src_sql_kernel_qsqlquery.cpp | 88 + .../code/src_sql_kernel_qsqlresult.cpp | 88 + .../code/src_sql_models_qsqlquerymodel.cpp | 62 + .../src/snippets/code/src_xml_dom_qdom.cpp | 230 + .../src/snippets/code/src_xml_sax_qxml.cpp | 3 + ...c_xmlpatterns_api_qabstracturiresolver.cpp | 3 + ...tterns_api_qabstractxmlforwarditerator.cpp | 3 + ..._xmlpatterns_api_qabstractxmlnodemodel.cpp | 72 + ...c_xmlpatterns_api_qabstractxmlreceiver.cpp | 57 + ...rc_xmlpatterns_api_qsimplexmlnodemodel.cpp | 69 + .../src_xmlpatterns_api_qxmlformatter.cpp | 58 + .../code/src_xmlpatterns_api_qxmlname.cpp | 58 + .../code/src_xmlpatterns_api_qxmlquery.cpp | 202 + .../src_xmlpatterns_api_qxmlresultitems.cpp | 66 + .../src_xmlpatterns_api_qxmlserializer.cpp | 57 + ..._assistant_compat_lib_qassistantclient.cpp | 75 + ...lib_extension_default_extensionfactory.cpp | 85 + ...s_designer_src_lib_extension_extension.cpp | 65 + ...er_src_lib_extension_qextensionmanager.cpp | 67 + ...esigner_src_lib_sdk_abstractformeditor.cpp | 61 + ...designer_src_lib_sdk_abstractformwindow.py | 74 + ...r_src_lib_sdk_abstractformwindowcursor.cpp | 58 + ..._src_lib_sdk_abstractformwindowmanager.cpp | 61 + ...er_src_lib_sdk_abstractobjectinspector.cpp | 61 + ...gner_src_lib_sdk_abstractpropertyeditor.py | 71 + ...designer_src_lib_sdk_abstractwidgetbox.cpp | 80 + ...gner_src_lib_uilib_abstractformbuilder.cpp | 67 + ...ols_designer_src_lib_uilib_formbuilder.cpp | 76 + ..._patternist_qapplicationargumentparser.cpp | 55 + ...ared_qtgradienteditor_qtgradientdialog.cpp | 94 + ...ed_qtpropertybrowser_qtpropertybrowser.cpp | 97 + ...ed_qtpropertybrowser_qtvariantproperty.cpp | 66 + ...shared_qttoolbardialog_qttoolbardialog.cpp | 62 + .../src/snippets/console/dbus_pingpong.txt | 3 + .../src/snippets/customstyle/customstyle.h | 69 + .../designer/autoconnection/imagedialog.h | 69 + .../designer/autoconnection/imagedialog.ui | 389 + .../designer/imagedialog/imagedialog.ui | 389 + .../multipleinheritance/imagedialog.h | 64 + .../multipleinheritance/imagedialog.ui | 389 + .../designer/noautoconnection/imagedialog.h | 69 + .../designer/noautoconnection/imagedialog.ui | 389 + .../designer/singleinheritance/imagedialog.h | 67 + .../designer/singleinheritance/imagedialog.ui | 389 + .../doc/src/snippets/dialogs/dialogs.py | 123 + .../doc/src/snippets/doc_src_qtcharts.py | 43 + .../doc/src/snippets/doc_src_qtgui.py | 53 + .../doc/src/snippets/doc_src_qtmultimedia.py | 53 + .../doc/src/snippets/doc_src_qtxmlpatterns.py | 54 + .../dockwidgets/Resources/modules.html | 28 + .../dockwidgets/Resources/qtcore.html | 122 + .../snippets/dockwidgets/Resources/qtgui.html | 276 + .../dockwidgets/Resources/qtnetwork.html | 35 + .../dockwidgets/Resources/qtopengl.html | 27 + .../snippets/dockwidgets/Resources/qtsql.html | 39 + .../snippets/dockwidgets/Resources/qtxml.html | 53 + .../snippets/dockwidgets/Resources/titles.txt | 7 + .../src/snippets/dockwidgets/dockwidgets.qrc | 12 + .../doc/src/snippets/dockwidgets/mainwindow.h | 80 + .../doc/src/snippets/draganddrop/dragwidget.h | 89 + .../doc/src/snippets/draganddrop/mainwindow.h | 81 + .../doc/src/snippets/dragging/images.qrc | 5 + .../doc/src/snippets/dragging/images/file.png | Bin 0 -> 313 bytes .../doc/src/snippets/dragging/mainwindow.cpp | 72 + .../doc/src/snippets/dragging/mainwindow.h | 81 + .../doc/src/snippets/dropactions/window.h | 81 + .../doc/src/snippets/droparea.cpp | 147 + .../doc/src/snippets/dropevents/window.py | 65 + .../doc/src/snippets/droprectangle/window.h | 81 + .../src/snippets/eventfilters/filterobject.h | 69 + .../explicitlysharedemployee/employee.h | 84 + .../src/snippets/i18n-non-qt-class/myclass.h | 69 + .../src/snippets/i18n-non-qt-class/myclass.ts | 12 + .../snippets/i18n-non-qt-class/resources.qrc | 6 + .../translations/i18n-non-qt-class_en.ts | 12 + .../translations/i18n-non-qt-class_fr.ts | 13 + .../doc/src/snippets/image/image.cpp | 69 + .../src/snippets/image/supportedformat.cpp | 56 + .../doc/src/snippets/inherited-slot/button.h | 69 + .../doc/src/snippets/itemselection/model.h | 84 + .../doc/src/snippets/layouts/layouts.cpp | 126 + .../doc/src/snippets/mainwindowsnippet.cpp | 58 + .../doc/src/snippets/matrix/matrix.cpp | 112 + .../doc/src/snippets/mdiareasnippets.cpp | 66 + .../doc/src/snippets/moc/myclass1.h | 75 + .../doc/src/snippets/moc/myclass2.h | 76 + .../doc/src/snippets/moc/myclass3.h | 69 + .../src/snippets/modelview-subclasses/model.h | 80 + .../src/snippets/modelview-subclasses/view.h | 100 + .../snippets/modelview-subclasses/window.h | 78 + .../doc/src/snippets/myscrollarea.cpp | 112 + .../doc/src/snippets/network/tcpwait.cpp | 71 + .../codesnippets/doc/src/snippets/ntfsp.cpp | 60 + .../src/snippets/patternist/anyHTMLElement.xq | 1 + .../snippets/patternist/anyXLinkAttribute.xq | 2 + .../src/snippets/patternist/bracesIncluded.xq | 1 + .../patternist/bracesIncludedResult.xml | 1 + .../src/snippets/patternist/bracesOmitted.xq | 1 + .../patternist/bracesOmittedResult.xml | 2 + .../patternist/computedTreeFragment.xq | 14 + .../src/snippets/patternist/copyAttribute.xq | 9 + .../doc/src/snippets/patternist/copyID.xq | 3 + .../snippets/patternist/directTreeFragment.xq | 7 + .../doc/src/snippets/patternist/doc.txt | 35 + .../src/snippets/patternist/docPlainHTML.xq | 1 + .../src/snippets/patternist/docPlainHTML2.xq | 1 + .../snippets/patternist/embedDataInXHTML.xq | 10 + .../snippets/patternist/embedDataInXHTML2.xq | 10 + .../snippets/patternist/emptyParagraphs.xq | 1 + .../snippets/patternist/escapeCurlyBraces.xq | 4 + .../patternist/escapeStringLiterals.xml | 2 + .../patternist/escapeStringLiterals.xq | 7 + .../patternist/expressionInsideAttribute.xq | 2 + .../src/snippets/patternist/filterOnPath.xq | 2 + .../src/snippets/patternist/filterOnStep.xq | 2 + .../src/snippets/patternist/firstParagraph.xq | 1 + .../patternist/fnStringOnAttribute.xq | 9 + .../doc/src/snippets/patternist/forClause.xq | 3 + .../doc/src/snippets/patternist/forClause2.xq | 3 + .../snippets/patternist/forClauseOnFeed.xq | 6 + .../doc/src/snippets/patternist/indented.xml | 5 + .../snippets/patternist/introAcneRemover.xq | 8 + .../src/snippets/patternist/introExample2.xq | 5 + .../patternist/introFileHierarchy.xml | 14 + .../snippets/patternist/introNavigateFS.xq | 12 + .../patternist/introductionExample.xq | 3 + .../snippets/patternist/invalidLetOrderBy.xq | 3 + .../doc/src/snippets/patternist/items.xq | 5 + .../doc/src/snippets/patternist/letOrderBy.xq | 4 + .../patternist/literalsAndOperators.xq | 2 + .../doc/src/snippets/patternist/mobeyDick.xml | 4 + .../snippets/patternist/nextLastParagraph.xq | 1 + .../nodeConstructorsAreExpressions.xq | 4 + .../patternist/nodeConstructorsInPaths.xq | 1 + .../patternist/nodeTestChildElement.xq | 1 + .../src/snippets/patternist/notIndented.xml | 1 + .../patternist/oneElementConstructor.xq | 1 + .../paragraphsExceptTheFiveFirst.xq | 1 + .../patternist/paragraphsWithTables.xq | 1 + .../doc/src/snippets/patternist/pathAB.xq | 1 + .../snippets/patternist/pathsAllParagraphs.xq | 1 + .../doc/src/snippets/patternist/simpleHTML.xq | 1 + .../src/snippets/patternist/simpleXHTML.xq | 2 + .../patternist/svgDocumentElement.xml | 1 + .../snippets/patternist/tablesInParagraphs.xq | 1 + .../src/snippets/patternist/twoSVGElements.xq | 5 + .../src/snippets/patternist/xmlStylesheet.xq | 1 + .../src/snippets/patternist/xsBooleanTrue.xq | 1 + .../patternist/xsvgDocumentElement.xml | 1 + .../snippets/persistentindexes/mainwindow.h | 80 + .../src/snippets/persistentindexes/model.h | 81 + .../doc/src/snippets/picture/picture.cpp | 121 + .../doc/src/snippets/plaintextlayout/window.h | 71 + .../doc/src/snippets/polygon/polygon.cpp | 96 + .../src/snippets/porting4-dropevents/window.h | 82 + .../src/snippets/printing-qprinter/errors.cpp | 68 + .../src/snippets/printing-qprinter/object.h | 62 + .../src/snippets/qabstractsliderisnippet.cpp | 519 + .../doc/src/snippets/qdir-listfiles/main.cpp | 64 + .../src/snippets/qdir-namefilters/main.cpp | 68 + .../doc/src/snippets/qfontdatabase/main.cpp | 74 + .../snippets/qlineargradient/paintwidget.h | 69 + .../src/snippets/qlistview-dnd/mainwindow.h | 71 + .../doc/src/snippets/qlistview-dnd/model.h | 73 + .../src/snippets/qlistview-using/mainwindow.h | 82 + .../doc/src/snippets/qlistview-using/model.h | 82 + .../src/snippets/qlistwidget-dnd/mainwindow.h | 72 + .../snippets/qlistwidget-using/mainwindow.h | 82 + .../doc/src/snippets/qmacnativewidget/main.mm | 144 + .../doc/src/snippets/qmake/delegate.h | 50 + .../doc/src/snippets/qmake/main.cpp | 50 + .../doc/src/snippets/qmake/model.cpp | 50 + .../doc/src/snippets/qmake/model.h | 50 + .../src/snippets/qmake/paintwidget_unix.cpp | 54 + .../doc/src/snippets/qmake/view.h | 50 + .../snippets/qmetaobject-invokable/window.h | 68 + .../doc/src/snippets/qquickview-ex.cpp | 67 + .../src/snippets/qsignalmapper/buttonwidget.h | 70 + .../src/snippets/qsignalmapper/mainwindow.h | 69 + .../qsortfilterproxymodel-details/main.cpp | 79 + .../doc/src/snippets/qsplashscreen/main.cpp | 66 + .../src/snippets/qsplashscreen/mainwindow.h | 64 + .../snippets/qsplashscreen/qsplashscreen.qrc | 5 + .../doc/src/snippets/qsplashscreen/splash.png | Bin 0 -> 27926 bytes .../doc/src/snippets/qstackedlayout/main.py | 87 + .../doc/src/snippets/qstackedwidget/main.py | 77 + .../doc/src/snippets/qstatustipevent/main.cpp | 74 + .../doc/src/snippets/qstyleoption/main.cpp | 105 + .../src/snippets/qsvgwidget/qsvgwidget.qrc | 5 + .../doc/src/snippets/qsvgwidget/spheres.svg | 79 + .../doc/src/snippets/qsvgwidget/sunflower.svg | 188 + .../qtablewidget-dnd/Images/cubed.png | Bin 0 -> 437 bytes .../qtablewidget-dnd/Images/squared.png | Bin 0 -> 440 bytes .../src/snippets/qtablewidget-dnd/images.qrc | 6 + .../snippets/qtablewidget-dnd/mainwindow.h | 78 + .../qtablewidget-resizing/mainwindow.h | 77 + .../qtablewidget-using/Images/cubed.png | Bin 0 -> 437 bytes .../qtablewidget-using/Images/squared.png | Bin 0 -> 440 bytes .../snippets/qtablewidget-using/images.qrc | 6 + .../snippets/qtablewidget-using/mainwindow.h | 80 + .../doc/src/snippets/qtcast/qtcast.h | 64 + .../snippets/qtreeview-dnd/dragdropmodel.h | 72 + .../src/snippets/qtreeview-dnd/mainwindow.h | 71 + .../doc/src/snippets/qtreeview-dnd/treeitem.h | 81 + .../src/snippets/qtreeview-dnd/treemodel.h | 89 + .../snippets/qtreewidget-using/mainwindow.cpp | 111 + .../snippets/qtreewidget-using/mainwindow.h | 87 + .../mainwindow.cpp | 59 + .../mainwindow.h | 87 + .../qtscript/registeringobjects/myobject.h | 67 + .../snippets/qtscript/scriptedslot/object.js | 18 + .../qtscript/scriptedslot/scriptedslot.qrc | 5 + .../snippets/quiloader/doc_src_qtuiloader.py | 53 + .../doc/src/snippets/quiloader/myform.ui | 130 + .../doc/src/snippets/quiloader/mywidget.h | 62 + .../doc/src/snippets/quiloader/mywidget.qrc | 5 + .../snippets/qx11embedwidget/embedwidget.h | 75 + .../src/snippets/qxmlquery/bindingExample.py | 59 + .../src/snippets/qxmlschemavalidator/main.cpp | 112 + .../src/snippets/reading-selections/model.h | 84 + .../src/snippets/reading-selections/window.h | 77 + .../src/snippets/separations/finalwidget.h | 87 + .../src/snippets/separations/screenwidget.h | 96 + .../doc/src/snippets/separations/viewer.h | 99 + .../doc/src/snippets/shareddirmodel/main.cpp | 90 + .../src/snippets/sharedemployee/employee.h | 104 + .../doc/src/snippets/sharedtablemodel/model.h | 84 + .../snippets/signalmapper/accountsfile.txt | 1 + .../src/snippets/signalmapper/filereader.h | 78 + .../src/snippets/signalmapper/reportfile.txt | 2 + .../doc/src/snippets/signalmapper/taxfile.txt | 1 + .../src/snippets/signalsandslots/lcdnumber.h | 98 + .../signalsandslots/signalsandslots.h | 99 + .../doc/src/snippets/simpleparse/handler.h | 77 + .../doc/src/snippets/splitter/splitter.cpp | 76 + .../src/snippets/splitterhandle/splitter.h | 61 + .../src/snippets/sqldatabase/sqldatabase.py | 489 + .../src/snippets/stringlistmodel/model.cpp | 170 + .../doc/src/snippets/stringlistmodel/model.h | 82 + .../doc/src/snippets/styles/styles.cpp | 80 + .../snippets/stylesheet/common-mistakes.cpp | 62 + .../snippets/textblock-fragments/mainwindow.h | 75 + .../snippets/textblock-fragments/xmlwriter.h | 74 + .../snippets/textdocument-blocks/mainwindow.h | 75 + .../snippets/textdocument-blocks/xmlwriter.h | 71 + .../src/snippets/textdocument-css/main.cpp | 58 + .../snippets/textdocument-frames/mainwindow.h | 74 + .../snippets/textdocument-frames/xmlwriter.h | 74 + .../textdocument-imagedrop/textedit.h | 66 + .../textdocument-imageformat/images.qrc | 6 + .../images/advert.png | Bin 0 -> 16291 bytes .../images/newimage.png | Bin 0 -> 5490 bytes .../snippets/textdocument-images/images.qrc | 5 + .../textdocument-images/images/advert.png | Bin 0 -> 16291 bytes .../textdocument-listitems/mainwindow.h | 85 + .../snippets/textdocument-lists/mainwindow.h | 89 + .../textdocument-printing/mainwindow.h | 82 + .../textdocument-selections/mainwindow.h | 89 + .../textdocument-tables/mainwindow.cpp | 125 + .../snippets/textdocument-tables/mainwindow.h | 75 + .../snippets/textdocument-tables/xmlwriter.h | 74 + .../snippets/textdocument-texttable/main.cpp | 56 + .../doc/src/snippets/threads/threads.h | 61 + .../doc/src/snippets/timers/timers.cpp | 88 + .../doc/src/snippets/transform/main.cpp | 110 + .../uitools/calculatorform/calculatorform.ui | 303 + .../src/snippets/updating-selections/model.h | 84 + .../src/snippets/updating-selections/window.h | 77 + .../doc/src/snippets/whatsthis/whatsthis.cpp | 57 + .../doc/src/snippets/widget-mask/mask.qrc | 5 + .../doc/src/snippets/widget-mask/tux.png | Bin 0 -> 12191 bytes .../doc/src/snippets/widgetdelegate.cpp | 72 + .../src/snippets/widgets-tutorial/template.py | 66 + .../doc/src/snippets/xml/rsslisting/handler.h | 84 + .../src/snippets/xml/rsslisting/rsslisting.h | 96 + .../examples/dbus/example-client.py | 100 + .../examples/dbus/example-server.py | 119 + .../cppextensions/plugins/plugin.cpp | 68 + .../cppextensions/plugins/plugins.qml | 62 + .../dialogs/classwizard/classwizard.py | 254 + .../dialogs/classwizard/classwizard.qrc | 11 + .../dialogs/classwizard/images/background.png | Bin 0 -> 22578 bytes .../dialogs/classwizard/images/banner.png | Bin 0 -> 3947 bytes .../dialogs/classwizard/images/logo1.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/logo2.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/logo3.png | Bin 0 -> 1619 bytes .../dialogs/classwizard/images/watermark1.png | Bin 0 -> 14516 bytes .../dialogs/classwizard/images/watermark2.png | Bin 0 -> 14912 bytes .../examples/dialogs/extension/finddialog.py | 119 + .../dialogs/licensewizard/images/logo.png | Bin 0 -> 1810 bytes .../licensewizard/images/watermark.png | Bin 0 -> 34998 bytes .../dialogs/licensewizard/licensewizard.h | 173 + .../dialogs/licensewizard/licensewizard.qrc | 6 + .../dialogs/standarddialogs/dialog.cpp | 80 + .../examples/dialogs/tabdialog/tabdialog.cpp | 193 + .../graphicsview/simpleanchorlayout/main.cpp | 72 + .../imageprovider/imageprovider-example.qml | 59 + .../examples/imageprovider/imageprovider.cpp | 83 + .../mysortfilterproxymodel.cpp | 109 + .../itemviews/pixelator/pixeldelegate.cpp | 103 + .../mainwindows/application/mainwindow.h | 112 + .../mainwindows/application/mainwindow.py | 357 + .../mainwindows/dockwidgets/mainwindow.py | 253 + .../examples/mainwindows/mainwindow.py | 366 + .../examples/mainwindows/mdi/mainwindow.py | 360 + .../examples/mainwindows/menus/mainwindow.py | 366 + .../examples/mainwindows/sdi/mainwindow.cpp | 60 + .../examples/quick/plugins/plugins.qml | 61 + .../relationaltablemodel.cpp | 120 + .../richtext/textobject/svgtextobject.h | 79 + .../examples/widgets/groupbox/window.cpp | 187 + .../widgets/icons/iconsizespinbox.cpp | 72 + .../examples/widgets/spinboxes/window.py | 247 + .../examples/xml/streambookmarks/xbelreader.h | 90 + .../snippets/customstyle/main.cpp | 61 + .../qtwebkit_qwebinspector_snippet.cpp | 60 + .../qtwebkit_qwebview_snippet.cpp | 80 + .../webkitsnippets/simple/main.cpp | 63 + .../webkitsnippets/webelement/main.cpp | 114 + .../webkitsnippets/webpage/main.cpp | 83 + sources/pyside2/doc/conf.py.in | 190 + sources/pyside2/doc/considerations.rst | 149 + sources/pyside2/doc/contents.rst | 23 + sources/pyside2/doc/deployment-briefcase.rst | 199 + sources/pyside2/doc/deployment-cxfreeze.rst | 130 + sources/pyside2/doc/deployment-fbs.rst | 97 + .../pyside2/doc/deployment-pyinstaller.rst | 158 + sources/pyside2/doc/deployment.rst | 120 + .../doc/examples/images/tabbedbrowser.png | Bin 0 -> 37147 bytes sources/pyside2/doc/examples/index.rst | 14 + .../pyside2/doc/examples/tabbedbrowser.rst | 58 + .../pyside2/doc/extras/QtCore.ClassInfo.rst | 23 + .../pyside2/doc/extras/QtCore.Property.rst | 62 + sources/pyside2/doc/extras/QtCore.QEnum.rst | 92 + sources/pyside2/doc/extras/QtCore.Signal.rst | 39 + sources/pyside2/doc/extras/QtCore.Slot.rst | 39 + sources/pyside2/doc/extras/QtCore.rst | 5 + sources/pyside2/doc/extras/QtGui.rst | 7 + sources/pyside2/doc/extras/QtHelp.rst | 5 + sources/pyside2/doc/extras/QtMultimedia.rst | 7 + sources/pyside2/doc/extras/QtNetwork.rst | 5 + sources/pyside2/doc/extras/QtOpenGL.rst | 14 + sources/pyside2/doc/extras/QtScript.rst | 21 + sources/pyside2/doc/extras/QtScriptTools.rst | 5 + sources/pyside2/doc/extras/QtSql.rst | 5 + sources/pyside2/doc/extras/QtSvg.rst | 5 + sources/pyside2/doc/extras/QtTest.rst | 7 + .../doc/extras/QtUiTools.loadUiType.rst | 36 + sources/pyside2/doc/extras/QtUiTools.rst | 9 + sources/pyside2/doc/extras/QtWebKit.rst | 94 + sources/pyside2/doc/extras/QtXml.rst | 5 + sources/pyside2/doc/extras/QtXmlPatterns.rst | 12 + sources/pyside2/doc/faq.rst | 37 + sources/pyside2/doc/gettingstarted-linux.rst | 96 + sources/pyside2/doc/gettingstarted-macOS.rst | 95 + .../pyside2/doc/gettingstarted-windows.rst | 104 + sources/pyside2/doc/gettingstarted.rst | 218 + sources/pyside2/doc/index.rst | 104 + sources/pyside2/doc/inheritance_diagram.py | 372 + sources/pyside2/doc/modules.rst | 101 + sources/pyside2/doc/pyside-config.qdocconf.in | 19 + .../pyside2/doc/pyside-examples/examples.qdoc | 37 + .../images/pyside2example-classwizard.png | Bin 0 -> 57931 bytes .../images/pyside2example-stardelegate.png | Bin 0 -> 22482 bytes .../images/screenshot_hello.png | Bin 0 -> 21193 bytes .../pyside-examples/pyside2-classwizard.qdoc | 39 + .../pyside-examples/pyside2-stardelegate.qdoc | 39 + sources/pyside2/doc/pysideinclude.py | 147 + .../pyside2/doc/qtattributionsscannertorst.py | 131 + .../doc/qtmodules/pyside-examples.qdocconf.in | 12 + .../qtmodules/pyside-qt3dextras.qdocconf.in | 3 + .../doc/qtmodules/pyside-qtcharts.qdocconf.in | 2 + .../qtmodules/pyside-qtconcurrent.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtcore.qdocconf.in | 2 + .../pyside-qtdatavisualization.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtgui.qdocconf.in | 2 + .../doc/qtmodules/pyside-qthelp.qdocconf.in | 2 + .../qtmodules/pyside-qtlocation.qdocconf.in | 3 + .../qtmodules/pyside-qtmacextras.qdocconf.in | 2 + .../pyside-qtmultimediawidgets.qdocconf.in | 3 + .../qtmodules/pyside-qtnetwork.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtopengl.qdocconf.in | 2 + .../pyside-qtpositioning.qdocconf.in | 3 + .../pyside-qtprintsupport.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtqml.qdocconf.in | 5 + .../pyside-qtquickwidgets.qdocconf.in | 3 + .../doc/qtmodules/pyside-qtscxml.qdocconf.in | 3 + .../qtmodules/pyside-qtsensors.qdocconf.in | 3 + .../doc/qtmodules/pyside-qtsql.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtsvg.qdocconf.in | 2 + .../doc/qtmodules/pyside-qttest.qdocconf.in | 2 + .../pyside-qttexttospeech.qdocconf.in | 3 + .../qtmodules/pyside-qtuitools.qdocconf.in | 2 + .../qtmodules/pyside-qtwebchannel.qdocconf.in | 2 + .../pyside-qtwebenginewidgets.qdocconf.in | 3 + .../qtmodules/pyside-qtwebsockets.qdocconf.in | 2 + .../qtmodules/pyside-qtwidgets.qdocconf.in | 2 + .../qtmodules/pyside-qtwinextras.qdocconf.in | 2 + .../qtmodules/pyside-qtx11extras.qdocconf.in | 2 + .../doc/qtmodules/pyside-qtxml.qdocconf.in | 2 + .../pyside-qtxmlpatterns.qdocconf.in | 2 + sources/pyside2/doc/quickstart.rst | 118 + sources/pyside2/doc/src/README.md | 1 + .../basictutorial/clickablebutton.rst | 90 + .../doc/tutorials/basictutorial/dialog.rst | 145 + .../doc/tutorials/basictutorial/icons.png | Bin 0 -> 3202 bytes .../tutorials/basictutorial/icons/forward.png | Bin 0 -> 1113 bytes .../tutorials/basictutorial/icons/pause.png | Bin 0 -> 1001 bytes .../tutorials/basictutorial/icons/play.png | Bin 0 -> 970 bytes .../basictutorial/icons/previous.png | Bin 0 -> 1050 bytes .../tutorials/basictutorial/icons/stop.png | Bin 0 -> 1064 bytes .../tutorials/basictutorial/player-new.png | Bin 0 -> 7818 bytes .../doc/tutorials/basictutorial/player.png | Bin 0 -> 5835 bytes .../doc/tutorials/basictutorial/qml.rst | 67 + .../doc/tutorials/basictutorial/qrcfiles.rst | 169 + .../doc/tutorials/basictutorial/style.qss | 23 + .../doc/tutorials/basictutorial/uifiles.rst | 187 + .../doc/tutorials/basictutorial/widgets.rst | 45 + .../basictutorial/widgetstyling-no.png | Bin 0 -> 26444 bytes .../basictutorial/widgetstyling-simple-no.png | Bin 0 -> 3834 bytes .../widgetstyling-simple-yes.png | Bin 0 -> 4743 bytes .../basictutorial/widgetstyling-yes.png | Bin 0 -> 32311 bytes .../tutorials/basictutorial/widgetstyling.py | 95 + .../tutorials/basictutorial/widgetstyling.rst | 169 + .../doc/tutorials/datavisualize/add_chart.rst | 20 + .../datavisualize/add_mainwindow.rst | 32 + .../tutorials/datavisualize/add_tableview.rst | 70 + .../doc/tutorials/datavisualize/all_hour.csv | 8 + .../datavisualize/datavisualize.tar.bz2 | Bin 0 -> 6086 bytes .../datavisualize/datavisualize1/main.py | 55 + .../datavisualize/datavisualize2/main.py | 78 + .../datavisualize/datavisualize3/main.py | 88 + .../datavisualize3/main_window.py | 69 + .../datavisualize/datavisualize4/main.py | 90 + .../datavisualize4/main_widget.py | 80 + .../datavisualize4/main_window.py | 69 + .../datavisualize4/table_model.py | 88 + .../datavisualize/datavisualize5/main.py | 90 + .../datavisualize5/main_widget.py | 91 + .../datavisualize5/main_window.py | 69 + .../datavisualize5/table_model.py | 88 + .../datavisualize/datavisualize6/main.py | 92 + .../datavisualize6/main_widget.py | 131 + .../datavisualize6/main_window.py | 70 + .../datavisualize6/table_model.py | 88 + .../tutorials/datavisualize/filter_data.rst | 29 + .../images/QMainWindow-layout.png | Bin 0 -> 17272 bytes .../images/datavisualization_app.png | Bin 0 -> 40458 bytes .../doc/tutorials/datavisualize/index.rst | 26 + .../datavisualize/plot_datapoints.rst | 25 + .../doc/tutorials/datavisualize/read_data.rst | 41 + .../doc/tutorials/expenses/expenses.rst | 314 + .../doc/tutorials/expenses/expenses_tool.png | Bin 0 -> 47826 bytes .../pyside2/doc/tutorials/expenses/main.py | 207 + .../doc/tutorials/expenses/main_snake_prop.py | 210 + .../tutorials/expenses/steps/01-expenses.py | 59 + .../tutorials/expenses/steps/02-expenses.py | 70 + .../tutorials/expenses/steps/03-expenses.py | 77 + .../tutorials/expenses/steps/04-expenses.py | 89 + .../tutorials/expenses/steps/05-expenses.py | 117 + .../tutorials/expenses/steps/06-expenses.py | 137 + .../tutorials/expenses/steps/07-expenses.py | 164 + .../tutorials/expenses/steps/08-expenses.py | 177 + .../tutorials/expenses/steps/09-expenses.py | 185 + .../tutorials/expenses/steps/10-expenses.py | 207 + sources/pyside2/doc/tutorials/index.rst | 42 + .../portingguide/chapter1/chapter1.rst | 89 + .../portingguide/chapter1/createdb.py | 131 + .../chapter1/images/chapter1_books.png | Bin 0 -> 25391 bytes .../tutorials/portingguide/chapter1/initdb.h | 160 + .../tutorials/portingguide/chapter1/main.py | 59 + .../portingguide/chapter2/bookdelegate.cpp | 143 + .../portingguide/chapter2/bookdelegate.h | 83 + .../portingguide/chapter2/bookdelegate.py | 134 + .../portingguide/chapter2/chapter2.rst | 93 + .../portingguide/chapter2/createdb.py | 131 + .../chapter2/images/chapter2_books.png | Bin 0 -> 34658 bytes .../images/chapter2_books_with_relation.png | Bin 0 -> 44122 bytes .../portingguide/chapter2/images/star.png | Bin 0 -> 782 bytes .../tutorials/portingguide/chapter2/main.py | 63 + .../portingguide/chapter3/bookdelegate-old.py | 134 + .../portingguide/chapter3/bookdelegate.py | 133 + .../tutorials/portingguide/chapter3/books.qrc | 5 + .../portingguide/chapter3/bookwindow.cpp | 171 + .../portingguide/chapter3/bookwindow.py | 137 + .../portingguide/chapter3/bookwindow.ui | 149 + .../portingguide/chapter3/chapter3.rst | 121 + .../portingguide/chapter3/createdb.py | 131 + .../chapter3/images/chapter3-books.png | Bin 0 -> 34624 bytes .../portingguide/chapter3/images/star.png | Bin 0 -> 782 bytes .../portingguide/chapter3/main-old.py | 52 + .../tutorials/portingguide/chapter3/main.py | 53 + .../tutorials/portingguide/hello_world_ex.py | 76 + .../doc/tutorials/portingguide/index.rst | 196 + sources/pyside2/doc/tutorials/qmlapp/logo.png | Bin 0 -> 6208 bytes sources/pyside2/doc/tutorials/qmlapp/main.py | 82 + .../doc/tutorials/qmlapp/newpyproject.png | Bin 0 -> 16091 bytes .../doc/tutorials/qmlapp/projectsmode.png | Bin 0 -> 8848 bytes .../doc/tutorials/qmlapp/pyprojname.png | Bin 0 -> 8068 bytes .../doc/tutorials/qmlapp/pyprojxplor.png | Bin 0 -> 10062 bytes .../doc/tutorials/qmlapp/qmlapplication.png | Bin 0 -> 10950 bytes .../doc/tutorials/qmlapp/qmlapplication.rst | 132 + sources/pyside2/doc/tutorials/qmlapp/view.qml | 102 + .../doc/tutorials/qmlintegration/main.py | 113 + .../qmlintegration/qmlintegration.rst | 111 + .../qmlintegration/qtquickcontrols2.conf | 10 + .../doc/tutorials/qmlintegration/style.qrc | 5 + .../qmlintegration/textproperties_default.png | Bin 0 -> 19347 bytes .../textproperties_material.png | Bin 0 -> 21170 bytes .../doc/tutorials/qmlintegration/view.qml | 183 + .../doc/tutorials/qmlsqlintegration/chat.qml | 127 + .../qmlsqlintegration/example_list_view.png | Bin 0 -> 6954 bytes .../doc/tutorials/qmlsqlintegration/main.py | 85 + .../qmlsqlintegration/qmlsqlintegration.rst | 225 + .../tutorials/qmlsqlintegration/sqlDialog.py | 146 + sources/pyside2/doc/typesystem_doc.xml.in | 63 + sources/pyside2/doc/videos.rst | 96 + sources/pyside2/libpyside/CMakeLists.txt | 208 + .../libpyside/PySide2Config-spec.cmake.in | 16 + .../pyside2/libpyside/PySide2Config.cmake.in | 5 + .../libpyside/PySide2ConfigVersion.cmake.in | 10 + .../pyside2/libpyside/dynamicqmetaobject.cpp | 588 + .../pyside2/libpyside/dynamicqmetaobject.h | 84 + .../pyside2/libpyside/dynamicqmetaobject_p.h | 107 + sources/pyside2/libpyside/feature_select.cpp | 735 + sources/pyside2/libpyside/feature_select.h | 55 + .../pyside2/libpyside/globalreceiverv2.cpp | 359 + sources/pyside2/libpyside/globalreceiverv2.h | 150 + sources/pyside2/libpyside/pyside.cpp | 628 + sources/pyside2/libpyside/pyside.h | 172 + sources/pyside2/libpyside/pyside2.pc.in | 15 + sources/pyside2/libpyside/pyside_p.h | 71 + sources/pyside2/libpyside/pysideclassinfo.cpp | 207 + sources/pyside2/libpyside/pysideclassinfo.h | 70 + sources/pyside2/libpyside/pysideclassinfo_p.h | 70 + sources/pyside2/libpyside/pysidemacros.h | 55 + .../pyside2/libpyside/pysidemetafunction.cpp | 231 + .../pyside2/libpyside/pysidemetafunction.h | 75 + .../pyside2/libpyside/pysidemetafunction_p.h | 62 + sources/pyside2/libpyside/pysideproperty.cpp | 648 + sources/pyside2/libpyside/pysideproperty.h | 116 + sources/pyside2/libpyside/pysideproperty_p.h | 182 + sources/pyside2/libpyside/pysideqenum.cpp | 258 + sources/pyside2/libpyside/pysideqenum.h | 57 + sources/pyside2/libpyside/pysideqflags.cpp | 213 + sources/pyside2/libpyside/pysideqflags.h | 79 + sources/pyside2/libpyside/pysidesignal.cpp | 1044 + sources/pyside2/libpyside/pysidesignal.h | 163 + sources/pyside2/libpyside/pysidesignal_p.h | 94 + sources/pyside2/libpyside/pysideslot.cpp | 199 + sources/pyside2/libpyside/pysideslot_p.h | 49 + .../pyside2/libpyside/pysidestaticstrings.cpp | 63 + .../pyside2/libpyside/pysidestaticstrings.h | 60 + sources/pyside2/libpyside/pysideweakref.cpp | 114 + sources/pyside2/libpyside/pysideweakref.h | 56 + sources/pyside2/libpyside/signalmanager.cpp | 692 + sources/pyside2/libpyside/signalmanager.h | 121 + sources/pyside2/plugins/CMakeLists.txt | 39 + sources/pyside2/plugins/customwidget.cpp | 138 + sources/pyside2/plugins/customwidget.h | 75 + sources/pyside2/plugins/customwidgets.cpp | 61 + sources/pyside2/plugins/customwidgets.h | 69 + sources/pyside2/pyside_version.py | 55 + sources/pyside2/tests/CMakeLists.txt | 56 + .../tests/Qt3DAnimation/CMakeLists.txt | 1 + sources/pyside2/tests/Qt3DCore/CMakeLists.txt | 1 + .../pyside2/tests/Qt3DExtras/CMakeLists.txt | 1 + .../tests/Qt3DExtras/qt3dextras_test.py | 161 + .../pyside2/tests/Qt3DInput/CMakeLists.txt | 1 + .../pyside2/tests/Qt3DLogic/CMakeLists.txt | 1 + .../pyside2/tests/Qt3DQuick/CMakeLists.txt | 1 + .../pyside2/tests/Qt3DRender/CMakeLists.txt | 1 + .../tests/QtAxContainer/CMakeLists.txt | 1 + sources/pyside2/tests/QtCharts/CMakeLists.txt | 1 + .../pyside2/tests/QtCharts/qcharts_test.py | 69 + .../pyside2/tests/QtConcurrent/CMakeLists.txt | 1 + sources/pyside2/tests/QtCore/CMakeLists.txt | 143 + .../pyside2/tests/QtCore/attr_cache_py3k.py | 73 + .../tests/QtCore/blocking_signals_test.py | 148 + sources/pyside2/tests/QtCore/bug_1019.py | 67 + sources/pyside2/tests/QtCore/bug_1031.py | 41 + sources/pyside2/tests/QtCore/bug_1063.py | 64 + sources/pyside2/tests/QtCore/bug_1069.py | 58 + sources/pyside2/tests/QtCore/bug_1313.py | 85 + sources/pyside2/tests/QtCore/bug_278_test.py | 58 + sources/pyside2/tests/QtCore/bug_332.py | 53 + sources/pyside2/tests/QtCore/bug_408.py | 62 + sources/pyside2/tests/QtCore/bug_428.py | 52 + sources/pyside2/tests/QtCore/bug_462.py | 79 + sources/pyside2/tests/QtCore/bug_505.py | 56 + sources/pyside2/tests/QtCore/bug_515.py | 54 + sources/pyside2/tests/QtCore/bug_606.py | 68 + sources/pyside2/tests/QtCore/bug_656.py | 45 + sources/pyside2/tests/QtCore/bug_686.py | 123 + sources/pyside2/tests/QtCore/bug_699.py | 52 + sources/pyside2/tests/QtCore/bug_706.py | 61 + sources/pyside2/tests/QtCore/bug_820.py | 103 + sources/pyside2/tests/QtCore/bug_826.py | 64 + sources/pyside2/tests/QtCore/bug_829.py | 72 + sources/pyside2/tests/QtCore/bug_835.py | 100 + sources/pyside2/tests/QtCore/bug_920.py | 59 + sources/pyside2/tests/QtCore/bug_927.py | 58 + sources/pyside2/tests/QtCore/bug_931.py | 55 + sources/pyside2/tests/QtCore/bug_938.py | 50 + sources/pyside2/tests/QtCore/bug_953.py | 54 + sources/pyside2/tests/QtCore/bug_987.py | 49 + sources/pyside2/tests/QtCore/bug_994.py | 61 + .../pyside2/tests/QtCore/bug_PYSIDE-164.py | 75 + sources/pyside2/tests/QtCore/bug_PYSIDE-42.py | 52 + .../pyside2/tests/QtCore/child_event_test.py | 86 + .../pyside2/tests/QtCore/classinfo_test.py | 116 + sources/pyside2/tests/QtCore/deepcopy_test.py | 118 + .../pyside2/tests/QtCore/deletelater_test.py | 56 + .../tests/QtCore/destroysignal_test.py | 62 + .../tests/QtCore/duck_punching_test.py | 108 + .../pyside2/tests/QtCore/emoji_string_test.py | 85 + sources/pyside2/tests/QtCore/hash_test.py | 93 + sources/pyside2/tests/QtCore/inherits_test.py | 50 + sources/pyside2/tests/QtCore/max_signals.py | 68 + .../tests/QtCore/missing_symbols_test.py | 50 + .../pyside2/tests/QtCore/mockclass_test.py | 62 + .../tests/QtCore/multiple_feature_test.py | 141 + .../pyside2/tests/QtCore/python_conversion.py | 100 + sources/pyside2/tests/QtCore/qabs_test.py | 54 + .../tests/QtCore/qabstractitemmodel_test.py | 74 + .../tests/QtCore/qabstracttransition_test.py | 191 + .../tests/QtCore/qanimationgroup_test.py | 60 + .../pyside2/tests/QtCore/qbitarray_test.py | 154 + .../QtCore/qbytearray_buffer_protocol_test.py | 60 + .../qbytearray_concatenation_operator_test.py | 65 + .../QtCore/qbytearray_operator_iadd_test.py | 93 + .../tests/QtCore/qbytearray_operator_test.py | 118 + .../pyside2/tests/QtCore/qbytearray_test.py | 291 + .../pyside2/tests/QtCore/qcalendar_test.py | 53 + sources/pyside2/tests/QtCore/qcbor_test.py | 80 + .../pyside2/tests/QtCore/qcollator_test.py | 66 + .../tests/QtCore/qcommandlineparser_test.py | 61 + .../QtCore/qcoreapplication_instance_test.py | 55 + .../tests/QtCore/qcoreapplication_test.py | 46 + .../pyside2/tests/QtCore/qdatastream_test.py | 362 + sources/pyside2/tests/QtCore/qdate_test.py | 68 + .../pyside2/tests/QtCore/qdatetime_test.py | 57 + .../pyside2/tests/QtCore/qeasingcurve_test.py | 60 + sources/pyside2/tests/QtCore/qenum_test.py | 247 + sources/pyside2/tests/QtCore/qevent_test.py | 59 + sources/pyside2/tests/QtCore/qfile_test.py | 92 + .../pyside2/tests/QtCore/qfileinfo_test.py | 48 + .../pyside2/tests/QtCore/qfileread_test.py | 87 + sources/pyside2/tests/QtCore/qflags_test.py | 128 + sources/pyside2/tests/QtCore/qhandle_test.py | 51 + .../tests/QtCore/qinstallmsghandler_test.py | 86 + .../tests/QtCore/qjsondocument_test.py | 63 + sources/pyside2/tests/QtCore/qlinef_test.py | 54 + sources/pyside2/tests/QtCore/qlocale_test.py | 74 + .../pyside2/tests/QtCore/qlockfile_test.py | 62 + .../QtCore/qmessageauthenticationcode_test.py | 52 + .../pyside2/tests/QtCore/qmetaobject_test.py | 96 + .../tests/QtCore/qmimedatabase_test.py | 84 + .../qmodelindex_internalpointer_test.py | 83 + .../QtCore/qobject_children_segfault_test.py | 62 + .../QtCore/qobject_connect_notify_test.py | 111 + .../tests/QtCore/qobject_destructor.py | 53 + .../tests/QtCore/qobject_event_filter_test.py | 148 + .../tests/QtCore/qobject_inherits_test.py | 131 + .../QtCore/qobject_objectproperty_test.py | 65 + .../tests/QtCore/qobject_parent_test.py | 296 + .../tests/QtCore/qobject_property_test.py | 75 + .../QtCore/qobject_protected_methods_test.py | 73 + sources/pyside2/tests/QtCore/qobject_test.py | 90 + .../tests/QtCore/qobject_timer_event_test.py | 79 + .../QtCore/qobject_tr_as_instance_test.py | 74 + .../QtCore/qoperatingsystemversion_test.py | 47 + sources/pyside2/tests/QtCore/qpoint_test.py | 54 + sources/pyside2/tests/QtCore/qprocess_test.py | 65 + .../tests/QtCore/qproperty_decorator.py | 71 + .../tests/QtCore/qrandomgenerator_test.py | 55 + sources/pyside2/tests/QtCore/qrect_test.py | 147 + sources/pyside2/tests/QtCore/qregexp_test.py | 55 + .../tests/QtCore/qregularexpression_test.py | 63 + .../pyside2/tests/QtCore/qresource_test.py | 77 + .../pyside2/tests/QtCore/qsettings_test.ini | 4 + .../pyside2/tests/QtCore/qsettings_test.py | 119 + sources/pyside2/tests/QtCore/qsize_test.py | 61 + .../pyside2/tests/QtCore/qslot_object_test.py | 78 + .../tests/QtCore/qsocketnotifier_test.py | 64 + sources/pyside2/tests/QtCore/qsrand_test.py | 50 + .../tests/QtCore/qstandardpaths_test.py | 55 + sources/pyside2/tests/QtCore/qstate_test.py | 71 + .../tests/QtCore/qstatemachine_test.py | 104 + .../pyside2/tests/QtCore/qstorageinfo_test.py | 49 + sources/pyside2/tests/QtCore/qstring_test.py | 58 + sources/pyside2/tests/QtCore/qsysinfo_test.py | 49 + .../pyside2/tests/QtCore/qtext_codec_test.py | 54 + .../pyside2/tests/QtCore/qtextstream_test.py | 122 + .../tests/QtCore/qthread_prod_cons_test.py | 142 + .../tests/QtCore/qthread_signal_test.py | 97 + sources/pyside2/tests/QtCore/qthread_test.py | 115 + .../tests/QtCore/qtimer_singleshot_test.py | 112 + .../tests/QtCore/qtimer_timeout_test.py | 92 + .../pyside2/tests/QtCore/qtimezone_test.py | 50 + .../pyside2/tests/QtCore/qtnamespace_test.py | 54 + sources/pyside2/tests/QtCore/quoteEnUS.txt | 1 + sources/pyside2/tests/QtCore/qurl_test.py | 169 + .../pyside2/tests/QtCore/qurlquery_test.py | 64 + sources/pyside2/tests/QtCore/quuid_test.py | 51 + .../tests/QtCore/qversionnumber_test.py | 54 + sources/pyside2/tests/QtCore/repr_test.py | 112 + sources/pyside2/tests/QtCore/resources.qrc | 7 + sources/pyside2/tests/QtCore/resources_mc.py | 3571 ++ sources/pyside2/tests/QtCore/sample.png | Bin 0 -> 55944 bytes .../tests/QtCore/setprop_on_ctor_test.py | 48 + .../tests/QtCore/snake_prop_feature_test.py | 106 + .../tests/QtCore/staticMetaObject_test.py | 57 + .../tests/QtCore/static_method_test.py | 89 + .../tests/QtCore/thread_signals_test.py | 65 + sources/pyside2/tests/QtCore/tr_noop_test.py | 81 + .../pyside2/tests/QtCore/translation_test.py | 91 + .../tests/QtCore/translations/trans_latin.qm | Bin 0 -> 125 bytes .../tests/QtCore/translations/trans_latin.ts | 11 + .../QtCore/translations/trans_russian.qm | Bin 0 -> 114 bytes .../QtCore/translations/trans_russian.ts | 11 + .../tests/QtCore/unaryoperator_test.py | 73 + sources/pyside2/tests/QtCore/unicode_test.py | 70 + .../pyside2/tests/QtCore/versioninfo_test.py | 55 + .../tests/QtDataVisualization/CMakeLists.txt | 1 + .../datavisualization_test.py | 92 + .../pyside2/tests/QtDesigner/CMakeLists.txt | 1 + sources/pyside2/tests/QtGui/CMakeLists.txt | 49 + sources/pyside2/tests/QtGui/bug_1091.py | 47 + sources/pyside2/tests/QtGui/bug_300_test.py | 52 + sources/pyside2/tests/QtGui/bug_367.py | 56 + sources/pyside2/tests/QtGui/bug_480.py | 59 + sources/pyside2/tests/QtGui/bug_606.py | 60 + sources/pyside2/tests/QtGui/bug_617.py | 57 + sources/pyside2/tests/QtGui/bug_652.py | 65 + sources/pyside2/tests/QtGui/bug_660.py | 62 + sources/pyside2/tests/QtGui/bug_716.py | 44 + sources/pyside2/tests/QtGui/bug_740.py | 48 + sources/pyside2/tests/QtGui/bug_743.py | 49 + sources/pyside2/tests/QtGui/bug_991.py | 50 + sources/pyside2/tests/QtGui/bug_PYSIDE-344.py | 70 + sources/pyside2/tests/QtGui/bug_PYSIDE-41.py | 78 + sources/pyside2/tests/QtGui/deepcopy_test.py | 156 + .../float_to_int_implicit_conversion_test.py | 65 + .../pyside2/tests/QtGui/pyside_reload_test.py | 89 + .../pyside2/tests/QtGui/qcolor_reduce_test.py | 66 + sources/pyside2/tests/QtGui/qcolor_test.py | 129 + sources/pyside2/tests/QtGui/qcursor_test.py | 51 + .../QtGui/qdatastream_gui_operators_test.py | 68 + .../tests/QtGui/qdesktopservices_test.py | 49 + .../pyside2/tests/QtGui/qfontmetrics_test.py | 233 + .../tests/QtGui/qguiapplication_test.py | 46 + sources/pyside2/tests/QtGui/qicon_test.py | 50 + .../tests/QtGui/qitemselection_test.py | 53 + .../pyside2/tests/QtGui/qkeysequence_test.py | 54 + sources/pyside2/tests/QtGui/qmatrix_test.py | 106 + .../pyside2/tests/QtGui/qopenglbuffer_test.py | 98 + .../pyside2/tests/QtGui/qopenglwindow_test.py | 109 + sources/pyside2/tests/QtGui/qpainter_test.py | 117 + .../pyside2/tests/QtGui/qpdfwriter_test.py | 54 + .../pyside2/tests/QtGui/qpixelformat_test.py | 56 + sources/pyside2/tests/QtGui/qpixmap_test.py | 90 + .../pyside2/tests/QtGui/qpixmapcache_test.py | 79 + sources/pyside2/tests/QtGui/qpolygonf_test.py | 66 + .../tests/QtGui/qradialgradient_test.py | 63 + .../pyside2/tests/QtGui/qrasterwindow_test.py | 92 + sources/pyside2/tests/QtGui/qregion_test.py | 54 + .../pyside2/tests/QtGui/qstylehints_test.py | 48 + .../tests/QtGui/qtextdocument_functions.py | 53 + .../QtGui/qtextdocument_undoredo_test.py | 64 + .../tests/QtGui/qtextdocumentwriter_test.py | 54 + sources/pyside2/tests/QtGui/qtextline_test.py | 56 + .../pyside2/tests/QtGui/qtransform_test.py | 108 + sources/pyside2/tests/QtGui/repr_test.py | 123 + sources/pyside2/tests/QtGui/sample.png | Bin 0 -> 55944 bytes .../QtGui/timed_app_and_patching_test.py | 66 + sources/pyside2/tests/QtHelp/CMakeLists.txt | 2 + sources/pyside2/tests/QtHelp/help_test.py | 47 + .../tests/QtHelp/helpsearchengine_test.py | 50 + .../pyside2/tests/QtLocation/CMakeLists.txt | 1 + sources/pyside2/tests/QtLocation/location.py | 49 + .../pyside2/tests/QtMacExtras/CMakeLists.txt | 1 + .../pyside2/tests/QtMultimedia/CMakeLists.txt | 1 + .../pyside2/tests/QtMultimedia/audio_test.py | 78 + .../tests/QtMultimediaWidgets/CMakeLists.txt | 1 + .../QtMultimediaWidgets/qmultimediawidgets.py | 65 + .../pyside2/tests/QtNetwork/CMakeLists.txt | 9 + .../tests/QtNetwork/accessManager_test.py | 77 + sources/pyside2/tests/QtNetwork/bug_1084.py | 51 + sources/pyside2/tests/QtNetwork/bug_446.py | 83 + .../pyside2/tests/QtNetwork/dnslookup_test.py | 65 + .../tests/QtNetwork/qipv6address_test.py | 56 + .../tests/QtNetwork/qpassworddigestor_test.py | 51 + .../pyside2/tests/QtNetwork/tcpserver_test.py | 58 + .../pyside2/tests/QtNetwork/udpsocket_test.py | 85 + sources/pyside2/tests/QtOpenGL/CMakeLists.txt | 2 + .../pyside2/tests/QtOpenGL/qglbuffer_test.py | 78 + .../pyside2/tests/QtOpenGL/qglwidget_test.py | 54 + .../tests/QtOpenGLFunctions/CMakeLists.txt | 1 + .../tests/QtPositioning/CMakeLists.txt | 1 + .../tests/QtPositioning/positioning.py | 51 + .../tests/QtPrintSupport/CMakeLists.txt | 2 + .../pyside2/tests/QtPrintSupport/bug_500.py | 49 + .../returnquadruplesofnumbers_test.py | 112 + sources/pyside2/tests/QtQml/CMakeLists.txt | 21 + sources/pyside2/tests/QtQml/bug_1029.py | 64 + sources/pyside2/tests/QtQml/bug_1029.qml | 43 + sources/pyside2/tests/QtQml/bug_451.py | 105 + sources/pyside2/tests/QtQml/bug_451.qml | 54 + sources/pyside2/tests/QtQml/bug_456.py | 77 + sources/pyside2/tests/QtQml/bug_456.qml | 59 + sources/pyside2/tests/QtQml/bug_557.py | 50 + sources/pyside2/tests/QtQml/bug_726.py | 78 + sources/pyside2/tests/QtQml/bug_726.qml | 59 + sources/pyside2/tests/QtQml/bug_814.py | 80 + sources/pyside2/tests/QtQml/bug_814.qml | 36 + sources/pyside2/tests/QtQml/bug_825.py | 88 + sources/pyside2/tests/QtQml/bug_825.qml | 38 + sources/pyside2/tests/QtQml/bug_847.py | 93 + sources/pyside2/tests/QtQml/bug_847.qml | 62 + sources/pyside2/tests/QtQml/bug_915.py | 64 + sources/pyside2/tests/QtQml/bug_926.py | 75 + sources/pyside2/tests/QtQml/bug_926.qml | 45 + sources/pyside2/tests/QtQml/bug_951.py | 68 + sources/pyside2/tests/QtQml/bug_951.qml | 35 + sources/pyside2/tests/QtQml/bug_995.py | 52 + sources/pyside2/tests/QtQml/bug_995.qml | 40 + sources/pyside2/tests/QtQml/bug_997.py | 59 + sources/pyside2/tests/QtQml/bug_997.qml | 34 + .../pyside2/tests/QtQml/connect_python_qml.py | 72 + .../tests/QtQml/connect_python_qml.qml | 48 + sources/pyside2/tests/QtQml/hw.qml | 48 + .../tests/QtQml/javascript_exceptions.py | 110 + .../tests/QtQml/javascript_exceptions.qml | 53 + .../QtQml/qqmlincubator_incubateWhile.py | 102 + .../QtQml/qqmlincubator_incubateWhile.qml | 67 + .../qqmlincubator_incubateWhile_component.qml | 35 + .../pyside2/tests/QtQml/qqmlnetwork_test.py | 78 + .../tests/QtQml/qquickitem_grabToImage.py | 88 + .../tests/QtQml/qquickitem_grabToImage.qml | 69 + .../pyside2/tests/QtQml/qquickview_test.py | 97 + sources/pyside2/tests/QtQml/registertype.py | 123 + sources/pyside2/tests/QtQml/registertype.qml | 57 + .../pyside2/tests/QtQml/signal_arguments.py | 77 + .../pyside2/tests/QtQml/signal_arguments.qml | 59 + sources/pyside2/tests/QtQml/view.qml | 43 + sources/pyside2/tests/QtQml/viewmodel.qml | 42 + sources/pyside2/tests/QtQuick/CMakeLists.txt | 1 + .../tests/QtQuickControls2/CMakeLists.txt | 1 + .../tests/QtQuickWidgets/CMakeLists.txt | 1 + .../tests/QtRemoteObjects/CMakeLists.txt | 1 + sources/pyside2/tests/QtScript/CMakeLists.txt | 5 + sources/pyside2/tests/QtScript/base_test.py | 39 + sources/pyside2/tests/QtScript/bug_1022.py | 47 + sources/pyside2/tests/QtScript/engine_test.py | 47 + .../pyside2/tests/QtScript/property_test.py | 96 + .../tests/QtScript/qscriptvalue_test.py | 78 + .../tests/QtScriptTools/CMakeLists.txt | 1 + .../tests/QtScriptTools/debugger_test.py | 81 + sources/pyside2/tests/QtScxml/CMakeLists.txt | 1 + sources/pyside2/tests/QtScxml/test_dynamic.py | 58 + .../pyside2/tests/QtScxml/trafficlight.scxml | 89 + .../pyside2/tests/QtSensors/CMakeLists.txt | 1 + sources/pyside2/tests/QtSensors/sensors.py | 63 + .../pyside2/tests/QtSerialPort/CMakeLists.txt | 1 + sources/pyside2/tests/QtSerialPort/serial.py | 95 + sources/pyside2/tests/QtSql/CMakeLists.txt | 3 + sources/pyside2/tests/QtSql/bug_1013.py | 66 + .../QtSql/qsqldatabaseandqueries_test.py | 105 + .../pyside2/tests/QtSql/qvarianttype_test.py | 69 + sources/pyside2/tests/QtSvg/CMakeLists.txt | 3 + .../pyside2/tests/QtSvg/qsvggenerator_test.py | 70 + .../pyside2/tests/QtSvg/qsvgrenderer_test.py | 60 + .../pyside2/tests/QtSvg/qsvgwidget_test.py | 62 + sources/pyside2/tests/QtSvg/tiger.svg | 730 + sources/pyside2/tests/QtTest/CMakeLists.txt | 5 + sources/pyside2/tests/QtTest/click_test.py | 61 + .../pyside2/tests/QtTest/eventfilter_test.py | 81 + .../pyside2/tests/QtTest/qvalidator_test.py | 140 + .../pyside2/tests/QtTest/touchevent_test.py | 83 + .../tests/QtTextToSpeech/CMakeLists.txt | 1 + .../QtTextToSpeech/qtexttospeech_test.py | 69 + .../pyside2/tests/QtUiTools/CMakeLists.txt | 13 + sources/pyside2/tests/QtUiTools/action.ui | 16 + sources/pyside2/tests/QtUiTools/bug_1060.py | 54 + sources/pyside2/tests/QtUiTools/bug_1060.ui | 19 + sources/pyside2/tests/QtUiTools/bug_360.py | 70 + sources/pyside2/tests/QtUiTools/bug_376.py | 53 + sources/pyside2/tests/QtUiTools/bug_392.py | 81 + sources/pyside2/tests/QtUiTools/bug_426.py | 52 + sources/pyside2/tests/QtUiTools/bug_426.ui | 19 + sources/pyside2/tests/QtUiTools/bug_552.py | 57 + sources/pyside2/tests/QtUiTools/bug_552.ui | 42 + sources/pyside2/tests/QtUiTools/bug_797.py | 49 + sources/pyside2/tests/QtUiTools/bug_909.py | 57 + sources/pyside2/tests/QtUiTools/bug_909.ui | 31 + sources/pyside2/tests/QtUiTools/bug_913.py | 57 + sources/pyside2/tests/QtUiTools/bug_913.ui | 57 + sources/pyside2/tests/QtUiTools/bug_958.py | 59 + sources/pyside2/tests/QtUiTools/bug_958.ui | 48 + sources/pyside2/tests/QtUiTools/bug_965.py | 55 + sources/pyside2/tests/QtUiTools/bug_965.ui | 27 + .../tests/QtUiTools/loadUiType_test.py | 75 + sources/pyside2/tests/QtUiTools/minimal.ui | 6 + .../pyside2/tests/QtUiTools/pycustomwidget.ui | 36 + .../tests/QtUiTools/pycustomwidget2.ui | 48 + sources/pyside2/tests/QtUiTools/test.ui | 48 + sources/pyside2/tests/QtUiTools/ui_test.py | 47 + .../pyside2/tests/QtUiTools/uiloader_test.py | 79 + .../pyside2/tests/QtWebChannel/CMakeLists.txt | 1 + .../pyside2/tests/QtWebEngine/CMakeLists.txt | 29 + .../QtWebEngine/web_engine_initialize.py | 52 + .../tests/QtWebEngineCore/CMakeLists.txt | 29 + .../web_engine_custom_scheme.py | 98 + .../tests/QtWebEngineWidgets/CMakeLists.txt | 29 + .../pyside2/tests/QtWebEngineWidgets/fox.html | 7 + .../pyside-474-qtwebengineview.py | 86 + sources/pyside2/tests/QtWebKit/CMakeLists.txt | 11 + sources/pyside2/tests/QtWebKit/bug_448.py | 52 + sources/pyside2/tests/QtWebKit/bug_694.py | 84 + sources/pyside2/tests/QtWebKit/bug_803.py | 53 + sources/pyside2/tests/QtWebKit/bug_899.py | 71 + sources/pyside2/tests/QtWebKit/bug_959.py | 133 + sources/pyside2/tests/QtWebKit/fox.html | 7 + .../pyside2/tests/QtWebKit/qml_plugin_test.py | 92 + .../tests/QtWebKit/qmlplugin/dummy.pys | 1 + .../tests/QtWebKit/qmlplugin/index.html | 5 + .../QtWebKit/qvariantlist_property_test.py | 78 + .../shouldInterruptjavascript_test.py | 63 + .../pyside2/tests/QtWebKit/webframe_test.py | 67 + .../pyside2/tests/QtWebKit/webpage_test.py | 95 + .../pyside2/tests/QtWebKit/webview_test.py | 101 + .../tests/QtWebKitWidgets/CMakeLists.txt | 1 + .../pyside2/tests/QtWebSockets/CMakeLists.txt | 1 + .../pyside2/tests/QtWidgets/CMakeLists.txt | 142 + .../pyside2/tests/QtWidgets/action_clear.py | 80 + .../tests/QtWidgets/add_action_test.py | 77 + sources/pyside2/tests/QtWidgets/api2_test.py | 94 + .../tests/QtWidgets/application_test.py | 65 + sources/pyside2/tests/QtWidgets/bug_1002.py | 53 + sources/pyside2/tests/QtWidgets/bug_1006.py | 116 + sources/pyside2/tests/QtWidgets/bug_1048.py | 44 + sources/pyside2/tests/QtWidgets/bug_1077.py | 54 + sources/pyside2/tests/QtWidgets/bug_172.py | 49 + sources/pyside2/tests/QtWidgets/bug_243.py | 50 + sources/pyside2/tests/QtWidgets/bug_307.py | 60 + sources/pyside2/tests/QtWidgets/bug_324.py | 65 + sources/pyside2/tests/QtWidgets/bug_338.py | 60 + sources/pyside2/tests/QtWidgets/bug_363.py | 59 + sources/pyside2/tests/QtWidgets/bug_389.py | 49 + sources/pyside2/tests/QtWidgets/bug_400.py | 61 + sources/pyside2/tests/QtWidgets/bug_416.py | 78 + sources/pyside2/tests/QtWidgets/bug_429.py | 46 + sources/pyside2/tests/QtWidgets/bug_430.py | 49 + sources/pyside2/tests/QtWidgets/bug_433.py | 49 + sources/pyside2/tests/QtWidgets/bug_467.py | 54 + sources/pyside2/tests/QtWidgets/bug_493.py | 56 + sources/pyside2/tests/QtWidgets/bug_512.py | 57 + sources/pyside2/tests/QtWidgets/bug_525.py | 56 + sources/pyside2/tests/QtWidgets/bug_546.py | 49 + sources/pyside2/tests/QtWidgets/bug_547.py | 91 + sources/pyside2/tests/QtWidgets/bug_549.py | 50 + sources/pyside2/tests/QtWidgets/bug_569.py | 54 + sources/pyside2/tests/QtWidgets/bug_575.py | 56 + sources/pyside2/tests/QtWidgets/bug_576.py | 68 + sources/pyside2/tests/QtWidgets/bug_585.py | 59 + sources/pyside2/tests/QtWidgets/bug_589.py | 54 + sources/pyside2/tests/QtWidgets/bug_632.py | 54 + sources/pyside2/tests/QtWidgets/bug_635.py | 64 + sources/pyside2/tests/QtWidgets/bug_640.py | 46 + sources/pyside2/tests/QtWidgets/bug_653.py | 52 + sources/pyside2/tests/QtWidgets/bug_662.py | 63 + sources/pyside2/tests/QtWidgets/bug_667.py | 59 + sources/pyside2/tests/QtWidgets/bug_668.py | 59 + sources/pyside2/tests/QtWidgets/bug_674.py | 58 + sources/pyside2/tests/QtWidgets/bug_675.py | 51 + sources/pyside2/tests/QtWidgets/bug_688.py | 123 + sources/pyside2/tests/QtWidgets/bug_693.py | 66 + sources/pyside2/tests/QtWidgets/bug_696.py | 60 + sources/pyside2/tests/QtWidgets/bug_711.py | 60 + sources/pyside2/tests/QtWidgets/bug_714.py | 60 + sources/pyside2/tests/QtWidgets/bug_722.py | 58 + sources/pyside2/tests/QtWidgets/bug_728.py | 59 + sources/pyside2/tests/QtWidgets/bug_736.py | 53 + sources/pyside2/tests/QtWidgets/bug_750.py | 60 + sources/pyside2/tests/QtWidgets/bug_778.py | 56 + sources/pyside2/tests/QtWidgets/bug_785.py | 63 + sources/pyside2/tests/QtWidgets/bug_793.py | 64 + sources/pyside2/tests/QtWidgets/bug_811.py | 66 + sources/pyside2/tests/QtWidgets/bug_834.py | 54 + sources/pyside2/tests/QtWidgets/bug_836.py | 64 + sources/pyside2/tests/QtWidgets/bug_844.py | 54 + sources/pyside2/tests/QtWidgets/bug_854.py | 75 + sources/pyside2/tests/QtWidgets/bug_860.py | 68 + sources/pyside2/tests/QtWidgets/bug_862.py | 97 + sources/pyside2/tests/QtWidgets/bug_871.py | 77 + sources/pyside2/tests/QtWidgets/bug_879.py | 64 + sources/pyside2/tests/QtWidgets/bug_919.py | 72 + sources/pyside2/tests/QtWidgets/bug_921.py | 85 + sources/pyside2/tests/QtWidgets/bug_941.py | 52 + sources/pyside2/tests/QtWidgets/bug_964.py | 54 + sources/pyside2/tests/QtWidgets/bug_967.py | 53 + sources/pyside2/tests/QtWidgets/bug_972.py | 74 + sources/pyside2/tests/QtWidgets/bug_979.py | 45 + sources/pyside2/tests/QtWidgets/bug_988.py | 53 + sources/pyside2/tests/QtWidgets/bug_998.py | 45 + .../tests/QtWidgets/customproxywidget_test.py | 68 + .../tests/QtWidgets/event_filter_test.py | 72 + .../QtWidgets/grandparent_method_test.py | 56 + .../tests/QtWidgets/hashabletype_test.py | 52 + .../pyside2/tests/QtWidgets/import_test.py | 2 + .../tests/QtWidgets/keep_reference_test.py | 109 + .../tests/QtWidgets/missing_symbols_test.py | 64 + .../tests/QtWidgets/paint_event_test.py | 104 + .../tests/QtWidgets/parent_method_test.py | 58 + .../tests/QtWidgets/private_mangle_test.py | 128 + .../tests/QtWidgets/python_properties_test.py | 52 + .../qabstracttextdocumentlayout_test.py | 82 + .../pyside2/tests/QtWidgets/qaction_test.py | 75 + .../pyside2/tests/QtWidgets/qapp_issue_585.py | 76 + sources/pyside2/tests/QtWidgets/qapp_test.py | 52 + .../qapplication_exit_segfault_test.py | 49 + .../tests/QtWidgets/qapplication_test.py | 46 + .../pyside2/tests/QtWidgets/qbrush_test.py | 58 + .../pyside2/tests/QtWidgets/qcolormap_test.py | 49 + .../tests/QtWidgets/qdynamic_signal.py | 61 + .../tests/QtWidgets/qfontdialog_test.py | 56 + .../tests/QtWidgets/qformlayout_test.py | 91 + .../QtWidgets/qgraphicsitem_isblocked_test.py | 64 + .../tests/QtWidgets/qgraphicsitem_test.py | 69 + .../QtWidgets/qgraphicsobjectreimpl_test.py | 82 + .../QtWidgets/qgraphicsproxywidget_test.py | 64 + .../tests/QtWidgets/qgraphicsscene_test.py | 224 + .../pyside2/tests/QtWidgets/qimage_test.py | 316 + .../tests/QtWidgets/qinputdialog_get_test.py | 58 + .../tests/QtWidgets/qkeysequenceedit_test.py | 53 + .../pyside2/tests/QtWidgets/qlabel_test.py | 88 + .../tests/QtWidgets/qlayout_ref_test.py | 185 + .../pyside2/tests/QtWidgets/qlayout_test.py | 145 + .../tests/QtWidgets/qlcdnumber_test.py | 50 + .../tests/QtWidgets/qlistwidget_test.py | 94 + .../tests/QtWidgets/qlistwidgetitem_test.py | 62 + .../tests/QtWidgets/qmainwindow_test.py | 118 + sources/pyside2/tests/QtWidgets/qmenu_test.py | 92 + .../pyside2/tests/QtWidgets/qmenuadd_test.py | 58 + .../tests/QtWidgets/qobject_mi_test.py | 76 + sources/pyside2/tests/QtWidgets/qpen_test.py | 79 + .../pyside2/tests/QtWidgets/qpicture_test.py | 71 + .../tests/QtWidgets/qpixmap_constructor.py | 285 + .../tests/QtWidgets/qpushbutton_test.py | 75 + .../pyside2/tests/QtWidgets/qshortcut_test.py | 81 + .../pyside2/tests/QtWidgets/qsplitter_test.py | 51 + .../QtWidgets/qstandarditemmodel_test.py | 106 + .../QtWidgets/qstring_qkeysequence_test.py | 68 + .../pyside2/tests/QtWidgets/qstyle_test.py | 98 + .../tests/QtWidgets/qtableview_test.py | 50 + .../tests/QtWidgets/qtabwidget_test.py | 62 + .../tests/QtWidgets/qtabwidgetclear_test.py | 69 + .../tests/QtWidgets/qtextedit_signal_test.py | 72 + .../pyside2/tests/QtWidgets/qtextedit_test.py | 67 + .../pyside2/tests/QtWidgets/qtoolbar_test.py | 68 + .../pyside2/tests/QtWidgets/qtoolbox_test.py | 65 + .../pyside2/tests/QtWidgets/qtreeview_test.py | 102 + .../tests/QtWidgets/qtreewidget_test.py | 70 + .../tests/QtWidgets/qtreewidgetitem_test.py | 74 + .../pyside2/tests/QtWidgets/qvariant_test.py | 83 + .../tests/QtWidgets/qwidget_setlayout_test.py | 67 + .../pyside2/tests/QtWidgets/qwidget_test.py | 87 + .../tests/QtWidgets/reference_count_test.py | 102 + sources/pyside2/tests/QtWidgets/sample.png | Bin 0 -> 55944 bytes .../pyside2/tests/QtWidgets/signature_test.py | 94 + .../tests/QtWidgets/standardpixmap_test.py | 49 + .../tests/QtWidgets/test_module_template.py | 48 + .../virtual_protected_inheritance_test.py | 103 + .../QtWidgets/virtual_pure_override_test.py | 83 + .../tests/QtWidgets/wrong_return_test.py | 66 + .../pyside2/tests/QtWinExtras/CMakeLists.txt | 1 + .../pyside2/tests/QtX11Extras/CMakeLists.txt | 1 + sources/pyside2/tests/QtXml/CMakeLists.txt | 2 + .../pyside2/tests/QtXml/qdomdocument_test.py | 104 + .../tests/QtXml/qxmlsimplereader_test.py | 70 + .../tests/QtXmlPatterns/CMakeLists.txt | 1 + .../tests/QtXmlPatterns/import_test.py | 66 + sources/pyside2/tests/init_paths.py | 104 + sources/pyside2/tests/mac/CMakeLists.txt | 1 + sources/pyside2/tests/mac/qmacstyle_test.py | 54 + sources/pyside2/tests/manually/README.txt | 5 + sources/pyside2/tests/manually/bug_841.py | 79 + .../pyside2/tests/pysidetest/CMakeLists.txt | 174 + .../tests/pysidetest/all_modules_load_test.py | 51 + sources/pyside2/tests/pysidetest/bug_1016.py | 48 + .../pysidetest/constructor_properties_test.py | 70 + .../pyside2/tests/pysidetest/curr_errors.txt | 12 + .../tests/pysidetest/decoratedslot_test.py | 74 + .../pysidetest/delegatecreateseditor_test.py | 105 + .../tests/pysidetest/embedding_test.py | 80 + sources/pyside2/tests/pysidetest/enum_test.py | 51 + .../pyside2/tests/pysidetest/flagstest.cpp | 36 + sources/pyside2/tests/pysidetest/flagstest.h | 55 + .../pyside2/tests/pysidetest/hiddenobject.cpp | 44 + .../pyside2/tests/pysidetest/hiddenobject.h | 52 + .../homonymoussignalandmethod_test.py | 88 + .../pyside2/tests/pysidetest/iterable_test.py | 91 + .../tests/pysidetest/list_signal_test.py | 58 + .../pysidetest/mixin_signal_slots_test.py | 223 + .../tests/pysidetest/modelview_test.py | 106 + .../new_inherited_functions_test.py | 202 + sources/pyside2/tests/pysidetest/notify_id.py | 83 + .../tests/pysidetest/properties_test.py | 132 + .../tests/pysidetest/property_python_test.py | 232 + .../tests/pysidetest/pysidetest_global.h | 38 + .../tests/pysidetest/pysidetest_macros.h | 43 + .../pysidetest/qapp_like_a_macro_test.py | 88 + .../pyside2/tests/pysidetest/qvariant_test.py | 51 + sources/pyside2/tests/pysidetest/repr_test.py | 90 + .../tests/pysidetest/signal_slot_warning.py | 76 + .../pysidetest/signal_tp_descr_get_test.py | 87 + .../pysidetest/signalandnamespace_test.py | 127 + .../signalemissionfrompython_test.py | 114 + .../pysidetest/signalwithdefaultvalue_test.py | 102 + .../pyside2/tests/pysidetest/symbols.filter | 7 + .../pyside2/tests/pysidetest/testobject.cpp | 78 + sources/pyside2/tests/pysidetest/testobject.h | 153 + sources/pyside2/tests/pysidetest/testview.cpp | 52 + sources/pyside2/tests/pysidetest/testview.h | 59 + .../tests/pysidetest/typedef_signal_test.py | 60 + .../pysidetest/typesystem_pysidetest.xml | 77 + .../pyside2/tests/pysidetest/version_test.py | 54 + sources/pyside2/tests/registry/CMakeLists.txt | 40 + .../pyside2/tests/registry/existence_test.py | 255 + .../tests/registry/exists_darwin_5_14_2_ci.py | 37734 +++++++++++++++ ...terprise_linux_workstation7_6_5_14_2_ci.py | 37756 +++++++++++++++ .../tests/registry/exists_win32_5_14_2_ci.py | 37964 ++++++++++++++++ .../exists_x86_64_suse_linux_5_14_2_ci.py | 37749 +++++++++++++++ .../pyside2/tests/registry/init_platform.py | 255 + .../tests/registry/scrape_testresults.py | 361 + sources/pyside2/tests/registry/util.py | 181 + sources/pyside2/tests/run_test.sh | 41 + sources/pyside2/tests/signals/CMakeLists.txt | 42 + .../tests/signals/args_dont_match_test.py | 57 + sources/pyside2/tests/signals/bug_189.py | 60 + sources/pyside2/tests/signals/bug_311.py | 77 + sources/pyside2/tests/signals/bug_312.py | 85 + sources/pyside2/tests/signals/bug_319.py | 70 + sources/pyside2/tests/signals/bug_79.py | 76 + .../pyside2/tests/signals/decorators_test.py | 111 + .../pyside2/tests/signals/disconnect_test.py | 92 + .../tests/signals/invalid_callback_test.py | 62 + .../pyside2/tests/signals/lambda_gui_test.py | 79 + sources/pyside2/tests/signals/lambda_test.py | 98 + .../tests/signals/leaking_signal_test.py | 51 + .../signals/multiple_connections_gui_test.py | 95 + .../signals/multiple_connections_test.py | 109 + .../pyside2/tests/signals/pysignal_test.py | 221 + .../tests/signals/qobject_destroyed_test.py | 56 + .../tests/signals/qobject_receivers_test.py | 83 + .../tests/signals/qobject_sender_test.py | 127 + sources/pyside2/tests/signals/ref01_test.py | 62 + sources/pyside2/tests/signals/ref02_test.py | 82 + sources/pyside2/tests/signals/ref03_test.py | 64 + sources/pyside2/tests/signals/ref04_test.py | 91 + sources/pyside2/tests/signals/ref05_test.py | 81 + sources/pyside2/tests/signals/ref06_test.py | 84 + .../signals/segfault_proxyparent_test.py | 92 + .../tests/signals/self_connect_test.py | 71 + .../tests/signals/short_circuit_test.py | 97 + .../signals/signal2signal_connect_test.py | 142 + .../tests/signals/signal_across_threads.py | 106 + .../tests/signals/signal_autoconnect_test.py | 65 + .../signal_connectiontype_support_test.py | 61 + .../tests/signals/signal_emission_gui_test.py | 148 + .../tests/signals/signal_emission_test.py | 158 + .../pyside2/tests/signals/signal_enum_test.py | 82 + .../pyside2/tests/signals/signal_func_test.py | 55 + .../signals/signal_manager_refcount_test.py | 59 + .../tests/signals/signal_number_limit_test.py | 97 + .../tests/signals/signal_object_test.py | 121 + .../tests/signals/signal_signature_test.py | 121 + .../signal_with_primitive_type_test.py | 65 + .../signals/slot_reference_count_test.py | 87 + .../tests/signals/static_metaobject_test.py | 92 + sources/pyside2/tests/support/CMakeLists.txt | 1 + sources/pyside2/tests/support/voidptr_test.py | 71 + .../tests/tools/list-class-hierarchy.py | 117 + sources/pyside2/tests/util/color.py | 41 + sources/pyside2/tests/util/helper/__init__.py | 1 + .../tests/util/helper/basicpyslotcase.py | 54 + .../pyside2/tests/util/helper/docmodifier.py | 116 + sources/pyside2/tests/util/helper/helper.py | 42 + .../tests/util/helper/helper.pyproject | 5 + .../tests/util/helper/timedqapplication.py | 49 + .../tests/util/helper/usesqapplication.py | 51 + .../tests/util/helper/usesqcoreapplication.py | 59 + .../tests/util/helper/usesqguiapplication.py | 49 + sources/pyside2/tests/util/httpd.py | 181 + .../util/module_wrapper/PySide/QtAssistant.py | 2 + .../util/module_wrapper/PySide/QtCore.py | 2 + .../util/module_wrapper/PySide/QtDesigner.py | 2 + .../tests/util/module_wrapper/PySide/QtGui.py | 2 + .../util/module_wrapper/PySide/QtHelp.py | 2 + .../util/module_wrapper/PySide/QtNetwork.py | 2 + .../util/module_wrapper/PySide/QtScript.py | 2 + .../tests/util/module_wrapper/PySide/QtSql.py | 2 + .../tests/util/module_wrapper/PySide/QtSvg.py | 2 + .../util/module_wrapper/PySide/QtTest.py | 2 + .../util/module_wrapper/PySide/QtWebKit.py | 2 + .../tests/util/module_wrapper/PySide/QtXml.py | 2 + .../module_wrapper/PySide/QtXmlPatterns.py | 2 + .../util/module_wrapper/PySide/__init__.py | 0 sources/pyside2/tests/util/processtimer.py | 77 + sources/pyside2/tests/util/py3kcompat.py | 82 + sources/pyside2/tests/util/pyqt_diff.py | 64 + sources/pyside2/tests/util/pyqtcheck.py | 74 + sources/pyside2/tests/util/rename_imports.sh | 42 + .../pyside2/tests/util/test_processtimer.py | 93 + sources/pyside2/tests/util/use_pyqt4.sh | 3 + sources/pyside2/tests/util/use_pyside.sh | 3 + .../pyside2/tests/util/valgrind-python.supp | 349 + sources/shiboken2/AUTHORS | 12 + sources/shiboken2/ApiExtractor/AUTHORS | 8 + sources/shiboken2/ApiExtractor/CMakeLists.txt | 96 + sources/shiboken2/ApiExtractor/COPYING | 342 + .../ApiExtractor/abstractmetabuilder.cpp | 3272 ++ .../ApiExtractor/abstractmetabuilder.h | 125 + .../ApiExtractor/abstractmetabuilder_p.h | 215 + .../ApiExtractor/abstractmetalang.cpp | 2755 ++ .../shiboken2/ApiExtractor/abstractmetalang.h | 1753 + .../ApiExtractor/abstractmetalang_typedefs.h | 53 + .../shiboken2/ApiExtractor/apiextractor.cpp | 284 + sources/shiboken2/ApiExtractor/apiextractor.h | 112 + .../ApiExtractor/apiextractormacros.h | 41 + .../ApiExtractor/clangparser/clangbuilder.cpp | 1199 + .../ApiExtractor/clangparser/clangbuilder.h | 62 + .../clangparser/clangdebugutils.cpp | 150 + .../clangparser/clangdebugutils.h | 48 + .../ApiExtractor/clangparser/clangparser.cpp | 307 + .../ApiExtractor/clangparser/clangparser.h | 98 + .../ApiExtractor/clangparser/clangutils.cpp | 286 + .../ApiExtractor/clangparser/clangutils.h | 124 + .../clangparser/compilersupport.cpp | 404 + .../clangparser/compilersupport.h | 55 + .../ApiExtractor/cmake_uninstall.cmake | 21 + sources/shiboken2/ApiExtractor/dependency.h | 47 + sources/shiboken2/ApiExtractor/docparser.cpp | 150 + sources/shiboken2/ApiExtractor/docparser.h | 134 + .../shiboken2/ApiExtractor/doxygenparser.cpp | 237 + .../shiboken2/ApiExtractor/doxygenparser.h | 43 + sources/shiboken2/ApiExtractor/fileout.cpp | 253 + sources/shiboken2/ApiExtractor/fileout.h | 69 + sources/shiboken2/ApiExtractor/graph.cpp | 134 + sources/shiboken2/ApiExtractor/graph.h | 77 + sources/shiboken2/ApiExtractor/header_paths.h | 72 + sources/shiboken2/ApiExtractor/icecc.cmake | 11 + sources/shiboken2/ApiExtractor/include.cpp | 70 + sources/shiboken2/ApiExtractor/include.h | 95 + sources/shiboken2/ApiExtractor/merge.xsl | 82 + sources/shiboken2/ApiExtractor/messages.cpp | 680 + sources/shiboken2/ApiExtractor/messages.h | 206 + .../ApiExtractor/parser/codemodel.cpp | 1612 + .../shiboken2/ApiExtractor/parser/codemodel.h | 814 + .../ApiExtractor/parser/codemodel_enums.h | 64 + .../ApiExtractor/parser/codemodel_fwd.h | 85 + .../ApiExtractor/parser/enumvalue.cpp | 76 + .../shiboken2/ApiExtractor/parser/enumvalue.h | 71 + .../shiboken2/ApiExtractor/propertyspec.cpp | 218 + sources/shiboken2/ApiExtractor/propertyspec.h | 116 + sources/shiboken2/ApiExtractor/qtcompat.h | 40 + .../shiboken2/ApiExtractor/qtdocparser.cpp | 358 + sources/shiboken2/ApiExtractor/qtdocparser.h | 53 + .../shiboken2/ApiExtractor/reporthandler.cpp | 198 + .../shiboken2/ApiExtractor/reporthandler.h | 71 + .../shiboken2/ApiExtractor/sourcelocation.cpp | 100 + .../shiboken2/ApiExtractor/sourcelocation.h | 67 + sources/shiboken2/ApiExtractor/symbols.filter | 7 + .../ApiExtractor/tests/CMakeLists.txt | 63 + sources/shiboken2/ApiExtractor/tests/a.xml | 14 + .../ApiExtractor/tests/injectedcode.txt | 5 + .../tests/testabstractmetaclass.cpp | 622 + .../tests/testabstractmetaclass.h | 57 + .../tests/testabstractmetatype.cpp | 247 + .../ApiExtractor/tests/testabstractmetatype.h | 49 + .../ApiExtractor/tests/testaddfunction.cpp | 467 + .../ApiExtractor/tests/testaddfunction.h | 54 + .../ApiExtractor/tests/testarrayargument.cpp | 171 + .../ApiExtractor/tests/testarrayargument.h | 43 + .../ApiExtractor/tests/testcodeinjection.cpp | 131 + .../ApiExtractor/tests/testcodeinjection.h | 46 + .../ApiExtractor/tests/testcodeinjection.qrc | 6 + .../ApiExtractor/tests/testcontainer.cpp | 108 + .../ApiExtractor/tests/testcontainer.h | 41 + .../tests/testconversionoperator.cpp | 196 + .../tests/testconversionoperator.h | 44 + .../tests/testconversionruletag.cpp | 251 + .../tests/testconversionruletag.h | 43 + .../tests/testctorinformation.cpp | 76 + .../ApiExtractor/tests/testctorinformation.h | 44 + .../tests/testdroptypeentries.cpp | 149 + .../ApiExtractor/tests/testdroptypeentries.h | 44 + .../tests/testdtorinformation.cpp | 119 + .../ApiExtractor/tests/testdtorinformation.h | 47 + .../shiboken2/ApiExtractor/tests/testenum.cpp | 437 + .../shiboken2/ApiExtractor/tests/testenum.h | 47 + .../ApiExtractor/tests/testextrainclude.cpp | 86 + .../ApiExtractor/tests/testextrainclude.h | 42 + .../ApiExtractor/tests/testfunctiontag.cpp | 98 + .../ApiExtractor/tests/testfunctiontag.h | 42 + .../tests/testimplicitconversions.cpp | 165 + .../tests/testimplicitconversions.h | 46 + .../ApiExtractor/tests/testinserttemplate.cpp | 86 + .../ApiExtractor/tests/testinserttemplate.h | 42 + .../tests/testmodifydocumentation.cpp | 107 + .../tests/testmodifydocumentation.h | 41 + .../tests/testmodifydocumentation.qrc | 5 + .../ApiExtractor/tests/testmodifyfunction.cpp | 466 + .../ApiExtractor/tests/testmodifyfunction.h | 49 + .../tests/testmultipleinheritance.cpp | 75 + .../tests/testmultipleinheritance.h | 43 + .../ApiExtractor/tests/testnamespace.cpp | 96 + .../ApiExtractor/tests/testnamespace.h | 44 + .../ApiExtractor/tests/testnestedtypes.cpp | 128 + .../ApiExtractor/tests/testnestedtypes.h | 41 + .../tests/testnumericaltypedef.cpp | 119 + .../ApiExtractor/tests/testnumericaltypedef.h | 42 + .../tests/testprimitivetypetag.cpp | 60 + .../ApiExtractor/tests/testprimitivetypetag.h | 41 + .../ApiExtractor/tests/testrefcounttag.cpp | 101 + .../ApiExtractor/tests/testrefcounttag.h | 42 + .../tests/testreferencetopointer.cpp | 59 + .../tests/testreferencetopointer.h | 41 + .../ApiExtractor/tests/testremovefield.cpp | 62 + .../ApiExtractor/tests/testremovefield.h | 41 + .../ApiExtractor/tests/testremoveimplconv.cpp | 70 + .../ApiExtractor/tests/testremoveimplconv.h | 41 + .../tests/testremoveoperatormethod.cpp | 117 + .../tests/testremoveoperatormethod.h | 41 + .../ApiExtractor/tests/testresolvetype.cpp | 66 + .../ApiExtractor/tests/testresolvetype.h | 41 + .../tests/testreverseoperators.cpp | 123 + .../ApiExtractor/tests/testreverseoperators.h | 41 + .../ApiExtractor/tests/testtemplates.cpp | 647 + .../ApiExtractor/tests/testtemplates.h | 55 + .../ApiExtractor/tests/testtoposort.cpp | 68 + .../ApiExtractor/tests/testtoposort.h | 42 + .../ApiExtractor/tests/testtyperevision.cpp | 107 + .../ApiExtractor/tests/testtyperevision.h | 44 + .../shiboken2/ApiExtractor/tests/testutil.h | 82 + .../tests/testvaluetypedefaultctortag.cpp | 64 + .../tests/testvaluetypedefaultctortag.h | 41 + .../ApiExtractor/tests/testvoidarg.cpp | 87 + .../ApiExtractor/tests/testvoidarg.h | 42 + .../shiboken2/ApiExtractor/tests/utf8code.txt | 1 + .../shiboken2/ApiExtractor/typedatabase.cpp | 1056 + sources/shiboken2/ApiExtractor/typedatabase.h | 225 + .../ApiExtractor/typedatabase_typedefs.h | 69 + sources/shiboken2/ApiExtractor/typeparser.cpp | 305 + sources/shiboken2/ApiExtractor/typeparser.h | 45 + sources/shiboken2/ApiExtractor/typesystem.cpp | 1278 + sources/shiboken2/ApiExtractor/typesystem.h | 1693 + .../shiboken2/ApiExtractor/typesystem_enums.h | 95 + .../ApiExtractor/typesystem_typedefs.h | 53 + .../ApiExtractor/typesystemparser.cpp | 3135 ++ .../shiboken2/ApiExtractor/typesystemparser.h | 284 + sources/shiboken2/ApiExtractor/xmlutils.cpp | 68 + sources/shiboken2/ApiExtractor/xmlutils.h | 53 + .../ApiExtractor/xmlutils_libxslt.cpp | 231 + .../shiboken2/ApiExtractor/xmlutils_libxslt.h | 40 + .../shiboken2/ApiExtractor/xmlutils_qt.cpp | 102 + sources/shiboken2/ApiExtractor/xmlutils_qt.h | 40 + sources/shiboken2/CMakeLists.txt | 229 + sources/shiboken2/COPYING | 342 + sources/shiboken2/COPYING.libsample | 501 + sources/shiboken2/COPYING.libshiboken | 501 + sources/shiboken2/Doxyfile | 311 + sources/shiboken2/cmake_uninstall.cmake | 21 + sources/shiboken2/data/CMakeLists.txt | 61 + .../data/GeneratorRunnerConfig.cmake.in | 17 + .../GeneratorRunnerConfigVersion.cmake.in | 10 + .../data/Shiboken2Config-spec.cmake.in | 41 + .../shiboken2/data/Shiboken2Config.cmake.in | 5 + .../data/Shiboken2ConfigVersion.cmake.in | 10 + sources/shiboken2/data/docgenerator.1 | 76 + sources/shiboken2/data/generatorrunner.1 | 76 + sources/shiboken2/data/generatorrunner.pc.in | 13 + sources/shiboken2/data/shiboken2.pc.in | 13 + sources/shiboken2/data/shiboken_helpers.cmake | 476 + sources/shiboken2/doc/CMakeLists.txt | 62 + sources/shiboken2/doc/README.md | 12 + sources/shiboken2/doc/_templates/index.html | 35 + sources/shiboken2/doc/_templates/layout.html | 29 + .../doc/_themes/pysidedocs/searchbox.html | 12 + .../_themes/pysidedocs/static/bg_header.png | Bin 0 -> 36012 bytes .../doc/_themes/pysidedocs/static/bg_topo.jpg | Bin 0 -> 14237 bytes .../doc/_themes/pysidedocs/static/fakebar.png | Bin 0 -> 101 bytes .../_themes/pysidedocs/static/logo_python.jpg | Bin 0 -> 2660 bytes .../doc/_themes/pysidedocs/static/logo_qt.png | Bin 0 -> 1032 bytes .../doc/_themes/pysidedocs/static/pyside.css | 2076 + .../_themes/pysidedocs/static/pysidelogo.png | Bin 0 -> 4936 bytes .../_themes/pysidedocs/static/relbar_bg.png | Bin 0 -> 130 bytes .../doc/_themes/pysidedocs/theme.conf | 7 + .../pysidedocs_qthelp/domainindex.html | 57 + .../pysidedocs_qthelp/static/fakebar.png | Bin 0 -> 101 bytes .../pysidedocs_qthelp/static/logo_python.jpg | Bin 0 -> 2660 bytes .../pysidedocs_qthelp/static/logo_qt.png | Bin 0 -> 1936 bytes .../pysidedocs_qthelp/static/minus.png | Bin 0 -> 199 bytes .../_themes/pysidedocs_qthelp/static/plus.png | Bin 0 -> 199 bytes .../pysidedocs_qthelp/static/pyside.css | 1943 + .../pysidedocs_qthelp/static/pysidelogo.png | Bin 0 -> 4936 bytes .../pysidedocs_qthelp/static/relbar_bg.png | Bin 0 -> 130 bytes .../doc/_themes/pysidedocs_qthelp/theme.conf | 7 + sources/shiboken2/doc/conf.py.in | 168 + sources/shiboken2/doc/considerations.rst | 183 + sources/shiboken2/doc/dependency-pyside.svg | 527 + sources/shiboken2/doc/examples/index.rst | 9 + .../shiboken2/doc/examples/samplebinding.rst | 246 + sources/shiboken2/doc/gettingstarted.rst | 72 + sources/shiboken2/doc/images/.directory | 3 + .../doc/images/bindinggen-development.png | Bin 0 -> 32698 bytes .../doc/images/bindinggen-development.svg | 542 + sources/shiboken2/doc/images/boostgen.png | Bin 0 -> 153473 bytes sources/shiboken2/doc/images/converter.png | Bin 0 -> 22467 bytes sources/shiboken2/doc/images/converter.svg | 349 + .../shiboken2/doc/images/genrunnerarch.png | Bin 0 -> 68761 bytes .../shiboken2/doc/images/genrunnerarch.svg | 654 + sources/shiboken2/doc/images/icecream.png | Bin 0 -> 4272 bytes .../doc/images/qtforpython-underthehood.png | Bin 0 -> 19144 bytes .../shiboken2/doc/images/shibokenqtarch.png | Bin 0 -> 17602 bytes .../shiboken2/doc/images/shibokenqtarch.svg | 188 + sources/shiboken2/doc/index.rst | 58 + sources/shiboken2/doc/shibokengenerator.rst | 317 + sources/shiboken2/doc/shibokenmodule.rst | 79 + sources/shiboken2/doc/typesystem.rst | 65 + .../shiboken2/doc/typesystem_arguments.rst | 207 + .../doc/typesystem_codegeneration.rst | 37 + .../doc/typesystem_codeinjection.rst | 390 + .../doc/typesystem_conversionrule.rst | 116 + .../shiboken2/doc/typesystem_converters.rst | 291 + .../doc/typesystem_documentation.rst | 43 + .../doc/typesystem_manipulating_objects.rst | 310 + .../doc/typesystem_modify_function.rst | 78 + .../shiboken2/doc/typesystem_ownership.rst | 234 + .../doc/typesystem_sequenceprotocol.rst | 29 + .../doc/typesystem_solving_compilation.rst | 70 + .../doc/typesystem_specifying_types.rst | 489 + .../shiboken2/doc/typesystem_templates.rst | 55 + .../shiboken2/doc/typesystem_variables.rst | 359 + sources/shiboken2/generator/CMakeLists.txt | 63 + sources/shiboken2/generator/__init__.py.in | 2 + sources/shiboken2/generator/_config.py.in | 9 + sources/shiboken2/generator/generator.cpp | 975 + sources/shiboken2/generator/generator.h | 436 + sources/shiboken2/generator/indentor.h | 99 + sources/shiboken2/generator/main.cpp | 649 + .../generator/qtdoc/qtdocgenerator.cpp | 2427 + .../generator/qtdoc/qtdocgenerator.h | 286 + .../generator/shiboken2/cppgenerator.cpp | 6469 +++ .../generator/shiboken2/cppgenerator.h | 419 + .../generator/shiboken2/ctypenames.h | 56 + .../generator/shiboken2/headergenerator.cpp | 662 + .../generator/shiboken2/headergenerator.h | 70 + .../generator/shiboken2/overloaddata.cpp | 1087 + .../generator/shiboken2/overloaddata.h | 164 + .../generator/shiboken2/shibokengenerator.cpp | 2874 ++ .../generator/shiboken2/shibokengenerator.h | 583 + .../shiboken2/generator/shibokenconfig.h.in | 6 + sources/shiboken2/generatorrunnerconfig.h.in | 13 + sources/shiboken2/generatorrunnermacros.h | 48 + .../generators/shiboken/shiboken.cpp | 32 + sources/shiboken2/icecc.cmake | 11 + sources/shiboken2/libshiboken/CMakeLists.txt | 160 + sources/shiboken2/libshiboken/autodecref.h | 111 + sources/shiboken2/libshiboken/basewrapper.cpp | 1921 + sources/shiboken2/libshiboken/basewrapper.h | 479 + sources/shiboken2/libshiboken/basewrapper_p.h | 292 + .../shiboken2/libshiboken/bindingmanager.cpp | 374 + .../shiboken2/libshiboken/bindingmanager.h | 110 + .../libshiboken/bufferprocs_py37.cpp | 396 + .../shiboken2/libshiboken/bufferprocs_py37.h | 145 + .../shiboken2/libshiboken/debugfreehook.cpp | 194 + sources/shiboken2/libshiboken/debugfreehook.h | 61 + .../libshiboken/embed/embedding_generator.py | 242 + .../libshiboken/embed/module_collector.py | 105 + .../libshiboken/embed/qt_python_license.txt | 87 + .../libshiboken/embed/signature_bootstrap.py | 180 + sources/shiboken2/libshiboken/gilstate.cpp | 74 + sources/shiboken2/libshiboken/gilstate.h | 69 + sources/shiboken2/libshiboken/helper.cpp | 281 + sources/shiboken2/libshiboken/helper.h | 124 + .../libshiboken/pep384_issue33738.cpp | 121 + sources/shiboken2/libshiboken/pep384impl.cpp | 835 + sources/shiboken2/libshiboken/pep384impl.h | 576 + .../shiboken2/libshiboken/pep384impl_doc.rst | 721 + .../shiboken2/libshiboken/python25compat.h | 104 + sources/shiboken2/libshiboken/qapp_macro.cpp | 100 + sources/shiboken2/libshiboken/qapp_macro.h | 52 + .../shiboken2/libshiboken/qt_attribution.json | 12 + .../libshiboken/sbkarrayconverter.cpp | 289 + .../shiboken2/libshiboken/sbkarrayconverter.h | 174 + .../libshiboken/sbkarrayconverter_p.h | 62 + .../shiboken2/libshiboken/sbkconverter.cpp | 597 + sources/shiboken2/libshiboken/sbkconverter.h | 405 + .../shiboken2/libshiboken/sbkconverter_p.h | 575 + sources/shiboken2/libshiboken/sbkdbg.h | 129 + sources/shiboken2/libshiboken/sbkenum.cpp | 807 + sources/shiboken2/libshiboken/sbkenum.h | 123 + sources/shiboken2/libshiboken/sbkmodule.cpp | 111 + sources/shiboken2/libshiboken/sbkmodule.h | 115 + .../libshiboken/sbknumpyarrayconverter.cpp | 308 + sources/shiboken2/libshiboken/sbkpython.h | 145 + .../libshiboken/sbkstaticstrings.cpp | 108 + .../shiboken2/libshiboken/sbkstaticstrings.h | 81 + .../libshiboken/sbkstaticstrings_p.h | 73 + sources/shiboken2/libshiboken/sbkstring.cpp | 339 + sources/shiboken2/libshiboken/sbkstring.h | 73 + sources/shiboken2/libshiboken/sbkversion.h.in | 53 + sources/shiboken2/libshiboken/shiboken.h | 61 + .../shiboken2/libshiboken/shibokenbuffer.cpp | 103 + .../shiboken2/libshiboken/shibokenbuffer.h | 85 + .../shiboken2/libshiboken/shibokenmacros.h | 64 + sources/shiboken2/libshiboken/signature.h | 55 + .../libshiboken/signature/signature.cpp | 482 + .../libshiboken/signature/signature_doc.rst | 357 + .../signature/signature_extend.cpp | 294 + .../signature/signature_globals.cpp | 295 + .../signature/signature_helper.cpp | 437 + .../libshiboken/signature/signature_p.h | 107 + .../libshiboken/threadstatesaver.cpp | 71 + .../shiboken2/libshiboken/threadstatesaver.h | 68 + .../tmp-referencetopython/sbkconverter.cpp | 216 + .../tmp-referencetopython/sbkconverter.h | 191 + sources/shiboken2/libshiboken/typespec.cpp | 777 + sources/shiboken2/libshiboken/typespec.h | 153 + sources/shiboken2/libshiboken/voidptr.cpp | 480 + sources/shiboken2/libshiboken/voidptr.h | 65 + sources/shiboken2/shiboken_tool.py | 53 + sources/shiboken2/shiboken_version.py | 55 + .../shiboken2/shibokenmodule/CMakeLists.txt | 90 + .../shiboken2/shibokenmodule/__init__.py.in | 30 + .../shiboken2/shibokenmodule/_config.py.in | 11 + .../files.dir/shibokensupport/__feature__.py | 189 + .../files.dir/shibokensupport/__init__.py | 40 + .../shibokensupport/backport_inspect.py | 900 + .../shibokensupport/fix-complaints.py | 98 + .../shibokensupport/signature/PSF-3.7.0.txt | 43 + .../shibokensupport/signature/__init__.py | 42 + .../shibokensupport/signature/errorhandler.py | 153 + .../signature/importhandler.py | 103 + .../shibokensupport/signature/layout.py | 281 + .../shibokensupport/signature/lib/__init__.py | 40 + .../shibokensupport/signature/lib/enum_sig.py | 216 + .../shibokensupport/signature/lib/tool.py | 154 + .../shibokensupport/signature/loader.py | 235 + .../shibokensupport/signature/mapping.py | 660 + .../shibokensupport/signature/parser.py | 463 + .../signature/qt_attribution.json | 13 + .../files.dir/shibokensupport/typing27.py | 2636 ++ sources/shiboken2/shibokenmodule/nothing.h | 0 .../shibokenmodule/shibokenmodule.txt.in | 16 + .../shibokenmodule/typesystem_shiboken.xml | 129 + sources/shiboken2/tests/CMakeLists.txt | 91 + .../tests/dumpcodemodel/CMakeLists.txt | 6 + .../shiboken2/tests/dumpcodemodel/main.cpp | 281 + .../shiboken2/tests/libminimal/CMakeLists.txt | 13 + .../tests/libminimal/libminimalmacros.h | 46 + .../shiboken2/tests/libminimal/listuser.cpp | 124 + sources/shiboken2/tests/libminimal/listuser.h | 75 + sources/shiboken2/tests/libminimal/minbool.h | 68 + sources/shiboken2/tests/libminimal/obj.cpp | 44 + sources/shiboken2/tests/libminimal/obj.h | 59 + .../shiboken2/tests/libminimal/typedef.cpp | 75 + sources/shiboken2/tests/libminimal/typedef.h | 54 + sources/shiboken2/tests/libminimal/val.h | 59 + .../shiboken2/tests/libother/CMakeLists.txt | 18 + .../libother/extendsnoimplicitconversion.h | 45 + .../shiboken2/tests/libother/libothermacros.h | 46 + sources/shiboken2/tests/libother/number.cpp | 59 + sources/shiboken2/tests/libother/number.h | 57 + .../shiboken2/tests/libother/otherderived.cpp | 64 + .../shiboken2/tests/libother/otherderived.h | 68 + .../tests/libother/othermultiplederived.cpp | 50 + .../tests/libother/othermultiplederived.h | 46 + .../tests/libother/otherobjecttype.cpp | 46 + .../tests/libother/otherobjecttype.h | 53 + .../tests/libother/othertypesystypedef.cpp | 44 + .../tests/libother/othertypesystypedef.h | 46 + .../tests/libother/smartptrtester.cpp | 55 + .../shiboken2/tests/libother/smartptrtester.h | 49 + .../shiboken2/tests/libsample/CMakeLists.txt | 61 + .../shiboken2/tests/libsample/abstract.cpp | 97 + sources/shiboken2/tests/libsample/abstract.h | 108 + .../shiboken2/tests/libsample/blackbox.cpp | 131 + sources/shiboken2/tests/libsample/blackbox.h | 67 + sources/shiboken2/tests/libsample/bucket.cpp | 86 + sources/shiboken2/tests/libsample/bucket.h | 59 + .../shiboken2/tests/libsample/bytearray.cpp | 214 + sources/shiboken2/tests/libsample/bytearray.h | 89 + .../shiboken2/tests/libsample/collector.cpp | 62 + sources/shiboken2/tests/libsample/collector.h | 71 + sources/shiboken2/tests/libsample/complex.cpp | 54 + sources/shiboken2/tests/libsample/complex.h | 55 + .../shiboken2/tests/libsample/ctorconvrule.h | 45 + sources/shiboken2/tests/libsample/cvlist.h | 53 + sources/shiboken2/tests/libsample/derived.cpp | 125 + sources/shiboken2/tests/libsample/derived.h | 95 + sources/shiboken2/tests/libsample/echo.cpp | 29 + sources/shiboken2/tests/libsample/echo.h | 55 + .../tests/libsample/exceptiontest.cpp | 64 + .../shiboken2/tests/libsample/exceptiontest.h | 48 + .../shiboken2/tests/libsample/expression.cpp | 137 + .../shiboken2/tests/libsample/expression.h | 64 + sources/shiboken2/tests/libsample/filter.cpp | 73 + sources/shiboken2/tests/libsample/filter.h | 99 + .../shiboken2/tests/libsample/functions.cpp | 255 + sources/shiboken2/tests/libsample/functions.h | 104 + sources/shiboken2/tests/libsample/handle.cpp | 44 + sources/shiboken2/tests/libsample/handle.h | 72 + .../tests/libsample/implicitconv.cpp | 66 + .../shiboken2/tests/libsample/implicitconv.h | 83 + .../shiboken2/tests/libsample/injectcode.cpp | 108 + .../shiboken2/tests/libsample/injectcode.h | 65 + .../tests/libsample/libsamplemacros.h | 46 + sources/shiboken2/tests/libsample/list.h | 106 + .../shiboken2/tests/libsample/listuser.cpp | 91 + sources/shiboken2/tests/libsample/listuser.h | 74 + sources/shiboken2/tests/libsample/main.cpp | 244 + sources/shiboken2/tests/libsample/mapuser.cpp | 74 + sources/shiboken2/tests/libsample/mapuser.h | 67 + .../shiboken2/tests/libsample/modelindex.h | 72 + .../tests/libsample/modifications.cpp | 186 + .../shiboken2/tests/libsample/modifications.h | 160 + .../tests/libsample/modified_constructor.cpp | 42 + .../tests/libsample/modified_constructor.h | 46 + .../tests/libsample/multiple_derived.cpp | 64 + .../tests/libsample/multiple_derived.h | 195 + .../tests/libsample/noimplicitconversion.h | 49 + .../tests/libsample/nondefaultctor.h | 75 + .../tests/libsample/nontypetemplate.h | 52 + sources/shiboken2/tests/libsample/null.h | 44 + .../shiboken2/tests/libsample/objectmodel.cpp | 42 + .../shiboken2/tests/libsample/objectmodel.h | 58 + .../shiboken2/tests/libsample/objecttype.cpp | 318 + .../shiboken2/tests/libsample/objecttype.h | 187 + .../tests/libsample/objecttypebyvalue.h | 46 + .../tests/libsample/objecttypeholder.cpp | 58 + .../tests/libsample/objecttypeholder.h | 52 + .../tests/libsample/objecttypelayout.cpp | 68 + .../tests/libsample/objecttypelayout.h | 56 + .../tests/libsample/objecttypeoperators.cpp | 63 + .../tests/libsample/objecttypeoperators.h | 61 + .../shiboken2/tests/libsample/objectview.cpp | 54 + .../shiboken2/tests/libsample/objectview.h | 58 + sources/shiboken2/tests/libsample/oddbool.cpp | 48 + sources/shiboken2/tests/libsample/oddbool.h | 108 + .../shiboken2/tests/libsample/onlycopy.cpp | 83 + sources/shiboken2/tests/libsample/onlycopy.h | 63 + .../shiboken2/tests/libsample/overload.cpp | 50 + sources/shiboken2/tests/libsample/overload.h | 143 + .../tests/libsample/overloadsort.cpp | 39 + .../shiboken2/tests/libsample/overloadsort.h | 95 + .../shiboken2/tests/libsample/pairuser.cpp | 57 + sources/shiboken2/tests/libsample/pairuser.h | 55 + sources/shiboken2/tests/libsample/pen.cpp | 81 + sources/shiboken2/tests/libsample/pen.h | 72 + sources/shiboken2/tests/libsample/photon.cpp | 50 + sources/shiboken2/tests/libsample/photon.h | 140 + sources/shiboken2/tests/libsample/point.cpp | 155 + sources/shiboken2/tests/libsample/point.h | 99 + .../shiboken2/tests/libsample/pointerholder.h | 45 + sources/shiboken2/tests/libsample/pointf.cpp | 126 + sources/shiboken2/tests/libsample/pointf.h | 88 + sources/shiboken2/tests/libsample/polygon.cpp | 75 + sources/shiboken2/tests/libsample/polygon.h | 66 + .../shiboken2/tests/libsample/privatector.h | 55 + .../shiboken2/tests/libsample/privatedtor.h | 60 + .../shiboken2/tests/libsample/protected.cpp | 32 + sources/shiboken2/tests/libsample/protected.h | 151 + sources/shiboken2/tests/libsample/rect.h | 86 + .../shiboken2/tests/libsample/reference.cpp | 78 + sources/shiboken2/tests/libsample/reference.h | 81 + .../tests/libsample/removednamespaces.h | 74 + .../shiboken2/tests/libsample/renaming.cpp | 46 + sources/shiboken2/tests/libsample/renaming.h | 50 + sources/shiboken2/tests/libsample/sample.cpp | 47 + sources/shiboken2/tests/libsample/sample.h | 51 + .../tests/libsample/samplenamespace.cpp | 137 + .../tests/libsample/samplenamespace.h | 162 + sources/shiboken2/tests/libsample/sbkdate.cpp | 48 + sources/shiboken2/tests/libsample/sbkdate.h | 50 + .../shiboken2/tests/libsample/simplefile.cpp | 108 + .../shiboken2/tests/libsample/simplefile.h | 56 + sources/shiboken2/tests/libsample/size.cpp | 39 + sources/shiboken2/tests/libsample/size.h | 206 + .../shiboken2/tests/libsample/sometime.cpp | 99 + sources/shiboken2/tests/libsample/sometime.h | 92 + sources/shiboken2/tests/libsample/str.cpp | 185 + sources/shiboken2/tests/libsample/str.h | 78 + sources/shiboken2/tests/libsample/strlist.cpp | 57 + sources/shiboken2/tests/libsample/strlist.h | 65 + .../shiboken2/tests/libsample/templateptr.cpp | 33 + .../shiboken2/tests/libsample/templateptr.h | 43 + .../shiboken2/tests/libsample/transform.cpp | 65 + sources/shiboken2/tests/libsample/transform.h | 45 + .../tests/libsample/typesystypedef.cpp | 37 + .../tests/libsample/typesystypedef.h | 57 + .../tests/libsample/valueandvirtual.h | 47 + .../tests/libsample/virtualmethods.cpp | 84 + .../tests/libsample/virtualmethods.h | 163 + .../shiboken2/tests/libsample/voidholder.h | 54 + .../shiboken2/tests/libsmart/CMakeLists.txt | 11 + .../shiboken2/tests/libsmart/libsmartmacros.h | 46 + sources/shiboken2/tests/libsmart/smart.cpp | 261 + sources/shiboken2/tests/libsmart/smart.h | 37 + .../shiboken2/tests/libsmart/smart_integer.h | 56 + sources/shiboken2/tests/libsmart/smart_obj.h | 62 + .../shiboken2/tests/libsmart/smart_registry.h | 68 + .../tests/libsmart/smart_sharedptr.h | 116 + .../tests/minimalbinding/CMakeLists.txt | 36 + .../minimalbinding/brace_pattern_test.py | 125 + .../shiboken2/tests/minimalbinding/global.h | 33 + .../tests/minimalbinding/listuser_test.py | 330 + .../tests/minimalbinding/minbool_test.py | 70 + .../minimalbinding/minimal-binding.txt.in | 15 + .../tests/minimalbinding/obj_test.py | 120 + .../tests/minimalbinding/typedef_test.py | 122 + .../minimalbinding/typesystem_minimal.xml | 93 + .../tests/minimalbinding/val_test.py | 121 + .../tests/otherbinding/CMakeLists.txt | 49 + .../collector_external_operator_test.py | 64 + ...class_without_implicit_conversions_test.py | 79 + .../extended_multiply_operator_test.py | 70 + sources/shiboken2/tests/otherbinding/global.h | 36 + .../tests/otherbinding/module_reload_test.py | 65 + .../otherbinding/new_ctor_operator_test.py | 62 + .../tests/otherbinding/objtypehashes_test.py | 59 + .../tests/otherbinding/other-binding.txt.in | 20 + .../tests/otherbinding/otherderived_test.py | 125 + .../otherbinding/othertypesystypedef_test.py | 62 + .../tests/otherbinding/signature_test.py | 54 + .../tests/otherbinding/smartptr_test.py | 61 + .../otherbinding/test_module_template.py | 40 + .../tests/otherbinding/typediscovery_test.py | 72 + .../tests/otherbinding/typesystem_other.xml | 24 + .../usersprimitivefromothermodule_test.py | 58 + .../tests/otherbinding/wrongctor_test.py | 59 + sources/shiboken2/tests/py3k.py | 2 + sources/shiboken2/tests/py3kcompat.py | 82 + .../tests/samplebinding/CMakeLists.txt | 158 + .../tests/samplebinding/__del___test.py | 57 + .../tests/samplebinding/abstract_test.py | 116 + .../tests/samplebinding/addedfunction_test.py | 68 + .../addedfunction_with_container_args_test.py | 57 + .../argumentmodifications_test.py | 116 + .../tests/samplebinding/array_numpy_test.py | 70 + .../samplebinding/array_sequence_test.py | 59 + .../tests/samplebinding/bug_554_test.py | 51 + .../tests/samplebinding/bug_704_test.py | 74 + .../bytearray_bufferprotocol.cpp | 55 + .../tests/samplebinding/bytearray_test.py | 157 + .../tests/samplebinding/child_return_test.py | 63 + .../tests/samplebinding/class_fields_test.py | 174 + .../tests/samplebinding/collector_test.py | 86 + .../tests/samplebinding/complex_test.py | 89 + .../samplebinding/conversion_operator_test.py | 61 + .../tests/samplebinding/copy_test.py | 92 + .../tests/samplebinding/ctorconvrule_test.py | 55 + .../tests/samplebinding/cyclic_test.py | 115 + .../tests/samplebinding/date_test.py | 63 + .../tests/samplebinding/decisor_test.py | 73 + .../tests/samplebinding/delete_test.py | 53 + .../tests/samplebinding/deprecated_test.py | 50 + .../tests/samplebinding/derived_test.py | 158 + .../tests/samplebinding/duck_punching_test.py | 182 + .../tests/samplebinding/echo_test.py | 58 + .../tests/samplebinding/enum_test.py | 188 + .../enumfromremovednamespace_test.py | 83 + .../event_loop_call_virtual_test.py | 76 + .../samplebinding/event_loop_thread_test.py | 102 + .../tests/samplebinding/exception_test.py | 84 + .../tests/samplebinding/filter_test.py | 51 + .../shiboken2/tests/samplebinding/global.h | 94 + .../tests/samplebinding/handleholder_test.py | 63 + .../tests/samplebinding/hashabletype_test.py | 60 + .../tests/samplebinding/ignorederefop_test.py | 44 + .../implicitconv_numerical_test.py | 157 + .../tests/samplebinding/implicitconv_test.py | 72 + .../samplebinding/inheritanceandscope_test.py | 54 + .../tests/samplebinding/injectcode_test.py | 138 + .../tests/samplebinding/innerclass_test.py | 48 + .../tests/samplebinding/intlist_test.py | 104 + .../invalid_virtual_return_test.py | 71 + .../samplebinding/keep_reference_test.py | 87 + .../tests/samplebinding/list_test.py | 127 + .../tests/samplebinding/lock_test.py | 101 + .../shiboken2/tests/samplebinding/map_test.py | 86 + .../tests/samplebinding/metaclass_test.py | 68 + .../samplebinding/mi_virtual_methods_test.py | 94 + .../tests/samplebinding/mixed_mi_test.py | 82 + .../tests/samplebinding/modelindex_test.py | 59 + .../tests/samplebinding/modelview_test.py | 84 + .../tests/samplebinding/modifications_test.py | 248 + .../modified_constructor_test.py | 55 + .../modifiedvirtualmethods_test.py | 254 + .../multi_cpp_inheritance_test.py | 110 + .../samplebinding/multiple_derived_test.py | 226 + .../tests/samplebinding/namespace_test.py | 88 + .../tests/samplebinding/newdivision_test.py | 50 + .../samplebinding/nondefaultctor_test.py | 76 + .../samplebinding/nontypetemplate_test.py | 65 + .../tests/samplebinding/nonzero_test.py | 50 + .../samplebinding/numericaltypedef_test.py | 62 + .../tests/samplebinding/numpy_test.py | 64 + .../tests/samplebinding/objecttype_test.py | 136 + .../objecttype_with_named_args_test.py | 78 + .../samplebinding/objecttypebyvalue_test.py | 50 + .../samplebinding/objecttypelayout_test.py | 307 + .../samplebinding/objecttypeoperators_test.py | 66 + ...pereferenceasvirtualmethodargument_test.py | 55 + .../tests/samplebinding/oddbool_test.py | 90 + .../oldstyleclass_as_number_test.py | 89 + .../tests/samplebinding/onlycopyclass_test.py | 64 + .../tests/samplebinding/overflow_test.py | 92 + .../samplebinding/overload_sorting_test.py | 107 + .../tests/samplebinding/overload_test.py | 215 + .../samplebinding/overloadwithdefault_test.py | 70 + .../ownership_argument_invalidation_test.py | 67 + .../ownership_delete_child_in_cpp_test.py | 60 + .../ownership_delete_child_in_python_test.py | 66 + .../ownership_delete_parent_test.py | 87 + .../ownership_invalidate_after_use_test.py | 115 + .../ownership_invalidate_child_test.py | 75 + ...wnership_invalidate_nonpolymorphic_test.py | 58 + .../ownership_invalidate_parent_test.py | 74 + .../ownership_reparenting_test.py | 136 + .../ownership_transference_test.py | 90 + .../tests/samplebinding/pair_test.py | 110 + .../shiboken2/tests/samplebinding/pen_test.py | 83 + .../tests/samplebinding/point_test.py | 117 + .../tests/samplebinding/pointerholder_test.py | 64 + .../pointerprimitivetype_test.py | 82 + .../tests/samplebinding/pointf_test.py | 75 + .../primitivereferenceargument_test.py | 55 + .../tests/samplebinding/privatector_test.py | 89 + .../tests/samplebinding/privatedtor_test.py | 104 + .../tests/samplebinding/protected_test.py | 363 + .../tests/samplebinding/pstrlist_test.py | 56 + .../tests/samplebinding/pystr_test.py | 54 + .../tests/samplebinding/python_thread_test.py | 122 + .../receive_null_cstring_test.py | 60 + .../tests/samplebinding/reference_test.py | 127 + .../samplebinding/referencetopointer_test.py | 103 + .../tests/samplebinding/renaming_test.py | 63 + .../tests/samplebinding/return_null_test.py | 64 + .../tests/samplebinding/richcompare_test.py | 52 + .../tests/samplebinding/sample-binding.txt.in | 15 + .../tests/samplebinding/sample_test.py | 84 + .../tests/samplebinding/simplefile_glue.cpp | 34 + .../tests/samplebinding/simplefile_test.py | 86 + .../tests/samplebinding/size_test.py | 125 + .../static_nonstatic_methods_test.py | 114 + .../shiboken2/tests/samplebinding/str_test.py | 121 + .../tests/samplebinding/strlist_test.py | 118 + .../templateinheritingclass_test.py | 87 + .../tests/samplebinding/time_test.py | 145 + .../tests/samplebinding/transform_test.py | 62 + .../samplebinding/typeconverters_test.py | 196 + .../tests/samplebinding/typedealloc_test.py | 81 + .../samplebinding/typedtordoublefree_test.py | 60 + .../tests/samplebinding/typesystem_sample.xml | 2492 + .../samplebinding/typesystypedef_test.py | 56 + .../tests/samplebinding/unsafe_parent_test.py | 59 + .../tests/samplebinding/useraddedctor_test.py | 51 + .../tests/samplebinding/virtualdtor_test.py | 81 + .../samplebinding/virtualmethods_test.py | 143 + .../samplebinding/visibilitychange_test.py | 53 + .../tests/samplebinding/voidholder_test.py | 75 + .../tests/samplebinding/weakref_test.py | 71 + .../samplebinding/writableclassdict_test.py | 59 + sources/shiboken2/tests/shiboken_paths.py | 131 + .../shiboken2/tests/shiboken_test_helper.py | 40 + .../tests/shibokenmodule/module_test.py | 123 + .../tests/smartbinding/CMakeLists.txt | 40 + sources/shiboken2/tests/smartbinding/global.h | 29 + .../tests/smartbinding/smart-binding.txt.in | 15 + .../tests/smartbinding/smart_pointer_test.py | 232 + .../tests/smartbinding/typesystem_smart.xml | 57 + sources/shiboken2/tests/sphinxtabletest.cpp | 332 + sources/shiboken2/tests/sphinxtabletest.h | 54 + .../tests/test_generator/CMakeLists.txt | 62 + .../tests/test_generator/dummygenerator.cpp | 70 + .../tests/test_generator/dummygenerator.h | 49 + .../dummygentest-project.txt.in | 20 + .../tests/test_generator/dummygentest.cpp | 138 + .../tests/test_generator/dummygentest.h | 56 + .../test_generator/dummygentestconfig.h.in | 15 + .../shiboken2/tests/test_generator/main.cpp | 39 + .../tests/test_generator/run_test.cmake | 11 + .../tests/test_generator/test_global.h | 1 + .../tests/test_generator/test_typesystem.xml | 3 + testing/__init__.py | 68 + testing/blacklist.py | 132 + testing/buildlog.py | 177 + testing/command.py | 357 + testing/helper.py | 79 + testing/parser.py | 186 + testing/runner.py | 243 + testing/testing.pyproject | 4 + testing/wheel_tester.py | 352 + testrunner.py | 53 + tools/checklibs.py | 386 + tools/create_changelog.py | 270 + tools/debug_windows.py | 365 + tools/dump_metaobject.py | 155 + tools/metaobject_dump.py | 67 + tools/metaobject_dump.pyproject | 3 + tools/missing_bindings-requirements.txt | 7 + tools/missing_bindings.py | 458 + tools/qtpy2cpp.py | 99 + tools/qtpy2cpp.pyproject | 6 + tools/qtpy2cpp_lib/astdump.py | 149 + tools/qtpy2cpp_lib/formatter.py | 264 + tools/qtpy2cpp_lib/nodedump.py | 86 + .../qtpy2cpp_lib/test_baseline/basic_test.py | 38 + tools/qtpy2cpp_lib/test_baseline/uic.py | 208 + tools/qtpy2cpp_lib/tokenizer.py | 91 + tools/qtpy2cpp_lib/visitor.py | 260 + 2861 files changed, 503384 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .travis.yml create mode 100644 CMakeLists.txt create mode 100644 LICENSE.COMMERCIAL create mode 100644 LICENSE.FDL create mode 100644 LICENSE.GPL2 create mode 100644 LICENSE.GPLv3 create mode 100644 LICENSE.GPLv3-EXCEPT create mode 100644 LICENSE.LGPLv3 create mode 100644 README.cmake.md create mode 100644 README.md create mode 100644 README.pyside2.md create mode 100644 README.shiboken2-generator.md create mode 100644 README.shiboken2.md create mode 100644 build_history/blacklist.txt create mode 100644 build_scripts/__init__.py create mode 100644 build_scripts/build_scripts.pyproject create mode 100644 build_scripts/config.py create mode 100644 build_scripts/main.py create mode 100644 build_scripts/options.py create mode 100644 build_scripts/platforms/__init__.py create mode 100644 build_scripts/platforms/linux.py create mode 100644 build_scripts/platforms/macos.py create mode 100644 build_scripts/platforms/unix.py create mode 100644 build_scripts/platforms/windows_desktop.py create mode 100644 build_scripts/qp5_tool.py create mode 100644 build_scripts/qtinfo.py create mode 100644 build_scripts/setup_runner.py create mode 100644 build_scripts/utils.py create mode 100644 build_scripts/wheel_override.py create mode 100644 build_scripts/wheel_utils.py create mode 100644 coin/instructions/common_environment.yaml create mode 100644 coin/instructions/execute_build_instructions.yaml create mode 100644 coin/instructions/execute_license_check.yaml create mode 100644 coin/instructions/execute_test_instructions.yaml create mode 100644 coin/instructions/find_path_to_msvc_compiler.yaml create mode 100644 coin/instructions/relocate_pyside.yaml create mode 100644 coin/module_config.yaml create mode 100644 coin_build_instructions.py create mode 100644 coin_test_instructions.py create mode 100644 dist/changes-1.2.3 create mode 100644 dist/changes-5.12.1 create mode 100644 dist/changes-5.12.2 create mode 100644 dist/changes-5.12.3 create mode 100644 dist/changes-5.12.4 create mode 100644 dist/changes-5.12.5 create mode 100644 dist/changes-5.12.6 create mode 100644 dist/changes-5.13.0 create mode 100644 dist/changes-5.13.1 create mode 100644 dist/changes-5.13.2 create mode 100644 dist/changes-5.14.0 create mode 100644 dist/changes-5.14.1 create mode 100644 dist/changes-5.14.2 create mode 100644 dist/changes-5.14.2.2 create mode 100644 dist/changes-5.14.2.3 create mode 100644 dist/changes-5.15.0 create mode 100644 dist/changes-5.15.1 create mode 100644 dist/changes-5.15.2 create mode 100644 docs/.gitignore create mode 100644 examples/3d/3d.pyproject create mode 100644 examples/3d/simple3d.py create mode 100644 examples/axcontainer/axcontainer.pyproject create mode 100644 examples/axcontainer/axviewer.py create mode 100644 examples/charts/audio.py create mode 100644 examples/charts/callout.py create mode 100644 examples/charts/charts.pyproject create mode 100644 examples/charts/chartthemes/README.md create mode 100644 examples/charts/chartthemes/chartthemes.pyproject create mode 100644 examples/charts/chartthemes/main.py create mode 100644 examples/charts/chartthemes/themewidget.ui create mode 100644 examples/charts/chartthemes/ui_themewidget.py create mode 100644 examples/charts/donutbreakdown.py create mode 100644 examples/charts/legend.py create mode 100644 examples/charts/lineandbar.py create mode 100644 examples/charts/linechart.py create mode 100644 examples/charts/logvalueaxis.py create mode 100644 examples/charts/memoryusage.py create mode 100644 examples/charts/modeldata.py create mode 100644 examples/charts/nesteddonuts.py create mode 100644 examples/charts/percentbarchart.py create mode 100644 examples/charts/piechart.py create mode 100644 examples/charts/qmlpolarchart/View1.qml create mode 100644 examples/charts/qmlpolarchart/View2.qml create mode 100644 examples/charts/qmlpolarchart/View3.qml create mode 100644 examples/charts/qmlpolarchart/main.qml create mode 100644 examples/charts/qmlpolarchart/qmlpolarchart.py create mode 100644 examples/charts/qmlpolarchart/qmlpolarchart.pyproject create mode 100644 examples/charts/temperaturerecords.py create mode 100644 examples/corelib/threads/mandelbrot.py create mode 100644 examples/corelib/threads/threads.pyproject create mode 100644 examples/corelib/tools/codecs/codecs.py create mode 100644 examples/corelib/tools/codecs/codecs.pyproject create mode 100644 examples/corelib/tools/regexp.py create mode 100644 examples/corelib/tools/settingseditor/settingseditor.py create mode 100644 examples/corelib/tools/settingseditor/settingseditor.pyproject create mode 100644 examples/corelib/tools/tools.pyproject create mode 100644 examples/datavisualization/bars3d.py create mode 100644 examples/datavisualization/datavisualization.pyproject create mode 100644 examples/declarative/declarative.pyproject create mode 100644 examples/declarative/extending/chapter1-basics/app.qml create mode 100644 examples/declarative/extending/chapter1-basics/basics.py create mode 100644 examples/declarative/extending/chapter1-basics/chapter1-basics.pyproject create mode 100644 examples/declarative/extending/chapter2-methods/app.qml create mode 100644 examples/declarative/extending/chapter2-methods/chapter2-methods.pyproject create mode 100644 examples/declarative/extending/chapter2-methods/methods.py create mode 100644 examples/declarative/extending/chapter3-bindings/app.qml create mode 100644 examples/declarative/extending/chapter3-bindings/bindings.py create mode 100644 examples/declarative/extending/chapter3-bindings/chapter3-bindings.pyproject create mode 100644 examples/declarative/extending/chapter4-customPropertyTypes/app.qml create mode 100644 examples/declarative/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject create mode 100644 examples/declarative/extending/chapter4-customPropertyTypes/customPropertyTypes.py create mode 100644 examples/declarative/extending/chapter5-listproperties/app.qml create mode 100644 examples/declarative/extending/chapter5-listproperties/chapter5-listproperties.pyproject create mode 100644 examples/declarative/extending/chapter5-listproperties/listproperties.py create mode 100644 examples/declarative/scrolling.py create mode 100644 examples/declarative/signals/pytoqml1/main.py create mode 100644 examples/declarative/signals/pytoqml1/pytoqml1.pyproject create mode 100644 examples/declarative/signals/pytoqml1/view.qml create mode 100644 examples/declarative/signals/qmltopy1/main.py create mode 100644 examples/declarative/signals/qmltopy1/qmltopy1.pyproject create mode 100644 examples/declarative/signals/qmltopy1/view.qml create mode 100644 examples/declarative/signals/qmltopy2/main.py create mode 100644 examples/declarative/signals/qmltopy2/qmltopy2.pyproject create mode 100644 examples/declarative/signals/qmltopy2/view.qml create mode 100644 examples/declarative/signals/qmltopy3/main.py create mode 100644 examples/declarative/signals/qmltopy3/qmltopy3.pyproject create mode 100644 examples/declarative/signals/qmltopy3/view.qml create mode 100644 examples/declarative/signals/qmltopy4/main.py create mode 100644 examples/declarative/signals/qmltopy4/qmltopy4.pyproject create mode 100644 examples/declarative/signals/qmltopy4/view.qml create mode 100644 examples/declarative/textproperties/main.py create mode 100644 examples/declarative/textproperties/textproperties.pyproject create mode 100644 examples/declarative/textproperties/view.qml create mode 100644 examples/declarative/usingmodel.py create mode 100644 examples/declarative/view.qml create mode 100644 examples/examples.pyproject create mode 100644 examples/external/matplotlib/requirements.txt create mode 100644 examples/external/matplotlib/widget_3dplot.py create mode 100644 examples/external/opencv/requirements.txt create mode 100644 examples/external/opencv/webcam_pattern_detection.py create mode 100644 examples/external/scikit/requirements.txt create mode 100644 examples/external/scikit/staining_colors_separation.py create mode 100644 examples/installer_test/hello.py create mode 100644 examples/installer_test/hello_app.spec create mode 100644 examples/macextras/macextras.pyproject create mode 100644 examples/macextras/macpasteboardmime.py create mode 100644 examples/multimedia/audiooutput.py create mode 100644 examples/multimedia/camera.py create mode 100644 examples/multimedia/multimedia.pyproject create mode 100644 examples/multimedia/player.py create mode 100644 examples/multimedia/shutter.svg create mode 100644 examples/network/blockingfortuneclient.py create mode 100644 examples/network/fortuneclient.py create mode 100644 examples/network/fortuneserver.py create mode 100644 examples/network/network.pyproject create mode 100644 examples/network/threadedfortuneserver.py create mode 100644 examples/opengl/2dpainting.py create mode 100644 examples/opengl/contextinfo.py create mode 100644 examples/opengl/grabber.py create mode 100644 examples/opengl/hellogl.py create mode 100644 examples/opengl/hellogl2.py create mode 100644 examples/opengl/opengl.pyproject create mode 100644 examples/opengl/overpainting.py create mode 100644 examples/opengl/samplebuffers.py create mode 100644 examples/opengl/textures/images/side1.png create mode 100644 examples/opengl/textures/images/side2.png create mode 100644 examples/opengl/textures/images/side3.png create mode 100644 examples/opengl/textures/images/side4.png create mode 100644 examples/opengl/textures/images/side5.png create mode 100644 examples/opengl/textures/images/side6.png create mode 100644 examples/opengl/textures/textures.py create mode 100644 examples/opengl/textures/textures.pyproject create mode 100644 examples/opengl/textures/textures.qrc create mode 100644 examples/opengl/textures/textures_rc.py create mode 100644 examples/quick/customitems/painteditem/main.qml create mode 100644 examples/quick/customitems/painteditem/painteditem.py create mode 100644 examples/quick/customitems/painteditem/painteditem.pyproject create mode 100644 examples/remoteobjects/modelview/modelview.pyproject create mode 100644 examples/remoteobjects/modelview/modelviewclient.py create mode 100644 examples/remoteobjects/modelview/modelviewserver.py create mode 100644 examples/samplebinding/CMakeLists.txt create mode 100644 examples/samplebinding/README.md create mode 100644 examples/samplebinding/bindings.h create mode 100644 examples/samplebinding/bindings.xml create mode 100644 examples/samplebinding/icecream.cpp create mode 100644 examples/samplebinding/icecream.h create mode 100644 examples/samplebinding/macros.h create mode 100644 examples/samplebinding/main.py create mode 100644 examples/samplebinding/truck.cpp create mode 100644 examples/samplebinding/truck.h create mode 100644 examples/script/README.md create mode 100644 examples/script/helloscript.py create mode 100644 examples/script/script.pyproject create mode 100644 examples/scriptableapplication/CMakeLists.txt create mode 100644 examples/scriptableapplication/README.md create mode 100644 examples/scriptableapplication/main.cpp create mode 100644 examples/scriptableapplication/mainwindow.cpp create mode 100644 examples/scriptableapplication/mainwindow.h create mode 100644 examples/scriptableapplication/pyside2.pri create mode 100644 examples/scriptableapplication/pythonutils.cpp create mode 100644 examples/scriptableapplication/pythonutils.h create mode 100644 examples/scriptableapplication/scriptableapplication.pro create mode 100644 examples/scriptableapplication/scriptableapplication.xml create mode 100644 examples/scriptableapplication/wrappedclasses.h create mode 100644 examples/sql/books/bookdelegate.py create mode 100644 examples/sql/books/books.pyproject create mode 100644 examples/sql/books/books.qrc create mode 100644 examples/sql/books/bookwindow.py create mode 100644 examples/sql/books/bookwindow.ui create mode 100644 examples/sql/books/createdb.py create mode 100644 examples/sql/books/images/star.png create mode 100644 examples/sql/books/main.py create mode 100644 examples/sql/books/rc_books.py create mode 100644 examples/sql/books/ui_bookwindow.py create mode 100644 examples/texttospeech/texttospeech.py create mode 100644 examples/texttospeech/texttospeech.pyproject create mode 100644 examples/tutorial/t1.py create mode 100644 examples/tutorial/t10.py create mode 100644 examples/tutorial/t11.py create mode 100644 examples/tutorial/t12.py create mode 100644 examples/tutorial/t13.py create mode 100644 examples/tutorial/t14.py create mode 100644 examples/tutorial/t2.py create mode 100644 examples/tutorial/t3.py create mode 100644 examples/tutorial/t4.py create mode 100644 examples/tutorial/t5.py create mode 100644 examples/tutorial/t6.py create mode 100644 examples/tutorial/t7.py create mode 100644 examples/tutorial/t8.py create mode 100644 examples/tutorial/t9.py create mode 100644 examples/tutorial/tutorial.pyproject create mode 100644 examples/uiloader/uiloader.py create mode 100644 examples/utils/pyside2_config.py create mode 100644 examples/utils/utils.py create mode 100644 examples/webchannel/standalone/core.py create mode 100644 examples/webchannel/standalone/dialog.py create mode 100644 examples/webchannel/standalone/dialog.ui create mode 100644 examples/webchannel/standalone/index.html create mode 100644 examples/webchannel/standalone/main.py create mode 100644 examples/webchannel/standalone/standalone.pyproject create mode 100644 examples/webchannel/standalone/ui_dialog.py create mode 100644 examples/webchannel/standalone/websocketclientwrapper.py create mode 100644 examples/webchannel/standalone/websockettransport.py create mode 100644 examples/webenginequick/browser.qml create mode 100644 examples/webenginequick/quicknanobrowser.py create mode 100644 examples/webenginequick/webenginequick.pyproject create mode 100644 examples/webenginewidgets/simplebrowser.py create mode 100644 examples/webenginewidgets/tabbedbrowser/bookmarkwidget.py create mode 100644 examples/webenginewidgets/tabbedbrowser/browsertabwidget.py create mode 100644 examples/webenginewidgets/tabbedbrowser/downloadwidget.py create mode 100644 examples/webenginewidgets/tabbedbrowser/findtoolbar.py create mode 100644 examples/webenginewidgets/tabbedbrowser/historywindow.py create mode 100644 examples/webenginewidgets/tabbedbrowser/main.py create mode 100644 examples/webenginewidgets/tabbedbrowser/tabbedbrowser.pyproject create mode 100644 examples/webenginewidgets/tabbedbrowser/webengineview.py create mode 100644 examples/webenginewidgets/webenginewidgets.pyproject create mode 100644 examples/widgetbinding/CMakeLists.txt create mode 100644 examples/widgetbinding/README.md create mode 100644 examples/widgetbinding/bindings.h create mode 100644 examples/widgetbinding/bindings.xml create mode 100644 examples/widgetbinding/dialog.py create mode 100644 examples/widgetbinding/macros.h create mode 100644 examples/widgetbinding/main.py create mode 100644 examples/widgetbinding/wigglywidget.cpp create mode 100644 examples/widgetbinding/wigglywidget.h create mode 100644 examples/widgetbinding/wigglywidget.py create mode 100644 examples/widgets/animation/animatedtiles/animatedtiles.py create mode 100644 examples/widgets/animation/animatedtiles/animatedtiles.pyproject create mode 100644 examples/widgets/animation/animatedtiles/animatedtiles.qrc create mode 100644 examples/widgets/animation/animatedtiles/animatedtiles_rc.py create mode 100644 examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg create mode 100644 examples/widgets/animation/animatedtiles/images/centered.png create mode 100644 examples/widgets/animation/animatedtiles/images/ellipse.png create mode 100644 examples/widgets/animation/animatedtiles/images/figure8.png create mode 100644 examples/widgets/animation/animatedtiles/images/kinetic.png create mode 100644 examples/widgets/animation/animatedtiles/images/random.png create mode 100644 examples/widgets/animation/animatedtiles/images/tile.png create mode 100644 examples/widgets/animation/appchooser/accessories-dictionary.png create mode 100644 examples/widgets/animation/appchooser/akregator.png create mode 100644 examples/widgets/animation/appchooser/appchooser.py create mode 100644 examples/widgets/animation/appchooser/appchooser.pyproject create mode 100644 examples/widgets/animation/appchooser/appchooser.qrc create mode 100644 examples/widgets/animation/appchooser/appchooser_rc.py create mode 100644 examples/widgets/animation/appchooser/digikam.png create mode 100644 examples/widgets/animation/appchooser/k3b.png create mode 100644 examples/widgets/animation/easing/easing.py create mode 100644 examples/widgets/animation/easing/easing.pyproject create mode 100644 examples/widgets/animation/easing/easing.qrc create mode 100644 examples/widgets/animation/easing/easing_rc.py create mode 100644 examples/widgets/animation/easing/form.ui create mode 100644 examples/widgets/animation/easing/images/qt-logo.png create mode 100644 examples/widgets/animation/easing/ui_form.py create mode 100644 examples/widgets/animation/states/states.py create mode 100644 examples/widgets/animation/states/states.pyproject create mode 100644 examples/widgets/animation/states/states_rc.py create mode 100644 examples/widgets/codeeditor/codeeditor.py create mode 100644 examples/widgets/codeeditor/main.py create mode 100644 examples/widgets/dialogs/classwizard/classwizard.py create mode 100644 examples/widgets/dialogs/classwizard/classwizard.pyproject create mode 100644 examples/widgets/dialogs/classwizard/classwizard.qrc create mode 100644 examples/widgets/dialogs/classwizard/classwizard_rc.py create mode 100644 examples/widgets/dialogs/classwizard/images/background.png create mode 100644 examples/widgets/dialogs/classwizard/images/banner.png create mode 100644 examples/widgets/dialogs/classwizard/images/logo1.png create mode 100644 examples/widgets/dialogs/classwizard/images/logo2.png create mode 100644 examples/widgets/dialogs/classwizard/images/logo3.png create mode 100644 examples/widgets/dialogs/classwizard/images/watermark1.png create mode 100644 examples/widgets/dialogs/classwizard/images/watermark2.png create mode 100644 examples/widgets/dialogs/dialogs.pyproject create mode 100644 examples/widgets/dialogs/extension.py create mode 100644 examples/widgets/dialogs/findfiles.py create mode 100644 examples/widgets/dialogs/standarddialogs.py create mode 100644 examples/widgets/dialogs/trivialwizard.py create mode 100644 examples/widgets/draganddrop/draggabletext/draggabletext.py create mode 100644 examples/widgets/draganddrop/draggabletext/draggabletext.pyproject create mode 100644 examples/widgets/draganddrop/draggabletext/draggabletext.qrc create mode 100644 examples/widgets/draganddrop/draggabletext/draggabletext_rc.py create mode 100644 examples/widgets/draganddrop/draggabletext/words.txt create mode 100644 examples/widgets/effects/effects.pyproject create mode 100644 examples/widgets/effects/lighting.py create mode 100644 examples/widgets/gallery/gallery.pyproject create mode 100644 examples/widgets/gallery/main.py create mode 100644 examples/widgets/gallery/widgetgallery.py create mode 100644 examples/widgets/graphicsview/anchorlayout.py create mode 100644 examples/widgets/graphicsview/collidingmice/collidingmice.py create mode 100644 examples/widgets/graphicsview/collidingmice/collidingmice.pyproject create mode 100644 examples/widgets/graphicsview/collidingmice/mice_rc.py create mode 100644 examples/widgets/graphicsview/diagramscene/diagramscene.py create mode 100644 examples/widgets/graphicsview/diagramscene/diagramscene.pyproject create mode 100644 examples/widgets/graphicsview/diagramscene/diagramscene.qrc create mode 100644 examples/widgets/graphicsview/diagramscene/diagramscene_rc.py create mode 100644 examples/widgets/graphicsview/diagramscene/images/background1.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/background2.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/background3.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/background4.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/bold.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/bringtofront.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/delete.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/floodfill.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/italic.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/linecolor.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/linepointer.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/pointer.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/sendtoback.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/textpointer.png create mode 100644 examples/widgets/graphicsview/diagramscene/images/underline.png create mode 100644 examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py create mode 100644 examples/widgets/graphicsview/dragdroprobot/dragdroprobot.pyproject create mode 100644 examples/widgets/graphicsview/dragdroprobot/dragdroprobot.qrc create mode 100644 examples/widgets/graphicsview/dragdroprobot/dragdroprobot_rc.py create mode 100644 examples/widgets/graphicsview/dragdroprobot/images/head.png create mode 100644 examples/widgets/graphicsview/elasticnodes.py create mode 100644 examples/widgets/graphicsview/graphicsview.pyproject create mode 100644 examples/widgets/itemviews/addressbook/adddialogwidget.py create mode 100644 examples/widgets/itemviews/addressbook/addressbook.py create mode 100644 examples/widgets/itemviews/addressbook/addressbook.pyproject create mode 100644 examples/widgets/itemviews/addressbook/addresswidget.py create mode 100644 examples/widgets/itemviews/addressbook/newaddresstab.py create mode 100644 examples/widgets/itemviews/addressbook/tablemodel.py create mode 100644 examples/widgets/itemviews/basicsortfiltermodel.py create mode 100644 examples/widgets/itemviews/fetchmore.py create mode 100644 examples/widgets/itemviews/itemviews.pyproject create mode 100644 examples/widgets/itemviews/stardelegate/stardelegate.py create mode 100644 examples/widgets/itemviews/stardelegate/stardelegate.pyproject create mode 100644 examples/widgets/itemviews/stardelegate/stareditor.py create mode 100644 examples/widgets/itemviews/stardelegate/starrating.py create mode 100644 examples/widgets/layouts/basiclayouts.py create mode 100644 examples/widgets/layouts/dynamiclayouts.py create mode 100644 examples/widgets/layouts/flowlayout.py create mode 100644 examples/widgets/layouts/layouts.pyproject create mode 100644 examples/widgets/mainwindows/application/application.py create mode 100644 examples/widgets/mainwindows/application/application.pyproject create mode 100644 examples/widgets/mainwindows/application/application.qrc create mode 100644 examples/widgets/mainwindows/application/application_rc.py create mode 100644 examples/widgets/mainwindows/application/images/copy.png create mode 100644 examples/widgets/mainwindows/application/images/cut.png create mode 100644 examples/widgets/mainwindows/application/images/new.png create mode 100644 examples/widgets/mainwindows/application/images/open.png create mode 100644 examples/widgets/mainwindows/application/images/paste.png create mode 100644 examples/widgets/mainwindows/application/images/save.png create mode 100644 examples/widgets/mainwindows/dockwidgets/dockwidgets.py create mode 100644 examples/widgets/mainwindows/dockwidgets/dockwidgets.pyproject create mode 100644 examples/widgets/mainwindows/dockwidgets/dockwidgets.qrc create mode 100644 examples/widgets/mainwindows/dockwidgets/dockwidgets_rc.py create mode 100644 examples/widgets/mainwindows/dockwidgets/images/new.png create mode 100644 examples/widgets/mainwindows/dockwidgets/images/print.png create mode 100644 examples/widgets/mainwindows/dockwidgets/images/save.png create mode 100644 examples/widgets/mainwindows/dockwidgets/images/undo.png create mode 100644 examples/widgets/mainwindows/mdi/images/copy.png create mode 100644 examples/widgets/mainwindows/mdi/images/cut.png create mode 100644 examples/widgets/mainwindows/mdi/images/new.png create mode 100644 examples/widgets/mainwindows/mdi/images/open.png create mode 100644 examples/widgets/mainwindows/mdi/images/paste.png create mode 100644 examples/widgets/mainwindows/mdi/images/save.png create mode 100644 examples/widgets/mainwindows/mdi/mdi.py create mode 100644 examples/widgets/mainwindows/mdi/mdi.pyproject create mode 100644 examples/widgets/mainwindows/mdi/mdi.qrc create mode 100644 examples/widgets/mainwindows/mdi/mdi_rc.py create mode 100644 examples/widgets/painting/basicdrawing/basicdrawing.py create mode 100644 examples/widgets/painting/basicdrawing/basicdrawing.pyproject create mode 100644 examples/widgets/painting/basicdrawing/basicdrawing.qrc create mode 100644 examples/widgets/painting/basicdrawing/basicdrawing_rc.py create mode 100644 examples/widgets/painting/basicdrawing/images/brick.png create mode 100644 examples/widgets/painting/basicdrawing/images/qt-logo.png create mode 100644 examples/widgets/painting/concentriccircles.py create mode 100644 examples/widgets/painting/painting.pyproject create mode 100644 examples/widgets/richtext/orderform.py create mode 100644 examples/widgets/richtext/richtext.pyproject create mode 100644 examples/widgets/richtext/syntaxhighlighter.py create mode 100644 examples/widgets/richtext/syntaxhighlighter/examples/example create mode 100644 examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.py create mode 100644 examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pyproject create mode 100644 examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.qrc create mode 100644 examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter_rc.py create mode 100644 examples/widgets/richtext/textobject/files/heart.svg create mode 100644 examples/widgets/richtext/textobject/textobject.py create mode 100644 examples/widgets/richtext/textobject/textobject.pyproject create mode 100644 examples/widgets/state-machine/eventtrans.py create mode 100644 examples/widgets/state-machine/factstates.py create mode 100644 examples/widgets/state-machine/pingpong.py create mode 100644 examples/widgets/state-machine/rogue.py create mode 100644 examples/widgets/state-machine/state-machine.pyproject create mode 100644 examples/widgets/state-machine/trafficlight.py create mode 100644 examples/widgets/state-machine/twowaybutton.py create mode 100644 examples/widgets/systray/images/bad.png create mode 100644 examples/widgets/systray/images/heart.png create mode 100644 examples/widgets/systray/images/trash.png create mode 100644 examples/widgets/systray/main.py create mode 100644 examples/widgets/systray/rc_systray.py create mode 100644 examples/widgets/systray/systray.pyproject create mode 100644 examples/widgets/systray/systray.qrc create mode 100644 examples/widgets/systray/window.py create mode 100644 examples/widgets/threads/thread_signals.py create mode 100644 examples/widgets/tutorials/addressbook/addressbook.pyproject create mode 100644 examples/widgets/tutorials/addressbook/part1.py create mode 100644 examples/widgets/tutorials/addressbook/part2.py create mode 100644 examples/widgets/tutorials/addressbook/part3.py create mode 100644 examples/widgets/tutorials/addressbook/part4.py create mode 100644 examples/widgets/tutorials/addressbook/part5.py create mode 100644 examples/widgets/tutorials/addressbook/part6.py create mode 100644 examples/widgets/tutorials/addressbook/part7.py create mode 100644 examples/widgets/widgets/hellogl_openglwidget_legacy.py create mode 100644 examples/widgets/widgets/tetrix.py create mode 100644 examples/widgets/widgets/widgets.pyproject create mode 100644 examples/xml/dombookmarks/dombookmarks.py create mode 100644 examples/xml/dombookmarks/dombookmarks.pyproject create mode 100644 examples/xml/dombookmarks/frank.xbel create mode 100644 examples/xml/dombookmarks/jennifer.xbel create mode 100644 examples/xmlpatterns/schema/files/contact.xsd create mode 100644 examples/xmlpatterns/schema/files/invalid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_order.xml create mode 100644 examples/xmlpatterns/schema/files/invalid_recipe.xml create mode 100644 examples/xmlpatterns/schema/files/order.xsd create mode 100644 examples/xmlpatterns/schema/files/recipe.xsd create mode 100644 examples/xmlpatterns/schema/files/valid_contact.xml create mode 100644 examples/xmlpatterns/schema/files/valid_order.xml create mode 100644 examples/xmlpatterns/schema/files/valid_recipe.xml create mode 100644 examples/xmlpatterns/schema/schema.py create mode 100644 examples/xmlpatterns/schema/schema.pyproject create mode 100644 examples/xmlpatterns/schema/schema.qrc create mode 100644 examples/xmlpatterns/schema/schema.ui create mode 100644 examples/xmlpatterns/schema/schema_rc.py create mode 100644 examples/xmlpatterns/schema/ui_schema.py create mode 100644 ez_setup.py create mode 100644 header.BSD-OLD create mode 100644 keyword-errors.lst create mode 100644 product_dependencies.yaml create mode 100644 requirements.txt create mode 100644 setup.py create mode 100644 sources/cmake_helpers/helpers.cmake create mode 100644 sources/patchelf/COPYING create mode 100644 sources/patchelf/README create mode 100644 sources/patchelf/elf.h create mode 100644 sources/patchelf/patchelf.cc create mode 100644 sources/pyside2-tools/CMakeLists.txt create mode 100644 sources/pyside2-tools/LICENSE-lupdate create mode 100644 sources/pyside2-tools/LICENSE-rcc create mode 100644 sources/pyside2-tools/LICENSE-uic create mode 100644 sources/pyside2-tools/README.md create mode 100644 sources/pyside2-tools/cmake_uninstall.cmake create mode 100644 sources/pyside2-tools/pylupdate/CMakeLists.txt create mode 100644 sources/pyside2-tools/pylupdate/fetchtr.cpp create mode 100644 sources/pyside2-tools/pylupdate/main.cpp create mode 100644 sources/pyside2-tools/pylupdate/merge.cpp create mode 100644 sources/pyside2-tools/pylupdate/metatranslator.cpp create mode 100644 sources/pyside2-tools/pylupdate/metatranslator.h create mode 100644 sources/pyside2-tools/pylupdate/numberh.cpp create mode 100644 sources/pyside2-tools/pylupdate/proparser.cpp create mode 100644 sources/pyside2-tools/pylupdate/proparser.h create mode 100644 sources/pyside2-tools/pylupdate/pyside2-lupdate.1 create mode 100644 sources/pyside2-tools/pylupdate/sametexth.cpp create mode 100644 sources/pyside2-tools/pylupdate/simtexth.cpp create mode 100644 sources/pyside2-tools/pylupdate/simtexth.h create mode 100644 sources/pyside2-tools/pylupdate/translator.cpp create mode 100644 sources/pyside2-tools/pylupdate/translator.h create mode 100755 sources/pyside2-tools/pyside_tool.py create mode 100644 sources/pyside2-tools/qt_attribution.json create mode 100644 sources/pyside2-tools/tests/CMakeLists.txt create mode 100644 sources/pyside2-tools/tests/qwizard_test.ui create mode 100644 sources/pyside2-tools/tests/rcc/CMakeLists.txt create mode 100644 sources/pyside2-tools/tests/rcc/document-print-preview.png create mode 100644 sources/pyside2-tools/tests/rcc/example.qrc create mode 100644 sources/pyside2-tools/tests/rcc/image.qrc create mode 100644 sources/pyside2-tools/tests/rcc/manychars.txt create mode 100644 sources/pyside2-tools/tests/rcc/rcc_image_test.py create mode 100644 sources/pyside2-tools/tests/rcc/rcc_test.py create mode 100755 sources/pyside2-tools/tests/rcc/run_test.sh create mode 100644 sources/pyside2-tools/tests/rcc/shining.txt create mode 100644 sources/pyside2-tools/tests/rcc/words.txt create mode 100644 sources/pyside2/CMakeLists.txt create mode 100644 sources/pyside2/COPYING create mode 100644 sources/pyside2/PySide2/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml create mode 100644 sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml create mode 100644 sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml create mode 100644 sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml create mode 100644 sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml create mode 100644 sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml create mode 100644 sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtAxContainer/QtAxContainer_global.post.h.in create mode 100644 sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml create mode 100644 sources/pyside2/PySide2/QtCharts/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtCharts/typesystem_charts.xml create mode 100644 sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtConcurrent/curr_errors.txt create mode 100644 sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml create mode 100644 sources/pyside2/PySide2/QtCore/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp create mode 100644 sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.h create mode 100644 sources/pyside2/PySide2/QtCore/typesystem_core.xml.in create mode 100644 sources/pyside2/PySide2/QtCore/typesystem_core_common.xml create mode 100644 sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml create mode 100644 sources/pyside2/PySide2/QtCore/typesystem_core_win.xml create mode 100644 sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml create mode 100644 sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml create mode 100644 sources/pyside2/PySide2/QtGui/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtGui/QtGui_global.post.h.in create mode 100644 sources/pyside2/PySide2/QtGui/typesystem_gui.xml.in create mode 100644 sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml create mode 100644 sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml create mode 100644 sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml create mode 100644 sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml create mode 100644 sources/pyside2/PySide2/QtHelp/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtHelp/typesystem_help.xml create mode 100644 sources/pyside2/PySide2/QtLocation/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtLocation/typesystem_location.xml create mode 100644 sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml create mode 100644 sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml create mode 100644 sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml create mode 100644 sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml create mode 100644 sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml create mode 100644 sources/pyside2/PySide2/QtNetwork/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtNetwork/typesystem_network.xml create mode 100644 sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_2_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_3_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0_compat.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_1.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_0.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3a.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_0.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_1.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_3.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4_core.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5_core.xml create mode 100644 sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications_va.xml create mode 100644 sources/pyside2/PySide2/QtPositioning/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml create mode 100644 sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in create mode 100644 sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml create mode 100644 sources/pyside2/PySide2/QtQml/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp create mode 100644 sources/pyside2/PySide2/QtQml/pysideqmlregistertype.h create mode 100644 sources/pyside2/PySide2/QtQml/typesystem_qml.xml create mode 100644 sources/pyside2/PySide2/QtQuick/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp create mode 100644 sources/pyside2/PySide2/QtQuick/pysidequickregistertype.h create mode 100644 sources/pyside2/PySide2/QtQuick/typesystem_quick.xml create mode 100644 sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml create mode 100644 sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml create mode 100644 sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml create mode 100644 sources/pyside2/PySide2/QtScript/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtScript/qscript_value_iterator_glue.cpp create mode 100644 sources/pyside2/PySide2/QtScript/typesystem_script.xml create mode 100644 sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml create mode 100644 sources/pyside2/PySide2/QtScxml/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml create mode 100644 sources/pyside2/PySide2/QtSensors/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml create mode 100644 sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml create mode 100644 sources/pyside2/PySide2/QtSql/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtSql/QtSql_global.pre.h.in create mode 100644 sources/pyside2/PySide2/QtSql/typesystem_sql.xml create mode 100644 sources/pyside2/PySide2/QtSvg/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtSvg/typesystem_svg.xml create mode 100644 sources/pyside2/PySide2/QtTest/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtTest/QtTest_global.post.h.in create mode 100644 sources/pyside2/PySide2/QtTest/QtTest_global.pre.h.in create mode 100644 sources/pyside2/PySide2/QtTest/typesystem_test.xml create mode 100644 sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml create mode 100644 sources/pyside2/PySide2/QtUiTools/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtUiTools/glue/plugins.h create mode 100644 sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml create mode 100644 sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml create mode 100644 sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml create mode 100644 sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml create mode 100644 sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml create mode 100644 sources/pyside2/PySide2/QtWebKit/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml create mode 100644 sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml create mode 100644 sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml create mode 100644 sources/pyside2/PySide2/QtWidgets/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWidgets/typesystem_widgets.xml.in create mode 100644 sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml create mode 100644 sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml create mode 100644 sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml create mode 100644 sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml create mode 100644 sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtWinExtras/QtWinExtras_global.pre.h.in create mode 100644 sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml create mode 100644 sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtX11Extras/QtX11Extras_global.post.h.in create mode 100644 sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml create mode 100644 sources/pyside2/PySide2/QtXml/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtXml/typesystem_xml.xml create mode 100644 sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt create mode 100644 sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml create mode 100644 sources/pyside2/PySide2/__init__.py.in create mode 100644 sources/pyside2/PySide2/_config.py.in create mode 100644 sources/pyside2/PySide2/global.h.in create mode 100644 sources/pyside2/PySide2/glue/qtcharts.cpp create mode 100644 sources/pyside2/PySide2/glue/qtcore.cpp create mode 100644 sources/pyside2/PySide2/glue/qtdatavisualization.cpp create mode 100644 sources/pyside2/PySide2/glue/qtgui.cpp create mode 100644 sources/pyside2/PySide2/glue/qtmultimedia.cpp create mode 100644 sources/pyside2/PySide2/glue/qtnetwork.cpp create mode 100644 sources/pyside2/PySide2/glue/qtopengl.cpp create mode 100644 sources/pyside2/PySide2/glue/qtprintsupport.cpp create mode 100644 sources/pyside2/PySide2/glue/qtqml.cpp create mode 100644 sources/pyside2/PySide2/glue/qtquick.cpp create mode 100644 sources/pyside2/PySide2/glue/qtscript.cpp create mode 100644 sources/pyside2/PySide2/glue/qtuitools.cpp create mode 100644 sources/pyside2/PySide2/glue/qtwebenginewidgets.cpp create mode 100644 sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp create mode 100644 sources/pyside2/PySide2/glue/qtwidgets.cpp create mode 100644 sources/pyside2/PySide2/glue/qtxml.cpp create mode 100644 sources/pyside2/PySide2/glue/qtxmlpatterns.cpp create mode 100644 sources/pyside2/PySide2/licensecomment.txt create mode 100644 sources/pyside2/PySide2/py.typed.in create mode 100644 sources/pyside2/PySide2/pysideqtesttouch.h create mode 100644 sources/pyside2/PySide2/pysidewtypes.h create mode 100644 sources/pyside2/PySide2/qpytextobject.cpp create mode 100644 sources/pyside2/PySide2/qpytextobject.h create mode 100644 sources/pyside2/PySide2/qt.conf.in create mode 100644 sources/pyside2/PySide2/support/__init__.py create mode 100644 sources/pyside2/PySide2/support/deprecated.py create mode 100644 sources/pyside2/PySide2/support/generate_pyi.py create mode 100644 sources/pyside2/PySide2/templates/core_common.xml create mode 100644 sources/pyside2/PySide2/templates/datavisualization_common.xml create mode 100644 sources/pyside2/PySide2/templates/gui_common.xml create mode 100644 sources/pyside2/PySide2/templates/opengl_common.xml create mode 100644 sources/pyside2/PySide2/templates/openglfunctions_common.xml create mode 100644 sources/pyside2/PySide2/templates/webkitwidgets_common.xml create mode 100644 sources/pyside2/PySide2/templates/widgets_common.xml create mode 100644 sources/pyside2/PySide2/templates/xml_common.xml create mode 100644 sources/pyside2/cmake/Macros/FindQt5Extra.cmake create mode 100644 sources/pyside2/cmake/Macros/PySideModules.cmake create mode 100644 sources/pyside2/cmake/Macros/icecc.cmake create mode 100644 sources/pyside2/cmake_uninstall.cmake create mode 100644 sources/pyside2/doc/CMakeLists.txt create mode 100644 sources/pyside2/doc/_templates/layout.html create mode 100644 sources/pyside2/doc/_themes/pysidedocs/domainindex.html create mode 100644 sources/pyside2/doc/_themes/pysidedocs/searchbox.html create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/bg_header.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/bg_topo.jpg create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/fakebar.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/logo_python.jpg create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/logo_qt.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/minus.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/plus.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/pyside.css create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/static/relbar_bg.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs/theme.conf create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/domainindex.html create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/plus.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png create mode 100644 sources/pyside2/doc/_themes/pysidedocs_qthelp/theme.conf create mode 100644 sources/pyside2/doc/additionaldocs.lst create mode 100644 sources/pyside2/doc/api.rst create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/accessibilityslidersnippet.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/audio/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/qt-logo.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/renderarea.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/stylewidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qnamespace.qdoc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.gui.text.qtextdocumentwriter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingcall.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodecplugin.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuture.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturesynchronizer.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturewatcher.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentfilter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentrun.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qthreadpool.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdatastream.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdir.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdiriterator.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfile.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qiodevice.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qprocess.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qsettings.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtemporaryfile.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtextstream.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qurl.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qtimer.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_qlibrary.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_quuid.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_statemachine_qstatemachine.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qatomic.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutex.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutexpool.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qsemaphore.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qthread.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qwaitcondition_unix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbitarray.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qdatetime.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qhash.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlocale.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qmap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qpoint.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qqueue.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qrect.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qregexp.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qsize.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qstring.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qtimeline.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qvector.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qwizard.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsgridlayout.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicslinearlayout.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qbitmap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qicon.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimage.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagereader.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagewriter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qmovie.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemeditorfactory.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtablewidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qaction.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qclipboard.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qevent.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qformlayout.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayout.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayoutitem.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcut.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qsound.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qwidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qbrush.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qcolor.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qdrawutil.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qmatrix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainterpath.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpen.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion_unix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qtransform.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyle.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyleoption.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfont.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfontmetrics.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qsyntaxhighlighter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextcursor.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextlayout.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qcompleter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qundostack.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qvalidator.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractspinbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdatetimeedit.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qframe.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qgroupbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlabel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlineedit.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenu.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenubar.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qpushbutton.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qradiobutton.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qrubberband.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qspinbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplashscreen.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplitter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qstatusbar.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextbrowser.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextedit.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qworkspace.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qftp.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qhttp.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkrequest.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostaddress.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qabstractsocket.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qtcpserver.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qudpsocket.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslconfiguration.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qgl.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglcolormap.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_qtestlib_qtestcase.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptable.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptclass.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptcontext.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengine.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengineagent.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalue.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalueiterator.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlerror.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlindex.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlquery.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlresult.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_dom_qdom.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_sax_qxml.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_qextensionmanager.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformeditor.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowcursor.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowmanager.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractobjectinspector.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_patternist_qapplicationargumentparser.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/console/dbus_pingpong.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/customstyle/customstyle.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/imagedialog/imagedialog.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/modules.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtcore.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtgui.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtnetwork.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtopengl.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtsql.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtxml.html create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/titles.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/dockwidgets.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/dragwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images/file.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dropactions/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/droprectangle/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/eventfilters/filterobject.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/explicitlysharedemployee/employee.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.ts create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/resources.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_en.ts create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_fr.ts create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/image/image.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/image/supportedformat.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/inherited-slot/button.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/itemselection/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass1.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass2.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass3.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/view.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/myscrollarea.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/ntfsp.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyHTMLElement.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyXLinkAttribute.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncluded.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncludedResult.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmitted.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmittedResult.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/computedTreeFragment.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyAttribute.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyID.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/directTreeFragment.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/doc.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML2.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML2.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/emptyParagraphs.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeCurlyBraces.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/expressionInsideAttribute.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnPath.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnStep.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/firstParagraph.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/fnStringOnAttribute.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause2.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClauseOnFeed.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/indented.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introAcneRemover.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introExample2.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introFileHierarchy.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introNavigateFS.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introductionExample.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/invalidLetOrderBy.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/items.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/letOrderBy.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/literalsAndOperators.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/mobeyDick.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nextLastParagraph.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsInPaths.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeTestChildElement.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/notIndented.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/oneElementConstructor.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsWithTables.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathAB.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathsAllParagraphs.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleHTML.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleXHTML.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/svgDocumentElement.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/tablesInParagraphs.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/twoSVGElements.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xmlStylesheet.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsBooleanTrue.xq create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsvgDocumentElement.xml create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/plaintextlayout/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/porting4-dropevents/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/errors.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/object.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qabstractsliderisnippet.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-listfiles/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-namefilters/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlineargradient/paintwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-dnd/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-using/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmacnativewidget/main.mm create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/delegate.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/paintwidget_unix.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/view.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qmetaobject-invokable/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qquickview-ex.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/buttonwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/qsplashscreen.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/splash.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qstatustipevent/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qstyleoption/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/qsvgwidget.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/spheres.svg create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/sunflower.svg create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/cubed.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/squared.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/images.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-resizing/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/cubed.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/squared.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/images.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtcast/qtcast.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/dragdropmodel.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treeitem.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treemodel.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/registeringobjects/myobject.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/object.js create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/scriptedslot.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/myform.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qx11embedwidget/embedwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlschemavalidator/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/separations/finalwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/separations/screenwidget.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/separations/viewer.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/sharedemployee/employee.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/sharedtablemodel/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/accountsfile.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/filereader.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/reportfile.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/taxfile.txt create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/lcdnumber.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/signalsandslots.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/simpleparse/handler.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/styles/styles.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/stylesheet/common-mistakes.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/xmlwriter.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/xmlwriter.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/xmlwriter.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imagedrop/textedit.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images/advert.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images/newimage.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images/advert.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-listitems/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-lists/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-printing/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-selections/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/xmlwriter.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/threads/threads.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/timers/timers.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/uitools/calculatorform/calculatorform.ui create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/model.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/window.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/mask.qrc create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/tux.png create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/widgetdelegate.cpp create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/handler.h create mode 100644 sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/rsslisting.h create mode 100755 sources/pyside2/doc/codesnippets/examples/dbus/example-client.py create mode 100755 sources/pyside2/doc/codesnippets/examples/dbus/example-server.py create mode 100644 sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugin.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugins.qml create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.qrc create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/background.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/banner.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo1.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo2.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo3.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/watermark1.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/watermark2.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/extension/finddialog.py create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/images/logo.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/images/watermark.png create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/licensewizard.h create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/licensewizard.qrc create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/dialogs/tabdialog/tabdialog.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/graphicsview/simpleanchorlayout/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider-example.qml create mode 100644 sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/itemviews/pixelator/pixeldelegate.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py create mode 100644 sources/pyside2/doc/codesnippets/examples/mainwindows/sdi/mainwindow.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/quick/plugins/plugins.qml create mode 100644 sources/pyside2/doc/codesnippets/examples/relationaltablemodel/relationaltablemodel.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/richtext/textobject/svgtextobject.h create mode 100644 sources/pyside2/doc/codesnippets/examples/widgets/groupbox/window.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp create mode 100644 sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py create mode 100644 sources/pyside2/doc/codesnippets/examples/xml/streambookmarks/xbelreader.h create mode 100644 sources/pyside2/doc/codesnippets/snippets/customstyle/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp create mode 100644 sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebview_snippet.cpp create mode 100644 sources/pyside2/doc/codesnippets/webkitsnippets/simple/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/webkitsnippets/webelement/main.cpp create mode 100644 sources/pyside2/doc/codesnippets/webkitsnippets/webpage/main.cpp create mode 100644 sources/pyside2/doc/conf.py.in create mode 100644 sources/pyside2/doc/considerations.rst create mode 100644 sources/pyside2/doc/contents.rst create mode 100644 sources/pyside2/doc/deployment-briefcase.rst create mode 100644 sources/pyside2/doc/deployment-cxfreeze.rst create mode 100644 sources/pyside2/doc/deployment-fbs.rst create mode 100644 sources/pyside2/doc/deployment-pyinstaller.rst create mode 100644 sources/pyside2/doc/deployment.rst create mode 100644 sources/pyside2/doc/examples/images/tabbedbrowser.png create mode 100644 sources/pyside2/doc/examples/index.rst create mode 100644 sources/pyside2/doc/examples/tabbedbrowser.rst create mode 100644 sources/pyside2/doc/extras/QtCore.ClassInfo.rst create mode 100644 sources/pyside2/doc/extras/QtCore.Property.rst create mode 100644 sources/pyside2/doc/extras/QtCore.QEnum.rst create mode 100644 sources/pyside2/doc/extras/QtCore.Signal.rst create mode 100644 sources/pyside2/doc/extras/QtCore.Slot.rst create mode 100644 sources/pyside2/doc/extras/QtCore.rst create mode 100644 sources/pyside2/doc/extras/QtGui.rst create mode 100644 sources/pyside2/doc/extras/QtHelp.rst create mode 100644 sources/pyside2/doc/extras/QtMultimedia.rst create mode 100644 sources/pyside2/doc/extras/QtNetwork.rst create mode 100644 sources/pyside2/doc/extras/QtOpenGL.rst create mode 100644 sources/pyside2/doc/extras/QtScript.rst create mode 100644 sources/pyside2/doc/extras/QtScriptTools.rst create mode 100644 sources/pyside2/doc/extras/QtSql.rst create mode 100644 sources/pyside2/doc/extras/QtSvg.rst create mode 100644 sources/pyside2/doc/extras/QtTest.rst create mode 100644 sources/pyside2/doc/extras/QtUiTools.loadUiType.rst create mode 100644 sources/pyside2/doc/extras/QtUiTools.rst create mode 100644 sources/pyside2/doc/extras/QtWebKit.rst create mode 100644 sources/pyside2/doc/extras/QtXml.rst create mode 100644 sources/pyside2/doc/extras/QtXmlPatterns.rst create mode 100644 sources/pyside2/doc/faq.rst create mode 100644 sources/pyside2/doc/gettingstarted-linux.rst create mode 100644 sources/pyside2/doc/gettingstarted-macOS.rst create mode 100644 sources/pyside2/doc/gettingstarted-windows.rst create mode 100644 sources/pyside2/doc/gettingstarted.rst create mode 100644 sources/pyside2/doc/index.rst create mode 100644 sources/pyside2/doc/inheritance_diagram.py create mode 100644 sources/pyside2/doc/modules.rst create mode 100644 sources/pyside2/doc/pyside-config.qdocconf.in create mode 100644 sources/pyside2/doc/pyside-examples/examples.qdoc create mode 100644 sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png create mode 100644 sources/pyside2/doc/pyside-examples/images/pyside2example-stardelegate.png create mode 100644 sources/pyside2/doc/pyside-examples/images/screenshot_hello.png create mode 100644 sources/pyside2/doc/pyside-examples/pyside2-classwizard.qdoc create mode 100644 sources/pyside2/doc/pyside-examples/pyside2-stardelegate.qdoc create mode 100644 sources/pyside2/doc/pysideinclude.py create mode 100644 sources/pyside2/doc/qtattributionsscannertorst.py create mode 100644 sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qt3dextras.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtcharts.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtconcurrent.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtcore.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtgui.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qthelp.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtlocation.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtmacextras.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtnetwork.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtopengl.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtpositioning.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtprintsupport.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtqml.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtscxml.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtsensors.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtsql.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtsvg.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qttest.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qttexttospeech.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtuitools.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtwebchannel.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtwebsockets.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtwidgets.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtwinextras.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtx11extras.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtxml.qdocconf.in create mode 100644 sources/pyside2/doc/qtmodules/pyside-qtxmlpatterns.qdocconf.in create mode 100644 sources/pyside2/doc/quickstart.rst create mode 100644 sources/pyside2/doc/src/README.md create mode 100644 sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/dialog.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons/forward.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons/pause.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons/play.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons/previous.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/icons/stop.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/player-new.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/player.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/qml.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/qrcfiles.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/style.qss create mode 100644 sources/pyside2/doc/tutorials/basictutorial/uifiles.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgets.rst create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-no.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling-yes.png create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py create mode 100644 sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/add_chart.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/all_hour.csv create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py create mode 100644 sources/pyside2/doc/tutorials/datavisualize/filter_data.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png create mode 100644 sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png create mode 100644 sources/pyside2/doc/tutorials/datavisualize/index.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst create mode 100644 sources/pyside2/doc/tutorials/datavisualize/read_data.rst create mode 100644 sources/pyside2/doc/tutorials/expenses/expenses.rst create mode 100644 sources/pyside2/doc/tutorials/expenses/expenses_tool.png create mode 100644 sources/pyside2/doc/tutorials/expenses/main.py create mode 100644 sources/pyside2/doc/tutorials/expenses/main_snake_prop.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/01-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/02-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/03-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/04-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/05-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/06-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/07-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/08-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/09-expenses.py create mode 100644 sources/pyside2/doc/tutorials/expenses/steps/10-expenses.py create mode 100644 sources/pyside2/doc/tutorials/index.rst create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter1/chapter1.rst create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter1/createdb.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter1/images/chapter1_books.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter1/main.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter2/main.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate-old.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/images/star.png create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/main-old.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/chapter3/main.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/hello_world_ex.py create mode 100644 sources/pyside2/doc/tutorials/portingguide/index.rst create mode 100644 sources/pyside2/doc/tutorials/qmlapp/logo.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/main.py create mode 100644 sources/pyside2/doc/tutorials/qmlapp/newpyproject.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/projectsmode.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/pyprojname.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/pyprojxplor.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/qmlapplication.png create mode 100644 sources/pyside2/doc/tutorials/qmlapp/qmlapplication.rst create mode 100644 sources/pyside2/doc/tutorials/qmlapp/view.qml create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/main.py create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/style.qrc create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/textproperties_material.png create mode 100644 sources/pyside2/doc/tutorials/qmlintegration/view.qml create mode 100644 sources/pyside2/doc/tutorials/qmlsqlintegration/chat.qml create mode 100644 sources/pyside2/doc/tutorials/qmlsqlintegration/example_list_view.png create mode 100644 sources/pyside2/doc/tutorials/qmlsqlintegration/main.py create mode 100644 sources/pyside2/doc/tutorials/qmlsqlintegration/qmlsqlintegration.rst create mode 100644 sources/pyside2/doc/tutorials/qmlsqlintegration/sqlDialog.py create mode 100644 sources/pyside2/doc/typesystem_doc.xml.in create mode 100644 sources/pyside2/doc/videos.rst create mode 100644 sources/pyside2/libpyside/CMakeLists.txt create mode 100644 sources/pyside2/libpyside/PySide2Config-spec.cmake.in create mode 100644 sources/pyside2/libpyside/PySide2Config.cmake.in create mode 100644 sources/pyside2/libpyside/PySide2ConfigVersion.cmake.in create mode 100644 sources/pyside2/libpyside/dynamicqmetaobject.cpp create mode 100644 sources/pyside2/libpyside/dynamicqmetaobject.h create mode 100644 sources/pyside2/libpyside/dynamicqmetaobject_p.h create mode 100644 sources/pyside2/libpyside/feature_select.cpp create mode 100644 sources/pyside2/libpyside/feature_select.h create mode 100644 sources/pyside2/libpyside/globalreceiverv2.cpp create mode 100644 sources/pyside2/libpyside/globalreceiverv2.h create mode 100644 sources/pyside2/libpyside/pyside.cpp create mode 100644 sources/pyside2/libpyside/pyside.h create mode 100644 sources/pyside2/libpyside/pyside2.pc.in create mode 100644 sources/pyside2/libpyside/pyside_p.h create mode 100644 sources/pyside2/libpyside/pysideclassinfo.cpp create mode 100644 sources/pyside2/libpyside/pysideclassinfo.h create mode 100644 sources/pyside2/libpyside/pysideclassinfo_p.h create mode 100644 sources/pyside2/libpyside/pysidemacros.h create mode 100644 sources/pyside2/libpyside/pysidemetafunction.cpp create mode 100644 sources/pyside2/libpyside/pysidemetafunction.h create mode 100644 sources/pyside2/libpyside/pysidemetafunction_p.h create mode 100644 sources/pyside2/libpyside/pysideproperty.cpp create mode 100644 sources/pyside2/libpyside/pysideproperty.h create mode 100644 sources/pyside2/libpyside/pysideproperty_p.h create mode 100644 sources/pyside2/libpyside/pysideqenum.cpp create mode 100644 sources/pyside2/libpyside/pysideqenum.h create mode 100644 sources/pyside2/libpyside/pysideqflags.cpp create mode 100644 sources/pyside2/libpyside/pysideqflags.h create mode 100644 sources/pyside2/libpyside/pysidesignal.cpp create mode 100644 sources/pyside2/libpyside/pysidesignal.h create mode 100644 sources/pyside2/libpyside/pysidesignal_p.h create mode 100644 sources/pyside2/libpyside/pysideslot.cpp create mode 100644 sources/pyside2/libpyside/pysideslot_p.h create mode 100644 sources/pyside2/libpyside/pysidestaticstrings.cpp create mode 100644 sources/pyside2/libpyside/pysidestaticstrings.h create mode 100644 sources/pyside2/libpyside/pysideweakref.cpp create mode 100644 sources/pyside2/libpyside/pysideweakref.h create mode 100644 sources/pyside2/libpyside/signalmanager.cpp create mode 100644 sources/pyside2/libpyside/signalmanager.h create mode 100644 sources/pyside2/plugins/CMakeLists.txt create mode 100644 sources/pyside2/plugins/customwidget.cpp create mode 100644 sources/pyside2/plugins/customwidget.h create mode 100644 sources/pyside2/plugins/customwidgets.cpp create mode 100644 sources/pyside2/plugins/customwidgets.h create mode 100644 sources/pyside2/pyside_version.py create mode 100644 sources/pyside2/tests/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DAnimation/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DCore/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DExtras/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DExtras/qt3dextras_test.py create mode 100644 sources/pyside2/tests/Qt3DInput/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DLogic/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DQuick/CMakeLists.txt create mode 100644 sources/pyside2/tests/Qt3DRender/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtAxContainer/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtCharts/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtCharts/qcharts_test.py create mode 100644 sources/pyside2/tests/QtConcurrent/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtCore/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtCore/attr_cache_py3k.py create mode 100644 sources/pyside2/tests/QtCore/blocking_signals_test.py create mode 100644 sources/pyside2/tests/QtCore/bug_1019.py create mode 100644 sources/pyside2/tests/QtCore/bug_1031.py create mode 100644 sources/pyside2/tests/QtCore/bug_1063.py create mode 100644 sources/pyside2/tests/QtCore/bug_1069.py create mode 100644 sources/pyside2/tests/QtCore/bug_1313.py create mode 100644 sources/pyside2/tests/QtCore/bug_278_test.py create mode 100644 sources/pyside2/tests/QtCore/bug_332.py create mode 100644 sources/pyside2/tests/QtCore/bug_408.py create mode 100644 sources/pyside2/tests/QtCore/bug_428.py create mode 100644 sources/pyside2/tests/QtCore/bug_462.py create mode 100644 sources/pyside2/tests/QtCore/bug_505.py create mode 100644 sources/pyside2/tests/QtCore/bug_515.py create mode 100644 sources/pyside2/tests/QtCore/bug_606.py create mode 100644 sources/pyside2/tests/QtCore/bug_656.py create mode 100644 sources/pyside2/tests/QtCore/bug_686.py create mode 100644 sources/pyside2/tests/QtCore/bug_699.py create mode 100644 sources/pyside2/tests/QtCore/bug_706.py create mode 100644 sources/pyside2/tests/QtCore/bug_820.py create mode 100644 sources/pyside2/tests/QtCore/bug_826.py create mode 100644 sources/pyside2/tests/QtCore/bug_829.py create mode 100644 sources/pyside2/tests/QtCore/bug_835.py create mode 100644 sources/pyside2/tests/QtCore/bug_920.py create mode 100644 sources/pyside2/tests/QtCore/bug_927.py create mode 100644 sources/pyside2/tests/QtCore/bug_931.py create mode 100644 sources/pyside2/tests/QtCore/bug_938.py create mode 100644 sources/pyside2/tests/QtCore/bug_953.py create mode 100644 sources/pyside2/tests/QtCore/bug_987.py create mode 100644 sources/pyside2/tests/QtCore/bug_994.py create mode 100644 sources/pyside2/tests/QtCore/bug_PYSIDE-164.py create mode 100644 sources/pyside2/tests/QtCore/bug_PYSIDE-42.py create mode 100644 sources/pyside2/tests/QtCore/child_event_test.py create mode 100644 sources/pyside2/tests/QtCore/classinfo_test.py create mode 100644 sources/pyside2/tests/QtCore/deepcopy_test.py create mode 100644 sources/pyside2/tests/QtCore/deletelater_test.py create mode 100644 sources/pyside2/tests/QtCore/destroysignal_test.py create mode 100644 sources/pyside2/tests/QtCore/duck_punching_test.py create mode 100644 sources/pyside2/tests/QtCore/emoji_string_test.py create mode 100644 sources/pyside2/tests/QtCore/hash_test.py create mode 100644 sources/pyside2/tests/QtCore/inherits_test.py create mode 100644 sources/pyside2/tests/QtCore/max_signals.py create mode 100644 sources/pyside2/tests/QtCore/missing_symbols_test.py create mode 100644 sources/pyside2/tests/QtCore/mockclass_test.py create mode 100644 sources/pyside2/tests/QtCore/multiple_feature_test.py create mode 100644 sources/pyside2/tests/QtCore/python_conversion.py create mode 100644 sources/pyside2/tests/QtCore/qabs_test.py create mode 100644 sources/pyside2/tests/QtCore/qabstractitemmodel_test.py create mode 100644 sources/pyside2/tests/QtCore/qabstracttransition_test.py create mode 100644 sources/pyside2/tests/QtCore/qanimationgroup_test.py create mode 100644 sources/pyside2/tests/QtCore/qbitarray_test.py create mode 100644 sources/pyside2/tests/QtCore/qbytearray_buffer_protocol_test.py create mode 100644 sources/pyside2/tests/QtCore/qbytearray_concatenation_operator_test.py create mode 100644 sources/pyside2/tests/QtCore/qbytearray_operator_iadd_test.py create mode 100644 sources/pyside2/tests/QtCore/qbytearray_operator_test.py create mode 100644 sources/pyside2/tests/QtCore/qbytearray_test.py create mode 100644 sources/pyside2/tests/QtCore/qcalendar_test.py create mode 100644 sources/pyside2/tests/QtCore/qcbor_test.py create mode 100644 sources/pyside2/tests/QtCore/qcollator_test.py create mode 100644 sources/pyside2/tests/QtCore/qcommandlineparser_test.py create mode 100644 sources/pyside2/tests/QtCore/qcoreapplication_instance_test.py create mode 100644 sources/pyside2/tests/QtCore/qcoreapplication_test.py create mode 100644 sources/pyside2/tests/QtCore/qdatastream_test.py create mode 100644 sources/pyside2/tests/QtCore/qdate_test.py create mode 100644 sources/pyside2/tests/QtCore/qdatetime_test.py create mode 100644 sources/pyside2/tests/QtCore/qeasingcurve_test.py create mode 100644 sources/pyside2/tests/QtCore/qenum_test.py create mode 100644 sources/pyside2/tests/QtCore/qevent_test.py create mode 100644 sources/pyside2/tests/QtCore/qfile_test.py create mode 100644 sources/pyside2/tests/QtCore/qfileinfo_test.py create mode 100644 sources/pyside2/tests/QtCore/qfileread_test.py create mode 100644 sources/pyside2/tests/QtCore/qflags_test.py create mode 100644 sources/pyside2/tests/QtCore/qhandle_test.py create mode 100644 sources/pyside2/tests/QtCore/qinstallmsghandler_test.py create mode 100644 sources/pyside2/tests/QtCore/qjsondocument_test.py create mode 100644 sources/pyside2/tests/QtCore/qlinef_test.py create mode 100644 sources/pyside2/tests/QtCore/qlocale_test.py create mode 100644 sources/pyside2/tests/QtCore/qlockfile_test.py create mode 100644 sources/pyside2/tests/QtCore/qmessageauthenticationcode_test.py create mode 100644 sources/pyside2/tests/QtCore/qmetaobject_test.py create mode 100644 sources/pyside2/tests/QtCore/qmimedatabase_test.py create mode 100644 sources/pyside2/tests/QtCore/qmodelindex_internalpointer_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_children_segfault_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_connect_notify_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_destructor.py create mode 100644 sources/pyside2/tests/QtCore/qobject_event_filter_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_inherits_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_objectproperty_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_parent_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_property_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_protected_methods_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_timer_event_test.py create mode 100644 sources/pyside2/tests/QtCore/qobject_tr_as_instance_test.py create mode 100644 sources/pyside2/tests/QtCore/qoperatingsystemversion_test.py create mode 100644 sources/pyside2/tests/QtCore/qpoint_test.py create mode 100644 sources/pyside2/tests/QtCore/qprocess_test.py create mode 100644 sources/pyside2/tests/QtCore/qproperty_decorator.py create mode 100644 sources/pyside2/tests/QtCore/qrandomgenerator_test.py create mode 100644 sources/pyside2/tests/QtCore/qrect_test.py create mode 100644 sources/pyside2/tests/QtCore/qregexp_test.py create mode 100644 sources/pyside2/tests/QtCore/qregularexpression_test.py create mode 100644 sources/pyside2/tests/QtCore/qresource_test.py create mode 100644 sources/pyside2/tests/QtCore/qsettings_test.ini create mode 100644 sources/pyside2/tests/QtCore/qsettings_test.py create mode 100644 sources/pyside2/tests/QtCore/qsize_test.py create mode 100644 sources/pyside2/tests/QtCore/qslot_object_test.py create mode 100644 sources/pyside2/tests/QtCore/qsocketnotifier_test.py create mode 100644 sources/pyside2/tests/QtCore/qsrand_test.py create mode 100644 sources/pyside2/tests/QtCore/qstandardpaths_test.py create mode 100644 sources/pyside2/tests/QtCore/qstate_test.py create mode 100644 sources/pyside2/tests/QtCore/qstatemachine_test.py create mode 100644 sources/pyside2/tests/QtCore/qstorageinfo_test.py create mode 100644 sources/pyside2/tests/QtCore/qstring_test.py create mode 100644 sources/pyside2/tests/QtCore/qsysinfo_test.py create mode 100644 sources/pyside2/tests/QtCore/qtext_codec_test.py create mode 100644 sources/pyside2/tests/QtCore/qtextstream_test.py create mode 100644 sources/pyside2/tests/QtCore/qthread_prod_cons_test.py create mode 100644 sources/pyside2/tests/QtCore/qthread_signal_test.py create mode 100644 sources/pyside2/tests/QtCore/qthread_test.py create mode 100644 sources/pyside2/tests/QtCore/qtimer_singleshot_test.py create mode 100644 sources/pyside2/tests/QtCore/qtimer_timeout_test.py create mode 100644 sources/pyside2/tests/QtCore/qtimezone_test.py create mode 100644 sources/pyside2/tests/QtCore/qtnamespace_test.py create mode 100644 sources/pyside2/tests/QtCore/quoteEnUS.txt create mode 100644 sources/pyside2/tests/QtCore/qurl_test.py create mode 100644 sources/pyside2/tests/QtCore/qurlquery_test.py create mode 100644 sources/pyside2/tests/QtCore/quuid_test.py create mode 100644 sources/pyside2/tests/QtCore/qversionnumber_test.py create mode 100644 sources/pyside2/tests/QtCore/repr_test.py create mode 100644 sources/pyside2/tests/QtCore/resources.qrc create mode 100644 sources/pyside2/tests/QtCore/resources_mc.py create mode 100644 sources/pyside2/tests/QtCore/sample.png create mode 100644 sources/pyside2/tests/QtCore/setprop_on_ctor_test.py create mode 100644 sources/pyside2/tests/QtCore/snake_prop_feature_test.py create mode 100644 sources/pyside2/tests/QtCore/staticMetaObject_test.py create mode 100644 sources/pyside2/tests/QtCore/static_method_test.py create mode 100644 sources/pyside2/tests/QtCore/thread_signals_test.py create mode 100644 sources/pyside2/tests/QtCore/tr_noop_test.py create mode 100644 sources/pyside2/tests/QtCore/translation_test.py create mode 100644 sources/pyside2/tests/QtCore/translations/trans_latin.qm create mode 100644 sources/pyside2/tests/QtCore/translations/trans_latin.ts create mode 100644 sources/pyside2/tests/QtCore/translations/trans_russian.qm create mode 100644 sources/pyside2/tests/QtCore/translations/trans_russian.ts create mode 100644 sources/pyside2/tests/QtCore/unaryoperator_test.py create mode 100644 sources/pyside2/tests/QtCore/unicode_test.py create mode 100644 sources/pyside2/tests/QtCore/versioninfo_test.py create mode 100644 sources/pyside2/tests/QtDataVisualization/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtDataVisualization/datavisualization_test.py create mode 100644 sources/pyside2/tests/QtDesigner/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtGui/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtGui/bug_1091.py create mode 100644 sources/pyside2/tests/QtGui/bug_300_test.py create mode 100644 sources/pyside2/tests/QtGui/bug_367.py create mode 100644 sources/pyside2/tests/QtGui/bug_480.py create mode 100644 sources/pyside2/tests/QtGui/bug_606.py create mode 100644 sources/pyside2/tests/QtGui/bug_617.py create mode 100644 sources/pyside2/tests/QtGui/bug_652.py create mode 100644 sources/pyside2/tests/QtGui/bug_660.py create mode 100644 sources/pyside2/tests/QtGui/bug_716.py create mode 100644 sources/pyside2/tests/QtGui/bug_740.py create mode 100644 sources/pyside2/tests/QtGui/bug_743.py create mode 100644 sources/pyside2/tests/QtGui/bug_991.py create mode 100644 sources/pyside2/tests/QtGui/bug_PYSIDE-344.py create mode 100644 sources/pyside2/tests/QtGui/bug_PYSIDE-41.py create mode 100644 sources/pyside2/tests/QtGui/deepcopy_test.py create mode 100644 sources/pyside2/tests/QtGui/float_to_int_implicit_conversion_test.py create mode 100644 sources/pyside2/tests/QtGui/pyside_reload_test.py create mode 100644 sources/pyside2/tests/QtGui/qcolor_reduce_test.py create mode 100644 sources/pyside2/tests/QtGui/qcolor_test.py create mode 100644 sources/pyside2/tests/QtGui/qcursor_test.py create mode 100644 sources/pyside2/tests/QtGui/qdatastream_gui_operators_test.py create mode 100644 sources/pyside2/tests/QtGui/qdesktopservices_test.py create mode 100644 sources/pyside2/tests/QtGui/qfontmetrics_test.py create mode 100644 sources/pyside2/tests/QtGui/qguiapplication_test.py create mode 100644 sources/pyside2/tests/QtGui/qicon_test.py create mode 100644 sources/pyside2/tests/QtGui/qitemselection_test.py create mode 100644 sources/pyside2/tests/QtGui/qkeysequence_test.py create mode 100644 sources/pyside2/tests/QtGui/qmatrix_test.py create mode 100644 sources/pyside2/tests/QtGui/qopenglbuffer_test.py create mode 100644 sources/pyside2/tests/QtGui/qopenglwindow_test.py create mode 100644 sources/pyside2/tests/QtGui/qpainter_test.py create mode 100644 sources/pyside2/tests/QtGui/qpdfwriter_test.py create mode 100644 sources/pyside2/tests/QtGui/qpixelformat_test.py create mode 100644 sources/pyside2/tests/QtGui/qpixmap_test.py create mode 100644 sources/pyside2/tests/QtGui/qpixmapcache_test.py create mode 100644 sources/pyside2/tests/QtGui/qpolygonf_test.py create mode 100644 sources/pyside2/tests/QtGui/qradialgradient_test.py create mode 100644 sources/pyside2/tests/QtGui/qrasterwindow_test.py create mode 100644 sources/pyside2/tests/QtGui/qregion_test.py create mode 100644 sources/pyside2/tests/QtGui/qstylehints_test.py create mode 100644 sources/pyside2/tests/QtGui/qtextdocument_functions.py create mode 100644 sources/pyside2/tests/QtGui/qtextdocument_undoredo_test.py create mode 100644 sources/pyside2/tests/QtGui/qtextdocumentwriter_test.py create mode 100644 sources/pyside2/tests/QtGui/qtextline_test.py create mode 100644 sources/pyside2/tests/QtGui/qtransform_test.py create mode 100644 sources/pyside2/tests/QtGui/repr_test.py create mode 100644 sources/pyside2/tests/QtGui/sample.png create mode 100644 sources/pyside2/tests/QtGui/timed_app_and_patching_test.py create mode 100644 sources/pyside2/tests/QtHelp/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtHelp/help_test.py create mode 100644 sources/pyside2/tests/QtHelp/helpsearchengine_test.py create mode 100644 sources/pyside2/tests/QtLocation/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtLocation/location.py create mode 100644 sources/pyside2/tests/QtMacExtras/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtMultimedia/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtMultimedia/audio_test.py create mode 100644 sources/pyside2/tests/QtMultimediaWidgets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtMultimediaWidgets/qmultimediawidgets.py create mode 100644 sources/pyside2/tests/QtNetwork/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtNetwork/accessManager_test.py create mode 100644 sources/pyside2/tests/QtNetwork/bug_1084.py create mode 100644 sources/pyside2/tests/QtNetwork/bug_446.py create mode 100644 sources/pyside2/tests/QtNetwork/dnslookup_test.py create mode 100644 sources/pyside2/tests/QtNetwork/qipv6address_test.py create mode 100644 sources/pyside2/tests/QtNetwork/qpassworddigestor_test.py create mode 100644 sources/pyside2/tests/QtNetwork/tcpserver_test.py create mode 100644 sources/pyside2/tests/QtNetwork/udpsocket_test.py create mode 100644 sources/pyside2/tests/QtOpenGL/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtOpenGL/qglbuffer_test.py create mode 100644 sources/pyside2/tests/QtOpenGL/qglwidget_test.py create mode 100644 sources/pyside2/tests/QtOpenGLFunctions/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtPositioning/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtPositioning/positioning.py create mode 100644 sources/pyside2/tests/QtPrintSupport/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtPrintSupport/bug_500.py create mode 100644 sources/pyside2/tests/QtPrintSupport/returnquadruplesofnumbers_test.py create mode 100644 sources/pyside2/tests/QtQml/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtQml/bug_1029.py create mode 100644 sources/pyside2/tests/QtQml/bug_1029.qml create mode 100644 sources/pyside2/tests/QtQml/bug_451.py create mode 100644 sources/pyside2/tests/QtQml/bug_451.qml create mode 100644 sources/pyside2/tests/QtQml/bug_456.py create mode 100644 sources/pyside2/tests/QtQml/bug_456.qml create mode 100644 sources/pyside2/tests/QtQml/bug_557.py create mode 100644 sources/pyside2/tests/QtQml/bug_726.py create mode 100644 sources/pyside2/tests/QtQml/bug_726.qml create mode 100644 sources/pyside2/tests/QtQml/bug_814.py create mode 100644 sources/pyside2/tests/QtQml/bug_814.qml create mode 100644 sources/pyside2/tests/QtQml/bug_825.py create mode 100644 sources/pyside2/tests/QtQml/bug_825.qml create mode 100644 sources/pyside2/tests/QtQml/bug_847.py create mode 100644 sources/pyside2/tests/QtQml/bug_847.qml create mode 100644 sources/pyside2/tests/QtQml/bug_915.py create mode 100644 sources/pyside2/tests/QtQml/bug_926.py create mode 100644 sources/pyside2/tests/QtQml/bug_926.qml create mode 100644 sources/pyside2/tests/QtQml/bug_951.py create mode 100644 sources/pyside2/tests/QtQml/bug_951.qml create mode 100644 sources/pyside2/tests/QtQml/bug_995.py create mode 100644 sources/pyside2/tests/QtQml/bug_995.qml create mode 100644 sources/pyside2/tests/QtQml/bug_997.py create mode 100644 sources/pyside2/tests/QtQml/bug_997.qml create mode 100644 sources/pyside2/tests/QtQml/connect_python_qml.py create mode 100644 sources/pyside2/tests/QtQml/connect_python_qml.qml create mode 100644 sources/pyside2/tests/QtQml/hw.qml create mode 100644 sources/pyside2/tests/QtQml/javascript_exceptions.py create mode 100644 sources/pyside2/tests/QtQml/javascript_exceptions.qml create mode 100644 sources/pyside2/tests/QtQml/qqmlincubator_incubateWhile.py create mode 100644 sources/pyside2/tests/QtQml/qqmlincubator_incubateWhile.qml create mode 100644 sources/pyside2/tests/QtQml/qqmlincubator_incubateWhile_component.qml create mode 100644 sources/pyside2/tests/QtQml/qqmlnetwork_test.py create mode 100644 sources/pyside2/tests/QtQml/qquickitem_grabToImage.py create mode 100644 sources/pyside2/tests/QtQml/qquickitem_grabToImage.qml create mode 100644 sources/pyside2/tests/QtQml/qquickview_test.py create mode 100644 sources/pyside2/tests/QtQml/registertype.py create mode 100644 sources/pyside2/tests/QtQml/registertype.qml create mode 100644 sources/pyside2/tests/QtQml/signal_arguments.py create mode 100644 sources/pyside2/tests/QtQml/signal_arguments.qml create mode 100644 sources/pyside2/tests/QtQml/view.qml create mode 100644 sources/pyside2/tests/QtQml/viewmodel.qml create mode 100644 sources/pyside2/tests/QtQuick/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtQuickControls2/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtQuickWidgets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtRemoteObjects/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtScript/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtScript/base_test.py create mode 100644 sources/pyside2/tests/QtScript/bug_1022.py create mode 100644 sources/pyside2/tests/QtScript/engine_test.py create mode 100644 sources/pyside2/tests/QtScript/property_test.py create mode 100644 sources/pyside2/tests/QtScript/qscriptvalue_test.py create mode 100644 sources/pyside2/tests/QtScriptTools/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtScriptTools/debugger_test.py create mode 100644 sources/pyside2/tests/QtScxml/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtScxml/test_dynamic.py create mode 100644 sources/pyside2/tests/QtScxml/trafficlight.scxml create mode 100644 sources/pyside2/tests/QtSensors/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtSensors/sensors.py create mode 100644 sources/pyside2/tests/QtSerialPort/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtSerialPort/serial.py create mode 100644 sources/pyside2/tests/QtSql/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtSql/bug_1013.py create mode 100644 sources/pyside2/tests/QtSql/qsqldatabaseandqueries_test.py create mode 100644 sources/pyside2/tests/QtSql/qvarianttype_test.py create mode 100644 sources/pyside2/tests/QtSvg/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtSvg/qsvggenerator_test.py create mode 100644 sources/pyside2/tests/QtSvg/qsvgrenderer_test.py create mode 100644 sources/pyside2/tests/QtSvg/qsvgwidget_test.py create mode 100644 sources/pyside2/tests/QtSvg/tiger.svg create mode 100644 sources/pyside2/tests/QtTest/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtTest/click_test.py create mode 100644 sources/pyside2/tests/QtTest/eventfilter_test.py create mode 100644 sources/pyside2/tests/QtTest/qvalidator_test.py create mode 100644 sources/pyside2/tests/QtTest/touchevent_test.py create mode 100644 sources/pyside2/tests/QtTextToSpeech/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtTextToSpeech/qtexttospeech_test.py create mode 100644 sources/pyside2/tests/QtUiTools/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtUiTools/action.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_1060.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_1060.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_360.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_376.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_392.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_426.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_426.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_552.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_552.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_797.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_909.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_909.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_913.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_913.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_958.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_958.ui create mode 100644 sources/pyside2/tests/QtUiTools/bug_965.py create mode 100644 sources/pyside2/tests/QtUiTools/bug_965.ui create mode 100644 sources/pyside2/tests/QtUiTools/loadUiType_test.py create mode 100644 sources/pyside2/tests/QtUiTools/minimal.ui create mode 100644 sources/pyside2/tests/QtUiTools/pycustomwidget.ui create mode 100644 sources/pyside2/tests/QtUiTools/pycustomwidget2.ui create mode 100644 sources/pyside2/tests/QtUiTools/test.ui create mode 100644 sources/pyside2/tests/QtUiTools/ui_test.py create mode 100644 sources/pyside2/tests/QtUiTools/uiloader_test.py create mode 100644 sources/pyside2/tests/QtWebChannel/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebEngine/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebEngine/web_engine_initialize.py create mode 100644 sources/pyside2/tests/QtWebEngineCore/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebEngineCore/web_engine_custom_scheme.py create mode 100644 sources/pyside2/tests/QtWebEngineWidgets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebEngineWidgets/fox.html create mode 100644 sources/pyside2/tests/QtWebEngineWidgets/pyside-474-qtwebengineview.py create mode 100644 sources/pyside2/tests/QtWebKit/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebKit/bug_448.py create mode 100644 sources/pyside2/tests/QtWebKit/bug_694.py create mode 100644 sources/pyside2/tests/QtWebKit/bug_803.py create mode 100644 sources/pyside2/tests/QtWebKit/bug_899.py create mode 100644 sources/pyside2/tests/QtWebKit/bug_959.py create mode 100644 sources/pyside2/tests/QtWebKit/fox.html create mode 100644 sources/pyside2/tests/QtWebKit/qml_plugin_test.py create mode 100644 sources/pyside2/tests/QtWebKit/qmlplugin/dummy.pys create mode 100644 sources/pyside2/tests/QtWebKit/qmlplugin/index.html create mode 100644 sources/pyside2/tests/QtWebKit/qvariantlist_property_test.py create mode 100644 sources/pyside2/tests/QtWebKit/shouldInterruptjavascript_test.py create mode 100644 sources/pyside2/tests/QtWebKit/webframe_test.py create mode 100644 sources/pyside2/tests/QtWebKit/webpage_test.py create mode 100644 sources/pyside2/tests/QtWebKit/webview_test.py create mode 100644 sources/pyside2/tests/QtWebKitWidgets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWebSockets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWidgets/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtWidgets/action_clear.py create mode 100644 sources/pyside2/tests/QtWidgets/add_action_test.py create mode 100644 sources/pyside2/tests/QtWidgets/api2_test.py create mode 100644 sources/pyside2/tests/QtWidgets/application_test.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_1002.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_1006.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_1048.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_1077.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_172.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_243.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_307.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_324.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_338.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_363.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_389.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_400.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_416.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_429.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_430.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_433.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_467.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_493.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_512.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_525.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_546.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_547.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_549.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_569.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_575.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_576.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_585.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_589.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_632.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_635.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_640.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_653.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_662.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_667.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_668.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_674.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_675.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_688.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_693.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_696.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_711.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_714.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_722.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_728.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_736.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_750.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_778.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_785.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_793.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_811.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_834.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_836.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_844.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_854.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_860.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_862.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_871.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_879.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_919.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_921.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_941.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_964.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_967.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_972.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_979.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_988.py create mode 100644 sources/pyside2/tests/QtWidgets/bug_998.py create mode 100644 sources/pyside2/tests/QtWidgets/customproxywidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/event_filter_test.py create mode 100644 sources/pyside2/tests/QtWidgets/grandparent_method_test.py create mode 100644 sources/pyside2/tests/QtWidgets/hashabletype_test.py create mode 100644 sources/pyside2/tests/QtWidgets/import_test.py create mode 100644 sources/pyside2/tests/QtWidgets/keep_reference_test.py create mode 100644 sources/pyside2/tests/QtWidgets/missing_symbols_test.py create mode 100644 sources/pyside2/tests/QtWidgets/paint_event_test.py create mode 100644 sources/pyside2/tests/QtWidgets/parent_method_test.py create mode 100644 sources/pyside2/tests/QtWidgets/private_mangle_test.py create mode 100644 sources/pyside2/tests/QtWidgets/python_properties_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qabstracttextdocumentlayout_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qaction_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qapp_issue_585.py create mode 100644 sources/pyside2/tests/QtWidgets/qapp_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qapplication_exit_segfault_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qapplication_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qbrush_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qcolormap_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qdynamic_signal.py create mode 100644 sources/pyside2/tests/QtWidgets/qfontdialog_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qformlayout_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qgraphicsitem_isblocked_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qgraphicsitem_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qgraphicsobjectreimpl_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qgraphicsproxywidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qgraphicsscene_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qimage_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qinputdialog_get_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qkeysequenceedit_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlabel_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlayout_ref_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlayout_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlcdnumber_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlistwidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qlistwidgetitem_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qmainwindow_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qmenu_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qmenuadd_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qobject_mi_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qpen_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qpicture_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qpixmap_constructor.py create mode 100644 sources/pyside2/tests/QtWidgets/qpushbutton_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qshortcut_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qsplitter_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qstandarditemmodel_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qstring_qkeysequence_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qstyle_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtableview_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtabwidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtabwidgetclear_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtextedit_signal_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtextedit_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtoolbar_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtoolbox_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtreeview_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtreewidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qtreewidgetitem_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qvariant_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qwidget_setlayout_test.py create mode 100644 sources/pyside2/tests/QtWidgets/qwidget_test.py create mode 100644 sources/pyside2/tests/QtWidgets/reference_count_test.py create mode 100644 sources/pyside2/tests/QtWidgets/sample.png create mode 100644 sources/pyside2/tests/QtWidgets/signature_test.py create mode 100644 sources/pyside2/tests/QtWidgets/standardpixmap_test.py create mode 100644 sources/pyside2/tests/QtWidgets/test_module_template.py create mode 100644 sources/pyside2/tests/QtWidgets/virtual_protected_inheritance_test.py create mode 100644 sources/pyside2/tests/QtWidgets/virtual_pure_override_test.py create mode 100644 sources/pyside2/tests/QtWidgets/wrong_return_test.py create mode 100644 sources/pyside2/tests/QtWinExtras/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtX11Extras/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtXml/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtXml/qdomdocument_test.py create mode 100644 sources/pyside2/tests/QtXml/qxmlsimplereader_test.py create mode 100644 sources/pyside2/tests/QtXmlPatterns/CMakeLists.txt create mode 100644 sources/pyside2/tests/QtXmlPatterns/import_test.py create mode 100644 sources/pyside2/tests/init_paths.py create mode 100644 sources/pyside2/tests/mac/CMakeLists.txt create mode 100644 sources/pyside2/tests/mac/qmacstyle_test.py create mode 100644 sources/pyside2/tests/manually/README.txt create mode 100644 sources/pyside2/tests/manually/bug_841.py create mode 100644 sources/pyside2/tests/pysidetest/CMakeLists.txt create mode 100644 sources/pyside2/tests/pysidetest/all_modules_load_test.py create mode 100644 sources/pyside2/tests/pysidetest/bug_1016.py create mode 100644 sources/pyside2/tests/pysidetest/constructor_properties_test.py create mode 100644 sources/pyside2/tests/pysidetest/curr_errors.txt create mode 100644 sources/pyside2/tests/pysidetest/decoratedslot_test.py create mode 100644 sources/pyside2/tests/pysidetest/delegatecreateseditor_test.py create mode 100644 sources/pyside2/tests/pysidetest/embedding_test.py create mode 100644 sources/pyside2/tests/pysidetest/enum_test.py create mode 100644 sources/pyside2/tests/pysidetest/flagstest.cpp create mode 100644 sources/pyside2/tests/pysidetest/flagstest.h create mode 100644 sources/pyside2/tests/pysidetest/hiddenobject.cpp create mode 100644 sources/pyside2/tests/pysidetest/hiddenobject.h create mode 100644 sources/pyside2/tests/pysidetest/homonymoussignalandmethod_test.py create mode 100644 sources/pyside2/tests/pysidetest/iterable_test.py create mode 100644 sources/pyside2/tests/pysidetest/list_signal_test.py create mode 100644 sources/pyside2/tests/pysidetest/mixin_signal_slots_test.py create mode 100644 sources/pyside2/tests/pysidetest/modelview_test.py create mode 100644 sources/pyside2/tests/pysidetest/new_inherited_functions_test.py create mode 100644 sources/pyside2/tests/pysidetest/notify_id.py create mode 100644 sources/pyside2/tests/pysidetest/properties_test.py create mode 100644 sources/pyside2/tests/pysidetest/property_python_test.py create mode 100644 sources/pyside2/tests/pysidetest/pysidetest_global.h create mode 100644 sources/pyside2/tests/pysidetest/pysidetest_macros.h create mode 100644 sources/pyside2/tests/pysidetest/qapp_like_a_macro_test.py create mode 100644 sources/pyside2/tests/pysidetest/qvariant_test.py create mode 100644 sources/pyside2/tests/pysidetest/repr_test.py create mode 100644 sources/pyside2/tests/pysidetest/signal_slot_warning.py create mode 100644 sources/pyside2/tests/pysidetest/signal_tp_descr_get_test.py create mode 100644 sources/pyside2/tests/pysidetest/signalandnamespace_test.py create mode 100644 sources/pyside2/tests/pysidetest/signalemissionfrompython_test.py create mode 100644 sources/pyside2/tests/pysidetest/signalwithdefaultvalue_test.py create mode 100644 sources/pyside2/tests/pysidetest/symbols.filter create mode 100644 sources/pyside2/tests/pysidetest/testobject.cpp create mode 100644 sources/pyside2/tests/pysidetest/testobject.h create mode 100644 sources/pyside2/tests/pysidetest/testview.cpp create mode 100644 sources/pyside2/tests/pysidetest/testview.h create mode 100644 sources/pyside2/tests/pysidetest/typedef_signal_test.py create mode 100644 sources/pyside2/tests/pysidetest/typesystem_pysidetest.xml create mode 100644 sources/pyside2/tests/pysidetest/version_test.py create mode 100644 sources/pyside2/tests/registry/CMakeLists.txt create mode 100644 sources/pyside2/tests/registry/existence_test.py create mode 100644 sources/pyside2/tests/registry/exists_darwin_5_14_2_ci.py create mode 100644 sources/pyside2/tests/registry/exists_red_hat_enterprise_linux_workstation7_6_5_14_2_ci.py create mode 100644 sources/pyside2/tests/registry/exists_win32_5_14_2_ci.py create mode 100644 sources/pyside2/tests/registry/exists_x86_64_suse_linux_5_14_2_ci.py create mode 100644 sources/pyside2/tests/registry/init_platform.py create mode 100644 sources/pyside2/tests/registry/scrape_testresults.py create mode 100644 sources/pyside2/tests/registry/util.py create mode 100755 sources/pyside2/tests/run_test.sh create mode 100644 sources/pyside2/tests/signals/CMakeLists.txt create mode 100644 sources/pyside2/tests/signals/args_dont_match_test.py create mode 100644 sources/pyside2/tests/signals/bug_189.py create mode 100644 sources/pyside2/tests/signals/bug_311.py create mode 100644 sources/pyside2/tests/signals/bug_312.py create mode 100644 sources/pyside2/tests/signals/bug_319.py create mode 100644 sources/pyside2/tests/signals/bug_79.py create mode 100644 sources/pyside2/tests/signals/decorators_test.py create mode 100644 sources/pyside2/tests/signals/disconnect_test.py create mode 100644 sources/pyside2/tests/signals/invalid_callback_test.py create mode 100644 sources/pyside2/tests/signals/lambda_gui_test.py create mode 100644 sources/pyside2/tests/signals/lambda_test.py create mode 100644 sources/pyside2/tests/signals/leaking_signal_test.py create mode 100644 sources/pyside2/tests/signals/multiple_connections_gui_test.py create mode 100644 sources/pyside2/tests/signals/multiple_connections_test.py create mode 100644 sources/pyside2/tests/signals/pysignal_test.py create mode 100644 sources/pyside2/tests/signals/qobject_destroyed_test.py create mode 100644 sources/pyside2/tests/signals/qobject_receivers_test.py create mode 100644 sources/pyside2/tests/signals/qobject_sender_test.py create mode 100644 sources/pyside2/tests/signals/ref01_test.py create mode 100644 sources/pyside2/tests/signals/ref02_test.py create mode 100644 sources/pyside2/tests/signals/ref03_test.py create mode 100644 sources/pyside2/tests/signals/ref04_test.py create mode 100644 sources/pyside2/tests/signals/ref05_test.py create mode 100644 sources/pyside2/tests/signals/ref06_test.py create mode 100644 sources/pyside2/tests/signals/segfault_proxyparent_test.py create mode 100644 sources/pyside2/tests/signals/self_connect_test.py create mode 100644 sources/pyside2/tests/signals/short_circuit_test.py create mode 100644 sources/pyside2/tests/signals/signal2signal_connect_test.py create mode 100644 sources/pyside2/tests/signals/signal_across_threads.py create mode 100644 sources/pyside2/tests/signals/signal_autoconnect_test.py create mode 100644 sources/pyside2/tests/signals/signal_connectiontype_support_test.py create mode 100644 sources/pyside2/tests/signals/signal_emission_gui_test.py create mode 100644 sources/pyside2/tests/signals/signal_emission_test.py create mode 100644 sources/pyside2/tests/signals/signal_enum_test.py create mode 100644 sources/pyside2/tests/signals/signal_func_test.py create mode 100644 sources/pyside2/tests/signals/signal_manager_refcount_test.py create mode 100644 sources/pyside2/tests/signals/signal_number_limit_test.py create mode 100644 sources/pyside2/tests/signals/signal_object_test.py create mode 100644 sources/pyside2/tests/signals/signal_signature_test.py create mode 100644 sources/pyside2/tests/signals/signal_with_primitive_type_test.py create mode 100644 sources/pyside2/tests/signals/slot_reference_count_test.py create mode 100644 sources/pyside2/tests/signals/static_metaobject_test.py create mode 100644 sources/pyside2/tests/support/CMakeLists.txt create mode 100644 sources/pyside2/tests/support/voidptr_test.py create mode 100755 sources/pyside2/tests/tools/list-class-hierarchy.py create mode 100644 sources/pyside2/tests/util/color.py create mode 100644 sources/pyside2/tests/util/helper/__init__.py create mode 100644 sources/pyside2/tests/util/helper/basicpyslotcase.py create mode 100644 sources/pyside2/tests/util/helper/docmodifier.py create mode 100644 sources/pyside2/tests/util/helper/helper.py create mode 100644 sources/pyside2/tests/util/helper/helper.pyproject create mode 100644 sources/pyside2/tests/util/helper/timedqapplication.py create mode 100644 sources/pyside2/tests/util/helper/usesqapplication.py create mode 100644 sources/pyside2/tests/util/helper/usesqcoreapplication.py create mode 100644 sources/pyside2/tests/util/helper/usesqguiapplication.py create mode 100644 sources/pyside2/tests/util/httpd.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtAssistant.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtCore.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtDesigner.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtGui.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtHelp.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtNetwork.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtScript.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtSql.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtSvg.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtTest.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtWebKit.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtXml.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/QtXmlPatterns.py create mode 100644 sources/pyside2/tests/util/module_wrapper/PySide/__init__.py create mode 100644 sources/pyside2/tests/util/processtimer.py create mode 100644 sources/pyside2/tests/util/py3kcompat.py create mode 100644 sources/pyside2/tests/util/pyqt_diff.py create mode 100644 sources/pyside2/tests/util/pyqtcheck.py create mode 100755 sources/pyside2/tests/util/rename_imports.sh create mode 100644 sources/pyside2/tests/util/test_processtimer.py create mode 100644 sources/pyside2/tests/util/use_pyqt4.sh create mode 100644 sources/pyside2/tests/util/use_pyside.sh create mode 100644 sources/pyside2/tests/util/valgrind-python.supp create mode 100644 sources/shiboken2/AUTHORS create mode 100644 sources/shiboken2/ApiExtractor/AUTHORS create mode 100644 sources/shiboken2/ApiExtractor/CMakeLists.txt create mode 100644 sources/shiboken2/ApiExtractor/COPYING create mode 100644 sources/shiboken2/ApiExtractor/abstractmetabuilder.cpp create mode 100644 sources/shiboken2/ApiExtractor/abstractmetabuilder.h create mode 100644 sources/shiboken2/ApiExtractor/abstractmetabuilder_p.h create mode 100644 sources/shiboken2/ApiExtractor/abstractmetalang.cpp create mode 100644 sources/shiboken2/ApiExtractor/abstractmetalang.h create mode 100644 sources/shiboken2/ApiExtractor/abstractmetalang_typedefs.h create mode 100644 sources/shiboken2/ApiExtractor/apiextractor.cpp create mode 100644 sources/shiboken2/ApiExtractor/apiextractor.h create mode 100644 sources/shiboken2/ApiExtractor/apiextractormacros.h create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangbuilder.cpp create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangbuilder.h create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.cpp create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangdebugutils.h create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangparser.h create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangutils.cpp create mode 100644 sources/shiboken2/ApiExtractor/clangparser/clangutils.h create mode 100644 sources/shiboken2/ApiExtractor/clangparser/compilersupport.cpp create mode 100644 sources/shiboken2/ApiExtractor/clangparser/compilersupport.h create mode 100644 sources/shiboken2/ApiExtractor/cmake_uninstall.cmake create mode 100644 sources/shiboken2/ApiExtractor/dependency.h create mode 100644 sources/shiboken2/ApiExtractor/docparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/docparser.h create mode 100644 sources/shiboken2/ApiExtractor/doxygenparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/doxygenparser.h create mode 100644 sources/shiboken2/ApiExtractor/fileout.cpp create mode 100644 sources/shiboken2/ApiExtractor/fileout.h create mode 100644 sources/shiboken2/ApiExtractor/graph.cpp create mode 100644 sources/shiboken2/ApiExtractor/graph.h create mode 100644 sources/shiboken2/ApiExtractor/header_paths.h create mode 100644 sources/shiboken2/ApiExtractor/icecc.cmake create mode 100644 sources/shiboken2/ApiExtractor/include.cpp create mode 100644 sources/shiboken2/ApiExtractor/include.h create mode 100644 sources/shiboken2/ApiExtractor/merge.xsl create mode 100644 sources/shiboken2/ApiExtractor/messages.cpp create mode 100644 sources/shiboken2/ApiExtractor/messages.h create mode 100644 sources/shiboken2/ApiExtractor/parser/codemodel.cpp create mode 100644 sources/shiboken2/ApiExtractor/parser/codemodel.h create mode 100644 sources/shiboken2/ApiExtractor/parser/codemodel_enums.h create mode 100644 sources/shiboken2/ApiExtractor/parser/codemodel_fwd.h create mode 100644 sources/shiboken2/ApiExtractor/parser/enumvalue.cpp create mode 100644 sources/shiboken2/ApiExtractor/parser/enumvalue.h create mode 100644 sources/shiboken2/ApiExtractor/propertyspec.cpp create mode 100644 sources/shiboken2/ApiExtractor/propertyspec.h create mode 100644 sources/shiboken2/ApiExtractor/qtcompat.h create mode 100644 sources/shiboken2/ApiExtractor/qtdocparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/qtdocparser.h create mode 100644 sources/shiboken2/ApiExtractor/reporthandler.cpp create mode 100644 sources/shiboken2/ApiExtractor/reporthandler.h create mode 100644 sources/shiboken2/ApiExtractor/sourcelocation.cpp create mode 100644 sources/shiboken2/ApiExtractor/sourcelocation.h create mode 100644 sources/shiboken2/ApiExtractor/symbols.filter create mode 100644 sources/shiboken2/ApiExtractor/tests/CMakeLists.txt create mode 100644 sources/shiboken2/ApiExtractor/tests/a.xml create mode 100644 sources/shiboken2/ApiExtractor/tests/injectedcode.txt create mode 100644 sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testabstractmetaclass.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testabstractmetatype.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testabstractmetatype.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testaddfunction.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testaddfunction.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testarrayargument.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testarrayargument.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testcodeinjection.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testcodeinjection.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testcodeinjection.qrc create mode 100644 sources/shiboken2/ApiExtractor/tests/testcontainer.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testcontainer.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testconversionoperator.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testconversionoperator.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testconversionruletag.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testconversionruletag.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testctorinformation.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testctorinformation.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testdroptypeentries.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testdroptypeentries.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testdtorinformation.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testdtorinformation.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testenum.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testenum.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testextrainclude.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testextrainclude.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testfunctiontag.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testfunctiontag.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testimplicitconversions.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testimplicitconversions.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testinserttemplate.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testinserttemplate.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testmodifydocumentation.qrc create mode 100644 sources/shiboken2/ApiExtractor/tests/testmodifyfunction.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testmodifyfunction.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testmultipleinheritance.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testnamespace.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testnamespace.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testnestedtypes.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testnestedtypes.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testnumericaltypedef.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testprimitivetypetag.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testrefcounttag.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testrefcounttag.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testreferencetopointer.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testreferencetopointer.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testremovefield.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testremovefield.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testremoveimplconv.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testremoveimplconv.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testremoveoperatormethod.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testresolvetype.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testresolvetype.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testreverseoperators.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testreverseoperators.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testtemplates.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testtemplates.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testtoposort.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testtoposort.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testtyperevision.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testtyperevision.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testutil.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testvaluetypedefaultctortag.h create mode 100644 sources/shiboken2/ApiExtractor/tests/testvoidarg.cpp create mode 100644 sources/shiboken2/ApiExtractor/tests/testvoidarg.h create mode 100644 sources/shiboken2/ApiExtractor/tests/utf8code.txt create mode 100644 sources/shiboken2/ApiExtractor/typedatabase.cpp create mode 100644 sources/shiboken2/ApiExtractor/typedatabase.h create mode 100644 sources/shiboken2/ApiExtractor/typedatabase_typedefs.h create mode 100644 sources/shiboken2/ApiExtractor/typeparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/typeparser.h create mode 100644 sources/shiboken2/ApiExtractor/typesystem.cpp create mode 100644 sources/shiboken2/ApiExtractor/typesystem.h create mode 100644 sources/shiboken2/ApiExtractor/typesystem_enums.h create mode 100644 sources/shiboken2/ApiExtractor/typesystem_typedefs.h create mode 100644 sources/shiboken2/ApiExtractor/typesystemparser.cpp create mode 100644 sources/shiboken2/ApiExtractor/typesystemparser.h create mode 100644 sources/shiboken2/ApiExtractor/xmlutils.cpp create mode 100644 sources/shiboken2/ApiExtractor/xmlutils.h create mode 100644 sources/shiboken2/ApiExtractor/xmlutils_libxslt.cpp create mode 100644 sources/shiboken2/ApiExtractor/xmlutils_libxslt.h create mode 100644 sources/shiboken2/ApiExtractor/xmlutils_qt.cpp create mode 100644 sources/shiboken2/ApiExtractor/xmlutils_qt.h create mode 100644 sources/shiboken2/CMakeLists.txt create mode 100644 sources/shiboken2/COPYING create mode 100644 sources/shiboken2/COPYING.libsample create mode 100644 sources/shiboken2/COPYING.libshiboken create mode 100644 sources/shiboken2/Doxyfile create mode 100644 sources/shiboken2/cmake_uninstall.cmake create mode 100644 sources/shiboken2/data/CMakeLists.txt create mode 100644 sources/shiboken2/data/GeneratorRunnerConfig.cmake.in create mode 100644 sources/shiboken2/data/GeneratorRunnerConfigVersion.cmake.in create mode 100644 sources/shiboken2/data/Shiboken2Config-spec.cmake.in create mode 100644 sources/shiboken2/data/Shiboken2Config.cmake.in create mode 100644 sources/shiboken2/data/Shiboken2ConfigVersion.cmake.in create mode 100644 sources/shiboken2/data/docgenerator.1 create mode 100644 sources/shiboken2/data/generatorrunner.1 create mode 100644 sources/shiboken2/data/generatorrunner.pc.in create mode 100644 sources/shiboken2/data/shiboken2.pc.in create mode 100644 sources/shiboken2/data/shiboken_helpers.cmake create mode 100644 sources/shiboken2/doc/CMakeLists.txt create mode 100644 sources/shiboken2/doc/README.md create mode 100644 sources/shiboken2/doc/_templates/index.html create mode 100644 sources/shiboken2/doc/_templates/layout.html create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/searchbox.html create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/bg_header.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/bg_topo.jpg create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/fakebar.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/logo_python.jpg create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/logo_qt.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/pyside.css create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/pysidelogo.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/static/relbar_bg.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs/theme.conf create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/domainindex.html create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/fakebar.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/minus.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/plus.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pyside.css create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png create mode 100644 sources/shiboken2/doc/_themes/pysidedocs_qthelp/theme.conf create mode 100644 sources/shiboken2/doc/conf.py.in create mode 100644 sources/shiboken2/doc/considerations.rst create mode 100644 sources/shiboken2/doc/dependency-pyside.svg create mode 100644 sources/shiboken2/doc/examples/index.rst create mode 100644 sources/shiboken2/doc/examples/samplebinding.rst create mode 100644 sources/shiboken2/doc/gettingstarted.rst create mode 100644 sources/shiboken2/doc/images/.directory create mode 100644 sources/shiboken2/doc/images/bindinggen-development.png create mode 100644 sources/shiboken2/doc/images/bindinggen-development.svg create mode 100644 sources/shiboken2/doc/images/boostgen.png create mode 100644 sources/shiboken2/doc/images/converter.png create mode 100644 sources/shiboken2/doc/images/converter.svg create mode 100644 sources/shiboken2/doc/images/genrunnerarch.png create mode 100644 sources/shiboken2/doc/images/genrunnerarch.svg create mode 100644 sources/shiboken2/doc/images/icecream.png create mode 100644 sources/shiboken2/doc/images/qtforpython-underthehood.png create mode 100644 sources/shiboken2/doc/images/shibokenqtarch.png create mode 100644 sources/shiboken2/doc/images/shibokenqtarch.svg create mode 100644 sources/shiboken2/doc/index.rst create mode 100644 sources/shiboken2/doc/shibokengenerator.rst create mode 100644 sources/shiboken2/doc/shibokenmodule.rst create mode 100644 sources/shiboken2/doc/typesystem.rst create mode 100644 sources/shiboken2/doc/typesystem_arguments.rst create mode 100644 sources/shiboken2/doc/typesystem_codegeneration.rst create mode 100644 sources/shiboken2/doc/typesystem_codeinjection.rst create mode 100644 sources/shiboken2/doc/typesystem_conversionrule.rst create mode 100644 sources/shiboken2/doc/typesystem_converters.rst create mode 100644 sources/shiboken2/doc/typesystem_documentation.rst create mode 100644 sources/shiboken2/doc/typesystem_manipulating_objects.rst create mode 100644 sources/shiboken2/doc/typesystem_modify_function.rst create mode 100644 sources/shiboken2/doc/typesystem_ownership.rst create mode 100644 sources/shiboken2/doc/typesystem_sequenceprotocol.rst create mode 100644 sources/shiboken2/doc/typesystem_solving_compilation.rst create mode 100644 sources/shiboken2/doc/typesystem_specifying_types.rst create mode 100644 sources/shiboken2/doc/typesystem_templates.rst create mode 100644 sources/shiboken2/doc/typesystem_variables.rst create mode 100644 sources/shiboken2/generator/CMakeLists.txt create mode 100644 sources/shiboken2/generator/__init__.py.in create mode 100644 sources/shiboken2/generator/_config.py.in create mode 100644 sources/shiboken2/generator/generator.cpp create mode 100644 sources/shiboken2/generator/generator.h create mode 100644 sources/shiboken2/generator/indentor.h create mode 100644 sources/shiboken2/generator/main.cpp create mode 100644 sources/shiboken2/generator/qtdoc/qtdocgenerator.cpp create mode 100644 sources/shiboken2/generator/qtdoc/qtdocgenerator.h create mode 100644 sources/shiboken2/generator/shiboken2/cppgenerator.cpp create mode 100644 sources/shiboken2/generator/shiboken2/cppgenerator.h create mode 100644 sources/shiboken2/generator/shiboken2/ctypenames.h create mode 100644 sources/shiboken2/generator/shiboken2/headergenerator.cpp create mode 100644 sources/shiboken2/generator/shiboken2/headergenerator.h create mode 100644 sources/shiboken2/generator/shiboken2/overloaddata.cpp create mode 100644 sources/shiboken2/generator/shiboken2/overloaddata.h create mode 100644 sources/shiboken2/generator/shiboken2/shibokengenerator.cpp create mode 100644 sources/shiboken2/generator/shiboken2/shibokengenerator.h create mode 100644 sources/shiboken2/generator/shibokenconfig.h.in create mode 100644 sources/shiboken2/generatorrunnerconfig.h.in create mode 100644 sources/shiboken2/generatorrunnermacros.h create mode 100644 sources/shiboken2/generators/shiboken/shiboken.cpp create mode 100644 sources/shiboken2/icecc.cmake create mode 100644 sources/shiboken2/libshiboken/CMakeLists.txt create mode 100644 sources/shiboken2/libshiboken/autodecref.h create mode 100644 sources/shiboken2/libshiboken/basewrapper.cpp create mode 100644 sources/shiboken2/libshiboken/basewrapper.h create mode 100644 sources/shiboken2/libshiboken/basewrapper_p.h create mode 100644 sources/shiboken2/libshiboken/bindingmanager.cpp create mode 100644 sources/shiboken2/libshiboken/bindingmanager.h create mode 100644 sources/shiboken2/libshiboken/bufferprocs_py37.cpp create mode 100644 sources/shiboken2/libshiboken/bufferprocs_py37.h create mode 100644 sources/shiboken2/libshiboken/debugfreehook.cpp create mode 100644 sources/shiboken2/libshiboken/debugfreehook.h create mode 100644 sources/shiboken2/libshiboken/embed/embedding_generator.py create mode 100644 sources/shiboken2/libshiboken/embed/module_collector.py create mode 100644 sources/shiboken2/libshiboken/embed/qt_python_license.txt create mode 100644 sources/shiboken2/libshiboken/embed/signature_bootstrap.py create mode 100644 sources/shiboken2/libshiboken/gilstate.cpp create mode 100644 sources/shiboken2/libshiboken/gilstate.h create mode 100644 sources/shiboken2/libshiboken/helper.cpp create mode 100644 sources/shiboken2/libshiboken/helper.h create mode 100644 sources/shiboken2/libshiboken/pep384_issue33738.cpp create mode 100644 sources/shiboken2/libshiboken/pep384impl.cpp create mode 100644 sources/shiboken2/libshiboken/pep384impl.h create mode 100644 sources/shiboken2/libshiboken/pep384impl_doc.rst create mode 100644 sources/shiboken2/libshiboken/python25compat.h create mode 100644 sources/shiboken2/libshiboken/qapp_macro.cpp create mode 100644 sources/shiboken2/libshiboken/qapp_macro.h create mode 100644 sources/shiboken2/libshiboken/qt_attribution.json create mode 100644 sources/shiboken2/libshiboken/sbkarrayconverter.cpp create mode 100644 sources/shiboken2/libshiboken/sbkarrayconverter.h create mode 100644 sources/shiboken2/libshiboken/sbkarrayconverter_p.h create mode 100644 sources/shiboken2/libshiboken/sbkconverter.cpp create mode 100644 sources/shiboken2/libshiboken/sbkconverter.h create mode 100644 sources/shiboken2/libshiboken/sbkconverter_p.h create mode 100644 sources/shiboken2/libshiboken/sbkdbg.h create mode 100644 sources/shiboken2/libshiboken/sbkenum.cpp create mode 100644 sources/shiboken2/libshiboken/sbkenum.h create mode 100644 sources/shiboken2/libshiboken/sbkmodule.cpp create mode 100644 sources/shiboken2/libshiboken/sbkmodule.h create mode 100644 sources/shiboken2/libshiboken/sbknumpyarrayconverter.cpp create mode 100644 sources/shiboken2/libshiboken/sbkpython.h create mode 100644 sources/shiboken2/libshiboken/sbkstaticstrings.cpp create mode 100644 sources/shiboken2/libshiboken/sbkstaticstrings.h create mode 100644 sources/shiboken2/libshiboken/sbkstaticstrings_p.h create mode 100644 sources/shiboken2/libshiboken/sbkstring.cpp create mode 100644 sources/shiboken2/libshiboken/sbkstring.h create mode 100644 sources/shiboken2/libshiboken/sbkversion.h.in create mode 100644 sources/shiboken2/libshiboken/shiboken.h create mode 100644 sources/shiboken2/libshiboken/shibokenbuffer.cpp create mode 100644 sources/shiboken2/libshiboken/shibokenbuffer.h create mode 100644 sources/shiboken2/libshiboken/shibokenmacros.h create mode 100644 sources/shiboken2/libshiboken/signature.h create mode 100644 sources/shiboken2/libshiboken/signature/signature.cpp create mode 100644 sources/shiboken2/libshiboken/signature/signature_doc.rst create mode 100644 sources/shiboken2/libshiboken/signature/signature_extend.cpp create mode 100644 sources/shiboken2/libshiboken/signature/signature_globals.cpp create mode 100644 sources/shiboken2/libshiboken/signature/signature_helper.cpp create mode 100644 sources/shiboken2/libshiboken/signature/signature_p.h create mode 100644 sources/shiboken2/libshiboken/threadstatesaver.cpp create mode 100644 sources/shiboken2/libshiboken/threadstatesaver.h create mode 100644 sources/shiboken2/libshiboken/tmp-referencetopython/sbkconverter.cpp create mode 100644 sources/shiboken2/libshiboken/tmp-referencetopython/sbkconverter.h create mode 100644 sources/shiboken2/libshiboken/typespec.cpp create mode 100644 sources/shiboken2/libshiboken/typespec.h create mode 100644 sources/shiboken2/libshiboken/voidptr.cpp create mode 100644 sources/shiboken2/libshiboken/voidptr.h create mode 100755 sources/shiboken2/shiboken_tool.py create mode 100644 sources/shiboken2/shiboken_version.py create mode 100644 sources/shiboken2/shibokenmodule/CMakeLists.txt create mode 100644 sources/shiboken2/shibokenmodule/__init__.py.in create mode 100644 sources/shiboken2/shibokenmodule/_config.py.in create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__feature__.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/__init__.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/backport_inspect.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/fix-complaints.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/PSF-3.7.0.txt create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/__init__.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/errorhandler.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/importhandler.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/layout.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/__init__.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/enum_sig.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/lib/tool.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/loader.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/mapping.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/parser.py create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/signature/qt_attribution.json create mode 100644 sources/shiboken2/shibokenmodule/files.dir/shibokensupport/typing27.py create mode 100644 sources/shiboken2/shibokenmodule/nothing.h create mode 100644 sources/shiboken2/shibokenmodule/shibokenmodule.txt.in create mode 100644 sources/shiboken2/shibokenmodule/typesystem_shiboken.xml create mode 100644 sources/shiboken2/tests/CMakeLists.txt create mode 100644 sources/shiboken2/tests/dumpcodemodel/CMakeLists.txt create mode 100644 sources/shiboken2/tests/dumpcodemodel/main.cpp create mode 100644 sources/shiboken2/tests/libminimal/CMakeLists.txt create mode 100644 sources/shiboken2/tests/libminimal/libminimalmacros.h create mode 100644 sources/shiboken2/tests/libminimal/listuser.cpp create mode 100644 sources/shiboken2/tests/libminimal/listuser.h create mode 100644 sources/shiboken2/tests/libminimal/minbool.h create mode 100644 sources/shiboken2/tests/libminimal/obj.cpp create mode 100644 sources/shiboken2/tests/libminimal/obj.h create mode 100644 sources/shiboken2/tests/libminimal/typedef.cpp create mode 100644 sources/shiboken2/tests/libminimal/typedef.h create mode 100644 sources/shiboken2/tests/libminimal/val.h create mode 100644 sources/shiboken2/tests/libother/CMakeLists.txt create mode 100644 sources/shiboken2/tests/libother/extendsnoimplicitconversion.h create mode 100644 sources/shiboken2/tests/libother/libothermacros.h create mode 100644 sources/shiboken2/tests/libother/number.cpp create mode 100644 sources/shiboken2/tests/libother/number.h create mode 100644 sources/shiboken2/tests/libother/otherderived.cpp create mode 100644 sources/shiboken2/tests/libother/otherderived.h create mode 100644 sources/shiboken2/tests/libother/othermultiplederived.cpp create mode 100644 sources/shiboken2/tests/libother/othermultiplederived.h create mode 100644 sources/shiboken2/tests/libother/otherobjecttype.cpp create mode 100644 sources/shiboken2/tests/libother/otherobjecttype.h create mode 100644 sources/shiboken2/tests/libother/othertypesystypedef.cpp create mode 100644 sources/shiboken2/tests/libother/othertypesystypedef.h create mode 100644 sources/shiboken2/tests/libother/smartptrtester.cpp create mode 100644 sources/shiboken2/tests/libother/smartptrtester.h create mode 100644 sources/shiboken2/tests/libsample/CMakeLists.txt create mode 100644 sources/shiboken2/tests/libsample/abstract.cpp create mode 100644 sources/shiboken2/tests/libsample/abstract.h create mode 100644 sources/shiboken2/tests/libsample/blackbox.cpp create mode 100644 sources/shiboken2/tests/libsample/blackbox.h create mode 100644 sources/shiboken2/tests/libsample/bucket.cpp create mode 100644 sources/shiboken2/tests/libsample/bucket.h create mode 100644 sources/shiboken2/tests/libsample/bytearray.cpp create mode 100644 sources/shiboken2/tests/libsample/bytearray.h create mode 100644 sources/shiboken2/tests/libsample/collector.cpp create mode 100644 sources/shiboken2/tests/libsample/collector.h create mode 100644 sources/shiboken2/tests/libsample/complex.cpp create mode 100644 sources/shiboken2/tests/libsample/complex.h create mode 100644 sources/shiboken2/tests/libsample/ctorconvrule.h create mode 100644 sources/shiboken2/tests/libsample/cvlist.h create mode 100644 sources/shiboken2/tests/libsample/derived.cpp create mode 100644 sources/shiboken2/tests/libsample/derived.h create mode 100644 sources/shiboken2/tests/libsample/echo.cpp create mode 100644 sources/shiboken2/tests/libsample/echo.h create mode 100644 sources/shiboken2/tests/libsample/exceptiontest.cpp create mode 100644 sources/shiboken2/tests/libsample/exceptiontest.h create mode 100644 sources/shiboken2/tests/libsample/expression.cpp create mode 100644 sources/shiboken2/tests/libsample/expression.h create mode 100644 sources/shiboken2/tests/libsample/filter.cpp create mode 100644 sources/shiboken2/tests/libsample/filter.h create mode 100644 sources/shiboken2/tests/libsample/functions.cpp create mode 100644 sources/shiboken2/tests/libsample/functions.h create mode 100644 sources/shiboken2/tests/libsample/handle.cpp create mode 100644 sources/shiboken2/tests/libsample/handle.h create mode 100644 sources/shiboken2/tests/libsample/implicitconv.cpp create mode 100644 sources/shiboken2/tests/libsample/implicitconv.h create mode 100644 sources/shiboken2/tests/libsample/injectcode.cpp create mode 100644 sources/shiboken2/tests/libsample/injectcode.h create mode 100644 sources/shiboken2/tests/libsample/libsamplemacros.h create mode 100644 sources/shiboken2/tests/libsample/list.h create mode 100644 sources/shiboken2/tests/libsample/listuser.cpp create mode 100644 sources/shiboken2/tests/libsample/listuser.h create mode 100644 sources/shiboken2/tests/libsample/main.cpp create mode 100644 sources/shiboken2/tests/libsample/mapuser.cpp create mode 100644 sources/shiboken2/tests/libsample/mapuser.h create mode 100644 sources/shiboken2/tests/libsample/modelindex.h create mode 100644 sources/shiboken2/tests/libsample/modifications.cpp create mode 100644 sources/shiboken2/tests/libsample/modifications.h create mode 100644 sources/shiboken2/tests/libsample/modified_constructor.cpp create mode 100644 sources/shiboken2/tests/libsample/modified_constructor.h create mode 100644 sources/shiboken2/tests/libsample/multiple_derived.cpp create mode 100644 sources/shiboken2/tests/libsample/multiple_derived.h create mode 100644 sources/shiboken2/tests/libsample/noimplicitconversion.h create mode 100644 sources/shiboken2/tests/libsample/nondefaultctor.h create mode 100644 sources/shiboken2/tests/libsample/nontypetemplate.h create mode 100644 sources/shiboken2/tests/libsample/null.h create mode 100644 sources/shiboken2/tests/libsample/objectmodel.cpp create mode 100644 sources/shiboken2/tests/libsample/objectmodel.h create mode 100644 sources/shiboken2/tests/libsample/objecttype.cpp create mode 100644 sources/shiboken2/tests/libsample/objecttype.h create mode 100644 sources/shiboken2/tests/libsample/objecttypebyvalue.h create mode 100644 sources/shiboken2/tests/libsample/objecttypeholder.cpp create mode 100644 sources/shiboken2/tests/libsample/objecttypeholder.h create mode 100644 sources/shiboken2/tests/libsample/objecttypelayout.cpp create mode 100644 sources/shiboken2/tests/libsample/objecttypelayout.h create mode 100644 sources/shiboken2/tests/libsample/objecttypeoperators.cpp create mode 100644 sources/shiboken2/tests/libsample/objecttypeoperators.h create mode 100644 sources/shiboken2/tests/libsample/objectview.cpp create mode 100644 sources/shiboken2/tests/libsample/objectview.h create mode 100644 sources/shiboken2/tests/libsample/oddbool.cpp create mode 100644 sources/shiboken2/tests/libsample/oddbool.h create mode 100644 sources/shiboken2/tests/libsample/onlycopy.cpp create mode 100644 sources/shiboken2/tests/libsample/onlycopy.h create mode 100644 sources/shiboken2/tests/libsample/overload.cpp create mode 100644 sources/shiboken2/tests/libsample/overload.h create mode 100644 sources/shiboken2/tests/libsample/overloadsort.cpp create mode 100644 sources/shiboken2/tests/libsample/overloadsort.h create mode 100644 sources/shiboken2/tests/libsample/pairuser.cpp create mode 100644 sources/shiboken2/tests/libsample/pairuser.h create mode 100644 sources/shiboken2/tests/libsample/pen.cpp create mode 100644 sources/shiboken2/tests/libsample/pen.h create mode 100644 sources/shiboken2/tests/libsample/photon.cpp create mode 100644 sources/shiboken2/tests/libsample/photon.h create mode 100644 sources/shiboken2/tests/libsample/point.cpp create mode 100644 sources/shiboken2/tests/libsample/point.h create mode 100644 sources/shiboken2/tests/libsample/pointerholder.h create mode 100644 sources/shiboken2/tests/libsample/pointf.cpp create mode 100644 sources/shiboken2/tests/libsample/pointf.h create mode 100644 sources/shiboken2/tests/libsample/polygon.cpp create mode 100644 sources/shiboken2/tests/libsample/polygon.h create mode 100644 sources/shiboken2/tests/libsample/privatector.h create mode 100644 sources/shiboken2/tests/libsample/privatedtor.h create mode 100644 sources/shiboken2/tests/libsample/protected.cpp create mode 100644 sources/shiboken2/tests/libsample/protected.h create mode 100644 sources/shiboken2/tests/libsample/rect.h create mode 100644 sources/shiboken2/tests/libsample/reference.cpp create mode 100644 sources/shiboken2/tests/libsample/reference.h create mode 100644 sources/shiboken2/tests/libsample/removednamespaces.h create mode 100644 sources/shiboken2/tests/libsample/renaming.cpp create mode 100644 sources/shiboken2/tests/libsample/renaming.h create mode 100644 sources/shiboken2/tests/libsample/sample.cpp create mode 100644 sources/shiboken2/tests/libsample/sample.h create mode 100644 sources/shiboken2/tests/libsample/samplenamespace.cpp create mode 100644 sources/shiboken2/tests/libsample/samplenamespace.h create mode 100644 sources/shiboken2/tests/libsample/sbkdate.cpp create mode 100644 sources/shiboken2/tests/libsample/sbkdate.h create mode 100644 sources/shiboken2/tests/libsample/simplefile.cpp create mode 100644 sources/shiboken2/tests/libsample/simplefile.h create mode 100644 sources/shiboken2/tests/libsample/size.cpp create mode 100644 sources/shiboken2/tests/libsample/size.h create mode 100644 sources/shiboken2/tests/libsample/sometime.cpp create mode 100644 sources/shiboken2/tests/libsample/sometime.h create mode 100644 sources/shiboken2/tests/libsample/str.cpp create mode 100644 sources/shiboken2/tests/libsample/str.h create mode 100644 sources/shiboken2/tests/libsample/strlist.cpp create mode 100644 sources/shiboken2/tests/libsample/strlist.h create mode 100644 sources/shiboken2/tests/libsample/templateptr.cpp create mode 100644 sources/shiboken2/tests/libsample/templateptr.h create mode 100644 sources/shiboken2/tests/libsample/transform.cpp create mode 100644 sources/shiboken2/tests/libsample/transform.h create mode 100644 sources/shiboken2/tests/libsample/typesystypedef.cpp create mode 100644 sources/shiboken2/tests/libsample/typesystypedef.h create mode 100644 sources/shiboken2/tests/libsample/valueandvirtual.h create mode 100644 sources/shiboken2/tests/libsample/virtualmethods.cpp create mode 100644 sources/shiboken2/tests/libsample/virtualmethods.h create mode 100644 sources/shiboken2/tests/libsample/voidholder.h create mode 100644 sources/shiboken2/tests/libsmart/CMakeLists.txt create mode 100644 sources/shiboken2/tests/libsmart/libsmartmacros.h create mode 100644 sources/shiboken2/tests/libsmart/smart.cpp create mode 100644 sources/shiboken2/tests/libsmart/smart.h create mode 100644 sources/shiboken2/tests/libsmart/smart_integer.h create mode 100644 sources/shiboken2/tests/libsmart/smart_obj.h create mode 100644 sources/shiboken2/tests/libsmart/smart_registry.h create mode 100644 sources/shiboken2/tests/libsmart/smart_sharedptr.h create mode 100644 sources/shiboken2/tests/minimalbinding/CMakeLists.txt create mode 100644 sources/shiboken2/tests/minimalbinding/brace_pattern_test.py create mode 100644 sources/shiboken2/tests/minimalbinding/global.h create mode 100644 sources/shiboken2/tests/minimalbinding/listuser_test.py create mode 100644 sources/shiboken2/tests/minimalbinding/minbool_test.py create mode 100644 sources/shiboken2/tests/minimalbinding/minimal-binding.txt.in create mode 100644 sources/shiboken2/tests/minimalbinding/obj_test.py create mode 100644 sources/shiboken2/tests/minimalbinding/typedef_test.py create mode 100644 sources/shiboken2/tests/minimalbinding/typesystem_minimal.xml create mode 100644 sources/shiboken2/tests/minimalbinding/val_test.py create mode 100644 sources/shiboken2/tests/otherbinding/CMakeLists.txt create mode 100644 sources/shiboken2/tests/otherbinding/collector_external_operator_test.py create mode 100644 sources/shiboken2/tests/otherbinding/conversion_operator_for_class_without_implicit_conversions_test.py create mode 100644 sources/shiboken2/tests/otherbinding/extended_multiply_operator_test.py create mode 100644 sources/shiboken2/tests/otherbinding/global.h create mode 100644 sources/shiboken2/tests/otherbinding/module_reload_test.py create mode 100644 sources/shiboken2/tests/otherbinding/new_ctor_operator_test.py create mode 100644 sources/shiboken2/tests/otherbinding/objtypehashes_test.py create mode 100644 sources/shiboken2/tests/otherbinding/other-binding.txt.in create mode 100644 sources/shiboken2/tests/otherbinding/otherderived_test.py create mode 100644 sources/shiboken2/tests/otherbinding/othertypesystypedef_test.py create mode 100644 sources/shiboken2/tests/otherbinding/signature_test.py create mode 100644 sources/shiboken2/tests/otherbinding/smartptr_test.py create mode 100644 sources/shiboken2/tests/otherbinding/test_module_template.py create mode 100644 sources/shiboken2/tests/otherbinding/typediscovery_test.py create mode 100644 sources/shiboken2/tests/otherbinding/typesystem_other.xml create mode 100644 sources/shiboken2/tests/otherbinding/usersprimitivefromothermodule_test.py create mode 100644 sources/shiboken2/tests/otherbinding/wrongctor_test.py create mode 100644 sources/shiboken2/tests/py3k.py create mode 100644 sources/shiboken2/tests/py3kcompat.py create mode 100644 sources/shiboken2/tests/samplebinding/CMakeLists.txt create mode 100644 sources/shiboken2/tests/samplebinding/__del___test.py create mode 100644 sources/shiboken2/tests/samplebinding/abstract_test.py create mode 100644 sources/shiboken2/tests/samplebinding/addedfunction_test.py create mode 100644 sources/shiboken2/tests/samplebinding/addedfunction_with_container_args_test.py create mode 100644 sources/shiboken2/tests/samplebinding/argumentmodifications_test.py create mode 100644 sources/shiboken2/tests/samplebinding/array_numpy_test.py create mode 100644 sources/shiboken2/tests/samplebinding/array_sequence_test.py create mode 100644 sources/shiboken2/tests/samplebinding/bug_554_test.py create mode 100644 sources/shiboken2/tests/samplebinding/bug_704_test.py create mode 100644 sources/shiboken2/tests/samplebinding/bytearray_bufferprotocol.cpp create mode 100644 sources/shiboken2/tests/samplebinding/bytearray_test.py create mode 100644 sources/shiboken2/tests/samplebinding/child_return_test.py create mode 100644 sources/shiboken2/tests/samplebinding/class_fields_test.py create mode 100644 sources/shiboken2/tests/samplebinding/collector_test.py create mode 100644 sources/shiboken2/tests/samplebinding/complex_test.py create mode 100644 sources/shiboken2/tests/samplebinding/conversion_operator_test.py create mode 100644 sources/shiboken2/tests/samplebinding/copy_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ctorconvrule_test.py create mode 100644 sources/shiboken2/tests/samplebinding/cyclic_test.py create mode 100644 sources/shiboken2/tests/samplebinding/date_test.py create mode 100644 sources/shiboken2/tests/samplebinding/decisor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/delete_test.py create mode 100644 sources/shiboken2/tests/samplebinding/deprecated_test.py create mode 100644 sources/shiboken2/tests/samplebinding/derived_test.py create mode 100644 sources/shiboken2/tests/samplebinding/duck_punching_test.py create mode 100644 sources/shiboken2/tests/samplebinding/echo_test.py create mode 100644 sources/shiboken2/tests/samplebinding/enum_test.py create mode 100644 sources/shiboken2/tests/samplebinding/enumfromremovednamespace_test.py create mode 100644 sources/shiboken2/tests/samplebinding/event_loop_call_virtual_test.py create mode 100644 sources/shiboken2/tests/samplebinding/event_loop_thread_test.py create mode 100644 sources/shiboken2/tests/samplebinding/exception_test.py create mode 100644 sources/shiboken2/tests/samplebinding/filter_test.py create mode 100644 sources/shiboken2/tests/samplebinding/global.h create mode 100644 sources/shiboken2/tests/samplebinding/handleholder_test.py create mode 100644 sources/shiboken2/tests/samplebinding/hashabletype_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ignorederefop_test.py create mode 100644 sources/shiboken2/tests/samplebinding/implicitconv_numerical_test.py create mode 100644 sources/shiboken2/tests/samplebinding/implicitconv_test.py create mode 100644 sources/shiboken2/tests/samplebinding/inheritanceandscope_test.py create mode 100644 sources/shiboken2/tests/samplebinding/injectcode_test.py create mode 100644 sources/shiboken2/tests/samplebinding/innerclass_test.py create mode 100644 sources/shiboken2/tests/samplebinding/intlist_test.py create mode 100644 sources/shiboken2/tests/samplebinding/invalid_virtual_return_test.py create mode 100644 sources/shiboken2/tests/samplebinding/keep_reference_test.py create mode 100644 sources/shiboken2/tests/samplebinding/list_test.py create mode 100644 sources/shiboken2/tests/samplebinding/lock_test.py create mode 100644 sources/shiboken2/tests/samplebinding/map_test.py create mode 100644 sources/shiboken2/tests/samplebinding/metaclass_test.py create mode 100644 sources/shiboken2/tests/samplebinding/mi_virtual_methods_test.py create mode 100644 sources/shiboken2/tests/samplebinding/mixed_mi_test.py create mode 100644 sources/shiboken2/tests/samplebinding/modelindex_test.py create mode 100644 sources/shiboken2/tests/samplebinding/modelview_test.py create mode 100644 sources/shiboken2/tests/samplebinding/modifications_test.py create mode 100644 sources/shiboken2/tests/samplebinding/modified_constructor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/modifiedvirtualmethods_test.py create mode 100644 sources/shiboken2/tests/samplebinding/multi_cpp_inheritance_test.py create mode 100644 sources/shiboken2/tests/samplebinding/multiple_derived_test.py create mode 100644 sources/shiboken2/tests/samplebinding/namespace_test.py create mode 100644 sources/shiboken2/tests/samplebinding/newdivision_test.py create mode 100644 sources/shiboken2/tests/samplebinding/nondefaultctor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/nontypetemplate_test.py create mode 100644 sources/shiboken2/tests/samplebinding/nonzero_test.py create mode 100644 sources/shiboken2/tests/samplebinding/numericaltypedef_test.py create mode 100644 sources/shiboken2/tests/samplebinding/numpy_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttype_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttype_with_named_args_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttypebyvalue_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttypelayout_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttypeoperators_test.py create mode 100644 sources/shiboken2/tests/samplebinding/objecttypereferenceasvirtualmethodargument_test.py create mode 100644 sources/shiboken2/tests/samplebinding/oddbool_test.py create mode 100644 sources/shiboken2/tests/samplebinding/oldstyleclass_as_number_test.py create mode 100644 sources/shiboken2/tests/samplebinding/onlycopyclass_test.py create mode 100644 sources/shiboken2/tests/samplebinding/overflow_test.py create mode 100644 sources/shiboken2/tests/samplebinding/overload_sorting_test.py create mode 100644 sources/shiboken2/tests/samplebinding/overload_test.py create mode 100644 sources/shiboken2/tests/samplebinding/overloadwithdefault_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_argument_invalidation_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_delete_child_in_cpp_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_delete_child_in_python_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_delete_parent_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_invalidate_after_use_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_invalidate_child_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_invalidate_nonpolymorphic_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_invalidate_parent_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_reparenting_test.py create mode 100644 sources/shiboken2/tests/samplebinding/ownership_transference_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pair_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pen_test.py create mode 100644 sources/shiboken2/tests/samplebinding/point_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pointerholder_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pointerprimitivetype_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pointf_test.py create mode 100644 sources/shiboken2/tests/samplebinding/primitivereferenceargument_test.py create mode 100644 sources/shiboken2/tests/samplebinding/privatector_test.py create mode 100644 sources/shiboken2/tests/samplebinding/privatedtor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/protected_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pstrlist_test.py create mode 100644 sources/shiboken2/tests/samplebinding/pystr_test.py create mode 100644 sources/shiboken2/tests/samplebinding/python_thread_test.py create mode 100644 sources/shiboken2/tests/samplebinding/receive_null_cstring_test.py create mode 100644 sources/shiboken2/tests/samplebinding/reference_test.py create mode 100644 sources/shiboken2/tests/samplebinding/referencetopointer_test.py create mode 100644 sources/shiboken2/tests/samplebinding/renaming_test.py create mode 100644 sources/shiboken2/tests/samplebinding/return_null_test.py create mode 100644 sources/shiboken2/tests/samplebinding/richcompare_test.py create mode 100644 sources/shiboken2/tests/samplebinding/sample-binding.txt.in create mode 100644 sources/shiboken2/tests/samplebinding/sample_test.py create mode 100644 sources/shiboken2/tests/samplebinding/simplefile_glue.cpp create mode 100644 sources/shiboken2/tests/samplebinding/simplefile_test.py create mode 100644 sources/shiboken2/tests/samplebinding/size_test.py create mode 100644 sources/shiboken2/tests/samplebinding/static_nonstatic_methods_test.py create mode 100644 sources/shiboken2/tests/samplebinding/str_test.py create mode 100644 sources/shiboken2/tests/samplebinding/strlist_test.py create mode 100644 sources/shiboken2/tests/samplebinding/templateinheritingclass_test.py create mode 100644 sources/shiboken2/tests/samplebinding/time_test.py create mode 100644 sources/shiboken2/tests/samplebinding/transform_test.py create mode 100644 sources/shiboken2/tests/samplebinding/typeconverters_test.py create mode 100644 sources/shiboken2/tests/samplebinding/typedealloc_test.py create mode 100644 sources/shiboken2/tests/samplebinding/typedtordoublefree_test.py create mode 100644 sources/shiboken2/tests/samplebinding/typesystem_sample.xml create mode 100644 sources/shiboken2/tests/samplebinding/typesystypedef_test.py create mode 100644 sources/shiboken2/tests/samplebinding/unsafe_parent_test.py create mode 100644 sources/shiboken2/tests/samplebinding/useraddedctor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/virtualdtor_test.py create mode 100644 sources/shiboken2/tests/samplebinding/virtualmethods_test.py create mode 100644 sources/shiboken2/tests/samplebinding/visibilitychange_test.py create mode 100644 sources/shiboken2/tests/samplebinding/voidholder_test.py create mode 100644 sources/shiboken2/tests/samplebinding/weakref_test.py create mode 100644 sources/shiboken2/tests/samplebinding/writableclassdict_test.py create mode 100644 sources/shiboken2/tests/shiboken_paths.py create mode 100644 sources/shiboken2/tests/shiboken_test_helper.py create mode 100644 sources/shiboken2/tests/shibokenmodule/module_test.py create mode 100644 sources/shiboken2/tests/smartbinding/CMakeLists.txt create mode 100644 sources/shiboken2/tests/smartbinding/global.h create mode 100644 sources/shiboken2/tests/smartbinding/smart-binding.txt.in create mode 100644 sources/shiboken2/tests/smartbinding/smart_pointer_test.py create mode 100644 sources/shiboken2/tests/smartbinding/typesystem_smart.xml create mode 100644 sources/shiboken2/tests/sphinxtabletest.cpp create mode 100644 sources/shiboken2/tests/sphinxtabletest.h create mode 100644 sources/shiboken2/tests/test_generator/CMakeLists.txt create mode 100644 sources/shiboken2/tests/test_generator/dummygenerator.cpp create mode 100644 sources/shiboken2/tests/test_generator/dummygenerator.h create mode 100644 sources/shiboken2/tests/test_generator/dummygentest-project.txt.in create mode 100644 sources/shiboken2/tests/test_generator/dummygentest.cpp create mode 100644 sources/shiboken2/tests/test_generator/dummygentest.h create mode 100644 sources/shiboken2/tests/test_generator/dummygentestconfig.h.in create mode 100644 sources/shiboken2/tests/test_generator/main.cpp create mode 100644 sources/shiboken2/tests/test_generator/run_test.cmake create mode 100644 sources/shiboken2/tests/test_generator/test_global.h create mode 100644 sources/shiboken2/tests/test_generator/test_typesystem.xml create mode 100644 testing/__init__.py create mode 100644 testing/blacklist.py create mode 100644 testing/buildlog.py create mode 100644 testing/command.py create mode 100644 testing/helper.py create mode 100644 testing/parser.py create mode 100644 testing/runner.py create mode 100644 testing/testing.pyproject create mode 100644 testing/wheel_tester.py create mode 100644 testrunner.py create mode 100644 tools/checklibs.py create mode 100644 tools/create_changelog.py create mode 100644 tools/debug_windows.py create mode 100644 tools/dump_metaobject.py create mode 100644 tools/metaobject_dump.py create mode 100644 tools/metaobject_dump.pyproject create mode 100644 tools/missing_bindings-requirements.txt create mode 100644 tools/missing_bindings.py create mode 100644 tools/qtpy2cpp.py create mode 100644 tools/qtpy2cpp.pyproject create mode 100644 tools/qtpy2cpp_lib/astdump.py create mode 100644 tools/qtpy2cpp_lib/formatter.py create mode 100644 tools/qtpy2cpp_lib/nodedump.py create mode 100644 tools/qtpy2cpp_lib/test_baseline/basic_test.py create mode 100644 tools/qtpy2cpp_lib/test_baseline/uic.py create mode 100644 tools/qtpy2cpp_lib/tokenizer.py create mode 100644 tools/qtpy2cpp_lib/visitor.py diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..0848fed --- /dev/null +++ b/.gitattributes @@ -0,0 +1,15 @@ +# Set the default behavior, in case people don't have core.autocrlf set. +* text=auto + +# Explicitly declare text files you want to always be normalized and converted +# to native line endings on checkout. +*.c text +*.h text +*.py text + +# Declare files that will always have CRLF line endings on checkout. +*.sln text eol=crlf + +# Denote all files that are truly binary and should not be modified. +*.png binary +*.jpg binary \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c4bc8c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,152 @@ +## PySide2 +/pyside*_build +/pyside*_install +/PySide +/PySide-*.*.* +/SciTE.* +/pysideuic + +distribute-*.egg +distribute-*.tar.gz +explore2 +build_history/2* + +*.qdocconf +*.qdocconf.in + +*.egg-info +*.pyc + +## C++ + +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app + +## Python +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +#dist/ # we place the changelogs here +downloads/ +eggs/ +.eggs/ +/lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +pip-wheel-metadata/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Translations +*.mo +*.pot + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don’t work, or not +# install all needed dependencies. +#Pipfile.lock + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +## CMake +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +#Testing Conflicts with the testing directory +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..42712d6 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "sources/pyside2-tools"] + path = sources/pyside2-tools + url = ../pyside-tools.git diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..8429d3a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: python +dist: trusty +python: + - "2.7" + - "3.5" +before_install: + - sudo add-apt-repository ppa:beineri/opt-qt551-trusty -y + - sudo apt-get update +install: + - sudo apt-get install qt55-meta-full -y +script: + - source /opt/qt55/bin/qt55-env.sh + - python setup.py install --jobs=2 --build-tests # --openssl=/path/to/openssl/bin + # how do we separate the build step and the tests, to see both as a result? diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..595489d --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +set(CMAKE_BUILD_TYPE Release CACHE STRING "Build Type") + +project(pyside2_super_project) + +if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR) + message(FATAL_ERROR "In-source builds are not allowed.") +endif() + +# Used to prevent overriding message function in both shiboken2 and pyside2. +set(is_pyside2_superproject_build 1) + +add_subdirectory(sources/shiboken2) + +# Semi-hack to include exported shiboken variables. +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/sources/shiboken2/data") +add_subdirectory(sources/pyside2) + +# Semi-hack to include exported pyside2 variables. +list(APPEND CMAKE_PREFIX_PATH "${CMAKE_CURRENT_BINARY_DIR}/sources/pyside2/libpyside") +add_subdirectory(sources/pyside2-tools) diff --git a/LICENSE.COMMERCIAL b/LICENSE.COMMERCIAL new file mode 100644 index 0000000..5dcd1f6 --- /dev/null +++ b/LICENSE.COMMERCIAL @@ -0,0 +1,914 @@ +QT LICENSE AGREEMENT Agreement version 4.0 + +This License Agreement (“Agreement”) is a legal agreement between The Qt +Company (as defined below) and the Licensee (as defined below) for the license +of Licensed Software (as defined below). Capitalized terms used herein are +defined in Section 1. + +WHEREAS: + +(A). Licensee wishes to use the Licensed Software for the purpose of developing +and distributing Applications and/or Devices; and + +(B). The Qt Company is willing to grant the Licensee a right to use Licensed +Software for such purpose pursuant to term and conditions of this Agreement. + +NOW, THEREFORE, THE PARTIES HEREBY AGREE AS FOLLOWS: + +1. DEFINITIONS + +“Affiliate” of a Party shall mean an entity (i) which is directly or indirectly +controlling such Party; (ii) which is under the same direct or indirect +ownership or control as such Party; or (iii) which is directly or indirectly +owned or controlled by such Party. For these purposes, an entity shall be +treated as being controlled by another if that other entity has fifty percent +(50 %) or more of the votes in such entity, is able to direct its affairs +and/or to control the composition of its board of directors or equivalent body. + +“Applications” shall mean Licensee's software products created using the +Licensed Software, which may include the Redistributables, or part +thereof. + +“Contractor(s)” shall mean third party consultants, distributors and +contractors performing services to a Party under applicable contractual +arrangement. + +“Customer(s)” shall mean Licensee’s end users to whom Licensee, directly or +indirectly, distributes copies of the Redistributables. + +“Deployment Platforms” shall mean operating systems specified in the License +Certificate, in which the Redistributables can be distributed pursuant to the +terms and conditions of this Agreement. + +“Designated User(s)” shall mean the employee(s) of Licensee or Licensee’s +Affiliates acting within the scope of their employment or Licensee's +Contractors acting within the scope of their services for Licensee and on +behalf of Licensee. Designated Users shall be named in the License Certificate. + +“Development License” shall mean the license needed by the Licensee for each +Designated User to use the Licensed Software under the license grant described +in Section 3.1 of this Agreement. + +“Development Platforms” shall mean those operating systems specified in the +License Certificate, in which the Licensed Software can be used under the +Development License, but not distributed in any form or used for any other +purpose. + +“Devices” shall mean hardware devices or products that 1) are manufactured +and/or distributed by the Licensee or its Affiliates or Contractors, and +(2)(i) incorporate or integrate the Redistributables or parts thereof; or (ii) +do not incorporate or integrate the Redistributables at the time of +distribution, but where, when used by a Customer, the main user interface or +substantial functionality of such device is provided by Application(s) or +otherwise depends on the Licensed Software. + +“Distribution License(s)” shall mean the license required for distribution of +Redistributables in connection with Devices pursuant to license grant described +in Section 3.3 of this Agreement. + +“Distribution License Packs” shall mean set of prepaid Distribution Licenses +for distribution of Redistributables, as defined in The Qt Company’s standard +price list, quote, Purchase Order confirmation or in an appendix hereto, +as the case may be. + +“Intellectual Property Rights” shall mean patents (including utility models), +design patents, and designs (whether or not capable of registration), chip +topography rights and other like protection, copyrights, trademarks, service +marks, trade names, logos or other words or symbols and any other form of +statutory protection of any kind and applications for any of the foregoing as +well as any trade secrets. + +“License Certificate” shall mean a certificate generated by The Qt Company for +each Designated User respectively upon them downloading the licensed Software. +License Certificate will be available under respective Designated User’s Qt +Account at account.qt.io and it will specify the Designated User, the +Development Platforms, Deployment Platforms and the License Term. The terms of +the License Certificate are considered part of this Agreement and shall be +updated from time to time to reflect any agreed changes to the foregoing terms +relating to Designated User’s rights to the Licensed Software. + +“License Fee” shall mean the fee charged to the Licensee for rights granted +under the terms of this Agreement. + +“License Term” shall mean the agreed validity period of the Development +License of the respective Designated User, during which time the +Designated User is entitled to use the Licensed Software, as set forth in the +respective License Certificate. + +“Licensed Software” shall mean all versions of the + +(i) Qt Toolkit (including Qt Essentials, Qt Add-Ons and Value-Add modules) as +described in http://doc.qt.io/qt-5/qtmodules.html, + +(ii). Qt Creator (including Creator IDE tool) as described in +http://doc.qt.io/qtcreator/index.html, + +(iii). Qt 3D Studio as described in http://doc.qt.io/qt3dstudio/index.html, and + +as well as corresponding online or electronic documentation, associated media +and printed materials, including the source code, example programs and the +documentation, licensed to the Licensee under this Agreement. Licensed Software +does not include Third Party Software (as defined in Section 4), Open Source +Qt, or other software products of The Qt Company (for example Qt Safe Renderer +and Qt for Automation), unless such other software products of The Qt Company +are separately agreed in writing to be included in scope of the Licensed +Software. + +“Licensee” shall mean the individual or legal entity that is party to this +Agreement, as identified on the signature page hereof. + +“Licensee’s Records” shall mean books and records that are likely to contain +information bearing on Licensee’s compliance with this Agreement or the +payments due to The Qt Company under this Agreement, including, but not limited +to: assembly logs, sales records and distribution records. + +“Modified Software” shall have the meaning as set forth in Section 2.3. + +“Online Services” shall mean any services or access to systems made available +by The Qt Company to the Licensee over the Internet relating to the Licensed +Software or for the purpose of use by the Licensee of the Licensed Software or +Support. Use of any such Online Services is discretionary for the Licensee and +some of them may be subject to additional fees. + +“Open Source Qt” shall mean the non-commercial Qt computer software products, +licensed under the terms of the GNU Lesser General Public License, version +2.1 or later (“LGPL”) or the GNU General Public License, version 2.0 or later +(“GPL”). For clarity, Open Source Qt shall not be provided nor governed under +this Agreement. + +”Party” or “Parties” shall mean Licensee and/or The Qt Company. + +"Redistributables" shall mean the portions of the Licensed Software set forth +in Appendix 1, Section 1 that may be distributed pursuant to the terms of this +Agreement in object code form only, including any relevant documentation. +Where relevant, any reference to Licensed Software in this Agreement shall +include and refer also to Redistributables. + +“Renewal Term” shall mean an extension of previous License Term as agreed +between the Parties. + +“Submitted Modified Software” shall have the meaning as set forth in +Section 2.3. + +“Support” shall mean standard developer support that is provided by The Qt +Company to assist Designated Users in using the Licensed Software in +accordance with The Qt Company’s standard support terms and as further +defined in Section 8 hereunder. + +“Taxes” shall have the meaning set forth in Section 10.5. + +“Term” shall have the meaning set forth in Section 12. + + “The Qt Company” shall mean: + +(i) in the event Licensee is an individual residing in the United States or a +legal entity incorporated in the United States or having its headquarters in +the United States, The Qt Company Inc., a Delaware corporation with its office +at 2350 Mission College Blvd., Suite 1020, Santa Clara, CA 95054, USA.; or + +(ii) in the event the Licensee is an individual residing outside of the United +States or a legal entity incorporated outside of the United States or having +its registered office outside of the United States, The Qt Company Ltd., a +Finnish company with its registered office at Bertel Jungin aukio D3A, 02600 +Espoo, Finland. + +"Third Party Software " shall have the meaning set forth in Section 4. + +“Updates” shall mean a release or version of the Licensed Software containing +bug fixes, error corrections and other changes that are generally made +available to users of the Licensed Software that have contracted for Support. +Updates are generally depicted as a change to the digits following the decimal +in the Licensed Software version number. The Qt Company shall make Updates +available to the Licensee under the Support. Updates shall be considered as +part of the Licensed Software hereunder. + +“Upgrades” shall mean a release or version of the Licensed Software containing +enhancements and new features and are generally depicted as a change to the +first digit of the Licensed Software version number. In the event Upgrades are +provided to the Licensee under this Agreement, they shall be considered as +part of the Licensed Software hereunder. + +2. OWNERSHIP + +2.1 Ownership of The Qt Company + +The Licensed Software is protected by copyright laws and international +copyright treaties, as well as other intellectual property laws and treaties. +The Licensed Software is licensed, not sold. + +All The Qt Company's Intellectual Property Rights are and shall remain the +exclusive property of The Qt Company or its licensors respectively. + +2.2 Ownership of Licensee + +All the Licensee's Intellectual Property Rights are and shall remain the +exclusive property of the Licensee or its licensors respectively. + +All Intellectual Property Rights to the Modified Software, Applications and +Devices shall remain with the Licensee and no rights thereto shall be granted +by the Licensee to The Qt Company under this Agreement (except as set forth in +Section 2.3 below). + +2.3 Modified Software + +Licensee may create bug-fixes, error corrections, patches or modifications to +the Licensed Software (“Modified Software”). Such Modified Software may break +the source or binary compatibility with the Licensed Software (including +without limitation through changing the application programming interfaces +("API") or by adding, changing or deleting any variable, method, or class +signature in the Licensed Software and/or any inter-process protocols, services +or standards in the Licensed Software libraries). To the extent that Licensee’s +Modified Software so breaks source or binary compatibility with the Licensed +Software, Licensee acknowledges that The Qt Company's ability to provide +Support may be prevented or limited and Licensee's ability to make use of +Updates may be restricted. + +Licensee may, at its sole and absolute discretion, choose to submit Modified +Software to The Qt Company (“Submitted Modified Software”) in connection with +Licensee’s Support request, service request or otherwise. In the event Licensee +does so, then, Licensee hereby grants The Qt Company a sublicensable, +assignable, irrevocable, perpetual, worldwide, non-exclusive, royalty-free and +fully paid-up license, under all of Licensee’s Intellectual Property Rights, to +reproduce, adapt, translate, modify, and prepare derivative works of, publicly +display, publicly perform, sublicense, make available and distribute such +Submitted Modified Software as The Qt Company sees fit at its free and absolute +discretion. + +3. LICENSES GRANTED + +3.1 Development with Licensed Software + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +personal, worldwide, non-exclusive, non-transferable license, valid for the +License Term, to use, modify and copy the Licensed Software by Designated Users +on the Development Platforms for the sole purposes of designing, developing, +demonstrating and testing Application(s) and/or Devices, and to provide thereto +related support and other related services to end-user Customers. + +Licensee may install copies of the Licensed Software on an unlimited number of +computers provided that (i) only the Designated Users may use the Licensed +Software, and (ii) all Designated Users must have a valid Development License +to use Licensed Software. + +Licensee may at any time designate another Designated User to replace a then- +current Designated User by notifying The Qt Company in writing, provided that +any Designated User may be replaced only once during any six-month period. + +Upon expiry of the initially agreed License Term, the respective License Terms +shall be automatically extended to one or more Renewal Term(s), unless and +until either Party notifies the other Party in writing that it does not wish to +continue the License Term, such notification to be provided to the other Party +no less than ninety (90) days before expiry of the respective License Term. +Unless otherwise agreed between the Parties, Renewal Term shall be of equal +length with the initial Term. + +Any such Renewal Term shall be subject to License Fees agreed between the +Parties or, if no advance agreement exists, subject to The Qt Company’s +standard pricing applicable at the commencement date of any such Renewal Term. + +3.2 Distribution of Applications + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +personal, worldwide, non-exclusive, non-transferable, revocable (for cause +pursuant to this Agreement) right and license, valid for the Term, to + +(i) distribute, by itself or through its Contractors, Redistributables as +installed, incorporated or integrated into Applications for execution on the +Deployment Platforms, and + +(ii) grant sublicenses to Redistributables, as distributed hereunder, for +Customers solely for Customer’s internal use and to the extent necessary in +order for the Customers to use the Applications for their respective intended +purposes. + +Right to distribute the Redistributables as part of an Application as provided +herein is not royalty-bearing but is conditional upon the Licensee having paid +the agreed Development Licenses from The Qt Company before distributing any +Redistributables to Customers. + +3.3 Distribution of Devices + +Subject to the terms of this Agreement, The Qt Company grants to Licensee a +personal, worldwide, non-exclusive, non-transferable, revocable (for cause +pursuant to this Agreement) right and license, valid for the Term, to + +(i) distribute, by itself or through one or more tiers of Contractors, +Redistributables as installed, incorporated or integrated, or intended to be +installed, incorporated or integrated into Devices for execution on the +Deployment Platforms, and + +(ii) grant sublicenses to Redistributables, as distributed hereunder, for +Customers solely for Customer’s internal use and to the extent necessary in +order for the Customers to use the Devices for their respective intended +purposes. + +Right to distribute the Redistributables with Devices as provided herein is +conditional upon the Licensee having purchased and paid the appropriate amount +of Development and Distribution Licenses from The Qt Company before +distributing any Redistributables to Customers. + +3.4 Further Requirements + +The licenses granted above in this Section 3 by The Qt Company to Licensee are +conditional and subject to Licensee's compliance with the following terms: + +(i) Licensee shall not remove or alter any copyright, trademark or other +proprietary rights notice contained in any portion of the Licensed Software; + +(ii) Applications must add primary and substantial functionality to the +Licensed Software; + +(iii) Applications may not pass on functionality which in any way makes it +possible for others to create software with the Licensed Software; provided +however that Licensee may use the Licensed Software's scripting and QML ("Qt +Quick") functionality solely in order to enable scripting, themes and styles +that augment the functionality and appearance of the Application(s) without +adding primary and substantial functionality to the Application(s); + +(iv) Applications must not compete with the Licensed Software; + +(v) Licensee shall not use The Qt Company's or any of its suppliers' names, +logos, or trademarks to market Applications, except that Licensee may use +“Built with Qt” logo to indicate that Application(s) was developed using the +Licensed Software; + +(vi) Licensee shall not distribute, sublicense or disclose source code of +Licensed Software to any third party (provided however that Licensee may +appoint employee(s) of Contractors as Designated Users to use Licensed +Software pursuant to this Agreement). Such right may be available for the +Licensee subject to a separate software development kit (“SDK”) license +agreement to be concluded with The Qt Company; + +(vii) Licensee shall not grant the Customers a right to (i) make copies of the +Redistributables except when and to the extent required to use the Applications +and/or Devices for their intended purpose, (ii) modify the Redistributables or +create derivative works thereof, (iii) decompile, disassemble or otherwise +reverse engineer Redistributables, or (iv) redistribute any copy or portion of +the Redistributables to any third party, except as part of the onward sale of +the Device on which the Redistributables are installed; + +(viii) Licensee shall not and shall cause that its Affiliates or Contractors +shall not a) in any way combine, incorporate or integrate Licensed Software +with, or use Licensed Software for creation of, any software created with or +incorporating Open Source Qt, or b) incorporate or integrate Applications +into a hardware device or product other than a Device, unless Licensee has +received an advance written permission from The Qt Company to do so. Absent +such written permission, any and all distribution by the Licensee during the +Term of a hardware device or product a) which incorporate or integrate any +part of Licensed Software or Open Source Qt; or b) where the main user +interface or substantial functionality is provided by software build with +Licensed Software or Open Source Qt or otherwise depends on the Licensed +Software or Open Source Qt, shall be considered as a Device distribution under +this Agreement and dependent on compliance thereof (including but not limited +to obligation to pay applicable License Fees for such distribution); + +(ix) Licensee shall cause all of its Affiliates and Contractors entitled to +make use of the licenses granted under this Agreement, to be contractually +bound to comply with the relevant terms of this Agreement and not to use the +Licensed Software beyond the terms hereof and for any purposes other than +operating within the scope of their services for Licensee. Licensee shall be +responsible for any and all actions and omissions of its Affiliates and +Contractors relating to the Licensed Software and use thereof (including but +not limited to payment of all applicable License Fees); + +(x) Except when and to the extent explicitly provided in this Section 3, +Licensee shall not transfer, publish, disclose, display or otherwise make +available the Licensed Software; + +; and + +(xi) Licensee shall not attempt or enlist a third party to conduct or attempt +to conduct any of the above. + +Above terms shall not be applicable if and to the extent they conflict with any +mandatory provisions of any applicable laws. + +Any use of Licensed Software beyond the provisions of this Agreement is +strictly prohibited and requires an additional license from The Qt Company. + +4. THIRD PARTY SOFTWARE + +The Licensed Software may provide links to third party libraries or code +(collectively "Third Party Software") to implement various functions. Third +Party Software does not comprise part of the Licensed Software. In some cases, +access to Third Party Software may be included in the Licensed Software. Such +Third Party Software will be listed in the ".../src/3rdparty" source tree +delivered with the Licensed Software or documented in the Licensed Software, as +such may be amended from time to time. Licensee acknowledges that use or +distribution of Third Party Software is in all respects subject to applicable +license terms of applicable third party right holders. + + 5. PRE-RELEASE CODE + +The Licensed Software may contain pre-release code and functionality marked or +otherwise stated as “Technology Preview”, “Alpha”, “Beta” or similar +designation. Such pre-release code may be present in order to provide +experimental support for new platforms or preliminary versions of one or more +new functionalities. The pre-release code may not be at the level of +performance and compatibility of a final, generally available, product +offering of the Licensed Software. The pre-release parts of the Licensed +Software may not operate correctly, may contain errors and may be substantially +modified by The Qt Company prior to the first commercial product release, if +any. The Qt Company is under no obligation to make pre-release code +commercially available, or provide any Support or Updates relating thereto. The +Qt Company assumes no liability whatsoever regarding any pre-release code, but +any use thereof is exclusively at Licensee’s own risk and expense. + +6. LIMITED WARRANTY AND WARRANTY DISCLAIMER + +The Qt Company hereby represents and warrants that it has the power and +authority to grant the rights and licenses granted to Licensee under this +Agreement. + +Except as set forth above, the Licensed Software is licensed to Licensee +"as is" and Licensee’s exclusive remedy and The Qt Company’s entire liability +for errors in the Licensed Software shall be limited, at The Qt Company’s +option, to correction of the error, replacement of the Licensed Software or +return of the applicable fees paid for the defective Licensed Software for the +time period during which the License is not able to utilize the Licensed +Software under the terms of this Agreement. + +TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE QT COMPANY ON BEHALF OF +ITSELF AND ITS LICENSORS, SUPPLIERS AND AFFILIATES, DISCLAIMS ALL OTHER +WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, ANY IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON- +INFRINGEMENT WITH REGARD TO THE LICENSED SOFTWARE. THE QT COMPANY DOES NOT +WARRANT THAT THE LICENSED SOFTWARE WILL SATISFY LICENSEE’S REQUIREMENTS OR THAT +IT WILL OPERATE WITHOUT DEFECT OR ERROR OR THAT THE OPERATION THEREOF WILL BE +UNINTERRUPTED. ALL USE OF AND RELIANCE ON THE LICENSED SOFTWARE IS AT THE SOLE +RISK OF AND RESPONSIBILITY OF LICENSEE. + +7. INDEMNIFICATION AND LIMITATION OF LIABILITY + +7.1 Limitation of Liability + +EXCEPT FOR (I) CASES OF GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT, AND (II) +BREACH OF CONFIDENTIALITY, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, IN NO +EVENT SHALL EITHER PARTY BE LIABLE TO THE OTHER PARTY FOR ANY LOSS OF PROFIT, +LOSS OF DATA, LOSS OF BUSINESS OR GOODWILL OR ANY OTHER INDIRECT, SPECIAL, +CONSEQUENTIAL, INCIDENTAL OR PUNITIVE COST, DAMAGES OR EXPENSE OF ANY KIND, +HOWSOEVER ARISING UNDER OR IN CONNECTION WITH THIS AGREEMENT. PARTIES +SPECIFICALLY AGREE THAT LICENSEE’S OBLIGATION TO PAY LICENSE AND OTHER FEES +CORRESPONDING TO ACTUAL USAGE OF LICENSED SOFTWARE HEREUNDER SHALL BE +CONSIDERED AS A DIRECT DAMAGE. + +EXCEPT FOR (I) CASES OF GROSS NEGLIGENCE OR INTENTIONAL MISCONDUCT, AND (II) +BREACH OF CONFIDENTIALITY, AND TO THE EXTENT PERMITTED BY APPLICABLE LAW, IN +NO EVENT SHALL EITHER PARTY’S TOTAL AGGREGATE LIABILITY UNDER THIS AGREEMENT +EXCEED THE AGGREGATE LICENSE FEES PAID OR PAYABLE TO THE QT COMPANY FROM +LICENSEE DURING THE PERIOD OF TWELVE (12) MONTHS IMMEDIATELY PRECEDING THE +EVENT RESULTING IN SUCH LIABILITY. + +THE PROVISIONS OF THIS SECTION 7 ALLOCATE THE RISKS UNDER THIS AGREEMENT +BETWEEN THE QT COMPANY AND LICENSEE AND THE PARTIES HAVE RELIED UPON THE +LIMITATIONS SET FORTH HEREIN IN DETERMINING WHETHER TO ENTER INTO THIS AGREEMENT. + +7.2 Licensee´s Indemnification + +Licensee shall indemnify and hold harmless The Qt Company from and against any +claim, injury, judgment, settlement, loss or expense, including attorneys' fees +related to: (a) Licensee’s misrepresentation in connection with The Qt Company +or the Licensed Software or breach of this Agreement, (b) the Application or +Device (except where such cause of liability is solely attributable to the +Licensed Software). + +8. SUPPORT, UPDATES AND ONLINE SERVICES + +Upon due payment of the agreed License Fees the Licensee will be eligible to +receive Support and Updates and to use the Online Services during the License +Term, provided, however, that in the event the License Term is longer than 36 +months, Support is provided only for the first 12 months, unless the Parties +specifically otherwise agree. + +Unless otherwise decided by The Company at its free and absolute discretion, +Upgrades will not be included in the Support but may be available subject to +additional fees. + +From time to time The Qt Company may change the Support terms, provided that +during the respective ongoing License Term the level of Support provided by The +Qt Company may not be reduced without the consent of the Licensee. + +Unless otherwise agreed, The Qt Company shall not be responsible for providing +any service or support to Customers. + +9. CONFIDENTIALITY + +Each Party acknowledges that during the Term of this Agreement each Party may +receive information about the other Party's business, business methods, +business plans, customers, business relations, technology, and other +information, including the terms of this Agreement, that is confidential and +of great value to the other Party, and the value of which would be +significantly reduced if disclosed to third parties (“Confidential +Information”). Accordingly, when a Party (the “Receiving Party”) receives +Confidential Information from the other Party (the “Disclosing Party”), the +Receiving Party shall only disclose such information to employees and +Contractors on a need to know basis, and shall cause its employees and +employees of its Affiliates to: (i) maintain any and all Confidential +Information in confidence; (ii) not disclose the Confidential Information to a +third party without the Disclosing Party's prior written approval; and (iii) +not, directly or indirectly, use the Confidential Information for any purpose +other than for exercising its rights and fulfilling its responsibilities +pursuant to this Agreement. Each Party shall take reasonable measures to +protect the Confidential Information of the other Party, which measures shall +not be less than the measures taken by such Party to protect its own +confidential and proprietary information. + +Obligation of confidentiality shall not apply to information that (i) is or +becomes generally known to the public through no act or omission of the +Receiving Party; (ii) was in the Receiving Party's lawful possession prior to +the disclosure hereunder and was not subject to limitations on disclosure or +use; (iii) is developed independently by employees or Contractors of the +Receiving Party or other persons working for the Receiving Party who have not +had access to the Confidential Information of the Disclosing Party, as proven +by the written records of the Receiving Party; (iv) is lawfully disclosed to +the Receiving Party without restrictions, by a third party not under an +obligation of confidentiality; or (v) the Receiving Party is legally compelled +to disclose, in which case the Receiving Party shall notify the Disclosing +Party of such compelled disclosure and assert the privileged and confidential +nature of the information and cooperate fully with the Disclosing Party to +limit the scope of disclosure and the dissemination of disclosed Confidential +Information to the minimum extent necessary. + +The obligations under this Section 9 shall continue to remain in force for a +period of five (5) years after the last disclosure, and, with respect to trade +secrets, for so long as such trade secrets are protected under applicable trade +secret laws. + +10. FEES, DELIVERY AND PAYMENT + +10.1 License Fees + +License Fees are described in The Qt Company’s standard price list, quote or +Purchase Order confirmation or in an appendix hereto, as the case may be. + +The License Fees shall not be refunded or claimed as a credit in any event or +for any reason whatsoever. + +10.2 Ordering Licenses + +Licensee may purchase Development Licenses and Distribution Licenses pursuant +to agreed pricing terms or, if no specific pricing terms have been agreed upon, +at The Qt Company's standard pricing terms applicable at the time of purchase. + +Licensee shall submit all purchase orders for Development Licenses and +Distribution Licenses to The Qt Company by email or any other method acceptable +to The Qt Company (each such order is referred to herein as a “Purchase Order”) +for confirmation, whereupon the Purchase Order shall become binding between the +Parties. + +10.3 Distribution License Packs + +Unless otherwise agreed, Distribution Licenses shall be purchased by way of +Distribution License Packs. + +Upon due payment of the ordered Distribution License Pack(s), the Licensee will +have an account of Distribution Licenses available for installing, bundling or +integrating (all jointly “installing”) the Redistributables with the Devices or +for otherwise distributing the Redistributables in accordance with this +Agreement. + +Each time Licensee “installs” or distributes a copy of Redistributables, then +one Distribution License is used, and Licensee’s account of available +Distribution Licenses is decreased accordingly. + +Licensee may “install” copies of the Redistributables so long as Licensee has +Distribution Licenses remaining on its account. + +Redistributables will be deemed to have been “installed” into a Device when one +of the following circumstances shall have occurred: a) the Redistributables +have been loaded onto the Device and used outside of the Licensee’s premises or +b) the Device has been fully tested and placed into Licensee's inventory +(or sold) for the first time (i.e., Licensee will not be required to use +(or pay for) more than one Distribution License for each individual Device, +e.g. in a situation where a Device is returned to Licensee's inventory after +delivery to a distributor or sale to a Customer). In addition, if Licensee +includes a back-up copy of the Redistributables on a CD-ROM or other storage +medium along with the product, that backup copy of the Redistributables will +not be deemed to have been “installed” and will not require an additional +Distribution License. + +10.4 Payment Terms + +License Fees and any other charges under this Agreement shall be paid by +Licensee no later than thirty (30) days from the date of the applicable invoice +from The Qt Company. + +The Qt Company will submit an invoice to Licensee after the date of this +Agreement and/or after The Qt Company receives a Purchase Order from +Licensee. + +A late payment charge of the lower of (a) one percent per month; or (b) the +interest rate stipulated by applicable law, shall be charged on any unpaid +balances that remain past due. + +The Qt Company shall have the right to suspend, terminate or withhold grants +of all rights to the Licensed Software hereunder, including but not limited to +the Developer License, Distribution License, and Support, should Licensee fail +to make payment in timely fashion. + +10.5 Taxes + +All License Fees and other charges payable hereunder are gross amounts but +exclusive of any value added tax, use tax, sales tax and other taxes, duties or +tariffs (“Taxes”). Such applicable Taxes shall be paid by Licensee, or, where +applicable, in lieu of payment of such Taxes, Licensee shall provide an +exemption certificate to The Qt Company and any applicable authority. + +11 RECORD-KEEPING AND REPORTING OBLIGATIONS; AUDIT RIGHTS + +11.1 Licensee’s Record-keeping + +Licensee shall at all times maintain accurate and up-to-date written records of +Licensee’s activities related to the use of Licensed Software and distribution +of Redistributables. The records shall be adequate to determine Licensee’s +compliance with the provisions of this Agreement and to demonstrate the number +of Designated Users and Redistributables distributed by Licensee. The records +shall conform to good accounting practices reasonably acceptable to The Qt +Company. + +Licensee shall, within thirty (30) days from receiving The Qt Company’s request +to that effect, deliver to The Qt Company a report on Licensee’s usage of +Licensed Software, such report to copies of Redistributables distributed by +Licensee during that calendar quarter, and also detailing the number of +undistributed copies of Redistributables made by Licensee and remaining in its +account contain information, in sufficient detail, on (i) amount of users +working with Licensed Software, (ii) copies of Redistributables distributed by +Licensee during that calendar quarter, (iii) number of undistributed copies of +Redistributables and corresponding number of unused Distribution Licenses +remaining on Licensee’s account, and (iv) any other information as The Qt +Company may reasonably require from time to time. + +11.2. The Qt Company’s Audit Rights + +The Qt Company or an independent auditor acting on behalf of The Qt Company’s, +may, upon at least five (5) business days’ prior written notice and at its +expense, audit Licensee with respect to the use of the Redistributables, but +not more frequently than once during each 6-month period. Such audit may be +conducted by mail, electronic means or through an in-person visit to Licensee’s +place of business. Any such in-person audit shall be conducted during regular +business hours at Licensee's facilities and shall not unreasonably interfere +with Licensee's business activities. The Qt Company or the independent auditor +acting on behalf of The Qt Company shall be entitled to inspect Licensee’s +Records. All such Licensee’s Records and use thereof shall be subject to an +obligation of confidentiality under this Agreement. + +If an audit reveals that Licensee is using the Licensed Software beyond scope +of the licenses Licensee has paid for, Licensee agrees to immediately pay The +Qt Company any amounts owed for such unauthorized use. + +In addition, in the event the audit reveals a material violation of the terms +of this Agreement (underpayment of more than 5% of License Fees shall always be +deemed a material violation for purposes of this section), then the Licensee +shall pay The Qt Company's reasonable cost of conducting such audit. + +12 TERM AND TERMINATION + +12.1 Term + +This Agreement shall enter into force upon due acceptance by both Parties and +remain in force for as long as there is any Development License(s) in force +(“Term”), unless and until terminated pursuant to the terms of this Section 12. + +12.2 Termination by The Qt Company + +The Qt Company shall have the right to terminate this Agreement upon thirty +(30) days prior written notice if the Licensee is in material breach of any +obligation of this Agreement and fails to remedy such breach within such notice +period. + +12.3 Mutual Right to Terminate + +Either Party shall have the right to terminate this Agreement immediately upon +written notice in the event that the other Party becomes insolvent, files for +any form of bankruptcy, makes any assignment for the benefit of creditors, has +a receiver, administrative receiver or officer appointed over the whole or a +substantial part of its assets, ceases to conduct business, or an act +equivalent to any of the above occurs under the laws of the jurisdiction of the +other Party. + +12.4 Parties´ Rights and Duties upon Termination + +Upon expiry or termination of the Agreement Licensee shall cease and shall +cause all Designated Users (including those of its Affiliates’ and +Contractors’) to cease using the Licensed Software and distribution of the +Redistributables under this Agreement. + +Notwithstanding the above, in the event the Agreement expires or is terminated: + +(i) as a result of The Qt Company choosing not to renew the Development +License(s) as set forth in Section 3.1, then all valid licenses possessed by +the Licensee at such date shall be extended to be valid in perpetuity under the +terms of this Agreement and Licensee is entitled to purchase additional +licenses as set forth in Section 10.2; or + +(ii) for reason other than by The Qt Company pursuant to item (i) above or +pursuant to Section 12.2, then the Licensee is entitled, for a period of six +(6) months after the effective date of termination, to continue distribution of +Devices under the Distribution Licenses paid but unused at such effective date +of termination. + +Upon any such termination the Licensee shall destroy or return to The Qt +Company all copies of the Licensed Software and all related materials and will +certify the same to The Qt Company upon its request, provided however that +Licensee may retain and exploit such copies of the Licensed Software as it may +reasonably require in providing continued support to Customers. + +Expiry or termination of this Agreement for any reason whatsoever shall not +relieve Licensee of its obligation to pay any License Fees accrued or payable +to The Qt Company prior to the effective date of termination, and Licensee +shall immediately pay to The Qt Company all such fees upon the effective date +of termination. Termination of this Agreement shall not affect any rights of +Customers to continue use of Applications and Devices (and therein incorporated +Redistributables). + +12.5 Extension in case of bankruptcy + +In the event The Qt Company is declared bankrupt under a final, non-cancellable +decision by relevant court of law, and this Agreement is not, at the date of +expiry of the Development License(s) pursuant to Section 3.1, assigned to +party, who has assumed The Qt Company’s position as a legitimate licensor of +Licensed Software under this Agreement, then all valid licenses possessed by +the Licensee at such date of expiry, and which the Licensee has not notified +for expiry, shall be extended to be valid in perpetuity under the terms of +this Agreement. + +13. GOVERNING LAW AND LEGAL VENUE + +In the event this Agreement is in the name of The Qt Company Inc., a Delaware +Corporation, then: + +(i) this Agreement shall be construed and interpreted in accordance with the +laws of the State of California, USA, excluding its choice of law provisions; + +(ii) the United Nations Convention on Contracts for the International Sale of +Goods will not apply to this Agreement; and + +(iii) any dispute, claim or controversy arising out of or relating to this +Agreement or the breach, termination, enforcement, interpretation or validity +thereof, including the determination of the scope or applicability of this +Agreement to arbitrate, shall be determined by arbitration in San Francisco, +USA, before one arbitrator. The arbitration shall be administered by JAMS +pursuant to JAMS' Streamlined Arbitration Rules and Procedures. Judgment on the +Award may be entered in any court having jurisdiction. This Section shall not +preclude parties from seeking provisional remedies in aid of arbitration from a +court of appropriate jurisdiction. + +In the event this Agreement is in the name of The Qt Company Ltd., a Finnish +Company, then: + +(i) this Agreement shall be construed and interpreted in accordance with the +laws of Finland, excluding its choice of law provisions; + +(ii) the United Nations Convention on Contracts for the International Sale of +Goods will not apply to this Agreement; and + +(iii) any disputes, controversy or claim arising out of or relating to this +Agreement, or the breach, termination or validity thereof shall be shall be +finally settled by arbitration in accordance with the Arbitration Rules of +Finland Chamber of Commerce. The arbitration tribunal shall consist of one (1), +or if either Party so requires, of three (3), arbitrators. The award shall be +final and binding and enforceable in any court of competent jurisdiction. The +arbitration shall be held in Helsinki, Finland and the process shall be +conducted in the English language. This Section shall not preclude parties from +seeking provisional remedies in aid of arbitration from a court of appropriate +jurisdiction. + +14. GENERAL PROVISIONS + +14.1 No Assignment + +Except in the case of a merger or sale of substantially all of its corporate +assets, Licensee shall not be entitled to assign or transfer all or any of its +rights, benefits and obligations under this Agreement without the prior written +consent of The Qt Company, which shall not be unreasonably withheld or delayed. +The Qt Company shall be entitled to freely assign or transfer any of its +rights, benefits or obligations under this Agreement. + +14.2 No Third Party Representations + +Licensee shall make no representations or warranties concerning the Licensed +Software on behalf of The Qt Company. Any representation or warranty Licensee +makes or purports to make on The Qt Company’s behalf shall be void as to The +Qt Company. + +14.3 Surviving Sections + +Any terms and conditions that by their nature or otherwise reasonably should +survive termination of this Agreement shall so be deemed to survive. + +14.4 Entire Agreement + +This Agreement, the exhibits hereto, the License Certificate and any applicable +Purchase Order constitute the complete agreement between the Parties and +supersedes all prior or contemporaneous discussions, representations, and +proposals, written or oral, with respect to the subject matters discussed +herein. + +In the event of any conflict or inconsistency between this Agreement and any +Purchase Order, the terms of this Agreement will prevail over the terms of the +Purchase Order with respect to such conflict or inconsistency. + +Parties specifically acknowledge and agree that this Agreement prevails over +any click-to-accept or similar agreements the Designated Users may need to +accept online upon download of the Licensed Software, as may be required by +The Qt Company’s applicable processes relating to Licensed Software. + +14.5 Modifications + +No modification of this Agreement shall be effective unless contained in a +writing executed by an authorized representative of each Party. No term or +condition contained in Licensee's Purchase Order shall apply unless expressly +accepted by The Qt Company in writing. + +14.6 Force Majeure + +Except for the payment obligations hereunder, neither Party shall be liable to +the other for any delay or non-performance of its obligations hereunder in the +event and to the extent that such delay or non-performance is due to an event +of act of God, terrorist attack or other similar unforeseeable catastrophic +event that prevents either Party for fulfilling its obligations under this +Agreement and which such Party cannot avoid or circumvent (“Force Majeure +Event”). If the Force Majeure Event results in a delay or non-performance of a +Party for a period of three (3) months or longer, then either Party shall have +the right to terminate this Agreement with immediate effect without any +liability (except for the obligations of payment arising prior to the event of +Force Majeure) towards the other Party. + +14.7 Notices + +Any notice given by one Party to the other shall be deemed properly given and +deemed received if specifically acknowledged by the receiving Party in writing +or when successfully delivered to the recipient by hand, fax, or special +courier during normal business hours on a business day to the addresses +specified for each Party on the signature page. Each communication and document +made or delivered by one Party to the other Party pursuant to this Agreement +shall be in the English language. + +14.8 Export Control + +Licensee acknowledges that the Redistributables may be subject to export +control restrictions under the applicable laws of respective countries. +Licensee shall fully comply with all applicable export license restrictions +and requirements as well as with all laws and regulations relating to the +Redistributables and exercise of licenses hereunder and shall procure all +necessary governmental authorizations, including without limitation, all +necessary licenses, approvals, permissions or consents, where necessary for the +re-exportation of the Redistributables, Applications and/or Devices. + +14.9 No Implied License + +There are no implied licenses or other implied rights granted under this +Agreement, and all rights, save for those expressly granted hereunder, shall +remain with The Qt Company and its licensors. In addition, no licenses or +immunities are granted to the combination of the Licensed Software with any +other software or hardware not delivered by The Qt Company under this Agreement. + +14.10 Attorney Fees + +The prevailing Party in any action to enforce this Agreement shall be entitled +to recover its attorney’s fees and costs in connection with such action. + +14.11 Severability + +If any provision of this Agreement shall be adjudged by any court of competent +jurisdiction to be unenforceable or invalid, that provision shall be limited or +eliminated to the minimum extent necessary so that this Agreement shall +otherwise remain in full force and effect and enforceable. + + +IN WITNESS WHEREOF, the Parties hereto, intending to be legally bound hereby, +have caused this Agreement to be executed by Licensee's authorized +representative installing the Licensed Software and accepting the terms +hereof in connection therewith. + + +Appendix 1 + +1. Parts of the Licensed Software that are permitted for distribution in +object code form only (“Redistributables”) under this Agreement: + +- The Licensed Software's Qt Essentials and Qt Add-on libraries +- The Licensed Software's configuration tool (“qtconfig”) +- The Licensed Software's help tool (“Qt Assistant”) +- The Licensed Software's internationalization tools (“Qt Linguist”, “lupdate”, +“lrelease”) +- The Licensed Software's QML (“Qt Quick”) launcher tool (“qmlscene” or +“qmlviewer”) +- The Licensed Software's installer framework +- Qt for Python (PySide2) + +2. Parts of the Licensed Software that are not permitted for distribution +include, but are not limited to: + +- The Licensed Software's source code and header files +- The Licensed Software's documentation +- The Licensed Software’s documentation generation tool (“qdoc”) +- The Licensed Software's tool for writing makefiles (“qmake”) +- The Licensed Software's Meta Object Compiler (“moc”) +- The Licensed Software's User Interface Compiler (“uic”) +- The Licensed Software's Resource Compiler (“rcc”) +- The Licensed Software's parts of the IDE tool (“Qt Creator”) +- The Licensed Software’s parts of the Design tools (“Qt 3D Studio” or “Qt +Quick Designer”) +- The Licensed Software's Emulator + diff --git a/LICENSE.FDL b/LICENSE.FDL new file mode 100644 index 0000000..938bb8d --- /dev/null +++ b/LICENSE.FDL @@ -0,0 +1,450 @@ + GNU Free Documentation License + Version 1.3, 3 November 2008 + + + Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +0. PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document "free" in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of "copyleft", which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + + +1. APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The "Document", below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as "you". You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A "Modified Version" of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A "Secondary Section" is a named appendix or a front-matter section of +the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The "Invariant Sections" are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The "Cover Texts" are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A "Transparent" copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not "Transparent" is called "Opaque". + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, LaTeX input format, SGML +or XML using a publicly available DTD, and standard-conforming simple +HTML, PostScript or PDF designed for human modification. Examples of +transparent image formats include PNG, XCF and JPG. Opaque formats +include proprietary formats that can be read and edited only by +proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the +machine-generated HTML, PostScript or PDF produced by some word +processors for output purposes only. + +The "Title Page" means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, "Title Page" means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The "publisher" means any person or entity that distributes copies of +the Document to the public. + +A section "Entitled XYZ" means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as "Acknowledgements", +"Dedications", "Endorsements", or "History".) To "Preserve the Title" +of such a section when you modify the Document means that it remains a +section "Entitled XYZ" according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +2. VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no +other conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + + +3. COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to +give them a chance to provide you with an updated version of the +Document. + + +4. MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +A. Use in the Title Page (and on the covers, if any) a title distinct + from that of the Document, and from those of previous versions + (which should, if there were any, be listed in the History section + of the Document). You may use the same title as a previous version + if the original publisher of that version gives permission. +B. List on the Title Page, as authors, one or more persons or entities + responsible for authorship of the modifications in the Modified + Version, together with at least five of the principal authors of the + Document (all of its principal authors, if it has fewer than five), + unless they release you from this requirement. +C. State on the Title page the name of the publisher of the + Modified Version, as the publisher. +D. Preserve all the copyright notices of the Document. +E. Add an appropriate copyright notice for your modifications + adjacent to the other copyright notices. +F. Include, immediately after the copyright notices, a license notice + giving the public permission to use the Modified Version under the + terms of this License, in the form shown in the Addendum below. +G. Preserve in that license notice the full lists of Invariant Sections + and required Cover Texts given in the Document's license notice. +H. Include an unaltered copy of this License. +I. Preserve the section Entitled "History", Preserve its Title, and add + to it an item stating at least the title, year, new authors, and + publisher of the Modified Version as given on the Title Page. If + there is no section Entitled "History" in the Document, create one + stating the title, year, authors, and publisher of the Document as + given on its Title Page, then add an item describing the Modified + Version as stated in the previous sentence. +J. Preserve the network location, if any, given in the Document for + public access to a Transparent copy of the Document, and likewise + the network locations given in the Document for previous versions + it was based on. These may be placed in the "History" section. + You may omit a network location for a work that was published at + least four years before the Document itself, or if the original + publisher of the version it refers to gives permission. +K. For any section Entitled "Acknowledgements" or "Dedications", + Preserve the Title of the section, and preserve in the section all + the substance and tone of each of the contributor acknowledgements + and/or dedications given therein. +L. Preserve all the Invariant Sections of the Document, + unaltered in their text and in their titles. Section numbers + or the equivalent are not considered part of the section titles. +M. Delete any section Entitled "Endorsements". Such a section + may not be included in the Modified Version. +N. Do not retitle any existing section to be Entitled "Endorsements" + or to conflict in title with any Invariant Section. +O. Preserve any Warranty Disclaimers. + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled "Endorsements", provided it contains +nothing but endorsements of your Modified Version by various +parties--for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + + +5. COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled "History" +in the various original documents, forming one section Entitled +"History"; likewise combine any sections Entitled "Acknowledgements", +and any sections Entitled "Dedications". You must delete all sections +Entitled "Endorsements". + + +6. COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other +documents released under this License, and replace the individual +copies of this License in the various documents with a single copy +that is included in the collection, provided that you follow the rules +of this License for verbatim copying of each of the documents in all +other respects. + +You may extract a single document from such a collection, and +distribute it individually under this License, provided you insert a +copy of this License into the extracted document, and follow this +License in all other respects regarding verbatim copying of that +document. + + +7. AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an "aggregate" if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + + +8. TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled "Acknowledgements", +"Dedications", or "History", the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + + +9. TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + + +10. FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions of the +GNU Free Documentation License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in +detail to address new problems or concerns. See +http://www.gnu.org/copyleft/. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License "or any later version" applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +11. RELICENSING + +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +"Massive Multiauthor Collaboration" (or "MMC") contained in the site +means any set of copyrightable works thus published on the MMC site. + +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +"Incorporate" means to publish or republish a Document, in whole or in +part, as part of another Document. + +An MMC is "eligible for relicensing" if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole or +in part into the MMC, (1) had no cover texts or invariant sections, and +(2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + + +ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + + Copyright (c) YEAR YOUR NAME. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. + A copy of the license is included in the section entitled "GNU + Free Documentation License". + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the "with...Texts." line with this: + + with the Invariant Sections being LIST THEIR TITLES, with the + Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. diff --git a/LICENSE.GPL2 b/LICENSE.GPL2 new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE.GPL2 @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/LICENSE.GPLv3 b/LICENSE.GPLv3 new file mode 100644 index 0000000..71c4ad4 --- /dev/null +++ b/LICENSE.GPLv3 @@ -0,0 +1,686 @@ + GNU GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt Toolkit under the terms of + GNU Lesser General Public License version 3. That license references + the General Public License version 3, that is displayed below. Other + portions of the Qt Toolkit may be licensed directly under this license. + +------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSE.GPLv3-EXCEPT b/LICENSE.GPLv3-EXCEPT new file mode 100644 index 0000000..b1cb1be --- /dev/null +++ b/LICENSE.GPLv3-EXCEPT @@ -0,0 +1,704 @@ +This is the GNU General Public License version 3, annotated with The +Qt Company GPL Exception 1.0: + +------------------------------------------------------------------------- + +The Qt Company GPL Exception 1.0 + +Exception 1: + +As a special exception you may create a larger work which contains the +output of this application and distribute that work under terms of your +choice, so long as the work is not otherwise derived from or based on +this application and so long as the work does not in itself generate +output that contains the output from this application in its original +or modified form. + +Exception 2: + +As a special exception, you have permission to combine this application +with Plugins licensed under the terms of your choice, to produce an +executable, and to copy and distribute the resulting executable under +the terms of your choice. However, the executable must be accompanied +by a prominent notice offering all users of the executable the entire +source code to this application, excluding the source code of the +independent modules, but including any changes you have made to this +application, under the terms of this license. + + +------------------------------------------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSE.LGPLv3 b/LICENSE.LGPLv3 new file mode 100644 index 0000000..1f78e05 --- /dev/null +++ b/LICENSE.LGPLv3 @@ -0,0 +1,177 @@ + GNU LESSER GENERAL PUBLIC LICENSE + + The Qt Toolkit is Copyright (C) 2015 The Qt Company Ltd. + Contact: http://www.qt.io/licensing/ + + You may use, distribute and copy the Qt Toolkit under the terms of + GNU Lesser General Public License version 3, which is displayed below. + This license makes reference to the version 3 of the GNU General + Public License, which you can find in the LICENSE.GPLv3 file. + +------------------------------------------------------------------------- + + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/README.cmake.md b/README.cmake.md new file mode 100644 index 0000000..60c446e --- /dev/null +++ b/README.cmake.md @@ -0,0 +1,39 @@ +# CMake super project +For development convenience, a CMake super project is included in the root of the repository. + +The super project can be built using standalone CMake, or using an IDE's CMake integration +(Qt Creator for example). + +Nevertheless the default build process is done via setup.py, in which case each of the +sub-projects are built and installed separately, as mentioned, the super project is just +for development convenience. + +## IDE (Qt Creator) case + +When using an IDE, just open the root CMakeLists.txt file as a new project, and make sure to +specify the following things: + + * LLVM_INSTALL_DIR - the environment variable should point to your libclang library location + * Qt - either select a Qt Kit when configuring the project, or make sure that the + qmake binary is present in the PATH environment variable. + * Python - the PATH environment variable should also point to the Python interpreter + which you wish to use for building the projects (can either be a system + interpreter, or a virtualenv one for example) + +Once that is done, just re-run CMake, so that it picks up the new environment values. +If needed, all other cache variables defined by the project files can be re-adjusted +(for example FORCE_LIMITED_API). + +## Command line CMake case + +When building using the command line CMake binary, make sure to invoke it in a separate +build directory, and not in the root source directory. + +Make sure you have the correct environment variables set up, as described in the previous section. + +The invocation would then look like: +```bash +mkdir build && cd build +cmake -DCMAKE_BUILD_TYPE=Release .. +# make or nmake or msbuild or jom +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..fe61136 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# Qt For Python + +Qt For Python is the [Python Qt bindings project](http://wiki.qt.io/PySide2), providing +access to the complete Qt 5.x framework as well as to generator tools for rapidly +generating bindings for any C++ libraries. + +shiboken2 is the generator used to build the bindings. + +See README.pyside2.md and README.shiboken2.md for details. diff --git a/README.pyside2.md b/README.pyside2.md new file mode 100644 index 0000000..94cdd16 --- /dev/null +++ b/README.pyside2.md @@ -0,0 +1,77 @@ +# PySide2 + +### Introduction + +PySide2 is the official Python module from the +[Qt for Python project](http://wiki.qt.io/Qt_for_Python), +which provides access to the complete Qt 5.12+ framework. + +The Qt for Python project is developed in the open, with all facilities you'd expect +from any modern OSS project such as all code in a git repository and an open +design process. We welcome any contribution conforming to the +[Qt Contribution Agreement](https://www.qt.io/contributionagreement/). + +### Installation + +Since the release of the [Technical Preview](https://blog.qt.io/blog/2018/06/13/qt-python-5-11-released/) +it is possible to install via `pip`, both from Qt's servers +and [PyPi](https://pypi.org/project/PySide2/): + + pip install PySide2 + +#### Dependencies + +PySide2 versions following 5.12 use a C++ parser based on +[Clang](http://clang.org/). The Clang library (C-bindings), version 6.0 or +higher is required for building. Prebuilt versions of it can be downloaded from +[download.qt.io](http://download.qt.io/development_releases/prebuilt/libclang/). + +After unpacking the archive, set the environment variable *LLVM_INSTALL_DIR* to +point to the folder containing the *include* and *lib* directories of Clang: + + 7z x .../libclang-release_60-linux-Rhel7.2-gcc5.3-x86_64-clazy.7z + export LLVM_INSTALL_DIR=$PWD/libclang + +On Windows: + + 7z x .../libclang-release_60-windows-vs2015_64-clazy.7z + SET LLVM_INSTALL_DIR=%CD%\libclang + +### Building from source + +For building PySide2 from scratch, please read about +[getting started](https://wiki.qt.io/Qt_for_Python/GettingStarted). +This process will include getting the code: + + git clone https://code.qt.io/pyside/pyside-setup + cd pyside-setup + git branch --track 5.12 origin/5.12 + git checkout 5.12 + +then install the dependencies, and following the instructions per platform. +A common build command will look like: + + python setup.py install --qmake= --parallel=8 --build-tests + +You can obtain more information about the options to build PySide +and Shiboken in [our wiki](https://wiki.qt.io/Qt_for_Python/). + +### Documentation and Bugs + +You can find more information about the PySide2 module API in the +[official Qt for Python documentation](https://doc.qt.io/qtforpython/). + +If you come across any issue, please file a bug report at our +[JIRA tracker](https://bugreports.qt.io/projects/PYSIDE) following +our [guidelines](https://wiki.qt.io/Qt_for_Python/Reporting_Bugs). + +### Community + +Check *#qt-pyside*, our official IRC channel on FreeNode, +or contact us via our [mailing list](http://lists.qt-project.org/mailman/listinfo/pyside). + +### Licensing + +PySide2 is available under both Open Source (LGPLv3/GPLv2) and commercial license. +Using PyPi is the recommended installation source, because the content of the wheels is valid for both cases. +For more information, refer to the [Qt Licensing page](https://www.qt.io/licensing/). diff --git a/README.shiboken2-generator.md b/README.shiboken2-generator.md new file mode 100644 index 0000000..a7fd322 --- /dev/null +++ b/README.shiboken2-generator.md @@ -0,0 +1,37 @@ +# Shiboken2-generator + +Shiboken is the generator used by the Qt for Python project. +It outputs C++ code for CPython extensions, which can be compiled +and transformed into a Python module. + +C++ projects based on Qt can be wrapped, but also projects +which are not related to Qt. + +## How does it work? + +Shiboken uses an API Extractor that does most of the job, +but it requires a typesystem (XML file) to customize how the +C++ classes/methods will be exposed to Python. + +The typesystem allows you to remove arguments from signatures, +modify return types, inject code and add conversion rules +from the C++ data types to Python data types, manipulate +the ownership of the objects, etc. + +# Examples + +An example related to wrap a C++ library not depending on Qt +can be found in our [repository](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/samplebinding). + +Additionally, you can find a couple of tests inside the +[git repository](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/sources/shiboken2/tests). + +For a more advanced case regarding extending a Qt/C++ application +with Python bindings based on the idea of the PySide module, +you can check the [scriptableapplication](https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/scriptableapplication) +example in our repository. + +# Documentation + +You can find more information about Shiboken in our +[official documentation page](https://doc.qt.io/qtforpython/shiboken2/). diff --git a/README.shiboken2.md b/README.shiboken2.md new file mode 100644 index 0000000..3d92f2a --- /dev/null +++ b/README.shiboken2.md @@ -0,0 +1,13 @@ +# Shiboken2 module + +The purpose of the [shiboken2 Python module](https://wiki.qt.io/Qt_for_Python/Shiboken) +is to access information related to the binding generation that could be used to integrate +C++ programs to Python, or even to get useful information to debug +an application. + +Mostly the idea is to interact with Shiboken objects, +where one can check if it is valid, or if the generated Python wrapper +is invalid after the underlying C++ object has been destroyed. + +More information on the available functions can be found +in our [official documentation](https://doc.qt.io/qtforpython/shiboken2/shibokenmodule.html) diff --git a/build_history/blacklist.txt b/build_history/blacklist.txt new file mode 100644 index 0000000..9b63f97 --- /dev/null +++ b/build_history/blacklist.txt @@ -0,0 +1,98 @@ +[pysidetest::delegatecreateseditor_test] + qt5.6 +[pysidetest::modelview_test] + darwin py3 +[pysidetest::qvariant_test] + darwin py3 +[pysidetest::utils_test] + win32 +[signals::signal_signature_test] + linux + darwin + win32 +[Qt3DExtras::qt3dextras_test] + linux + darwin +[QtCore::qfile_test] + win32 + darwin py3 +[QtCore::qfileread_test] + darwin +# Nested exception in Python 3 +[QtCore::qflags_test] + py3 +[QtCore::qobject_connect_notify_test] + linux + darwin + win32 +[QtGui::qmatrix_test] + win32 +[QtWidgets::bug_576] + linux + win32 + darwin py3 +[QtWidgets::returnquadruplesofnumbers_test] + linux + darwin + win32 +[QtWidgets::qstandarditemmodel_test] + py2 + py3 +[QtTest::touchevent_test] + linux + darwin + win32 +[QtMultimedia::audio_test] + linux + darwin + win32 +[QtQml::bug_951] + py3 +[QtQml::javascript_exceptions] + py3 +[QtScript::qscriptvalue_test] + linux + darwin + win32 +[QtScriptTools::debugger_test] + linux + darwin + win32 +# AttributeError: 'PySide2.QtQuick.QQuickItem' object has no attribute 'simpleFunction' +[QtQml::bug_451] + py2 + py3 +# Crashes with Python 2 on Windows +[QtQml::qqmlnetwork_test] + py2 win32 +[QtQml::qquickitem_grabToImage] + darwin +[smart::smart_pointer] + py2 +# PYSIDE-474 +[QtWebEngineWidgets::pyside-474-qtwebengineview] + py2 + py3 +[QtCore::thread_signals_test] + win32 + linux + darwin +[QtCore::qthread_prod_cons_test] + win32 + linux + darwin +# PYSIDE-754 +[QtWebEngineCore::web_engine_custom_scheme] + win32 + linux + darwin +# In addition to a pre-existing windows failure, +# qtlocation/ac899dcc40bb3ad09307583fb7e6befd45a77b33 / QTBUG-66304 introduced +# a failure in 5.14 +[QtPositioning::positioning] + win32 + linux + darwin +# Open GL functions failures on macOS (2/2020) +[registry::existence_test] + darwin diff --git a/build_scripts/__init__.py b/build_scripts/__init__.py new file mode 100644 index 0000000..571d374 --- /dev/null +++ b/build_scripts/__init__.py @@ -0,0 +1,38 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# diff --git a/build_scripts/build_scripts.pyproject b/build_scripts/build_scripts.pyproject new file mode 100644 index 0000000..80df4d3 --- /dev/null +++ b/build_scripts/build_scripts.pyproject @@ -0,0 +1,9 @@ +{ + "files": ["main.py", "__init__.py", "config.py", "options.py", "qtinfo.py", + "setup_runner.py", "utils.py", "wheel_override.py", "wheel_utils.py", + "platforms/__init__.py", "platforms/linux.py", + "platforms/macos.py", "platforms/unix.py", + "platforms/windows_desktop.py", + "../setup.py", + "../coin_build_instructions.py", "../coin_test_instructions.py"] +} diff --git a/build_scripts/config.py b/build_scripts/config.py new file mode 100644 index 0000000..b1b3206 --- /dev/null +++ b/build_scripts/config.py @@ -0,0 +1,397 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import distutils.log as log + + +class Config(object): + def __init__(self): + # Constants + self._build_type_all = "all" + self._invocation_type_top_level = "top-level" + self._invocation_type_internal = "internal" + + # The keyword arguments which will be given to setuptools.setup + self.setup_kwargs = {} + + # The setup.py invocation type. + # top-level + # internal + self.invocation_type = None + + # The type of the top-level build. + # all - build shiboken2 module, shiboken2-generator and PySide2 + # modules + # shiboken2 - build only shiboken2 module + # shiboken2-generator - build only the shiboken2-generator + # pyside2 - build only PySide2 modules + self.build_type = None + + # The internal build type, used for internal invocations of + # setup.py to build a specific module only. + self.internal_build_type = None + + # Options that can be given to --build-type and + # --internal-build-type + self.shiboken_module_option_name = "shiboken2" + self.shiboken_generator_option_name = "shiboken2-generator" + self.pyside_option_name = "pyside2" + + # Names to be passed to setuptools.setup() name key, + # so not package name, but rather project name as it appears + # in the wheel name and on PyPi. + self.shiboken_module_st_name = "shiboken2" + self.shiboken_generator_st_name = "shiboken2-generator" + self.pyside_st_name = "PySide2" + + # Used by check_allowed_python_version to validate the + # interpreter version. + self.python_version_classifiers = [ + 'Programming Language :: Python', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + ] + + self.setup_script_dir = None + + def init_config(self, build_type=None, internal_build_type=None, + cmd_class_dict=None, package_version=None, + ext_modules=None, setup_script_dir=None, + quiet=False): + """ + Sets up the global singleton config which is used in many parts + of the setup process. + """ + + # if --internal-build-type was passed, it means that this is a + # sub-invocation to build a specific package. + if internal_build_type: + self.set_is_internal_invocation() + self.set_internal_build_type(internal_build_type) + else: + self.set_is_top_level_invocation() + + # --build-type was specified explicitly, so set it. Otherwise + # default to all. + if build_type: + self.build_type = build_type + else: + self.build_type = self._build_type_all + + self.setup_script_dir = setup_script_dir + + setup_kwargs = {} + setup_kwargs['long_description'] = self.get_long_description() + setup_kwargs['long_description_content_type'] = 'text/markdown' + setup_kwargs['keywords'] = 'Qt' + setup_kwargs['author'] = 'Qt for Python Team' + setup_kwargs['author_email'] = 'pyside@qt-project.org' + setup_kwargs['url'] = 'https://www.pyside.org' + setup_kwargs['download_url'] = 'https://download.qt.io/official_releases/QtForPython' + setup_kwargs['license'] = 'LGPL' + setup_kwargs['zip_safe'] = False + setup_kwargs['cmdclass'] = cmd_class_dict + setup_kwargs['version'] = package_version + setup_kwargs['python_requires'] = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <3.10" + + if quiet: + # Tells distutils / setuptools to be quiet, and only print warnings or errors. + # Makes way less noise in the terminal when building. + setup_kwargs['verbose'] = 0 + + # Setting these two keys is still a bit of a discussion point. + # In general not setting them will allow using "build" and + # "bdist_wheel" just fine. What they do, is they specify to the + # setuptools.command.build_py command that certain pure python + # modules (.py files) exist in the specified package location, + # and that they should be copied over to the setuptools build + # dir. + # But it doesn't really make sense for us, because we copy all + # the necessary files to the build dir via prepare_packages() + # function anyway. + # If we don't set them, the build_py sub-command will be + # skipped, but the build command will still be executed, which + # is where we run cmake / make. + # The only plausible usage of it, is if we will implement a + # correctly functioning setup.py develop command (or bdist_egg). + # But currently that doesn't seem to work. + setup_kwargs['packages'] = self.get_setup_tools_packages_for_current_build() + setup_kwargs['package_dir'] = self.get_package_name_to_dir_path_mapping() + + # Add a bogus extension module (will never be built here since + # we are overriding the build command to do it using cmake) so + # things like bdist_egg will know that there are extension + # modules and will name the dist with the full platform info. + setup_kwargs['ext_modules'] = ext_modules + + common_classifiers = [ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Environment :: MacOS X', + 'Environment :: X11 Applications :: Qt', + 'Environment :: Win32 (MS Windows)', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', + 'License :: Other/Proprietary License', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: POSIX', + 'Operating System :: POSIX :: Linux', + 'Operating System :: Microsoft', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: C++'] + common_classifiers.extend(self.python_version_classifiers) + common_classifiers.extend([ + 'Topic :: Database', + 'Topic :: Software Development', + 'Topic :: Software Development :: Code Generators', + 'Topic :: Software Development :: Libraries :: Application Frameworks', + 'Topic :: Software Development :: User Interfaces', + 'Topic :: Software Development :: Widget Sets']) + setup_kwargs['classifiers'] = common_classifiers + + if self.internal_build_type == self.shiboken_module_option_name: + setup_kwargs['name'] = self.shiboken_module_st_name + setup_kwargs['description'] = "Python / C++ bindings helper module" + setup_kwargs['entry_points'] = {} + + elif self.internal_build_type == self.shiboken_generator_option_name: + setup_kwargs['name'] = self.shiboken_generator_st_name + setup_kwargs['description'] = "Python / C++ bindings generator" + setup_kwargs['install_requires'] = ["{}=={}".format(self.shiboken_module_st_name, package_version)] + setup_kwargs['entry_points'] = { + 'console_scripts': [ + 'shiboken2 = {}.scripts.shiboken_tool:main'.format(self.package_name()), + ] + } + + elif self.internal_build_type == self.pyside_option_name: + setup_kwargs['name'] = self.pyside_st_name + setup_kwargs['description'] = "Python bindings for the Qt cross-platform application and UI framework" + setup_kwargs['install_requires'] = ["{}=={}".format(self.shiboken_module_st_name, package_version)] + setup_kwargs['entry_points'] = { + 'console_scripts': [ + 'pyside2-uic = {}.scripts.pyside_tool:uic'.format(self.package_name()), + 'pyside2-rcc = {}.scripts.pyside_tool:rcc'.format(self.package_name()), + 'pyside2-designer= {}.scripts.pyside_tool:designer'.format(self.package_name()), + 'pyside2-lupdate = {}.scripts.pyside_tool:main'.format(self.package_name()), + ] + } + self.setup_kwargs = setup_kwargs + + def get_long_description(self): + readme_filename = 'README.md' + changes_filename = 'CHANGES.rst' + + if self.is_internal_shiboken_module_build(): + readme_filename = 'README.shiboken2.md' + elif self.is_internal_shiboken_generator_build(): + readme_filename = 'README.shiboken2-generator.md' + elif self.is_internal_pyside_build(): + readme_filename = 'README.pyside2.md' + + content = '' + changes = '' + try: + with open(os.path.join(self.setup_script_dir, readme_filename)) as f: + readme = f.read() + except Exception as e: + log.error("Couldn't read contents of {}.".format(readme_filename)) + raise + + # Don't include CHANGES.rst for now, because we have not decided + # how to handle change files yet. + include_changes = False + if include_changes: + try: + with open(os.path.join(self.setup_script_dir, changes_filename)) as f: + changes = f.read() + except Exception as e: + log.error("Couldn't read contents of {}".format(changes_filename)) + raise + content += readme + + if changes: + content += "\n\n" + changes + + return content + + def package_name(self): + """ + Returns package name as it appears in Python's site-packages + directory. + + Package names can only be delimited by underscores, and not by + dashes. + """ + if self.is_internal_shiboken_module_build(): + return "shiboken2" + elif self.is_internal_shiboken_generator_build(): + return "shiboken2_generator" + elif self.is_internal_pyside_build(): + return "PySide2" + else: + return None + + def get_setup_tools_packages_for_current_build(self): + """ + Returns a list of packages for setup tools to consider in the + build_py command, so that it can copy the pure python files. + Not really necessary because it's done in prepare_packages() + anyway. + + This is really just to satisfy some checks in setuptools + build_py command, and if we ever properly implement the develop + command. + """ + if self.internal_build_type == self.pyside_option_name: + return [ + config.package_name(), + ] + elif self.internal_build_type == self.shiboken_module_option_name: + return [self.package_name()] + else: + return [] + + def get_package_name_to_dir_path_mapping(self): + """ + Used in setuptools.setup 'package_dir' argument to specify where + the actual module packages are located. + + For example when building the shiboken module, setuptools will + expect to find the "shiboken2" module sources under + "sources/shiboken2/shibokenmodule". + + This is really just to satisfy some checks in setuptools + build_py command, and if we ever properly implement the develop + command. + """ + if self.is_internal_shiboken_module_build(): + return { + self.package_name(): "sources/shiboken2/shibokenmodule" + } + elif self.is_internal_shiboken_generator_build(): + # This is left empty on purpose, because the shiboken + # generator doesn't have a python module for now. + return {} + elif self.is_internal_pyside_build(): + return { + self.package_name(): "sources/pyside2/PySide2", + } + else: + return {} + + def get_buildable_extensions(self): + """ + Used by PysideBuild.run to build the CMake projects. + :return: A list of directory names under the sources directory. + """ + if self.is_internal_shiboken_module_build() or self.is_internal_shiboken_generator_build(): + return ['shiboken2'] + elif self.is_internal_pyside_build(): + return ['pyside2', 'pyside2-tools'] + return None + + def set_is_top_level_invocation(self): + self.invocation_type = self._invocation_type_top_level + + def set_is_internal_invocation(self): + self.invocation_type = self._invocation_type_internal + + def is_top_level_invocation(self): + return self.invocation_type == self._invocation_type_top_level + + def is_internal_invocation(self): + return self.invocation_type == self._invocation_type_internal + + def is_top_level_build_all(self): + return self.build_type == self._build_type_all + + def is_top_level_build_shiboken_module(self): + return self.build_type == self.shiboken_module_option_name + + def is_top_level_build_shiboken_generator(self): + return self.build_type == self.shiboken_generator_option_name + + def is_top_level_build_pyside(self): + return self.build_type == self.pyside_option_name + + def set_internal_build_type(self, internal_build_type): + self.internal_build_type = internal_build_type + + def is_internal_shiboken_module_build(self): + return self.internal_build_type == self.shiboken_module_option_name + + def is_internal_shiboken_generator_build(self): + return self.internal_build_type == self.shiboken_generator_option_name + + def is_internal_pyside_build(self): + return self.internal_build_type == self.pyside_option_name + + def is_internal_shiboken_generator_build_and_part_of_top_level_all(self): + """ + Used to skip certain build rules and output, when we know that + the CMake build of shiboken was already done as part of the + top-level "all" build when shiboken2-module was built. + """ + return self.is_internal_shiboken_generator_build() and self.is_top_level_build_all() + + def get_allowed_top_level_build_values(self): + return [ + self._build_type_all, + self.shiboken_module_option_name, + self.shiboken_generator_option_name, + self.pyside_option_name + ] + + def get_allowed_internal_build_values(self): + return [ + self.shiboken_module_option_name, + self.shiboken_generator_option_name, + self.pyside_option_name + ] + + +config = Config() diff --git a/build_scripts/main.py b/build_scripts/main.py new file mode 100644 index 0000000..ea91ef7 --- /dev/null +++ b/build_scripts/main.py @@ -0,0 +1,1255 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function +from distutils.version import LooseVersion + +import os +import platform +import re +import sys +from textwrap import dedent +import time +from .config import config +from .utils import get_python_dict +from .options import DistUtilsCommandMixin, OPTION +from .wheel_utils import (get_package_version, get_qt_version, + get_package_timestamp, macos_plat_name, + macos_pyside_min_deployment_target) + +setup_script_dir = os.getcwd() +build_scripts_dir = os.path.join(setup_script_dir, 'build_scripts') +setup_py_path = os.path.join(setup_script_dir, "setup.py") + +start_time = int(time.time()) + + +def elapsed(): + return int(time.time()) - start_time + + +def get_setuptools_extension_modules(): + # Setting py_limited_api on the extension is the "correct" thing + # to do, but it doesn't actually do anything, because we + # override build_ext. So this is just foolproofing for the + # future. + extension_args = ('QtCore', []) + extension_kwargs = {} + if OPTION["LIMITED_API"] == 'yes': + extension_kwargs['py_limited_api'] = True + extension_modules = [Extension(*extension_args, **extension_kwargs)] + return extension_modules + + +def _get_make(platform_arch, build_type): + """Helper for retrieving the make command and CMake generator name""" + makespec = OPTION["MAKESPEC"] + if makespec == "make": + return ("make", "Unix Makefiles") + if makespec == "msvc": + nmake_path = find_executable("nmake") + if nmake_path is None or not os.path.exists(nmake_path): + log.info("nmake not found. Trying to initialize the MSVC env...") + init_msvc_env(platform_arch, build_type) + nmake_path = find_executable("nmake") + if not nmake_path or not os.path.exists(nmake_path): + raise DistutilsSetupError('"nmake" could not be found.') + if not OPTION["NO_JOM"]: + jom_path = find_executable("jom") + if jom_path: + log.info("jom was found in {}".format(jom_path)) + return (jom_path, "NMake Makefiles JOM") + log.info("nmake was found in {}".format(nmake_path)) + if OPTION["JOBS"]: + msg = "Option --jobs can only be used with 'jom' on Windows." + raise DistutilsSetupError(msg) + return (nmake_path, "NMake Makefiles") + if makespec == "mingw": + return ("mingw32-make", "mingw32-make") + if makespec == "ninja": + return ("ninja", "Ninja") + m = 'Invalid option --make-spec "{}".'.format(makespec) + raise DistutilsSetupError(m) + + +def get_make(platform_arch, build_type): + """Retrieve the make command and CMake generator name""" + (make_path, make_generator) = _get_make(platform_arch, build_type) + if not os.path.isabs(make_path): + make_path = find_executable(make_path) + if not make_path or not os.path.exists(make_path): + raise DistutilsSetupError("You need the program '{}' on your system path to " + "compile PySide2.".format(make_path)) + return (make_path, make_generator) + + +def _get_py_library_win(build_type, py_version, py_prefix, py_libdir, + py_include_dir): + """Helper for finding the Python library on Windows""" + if py_include_dir is None or not os.path.exists(py_include_dir): + py_include_dir = os.path.join(py_prefix, "include") + if py_libdir is None or not os.path.exists(py_libdir): + # For virtual environments on Windows, the py_prefix will contain a + # path pointing to it, instead of the system Python installation path. + # Since INCLUDEPY contains a path to the system location, we use the + # same base directory to define the py_libdir variable. + py_libdir = os.path.join(os.path.dirname(py_include_dir), "libs") + if not os.path.isdir(py_libdir): + raise DistutilsSetupError("Failed to locate the 'libs' directory") + dbg_postfix = "_d" if build_type == "Debug" else "" + if OPTION["MAKESPEC"] == "mingw": + static_lib_name = "libpython{}{}.a".format( + py_version.replace(".", ""), dbg_postfix) + return os.path.join(py_libdir, static_lib_name) + v = py_version.replace(".", "") + python_lib_name = "python{}{}.lib".format(v, dbg_postfix) + return os.path.join(py_libdir, python_lib_name) + + +def _get_py_library_unix(build_type, py_version, py_prefix, py_libdir, + py_include_dir): + """Helper for finding the Python library on UNIX""" + if py_libdir is None or not os.path.exists(py_libdir): + py_libdir = os.path.join(py_prefix, "lib") + if py_include_dir is None or not os.path.exists(py_include_dir): + dir = "include/python{}".format(py_version) + py_include_dir = os.path.join(py_prefix, dir) + dbg_postfix = "_d" if build_type == "Debug" else "" + lib_exts = ['.so'] + if sys.platform == 'darwin': + lib_exts.append('.dylib') + if sys.version_info[0] > 2: + lib_suff = getattr(sys, 'abiflags', None) + else: # Python 2 + lib_suff = '' + lib_exts.append('.so.1') + # Suffix for OpenSuSE 13.01 + lib_exts.append('.so.1.0') + # static library as last gasp + lib_exts.append('.a') + + if sys.version_info[0] == 2 and dbg_postfix: + # For Python2 add a duplicate set of extensions combined with the + # dbg_postfix, so we test for both the debug version of the lib + # and the normal one. This allows a debug PySide2 to be built with a + # non-debug Python. + lib_exts = [dbg_postfix + e for e in lib_exts] + lib_exts + + libs_tried = [] + for lib_ext in lib_exts: + lib_name = "libpython{}{}{}".format(py_version, lib_suff, lib_ext) + py_library = os.path.join(py_libdir, lib_name) + if os.path.exists(py_library): + return py_library + libs_tried.append(py_library) + # At least on macOS 10.11, the system Python 2.6 does not include a + # symlink to the framework file disguised as a .dylib file, thus finding + # the library would fail. Manually check if a framework file "Python" + # exists in the Python framework bundle. + if sys.platform == 'darwin' and sys.version_info[:2] == (2, 6): + # These manipulations essentially transform + # /System/Library/Frameworks/Python.framework/Versions/2.6/lib + # to + # /System/Library/Frameworks/Python.framework/Versions/2.6/Python + possible_framework_path = os.path.realpath(os.path.join(py_libdir, '..')) + possible_framework_version = os.path.basename(possible_framework_path) + possible_framework_library = os.path.join(possible_framework_path, 'Python') + + if (possible_framework_version == '2.6' + and os.path.exists(possible_framework_library)): + return possible_framework_library + libs_tried.append(possible_framework_library) + + # Try to find shared libraries which have a multi arch + # suffix. + py_multiarch = get_config_var("MULTIARCH") + if py_multiarch: + try_py_libdir = os.path.join(py_libdir, py_multiarch) + libs_tried = [] + for lib_ext in lib_exts: + lib_name = "libpython{}{}{}".format(py_version, lib_suff, lib_ext) + py_library = os.path.join(try_py_libdir, lib_name) + if os.path.exists(py_library): + return py_library + libs_tried.append(py_library) + + m = "Failed to locate the Python library with {}".format(", ".join(libs_tried)) + raise DistutilsSetupError(m) + + +def get_py_library(build_type, py_version, py_prefix, py_libdir, py_include_dir): + """Find the Python library""" + if sys.platform == "win32": + py_library = _get_py_library_win(build_type, py_version, py_prefix, + py_libdir, py_include_dir) + else: + py_library = _get_py_library_unix(build_type, py_version, py_prefix, + py_libdir, py_include_dir) + if py_library.endswith('.a'): + # Python was compiled as a static library + log.error("Failed to locate a dynamic Python library, using {}".format(py_library)) + return py_library + + +# Git submodules: ["submodule_name", "location_relative_to_sources_folder"] +submodules = [["pyside2-tools"]] + +try: + import setuptools +except ImportError: + from ez_setup import use_setuptools + use_setuptools() + +from setuptools import Extension +from setuptools.command.install import install as _install +from setuptools.command.install_lib import install_lib as _install_lib +from setuptools.command.bdist_egg import bdist_egg as _bdist_egg +from setuptools.command.develop import develop as _develop +from setuptools.command.build_py import build_py as _build_py + +import distutils.log as log +from distutils.errors import DistutilsSetupError +from distutils.sysconfig import get_config_var +from distutils.sysconfig import get_python_lib +from distutils.spawn import find_executable +from distutils.command.build import build as _build +from distutils.command.build_ext import build_ext as _build_ext +from distutils.util import get_platform +from distutils.cmd import Command + +from .qtinfo import QtInfo +from .utils import rmtree, detect_clang, copyfile, copydir, run_process_output, run_process +from .utils import update_env_path, init_msvc_env, filter_match +from .utils import macos_fix_rpaths_for_library +from .utils import linux_fix_rpaths_for_library +from .platforms.unix import prepare_packages_posix +from .platforms.windows_desktop import prepare_packages_win32 +from .wheel_override import wheel_module_exists, get_bdist_wheel_override + + +def check_allowed_python_version(): + """ + Make sure that setup.py is run with an allowed python version. + """ + + import re + pattern = r'Programming Language :: Python :: (\d+)\.(\d+)' + supported = [] + + for line in config.python_version_classifiers: + found = re.search(pattern, line) + if found: + major = int(found.group(1)) + minor = int(found.group(2)) + supported.append((major, minor)) + this_py = sys.version_info[:2] + if this_py not in supported: + print("Unsupported python version detected. Only these python versions are supported: {}" + .format(supported)) + sys.exit(1) + + +qt_src_dir = '' + + +def is_debug_python(): + return getattr(sys, "gettotalrefcount", None) is not None + + +# Return a prefix suitable for the _install/_build directory +def prefix(): + virtual_env_name = os.environ.get('VIRTUAL_ENV', None) + if virtual_env_name is not None: + name = os.path.basename(virtual_env_name) + else: + name = "pyside" + name += str(sys.version_info[0]) + if OPTION["DEBUG"]: + name += "d" + if is_debug_python(): + name += "p" + if OPTION["LIMITED_API"] == "yes" and sys.version_info[0] == 3: + name += "a" + return name + + +# Initialize, pull and checkout submodules +def prepare_sub_modules(): + print("Initializing submodules for PySide2 version: {}".format( + get_package_version())) + submodules_dir = os.path.join(setup_script_dir, "sources") + + # Create list of [name, desired branch, absolute path, desired + # branch] and determine whether all submodules are present + need_init_sub_modules = False + + for m in submodules: + module_name = m[0] + module_dir = m[1] if len(m) > 1 else '' + module_dir = os.path.join(submodules_dir, module_dir, module_name) + # Check for non-empty directory (repository checked out) + if not os.listdir(module_dir): + need_init_sub_modules = True + break + + if need_init_sub_modules: + git_update_cmd = ["git", "submodule", "update", "--init"] + if run_process(git_update_cmd) != 0: + m = "Failed to initialize the git submodules: update --init failed" + raise DistutilsSetupError(m) + git_pull_cmd = ["git", "submodule", "foreach", "git", "fetch", "--all"] + if run_process(git_pull_cmd) != 0: + m = "Failed to initialize the git submodules: git fetch --all failed" + raise DistutilsSetupError(m) + else: + print("All submodules present.") + + git_update_cmd = ["git", "submodule", "update"] + if run_process(git_update_cmd) != 0: + m = "Failed to checkout the correct git submodules SHA1s." + raise DistutilsSetupError(m) + + +def prepare_build(): + if (os.path.isdir(".git") and not OPTION["IGNOREGIT"] and not OPTION["ONLYPACKAGE"] + and not OPTION["REUSE_BUILD"]): + prepare_sub_modules() + # Clean up temp build folder. + for n in ["build"]: + d = os.path.join(setup_script_dir, n) + if os.path.isdir(d): + log.info("Removing {}".format(d)) + try: + rmtree(d) + except Exception as e: + print('***** problem removing "{}"'.format(d)) + print('ignored error: {}'.format(e)) + + # locate Qt sources for the documentation + if OPTION["QT_SRC"] is None: + install_prefix = QtInfo().prefix_dir + if install_prefix: + global qt_src_dir + # In-source, developer build + if install_prefix.endswith("qtbase"): + qt_src_dir = install_prefix + else: # SDK: Use 'Src' directory + qt_src_dir = os.path.join(os.path.dirname(install_prefix), 'Src', 'qtbase') + + +class PysideInstall(_install, DistUtilsCommandMixin): + + user_options = _install.user_options + DistUtilsCommandMixin.mixin_user_options + + def __init__(self, *args, **kwargs): + _install.__init__(self, *args, **kwargs) + DistUtilsCommandMixin.__init__(self) + + def initialize_options(self): + _install.initialize_options(self) + + if sys.platform == 'darwin': + # Because we change the plat_name to include a correct + # deployment target on macOS distutils thinks we are + # cross-compiling, and throws an exception when trying to + # execute setup.py install. The check looks like this + # if self.warn_dir and build_plat != get_platform(): + # raise DistutilsPlatformError("Can't install when " + # "cross-compiling") + # Obviously get_platform will return the old deployment + # target. The fix is to disable the warn_dir flag, which + # was created for bdist_* derived classes to override, for + # similar cases. + self.warn_dir = False + + def finalize_options(self): + DistUtilsCommandMixin.mixin_finalize_options(self) + _install.finalize_options(self) + + def run(self): + _install.run(self) + print('--- Install completed ({}s)'.format(elapsed())) + + +class PysideDevelop(_develop): + + def __init__(self, *args, **kwargs): + _develop.__init__(self, *args, **kwargs) + + def run(self): + self.run_command("build") + _develop.run(self) + + +class PysideBdistEgg(_bdist_egg): + + def __init__(self, *args, **kwargs): + _bdist_egg.__init__(self, *args, **kwargs) + + def run(self): + self.run_command("build") + _bdist_egg.run(self) + + +class PysideBuildExt(_build_ext): + + def __init__(self, *args, **kwargs): + _build_ext.__init__(self, *args, **kwargs) + + def run(self): + pass + + +class PysideBuildPy(_build_py): + + def __init__(self, *args, **kwargs): + _build_py.__init__(self, *args, **kwargs) + + +# _install_lib is reimplemented to preserve +# symlinks when distutils / setuptools copy files to various +# directories from the setup tools build dir to the install dir. +class PysideInstallLib(_install_lib): + + def __init__(self, *args, **kwargs): + _install_lib.__init__(self, *args, **kwargs) + + def install(self): + """ + Installs files from build/xxx directory into final + site-packages/PySide2 directory. + """ + + if os.path.isdir(self.build_dir): + # Using our own copydir makes sure to preserve symlinks. + outfiles = copydir(os.path.abspath(self.build_dir), os.path.abspath(self.install_dir)) + else: + self.warn("'{}' does not exist -- no Python modules to install".format(self.build_dir)) + return + return outfiles + + +class PysideBuild(_build, DistUtilsCommandMixin): + + user_options = _build.user_options + DistUtilsCommandMixin.mixin_user_options + + def __init__(self, *args, **kwargs): + _build.__init__(self, *args, **kwargs) + DistUtilsCommandMixin.__init__(self) + + def finalize_options(self): + os_name_backup = os.name + DistUtilsCommandMixin.mixin_finalize_options(self) + if sys.platform == 'darwin': + self.plat_name = macos_plat_name() + # This is a hack to circumvent the dubious check in + # distutils.commands.build -> finalize_options, which only + # allows setting the plat_name for windows NT. + # That is not the case for the wheel module though (which + # does allow setting plat_name), so we circumvent by faking + # the os name when finalizing the options, and then + # restoring the original os name. + os.name = "nt" + + _build.finalize_options(self) + + if sys.platform == 'darwin': + os.name = os_name_backup + + def initialize_options(self): + _build.initialize_options(self) + self.make_path = None + self.make_generator = None + self.script_dir = None + self.sources_dir = None + self.build_dir = None + self.install_dir = None + self.py_executable = None + self.py_include_dir = None + self.py_library = None + self.py_version = None + self.py_arch = None + self.build_type = "Release" + self.qtinfo = None + self.build_tests = False + + def run(self): + prepare_build() + platform_arch = platform.architecture()[0] + log.info("Python architecture is {}".format(platform_arch)) + self.py_arch = platform_arch[:-3] + + build_type = "Debug" if OPTION["DEBUG"] else "Release" + if OPTION["RELWITHDEBINFO"]: + build_type = 'RelWithDebInfo' + + # Check env + make_path = None + make_generator = None + if not OPTION["ONLYPACKAGE"]: + (make_path, make_generator) = get_make(platform_arch, build_type) + + # Prepare parameters + py_executable = sys.executable + py_version = "{}.{}".format(sys.version_info[0], sys.version_info[1]) + py_include_dir = get_config_var("INCLUDEPY") + py_libdir = get_config_var("LIBDIR") + py_prefix = get_config_var("prefix") + if not py_prefix or not os.path.exists(py_prefix): + py_prefix = sys.prefix + self.py_prefix = py_prefix + if sys.platform == "win32": + py_scripts_dir = os.path.join(py_prefix, "Scripts") + else: + py_scripts_dir = os.path.join(py_prefix, "bin") + self.py_scripts_dir = py_scripts_dir + + self.qtinfo = QtInfo() + qt_dir = os.path.dirname(OPTION["QMAKE"]) + qt_version = get_qt_version() + + # Update the PATH environment variable + additional_paths = [self.py_scripts_dir, qt_dir] + + # Add Clang to path for Windows. + # Revisit once Clang is bundled with Qt. + if (sys.platform == "win32" + and LooseVersion(self.qtinfo.version) >= LooseVersion("5.7.0")): + clang_dir = detect_clang() + if clang_dir[0]: + clangBinDir = os.path.join(clang_dir[0], 'bin') + if clangBinDir not in os.environ.get('PATH'): + log.info("Adding {} as detected by {} to PATH".format(clangBinDir, + clang_dir[1])) + additional_paths.append(clangBinDir) + else: + raise DistutilsSetupError("Failed to detect Clang when checking " + "LLVM_INSTALL_DIR, CLANG_INSTALL_DIR, llvm-config") + + update_env_path(additional_paths) + + # Used for test blacklists and registry test. + self.build_classifiers = "py{}-qt{}-{}-{}".format(py_version, qt_version, + platform.architecture()[0], + build_type.lower()) + if OPTION["SHORTER_PATHS"]: + build_name = "p{}".format(py_version) + else: + build_name = self.build_classifiers + + script_dir = setup_script_dir + sources_dir = os.path.join(script_dir, "sources") + build_dir = os.path.join(script_dir, prefix() + "_build", "{}".format(build_name)) + install_dir = os.path.join(script_dir, prefix() + "_install", "{}".format(build_name)) + + self.make_path = make_path + self.make_generator = make_generator + self.script_dir = script_dir + self.st_build_dir = os.path.join(self.script_dir, self.build_lib) + self.sources_dir = sources_dir + self.build_dir = build_dir + self.install_dir = install_dir + self.py_executable = py_executable + self.py_include_dir = py_include_dir + self.py_library = get_py_library(build_type, py_version, py_prefix, + py_libdir, py_include_dir) + self.py_version = py_version + self.build_type = build_type + self.site_packages_dir = get_python_lib(1, 0, prefix=install_dir) + self.build_tests = OPTION["BUILDTESTS"] + + # Save the shiboken build dir path for clang deployment + # purposes. + self.shiboken_build_dir = os.path.join(self.build_dir, "shiboken2") + + self.log_pre_build_info() + + # Prepare folders + if not os.path.exists(self.sources_dir): + log.info("Creating sources folder {}...".format(self.sources_dir)) + os.makedirs(self.sources_dir) + if not os.path.exists(self.build_dir): + log.info("Creating build folder {}...".format(self.build_dir)) + os.makedirs(self.build_dir) + if not os.path.exists(self.install_dir): + log.info("Creating install folder {}...".format(self.install_dir)) + os.makedirs(self.install_dir) + + if (not OPTION["ONLYPACKAGE"] + and not config.is_internal_shiboken_generator_build_and_part_of_top_level_all()): + # Build extensions + for ext in config.get_buildable_extensions(): + self.build_extension(ext) + + if OPTION["BUILDTESTS"]: + # we record the latest successful build and note the + # build directory for supporting the tests. + timestamp = time.strftime('%Y-%m-%d_%H%M%S') + build_history = os.path.join(setup_script_dir, 'build_history') + unique_dir = os.path.join(build_history, timestamp) + os.makedirs(unique_dir) + fpath = os.path.join(unique_dir, 'build_dir.txt') + with open(fpath, 'w') as f: + print(build_dir, file=f) + print(self.build_classifiers, file=f) + log.info("Created {}".format(build_history)) + + if not OPTION["SKIP_PACKAGING"]: + # Build patchelf if needed + self.build_patchelf() + + # Prepare packages + self.prepare_packages() + + # Build packages + _build.run(self) + else: + log.info("Skipped preparing and building packages.") + print('--- Build completed ({}s)'.format(elapsed())) + + def log_pre_build_info(self): + if config.is_internal_shiboken_generator_build_and_part_of_top_level_all(): + return + + setuptools_install_prefix = get_python_lib(1) + if OPTION["FINAL_INSTALL_PREFIX"]: + setuptools_install_prefix = OPTION["FINAL_INSTALL_PREFIX"] + log.info("=" * 30) + log.info("Package version: {}".format(get_package_version())) + log.info("Build type: {}".format(self.build_type)) + log.info("Build tests: {}".format(self.build_tests)) + log.info("-" * 3) + log.info("Make path: {}".format(self.make_path)) + log.info("Make generator: {}".format(self.make_generator)) + log.info("Make jobs: {}".format(OPTION["JOBS"])) + log.info("-" * 3) + log.info("setup.py directory: {}".format(self.script_dir)) + log.info("Build scripts directory: {}".format(build_scripts_dir)) + log.info("Sources directory: {}".format(self.sources_dir)) + log.info(dedent(""" + Building {st_package_name} will create and touch directories + in the following order: + make build directory (py*_build/*/*) -> + make install directory (py*_install/*/*) -> + setuptools build directory (build/*/*) -> + setuptools install directory + (usually path-installed-python/lib/python*/site-packages/*) + """).format(st_package_name=config.package_name())) + log.info("make build directory: {}".format(self.build_dir)) + log.info("make install directory: {}".format(self.install_dir)) + log.info("setuptools build directory: {}".format(self.st_build_dir)) + log.info("setuptools install directory: {}".format(setuptools_install_prefix)) + log.info(dedent(""" + make-installed site-packages directory: {} + (only relevant for copying files from 'make install directory' + to 'setuptools build directory' + """).format( + self.site_packages_dir)) + log.info("-" * 3) + log.info("Python executable: {}".format(self.py_executable)) + log.info("Python includes: {}".format(self.py_include_dir)) + log.info("Python library: {}".format(self.py_library)) + log.info("Python prefix: {}".format(self.py_prefix)) + log.info("Python scripts: {}".format(self.py_scripts_dir)) + log.info("-" * 3) + log.info("Qt qmake: {}".format(self.qtinfo.qmake_command)) + log.info("Qt version: {}".format(self.qtinfo.version)) + log.info("Qt bins: {}".format(self.qtinfo.bins_dir)) + log.info("Qt docs: {}".format(self.qtinfo.docs_dir)) + log.info("Qt plugins: {}".format(self.qtinfo.plugins_dir)) + log.info("-" * 3) + if sys.platform == 'win32': + log.info("OpenSSL dll directory: {}".format(OPTION["OPENSSL"])) + if sys.platform == 'darwin': + pyside_macos_deployment_target = ( + macos_pyside_min_deployment_target() + ) + log.info("MACOSX_DEPLOYMENT_TARGET set to: {}".format( + pyside_macos_deployment_target)) + log.info("=" * 30) + + def build_patchelf(self): + if not sys.platform.startswith('linux'): + return + self._patchelf_path = find_executable('patchelf') + if self._patchelf_path: + if not os.path.isabs(self._patchelf_path): + self._patchelf_path = os.path.join(os.getcwd(), self._patchelf_path) + log.info("Using {} ...".format(self._patchelf_path)) + return + log.info("Building patchelf...") + module_src_dir = os.path.join(self.sources_dir, "patchelf") + build_cmd = ["g++", "{}/patchelf.cc".format(module_src_dir), "-o", "patchelf"] + if run_process(build_cmd) != 0: + raise DistutilsSetupError("Error building patchelf") + self._patchelf_path = os.path.join(self.script_dir, "patchelf") + + def build_extension(self, extension): + # calculate the subrepos folder name + + log.info("Building module {}...".format(extension)) + + # Prepare folders + os.chdir(self.build_dir) + module_build_dir = os.path.join(self.build_dir, extension) + skipflag_file = "{} -skip".format(module_build_dir) + if os.path.exists(skipflag_file): + log.info("Skipping {} because {} exists".format(extension, skipflag_file)) + return + + module_build_exists = os.path.exists(module_build_dir) + if module_build_exists: + if not OPTION["REUSE_BUILD"]: + log.info("Deleting module build folder {}...".format(module_build_dir)) + try: + rmtree(module_build_dir) + except Exception as e: + print('***** problem removing "{}"'.format(module_build_dir)) + print('ignored error: {}'.format(e)) + else: + log.info("Reusing module build folder {}...".format(module_build_dir)) + if not os.path.exists(module_build_dir): + log.info("Creating module build folder {}...".format(module_build_dir)) + os.makedirs(module_build_dir) + os.chdir(module_build_dir) + + module_src_dir = os.path.join(self.sources_dir, extension) + + # Build module + cmake_cmd = [OPTION["CMAKE"]] + if OPTION["QUIET"]: + # Pass a special custom option, to allow printing a lot less information when doing + # a quiet build. + cmake_cmd.append('-DQUIET_BUILD=1') + if self.make_generator == "Unix Makefiles": + # Hide progress messages for each built source file. + # Doesn't seem to work if set within the cmake files themselves. + cmake_cmd.append('-DCMAKE_RULE_MESSAGES=0') + + cmake_cmd += [ + "-G", self.make_generator, + "-DBUILD_TESTS={}".format(self.build_tests), + "-DQt5Help_DIR={}".format(self.qtinfo.docs_dir), + "-DCMAKE_BUILD_TYPE={}".format(self.build_type), + "-DCMAKE_INSTALL_PREFIX={}".format(self.install_dir), + module_src_dir + ] + cmake_cmd.append("-DPYTHON_EXECUTABLE={}".format(self.py_executable)) + cmake_cmd.append("-DPYTHON_INCLUDE_DIR={}".format(self.py_include_dir)) + cmake_cmd.append("-DPYTHON_LIBRARY={}".format(self.py_library)) + + # If a custom shiboken cmake config directory path was provided, pass it to CMake. + if OPTION["SHIBOKEN_CONFIG_DIR"] and config.is_internal_pyside_build(): + if os.path.exists(OPTION["SHIBOKEN_CONFIG_DIR"]): + log.info("Using custom provided shiboken2 installation: {}" + .format(OPTION["SHIBOKEN_CONFIG_DIR"])) + cmake_cmd.append("-DShiboken2_DIR={}".format(OPTION["SHIBOKEN_CONFIG_DIR"])) + else: + log.info("Custom provided shiboken2 installation not found. Path given: {}" + .format(OPTION["SHIBOKEN_CONFIG_DIR"])) + + if OPTION["MODULE_SUBSET"]: + module_sub_set = '' + for m in OPTION["MODULE_SUBSET"].split(','): + if m.startswith('Qt'): + m = m[2:] + if module_sub_set: + module_sub_set += ';' + module_sub_set += m + cmake_cmd.append("-DMODULES={}".format(module_sub_set)) + if OPTION["SKIP_MODULES"]: + skip_modules = '' + for m in OPTION["SKIP_MODULES"].split(','): + if m.startswith('Qt'): + m = m[2:] + if skip_modules: + skip_modules += ';' + skip_modules += m + cmake_cmd.append("-DSKIP_MODULES={}".format(skip_modules)) + # Add source location for generating documentation + cmake_src_dir = OPTION["QT_SRC"] if OPTION["QT_SRC"] else qt_src_dir + cmake_cmd.append("-DQT_SRC_DIR={}".format(cmake_src_dir)) + log.info("Qt Source dir: {}".format(cmake_src_dir)) + + if self.build_type.lower() == 'debug': + cmake_cmd.append("-DPYTHON_DEBUG_LIBRARY={}".format( + self.py_library)) + + if OPTION["LIMITED_API"] == "yes": + cmake_cmd.append("-DFORCE_LIMITED_API=yes") + elif OPTION["LIMITED_API"] == "no": + cmake_cmd.append("-DFORCE_LIMITED_API=no") + elif not OPTION["LIMITED_API"]: + pass + else: + raise DistutilsSetupError("option limited-api must be 'yes' or 'no' " + "(default yes if applicable, i.e. python version >= 3.5)") + + if OPTION["VERBOSE_BUILD"]: + cmake_cmd.append("-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON") + + if OPTION["SANITIZE_ADDRESS"]: + # Some simple sanity checking. Only use at your own risk. + if (sys.platform.startswith('linux') + or sys.platform.startswith('darwin')): + cmake_cmd.append("-DSANITIZE_ADDRESS=ON") + else: + raise DistutilsSetupError("Address sanitizer can only be used on Linux and macOS.") + + if extension.lower() == "pyside2": + pyside_qt_conf_prefix = '' + if OPTION["QT_CONF_PREFIX"]: + pyside_qt_conf_prefix = OPTION["QT_CONF_PREFIX"] + else: + if OPTION["STANDALONE"]: + pyside_qt_conf_prefix = '"Qt"' + if sys.platform == 'win32': + pyside_qt_conf_prefix = '"."' + cmake_cmd.append("-DPYSIDE_QT_CONF_PREFIX={}".format( + pyside_qt_conf_prefix)) + + # Pass package version to CMake, so this string can be + # embedded into _config.py file. + package_version = get_package_version() + cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_VERSION={}".format(package_version)) + + # In case if this is a snapshot build, also pass the + # timestamp as a separate value, because it is the only + # version component that is actually generated by setup.py. + timestamp = '' + if OPTION["SNAPSHOT_BUILD"]: + timestamp = get_package_timestamp() + cmake_cmd.append("-DPACKAGE_SETUP_PY_PACKAGE_TIMESTAMP={}".format(timestamp)) + + if extension.lower() in ["shiboken2", "pyside2-tools"]: + cmake_cmd.append("-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=yes") + if sys.version_info[0] > 2: + cmake_cmd.append("-DUSE_PYTHON_VERSION=3.3") + + if sys.platform == 'darwin': + if OPTION["MACOS_ARCH"]: + # also tell cmake which architecture to use + cmake_cmd.append("-DCMAKE_OSX_ARCHITECTURES:STRING={}".format(OPTION["MACOS_ARCH"])) + + if OPTION["MACOS_USE_LIBCPP"]: + # Explicitly link the libc++ standard library (useful + # for macOS deployment targets lower than 10.9). + # This is not on by default, because most libraries and + # executables on macOS <= 10.8 are linked to libstdc++, + # and mixing standard libraries can lead to crashes. + # On macOS >= 10.9 with a similar minimum deployment + # target, libc++ is linked in implicitly, thus the + # option is a no-op in those cases. + cmake_cmd.append("-DOSX_USE_LIBCPP=ON") + + if OPTION["MACOS_SYSROOT"]: + cmake_cmd.append("-DCMAKE_OSX_SYSROOT={}".format( + OPTION["MACOS_SYSROOT"])) + else: + latest_sdk_path = run_process_output(['xcrun', '--sdk', 'macosx', + '--show-sdk-path']) + if latest_sdk_path: + latest_sdk_path = latest_sdk_path[0] + cmake_cmd.append("-DCMAKE_OSX_SYSROOT={}".format( + latest_sdk_path)) + + # Set macOS minimum deployment target (version). + # This is required so that calling + # run_process -> distutils.spawn() + # does not set its own minimum deployment target + # environment variable which is based on the python + # interpreter sysconfig value. + # Doing so could break the detected clang include paths + # for example. + deployment_target = macos_pyside_min_deployment_target() + cmake_cmd.append("-DCMAKE_OSX_DEPLOYMENT_TARGET={}".format(deployment_target)) + os.environ['MACOSX_DEPLOYMENT_TARGET'] = deployment_target + + if OPTION["DOC_BUILD_ONLINE"]: + log.info("Output format will be HTML") + cmake_cmd.append("-DDOC_OUTPUT_FORMAT=html") + else: + log.info("Output format will be qthelp") + cmake_cmd.append("-DDOC_OUTPUT_FORMAT=qthelp") + + # Build the whole documentation (rst + API) by default + cmake_cmd.append("-DFULLDOCSBUILD=1") + + if not OPTION["SKIP_CMAKE"]: + log.info("Configuring module {} ({})...".format(extension, module_src_dir)) + if run_process(cmake_cmd) != 0: + raise DistutilsSetupError("Error configuring {}".format(extension)) + else: + log.info("Reusing old configuration for module {} ({})...".format( + extension, module_src_dir)) + + log.info("-- Compiling module {}...".format(extension)) + cmd_make = [self.make_path] + if OPTION["JOBS"]: + cmd_make.append(OPTION["JOBS"]) + if run_process(cmd_make) != 0: + raise DistutilsSetupError("Error compiling {}".format(extension)) + + if not OPTION["SKIP_DOCS"]: + if extension.lower() == "shiboken2": + try: + # Check if sphinx is installed to proceed. + import sphinx + + log.info("Generating Shiboken documentation") + if run_process([self.make_path, "doc"]) != 0: + raise DistutilsSetupError("Error generating documentation " + "for {}".format(extension)) + except ImportError: + log.info("Sphinx not found, skipping documentation build") + else: + log.info("Skipped documentation generation") + + if not OPTION["SKIP_MAKE_INSTALL"]: + log.info("Installing module {}...".format(extension)) + # Need to wait a second, so installed file timestamps are + # older than build file timestamps. + # See https://gitlab.kitware.com/cmake/cmake/issues/16155 + # for issue details. + if sys.platform == 'darwin': + log.info("Waiting 1 second, to ensure installation is successful...") + time.sleep(1) + # ninja: error: unknown target 'install/fast' + target = 'install/fast' if self.make_generator != 'Ninja' else 'install' + if run_process([self.make_path, target]) != 0: + raise DistutilsSetupError("Error pseudo installing {}".format( + extension)) + else: + log.info("Skipped installing module {}".format(extension)) + + os.chdir(self.script_dir) + + def prepare_packages(self): + """ + This will copy all relevant files from the various locations in the "cmake install dir", + to the setup tools build dir (which is read from self.build_lib provided by distutils). + + After that setuptools.command.build_py is smart enough to copy everything + from the build dir to the install dir (the virtualenv site-packages for example). + """ + try: + log.info("\nPreparing setup tools build directory.\n") + vars = { + "site_packages_dir": self.site_packages_dir, + "sources_dir": self.sources_dir, + "install_dir": self.install_dir, + "build_dir": self.build_dir, + "script_dir": self.script_dir, + "st_build_dir": self.st_build_dir, + "cmake_package_name": config.package_name(), + "st_package_name": config.package_name(), + "ssl_libs_dir": OPTION["OPENSSL"], + "py_version": self.py_version, + "qt_version": self.qtinfo.version, + "qt_bin_dir": self.qtinfo.bins_dir, + "qt_doc_dir": self.qtinfo.docs_dir, + "qt_lib_dir": self.qtinfo.libs_dir, + "qt_lib_execs_dir": self.qtinfo.lib_execs_dir, + "qt_plugins_dir": self.qtinfo.plugins_dir, + "qt_prefix_dir": self.qtinfo.prefix_dir, + "qt_translations_dir": self.qtinfo.translations_dir, + "qt_qml_dir": self.qtinfo.qml_dir, + "target_arch": self.py_arch, + } + + # Needed for correct file installation in generator build + # case. + if config.is_internal_shiboken_generator_build(): + vars['cmake_package_name'] = config.shiboken_module_option_name + + os.chdir(self.script_dir) + + if sys.platform == "win32": + vars['dbg_postfix'] = OPTION["DEBUG"] and "_d" or "" + return prepare_packages_win32(self, vars) + else: + return prepare_packages_posix(self, vars) + except IOError as e: + print('setup.py/prepare_packages: ', e) + raise + + def qt_is_framework_build(self): + if os.path.isdir(self.qtinfo.headers_dir + "/../lib/QtCore.framework"): + return True + return False + + def get_built_pyside_config(self, vars): + # Get config that contains list of built modules, and + # SOVERSIONs of the built libraries. + st_build_dir = vars['st_build_dir'] + config_path = os.path.join(st_build_dir, config.package_name(), "_config.py") + temp_config = get_python_dict(config_path) + if 'built_modules' not in temp_config: + temp_config['built_modules'] = [] + return temp_config + + def is_webengine_built(self, built_modules): + return ('WebEngineWidgets' in built_modules + or 'WebEngineCore' in built_modules + or 'WebEngine' in built_modules) + + def prepare_standalone_clang(self, is_win=False): + """ + Copies the libclang library to the shiboken2-generator + package so that the shiboken executable works. + """ + log.info('Finding path to the libclang shared library.') + cmake_cmd = [ + OPTION["CMAKE"], + "-L", # Lists variables + "-N", # Just inspects the cache (faster) + "--build", # Specifies the build dir + self.shiboken_build_dir + ] + out = run_process_output(cmake_cmd) + lines = [s.strip() for s in out] + pattern = re.compile(r"CLANG_LIBRARY:FILEPATH=(.+)$") + + clang_lib_path = None + for line in lines: + match = pattern.search(line) + if match: + clang_lib_path = match.group(1) + break + + if not clang_lib_path: + raise RuntimeError("Could not find the location of the libclang " + "library inside the CMake cache file.") + + if is_win: + # clang_lib_path points to the static import library + # (lib/libclang.lib), whereas we want to copy the shared + # library (bin/libclang.dll). + clang_lib_path = re.sub(r'lib/libclang.lib$', + 'bin/libclang.dll', + clang_lib_path) + else: + # shiboken2 links against libclang.so.6 or a similarly + # named library. + # If the linked against library is a symlink, resolve + # the symlink once (but not all the way to the real + # file) on Linux and macOS, + # so that we get the path to the "SO version" symlink + # (the one used as the install name in the shared library + # dependency section). + # E.g. On Linux libclang.so -> libclang.so.6 -> + # libclang.so.6.0. + # "libclang.so.6" is the name we want for the copied file. + if os.path.islink(clang_lib_path): + link_target = os.readlink(clang_lib_path) + if os.path.isabs(link_target): + clang_lib_path = link_target + else: + # link_target is relative, transform to absolute. + clang_lib_path = os.path.join(os.path.dirname(clang_lib_path), link_target) + clang_lib_path = os.path.abspath(clang_lib_path) + + # The destination will be the shiboken package folder. + vars = {} + vars['st_build_dir'] = self.st_build_dir + vars['st_package_name'] = config.package_name() + destination_dir = "{st_build_dir}/{st_package_name}".format(**vars) + + if os.path.exists(clang_lib_path): + basename = os.path.basename(clang_lib_path) + log.info('Copying libclang shared library {} to the package folder as {}.'.format( + clang_lib_path, basename)) + destination_path = os.path.join(destination_dir, basename) + + # Need to modify permissions in case file is not writable + # (a reinstall would cause a permission denied error). + copyfile(clang_lib_path, + destination_path, + force_copy_symlink=True, + make_writable_by_owner=True) + else: + raise RuntimeError("Error copying libclang library " + "from {} to {}. ".format(clang_lib_path, destination_dir)) + + def update_rpath(self, package_path, executables): + if sys.platform.startswith('linux'): + pyside_libs = [lib for lib in os.listdir( + package_path) if filter_match(lib, ["*.so", "*.so.*"])] + + def rpath_cmd(srcpath): + final_rpath = '' + # Command line rpath option takes precedence over + # automatically added one. + if OPTION["RPATH_VALUES"]: + final_rpath = OPTION["RPATH_VALUES"] + else: + # Add rpath values pointing to $ORIGIN and the + # installed qt lib directory. + final_rpath = self.qtinfo.libs_dir + if OPTION["STANDALONE"]: + final_rpath = "$ORIGIN/Qt/lib" + override = OPTION["STANDALONE"] + linux_fix_rpaths_for_library(self._patchelf_path, srcpath, final_rpath, + override=override) + + elif sys.platform == 'darwin': + pyside_libs = [lib for lib in os.listdir( + package_path) if filter_match(lib, ["*.so", "*.dylib"])] + + def rpath_cmd(srcpath): + final_rpath = '' + # Command line rpath option takes precedence over + # automatically added one. + if OPTION["RPATH_VALUES"]: + final_rpath = OPTION["RPATH_VALUES"] + else: + if OPTION["STANDALONE"]: + final_rpath = "@loader_path/Qt/lib" + else: + final_rpath = self.qtinfo.libs_dir + macos_fix_rpaths_for_library(srcpath, final_rpath) + + else: + raise RuntimeError('Not configured for platform {}'.format(sys.platform)) + + pyside_libs.extend(executables) + + # Update rpath in PySide2 libs + for srcname in pyside_libs: + srcpath = os.path.join(package_path, srcname) + if os.path.isdir(srcpath) or os.path.islink(srcpath): + continue + if not os.path.exists(srcpath): + continue + rpath_cmd(srcpath) + log.info("Patched rpath to '$ORIGIN/' (Linux) or " + "updated rpath (OS/X) in {}.".format(srcpath)) + + +class PysideRstDocs(Command, DistUtilsCommandMixin): + description = "Build .rst documentation only" + user_options = DistUtilsCommandMixin.mixin_user_options + + def initialize_options(self): + DistUtilsCommandMixin.__init__(self) + log.info("-- This build process will not include the API documentation." + "API documentation requires a full build of pyside/shiboken.") + self.skip = False + if config.is_internal_shiboken_generator_build(): + self.skip = True + if not self.skip: + self.name = config.package_name().lower() + self.doc_dir = os.path.join(config.setup_script_dir, "sources") + self.doc_dir = os.path.join(self.doc_dir, self.name) + self.doc_dir = os.path.join(self.doc_dir, "doc") + try: + # Check if sphinx is installed to proceed. + import sphinx + if self.name == "shiboken2": + log.info("-- Generating Shiboken documentation") + log.info("-- Documentation directory: 'html/pyside2/shiboken2/'") + elif self.name == "pyside2": + log.info("-- Generating PySide documentation") + log.info("-- Documentation directory: 'html/pyside2/'") + except ImportError: + raise DistutilsSetupError("Sphinx not found - aborting") + self.html_dir = "html" + + # creating directories html/pyside2/shiboken2 + try: + if not os.path.isdir(self.html_dir): + os.mkdir(self.html_dir) + if self.name == "shiboken2": + out_pyside = os.path.join(self.html_dir, "pyside2") + if not os.path.isdir(out_pyside): + os.mkdir(out_pyside) + out_shiboken = os.path.join(out_pyside, "shiboken2") + if not os.path.isdir(out_shiboken): + os.mkdir(out_shiboken) + self.out_dir = out_shiboken + # We know that on the shiboken step, we already created the + # 'pyside2' directory + elif self.name == "pyside2": + self.out_dir = os.path.join(self.html_dir, "pyside2") + except: + raise DistutilsSetupError("Error while creating directories for {}".format(self.doc_dir)) + + def run(self): + if not self.skip: + cmake_cmd = [OPTION["CMAKE"]] + cmake_cmd += [ + "-S", self.doc_dir, + "-B", self.out_dir, + "-DDOC_OUTPUT_FORMAT=html", + "-DFULLDOCSBUILD=0", + ] + if run_process(cmake_cmd) != 0: + raise DistutilsSetupError("Error running CMake for {}".format(self.doc_dir)) + + if self.name == "pyside2": + self.sphinx_src = os.path.join(self.out_dir, "rst") + elif self.name == "shiboken2": + self.sphinx_src = self.out_dir + + sphinx_cmd = ["sphinx-build", "-b", "html", "-c", self.sphinx_src, + self.doc_dir, self.out_dir] + if run_process(sphinx_cmd) != 0: + raise DistutilsSetupError("Error running CMake for {}".format(self.doc_dir)) + # Last message + if not self.skip and self.name == "pyside2": + log.info("-- The documentation was built. Check html/pyside2/index.html") + + def finalize_options(self): + DistUtilsCommandMixin.mixin_finalize_options(self) + + +cmd_class_dict = { + 'build': PysideBuild, + 'build_py': PysideBuildPy, + 'build_ext': PysideBuildExt, + 'bdist_egg': PysideBdistEgg, + 'develop': PysideDevelop, + 'install': PysideInstall, + 'install_lib': PysideInstallLib, + 'build_rst_docs': PysideRstDocs, +} +if wheel_module_exists: + pyside_bdist_wheel = get_bdist_wheel_override() + if pyside_bdist_wheel: + cmd_class_dict['bdist_wheel'] = pyside_bdist_wheel diff --git a/build_scripts/options.py b/build_scripts/options.py new file mode 100644 index 0000000..eb5d438 --- /dev/null +++ b/build_scripts/options.py @@ -0,0 +1,340 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function +import distutils.log as log +from distutils.spawn import find_executable +import sys +import os +import warnings + +from .qtinfo import QtInfo + + +_AVAILABLE_MKSPECS = ["msvc", "mingw", "ninja"] if sys.platform == "win32" else ["make", "ninja"] + + +# Global options not which are not part of the commands +ADDITIONAL_OPTIONS = """ +Additional options: + --limited-api Use Limited API [yes/no] + ---macos-use-libc++ Use libc++ on macOS + --snapshot-build Snapshot build + --package-timestamp Package Timestamp +""" + + +def _warn_multiple_option(option): + warnings.warn('Option "{}" occurs multiple times on the command line.'.format(option)) + + +def _warn_deprecated_option(option, replacement=None): + w = 'Option "{}" is deprecated and may be removed in a future release.'.format(option) + if replacement: + w = '{}\nUse "{}" instead.'.format(w, replacement) + warnings.warn(w) + + +class Options(object): + def __init__(self): + + # Dictionary containing values of all the possible options. + self.dict = {} + + def has_option(self, name, remove=True): + """ Returns True if argument '--name' was passed on the command + line. """ + option = '--{}'.format(name) + count = sys.argv.count(option) + remove_count = count + if not remove and count > 0: + remove_count -= 1 + for i in range(remove_count): + sys.argv.remove(option) + if count > 1: + _warn_multiple_option(option) + return count > 0 + + def option_value(self, name, short_option_name=None, remove=True): + """ + Returns the value of a command line option or environment + variable. + + :param name: The name of the command line option or environment + variable. + + :param remove: Whether the option and its value should be + removed from sys.argv. Useful when there's a need to query for + the value and also pass it along to setuptools for example. + + :return: Either the option value or None. + """ + option = '--' + name + short_option = '-' + short_option_name if short_option_name else None + single_option_prefix = option + '=' + value = None + for index in reversed(range(len(sys.argv))): + arg = sys.argv[index] + if arg == option or short_option and arg == short_option: + if value: + _warn_multiple_option(option) + else: + if index + 1 >= len(sys.argv): + raise RuntimeError("The option {} requires a value".format(option)) + value = sys.argv[index + 1] + + if remove: + sys.argv[index:index + 2] = [] + + elif arg.startswith(single_option_prefix): + if value: + _warn_multiple_option(option) + else: + value = arg[len(single_option_prefix):] + + if remove: + sys.argv[index:index + 1] = [] + + if value is None: + value = os.getenv(name.upper().replace('-', '_')) + + self.dict[name] = value + return value + + +options = Options() + + +def has_option(*args, **kwargs): + return options.has_option(*args, **kwargs) + + +def option_value(*args, **kwargs): + return options.option_value(*args, **kwargs) + + +def _jobs_option_value(): + """Option value for parallel builds.""" + value = option_value('parallel', short_option_name='j') + if value: + return '-j' + value if not value.startswith('-j') else value + return '' + + +# Declare options which need to be known when instantiating the DistUtils +# commands. +OPTION = { + "BUILD_TYPE": option_value("build-type"), + "INTERNAL_BUILD_TYPE": option_value("internal-build-type"), + # number of parallel build jobs + "JOBS": _jobs_option_value(), + # Legacy, not used any more. + "JOM": has_option('jom'), + "MACOS_USE_LIBCPP": has_option("macos-use-libc++"), + "QUIET": has_option('quiet', remove=False), + "SNAPSHOT_BUILD": has_option("snapshot-build"), + "LIMITED_API": option_value("limited-api"), + "PACKAGE_TIMESTAMP": option_value("package-timestamp"), + # This is used automatically by distutils.command.install object, to + # specify the final installation location. + "FINAL_INSTALL_PREFIX": option_value("prefix", remove=False) + # This is used to identify the template for doc builds +} +_deprecated_option_jobs = option_value('jobs') +if _deprecated_option_jobs: + _warn_deprecated_option('jobs', 'parallel') + OPTION["JOBS"] = _deprecated_option_jobs + + +class DistUtilsCommandMixin(object): + """Mixin for the DistUtils build/install commands handling the options.""" + + _finalized = False + + mixin_user_options = [ + ('debug', None, 'Build with debug information'), + ('relwithdebinfo', None, 'Build in release mode with debug information'), + ('only-package', None, 'Package only'), + ('standalone', None, 'Standalone build'), + ('ignore-git', None, 'Do update subrepositories'), + ('skip-docs', None, 'Skip documentation build'), + ('no-examples', None, 'Do not build examples'), + ('no-jom', None, 'Do not use jom (MSVC)'), + ('build-tests', None, 'Build tests'), + ('use-xvfb', None, 'Use Xvfb for testing'), + ('reuse-build', None, 'Reuse existing build'), + ('skip-cmake', None, 'Skip CMake step'), + ('skip-make-install', None, 'Skip install step'), + ('skip-packaging', None, 'Skip packaging step'), + ('verbose-build', None, 'Verbose build'), + ('sanitize-address', None, 'Build with address sanitizer'), + ('shorter-paths', None, 'Use shorter paths'), + ('doc-build-online', None, 'Build online documentation'), + ('qmake=', None, 'Path to qmake'), + ('qt=', None, 'Qt version'), + ('cmake=', None, 'Path to CMake'), + ('openssl=', None, 'Path to OpenSSL libraries'), + ('shiboken-config-dir=', None, 'shiboken configuration directory'), + ('make-spec=', None, 'Qt make-spec'), + ('macos-arch=', None, 'macOS architecture'), + ('macos-sysroot=', None, 'macOS sysroot'), + ('macos-deployment-target=', None, 'macOS deployment target'), + ('skip-modules=', None, 'Qt modules to be skipped'), + ('module-subset=', None, 'Qt modules to be built'), + ('rpath=', None, 'RPATH'), + ('qt-conf-prefix=', None, 'Qt configuration prefix'), + ('qt-src-dir=', None, 'Qt source directory')] + + def __init__(self): + self.debug = False + self.relwithdebinfo = False + self.only_package = False + self.standalone = False + self.ignore_git = False + self.skip_docs = False + self.no_examples = False + self.no_jom = False + self.build_tests = False + self.use_xvfb = False + self.reuse_build = False + self.skip_cmake = False + self.skip_make_install = False + self.skip_packaging = False + self.verbose_build = False + self.sanitize_address = False + self.snapshot_build = False + self.shorter_paths = False + self.doc_build_online = False + self.qmake = None + self.qt = '5' + self.cmake = None + self.openssl = None + self.shiboken_config_dir = None + self.make_spec = None + self.macos_arch = None + self.macos_sysroot = None + self.macos_deployment_target = None + self.skip_modules = None + self.module_subset = None + self.rpath = None + self.qt_conf_prefix = None + self.qt_src_dir = None + + def mixin_finalize_options(self): + # Bail out on 2nd call to mixin_finalize_options() since that is the + # build command following the install command when invoking + # setup.py install + if not DistUtilsCommandMixin._finalized: + DistUtilsCommandMixin._finalized = True + self._do_finalize() + + def _do_finalize(self): + if not self._determine_defaults_and_check(): + sys.exit(-1) + OPTION['DEBUG'] = self.debug + OPTION['RELWITHDEBINFO'] = self.relwithdebinfo + OPTION['ONLYPACKAGE'] = self.only_package + OPTION['STANDALONE'] = self.standalone + OPTION['IGNOREGIT'] = self.ignore_git + OPTION['SKIP_DOCS'] = self.skip_docs + OPTION['NOEXAMPLES'] = self.no_examples + OPTION['BUILDTESTS'] = self.build_tests + OPTION['NO_JOM'] = self.no_jom + OPTION['XVFB'] = self.use_xvfb + OPTION['REUSE_BUILD'] = self.reuse_build + OPTION['SKIP_CMAKE'] = self.skip_cmake + OPTION['SKIP_MAKE_INSTALL'] = self.skip_make_install + OPTION['SKIP_PACKAGING'] = self.skip_packaging + OPTION['VERBOSE_BUILD'] = self.verbose_build + if self.verbose_build: + log.set_verbosity(1) + OPTION['SANITIZE_ADDRESS'] = self.sanitize_address + OPTION['SHORTER_PATHS'] = self.shorter_paths + OPTION['DOC_BUILD_ONLINE'] = self.doc_build_online + # make qtinfo.py independent of relative paths. + qmake_abs_path = os.path.abspath(self.qmake) + OPTION['QMAKE'] = qmake_abs_path + OPTION['QT_VERSION'] = self.qt + QtInfo().setup(qmake_abs_path, self.qt) + OPTION['CMAKE'] = os.path.abspath(self.cmake) + OPTION['OPENSSL'] = self.openssl + OPTION['SHIBOKEN_CONFIG_DIR'] = self.shiboken_config_dir + OPTION['MAKESPEC'] = self.make_spec + OPTION['MACOS_ARCH'] = self.macos_arch + OPTION['MACOS_SYSROOT'] = self.macos_sysroot + OPTION['MACOS_DEPLOYMENT_TARGET'] = self.macos_deployment_target + OPTION['SKIP_MODULES'] = self.skip_modules + OPTION['MODULE_SUBSET'] = self.module_subset + OPTION['RPATH_VALUES'] = self.rpath + OPTION['QT_CONF_PREFIX'] = self.qt_conf_prefix + OPTION['QT_SRC'] = self.qt_src_dir + + def _determine_defaults_and_check(self): + if not self.cmake: + self.cmake = find_executable("cmake") + if not self.cmake: + print("cmake could not be found.") + return False + if not os.path.exists(self.cmake): + print("'{}' does not exist.".format(self.cmake)) + return False + + if not self.qmake: + self.qmake = find_executable("qmake") + if not self.qmake: + self.qmake = find_executable("qmake-qt5") + if not self.qmake: + print("qmake could not be found.") + return False + if not os.path.exists(self.qmake): + print("'{}' does not exist.".format(self.qmake)) + return False + + if not self.make_spec: + self.make_spec = _AVAILABLE_MKSPECS[0] + if self.make_spec not in _AVAILABLE_MKSPECS: + print('Invalid option --make-spec "{}". Available values are {}'.format(OPTION["MAKESPEC"], + _AVAILABLE_MKSPECS)) + return False + + if OPTION["JOBS"] and sys.platform == 'win32' and self.no_jom: + print("Option --jobs can only be used with jom on Windows.") + return False + + return True diff --git a/build_scripts/platforms/__init__.py b/build_scripts/platforms/__init__.py new file mode 100644 index 0000000..571d374 --- /dev/null +++ b/build_scripts/platforms/__init__.py @@ -0,0 +1,38 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# diff --git a/build_scripts/platforms/linux.py b/build_scripts/platforms/linux.py new file mode 100644 index 0000000..712739e --- /dev/null +++ b/build_scripts/platforms/linux.py @@ -0,0 +1,146 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from ..utils import (copydir, copyfile, copy_icu_libs, find_files_using_glob, + linux_set_rpaths, linux_run_read_elf, linux_get_rpaths, + rpaths_has_origin) +from ..config import config + + +def prepare_standalone_package_linux(self, vars): + built_modules = vars['built_modules'] + + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + should_copy_icu_libs = True + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + should_copy_icu_libs = False + + # /lib/* -> /{st_package_name}/Qt/lib + destination_lib_dir = "{st_build_dir}/{st_package_name}/Qt/lib" + + accepted_modules = ['libQt5*.so.?'] + if constrain_modules: + accepted_modules = ["libQt5" + module + "*.so.?" for module in constrain_modules] + accepted_modules.append("libicu*.so.??") + + copydir("{qt_lib_dir}", destination_lib_dir, + filter=accepted_modules, + recursive=False, vars=vars, force_copy_symlinks=True) + + if should_copy_icu_libs: + # Check if ICU libraries were copied over to the destination + # Qt libdir. + resolved_destination_lib_dir = destination_lib_dir.format(**vars) + maybe_icu_libs = find_files_using_glob(resolved_destination_lib_dir, "libicu*") + + # If no ICU libraries are present in the Qt libdir (like when + # Qt is built against system ICU, or in the Coin CI where ICU + # libs are in a different directory) try to find out / resolve + # which ICU libs are used by QtCore (if used at all) using a + # custom written ldd, and copy the ICU libs to the Pyside Qt + # dir if necessary. We choose the QtCore lib to inspect, by + # checking which QtCore library the shiboken2 executable uses. + if not maybe_icu_libs: + copy_icu_libs(self._patchelf_path, resolved_destination_lib_dir) + + # Patching designer to use the Qt libraries provided in the wheel + if config.is_internal_pyside_build(): + designer_path = "{st_build_dir}/{st_package_name}/designer".format(**vars) + rpaths = linux_get_rpaths(designer_path) + if not rpaths or not rpaths_has_origin(rpaths): + rpaths.insert(0, '$ORIGIN/../lib') + new_rpaths_string = ":".join(rpaths) + linux_set_rpaths(self._patchelf_path, designer_path, new_rpaths_string) + + if self.is_webengine_built(built_modules): + copydir("{qt_lib_execs_dir}", + "{st_build_dir}/{st_package_name}/Qt/libexec", + filter=None, + recursive=False, + vars=vars) + + copydir("{qt_prefix_dir}/resources", + "{st_build_dir}/{st_package_name}/Qt/resources", + filter=None, + recursive=False, + vars=vars) + + if copy_plugins: + # /plugins/* -> /{st_package_name}/Qt/plugins + copydir("{qt_plugins_dir}", + "{st_build_dir}/{st_package_name}/Qt/plugins", + filter=["*.so"], + recursive=True, + vars=vars) + + if copy_qml: + # /qml/* -> /{st_package_name}/Qt/qml + copydir("{qt_qml_dir}", + "{st_build_dir}/{st_package_name}/Qt/qml", + filter=None, + force=False, + recursive=True, + ignore=["*.so.debug"], + vars=vars) + + if copy_translations: + # /translations/* -> + # /{st_package_name}/Qt/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/Qt/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) + + if copy_qt_conf: + # Copy the qt.conf file to libexec. + copyfile( + "{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}/Qt/libexec", + vars=vars) diff --git a/build_scripts/platforms/macos.py b/build_scripts/platforms/macos.py new file mode 100644 index 0000000..7932db3 --- /dev/null +++ b/build_scripts/platforms/macos.py @@ -0,0 +1,211 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import fnmatch +import os +from ..utils import copydir, copyfile, macos_fix_rpaths_for_library, macos_add_rpath +from ..config import config + + +def prepare_standalone_package_macos(self, vars): + built_modules = vars['built_modules'] + + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + constrain_frameworks = ['Qt' + name + '.framework' for name in constrain_modules] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + + # Directory filter for skipping unnecessary files. + def general_dir_filter(dir_name, parent_full_path, dir_full_path): + if fnmatch.fnmatch(dir_name, "*.dSYM"): + return False + return True + + # Filter out debug plugins and qml plugins in the + # debug_and_release config. + no_copy_debug = True + + def file_variant_filter(file_name, file_full_path): + if self.qtinfo.build_type != 'debug_and_release': + return True + if file_name.endswith('_debug.dylib') and no_copy_debug: + return False + return True + + # Patching designer to use the Qt libraries provided in the wheel + if config.is_internal_pyside_build(): + designer_bundle = "{st_build_dir}/{st_package_name}/Designer.app".format(**vars) + designer_binary = "{}/Contents/MacOS/Designer".format(designer_bundle) + rpath = "@loader_path/../../../Qt/lib" + macos_add_rpath(rpath, designer_binary) + + # /lib/* -> /{st_package_name}/Qt/lib + if self.qt_is_framework_build(): + def framework_dir_filter(dir_name, parent_full_path, dir_full_path): + if '.framework' in dir_name: + if (dir_name.startswith('QtWebEngine') + and not self.is_webengine_built(built_modules)): + return False + if constrain_modules and dir_name not in constrain_frameworks: + return False + + if dir_name in ['Headers', 'fonts']: + return False + if dir_full_path.endswith('Versions/Current'): + return False + if dir_full_path.endswith('Versions/5/Resources'): + return False + if dir_full_path.endswith('Versions/5/Helpers'): + return False + return general_dir_filter(dir_name, parent_full_path, dir_full_path) + + # Filter out debug frameworks in the + # debug_and_release config. + no_copy_debug = True + + def framework_variant_filter(file_name, file_full_path): + if self.qtinfo.build_type != 'debug_and_release': + return True + dir_path = os.path.dirname(file_full_path) + in_framework = dir_path.endswith("Versions/5") + if file_name.endswith('_debug') and in_framework and no_copy_debug: + return False + return True + + copydir("{qt_lib_dir}", "{st_build_dir}/{st_package_name}/Qt/lib", + recursive=True, vars=vars, + ignore=["*.la", "*.a", "*.cmake", "*.pc", "*.prl"], + dir_filter_function=framework_dir_filter, + file_filter_function=framework_variant_filter) + + # Fix rpath for WebEngine process executable. The already + # present rpath does not work because it assumes a symlink + # from Versions/5/Helpers, thus adding two more levels of + # directory hierarchy. + if self.is_webengine_built(built_modules): + qt_lib_path = "{st_build_dir}/{st_package_name}/Qt/lib".format(**vars) + bundle = "QtWebEngineCore.framework/Helpers/" + bundle += "QtWebEngineProcess.app" + binary = "Contents/MacOS/QtWebEngineProcess" + webengine_process_path = os.path.join(bundle, binary) + final_path = os.path.join(qt_lib_path, webengine_process_path) + rpath = "@loader_path/../../../../../" + macos_fix_rpaths_for_library(final_path, rpath) + else: + ignored_modules = [] + if not self.is_webengine_built(built_modules): + ignored_modules.extend(['libQt5WebEngine*.dylib']) + if 'WebKit' not in built_modules: + ignored_modules.extend(['libQt5WebKit*.dylib']) + accepted_modules = ['libQt5*.5.dylib'] + if constrain_modules: + accepted_modules = ["libQt5" + module + "*.5.dylib" for module in constrain_modules] + + copydir("{qt_lib_dir}", + "{st_build_dir}/{st_package_name}/Qt/lib", + filter=accepted_modules, + ignore=ignored_modules, + file_filter_function=file_variant_filter, + recursive=True, vars=vars, force_copy_symlinks=True) + + if self.is_webengine_built(built_modules): + copydir("{qt_lib_execs_dir}", + "{st_build_dir}/{st_package_name}/Qt/libexec", + filter=None, + recursive=False, + vars=vars) + + copydir("{qt_prefix_dir}/resources", + "{st_build_dir}/{st_package_name}/Qt/resources", + filter=None, + recursive=False, + vars=vars) + + # Fix rpath for WebEngine process executable. + qt_libexec_path = "{st_build_dir}/{st_package_name}/Qt/libexec".format(**vars) + binary = "QtWebEngineProcess" + final_path = os.path.join(qt_libexec_path, binary) + rpath = "@loader_path/../lib" + macos_fix_rpaths_for_library(final_path, rpath) + + if copy_qt_conf: + # Copy the qt.conf file to libexec. + copyfile( + "{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}/Qt/libexec", + vars=vars) + + if copy_plugins: + # /plugins/* -> /{st_package_name}/Qt/plugins + copydir("{qt_plugins_dir}", + "{st_build_dir}/{st_package_name}/Qt/plugins", + filter=["*.dylib"], + recursive=True, + dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, + vars=vars) + + if copy_qml: + # /qml/* -> /{st_package_name}/Qt/qml + copydir("{qt_qml_dir}", + "{st_build_dir}/{st_package_name}/Qt/qml", + filter=None, + recursive=True, + force=False, + dir_filter_function=general_dir_filter, + file_filter_function=file_variant_filter, + vars=vars) + + if copy_translations: + # /translations/* -> + # /{st_package_name}/Qt/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/Qt/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) diff --git a/build_scripts/platforms/unix.py b/build_scripts/platforms/unix.py new file mode 100644 index 0000000..b842510 --- /dev/null +++ b/build_scripts/platforms/unix.py @@ -0,0 +1,227 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import sys +import fnmatch +from .linux import prepare_standalone_package_linux +from .macos import prepare_standalone_package_macos + +from ..config import config +from ..options import OPTION +from ..utils import copydir, copyfile, makefile +from ..utils import regenerate_qt_resources + + +def prepare_packages_posix(self, vars): + executables = [] + + # /lib/site-packages/{st_package_name}/* -> + # /{st_package_name} + # This copies the module .so/.dylib files and various .py files + # (__init__, config, git version, etc.) + copydir( + "{site_packages_dir}/{st_package_name}", + "{st_build_dir}/{st_package_name}", + vars=vars) + + generated_config = self.get_built_pyside_config(vars) + + def adjusted_lib_name(name, version): + postfix = '' + if sys.platform.startswith('linux'): + postfix = '.so.' + version + elif sys.platform == 'darwin': + postfix = '.' + version + '.dylib' + return name + postfix + + if config.is_internal_shiboken_module_build(): + # /shiboken2/doc/html/* -> + # /{st_package_name}/docs/shiboken2 + copydir( + "{build_dir}/shiboken2/doc/html", + "{st_build_dir}/{st_package_name}/docs/shiboken2", + force=False, vars=vars) + + # /lib/lib* -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=[ + adjusted_lib_name("libshiboken*", + generated_config['shiboken_library_soversion']), + ], + recursive=False, vars=vars, force_copy_symlinks=True) + + if config.is_internal_shiboken_generator_build(): + # /bin/* -> {st_package_name}/ + executables.extend(copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=[ + "shiboken2", + ], + recursive=False, vars=vars)) + + # Used to create scripts directory. + makefile( + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + vars=vars) + + # For setting up setuptools entry points. + copyfile( + "{install_dir}/bin/shiboken_tool.py", + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + force=False, vars=vars) + + if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build(): + # /include/* -> /{st_package_name}/include + copydir( + "{install_dir}/include/{cmake_package_name}", + "{st_build_dir}/{st_package_name}/include", + vars=vars) + + if config.is_internal_pyside_build(): + makefile( + "{st_build_dir}/{st_package_name}/scripts/__init__.py", + vars=vars) + + # For setting up setuptools entry points + copyfile( + "{install_dir}/bin/pyside_tool.py", + "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py", + force=False, vars=vars) + + # /bin/* -> {st_package_name}/ + executables.extend(copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=[ + "pyside2-lupdate", + "uic", + "rcc", + ], + recursive=False, vars=vars)) + + # Copying designer + if sys.platform == "darwin": + executables.extend(copydir( + "{install_dir}/bin/Designer.app", + "{st_build_dir}/{st_package_name}/Designer.app", + filter=None, recursive=True, + force=False, vars=vars)) + else: + copyfile( + "{install_dir}/bin/designer", + "{st_build_dir}/{st_package_name}/designer", + force=False, vars=vars) + + # /lib/lib* -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=[ + adjusted_lib_name("libpyside*", + generated_config['pyside_library_soversion']), + ], + recursive=False, vars=vars, force_copy_symlinks=True) + + # /share/{st_package_name}/typesystems/* -> + # /{st_package_name}/typesystems + copydir( + "{install_dir}/share/{st_package_name}/typesystems", + "{st_build_dir}/{st_package_name}/typesystems", + vars=vars) + + # /share/{st_package_name}/glue/* -> + # /{st_package_name}/glue + copydir( + "{install_dir}/share/{st_package_name}/glue", + "{st_build_dir}/{st_package_name}/glue", + vars=vars) + + # /pyside2/{st_package_name}/support/* -> + # /{st_package_name}/support/* + copydir( + "{build_dir}/pyside2/{st_package_name}/support", + "{st_build_dir}/{st_package_name}/support", + vars=vars) + + # /pyside2/{st_package_name}/*.pyi -> + # /{st_package_name}/*.pyi + copydir( + "{build_dir}/pyside2/{st_package_name}", + "{st_build_dir}/{st_package_name}", + filter=["*.pyi", "py.typed"], + vars=vars) + + if not OPTION["NOEXAMPLES"]: + def pycache_dir_filter(dir_name, parent_full_path, dir_full_path): + if fnmatch.fnmatch(dir_name, "__pycache__"): + return False + return True + # examples/* -> /{st_package_name}/examples + copydir(os.path.join(self.script_dir, "examples"), + "{st_build_dir}/{st_package_name}/examples", + force=False, vars=vars, dir_filter_function=pycache_dir_filter) + # Re-generate examples Qt resource files for Python 3 + # compatibility + if sys.version_info[0] == 3: + examples_path = "{st_build_dir}/{st_package_name}/examples".format(**vars) + pyside_rcc_path = "{install_dir}/bin/rcc".format(**vars) + pyside_rcc_options = ['-g', 'python'] + regenerate_qt_resources(examples_path, pyside_rcc_path, pyside_rcc_options) + + # Copy Qt libs to package + if OPTION["STANDALONE"]: + if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build(): + vars['built_modules'] = generated_config['built_modules'] + if sys.platform == 'darwin': + prepare_standalone_package_macos(self, vars) + else: + prepare_standalone_package_linux(self, vars) + + if config.is_internal_shiboken_generator_build(): + # Copy over clang before rpath patching. + self.prepare_standalone_clang(is_win=False) + + # Update rpath to $ORIGIN + if sys.platform.startswith('linux') or sys.platform.startswith('darwin'): + rpath_path = "{st_build_dir}/{st_package_name}".format(**vars) + self.update_rpath(rpath_path, executables) diff --git a/build_scripts/platforms/windows_desktop.py b/build_scripts/platforms/windows_desktop.py new file mode 100644 index 0000000..345847e --- /dev/null +++ b/build_scripts/platforms/windows_desktop.py @@ -0,0 +1,478 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import functools +import os +import sys +import fnmatch + +from ..config import config +from ..options import OPTION +from ..utils import copydir, copyfile, makefile +from ..utils import regenerate_qt_resources, filter_match +from ..utils import download_and_extract_7z + + +def prepare_packages_win32(self, vars): + # For now, debug symbols will not be shipped into the package. + copy_pdbs = False + pdbs = [] + if (self.debug or self.build_type == 'RelWithDebInfo') and copy_pdbs: + pdbs = ['*.pdb'] + + # /lib/site-packages/{st_package_name}/* -> + # /{st_package_name} + # This copies the module .pyd files and various .py files + # (__init__, config, git version, etc.) + copydir( + "{site_packages_dir}/{st_package_name}", + "{st_build_dir}/{st_package_name}", + vars=vars) + + if config.is_internal_shiboken_module_build(): + # /shiboken2/doc/html/* -> + # /{st_package_name}/docs/shiboken2 + copydir( + "{build_dir}/shiboken2/doc/html", + "{st_build_dir}/{st_package_name}/docs/shiboken2", + force=False, vars=vars) + + # /bin/*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.dll"], + recursive=False, vars=vars) + + # /lib/*.lib -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.lib"], + recursive=False, vars=vars) + + # @TODO: Fix this .pdb file not to overwrite release + # {shibokengenerator}.pdb file. + # Task-number: PYSIDE-615 + copydir( + "{build_dir}/shiboken2/shibokenmodule", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + # pdb files for libshiboken and libpyside + copydir( + "{build_dir}/shiboken2/libshiboken", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + if config.is_internal_shiboken_generator_build(): + # /bin/*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["shiboken*.exe"], + recursive=False, vars=vars) + + # Used to create scripts directory. + makefile( + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + vars=vars) + + # For setting up setuptools entry points. + copyfile( + "{install_dir}/bin/shiboken_tool.py", + "{st_build_dir}/{st_package_name}/scripts/shiboken_tool.py", + force=False, vars=vars) + + # @TODO: Fix this .pdb file not to overwrite release + # {shibokenmodule}.pdb file. + # Task-number: PYSIDE-615 + copydir( + "{build_dir}/shiboken2/generator", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + if config.is_internal_shiboken_generator_build() or config.is_internal_pyside_build(): + # /include/* -> /{st_package_name}/include + copydir( + "{install_dir}/include/{cmake_package_name}", + "{st_build_dir}/{st_package_name}/include", + vars=vars) + + if config.is_internal_pyside_build(): + # /pyside2/{st_package_name}/*.pdb -> + # /{st_package_name} + copydir( + "{build_dir}/pyside2/{st_package_name}", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + makefile( + "{st_build_dir}/{st_package_name}/scripts/__init__.py", + vars=vars) + + # For setting up setuptools entry points + copyfile( + "{install_dir}/bin/pyside_tool.py", + "{st_build_dir}/{st_package_name}/scripts/pyside_tool.py", + force=False, vars=vars) + + # /bin/*.exe,*.dll -> {st_package_name}/ + copydir( + "{install_dir}/bin/", + "{st_build_dir}/{st_package_name}", + filter=["pyside*.exe", "pyside*.dll", "uic.exe", "rcc.exe", "designer.exe"], + recursive=False, vars=vars) + + # /lib/*.lib -> {st_package_name}/ + copydir( + "{install_dir}/lib/", + "{st_build_dir}/{st_package_name}", + filter=["pyside*.lib"], + recursive=False, vars=vars) + + # /share/{st_package_name}/typesystems/* -> + # /{st_package_name}/typesystems + copydir( + "{install_dir}/share/{st_package_name}/typesystems", + "{st_build_dir}/{st_package_name}/typesystems", + vars=vars) + + # /share/{st_package_name}/glue/* -> + # /{st_package_name}/glue + copydir( + "{install_dir}/share/{st_package_name}/glue", + "{st_build_dir}/{st_package_name}/glue", + vars=vars) + + # /pyside2/{st_package_name}/support/* -> + # /{st_package_name}/support/* + copydir( + "{build_dir}/pyside2/{st_package_name}/support", + "{st_build_dir}/{st_package_name}/support", + vars=vars) + + # /pyside2/{st_package_name}/*.pyi -> + # /{st_package_name}/*.pyi + copydir( + "{build_dir}/pyside2/{st_package_name}", + "{st_build_dir}/{st_package_name}", + filter=["*.pyi", "py.typed"], + vars=vars) + + copydir( + "{build_dir}/pyside2/libpyside", + "{st_build_dir}/{st_package_name}", + filter=pdbs, + recursive=False, vars=vars) + + if not OPTION["NOEXAMPLES"]: + def pycache_dir_filter(dir_name, parent_full_path, dir_full_path): + if fnmatch.fnmatch(dir_name, "__pycache__"): + return False + return True + # examples/* -> /{st_package_name}/examples + copydir(os.path.join(self.script_dir, "examples"), + "{st_build_dir}/{st_package_name}/examples", + force=False, vars=vars, dir_filter_function=pycache_dir_filter) + # Re-generate examples Qt resource files for Python 3 + # compatibility + if sys.version_info[0] == 3: + examples_path = "{st_build_dir}/{st_package_name}/examples".format( + **vars) + pyside_rcc_path = "{install_dir}/bin/rcc.exe".format( + **vars) + pyside_rcc_options = ['-g', 'python'] + regenerate_qt_resources(examples_path, pyside_rcc_path, pyside_rcc_options) + + if vars['ssl_libs_dir']: + # /* -> /{st_package_name}/openssl + copydir("{ssl_libs_dir}", "{st_build_dir}/{st_package_name}/openssl", + filter=[ + "libeay32.dll", + "ssleay32.dll"], + force=False, vars=vars) + + if config.is_internal_shiboken_module_build(): + # The C++ std library dlls need to be packaged with the + # shiboken module, because libshiboken uses C++ code. + copy_msvc_redist_files(vars, "{build_dir}/msvc_redist".format(**vars)) + + if config.is_internal_pyside_build() or config.is_internal_shiboken_generator_build(): + copy_qt_artifacts(self, copy_pdbs, vars) + copy_msvc_redist_files(vars, "{build_dir}/msvc_redist".format(**vars)) + + +def copy_msvc_redist_files(vars, redist_target_path): + # MSVC redistributable file list. + msvc_redist = [ + "concrt140.dll", + "msvcp140.dll", + "ucrtbase.dll", + "vcamp140.dll", + "vccorlib140.dll", + "vcomp140.dll", + "vcruntime140.dll", + "vcruntime140_1.dll", + "msvcp140_1.dll", + "msvcp140_2.dll", + "msvcp140_codecvt_ids.dll" + ] + + # Make a directory where the files should be extracted. + if not os.path.exists(redist_target_path): + os.makedirs(redist_target_path) + + # Extract Qt dependency dlls when building on Qt CI. + in_coin = os.environ.get('COIN_LAUNCH_PARAMETERS', None) + if in_coin is not None: + redist_url = "http://download.qt.io/development_releases/prebuilt/vcredist/" + zip_file = "pyside_qt_deps_64_2019.7z" + if "{target_arch}".format(**vars) == "32": + zip_file = "pyside_qt_deps_32_2019.7z" + download_and_extract_7z(redist_url + zip_file, redist_target_path) + else: + print("Qt dependency DLLs (MSVC redist) will not be downloaded and extracted.") + + copydir(redist_target_path, + "{st_build_dir}/{st_package_name}", + filter=msvc_redist, recursive=False, vars=vars) + + +def copy_qt_artifacts(self, copy_pdbs, vars): + built_modules = self.get_built_pyside_config(vars)['built_modules'] + + constrain_modules = None + copy_plugins = True + copy_qml = True + copy_translations = True + copy_qt_conf = True + copy_qt_permanent_artifacts = True + copy_msvc_redist = False + copy_clang = False + + if config.is_internal_shiboken_generator_build(): + constrain_modules = ["Core", "Network", "Xml", "XmlPatterns"] + copy_plugins = False + copy_qml = False + copy_translations = False + copy_qt_conf = False + copy_qt_permanent_artifacts = False + copy_msvc_redist = True + copy_clang = True + + # /bin/*.dll and Qt *.exe -> /{st_package_name} + qt_artifacts_permanent = [ + "opengl*.dll", + "d3d*.dll", + "designer.exe", + "linguist.exe", + "lrelease.exe", + "lupdate.exe", + "lconvert.exe", + "qtdiag.exe" + ] + + # Choose which EGL library variants to copy. + qt_artifacts_egl = [ + "libEGL{}.dll", + "libGLESv2{}.dll" + ] + if self.qtinfo.build_type != 'debug_and_release': + egl_suffix = '*' + elif self.debug: + egl_suffix = 'd' + else: + egl_suffix = '' + qt_artifacts_egl = [a.format(egl_suffix) for a in qt_artifacts_egl] + + artifacts = [] + if copy_qt_permanent_artifacts: + artifacts += qt_artifacts_permanent + artifacts += qt_artifacts_egl + + if copy_msvc_redist: + # The target path has to be qt_bin_dir at the moment, + # because the extracted archive also contains the opengl32sw + # and the d3dcompiler dlls, which are copied not by this + # function, but by the copydir below. + copy_msvc_redist_files(vars, "{qt_bin_dir}".format(**vars)) + + if artifacts: + copydir("{qt_bin_dir}", + "{st_build_dir}/{st_package_name}", + filter=artifacts, recursive=False, vars=vars) + + # /bin/*.dll and Qt *.pdbs -> /{st_package_name} part two + # File filter to copy only debug or only release files. + if constrain_modules: + qt_dll_patterns = ["Qt5" + x + "{}.dll" for x in constrain_modules] + if copy_pdbs: + qt_dll_patterns += ["Qt5" + x + "{}.pdb" for x in constrain_modules] + else: + qt_dll_patterns = ["Qt5*{}.dll", "lib*{}.dll"] + if copy_pdbs: + qt_dll_patterns += ["Qt5*{}.pdb", "lib*{}.pdb"] + + def qt_build_config_filter(patterns, file_name, file_full_path): + release = [a.format('') for a in patterns] + debug = [a.format('d') for a in patterns] + + # If qt is not a debug_and_release build, that means there + # is only one set of shared libraries, so we can just copy + # them. + if self.qtinfo.build_type != 'debug_and_release': + if filter_match(file_name, release): + return True + return False + + # In debug_and_release case, choosing which files to copy + # is more difficult. We want to copy only the files that + # match the PySide2 build type. So if PySide2 is built in + # debug mode, we want to copy only Qt debug libraries + # (ending with "d.dll"). Or vice versa. The problem is that + # some libraries have "d" as the last character of the + # actual library name (for example Qt5Gamepad.dll and + # Qt5Gamepadd.dll). So we can't just match a pattern ending + # in "d". Instead we check if there exists a file with the + # same name plus an additional "d" at the end, and using + # that information we can judge if the currently processed + # file is a debug or release file. + + # e.g. ["Qt5Cored", ".dll"] + file_split = os.path.splitext(file_name) + file_base_name = file_split[0] + file_ext = file_split[1] + # e.g. "/home/work/qt/qtbase/bin" + file_path_dir_name = os.path.dirname(file_full_path) + # e.g. "Qt5Coredd" + maybe_debug_name = "{}d".format(file_base_name) + if self.debug: + filter = debug + + def predicate(path): + return not os.path.exists(path) + else: + filter = release + + def predicate(path): + return os.path.exists(path) + # e.g. "/home/work/qt/qtbase/bin/Qt5Coredd.dll" + other_config_path = os.path.join(file_path_dir_name, maybe_debug_name + file_ext) + + if (filter_match(file_name, filter) and predicate(other_config_path)): + return True + return False + + qt_dll_filter = functools.partial(qt_build_config_filter, + qt_dll_patterns) + copydir("{qt_bin_dir}", + "{st_build_dir}/{st_package_name}", + file_filter_function=qt_dll_filter, + recursive=False, vars=vars) + + if copy_plugins: + # /plugins/* -> /{st_package_name}/plugins + plugin_dll_patterns = ["*{}.dll"] + pdb_pattern = "*{}.pdb" + if copy_pdbs: + plugin_dll_patterns += [pdb_pattern] + plugin_dll_filter = functools.partial(qt_build_config_filter, plugin_dll_patterns) + copydir("{qt_plugins_dir}", "{st_build_dir}/{st_package_name}/plugins", + file_filter_function=plugin_dll_filter, + vars=vars) + + if copy_translations: + # /translations/* -> /{st_package_name}/translations + copydir("{qt_translations_dir}", + "{st_build_dir}/{st_package_name}/translations", + filter=["*.qm", "*.pak"], + force=False, + vars=vars) + + if copy_qml: + # /qml/* -> /{st_package_name}/qml + qml_dll_patterns = ["*{}.dll"] + qml_ignore_patterns = qml_dll_patterns + [pdb_pattern] + qml_ignore = [a.format('') for a in qml_ignore_patterns] + + # Copy all files that are not dlls and pdbs (.qml, qmldir). + copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml", + ignore=qml_ignore, + force=False, + recursive=True, + vars=vars) + + if copy_pdbs: + qml_dll_patterns += [pdb_pattern] + qml_dll_filter = functools.partial(qt_build_config_filter, qml_dll_patterns) + + # Copy all dlls (and possibly pdbs). + copydir("{qt_qml_dir}", "{st_build_dir}/{st_package_name}/qml", + file_filter_function=qml_dll_filter, + force=False, + recursive=True, + vars=vars) + + if self.is_webengine_built(built_modules): + copydir("{qt_prefix_dir}/resources", + "{st_build_dir}/{st_package_name}/resources", + filter=None, + recursive=False, + vars=vars) + + filter = 'QtWebEngineProcess{}.exe'.format( + 'd' if self.debug else '') + copydir("{qt_bin_dir}", + "{st_build_dir}/{st_package_name}", + filter=[filter], + recursive=False, vars=vars) + + if copy_qt_conf: + # Copy the qt.conf file to prefix dir. + copyfile("{build_dir}/pyside2/{st_package_name}/qt.conf", + "{st_build_dir}/{st_package_name}", + vars=vars) + + if copy_clang: + self.prepare_standalone_clang(is_win=True) diff --git a/build_scripts/qp5_tool.py b/build_scripts/qp5_tool.py new file mode 100644 index 0000000..0dea03b --- /dev/null +++ b/build_scripts/qp5_tool.py @@ -0,0 +1,435 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +from argparse import ArgumentParser, RawTextHelpFormatter +import datetime +from enum import Enum +import os +import re +import subprocess +import sys +import time +import warnings + + +DESC = """ +Utility script for working with Qt for Python. + +Feel free to extend! + +Typical Usage: +Update and build a repository: python qp5_tool -p -b + +qp5_tool.py uses a configuration file "%CONFIGFILE%" +in the format key=value. + +It is possible to use repository-specific values by adding a key postfixed by +a dash and the repository folder base name, eg: +Modules-pyside-setup512=Core,Gui,Widgets,Network,Test + +Configuration keys: +Acceleration Incredibuild or unset +BuildArguments Arguments to setup.py +Generator Generator to be used for CMake. Currently, only Ninja is + supported. +Jobs Number of jobs to be run simultaneously +Modules Comma separated list of modules to be built + (for --module-subset=) +Python Python executable (Use python_d for debug builds on Windows) + +Arbitrary keys can be defined and referenced by $(name): + +MinimalModules=Core,Gui,Widgets,Network,Test +Modules=$(MinimalModules),Multimedia +Modules-pyside-setup-minimal=$(MinimalModules) +""" + + +class Acceleration(Enum): + NONE = 0 + INCREDIBUILD = 1 + + +class BuildMode(Enum): + NONE = 0 + BUILD = 1 + RECONFIGURE = 2 + MAKE = 3 + + +DEFAULT_BUILD_ARGS = ['--build-tests', '--skip-docs', '--quiet'] +IS_WINDOWS = sys.platform == 'win32' +INCREDIBUILD_CONSOLE = 'BuildConsole' if IS_WINDOWS else '/opt/incredibuild/bin/ib_console' +# Config file keys +ACCELERATION_KEY = 'Acceleration' +BUILDARGUMENTS_KEY = 'BuildArguments' +GENERATOR_KEY = 'Generator' +JOBS_KEY = 'Jobs' +MODULES_KEY = 'Modules' +PYTHON_KEY = 'Python' + +DEFAULT_MODULES = "Core,Gui,Widgets,Network,Test,Qml,Quick,Multimedia,MultimediaWidgets" +DEFAULT_CONFIG_FILE = "Modules={}\n".format(DEFAULT_MODULES) + +build_mode = BuildMode.NONE +opt_dry_run = False + + +def which(needle): + """Perform a path search""" + needles = [needle] + if IS_WINDOWS: + for ext in ("exe", "bat", "cmd"): + needles.append("{}.{}".format(needle, ext)) + + for path in os.environ.get("PATH", "").split(os.pathsep): + for n in needles: + binary = os.path.join(path, n) + if os.path.isfile(binary): + return binary + return None + + +def command_log_string(args, dir): + result = '[{}]'.format(os.path.basename(dir)) + for arg in args: + result += ' "{}"'.format(arg) if ' ' in arg else ' {}'.format(arg) + return result + + +def execute(args): + """Execute a command and print to log""" + log_string = command_log_string(args, os.getcwd()) + print(log_string) + if opt_dry_run: + return + exit_code = subprocess.call(args) + if exit_code != 0: + raise RuntimeError('FAIL({}): {}'.format(exit_code, log_string)) + + +def run_process_output(args): + """Run a process and return its output. Also run in dry_run mode""" + std_out = subprocess.Popen(args, universal_newlines=1, + stdout=subprocess.PIPE).stdout + result = [line.rstrip() for line in std_out.readlines()] + std_out.close() + return result + + +def run_git(args): + """Run git in the current directory and its submodules""" + args.insert(0, git) # run in repo + execute(args) # run for submodules + module_args = [git, "submodule", "foreach"] + module_args.extend(args) + execute(module_args) + + +def expand_reference(cache_dict, value): + """Expand references to other keys in config files $(name) by value.""" + pattern = re.compile(r"\$\([^)]+\)") + while True: + match = pattern.match(value) + if not match: + break + key = match.group(0)[2:-1] + value = value[:match.start(0)] + cache_dict[key] + value[match.end(0):] + return value + + +def editor(): + editor = os.getenv('EDITOR') + if not editor: + return 'notepad' if IS_WINDOWS else 'vi' + editor = editor.strip() + if IS_WINDOWS: + # Windows: git requires quotes in the variable + if editor.startswith('"') and editor.endswith('"'): + editor = editor[1:-1] + editor = editor.replace('/', '\\') + return editor + + +def edit_config_file(): + exit_code = -1 + try: + exit_code = subprocess.call([editor(), config_file]) + except Exception as e: + reason = str(e) + print('Unable to launch: {}: {}'.format(editor(), reason)) + return exit_code + + +""" +Config file handling, cache and read function +""" +config_dict = {} + + +def read_config_file(file_name): + """Read the config file into config_dict, expanding continuation lines""" + global config_dict + keyPattern = re.compile(r'^\s*([A-Za-z0-9\_\-]+)\s*=\s*(.*)$') + with open(file_name) as f: + while True: + line = f.readline() + if not line: + break + line = line.rstrip() + match = keyPattern.match(line) + if match: + key = match.group(1) + value = match.group(2) + while value.endswith('\\'): + value = value.rstrip('\\') + value += f.readline().rstrip() + config_dict[key] = expand_reference(config_dict, value) + + +def read_config(key): + """ + Read a value from the '$HOME/.qp5_tool' configuration file. When given + a key 'key' for the repository directory '/foo/qt-5', check for the + repo-specific value 'key-qt5' and then for the general 'key'. + """ + if not config_dict: + read_config_file(config_file) + repo_value = config_dict.get(key + '-' + base_dir) + return repo_value if repo_value else config_dict.get(key) + + +def read_bool_config(key): + value = read_config(key) + return value and value in ['1', 'true', 'True'] + + +def read_int_config(key, default=-1): + value = read_config(key) + return int(value) if value else default + + +def read_acceleration_config(): + value = read_config(ACCELERATION_KEY) + if value: + value = value.lower() + if value == 'incredibuild': + return Acceleration.INCREDIBUILD + return Acceleration.NONE + + +def read_config_build_arguments(): + value = read_config(BUILDARGUMENTS_KEY) + if value: + return re.split(r'\s+', value) + return DEFAULT_BUILD_ARGS + + +def read_config_modules_argument(): + value = read_config(MODULES_KEY) + if value and value != '' and value != 'all': + return '--module-subset=' + value + return None + + +def read_config_python_binary(): + binary = read_config(PYTHON_KEY) + if binary: + return binary + # Use 'python3' unless virtualenv is set + use_py3 = (not os.environ.get('VIRTUAL_ENV') and which('python3')) + return 'python3' if use_py3 else 'python' + + +def get_config_file(base_name): + home = os.getenv('HOME') + if IS_WINDOWS: + # Set a HOME variable on Windows such that scp. etc. + # feel at home (locating .ssh). + if not home: + home = os.getenv('HOMEDRIVE') + os.getenv('HOMEPATH') + os.environ['HOME'] = home + user = os.getenv('USERNAME') + config_file = os.path.join(os.getenv('APPDATA'), base_name) + else: + user = os.getenv('USER') + config_dir = os.path.join(home, '.config') + if os.path.exists(config_dir): + config_file = os.path.join(config_dir, base_name) + else: + config_file = os.path.join(home, '.' + base_name) + return config_file + + +def build(target): + """Run configure and build steps""" + start_time = time.time() + + arguments = [] + acceleration = read_acceleration_config() + if not IS_WINDOWS and acceleration == Acceleration.INCREDIBUILD: + arguments.append(INCREDIBUILD_CONSOLE) + arguments.append('--avoid') # caching, v0.96.74 + arguments.extend([read_config_python_binary(), 'setup.py', target]) + arguments.extend(read_config_build_arguments()) + generator = read_config(GENERATOR_KEY) + if generator == 'Ninja': + arguments.extend(['--make-spec', 'ninja']) + jobs = read_int_config(JOBS_KEY) + if jobs > 1: + arguments.extend(['-j', str(jobs)]) + if build_mode != BuildMode.BUILD: + arguments.extend(['--reuse-build', '--ignore-git']) + if build_mode != BuildMode.RECONFIGURE: + arguments.append('--skip-cmake') + modules = read_config_modules_argument() + if modules: + arguments.append(modules) + if IS_WINDOWS and acceleration == Acceleration.INCREDIBUILD: + arg_string = ' '.join(arguments) + arguments = [INCREDIBUILD_CONSOLE, '/command={}'.format(arg_string)] + + execute(arguments) + + elapsed_time = int(time.time() - start_time) + print('--- Done({}s) ---'.format(elapsed_time)) + + +def run_tests(): + """Run tests redirected into a log file with a time stamp""" + logfile_name = datetime.datetime.today().strftime("test_%Y%m%d_%H%M.txt") + binary = sys.executable + command = '"{}" testrunner.py test > {}'.format(binary, logfile_name) + print(command_log_string([command], os.getcwd())) + start_time = time.time() + result = 0 if opt_dry_run else os.system(command) + elapsed_time = int(time.time() - start_time) + print('--- Done({}s) ---'.format(elapsed_time)) + return result + + +def create_argument_parser(desc): + parser = ArgumentParser(description=desc, formatter_class=RawTextHelpFormatter) + parser.add_argument('--dry-run', '-d', action='store_true', + help='Dry run, print commands') + parser.add_argument('--edit', '-e', action='store_true', + help='Edit config file') + parser.add_argument('--reset', '-r', action='store_true', + help='Git reset hard to upstream state') + parser.add_argument('--clean', '-c', action='store_true', + help='Git clean') + parser.add_argument('--pull', '-p', action='store_true', + help='Git pull') + parser.add_argument('--build', '-b', action='store_true', + help='Build (configure + build)') + parser.add_argument('--make', '-m', action='store_true', help='Make') + parser.add_argument('--no-install', '-n', action='store_true', + help='Run --build only, do not install') + parser.add_argument('--Make', '-M', action='store_true', + help='cmake + Make (continue broken build)') + parser.add_argument('--test', '-t', action='store_true', + help='Run tests') + parser.add_argument('--version', '-v', action='version', version='%(prog)s 1.0') + return parser + + +if __name__ == '__main__': + git = None + base_dir = None + config_file = None + user = None + + config_file = get_config_file('qp5_tool.conf') + argument_parser = create_argument_parser(DESC.replace('%CONFIGFILE%', config_file)) + options = argument_parser.parse_args() + opt_dry_run = options.dry_run + + if options.edit: + sys.exit(edit_config_file()) + + if options.build: + build_mode = BuildMode.BUILD + elif options.make: + build_mode = BuildMode.MAKE + elif options.Make: + build_mode = BuildMode.RECONFIGURE + + if build_mode == BuildMode.NONE and not (options.clean or options.reset + or options.pull or options.test): + argument_parser.print_help() + sys.exit(0) + + git = 'git' + if which(git) is None: + warnings.warn('Unable to find git', RuntimeWarning) + sys.exit(-1) + + if not os.path.exists(config_file): + print('Create initial config file ', config_file, " ..") + with open(config_file, 'w') as f: + f.write(DEFAULT_CONFIG_FILE.format(' '.join(DEFAULT_BUILD_ARGS))) + + while not os.path.exists('.gitmodules'): + cwd = os.getcwd() + if cwd == '/' or (IS_WINDOWS and len(cwd) < 4): + warnings.warn('Unable to find git root', RuntimeWarning) + sys.exit(-1) + os.chdir(os.path.dirname(cwd)) + + base_dir = os.path.basename(os.getcwd()) + + if options.clean: + run_git(['clean', '-dxf']) + + if options.reset: + run_git(['reset', '--hard', '@{upstream}']) + + if options.pull: + run_git(['pull', '--rebase']) + + if build_mode != BuildMode.NONE: + target = 'build' if options.no_install else 'install' + build(target) + + if options.test: + sys.exit(run_tests()) + + sys.exit(0) diff --git a/build_scripts/qtinfo.py b/build_scripts/qtinfo.py new file mode 100644 index 0000000..62bfee8 --- /dev/null +++ b/build_scripts/qtinfo.py @@ -0,0 +1,262 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import sys +import re +import subprocess + + +def _effective_qmake_command(qmake, qt_version): + """Check whether qmake path is a link to qtchooser and append the + desired Qt version in that case""" + result = [qmake] + # Looking whether qmake path is a link to qtchooser and whether the link + # exists + if os.path.islink(qmake) and os.path.lexists(qmake): + if not qt_version: + print('--qt must be specified when using qtchooser.') + sys.exit(-1) + # Set -qt=X here. + if "qtchooser" in os.readlink(qmake): + result.append("-qt={}".format(qt_version)) + return result + + +class QtInfo(object): + class __QtInfo: # Python singleton + def __init__(self): + self._qmake_command = None + # Dict to cache qmake values. + self._query_dict = {} + # Dict to cache mkspecs variables. + self._mkspecs_dict = {} + + def setup(self, qmake, qt_version): + self._qmake_command = _effective_qmake_command(qmake, qt_version) + + def get_qmake_command(self): + qmake_command_string = self._qmake_command[0] + for entry in self._qmake_command[1:]: + qmake_command_string += " {}".format(entry) + return qmake_command_string + + def get_version(self): + return self.get_property("QT_VERSION") + + def get_bins_path(self): + return self.get_property("QT_INSTALL_BINS") + + def get_libs_path(self): + return self.get_property("QT_INSTALL_LIBS") + + def get_libs_execs_path(self): + return self.get_property("QT_INSTALL_LIBEXECS") + + def get_plugins_path(self): + return self.get_property("QT_INSTALL_PLUGINS") + + def get_prefix_path(self): + return self.get_property("QT_INSTALL_PREFIX") + + def get_imports_path(self): + return self.get_property("QT_INSTALL_IMPORTS") + + def get_translations_path(self): + return self.get_property("QT_INSTALL_TRANSLATIONS") + + def get_headers_path(self): + return self.get_property("QT_INSTALL_HEADERS") + + def get_docs_path(self): + return self.get_property("QT_INSTALL_DOCS") + + def get_qml_path(self): + return self.get_property("QT_INSTALL_QML") + + def get_macos_deployment_target(self): + """ Return value is a macOS version or None. """ + return self.get_property("QMAKE_MACOSX_DEPLOYMENT_TARGET") + + def get_build_type(self): + """ + Return value is either debug, release, debug_release, or None. + """ + return self.get_property("BUILD_TYPE") + + def get_src_dir(self): + """ Return path to Qt src dir or None.. """ + return self.get_property("QT_INSTALL_PREFIX/src") + + def get_property(self, prop_name): + if not self._query_dict: + self._get_query_properties() + self._get_other_properties() + if prop_name not in self._query_dict: + return None + return self._query_dict[prop_name] + + def get_mkspecs_variables(self): + return self._mkspecs_dict + + def _get_qmake_output(self, args_list=[]): + assert(self._qmake_command) + cmd = self._qmake_command + args_list + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=False) + output = proc.communicate()[0] + proc.wait() + if proc.returncode != 0: + return "" + if sys.version_info >= (3,): + output = str(output, 'ascii').strip() + else: + output = output.strip() + return output + + def _parse_query_properties(self, process_output): + props = {} + if not process_output: + return props + lines = [s.strip() for s in process_output.splitlines()] + for line in lines: + if line and ':' in line: + key, value = line.split(':', 1) + props[key] = value + return props + + def _get_query_properties(self): + output = self._get_qmake_output(['-query']) + self._query_dict = self._parse_query_properties(output) + + def _parse_qt_build_type(self): + key = 'QT_CONFIG' + if key not in self._mkspecs_dict: + return None + + qt_config = self._mkspecs_dict[key] + if 'debug_and_release' in qt_config: + return 'debug_and_release' + + split = qt_config.split(' ') + if 'release' in split and 'debug' in split: + return 'debug_and_release' + + if 'release' in split: + return 'release' + + if 'debug' in split: + return 'debug' + + return None + + def _get_other_properties(self): + # Get the src property separately, because it is not returned by + # qmake unless explicitly specified. + key = 'QT_INSTALL_PREFIX/src' + result = self._get_qmake_output(['-query', key]) + self._query_dict[key] = result + + # Get mkspecs variables and cache them. + self._get_qmake_mkspecs_variables() + + # Get macOS minimum deployment target. + key = 'QMAKE_MACOSX_DEPLOYMENT_TARGET' + if key in self._mkspecs_dict: + self._query_dict[key] = self._mkspecs_dict[key] + + # Figure out how Qt was built: + # debug mode, release mode, or both. + build_type = self._parse_qt_build_type() + if build_type: + self._query_dict['BUILD_TYPE'] = build_type + + def _get_qmake_mkspecs_variables(self): + # Create empty temporary qmake project file. + temp_file_name = 'qmake_fake_empty_project.txt' + open(temp_file_name, 'a').close() + + # Query qmake for all of its mkspecs variables. + qmake_output = self._get_qmake_output(['-E', temp_file_name]) + lines = [s.strip() for s in qmake_output.splitlines()] + pattern = re.compile(r"^(.+?)=(.+?)$") + for line in lines: + found = pattern.search(line) + if found: + key = found.group(1).strip() + value = found.group(2).strip() + self._mkspecs_dict[key] = value + + # We need to clean up after qmake, which always creates a + # .qmake.stash file after a -E invocation. + qmake_stash_file = os.path.join(os.getcwd(), ".qmake.stash") + if os.path.exists(qmake_stash_file): + os.remove(qmake_stash_file) + + # Also clean up the temporary empty project file. + if os.path.exists(temp_file_name): + os.remove(temp_file_name) + + version = property(get_version) + bins_dir = property(get_bins_path) + libs_dir = property(get_libs_path) + lib_execs_dir = property(get_libs_execs_path) + plugins_dir = property(get_plugins_path) + prefix_dir = property(get_prefix_path) + qmake_command = property(get_qmake_command) + imports_dir = property(get_imports_path) + translations_dir = property(get_translations_path) + headers_dir = property(get_headers_path) + docs_dir = property(get_docs_path) + qml_dir = property(get_qml_path) + macos_min_deployment_target = property(get_macos_deployment_target) + build_type = property(get_build_type) + src_dir = property(get_src_dir) + + _instance = None # singleton helpers + + def __new__(cls): # __new__ always a classmethod + if not QtInfo._instance: + QtInfo._instance = QtInfo.__QtInfo() + return QtInfo._instance + + def __getattr__(self, name): + return getattr(self._instance, name) + + def __setattr__(self, name): + return setattr(self._instance, name) diff --git a/build_scripts/setup_runner.py b/build_scripts/setup_runner.py new file mode 100644 index 0000000..57c8fbd --- /dev/null +++ b/build_scripts/setup_runner.py @@ -0,0 +1,177 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import os +import textwrap + +from setuptools import setup # Import setuptools before distutils +import distutils.log as log + +from build_scripts.config import config +from build_scripts.main import get_package_version, get_setuptools_extension_modules +from build_scripts.main import cmd_class_dict +from build_scripts.options import ADDITIONAL_OPTIONS, OPTION +from build_scripts.utils import run_process + + +class SetupRunner(object): + def __init__(self, orig_argv): + self.invocations_list = [] + + # Keep the original args around in case we ever need to pass + # modified arguments to the sub invocations. + self.orig_argv = orig_argv + self.sub_argv = list(orig_argv) + + self.setup_script_dir = os.getcwd() + + @staticmethod + def cmd_line_argument_is_in_args(argument, args): + """ Check if command line argument was passed in args. """ + return any(arg for arg in list(args) if "--" + argument in arg) + + @staticmethod + def remove_cmd_line_argument_in_args(argument, args): + """ Remove command line argument from args. """ + return [arg for arg in list(args) if "--" + argument not in arg] + + @staticmethod + def construct_cmd_line_argument(name, value=None): + """ Constructs a command line argument given name and value. """ + if not value: + return "--{}".format(name) + return "--{}={}".format(name, value) + + @staticmethod + def construct_internal_build_type_cmd_line_argument(internal_build_type): + return SetupRunner.construct_cmd_line_argument("internal-build-type", internal_build_type) + + def add_setup_internal_invocation(self, build_type, reuse_build=False): + """ Enqueues a script sub-invocation to be executed later. """ + internal_build_type_arg = self.construct_internal_build_type_cmd_line_argument(build_type) + setup_cmd = [sys.executable] + self.sub_argv + [internal_build_type_arg] + + # Add --reuse-build option if requested and not already present. + if reuse_build and not self.cmd_line_argument_is_in_args("reuse-build", self.sub_argv): + setup_cmd.append(self.construct_cmd_line_argument("reuse-build")) + self.invocations_list.append(setup_cmd) + + def run_setup(self): + """ + Decide what kind of build is requested and then execute it. + In the top-level invocation case, the script + will spawn setup.py again (possibly multiple times). + In the internal invocation case, the script + will run setuptools.setup(). + """ + + # Prepare initial config. + config.init_config(build_type=OPTION["BUILD_TYPE"], + internal_build_type=OPTION["INTERNAL_BUILD_TYPE"], + cmd_class_dict=cmd_class_dict, + package_version=get_package_version(), + ext_modules=get_setuptools_extension_modules(), + setup_script_dir=self.setup_script_dir, + quiet=OPTION["QUIET"]) + + # This is an internal invocation of setup.py, so start actual + # build. + if config.is_internal_invocation(): + if config.internal_build_type not in config.get_allowed_internal_build_values(): + raise RuntimeError("Invalid '{}' option given to --internal-build-type. " + .format(config.internal_build_type)) + self.run_setuptools_setup() + return + + # This is a top-level invocation of setup.py, so figure out what + # modules we will build and depending on that, call setup.py + # multiple times with different arguments. + if config.build_type not in config.get_allowed_top_level_build_values(): + raise RuntimeError("Invalid '{}' option given to --build-type. " + .format(config.build_type)) + + # Build everything: shiboken2, shiboken2-generator and PySide2. + help_requested = '--help' in self.sub_argv or '-h' in self.sub_argv + if help_requested: + self.add_setup_internal_invocation(config.pyside_option_name) + + elif config.is_top_level_build_all(): + self.add_setup_internal_invocation(config.shiboken_module_option_name) + + # Reuse the shiboken build for the generator package instead + # of rebuilding it again. + self.add_setup_internal_invocation(config.shiboken_generator_option_name, + reuse_build=True) + + self.add_setup_internal_invocation(config.pyside_option_name) + + elif config.is_top_level_build_shiboken_module(): + self.add_setup_internal_invocation(config.shiboken_module_option_name) + + elif config.is_top_level_build_shiboken_generator(): + self.add_setup_internal_invocation(config.shiboken_generator_option_name) + + elif config.is_top_level_build_pyside(): + self.add_setup_internal_invocation(config.pyside_option_name) + + for cmd in self.invocations_list: + cmd_as_string = " ".join(cmd) + log.info("\nRunning setup: {}\n".format(cmd_as_string)) + exit_code = run_process(cmd) + if exit_code != 0: + msg = textwrap.dedent(""" + setup.py invocation failed with exit code: {}.\n\n + setup.py invocation was: {} + """).format(exit_code, cmd_as_string) + raise RuntimeError(msg) + + if help_requested: + print(ADDITIONAL_OPTIONS) + + + @staticmethod + def run_setuptools_setup(): + """ + Runs setuptools.setup() once in a single setup.py + sub-invocation. + """ + + kwargs = config.setup_kwargs + setup(**kwargs) diff --git a/build_scripts/utils.py b/build_scripts/utils.py new file mode 100644 index 0000000..0782ae0 --- /dev/null +++ b/build_scripts/utils.py @@ -0,0 +1,1166 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import os +import re +import stat +import errno +import shutil +import subprocess +import fnmatch +import itertools +import glob + +# There is no urllib.request in Python2 +try: + import urllib.request as urllib +except ImportError: + import urllib + +import distutils.log as log +from distutils.errors import DistutilsSetupError + +try: + WindowsError +except NameError: + WindowsError = None + + +def filter_match(name, patterns): + for pattern in patterns: + if pattern is None: + continue + if fnmatch.fnmatch(name, pattern): + return True + return False + + +def update_env_path(newpaths): + paths = os.environ['PATH'].lower().split(os.pathsep) + for path in newpaths: + if not path.lower() in paths: + log.info("Inserting path '{}' to environment".format(path)) + paths.insert(0, path) + os.environ['PATH'] = "{}{}{}".format(path, os.pathsep, os.environ['PATH']) + + +def winsdk_setenv(platform_arch, build_type): + from distutils.msvc9compiler import VERSION as MSVC_VERSION + from distutils.msvc9compiler import Reg + from distutils.msvc9compiler import HKEYS + from distutils.msvc9compiler import WINSDK_BASE + + sdk_version_map = { + "v6.0a": 9.0, + "v6.1": 9.0, + "v7.0": 9.0, + "v7.0a": 10.0, + "v7.1": 10.0 + } + + log.info("Searching Windows SDK with MSVC compiler version {}".format(MSVC_VERSION)) + setenv_paths = [] + for base in HKEYS: + sdk_versions = Reg.read_keys(base, WINSDK_BASE) + if sdk_versions: + for sdk_version in sdk_versions: + installationfolder = Reg.get_value("{}\\{}".format(WINSDK_BASE, sdk_version), + "installationfolder") + # productversion = Reg.get_value("{}\\{}".format(WINSDK_BASE, sdk_version), + # "productversion") + setenv_path = os.path.join(installationfolder, os.path.join('bin', 'SetEnv.cmd')) + if not os.path.exists(setenv_path): + continue + if sdk_version not in sdk_version_map: + continue + if sdk_version_map[sdk_version] != MSVC_VERSION: + continue + setenv_paths.append(setenv_path) + if len(setenv_paths) == 0: + raise DistutilsSetupError("Failed to find the Windows SDK with MSVC compiler " + "version {}".format(MSVC_VERSION)) + for setenv_path in setenv_paths: + log.info("Found {}".format(setenv_path)) + + # Get SDK env (use latest SDK version installed on system) + setenv_path = setenv_paths[-1] + log.info("Using {} ".format(setenv_path)) + build_arch = "/x86" if platform_arch.startswith("32") else "/x64" + build_type = "/Debug" if build_type.lower() == "debug" else "/Release" + setenv_cmd = [setenv_path, build_arch, build_type] + setenv_env = get_environment_from_batch_command(setenv_cmd) + setenv_env_paths = os.pathsep.join([setenv_env[k] for k in setenv_env if k.upper() == 'PATH']).split(os.pathsep) + setenv_env_without_paths = dict([(k, setenv_env[k]) for k in setenv_env if k.upper() != 'PATH']) + + # Extend os.environ with SDK env + log.info("Initializing Windows SDK env...") + update_env_path(setenv_env_paths) + for k in sorted(setenv_env_without_paths): + v = setenv_env_without_paths[k] + log.info("Inserting '{} = {}' to environment".format(k, v)) + os.environ[k] = v + log.info("Done initializing Windows SDK env") + + +def find_vcdir(version): + """ + This is the customized version of + distutils.msvc9compiler.find_vcvarsall method + """ + from distutils.msvc9compiler import VS_BASE + from distutils.msvc9compiler import Reg + vsbase = VS_BASE % version + try: + productdir = Reg.get_value(r"{}\Setup\VC".format(vsbase), "productdir") + except KeyError: + productdir = None + + # trying Express edition + if productdir is None: + try: + from distutils.msvc9compiler import VSEXPRESS_BASE + except ImportError: + pass + else: + vsbase = VSEXPRESS_BASE % version + try: + productdir = Reg.get_value(r"{}\Setup\VC".format(vsbase), "productdir") + except KeyError: + productdir = None + log.debug("Unable to find productdir in registry") + + if not productdir or not os.path.isdir(productdir): + toolskey = "VS{:0.0f}0COMNTOOLS".format(version) + toolsdir = os.environ.get(toolskey, None) + + if toolsdir and os.path.isdir(toolsdir): + productdir = os.path.join(toolsdir, os.pardir, os.pardir, "VC") + productdir = os.path.abspath(productdir) + if not os.path.isdir(productdir): + log.debug("{} is not a valid directory".format(productdir)) + return None + else: + log.debug("Env var {} is not set or invalid".format(toolskey)) + if not productdir: + log.debug("No productdir found") + return None + return productdir + + +def init_msvc_env(platform_arch, build_type): + from distutils.msvc9compiler import VERSION as MSVC_VERSION + + log.info("Searching MSVC compiler version {}".format(MSVC_VERSION)) + vcdir_path = find_vcdir(MSVC_VERSION) + if not vcdir_path: + raise DistutilsSetupError("Failed to find the MSVC compiler version {} on your " + "system.".format(MSVC_VERSION)) + else: + log.info("Found {}".format(vcdir_path)) + + log.info("Searching MSVC compiler {} environment init script".format(MSVC_VERSION)) + if platform_arch.startswith("32"): + vcvars_path = os.path.join(vcdir_path, "bin", "vcvars32.bat") + else: + vcvars_path = os.path.join(vcdir_path, "bin", "vcvars64.bat") + if not os.path.exists(vcvars_path): + vcvars_path = os.path.join(vcdir_path, "bin", "amd64", "vcvars64.bat") + if not os.path.exists(vcvars_path): + vcvars_path = os.path.join(vcdir_path, "bin", "amd64", "vcvarsamd64.bat") + + if not os.path.exists(vcvars_path): + # MSVC init script not found, try to find and init Windows SDK env + log.error("Failed to find the MSVC compiler environment init script " + "(vcvars.bat) on your system.") + winsdk_setenv(platform_arch, build_type) + return + else: + log.info("Found {}".format(vcvars_path)) + + # Get MSVC env + log.info("Using MSVC {} in {}".format(MSVC_VERSION, vcvars_path)) + msvc_arch = "x86" if platform_arch.startswith("32") else "amd64" + log.info("Getting MSVC env for {} architecture".format(msvc_arch)) + vcvars_cmd = [vcvars_path, msvc_arch] + msvc_env = get_environment_from_batch_command(vcvars_cmd) + msvc_env_paths = os.pathsep.join([msvc_env[k] for k in msvc_env if k.upper() == 'PATH']).split(os.pathsep) + msvc_env_without_paths = dict([(k, msvc_env[k]) for k in msvc_env if k.upper() != 'PATH']) + + # Extend os.environ with MSVC env + log.info("Initializing MSVC env...") + update_env_path(msvc_env_paths) + for k in sorted(msvc_env_without_paths): + v = msvc_env_without_paths[k] + log.info("Inserting '{} = {}' to environment".format(k, v)) + os.environ[k] = v + log.info("Done initializing MSVC env") + + +def copyfile(src, dst, force=True, vars=None, force_copy_symlink=False, + make_writable_by_owner=False): + if vars is not None: + src = src.format(**vars) + dst = dst.format(**vars) + + if not os.path.exists(src) and not force: + log.info("**Skiping copy file {} to {}. Source does not exists.".format(src, dst)) + return + + if not os.path.islink(src) or force_copy_symlink: + log.info("Copying file {} to {}.".format(src, dst)) + shutil.copy2(src, dst) + if make_writable_by_owner: + make_file_writable_by_owner(dst) + + else: + link_target_path = os.path.realpath(src) + if os.path.dirname(link_target_path) == os.path.dirname(src): + link_target = os.path.basename(link_target_path) + link_name = os.path.basename(src) + current_directory = os.getcwd() + try: + target_dir = dst if os.path.isdir(dst) else os.path.dirname(dst) + os.chdir(target_dir) + if os.path.exists(link_name): + os.remove(link_name) + log.info("Symlinking {} -> {} in {}.".format(link_name, link_target, target_dir)) + os.symlink(link_target, link_name) + except OSError: + log.error("{} -> {}: Error creating symlink".format(link_name, link_target)) + finally: + os.chdir(current_directory) + else: + log.error("{} -> {}: Can only create symlinks within the same " + "directory".format(src, link_target_path)) + + return dst + + +def makefile(dst, content=None, vars=None): + if vars is not None: + if content is not None: + content = content.format(**vars) + dst = dst.format(**vars) + + log.info("Making file {}.".format(dst)) + + dstdir = os.path.dirname(dst) + if not os.path.exists(dstdir): + os.makedirs(dstdir) + + with open(dst, "wt") as f: + if content is not None: + f.write(content) + + +def copydir(src, dst, filter=None, ignore=None, force=True, recursive=True, vars=None, + dir_filter_function=None, file_filter_function=None, force_copy_symlinks=False): + + if vars is not None: + src = src.format(**vars) + dst = dst.format(**vars) + if filter is not None: + for i in range(len(filter)): + filter[i] = filter[i].format(**vars) + if ignore is not None: + for i in range(len(ignore)): + ignore[i] = ignore[i].format(**vars) + + if not os.path.exists(src) and not force: + log.info("**Skiping copy tree {} to {}. Source does not exists. " + "filter={}. ignore={}.".format(src, dst, filter, ignore)) + return [] + + log.info("Copying tree {} to {}. filter={}. ignore={}.".format(src, dst, filter, ignore)) + + names = os.listdir(src) + + results = [] + errors = [] + for name in names: + srcname = os.path.join(src, name) + dstname = os.path.join(dst, name) + try: + if os.path.isdir(srcname): + if (dir_filter_function and not dir_filter_function(name, src, srcname)): + continue + if recursive: + results.extend(copydir(srcname, dstname, filter, ignore, force, recursive, + vars, dir_filter_function, file_filter_function, + force_copy_symlinks)) + else: + if ((file_filter_function is not None and not file_filter_function(name, srcname)) + or (filter is not None and not filter_match(name, filter)) + or (ignore is not None and filter_match(name, ignore))): + continue + if not os.path.exists(dst): + os.makedirs(dst) + results.append(copyfile(srcname, dstname, True, vars, force_copy_symlinks)) + # catch the Error from the recursive copytree so that we can + # continue with other files + except shutil.Error as err: + errors.extend(err.args[0]) + except EnvironmentError as why: + errors.append((srcname, dstname, str(why))) + try: + if os.path.exists(dst): + shutil.copystat(src, dst) + except OSError as why: + if WindowsError is not None and isinstance(why, WindowsError): + # Copying file access times may fail on Windows + pass + else: + errors.extend((src, dst, str(why))) + if errors: + raise EnvironmentError(errors) + return results + + +def make_file_writable_by_owner(path): + current_permissions = stat.S_IMODE(os.lstat(path).st_mode) + os.chmod(path, current_permissions | stat.S_IWUSR) + + +def rmtree(dirname, ignore=False): + def handle_remove_readonly(func, path, exc): + excvalue = exc[1] + if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES: + os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO) # 0777 + func(path) + else: + raise IOError + shutil.rmtree(dirname, ignore_errors=ignore, onerror=handle_remove_readonly) + + +def run_process_output(args, initial_env=None): + if initial_env is None: + initial_env = os.environ + std_out = subprocess.Popen(args, env=initial_env, universal_newlines=1, + stdout=subprocess.PIPE).stdout + result = [] + for raw_line in std_out.readlines(): + line = raw_line if sys.version_info >= (3,) else raw_line.decode('utf-8') + result.append(line.rstrip()) + std_out.close() + return result + + +def run_process(args, initial_env=None): + """ + Run process until completion and return the process exit code. + No output is captured. + """ + command = " ".join([(" " in x and '"{}"'.format(x) or x) for x in args]) + log.info("In directory {}:\n\tRunning command: {}".format(os.getcwd(), command)) + + if initial_env is None: + initial_env = os.environ + + kwargs = {} + kwargs['env'] = initial_env + + exit_code = subprocess.call(args, **kwargs) + return exit_code + + +def get_environment_from_batch_command(env_cmd, initial=None): + """ + Take a command (either a single command or list of arguments) + and return the environment created after running that command. + Note that if the command must be a batch file or .cmd file, or the + changes to the environment will not be captured. + + If initial is supplied, it is used as the initial environment passed + to the child process. + """ + + def validate_pair(ob): + try: + if not (len(ob) == 2): + print("Unexpected result: {}".format(ob)) + raise ValueError + except: + return False + return True + + def consume(iter): + try: + while True: + next(iter) + except StopIteration: + pass + + if not isinstance(env_cmd, (list, tuple)): + env_cmd = [env_cmd] + # construct the command that will alter the environment + env_cmd = subprocess.list2cmdline(env_cmd) + # create a tag so we can tell in the output when the proc is done + tag = 'Done running command' + # construct a cmd.exe command to do accomplish this + cmd = 'cmd.exe /E:ON /V:ON /s /c "{} && echo "{}" && set"'.format(env_cmd, tag) + # launch the process + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, env=initial) + # parse the output sent to stdout + lines = proc.stdout + if sys.version_info[0] > 2: + # make sure the lines are strings + lines = map(lambda s: s.decode(), lines) + # consume whatever output occurs until the tag is reached + consume(itertools.takewhile(lambda l: tag not in l, lines)) + # define a way to handle each KEY=VALUE line + # parse key/values into pairs + pairs = map(lambda l: l.rstrip().split('=', 1), lines) + # make sure the pairs are valid + valid_pairs = filter(validate_pair, pairs) + # construct a dictionary of the pairs + result = dict(valid_pairs) + # let the process finish + proc.communicate() + return result + + +def regenerate_qt_resources(src, pyside_rcc_path, pyside_rcc_options): + names = os.listdir(src) + for name in names: + srcname = os.path.join(src, name) + if os.path.isdir(srcname): + regenerate_qt_resources(srcname, pyside_rcc_path, pyside_rcc_options) + elif srcname.endswith('.qrc'): + # Replace last occurence of '.qrc' in srcname + srcname_split = srcname.rsplit('.qrc', 1) + dstname = '_rc.py'.join(srcname_split) + if os.path.exists(dstname): + log.info('Regenerating {} from {}'.format(dstname, os.path.basename(srcname))) + run_process([pyside_rcc_path] + pyside_rcc_options + [srcname, '-o', dstname]) + + +def back_tick(cmd, ret_err=False): + """ + Run command `cmd`, return stdout, or stdout, stderr, + return_code if `ret_err` is True. + + Roughly equivalent to ``check_output`` in Python 2.7 + + Parameters + ---------- + cmd : str + command to execute + ret_err : bool, optional + If True, return stderr and return_code in addition to stdout. + If False, just return stdout + + Returns + ------- + out : str or tuple + If `ret_err` is False, return stripped string containing stdout from + `cmd`. + If `ret_err` is True, return tuple of (stdout, stderr, return_code) + where ``stdout`` is the stripped stdout, and ``stderr`` is the stripped + stderr, and ``return_code`` is the process exit code. + + Raises + ------ + Raises RuntimeError if command returns non-zero exit code when ret_err + isn't set. + """ + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + out, err = proc.communicate() + if not isinstance(out, str): + # python 3 + out = out.decode() + err = err.decode() + retcode = proc.returncode + if retcode is None and not ret_err: + proc.terminate() + raise RuntimeError("{} process did not terminate".format(cmd)) + if retcode != 0 and not ret_err: + raise RuntimeError("{} process returned code {}\n*** {}".format( + (cmd, retcode, err))) + out = out.strip() + if not ret_err: + return out + return out, err.strip(), retcode + + +MACOS_OUTNAME_RE = re.compile(r'\(compatibility version [\d.]+, current version [\d.]+\)') + + +def macos_get_install_names(libpath): + """ + Get macOS library install names from library `libpath` using ``otool`` + + Parameters + ---------- + libpath : str + path to library + + Returns + ------- + install_names : list of str + install names in library `libpath` + """ + out = back_tick("otool -L {}".format(libpath)) + libs = [line for line in out.split('\n')][1:] + return [MACOS_OUTNAME_RE.sub('', lib).strip() for lib in libs] + + +MACOS_RPATH_RE = re.compile(r"path (.+) \(offset \d+\)") + + +def macos_get_rpaths(libpath): + """ Get rpath load commands from library `libpath` using ``otool`` + + Parameters + ---------- + libpath : str + path to library + + Returns + ------- + rpaths : list of str + rpath values stored in ``libpath`` + + Notes + ----- + See ``man dyld`` for more information on rpaths in libraries + """ + lines = back_tick('otool -l {}'.format(libpath)).split('\n') + ctr = 0 + rpaths = [] + while ctr < len(lines): + line = lines[ctr].strip() + if line != 'cmd LC_RPATH': + ctr += 1 + continue + assert lines[ctr + 1].strip().startswith('cmdsize') + rpath_line = lines[ctr + 2].strip() + match = MACOS_RPATH_RE.match(rpath_line) + if match is None: + raise RuntimeError("Unexpected path line: {}".format(rpath_line)) + rpaths.append(match.groups()[0]) + ctr += 3 + return rpaths + + +def macos_add_rpath(rpath, library_path): + back_tick("install_name_tool -add_rpath {} {}".format(rpath, library_path)) + + +def macos_fix_rpaths_for_library(library_path, qt_lib_dir): + """ Adds required rpath load commands to given library. + + This is a necessary post-installation step, to allow loading PySide + modules without setting DYLD_LIBRARY_PATH or DYLD_FRAMEWORK_PATH. + The CMake rpath commands which are added at build time are used only + for testing (make check), and they are stripped once the equivalent + of make install is executed (except for shiboken, which currently + uses CMAKE_INSTALL_RPATH_USE_LINK_PATH, which might be necessary to + remove in the future). + + Parameters + ---------- + library_path : str + path to library for which to set rpaths. + qt_lib_dir : str + rpath to installed Qt lib directory. + """ + + install_names = macos_get_install_names(library_path) + existing_rpath_commands = macos_get_rpaths(library_path) + + needs_loader_path = False + for install_name in install_names: + # Absolute path, skip it. + if install_name[0] == '/': + continue + + # If there are dynamic library install names that contain + # @rpath tokens, we will provide an rpath load command with the + # value of "@loader_path". This will allow loading dependent + # libraries from within the same directory as 'library_path'. + if install_name[0] == '@': + needs_loader_path = True + break + + if needs_loader_path and "@loader_path" not in existing_rpath_commands: + macos_add_rpath("@loader_path", library_path) + + # If the library depends on a Qt library, add an rpath load comment + # pointing to the Qt lib directory. + macos_add_qt_rpath(library_path, qt_lib_dir, existing_rpath_commands, install_names) + + +def macos_add_qt_rpath(library_path, qt_lib_dir, existing_rpath_commands=[], + library_dependencies=[]): + """ + Adds an rpath load command to the Qt lib directory if necessary + + Checks if library pointed to by 'library_path' has Qt dependencies, + and adds an rpath load command that points to the Qt lib directory + (qt_lib_dir). + """ + if not existing_rpath_commands: + existing_rpath_commands = macos_get_rpaths(library_path) + + # Return early if qt rpath is already present. + if qt_lib_dir in existing_rpath_commands: + return + + # Check if any library dependencies are Qt libraries (hacky). + if not library_dependencies: + library_dependencies = macos_get_install_names(library_path) + + needs_qt_rpath = False + for library in library_dependencies: + if 'Qt' in library: + needs_qt_rpath = True + break + + if needs_qt_rpath: + macos_add_rpath(qt_lib_dir, library_path) + + +# Find an executable specified by a glob pattern ('foo*') in the OS path +def find_glob_in_path(pattern): + result = [] + if sys.platform == 'win32': + pattern += '.exe' + + for path in os.environ.get('PATH', '').split(os.pathsep): + for match in glob.glob(os.path.join(path, pattern)): + result.append(match) + return result + + +# Locate the most recent version of llvm_config in the path. +def find_llvm_config(): + version_re = re.compile(r'(\d+)\.(\d+)\.(\d+)') + result = None + last_version_string = '000000' + for llvm_config in find_glob_in_path('llvm-config*'): + try: + output = run_process_output([llvm_config, '--version']) + if output: + match = version_re.match(output[0]) + if match: + version_string = "{:02d}{:02d}{:02d}".format(int(match.group(1)), + int(match.group(2)), + int(match.group(3))) + if (version_string > last_version_string): + result = llvm_config + last_version_string = version_string + except OSError: + pass + return result + + +# Add Clang to path for Windows for the shiboken ApiExtractor tests. +# Revisit once Clang is bundled with Qt. +def detect_clang(): + source = 'LLVM_INSTALL_DIR' + clang_dir = os.environ.get(source, None) + if not clang_dir: + source = 'CLANG_INSTALL_DIR' + clang_dir = os.environ.get(source, None) + if not clang_dir: + source = find_llvm_config() + try: + if source is not None: + output = run_process_output([source, '--prefix']) + if output: + clang_dir = output[0] + except OSError: + pass + if clang_dir: + arch = '64' if sys.maxsize > 2 ** 31 - 1 else '32' + clang_dir = clang_dir.replace('_ARCH_', arch) + return (clang_dir, source) + + +_7z_binary = None + + +def download_and_extract_7z(fileurl, target): + """ Downloads 7z file from fileurl and extract to target """ + info = "" + localfile = None + for i in range(1, 10): + try: + print("Downloading fileUrl {}, attempt #{}".format(fileurl, i)) + localfile, info = urllib.urlretrieve(fileurl) + break + except: + pass + if not localfile: + print("Error downloading {} : {}".format(fileurl, info)) + raise RuntimeError(' Error downloading {}'.format(fileurl)) + + try: + global _7z_binary + outputDir = "-o{}".format(target) + if not _7z_binary: + if sys.platform == 'win32': + candidate = 'c:\\Program Files\\7-Zip\\7z.exe' + if os.path.exists(candidate): + _7z_binary = candidate + if not _7z_binary: + _7z_binary = '7z' + print("calling {} x {} {}".format(_7z_binary, localfile, outputDir)) + subprocess.call([_7z_binary, "x", "-y", localfile, outputDir]) + except: + raise RuntimeError(' Error extracting {}'.format(localfile)) + + +def split_and_strip(sinput): + lines = [s.strip() for s in sinput.splitlines()] + return lines + + +def ldd_get_dependencies(executable_path): + """ + Returns a dictionary of dependencies that `executable_path` + depends on. + + The keys are library names and the values are the library paths. + + """ + output = ldd(executable_path) + lines = split_and_strip(output) + pattern = re.compile(r"\s*(.*?)\s+=>\s+(.*?)\s+\(.*\)") + dependencies = {} + for line in lines: + match = pattern.search(line) + if match: + dependencies[match.group(1)] = match.group(2) + return dependencies + + +def ldd_get_paths_for_dependencies(dependencies_regex, executable_path=None, dependencies=None): + """ + Returns file paths to shared library dependencies that match given + `dependencies_regex` against given `executable_path`. + + The function retrieves the list of shared library dependencies using + ld.so for the given `executable_path` in order to search for + libraries that match the `dependencies_regex`, and then returns a + list of absolute paths of the matching libraries. + + If no matching library is found in the list of dependencies, + an empty list is returned. + """ + + if not dependencies and not executable_path: + return None + + if not dependencies: + dependencies = ldd_get_dependencies(executable_path) + + pattern = re.compile(dependencies_regex) + + paths = [] + for key in dependencies: + match = pattern.search(key) + if match: + paths.append(dependencies[key]) + + return paths + + +def ldd(executable_path): + """ + Returns ld.so output of shared library dependencies for given + `executable_path`. + + This is a partial port of /usr/bin/ldd from bash to Python. + The dependency list is retrieved by setting the + LD_TRACE_LOADED_OBJECTS=1 environment variable, and executing the + given path via the dynamic loader ld.so. + + Only works on Linux. The port is required to make this work on + systems that might not have ldd. + This is because ldd (on Ubuntu) is shipped in the libc-bin package + that, which might have a + minuscule percentage of not being installed. + + Parameters + ---------- + executable_path : str + path to executable or shared library. + + Returns + ------- + output : str + the raw output retrieved from the dynamic linker. + """ + + chosen_rtld = None + # List of ld's considered by ldd on Ubuntu (here's hoping it's the + # same on all distros). + rtld_list = ["/lib/ld-linux.so.2", "/lib64/ld-linux-x86-64.so.2", "/libx32/ld-linux-x32.so.2"] + + # Choose appropriate runtime dynamic linker. + for rtld in rtld_list: + if os.path.isfile(rtld) and os.access(rtld, os.X_OK): + (_, _, code) = back_tick(rtld, True) + # Code 127 is returned by ld.so when called without any + # arguments (some kind of sanity check I guess). + if code == 127: + (_, _, code) = back_tick("{} --verify {}".format(rtld, executable_path), True) + # Codes 0 and 2 mean given executable_path can be + # understood by ld.so. + if code in [0, 2]: + chosen_rtld = rtld + break + + if not chosen_rtld: + raise RuntimeError("Could not find appropriate ld.so to query for dependencies.") + + # Query for shared library dependencies. + rtld_env = "LD_TRACE_LOADED_OBJECTS=1" + rtld_cmd = "{} {} {}".format(rtld_env, chosen_rtld, executable_path) + (out, _, return_code) = back_tick(rtld_cmd, True) + if return_code == 0: + return out + else: + raise RuntimeError("ld.so failed to query for dependent shared " + "libraries of {} ".format(executable_path)) + + +def find_files_using_glob(path, pattern): + """ Returns list of files that matched glob `pattern` in `path`. """ + final_pattern = os.path.join(path, pattern) + maybe_files = glob.glob(final_pattern) + return maybe_files + + +def find_qt_core_library_glob(lib_dir): + """ Returns path to the QtCore library found in `lib_dir`. """ + maybe_file = find_files_using_glob(lib_dir, "libQt5Core.so.?") + if len(maybe_file) == 1: + return maybe_file[0] + return None + + +# @TODO: Possibly fix ICU library copying on macOS and Windows. +# This would require to implement the equivalent of the custom written +# ldd for the specified platforms. +# This has less priority because ICU libs are not used in the default +# Qt configuration build. +def copy_icu_libs(patchelf, destination_lib_dir): + """ + Copy ICU libraries that QtCore depends on, + to given `destination_lib_dir`. + """ + qt_core_library_path = find_qt_core_library_glob(destination_lib_dir) + + if not qt_core_library_path or not os.path.exists(qt_core_library_path): + raise RuntimeError('QtCore library does not exist at path: {}. ' + 'Failed to copy ICU libraries.'.format(qt_core_library_path)) + + dependencies = ldd_get_dependencies(qt_core_library_path) + + icu_regex = r"^libicu.+" + icu_compiled_pattern = re.compile(icu_regex) + icu_required = False + for dependency in dependencies: + match = icu_compiled_pattern.search(dependency) + if match: + icu_required = True + break + + if icu_required: + paths = ldd_get_paths_for_dependencies(icu_regex, dependencies=dependencies) + if not paths: + raise RuntimeError("Failed to find the necessary ICU libraries required by QtCore.") + log.info('Copying the detected ICU libraries required by QtCore.') + + if not os.path.exists(destination_lib_dir): + os.makedirs(destination_lib_dir) + + for path in paths: + basename = os.path.basename(path) + destination = os.path.join(destination_lib_dir, basename) + copyfile(path, destination, force_copy_symlink=True) + # Patch the ICU libraries to contain the $ORIGIN rpath + # value, so that only the local package libraries are used. + linux_set_rpaths(patchelf, destination, '$ORIGIN') + + # Patch the QtCore library to find the copied over ICU libraries + # (if necessary). + log.info("Checking if QtCore library needs a new rpath to make it work with ICU libs.") + rpaths = linux_get_rpaths(qt_core_library_path) + if not rpaths or not rpaths_has_origin(rpaths): + log.info('Patching QtCore library to contain $ORIGIN rpath.') + rpaths.insert(0, '$ORIGIN') + new_rpaths_string = ":".join(rpaths) + linux_set_rpaths(patchelf, qt_core_library_path, new_rpaths_string) + + +def linux_run_read_elf(executable_path): + cmd = "readelf -d {}".format(executable_path) + (out, err, code) = back_tick(cmd, True) + if code != 0: + raise RuntimeError("Running `readelf -d {}` failed with error " + "output:\n {}. ".format(executable_path, err)) + lines = split_and_strip(out) + return lines + + +def linux_set_rpaths(patchelf, executable_path, rpath_string): + """ Patches the `executable_path` with a new rpath string. """ + + cmd = [patchelf, '--set-rpath', rpath_string, executable_path] + + if run_process(cmd) != 0: + raise RuntimeError("Error patching rpath in {}".format(executable_path)) + + +def linux_get_dependent_libraries(executable_path): + """ + Returns a list of libraries that executable_path depends on. + """ + + lines = linux_run_read_elf(executable_path) + pattern = re.compile(r"^.+?\(NEEDED\).+?\[(.+?)\]$") + + library_lines = [] + for line in lines: + match = pattern.search(line) + if match: + library_line = match.group(1) + library_lines.append(library_line) + + return library_lines + + +def linux_get_rpaths(executable_path): + """ + Returns a list of run path values embedded in the executable or just + an empty list. + """ + + lines = linux_run_read_elf(executable_path) + pattern = re.compile(r"^.+?\(RUNPATH\).+?\[(.+?)\]$") + + rpath_line = None + for line in lines: + match = pattern.search(line) + if match: + rpath_line = match.group(1) + break + + rpaths = [] + + if rpath_line: + rpaths = rpath_line.split(':') + + return rpaths + + +def rpaths_has_origin(rpaths): + """ + Return True if the specified list of rpaths has an "$ORIGIN" value + (aka current dir). + """ + if not rpaths: + return False + + pattern = re.compile(r"^\$ORIGIN(/)?$") + for rpath in rpaths: + match = pattern.search(rpath) + if match: + return True + return False + + +def linux_needs_qt_rpath(executable_path): + """ + Returns true if library_path depends on Qt libraries. + """ + + dependencies = linux_get_dependent_libraries(executable_path) + + # Check if any library dependencies are Qt libraries (hacky). + needs_qt_rpath = False + for dep in dependencies: + if 'Qt' in dep: + needs_qt_rpath = True + break + return needs_qt_rpath + + +def linux_fix_rpaths_for_library(patchelf, executable_path, qt_rpath, override=False): + """ + Adds or overrides required rpaths in given executable / library. + """ + rpaths = ['$ORIGIN/'] + existing_rpaths = [] + if not override: + existing_rpaths = linux_get_rpaths(executable_path) + rpaths.extend(existing_rpaths) + + if linux_needs_qt_rpath(executable_path) and qt_rpath not in existing_rpaths: + rpaths.append(qt_rpath) + + rpaths_string = ':'.join(rpaths) + linux_set_rpaths(patchelf, executable_path, rpaths_string) + + +def memoize(function): + """ + Decorator to wrap a function with a memoizing callable. + It returns cached values when the wrapped function is called with + the same arguments. + """ + memo = {} + + def wrapper(*args): + if args in memo: + return memo[args] + else: + rv = function(*args) + memo[args] = rv + return rv + return wrapper + + +def get_python_dict(python_script_path): + try: + with open(python_script_path) as f: + python_dict = {} + code = compile(f.read(), python_script_path, 'exec') + exec(code, {}, python_dict) + return python_dict + except IOError as e: + print("get_python_dict: Couldn't get dict from python " + "file: {}.".format(python_script_path)) + raise + + +def install_pip_package_from_url_specifier(env_pip, url, upgrade=True): + args = [env_pip, "install", url] + if upgrade: + args.append("--upgrade") + args.append(url) + run_instruction(args, "Failed to install {}".format(url)) + + +def install_pip_dependencies(env_pip, packages, upgrade=True): + for p in packages: + args = [env_pip, "install"] + if upgrade: + args.append("--upgrade") + args.append(p) + run_instruction(args, "Failed to install {}".format(p)) + + +def get_qtci_virtualEnv(python_ver, host, hostArch, targetArch): + _pExe = "python" + _env = "env{}".format(str(python_ver)) + env_python = _env + "/bin/python" + env_pip = _env + "/bin/pip" + + if host == "Windows": + print("New virtualenv to build {} in {} host".format(targetArch, hostArch)) + _pExe = "python.exe" + # With windows we are creating building 32-bit target in 64-bit host + if hostArch == "X86_64" and targetArch == "X86": + if python_ver.startswith("3"): + var = "PYTHON" + python_ver + "-32_PATH" + print("Try to find python from {} env variable".format(var)) + _path = os.getenv(var, "") + _pExe = os.path.join(_path, "python.exe") + if not os.path.isfile(_pExe): + print("Can't find python.exe from {}, using default python3".format(_pExe)) + _pExe = os.path.join(os.getenv("PYTHON3_32_PATH"), "python.exe") + else: + _pExe = os.path.join(os.getenv("PYTHON2_32_PATH"), "python.exe") + else: + if python_ver.startswith("3"): + var = "PYTHON" + python_ver + "-64_PATH" + print("Try to find python from {} env variable".format(var)) + _path = os.getenv(var, "") + _pExe = os.path.join(_path, "python.exe") + if not os.path.isfile(_pExe): + print("Can't find python.exe from {}, using default python3".format(_pExe)) + _pExe = os.path.join(os.getenv("PYTHON3_PATH"), "python.exe") + env_python = _env + "\\Scripts\\python.exe" + env_pip = _env + "\\Scripts\\pip.exe" + else: + if python_ver == "3": + _pExe = "python3" + return(_pExe, _env, env_pip, env_python) + + +def run_instruction(instruction, error, initial_env=None): + if initial_env is None: + initial_env = os.environ + print("Running Coin instruction: {}".format(' '.join(str(e) for e in instruction))) + result = subprocess.call(instruction, env=initial_env) + if result != 0: + print("ERROR : {}".format(error)) + exit(result) + + +def acceptCITestConfiguration(hostOS, hostOSVer, targetArch, compiler): + # Disable unsupported CI configs for now + # NOTE: String must match with QT CI's storagestruct thrift + if (hostOSVer in ["WinRT_10", "WebAssembly", "Ubuntu_18_04", "Android_ANY"] + or hostOSVer.startswith("SLES_")): + print("Disabled {} from Coin configuration".format(hostOSVer)) + return False + # With 5.11 CI will create two sets of release binaries, + # one with msvc 2015 and one with msvc 2017 + # we shouldn't release the 2015 version. + # BUT, 32 bit build is done only on msvc 2015... + if compiler in ["MSVC2015"] and targetArch in ["X86_64"]: + print("Disabled {} to {} from Coin configuration".format(compiler, targetArch)) + return False + return True + + +def get_ci_qmake_path(ci_install_dir, ci_host_os): + qmake_path = "--qmake={}".format(ci_install_dir) + if ci_host_os == "MacOS": + return qmake_path + "/bin/qmake" + elif ci_host_os == "Windows": + return qmake_path + "\\bin\\qmake.exe" + else: + return qmake_path + "/bin/qmake" diff --git a/build_scripts/wheel_override.py b/build_scripts/wheel_override.py new file mode 100644 index 0000000..6614176 --- /dev/null +++ b/build_scripts/wheel_override.py @@ -0,0 +1,216 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + + +wheel_module_exists = False + +import os +import sys +from .options import DistUtilsCommandMixin, OPTION +from distutils import log as logger +from email.generator import Generator +from .wheel_utils import get_package_version, get_qt_version, macos_plat_name + +try: + + from distutils import log as logger + from wheel.bdist_wheel import bdist_wheel as _bdist_wheel + from wheel.bdist_wheel import safer_name as _safer_name + from wheel.bdist_wheel import get_abi_tag, get_platform + from packaging import tags + from wheel import __version__ as wheel_version + + wheel_module_exists = True +except Exception as e: + _bdist_wheel, wheel_version = type, '' # dummy to make class statement happy + print('***** Exception while trying to prepare bdist_wheel override class: {}. ' + 'Skipping wheel overriding.'.format(e)) + + +def get_bdist_wheel_override(): + return PysideBuildWheel if wheel_module_exists else None + + +class PysideBuildWheel(_bdist_wheel, DistUtilsCommandMixin): + + user_options = (_bdist_wheel.user_options + DistUtilsCommandMixin.mixin_user_options + if wheel_module_exists else None) + + def __init__(self, *args, **kwargs): + self._package_version = None + _bdist_wheel.__init__(self, *args, **kwargs) + DistUtilsCommandMixin.__init__(self) + + def finalize_options(self): + DistUtilsCommandMixin.mixin_finalize_options(self) + if sys.platform == 'darwin': + # Override the platform name to contain the correct + # minimum deployment target. + # This is used in the final wheel name. + self.plat_name = macos_plat_name() + + # When limited API is requested, notify bdist_wheel to + # create a properly named package. + limited_api_enabled = (OPTION["LIMITED_API"] == 'yes' + and sys.version_info[0] >= 3) + if limited_api_enabled: + self.py_limited_api = "cp35.cp36.cp37.cp38.cp39" + + self._package_version = get_package_version() + + _bdist_wheel.finalize_options(self) + + @property + def wheel_dist_name(self): + # Slightly modified version of wheel's wheel_dist_name + # method, to add the Qt version as well. + # Example: + # PySide2-5.6-5.6.4-cp27-cp27m-macosx_10_10_intel.whl + # The PySide2 version is "5.6". + # The Qt version built against is "5.6.4". + wheel_version = "{}-{}".format(self._package_version, get_qt_version()) + components = (_safer_name(self.distribution.get_name()), wheel_version) + if self.build_number: + components += (self.build_number,) + return '-'.join(components) + + # Copy of get_tag from bdist_wheel.py, to allow setting a + # multi-python impl tag, by removing an assert. Otherwise we + # would have to rename wheels manually for limited api + # packages. Also we set "none" abi tag on Windows, because + # pip does not yet support "abi3" tag, leading to + # installation failure when tried. + def get_tag(self): + # bdist sets self.plat_name if unset, we should only use it for purepy + # wheels if the user supplied it. + if self.plat_name_supplied: + plat_name = self.plat_name + elif self.root_is_pure: + plat_name = 'any' + else: + # macosx contains system version in platform name so need special handle + if self.plat_name and not self.plat_name.startswith("macosx"): + plat_name = self.plat_name + else: + # on macosx always limit the platform name to comply with any + # c-extension modules in bdist_dir, since the user can specify + # a higher MACOSX_DEPLOYMENT_TARGET via tools like CMake + + # on other platforms, and on macosx if there are no c-extension + # modules, use the default platform name. + plat_name = get_platform(self.bdist_dir) + + if plat_name in ('linux-x86_64', 'linux_x86_64') and sys.maxsize == 2147483647: + plat_name = 'linux_i686' + + # To allow uploading to pypi, we need the wheel name + # to contain 'manylinux1'. + # The wheel which will be uploaded to pypi will be + # built on RHEL7, so it doesn't completely qualify for + # manylinux1 support, but it's the minimum requirement + # for building Qt. We only enable this for x64 limited + # api builds (which are the only ones uploaded to + # pypi). + # TODO: Add actual distro detection, instead of + # relying on limited_api option. + if (plat_name in ('linux-x86_64', 'linux_x86_64') + and sys.maxsize > 2147483647 + and (self.py_limited_api or sys.version_info[0] == 2)): + plat_name = 'manylinux1_x86_64' + plat_name = plat_name.replace('-', '_').replace('.', '_') + + if self.root_is_pure: + if self.universal: + impl = 'py2.py3' + else: + impl = self.python_tag + tag = (impl, 'none', plat_name) + else: + impl_name = tags.interpreter_name() + impl_ver = tags.interpreter_version() + impl = impl_name + impl_ver + # We don't work on CPython 3.1, 3.0. + if self.py_limited_api and (impl_name + impl_ver).startswith('cp3'): + impl = self.py_limited_api + abi_tag = "abi3" if sys.platform != "win32" else "none" + else: + abi_tag = str(get_abi_tag()).lower() + tag = (impl, abi_tag, plat_name) + supported_tags = [(t.interpreter, t.abi, t.platform) + for t in tags.sys_tags()] + # XXX switch to this alternate implementation for non-pure: + if (self.py_limited_api) or (plat_name in ('manylinux1_x86_64') and sys.version_info[0] == 2): + return tag + assert tag in supported_tags, ("would build wheel with unsupported tag {}".format(tag)) + return tag + + # Copy of get_tag from bdist_wheel.py, to write a triplet Tag + # only once for the limited_api case. + def write_wheelfile(self, wheelfile_base, generator='bdist_wheel (' + wheel_version + ')'): + from email.message import Message + msg = Message() + msg['Wheel-Version'] = '1.0' # of the spec + msg['Generator'] = generator + msg['Root-Is-Purelib'] = str(self.root_is_pure).lower() + if self.build_number is not None: + msg['Build'] = self.build_number + + # Doesn't work for bdist_wininst + impl_tag, abi_tag, plat_tag = self.get_tag() + # To enable pypi upload we are adjusting the wheel name + pypi_ready = (OPTION["LIMITED_API"] and sys.version_info[0] >= 3) or (sys.version_info[0] == 2) + + def writeTag(impl): + for abi in abi_tag.split('.'): + for plat in plat_tag.split('.'): + msg['Tag'] = '-'.join((impl, abi, plat)) + if pypi_ready: + writeTag(impl_tag) + else: + for impl in impl_tag.split('.'): + writeTag(impl) + + wheelfile_path = os.path.join(wheelfile_base, 'WHEEL') + logger.info('creating %s', wheelfile_path) + with open(wheelfile_path, 'w') as f: + Generator(f, maxheaderlen=0).flatten(msg) + + +if not wheel_module_exists: + del PysideBuildWheel diff --git a/build_scripts/wheel_utils.py b/build_scripts/wheel_utils.py new file mode 100644 index 0000000..71b4e0a --- /dev/null +++ b/build_scripts/wheel_utils.py @@ -0,0 +1,162 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import time + +from distutils.errors import DistutilsSetupError +from distutils.sysconfig import get_config_var +from distutils.util import get_platform +from distutils.version import LooseVersion + +from .options import OPTION +from .qtinfo import QtInfo +from .utils import memoize, get_python_dict + + +@memoize +def get_package_timestamp(): + """ In a Coin CI build the returned timestamp will be the + Coin integration id timestamp. For regular builds it's + just the current timestamp or a user provided one.""" + option_value = OPTION["PACKAGE_TIMESTAMP"] + return option_value if option_value else int(time.time()) + + +def get_qt_version(): + qtinfo = QtInfo() + qt_version = qtinfo.version + + if not qt_version: + m = "Failed to query the Qt version with qmake {0}".format(qtinfo.qmake_command) + raise DistutilsSetupError(m) + + if LooseVersion(qtinfo.version) < LooseVersion("5.7"): + m = "Incompatible Qt version detected: {}. A Qt version >= 5.7 is required.".format(qt_version) + raise DistutilsSetupError(m) + + return qt_version + + +@memoize +def get_package_version(): + """ Returns the version string for the PySide2 package. """ + setup_script_dir = os.getcwd() + pyside_version_py = os.path.join( + setup_script_dir, "sources", "pyside2", "pyside_version.py") + d = get_python_dict(pyside_version_py) + + final_version = "{}.{}.{}".format( + d['major_version'], d['minor_version'], d['patch_version']) + release_version_type = d['release_version_type'] + pre_release_version = d['pre_release_version'] + if pre_release_version and release_version_type: + final_version += release_version_type + pre_release_version + if release_version_type.startswith("comm"): + final_version += "." + release_version_type + + # Add the current timestamp to the version number, to suggest it + # is a development snapshot build. + if OPTION["SNAPSHOT_BUILD"]: + final_version += ".dev{}".format(get_package_timestamp()) + return final_version + + +def macos_qt_min_deployment_target(): + target = QtInfo().macos_min_deployment_target + + if not target: + raise DistutilsSetupError("Failed to query for Qt's QMAKE_MACOSX_DEPLOYMENT_TARGET.") + return target + + +@memoize +def macos_pyside_min_deployment_target(): + """ + Compute and validate PySide2 MACOSX_DEPLOYMENT_TARGET value. + Candidate sources that are considered: + - setup.py provided value + - maximum value between minimum deployment target of the + Python interpreter and the minimum deployment target of + the Qt libraries. + If setup.py value is provided, that takes precedence. + Otherwise use the maximum of the above mentioned two values. + """ + python_target = get_config_var('MACOSX_DEPLOYMENT_TARGET') or None + qt_target = macos_qt_min_deployment_target() + setup_target = OPTION["MACOS_DEPLOYMENT_TARGET"] + + qt_target_split = [int(x) for x in qt_target.split('.')] + if python_target: + python_target_split = [int(x) for x in python_target.split('.')] + if setup_target: + setup_target_split = [int(x) for x in setup_target.split('.')] + + message = ("Can't set MACOSX_DEPLOYMENT_TARGET value to {} because " + "{} was built with minimum deployment target set to {}.") + # setup.py provided OPTION["MACOS_DEPLOYMENT_TARGET"] value takes + # precedence. + if setup_target: + if python_target and setup_target_split < python_target_split: + raise DistutilsSetupError(message.format(setup_target, "Python", + python_target)) + if setup_target_split < qt_target_split: + raise DistutilsSetupError(message.format(setup_target, "Qt", + qt_target)) + # All checks clear, use setup.py provided value. + return setup_target + + # Setup.py value not provided, + # use same value as provided by Qt. + if python_target: + maximum_target = '.'.join([str(e) for e in max(python_target_split, qt_target_split)]) + else: + maximum_target = qt_target + return maximum_target + + +@memoize +def macos_plat_name(): + deployment_target = macos_pyside_min_deployment_target() + # Example triple "macosx-10.12-x86_64". + plat = get_platform().split("-") + plat_name = "{}-{}-{}".format(plat[0], deployment_target, plat[2]) + return plat_name diff --git a/coin/instructions/common_environment.yaml b/coin/instructions/common_environment.yaml new file mode 100644 index 0000000..2c66033 --- /dev/null +++ b/coin/instructions/common_environment.yaml @@ -0,0 +1,117 @@ +type: Group +instructions: + - type: EnvironmentVariable + variableName: TARGET_ARCHITECTURE + variableValue: amd64 + enable_if: + condition: and + conditions: + - condition: property + property: target.arch + equals_value: X86_64 + - condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: TARGET_ARCHITECTURE + variableValue: amd64_x86 + enable_if: + condition: and + conditions: + - condition: property + property: target.arch + equals_value: X86 + - condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: CI_TARGET_ARCHITECTURE + variableValue: X86_64 + enable_if: + condition: property + property: target.arch + equals_value: X86_64 + - type: EnvironmentVariable + variableName: CI_TARGET_ARCHITECTURE + variableValue: X86 + enable_if: + condition: property + property: target.arch + equals_value: X86 + - type: EnvironmentVariable + variableName: CI_PACKAGING_FEATURE + variableValue: "--packaging" + enable_if: + condition: property + property: features + contains_value: Packaging + - type: EnvironmentVariable + variableName: CI_OS + variableValue: "MacOS" + enable_if: + condition: property + property: host.os + equals_value: MacOS + - type: EnvironmentVariable + variableName: CI_OS + variableValue: "Linux" + enable_if: + condition: property + property: host.os + equals_value: Linux + - type: EnvironmentVariable + variableName: CI_OS + variableValue: "Windows" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: MAKEFLAGS + variableValue: "" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: AppendToEnvironmentVariable + variableName: PATH + variableValue: ;%CI_JOM_PATH% + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: PrependToEnvironmentVariable + variableName: PATH + variableValue: "\\Users\\qt\\work\\install\\bin;" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: EnvironmentVariable + variableName: ICC64_18_LDLP + variableValue: /opt/intel/lib/intel64 + enable_if: + condition: property + property: target.compiler + equals_value: ICC_18 + - type: EnvironmentVariable + variableName: ICC64_18_PATH # Seems a bit hard to maintain + variableValue: /opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64:/opt/intel/bin + enable_if: + condition: property + property: target.compiler + equals_value: ICC_18 + - type: AppendToEnvironmentVariable + variableName: LD_LIBRARY_PATH + variableValue: :/opt/intel/lib/intel64 + enable_if: + condition: property + property: target.compiler + equals_value: ICC_18 + - type: AppendToEnvironmentVariable + variableName: PATH + variableValue: ":{{.Env.ICC64_18_PATH}}" + enable_if: + condition: property + property: target.compiler + equals_value: ICC_18 diff --git a/coin/instructions/execute_build_instructions.yaml b/coin/instructions/execute_build_instructions.yaml new file mode 100644 index 0000000..1a0c730 --- /dev/null +++ b/coin/instructions/execute_build_instructions.yaml @@ -0,0 +1,56 @@ +type: Group +instructions: + - type: ExecuteCommand + command: "python -u coin_build_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=/Users/qt/work/install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}} --phase=ALL" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 1200 + enable_if: + condition: property + property: host.os + equals_value: MacOS + userMessageOnFailure: > + Failed to execute build instructions on osx + - type: ExecuteCommand + command: "python -u coin_build_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=/home/qt/work/install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}} --phase=ALL" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 600 + enable_if: + condition: property + property: host.os + equals_value: Linux + userMessageOnFailure: > + Failed to execute build instructions on Linux + - type: ExecuteCommand + command: "c:\\users\\qt\\MSVC.bat python -u coin_build_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=\\Users\\qt\\work\\install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}} --phase=BUILD" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 600 + enable_if: + condition: property + property: host.os + equals_value: Windows + userMessageOnFailure: > + Failed to execute build instructions on Windows + - type: SignPackage + directory: "{{.AgentWorkingDir}}\\pyside" + maxTimeInSeconds: 1200 + maxTimeBetweenOutput: 1200 + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: ChangeDirectory + directory: "{{.AgentWorkingDir}}\\pyside\\pyside-setup" + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: ExecuteCommand + command: "c:\\users\\qt\\MSVC.bat python -u coin_build_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=\\Users\\qt\\work\\install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}} --phase=WHEEL" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 300 + enable_if: + condition: property + property: host.os + equals_value: Windows + userMessageOnFailure: > + Failed to create wheels for Windows diff --git a/coin/instructions/execute_license_check.yaml b/coin/instructions/execute_license_check.yaml new file mode 100644 index 0000000..51027ba --- /dev/null +++ b/coin/instructions/execute_license_check.yaml @@ -0,0 +1,31 @@ +type: Group +instructions: + - type: ChangeDirectory + directory: "{{.AgentWorkingDir}}" + - type: InstallSourceArchive + maxTimeInSeconds: 600 + maxTimeBetweenOutput: 600 + project: qt/qtbase + ref: 5.15 + directory: qt/qtbase + userMessageOnFailure: > + Could not install source archive. Please investigate why. + - type: InstallSourceArchive + maxTimeInSeconds: 600 + maxTimeBetweenOutput: 600 + project: qt/qtqa + ref: master + directory: qt/qtqa-latest + userMessageOnFailure: > + Could not install source archive. Please investigate why. + - type: EnvironmentVariable + variableName: QT_MODULE_TO_TEST + variableValue: pyside/pyside-setup + userMessageOnFailure: > + Failed to set environment variable. This should not happen. + - type: ExecuteCommand + command: perl qt/qtqa-latest/tests/prebuild/license/tst_licenses.pl + maxTimeInSeconds: 7200 + maxTimeBetweenOutput: 120 + userMessageOnFailure: > + Failed to run license check script. diff --git a/coin/instructions/execute_test_instructions.yaml b/coin/instructions/execute_test_instructions.yaml new file mode 100644 index 0000000..22a9806 --- /dev/null +++ b/coin/instructions/execute_test_instructions.yaml @@ -0,0 +1,39 @@ +type: Group +enable_if: + condition: property + property: features + not_contains_value: LicenseCheck +instructions: + - type: EnvironmentVariable + variableName: QTEST_ENVIRONMENT + variableValue: "ci" + - type: ExecuteCommand + command: "python -u coin_test_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=/Users/qt/work/install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}}" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 1200 + enable_if: + condition: property + property: host.os + equals_value: MacOS + userMessageOnFailure: > + Failed to execute test instructions on osx + - type: ExecuteCommand + command: "python -u coin_test_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=/home/qt/work/install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}}" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 600 + enable_if: + condition: property + property: host.os + equals_value: Linux + userMessageOnFailure: > + Failed to execute test instructions on Linux + - type: ExecuteCommand + command: "c:\\users\\qt\\MSVC.bat python -u coin_test_instructions.py --os={{.Env.CI_OS}} {{.Env.CI_PACKAGING_FEATURE}} --instdir=\\Users\\qt\\work\\install --targetOs={{.Env.CI_OS}} --hostArch=X86_64 --targetArch={{.Env.CI_TARGET_ARCHITECTURE}}" + maxTimeInSeconds: 14400 + maxTimeBetweenOutput: 600 + enable_if: + condition: property + property: host.os + equals_value: Windows + userMessageOnFailure: > + Failed to execute test instructions on 64 bit Windows diff --git a/coin/instructions/find_path_to_msvc_compiler.yaml b/coin/instructions/find_path_to_msvc_compiler.yaml new file mode 100644 index 0000000..8f9bed8 --- /dev/null +++ b/coin/instructions/find_path_to_msvc_compiler.yaml @@ -0,0 +1,28 @@ +type: Group +enable_if: + condition: property + property: host.os + equals_value: Windows +instructions: + - type: EnvironmentVariable + variableName: VC_SCRIPT + variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio\\2017\\Professional\\VC\\Auxiliary\\Build\\vcvarsall.bat" + enable_if: + condition: property + property: host.compiler + equals_value: MSVC2017 + - type: EnvironmentVariable + variableName: VC_SCRIPT + variableValue: "%ProgramFiles(x86)%\\Microsoft Visual Studio\\2019\\Professional\\VC\\Auxiliary\\Build\\vcvarsall.bat" + enable_if: + condition: property + property: host.compiler + equals_value: MSVC2019 + - type: WriteFile + fileContents: "call \"{{.Env.VC_SCRIPT}}\" {{.Env.TARGET_ARCHITECTURE}} \r\ncmd /c %*" + filename: "c:\\users\\qt\\MSVC.bat" + fileMode: 420 + enable_if: + condition: property + property: host.os + equals_value: Windows diff --git a/coin/instructions/relocate_pyside.yaml b/coin/instructions/relocate_pyside.yaml new file mode 100644 index 0000000..afab83c --- /dev/null +++ b/coin/instructions/relocate_pyside.yaml @@ -0,0 +1,57 @@ +type: Group +enable_if: + condition: property + property: features + not_contains_value: LicenseCheck +instructions: + - type: ChangeDirectory + directory: "{{.AgentWorkingDir}}/pyside" + maxTimeInSeconds: 300 + maxTimeBetweenOutput: 120 + userMessageOnFailure: > + Failed to change to pyside dir + - type: ExecuteCommand + command: c:\\users\\qt\\MSVC.bat rd /s /q pyside-setup + maxTimeInSeconds: 300 + maxTimeBetweenOutput: 120 + enable_if: + condition: property + property: host.os + equals_value: Windows + userMessageOnFailure: > + Failed to remove pyside-setup dir + - type: ExecuteCommand + command: /bin/rm -rf pyside-setup + maxTimeInSeconds: 300 + maxTimeBetweenOutput: 120 + enable_if: + condition: property + property: host.os + not_equals_value: Windows + userMessageOnFailure: > + Failed to remove pyside-setup dir + - type: InstallBinaryArchive + relativeStoragePath: "{{.Env.MODULE_ARTIFACTS_RELATIVE_STORAGE_PATH}}/artifacts.tar.gz" + directory: "pyside" + maxTimeInSeconds: 1200 + maxTimeBetweenOutput: 1200 + - type: ChangeDirectory + directory: "{{.AgentWorkingDir}}\\pyside\\pyside-setup" + maxTimeInSeconds: 7200 + maxTimeBetweenOutput: 120 + enable_if: + condition: property + property: host.os + equals_value: Windows + userMessageOnFailure: > + Failed to install binary artifacts + - type: ChangeDirectory + directory: "{{.AgentWorkingDir}}/pyside/pyside-setup" + maxTimeInSeconds: 7200 + maxTimeBetweenOutput: 120 + enable_if: + condition: property + property: host.os + not_equals_value: Windows + userMessageOnFailure: > + Failed to change to pyside-setup dir diff --git a/coin/module_config.yaml b/coin/module_config.yaml new file mode 100644 index 0000000..fd80acf --- /dev/null +++ b/coin/module_config.yaml @@ -0,0 +1,68 @@ +version: 2 +accept_configuration: + condition: or + conditions: + - condition: and + conditions: + - condition: property # No cross compilation + property: host.os + equals_property: target.os + - condition: property # qtnamespace is not supported + property: configureArgs + not_contains_value: -qtnamespace + - condition: property # no-widgets is notsupported + property: configureArgs + not_contains_value: -no-widgets + - condition: property # no-gui is not supported + property: configureArgs + not_contains_value: -no-gui + - condition: property # Following configs are not supported + property: target.osVersion + not_in_values: [OPENSUSE_13_01, QEMU, WebAssembly, Ubuntu_18_04, SLES_12, SLES_15] + - condition: property # MibnGW and msvc2015 are not supported + property: target.compiler + not_in_values: [Mingw, MSVC2015] + - condition: and + conditions: + - condition: property + property: target.osVersion + equals_value: Ubuntu_18_04 + - condition: property + property: features + contains_value: LicenseCheck + +upload_pyside: &upload_pyside + type: Group + instructions: + - type: UploadArtifact + archiveDirectory: "{{.AgentWorkingDir}}\\pyside" + transferType: UploadModuleBuildArtifact + maxTimeInSeconds: 1200 + maxTimeBetweenOutput: 1200 + enable_if: + condition: property + property: host.os + equals_value: Windows + - type: UploadArtifact + archiveDirectory: "{{.AgentWorkingDir}}/pyside" + transferType: UploadModuleBuildArtifact + maxTimeInSeconds: 1200 + maxTimeBetweenOutput: 1200 + enable_if: + condition: property + property: host.os + not_equals_value: Windows + +instructions: + LicenseCheck: + - !include "{{pyside/pyside-setup}}/execute_license_check.yaml" + Build: + - !include "{{pyside/pyside-setup}}/common_environment.yaml" + - !include "{{pyside/pyside-setup}}/find_path_to_msvc_compiler.yaml" + - !include "{{pyside/pyside-setup}}/execute_build_instructions.yaml" + - *upload_pyside + Test: + - !include "{{pyside/pyside-setup}}/common_environment.yaml" + - !include "{{pyside/pyside-setup}}/find_path_to_msvc_compiler.yaml" + - !include "{{pyside/pyside-setup}}/relocate_pyside.yaml" + - !include "{{pyside/pyside-setup}}/execute_test_instructions.yaml" diff --git a/coin_build_instructions.py b/coin_build_instructions.py new file mode 100644 index 0000000..95d800b --- /dev/null +++ b/coin_build_instructions.py @@ -0,0 +1,186 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +from build_scripts.options import has_option +from build_scripts.options import option_value +from build_scripts.utils import install_pip_dependencies +from build_scripts.utils import get_qtci_virtualEnv +from build_scripts.utils import run_instruction +from build_scripts.utils import rmtree +from build_scripts.utils import get_python_dict +from build_scripts.utils import get_ci_qmake_path +import os +import datetime +import calendar +import site +import sys + +# Values must match COIN thrift +CI_HOST_OS = option_value("os") +CI_TARGET_OS = option_value("targetOs") +CI_HOST_ARCH = option_value("hostArch") +CI_TARGET_ARCH = option_value("targetArch") +CI_HOST_OS_VER = option_value("osVer") +CI_ENV_INSTALL_DIR = option_value("instdir") +CI_ENV_AGENT_DIR = option_value("agentdir") +CI_COMPILER = option_value("compiler") +CI_INTEGRATION_ID = option_value("coinIntegrationId") or str(calendar.timegm(datetime.datetime.now().timetuple())) +CI_FEATURES = [] +_ci_features = option_value("features") +if _ci_features is not None: + for f in _ci_features.split(', '): + CI_FEATURES.append(f) +CI_RELEASE_CONF = has_option("packaging") +CI_TEST_PHASE = option_value("phase") +if CI_TEST_PHASE not in ["ALL", "BUILD", "WHEEL"]: + CI_TEST_PHASE = "ALL" + + + +def get_current_script_path(): + """ Returns the absolute path containing this script. """ + try: + this_file = __file__ + except NameError: + this_file = sys.argv[0] + this_file = os.path.abspath(this_file) + return os.path.dirname(this_file) + +def is_snapshot_build(): + """ + Returns True if project needs to be built with --snapshot-build + + This is true if the version found in pyside_version.py is not a + pre-release version (no alphas, betas). + + This eliminates the need to remove the --snapshot-build option + on a per-release branch basis (less things to remember to do + for a release). + """ + setup_script_dir = get_current_script_path() + pyside_version_py = os.path.join( + setup_script_dir, "sources", "pyside2", "pyside_version.py") + d = get_python_dict(pyside_version_py) + + release_version_type = d['release_version_type'] + pre_release_version = d['pre_release_version'] + if pre_release_version and release_version_type: + return True + return False + +def call_setup(python_ver, phase): + print("call_setup") + print("python_ver", python_ver) + print("phase", phase) + _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) + + if phase in ["BUILD"]: + rmtree(_env, True) + # Pinning the virtualenv before creating one + run_instruction(["pip", "install", "--user", "virtualenv==20.0.25"], "Failed to pin virtualenv") + # installing to user base might not be in PATH by default. + env_path = os.path.join(site.USER_BASE, "bin") + v_env = os.path.join(env_path, "virtualenv") + if sys.platform == "win32": + env_path = os.path.join(site.USER_BASE, "Scripts") + v_env = os.path.join(env_path, "virtualenv.exe") + try: + run_instruction([v_env, "--version"], "Using default virtualenv") + except Exception as e: + v_env = "virtualenv" + run_instruction([v_env, "-p", _pExe, _env], "Failed to create virtualenv") + # When the 'python_ver' variable is empty, we are using Python 2 + # Pip is always upgraded when CI template is provisioned, upgrading it in later phase may cause perm issue + run_instruction([env_pip, "install", "-r", "requirements.txt"], "Failed to install dependencies") + if sys.platform == "win32": + run_instruction([env_pip, "install", "numpy==1.19.3"], "Failed to install numpy 1.19.3") + else: + run_instruction([env_pip, "install", "numpy"], "Failed to install numpy") + + cmd = [env_python, "-u", "setup.py"] + if phase in ["BUILD"]: + cmd += ["build", "--standalone", "--skip-packaging"] + elif phase in ["WHEEL"] or CI_RELEASE_CONF: + cmd += ["bdist_wheel", "--reuse-build", "--standalone", "--skip-cmake", "--skip-make-install", "--only-package"] + + cmd += ["--build-tests", + "--parallel=4", + "--verbose-build"] + if python_ver == "3": + cmd += ["--limited-api=yes"] + if is_snapshot_build(): + cmd += ["--snapshot-build"] + + qmake_path = get_ci_qmake_path(CI_ENV_INSTALL_DIR, CI_HOST_OS) + cmd.append(qmake_path) + + # Due to certain older CMake versions generating very long paths + # (at least with CMake 3.6.2) when using the export() function, + # pass the shorter paths option on Windows so we don't hit + # the path character length limit (260). + if CI_HOST_OS == "Windows": + cmd += ["--shorter-paths"] + + cmd += ["--package-timestamp=" + CI_INTEGRATION_ID] + + env = os.environ + run_instruction(cmd, "Failed to run setup.py for build", initial_env=env) + +def run_build_instructions(phase): + + # Uses default python, hopefully we have python2 installed on all hosts + # Skip building using Python 2 on Windows, because of different MSVC C runtimes (VS2008 vs VS2015+) + if CI_HOST_OS != "Windows": + call_setup("", phase) + # In case of packaging build, we have to build also python3 wheel + + if CI_RELEASE_CONF and CI_HOST_OS_VER not in ["RHEL_6_6"]: + call_setup("3", phase) + +if __name__ == "__main__": + + # Remove some environment variables that impact cmake + for env_var in ['CC', 'CXX']: + if os.environ.get(env_var): + del os.environ[env_var] + + if CI_TEST_PHASE in ["ALL", "BUILD"]: + run_build_instructions("BUILD") + + if CI_TEST_PHASE in ["ALL", "WHEEL"]: + run_build_instructions("WHEEL") diff --git a/coin_test_instructions.py b/coin_test_instructions.py new file mode 100644 index 0000000..467f58d --- /dev/null +++ b/coin_test_instructions.py @@ -0,0 +1,126 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +from build_scripts.options import has_option +from build_scripts.options import option_value +from build_scripts.utils import install_pip_dependencies +from build_scripts.utils import get_qtci_virtualEnv +from build_scripts.utils import run_instruction +from build_scripts.utils import rmtree +from build_scripts.utils import get_ci_qmake_path +import os +import site +import sys + +# Values must match COIN thrift +CI_HOST_OS = option_value("os") +CI_TARGET_OS = option_value("targetOs") +CI_HOST_ARCH = option_value("hostArch") +CI_TARGET_ARCH = option_value("targetArch") +CI_HOST_OS_VER = option_value("osVer") +CI_ENV_INSTALL_DIR = option_value("instdir") +CI_ENV_AGENT_DIR = option_value("agentdir") or "." +CI_COMPILER = option_value("compiler") +CI_FEATURES = [] +_ci_features = option_value("features") +if _ci_features is not None: + for f in _ci_features.split(', '): + CI_FEATURES.append(f) +CI_RELEASE_CONF = has_option("packaging") + +def call_testrunner(python_ver, buildnro): + _pExe, _env, env_pip, env_python = get_qtci_virtualEnv(python_ver, CI_HOST_OS, CI_HOST_ARCH, CI_TARGET_ARCH) + rmtree(_env, True) + # Pinning the virtualenv before creating one + run_instruction(["pip", "install", "--user", "virtualenv==20.0.25"], "Failed to pin virtualenv") + # installing to user base might not be in PATH by default. + env_path = os.path.join(site.USER_BASE, "bin") + v_env = os.path.join(env_path, "virtualenv") + if sys.platform == "win32": + env_path = os.path.join(site.USER_BASE, "Scripts") + v_env = os.path.join(env_path, "virtualenv.exe") + try: + run_instruction([v_env, "--version"], "Using default virtualenv") + except Exception as e: + v_env = "virtualenv" + + run_instruction([v_env, "-p", _pExe, _env], "Failed to create virtualenv") + # When the 'python_ver' variable is empty, we are using Python 2 + # Pip is always upgraded when CI template is provisioned, upgrading it in later phase may cause perm issue + run_instruction([env_pip, "install", "-r", "requirements.txt"], "Failed to install dependencies") + if sys.platform == "win32": + run_instruction([env_pip, "install", "numpy==1.19.3"], "Failed to install numpy 1.19.3") + else: + run_instruction([env_pip, "install", "numpy"], "Failed to install numpy") + + cmd = [env_python, "testrunner.py", "test", + "--blacklist", "build_history/blacklist.txt", + "--buildno=" + buildnro] + run_instruction(cmd, "Failed to run testrunner.py") + + qmake_path = get_ci_qmake_path(CI_ENV_INSTALL_DIR, CI_HOST_OS) + + # Try to install built wheels, and build some buildable examples. + if CI_RELEASE_CONF: + wheel_tester_path = os.path.join("testing", "wheel_tester.py") + cmd = [env_python, wheel_tester_path, qmake_path] + run_instruction(cmd, "Error while running wheel_tester.py") + +def run_test_instructions(): + # Remove some environment variables that impact cmake + for env_var in ['CC', 'CXX']: + if os.environ.get(env_var): + del os.environ[env_var] + + os.chdir(CI_ENV_AGENT_DIR) + testRun = 0 + # We didn't build for Python 2 in win + if CI_HOST_OS != "Windows": + call_testrunner("", str(testRun)) + testRun =+ 1 + # We know that second build was with python3 + if CI_RELEASE_CONF: + # In win machines, there are additional python versions to test with + if CI_HOST_OS == "Windows": + call_testrunner("3.6.1", str(testRun)) + call_testrunner("3.8.1", str(testRun)) + else: + call_testrunner("3", str(testRun)) + +if __name__ == "__main__": + run_test_instructions() diff --git a/dist/changes-1.2.3 b/dist/changes-1.2.3 new file mode 100644 index 0000000..7deaa8b --- /dev/null +++ b/dist/changes-1.2.3 @@ -0,0 +1,405 @@ +Changes +======= + +1.2.3 (2014-??-??) +------------------ + +Major changes +~~~~~~~~~~~~~ + +PySide-setup +************ + +- On Linux systems there is no more need to call the post-install script + +1.2.2 (2014-04-24) +------------------ + +Complete list of changes and bug fixes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PySide +****** + +- Fix PYSIDE-190: QCoreApplication would deadlock on exit if the global + QThreadPool.globalInstance() is running a QRunnable with python code +- Change GlobalReceiver to explicitly 'use' [dis]connectNotify of the base + class in order to avoid hiding these with its own overloads. +- Add explicit casts when initializing an int[] using {}'s, as required + by C++11 to be "well formed" +- Fix PYSIDE-172: multiple rules for file +- Use file system encoding instead of assumed 'ascii' when registering + qt.conf in Qt resource system + +Shiboken +******** + +- Remove rejection lines that cause the sample_list test to fail +- Remove protected from samblebinding test +- Add parsing of 'noexcept' keyword +- Fix function rejections (i.e. support overloads) +- Fix building with python 3.3 and 3.4 +- Doc: Stop requiring sphinx.ext.refcounting with Sphinx 1.2+ +- Fix for containers with 'const' values +- Fix compilation issue on OS X 10.9 +- Only use fields in PyTypeObject when defining types +- Fix buffer overrun processing macro definitions +- Fix 'special' include handling +- Fix finding container base classes +- Refactor and improve added function resolving +- Work around MSVC's deficient in libsample/transform.cpp +- Fix description of sample/transform unit test +- Change wrapping and indent of some code in Handler::startElement to + improve consistency +- Fix '%#' substitution for # > 9 +- Improve dependencies for tests + +1.2.1 (2013-08-16) +------------------ + +Major changes +~~~~~~~~~~~~~ + +PySide +****** + +- In memory qt.conf generation and registration + +Shiboken +******** + +- Better support for more than 9 arguments to methods +- Avoiding a segfault when getting the .name attribute on an enum value with no name + +PySide-setup +************ + +- Switched to the new setuptools (v0.9.8) which has been merged with Distribute again and works for Python 2 and 3 with one codebase +- Support for building windows binaries with only Windows SDK installed (Visual Studio is no more required) +- Removed --msvc-version option. Required msvc compiler version is now resolved from python interpreter version + +1.2.0 (2013-07-02) +------------------ + +Major changes +~~~~~~~~~~~~~ + +PySide +****** + +- Fix multiple segfaults and better track the life time of Qt objects +- Fix multiple memory leaks + +Shiboken +******** + +- Install the shiboken module to site-packages +- Fix multiple segfaults + +PySide-setup +************ + +- On Windows system, when installing PySide binary distribution via easy_install, + there is no more need to call the post-install script +- Support for building windows binaries outside of Visual Studio command prompt +- Build and package the shiboken docs when sphinx is installed + +Complete list of changes and bug fixes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PySide +****** + +- Set up PYTHONPATH for tests correctly +- Fix potential segfault at shutdown +- Fix PYSIDE-61 +- Tell Qt to look for qml imports in the PySide package +- fix build in C++11 mode +- Fix QByteArray memory leak +- Ignore QtCore import errors when initializing plugins folder +- Preload OpenSSL DLLs on Windows. +- Look first in the PySide package for Qt's plugins folder, instead of just in Qt's install or build folder +- Add explicit type conversion to fix mingw compile error +- Use QObject property to invalidate wrapper before deletion +- Invalidate metaObject wrapper before deletion +- Fix reference leak on convertion from a C++ map type to Python dict +- Change the order of pysitetest and signals directories because signals/disconnect_test.py depends on pysidetest module + +Shiboken +******** + +- Removed old logos from html docs +- Add missing return on module init error +- Don't break -Werror=non-virtual-dtor +- Fixing shiboken test for minimal binding test +- Decref reference to type object +- Fix segfault when using shiboken.delete +- Use non-static method def for instance methods +- Fix bug introduced when recursive_invalidate was added +- fix build in C++11 mode +- Prevent infinite recursion in invalidate +- Fix possible conflict with garbage collector +- Fix possible crash at exit +- Fix handling of unsigned long long and provide unittests +- Add test to illustrate issue on typedef enum +- Use getWrapperForQObject to convert if generating for PySide +- Allow compilation without a python shared library +- Use parent class's metaObject if wrapper is NULL +- Optionally assert on free'd pointer with a valid wrapper +- Find python3 libraries when built with pydebug enabled +- Fix PYSIDE-108 bug and add example +- PYSIDE-83 Fix segfault calling shiboken.dump +- Fix and test case for bug PYSIDE-72 +- Override all functions with the same name, not just one +- Update vector conversion +- Add typedef examples to minimal +- Add test files back to cmake +- Don't use it->second after erasing it +- Find function modifications defined in the 2nd+ base class. Fixes bug PYSIDE-54. +- Set a default hash function for all ObjectTypes. Fix bug PYSIDE-42. +- Fix compilation when there is no libxslt installed on the system. +- Fixed resolving of SOABI. SOABI is implemented on Linux, but not on Windows +- Don't use inline methods in dllexported classes to keep VC++ happy +- Use SpooledTemporaryFile in 2.6+ os.tmpfile() fails on win32 if process doesn't have admin permissions + +PySide-setup +************ + +- Support for building windows binaries outside of Visual Studio command prompt +- Build and package the shiboken docs when sphinx is installed +- Support Ubuntu 13.04 and Fedora 18 +- Fixed "develop" setuptools command +- Documentation updates +- Add --build-tests option to enable building the tests +- Add --jom and --jobs options +- Add --no-examples option to exclude the examples +- Add --relwithdebinfo option to enable a release-with-debug-info build mode +- Add --ignore-git option +- Add --make-spec option to specify make generator + +1.1.2 (2012-08-28) +------------------ + +Bug fixes +~~~~~~~~~ + +- During signal emission don't get return type after callback +- Invalidate QStandardModel::invisibleRootItem in clear() method +- QAbstractItemModel has wrong ownership policy for selectionModel() +- Improved QVector to python conversion +- Disable docstring generation if tools aren't found. +- Fixed some issues compiling PySide using VC++ +- Install the shiboken module to site-packages +- Fix compilation when there is no libxslt installed on the system. +- Set a default hash function for all ObjectTypes. +- Fix segfault calling shiboken.dump + +1.1.1 (2012-04-19) +------------------ + +Major changes +~~~~~~~~~~~~~ + +- Unified toolchain! No more GeneratorRunner and ApiExtractor, now you just need Shiboken to compile PySide. + +Bug fixes +~~~~~~~~~ + +- 1105 Spyder fails with HEAD +- 1126 Segfault when exception is raised in signalInstanceDisconnect +- 1135 SIGSEGV when loading custom widget using QUiLoader when overriding createWidget() +- 1041 QAbstractItemModel has wrong ownership policy for selectionModel() +- 1086 generatorrunner segfault processing #include +- 1110 Concurrency error causes GC heap corruption +- 1113 Instantiating QObject in user-defined QML element's constructor crashes if instantiated from QML +- 1129 Segmentation fault on close by QStandardItem/QStandardItemModel +- 1104 QSettings has problems with long integers +- 1108 tests/QtGui/pyside_reload_test.py fails when bytecode writing is disabled +- 1138 Subclassing of QUiLoader leads to "Internal C++ object already deleted" exception (again) +- 1124 QPainter.drawPixmapFragments should take a list as first argument +- 1065 Invalid example in QFileDialog documentation +- 1092 shiboken names itself a 'generator' +- 1094 shiboken doesn't complain about invalid options +- 1044 Incorrect call to parent constructor in example +- 1139 Crash at exit due to thread state (tstate) being NULL +- PYSIDE-41 QModelIndex unhashable + +1.1.0 (2012-01-02) +------------------ + +Major changes +~~~~~~~~~~~~~ + +- New type converter scheme + +Bug fixes +~~~~~~~~~ + +- 1010 Shiboken Cygwin patch +- 1034 Error compiling PySide with Python 3.2.2 32bit on Windows +- 1040 pyside-uic overwriting attributes before they are being used +- 1053 pyside-lupdate used with .pro files can't handle Windows paths that contain spaces +- 1060 Subclassing of QUiLoader leads to "Internal C++ object already deleted" exception +- 1063 Bug writing to files using "QTextStream + QFile + QTextEdit" on Linux +- 1069 QtCore.QDataStream silently fails on writing Python string +- 1077 Application exit crash when call QSyntaxHighlighter.document() +- 1082 OSX binary links are broken +- 1083 winId returns a PyCObject making it impossible to compare two winIds +- 1084 Crash (segfault) when writing unicode string on socket +- 1091 PixmapFragment and drawPixmapFragments are not bound +- 1095 No examples for shiboken tutorial +- 1097 QtGui.QShortcut.setKey requires QKeySequence +- 1101 Report invalid function signatures in typesystem +- 902 Expose Shiboken functionality through a Python module +- 969 viewOptions of QAbstractItemView error + +1.0.9 (2011-11-29) +------------------ + +Bug fixes +~~~~~~~~~ + +- 1058 Strange code in PySide/QtUiTools/glue/plugins.h +- 1057 valgrind detected "Conditional jump or move depends on uninitialised value" +- 1052 PySideConfig.cmake contains an infinite loop due to missing default for SHIBOKEN_PYTHON_SUFFIX +- 1048 QGridLayout.itemAtPosition() crashes when it should return None +- 1037 shiboken fails to build against python 3.2 (both normal and -dbg) on i386 (and others) +- 1036 Qt.KeyboardModifiers always evaluates to zero +- 1033 QDialog.DialogCode instances and return value from \QDialog.exec_ hash to different values +- 1031 QState.parentState() or QState.machine() causes python crash at exit +- 1029 qmlRegisterType Fails to Increase the Ref Count +- 1028 QWidget winId missing +- 1016 Calling of Q_INVOKABLE method returning not QVariant is impossible... +- 1013 connect to QSqlTableModel.primeInsert() causes crash +- 1012 FTBFS with hardening flags enabled +- 1011 PySide Cygwin patch +- 1010 Shiboken Cygwin patch +- 1009 GeneratorRunner Cygwin patch +- 1008 ApiExtractor Cygwin patch +- 891 ApiExtractor doesn't support doxygen as backend to doc generation. + +1.0.8 (2011-10-21) +------------------ + +Major changes +~~~~~~~~~~~~~ + +- Experimental Python3.2 support +- Qt4.8 beta support + +Bug fixes +~~~~~~~~~ + +- 1022 RuntimeError: maximum recursion depth exceeded while getting the str of an object +- 1019 Overriding QWidget.show or QWidget.hide do not work +- 944 Segfault on QIcon(None).pixmap() + +1.0.7 (2011-09-21) +------------------ + +Bug fixes +~~~~~~~~~ + +- 996 Missing dependencies for QtWebKit in buildscripts for Fedora +- 986 Documentation links +- 985 Provide versioned pyside-docs zip file to help packagers +- 981 QSettings docs should empathize the behavior changes of value() on different platforms +- 902 Expose Shiboken functionality through a Python module +- 997 QDeclarativePropertyMap doesn't work. +- 994 QIODevice.readData must use qmemcpy instead of qstrncpy +- 989 Pickling QColor fails +- 987 Disconnecting a signal that has not been connected +- 973 shouldInterruptJavaScript slot override is never called +- 966 QX11Info.display() missing +- 959 can't pass QVariant to the QtWebkit bridge +- 1006 Segfault in QLabel init +- 1002 Segmentation fault on PySide/Spyder exit +- 998 Segfault with Spyder after switching to another app +- 995 QDeclarativeView.itemAt returns faulty reference. (leading to SEGFAULT) +- 990 Segfault when trying to disconnect a signal that is not connected +- 975 Possible memory leak +- 991 The __repr__ of various types is broken +- 988 The type supplied with currentChanged signal in QTabWidget has changed in 1.0.6 + +1.0.6 (2011-08-22) +------------------ + +Major changes +~~~~~~~~~~~~~ + +- New documentation layout; +- Fixed some regressions from the last release (1.0.5); +- Optimizations during anonymous connection; + +Bug fixes +~~~~~~~~~ + +- 972 anchorlayout.py of graphicsview example raised a unwriteable memory exception when exits +- 953 Segfault when QObject is garbage collected after QTimer.singeShot +- 951 ComponentComplete not called on QDeclarativeItem subclass +- 965 Segfault in QtUiTools.QUiLoader.load +- 958 Segmentation fault with resource files +- 944 Segfault on QIcon(None).pixmap() +- 941 Signals with QtCore.Qt types as arguments has invalid signatures +- 964 QAbstractItemView.moveCursor() method is missing +- 963 What's This not displaying QTableWidget column header information as in Qt Designer +- 961 QColor.__repr__/__str__ should be more pythonic +- 960 QColor.__reduce__ is incorrect for HSL colors +- 950 implement Q_INVOKABLE +- 940 setAttributeArray/setUniformValueArray do not take arrays +- 931 isinstance() fails with Signal instances +- 928 100's of QGraphicItems with signal connections causes slowdown +- 930 Documentation mixes signals and functions. +- 923 Make QScriptValue (or QScriptValueIterator) implement the Python iterator protocol +- 922 QScriptValue's repr() should give some information about its data +- 900 QtCore.Property as decorator +- 895 jQuery version is outdated, distribution code de-duplication breaks documentation search +- 731 Can't specify more than a single 'since' argument +- 983 copy.deepcopy raises SystemError with QColor +- 947 NETWORK_ERR during interaction QtWebKit window with server +- 873 Deprecated methods could emit DeprecationWarning +- 831 PySide docs would have a "Inherited by" list for each class + +1.0.5 (2011-07-22) +------------------ + +Major changes +~~~~~~~~~~~~~ + +- Widgets present on "ui" files are exported in the root widget, check PySide ML thread for more information[1]; +- pyside-uic generate menubars without parent on MacOS plataform; +- Signal connection optimizations; + +Bug fixes +~~~~~~~~~ + +- 892 Segfault when destructing QWidget and QApplication has event filter installed +- 407 Crash while multiple inheriting with QObject and native python class +- 939 Shiboken::importModule must verify if PyImport_ImportModule succeeds +- 937 missing pid method in QProcess +- 927 Segfault on QThread code. +- 925 Segfault when passing a QScriptValue as QObject or when using .toVariant() on a QScriptValue +- 905 QtGui.QHBoxLayout.setMargin function call is created by pyside-uic, but this is not available in the pyside bindings +- 904 Repeatedly opening a QDialog with Qt.WA_DeleteOnClose set crashes PySide +- 899 Segfault with 'QVariantList' Property. +- 893 Shiboken leak reference in the parent control +- 878 Shiboken may generate incompatible modules if a new class is added. +- 938 QTemporaryFile JPEG problem +- 934 A __getitem__ of QByteArray behaves strange +- 929 pkg-config files do not know about Python version tags +- 926 qmlRegisterType does not work with QObject +- 924 Allow QScriptValue to be accessed via [] +- 921 Signals not automatically disconnected on object destruction +- 920 Cannot use same slot for two signals +- 919 Default arguments on QStyle methods not working +- 915 QDeclarativeView.scene().addItem(x) make the x object invalid +- 913 Widgets inside QTabWidget are not exported as members of the containing widget +- 910 installEventFilter() increments reference count on target object +- 907 pyside-uic adds MainWindow.setMenuBar(self.menubar) to the generated code under OS X +- 903 eventFilter in ItemDelegate +- 897 QObject.property() and QObject.setProperty() methods fails for user-defined properties +- 896 QObject.staticMetaObject() is missing +- 916 Missing info about when is possible to use keyword arguments in docs [was: QListWidgetItem's constructor ignores text parameter] +- 890 Add signal connection example for valueChanged(int) on QSpinBox to the docs +- 821 Mapping interface for QPixmapCache +- 909 Deletion of QMainWindow/QApplication leads to segmentation fault diff --git a/dist/changes-5.12.1 b/dist/changes-5.12.1 new file mode 100644 index 0000000..e0eeeff --- /dev/null +++ b/dist/changes-5.12.1 @@ -0,0 +1,45 @@ +Qt for Python 5.12.1 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-878] Added binding for QWebEngineUrlScheme which was missing + - Completed the signature introspection + - Activated existence_test.py for 5.12 + - [PYSIDE-868] Fixed a crash related to multiple inheritance + - [PYSIDE-886] Fixed crash when mixing static overloads with instance methods in derived classes + - [PYSIDE-892] Added free functions from namespace QtQml + - Fixed a rare type hint racing condition + - Used helper function for accessing the meta object in quick type registration for libpyside + - [PYSIDE-883] Fixed regression related to removing createIndex method that uses PyObject* + - [PYSIDE-882] Avoided the creation of empty build directories in the install tree + - Produced TypeError messages using the signature module + - Replaced nullptr by None in signatures in the documentation + - Updated and fixed the Slot documentation + - Added \nullptr macro definition in the documentation + - [PYSIDE-874] Fixed wrong METADATA for generated wheels + - [PYSIDE-898] Improved check when a QFlag is found + - [PYSIDE-790] Fixed a crash when overriding QAbstractNativeEventFilter.QAbstractNativeEventFilter() + - Added support for the help() function using the signature module + - [PYSIDE-880] Fixed an issue on the setup.py when running under non-UTF8 locale + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - Make signatures in overload decisor code more verbose in shiboken + - [PYSIDE-914] Included MSVC dlls in the shiboken module package diff --git a/dist/changes-5.12.2 b/dist/changes-5.12.2 new file mode 100644 index 0000000..b45d38c --- /dev/null +++ b/dist/changes-5.12.2 @@ -0,0 +1,49 @@ +Qt for Python 5.12.2 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-934] Added a method to VoidPtr called toBytes() to get the bytes representation. + - [PYSIDE-95] Added ownership transfer for QGraphicsItemGroup.addToGroup + - [PYSIDE-928][PYSIDE-937][PYSIDE-943] Fixing a refcounting bug shown by __doc__ handling + - [PYSIDE-931] Added the attribute 'allow-thread' to the type system and class entries. + - [PYSIDE-947] Fixed conversions of list of smart pointers to python + - [PYSIDE-953] Preventing Python 3.5 from crashing the build + - [PYSIDE-940] Added setPageSize new signature to QPageSize + - [PYSIDE-950] Allowed subclassing PyCFunction in extension modules + - [PYSIDE-938] Set the proper parent when overloading QUiLoader.addAction() + - Added common QPrintSupport typesystem for QWebEngine + - [PYSIDE-942] Fixed an error when importing signatures in frozen executables + - [PYSIDE-948] Fixed problem when using smart pointers with namespaces + - [PYSIDE-45] Added support for using PyObject wrapper when an invalid QVariant is used + - [PYSIDE-922] Added pyObj check for the setSequenceOwnership + - [PYSIDE-919] Modernized the cmake build process + - [PYSIDE-924] Propagated Property attributes to the MetaObject + - Improved the type hints for containers + - [PYSIDE-906] Added missing classes QWebEngineHistory and WebEngineHistoryItem + - Added QtRemoteObject classes + - Added a script to generate a debug log in windows called debug_windows.py + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - Fixed many build warnings on shiboken and pyside + - Extended the exception handling test in shiboken + - [PYSIDE-929] Added dependency version for shiboken2 + - [PYSIDE-914] Including MSVC dlls in the shiboken module package + - [PYSIDE-932] Implement Embedding To Make Signatures Always Available diff --git a/dist/changes-5.12.3 b/dist/changes-5.12.3 new file mode 100644 index 0000000..fda65b4 --- /dev/null +++ b/dist/changes-5.12.3 @@ -0,0 +1,35 @@ +Qt for Python 5.12.3 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-993] Use correct environment variable to detect when running in Coin + - Many updated to the documentation + - Add array modification for QGLShaderProgram::setAttributeArray(int,const float *v,int,int) + - Signatures: Add support for PySide2.QtCore.short/ushort/signed char + - Add explicit methods for QOpenGLShaderProgramm.setUniformValue (i/f) + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-977] Shiboken: Add "noexcept" to wrapper when wrapped function is noexcept + - [PYSIDE-975] shiboken: Allow for include paths with relative directories + - [PYSIDE-995] shiboken: Enable adding call operators + - shiboken: Move the Api extractor documentation into shiboken + - shiboken: Fix code injection not working for operator functions + - shiboken: Enable including typesystem XML snippets via entities diff --git a/dist/changes-5.12.4 b/dist/changes-5.12.4 new file mode 100644 index 0000000..d6d1679 --- /dev/null +++ b/dist/changes-5.12.4 @@ -0,0 +1,43 @@ +Qt for Python 5.12.4 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-571] correct bool(qApp) on Python 2 + - [PYSIDE-735] generate_pyi: Simplify, Enhance and Get Rid Of Any Import Problems + - [PYSIDE-865] opengl/contextinfo.py: Fix exception on exit + - [PYSIDE-865] opengl/contextinfo.py: Polish the example a bit + - [PYSIDE-908] Complete the help() support for Types + - [PYSIDE-955] Add PySide2: Add OpenGL version functions as separate module + - [PYSIDE-980] CMake: Change the default behavior CMAKE_BUILD_TYPE + - [PYSIDE-996] Fix PyInstaller after removal of COIN glitches + - [PYSIDE-1003] Fix Shiboken.ObjectType.__new__ for Python 2.7 V2 + - [PYSIDE-1004] Make the __signature__ attribute writable by default + - [PYSIDE-1008] Fix propagation of existing LD env vars when calling generate_pyi + - [PYSIDE-1009] Signature: Try to recognize unknown modules in errorhandler.py + - [PYSIDE-1012] Fix build on centOS/conda forge + - [PYSIDE-1019] PySide: Allow any existing attribute in the constructor + - [PYSIDE-1022] TabbedBrowser Example: Fix "Open in new tab" + - [PYSIDE-1027] Fix negative refcount on QSocketNotifier + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-955] shiboken/Generators: Cache class information lists per class + - [PYSIDE-1016] shiboken: Fix handling shared pointers passed by const-ref, take 2 + - [PYSIDE-1017] shiboken: Enable specifying names for a parameters of added functions diff --git a/dist/changes-5.12.5 b/dist/changes-5.12.5 new file mode 100644 index 0000000..d463b83 --- /dev/null +++ b/dist/changes-5.12.5 @@ -0,0 +1,40 @@ + +Qt for Python 5.12.5 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-571] Support the qApp macro in "scriptable application" + - [PYSIDE-634] Add support for parameterNames in Signals + - [PYSIDE-951] Correct QtPrintSupport dependency + - [PYSIDE-1010] Add optional support for types in QSettings::value + - [PYSIDE-1020] Fix pyside2-uic to generate correct code for QWebview and QQuickWidget + - [PYSIDE-1028] Leave QVariantMap as a name, not a type + - [PYSIDE-1029] Fix type name for lookup of QFlags<> converters + - [PYSIDE-1032] Use default compiler on macOS + - [PYSIDE-1035] Fix pyside2-uic to generate correct code for QTableWidget + - [PYSIDE-1066] Fix Xcode sdk value embedded into PySide2 binaries + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1024] shiboken: Generate code for smart pointers only within declaring package + - [PYSIDE-1037] shiboken: Allow for "auto" as target of type for CONVERTTOCPP in injected code + + diff --git a/dist/changes-5.12.6 b/dist/changes-5.12.6 new file mode 100644 index 0000000..d1eba40 --- /dev/null +++ b/dist/changes-5.12.6 @@ -0,0 +1,29 @@ +Qt for Python 5.12.6 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [Fixes: PYSIDE-1007] Remove extra ref on QDataStream::setDevice + - [Fixes: PYSIDE-1051] Fix heaptype conflict with QtCore.QObject.__new__in Python 2.7 + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - No changes + diff --git a/dist/changes-5.13.0 b/dist/changes-5.13.0 new file mode 100644 index 0000000..4b7a2b7 --- /dev/null +++ b/dist/changes-5.13.0 @@ -0,0 +1,33 @@ +Qt for Python 5.13.0 is a minor release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-487] Add bindings for 5.13 + - [PYSIDE-571] Support the qApp macro in "scriptable application" + - [PYSIDE-841] Doc: Add QML Integration tutorial + - [PYSIDE-841] Docs: Add Expenses tool tutorial + - [PYSIDE-855] Regenerate all example forms using the python-extended rcc of 5.14 + - [PYSIDE-1029] Fix type name for lookup of QFlags<> converters + - [PYSIDE-1032] Use default compiler on macOS + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1024] shiboken: Generate code for smart pointers only within declaring package diff --git a/dist/changes-5.13.1 b/dist/changes-5.13.1 new file mode 100644 index 0000000..9b99390 --- /dev/null +++ b/dist/changes-5.13.1 @@ -0,0 +1,47 @@ + +Qt for Python 5.13.1 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [Fixes https://github.com/spyder-ide/qtpy/issues/195] Fix RuntimeError: dictionary changed size during iteration + - [PYSIDE-634] Add support for parameterNames in Signals + - [PYSIDE-951] Cleanup signature module before substantial change + - [PYSIDE-951] correct QtPrintSupport dependency + - [PYSIDE-1010] Add optional support for types in QSettings::value + - [PYSIDE-1020] Fix pyside2-uic to generate correct code for QWebview and QQuickWidget + - [PYSIDE-1028] Leave QVariantMap as a name, not a type + - [PYSIDE-1033] CMake modularization: macros creation + - [PYSIDE-1035] Fix pyside2-uic to generate correct code for QTableWidget + - [PYSIDE-1051] Fix heaptype conflict with QtCore.QObject.__new__in Python 2.7 + - [PYSIDE-1052] Add QtCore.Slot.__signature__ and much more manually + - [PYSIDE-1059] Documentation: update QInputDialog snippets + - [PYSIDE-1066] Fix Xcode sdk value embedded into PySide2 binaries + - [PYSIDE-1067] Update docs style + - [PYSIDE-1073] Fix a typing bug in Python 2.7 and update + - [PYSIDE-1077] Fix wrong Python init return codes + - [PYSIDE-1079] signature: Support typing.Optional[T] and refine a bit + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1024] shiboken: Generate code for smart pointers only within declaring package + - [PYSIDE-1037] shiboken: Allow for "auto" as target of type for CONVERTTOCPP in injected code + + diff --git a/dist/changes-5.13.2 b/dist/changes-5.13.2 new file mode 100644 index 0000000..52edd7a --- /dev/null +++ b/dist/changes-5.13.2 @@ -0,0 +1,37 @@ +Qt for Python 5.13.2 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-785] Release ownership in QAbstractVideoFilterWrapper::createFilterRunnable + - [PYSIDE-820] Fix booleans and empty list cases in QSettings + - [PYSIDE-849] Add inject-code for QVideoFrame::bits() + - [PYSIDE-1007] Remove extra ref on QDataStream::setDevice + - [PYSIDE-1019] libpyside: Fix compiler warning + - [PYSIDE-1049] Split build instructions to build and packaging + - [PYSIDE-1051] Fix heaptype conflict with QtCore.QObject.__new__in Python 2.7 + - [PYSIDE-1089] Fix formatting of the deployment documentation + - [PYSIDE-1093] Fix bad shutdown effect on QApplication.instance() + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1095] shiboken: Fix handling of modified default expressions + + diff --git a/dist/changes-5.14.0 b/dist/changes-5.14.0 new file mode 100644 index 0000000..46b4a6b --- /dev/null +++ b/dist/changes-5.14.0 @@ -0,0 +1,69 @@ +Qt for Python 5.14.0 is a minor release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Source Incompatible/Behavior Changes * +**************************************************************************** + +- [PYSIDE-990] It is no longer possible to nest types in typesystem files by + by qualifying the namespace components with "::". The elements + need to be properly nested. + + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-487] Add bindings for Qt 5.14 + - [PYSIDE-785] Release ownership in QAbstractVideoFilterWrapper::createFilterRunnable + - [PYSIDE-795] Create a framework for deprecated functions + - [PYSIDE-795] Make the function registry more usable in Python modules + - [PYSIDE-795] Improve the NumPy Support by iterables + - [PYSIDE-820] Fix booleans and empty list cases in QSettings + - [PYSIDE-849] Add inject-code for QVideoFrame::bits() + - [PYSIDE-939] Add support for Python 3.8 + - [PYSIDE-939] Fix refcount issues with QSettings glue code + - [PYSIDE-939] Finalize the Python 3.8 refcount fix + - [PYSIDE-951] Support Pointer Primitive Types by Arrays or Result Tuples + - [PYSIDE-1007] Remove extra ref on QDataStream::setDevice + - [PYSIDE-1033] CMake modularization: macros creation + - [PYSIDE-1041] Enable multimedia classes after API fixup + - [PYSIDE-1047] QtWinExtras: Add QtWin namespace + - [PYSIDE-1051] Fix heaptype conflict with QtCore.QObject.__new__in Python 2.7 + - [PYSIDE-1052] Add QtCore.Slot.__signature__ and much more manually + - [PYSIDE-1059] Documentation: update QInputDialog snippets + - [PYSIDE-1066] Fix Xcode sdk value embedded into PySide2 binaries + - [PYSIDE-1067] Update docs style + - [PYSIDE-1067] New documentation structure + - [PYSIDE-1068] Add designer to the pyside tools + - [PYSIDE-1073] Fix a typing bug in Python 2.7 and update + - [PYSIDE-1077] Fix wrong Python init return codes + - [PYSIDE-1079] signature: Support typing.Optional[T] and refine a bit + - [PYSIDE-1089] Fix formatting of the deployment documentation + - [PYSIDE-1093] Fix bad shutdown effect on QApplication.instance() + - [PYSIDE-1098] Replace pyside2-uic/pyside2-rcc by + uic/rcc which now have an option to generate Python + - [PYSIDE-1101] Remove QGraphicsItem::scroll from QtChart + - [PYSIDE-1140] Add python_requires to the python setup + - [QTBUG-66304] Blacklist failing QtPositioning test + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-454] Fix crash when smartptr template class cannot be found + - [PYSIDE-1037] Allow for "auto" as target of type for CONVERTTOCPP in injected code + - [PYSIDE-1095] Fix handling of modified default expressions diff --git a/dist/changes-5.14.1 b/dist/changes-5.14.1 new file mode 100644 index 0000000..b7441f3 --- /dev/null +++ b/dist/changes-5.14.1 @@ -0,0 +1,35 @@ +Qt for Python 5.14.1 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-841] Add example for Threads and Signals + - [PYSIDE-1135] qApp: Ensure QtCore import when embedded QApplication subclass is used + - [PYSIDE-1158] Let qApp be noApp instead of pretending to be None + - [PYSIDE-1164] qApp: make sure to create the right instance when embedding + - [PYSIDE-1165] designer: patch rpath for unix + - [PYSIDE-1192] libpyside: Set default signal name only if previously assigned + - [PYSIDE-1201] docs: Fix pre overlap and improve reading + - [PYSIDE-1205] libpyside: avoid freeing char* + - [PYSIDE-1207] Fix ownership of QTextDocument::createObject + + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1191] shiboken: Introduce "until" version attribute as opposite of "since" diff --git a/dist/changes-5.14.2 b/dist/changes-5.14.2 new file mode 100644 index 0000000..3473d41 --- /dev/null +++ b/dist/changes-5.14.2 @@ -0,0 +1,66 @@ +Qt for Python 5.14.2 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-135] Add doc getter for Property + - [PYSIDE-239] Python enum types can now be used as a valid signal type. + - [PYSIDE-939] Fix Python 3.8 warnings about deprecated int conversions of + enums/flags + - [PYSIDE-571] qApp has been turned into a normal Python variable. This + implies that QtWidgets.qApp no longer works; + it should be replaced by qApp. + - [PYSIDE-803] GUI slowdowns caused by background threads have been fixed by + reducing GIL allocation and usage of + Py_(BEGIN|END)_ALLOW_THREADS. + - [PYSIDE-858] Windows binaries are now signed. + - [PYSIDE-939] Fix testrunner for Python 3.8/Linux + - [PYSIDE-946] Add functions with callback of QWebEnginePage + - [PYSIDE-1231] Further issues introduced by Python 3.8 have been addressed: + - Warnings about deprecated int conversions of enumerations + and flags have been fixed. + - Packages can now be built with Python 3.8.1. + - Tests run with Python 3.8.1. + - [PYSIDE-1189] A crash caused by wrong ownership of the return value of + QList/QTable/QTreeWidget.mimeData() has been fixed. + - [PYSIDE-1199] The webchannel standalone example has been added. + - [PYSIDE-1204] QByteArray now properly supports the PyBuffer interface. + - [PYSIDE-1214] For accessors returning non-exposed classes inheriting + QObject, the most-derived wrapper is now created. + - [PYSIDE-1229] testrunner: Fix disrupted lines in the error log + - [PYSIDE-1236] Fix running scriptableapplication in a virtualenv on Windows + with Python 3.8 + - [PYSIDE-1247] Avoid a signature warning in Python 3.6 + - [PYSIDE-1250] PySide2: Use int for QVariant conversion when possible + - [PYSIDE-1251] Invert QTreeWidgetItem clear function loop + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-803] The default of the "allow-thread" attribute has been changed + to false as it was observed to cause performance issues when + using threads. + - [PYSIDE-1112] The shiboken documentation has been re-structured. + - [PYSIDE-1228] Typedef'ed anonymous enums are now supported. + - [PYSIDE-1240] The manual test dumpcodemodel has been modified to output + typesystem XML, enabling convenient generation of typesystem + file skeletons for new bindings. + - [PYSIDE-1241] Improve error messages about invalid types of added functions + - [PYSIDE-1241] Enable flags types in added functions + - [PYSIDE-1246] Fix classes with virtual destructors not being considered + polymorphic diff --git a/dist/changes-5.14.2.2 b/dist/changes-5.14.2.2 new file mode 100644 index 0000000..63a7a91 --- /dev/null +++ b/dist/changes-5.14.2.2 @@ -0,0 +1,38 @@ +Qt for Python 5.14.2.2 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-1100] Support type checking with the mypy module + - [PYSIDE-1236] samplebinding: Fix running with Python 3.8.2 on Windows + - [PYSIDE-1255] Fix memory corruption for QML registered types + - [PYSIDE-1271] QMutexLocker: allow-thread in constructor + - [PYSIDE-1272] signature: Add comparison for existing_doc type + - [PYSIDE-1285] qareaseries: keep references of lower/upper series + - [PYSIDE-1293] Windows: Fix encoding in custom message handler + - [PYSIDE-15] Support pickling of Qt Enum objects + - [PYSIDE-1223] Add QtUiTools.loadUiType + - [PYSIDE-1286] Implement __qualname__ and correct __module__ for classes + - [PYSIDE-1303] PySide2: Fix conversion of quintptr + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1286] shiboken: Prepare for introduction of __qualname__ + - [PYSIDE-1298] libshiboken: Support musl libc + - [PYSIDE-1299] shiboken: Fix cross builds diff --git a/dist/changes-5.14.2.3 b/dist/changes-5.14.2.3 new file mode 100644 index 0000000..6f17bc4 --- /dev/null +++ b/dist/changes-5.14.2.3 @@ -0,0 +1,35 @@ +Qt for Python 5.14.2.3 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + - [PYSIDE-1223] pyside2-uic instead of uic is not used for loadUiType() + - [PYSIDE-1257] Deployment with cx_freeze using zip_include_packages has + been fixed + - [PYSIDE-1282] A crash using QThread.terminate() on pthreads has + been fixed + - [PYSIDE-1311] The downloads functionality of the Tabbedbrowser example + has been fixed + - [PYSIDE-1321] A leaking reference in the PySide2 property getter has + been fixed + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-1325] Wrong generated code for default-initialized function + arguments ({}) has been fixed diff --git a/dist/changes-5.15.0 b/dist/changes-5.15.0 new file mode 100644 index 0000000..77c8e7d --- /dev/null +++ b/dist/changes-5.15.0 @@ -0,0 +1,49 @@ +Qt for Python 5.15.0 is a minor release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + + - [PYSIDE-487] Add API of Qt 5.15 + - [PYSIDE-487] Add support for QSerialPort + - [PYSIDE-487] Add QtQuickControls2 + - [PYSIDE-841] example: add systray example + - [PYSIDE-841] doc: add more videos from Qt events + - [PYSIDE-841] doc: add tutorial for using qrc files + - [PYSIDE-904] libpyside: Remove deprecated API + - [PYSIDE-904] Add support for template type aliases + - [PYSIDE-957] Add a tool to dump meta objects of QObject-derived classes + - [PYSIDE-1280] Enable injecting raw code for setattro/getattro + - [PYSIDE-1309] Rename and update some snippets + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-454] shiboken: Add a way of specifying system includes to be parsed + - [PYSIDE-454] shiboken: Handle smart pointers with const pointees + - [PYSIDE-904] libshiboken: Remove deprecated API + - [PYSIDE-957] shiboken: Fix refcounts of sbkenum + - [PYSIDE-990] shiboken: Handle inline namespaces + - [PYSIDE-1024] shiboken: Make it possible to specify smartpointer instantiations + - [PYSIDE-1074] shiboken: Fix classes in hidden namespaces + - [PYSIDE-1188] shiboken: Fix shared pointer return value in virtual function + - [PYSIDE-1265] shiboken: Introduce a separate logging category for documentation generation + - [PYSIDE-1265] shiboken: Change debug messages to use qCInfo and remove some messages + - [PYSIDE-1267] shiboken: Allow for parsing headers under system include paths + - [PYSIDE-1296] shiboken: Support non-type template parameters in functions + diff --git a/dist/changes-5.15.1 b/dist/changes-5.15.1 new file mode 100644 index 0000000..8627d3e --- /dev/null +++ b/dist/changes-5.15.1 @@ -0,0 +1,67 @@ +Qt for Python 5.15.1 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + + - [PYSIDE-74] Implement default __ne__ and __eq__ for all PySide types + - [PYSIDE-198] Add compatibility with Nuitka + - [PYSIDE-829] signature: Avoid non-existent attributes in compiled code (Nuitka) + - [PYSIDE-841] doc: Add widget styling tutorial + - [PYSIDE-841] add quick painteditem example + - [PYSIDE-904] Add QObject.findChildren(QRegularExpression) + - [PYSIDE-904] qp5_tool.py: Add an configuration key for the CMake generator + - [PYSIDE-904] Port some examples from QRegExp to QRegularExpression + - [PYSIDE-904] Fix libsample/photon test for Qt 6 / Windows + - [PYSIDE-904] Enable adding operators ==, != as functions without code injection + - [PYSIDE-957] Implement the QEnum/QFlag decorator, V2 + - [PYSIDE-981] Return QVariantList when using list as Signal argument + - [PYSIDE-1019] feature-select: Implement a selectable feature framework + - [PYSIDE-1019] feature-select: allow snake_case instead of camelCase for methods + - [PYSIDE-1019] feature-select: delay the feature switching + - [PYSIDE-1223] Use pyside2-uic instead of uic for the loadUiType + - [PYSIDE-1257] Potential fix for deploying with cx_freeze using zip_include_packages + - [PYSIDE-1282] pthreads: Try to abandon the GIL in case a thread was terminated + - [PYSIDE-1292] Doc: Enable doc builds using the offline template + - [PYSIDE-1313] basewrapper.cpp: add PyErr_Fetch/Restore in SbkDeallocWrapperCommon() + - [PYSIDE-1317] Add QSocketDescriptor class + - [PYSIDE-1321] Fix leaking reference in PySide2 property getter + - [PYSIDE-1321] Fix some leaks in enumeration creation + - [PYSIDE-1323] Add missing Win runtime dll into win wheels + - [PYSIDE-1323] Update vcredist binaries for MSVC 2019 + - [PYSIDE-1332] Fix crashes in QThread::wait(), QWaitCondition::wait() + - [PYSIDE-1349] QQmlComponent: allow thread in constructors + - [PYSIDE-1353] doc: fix Property indentation + - [PYSIDE-1355] Add Qt3DExtras.QNormalDiffuseMapAlphaMaterial + - [PYSIDE-1368] __feature__: ignore if `__name__` does not exist in a module + - [PYSIDE-1372] QDomElement: remove unnecesary setAttribute overloads + - [PYSIDE-1374] Add the QWidget *-based overloads of the QtWinExtras functions + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + * shiboken now accepts multiple headers on the command line. + * A number of error and warning messages have been prefixed by file name + and line for better tooling. + - [PYSIDE-841] Add custom widget shiboken example + - [PYSIDE-904] shiboken2: Handle virtual methods returning a reference + - [PYSIDE-1019] shiboken2: Re-add support for parsing Q_PROPERTY + - [PYSIDE-1177] shiboken: Fix __doc__ setter for derived types + - [PYSIDE-1325] shiboken: Fix default-initialized function arguments + - [PYSIDE-1327] shiboken: Resolve typedef'ed base classes + diff --git a/dist/changes-5.15.2 b/dist/changes-5.15.2 new file mode 100644 index 0000000..0baf774 --- /dev/null +++ b/dist/changes-5.15.2 @@ -0,0 +1,70 @@ +Qt for Python 5.15.2 is a bug-fix release. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qtforpython/ + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + + +**************************************************************************** +* Important Source Incompatible/Behavior Changes * +**************************************************************************** + +- Projects generating bindings for Qt-based code no longer need to include + pyside2_global.h for the property and signal/slot annotations to work. + +**************************************************************************** +* PySide2 * +**************************************************************************** + + + - [PYSIDE-487] Some missing enumerations and classes were added. + - [PYSIDE-644] QNetworkCookie was added to WebEngineCore. + - [PYSIDE-665] A crash when reimplementing QLayout.takeAt() was fixed. + - [PYSIDE-807] setup.py was rewritten to properly show options the in command + help. + - [PYSIDE-972] Launching PySide2 from paths with non-ASCII Latin1 characters + was fixed. + - [PYSIDE-1019] feature_select: Qt Properties are now represented as Python + properties. + - [PYSIDE-1070] A crash when overriding QUiLoader::createWidget() in QUiLoader + was fixed. + - [PYSIDE-1082] A crash when creating QMimeData from + Q(Plain)TextEdit::createMimeDataFromSelection() was fixed. + - [PYSIDE-1202] More classes from QtConcurrent were added. + - [PYSIDE-1224] The namespace QColorConstants was added. + - [PYSIDE-1326] Operators for QFlags on hidden top level namespace are now + generated. + - [PYSIDE-1354] Slots being invoked from the wrong thread were fixed. + - [PYSIDE-1381] The dependency of the QtQml module header on internal header + pysideqmlregistertype.h was removed. + - [PYSIDE-1385] Deprecated wheel.pep425tags imports were removed. + - [PYSIDE-1390] setup.py: The build_rst_docs command was added to build + rst documentation only + - [PYSIDE-1397] Functions taking a smart pointer now accept smart pointers to + base classes. + - [PYSIDE-1410] QAxBase::dynamicCall() was fixed. + +**************************************************************************** +* Shiboken2 * +**************************************************************************** + + - [PYSIDE-841] The documentation on modifications was restructured. + - [PYSIDE-904] An attribute for generating "using namespace" was added. + - [PYSIDE-1019] A way of specifying properties for non-Qt classes in + typesystem XML was added. + - [PYSIDE-1075] Functions from invisible namespaces are now generated into + their parent namespaces. + - [PYSIDE-1224] Variables in namespaces are now generated. + - [PYSIDE-1366] The order of overloads may now be specified to work around + problems with the order generated by the overload decisor. + - [PYSIDE-1388] Final classes with protected methods when disabling the + protected hack are now correctly generated. diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..69fa449 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/examples/3d/3d.pyproject b/examples/3d/3d.pyproject new file mode 100644 index 0000000..4c85ba5 --- /dev/null +++ b/examples/3d/3d.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["simple3d.py"] +} diff --git a/examples/3d/simple3d.py b/examples/3d/simple3d.py new file mode 100644 index 0000000..cea662a --- /dev/null +++ b/examples/3d/simple3d.py @@ -0,0 +1,162 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the qt3d/simple-cpp example from Qt v5.x""" + +import sys +from PySide2.QtCore import(Property, QObject, QPropertyAnimation, Signal) +from PySide2.QtGui import (QGuiApplication, QMatrix4x4, QQuaternion, QVector3D) +from PySide2.Qt3DCore import (Qt3DCore) +from PySide2.Qt3DExtras import (Qt3DExtras) + +class OrbitTransformController(QObject): + def __init__(self, parent): + super(OrbitTransformController, self).__init__(parent) + self._target = None + self._matrix = QMatrix4x4() + self._radius = 1 + self._angle = 0 + + def setTarget(self, t): + self._target = t + + def getTarget(self): + return self._target + + def setRadius(self, radius): + if self._radius != radius: + self._radius = radius + self.updateMatrix() + self.radiusChanged.emit() + + def getRadius(self): + return self._radius + + def setAngle(self, angle): + if self._angle != angle: + self._angle = angle + self.updateMatrix() + self.angleChanged.emit() + + def getAngle(self): + return self._angle + + def updateMatrix(self): + self._matrix.setToIdentity() + self._matrix.rotate(self._angle, QVector3D(0, 1, 0)) + self._matrix.translate(self._radius, 0, 0) + if self._target is not None: + self._target.setMatrix(self._matrix) + + angleChanged = Signal() + radiusChanged = Signal() + angle = Property(float, getAngle, setAngle, notify=angleChanged) + radius = Property(float, getRadius, setRadius, notify=radiusChanged) + +class Window(Qt3DExtras.Qt3DWindow): + def __init__(self): + super(Window, self).__init__() + + # Camera + self.camera().lens().setPerspectiveProjection(45, 16 / 9, 0.1, 1000) + self.camera().setPosition(QVector3D(0, 0, 40)) + self.camera().setViewCenter(QVector3D(0, 0, 0)) + + # For camera controls + self.createScene() + self.camController = Qt3DExtras.QOrbitCameraController(self.rootEntity) + self.camController.setLinearSpeed(50) + self.camController.setLookSpeed(180) + self.camController.setCamera(self.camera()) + + self.setRootEntity(self.rootEntity) + + def createScene(self): + # Root entity + self.rootEntity = Qt3DCore.QEntity() + + # Material + self.material = Qt3DExtras.QPhongMaterial(self.rootEntity) + + # Torus + self.torusEntity = Qt3DCore.QEntity(self.rootEntity) + self.torusMesh = Qt3DExtras.QTorusMesh() + self.torusMesh.setRadius(5) + self.torusMesh.setMinorRadius(1) + self.torusMesh.setRings(100) + self.torusMesh.setSlices(20) + + self.torusTransform = Qt3DCore.QTransform() + self.torusTransform.setScale3D(QVector3D(1.5, 1, 0.5)) + self.torusTransform.setRotation(QQuaternion.fromAxisAndAngle(QVector3D(1, 0, 0), 45)) + + self.torusEntity.addComponent(self.torusMesh) + self.torusEntity.addComponent(self.torusTransform) + self.torusEntity.addComponent(self.material) + + # Sphere + self.sphereEntity = Qt3DCore.QEntity(self.rootEntity) + self.sphereMesh = Qt3DExtras.QSphereMesh() + self.sphereMesh.setRadius(3) + + self.sphereTransform = Qt3DCore.QTransform() + self.controller = OrbitTransformController(self.sphereTransform) + self.controller.setTarget(self.sphereTransform) + self.controller.setRadius(20) + + self.sphereRotateTransformAnimation = QPropertyAnimation(self.sphereTransform) + self.sphereRotateTransformAnimation.setTargetObject(self.controller) + self.sphereRotateTransformAnimation.setPropertyName(b"angle") + self.sphereRotateTransformAnimation.setStartValue(0) + self.sphereRotateTransformAnimation.setEndValue(360) + self.sphereRotateTransformAnimation.setDuration(10000) + self.sphereRotateTransformAnimation.setLoopCount(-1) + self.sphereRotateTransformAnimation.start() + + self.sphereEntity.addComponent(self.sphereMesh) + self.sphereEntity.addComponent(self.sphereTransform) + self.sphereEntity.addComponent(self.material) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = Window() + view.show() + sys.exit(app.exec_()) diff --git a/examples/axcontainer/axcontainer.pyproject b/examples/axcontainer/axcontainer.pyproject new file mode 100644 index 0000000..b054d6f --- /dev/null +++ b/examples/axcontainer/axcontainer.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["axviewer.py"] +} diff --git a/examples/axcontainer/axviewer.py b/examples/axcontainer/axviewer.py new file mode 100644 index 0000000..e9083d8 --- /dev/null +++ b/examples/axcontainer/axviewer.py @@ -0,0 +1,82 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 Active Qt Viewer example""" + +import sys +from PySide2.QtAxContainer import QAxSelect, QAxWidget +from PySide2.QtWidgets import (QAction, QApplication, QDialog, + QMainWindow, QMessageBox, QToolBar) + +class MainWindow(QMainWindow): + + def __init__(self): + super(MainWindow, self).__init__() + + toolBar = QToolBar() + self.addToolBar(toolBar) + fileMenu = self.menuBar().addMenu("&File") + loadAction = QAction("Load...", self, shortcut="Ctrl+L", triggered=self.load) + fileMenu.addAction(loadAction) + toolBar.addAction(loadAction) + exitAction = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=self.close) + fileMenu.addAction(exitAction) + + aboutMenu = self.menuBar().addMenu("&About") + aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt) + aboutMenu.addAction(aboutQtAct) + self.axWidget = QAxWidget() + self.setCentralWidget(self.axWidget) + + def load(self): + axSelect = QAxSelect(self) + if axSelect.exec_() == QDialog.Accepted: + clsid = axSelect.clsid() + if not self.axWidget.setControl(clsid): + QMessageBox.warning(self, "AxViewer", "Unable to load " + clsid + ".") + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + availableGeometry = app.desktop().availableGeometry(mainWin) + mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/charts/audio.py b/examples/charts/audio.py new file mode 100644 index 0000000..f899ac4 --- /dev/null +++ b/examples/charts/audio.py @@ -0,0 +1,126 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the charts/audio example from Qt v5.x""" + +import sys +from PySide2.QtCharts import QtCharts +from PySide2.QtCore import QPointF +from PySide2.QtMultimedia import (QAudioDeviceInfo, QAudioFormat, + QAudioInput) +from PySide2.QtWidgets import QApplication, QMainWindow, QMessageBox + +sampleCount = 2000 +resolution = 4 + +class MainWindow(QMainWindow): + def __init__(self, device): + super(MainWindow, self).__init__() + + self.series = QtCharts.QLineSeries() + self.chart = QtCharts.QChart() + self.chart.addSeries(self.series) + self.axisX = QtCharts.QValueAxis() + self.axisX.setRange(0, sampleCount) + self.axisX.setLabelFormat("%g") + self.axisX.setTitleText("Samples") + self.axisY = QtCharts.QValueAxis() + self.axisY.setRange(-1, 1) + self.axisY.setTitleText("Audio level") + self.chart.setAxisX(self.axisX, self.series) + self.chart.setAxisY(self.axisY, self.series) + self.chart.legend().hide() + self.chart.setTitle("Data from the microphone ({})".format(device.deviceName())) + + formatAudio = QAudioFormat() + formatAudio.setSampleRate(8000) + formatAudio.setChannelCount(1) + formatAudio.setSampleSize(8) + formatAudio.setCodec("audio/pcm") + formatAudio.setByteOrder(QAudioFormat.LittleEndian) + formatAudio.setSampleType(QAudioFormat.UnSignedInt) + + self.audioInput = QAudioInput(device, formatAudio, self) + self.ioDevice = self.audioInput.start() + self.ioDevice.readyRead.connect(self._readyRead) + + self.chartView = QtCharts.QChartView(self.chart) + self.setCentralWidget(self.chartView) + + self.buffer = [QPointF(x, 0) for x in range(sampleCount)] + self.series.append(self.buffer) + + def closeEvent(self, event): + if self.audioInput is not None: + self.audioInput.stop() + event.accept() + + def _readyRead(self): + data = self.ioDevice.readAll() + availableSamples = data.size() // resolution + start = 0 + if (availableSamples < sampleCount): + start = sampleCount - availableSamples + for s in range(start): + self.buffer[s].setY(self.buffer[s + availableSamples].y()) + + dataIndex = 0 + for s in range(start, sampleCount): + value = (ord(data[dataIndex]) - 128) / 128 + self.buffer[s].setY(value) + dataIndex = dataIndex + resolution + self.series.replace(self.buffer) + +if __name__ == '__main__': + app = QApplication(sys.argv) + + inputDevice = QAudioDeviceInfo.defaultInputDevice() + if (inputDevice.isNull()): + QMessageBox.warning(None, "audio", "There is no audio input device available.") + sys.exit(-1) + + mainWin = MainWindow(inputDevice) + mainWin.setWindowTitle("audio") + availableGeometry = app.desktop().availableGeometry(mainWin) + size = availableGeometry.height() * 3 / 4 + mainWin.resize(size, size) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/charts/callout.py b/examples/charts/callout.py new file mode 100644 index 0000000..54e8eaf --- /dev/null +++ b/examples/charts/callout.py @@ -0,0 +1,257 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Callout example from Qt v5.x""" + +import sys +from PySide2.QtWidgets import (QApplication, QGraphicsScene, + QGraphicsView, QGraphicsSimpleTextItem, QGraphicsItem) +from PySide2.QtCore import Qt, QPointF, QRectF, QRect +from PySide2.QtCharts import QtCharts +from PySide2.QtGui import QPainter, QFont, QFontMetrics, QPainterPath, QColor + + +class Callout(QGraphicsItem): + + def __init__(self, chart): + QGraphicsItem.__init__(self, chart) + self._chart = chart + self._text = "" + self._textRect = QRectF() + self._anchor = QPointF() + self._font = QFont() + self._rect = QRectF() + + def boundingRect(self): + anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) + rect = QRectF() + rect.setLeft(min(self._rect.left(), anchor.x())) + rect.setRight(max(self._rect.right(), anchor.x())) + rect.setTop(min(self._rect.top(), anchor.y())) + rect.setBottom(max(self._rect.bottom(), anchor.y())) + + return rect + + def paint(self, painter, option, widget): + path = QPainterPath() + path.addRoundedRect(self._rect, 5, 5) + anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor)) + if not self._rect.contains(anchor) and not self._anchor.isNull(): + point1 = QPointF() + point2 = QPointF() + + # establish the position of the anchor point in relation to _rect + above = anchor.y() <= self._rect.top() + aboveCenter = (anchor.y() > self._rect.top() and + anchor.y() <= self._rect.center().y()) + belowCenter = (anchor.y() > self._rect.center().y() and + anchor.y() <= self._rect.bottom()) + below = anchor.y() > self._rect.bottom() + + onLeft = anchor.x() <= self._rect.left() + leftOfCenter = (anchor.x() > self._rect.left() and + anchor.x() <= self._rect.center().x()) + rightOfCenter = (anchor.x() > self._rect.center().x() and + anchor.x() <= self._rect.right()) + onRight = anchor.x() > self._rect.right() + + # get the nearest _rect corner. + x = (onRight + rightOfCenter) * self._rect.width() + y = (below + belowCenter) * self._rect.height() + cornerCase = ((above and onLeft) or (above and onRight) or + (below and onLeft) or (below and onRight)) + vertical = abs(anchor.x() - x) > abs(anchor.y() - y) + + x1 = (x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * + int(not vertical) * (onLeft * 10 - onRight * 20)) + y1 = (y + aboveCenter * 10 - belowCenter * 20 + cornerCase * + vertical * (above * 10 - below * 20)) + point1.setX(x1) + point1.setY(y1) + + x2 = (x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * + int(not vertical) * (onLeft * 20 - onRight * 10)) + y2 = (y + aboveCenter * 20 - belowCenter * 10 + cornerCase * + vertical * (above * 20 - below * 10)) + point2.setX(x2) + point2.setY(y2) + + path.moveTo(point1) + path.lineTo(anchor) + path.lineTo(point2) + path = path.simplified() + + painter.setBrush(QColor(255, 255, 255)) + painter.drawPath(path) + painter.drawText(self._textRect, self._text) + + def mousePressEvent(self, event): + event.setAccepted(True) + + def mouseMoveEvent(self, event): + if event.buttons() & Qt.LeftButton: + self.setPos(mapToParent( + event.pos() - event.buttonDownPos(Qt.LeftButton))) + event.setAccepted(True) + else: + event.setAccepted(False) + + def setText(self, text): + self._text = text + metrics = QFontMetrics(self._font) + self._textRect = QRectF(metrics.boundingRect( + QRect(0.0, 0.0, 150.0, 150.0),Qt.AlignLeft, self._text)) + self._textRect.translate(5, 5) + self.prepareGeometryChange() + self._rect = self._textRect.adjusted(-5, -5, 5, 5) + + def setAnchor(self, point): + self._anchor = QPointF(point) + + def updateGeometry(self): + self.prepareGeometryChange() + self.setPos(self._chart.mapToPosition( + self._anchor) + QPointF(10, -50)) + + +class View(QGraphicsView): + def __init__(self, parent = None): + super(View, self).__init__(parent) + self.setScene(QGraphicsScene(self)) + + self.setDragMode(QGraphicsView.NoDrag) + self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + + # Chart + self._chart = QtCharts.QChart() + self._chart.setMinimumSize(640, 480) + self._chart.setTitle("Hover the line to show callout. Click the line " + "to make it stay") + self._chart.legend().hide() + self.series = QtCharts.QLineSeries() + self.series.append(1, 3) + self.series.append(4, 5) + self.series.append(5, 4.5) + self.series.append(7, 1) + self.series.append(11, 2) + self._chart.addSeries(self.series) + + self.series2 = QtCharts.QSplineSeries() + self.series2.append(1.6, 1.4) + self.series2.append(2.4, 3.5) + self.series2.append(3.7, 2.5) + self.series2.append(7, 4) + self.series2.append(10, 2) + self._chart.addSeries(self.series2) + + self._chart.createDefaultAxes() + self._chart.setAcceptHoverEvents(True) + + self.setRenderHint(QPainter.Antialiasing) + self.scene().addItem(self._chart) + + self._coordX = QGraphicsSimpleTextItem(self._chart) + self._coordX.setPos( + self._chart.size().width()/2 - 50, self._chart.size().height()) + self._coordX.setText("X: ") + self._coordY = QGraphicsSimpleTextItem(self._chart) + self._coordY.setPos( + self._chart.size().width()/2 + 50, self._chart.size().height()) + self._coordY.setText("Y: ") + + self._callouts = [] + self._tooltip = Callout(self._chart) + + self.series.clicked.connect(self.keepCallout) + self.series.hovered.connect(self.tooltip) + + self.series2.clicked.connect(self.keepCallout) + self.series2.hovered.connect(self.tooltip) + + self.setMouseTracking(True) + + def resizeEvent(self, event): + if self.scene(): + self.scene().setSceneRect(QRectF(QPointF(0, 0), event.size())) + self._chart.resize(event.size()) + self._coordX.setPos( + self._chart.size().width()/2 - 50, + self._chart.size().height() - 20) + self._coordY.setPos( + self._chart.size().width()/2 + 50, + self._chart.size().height() - 20) + for callout in self._callouts: + callout.updateGeometry() + QGraphicsView.resizeEvent(self, event) + + + def mouseMoveEvent(self, event): + self._coordX.setText("X: {0:.2f}" + .format(self._chart.mapToValue(event.pos()).x())) + self._coordY.setText("Y: {0:.2f}" + .format(self._chart.mapToValue(event.pos()).y())) + QGraphicsView.mouseMoveEvent(self, event) + + def keepCallout(self): + self._callouts.append(self._tooltip) + self._tooltip = Callout(self._chart) + + def tooltip(self, point, state): + if self._tooltip == 0: + self._tooltip = Callout(self._chart) + + if state: + self._tooltip.setText("X: {0:.2f} \nY: {1:.2f} " + .format(point.x(),point.y())) + self._tooltip.setAnchor(point) + self._tooltip.setZValue(11) + self._tooltip.updateGeometry() + self._tooltip.show() + else: + self._tooltip.hide() + + +if __name__ == "__main__": + app = QApplication(sys.argv) + v = View() + v.show() + sys.exit(app.exec_()) diff --git a/examples/charts/charts.pyproject b/examples/charts/charts.pyproject new file mode 100644 index 0000000..15a48a3 --- /dev/null +++ b/examples/charts/charts.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["percentbarchart.py", "donutbreakdown.py", "legend.py", "nesteddonuts.py", + "modeldata.py", "lineandbar.py", "memoryusage.py", "callout.py", "audio.py", + "linechart.py", "logvalueaxis.py", "piechart.py", "temperaturerecords.py"] +} diff --git a/examples/charts/chartthemes/README.md b/examples/charts/chartthemes/README.md new file mode 100644 index 0000000..e11fa93 --- /dev/null +++ b/examples/charts/chartthemes/README.md @@ -0,0 +1,9 @@ +# Chart themes + +To generated the file `ui_themewidget.py`, the following +command need to be executed: + +`pyside2-uic themewidget.ui > ui_themewidget.py` + +Also, if you modify the UI file, then you would need +to run the previous command again. diff --git a/examples/charts/chartthemes/chartthemes.pyproject b/examples/charts/chartthemes/chartthemes.pyproject new file mode 100644 index 0000000..4a0b387 --- /dev/null +++ b/examples/charts/chartthemes/chartthemes.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "README.md", "themewidget.ui"] +} diff --git a/examples/charts/chartthemes/main.py b/examples/charts/chartthemes/main.py new file mode 100644 index 0000000..e18e92c --- /dev/null +++ b/examples/charts/chartthemes/main.py @@ -0,0 +1,396 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Chart Themes example from Qt v5.x""" + +import sys +from PySide2.QtCore import QPointF, Qt +from PySide2.QtGui import QColor, QPainter, QPalette +from PySide2.QtWidgets import (QApplication, QMainWindow, QSizePolicy, + QWidget) +from PySide2.QtCharts import QtCharts + +from ui_themewidget import Ui_ThemeWidgetForm as ui + +from random import random, uniform + +class ThemeWidget(QWidget): + def __init__(self, parent): + QWidget.__init__(self, parent) + self.charts = [] + + self.ui = ui() + self.list_count = 3 + self.value_max = 10 + self.value_count = 7 + self.data_table = self.generate_random_data(self.list_count, + self.value_max, self.value_count) + + self.ui.setupUi(self) + self.populate_themebox() + self.populate_animationbox() + self.populate_legendbox() + + # Area Chart + chart_view = QtCharts.QChartView(self.create_areachart()) + self.ui.gridLayout.addWidget(chart_view, 1, 0) + self.charts.append(chart_view) + + # Pie Chart + chart_view = QtCharts.QChartView(self.createPieChart()) + chart_view.setSizePolicy(QSizePolicy.Ignored, + QSizePolicy.Ignored) + self.ui.gridLayout.addWidget(chart_view, 1, 1) + self.charts.append(chart_view) + + # Line Chart + chart_view = QtCharts.QChartView(self.createLineChart()) + self.ui.gridLayout.addWidget(chart_view, 1, 2) + self.charts.append(chart_view) + + # Bar Chart + chart_view = QtCharts.QChartView(self.createBarChart()) + self.ui.gridLayout.addWidget(chart_view, 2, 0) + self.charts.append(chart_view) + + # Spline Chart + chart_view = QtCharts.QChartView(self.createSplineChart()) + self.ui.gridLayout.addWidget(chart_view, 2, 1) + self.charts.append(chart_view) + + # Scatter Chart + chart_view = QtCharts.QChartView(self.create_scatterchart()) + self.ui.gridLayout.addWidget(chart_view, 2, 2) + self.charts.append(chart_view) + + # Set defaults + self.ui.antialiasCheckBox.setChecked(True) + + # Set the colors from the light theme as default ones + pal = qApp.palette() + pal.setColor(QPalette.Window, QColor(0xf0f0f0)) + pal.setColor(QPalette.WindowText, QColor(0x404044)) + qApp.setPalette(pal) + + self.updateUI() + + + def generate_random_data(self, list_count, value_max, value_count): + data_table = [] + for i in range(list_count): + data_list = [] + y_value = 0 + for j in range(value_count): + constant = value_max / float(value_count) + y_value += uniform(0, constant) + x_value = (j + random()) * constant + value = QPointF(x_value, y_value) + label = "Slice {}: {}".format(i, j) + data_list.append((value, label)) + data_table.append(data_list) + + return data_table + + def populate_themebox(self): + theme = self.ui.themeComboBox + + theme.addItem("Light", QtCharts.QChart.ChartThemeLight) + theme.addItem("Blue Cerulean", QtCharts.QChart.ChartThemeBlueCerulean) + theme.addItem("Dark", QtCharts.QChart.ChartThemeDark) + theme.addItem("Brown Sand", QtCharts.QChart.ChartThemeBrownSand) + theme.addItem("Blue NCS", QtCharts.QChart.ChartThemeBlueNcs) + theme.addItem("High Contrast", QtCharts.QChart.ChartThemeHighContrast) + theme.addItem("Blue Icy", QtCharts.QChart.ChartThemeBlueIcy) + theme.addItem("Qt", QtCharts.QChart.ChartThemeQt) + + def populate_animationbox(self): + animated = self.ui.animatedComboBox + + animated.addItem("No Animations", QtCharts.QChart.NoAnimation) + animated.addItem("GridAxis Animations", QtCharts.QChart.GridAxisAnimations) + animated.addItem("Series Animations", QtCharts.QChart.SeriesAnimations) + animated.addItem("All Animations", QtCharts.QChart.AllAnimations) + + def populate_legendbox(self): + legend = self.ui.legendComboBox + + legend.addItem("No Legend ", 0) + legend.addItem("Legend Top", Qt.AlignTop) + legend.addItem("Legend Bottom", Qt.AlignBottom) + legend.addItem("Legend Left", Qt.AlignLeft) + legend.addItem("Legend Right", Qt.AlignRight) + + def create_areachart(self): + chart = QtCharts.QChart() + chart.setTitle("Area Chart") + + # The lower series initialized to zero values + lower_series = None + name = "Series " + for i in range(len(self.data_table)): + upper_series = QtCharts.QLineSeries(chart) + for j in range(len(self.data_table[i])): + data = self.data_table[i][j] + if lower_series: + points = lower_series.pointsVector() + y_value = points[i].y() + data[0].y() + upper_series.append(QPointF(j, y_value)) + else: + upper_series.append(QPointF(j, data[0].y())) + area = QtCharts.QAreaSeries(upper_series, lower_series) + area.setName("{}{}".format(name, i)) + chart.addSeries(area) + lower_series = upper_series + + chart.createDefaultAxes() + chart.axisX().setRange(0, self.value_count - 1) + chart.axisY().setRange(0, self.value_max) + # Add space to label to add space between labels and axis + chart.axisY().setLabelFormat("%.1f ") + + return chart + + def createBarChart(self): + chart = QtCharts.QChart() + chart.setTitle("Bar chart") + + series = QtCharts.QStackedBarSeries(chart) + for i in range(len(self.data_table)): + barset = QtCharts.QBarSet("Bar set {}".format(i)) + for data in self.data_table[i]: + barset.append(data[0].y()) + series.append(barset) + + chart.addSeries(series) + + chart.createDefaultAxes() + chart.axisY().setRange(0, self.value_max * 2) + # Add space to label to add space between labels and axis + chart.axisY().setLabelFormat("%.1f ") + + return chart + + def createLineChart(self): + chart = QtCharts.QChart() + chart.setTitle("Line chart") + + name = "Series " + for i, lst in enumerate(self.data_table): + series = QtCharts.QLineSeries(chart) + for data in lst: + series.append(data[0]) + series.setName("{}{}".format(name, i)) + chart.addSeries(series) + + chart.createDefaultAxes() + chart.axisX().setRange(0, self.value_max) + chart.axisY().setRange(0, self.value_count) + # Add space to label to add space between labels and axis + chart.axisY().setLabelFormat("%.1f ") + + return chart + + def createPieChart(self): + chart = QtCharts.QChart() + chart.setTitle("Pie chart") + + series = QtCharts.QPieSeries(chart) + for data in self.data_table[0]: + slc = series.append(data[1], data[0].y()) + if data == self.data_table[0][0]: + # Show the first slice exploded with label + slc.setLabelVisible() + slc.setExploded() + slc.setExplodeDistanceFactor(0.5) + + series.setPieSize(0.4) + chart.addSeries(series) + + return chart + + def createSplineChart(self): + chart = QtCharts.QChart() + chart.setTitle("Spline chart") + name = "Series " + for i, lst in enumerate(self.data_table): + series = QtCharts.QSplineSeries(chart) + for data in lst: + series.append(data[0]) + series.setName("{}{}".format(name, i)) + chart.addSeries(series) + + chart.createDefaultAxes() + chart.axisX().setRange(0, self.value_max) + chart.axisY().setRange(0, self.value_count) + # Add space to label to add space between labels and axis + chart.axisY().setLabelFormat("%.1f ") + + return chart + + def create_scatterchart(self): + chart = QtCharts.QChart() + chart.setTitle("Scatter chart") + name = "Series " + for i, lst in enumerate(self.data_table): + series = QtCharts.QScatterSeries(chart) + for data in lst: + series.append(data[0]) + series.setName("{}{}".format(name, i)) + chart.addSeries(series) + + chart.createDefaultAxes() + chart.axisX().setRange(0, self.value_max) + chart.axisY().setRange(0, self.value_count) + # Add space to label to add space between labels and axis + chart.axisY().setLabelFormat("%.1f ") + + return chart + + def updateUI(self): + def set_colors(window_color, text_color): + pal = self.window().palette() + pal.setColor(QPalette.Window, window_color) + pal.setColor(QPalette.WindowText, text_color) + self.window().setPalette(pal) + + idx = self.ui.themeComboBox.currentIndex() + theme = self.ui.themeComboBox.itemData(idx) + + if len(self.charts): + chart_theme = self.charts[0].chart().theme() + if chart_theme != theme: + for chart_view in self.charts: + if theme == 0: + theme_name = QtCharts.QChart.ChartThemeLight + elif theme == 1: + theme_name = QtCharts.QChart.ChartThemeBlueCerulean + elif theme == 2: + theme_name = QtCharts.QChart.ChartThemeDark + elif theme == 3: + theme_name = QtCharts.QChart.ChartThemeBrownSand + elif theme == 4: + theme_name = QtCharts.QChart.ChartThemeBlueNcs + elif theme == 5: + theme_name = QtCharts.QChart.ChartThemeHighContrast + elif theme == 6: + theme_name = QtCharts.QChart.ChartThemeBlueIcy + elif theme == 7: + theme_name = QtCharts.QChart.ChartThemeQt + else: + theme_name = QtCharts.QChart.ChartThemeLight + + chart_view.chart().setTheme(theme_name) + + # Set palette colors based on selected theme + if theme == QtCharts.QChart.ChartThemeLight: + set_colors(QColor(0xf0f0f0), QColor(0x404044)) + elif theme == QtCharts.QChart.ChartThemeDark: + set_colors(QColor(0x121218), QColor(0xd6d6d6)) + elif theme == QtCharts.QChart.ChartThemeBlueCerulean: + set_colors(QColor(0x40434a), QColor(0xd6d6d6)) + elif theme == QtCharts.QChart.ChartThemeBrownSand: + set_colors(QColor(0x9e8965), QColor(0x404044)) + elif theme == QtCharts.QChart.ChartThemeBlueNcs: + set_colors(QColor(0x018bba), QColor(0x404044)) + elif theme == QtCharts.QChart.ChartThemeHighContrast: + set_colors(QColor(0xffab03), QColor(0x181818)) + elif theme == QtCharts.QChart.ChartThemeBlueIcy: + set_colors(QColor(0xcee7f0), QColor(0x404044)) + else: + set_colors(QColor(0xf0f0f0), QColor(0x404044)) + + + # Update antialiasing + checked = self.ui.antialiasCheckBox.isChecked() + for chart in self.charts: + chart.setRenderHint(QPainter.Antialiasing, checked) + + # Update animation options + idx = self.ui.animatedComboBox.currentIndex() + options = self.ui.animatedComboBox.itemData(idx) + + if len(self.charts): + chart = self.charts[0].chart() + animation_options = chart.animationOptions() + if animation_options != options: + for chart_view in self.charts: + options_name = QtCharts.QChart.NoAnimation + if options == 0: + options_name = QtCharts.QChart.NoAnimation + elif options == 1: + options_name = QtCharts.QChart.GridAxisAnimations + elif options == 2: + options_name = QtCharts.QChart.SeriesAnimations + elif options == 3: + options_name = QtCharts.QChart.AllAnimations + chart_view.chart().setAnimationOptions(options_name) + + # Update legend alignment + idx = self.ui.legendComboBox.currentIndex() + alignment = self.ui.legendComboBox.itemData(idx) + + if not alignment: + for chart_view in self.charts: + chart_view.chart().legend().hide() + else: + for chart_view in self.charts: + alignment_name = Qt.AlignTop + if alignment == 32: + alignment_name = Qt.AlignTop + elif alignment == 64: + alignment_name = Qt.AlignBottom + elif alignment == 1: + alignment_name = Qt.AlignLeft + elif alignment == 2: + alignment_name = Qt.AlignRight + chart_view.chart().legend().setAlignment(alignment_name) + chart_view.chart().legend().show() + + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = QMainWindow() + widget = ThemeWidget(None) + window.setCentralWidget(widget) + available_geometry = app.desktop().availableGeometry(window) + size = available_geometry.height() * 0.75 + window.setFixedSize(size, size * 0.8) + window.show() + sys.exit(app.exec_()) diff --git a/examples/charts/chartthemes/themewidget.ui b/examples/charts/chartthemes/themewidget.ui new file mode 100644 index 0000000..9ea2bb7 --- /dev/null +++ b/examples/charts/chartthemes/themewidget.ui @@ -0,0 +1,103 @@ + + + ThemeWidgetForm + + + + 0 + 0 + 900 + 600 + + + + + + + + + Theme: + + + + + + + + + + Animation: + + + + + + + + + + Legend: + + + + + + + + + + Anti-aliasing + + + false + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + themeComboBox + currentIndexChanged(int) + ThemeWidgetForm + updateUI() + + + antialiasCheckBox + toggled(bool) + ThemeWidgetForm + updateUI() + + + legendComboBox + currentIndexChanged(int) + ThemeWidgetForm + updateUI() + + + animatedComboBox + currentIndexChanged(int) + ThemeWidgetForm + updateUI() + + + + updateUI() + + diff --git a/examples/charts/chartthemes/ui_themewidget.py b/examples/charts/chartthemes/ui_themewidget.py new file mode 100644 index 0000000..bf67039 --- /dev/null +++ b/examples/charts/chartthemes/ui_themewidget.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'themewidget.ui' +## +## Created by: Qt User Interface Compiler version 5.14.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint, + QRect, QSize, QUrl, Qt) +from PySide2.QtGui import (QColor, QFont, QIcon, QPixmap) +from PySide2.QtWidgets import * + +class Ui_ThemeWidgetForm(object): + def setupUi(self, ThemeWidgetForm): + if ThemeWidgetForm.objectName(): + ThemeWidgetForm.setObjectName(u"ThemeWidgetForm") + ThemeWidgetForm.resize(900, 600) + self.gridLayout = QGridLayout(ThemeWidgetForm) + self.gridLayout.setObjectName(u"gridLayout") + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.themeLabel = QLabel(ThemeWidgetForm) + self.themeLabel.setObjectName(u"themeLabel") + + self.horizontalLayout.addWidget(self.themeLabel) + + self.themeComboBox = QComboBox(ThemeWidgetForm) + self.themeComboBox.setObjectName(u"themeComboBox") + + self.horizontalLayout.addWidget(self.themeComboBox) + + self.animatedLabel = QLabel(ThemeWidgetForm) + self.animatedLabel.setObjectName(u"animatedLabel") + + self.horizontalLayout.addWidget(self.animatedLabel) + + self.animatedComboBox = QComboBox(ThemeWidgetForm) + self.animatedComboBox.setObjectName(u"animatedComboBox") + + self.horizontalLayout.addWidget(self.animatedComboBox) + + self.legendLabel = QLabel(ThemeWidgetForm) + self.legendLabel.setObjectName(u"legendLabel") + + self.horizontalLayout.addWidget(self.legendLabel) + + self.legendComboBox = QComboBox(ThemeWidgetForm) + self.legendComboBox.setObjectName(u"legendComboBox") + + self.horizontalLayout.addWidget(self.legendComboBox) + + self.antialiasCheckBox = QCheckBox(ThemeWidgetForm) + self.antialiasCheckBox.setObjectName(u"antialiasCheckBox") + self.antialiasCheckBox.setChecked(False) + + self.horizontalLayout.addWidget(self.antialiasCheckBox) + + self.horizontalSpacer = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum) + + self.horizontalLayout.addItem(self.horizontalSpacer) + + + self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 3) + + + self.retranslateUi(ThemeWidgetForm) + self.themeComboBox.currentIndexChanged.connect(ThemeWidgetForm.updateUI) + self.antialiasCheckBox.toggled.connect(ThemeWidgetForm.updateUI) + self.legendComboBox.currentIndexChanged.connect(ThemeWidgetForm.updateUI) + self.animatedComboBox.currentIndexChanged.connect(ThemeWidgetForm.updateUI) + + QMetaObject.connectSlotsByName(ThemeWidgetForm) + # setupUi + + def retranslateUi(self, ThemeWidgetForm): + self.themeLabel.setText(QCoreApplication.translate("ThemeWidgetForm", u"Theme:", None)) + self.animatedLabel.setText(QCoreApplication.translate("ThemeWidgetForm", u"Animation:", None)) + self.legendLabel.setText(QCoreApplication.translate("ThemeWidgetForm", u"Legend:", None)) + self.antialiasCheckBox.setText(QCoreApplication.translate("ThemeWidgetForm", u"Anti-aliasing", None)) + # retranslateUi + diff --git a/examples/charts/donutbreakdown.py b/examples/charts/donutbreakdown.py new file mode 100644 index 0000000..712bea5 --- /dev/null +++ b/examples/charts/donutbreakdown.py @@ -0,0 +1,181 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Donut Chart Breakdown example from Qt v5.x""" + + +import sys +from PySide2.QtCore import Qt +from PySide2.QtGui import QColor, QFont, QPainter +from PySide2.QtWidgets import QApplication, QMainWindow +from PySide2.QtCharts import QtCharts + +class MainSlice(QtCharts.QPieSlice): + def __init__(self, breakdown_series, parent=None): + super(MainSlice, self).__init__(parent) + + self.breakdown_series = breakdown_series + self.name = None + + self.percentageChanged.connect(self.update_label) + + def get_breakdown_series(self): + return self.breakdown_series + + def setName(self, name): + self.name = name + + def name(self): + return self.name + + def update_label(self): + self.setLabel("{} {:.2f}%".format(self.name, + self.percentage() * 100)) + + +class DonutBreakdownChart(QtCharts.QChart): + def __init__(self, parent=None): + super(DonutBreakdownChart, self).__init__(QtCharts.QChart.ChartTypeCartesian, parent, Qt.WindowFlags()) + self.main_series = QtCharts.QPieSeries() + self.main_series.setPieSize(0.7) + self.addSeries(self.main_series) + + def add_breakdown_series(self, breakdown_series, color): + font = QFont("Arial", 8) + + # add breakdown series as a slice to center pie + main_slice = MainSlice(breakdown_series) + main_slice.setName(breakdown_series.name()) + main_slice.setValue(breakdown_series.sum()) + self.main_series.append(main_slice) + + # customize the slice + main_slice.setBrush(color) + main_slice.setLabelVisible() + main_slice.setLabelColor(Qt.white) + main_slice.setLabelPosition(QtCharts.QPieSlice.LabelInsideHorizontal) + main_slice.setLabelFont(font) + + # position and customize the breakdown series + breakdown_series.setPieSize(0.8) + breakdown_series.setHoleSize(0.7) + breakdown_series.setLabelsVisible() + + for pie_slice in breakdown_series.slices(): + color = QColor(color).lighter(115) + pie_slice.setBrush(color) + pie_slice.setLabelFont(font) + + # add the series to the chart + self.addSeries(breakdown_series) + + # recalculate breakdown donut segments + self.recalculate_angles() + + # update customize legend markers + self.update_legend_markers() + + def recalculate_angles(self): + angle = 0 + slices = self.main_series.slices() + for pie_slice in slices: + breakdown_series = pie_slice.get_breakdown_series() + breakdown_series.setPieStartAngle(angle) + angle += pie_slice.percentage() * 360.0 # full pie is 360.0 + breakdown_series.setPieEndAngle(angle) + + def update_legend_markers(self): + # go through all markers + for series in self.series(): + markers = self.legend().markers(series) + for marker in markers: + if series == self.main_series: + # hide markers from main series + marker.setVisible(False) + else: + # modify markers from breakdown series + marker.setLabel("{} {:.2f}%".format( + marker.slice().label(), + marker.slice().percentage() * 100, 0)) + marker.setFont(QFont("Arial", 8)) + +if __name__ == "__main__": + app = QApplication(sys.argv) + # Graph is based on data of: + # 'Total consumption of energy increased by 10 per cent in 2010' + # Statistics Finland, 13 December 2011 + # http://www.stat.fi/til/ekul/2010/ekul_2010_2011-12-13_tie_001_en.html + series1 = QtCharts.QPieSeries() + series1.setName("Fossil fuels") + series1.append("Oil", 353295) + series1.append("Coal", 188500) + series1.append("Natural gas", 148680) + series1.append("Peat", 94545) + + series2 = QtCharts.QPieSeries() + series2.setName("Renewables") + series2.append("Wood fuels", 319663) + series2.append("Hydro power", 45875) + series2.append("Wind power", 1060) + + series3 = QtCharts.QPieSeries() + series3.setName("Others") + series3.append("Nuclear energy", 238789) + series3.append("Import energy", 37802) + series3.append("Other", 32441) + + donut_breakdown = DonutBreakdownChart() + donut_breakdown.setAnimationOptions(QtCharts.QChart.AllAnimations) + donut_breakdown.setTitle("Total consumption of energy in Finland 2010") + donut_breakdown.legend().setAlignment(Qt.AlignRight) + donut_breakdown.add_breakdown_series(series1, Qt.red) + donut_breakdown.add_breakdown_series(series2, Qt.darkGreen) + donut_breakdown.add_breakdown_series(series3, Qt.darkBlue) + + window = QMainWindow() + chart_view = QtCharts.QChartView(donut_breakdown) + chart_view.setRenderHint(QPainter.Antialiasing) + window.setCentralWidget(chart_view) + available_geometry = app.desktop().availableGeometry(window) + size = available_geometry.height() * 0.75 + window.resize(size, size * 0.8) + window.show() + + sys.exit(app.exec_()) diff --git a/examples/charts/legend.py b/examples/charts/legend.py new file mode 100644 index 0000000..47099e7 --- /dev/null +++ b/examples/charts/legend.py @@ -0,0 +1,252 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Legend example from Qt v5.x""" + +import sys +from PySide2.QtCore import Qt, QRectF +from PySide2.QtGui import QBrush, QColor, QPainter, QPen +from PySide2.QtWidgets import (QApplication, QDoubleSpinBox, + QFormLayout, QGridLayout, QGroupBox, QPushButton, QWidget) +from PySide2.QtCharts import QtCharts + +class MainWidget(QWidget): + def __init__(self, parent=None): + super(MainWidget, self).__init__(parent) + self.chart = QtCharts.QChart() + self.series = QtCharts.QBarSeries() + + self.main_layout = QGridLayout() + self.button_layout = QGridLayout() + self.font_layout = QFormLayout() + + self.font_size = QDoubleSpinBox() + + self.legend_posx = QDoubleSpinBox() + self.legend_posy = QDoubleSpinBox() + self.legend_width = QDoubleSpinBox() + self.legend_height = QDoubleSpinBox() + + self.detach_legend_button = QPushButton("Toggle attached") + self.detach_legend_button.clicked.connect(self.toggle_attached) + self.button_layout.addWidget(self.detach_legend_button, 0, 0) + + self.add_set_button = QPushButton("add barset") + self.add_set_button.clicked.connect(self.add_barset) + self.button_layout.addWidget(self.add_set_button, 2, 0) + + self.remove_barset_button = QPushButton("remove barset") + self.remove_barset_button.clicked.connect(self.remove_barset) + self.button_layout.addWidget(self.remove_barset_button, 3, 0) + + self.align_button = QPushButton("Align (Bottom)") + self.align_button.clicked.connect(self.set_legend_alignment) + self.button_layout.addWidget(self.align_button, 4, 0) + + self.bold_button = QPushButton("Toggle bold") + self.bold_button.clicked.connect(self.toggle_bold) + self.button_layout.addWidget(self.bold_button, 8, 0) + + self.italic_button = QPushButton("Toggle italic") + self.italic_button.clicked.connect(self.toggle_italic) + self.button_layout.addWidget(self.italic_button, 9, 0) + + self.legend_posx.valueChanged.connect(self.update_legend_layout) + self.legend_posy.valueChanged.connect(self.update_legend_layout) + self.legend_width.valueChanged.connect(self.update_legend_layout) + self.legend_height.valueChanged.connect(self.update_legend_layout) + + legend_layout = QFormLayout() + legend_layout.addRow("HPos", self.legend_posx) + legend_layout.addRow("VPos", self.legend_posy) + legend_layout.addRow("Width", self.legend_width) + legend_layout.addRow("Height", self.legend_height) + + self.legend_settings = QGroupBox("Detached legend") + self.legend_settings.setLayout(legend_layout) + self.button_layout.addWidget(self.legend_settings) + self.legend_settings.setVisible(False) + + # Create chart view with the chart + self.chart_view = QtCharts.QChartView(self.chart, self) + + # Create spinbox to modify font size + self.font_size.setValue(self.chart.legend().font().pointSizeF()) + self.font_size.valueChanged.connect(self.font_size_changed) + + self.font_layout.addRow("Legend font size", self.font_size) + + # Create layout for grid and detached legend + self.main_layout.addLayout(self.button_layout, 0, 0) + self.main_layout.addLayout(self.font_layout, 1, 0) + self.main_layout.addWidget(self.chart_view, 0, 1, 3, 1) + self.setLayout(self.main_layout) + + self.create_series() + + def create_series(self): + self.add_barset() + self.add_barset() + self.add_barset() + self.add_barset() + + self.chart.addSeries(self.series) + self.chart.setTitle("Legend detach example") + self.chart.createDefaultAxes() + + self.chart.legend().setVisible(True) + self.chart.legend().setAlignment(Qt.AlignBottom) + + self.chart_view.setRenderHint(QPainter.Antialiasing) + + def show_legend_spinbox(self): + self.legend_settings.setVisible(True) + chart_viewrect = self.chart_view.rect() + + self.legend_posx.setMinimum(0) + self.legend_posx.setMaximum(chart_viewrect.width()) + self.legend_posx.setValue(150) + + self.legend_posy.setMinimum(0) + self.legend_posy.setMaximum(chart_viewrect.height()) + self.legend_posy.setValue(150) + + self.legend_width.setMinimum(0) + self.legend_width.setMaximum(chart_viewrect.width()) + self.legend_width.setValue(150) + + self.legend_height.setMinimum(0) + self.legend_height.setMaximum(chart_viewrect.height()) + self.legend_height.setValue(75) + + def hideLegendSpinbox(self): + self.legend_settings.setVisible(False) + + def toggle_attached(self): + legend = self.chart.legend() + if legend.isAttachedToChart(): + legend.detachFromChart() + legend.setBackgroundVisible(True) + legend.setBrush(QBrush(QColor(128, 128, 128, 128))) + legend.setPen(QPen(QColor(192, 192, 192, 192))) + + self.show_legend_spinbox() + self.update_legend_layout() + else: + legend.attachToChart() + legend.setBackgroundVisible(False) + self.hideLegendSpinbox() + self.update() + + def add_barset(self): + series_count = self.series.count() + bar_set = QtCharts.QBarSet("set {}".format(series_count)) + delta = series_count * 0.1 + bar_set.append([1 + delta, 2 + delta, 3 + delta, 4 + delta]) + self.series.append(bar_set) + + def remove_barset(self): + sets = self.series.barSets() + len_sets = len(sets) + if len_sets > 0: + self.series.remove(sets[len_sets - 1]) + + def set_legend_alignment(self): + button = self.sender() + legend = self.chart.legend() + alignment = legend.alignment() + + if alignment == Qt.AlignTop: + legend.setAlignment(Qt.AlignLeft) + if button: + button.setText("Align (Left)") + elif alignment == Qt.AlignLeft: + legend.setAlignment(Qt.AlignBottom) + if button: + button.setText("Align (Bottom)") + elif alignment == Qt.AlignBottom: + legend.setAlignment(Qt.AlignRight) + if button: + button.setText("Align (Right)") + else: + if button: + button.setText("Align (Top)") + legend.setAlignment(Qt.AlignTop) + + def toggle_bold(self): + legend = self.chart.legend() + font = legend.font() + font.setBold(not font.bold()) + legend.setFont(font) + + def toggle_italic(self): + legend = self.chart.legend() + font = legend.font() + font.setItalic(not font.italic()) + legend.setFont(font) + + def font_size_changed(self): + legend = self.chart.legend() + font = legend.font() + font_size = self.font_size.value() + if font_size < 1: + font_size = 1 + font.setPointSizeF(font_size) + legend.setFont(font) + + def update_legend_layout(self): + legend = self.chart.legend() + + rect = QRectF(self.legend_posx.value(), + self.legend_posy.value(), + self.legend_width.value(), + self.legend_height.value()) + legend.setGeometry(rect) + + legend.update() + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = MainWidget() + available_geometry = app.desktop().availableGeometry(w) + size = available_geometry.height() * 0.75 + w.setFixedSize(size, size) + w.show() + sys.exit(app.exec_()) diff --git a/examples/charts/lineandbar.py b/examples/charts/lineandbar.py new file mode 100644 index 0000000..0a29aa7 --- /dev/null +++ b/examples/charts/lineandbar.py @@ -0,0 +1,116 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the line/bar example from Qt v5.x""" + +import sys +from PySide2.QtCore import QPoint, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QMainWindow, QApplication +from PySide2.QtCharts import QtCharts + + +class TestChart(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + + self.set0 = QtCharts.QBarSet("Jane") + self.set1 = QtCharts.QBarSet("John") + self.set2 = QtCharts.QBarSet("Axel") + self.set3 = QtCharts.QBarSet("Mary") + self.set4 = QtCharts.QBarSet("Sam") + + self.set0.append([1, 2, 3, 4, 5, 6]) + self.set1.append([5, 0, 0, 4, 0, 7]) + self.set2.append([3, 5, 8, 13, 8, 5]) + self.set3.append([5, 6, 7, 3, 4, 5]) + self.set4.append([9, 7, 5, 3, 1, 2]) + + self.barSeries = QtCharts.QBarSeries() + self.barSeries.append(self.set0) + self.barSeries.append(self.set1) + self.barSeries.append(self.set2) + self.barSeries.append(self.set3) + self.barSeries.append(self.set4) + + self.lineSeries = QtCharts.QLineSeries() + self.lineSeries.setName("trend") + self.lineSeries.append(QPoint(0, 4)) + self.lineSeries.append(QPoint(1, 15)) + self.lineSeries.append(QPoint(2, 20)) + self.lineSeries.append(QPoint(3, 4)) + self.lineSeries.append(QPoint(4, 12)) + self.lineSeries.append(QPoint(5, 17)) + + self.chart = QtCharts.QChart() + self.chart.addSeries(self.barSeries) + self.chart.addSeries(self.lineSeries) + self.chart.setTitle("Line and barchart example") + + self.categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] + self.axisX = QtCharts.QBarCategoryAxis() + self.axisX.append(self.categories) + self.chart.setAxisX(self.axisX, self.lineSeries) + self.chart.setAxisX(self.axisX, self.barSeries) + self.axisX.setRange("Jan", "Jun") + + self.axisY = QtCharts.QValueAxis() + self.chart.setAxisY(self.axisY, self.lineSeries) + self.chart.setAxisY(self.axisY, self.barSeries) + self.axisY.setRange(0, 20) + + self.chart.legend().setVisible(True) + self.chart.legend().setAlignment(Qt.AlignBottom) + + self.chartView = QtCharts.QChartView(self.chart) + self.chartView.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(self.chartView) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + window = TestChart() + window.show() + window.resize(440, 300) + + sys.exit(app.exec_()) diff --git a/examples/charts/linechart.py b/examples/charts/linechart.py new file mode 100644 index 0000000..98d17b3 --- /dev/null +++ b/examples/charts/linechart.py @@ -0,0 +1,84 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the linechart example from Qt v5.x""" + +import sys +from PySide2.QtCore import QPointF +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QMainWindow, QApplication +from PySide2.QtCharts import QtCharts + + +class TestChart(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + + self.series = QtCharts.QLineSeries() + self.series.append(0, 6) + self.series.append(2, 4) + self.series.append(3, 8) + self.series.append(7, 4) + self.series.append(10, 5) + self.series.append(QPointF(11, 1)) + self.series.append(QPointF(13, 3)) + self.series.append(QPointF(17, 6)) + self.series.append(QPointF(18, 3)) + self.series.append(QPointF(20, 2)) + + self.chart = QtCharts.QChart() + self.chart.legend().hide() + self.chart.addSeries(self.series) + self.chart.createDefaultAxes() + self.chart.setTitle("Simple line chart example") + + self.chartView = QtCharts.QChartView(self.chart) + self.chartView.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(self.chartView) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + window = TestChart() + window.show() + window.resize(440, 300) + sys.exit(app.exec_()) diff --git a/examples/charts/logvalueaxis.py b/examples/charts/logvalueaxis.py new file mode 100644 index 0000000..7fb5604 --- /dev/null +++ b/examples/charts/logvalueaxis.py @@ -0,0 +1,94 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Logarithmic Axis Example from Qt v5.x""" + + + +import sys +from PySide2.QtCore import Qt, QPointF +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QMainWindow, QApplication +from PySide2.QtCharts import QtCharts + + +class TestChart(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + + self.series = QtCharts.QLineSeries() + self.series.append([ + QPointF(1.0, 1.0), QPointF(2.0, 73.0), QPointF(3.0, 268.0), + QPointF(4.0, 17.0), QPointF(5.0, 4325.0), QPointF(6.0, 723.0)]) + + self.chart = QtCharts.QChart() + self.chart.addSeries(self.series) + self.chart.legend().hide() + self.chart.setTitle("Logarithmic axis example") + + self.axisX = QtCharts.QValueAxis() + self.axisX.setTitleText("Data point") + self.axisX.setLabelFormat("%i") + self.axisX.setTickCount(self.series.count()) + self.chart.addAxis(self.axisX, Qt.AlignBottom) + self.series.attachAxis(self.axisX) + + self.axisY = QtCharts.QLogValueAxis() + self.axisY.setTitleText("Values") + self.axisY.setLabelFormat("%g") + self.axisY.setBase(8.0) + self.axisY.setMinorTickCount(-1) + self.chart.addAxis(self.axisY, Qt.AlignLeft) + self.series.attachAxis(self.axisY) + + self.chartView = QtCharts.QChartView(self.chart) + self.chartView.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(self.chartView) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + window = TestChart() + window.show() + window.resize(800, 600) + + sys.exit(app.exec_()) diff --git a/examples/charts/memoryusage.py b/examples/charts/memoryusage.py new file mode 100644 index 0000000..4954b9c --- /dev/null +++ b/examples/charts/memoryusage.py @@ -0,0 +1,125 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 Charts example: Simple memory usage viewer""" + +import os +import sys +from PySide2.QtCore import QProcess +from PySide2.QtWidgets import QApplication, QMainWindow +from PySide2.QtCharts import QtCharts + +def runProcess(command, arguments): + process = QProcess() + process.start(command, arguments) + process.waitForFinished() + std_output = process.readAllStandardOutput().data().decode('utf-8') + return std_output.split('\n') + +def getMemoryUsage(): + result = [] + if sys.platform == 'win32': + # Windows: Obtain memory usage in KB from 'tasklist' + for line in runProcess('tasklist', [])[3:]: + if len(line) >= 74: + command = line[0:23].strip() + if command.endswith('.exe'): + command = command[0:len(command) - 4] + memoryUsage = float(line[64:74].strip().replace(',', '').replace('.', '')) + legend = '' + if memoryUsage > 10240: + legend = '{} {}M'.format(command, round(memoryUsage / 1024)) + else: + legend = '{} {}K'.format(command, round(memoryUsage)) + result.append([legend, memoryUsage]) + else: + # Unix: Obtain memory usage percentage from 'ps' + psOptions = ['-e', 'v'] + memoryColumn = 8 + commandColumn = 9 + if sys.platform == 'darwin': + psOptions = ['-e', '-v'] + memoryColumn = 11 + commandColumn = 12 + for line in runProcess('ps', psOptions): + tokens = line.split(None) + if len(tokens) > commandColumn and "PID" not in tokens: # Percentage and command + command = tokens[commandColumn] + if not command.startswith('['): + command = os.path.basename(command) + memoryUsage = round(float(tokens[memoryColumn].replace(',', '.'))) + legend = '{} {}%'.format(command, memoryUsage) + result.append([legend, memoryUsage]) + + result.sort(key = lambda x: x[1], reverse=True) + return result + +class MainWindow(QMainWindow): + + def __init__(self): + super(MainWindow, self).__init__() + + self.setWindowTitle('Memory Usage') + + memoryUsage = getMemoryUsage() + if len(memoryUsage) > 5: + memoryUsage = memoryUsage[0:4] + + self.series = QtCharts.QPieSeries() + for item in memoryUsage: + self.series.append(item[0], item[1]) + + slice = self.series.slices()[0] + slice.setExploded() + slice.setLabelVisible() + self.chart = QtCharts.QChart() + self.chart.addSeries(self.series) + self.chartView = QtCharts.QChartView(self.chart) + self.setCentralWidget(self.chartView) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + availableGeometry = app.desktop().availableGeometry(mainWin) + size = availableGeometry.height() * 3 / 4 + mainWin.resize(size, size) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/charts/modeldata.py b/examples/charts/modeldata.py new file mode 100644 index 0000000..aa53e74 --- /dev/null +++ b/examples/charts/modeldata.py @@ -0,0 +1,182 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Model Data example from Qt v5.x""" + +import sys +from random import randrange + +from PySide2.QtCore import QAbstractTableModel, QModelIndex, QRect, Qt +from PySide2.QtGui import QColor, QPainter +from PySide2.QtWidgets import (QApplication, QGridLayout, QHeaderView, + QTableView, QWidget) +from PySide2.QtCharts import QtCharts + +class CustomTableModel(QAbstractTableModel): + def __init__(self): + QAbstractTableModel.__init__(self) + self.input_data = [] + self.mapping = {} + self.column_count = 4 + self.row_count = 15 + + for i in range(self.row_count): + data_vec = [0]*self.column_count + for k in range(len(data_vec)): + if k % 2 == 0: + data_vec[k] = i * 50 + randrange(30) + else: + data_vec[k] = randrange(100) + self.input_data.append(data_vec) + + def rowCount(self, parent=QModelIndex()): + return len(self.input_data) + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + + if orientation == Qt.Horizontal: + if section % 2 == 0: + return "x" + else: + return "y" + else: + return "{}".format(section + 1) + + def data(self, index, role=Qt.DisplayRole): + if role == Qt.DisplayRole: + return self.input_data[index.row()][index.column()] + elif role == Qt.EditRole: + return self.input_data[index.row()][index.column()] + elif role == Qt.BackgroundRole: + for color, rect in self.mapping.items(): + if rect.contains(index.column(), index.row()): + return QColor(color) + # cell not mapped return white color + return QColor(Qt.white) + return None + + def setData(self, index, value, role=Qt.EditRole): + if index.isValid() and role == Qt.EditRole: + self.input_data[index.row()][index.column()] = float(value) + self.dataChanged.emit(index, index) + return True + return False + + def flags(self, index): + return Qt.ItemIsEnabled | Qt.ItemIsEditable | Qt.ItemIsSelectable + + def add_mapping(self, color, area): + self.mapping[color] = area + + def clear_mapping(self): + self.mapping = {} + + + +class TableWidget(QWidget): + def __init__(self): + QWidget.__init__(self) + + self.model = CustomTableModel() + + self.table_view = QTableView() + self.table_view.setModel(self.model) + self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) + self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) + + self.chart = QtCharts.QChart() + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + + self.series = QtCharts.QLineSeries() + self.series.setName("Line 1") + self.mapper = QtCharts.QVXYModelMapper(self) + self.mapper.setXColumn(0) + self.mapper.setYColumn(1) + self.mapper.setSeries(self.series) + self.mapper.setModel(self.model) + self.chart.addSeries(self.series) + + # for storing color hex from the series + seriesColorHex = "#000000" + + # get the color of the series and use it for showing the mapped area + seriesColorHex = "{}".format(self.series.pen().color().name()) + self.model.add_mapping(seriesColorHex, QRect(0, 0, 2, self.model.rowCount())) + + # series 2 + self.series = QtCharts.QLineSeries() + self.series.setName("Line 2") + + self.mapper = QtCharts.QVXYModelMapper(self) + self.mapper.setXColumn(2) + self.mapper.setYColumn(3) + self.mapper.setSeries(self.series) + self.mapper.setModel(self.model) + self.chart.addSeries(self.series) + + # get the color of the series and use it for showing the mapped area + seriesColorHex = "{}".format(self.series.pen().color().name()) + self.model.add_mapping(seriesColorHex, QRect(2, 0, 2, self.model.rowCount())) + + self.chart.createDefaultAxes() + self.chart_view = QtCharts.QChartView(self.chart) + self.chart_view.setRenderHint(QPainter.Antialiasing) + self.chart_view.setMinimumSize(640, 480) + + # create main layout + self.main_layout = QGridLayout() + self.main_layout.addWidget(self.table_view, 1, 0) + self.main_layout.addWidget(self.chart_view, 1, 1) + self.main_layout.setColumnStretch(1, 1) + self.main_layout.setColumnStretch(0, 0) + self.setLayout(self.main_layout) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = TableWidget() + w.show() + sys.exit(app.exec_()) diff --git a/examples/charts/nesteddonuts.py b/examples/charts/nesteddonuts.py new file mode 100644 index 0000000..77bbabf --- /dev/null +++ b/examples/charts/nesteddonuts.py @@ -0,0 +1,136 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Nested Donuts example from Qt v5.x""" + +import sys + +from PySide2.QtCore import Qt, QTimer +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QApplication, QGridLayout, QWidget +from PySide2.QtCharts import QtCharts + +from random import randrange +from functools import partial + +class Widget(QWidget): + def __init__(self): + QWidget.__init__(self) + self.setMinimumSize(800, 600) + self.donuts = [] + self.chart_view = QtCharts.QChartView() + self.chart_view.setRenderHint(QPainter.Antialiasing) + self.chart = self.chart_view.chart() + self.chart.legend().setVisible(False) + self.chart.setTitle("Nested donuts demo") + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + + self.min_size = 0.1 + self.max_size = 0.9 + self.donut_count = 5 + + self.setup_donuts() + + # create main layout + self.main_layout = QGridLayout(self) + self.main_layout.addWidget(self.chart_view, 1, 1) + self.setLayout(self.main_layout) + + self.update_timer = QTimer(self) + self.update_timer.timeout.connect(self.update_rotation) + self.update_timer.start(1250) + + def setup_donuts(self): + for i in range(self.donut_count): + donut = QtCharts.QPieSeries() + slccount = randrange(3, 6) + for j in range(slccount): + value = randrange(100, 200) + + slc = QtCharts.QPieSlice(str(value), value) + slc.setLabelVisible(True) + slc.setLabelColor(Qt.white) + slc.setLabelPosition(QtCharts.QPieSlice.LabelInsideTangential) + + # Connection using an extra parameter for the slot + slc.hovered[bool].connect(partial(self.explode_slice, slc=slc)) + + donut.append(slc) + size = (self.max_size - self.min_size)/self.donut_count + donut.setHoleSize(self.min_size + i * size) + donut.setPieSize(self.min_size + (i + 1) * size) + + self.donuts.append(donut) + self.chart_view.chart().addSeries(donut) + + + + def update_rotation(self): + for donut in self.donuts: + phase_shift = randrange(-50, 100) + donut.setPieStartAngle(donut.pieStartAngle() + phase_shift) + donut.setPieEndAngle(donut.pieEndAngle() + phase_shift) + + def explode_slice(self, exploded, slc): + if exploded: + self.update_timer.stop() + slice_startangle = slc.startAngle() + slice_endangle = slc.startAngle() + slc.angleSpan() + + donut = slc.series() + idx = self.donuts.index(donut) + for i in range(idx + 1, len(self.donuts)): + self.donuts[i].setPieStartAngle(slice_endangle) + self.donuts[i].setPieEndAngle(360 + slice_startangle) + else: + for donut in self.donuts: + donut.setPieStartAngle(0) + donut.setPieEndAngle(360) + + self.update_timer.start() + + slc.setExploded(exploded) + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = Widget() + w.show() + sys.exit(app.exec_()) diff --git a/examples/charts/percentbarchart.py b/examples/charts/percentbarchart.py new file mode 100644 index 0000000..256070e --- /dev/null +++ b/examples/charts/percentbarchart.py @@ -0,0 +1,98 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Percent Bar Chart example from Qt v5.x""" + +import sys +from PySide2.QtCore import Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QMainWindow, QApplication) +from PySide2.QtCharts import QtCharts + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + + set0 = QtCharts.QBarSet("Jane") + set1 = QtCharts.QBarSet("John") + set2 = QtCharts.QBarSet("Axel") + set3 = QtCharts.QBarSet("Mary") + set4 = QtCharts.QBarSet("Samantha") + + set0.append([1, 2, 3, 4, 5, 6]) + set1.append([5, 0, 0, 4, 0, 7]) + set2.append([3, 5, 8, 13, 8, 5]) + set3.append([5, 6, 7, 3, 4, 5]) + set4.append([9, 7, 5, 3, 1, 2]) + + series = QtCharts.QPercentBarSeries() + series.append(set0) + series.append(set1) + series.append(set2) + series.append(set3) + series.append(set4) + + chart = QtCharts.QChart() + chart.addSeries(series) + chart.setTitle("Simple percentbarchart example") + chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) + + categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"] + axis = QtCharts.QBarCategoryAxis() + axis.append(categories) + chart.createDefaultAxes() + chart.setAxisX(axis, series) + + chart.legend().setVisible(True) + chart.legend().setAlignment(Qt.AlignBottom) + + chart_view = QtCharts.QChartView(chart) + chart_view.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(chart_view) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = MainWindow() + w.resize(420, 300) + w.show() + sys.exit(app.exec_()) diff --git a/examples/charts/piechart.py b/examples/charts/piechart.py new file mode 100644 index 0000000..820da8b --- /dev/null +++ b/examples/charts/piechart.py @@ -0,0 +1,87 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Pie Chart Example from Qt v5.x""" + +import sys +from PySide2.QtCore import Qt +from PySide2.QtGui import QPainter, QPen +from PySide2.QtWidgets import QMainWindow, QApplication +from PySide2.QtCharts import QtCharts + + +class TestChart(QMainWindow): + + def __init__(self): + QMainWindow.__init__(self) + + self.series = QtCharts.QPieSeries() + + self.series.append('Jane', 1) + self.series.append('Joe', 2) + self.series.append('Andy', 3) + self.series.append('Barbara', 4) + self.series.append('Axel', 5) + + self.slice = self.series.slices()[1] + self.slice.setExploded() + self.slice.setLabelVisible() + self.slice.setPen(QPen(Qt.darkGreen, 2)) + self.slice.setBrush(Qt.green) + + self.chart = QtCharts.QChart() + self.chart.addSeries(self.series) + self.chart.setTitle('Simple piechart example') + self.chart.legend().hide() + + self.chartView = QtCharts.QChartView(self.chart) + self.chartView.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(self.chartView) + + +if __name__ == "__main__": + app = QApplication(sys.argv) + + window = TestChart() + window.show() + window.resize(440, 300) + + sys.exit(app.exec_()) diff --git a/examples/charts/qmlpolarchart/View1.qml b/examples/charts/qmlpolarchart/View1.qml new file mode 100644 index 0000000..ad17fec --- /dev/null +++ b/examples/charts/qmlpolarchart/View1.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtCharts 2.0 + +Item { + anchors.fill: parent + //![1] + PolarChartView { + title: "Two Series, Common Axes" + anchors.fill: parent + legend.visible: false + antialiasing: true + + ValueAxis { + id: axisAngular + min: 0 + max: 20 + tickCount: 9 + } + + ValueAxis { + id: axisRadial + min: -0.5 + max: 1.5 + } + + SplineSeries { + id: series1 + axisAngular: axisAngular + axisRadial: axisRadial + pointsVisible: true + } + + ScatterSeries { + id: series2 + axisAngular: axisAngular + axisRadial: axisRadial + markerSize: 10 + } + } + + // Add data dynamically to the series + Component.onCompleted: { + for (var i = 0; i <= 20; i++) { + series1.append(i, Math.random()); + series2.append(i, Math.random()); + } + } + //![1] +} diff --git a/examples/charts/qmlpolarchart/View2.qml b/examples/charts/qmlpolarchart/View2.qml new file mode 100644 index 0000000..7f241c3 --- /dev/null +++ b/examples/charts/qmlpolarchart/View2.qml @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtCharts 2.0 + +Item { + anchors.fill: parent + + //![1] + PolarChartView { + title: "Historical Area Series" + anchors.fill: parent + legend.visible: false + antialiasing: true + + DateTimeAxis { + id: axis1 + format: "yyyy MMM" + tickCount: 13 + } + ValueAxis { + id: axis2 + } + LineSeries { + id: lowerLine + axisAngular: axis1 + axisRadial: axis2 + + // Please note that month in JavaScript months are zero based, so 2 means March + XYPoint { x: toMsecsSinceEpoch(new Date(1950, 0, 1)); y: 15 } + XYPoint { x: toMsecsSinceEpoch(new Date(1962, 4, 1)); y: 35 } + XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 50 } + XYPoint { x: toMsecsSinceEpoch(new Date(1978, 2, 1)); y: 75 } + XYPoint { x: toMsecsSinceEpoch(new Date(1987, 11, 1)); y: 102 } + XYPoint { x: toMsecsSinceEpoch(new Date(1992, 1, 1)); y: 132 } + XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 100 } + XYPoint { x: toMsecsSinceEpoch(new Date(2002, 4, 1)); y: 120 } + XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 1)); y: 140 } + XYPoint { x: toMsecsSinceEpoch(new Date(2013, 5, 1)); y: 150 } + } + LineSeries { + id: upperLine + axisAngular: axis1 + axisRadial: axis2 + + // Please note that month in JavaScript months are zero based, so 2 means March + XYPoint { x: toMsecsSinceEpoch(new Date(1950, 0, 1)); y: 30 } + XYPoint { x: toMsecsSinceEpoch(new Date(1962, 4, 1)); y: 55 } + XYPoint { x: toMsecsSinceEpoch(new Date(1970, 0, 1)); y: 80 } + XYPoint { x: toMsecsSinceEpoch(new Date(1978, 2, 1)); y: 105 } + XYPoint { x: toMsecsSinceEpoch(new Date(1987, 11, 1)); y: 125 } + XYPoint { x: toMsecsSinceEpoch(new Date(1992, 1, 1)); y: 160 } + XYPoint { x: toMsecsSinceEpoch(new Date(1998, 7, 1)); y: 140 } + XYPoint { x: toMsecsSinceEpoch(new Date(2002, 4, 1)); y: 140 } + XYPoint { x: toMsecsSinceEpoch(new Date(2012, 8, 1)); y: 170 } + XYPoint { x: toMsecsSinceEpoch(new Date(2013, 5, 1)); y: 200 } + } + AreaSeries { + axisAngular: axis1 + axisRadial: axis2 + lowerSeries: lowerLine + upperSeries: upperLine + } + } + // DateTimeAxis is based on QDateTimes so we must convert our JavaScript dates to + // milliseconds since epoch to make them match the DateTimeAxis values + function toMsecsSinceEpoch(date) { + var msecs = date.getTime(); + return msecs; + } + //![1] +} diff --git a/examples/charts/qmlpolarchart/View3.qml b/examples/charts/qmlpolarchart/View3.qml new file mode 100644 index 0000000..5695a89 --- /dev/null +++ b/examples/charts/qmlpolarchart/View3.qml @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtCharts 2.0 + +Item { + anchors.fill: parent + + //![1] + PolarChartView { + title: "Numerical Data for Dummies" + anchors.fill: parent + legend.visible: false + antialiasing: true + + LineSeries { + axisRadial: CategoryAxis { + min: 0 + max: 30 + CategoryRange { + label: "critical" + endValue: 2 + } + CategoryRange { + label: "low" + endValue: 7 + } + CategoryRange { + label: "normal" + endValue: 12 + } + CategoryRange { + label: "high" + endValue: 18 + } + CategoryRange { + label: "extremely high" + endValue: 30 + } + } + + axisAngular: ValueAxis { + tickCount: 13 + } + + XYPoint { x: 0; y: 4.3 } + XYPoint { x: 1; y: 4.1 } + XYPoint { x: 2; y: 4.7 } + XYPoint { x: 3; y: 3.9 } + XYPoint { x: 4; y: 5.2 } + XYPoint { x: 5; y: 5.3 } + XYPoint { x: 6; y: 6.1 } + XYPoint { x: 7; y: 7.7 } + XYPoint { x: 8; y: 12.9 } + XYPoint { x: 9; y: 19.2 } + } + } + //![1] +} diff --git a/examples/charts/qmlpolarchart/main.qml b/examples/charts/qmlpolarchart/main.qml new file mode 100644 index 0000000..ed7a810 --- /dev/null +++ b/examples/charts/qmlpolarchart/main.qml @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Charts module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 800 + height: 600 + property bool sourceLoaded: false + + ListView { + id: root + focus: true + anchors.fill: parent + snapMode: ListView.SnapOneItem + highlightRangeMode: ListView.StrictlyEnforceRange + highlightMoveDuration: 250 + orientation: ListView.Horizontal + boundsBehavior: Flickable.StopAtBounds + + onCurrentIndexChanged: { + if (infoText.opacity > 0.0) { + if (sourceLoaded) + infoText.opacity = 0.0; + else if (currentIndex != 0) + currentIndex = 0; + } + } + + model: ListModel { + ListElement {component: "View1.qml"} + ListElement {component: "View2.qml"} + ListElement {component: "View3.qml"} + } + + delegate: Loader { + width: root.width + height: root.height + + source: component + asynchronous: true + + onLoaded: sourceLoaded = true + } + } + + Rectangle { + id: infoText + anchors.centerIn: parent + width: parent.width + height: 40 + color: "black" + Text { + color: "white" + anchors.centerIn: parent + text: "You can navigate between views using swipe or arrow keys" + } + + Behavior on opacity { + NumberAnimation { duration: 400 } + } + } +} diff --git a/examples/charts/qmlpolarchart/qmlpolarchart.py b/examples/charts/qmlpolarchart/qmlpolarchart.py new file mode 100644 index 0000000..4398169 --- /dev/null +++ b/examples/charts/qmlpolarchart/qmlpolarchart.py @@ -0,0 +1,63 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the QML Polar Chart Example from Qt v5.x""" + +import sys +import os +from PySide2.QtQuick import QQuickView +from PySide2.QtCore import Qt, QUrl +from PySide2.QtWidgets import QApplication, QMainWindow + + +if __name__ == '__main__': + app = QApplication(sys.argv) + viewer = QQuickView() + + viewer.engine().addImportPath(os.path.dirname(__file__)) + viewer.engine().quit.connect(viewer.close) + + viewer.setTitle = "QML Polar Chart" + qmlFile = os.path.join(os.path.dirname(__file__), 'main.qml') + viewer.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + viewer.setResizeMode(QQuickView.SizeRootObjectToView) + viewer.show() + + sys.exit(app.exec_()) diff --git a/examples/charts/qmlpolarchart/qmlpolarchart.pyproject b/examples/charts/qmlpolarchart/qmlpolarchart.pyproject new file mode 100644 index 0000000..6c18b1f --- /dev/null +++ b/examples/charts/qmlpolarchart/qmlpolarchart.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["View1.qml", "View1.qml", "View2.qml", "View3.qml", "main.qml", "qmlpolarchart.py"] +} diff --git a/examples/charts/temperaturerecords.py b/examples/charts/temperaturerecords.py new file mode 100644 index 0000000..dfd4dd6 --- /dev/null +++ b/examples/charts/temperaturerecords.py @@ -0,0 +1,95 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the Temperature Records example from Qt v5.x""" + +import sys +from PySide2.QtCore import Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import QMainWindow, QApplication +from PySide2.QtCharts import QtCharts + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + low = QtCharts.QBarSet("Min") + high = QtCharts.QBarSet("Max") + low.append([-52, -50, -45.3, -37.0, -25.6, -8.0, + -6.0, -11.8, -19.7, -32.8, -43.0, -48.0]) + high.append([11.9, 12.8, 18.5, 26.5, 32.0, 34.8, + 38.2, 34.8, 29.8, 20.4, 15.1, 11.8]) + + series = QtCharts.QStackedBarSeries() + series.append(low) + series.append(high) + + chart = QtCharts.QChart() + chart.addSeries(series) + chart.setTitle("Temperature records in celcius") + chart.setAnimationOptions(QtCharts.QChart.SeriesAnimations) + + categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", + "Aug", "Sep", "Oct", "Nov", "Dec"] + axisX = QtCharts.QBarCategoryAxis() + axisX.append(categories) + axisX.setTitleText("Month") + chart.addAxis(axisX, Qt.AlignBottom) + axisY = QtCharts.QValueAxis() + axisY.setRange(-52, 52) + axisY.setTitleText("Temperature [°C]") + chart.addAxis(axisY, Qt.AlignLeft) + series.attachAxis(axisX) + series.attachAxis(axisY) + + chart.legend().setVisible(True) + chart.legend().setAlignment(Qt.AlignBottom) + + chart_view = QtCharts.QChartView(chart) + chart_view.setRenderHint(QPainter.Antialiasing) + + self.setCentralWidget(chart_view) + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = MainWindow() + w.resize(600, 300) + w.show() + sys.exit(app.exec_()) diff --git a/examples/corelib/threads/mandelbrot.py b/examples/corelib/threads/mandelbrot.py new file mode 100644 index 0000000..f0d13db --- /dev/null +++ b/examples/corelib/threads/mandelbrot.py @@ -0,0 +1,348 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the corelib/threads/mandelbrot example from Qt v5.x, originating from PyQt""" + +from PySide2.QtCore import (Signal, QMutex, QMutexLocker, QPoint, QSize, Qt, + QThread, QWaitCondition) +from PySide2.QtGui import QColor, QImage, QPainter, QPixmap, qRgb +from PySide2.QtWidgets import QApplication, QWidget + + +DefaultCenterX = -0.647011 +DefaultCenterY = -0.0395159 +DefaultScale = 0.00403897 + +ZoomInFactor = 0.8 +ZoomOutFactor = 1 / ZoomInFactor +ScrollStep = 20 + + +class RenderThread(QThread): + ColormapSize = 512 + + renderedImage = Signal(QImage, float) + + def __init__(self, parent=None): + super(RenderThread, self).__init__(parent) + + self.mutex = QMutex() + self.condition = QWaitCondition() + self.centerX = 0.0 + self.centerY = 0.0 + self.scaleFactor = 0.0 + self.resultSize = QSize() + self.colormap = [] + + self.restart = False + self.abort = False + + for i in range(RenderThread.ColormapSize): + self.colormap.append(self.rgbFromWaveLength(380.0 + (i * 400.0 / RenderThread.ColormapSize))) + + def stop(self): + self.mutex.lock() + self.abort = True + self.condition.wakeOne() + self.mutex.unlock() + + self.wait(2000) + + def render(self, centerX, centerY, scaleFactor, resultSize): + locker = QMutexLocker(self.mutex) + + self.centerX = centerX + self.centerY = centerY + self.scaleFactor = scaleFactor + self.resultSize = resultSize + + if not self.isRunning(): + self.start(QThread.LowPriority) + else: + self.restart = True + self.condition.wakeOne() + + def run(self): + while True: + self.mutex.lock() + resultSize = self.resultSize + scaleFactor = self.scaleFactor + centerX = self.centerX + centerY = self.centerY + self.mutex.unlock() + + halfWidth = resultSize.width() // 2 + halfHeight = resultSize.height() // 2 + image = QImage(resultSize, QImage.Format_RGB32) + + NumPasses = 8 + curpass = 0 + + while curpass < NumPasses: + MaxIterations = (1 << (2 * curpass + 6)) + 32 + Limit = 4 + allBlack = True + + for y in range(-halfHeight, halfHeight): + if self.restart: + break + if self.abort: + return + + ay = 1j * (centerY + (y * scaleFactor)) + + for x in range(-halfWidth, halfWidth): + c0 = centerX + (x * scaleFactor) + ay + c = c0 + numIterations = 0 + + while numIterations < MaxIterations: + numIterations += 1 + c = c*c + c0 + if abs(c) >= Limit: + break + numIterations += 1 + c = c*c + c0 + if abs(c) >= Limit: + break + numIterations += 1 + c = c*c + c0 + if abs(c) >= Limit: + break + numIterations += 1 + c = c*c + c0 + if abs(c) >= Limit: + break + + if numIterations < MaxIterations: + image.setPixel(x + halfWidth, y + halfHeight, + self.colormap[numIterations % RenderThread.ColormapSize]) + allBlack = False + else: + image.setPixel(x + halfWidth, y + halfHeight, qRgb(0, 0, 0)) + + if allBlack and curpass == 0: + curpass = 4 + else: + if not self.restart: + self.renderedImage.emit(image, scaleFactor) + curpass += 1 + + self.mutex.lock() + if not self.restart: + self.condition.wait(self.mutex) + self.restart = False + self.mutex.unlock() + + def rgbFromWaveLength(self, wave): + r = 0.0 + g = 0.0 + b = 0.0 + + if wave >= 380.0 and wave <= 440.0: + r = -1.0 * (wave - 440.0) / (440.0 - 380.0) + b = 1.0 + elif wave >= 440.0 and wave <= 490.0: + g = (wave - 440.0) / (490.0 - 440.0) + b = 1.0 + elif wave >= 490.0 and wave <= 510.0: + g = 1.0 + b = -1.0 * (wave - 510.0) / (510.0 - 490.0) + elif wave >= 510.0 and wave <= 580.0: + r = (wave - 510.0) / (580.0 - 510.0) + g = 1.0 + elif wave >= 580.0 and wave <= 645.0: + r = 1.0 + g = -1.0 * (wave - 645.0) / (645.0 - 580.0) + elif wave >= 645.0 and wave <= 780.0: + r = 1.0 + + s = 1.0 + if wave > 700.0: + s = 0.3 + 0.7 * (780.0 - wave) / (780.0 - 700.0) + elif wave < 420.0: + s = 0.3 + 0.7 * (wave - 380.0) / (420.0 - 380.0) + + r = pow(r * s, 0.8) + g = pow(g * s, 0.8) + b = pow(b * s, 0.8) + + return qRgb(r*255, g*255, b*255) + + +class MandelbrotWidget(QWidget): + def __init__(self, parent=None): + super(MandelbrotWidget, self).__init__(parent) + + self.thread = RenderThread() + self.pixmap = QPixmap() + self.pixmapOffset = QPoint() + self.lastDragPos = QPoint() + + self.centerX = DefaultCenterX + self.centerY = DefaultCenterY + self.pixmapScale = DefaultScale + self.curScale = DefaultScale + + self.thread.renderedImage.connect(self.updatePixmap) + + self.setWindowTitle("Mandelbrot") + self.setCursor(Qt.CrossCursor) + self.resize(550, 400) + + def paintEvent(self, event): + painter = QPainter(self) + painter.fillRect(self.rect(), Qt.black) + + if self.pixmap.isNull(): + painter.setPen(Qt.white) + painter.drawText(self.rect(), Qt.AlignCenter, + "Rendering initial image, please wait...") + return + + if self.curScale == self.pixmapScale: + painter.drawPixmap(self.pixmapOffset, self.pixmap) + else: + scaleFactor = self.pixmapScale / self.curScale + newWidth = int(self.pixmap.width() * scaleFactor) + newHeight = int(self.pixmap.height() * scaleFactor) + newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2 + newY = self.pixmapOffset.y() + (self.pixmap.height() - newHeight) / 2 + + painter.save() + painter.translate(newX, newY) + painter.scale(scaleFactor, scaleFactor) + exposed, _ = painter.matrix().inverted() + exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1) + painter.drawPixmap(exposed, self.pixmap, exposed) + painter.restore() + + text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \ + "hold left mouse button to scroll." + metrics = painter.fontMetrics() + textWidth = metrics.width(text) + + painter.setPen(Qt.NoPen) + painter.setBrush(QColor(0, 0, 0, 127)) + painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10, + metrics.lineSpacing() + 5) + painter.setPen(Qt.white) + painter.drawText((self.width() - textWidth) / 2, + metrics.leading() + metrics.ascent(), text) + + def resizeEvent(self, event): + self.thread.render(self.centerX, self.centerY, self.curScale, self.size()) + + def keyPressEvent(self, event): + if event.key() == Qt.Key_Plus: + self.zoom(ZoomInFactor) + elif event.key() == Qt.Key_Minus: + self.zoom(ZoomOutFactor) + elif event.key() == Qt.Key_Left: + self.scroll(-ScrollStep, 0) + elif event.key() == Qt.Key_Right: + self.scroll(+ScrollStep, 0) + elif event.key() == Qt.Key_Down: + self.scroll(0, -ScrollStep) + elif event.key() == Qt.Key_Up: + self.scroll(0, +ScrollStep) + else: + super(MandelbrotWidget, self).keyPressEvent(event) + + def wheelEvent(self, event): + numDegrees = event.angleDelta().y() / 8 + numSteps = numDegrees / 15.0 + self.zoom(pow(ZoomInFactor, numSteps)) + + def mousePressEvent(self, event): + if event.buttons() == Qt.LeftButton: + self.lastDragPos = QPoint(event.pos()) + + def mouseMoveEvent(self, event): + if event.buttons() & Qt.LeftButton: + self.pixmapOffset += event.pos() - self.lastDragPos + self.lastDragPos = QPoint(event.pos()) + self.update() + + def mouseReleaseEvent(self, event): + if event.button() == Qt.LeftButton: + self.pixmapOffset += event.pos() - self.lastDragPos + self.lastDragPos = QPoint() + + deltaX = (self.width() - self.pixmap.width()) / 2 - self.pixmapOffset.x() + deltaY = (self.height() - self.pixmap.height()) / 2 - self.pixmapOffset.y() + self.scroll(deltaX, deltaY) + + def updatePixmap(self, image, scaleFactor): + if not self.lastDragPos.isNull(): + return + + self.pixmap = QPixmap.fromImage(image) + self.pixmapOffset = QPoint() + self.lastDragPosition = QPoint() + self.pixmapScale = scaleFactor + self.update() + + def zoom(self, zoomFactor): + self.curScale *= zoomFactor + self.update() + self.thread.render(self.centerX, self.centerY, self.curScale, + self.size()) + + def scroll(self, deltaX, deltaY): + self.centerX += deltaX * self.curScale + self.centerY += deltaY * self.curScale + self.update() + self.thread.render(self.centerX, self.centerY, self.curScale, + self.size()) + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + widget = MandelbrotWidget() + widget.show() + r = app.exec_() + widget.thread.stop() + sys.exit(r) diff --git a/examples/corelib/threads/threads.pyproject b/examples/corelib/threads/threads.pyproject new file mode 100644 index 0000000..254aabe --- /dev/null +++ b/examples/corelib/threads/threads.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["mandelbrot.py"] +} diff --git a/examples/corelib/tools/codecs/codecs.py b/examples/corelib/tools/codecs/codecs.py new file mode 100644 index 0000000..63e74a6 --- /dev/null +++ b/examples/corelib/tools/codecs/codecs.py @@ -0,0 +1,253 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/tools/codecs example from Qt v5.x""" + +from PySide2 import QtCore, QtWidgets + + +def codec_name(codec): + try: + # Python v3. + name = str(codec.name(), encoding='ascii') + except TypeError: + # Python v2. + name = str(codec.name()) + + return name + + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + self.textEdit = QtWidgets.QTextEdit() + self.textEdit.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.setCentralWidget(self.textEdit) + + self.codecs = [] + self.findCodecs() + + self.previewForm = PreviewForm(self) + self.previewForm.setCodecList(self.codecs) + + self.saveAsActs = [] + self.createActions() + self.createMenus() + + self.setWindowTitle("Codecs") + self.resize(500, 400) + + def open(self): + fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self) + if fileName: + inFile = QtCore.QFile(fileName) + if not inFile.open(QtCore.QFile.ReadOnly): + QtWidgets.QMessageBox.warning(self, "Codecs", + "Cannot read file %s:\n%s" % (fileName, inFile.errorString())) + return + + data = inFile.readAll() + + self.previewForm.setEncodedData(data) + if self.previewForm.exec_(): + self.textEdit.setPlainText(self.previewForm.decodedString()) + + def save(self): + fileName = QtWidgets.QFileDialog.getSaveFileName(self) + if fileName: + outFile = QtCore.QFile(fileName) + if not outFile.open(QtCore.QFile.WriteOnly|QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(self, "Codecs", + "Cannot write file %s:\n%s" % (fileName, outFile.errorString())) + return + + action = self.sender() + codecName = action.data() + + out = QtCore.QTextStream(outFile) + out.setCodec(codecName) + out << self.textEdit.toPlainText() + + def about(self): + QtWidgets.QMessageBox.about(self, "About Codecs", + "The Codecs example demonstrates how to read and " + "write files using various encodings.") + + def aboutToShowSaveAsMenu(self): + currentText = self.textEdit.toPlainText() + + for action in self.saveAsActs: + codecName = str(action.data()) + codec = QtCore.QTextCodec.codecForName(codecName) + action.setVisible(codec and codec.canEncode(currentText)) + + def findCodecs(self): + codecMap = [] + iso8859RegExp = QtCore.QRegularExpression('^ISO[- ]8859-([0-9]+).*$') + assert iso8859RegExp.isValid() + + for mib in QtCore.QTextCodec.availableMibs(): + codec = QtCore.QTextCodec.codecForMib(mib) + sortKey = codec_name(codec).upper() + rank = 0 + + if sortKey.startswith('UTF-8'): + rank = 1 + elif sortKey.startswith('UTF-16'): + rank = 2 + else: + match = iso8859RegExp.match(sortKey) + if match.hasMatch(): + if len(match.captured(1)) == 1: + rank = 3 + else: + rank = 4 + else: + rank = 5 + + codecMap.append((str(rank) + sortKey, codec)) + + codecMap.sort() + self.codecs = [item[-1] for item in codecMap] + + def createActions(self): + self.openAct = QtWidgets.QAction("&Open...", self, shortcut="Ctrl+O", + triggered=self.open) + + for codec in self.codecs: + name = codec_name(codec) + + action = QtWidgets.QAction(name + '...', self, triggered=self.save) + action.setData(name) + self.saveAsActs.append(action) + + self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q", + triggered=self.close) + + self.aboutAct = QtWidgets.QAction("&About", self, triggered=self.about) + + self.aboutQtAct = QtWidgets.QAction("About &Qt", self, + triggered=qApp.aboutQt) + + def createMenus(self): + self.saveAsMenu = QtWidgets.QMenu("&Save As", self) + for action in self.saveAsActs: + self.saveAsMenu.addAction(action) + + self.saveAsMenu.aboutToShow.connect(self.aboutToShowSaveAsMenu) + + self.fileMenu = QtWidgets.QMenu("&File", self) + self.fileMenu.addAction(self.openAct) + self.fileMenu.addMenu(self.saveAsMenu) + self.fileMenu.addSeparator() + self.fileMenu.addAction(self.exitAct) + + self.helpMenu = QtWidgets.QMenu("&Help", self) + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + self.menuBar().addMenu(self.fileMenu) + self.menuBar().addSeparator() + self.menuBar().addMenu(self.helpMenu) + + +class PreviewForm(QtWidgets.QDialog): + def __init__(self, parent): + super(PreviewForm, self).__init__(parent) + + self.encodingComboBox = QtWidgets.QComboBox() + encodingLabel = QtWidgets.QLabel("&Encoding:") + encodingLabel.setBuddy(self.encodingComboBox) + + self.textEdit = QtWidgets.QTextEdit() + self.textEdit.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) + self.textEdit.setReadOnly(True) + + buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) + + self.encodingComboBox.activated.connect(self.updateTextEdit) + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(encodingLabel, 0, 0) + mainLayout.addWidget(self.encodingComboBox, 0, 1) + mainLayout.addWidget(self.textEdit, 1, 0, 1, 2) + mainLayout.addWidget(buttonBox, 2, 0, 1, 2) + self.setLayout(mainLayout) + + self.setWindowTitle("Choose Encoding") + self.resize(400, 300) + + def setCodecList(self, codecs): + self.encodingComboBox.clear() + for codec in codecs: + self.encodingComboBox.addItem(codec_name(codec), codec.mibEnum()) + + def setEncodedData(self, data): + self.encodedData = data + self.updateTextEdit() + + def decodedString(self): + return self.decodedStr + + def updateTextEdit(self): + mib = self.encodingComboBox.itemData(self.encodingComboBox.currentIndex()) + codec = QtCore.QTextCodec.codecForMib(mib) + + data = QtCore.QTextStream(self.encodedData) + data.setAutoDetectUnicode(False) + data.setCodec(codec) + + self.decodedStr = data.readAll() + self.textEdit.setPlainText(self.decodedStr) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/corelib/tools/codecs/codecs.pyproject b/examples/corelib/tools/codecs/codecs.pyproject new file mode 100644 index 0000000..72237d6 --- /dev/null +++ b/examples/corelib/tools/codecs/codecs.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["codecs.py"] +} diff --git a/examples/corelib/tools/regexp.py b/examples/corelib/tools/regexp.py new file mode 100644 index 0000000..3a95332 --- /dev/null +++ b/examples/corelib/tools/regexp.py @@ -0,0 +1,194 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/tools/regexp example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets + + +class RegExpDialog(QtWidgets.QDialog): + MaxCaptures = 6 + + def __init__(self, parent=None): + super(RegExpDialog, self).__init__(parent) + + self.patternComboBox = QtWidgets.QComboBox() + self.patternComboBox.setEditable(True) + self.patternComboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, + QtWidgets.QSizePolicy.Preferred) + + patternLabel = QtWidgets.QLabel("&Pattern:") + patternLabel.setBuddy(self.patternComboBox) + + self.escapedPatternLineEdit = QtWidgets.QLineEdit() + self.escapedPatternLineEdit.setReadOnly(True) + palette = self.escapedPatternLineEdit.palette() + palette.setBrush(QtGui.QPalette.Base, + palette.brush(QtGui.QPalette.Disabled, QtGui.QPalette.Base)) + self.escapedPatternLineEdit.setPalette(palette) + + escapedPatternLabel = QtWidgets.QLabel("&Escaped Pattern:") + escapedPatternLabel.setBuddy(self.escapedPatternLineEdit) + + self.syntaxComboBox = QtWidgets.QComboBox() + self.syntaxComboBox.addItem("Regular expression v1", + QtCore.QRegExp.RegExp) + self.syntaxComboBox.addItem("Regular expression v2", + QtCore.QRegExp.RegExp2) + self.syntaxComboBox.addItem("Wildcard", QtCore.QRegExp.Wildcard) + self.syntaxComboBox.addItem("Fixed string", + QtCore.QRegExp.FixedString) + + syntaxLabel = QtWidgets.QLabel("&Pattern Syntax:") + syntaxLabel.setBuddy(self.syntaxComboBox) + + self.textComboBox = QtWidgets.QComboBox() + self.textComboBox.setEditable(True) + self.textComboBox.setSizePolicy(QtWidgets.QSizePolicy.Expanding, + QtWidgets.QSizePolicy.Preferred) + + textLabel = QtWidgets.QLabel("&Text:") + textLabel.setBuddy(self.textComboBox) + + self.caseSensitiveCheckBox = QtWidgets.QCheckBox("Case &Sensitive") + self.caseSensitiveCheckBox.setChecked(True) + self.minimalCheckBox = QtWidgets.QCheckBox("&Minimal") + + indexLabel = QtWidgets.QLabel("Index of Match:") + self.indexEdit = QtWidgets.QLineEdit() + self.indexEdit.setReadOnly(True) + + matchedLengthLabel = QtWidgets.QLabel("Matched Length:") + self.matchedLengthEdit = QtWidgets.QLineEdit() + self.matchedLengthEdit.setReadOnly(True) + + self.captureLabels = [] + self.captureEdits = [] + for i in range(self.MaxCaptures): + self.captureLabels.append(QtWidgets.QLabel("Capture %d:" % i)) + self.captureEdits.append(QtWidgets.QLineEdit()) + self.captureEdits[i].setReadOnly(True) + self.captureLabels[0].setText("Match:") + + checkBoxLayout = QtWidgets.QHBoxLayout() + checkBoxLayout.addWidget(self.caseSensitiveCheckBox) + checkBoxLayout.addWidget(self.minimalCheckBox) + checkBoxLayout.addStretch(1) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(patternLabel, 0, 0) + mainLayout.addWidget(self.patternComboBox, 0, 1) + mainLayout.addWidget(escapedPatternLabel, 1, 0) + mainLayout.addWidget(self.escapedPatternLineEdit, 1, 1) + mainLayout.addWidget(syntaxLabel, 2, 0) + mainLayout.addWidget(self.syntaxComboBox, 2, 1) + mainLayout.addLayout(checkBoxLayout, 3, 0, 1, 2) + mainLayout.addWidget(textLabel, 4, 0) + mainLayout.addWidget(self.textComboBox, 4, 1) + mainLayout.addWidget(indexLabel, 5, 0) + mainLayout.addWidget(self.indexEdit, 5, 1) + mainLayout.addWidget(matchedLengthLabel, 6, 0) + mainLayout.addWidget(self.matchedLengthEdit, 6, 1) + + for i in range(self.MaxCaptures): + mainLayout.addWidget(self.captureLabels[i], 7 + i, 0) + mainLayout.addWidget(self.captureEdits[i], 7 + i, 1) + self.setLayout(mainLayout) + + self.patternComboBox.editTextChanged.connect(self.refresh) + self.textComboBox.editTextChanged.connect(self.refresh) + self.caseSensitiveCheckBox.toggled.connect(self.refresh) + self.minimalCheckBox.toggled.connect(self.refresh) + self.syntaxComboBox.currentIndexChanged.connect(self.refresh) + + self.patternComboBox.addItem("[A-Za-z_]+([A-Za-z_0-9]*)") + self.textComboBox.addItem("(10 + delta4)* 32") + + self.setWindowTitle("RegExp") + self.setFixedHeight(self.sizeHint().height()) + self.refresh() + + def refresh(self): + self.setUpdatesEnabled(False) + + pattern = self.patternComboBox.currentText() + text = self.textComboBox.currentText() + + escaped = str(pattern) + escaped.replace('\\', '\\\\') + escaped.replace('"', '\\"') + self.escapedPatternLineEdit.setText('"' + escaped + '"') + + rx = QtCore.QRegExp(pattern) + cs = QtCore.Qt.CaseInsensitive + if self.caseSensitiveCheckBox.isChecked(): + cs = QtCore.Qt.CaseSensitive + rx.setCaseSensitivity(cs) + rx.setMinimal(self.minimalCheckBox.isChecked()) + syntax = self.syntaxComboBox.itemData(self.syntaxComboBox.currentIndex()) + rx.setPatternSyntax(QtCore.QRegExp.PatternSyntax(syntax)) + + palette = self.patternComboBox.palette() + if rx.isValid(): + palette.setColor(QtGui.QPalette.Text, + self.textComboBox.palette().color(QtGui.QPalette.Text)) + else: + palette.setColor(QtGui.QPalette.Text, QtCore.Qt.red) + self.patternComboBox.setPalette(palette) + + self.indexEdit.setText(str(rx.indexIn(text))) + self.matchedLengthEdit.setText(str(rx.matchedLength())) + + for i in range(self.MaxCaptures): + self.captureLabels[i].setEnabled(i <= rx.captureCount()) + self.captureEdits[i].setEnabled(i <= rx.captureCount()) + self.captureEdits[i].setText(rx.cap(i)) + + self.setUpdatesEnabled(True) + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + dialog = RegExpDialog() + sys.exit(dialog.exec_()) diff --git a/examples/corelib/tools/settingseditor/settingseditor.py b/examples/corelib/tools/settingseditor/settingseditor.py new file mode 100644 index 0000000..a3e50a7 --- /dev/null +++ b/examples/corelib/tools/settingseditor/settingseditor.py @@ -0,0 +1,770 @@ +# -*- coding: utf-8 -*- + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/tools/settingseditor example from Qt v5.x""" + +import sys + +from PySide2.QtCore import (QByteArray, QDate, QDateTime, QDir, QEvent, QPoint, + QRect, QRegularExpression, QSettings, QSize, QTime, QTimer, Qt) +from PySide2.QtGui import (QColor, QIcon, QIntValidator, QDoubleValidator, + QRegularExpressionValidator, QValidator) +from PySide2.QtWidgets import (QAbstractItemView, QAction, QApplication, + QCheckBox, QComboBox, QFileDialog, QDialog, QDialogButtonBox, QGridLayout, + QGroupBox, QHeaderView, QInputDialog, QItemDelegate, QLabel, QLineEdit, + QMainWindow, QMessageBox, QStyle, QSpinBox, QStyleOptionViewItem, + QTableWidget, QTableWidgetItem, QTreeWidget, QTreeWidgetItem, QVBoxLayout) + + +class TypeChecker: + def __init__(self, parent=None): + self.bool_exp = QRegularExpression('^(true)|(false)$') + assert self.bool_exp.isValid() + self.bool_exp.setPatternOptions(QRegularExpression.CaseInsensitiveOption) + + self.byteArray_exp = QRegularExpression(r'^[\x00-\xff]*$') + assert self.byteArray_exp.isValid() + + self.char_exp = QRegularExpression('^.$') + assert self.char_exp.isValid() + + pattern = r'^[+-]?\d+$' + self.int_exp = QRegularExpression(pattern) + assert self.int_exp.isValid() + + pattern = r'^\(([0-9]*),([0-9]*),([0-9]*),([0-9]*)\)$' + self.color_exp = QRegularExpression(pattern) + assert self.color_exp.isValid() + + pattern = r'^\((-?[0-9]*),(-?[0-9]*)\)$' + self.point_exp = QRegularExpression(pattern) + assert self.point_exp.isValid() + + pattern = r'^\((-?[0-9]*),(-?[0-9]*),(-?[0-9]*),(-?[0-9]*)\)$' + self.rect_exp = QRegularExpression(pattern) + assert self.rect_exp.isValid() + + self.size_exp = QRegularExpression(self.point_exp) + + date_pattern = '([0-9]{,4})-([0-9]{,2})-([0-9]{,2})' + self.date_exp = QRegularExpression('^{}$'.format(date_pattern)) + assert self.date_exp.isValid() + + time_pattern = '([0-9]{,2}):([0-9]{,2}):([0-9]{,2})' + self.time_exp = QRegularExpression('^{}$'.format(time_pattern)) + assert self.time_exp.isValid() + + pattern = '^{}T{}$'.format(date_pattern, time_pattern) + self.dateTime_exp = QRegularExpression(pattern) + assert self.dateTime_exp.isValid() + + def type_from_text(self, text): + if self.bool_exp.match(text).hasMatch(): + return bool + if self.int_exp.match(text).hasMatch(): + return int + return None + + def create_validator(self, value, parent): + if isinstance(value, bool): + return QRegularExpressionValidator(self.bool_exp, parent) + if isinstance(value, float): + return QDoubleValidator(parent) + if isinstance(value, int): + return QIntValidator(parent) + if isinstance(value, QByteArray): + return QRegularExpressionValidator(self.byteArray_exp, parent) + if isinstance(value, QColor): + return QRegularExpressionValidator(self.color_exp, parent) + if isinstance(value, QDate): + return QRegularExpressionValidator(self.date_exp, parent) + if isinstance(value, QDateTime): + return QRegularExpressionValidator(self.dateTime_exp, parent) + if isinstance(value, QTime): + return QRegularExpressionValidator(self.time_exp, parent) + if isinstance(value, QPoint): + return QRegularExpressionValidator(self.point_exp, parent) + if isinstance(value, QRect): + return QRegularExpressionValidator(self.rect_exp, parent) + if isinstance(value, QSize): + return QRegularExpressionValidator(self.size_exp, parent) + return None + + def from_string(self, text, original_value): + if isinstance(original_value, QColor): + match = self.color_exp.match(text) + return QColor(min(int(match.captured(1)), 255), + min(int(match.captured(2)), 255), + min(int(match.captured(3)), 255), + min(int(match.captured(4)), 255)) + if isinstance(original_value, QDate): + value = QDate.fromString(text, Qt.ISODate) + return value if value.isValid() else None + if isinstance(original_value, QDateTime): + value = QDateTime.fromString(text, Qt.ISODate) + return value if value.isValid() else None + if isinstance(original_value, QTime): + value = QTime.fromString(text, Qt.ISODate) + return value if value.isValid() else None + if isinstance(original_value, QPoint): + match = self.point_exp.match(text) + return QPoint(int(match.captured(1)), + int(match.captured(2))) + if isinstance(original_value, QRect): + match = self.rect_exp.match(text) + return QRect(int(match.captured(1)), + int(match.captured(2)), + int(match.captured(3)), + int(match.captured(4))) + if isinstance(original_value, QSize): + match = self.size_exp.match(text) + return QSize(int(match.captured(1)), + int(match.captured(2))) + if isinstance(original_value, list): + return text.split(',') + return type(original_value)(text) + + +class MainWindow(QMainWindow): + def __init__(self, parent=None): + super(MainWindow, self).__init__(parent) + + self.settings_tree = SettingsTree() + self.setCentralWidget(self.settings_tree) + + self.location_dialog = None + + self.create_actions() + self.create_menus() + + self.auto_refresh_action.setChecked(True) + self.fallbacks_action.setChecked(True) + + self.setWindowTitle("Settings Editor") + self.resize(500, 600) + + def open_settings(self): + if self.location_dialog is None: + self.location_dialog = LocationDialog(self) + + if self.location_dialog.exec_(): + settings = QSettings(self.location_dialog.format(), + self.location_dialog.scope(), + self.location_dialog.organization(), + self.location_dialog.application()) + self.set_settings_object(settings) + self.fallbacks_action.setEnabled(True) + + def open_inifile(self): + file_name, _ = QFileDialog.getOpenFileName(self, "Open INI File", + '', "INI Files (*.ini *.conf)") + + if file_name: + self.load_ini_file(file_name) + + def load_ini_file(self, file_name): + settings = QSettings(file_name, QSettings.IniFormat) + if settings.status() != QSettings.NoError: + return + self.set_settings_object(settings) + self.fallbacks_action.setEnabled(False) + + def open_property_list(self): + file_name, _ = QFileDialog.getOpenFileName(self, + "Open Property List", '', "Property List Files (*.plist)") + + if file_name: + settings = QSettings(file_name, QSettings.NativeFormat) + self.set_settings_object(settings) + self.fallbacks_action.setEnabled(False) + + def open_registry_path(self): + path, ok = QInputDialog.getText(self, "Open Registry Path", + "Enter the path in the Windows registry:", + QLineEdit.Normal, 'HKEY_CURRENT_USER\\') + + if ok and path != '': + settings = QSettings(path, QSettings.NativeFormat) + self.set_settings_object(settings) + self.fallbacks_action.setEnabled(False) + + def about(self): + QMessageBox.about(self, "About Settings Editor", + "The Settings Editor example shows how to access " + "application settings using Qt.") + + def create_actions(self): + self.open_settings_action = QAction("&Open Application Settings...", + self, shortcut="Ctrl+O", triggered=self.open_settings) + + self.open_ini_file_action = QAction("Open I&NI File...", self, + shortcut="Ctrl+N", triggered=self.open_inifile) + + self.open_property_list_action = QAction("Open macOS &Property List...", + self, shortcut="Ctrl+P", triggered=self.open_property_list) + if sys.platform != 'darwin': + self.open_property_list_action.setEnabled(False) + + self.open_registry_path_action = QAction( + "Open Windows &Registry Path...", self, shortcut="Ctrl+G", + triggered=self.open_registry_path) + if sys.platform != 'win32': + self.open_registry_path_action.setEnabled(False) + + self.refresh_action = QAction("&Refresh", self, shortcut="Ctrl+R", + enabled=False, triggered=self.settings_tree.refresh) + + self.exit_action = QAction("E&xit", self, shortcut="Ctrl+Q", + triggered=self.close) + + self.auto_refresh_action = QAction("&Auto-Refresh", self, + shortcut="Ctrl+A", checkable=True, enabled=False) + self.auto_refresh_action.triggered[bool].connect(self.settings_tree.set_auto_refresh) + self.auto_refresh_action.triggered[bool].connect(self.refresh_action.setDisabled) + + self.fallbacks_action = QAction("&Fallbacks", self, + shortcut="Ctrl+F", checkable=True, enabled=False) + self.fallbacks_action.triggered[bool].connect(self.settings_tree.set_fallbacks_enabled) + + self.about_action = QAction("&About", self, triggered=self.about) + + self.about_Qt_action = QAction("About &Qt", self, + triggered=qApp.aboutQt) + + def create_menus(self): + self.file_menu = self.menuBar().addMenu("&File") + self.file_menu.addAction(self.open_settings_action) + self.file_menu.addAction(self.open_ini_file_action) + self.file_menu.addAction(self.open_property_list_action) + self.file_menu.addAction(self.open_registry_path_action) + self.file_menu.addSeparator() + self.file_menu.addAction(self.refresh_action) + self.file_menu.addSeparator() + self.file_menu.addAction(self.exit_action) + + self.options_menu = self.menuBar().addMenu("&Options") + self.options_menu.addAction(self.auto_refresh_action) + self.options_menu.addAction(self.fallbacks_action) + + self.menuBar().addSeparator() + + self.help_menu = self.menuBar().addMenu("&Help") + self.help_menu.addAction(self.about_action) + self.help_menu.addAction(self.about_Qt_action) + + def set_settings_object(self, settings): + settings.setFallbacksEnabled(self.fallbacks_action.isChecked()) + self.settings_tree.set_settings_object(settings) + + self.refresh_action.setEnabled(True) + self.auto_refresh_action.setEnabled(True) + + nice_name = QDir.fromNativeSeparators(settings.fileName()) + nice_name = nice_name.split('/')[-1] + + if not settings.isWritable(): + nice_name += " (read only)" + + self.setWindowTitle("{} - Settings Editor".format(nice_name)) + + +class LocationDialog(QDialog): + def __init__(self, parent=None): + super(LocationDialog, self).__init__(parent) + + self.format_combo = QComboBox() + self.format_combo.addItem("Native") + self.format_combo.addItem("INI") + + self.scope_cCombo = QComboBox() + self.scope_cCombo.addItem("User") + self.scope_cCombo.addItem("System") + + self.organization_combo = QComboBox() + self.organization_combo.addItem("Trolltech") + self.organization_combo.setEditable(True) + + self.application_combo = QComboBox() + self.application_combo.addItem("Any") + self.application_combo.addItem("Application Example") + self.application_combo.addItem("Assistant") + self.application_combo.addItem("Designer") + self.application_combo.addItem("Linguist") + self.application_combo.setEditable(True) + self.application_combo.setCurrentIndex(3) + + format_label = QLabel("&Format:") + format_label.setBuddy(self.format_combo) + + scope_label = QLabel("&Scope:") + scope_label.setBuddy(self.scope_cCombo) + + organization_label = QLabel("&Organization:") + organization_label.setBuddy(self.organization_combo) + + application_label = QLabel("&Application:") + application_label.setBuddy(self.application_combo) + + self.locations_groupbox = QGroupBox("Setting Locations") + + self.locations_table = QTableWidget() + self.locations_table.setSelectionMode(QAbstractItemView.SingleSelection) + self.locations_table.setSelectionBehavior(QAbstractItemView.SelectRows) + self.locations_table.setEditTriggers(QAbstractItemView.NoEditTriggers) + self.locations_table.setColumnCount(2) + self.locations_table.setHorizontalHeaderLabels(("Location", "Access")) + self.locations_table.horizontalHeader().setSectionResizeMode(0, QHeaderView.Stretch) + self.locations_table.horizontalHeader().resizeSection(1, 180) + + self.button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) + + self.format_combo.activated.connect(self.update_locations) + self.scope_cCombo.activated.connect(self.update_locations) + self.organization_combo.lineEdit().editingFinished.connect(self.update_locations) + self.application_combo.lineEdit().editingFinished.connect(self.update_locations) + self.button_box.accepted.connect(self.accept) + self.button_box.rejected.connect(self.reject) + + locations_layout = QVBoxLayout(self.locations_groupbox) + locations_layout.addWidget(self.locations_table) + + mainLayout = QGridLayout(self) + mainLayout.addWidget(format_label, 0, 0) + mainLayout.addWidget(self.format_combo, 0, 1) + mainLayout.addWidget(scope_label, 1, 0) + mainLayout.addWidget(self.scope_cCombo, 1, 1) + mainLayout.addWidget(organization_label, 2, 0) + mainLayout.addWidget(self.organization_combo, 2, 1) + mainLayout.addWidget(application_label, 3, 0) + mainLayout.addWidget(self.application_combo, 3, 1) + mainLayout.addWidget(self.locations_groupbox, 4, 0, 1, 2) + mainLayout.addWidget(self.button_box, 5, 0, 1, 2) + + self.update_locations() + + self.setWindowTitle("Open Application Settings") + self.resize(650, 400) + + def format(self): + if self.format_combo.currentIndex() == 0: + return QSettings.NativeFormat + else: + return QSettings.IniFormat + + def scope(self): + if self.scope_cCombo.currentIndex() == 0: + return QSettings.UserScope + else: + return QSettings.SystemScope + + def organization(self): + return self.organization_combo.currentText() + + def application(self): + if self.application_combo.currentText() == "Any": + return '' + + return self.application_combo.currentText() + + def update_locations(self): + self.locations_table.setUpdatesEnabled(False) + self.locations_table.setRowCount(0) + + for i in range(2): + if i == 0: + if self.scope() == QSettings.SystemScope: + continue + + actualScope = QSettings.UserScope + else: + actualScope = QSettings.SystemScope + + for j in range(2): + if j == 0: + if not self.application(): + continue + + actualApplication = self.application() + else: + actualApplication = '' + + settings = QSettings(self.format(), actualScope, + self.organization(), actualApplication) + + row = self.locations_table.rowCount() + self.locations_table.setRowCount(row + 1) + + item0 = QTableWidgetItem() + item0.setText(settings.fileName()) + + item1 = QTableWidgetItem() + disable = not (settings.childKeys() or settings.childGroups()) + + if row == 0: + if settings.isWritable(): + item1.setText("Read-write") + disable = False + else: + item1.setText("Read-only") + self.button_box.button(QDialogButtonBox.Ok).setDisabled(disable) + else: + item1.setText("Read-only fallback") + + if disable: + item0.setFlags(item0.flags() & ~Qt.ItemIsEnabled) + item1.setFlags(item1.flags() & ~Qt.ItemIsEnabled) + + self.locations_table.setItem(row, 0, item0) + self.locations_table.setItem(row, 1, item1) + + self.locations_table.setUpdatesEnabled(True) + + +class SettingsTree(QTreeWidget): + def __init__(self, parent=None): + super(SettingsTree, self).__init__(parent) + + self._type_checker = TypeChecker() + self.setItemDelegate(VariantDelegate(self._type_checker, self)) + + self.setHeaderLabels(("Setting", "Type", "Value")) + self.header().setSectionResizeMode(0, QHeaderView.Stretch) + self.header().setSectionResizeMode(2, QHeaderView.Stretch) + + self.settings = None + self.refresh_timer = QTimer() + self.refresh_timer.setInterval(2000) + self.auto_refresh = False + + self.group_icon = QIcon() + style = self.style() + self.group_icon.addPixmap(style.standardPixmap(QStyle.SP_DirClosedIcon), + QIcon.Normal, QIcon.Off) + self.group_icon.addPixmap(style.standardPixmap(QStyle.SP_DirOpenIcon), + QIcon.Normal, QIcon.On) + self.key_icon = QIcon() + self.key_icon.addPixmap(style.standardPixmap(QStyle.SP_FileIcon)) + + self.refresh_timer.timeout.connect(self.maybe_refresh) + + def set_settings_object(self, settings): + self.settings = settings + self.clear() + + if self.settings is not None: + self.settings.setParent(self) + self.refresh() + if self.auto_refresh: + self.refresh_timer.start() + else: + self.refresh_timer.stop() + + def sizeHint(self): + return QSize(800, 600) + + def set_auto_refresh(self, autoRefresh): + self.auto_refresh = autoRefresh + + if self.settings is not None: + if self.auto_refresh: + self.maybe_refresh() + self.refresh_timer.start() + else: + self.refresh_timer.stop() + + def set_fallbacks_enabled(self, enabled): + if self.settings is not None: + self.settings.setFallbacksEnabled(enabled) + self.refresh() + + def maybe_refresh(self): + if self.state() != QAbstractItemView.EditingState: + self.refresh() + + def refresh(self): + if self.settings is None: + return + + # The signal might not be connected. + try: + self.itemChanged.disconnect(self.update_setting) + except: + pass + + self.settings.sync() + self.update_child_items(None) + + self.itemChanged.connect(self.update_setting) + + def event(self, event): + if event.type() == QEvent.WindowActivate: + if self.isActiveWindow() and self.auto_refresh: + self.maybe_refresh() + + return super(SettingsTree, self).event(event) + + def update_setting(self, item): + key = item.text(0) + ancestor = item.parent() + + while ancestor: + key = ancestor.text(0) + '/' + key + ancestor = ancestor.parent() + + d = item.data(2, Qt.UserRole) + self.settings.setValue(key, item.data(2, Qt.UserRole)) + + if self.auto_refresh: + self.refresh() + + def update_child_items(self, parent): + divider_index = 0 + + for group in self.settings.childGroups(): + child_index = self.find_child(parent, group, divider_index) + if child_index != -1: + child = self.child_at(parent, child_index) + child.setText(1, '') + child.setText(2, '') + child.setData(2, Qt.UserRole, None) + self.move_item_forward(parent, child_index, divider_index) + else: + child = self.create_item(group, parent, divider_index) + + child.setIcon(0, self.group_icon) + divider_index += 1 + + self.settings.beginGroup(group) + self.update_child_items(child) + self.settings.endGroup() + + for key in self.settings.childKeys(): + child_index = self.find_child(parent, key, 0) + if child_index == -1 or child_index >= divider_index: + if child_index != -1: + child = self.child_at(parent, child_index) + for i in range(child.childCount()): + self.delete_item(child, i) + self.move_item_forward(parent, child_index, divider_index) + else: + child = self.create_item(key, parent, divider_index) + child.setIcon(0, self.key_icon) + divider_index += 1 + else: + child = self.child_at(parent, child_index) + + value = self.settings.value(key) + if value is None: + child.setText(1, 'Invalid') + else: + # Try to convert to type unless a QByteArray is received + if isinstance(value, str): + value_type = self._type_checker.type_from_text(value) + if value_type: + value = self.settings.value(key, type=value_type) + child.setText(1, value.__class__.__name__) + child.setText(2, VariantDelegate.displayText(value)) + child.setData(2, Qt.UserRole, value) + + while divider_index < self.child_count(parent): + self.delete_item(parent, divider_index) + + def create_item(self, text, parent, index): + after = None + + if index != 0: + after = self.child_at(parent, index - 1) + + if parent is not None: + item = QTreeWidgetItem(parent, after) + else: + item = QTreeWidgetItem(self, after) + + item.setText(0, text) + item.setFlags(item.flags() | Qt.ItemIsEditable) + return item + + def delete_item(self, parent, index): + if parent is not None: + item = parent.takeChild(index) + else: + item = self.takeTopLevelItem(index) + del item + + def child_at(self, parent, index): + if parent is not None: + return parent.child(index) + else: + return self.topLevelItem(index) + + def child_count(self, parent): + if parent is not None: + return parent.childCount() + else: + return self.topLevelItemCount() + + def find_child(self, parent, text, startIndex): + for i in range(self.child_count(parent)): + if self.child_at(parent, i).text(0) == text: + return i + return -1 + + def move_item_forward(self, parent, oldIndex, newIndex): + for int in range(oldIndex - newIndex): + self.delete_item(parent, newIndex) + + +class VariantDelegate(QItemDelegate): + def __init__(self, type_checker, parent=None): + super(VariantDelegate, self).__init__(parent) + self._type_checker = type_checker + + def paint(self, painter, option, index): + if index.column() == 2: + value = index.model().data(index, Qt.UserRole) + if not self.is_supported_type(value): + my_option = QStyleOptionViewItem(option) + my_option.state &= ~QStyle.State_Enabled + super(VariantDelegate, self).paint(painter, my_option, index) + return + + super(VariantDelegate, self).paint(painter, option, index) + + def createEditor(self, parent, option, index): + if index.column() != 2: + return None + + original_value = index.model().data(index, Qt.UserRole) + if not self.is_supported_type(original_value): + return None + + editor = None + if isinstance(original_value, bool): + editor = QCheckBox(parent) + if isinstance(original_value, int): + editor = QSpinBox(parent) + editor.setRange(-32767, 32767) + else: + editor = QLineEdit(parent) + editor.setFrame(False) + validator = self._type_checker.create_validator(original_value, editor) + if validator: + editor.setValidator(validator) + return editor + + def setEditorData(self, editor, index): + if not editor: + return + value = index.model().data(index, Qt.UserRole) + if isinstance(editor, QCheckBox): + editor.setCheckState(Qt.Checked if value else Qt.Unchecked) + elif isinstance(editor, QSpinBox): + editor.setValue(value) + else: + editor.setText(self.displayText(value)) + + def value_from_lineedit(self, lineedit, model, index): + if not lineedit.isModified(): + return None + text = lineedit.text() + validator = lineedit.validator() + if validator is not None: + state, text, _ = validator.validate(text, 0) + if state != QValidator.Acceptable: + return None + original_value = index.model().data(index, Qt.UserRole) + return self._type_checker.from_string(text, original_value) + + def setModelData(self, editor, model, index): + value = None + if isinstance(editor, QCheckBox): + value = editor.checkState() == Qt.Checked + elif isinstance(editor, QSpinBox): + value = editor.value() + else: + value = self.value_from_lineedit(editor, model, index) + if not value is None: + model.setData(index, value, Qt.UserRole) + model.setData(index, self.displayText(value), Qt.DisplayRole) + + @staticmethod + def is_supported_type(value): + return isinstance(value, (bool, float, int, QByteArray, str, QColor, + QDate, QDateTime, QTime, QPoint, QRect, + QSize, list)) + + @staticmethod + def displayText(value): + if isinstance(value, str): + return value + if isinstance(value, bool): + return '✓' if value else '☐' + if isinstance(value, (int, float, QByteArray)): + return str(value) + if isinstance(value, QColor): + return '({},{},{},{})'.format(value.red(), value.green(), + value.blue(), value.alpha()) + if isinstance(value, (QDate, QDateTime, QTime)): + return value.toString(Qt.ISODate) + if isinstance(value, QPoint): + return '({},{})'.format(value.x(), value.y()) + if isinstance(value, QRect): + return '({},{},{},{})'.format(value.x(), value.y(), value.width(), + value.height()) + if isinstance(value, QSize): + return '({},{})'.format(value.width(), value.height()) + if isinstance(value, list): + return ','.join(value) + if value is None: + return '' + + return '<{}>'.format(value) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + main_win = MainWindow() + if len(sys.argv) > 1: + main_win.load_ini_file(sys.argv[1]) + main_win.show() + sys.exit(app.exec_()) diff --git a/examples/corelib/tools/settingseditor/settingseditor.pyproject b/examples/corelib/tools/settingseditor/settingseditor.pyproject new file mode 100644 index 0000000..9eb637a --- /dev/null +++ b/examples/corelib/tools/settingseditor/settingseditor.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["settingseditor.py"] +} diff --git a/examples/corelib/tools/tools.pyproject b/examples/corelib/tools/tools.pyproject new file mode 100644 index 0000000..63f9c61 --- /dev/null +++ b/examples/corelib/tools/tools.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["regexp.py"] +} diff --git a/examples/datavisualization/bars3d.py b/examples/datavisualization/bars3d.py new file mode 100644 index 0000000..d0a69a8 --- /dev/null +++ b/examples/datavisualization/bars3d.py @@ -0,0 +1,113 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 QtDataVisualization example""" + +import sys +from PySide2.QtCore import Qt +from PySide2.QtGui import QGuiApplication +from PySide2.QtWidgets import QApplication, QSizePolicy, QMainWindow, QWidget +from PySide2.QtDataVisualization import QtDataVisualization + +def dataToBarDataRow(data): + return list(QtDataVisualization.QBarDataItem(d) for d in data) + +def dataToBarDataArray(data): + return list(dataToBarDataRow(row) for row in data) + +class MainWindow(QMainWindow): + + def __init__(self): + super(MainWindow, self).__init__() + + self.setWindowTitle('Qt DataVisualization 3D Bars') + + self.bars = QtDataVisualization.Q3DBars() + + self.columnAxis = QtDataVisualization.QCategory3DAxis() + self.columnAxis.setTitle('Columns') + self.columnAxis.setTitleVisible(True) + self.columnAxis.setLabels(['Column1', 'Column2']) + self.columnAxis.setLabelAutoRotation(30) + + self.rowAxis = QtDataVisualization.QCategory3DAxis() + self.rowAxis.setTitle('Rows') + self.rowAxis.setTitleVisible(True) + self.rowAxis.setLabels(['Row1', 'Row2']) + self.rowAxis.setLabelAutoRotation(30) + + self.valueAxis = QtDataVisualization.QValue3DAxis() + self.valueAxis.setTitle('Values') + self.valueAxis.setTitleVisible(True) + self.valueAxis.setRange(0, 5) + + self.bars.setRowAxis(self.rowAxis) + self.bars.setColumnAxis(self.columnAxis) + self.bars.setValueAxis(self.valueAxis) + + self.series = QtDataVisualization.QBar3DSeries() + self.arrayData = [[1, 2], [3, 4]] + self.series.dataProxy().addRows(dataToBarDataArray(self.arrayData)) + + self.bars.setPrimarySeries(self.series) + + self.container = QWidget.createWindowContainer(self.bars) + + if not self.bars.hasContext(): + print("Couldn't initialize the OpenGL context.") + sys.exit(-1) + + camera = self.bars.scene().activeCamera() + camera.setYRotation(22.5) + + geometry = QGuiApplication.primaryScreen().geometry() + size = geometry.height() * 3 / 4 + self.container.setMinimumSize(size, size) + + self.container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + self.container.setFocusPolicy(Qt.StrongFocus) + self.setCentralWidget(self.container) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/datavisualization/datavisualization.pyproject b/examples/datavisualization/datavisualization.pyproject new file mode 100644 index 0000000..415133f --- /dev/null +++ b/examples/datavisualization/datavisualization.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["bars3d.py"] +} diff --git a/examples/declarative/declarative.pyproject b/examples/declarative/declarative.pyproject new file mode 100644 index 0000000..e64c1d9 --- /dev/null +++ b/examples/declarative/declarative.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["view.qml", "scrolling.py", "usingmodel.py"] +} diff --git a/examples/declarative/extending/chapter1-basics/app.qml b/examples/declarative/extending/chapter1-basics/app.qml new file mode 100644 index 0000000..190d024 --- /dev/null +++ b/examples/declarative/extending/chapter1-basics/app.qml @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: aPieChart + anchors.centerIn: parent + width: 100; height: 100 + name: "A simple pie chart" + color: "red" + } + + Text { + anchors { + bottom: parent.bottom; + horizontalCenter: parent.horizontalCenter; + bottomMargin: 20 + } + text: aPieChart.name + } +} +//![0] diff --git a/examples/declarative/extending/chapter1-basics/basics.py b/examples/declarative/extending/chapter1-basics/basics.py new file mode 100644 index 0000000..95ee363 --- /dev/null +++ b/examples/declarative/extending/chapter1-basics/basics.py @@ -0,0 +1,99 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +"""PySide2 port of the qml/tutorials/extending-qml/chapter1-basics example from Qt v5.x""" + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'utils')) +from utils import text_type + +from PySide2.QtCore import Property, Signal, QUrl +from PySide2.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide2.QtQml import qmlRegisterType +from PySide2.QtQuick import QQuickPaintedItem, QQuickView + +class PieChart (QQuickPaintedItem): + def __init__(self, parent = None): + QQuickPaintedItem.__init__(self, parent) + self._name = u'' + + def paint(self, painter): + pen = QPen(self.color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1), 90 * 16, 290 * 16) + + def getColor(self): + return self._color + + def setColor(self, value): + self._color = value + + def getName(self): + return self._name + + def setName(self, value): + self._name = value + + nameChanged = Signal() + + color = Property(QColor, getColor, setColor) + name = Property(text_type, getName, setName, notify=nameChanged) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart') + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlFile = os.path.join(os.path.dirname(__file__), 'app.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/extending/chapter1-basics/chapter1-basics.pyproject b/examples/declarative/extending/chapter1-basics/chapter1-basics.pyproject new file mode 100644 index 0000000..869556b --- /dev/null +++ b/examples/declarative/extending/chapter1-basics/chapter1-basics.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["basics.py", "app.qml"] +} diff --git a/examples/declarative/extending/chapter2-methods/app.qml b/examples/declarative/extending/chapter2-methods/app.qml new file mode 100644 index 0000000..3a44798 --- /dev/null +++ b/examples/declarative/extending/chapter2-methods/app.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: aPieChart + anchors.centerIn: parent + width: 100; height: 100 + color: "red" + + onChartCleared: console.log("The chart has been cleared") + } + + MouseArea { + anchors.fill: parent + onClicked: aPieChart.clearChart() + } + + Text { + anchors { + bottom: parent.bottom; + horizontalCenter: parent.horizontalCenter; + bottomMargin: 20 + } + text: "Click anywhere to clear the chart" + } +} +//![0] diff --git a/examples/declarative/extending/chapter2-methods/chapter2-methods.pyproject b/examples/declarative/extending/chapter2-methods/chapter2-methods.pyproject new file mode 100644 index 0000000..cdf33be --- /dev/null +++ b/examples/declarative/extending/chapter2-methods/chapter2-methods.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["methods.py", "app.qml"] +} diff --git a/examples/declarative/extending/chapter2-methods/methods.py b/examples/declarative/extending/chapter2-methods/methods.py new file mode 100644 index 0000000..1d02628 --- /dev/null +++ b/examples/declarative/extending/chapter2-methods/methods.py @@ -0,0 +1,104 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +"""PySide2 port of the qml/tutorials/extending-qml/chapter2-methods example from Qt v5.x""" + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'utils')) +from utils import text_type + +from PySide2.QtCore import Property, Signal, Slot, QUrl, Qt +from PySide2.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide2.QtQml import qmlRegisterType +from PySide2.QtQuick import QQuickPaintedItem, QQuickView + +class PieChart (QQuickPaintedItem): + def __init__(self, parent = None): + QQuickPaintedItem.__init__(self, parent) + self._name = u'' + + def paint(self, painter): + pen = QPen(self.color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1), 90 * 16, 290 * 16) + + def getColor(self): + return self._color + + def setColor(self, value): + self._color = value + + def getName(self): + return self._name + + def setName(self, value): + self._name = value + + color = Property(QColor, getColor, setColor) + name = Property(text_type, getName, setName) + chartCleared = Signal() + + @Slot() # This should be something like @Invokable + def clearChart(self): + self.setColor(Qt.transparent) + self.update() + self.chartCleared.emit() + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart') + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlFile = os.path.join(os.path.dirname(__file__), 'app.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/extending/chapter3-bindings/app.qml b/examples/declarative/extending/chapter3-bindings/app.qml new file mode 100644 index 0000000..277b897 --- /dev/null +++ b/examples/declarative/extending/chapter3-bindings/app.qml @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + Row { + anchors.centerIn: parent + spacing: 20 + + PieChart { + id: chartA + width: 100; height: 100 + color: "red" + } + + PieChart { + id: chartB + width: 100; height: 100 + color: chartA.color + } + } + + MouseArea { + anchors.fill: parent + onClicked: { chartA.color = "blue" } + } + + Text { + anchors { + bottom: parent.bottom; + horizontalCenter: parent.horizontalCenter; + bottomMargin: 20 + } + text: "Click anywhere to change the chart color" + } +} +//![0] diff --git a/examples/declarative/extending/chapter3-bindings/bindings.py b/examples/declarative/extending/chapter3-bindings/bindings.py new file mode 100644 index 0000000..f20fc0b --- /dev/null +++ b/examples/declarative/extending/chapter3-bindings/bindings.py @@ -0,0 +1,109 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +"""PySide2 port of the qml/tutorials/extending-qml/chapter3-bindings example from Qt v5.x""" + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'utils')) +from utils import text_type + +from PySide2.QtCore import Property, Signal, Slot, QUrl, Qt +from PySide2.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide2.QtQml import qmlRegisterType +from PySide2.QtQuick import QQuickPaintedItem, QQuickView + +class PieChart (QQuickPaintedItem): + def __init__(self, parent = None): + QQuickPaintedItem.__init__(self, parent) + self._name = u'' + self._color = QColor() + + def paint(self, painter): + pen = QPen(self._color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1), 90 * 16, 290 * 16) + + def getColor(self): + return self._color + + def setColor(self, value): + if value != self._color: + self._color = value + self.update() + self.colorChanged.emit() + + def getName(self): + return self._name + + def setName(self, value): + self._name = value + + colorChanged = Signal() + color = Property(QColor, getColor, setColor, notify=colorChanged) + name = Property(text_type, getName, setName) + chartCleared = Signal() + + @Slot() # This should be something like @Invokable + def clearChart(self): + self.setColor(Qt.transparent) + self.update() + self.chartCleared.emit() + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart') + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlFile = os.path.join(os.path.dirname(__file__), 'app.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/extending/chapter3-bindings/chapter3-bindings.pyproject b/examples/declarative/extending/chapter3-bindings/chapter3-bindings.pyproject new file mode 100644 index 0000000..6e21f86 --- /dev/null +++ b/examples/declarative/extending/chapter3-bindings/chapter3-bindings.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["app.qml", "bindings.py"] +} diff --git a/examples/declarative/extending/chapter4-customPropertyTypes/app.qml b/examples/declarative/extending/chapter4-customPropertyTypes/app.qml new file mode 100644 index 0000000..29ad37d --- /dev/null +++ b/examples/declarative/extending/chapter4-customPropertyTypes/app.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + id: chart + anchors.centerIn: parent + width: 100; height: 100 + + pieSlice: PieSlice { + anchors.fill: parent + color: "red" + } + } + + Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color) +} +//![0] diff --git a/examples/declarative/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject b/examples/declarative/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject new file mode 100644 index 0000000..af1cfef --- /dev/null +++ b/examples/declarative/extending/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["app.qml", "customPropertyTypes.py"] +} diff --git a/examples/declarative/extending/chapter4-customPropertyTypes/customPropertyTypes.py b/examples/declarative/extending/chapter4-customPropertyTypes/customPropertyTypes.py new file mode 100644 index 0000000..66e4dea --- /dev/null +++ b/examples/declarative/extending/chapter4-customPropertyTypes/customPropertyTypes.py @@ -0,0 +1,115 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +"""PySide2 port of the qml/tutorials/extending-qml/chapter4-customPropertyTypes example from Qt v5.x""" + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'utils')) +from utils import text_type + +from PySide2.QtCore import Property, QUrl +from PySide2.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide2.QtQml import qmlRegisterType +from PySide2.QtQuick import QQuickPaintedItem, QQuickView, QQuickItem + +class PieSlice (QQuickPaintedItem): + + def __init__(self, parent = None): + QQuickPaintedItem.__init__(self, parent) + self._color = QColor() + + def getColor(self): + return self._color + + def setColor(self, value): + self._color = value + + color = Property(QColor, getColor, setColor) + + def paint(self, painter): + pen = QPen(self._color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1), 90 * 16, 290 * 16) + +class PieChart (QQuickItem): + def __init__(self, parent = None): + QQuickItem.__init__(self, parent) + self._name = None + self._pieSlice = None + + def getName(self): + return self._name + + def setName(self, value): + self._name = value + + name = Property(text_type, getName, setName) + + def getPieSlice(self): + return self._pieSlice + + def setPieSlice(self, value): + self._pieSlice = value + self._pieSlice.setParentItem(self) + + pieSlice = Property(PieSlice, getPieSlice, setPieSlice) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart') + qmlRegisterType(PieSlice, "Charts", 1, 0, "PieSlice") + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlFile = os.path.join(os.path.dirname(__file__), 'app.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/extending/chapter5-listproperties/app.qml b/examples/declarative/extending/chapter5-listproperties/app.qml new file mode 100644 index 0000000..9ff6e3b --- /dev/null +++ b/examples/declarative/extending/chapter5-listproperties/app.qml @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import Charts 1.0 +import QtQuick 2.0 + +Item { + width: 300; height: 200 + + PieChart { + anchors.centerIn: parent + width: 100; height: 100 + + slices: [ + PieSlice { + anchors.fill: parent + color: "red" + fromAngle: 0; angleSpan: 110 + }, + PieSlice { + anchors.fill: parent + color: "black" + fromAngle: 110; angleSpan: 50 + }, + PieSlice { + anchors.fill: parent + color: "blue" + fromAngle: 160; angleSpan: 100 + } + ] + } +} +//![0] diff --git a/examples/declarative/extending/chapter5-listproperties/chapter5-listproperties.pyproject b/examples/declarative/extending/chapter5-listproperties/chapter5-listproperties.pyproject new file mode 100644 index 0000000..a3f89d5 --- /dev/null +++ b/examples/declarative/extending/chapter5-listproperties/chapter5-listproperties.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["app.qml", "listproperties.py"] +} diff --git a/examples/declarative/extending/chapter5-listproperties/listproperties.py b/examples/declarative/extending/chapter5-listproperties/listproperties.py new file mode 100644 index 0000000..659f8d5 --- /dev/null +++ b/examples/declarative/extending/chapter5-listproperties/listproperties.py @@ -0,0 +1,127 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +"""PySide2 port of the qml/tutorials/extending-qml/chapter5-listproperties example from Qt v5.x""" + +import sys, os +sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', '..', 'utils')) +from utils import text_type + +from PySide2.QtCore import Property, QUrl +from PySide2.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide2.QtQml import qmlRegisterType, ListProperty +from PySide2.QtQuick import QQuickPaintedItem, QQuickView, QQuickItem + +class PieSlice (QQuickPaintedItem): + def __init__(self, parent = None): + QQuickPaintedItem.__init__(self, parent) + self._color = QColor() + self._fromAngle = 0 + self._angleSpan = 0 + + def getColor(self): + return self._color + + def setColor(self, value): + self._color = value + + def getFromAngle(self): + return self._angle + + def setFromAngle(self, value): + self._fromAngle = value + + def getAngleSpan(self): + return self._angleSpan + + def setAngleSpan(self, value): + self._angleSpan = value + + color = Property(QColor, getColor, setColor) + fromAngle = Property(int, getFromAngle, setFromAngle) + angleSpan = Property(int, getAngleSpan, setAngleSpan) + + def paint(self, painter): + pen = QPen(self._color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1,1,-1,-1), self._fromAngle * 16, self._angleSpan * 16) + +class PieChart (QQuickItem): + def __init__(self, parent = None): + QQuickItem.__init__(self, parent) + self._name = u'' + self._slices = [] + + def getName(self): + return self._name + + def setName(self, value): + self._name = value + + name = Property(text_type, getName, setName) + + def appendSlice(self, _slice): + _slice.setParentItem(self) + self._slices.append(_slice) + + slices = ListProperty(PieSlice, appendSlice) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + qmlRegisterType(PieChart, 'Charts', 1, 0, 'PieChart') + qmlRegisterType(PieSlice, "Charts", 1, 0, "PieSlice") + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlFile = os.path.join(os.path.dirname(__file__), 'app.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/scrolling.py b/examples/declarative/scrolling.py new file mode 100644 index 0000000..b4a0ee2 --- /dev/null +++ b/examples/declarative/scrolling.py @@ -0,0 +1,71 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QUrl +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +# This example uses a QML file to show a scrolling list containing +# all the items listed in dataList. + +if __name__ == '__main__': + dataList = ["Item 1", "Item 2", "Item 3", "Item 4"] + + app = QGuiApplication(sys.argv) + view = QQuickView() + + ctxt = view.rootContext() + ctxt.setContextProperty("myModel", dataList) + + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + + app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view diff --git a/examples/declarative/signals/pytoqml1/main.py b/examples/declarative/signals/pytoqml1/main.py new file mode 100644 index 0000000..218d885 --- /dev/null +++ b/examples/declarative/signals/pytoqml1/main.py @@ -0,0 +1,70 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QTimer, QUrl +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + timer = QTimer() + timer.start(2000) + + view = QQuickView() + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + root = view.rootObject() + + timer.timeout.connect(root.updateRotater) + + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/signals/pytoqml1/pytoqml1.pyproject b/examples/declarative/signals/pytoqml1/pytoqml1.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/signals/pytoqml1/pytoqml1.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/signals/pytoqml1/view.qml b/examples/declarative/signals/pytoqml1/view.qml new file mode 100644 index 0000000..a35b486 --- /dev/null +++ b/examples/declarative/signals/pytoqml1/view.qml @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: page + + function updateRotater() { + rotater.angle = rotater.angle + 45 + } + + width: 500; height: 200 + color: "lightgray" + + Rectangle { + id: rotater + property real angle : 0 + x: 240 + width: 100; height: 10 + color: "black" + y: 95 + + transform: Rotation { + origin.x: 10; origin.y: 5 + angle: rotater.angle + Behavior on angle { + SpringAnimation { + spring: 1.4 + damping: .05 + } + } + } + } + +} diff --git a/examples/declarative/signals/qmltopy1/main.py b/examples/declarative/signals/qmltopy1/main.py new file mode 100644 index 0000000..1342dba --- /dev/null +++ b/examples/declarative/signals/qmltopy1/main.py @@ -0,0 +1,87 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QObject, QUrl, Slot +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +class Console(QObject): + """Output stuff on the console.""" + + @Slot(str) + @Slot('double') + def output(self, s): + print(s) + + @Slot(str) + def outputStr(self, s): + print(s) + + @Slot('double') + def outputFloat(self, x): + print(x) + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + + # Instantiate the Python object. + con = Console() + + # Expose the object to QML. + context = view.rootContext() + context.setContextProperty("con", con) + + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/signals/qmltopy1/qmltopy1.pyproject b/examples/declarative/signals/qmltopy1/qmltopy1.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/signals/qmltopy1/qmltopy1.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/signals/qmltopy1/view.qml b/examples/declarative/signals/qmltopy1/view.qml new file mode 100644 index 0000000..32a66ef --- /dev/null +++ b/examples/declarative/signals/qmltopy1/view.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +import QtQuick 2.0 + +Rectangle { + id: page + + width: 500; height: 200 + color: "lightgray" + + Text { + id: helloText + text: "Hello world!" + anchors.horizontalCenter: page.horizontalCenter + y: 30 + font.pointSize: 24; font.bold: true + } + + Rectangle { + id: button + width: 150; height: 40 + color: "darkgray" + anchors.horizontalCenter: page.horizontalCenter + y: 120 + MouseArea { + id: buttonMouseArea + objectName: "buttonMouseArea" + anchors.fill: parent + onClicked: { + // once the "con" context has been declared, + // slots can be called like functions + con.outputFloat(123) + con.outputStr("foobar") + con.output(helloText.x) + con.output(helloText.text) + } + } + Text { + id: buttonText + text: "Press me!" + anchors.horizontalCenter: button.horizontalCenter + anchors.verticalCenter: button.verticalCenter + font.pointSize: 16 + } + } +} diff --git a/examples/declarative/signals/qmltopy2/main.py b/examples/declarative/signals/qmltopy2/main.py new file mode 100644 index 0000000..9b0aca8 --- /dev/null +++ b/examples/declarative/signals/qmltopy2/main.py @@ -0,0 +1,79 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QObject, QUrl, Slot +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +class RotateValue(QObject): + def __init__(self): + super(RotateValue,self).__init__() + self.r = 0 + + # If a slot returns a value, the return value type must be explicitly + # defined in the decorator. + @Slot(result=int) + def val(self): + self.r = self.r + 10 + return self.r + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + + rotatevalue = RotateValue() + context = view.rootContext() + context.setContextProperty("rotatevalue", rotatevalue) + + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/signals/qmltopy2/qmltopy2.pyproject b/examples/declarative/signals/qmltopy2/qmltopy2.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/signals/qmltopy2/qmltopy2.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/signals/qmltopy2/view.qml b/examples/declarative/signals/qmltopy2/view.qml new file mode 100644 index 0000000..6fe6087 --- /dev/null +++ b/examples/declarative/signals/qmltopy2/view.qml @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: page + + width: 500; height: 200 + color: "lightgray" + + Text { + id: helloText + text: "Hello world!" + anchors.horizontalCenter: page.horizontalCenter + y: 30 + font.pointSize: 24; font.bold: true + } + + + Rectangle { + id: button + width: 150; height: 40 + color: "darkgray" + anchors.horizontalCenter: page.horizontalCenter + y: 120 + MouseArea { + id: buttonMouseArea + objectName: "buttonMouseArea" + anchors.fill: parent + onClicked: { + helloText.rotation = rotatevalue.val() + } + } + Text { + id: buttonText + text: "Press me!" + anchors.horizontalCenter: button.horizontalCenter + anchors.verticalCenter: button.verticalCenter + font.pointSize: 16 + } + } +} diff --git a/examples/declarative/signals/qmltopy3/main.py b/examples/declarative/signals/qmltopy3/main.py new file mode 100644 index 0000000..485dd62 --- /dev/null +++ b/examples/declarative/signals/qmltopy3/main.py @@ -0,0 +1,70 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QUrl +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +def sayThis(s): + print(s) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + + root = view.rootObject() + root.textRotationChanged.connect(sayThis) + root.buttonClicked.connect(lambda: sayThis("clicked button (QML top-level signal)")) + + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/signals/qmltopy3/qmltopy3.pyproject b/examples/declarative/signals/qmltopy3/qmltopy3.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/signals/qmltopy3/qmltopy3.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/signals/qmltopy3/view.qml b/examples/declarative/signals/qmltopy3/view.qml new file mode 100644 index 0000000..9657cd4 --- /dev/null +++ b/examples/declarative/signals/qmltopy3/view.qml @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: page + + signal buttonClicked + signal textRotationChanged(double rot) + + width: 500; height: 200 + color: "lightgray" + + Text { + id: helloText + text: "Hello world!" + y: 30 + x: page.width/2-width/2 + font.pointSize: 24; font.bold: true + onRotationChanged: textRotationChanged(rotation) + + states: State { + name: "down"; when: buttonMouseArea.pressed === true + PropertyChanges { + target: helloText; + rotation: 180; + y: 100; + } + } + + transitions: Transition { + from: ""; to: "down"; reversible: true + ParallelAnimation { + NumberAnimation { + properties: "y,rotation" + duration: 500 + easing.type: Easing.InOutQuad + } + } + } + } + + Rectangle { + id: button + width: 150; height: 40 + color: "darkgray" + anchors.horizontalCenter: page.horizontalCenter + y: 120 + MouseArea { + id: buttonMouseArea + objectName: "buttonMouseArea" + anchors.fill: parent + onClicked: { + buttonClicked() + } + } + Text { + id: buttonText + text: "Press me!" + anchors.horizontalCenter: button.horizontalCenter + anchors.verticalCenter: button.verticalCenter + font.pointSize: 16 + } + } +} diff --git a/examples/declarative/signals/qmltopy4/main.py b/examples/declarative/signals/qmltopy4/main.py new file mode 100644 index 0000000..d165e61 --- /dev/null +++ b/examples/declarative/signals/qmltopy4/main.py @@ -0,0 +1,70 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QObject, QUrl +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +def sayThis(s): + print(s) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + + root = view.rootObject() + button = root.findChild(QObject, "buttonMouseArea") + button.clicked.connect(lambda: sayThis("clicked button (signal directly connected)")) + + view.show() + res = app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/declarative/signals/qmltopy4/qmltopy4.pyproject b/examples/declarative/signals/qmltopy4/qmltopy4.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/signals/qmltopy4/qmltopy4.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/signals/qmltopy4/view.qml b/examples/declarative/signals/qmltopy4/view.qml new file mode 100644 index 0000000..0d1349f --- /dev/null +++ b/examples/declarative/signals/qmltopy4/view.qml @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: page + + width: 500; height: 200 + color: "lightgray" + + Rectangle { + id: button + width: 150; height: 40 + color: "darkgray" + anchors.horizontalCenter: page.horizontalCenter + anchors.verticalCenter: page.verticalCenter + MouseArea { + id: buttonMouseArea + objectName: "buttonMouseArea" + anchors.fill: parent + } + Text { + id: buttonText + text: "Press me!" + anchors.horizontalCenter: button.horizontalCenter + anchors.verticalCenter: button.verticalCenter + font.pointSize: 16 + } + } +} diff --git a/examples/declarative/textproperties/main.py b/examples/declarative/textproperties/main.py new file mode 100644 index 0000000..2f9b987 --- /dev/null +++ b/examples/declarative/textproperties/main.py @@ -0,0 +1,113 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from os.path import abspath, dirname, join + +from PySide2.QtCore import QObject, Slot +from PySide2.QtGui import QGuiApplication +from PySide2.QtQml import QQmlApplicationEngine +from PySide2.QtQuickControls2 import QQuickStyle + + +class Bridge(QObject): + + @Slot(str, result=str) + def getColor(self, s): + if s.lower() == "red": + return "#ef9a9a" + elif s.lower() == "green": + return "#a5d6a7" + elif s.lower() == "blue": + return "#90caf9" + else: + return "white" + + @Slot(float, result=int) + def getSize(self, s): + size = int(s * 34) + if size <= 0: + return 1 + else: + return size + + @Slot(str, result=bool) + def getItalic(self, s): + if s.lower() == "italic": + return True + else: + return False + + @Slot(str, result=bool) + def getBold(self, s): + if s.lower() == "bold": + return True + else: + return False + + @Slot(str, result=bool) + def getUnderline(self, s): + if s.lower() == "underline": + return True + else: + return False + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + QQuickStyle.setStyle("Material") + engine = QQmlApplicationEngine() + + # Instance of the Python object + bridge = Bridge() + + # Expose the Python object to QML + context = engine.rootContext() + context.setContextProperty("con", bridge) + + # Get the path of the current directory, and then add the name + # of the QML file, to load it. + qmlFile = join(dirname(__file__), 'view.qml') + engine.load(abspath(qmlFile)) + + if not engine.rootObjects(): + sys.exit(-1) + + sys.exit(app.exec_()) diff --git a/examples/declarative/textproperties/textproperties.pyproject b/examples/declarative/textproperties/textproperties.pyproject new file mode 100644 index 0000000..e6f087c --- /dev/null +++ b/examples/declarative/textproperties/textproperties.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "view.qml"] +} diff --git a/examples/declarative/textproperties/view.qml b/examples/declarative/textproperties/view.qml new file mode 100644 index 0000000..98289a1 --- /dev/null +++ b/examples/declarative/textproperties/view.qml @@ -0,0 +1,191 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +import QtQuick 2.0 +import QtQuick.Layouts 1.11 +import QtQuick.Controls 2.1 +import QtQuick.Window 2.1 +import QtQuick.Controls.Material 2.1 + +ApplicationWindow { + id: page + width: 800 + height: 400 + visible: true + Material.theme: Material.Dark + Material.accent: Material.Red + + GridLayout { + id: grid + columns: 2 + rows: 3 + + ColumnLayout { + spacing: 2 + Layout.columnSpan: 1 + Layout.preferredWidth: 400 + + Text { + id: leftlabel + Layout.alignment: Qt.AlignHCenter + color: "white" + font.pointSize: 16 + text: "Qt for Python" + Layout.preferredHeight: 100 + Material.accent: Material.Green + } + + RadioButton { + id: italic + Layout.alignment: Qt.AlignLeft + text: "Italic" + onToggled: { + leftlabel.font.italic = con.getItalic(italic.text) + leftlabel.font.bold = con.getBold(italic.text) + leftlabel.font.underline = con.getUnderline(italic.text) + + } + } + RadioButton { + id: bold + Layout.alignment: Qt.AlignLeft + text: "Bold" + onToggled: { + leftlabel.font.italic = con.getItalic(bold.text) + leftlabel.font.bold = con.getBold(bold.text) + leftlabel.font.underline = con.getUnderline(bold.text) + } + } + RadioButton { + id: underline + Layout.alignment: Qt.AlignLeft + text: "Underline" + onToggled: { + leftlabel.font.italic = con.getItalic(underline.text) + leftlabel.font.bold = con.getBold(underline.text) + leftlabel.font.underline = con.getUnderline(underline.text) + } + } + RadioButton { + id: noneradio + Layout.alignment: Qt.AlignLeft + text: "None" + checked: true + onToggled: { + leftlabel.font.italic = con.getItalic(noneradio.text) + leftlabel.font.bold = con.getBold(noneradio.text) + leftlabel.font.underline = con.getUnderline(noneradio.text) + } + } + } + + ColumnLayout { + id: rightcolumn + spacing: 2 + Layout.columnSpan: 1 + Layout.preferredWidth: 400 + Layout.preferredHeight: 400 + Layout.fillWidth: true + + RowLayout { + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + + + Button { + id: red + text: "Red" + highlighted: true + Material.accent: Material.Red + onClicked: { + leftlabel.color = con.getColor(red.text) + } + } + Button { + id: green + text: "Green" + highlighted: true + Material.accent: Material.Green + onClicked: { + leftlabel.color = con.getColor(green.text) + } + } + Button { + id: blue + text: "Blue" + highlighted: true + Material.accent: Material.Blue + onClicked: { + leftlabel.color = con.getColor(blue.text) + } + } + Button { + id: nonebutton + text: "None" + highlighted: true + Material.accent: Material.BlueGrey + onClicked: { + leftlabel.color = con.getColor(nonebutton.text) + } + } + } + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter + Text { + id: rightlabel + color: "white" + Layout.alignment: Qt.AlignLeft + text: "Font size" + Material.accent: Material.White + } + Slider { + width: rightcolumn.width*0.6 + Layout.alignment: Qt.AlignRight + id: slider + value: 0.5 + onValueChanged: { + leftlabel.font.pointSize = con.getSize(value) + } + } + } + } + } +} diff --git a/examples/declarative/usingmodel.py b/examples/declarative/usingmodel.py new file mode 100644 index 0000000..9b67bd0 --- /dev/null +++ b/examples/declarative/usingmodel.py @@ -0,0 +1,100 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +import os +import sys +from PySide2.QtCore import QAbstractListModel, Qt, QUrl, QByteArray +from PySide2.QtGui import QGuiApplication +from PySide2.QtQuick import QQuickView + +class PersonModel (QAbstractListModel): + MyRole = Qt.UserRole + 1 + + def __init__(self, parent = None): + QAbstractListModel.__init__(self, parent) + self._data = [] + + def roleNames(self): + roles = { + PersonModel.MyRole : QByteArray(b'modelData'), + Qt.DisplayRole : QByteArray(b'display') + } + return roles + + def rowCount(self, index): + return len(self._data) + + def data(self, index, role): + d = self._data[index.row()] + + if role == Qt.DisplayRole: + return d['name'] + elif role == Qt.DecorationRole: + return Qt.black + elif role == PersonModel.MyRole: + return d['myrole'] + return None + + def populate(self): + self._data.append({'name':'Qt', 'myrole':'role1'}) + self._data.append({'name':'PySide', 'myrole':'role2'}) + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + + myModel = PersonModel() + myModel.populate() + + view.rootContext().setContextProperty("myModel", myModel) + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + + app.exec_() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view diff --git a/examples/declarative/view.qml b/examples/declarative/view.qml new file mode 100644 index 0000000..8eb4f7f --- /dev/null +++ b/examples/declarative/view.qml @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +ListView { + width: 100 + height: 100 + anchors.fill: parent + model: myModel + delegate: Component { + Rectangle { + height: 25 + width: 100 + Text { + function displayText() { + var result = "" + if (typeof display !== "undefined") + result = display + ": " + result += modelData + return result + } + + text: displayText() + } + } + } +} diff --git a/examples/examples.pyproject b/examples/examples.pyproject new file mode 100644 index 0000000..330884f --- /dev/null +++ b/examples/examples.pyproject @@ -0,0 +1,106 @@ +{ + "files": ["charts/memoryusage.py", + "corelib/threads/mandelbrot.py", + "corelib/tools/codecs/codecs.py", + "corelib/tools/regexp.py", + "corelib/tools/settingseditor/settingseditor.py", + "declarative/extending/chapter1-basics/basics.py", + "declarative/extending/chapter2-methods/methods.py", + "declarative/extending/chapter3-bindings/bindings.py", + "declarative/extending/chapter4-customPropertyTypes/customPropertyTypes.py", + "declarative/extending/chapter5-listproperties/listproperties.py", + "declarative/scrolling.py", + "declarative/signals/pytoqml1/main.py", + "declarative/signals/qmltopy1/main.py", + "declarative/signals/qmltopy2/main.py", + "declarative/signals/qmltopy3/main.py", + "declarative/signals/qmltopy4/main.py", + "declarative/usingmodel.py", + "installer_test/hello.py", + "macextras/macpasteboardmime.py", + "multimedia/audiooutput.py", + "multimedia/camera.py", + "multimedia/player.py", + "network/blockingfortuneclient.py", + "network/fortuneclient.py", + "network/fortuneserver.py", + "network/threadedfortuneserver.py", + "opengl/2dpainting.py", + "opengl/grabber.py", + "opengl/hellogl.py", + "opengl/overpainting.py", + "opengl/samplebuffers.py", + "opengl/textures/textures.py", + "script/helloscript.py", + "texttospeech/texttospeech.py", + "tutorial/t1.py", + "tutorial/t10.py", + "tutorial/t11.py", + "tutorial/t12.py", + "tutorial/t13.py", + "tutorial/t14.py", + "tutorial/t2.py", + "tutorial/t3.py", + "tutorial/t4.py", + "tutorial/t5.py", + "tutorial/t6.py", + "tutorial/t7.py", + "tutorial/t8.py", + "tutorial/t9.py", + "webenginewidgets/simplebrowser.py", + "widgets/animation/animatedtiles/animatedtiles.py", + "widgets/animation/appchooser/appchooser.py", + "widgets/animation/easing/easing.py", + "widgets/animation/states/states.py", + "widgets/dialogs/classwizard/classwizard.py", + "widgets/dialogs/extension.py", + "widgets/dialogs/findfiles.py", + "widgets/dialogs/standarddialogs.py", + "widgets/dialogs/trivialwizard.py", + "widgets/draganddrop/draggabletext/draggabletext.py", + "widgets/effects/lighting.py", + "widgets/graphicsview/anchorlayout.py", + "widgets/graphicsview/collidingmice/collidingmice.py", + "widgets/graphicsview/diagramscene/diagramscene.py", + "widgets/graphicsview/dragdroprobot/dragdroprobot.py", + "widgets/graphicsview/elasticnodes.py", + "widgets/itemviews/addressbook/adddialogwidget.py", + "widgets/itemviews/addressbook/addressbook.py", + "widgets/itemviews/addressbook/addresswidget.py", + "widgets/itemviews/addressbook/newaddresstab.py", + "widgets/itemviews/addressbook/tablemodel.py", + "widgets/itemviews/basicsortfiltermodel.py", + "widgets/itemviews/fetchmore.py", + "widgets/itemviews/stardelegate/stardelegate.py", + "widgets/itemviews/stardelegate/stareditor.py", + "widgets/itemviews/stardelegate/starrating.py", + "widgets/layouts/basiclayouts.py", + "widgets/layouts/dynamiclayouts.py", + "widgets/layouts/flowlayout.py", + "widgets/mainwindows/application/application.py", + "widgets/mainwindows/dockwidgets/dockwidgets.py", + "widgets/mainwindows/mdi/mdi.py", + "widgets/painting/basicdrawing/basicdrawing.py", + "widgets/painting/concentriccircles.py", + "widgets/richtext/orderform.py", + "widgets/richtext/syntaxhighlighter.py", + "widgets/richtext/syntaxhighlighter/syntaxhighlighter.py", + "widgets/richtext/textobject/textobject.py", + "widgets/state-machine/eventtrans.py", + "widgets/state-machine/factstates.py", + "widgets/state-machine/pingpong.py", + "widgets/state-machine/rogue.py", + "widgets/state-machine/trafficlight.py", + "widgets/state-machine/twowaybutton.py", + "widgets/tutorials/addressbook/part1.py", + "widgets/tutorials/addressbook/part2.py", + "widgets/tutorials/addressbook/part3.py", + "widgets/tutorials/addressbook/part4.py", + "widgets/tutorials/addressbook/part5.py", + "widgets/tutorials/addressbook/part6.py", + "widgets/tutorials/addressbook/part7.py", + "widgets/widgets/hellogl_openglwidget_legacy.py", + "widgets/widgets/tetrix.py", + "xml/dombookmarks/dombookmarks.py", + "xmlpatterns/schema/schema.py"] +} diff --git a/examples/external/matplotlib/requirements.txt b/examples/external/matplotlib/requirements.txt new file mode 100644 index 0000000..6ccafc3 --- /dev/null +++ b/examples/external/matplotlib/requirements.txt @@ -0,0 +1 @@ +matplotlib diff --git a/examples/external/matplotlib/widget_3dplot.py b/examples/external/matplotlib/widget_3dplot.py new file mode 100644 index 0000000..b964056 --- /dev/null +++ b/examples/external/matplotlib/widget_3dplot.py @@ -0,0 +1,242 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +import numpy as np +from matplotlib.backends.backend_qt5agg import FigureCanvas +from matplotlib.figure import Figure +from mpl_toolkits.mplot3d import axes3d +from PySide2.QtCore import Qt, Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import (QAction, QApplication, QComboBox, QHBoxLayout, + QHeaderView, QLabel, QMainWindow, QSlider, + QTableWidget, QTableWidgetItem, QVBoxLayout, + QWidget) + + +"""This example implements the interaction between Qt Widgets and a 3D +matplotlib plot""" + + +class ApplicationWindow(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + + self.column_names = ["Column A", "Column B", "Column C"] + + # Central widget + self._main = QWidget() + self.setCentralWidget(self._main) + + # Main menu bar + self.menu = self.menuBar() + self.menu_file = self.menu.addMenu("File") + exit = QAction("Exit", self, triggered=qApp.quit) + self.menu_file.addAction(exit) + + self.menu_about = self.menu.addMenu("&About") + about = QAction("About Qt", self, shortcut=QKeySequence(QKeySequence.HelpContents), + triggered=qApp.aboutQt) + self.menu_about.addAction(about) + + # Figure (Left) + self.fig = Figure(figsize=(5, 3)) + self.canvas = FigureCanvas(self.fig) + + # Sliders (Left) + self.slider_azim = QSlider(minimum=0, maximum=360, orientation=Qt.Horizontal) + self.slider_elev = QSlider(minimum=0, maximum=360, orientation=Qt.Horizontal) + + self.slider_azim_layout = QHBoxLayout() + self.slider_azim_layout.addWidget(QLabel("{}".format(self.slider_azim.minimum()))) + self.slider_azim_layout.addWidget(self.slider_azim) + self.slider_azim_layout.addWidget(QLabel("{}".format(self.slider_azim.maximum()))) + + self.slider_elev_layout = QHBoxLayout() + self.slider_elev_layout.addWidget(QLabel("{}".format(self.slider_elev.minimum()))) + self.slider_elev_layout.addWidget(self.slider_elev) + self.slider_elev_layout.addWidget(QLabel("{}".format(self.slider_elev.maximum()))) + + # Table (Right) + self.table = QTableWidget() + header = self.table.horizontalHeader() + header.setSectionResizeMode(QHeaderView.Stretch) + + # ComboBox (Right) + self.combo = QComboBox() + self.combo.addItems(["Wired", "Surface", "Triangular Surface", "Sphere"]) + + # Right layout + rlayout = QVBoxLayout() + rlayout.setContentsMargins(1, 1, 1, 1) + rlayout.addWidget(QLabel("Plot type:")) + rlayout.addWidget(self.combo) + rlayout.addWidget(self.table) + + # Left layout + llayout = QVBoxLayout() + rlayout.setContentsMargins(1, 1, 1, 1) + llayout.addWidget(self.canvas, 88) + llayout.addWidget(QLabel("Azimuth:"), 1) + llayout.addLayout(self.slider_azim_layout, 5) + llayout.addWidget(QLabel("Elevation:"), 1) + llayout.addLayout(self.slider_elev_layout, 5) + + # Main layout + layout = QHBoxLayout(self._main) + layout.addLayout(llayout, 70) + layout.addLayout(rlayout, 30) + + # Signal and Slots connections + self.combo.currentTextChanged.connect(self.combo_option) + self.slider_azim.valueChanged.connect(self.rotate_azim) + self.slider_elev.valueChanged.connect(self.rotate_elev) + + # Initial setup + self.plot_wire() + self._ax.view_init(30, 30) + self.slider_azim.setValue(30) + self.slider_elev.setValue(30) + self.fig.canvas.mpl_connect("button_release_event", self.on_click) + + # Matplotlib slot method + def on_click(self, event): + azim, elev = self._ax.azim, self._ax.elev + self.slider_azim.setValue(azim + 180) + self.slider_elev.setValue(elev + 180) + + # Utils methods + + def set_table_data(self, X, Y, Z): + for i in range(len(X)): + self.table.setItem(i, 0, QTableWidgetItem("{:.2f}".format(X[i]))) + self.table.setItem(i, 1, QTableWidgetItem("{:.2f}".format(Y[i]))) + self.table.setItem(i, 2, QTableWidgetItem("{:.2f}".format(Z[i]))) + + def set_canvas_table_configuration(self, row_count, data): + self.fig.set_canvas(self.canvas) + self._ax = self.canvas.figure.add_subplot(projection="3d") + + self._ax.set_xlabel(self.column_names[0]) + self._ax.set_ylabel(self.column_names[1]) + self._ax.set_zlabel(self.column_names[2]) + + self.table.setRowCount(row_count) + self.table.setColumnCount(3) + self.table.setHorizontalHeaderLabels(self.column_names) + self.set_table_data(data[0], data[1], data[2]) + + # Plot methods + + def plot_wire(self): + # Data + self.X, self.Y, self.Z = axes3d.get_test_data(0.03) + + self.set_canvas_table_configuration(len(self.X[0]), (self.X[0], self.Y[0], self.Z[0])) + self._ax.plot_wireframe(self.X, self.Y, self.Z, rstride=10, cstride=10, cmap="viridis") + self.canvas.draw() + + def plot_surface(self): + # Data + self.X, self.Y = np.meshgrid(np.linspace(-6, 6, 30), np.linspace(-6, 6, 30)) + self.Z = np.sin(np.sqrt(self.X ** 2 + self.Y ** 2)) + + self.set_canvas_table_configuration(len(self.X[0]), (self.X[0], self.Y[0], self.Z[0])) + self._ax.plot_surface(self.X, self.Y, self.Z, + rstride=1, cstride=1, cmap="viridis", edgecolor="none") + self.canvas.draw() + + def plot_triangular_surface(self): + # Data + radii = np.linspace(0.125, 1.0, 8) + angles = np.linspace(0, 2 * np.pi, 36, endpoint=False)[..., np.newaxis] + self.X = np.append(0, (radii * np.cos(angles)).flatten()) + self.Y = np.append(0, (radii * np.sin(angles)).flatten()) + self.Z = np.sin(-self.X * self.Y) + + self.set_canvas_table_configuration(len(self.X), (self.X, self.Y, self.Z)) + self._ax.plot_trisurf(self.X, self.Y, self.Z, linewidth=0.2, antialiased=True) + self.canvas.draw() + + def plot_sphere(self): + # Data + u = np.linspace(0, 2 * np.pi, 100) + v = np.linspace(0, np.pi, 100) + self.X = 10 * np.outer(np.cos(u), np.sin(v)) + self.Y = 10 * np.outer(np.sin(u), np.sin(v)) + self.Z = 9 * np.outer(np.ones(np.size(u)), np.cos(v)) + + self.set_canvas_table_configuration(len(self.X), (self.X[0], self.Y[0], self.Z[0])) + self._ax.plot_surface(self.X, self.Y, self.Z) + self.canvas.draw() + + # Slots + + @Slot() + def combo_option(self, text): + if text == "Wired": + self.plot_wire() + elif text == "Surface": + self.plot_surface() + elif text == "Triangular Surface": + self.plot_triangular_surface() + elif text == "Sphere": + self.plot_sphere() + + @Slot() + def rotate_azim(self, value): + self._ax.view_init(self._ax.elev, value) + self.fig.set_canvas(self.canvas) + self.canvas.draw() + + @Slot() + def rotate_elev(self, value): + self._ax.view_init(value, self._ax.azim) + self.fig.set_canvas(self.canvas) + self.canvas.draw() + + +if __name__ == "__main__": + app = QApplication(sys.argv) + w = ApplicationWindow() + w.setFixedSize(1280, 720) + w.show() + app.exec_() diff --git a/examples/external/opencv/requirements.txt b/examples/external/opencv/requirements.txt new file mode 100644 index 0000000..0dd006b --- /dev/null +++ b/examples/external/opencv/requirements.txt @@ -0,0 +1 @@ +opencv-python diff --git a/examples/external/opencv/webcam_pattern_detection.py b/examples/external/opencv/webcam_pattern_detection.py new file mode 100644 index 0000000..5532616 --- /dev/null +++ b/examples/external/opencv/webcam_pattern_detection.py @@ -0,0 +1,207 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import sys +import time + +import cv2 +from PySide2.QtCore import Qt, QThread, Signal, Slot +from PySide2.QtGui import QImage, QKeySequence, QPixmap +from PySide2.QtWidgets import (QAction, QApplication, QComboBox, QGroupBox, + QHBoxLayout, QLabel, QMainWindow, QPushButton, + QSizePolicy, QVBoxLayout, QWidget) + + +"""This example uses the video from a webcam to apply pattern +detection from the OpenCV module. e.g.: face, eyes, body, etc.""" + + +class Thread(QThread): + updateFrame = Signal(QImage) + + def __init__(self, parent=None): + QThread.__init__(self, parent) + self.trained_file = None + self.status = True + self.cap = True + + def set_file(self, fname): + # The data comes with the 'opencv-python' module + self.trained_file = os.path.join(cv2.data.haarcascades, fname) + + def run(self): + self.cap = cv2.VideoCapture(0) + while self.status: + cascade = cv2.CascadeClassifier(self.trained_file) + ret, frame = self.cap.read() + if not ret: + continue + + # Reading frame in gray scale to process the pattern + gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) + + detections = cascade.detectMultiScale(gray_frame, scaleFactor=1.1, + minNeighbors=5, minSize=(30, 30)) + + # Drawing green rectangle around the pattern + for (x, y, w, h) in detections: + pos_ori = (x, y) + pos_end = (x + w, y + h) + color = (0, 255, 0) + cv2.rectangle(frame, pos_ori, pos_end, color, 2) + + # Reading the image in RGB to display it + color_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) + + # Creating and scaling QImage + h, w, ch = color_frame.shape + img = QImage(color_frame.data, w, h, ch * w, QImage.Format_RGB888) + scaled_img = img.scaled(640, 480, Qt.KeepAspectRatio) + + # Emit signal + self.updateFrame.emit(scaled_img) + sys.exit(-1) + + +class Window(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + # Title and dimensions + self.setWindowTitle("Patterns detection") + self.setGeometry(0, 0, 800, 500) + + # Main menu bar + self.menu = self.menuBar() + self.menu_file = self.menu.addMenu("File") + exit = QAction("Exit", self, triggered=qApp.quit) + self.menu_file.addAction(exit) + + self.menu_about = self.menu.addMenu("&About") + about = QAction("About Qt", self, shortcut=QKeySequence(QKeySequence.HelpContents), + triggered=qApp.aboutQt) + self.menu_about.addAction(about) + + # Create a label for the display camera + self.label = QLabel(self) + self.label.setFixedSize(640, 480) + + # Thread in charge of updating the image + self.th = Thread(self) + self.th.finished.connect(self.close) + self.th.updateFrame.connect(self.setImage) + + # Model group + self.group_model = QGroupBox("Trained model") + self.group_model.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + model_layout = QHBoxLayout() + + self.combobox = QComboBox() + for xml_file in os.listdir(cv2.data.haarcascades): + if xml_file.endswith(".xml"): + self.combobox.addItem(xml_file) + + model_layout.addWidget(QLabel("File:"), 10) + model_layout.addWidget(self.combobox, 90) + self.group_model.setLayout(model_layout) + + # Buttons layout + buttons_layout = QHBoxLayout() + self.button1 = QPushButton("Start") + self.button2 = QPushButton("Stop/Close") + self.button1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.button2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + buttons_layout.addWidget(self.button2) + buttons_layout.addWidget(self.button1) + + right_layout = QHBoxLayout() + right_layout.addWidget(self.group_model, 1) + right_layout.addLayout(buttons_layout, 1) + + # Main layout + layout = QVBoxLayout() + layout.addWidget(self.label) + layout.addLayout(right_layout) + + # Central widget + widget = QWidget(self) + widget.setLayout(layout) + self.setCentralWidget(widget) + + # Connections + self.button1.clicked.connect(self.start) + self.button2.clicked.connect(self.kill_thread) + self.button2.setEnabled(False) + self.combobox.currentTextChanged.connect(self.set_model) + + @Slot() + def set_model(self, text): + self.th.set_file(text) + + @Slot() + def kill_thread(self): + print("Finishing...") + self.button2.setEnabled(False) + self.button1.setEnabled(True) + self.th.cap.release() + cv2.destroyAllWindows() + self.status = False + self.th.terminate() + # Give time for the thread to finish + time.sleep(1) + + @Slot() + def start(self): + print("Starting...") + self.button2.setEnabled(True) + self.button1.setEnabled(False) + self.th.set_file(self.combobox.currentText()) + self.th.start() + + @Slot(QImage) + def setImage(self, image): + self.label.setPixmap(QPixmap.fromImage(image)) + + +if __name__ == "__main__": + app = QApplication() + w = Window() + w.show() + sys.exit(app.exec_()) diff --git a/examples/external/scikit/requirements.txt b/examples/external/scikit/requirements.txt new file mode 100644 index 0000000..391ca2f --- /dev/null +++ b/examples/external/scikit/requirements.txt @@ -0,0 +1 @@ +scikit-image diff --git a/examples/external/scikit/staining_colors_separation.py b/examples/external/scikit/staining_colors_separation.py new file mode 100644 index 0000000..051b2bc --- /dev/null +++ b/examples/external/scikit/staining_colors_separation.py @@ -0,0 +1,184 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +import numpy as np +from matplotlib.backends.backend_qt5agg import FigureCanvas +from matplotlib.colors import LinearSegmentedColormap +from matplotlib.figure import Figure +from PySide2.QtCore import Qt, Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import (QAction, QApplication, QHBoxLayout, QLabel, + QMainWindow, QPushButton, QSizePolicy, + QVBoxLayout, QWidget) +from skimage import data +from skimage.color import rgb2hed +from skimage.exposure import rescale_intensity + + +class ApplicationWindow(QMainWindow): + """ + Example based on the example by 'scikit-image' gallery: + "Immunohistochemical staining colors separation" + https://scikit-image.org/docs/stable/auto_examples/color_exposure/plot_ihc_color_separation.html + """ + + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + self._main = QWidget() + self.setCentralWidget(self._main) + + # Main menu bar + self.menu = self.menuBar() + self.menu_file = self.menu.addMenu("File") + exit = QAction("Exit", self, triggered=qApp.quit) + self.menu_file.addAction(exit) + + self.menu_about = self.menu.addMenu("&About") + about = QAction("About Qt", self, shortcut=QKeySequence(QKeySequence.HelpContents), + triggered=qApp.aboutQt) + self.menu_about.addAction(about) + + # Create an artificial color close to the original one + self.ihc_rgb = data.immunohistochemistry() + self.ihc_hed = rgb2hed(self.ihc_rgb) + + main_layout = QVBoxLayout(self._main) + plot_layout = QHBoxLayout() + button_layout = QHBoxLayout() + label_layout = QHBoxLayout() + + self.canvas1 = FigureCanvas(Figure(figsize=(5, 5))) + self.canvas2 = FigureCanvas(Figure(figsize=(5, 5))) + + self._ax1 = self.canvas1.figure.subplots() + self._ax2 = self.canvas2.figure.subplots() + + self._ax1.imshow(self.ihc_rgb) + + plot_layout.addWidget(self.canvas1) + plot_layout.addWidget(self.canvas2) + + self.button1 = QPushButton("Hematoxylin") + self.button2 = QPushButton("Eosin") + self.button3 = QPushButton("DAB") + self.button4 = QPushButton("Fluorescence") + + self.button1.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.button2.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.button3.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + self.button4.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Expanding) + + self.button1.clicked.connect(self.plot_hematoxylin) + self.button2.clicked.connect(self.plot_eosin) + self.button3.clicked.connect(self.plot_dab) + self.button4.clicked.connect(self.plot_final) + + self.label1 = QLabel("Original", alignment=Qt.AlignCenter) + self.label2 = QLabel("", alignment=Qt.AlignCenter) + + font = self.label1.font() + font.setPointSize(16) + self.label1.setFont(font) + self.label2.setFont(font) + + label_layout.addWidget(self.label1) + label_layout.addWidget(self.label2) + + button_layout.addWidget(self.button1) + button_layout.addWidget(self.button2) + button_layout.addWidget(self.button3) + button_layout.addWidget(self.button4) + + main_layout.addLayout(label_layout, 2) + main_layout.addLayout(plot_layout, 88) + main_layout.addLayout(button_layout, 10) + + # Default image + self.plot_hematoxylin() + + def set_buttons_state(self, states): + self.button1.setEnabled(states[0]) + self.button2.setEnabled(states[1]) + self.button3.setEnabled(states[2]) + self.button4.setEnabled(states[3]) + + @Slot() + def plot_hematoxylin(self): + cmap_hema = LinearSegmentedColormap.from_list("mycmap", ["white", "navy"]) + self._ax2.imshow(self.ihc_hed[:, :, 0], cmap=cmap_hema) + self.canvas2.draw() + self.label2.setText("Hematoxylin") + self.set_buttons_state((False, True, True, True)) + + @Slot() + def plot_eosin(self): + cmap_eosin = LinearSegmentedColormap.from_list("mycmap", ["darkviolet", "white"]) + self._ax2.imshow(self.ihc_hed[:, :, 1], cmap=cmap_eosin) + self.canvas2.draw() + self.label2.setText("Eosin") + self.set_buttons_state((True, False, True, True)) + + @Slot() + def plot_dab(self): + cmap_dab = LinearSegmentedColormap.from_list("mycmap", ["white", "saddlebrown"]) + self._ax2.imshow(self.ihc_hed[:, :, 2], cmap=cmap_dab) + self.canvas2.draw() + self.label2.setText("DAB") + self.set_buttons_state((True, True, False, True)) + + @Slot() + def plot_final(self): + h = rescale_intensity(self.ihc_hed[:, :, 0], out_range=(0, 1)) + d = rescale_intensity(self.ihc_hed[:, :, 2], out_range=(0, 1)) + zdh = np.dstack((np.zeros_like(h), d, h)) + self._ax2.imshow(zdh) + self.canvas2.draw() + self.label2.setText("Stain separated image") + self.set_buttons_state((True, True, True, False)) + + +if __name__ == "__main__": + + app = QApplication(sys.argv) + w = ApplicationWindow() + w.show() + app.exec_() diff --git a/examples/installer_test/hello.py b/examples/installer_test/hello.py new file mode 100644 index 0000000..3aa7a15 --- /dev/null +++ b/examples/installer_test/hello.py @@ -0,0 +1,104 @@ +# This Python file uses the following encoding: utf-8 +# It has been edited by fix-complaints.py . + +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +""" +hello.py +-------- + +This simple script shows a label with changing "Hello World" messages. +It can be used directly as a script, but we use it also to automatically +test PyInstaller. See testing/wheel_tester.py . + +When used with PyInstaller, it automatically stops its execution after +2 seconds. +""" +from __future__ import print_function + +import sys +import random +import platform +import time + +from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, + QVBoxLayout, QWidget) +from PySide2.QtCore import Slot, Qt, QTimer + +class MyWidget(QWidget): + def __init__(self): + QWidget.__init__(self) + + self.hello = ["Hallo Welt", "你好,世界", "Hei maailma", + "Hola Mundo", "Привет мир"] + + self.button = QPushButton("Click me!") + self.text = QLabel("Hello World embedded={}".format(sys.pyside_uses_embedding)) + self.text.setAlignment(Qt.AlignCenter) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.text) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + # Connecting the signal + self.button.clicked.connect(self.magic) + + @Slot() + def magic(self): + self.text.setText(random.choice(self.hello)) + +if __name__ == "__main__": + print("Start of hello.py ", time.ctime()) + print(" sys.version = {}".format(sys.version.splitlines()[0])) + print(" platform.platform() = {}".format(platform.platform())) + + app = QApplication() + + widget = MyWidget() + widget.resize(800, 600) + widget.show() + if sys.pyside_uses_embedding: + milliseconds = 2 * 1000 # run 2 second + QTimer.singleShot(milliseconds, app.quit) + retcode = app.exec_() + print("End of hello.py ", time.ctime()) + sys.exit(retcode) diff --git a/examples/installer_test/hello_app.spec b/examples/installer_test/hello_app.spec new file mode 100644 index 0000000..05ff1b8 --- /dev/null +++ b/examples/installer_test/hello_app.spec @@ -0,0 +1,93 @@ +# This Python file uses the following encoding: utf-8 +# It has been edited by fix-complaints.py . + +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +""" +hello_app.spec + +This is almost the spec file generated by running PyInstaller. +Just the paths were adjusted and made relative. +As an effect, all the analysis is avoided, and the log file of +wheel_tester.py went down from 775 lines to 278 lines. :-) +""" + +block_cipher = None + + +a = Analysis(['hello.py'], + pathex=['pyinstaller'], + binaries=[], + datas=[], + hiddenimports=[], + hookspath=[], + runtime_hooks=[], + # 2019-04-28 + # This hack circumvents a side effect of Python 2.7.16 which leads to a failure + # in 'hook-_tkinter.py'. The error is reported. Until it is fixed, we circumvent + # the problem by this exclude. + # This effect is triggered by installing 'numpy'. It is somewhat special since + # the problem does not show up in Python 3.7 . tkinter would have the same + # problem on Python 3.7, but numpy would not trigger it for some reason. + excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'], + win_no_prefer_redirects=False, + win_private_assemblies=False, + cipher=block_cipher, + noarchive=False) +pyz = PYZ(a.pure, a.zipped_data, + cipher=block_cipher) +exe = EXE(pyz, + a.scripts, + [], + exclude_binaries=True, + name='hello_app', + debug=False, + bootloader_ignore_signals=False, + strip=False, + upx=True, + console=True ) +coll = COLLECT(exe, + a.binaries, + a.zipfiles, + a.datas, + strip=False, + upx=True, + name='hello_app') diff --git a/examples/macextras/macextras.pyproject b/examples/macextras/macextras.pyproject new file mode 100644 index 0000000..d559b7c --- /dev/null +++ b/examples/macextras/macextras.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["macpasteboardmime.py"] +} diff --git a/examples/macextras/macpasteboardmime.py b/examples/macextras/macpasteboardmime.py new file mode 100644 index 0000000..c851339 --- /dev/null +++ b/examples/macextras/macpasteboardmime.py @@ -0,0 +1,125 @@ + +############################################################################ +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +import sys +from PySide2 import QtCore, QtWidgets + +try: + from PySide2 import QtMacExtras +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "QtMacExtras macpasteboardmime", + "This exampe only runs on macOS and QtMacExtras must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.exec_() + sys.exit(1) + +class VCardMime(QtMacExtras.QMacPasteboardMime): + def __init__(self, t = QtMacExtras.QMacPasteboardMime.MIME_ALL): + super(VCardMime, self).__init__(t) + + def convertorName(self): + return "VCardMime" + + def canConvert(self, mime, flav): + if self.mimeFor(flav) == mime: + return True + else: + return False + + def mimeFor(self, flav): + if flav == "public.vcard": + return "application/x-mycompany-VCard" + else: + return "" + + def flavorFor(self, mime): + if mime == "application/x-mycompany-VCard": + return "public.vcard" + else: + return "" + + def convertToMime(self, mime, data, flav): + all = QtCore.QByteArray() + for i in data: + all += i + return all + + def convertFromMime(mime, data, flav): + # Todo: implement! + return [] + +class TestWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + super(TestWidget, self).__init__(parent) + self.vcardMime = VCardMime() + self.setAcceptDrops(True) + + self.label1 = QtWidgets.QLabel() + self.label2 = QtWidgets.QLabel() + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.label1) + layout.addWidget(self.label2) + self.setLayout(layout) + + self.label1.setText("Please drag a \"VCard\" from Contacts application, normally a name in the list, and drop here.") + + def dragEnterEvent(self, e): + e.accept() + + def dropEvent(self, e): + e.accept() + self.contentsDropEvent(e) + + def contentsDropEvent(self, e): + if e.mimeData().hasFormat("application/x-mycompany-VCard"): + s = e.mimeData().data( "application/x-mycompany-VCard" ) + # s now contains text of vcard + self.label2.setText(str(s)) + e.acceptProposedAction() + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + QtMacExtras.qRegisterDraggedTypes(["public.vcard"]) + wid1 = TestWidget() + wid1.show() + sys.exit(app.exec_()) diff --git a/examples/multimedia/audiooutput.py b/examples/multimedia/audiooutput.py new file mode 100644 index 0000000..c6c7b9f --- /dev/null +++ b/examples/multimedia/audiooutput.py @@ -0,0 +1,300 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the multimedia/audiooutput example from Qt v5.x, originating from PyQt""" + +from math import pi, sin +from struct import pack + +from PySide2.QtCore import QByteArray, QIODevice, Qt, QTimer, qWarning +from PySide2.QtMultimedia import (QAudio, QAudioDeviceInfo, QAudioFormat, + QAudioOutput) +from PySide2.QtWidgets import (QApplication, QComboBox, QHBoxLayout, QLabel, + QMainWindow, QPushButton, QSlider, QVBoxLayout, QWidget) + + +class Generator(QIODevice): + + def __init__(self, format, durationUs, sampleRate, parent): + super(Generator, self).__init__(parent) + + self.m_pos = 0 + self.m_buffer = QByteArray() + + self.generateData(format, durationUs, sampleRate) + + def start(self): + self.open(QIODevice.ReadOnly) + + def stop(self): + self.m_pos = 0 + self.close() + + def generateData(self, format, durationUs, sampleRate): + pack_format = '' + + if format.sampleSize() == 8: + if format.sampleType() == QAudioFormat.UnSignedInt: + scaler = lambda x: ((1.0 + x) / 2 * 255) + pack_format = 'B' + elif format.sampleType() == QAudioFormat.SignedInt: + scaler = lambda x: x * 127 + pack_format = 'b' + elif format.sampleSize() == 16: + if format.sampleType() == QAudioFormat.UnSignedInt: + scaler = lambda x: (1.0 + x) / 2 * 65535 + pack_format = 'H' + elif format.sampleType() == QAudioFormat.SignedInt: + scaler = lambda x: x * 32767 + pack_format = 'h' + + assert(pack_format != '') + + channelBytes = format.sampleSize() // 8 + sampleBytes = format.channelCount() * channelBytes + + length = (format.sampleRate() * format.channelCount() * (format.sampleSize() // 8)) * durationUs // 100000 + + self.m_buffer.clear() + sampleIndex = 0 + factor = 2 * pi * sampleRate / format.sampleRate() + + while length != 0: + x = sin((sampleIndex % format.sampleRate()) * factor) + packed = pack(pack_format, int(scaler(x))) + + for _ in range(format.channelCount()): + self.m_buffer.append(packed) + length -= channelBytes + + sampleIndex += 1 + + def readData(self, maxlen): + data = QByteArray() + total = 0 + + while maxlen > total: + chunk = min(self.m_buffer.size() - self.m_pos, maxlen - total) + data.append(self.m_buffer.mid(self.m_pos, chunk)) + self.m_pos = (self.m_pos + chunk) % self.m_buffer.size() + total += chunk + + return data.data() + + def writeData(self, data): + return 0 + + def bytesAvailable(self): + return self.m_buffer.size() + super(Generator, self).bytesAvailable() + + +class AudioTest(QMainWindow): + + PUSH_MODE_LABEL = "Enable push mode" + PULL_MODE_LABEL = "Enable pull mode" + SUSPEND_LABEL = "Suspend playback" + RESUME_LABEL = "Resume playback" + + DurationSeconds = 1 + ToneSampleRateHz = 600 + DataSampleRateHz = 44100 + + def __init__(self): + super(AudioTest, self).__init__() + + self.m_device = QAudioDeviceInfo.defaultOutputDevice() + self.m_output = None + + self.initializeWindow() + self.initializeAudio() + + def initializeWindow(self): + layout = QVBoxLayout() + + self.m_deviceBox = QComboBox() + self.m_deviceBox.activated[int].connect(self.deviceChanged) + for deviceInfo in QAudioDeviceInfo.availableDevices(QAudio.AudioOutput): + self.m_deviceBox.addItem(deviceInfo.deviceName(), deviceInfo) + + layout.addWidget(self.m_deviceBox) + + self.m_modeButton = QPushButton() + self.m_modeButton.clicked.connect(self.toggleMode) + self.m_modeButton.setText(self.PUSH_MODE_LABEL) + + layout.addWidget(self.m_modeButton) + + self.m_suspendResumeButton = QPushButton( + clicked=self.toggleSuspendResume) + self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) + + layout.addWidget(self.m_suspendResumeButton) + + volumeBox = QHBoxLayout() + volumeLabel = QLabel("Volume:") + self.m_volumeSlider = QSlider(Qt.Horizontal, minimum=0, maximum=100, + singleStep=10) + self.m_volumeSlider.valueChanged.connect(self.volumeChanged) + + volumeBox.addWidget(volumeLabel) + volumeBox.addWidget(self.m_volumeSlider) + + layout.addLayout(volumeBox) + + window = QWidget() + window.setLayout(layout) + + self.setCentralWidget(window) + + def initializeAudio(self): + self.m_pullTimer = QTimer(self) + self.m_pullTimer.timeout.connect(self.pullTimerExpired) + self.m_pullMode = True + + self.m_format = QAudioFormat() + self.m_format.setSampleRate(self.DataSampleRateHz) + self.m_format.setChannelCount(1) + self.m_format.setSampleSize(16) + self.m_format.setCodec('audio/pcm') + self.m_format.setByteOrder(QAudioFormat.LittleEndian) + self.m_format.setSampleType(QAudioFormat.SignedInt) + + info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice()) + if not info.isFormatSupported(self.m_format): + qWarning("Default format not supported - trying to use nearest") + self.m_format = info.nearestFormat(self.m_format) + + self.m_generator = Generator(self.m_format, + self.DurationSeconds * 1000000, self.ToneSampleRateHz, self) + + self.createAudioOutput() + + def createAudioOutput(self): + self.m_audioOutput = QAudioOutput(self.m_device, self.m_format) + self.m_audioOutput.notify.connect(self.notified) + self.m_audioOutput.stateChanged.connect(self.handleStateChanged) + + self.m_generator.start() + self.m_audioOutput.start(self.m_generator) + self.m_volumeSlider.setValue(self.m_audioOutput.volume() * 100) + + def deviceChanged(self, index): + self.m_pullTimer.stop() + self.m_generator.stop() + self.m_audioOutput.stop() + self.m_device = self.m_deviceBox.itemData(index) + + self.createAudioOutput() + + def volumeChanged(self, value): + if self.m_audioOutput is not None: + self.m_audioOutput.setVolume(value / 100.0) + + def notified(self): + qWarning("bytesFree = %d, elapsedUSecs = %d, processedUSecs = %d" % ( + self.m_audioOutput.bytesFree(), + self.m_audioOutput.elapsedUSecs(), + self.m_audioOutput.processedUSecs())) + + def pullTimerExpired(self): + if self.m_audioOutput is not None and self.m_audioOutput.state() != QAudio.StoppedState: + chunks = self.m_audioOutput.bytesFree() // self.m_audioOutput.periodSize() + for _ in range(chunks): + data = self.m_generator.read(self.m_audioOutput.periodSize()) + if data is None or len(data) != self.m_audioOutput.periodSize(): + break + + self.m_output.write(data) + + def toggleMode(self): + self.m_pullTimer.stop() + self.m_audioOutput.stop() + + if self.m_pullMode: + self.m_modeButton.setText(self.PULL_MODE_LABEL) + self.m_output = self.m_audioOutput.start() + self.m_pullMode = False + self.m_pullTimer.start(20) + else: + self.m_modeButton.setText(self.PUSH_MODE_LABEL) + self.m_pullMode = True + self.m_audioOutput.start(self.m_generator) + + self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) + + def toggleSuspendResume(self): + if self.m_audioOutput.state() == QAudio.SuspendedState: + qWarning("status: Suspended, resume()") + self.m_audioOutput.resume() + self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) + elif self.m_audioOutput.state() == QAudio.ActiveState: + qWarning("status: Active, suspend()") + self.m_audioOutput.suspend() + self.m_suspendResumeButton.setText(self.RESUME_LABEL) + elif self.m_audioOutput.state() == QAudio.StoppedState: + qWarning("status: Stopped, resume()") + self.m_audioOutput.resume() + self.m_suspendResumeButton.setText(self.SUSPEND_LABEL) + elif self.m_audioOutput.state() == QAudio.IdleState: + qWarning("status: IdleState") + + stateMap = { + QAudio.ActiveState: "ActiveState", + QAudio.SuspendedState: "SuspendedState", + QAudio.StoppedState: "StoppedState", + QAudio.IdleState: "IdleState"} + + def handleStateChanged(self, state): + qWarning("state = " + self.stateMap.get(state, "Unknown")) + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + app.setApplicationName("Audio Output Test") + + audio = AudioTest() + audio.show() + + sys.exit(app.exec_()) diff --git a/examples/multimedia/camera.py b/examples/multimedia/camera.py new file mode 100644 index 0000000..d58b526 --- /dev/null +++ b/examples/multimedia/camera.py @@ -0,0 +1,169 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 Multimedia Camera Example""" + +import os, sys +from PySide2.QtCore import QDate, QDir, QStandardPaths, Qt, QUrl +from PySide2.QtGui import QGuiApplication, QDesktopServices, QIcon +from PySide2.QtGui import QImage, QPixmap +from PySide2.QtWidgets import (QAction, QApplication, QHBoxLayout, QLabel, + QMainWindow, QPushButton, QTabWidget, QToolBar, QVBoxLayout, QWidget) +from PySide2.QtMultimedia import QCamera, QCameraImageCapture, QCameraInfo +from PySide2.QtMultimediaWidgets import QCameraViewfinder + +class ImageView(QWidget): + def __init__(self, previewImage, fileName): + super(ImageView, self).__init__() + + self.fileName = fileName + + mainLayout = QVBoxLayout(self) + self.imageLabel = QLabel() + self.imageLabel.setPixmap(QPixmap.fromImage(previewImage)) + mainLayout.addWidget(self.imageLabel) + + topLayout = QHBoxLayout() + self.fileNameLabel = QLabel(QDir.toNativeSeparators(fileName)) + self.fileNameLabel.setTextInteractionFlags(Qt.TextBrowserInteraction) + + topLayout.addWidget(self.fileNameLabel) + topLayout.addStretch() + copyButton = QPushButton("Copy") + copyButton.setToolTip("Copy file name to clipboard") + topLayout.addWidget(copyButton) + copyButton.clicked.connect(self.copy) + launchButton = QPushButton("Launch") + launchButton.setToolTip("Launch image viewer") + topLayout.addWidget(launchButton) + launchButton.clicked.connect(self.launch) + mainLayout.addLayout(topLayout) + + def copy(self): + QGuiApplication.clipboard().setText(self.fileNameLabel.text()) + + def launch(self): + QDesktopServices.openUrl(QUrl.fromLocalFile(self.fileName)) + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + self.cameraInfo = QCameraInfo.defaultCamera() + self.camera = QCamera(self.cameraInfo) + self.camera.setCaptureMode(QCamera.CaptureStillImage) + self.imageCapture = QCameraImageCapture(self.camera) + self.imageCapture.imageCaptured.connect(self.imageCaptured) + self.imageCapture.imageSaved.connect(self.imageSaved) + self.currentPreview = QImage() + + toolBar = QToolBar() + self.addToolBar(toolBar) + + fileMenu = self.menuBar().addMenu("&File") + shutterIcon = QIcon(os.path.join(os.path.dirname(__file__), + "shutter.svg")) + self.takePictureAction = QAction(shutterIcon, "&Take Picture", self, + shortcut="Ctrl+T", + triggered=self.takePicture) + self.takePictureAction.setToolTip("Take Picture") + fileMenu.addAction(self.takePictureAction) + toolBar.addAction(self.takePictureAction) + + exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit", + self, shortcut="Ctrl+Q", triggered=self.close) + fileMenu.addAction(exitAction) + + aboutMenu = self.menuBar().addMenu("&About") + aboutQtAction = QAction("About &Qt", self, triggered=qApp.aboutQt) + aboutMenu.addAction(aboutQtAction) + + self.tabWidget = QTabWidget() + self.setCentralWidget(self.tabWidget) + + self.cameraViewfinder = QCameraViewfinder() + self.camera.setViewfinder(self.cameraViewfinder) + self.tabWidget.addTab(self.cameraViewfinder, "Viewfinder") + + if self.camera.status() != QCamera.UnavailableStatus: + name = self.cameraInfo.description() + self.setWindowTitle("PySide2 Camera Example (" + name + ")") + self.statusBar().showMessage("Starting: '" + name + "'", 5000) + self.camera.start() + else: + self.setWindowTitle("PySide2 Camera Example") + self.takePictureAction.setEnabled(False) + self.statusBar().showMessage("Camera unavailable", 5000) + + def nextImageFileName(self): + picturesLocation = QStandardPaths.writableLocation(QStandardPaths.PicturesLocation) + dateString = QDate.currentDate().toString("yyyyMMdd") + pattern = picturesLocation + "/pyside2_camera_" + dateString + "_{:03d}.jpg" + n = 1 + while True: + result = pattern.format(n) + if not os.path.exists(result): + return result + n = n + 1 + return None + + def takePicture(self): + self.currentPreview = QImage() + self.camera.searchAndLock() + self.imageCapture.capture(self.nextImageFileName()) + self.camera.unlock() + + def imageCaptured(self, id, previewImage): + self.currentPreview = previewImage + + def imageSaved(self, id, fileName): + index = self.tabWidget.count() + imageView = ImageView(self.currentPreview, fileName) + self.tabWidget.addTab(imageView, "Capture #{}".format(index)) + self.tabWidget.setCurrentIndex(index) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + availableGeometry = app.desktop().availableGeometry(mainWin) + mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/multimedia/multimedia.pyproject b/examples/multimedia/multimedia.pyproject new file mode 100644 index 0000000..a0b8b44 --- /dev/null +++ b/examples/multimedia/multimedia.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["player.py", "audiooutput.py", "camera.py"] +} diff --git a/examples/multimedia/player.py b/examples/multimedia/player.py new file mode 100644 index 0000000..cb70e50 --- /dev/null +++ b/examples/multimedia/player.py @@ -0,0 +1,157 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 Multimedia player example""" + +import sys +from PySide2.QtCore import QStandardPaths, Qt +from PySide2.QtGui import QIcon, QKeySequence +from PySide2.QtWidgets import (QAction, QApplication, QDialog, QFileDialog, + QMainWindow, QSlider, QStyle, QToolBar) +from PySide2.QtMultimedia import QMediaPlayer, QMediaPlaylist +from PySide2.QtMultimediaWidgets import QVideoWidget + +class MainWindow(QMainWindow): + + def __init__(self): + super(MainWindow, self).__init__() + + self.playlist = QMediaPlaylist() + self.player = QMediaPlayer() + + toolBar = QToolBar() + self.addToolBar(toolBar) + + fileMenu = self.menuBar().addMenu("&File") + openAction = QAction(QIcon.fromTheme("document-open"), + "&Open...", self, shortcut=QKeySequence.Open, + triggered=self.open) + fileMenu.addAction(openAction) + exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit", + self, shortcut="Ctrl+Q", triggered=self.close) + fileMenu.addAction(exitAction) + + playMenu = self.menuBar().addMenu("&Play") + playIcon = self.style().standardIcon(QStyle.SP_MediaPlay) + self.playAction = toolBar.addAction(playIcon, "Play") + self.playAction.triggered.connect(self.player.play) + playMenu.addAction(self.playAction) + + previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward) + self.previousAction = toolBar.addAction(previousIcon, "Previous") + self.previousAction.triggered.connect(self.previousClicked) + playMenu.addAction(self.previousAction) + + pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause) + self.pauseAction = toolBar.addAction(pauseIcon, "Pause") + self.pauseAction.triggered.connect(self.player.pause) + playMenu.addAction(self.pauseAction) + + nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward) + self.nextAction = toolBar.addAction(nextIcon, "Next") + self.nextAction.triggered.connect(self.playlist.next) + playMenu.addAction(self.nextAction) + + stopIcon = self.style().standardIcon(QStyle.SP_MediaStop) + self.stopAction = toolBar.addAction(stopIcon, "Stop") + self.stopAction.triggered.connect(self.player.stop) + playMenu.addAction(self.stopAction) + + self.volumeSlider = QSlider() + self.volumeSlider.setOrientation(Qt.Horizontal) + self.volumeSlider.setMinimum(0) + self.volumeSlider.setMaximum(100) + self.volumeSlider.setFixedWidth(app.desktop().availableGeometry(self).width() / 10) + self.volumeSlider.setValue(self.player.volume()) + self.volumeSlider.setTickInterval(10) + self.volumeSlider.setTickPosition(QSlider.TicksBelow) + self.volumeSlider.setToolTip("Volume") + self.volumeSlider.valueChanged.connect(self.player.setVolume) + toolBar.addWidget(self.volumeSlider) + + aboutMenu = self.menuBar().addMenu("&About") + aboutQtAct = QAction("About &Qt", self, triggered=qApp.aboutQt) + aboutMenu.addAction(aboutQtAct) + + self.videoWidget = QVideoWidget() + self.setCentralWidget(self.videoWidget) + self.player.setPlaylist(self.playlist) + self.player.stateChanged.connect(self.updateButtons) + self.player.setVideoOutput(self.videoWidget) + + self.updateButtons(self.player.state()) + + def open(self): + fileDialog = QFileDialog(self) + supportedMimeTypes = QMediaPlayer.supportedMimeTypes() + if not supportedMimeTypes: + supportedMimeTypes.append("video/x-msvideo") # AVI + fileDialog.setMimeTypeFilters(supportedMimeTypes) + moviesLocation = QStandardPaths.writableLocation(QStandardPaths.MoviesLocation) + fileDialog.setDirectory(moviesLocation) + if fileDialog.exec_() == QDialog.Accepted: + self.playlist.addMedia(fileDialog.selectedUrls()[0]) + self.player.play() + + def previousClicked(self): + # Go to previous track if we are within the first 5 seconds of playback + # Otherwise, seek to the beginning. + if self.player.position() <= 5000: + self.playlist.previous() + else: + player.setPosition(0) + + def updateButtons(self, state): + mediaCount = self.playlist.mediaCount() + self.playAction.setEnabled(mediaCount > 0 + and state != QMediaPlayer.PlayingState) + self.pauseAction.setEnabled(state == QMediaPlayer.PlayingState) + self.stopAction.setEnabled(state != QMediaPlayer.StoppedState) + self.previousAction.setEnabled(self.player.position() > 0) + self.nextAction.setEnabled(mediaCount > 1) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + availableGeometry = app.desktop().availableGeometry(mainWin) + mainWin.resize(availableGeometry.width() / 3, availableGeometry.height() / 2) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/multimedia/shutter.svg b/examples/multimedia/shutter.svg new file mode 100644 index 0000000..1849336 --- /dev/null +++ b/examples/multimedia/shutter.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + diff --git a/examples/network/blockingfortuneclient.py b/examples/network/blockingfortuneclient.py new file mode 100644 index 0000000..028c05c --- /dev/null +++ b/examples/network/blockingfortuneclient.py @@ -0,0 +1,224 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the network/blockingfortunclient example from Qt v5.x, originating from PyQt""" + +from PySide2.QtCore import (Signal, QDataStream, QMutex, QMutexLocker, + QThread, QWaitCondition) +from PySide2.QtGui import QIntValidator +from PySide2.QtWidgets import (QApplication, QDialogButtonBox, QGridLayout, + QLabel, QLineEdit, QMessageBox, QPushButton, QWidget) +from PySide2.QtNetwork import (QAbstractSocket, QHostAddress, QNetworkInterface, + QTcpSocket) + + +class FortuneThread(QThread): + newFortune = Signal(str) + + error = Signal(int, str) + + def __init__(self, parent=None): + super(FortuneThread, self).__init__(parent) + + self.quit = False + self.hostName = '' + self.cond = QWaitCondition() + self.mutex = QMutex() + self.port = 0 + + def __del__(self): + self.mutex.lock() + self.quit = True + self.cond.wakeOne() + self.mutex.unlock() + self.wait() + + def requestNewFortune(self, hostname, port): + locker = QMutexLocker(self.mutex) + self.hostName = hostname + self.port = port + if not self.isRunning(): + self.start() + else: + self.cond.wakeOne() + + def run(self): + self.mutex.lock() + serverName = self.hostName + serverPort = self.port + self.mutex.unlock() + + while not self.quit: + Timeout = 5 * 1000 + + socket = QTcpSocket() + socket.connectToHost(serverName, serverPort) + + if not socket.waitForConnected(Timeout): + self.error.emit(socket.error(), socket.errorString()) + return + + while socket.bytesAvailable() < 2: + if not socket.waitForReadyRead(Timeout): + self.error.emit(socket.error(), socket.errorString()) + return + + instr = QDataStream(socket) + instr.setVersion(QDataStream.Qt_4_0) + blockSize = instr.readUInt16() + + while socket.bytesAvailable() < blockSize: + if not socket.waitForReadyRead(Timeout): + self.error.emit(socket.error(), socket.errorString()) + return + + self.mutex.lock() + fortune = instr.readQString() + self.newFortune.emit(fortune) + + self.cond.wait(self.mutex) + serverName = self.hostName + serverPort = self.port + self.mutex.unlock() + + +class BlockingClient(QWidget): + def __init__(self, parent=None): + super(BlockingClient, self).__init__(parent) + + self.thread = FortuneThread() + self.currentFortune = '' + + hostLabel = QLabel("&Server name:") + portLabel = QLabel("S&erver port:") + + for ipAddress in QNetworkInterface.allAddresses(): + if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: + break + else: + ipAddress = QHostAddress(QHostAddress.LocalHost) + + ipAddress = ipAddress.toString() + + self.hostLineEdit = QLineEdit(ipAddress) + self.portLineEdit = QLineEdit() + self.portLineEdit.setValidator(QIntValidator(1, 65535, self)) + + hostLabel.setBuddy(self.hostLineEdit) + portLabel.setBuddy(self.portLineEdit) + + self.statusLabel = QLabel( + "This example requires that you run the Fortune Server example as well.") + self.statusLabel.setWordWrap(True) + + self.getFortuneButton = QPushButton("Get Fortune") + self.getFortuneButton.setDefault(True) + self.getFortuneButton.setEnabled(False) + + quitButton = QPushButton("Quit") + + buttonBox = QDialogButtonBox() + buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) + buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) + + self.getFortuneButton.clicked.connect(self.requestNewFortune) + quitButton.clicked.connect(self.close) + self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) + self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) + self.thread.newFortune.connect(self.showFortune) + self.thread.error.connect(self.displayError) + + mainLayout = QGridLayout() + mainLayout.addWidget(hostLabel, 0, 0) + mainLayout.addWidget(self.hostLineEdit, 0, 1) + mainLayout.addWidget(portLabel, 1, 0) + mainLayout.addWidget(self.portLineEdit, 1, 1) + mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) + mainLayout.addWidget(buttonBox, 3, 0, 1, 2) + self.setLayout(mainLayout) + + self.setWindowTitle("Blocking Fortune Client") + self.portLineEdit.setFocus() + + def requestNewFortune(self): + self.getFortuneButton.setEnabled(False) + self.thread.requestNewFortune(self.hostLineEdit.text(), + int(self.portLineEdit.text())) + + def showFortune(self, nextFortune): + if nextFortune == self.currentFortune: + self.requestNewFortune() + return + + self.currentFortune = nextFortune + self.statusLabel.setText(self.currentFortune) + self.getFortuneButton.setEnabled(True) + + def displayError(self, socketError, message): + if socketError == QAbstractSocket.HostNotFoundError: + QMessageBox.information(self, "Blocking Fortune Client", + "The host was not found. Please check the host and port " + "settings.") + elif socketError == QAbstractSocket.ConnectionRefusedError: + QMessageBox.information(self, "Blocking Fortune Client", + "The connection was refused by the peer. Make sure the " + "fortune server is running, and check that the host name " + "and port settings are correct.") + else: + QMessageBox.information(self, "Blocking Fortune Client", + "The following error occurred: %s." % message) + + self.getFortuneButton.setEnabled(True) + + def enableGetFortuneButton(self): + self.getFortuneButton.setEnabled(self.hostLineEdit.text() != '' and + self.portLineEdit.text() != '') + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + client = BlockingClient() + client.show() + sys.exit(app.exec_()) diff --git a/examples/network/fortuneclient.py b/examples/network/fortuneclient.py new file mode 100644 index 0000000..c774973 --- /dev/null +++ b/examples/network/fortuneclient.py @@ -0,0 +1,167 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the network/fortuneclient example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets, QtNetwork + + +class Client(QtWidgets.QDialog): + def __init__(self, parent=None): + super(Client, self).__init__(parent) + + self.blockSize = 0 + self.currentFortune = '' + + hostLabel = QtWidgets.QLabel("&Server name:") + portLabel = QtWidgets.QLabel("S&erver port:") + + self.hostLineEdit = QtWidgets.QLineEdit('Localhost') + self.portLineEdit = QtWidgets.QLineEdit() + self.portLineEdit.setValidator(QtGui.QIntValidator(1, 65535, self)) + + hostLabel.setBuddy(self.hostLineEdit) + portLabel.setBuddy(self.portLineEdit) + + self.statusLabel = QtWidgets.QLabel("This examples requires that you run " + "the Fortune Server example as well.") + + self.getFortuneButton = QtWidgets.QPushButton("Get Fortune") + self.getFortuneButton.setDefault(True) + self.getFortuneButton.setEnabled(False) + + quitButton = QtWidgets.QPushButton("Quit") + + buttonBox = QtWidgets.QDialogButtonBox() + buttonBox.addButton(self.getFortuneButton, + QtWidgets.QDialogButtonBox.ActionRole) + buttonBox.addButton(quitButton, QtWidgets.QDialogButtonBox.RejectRole) + + self.tcpSocket = QtNetwork.QTcpSocket(self) + + self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) + self.portLineEdit.textChanged.connect(self.enableGetFortuneButton) + self.getFortuneButton.clicked.connect(self.requestNewFortune) + quitButton.clicked.connect(self.close) + self.tcpSocket.readyRead.connect(self.readFortune) + self.tcpSocket.error.connect(self.displayError) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(hostLabel, 0, 0) + mainLayout.addWidget(self.hostLineEdit, 0, 1) + mainLayout.addWidget(portLabel, 1, 0) + mainLayout.addWidget(self.portLineEdit, 1, 1) + mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) + mainLayout.addWidget(buttonBox, 3, 0, 1, 2) + self.setLayout(mainLayout) + + self.setWindowTitle("Fortune Client") + self.portLineEdit.setFocus() + + def requestNewFortune(self): + self.getFortuneButton.setEnabled(False) + self.blockSize = 0 + self.tcpSocket.abort() + self.tcpSocket.connectToHost(self.hostLineEdit.text(), + int(self.portLineEdit.text())) + + def readFortune(self): + instr = QtCore.QDataStream(self.tcpSocket) + instr.setVersion(QtCore.QDataStream.Qt_4_0) + + if self.blockSize == 0: + if self.tcpSocket.bytesAvailable() < 2: + return + + self.blockSize = instr.readUInt16() + + if self.tcpSocket.bytesAvailable() < self.blockSize: + return + + nextFortune = instr.readString() + + try: + # Python v3. + nextFortune = str(nextFortune, encoding='ascii') + except TypeError: + # Python v2. + pass + + if nextFortune == self.currentFortune: + QtCore.QTimer.singleShot(0, self.requestNewFortune) + return + + self.currentFortune = nextFortune + self.statusLabel.setText(self.currentFortune) + self.getFortuneButton.setEnabled(True) + + def displayError(self, socketError): + if socketError == QtNetwork.QAbstractSocket.RemoteHostClosedError: + pass + elif socketError == QtNetwork.QAbstractSocket.HostNotFoundError: + QtWidgets.QMessageBox.information(self, "Fortune Client", + "The host was not found. Please check the host name and " + "port settings.") + elif socketError == QtNetwork.QAbstractSocket.ConnectionRefusedError: + QtWidgets.QMessageBox.information(self, "Fortune Client", + "The connection was refused by the peer. Make sure the " + "fortune server is running, and check that the host name " + "and port settings are correct.") + else: + QtWidgets.QMessageBox.information(self, "Fortune Client", + "The following error occurred: %s." % self.tcpSocket.errorString()) + + self.getFortuneButton.setEnabled(True) + + def enableGetFortuneButton(self): + self.getFortuneButton.setEnabled(bool(self.hostLineEdit.text() and + self.portLineEdit.text())) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + client = Client() + client.show() + sys.exit(client.exec_()) diff --git a/examples/network/fortuneserver.py b/examples/network/fortuneserver.py new file mode 100644 index 0000000..790e9df --- /dev/null +++ b/examples/network/fortuneserver.py @@ -0,0 +1,117 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the network/fortuneserver example from Qt v5.x""" + +import random + +from PySide2 import QtCore, QtWidgets, QtNetwork + + +class Server(QtWidgets.QDialog): + def __init__(self, parent=None): + super(Server, self).__init__(parent) + + statusLabel = QtWidgets.QLabel() + quitButton = QtWidgets.QPushButton("Quit") + quitButton.setAutoDefault(False) + + self.tcpServer = QtNetwork.QTcpServer(self) + if not self.tcpServer.listen(): + QtWidgets.QMessageBox.critical(self, "Fortune Server", + "Unable to start the server: %s." % self.tcpServer.errorString()) + self.close() + return + + statusLabel.setText("The server is running on port %d.\nRun the " + "Fortune Client example now." % self.tcpServer.serverPort()) + + self.fortunes = ( + "You've been leading a dog's life. Stay off the furniture.", + "You've got to think about tomorrow.", + "You will be surprised by a loud noise.", + "You will feel hungry again in another hour.", + "You might have mail.", + "You cannot kill time without injuring eternity.", + "Computers are not intelligent. They only think they are.") + + quitButton.clicked.connect(self.close) + self.tcpServer.newConnection.connect(self.sendFortune) + + buttonLayout = QtWidgets.QHBoxLayout() + buttonLayout.addStretch(1) + buttonLayout.addWidget(quitButton) + buttonLayout.addStretch(1) + + mainLayout = QtWidgets.QVBoxLayout() + mainLayout.addWidget(statusLabel) + mainLayout.addLayout(buttonLayout) + self.setLayout(mainLayout) + + self.setWindowTitle("Fortune Server") + + def sendFortune(self): + block = QtCore.QByteArray() + out = QtCore.QDataStream(block, QtCore.QIODevice.WriteOnly) + out.setVersion(QtCore.QDataStream.Qt_4_0) + out.writeUInt16(0) + fortune = self.fortunes[random.randint(0, len(self.fortunes) - 1)] + + out.writeString(fortune) + out.device().seek(0) + out.writeUInt16(block.size() - 2) + + clientConnection = self.tcpServer.nextPendingConnection() + clientConnection.disconnected.connect(clientConnection.deleteLater) + + clientConnection.write(block) + clientConnection.disconnectFromHost() + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + server = Server() + random.seed(None) + sys.exit(server.exec_()) diff --git a/examples/network/network.pyproject b/examples/network/network.pyproject new file mode 100644 index 0000000..44b9ec4 --- /dev/null +++ b/examples/network/network.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["blockingfortuneclient.py", "fortuneserver.py", + "threadedfortuneserver.py", "fortuneclient.py"] +} diff --git a/examples/network/threadedfortuneserver.py b/examples/network/threadedfortuneserver.py new file mode 100644 index 0000000..c16c77a --- /dev/null +++ b/examples/network/threadedfortuneserver.py @@ -0,0 +1,152 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the network/threadedfortuneserver example from Qt v5.x, originating from PyQt""" + +import random + +from PySide2.QtCore import (Signal, QByteArray, QDataStream, QIODevice, + QThread, Qt) +from PySide2.QtWidgets import (QApplication, QDialog, QHBoxLayout, QLabel, + QMessageBox, QPushButton, QVBoxLayout) +from PySide2.QtNetwork import (QHostAddress, QNetworkInterface, QTcpServer, + QTcpSocket) + + +class FortuneThread(QThread): + error = Signal(QTcpSocket.SocketError) + + def __init__(self, socketDescriptor, fortune, parent): + super(FortuneThread, self).__init__(parent) + + self.socketDescriptor = socketDescriptor + self.text = fortune + + def run(self): + tcpSocket = QTcpSocket() + if not tcpSocket.setSocketDescriptor(self.socketDescriptor): + self.error.emit(tcpSocket.error()) + return + + block = QByteArray() + outstr = QDataStream(block, QIODevice.WriteOnly) + outstr.setVersion(QDataStream.Qt_4_0) + outstr.writeUInt16(0) + outstr.writeQString(self.text) + outstr.device().seek(0) + outstr.writeUInt16(block.size() - 2) + + tcpSocket.write(block) + tcpSocket.disconnectFromHost() + tcpSocket.waitForDisconnected() + + +class FortuneServer(QTcpServer): + fortunes = ( + "You've been leading a dog's life. Stay off the furniture.", + "You've got to think about tomorrow.", + "You will be surprised by a loud noise.", + "You will feel hungry again in another hour.", + "You might have mail.", + "You cannot kill time without injuring eternity.", + "Computers are not intelligent. They only think they are.") + + def incomingConnection(self, socketDescriptor): + fortune = self.fortunes[random.randint(0, len(self.fortunes) - 1)] + + thread = FortuneThread(socketDescriptor, fortune, self) + thread.finished.connect(thread.deleteLater) + thread.start() + + +class Dialog(QDialog): + def __init__(self, parent=None): + super(Dialog, self).__init__(parent) + + self.server = FortuneServer() + + statusLabel = QLabel() + statusLabel.setTextInteractionFlags(Qt.TextBrowserInteraction) + statusLabel.setWordWrap(True) + quitButton = QPushButton("Quit") + quitButton.setAutoDefault(False) + + if not self.server.listen(): + QMessageBox.critical(self, "Threaded Fortune Server", + "Unable to start the server: %s." % self.server.errorString()) + self.close() + return + + for ipAddress in QNetworkInterface.allAddresses(): + if ipAddress != QHostAddress.LocalHost and ipAddress.toIPv4Address() != 0: + break + else: + ipAddress = QHostAddress(QHostAddress.LocalHost) + + ipAddress = ipAddress.toString() + + statusLabel.setText("The server is running on\n\nIP: %s\nport: %d\n\n" + "Run the Fortune Client example now." % (ipAddress, self.server.serverPort())) + + quitButton.clicked.connect(self.close) + + buttonLayout = QHBoxLayout() + buttonLayout.addStretch(1) + buttonLayout.addWidget(quitButton) + buttonLayout.addStretch(1) + + mainLayout = QVBoxLayout() + mainLayout.addWidget(statusLabel) + mainLayout.addLayout(buttonLayout) + self.setLayout(mainLayout) + + self.setWindowTitle("Threaded Fortune Server") + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + dialog = Dialog() + dialog.show() + sys.exit(dialog.exec_()) diff --git a/examples/opengl/2dpainting.py b/examples/opengl/2dpainting.py new file mode 100644 index 0000000..5b3ba61 --- /dev/null +++ b/examples/opengl/2dpainting.py @@ -0,0 +1,172 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/2dpainting example from Qt v5.x""" + +import sys +from PySide2.QtCore import * +from PySide2.QtGui import * +from PySide2.QtWidgets import * +from PySide2.QtOpenGL import * + +try: + from OpenGL import GL +except ImportError: + app = QApplication(sys.argv) + messageBox = QMessageBox(QMessageBox.Critical, "OpenGL 2dpainting", + "PyOpenGL must be installed to run this example.", + QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class Helper: + def __init__(self): + gradient = QLinearGradient(QPointF(50, -20), QPointF(80, 20)) + gradient.setColorAt(0.0, Qt.white) + gradient.setColorAt(1.0, QColor(0xa6, 0xce, 0x39)) + + self.background = QBrush(QColor(64, 32, 64)) + self.circleBrush = QBrush(gradient) + self.circlePen = QPen(Qt.black) + self.circlePen.setWidth(1) + self.textPen = QPen(Qt.white) + self.textFont = QFont() + self.textFont.setPixelSize(50) + + def paint(self, painter, event, elapsed): + painter.fillRect(event.rect(), self.background) + painter.translate(100, 100) + + painter.save() + painter.setBrush(self.circleBrush) + painter.setPen(self.circlePen) + painter.rotate(elapsed * 0.030) + + r = elapsed/1000.0 + n = 30 + for i in range(n): + painter.rotate(30) + radius = 0 + 120.0*((i+r)/n) + circleRadius = 1 + ((i+r)/n)*20 + painter.drawEllipse(QRectF(radius, -circleRadius, + circleRadius*2, circleRadius*2)) + + painter.restore() + + painter.setPen(self.textPen) + painter.setFont(self.textFont) + painter.drawText(QRect(-50, -50, 100, 100), Qt.AlignCenter, "Qt") + + +class Widget(QWidget): + def __init__(self, helper, parent = None): + QWidget.__init__(self, parent) + + self.helper = helper + self.elapsed = 0 + self.setFixedSize(200, 200) + + def animate(self): + self.elapsed = (self.elapsed + self.sender().interval()) % 1000 + self.repaint() + + def paintEvent(self, event): + painter = QPainter() + painter.begin(self) + painter.setRenderHint(QPainter.Antialiasing) + self.helper.paint(painter, event, self.elapsed) + painter.end() + + +class GLWidget(QGLWidget): + def __init__(self, helper, parent = None): + QGLWidget.__init__(self, QGLFormat(QGL.SampleBuffers), parent) + + self.helper = helper + self.elapsed = 0 + self.setFixedSize(200, 200) + + def animate(self): + self.elapsed = (self.elapsed + self.sender().interval()) % 1000 + self.repaint() + + def paintEvent(self, event): + painter = QPainter() + painter.begin(self) + self.helper.paint(painter, event, self.elapsed) + painter.end() + + +class Window(QWidget): + def __init__(self, parent = None): + QWidget.__init__(self, parent) + + helper = Helper() + native = Widget(helper, self) + openGL = GLWidget(helper, self) + nativeLabel = QLabel(self.tr("Native")) + nativeLabel.setAlignment(Qt.AlignHCenter) + openGLLabel = QLabel(self.tr("OpenGL")) + openGLLabel.setAlignment(Qt.AlignHCenter) + + layout = QGridLayout() + layout.addWidget(native, 0, 0) + layout.addWidget(openGL, 0, 1) + layout.addWidget(nativeLabel, 1, 0) + layout.addWidget(openGLLabel, 1, 1) + self.setLayout(layout) + + timer = QTimer(self) + self.connect(timer, SIGNAL("timeout()"), native.animate) + self.connect(timer, SIGNAL("timeout()"), openGL.animate) + timer.start(50) + + self.setWindowTitle(self.tr("2D Painting on Native and OpenGL Widgets")) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/opengl/contextinfo.py b/examples/opengl/contextinfo.py new file mode 100644 index 0000000..a963b89 --- /dev/null +++ b/examples/opengl/contextinfo.py @@ -0,0 +1,283 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the opengl/contextinfo example from Qt v5.x""" + +from argparse import ArgumentParser, RawTextHelpFormatter +import numpy +import sys +from textwrap import dedent + + +from PySide2.QtCore import QCoreApplication, QLibraryInfo, QSize, QTimer, Qt +from PySide2.QtGui import (QMatrix4x4, QOpenGLBuffer, QOpenGLContext, QOpenGLShader, + QOpenGLShaderProgram, QOpenGLVertexArrayObject, QSurfaceFormat, QWindow) +from PySide2.QtWidgets import (QApplication, QHBoxLayout, QMessageBox, QPlainTextEdit, + QWidget) +from PySide2.support import VoidPtr +try: + from OpenGL import GL +except ImportError: + app = QApplication(sys.argv) + messageBox = QMessageBox(QMessageBox.Critical, "ContextInfo", + "PyOpenGL must be installed to run this example.", + QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + +vertexShaderSource110 = dedent(""" + // version 110 + attribute highp vec4 posAttr; + attribute lowp vec4 colAttr; + varying lowp vec4 col; + uniform highp mat4 matrix; + void main() { + col = colAttr; + gl_Position = matrix * posAttr; + } + """) + +fragmentShaderSource110 = dedent(""" + // version 110 + varying lowp vec4 col; + void main() { + gl_FragColor = col; + } + """) + +vertexShaderSource = dedent(""" + // version 150 + in vec4 posAttr; + in vec4 colAttr; + out vec4 col; + uniform mat4 matrix; + void main() { + col = colAttr; + gl_Position = matrix * posAttr; + } + """) + +fragmentShaderSource = dedent(""" + // version 150 + in vec4 col; + out vec4 fragColor; + void main() { + fragColor = col; + } + """) + +vertices = numpy.array([0, 0.707, -0.5, -0.5, 0.5, -0.5], dtype = numpy.float32) +colors = numpy.array([1, 0, 0, 0, 1, 0, 0, 0, 1], dtype = numpy.float32) + + +def print_surface_format(surface_format): + profile_name = 'core' if surface_format.profile() == QSurfaceFormat.CoreProfile else 'compatibility' + return "{} version {}.{}".format(profile_name, + surface_format.majorVersion(), surface_format.minorVersion()) + +class RenderWindow(QWindow): + def __init__(self, format): + super(RenderWindow, self).__init__() + self.setSurfaceType(QWindow.OpenGLSurface) + self.setFormat(format) + self.context = QOpenGLContext(self) + self.context.setFormat(self.requestedFormat()) + if not self.context.create(): + raise Exception("Unable to create GL context") + self.program = None + self.timer = None + self.angle = 0 + + def initGl(self): + self.program = QOpenGLShaderProgram(self) + self.vao = QOpenGLVertexArrayObject() + self.vbo = QOpenGLBuffer() + + format = self.context.format() + useNewStyleShader = format.profile() == QSurfaceFormat.CoreProfile + # Try to handle 3.0 & 3.1 that do not have the core/compatibility profile + # concept 3.2+ has. This may still fail since version 150 (3.2) is + # specified in the sources but it's worth a try. + if (format.renderableType() == QSurfaceFormat.OpenGL and format.majorVersion() == 3 + and format.minorVersion() <= 1): + useNewStyleShader = not format.testOption(QSurfaceFormat.DeprecatedFunctions) + + vertexShader = vertexShaderSource if useNewStyleShader else vertexShaderSource110 + fragmentShader = fragmentShaderSource if useNewStyleShader else fragmentShaderSource110 + if not self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertexShader): + raise Exception("Vertex shader could not be added: {} ({})".format(self.program.log(), vertexShader)) + if not self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragmentShader): + raise Exception("Fragment shader could not be added: {} ({})".format(self.program.log(), fragmentShader)) + if not self.program.link(): + raise Exception("Could not link shaders: {}".format(self.program.log())) + + self.posAttr = self.program.attributeLocation("posAttr") + self.colAttr = self.program.attributeLocation("colAttr") + self.matrixUniform = self.program.uniformLocation("matrix") + + self.vbo.create() + self.vbo.bind() + self.verticesData = vertices.tobytes() + self.colorsData = colors.tobytes() + verticesSize = 4 * vertices.size + colorsSize = 4 * colors.size + self.vbo.allocate(VoidPtr(self.verticesData), verticesSize + colorsSize) + self.vbo.write(verticesSize, VoidPtr(self.colorsData), colorsSize) + self.vbo.release() + + vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao) + if self.vao.isCreated(): # have VAO support, use it + self.setupVertexAttribs() + + def setupVertexAttribs(self): + self.vbo.bind() + self.program.setAttributeBuffer(self.posAttr, GL.GL_FLOAT, 0, 2) + self.program.setAttributeBuffer(self.colAttr, GL.GL_FLOAT, 4 * vertices.size, 3) + self.program.enableAttributeArray(self.posAttr) + self.program.enableAttributeArray(self.colAttr) + self.vbo.release() + + def exposeEvent(self, event): + if self.isExposed(): + self.render() + if self.timer is None: + self.timer = QTimer(self) + self.timer.timeout.connect(self.slotTimer) + if not self.timer.isActive(): + self.timer.start(10) + else: + if self.timer and self.timer.isActive(): + self.timer.stop() + + def render(self): + if not self.context.makeCurrent(self): + raise Exception("makeCurrent() failed") + functions = self.context.functions() + if self.program is None: + functions.glEnable(GL.GL_DEPTH_TEST) + functions.glClearColor(0, 0, 0, 1) + self.initGl() + + retinaScale = self.devicePixelRatio() + functions.glViewport(0, 0, self.width() * retinaScale, + self.height() * retinaScale) + functions.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) + + self.program.bind() + matrix = QMatrix4x4() + matrix.perspective(60, 4 / 3, 0.1, 100) + matrix.translate(0, 0, -2) + matrix.rotate(self.angle, 0, 1, 0) + self.program.setUniformValue(self.matrixUniform, matrix) + + if self.vao.isCreated(): + self.vao.bind() + else: # no VAO support, set the vertex attribute arrays now + self.setupVertexAttribs() + + functions.glDrawArrays(GL.GL_TRIANGLES, 0, 3) + + self.vao.release() + self.program.release() + + # swapInterval is 1 by default which means that swapBuffers() will (hopefully) block + # and wait for vsync. + self.context.swapBuffers(self) + self.context.doneCurrent() + + def slotTimer(self): + self.render() + self.angle += 1 + + def glInfo(self): + if not self.context.makeCurrent(self): + raise Exception("makeCurrent() failed") + functions = self.context.functions() + text = """Vendor: {}\nRenderer: {}\nVersion: {}\nShading language: {} +\nContext Format: {}\n\nSurface Format: {}""".format( + functions.glGetString(GL.GL_VENDOR), functions.glGetString(GL.GL_RENDERER), + functions.glGetString(GL.GL_VERSION), + functions.glGetString(GL.GL_SHADING_LANGUAGE_VERSION), + print_surface_format(self.context.format()), + print_surface_format(self.format())) + self.context.doneCurrent() + return text + +class MainWindow(QWidget): + def __init__(self): + super(MainWindow, self).__init__() + hBoxLayout = QHBoxLayout(self) + self.plainTextEdit = QPlainTextEdit() + self.plainTextEdit.setMinimumWidth(400) + self.plainTextEdit.setReadOnly(True) + hBoxLayout.addWidget(self.plainTextEdit) + self.renderWindow = RenderWindow(QSurfaceFormat()) + container = QWidget.createWindowContainer(self.renderWindow) + container.setMinimumSize(QSize(400, 400)) + hBoxLayout.addWidget(container) + + def updateDescription(self): + text = "{}\n\nPython {}\n\n{}".format(QLibraryInfo.build(), sys.version, + self.renderWindow.glInfo()) + self.plainTextEdit.setPlainText(text) + +if __name__ == '__main__': + parser = ArgumentParser(description="contextinfo", formatter_class=RawTextHelpFormatter) + parser.add_argument('--gles', '-g', action='store_true', + help='Use OpenGL ES') + parser.add_argument('--software', '-s', action='store_true', + help='Use Software OpenGL') + parser.add_argument('--desktop', '-d', action='store_true', + help='Use Desktop OpenGL') + options = parser.parse_args() + if options.gles: + QCoreApplication.setAttribute(Qt.AA_UseOpenGLES) + elif options.software: + QCoreApplication.setAttribute(Qt.AA_UseSoftwareOpenGL) + elif options.desktop: + QCoreApplication.setAttribute(Qt.AA_UseDesktopOpenGL) + + app = QApplication(sys.argv) + mainWindow = MainWindow() + mainWindow.show() + mainWindow.updateDescription() + sys.exit(app.exec_()) diff --git a/examples/opengl/grabber.py b/examples/opengl/grabber.py new file mode 100644 index 0000000..4c8f9a0 --- /dev/null +++ b/examples/opengl/grabber.py @@ -0,0 +1,437 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/grabber example from Qt v5.x""" + +import sys +import math + +from PySide2 import QtCore, QtGui, QtWidgets, QtOpenGL + +try: + from OpenGL.GL import * +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL grabber", + "PyOpenGL must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class GLWidget(QtOpenGL.QGLWidget): + xRotationChanged = QtCore.Signal(int) + yRotationChanged = QtCore.Signal(int) + zRotationChanged = QtCore.Signal(int) + + def __init__(self, parent=None): + super(GLWidget, self).__init__(parent) + + self.gear1 = 0 + self.gear2 = 0 + self.gear3 = 0 + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + self.gear1Rot = 0 + + timer = QtCore.QTimer(self) + timer.timeout.connect(self.advanceGears) + timer.start(20) + + def freeResources(self): + self.makeCurrent() + glDeleteLists(self.gear1, 1) + glDeleteLists(self.gear2, 1) + glDeleteLists(self.gear3, 1) + + def setXRotation(self, angle): + self.normalizeAngle(angle) + + if angle != self.xRot: + self.xRot = angle + self.xRotationChanged.emit(angle) + self.updateGL() + + def setYRotation(self, angle): + self.normalizeAngle(angle) + + if angle != self.yRot: + self.yRot = angle + self.yRotationChanged.emit(angle) + self.updateGL() + + def setZRotation(self, angle): + self.normalizeAngle(angle) + + if angle != self.zRot: + self.zRot = angle + self.zRotationChanged.emit(angle) + self.updateGL() + + def initializeGL(self): + lightPos = (5.0, 5.0, 10.0, 1.0) + reflectance1 = (0.8, 0.1, 0.0, 1.0) + reflectance2 = (0.0, 0.8, 0.2, 1.0) + reflectance3 = (0.2, 0.2, 1.0, 1.0) + + glLightfv(GL_LIGHT0, GL_POSITION, lightPos) + glEnable(GL_LIGHTING) + glEnable(GL_LIGHT0) + glEnable(GL_DEPTH_TEST) + + self.gear1 = self.makeGear(reflectance1, 1.0, 4.0, 1.0, 0.7, 20) + self.gear2 = self.makeGear(reflectance2, 0.5, 2.0, 2.0, 0.7, 10) + self.gear3 = self.makeGear(reflectance3, 1.3, 2.0, 0.5, 0.7, 10) + + glEnable(GL_NORMALIZE) + glClearColor(0.0, 0.0, 0.0, 1.0) + + def paintGL(self): + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + glPushMatrix() + glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) + glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) + glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) + + self.drawGear(self.gear1, -3.0, -2.0, 0.0, self.gear1Rot / 16.0) + self.drawGear(self.gear2, +3.1, -2.0, 0.0, + -2.0 * (self.gear1Rot / 16.0) - 9.0) + + glRotated(+90.0, 1.0, 0.0, 0.0) + self.drawGear(self.gear3, -3.1, -1.8, -2.2, + +2.0 * (self.gear1Rot / 16.0) - 2.0) + + glPopMatrix() + + def resizeGL(self, width, height): + side = min(width, height) + if side < 0: + return + + glViewport(int((width - side) / 2), int((height - side) / 2), side, side) + + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + glTranslated(0.0, 0.0, -40.0) + + def mousePressEvent(self, event): + self.lastPos = event.pos() + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & QtCore.Qt.LeftButton: + self.setXRotation(self.xRot + 8 * dy) + self.setYRotation(self.yRot + 8 * dx) + elif event.buttons() & QtCore.Qt.RightButton: + self.setXRotation(self.xRot + 8 * dy) + self.setZRotation(self.zRot + 8 * dx) + + self.lastPos = event.pos() + + def advanceGears(self): + self.gear1Rot += 2 * 16 + self.updateGL() + + def xRotation(self): + return self.xRot + + def yRotation(self): + return self.yRot + + def zRotation(self): + return self.zRot + + def makeGear(self, reflectance, innerRadius, outerRadius, thickness, toothSize, toothCount): + list = glGenLists(1) + glNewList(list, GL_COMPILE) + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance) + + r0 = innerRadius + r1 = outerRadius - toothSize / 2.0 + r2 = outerRadius + toothSize / 2.0 + delta = (2.0 * math.pi / toothCount) / 4.0 + z = thickness / 2.0 + + glShadeModel(GL_FLAT) + + for i in range(2): + if i == 0: + sign = +1.0 + else: + sign = -1.0 + + glNormal3d(0.0, 0.0, sign) + + glBegin(GL_QUAD_STRIP) + + for j in range(toothCount+1): + angle = 2.0 * math.pi * j / toothCount + glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), sign * z) + glVertex3d(r1 * math.cos(angle), r1 * math.sin(angle), sign * z) + glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), sign * z) + glVertex3d(r1 * math.cos(angle + 3 * delta), r1 * math.sin(angle + 3 * delta), sign * z) + + glEnd() + + glBegin(GL_QUADS) + + for j in range(toothCount): + angle = 2.0 * math.pi * j / toothCount + glVertex3d(r1 * math.cos(angle), r1 * math.sin(angle), sign * z) + glVertex3d(r2 * math.cos(angle + delta), r2 * math.sin(angle + delta), sign * z) + glVertex3d(r2 * math.cos(angle + 2 * delta), r2 * math.sin(angle + 2 * delta), sign * z) + glVertex3d(r1 * math.cos(angle + 3 * delta), r1 * math.sin(angle + 3 * delta), sign * z) + + glEnd() + + glBegin(GL_QUAD_STRIP) + + for i in range(toothCount): + for j in range(2): + angle = 2.0 * math.pi * (i + (j / 2.0)) / toothCount + s1 = r1 + s2 = r2 + + if j == 1: + s1, s2 = s2, s1 + + glNormal3d(math.cos(angle), math.sin(angle), 0.0) + glVertex3d(s1 * math.cos(angle), s1 * math.sin(angle), +z) + glVertex3d(s1 * math.cos(angle), s1 * math.sin(angle), -z) + + glNormal3d(s2 * math.sin(angle + delta) - s1 * math.sin(angle), s1 * math.cos(angle) - s2 * math.cos(angle + delta), 0.0) + glVertex3d(s2 * math.cos(angle + delta), s2 * math.sin(angle + delta), +z) + glVertex3d(s2 * math.cos(angle + delta), s2 * math.sin(angle + delta), -z) + + glVertex3d(r1, 0.0, +z) + glVertex3d(r1, 0.0, -z) + glEnd() + + glShadeModel(GL_SMOOTH) + + glBegin(GL_QUAD_STRIP) + + for i in range(toothCount+1): + angle = i * 2.0 * math.pi / toothCount + glNormal3d(-math.cos(angle), -math.sin(angle), 0.0) + glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), +z) + glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), -z) + + glEnd() + + glEndList() + + return list + + def drawGear(self, gear, dx, dy, dz, angle): + glPushMatrix() + glTranslated(dx, dy, dz) + glRotated(angle, 0.0, 0.0, 1.0) + glCallList(gear) + glPopMatrix() + + def normalizeAngle(self, angle): + while (angle < 0): + angle += 360 * 16 + + while (angle > 360 * 16): + angle -= 360 * 16 + + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + centralWidget = QtWidgets.QWidget() + self.setCentralWidget(centralWidget) + + self.glWidget = GLWidget() + self.pixmapLabel = QtWidgets.QLabel() + + self.glWidgetArea = QtWidgets.QScrollArea() + self.glWidgetArea.setWidget(self.glWidget) + self.glWidgetArea.setWidgetResizable(True) + self.glWidgetArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.glWidgetArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + self.glWidgetArea.setSizePolicy(QtWidgets.QSizePolicy.Ignored, + QtWidgets.QSizePolicy.Ignored) + self.glWidgetArea.setMinimumSize(50, 50) + + self.pixmapLabelArea = QtWidgets.QScrollArea() + self.pixmapLabelArea.setWidget(self.pixmapLabel) + self.pixmapLabelArea.setSizePolicy(QtWidgets.QSizePolicy.Ignored, + QtWidgets.QSizePolicy.Ignored) + self.pixmapLabelArea.setMinimumSize(50, 50) + + xSlider = self.createSlider(self.glWidget.xRotationChanged, + self.glWidget.setXRotation) + ySlider = self.createSlider(self.glWidget.yRotationChanged, + self.glWidget.setYRotation) + zSlider = self.createSlider(self.glWidget.zRotationChanged, + self.glWidget.setZRotation) + + self.createActions() + self.createMenus() + + centralLayout = QtWidgets.QGridLayout() + centralLayout.addWidget(self.glWidgetArea, 0, 0) + centralLayout.addWidget(self.pixmapLabelArea, 0, 1) + centralLayout.addWidget(xSlider, 1, 0, 1, 2) + centralLayout.addWidget(ySlider, 2, 0, 1, 2) + centralLayout.addWidget(zSlider, 3, 0, 1, 2) + centralWidget.setLayout(centralLayout) + + xSlider.setValue(15 * 16) + ySlider.setValue(345 * 16) + zSlider.setValue(0 * 16) + + self.setWindowTitle("Grabber") + self.resize(400, 300) + + def renderIntoPixmap(self): + size = self.getSize() + + if size.isValid(): + pixmap = self.glWidget.renderPixmap(size.width(), size.height()) + self.setPixmap(pixmap) + + def grabFrameBuffer(self): + image = self.glWidget.grabFrameBuffer() + self.setPixmap(QtGui.QPixmap.fromImage(image)) + + def clearPixmap(self): + self.setPixmap(QtGui.QPixmap()) + + def about(self): + QtWidgets.QMessageBox.about(self, "About Grabber", + "The Grabber example demonstrates two approaches for " + "rendering OpenGL into a Qt pixmap.") + + def createActions(self): + self.renderIntoPixmapAct = QtWidgets.QAction("&Render into Pixmap...", + self, shortcut="Ctrl+R", triggered=self.renderIntoPixmap) + + self.grabFrameBufferAct = QtWidgets.QAction("&Grab Frame Buffer", self, + shortcut="Ctrl+G", triggered=self.grabFrameBuffer) + + self.clearPixmapAct = QtWidgets.QAction("&Clear Pixmap", self, + shortcut="Ctrl+L", triggered=self.clearPixmap) + + self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q", + triggered=self.close) + + self.aboutAct = QtWidgets.QAction("&About", self, triggered=self.about) + + self.aboutQtAct = QtWidgets.QAction("About &Qt", self, + triggered=qApp.aboutQt) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.renderIntoPixmapAct) + self.fileMenu.addAction(self.grabFrameBufferAct) + self.fileMenu.addAction(self.clearPixmapAct) + self.fileMenu.addSeparator() + self.fileMenu.addAction(self.exitAct) + + self.helpMenu = self.menuBar().addMenu("&Help") + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + def createSlider(self, changedSignal, setterSlot): + slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + slider.setRange(0, 360 * 16) + slider.setSingleStep(16) + slider.setPageStep(15 * 16) + slider.setTickInterval(15 * 16) + slider.setTickPosition(QtWidgets.QSlider.TicksRight) + + slider.valueChanged.connect(setterSlot) + changedSignal.connect(slider.setValue) + + return slider + + def setPixmap(self, pixmap): + self.pixmapLabel.setPixmap(pixmap) + size = pixmap.size() + + if size - QtCore.QSize(1, 0) == self.pixmapLabelArea.maximumViewportSize(): + size -= QtCore.QSize(1, 0) + + self.pixmapLabel.resize(size) + + def getSize(self): + text, ok = QtWidgets.QInputDialog.getText(self, "Grabber", + "Enter pixmap size:", QtWidgets.QLineEdit.Normal, + "%d x %d" % (self.glWidget.width(), self.glWidget.height())) + + if not ok: + return QtCore.QSize() + + regExp = QtCore.QRegularExpression("([0-9]+) *x *([0-9]+)") + assert regExp.isValid() + + match = regExp.match(text) + if match.hasMatch(): + width = int(match.captured(1)) + height = int(match.captured(2)) + if width > 0 and width < 2048 and height > 0 and height < 2048: + return QtCore.QSize(width, height) + + return self.glWidget.size() + + +if __name__ == '__main__': + + app = QtWidgets.QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + res = app.exec_() + mainWin.glWidget.freeResources() + sys.exit(res) diff --git a/examples/opengl/hellogl.py b/examples/opengl/hellogl.py new file mode 100644 index 0000000..f3aa73a --- /dev/null +++ b/examples/opengl/hellogl.py @@ -0,0 +1,287 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/hellogl example from Qt v5.x""" + +import sys +import math +from PySide2 import QtCore, QtGui, QtWidgets, QtOpenGL + +try: + from OpenGL import GL +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL hellogl", + "PyOpenGL must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class Window(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.glWidget = GLWidget() + + self.xSlider = self.createSlider(QtCore.SIGNAL("xRotationChanged(int)"), + self.glWidget.setXRotation) + self.ySlider = self.createSlider(QtCore.SIGNAL("yRotationChanged(int)"), + self.glWidget.setYRotation) + self.zSlider = self.createSlider(QtCore.SIGNAL("zRotationChanged(int)"), + self.glWidget.setZRotation) + + mainLayout = QtWidgets.QHBoxLayout() + mainLayout.addWidget(self.glWidget) + mainLayout.addWidget(self.xSlider) + mainLayout.addWidget(self.ySlider) + mainLayout.addWidget(self.zSlider) + self.setLayout(mainLayout) + + self.xSlider.setValue(170 * 16) + self.ySlider.setValue(160 * 16) + self.zSlider.setValue(90 * 16) + + self.setWindowTitle(self.tr("Hello GL")) + + def createSlider(self, changedSignal, setterSlot): + slider = QtWidgets.QSlider(QtCore.Qt.Vertical) + + slider.setRange(0, 360 * 16) + slider.setSingleStep(16) + slider.setPageStep(15 * 16) + slider.setTickInterval(15 * 16) + slider.setTickPosition(QtWidgets.QSlider.TicksRight) + + self.glWidget.connect(slider, QtCore.SIGNAL("valueChanged(int)"), setterSlot) + self.connect(self.glWidget, changedSignal, slider, QtCore.SLOT("setValue(int)")) + + return slider + + +class GLWidget(QtOpenGL.QGLWidget): + xRotationChanged = QtCore.Signal(int) + yRotationChanged = QtCore.Signal(int) + zRotationChanged = QtCore.Signal(int) + + def __init__(self, parent=None): + QtOpenGL.QGLWidget.__init__(self, parent) + + self.object = 0 + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + + self.lastPos = QtCore.QPoint() + + self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) + self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0) + + def xRotation(self): + return self.xRot + + def yRotation(self): + return self.yRot + + def zRotation(self): + return self.zRot + + def minimumSizeHint(self): + return QtCore.QSize(50, 50) + + def sizeHint(self): + return QtCore.QSize(400, 400) + + def setXRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.xRot: + self.xRot = angle + self.emit(QtCore.SIGNAL("xRotationChanged(int)"), angle) + self.updateGL() + + def setYRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.yRot: + self.yRot = angle + self.emit(QtCore.SIGNAL("yRotationChanged(int)"), angle) + self.updateGL() + + def setZRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.zRot: + self.zRot = angle + self.emit(QtCore.SIGNAL("zRotationChanged(int)"), angle) + self.updateGL() + + def initializeGL(self): + self.qglClearColor(self.trolltechPurple.darker()) + self.object = self.makeObject() + GL.glShadeModel(GL.GL_FLAT) + GL.glEnable(GL.GL_DEPTH_TEST) + GL.glEnable(GL.GL_CULL_FACE) + + def paintGL(self): + GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) + GL.glLoadIdentity() + GL.glTranslated(0.0, 0.0, -10.0) + GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) + GL.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) + GL.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) + GL.glCallList(self.object) + + def resizeGL(self, width, height): + side = min(width, height) + GL.glViewport(int((width - side) / 2),int((height - side) / 2), side, side) + + GL.glMatrixMode(GL.GL_PROJECTION) + GL.glLoadIdentity() + GL.glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0) + GL.glMatrixMode(GL.GL_MODELVIEW) + + def mousePressEvent(self, event): + self.lastPos = QtCore.QPoint(event.pos()) + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & QtCore.Qt.LeftButton: + self.setXRotation(self.xRot + 8 * dy) + self.setYRotation(self.yRot + 8 * dx) + elif event.buttons() & QtCore.Qt.RightButton: + self.setXRotation(self.xRot + 8 * dy) + self.setZRotation(self.zRot + 8 * dx) + + self.lastPos = QtCore.QPoint(event.pos()) + + def makeObject(self): + genList = GL.glGenLists(1) + GL.glNewList(genList, GL.GL_COMPILE) + + GL.glBegin(GL.GL_QUADS) + + x1 = +0.06 + y1 = -0.14 + x2 = +0.14 + y2 = -0.06 + x3 = +0.08 + y3 = +0.00 + x4 = +0.30 + y4 = +0.22 + + self.quad(x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(x3, y3, x4, y4, y4, x4, y3, x3) + + self.extrude(x1, y1, x2, y2) + self.extrude(x2, y2, y2, x2) + self.extrude(y2, x2, y1, x1) + self.extrude(y1, x1, x1, y1) + self.extrude(x3, y3, x4, y4) + self.extrude(x4, y4, y4, x4) + self.extrude(y4, x4, y3, x3) + + Pi = 3.14159265358979323846 + NumSectors = 200 + + for i in range(NumSectors): + angle1 = (i * 2 * Pi) / NumSectors + x5 = 0.30 * math.sin(angle1) + y5 = 0.30 * math.cos(angle1) + x6 = 0.20 * math.sin(angle1) + y6 = 0.20 * math.cos(angle1) + + angle2 = ((i + 1) * 2 * Pi) / NumSectors + x7 = 0.20 * math.sin(angle2) + y7 = 0.20 * math.cos(angle2) + x8 = 0.30 * math.sin(angle2) + y8 = 0.30 * math.cos(angle2) + + self.quad(x5, y5, x6, y6, x7, y7, x8, y8) + + self.extrude(x6, y6, x7, y7) + self.extrude(x8, y8, x5, y5) + + GL.glEnd() + GL.glEndList() + + return genList + + def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): + self.qglColor(self.trolltechGreen) + + GL.glVertex3d(x1, y1, +0.05) + GL.glVertex3d(x2, y2, +0.05) + GL.glVertex3d(x3, y3, +0.05) + GL.glVertex3d(x4, y4, +0.05) + + GL.glVertex3d(x4, y4, -0.05) + GL.glVertex3d(x3, y3, -0.05) + GL.glVertex3d(x2, y2, -0.05) + GL.glVertex3d(x1, y1, -0.05) + + def extrude(self, x1, y1, x2, y2): + self.qglColor(self.trolltechGreen.darker(250 + int(100 * x1))) + + GL.glVertex3d(x1, y1, -0.05) + GL.glVertex3d(x2, y2, -0.05) + GL.glVertex3d(x2, y2, +0.05) + GL.glVertex3d(x1, y1, +0.05) + + def normalizeAngle(self, angle): + while angle < 0: + angle += 360 * 16 + while angle > 360 * 16: + angle -= 360 * 16 + return angle + + def freeResources(self): + self.makeCurrent() + GL.glDeleteLists(self.object, 1) + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + window = Window() + window.show() + res = app.exec_() + window.glWidget.freeResources() + sys.exit(res) diff --git a/examples/opengl/hellogl2.py b/examples/opengl/hellogl2.py new file mode 100644 index 0000000..ad3562f --- /dev/null +++ b/examples/opengl/hellogl2.py @@ -0,0 +1,472 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/hellogl2 example from Qt v5.x""" + +import sys +import math +import numpy +import ctypes +from PySide2.QtCore import QCoreApplication, Signal, SIGNAL, SLOT, Qt, QSize, QPoint +from PySide2.QtGui import (QVector3D, QOpenGLFunctions, QOpenGLVertexArrayObject, QOpenGLBuffer, + QOpenGLShaderProgram, QMatrix4x4, QOpenGLShader, QOpenGLContext, QSurfaceFormat) +from PySide2.QtWidgets import (QApplication, QWidget, QMessageBox, QHBoxLayout, QSlider, + QOpenGLWidget) +from shiboken2 import VoidPtr + +try: + from OpenGL import GL +except ImportError: + app = QApplication(sys.argv) + messageBox = QMessageBox(QMessageBox.Critical, "OpenGL hellogl", + "PyOpenGL must be installed to run this example.", + QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class Window(QWidget): + def __init__(self, parent=None): + QWidget.__init__(self, parent) + + self.glWidget = GLWidget() + + self.xSlider = self.createSlider(SIGNAL("xRotationChanged(int)"), + self.glWidget.setXRotation) + self.ySlider = self.createSlider(SIGNAL("yRotationChanged(int)"), + self.glWidget.setYRotation) + self.zSlider = self.createSlider(SIGNAL("zRotationChanged(int)"), + self.glWidget.setZRotation) + + mainLayout = QHBoxLayout() + mainLayout.addWidget(self.glWidget) + mainLayout.addWidget(self.xSlider) + mainLayout.addWidget(self.ySlider) + mainLayout.addWidget(self.zSlider) + self.setLayout(mainLayout) + + self.xSlider.setValue(15 * 16) + self.ySlider.setValue(345 * 16) + self.zSlider.setValue(0 * 16) + + self.setWindowTitle(self.tr("Hello GL")) + + def createSlider(self, changedSignal, setterSlot): + slider = QSlider(Qt.Vertical) + + slider.setRange(0, 360 * 16) + slider.setSingleStep(16) + slider.setPageStep(15 * 16) + slider.setTickInterval(15 * 16) + slider.setTickPosition(QSlider.TicksRight) + + self.glWidget.connect(slider, SIGNAL("valueChanged(int)"), setterSlot) + self.connect(self.glWidget, changedSignal, slider, SLOT("setValue(int)")) + + return slider + + def keyPressEvent(self, event): + if event.key() == Qt.Key_Escape: + self.close() + else: + super(Window, self).keyPressEvent(event) + +class Logo(): + def __init__(self): + self.m_count = 0 + self.i = 0 + self.m_data = numpy.empty(2500 * 6, dtype = ctypes.c_float) + + x1 = +0.06 + y1 = -0.14 + x2 = +0.14 + y2 = -0.06 + x3 = +0.08 + y3 = +0.00 + x4 = +0.30 + y4 = +0.22 + + self.quad(x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(x3, y3, x4, y4, y4, x4, y3, x3) + + self.extrude(x1, y1, x2, y2) + self.extrude(x2, y2, y2, x2) + self.extrude(y2, x2, y1, x1) + self.extrude(y1, x1, x1, y1) + self.extrude(x3, y3, x4, y4) + self.extrude(x4, y4, y4, x4) + self.extrude(y4, x4, y3, x3) + + Pi = 3.14159265358979323846 + NumSectors = 100 + + for i in range(NumSectors): + angle = (i * 2 * Pi) / NumSectors + x5 = 0.30 * math.sin(angle) + y5 = 0.30 * math.cos(angle) + x6 = 0.20 * math.sin(angle) + y6 = 0.20 * math.cos(angle) + + angle = ((i + 1) * 2 * Pi) / NumSectors + x7 = 0.20 * math.sin(angle) + y7 = 0.20 * math.cos(angle) + x8 = 0.30 * math.sin(angle) + y8 = 0.30 * math.cos(angle) + + self.quad(x5, y5, x6, y6, x7, y7, x8, y8) + + self.extrude(x6, y6, x7, y7) + self.extrude(x8, y8, x5, y5) + + def constData(self): + return self.m_data.tobytes() + + def count(self): + return self.m_count + + def vertexCount(self): + return self.m_count / 6 + + def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): + n = QVector3D.normal(QVector3D(x4 - x1, y4 - y1, 0), QVector3D(x2 - x1, y2 - y1, 0)) + + self.add(QVector3D(x1, y1, -0.05), n) + self.add(QVector3D(x4, y4, -0.05), n) + self.add(QVector3D(x2, y2, -0.05), n) + + self.add(QVector3D(x3, y3, -0.05), n) + self.add(QVector3D(x2, y2, -0.05), n) + self.add(QVector3D(x4, y4, -0.05), n) + + n = QVector3D.normal(QVector3D(x1 - x4, y1 - y4, 0), QVector3D(x2 - x4, y2 - y4, 0)) + + self.add(QVector3D(x4, y4, 0.05), n) + self.add(QVector3D(x1, y1, 0.05), n) + self.add(QVector3D(x2, y2, 0.05), n) + + self.add(QVector3D(x2, y2, 0.05), n) + self.add(QVector3D(x3, y3, 0.05), n) + self.add(QVector3D(x4, y4, 0.05), n) + + def extrude(self, x1, y1, x2, y2): + n = QVector3D.normal(QVector3D(0, 0, -0.1), QVector3D(x2 - x1, y2 - y1, 0)) + + self.add(QVector3D(x1, y1, 0.05), n) + self.add(QVector3D(x1, y1, -0.05), n) + self.add(QVector3D(x2, y2, 0.05), n) + + self.add(QVector3D(x2, y2, -0.05), n) + self.add(QVector3D(x2, y2, 0.05), n) + self.add(QVector3D(x1, y1, -0.05), n) + + def add(self, v, n): + self.m_data[self.i] = v.x() + self.i += 1 + self.m_data[self.i] = v.y() + self.i += 1 + self.m_data[self.i] = v.z() + self.i += 1 + self.m_data[self.i] = n.x() + self.i += 1 + self.m_data[self.i] = n.y() + self.i += 1 + self.m_data[self.i] = n.z() + self.i += 1 + self.m_count += 6 + +class GLWidget(QOpenGLWidget, QOpenGLFunctions): + xRotationChanged = Signal(int) + yRotationChanged = Signal(int) + zRotationChanged = Signal(int) + + def __init__(self, parent=None): + QOpenGLWidget.__init__(self, parent) + QOpenGLFunctions.__init__(self) + + self.core = "--coreprofile" in QCoreApplication.arguments() + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + self.lastPos = 0 + self.logo = Logo() + self.vao = QOpenGLVertexArrayObject() + self.logoVbo = QOpenGLBuffer() + self.program = QOpenGLShaderProgram() + self.projMatrixLoc = 0 + self.mvMatrixLoc = 0 + self.normalMatrixLoc = 0 + self.lightPosLoc = 0 + self.proj = QMatrix4x4() + self.camera = QMatrix4x4() + self.world = QMatrix4x4() + self.transparent = "--transparent" in QCoreApplication.arguments() + if self.transparent: + fmt = self.format() + fmt.setAlphaBufferSize(8) + self.setFormat(fmt) + + def xRotation(self): + return self.xRot + + def yRotation(self): + return self.yRot + + def zRotation(self): + return self.zRot + + def minimumSizeHint(self): + return QSize(50, 50) + + def sizeHint(self): + return QSize(400, 400) + + def normalizeAngle(self, angle): + while angle < 0: + angle += 360 * 16 + while angle > 360 * 16: + angle -= 360 * 16 + return angle + + def setXRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.xRot: + self.xRot = angle + self.emit(SIGNAL("xRotationChanged(int)"), angle) + self.update() + + def setYRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.yRot: + self.yRot = angle + self.emit(SIGNAL("yRotationChanged(int)"), angle) + self.update() + + def setZRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.zRot: + self.zRot = angle + self.emit(SIGNAL("zRotationChanged(int)"), angle) + self.update() + + def cleanup(self): + self.makeCurrent() + self.logoVbo.destroy() + del self.program + self.program = None + self.doneCurrent() + + def vertexShaderSourceCore(self): + return """#version 150 + in vec4 vertex; + in vec3 normal; + out vec3 vert; + out vec3 vertNormal; + uniform mat4 projMatrix; + uniform mat4 mvMatrix; + uniform mat3 normalMatrix; + void main() { + vert = vertex.xyz; + vertNormal = normalMatrix * normal; + gl_Position = projMatrix * mvMatrix * vertex; + }""" + + def fragmentShaderSourceCore(self): + return """#version 150 + in highp vec3 vert; + in highp vec3 vertNormal; + out highp vec4 fragColor; + uniform highp vec3 lightPos; + void main() { + highp vec3 L = normalize(lightPos - vert); + highp float NL = max(dot(normalize(vertNormal), L), 0.0); + highp vec3 color = vec3(0.39, 1.0, 0.0); + highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0); + fragColor = vec4(col, 1.0); + }""" + + + def vertexShaderSource(self): + return """attribute vec4 vertex; + attribute vec3 normal; + varying vec3 vert; + varying vec3 vertNormal; + uniform mat4 projMatrix; + uniform mat4 mvMatrix; + uniform mat3 normalMatrix; + void main() { + vert = vertex.xyz; + vertNormal = normalMatrix * normal; + gl_Position = projMatrix * mvMatrix * vertex; + }""" + + def fragmentShaderSource(self): + return """varying highp vec3 vert; + varying highp vec3 vertNormal; + uniform highp vec3 lightPos; + void main() { + highp vec3 L = normalize(lightPos - vert); + highp float NL = max(dot(normalize(vertNormal), L), 0.0); + highp vec3 color = vec3(0.39, 1.0, 0.0); + highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0); + gl_FragColor = vec4(col, 1.0); + }""" + + def initializeGL(self): + self.context().aboutToBeDestroyed.connect(self.cleanup) + self.initializeOpenGLFunctions() + self.glClearColor(0, 0, 0, 1) + + self.program = QOpenGLShaderProgram() + + if self.core: + self.vertexShader = self.vertexShaderSourceCore() + self.fragmentShader = self.fragmentShaderSourceCore() + else: + self.vertexShader = self.vertexShaderSource() + self.fragmentShader = self.fragmentShaderSource() + + self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, self.vertexShader) + self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, self.fragmentShader) + self.program.bindAttributeLocation("vertex", 0) + self.program.bindAttributeLocation("normal", 1) + self.program.link() + + self.program.bind() + self.projMatrixLoc = self.program.uniformLocation("projMatrix") + self.mvMatrixLoc = self.program.uniformLocation("mvMatrix") + self.normalMatrixLoc = self.program.uniformLocation("normalMatrix") + self.lightPosLoc = self.program.uniformLocation("lightPos") + + self.vao.create() + vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao) + + self.logoVbo.create() + self.logoVbo.bind() + float_size = ctypes.sizeof(ctypes.c_float) + self.logoVbo.allocate(self.logo.constData(), self.logo.count() * float_size) + + self.setupVertexAttribs() + + self.camera.setToIdentity() + self.camera.translate(0, 0, -1) + + self.program.setUniformValue(self.lightPosLoc, QVector3D(0, 0, 70)) + self.program.release() + vaoBinder = None + + def setupVertexAttribs(self): + self.logoVbo.bind() + f = QOpenGLContext.currentContext().functions() + f.glEnableVertexAttribArray(0) + f.glEnableVertexAttribArray(1) + float_size = ctypes.sizeof(ctypes.c_float) + + null = VoidPtr(0) + pointer = VoidPtr(3 * float_size) + f.glVertexAttribPointer(0, 3, int(GL.GL_FLOAT), int(GL.GL_FALSE), 6 * float_size, null) + f.glVertexAttribPointer(1, 3, int(GL.GL_FLOAT), int(GL.GL_FALSE), 6 * float_size, pointer) + self.logoVbo.release() + + def paintGL(self): + self.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) + self.glEnable(GL.GL_DEPTH_TEST) + self.glEnable(GL.GL_CULL_FACE) + + self.world.setToIdentity() + self.world.rotate(180 - (self.xRot / 16), 1, 0, 0) + self.world.rotate(self.yRot / 16, 0, 1, 0) + self.world.rotate(self.zRot / 16, 0, 0, 1) + + vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao) + self.program.bind() + self.program.setUniformValue(self.projMatrixLoc, self.proj) + self.program.setUniformValue(self.mvMatrixLoc, self.camera * self.world) + normalMatrix = self.world.normalMatrix() + self.program.setUniformValue(self.normalMatrixLoc, normalMatrix) + + self.glDrawArrays(GL.GL_TRIANGLES, 0, self.logo.vertexCount()) + self.program.release() + vaoBinder = None + + def resizeGL(self, width, height): + self.proj.setToIdentity() + self.proj.perspective(45, width / height, 0.01, 100) + + def mousePressEvent(self, event): + self.lastPos = QPoint(event.pos()) + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & Qt.LeftButton: + self.setXRotation(self.xRot + 8 * dy) + self.setYRotation(self.yRot + 8 * dx) + elif event.buttons() & Qt.RightButton: + self.setXRotation(self.xRot + 8 * dy) + self.setZRotation(self.zRot + 8 * dx) + + self.lastPos = QPoint(event.pos()) + +if __name__ == '__main__': + app = QApplication(sys.argv) + + fmt = QSurfaceFormat() + fmt.setDepthBufferSize(24) + if "--multisample" in QCoreApplication.arguments(): + fmt.setSamples(4) + if "--coreprofile" in QCoreApplication.arguments(): + fmt.setVersion(3, 2) + fmt.setProfile(QSurfaceFormat.CoreProfile) + QSurfaceFormat.setDefaultFormat(fmt) + + mainWindow = Window() + if "--transparent" in QCoreApplication.arguments(): + mainWindow.setAttribute(Qt.WA_TranslucentBackground) + mainWindow.setAttribute(Qt.WA_NoSystemBackground, False) + + mainWindow.resize(mainWindow.sizeHint()) + mainWindow.show() + + res = app.exec_() + sys.exit(res) diff --git a/examples/opengl/opengl.pyproject b/examples/opengl/opengl.pyproject new file mode 100644 index 0000000..12f435d --- /dev/null +++ b/examples/opengl/opengl.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["grabber.py", "samplebuffers.py", "hellogl.py", + "hellogl2.py", "contextinfo.py", "2dpainting.py", + "overpainting.py"] +} diff --git a/examples/opengl/overpainting.py b/examples/opengl/overpainting.py new file mode 100644 index 0000000..786337f --- /dev/null +++ b/examples/opengl/overpainting.py @@ -0,0 +1,385 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/overpainting example from Qt v5.x""" + +import sys +import math, random +from PySide2.QtCore import * +from PySide2.QtGui import * +from PySide2.QtWidgets import * +from PySide2.QtOpenGL import * + +try: + from OpenGL.GL import * +except ImportError: + app = QApplication(sys.argv) + messageBox = QMessageBox(QMessageBox.Critical, "OpenGL overpainting", + "PyOpenGL must be installed to run this example.", + QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class Bubble: + def __init__(self, position, radius, velocity): + self.position = position + self.vel = velocity + self.radius = radius + self.innerColor = self.randomColor() + self.outerColor = self.randomColor() + self.updateBrush() + + def updateBrush(self): + gradient = QRadialGradient(QPointF(self.radius, self.radius), self.radius, + QPointF(self.radius*0.5, self.radius*0.5)) + + gradient.setColorAt(0, QColor(255, 255, 255, 255)) + gradient.setColorAt(0.25, self.innerColor) + gradient.setColorAt(1, self.outerColor) + self.brush = QBrush(gradient) + + def drawBubble(self, painter): + painter.save() + painter.translate(self.position.x() - self.radius, + self.position.y() - self.radius) + painter.setBrush(self.brush) + painter.drawEllipse(0, 0, int(2*self.radius), int(2*self.radius)) + painter.restore() + + def randomColor(self): + red = random.randrange(205, 256) + green = random.randrange(205, 256) + blue = random.randrange(205, 256) + alpha = random.randrange(91, 192) + + return QColor(red, green, blue, alpha) + + def move(self, bbox): + self.position += self.vel + leftOverflow = self.position.x() - self.radius - bbox.left() + rightOverflow = self.position.x() + self.radius - bbox.right() + topOverflow = self.position.y() - self.radius - bbox.top() + bottomOverflow = self.position.y() + self.radius - bbox.bottom() + + if leftOverflow < 0.0: + self.position.setX(self.position.x() - 2 * leftOverflow) + self.vel.setX(-self.vel.x()) + elif rightOverflow > 0.0: + self.position.setX(self.position.x() - 2 * rightOverflow) + self.vel.setX(-self.vel.x()) + + if topOverflow < 0.0: + self.position.setY(self.position.y() - 2 * topOverflow) + self.vel.setY(-self.vel.y()) + elif bottomOverflow > 0.0: + self.position.setY(self.position.y() - 2 * bottomOverflow) + self.vel.setY(-self.vel.y()) + + def rect(self): + return QRectF(self.position.x() - self.radius, + self.position.y() - self.radius, + 2 * self.radius, 2 * self.radius) + + +class GLWidget(QGLWidget): + def __init__(self, parent = None): + QGLWidget.__init__(self, QGLFormat(QGL.SampleBuffers), parent) + + midnight = QTime(0, 0, 0) + random.seed(midnight.secsTo(QTime.currentTime())) + + self.object = 0 + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + self.image = QImage() + self.bubbles = [] + self.lastPos = QPoint() + + self.trolltechGreen = QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) + self.trolltechPurple = QColor.fromCmykF(0.39, 0.39, 0.0, 0.0) + + self.animationTimer = QTimer() + self.animationTimer.setSingleShot(False) + self.connect(self.animationTimer, SIGNAL("timeout()"), self.animate) + self.animationTimer.start(25) + + self.setAttribute(Qt.WA_NoSystemBackground) + self.setMinimumSize(200, 200) + self.setWindowTitle(self.tr("Overpainting a Scene")) + + def freeResources(self): + self.makeCurrent() + glDeleteLists(self.object, 1) + + def setXRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.xRot: + self.xRot = angle + self.emit(SIGNAL("xRotationChanged(int)"), angle) + + def setYRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.yRot: + self.yRot = angle + self.emit(SIGNAL("yRotationChanged(int)"), angle) + + def setZRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.zRot: + self.zRot = angle + self.emit(SIGNAL("zRotationChanged(int)"), angle) + + def initializeGL(self): + self.object = self.makeObject() + + def mousePressEvent(self, event): + self.lastPos = QPoint(event.pos()) + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & Qt.LeftButton: + self.setXRotation(self.xRot + 8 * dy) + self.setYRotation(self.yRot + 8 * dx) + elif event.buttons() & Qt.RightButton: + self.setXRotation(self.xRot + 8 * dy) + self.setZRotation(self.zRot + 8 * dx) + + self.lastPos = QPoint(event.pos()) + + def paintEvent(self, event): + painter = QPainter() + painter.begin(self) + painter.setRenderHint(QPainter.Antialiasing) + + glPushAttrib(GL_ALL_ATTRIB_BITS) + glMatrixMode(GL_PROJECTION) + glPushMatrix() + glMatrixMode(GL_MODELVIEW) + glPushMatrix() + + self.qglClearColor(self.trolltechPurple.darker()) + glShadeModel(GL_SMOOTH) + glEnable(GL_DEPTH_TEST) + glEnable(GL_CULL_FACE) + glEnable(GL_LIGHTING) + glEnable(GL_LIGHT0) + lightPosition = ( 0.5, 5.0, 7.0, 1.0 ) + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition) + + self.resizeGL(self.width(), self.height()) + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + glLoadIdentity() + glTranslated(0.0, 0.0, -10.0) + glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) + glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) + glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) + glCallList(self.object) + + glPopAttrib() + glMatrixMode(GL_MODELVIEW) + glPopMatrix() + glMatrixMode(GL_PROJECTION) + glPopMatrix() + + glDisable(GL_CULL_FACE) ### not required if begin() also does it + + for bubble in self.bubbles: + if bubble.rect().intersects(QRectF(event.rect())): + bubble.drawBubble(painter) + + painter.drawImage((self.width() - self.image.width())/2, 0, self.image) + painter.end() + + def resizeGL(self, width, height): + side = min(width, height) + glViewport(int((width - side) / 2), int((height - side) / 2), side, side) + + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0) + glMatrixMode(GL_MODELVIEW) + + self.formatInstructions(width, height) + + def showEvent(self, event): + self.createBubbles(20 - len(self.bubbles)) + + def sizeHint(self): + return QSize(400, 400) + + def makeObject(self): + list = glGenLists(1) + glNewList(list, GL_COMPILE) + + glEnable(GL_NORMALIZE) + glBegin(GL_QUADS) + + logoDiffuseColor = (self.trolltechGreen.red()/255.0, + self.trolltechGreen.green()/255.0, + self.trolltechGreen.blue()/255.0, 1.0) + glMaterialfv(GL_FRONT, GL_DIFFUSE, logoDiffuseColor) + + x1 = +0.06 + y1 = -0.14 + x2 = +0.14 + y2 = -0.06 + x3 = +0.08 + y3 = +0.00 + x4 = +0.30 + y4 = +0.22 + + self.quad(x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(x3, y3, x4, y4, y4, x4, y3, x3) + + self.extrude(x1, y1, x2, y2) + self.extrude(x2, y2, y2, x2) + self.extrude(y2, x2, y1, x1) + self.extrude(y1, x1, x1, y1) + self.extrude(x3, y3, x4, y4) + self.extrude(x4, y4, y4, x4) + self.extrude(y4, x4, y3, x3) + + NumSectors = 200 + + for i in range(NumSectors): + angle1 = (i * 2 * math.pi) / NumSectors + x5 = 0.30 * math.sin(angle1) + y5 = 0.30 * math.cos(angle1) + x6 = 0.20 * math.sin(angle1) + y6 = 0.20 * math.cos(angle1) + + angle2 = ((i + 1) * 2 * math.pi) / NumSectors + x7 = 0.20 * math.sin(angle2) + y7 = 0.20 * math.cos(angle2) + x8 = 0.30 * math.sin(angle2) + y8 = 0.30 * math.cos(angle2) + + self.quad(x5, y5, x6, y6, x7, y7, x8, y8) + + self.extrude(x6, y6, x7, y7) + self.extrude(x8, y8, x5, y5) + + glEnd() + + glEndList() + return list + + def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): + glNormal3d(0.0, 0.0, -1.0) + glVertex3d(x1, y1, -0.05) + glVertex3d(x2, y2, -0.05) + glVertex3d(x3, y3, -0.05) + glVertex3d(x4, y4, -0.05) + + glNormal3d(0.0, 0.0, 1.0) + glVertex3d(x4, y4, +0.05) + glVertex3d(x3, y3, +0.05) + glVertex3d(x2, y2, +0.05) + glVertex3d(x1, y1, +0.05) + + def extrude(self, x1, y1, x2, y2): + self.qglColor(self.trolltechGreen.darker(250 + int(100 * x1))) + + glNormal3d((x1 + x2)/2.0, (y1 + y2)/2.0, 0.0) + glVertex3d(x1, y1, +0.05) + glVertex3d(x2, y2, +0.05) + glVertex3d(x2, y2, -0.05) + glVertex3d(x1, y1, -0.05) + + def normalizeAngle(self, angle): + while angle < 0: + angle += 360 * 16 + while angle > 360 * 16: + angle -= 360 * 16 + return angle + + def createBubbles(self, number): + for i in range(number): + position = QPointF(self.width()*(0.1 + 0.8*random.random()), + self.height()*(0.1 + 0.8*random.random())) + radius = min(self.width(), self.height())*(0.0125 + 0.0875*random.random()) + velocity = QPointF(self.width()*0.0125*(-0.5 + random.random()), + self.height()*0.0125*(-0.5 + random.random())) + + self.bubbles.append(Bubble(position, radius, velocity)) + + def animate(self): + for bubble in self.bubbles: + self.update(bubble.rect().toRect()) + bubble.move(self.rect()) + self.update(bubble.rect().toRect()) + + def formatInstructions(self, width, height): + text = self.tr("Click and drag with the left mouse button " + "to rotate the Qt logo.") + metrics = QFontMetrics(self.font()) + border = max(4, metrics.leading()) + + rect = metrics.boundingRect(0, 0, width - 2*border, int(height*0.125), + Qt.AlignCenter | Qt.TextWordWrap, text) + self.image = QImage(width, rect.height() + 2*border, + QImage.Format_ARGB32_Premultiplied) + self.image.fill(qRgba(0, 0, 0, 127)) + + painter = QPainter() + painter.begin(self.image) + painter.setRenderHint(QPainter.TextAntialiasing) + painter.setPen(Qt.white) + painter.drawText((width - rect.width())/2, border, + rect.width(), rect.height(), + Qt.AlignCenter | Qt.TextWordWrap, text) + painter.end() + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = GLWidget() + window.show() + res = app.exec_() + window.freeResources() + sys.exit(res) diff --git a/examples/opengl/samplebuffers.py b/examples/opengl/samplebuffers.py new file mode 100644 index 0000000..ad5b794 --- /dev/null +++ b/examples/opengl/samplebuffers.py @@ -0,0 +1,192 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/samplebuffers example from Qt v5.x""" + +import sys +import math +from PySide2 import QtCore, QtGui, QtWidgets, QtOpenGL + +try: + from OpenGL import GL +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL samplebuffers", + "PyOpenGL must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class GLWidget(QtOpenGL.QGLWidget): + GL_MULTISAMPLE = 0x809D + rot = 0.0 + + def __init__(self, parent=None): + QtOpenGL.QGLWidget.__init__(self, QtOpenGL.QGLFormat(QtOpenGL.QGL.SampleBuffers), parent) + + self.list_ = [] + + self.startTimer(40) + self.setWindowTitle(self.tr("Sample Buffers")) + + def initializeGL(self): + GL.glMatrixMode(GL.GL_PROJECTION) + GL.glLoadIdentity() + GL.glOrtho( -.5, .5, .5, -.5, -1000, 1000) + GL.glMatrixMode(GL.GL_MODELVIEW) + GL.glLoadIdentity() + GL.glClearColor(1.0, 1.0, 1.0, 1.0) + + self.makeObject() + + def resizeGL(self, w, h): + GL.glViewport(0, 0, w, h) + + def paintGL(self): + GL.glClear(GL.GL_COLOR_BUFFER_BIT) + + GL.glMatrixMode(GL.GL_MODELVIEW) + GL.glPushMatrix() + GL.glEnable(GLWidget.GL_MULTISAMPLE) + GL.glTranslatef( -0.25, -0.10, 0.0) + GL.glScalef(0.75, 1.15, 0.0) + GL.glRotatef(GLWidget.rot, 0.0, 0.0, 1.0) + GL.glCallList(self.list_) + GL.glPopMatrix() + + GL.glPushMatrix() + GL.glDisable(GLWidget.GL_MULTISAMPLE) + GL.glTranslatef(0.25, -0.10, 0.0) + GL.glScalef(0.75, 1.15, 0.0) + GL.glRotatef(GLWidget.rot, 0.0, 0.0, 1.0) + GL.glCallList(self.list_) + GL.glPopMatrix() + + GLWidget.rot += 0.2 + + self.qglColor(QtCore.Qt.black) + self.renderText(-0.35, 0.4, 0.0, "Multisampling enabled") + self.renderText(0.15, 0.4, 0.0, "Multisampling disabled") + + def timerEvent(self, event): + self.update() + + def makeObject(self): + trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) + Pi = 3.14159265358979323846 + NumSectors = 15 + x1 = +0.06 + y1 = -0.14 + x2 = +0.14 + y2 = -0.06 + x3 = +0.08 + y3 = +0.00 + x4 = +0.30 + y4 = +0.22 + + self.list_ = GL.glGenLists(1) + GL.glNewList(self.list_, GL.GL_COMPILE) + + for i in range(NumSectors): + angle1 = float((i * 2 * Pi) / NumSectors) + x5 = 0.30 * math.sin(angle1) + y5 = 0.30 * math.cos(angle1) + x6 = 0.20 * math.sin(angle1) + y6 = 0.20 * math.cos(angle1) + + angle2 = float(((i + 1) * 2 * Pi) / NumSectors) + x7 = 0.20 * math.sin(angle2) + y7 = 0.20 * math.cos(angle2) + x8 = 0.30 * math.sin(angle2) + y8 = 0.30 * math.cos(angle2) + + self.qglColor(trolltechGreen) + self.quad(GL.GL_QUADS, x5, y5, x6, y6, x7, y7, x8, y8) + self.qglColor(QtCore.Qt.black) + self.quad(GL.GL_LINE_LOOP, x5, y5, x6, y6, x7, y7, x8, y8) + + self.qglColor(trolltechGreen) + self.quad(GL.GL_QUADS, x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(GL.GL_QUADS, x3, y3, x4, y4, y4, x4, y3, x3) + + self.qglColor(QtCore.Qt.black) + self.quad(GL.GL_LINE_LOOP, x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(GL.GL_LINE_LOOP, x3, y3, x4, y4, y4, x4, y3, x3) + + GL.glEndList() + + def quad(self, primitive, x1, y1, x2, y2, x3, y3, x4, y4): + GL.glBegin(primitive) + + GL.glVertex2d(x1, y1) + GL.glVertex2d(x2, y2) + GL.glVertex2d(x3, y3) + GL.glVertex2d(x4, y4) + + GL.glEnd() + + def freeResources(self): + self.makeCurrent() + GL.glDeleteLists(self.list_, 1) + + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + + if not QtOpenGL.QGLFormat.hasOpenGL(): + QMessageBox.information(0, "OpenGL pbuffers", + "This system does not support OpenGL.", + QMessageBox.Ok) + sys.exit(1) + + f = QtOpenGL.QGLFormat.defaultFormat() + f.setSampleBuffers(True) + QtOpenGL.QGLFormat.setDefaultFormat(f) + + widget = GLWidget() + widget.resize(640, 480) + widget.show() + res = app.exec_() + widget.freeResources() + sys.exit(res) diff --git a/examples/opengl/textures/images/side1.png b/examples/opengl/textures/images/side1.png new file mode 100644 index 0000000000000000000000000000000000000000..68fd4336d407d8a3abaddeaa14a3925c918519dd GIT binary patch literal 1044 zcmc)IdrZbk>xq7)G zgjnH%&?tl`l2XW-PC`mujEICA!fhfxGZYYRP)vA0DZz$|Y`C%nuK0nJ;KDU7 z$aqjCfGQ!>5HU~}1NCC4Plo$MIw*-8Q00Ic!_#8WTm+32bW+gEz*qyudN2`6=vG3X z8u~OaMCiey2dfFJeK0~;;5#t_KmgbwFsmw^9MvUV5SvM&V6tw}rmRPZK07>gqbR5A zQ_tSa4xStCFLCqnqI?dgGVfv5KDT`qha>Gl=j%)E8B4htO<(d~)m#0wdz5eH=&q0Y zk$p(%_AH!u7AvhL?&svdKO5}u;LE+(vrm>KVw*DC5!jpTBxN;MHwV8!qgx+!sH$9K zf+z2K;&agvpQA}*74F#1sd;ZUAYr4efzsW6*uueg&zkkE98a+gT5ryj3C!_GFATL1w}J(-2s~dDNK^Dz8Ais z;Z)o;NngOXycIOx#q=-x>F4Cs(BYvlq zw>)k>uixo%M^J;t|1rPBm^(J{Z~u4UCgD3LaHKzPo|k$+(v|rdT|S6wlX1R3&(~8u z;NmyF+mDw_iK80Py~tm;nr68Q&zJ5|^%OItKT6XWSGjoD)M794&_%4F2aEcHMy+w>-1oL?$iGHgBvIM N;r#8P@=fB?zX5W6naThF literal 0 HcmV?d00001 diff --git a/examples/opengl/textures/images/side2.png b/examples/opengl/textures/images/side2.png new file mode 100644 index 0000000000000000000000000000000000000000..b12d30d497620e0fa8b3098ebeed08b8031a1c72 GIT binary patch literal 1768 zcmb8v`BT%^769=3O=1E>c3x#OW|W5rR8$ZmvP2VWf-DhPi_ow8G@~qNI}w~F@Rv^6=*PQ0)f=W5(9<=zl0|CA85~f?mc(T%)N8ZFXs{? z^suRky$Jxoluo0D0|4od5HLdPQ+iWOgg%upf+G$ABnKd{5dvEn6x$-jL<6o1!rf(1 zK|(6X20R+VV;D5XAdO6emQKV7T`M%S zE{p~b8}u*!^Kd3aRyUWrEXUv8{rl3zT|q->QAQ5n`L|07^%-~Ud$o9WBV(R0Jov1S zU3EDYrR01@$&DU!<2msj`^+Cj29Qi z0>A3j)Z4jUCKIydBAN6TBG@^Vv!%BWa;bA+Ak;%SBStWJEOuqnHc;UQqU?ci^QGi8AcXyjpPuC$FGtGvzMqMrX|)SZMPo^?%{xZ_X*jDS9rpkJfuVIX)In z*lI2rGiC<%M+cOS?y`#*fWAD(ATei}i#W#F1CTDSb}I3*VD>J!{v6W1x;R7$6cAPk zL^H;S-MTVzI_wSLf2EUlib86trpOKxM+np7x1J1iWm^wDhMxKLe3S*`+G1L2O_f@@ z`sJ)e{EoeuaBA?{q!)%*XR6$1-j?r~ObeL)4Xe3@dnEh6l%lpd{y&hHq7_9~8g~Pi zFHX#RG;q)fhZ{1q@FXb>&YIiOV-tl*0ZlK<7n|>)EYskWjQ)cBqZM4NX4$-*-^F5S zz9ib-X_0@=#|}$55%<|FDhg~V#jPh;--)+$6;1!Lh0>U7ECyl`D>(rz-hLvk4X~sdVf?jP@l$;>^l7ePNm$2CQmGY{r_16 zwZNmqq&5ZG`8)c_5>6m>eXANq4|pnU%2uqHEPaK93-HmWtTArn5^f>`i*puT>1c}v zA#h9x$1xVXeUOSLZe-s-Jd=VJ1|6;Oi-hruphgB-A|G#b#!JQtssSmGbeb9UM}g&X zR7Ii>ZDil6!W|ZLnD!zHB*J6ob6nueaK^|>uXbhmH+!vNbL0@Yy(gIX~@KYj4{8qBKk+7esHcf&W)VA9+t0-+b;ah(uI?bk$RfQS@~ecRaL7uy!nQzbtn9J znX1(p&PMYB4{77r6i{%*SLdXOi~X-^t|hGX&W9sb{PLr=8uK}wEa+e8ta#k9)~=?9 zE4#iL?;7bS(jsoJ7Qb73`gL>ZO=IQ2Iebu?>{(G|d(l&Y{fTv&Dd4X3{&;Mx$=#e- zZWp+=kK9xz3LMScdJ{Yk{{{)AJCLb2r)m~9;pE7hk%QTY*}aWCV!>>%EnK9UI*W;i zeHj+(S;MQ-fE6@(56{qE8wB;Wn)|3*)yaFwcijtWfgA3xxynm2l0hWkj%&=sHD=&k wGH|?v&wNh)?V-zbgEK!(>vfcXQeZ z0HW9;KpC%y{XBm^MSNj;`Z-4fh$;{usti$em_mjr^I-}Frchyu0Zdmggz3gGod(la z!Yl=Am_>(K_ArY9xe88@>jt@=kjsR{3VyKI9~QG=F$W41f}tP;3PPbE910Z4=c-0HRGqa-4$(8pG z^)?ypwk_-Wv%|I4VwIICqam3A2)`Lrg_8k7#*7%e6*2$4`af1)GG9GlPlmbt@WxDn z$(Tv5+2$rzjB^?uZE={PWf#&sk^=TrTVaFz%==#NJvSZP@rWQEnX@$cbxF&^%4$8V z*FP!)yGGBCByeYGLeWlbQ!Q_>T`%9hKVr)O6%=n#`I|p&)!ptIg6pGLCwmH|*g#h8S+e zDc@ddi`w-JRu-IBm!3Zo(?hgGBU`~If)0j!o7WcO2Oc+288QwIE@EUvdbkqA8U;;1 zwKXw!GC1Z0@=n_?S)pZsv@0j4PBzW05Fl<#kal6|?d}JhFJl?WV8D zr`3#cOFCJrdyj6Yd6qb7OI63-NaV-s_cI%j*c%|^=if)(tYcHv2;9L)hb>k_SvRPi zI{V4oEC1vL+PPoDzw{g(7CZI?MqJ)z|HXlSr-p#hR!pb`;=)7iXSGt)(6M@^_Zc-b z;&?XI^Ks~W#_}m<=#wwd=tUcuCb|RA-X$)6(PUO?q0rJ9dNt!A0P814^$ukn{FpQ zUz!X+*`EVuNkRgk&_|3c`?Wx3QTT~^XLEOtd#muU!4!4BDH~xvA_{Kn&&HjFM1RwY za*Ek`sidv zbV>VcjIU7rqden`B^st8?$>9O5u#IR=oD7m8nf3XZnHxX1z$WlK)kT&jbnZ8Rb3x~ zu;C1C)%N~AP#fbZ7OF%GUJJ~kghIFr|votJXb=rlIOMh7-S)?2tG8yX+ z^GU`A&F`A4iVD=jpB}sKC5o%9c)_3RLu!9~C^gUOk?M0ki9lKzT-W^fd=>B zmiXagr`cW&r`_lAj!J?S&y#e7SPgZTZnKdDtqXkmjBo<|aDY_C&sVl7qph((KYH*G z^#qE^m0#gM4yD|Em5rx3U`8V!rjs_A$mk(lQ2i?Y$Uxi3t5}SPL-6R>k5xnE=2PPG zz(N%|XqaH}|9Yg&Z}MCR*8Io}n!~ioUHf6;g0!_f!O{Xp1KOpbxA$ed;Z7dv*F^U) z@SI#}_EU>vwt3tA--;HK+SzG#=z(+5{k>5`Nm0%BSYPP0Uw}aX-uqtkt?lDAe~yxz zs~?Q_D&p9RE9(%@OT5_=O{@iXXt(n9@f>`J;96|Kxzc;1_%eCh3mLC&F{deH%GDQK z21BNWdCC4UBurKMY-gtbHAG4rm6)4I*nmSqYYu+AcItIk4S7)6$mdYRrEk_h4;>_8 ziVuaSx#bF0;X8dBvWMwUr!heu?2LYm%n!}X%% z4<$V>16SvI)?PGNx-oltrfqz0nd4T>HO+X>87)P7{_hwlh|v3|U`OYWyVm^fVDiwI Y&gWFukWRh775xr?yR)|we=R5BKW?))oB#j- literal 0 HcmV?d00001 diff --git a/examples/opengl/textures/images/side4.png b/examples/opengl/textures/images/side4.png new file mode 100644 index 0000000000000000000000000000000000000000..19829d2d6debc1ffac9c3780f43bf93ec06b5ae9 GIT binary patch literal 1342 zcma*nYfuwM902gWT#^froCpeso@rowK(tgWViXzZ& z6+iWa?~e}Qj-1%z%gISlfxcZ7Y4`QdFwSmY&4>v@Z5M&LS$xZQ4rEqn_+AH5&9Iic z4q`@y#?&T(oC=L?c7gCz&00JogMsTPhnj!*_kv3jC{K&6E+Q8s1+n7XBKK^Yl2r%xqNHuO=qiiPeT zca{XqDi5Bn4n7-X07c57LPd(qlxrDCmB9X?^OI$i_hKTsenA2#lBX+Z?&mT}Mv1?} z*;+U#s<$Z}pU^*YR*<}9QGOX|3b#h`pwFLqeE4^Jk*SABW z^S6O2A_kaW#E&)zb2XgD3)%+uCYeCoXz=y4RmFZ5*s^j8cxLOjo_fVq9@t zSKiJGPU8KmF|Js_D8DYJr4mlnT~m+#JUeVTDy4=kM_Q^gc$4!Nxmzq%S0iN!e$sWR<$uE*Xf4FrQWit+v7E*lJ zuu{8m>}wk7{>Fh&bOmLP;DzSo;ZSZ^-u_Ou z`~tCfo$%@$ZU?Q4nZuRS{C3)_s%@3(FaFERKb)m$iGTMHWsQtldY>p>lot~tu!x8 zx9aRfy+>A4zU-^5Zas`}gdOgjOguj(6(dV7E&h_>z7m>tb8swKv!BY3X|^UV51ZmU z*J5hY3saa$cY^+@O(yc=q1x2{Q?4U>^uYbH(s@caH&Wza)1OK@qb`^4FAl(e3Yed| LFy))Mmh!&<$8RVO literal 0 HcmV?d00001 diff --git a/examples/opengl/textures/images/side5.png b/examples/opengl/textures/images/side5.png new file mode 100644 index 0000000000000000000000000000000000000000..3843b1229db89f2e601512cd6022661fa9d4485f GIT binary patch literal 1959 zcmb8w`#Y3*9|!R7-HaJo#^jJ$Av(yZnuMg0TT-k;qb7$;i*iibu|?!`vsR+w$zg?E zhZP!fi10Xd7g3FBRu034d#%SY3^~k`d$OkgV6W@-z22W6zt`u7&-)hB@uZxLstf=? z&erDmX#k*&5dzYLjR-7vWo^VAraj9#3MJM`y;98)UE)9&YETD}F^ zYDt9HY* zAQ}G^tfI_nII`bXUf31NK2%QbJVNx!W%z_UIfuM=Z2VLaG|gowhi4vDk7;+JiOBCl zR_c6I8#@NBbjH|Hn2XQ43_6U5=nlN$BX?)Q$?FG1!vA;dKlvj9e#LxkDAWQd@)e|D z1Zy9LlSux%$vSA>NV?eAH4b77K$qyK`~Y;04r__+sj@=58-OCl?Z3Q8rAYC|$aJ5W zZwjHyI>>GdR71v-Cy#L{9Hu(v6oN2A5ZC2;V6tP;AsS&V-(qTq+bB^|%UZXh9qrCl zs>IIru@Th>C-GjUWek*ogXNoIblrrw{!#j~CGA9Tu3Ab!=KrjN^>~jNVuM8nue;>p zy>=(1gxLA*tq~P7A6M&w?iVkd?Kjd`UL+X#0k8cdPjuiS4K$q1a8}oJlE;>1u~H5A zI!Rb$26N5eVl%kH3@$K3PxV5MTtYgRz~T~mxCA3Ep_Z6$3YVC{m8Rf~I--b-g6wI~ zI1Lh}LGd&gVUepgoFxm&C>R@0Te&9N((*7ccUGV>L=Rd$@Yb<%8p&4^r;4{~AL(jb2MV6Dfog)%gmb3-+daqQw>%*U_`&t}) zS*HVn>mek6er=jwlTNj+^3G-pEJn^)uNZr1p>D;cK_A==hASx8E>m-c$2LTGd4b~t z-aS{0|26b1K<<58b6yb?`hQoBs`AFWe9b}DbK4qsIV43lgX2QLVw0>#pMd<=6K>TC zz?C5NyE_??D$A1TgFI0n;OPM)8an5t3}nfgItyFB;cLxkuj&K;{EV6hI3Q%ybS)Ov zmS*?2&i`4w?{2{%zuKiSas!n*>KM6@6L@vKuj68Kng%xiWpme?ilJ*$BU=p}ACOH` zZchF&`CY5s($6<74bZi)#G{WcKTa;OkSfnm#~xK1=Cwu#mQ?2dH~__kZxQcl{SXHj z^1^{~PPB3Gt}1WxERByt7c%x7i?SF@?-^jAFLiehuRtqUv+WcV>GLPXc-m^wZE{k1TkFiti%qoI>F^lA~`I= zcYO;d=BFq1=l1BsdbPiV(TSSVRip)QhyVPyO4J8jq8bs$7cx*KTN>I#*KWFAH)k~g zG?CSa!Ou}?v7w$W$XP=|?PwDFV%T3g-rD|2js4D6>wpgYEZCu)9AhD+$9sRC#eB{) zzxD3}6WBxm4Sw3zKjC<5uO|&Osp2zl{bYzD2uKN6AI)5imeOsFAj)EG(Z7YR#g{fP zz+~a6hX`nnZU~Q_IlA(WcSdtx^V1#LyF$H0i$C1BR>K>yP>FF?CSlzopJC?E7P-i1 z)YgH9B%UM9nIHfvcf!xIZ7{R+}s|m7HiA3O;!QJCk$7Vimaxdk&5f} zq_N;I3;l*g&HDeevQ!S!(O$;&ojUu>$svn$+9uzsoynG9)-}5+#Ab1N^_RiSfHAhd z!h6n1o)zrSZ^*5&QS&#}ZG|;LwTs`IaRy7n++cG%on-?h=Ti*Jo&4 z&1C$pmZjbQ;9&MtP1NI$1GNIiGqc7iqs?>0$$31PQ|aYt;-ZSAY(?d~V4ayA_X|q| z#uYmLb$QW)1wF|RUWe{?Q)`Ie@lE}XbcD3ku3kwU>z&Z((2r>W5cS`H0jue2(a6C= g$zMwbo|^H{jXs%s+d}=rMyUZ?Yscdi$2{Zy0sGB{O#lD@ literal 0 HcmV?d00001 diff --git a/examples/opengl/textures/images/side6.png b/examples/opengl/textures/images/side6.png new file mode 100644 index 0000000000000000000000000000000000000000..798a9bb667e6a33520a57c7af226e7572c2812c7 GIT binary patch literal 2446 zcmb8w`9IWa8wc?FJ2NsI$JT;WCdnZ=DU}fBXfRW=Vg|8iZg`==|-!_DPq)upNc zfS+kpiWdL~Rw96i$0C^LzA; zp$QwVWkU-L7jERjEnK*j3(1&#NXduPeCV1FJuoHEy9D}_K)({mz*ND*RghT)L#kjX zh7Tk7Foq9f`4GhjV6p(F3Lr}W*%%?r6hf{L<_TdwMhpwZutW@bVpxUggSCB--v=A| zpa3I*tr94dK#>HBF;dtqg?&=^QVJy)8GJ8;QW+eTK^X?Zukgp2g*`lb3HEoDQ0m@r zEUEvw&h5eW01zoO%5UB=17oj(eFvzEfQ0OYD0%aQ+qDjw(+mAd8H?|xG63y~LSZ#i zP(N0u5q>V)qCM|B?=;scdnQ}&CpGsaI1=~)J;HDV1Ts2^uuA2c0Qvtgz6B1srMPRn zdh+){F!`ZA_e;O$hIva)F@GaLU~p$$xIquaa`m5oX-K9j-QT`PD@t_&(bM$|OUHo? z?}WI9=r8Lp=QqXJ<$!m$I`n(FxlS7S(QCE)NBEsMnQdUTxW~D+2|e39>U*2|9GT-W znc=IqXGuo$R<%WKK5(zpYTuY!{a!`v@`9t{O3R>mpBrCqJEV^?m=uM)E9mst>*@{**7KkydO_(NPxpFGu9)p1H z_^6;a6TxRTTM;m*hHeOi4)|4Ipl~8Vp9OR?h7-Op2!ahx`(!!Uh=<`~)COyHEmILU zNJNh$5kfVb!J@QJ1`GnI20qv$M!EIj0SlZY1tJkF5Slh&pz@T69v-@~M!B)7SzE~$)uxh{@3o}wx! z;-H%{kQ2`jhFoI}DX+vyJtn>2|T+}Td;ZDWZ2 zvvAp@NnvldvsH`rwpYlsR8M!V_dpb{FL1gz~I z+^XPY?Hy4QGiK%1KoFWc>r3}M2IyUN1hoBv`DbBBkXq;iIA->E8W}fQFQVIkvam^s zUGVX1PimE9dzBx2pTEhvbm;6ooXF??%S!59Q>&q1RhdXWbetBgbZ3(iKj8WW6BUV| zccFw{Ywyt5WN>%KV6OYU+ZkLzLVVZ4eB&!K@O#VW&taX9Llu(+*TL1<{`9Qg+rxGz zl61_Gi?eoet%8;1Vf2N&%@Mx-cSCFcGh9io{zN2UORZ5uliq>#G2L1cbe&@Lqt-Q7 z1zDFt?4+M{Pp|FZhnr3j1j(AF&9;8=qFoE`Eyazt+vsqM|9RP|Dd22on-anW6(K0U zR_EKJI#D2zR6SQwb4=LsT`6`rHnXk5qgalFu8j_Do2zo+XvmSO!2$bkHFVbwx~{Dw zZnstVH1CE1m??=(91%@$>^|-Xhl`>HecWxIYoK~x3>U4Pcba38Hw#>j)?O8M`5cju zk}Vw$%qLB&@L+xmEkp$%&DG zpL`uqoh7J5>#wiv&B^iLC#-HX{ctdNL3Yb;&F^*v9sERGU!Rmzrf1&Sp=_(nP@<{W zUtV!~)^i(r@1>zdzWr!M3b2dHZ8#Kb_txfxl2o0XepUa(O=i6u|B?m?w^Vf~nRqx-UhHg; zrmy~b8z7$~@^6I}hT0hc0E7P_^>RMivx7iyf2k(F@SO8Ae<~=cu@=o7jeDk-F`<>L z1Wt8>;{Ky?r1t2Irb=8-tIi^3w7l68T< zrSI^4-sr{03?P_U_F{O-tRZtH37~J@JStMqhhF(5BA|9*?qP@cg6XIS0AWO$xiS>x z@>7pU2xzDihvl@d+ksLMAdp;{r0y+VCXCydhzD@cOtfo(SCK#Yj`ldV+Zh9QMcQZP zszpPu^a-3O0sxZxQ76mJ`x%e)RdX}83WuMRcC-ZwzIl#olGBp`5&fSr)}VnZKQ?&$fRR910 literal 0 HcmV?d00001 diff --git a/examples/opengl/textures/textures.py b/examples/opengl/textures/textures.py new file mode 100644 index 0000000..9730cf0 --- /dev/null +++ b/examples/opengl/textures/textures.py @@ -0,0 +1,231 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/textures example from Qt v5.x""" + +import sys +from PySide2 import QtCore, QtGui, QtWidgets, QtOpenGL + +try: + from OpenGL.GL import * +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL textures", + "PyOpenGL must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + +import textures_rc + + +class GLWidget(QtOpenGL.QGLWidget): + sharedObject = 0 + refCount = 0 + + coords = ( + ( ( +1, -1, -1 ), ( -1, -1, -1 ), ( -1, +1, -1 ), ( +1, +1, -1 ) ), + ( ( +1, +1, -1 ), ( -1, +1, -1 ), ( -1, +1, +1 ), ( +1, +1, +1 ) ), + ( ( +1, -1, +1 ), ( +1, -1, -1 ), ( +1, +1, -1 ), ( +1, +1, +1 ) ), + ( ( -1, -1, -1 ), ( -1, -1, +1 ), ( -1, +1, +1 ), ( -1, +1, -1 ) ), + ( ( +1, -1, +1 ), ( -1, -1, +1 ), ( -1, -1, -1 ), ( +1, -1, -1 ) ), + ( ( -1, -1, +1 ), ( +1, -1, +1 ), ( +1, +1, +1 ), ( -1, +1, +1 ) ) + ) + + clicked = QtCore.Signal() + + def __init__(self, parent, shareWidget): + QtOpenGL.QGLWidget.__init__(self, parent, shareWidget) + + self.clearColor = QtCore.Qt.black + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + self.clearColor = QtGui.QColor() + self.lastPos = QtCore.QPoint() + + def freeGLResources(self): + GLWidget.refCount -= 1 + if GLWidget.refCount == 0: + self.makeCurrent() + glDeleteLists(self.__class__.sharedObject, 1) + + def minimumSizeHint(self): + return QtCore.QSize(50, 50) + + def sizeHint(self): + return QtCore.QSize(200, 200) + + def rotateBy(self, xAngle, yAngle, zAngle): + self.xRot = (self.xRot + xAngle) % 5760 + self.yRot = (self.yRot + yAngle) % 5760 + self.zRot = (self.zRot + zAngle) % 5760 + self.updateGL() + + def setClearColor(self, color): + self.clearColor = color + self.updateGL() + + def initializeGL(self): + if not GLWidget.sharedObject: + self.textures = [] + for i in range(6): + self.textures.append(self.bindTexture(QtGui.QPixmap(":/images/side%d.png" % (i + 1)))) + GLWidget.sharedObject = self.makeObject() + GLWidget.refCount += 1 + + glEnable(GL_DEPTH_TEST) + glEnable(GL_CULL_FACE) + glEnable(GL_TEXTURE_2D) + + def paintGL(self): + self.qglClearColor(self.clearColor) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + glLoadIdentity() + glTranslated(0.0, 0.0, -10.0) + glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) + glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) + glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) + glCallList(GLWidget.sharedObject) + + def resizeGL(self, width, height): + side = min(width, height) + glViewport(int((width - side) / 2), int((height - side) / 2), side, side) + + glMatrixMode(GL_PROJECTION) + glLoadIdentity() + glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0) + glMatrixMode(GL_MODELVIEW) + + def mousePressEvent(self, event): + self.lastPos = QtCore.QPoint(event.pos()) + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & QtCore.Qt.LeftButton: + self.rotateBy(8 * dy, 8 * dx, 0) + elif event.buttons() & QtCore.Qt.RightButton: + self.rotateBy(8 * dy, 0, 8 * dx) + + self.lastPos = QtCore.QPoint(event.pos()) + + def mouseReleaseEvent(self, event): + self.clicked.emit() + + def makeObject(self): + dlist = glGenLists(1) + glNewList(dlist, GL_COMPILE) + + for i in range(6): + glBindTexture(GL_TEXTURE_2D, self.textures[i]) + + glBegin(GL_QUADS) + for j in range(4): + tx = {False: 0, True: 1}[j == 0 or j == 3] + ty = {False: 0, True: 1}[j == 0 or j == 1] + glTexCoord2d(tx, ty) + glVertex3d(0.2 * GLWidget.coords[i][j][0], + 0.2 * GLWidget.coords[i][j][1], + 0.2 * GLWidget.coords[i][j][2]) + + glEnd() + + glEndList() + return dlist + + +class Window(QtWidgets.QWidget): + NumRows = 2 + NumColumns = 3 + + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + mainLayout = QtWidgets.QGridLayout() + self.glWidgets = [] + + for i in range(Window.NumRows): + self.glWidgets.append([]) + for j in range(Window.NumColumns): + self.glWidgets[i].append(None) + + for i in range(Window.NumRows): + for j in range(Window.NumColumns): + clearColor = QtGui.QColor() + clearColor.setHsv(((i * Window.NumColumns) + j) * 255 + / (Window.NumRows * Window.NumColumns - 1), + 255, 63) + + self.glWidgets[i][j] = GLWidget(self, self.glWidgets[0][0]) + self.glWidgets[i][j].setClearColor(clearColor) + self.glWidgets[i][j].rotateBy(+42 * 16, +42 * 16, -21 * 16) + mainLayout.addWidget(self.glWidgets[i][j], i, j) + + self.glWidgets[i][j].clicked.connect(self.setCurrentGlWidget) + qApp.lastWindowClosed.connect(self.glWidgets[i][j].freeGLResources) + + self.setLayout(mainLayout) + + self.currentGlWidget = self.glWidgets[0][0] + + timer = QtCore.QTimer(self) + timer.timeout.connect(self.rotateOneStep) + timer.start(20) + + self.setWindowTitle(self.tr("Textures")) + + def setCurrentGlWidget(self): + self.currentGlWidget = self.sender() + + def rotateOneStep(self): + if self.currentGlWidget: + self.currentGlWidget.rotateBy(+2 * 16, +2 * 16, -1 * 16) + + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/opengl/textures/textures.pyproject b/examples/opengl/textures/textures.pyproject new file mode 100644 index 0000000..0541619 --- /dev/null +++ b/examples/opengl/textures/textures.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["textures.qrc", "textures_rc.py", "textures.py"] +} diff --git a/examples/opengl/textures/textures.qrc b/examples/opengl/textures/textures.qrc new file mode 100644 index 0000000..efa9e9c --- /dev/null +++ b/examples/opengl/textures/textures.qrc @@ -0,0 +1,10 @@ + + + images/side1.png + images/side2.png + images/side3.png + images/side4.png + images/side5.png + images/side6.png + + diff --git a/examples/opengl/textures/textures_rc.py b/examples/opengl/textures/textures_rc.py new file mode 100644 index 0000000..1e3923f --- /dev/null +++ b/examples/opengl/textures/textures_rc.py @@ -0,0 +1,762 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x04\x14\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01\x00\x00\x00\x01\x00\x08\x03\x00\x00\x00k\xacXT\ +\x00\x00\x00\x9fPLTE\xf8|\x00\xf8\x80\x00\xf8\x80\ +\x08\xf8\x84\x08\xf8\x84\x10\xf8\x88\x10\xf8\x88\x18\xf8\x8c\x18\ +\xf8\x8c \xf8\x90 \xf8\x94(\xf8\x940\xf8\x980\xf8\ +\x988\xf8\x9c8\xf8\xa0@\xf8\xa4H\xf8\xa4P\xf8\xa8\ +P\xf8\xa8X\xf8\xacX\xf8\xb0`\xf8\xb0h\xf8\xb4h\ +\xf8\xb4p\xf8\xb8p\xf8\xb8x\xf8\xbcx\xf8\xc0\x80\xf8\ +\xc4\x88\xf8\xc8\x90\xf8\xc8\x98\xf8\xcc\x98\xf8\xd0\xa0\xf8\xd4\ +\xa8\xf8\xd4\xb0\xf8\xd8\xb0\xf8\xd8\xb8\xf8\xdc\xb8\xf8\xe0\xc0\ +\xf8\xe0\xc8\xf8\xe4\xc8\xf8\xe4\xd0\xf8\xe8\xd0\xf8\xec\xd8\xf8\ +\xec\xe0\xf8\xf0\xe0\xf8\xf0\xe8\xf8\xf4\xe8\xf8\xf4\xf0\xf8\xf8\ +\xf0\xf8\xf8\xf8\xf8\xfc\xf85u\xa4p\x00\x00\x00\x09p\ +HYs\x00\x00\x00H\x00\x00\x00H\x00F\xc9k>\ +\x00\x00\x03\x1bIDATx\xda\xed\xddas\xd2@\ +\x10\x80\xe1\x8b\x10#\x1a\x01#il\x0b\xb1\x80\x0db\ +\x10b\xe8\xff\xffm\xb6\xd5\xd1\x92\x12r)8r\xbb\ +\xef~\xce\xb0\xec3\xc9]\xb8\xd9\x1d\xcc\x9d\xf20\x00\ +\x00\x00\x00\x00\x00\xdc\x19\x85\x01\x00\x00\x00\xec\x02\xa8Z\ +\xfa\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x80\xff\x18E\xae\x1a \x1by\ +\x91^\x80\xf5\xb8w\xff5\xdeh\x05\x98\x0d\xbd\xa7\xbd\ +;\xca\x00\xf2K\xbf\xd2\xbc\xa4\x09\xa0H\xc3\xe7\xdd[\ +z\x00n#o_\xfb\x9a\x12\x80\xfc*\xa8\xe9\xdf\xd3\ +\x00P\xb9\xf5\xb5\x01\xcc\xab\xb7\xbe*\x80\xaf\x89\xdf\xd0\ +\xc2*\x19`\xf5\xf8\xc2\xa3\x15\xa0H\xdf[51\xcb\ +\x04(\xa7C\xcf\xb2\x8b[ \xc0v\x1eu\xec\xdb\xd8\ +\xc5\x01dq\xb7U\x1f\xbf,\x80\xec\xc2o;\xc8 \ +\x08`\x91\xbc~\xc1$\x87\x14\x80\xace\xf5\xb2\x00\xb2\ +\xd8\x7f\xf1,\x8f\xf3\x00\xe5l\xd4=f\x98\xc9m\x80\ +\xcd\xcd\xf0\xd5\x91\xd3\x5c\x0e\x03\xe4\xe3\xbew\xfc8\x9b\ +\xa3\x00\xe5\x97\x8b\xe04\xf3|.\x02,'\x03\xefd\ +\x03\x8d\xae\x01\xe4i\xe4\x9b\xd3\x84\x83\x00\xab\x0f\xa7*\ +\xdeQ\x80\xcc\xae2/J\x02\x99\x00\x0b\x9b\xf2;\x97\ +\xeb\xfb\xd3\x00_$\xc0\xb2\xb9*\x7f\x5c<^\x9a\x88\ +\x04\xf8\xdeTS/-\x7f_:\x15\x09P\x1e\xae\xe8\ +\xdd\xb4\xd5\xcd\xe2\xe26x\xe8\xc9\x1e\xdc\xeel\x182\ +\x01\xfa\xf5\x0b\xff\xb2r&*\x13 \xae)?^\xb5\ +|Z\x5c\x05Hk\xf7\xbd\xbd\xa9\xe5\x01\xecY\xda\x82\ +\xc9\x8f\xda\xd4\x02\x7f\x0bT\xcf\xbb{7\xdb\x03\xa9\x05\ +\x02\x0cwJ\x08g\x87S\x0b\x04\xf8\xfct\xdf\xcb\x9a\ +R\x0b\x04X\xffY\xf8G\xdf\x9aSK<\x0f\xf8\xf5\ +&\xd0IV6\xa9%\x02\x00\x00\ +\x06\xc0IDATx\xda\xed\xdd\xdbb\x9b8\x10\x06\ +`K\x85B!f\xa1&\x1c\x8a\x03\x81\x9a@!\xf0\ +\xfe\x8f\xb7\x17\xbbm\xe2\xc6\x18\x8c\xf5\x13\x81\x86\xcb6\ +\x17\xf83\x16\xd2hf\xb4\xeb\x15\xbfv\x04@\x00\x04\ +@\x00\x04\xd0\xef\x14\xbc\x08\x80\x00\x08\xe0\x1c@\xa9\xa1\ +\x8f\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\ +\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\ +\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\ +\x80\x00\x08\xe0\xae\xabC\xde|\xd7I\x0f\xf0\xccv\x5c\ +7\xac\x07\xc7;\x04a\x9c\x1d\x7f\xc4Q\x18\ +\xf8\x07\xcfu\xf6\xb6e\x1a\xba\xc6\xd9n\xc7\x7fI\x0e\ +P\xf2\xc1\xcc,\xc65\xdd0M\xcb\xde;\x8e\xeby\ +\x07\xff1\xf8\xf0\xf9\xc6/Gr\x80\x00\x9d\xe0fH\ +\x0e\x10\xa1\x01|\xc9\x01\x124@&9@\x8a\x06h\ +%\x07(\xc0\x9f\xdf\x94\xfd5X\x82\x01<\xd9\x01j\ +0\xc0\x0f\xd9\x01Z0@!\xfdL\x10\x0c\xf0Kz\ +\x00\x0e\xfd\xfcL\xfe\xc5\x90\x0e\x05\xd0\xe4\x070e\x7f\ +\x0b\xa2\x01l(\x80%?\xc0\x1e\x0a`\xcb\x0f\xe0\xaa\ +\x0epP\x1d\xe0Qu\x80Pu\x80X\xf5\xb7\x006\ +\x22\xf2M~\x80T\xf5\x89P&yH\x14\x0e\x90\xab\ +\xbe\x16\xc0\xc6\xc4V\xb0\x1a\x04\xc7\xc4\xe4\xdf\x1a{Q\ +\xfd-PA\x7f\x01\x95\xfc\x00\xf5\x87\xfd\xc0\xff6\x04\ +\xff\xec\x08\xfaA\x18Fq\x9c\x1c\x8fi\x96\xe5Eq\ +*\xcb\xb2<\xfd,\xf2<\xcb\xd2\xa7c\x92\xc4Q\x14\ +\x86\x81\xef\x1f\xbe{\xae\xeb\xec\xf7\xb6m\x99\xa6\xf1U\ +\xd74\x1e\xf5\xf2\x034g\x00a/\xdf\xb5(@\xa4\ +\x1e\xc0y\x5c\xadl\ +\xb2\x8b\xa7?\x05\xac\x95\x1d\xe0\xad\xb12\x9f\xbe~k\ +\xa7\xaf\xa0r\xd9\x01\x82y\x11\xfd'\xbe\xdc\x82\x00<\ +\x0f\xf0\xd9\xacp~5q$\xb0d\x07\xe8\xfb\xca\x99\ +\x15\xc9n\xa6-#Y'=@\xdf\x9ffEo:\ +k\xa1\xc9 \x1e`\xe6\xd5\x1a\xcb\xcc\x04\xa4\x05\xe8\xeb\ +)K\xe9h\xc3\x00\x93\xfa\x90y[\x06\x98\x12S\xb7\ +7\x0d\xd0\x8d\xbf\x0c\xcdM\x03L\xd8Z5\xb6\x0d0\ +\x1eT\xd66\x0e0:\x0e\xf2\x8d\x03\x8c\x86\xd5\xd9\xd6\ +\x01b\xd5\x9f\x80\xb1\xa8\xaa\xbeu\x80\xb1\xf6\xf4\xe6\xe6\ +\x01b\x95'B}?\xda\x94\xd4\xd9<\xc0\xc8)%\ +\xde\xf6\x01\xf6\xe0\xbcI\xe9\x01|e\xe3\x01\xff_\xd7\ +3\x0d\xab\xed\x03\xe4\xe0\xd6\xd2\xd2\x03T\xd8i\x80\xfc\ +\x00\xbf\xc0\xfb\xc3\xd2\x03\x5c=\xaf-Q\x00\xe0j\x92\ +I\xad\x00@\x8f\x1d\x02\xd6\xfd\x04\x84*\x004\xe0<\ +1\xe9\x01jd@p\x0d\x00W\xea\xce|\x99\x01*\ +WPaK\x8a\x9c\x07\xc3\x00Z\x9f\x89*p\x8b\xd6\ +\x98(\x19\x7f\xd9\xedv\x5c\xcc#0|^]&+\ +\xc0\xb3!2\xa1\xdd\xc4\xc5CA\x00\x7f\xaad\x98\x88\ +\xc6\x07\x1d\x03W\xcd\x88\x07x{f\xff\x11p\x7f\x83\ +\xb5\xb7Z'+@*\xb4\x97x0\x04 \xea\xb0\x06\ +\xf1\x00\x8d\xd0\xc2\x9e\xaf\xc0e\x00j\x104\x04\xe6\xf1\ +\x95\xc0\x14I\x18\xc0\xbb0&\xbbw\xb6\xeeC\xe7\x00\ + \x80\xf7{\xda\xfa}\x93\x81v`W\x80U2\x03\ +\xb4\xe2\x8a\x5ccx\xe1(d&h\x8a\xba\xd7VC\ +\xff\x000\x00g?\x5cv\xc7p5\xf0\x0e\xd4d/\ +\x9f?\xef\x9b\xc1g\xff^k\x86\x5c\x04\x00\x01\xda\xf3\ +\x1b\xd7\xe7N\x89-`\x18\x00\xbb\x1a\xfc\xeb\xceg\x0a\ +\x04\xf8\x01\x00\x05\xf0\xf7\xad\xebs~\x05)\xbe{\x04\ +\x0c\xe0\xc3~\x9ev\xfb\x84\xa8\xb8<\x00\xe8\xa2O\xa9\ +\x80\x00\xbc~\xb8y~\xeb>\xf6\xcf\xcbS .\xbc\ +\xbf\x22&$va\xf8\xf2ozt\xb3\xcb\xdf?\x17\ +\x7fV\x15\x06\xe0\xd2\xf8e\xdeP\xdd\x11\x0d|~\xc0\ +IM\x18\x80\x8b\x9b\xfa,\x98\xf8\x104\x03\xb9q\x1a\ +\xe2\xa0&PTx`\x04\x9b\x14\xc5\x18\xaa\x9c\xd4!\ +\xbdEA\xfb\x02Ci\xdeF2\xf6\x14\xa4C\xe9\xc1\ +\x06\xa6\xb7*\x08\xe0qx?+\xb8\xf2 \xb7\x91\xbe\ +T\x1790\xc0\xd5\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01\x00\x00\x00\x01\x00\x08\x03\x00\x00\x00k\xacXT\ +\x00\x00\x00\xa5PLTE\x00|\xf8\x00\x80\xf8\x08\x80\ +\xf8\x08\x84\xf8\x10\x84\xf8\x10\x88\xf8\x18\x88\xf8\x18\x8c\xf8\ + \x90\xf8(\x90\xf8(\x94\xf80\x94\xf80\x98\xf88\ +\x98\xf88\x9c\xf8@\x9c\xf8@\xa0\xf8H\xa4\xf8P\xa4\ +\xf8P\xa8\xf8X\xa8\xf8X\xac\xf8`\xb0\xf8h\xb0\xf8\ +h\xb4\xf8p\xb4\xf8p\xb8\xf8x\xbc\xf8\x80\xbc\xf8\x80\ +\xc0\xf8\x88\xc4\xf8\x90\xc4\xf8\x90\xc8\xf8\x98\xcc\xf8\xa0\xcc\ +\xf8\xa0\xd0\xf8\xa8\xd4\xf8\xb0\xd8\xf8\xb8\xd8\xf8\xb8\xdc\xf8\ +\xc0\xdc\xf8\xc0\xe0\xf8\xc8\xe0\xf8\xc8\xe4\xf8\xd0\xe4\xf8\xd0\ +\xe8\xf8\xd8\xe8\xf8\xd8\xec\xf8\xe0\xec\xf8\xe0\xf0\xf8\xe8\xf4\ +\xf8\xf0\xf4\xf8\xf0\xf8\xf8\xf8\xf8\xf8\xf8\xfc\xf8\xce\x99\xaa\ +w\x00\x00\x00\x09pHYs\x00\x00\x00H\x00\x00\x00\ +H\x00F\xc9k>\x00\x00\x04?IDATx\xda\ +\xed\xdd\xe1v\xd2@\x10\x05\xe0\x0d4\x05\x91b(\x82\ +\x14$\x16S\xc4\x88\x18\x13\xd3y\xffG\xf3\x8f\x9e\xee\ + %\x9b\x9e\xb6\xb6s\xef>@\x0f\xfbA\x93\xbd3\ +\x13p\x02\xbe\x1c\x01\x08@\x00\x02\x10@\x1c\xe0\x22\x00\ +\x01\x08\xa0\x01\xa0.}\x04 \x00\x01\x08@\x00\x02\x10\ +\x80\x00\x04 \x00\x01\x08@\x00\x02\x10\x80\x00\x04 \x00\ +\x01\x08@\x00\x02\x10\x80\x00\x04 \x00\x01\x08@\x00\x02\ +\x10\xe0\x05\xac\x9f\xd9|8\x02\x05\xa8\xf3t\xd2s\xce\ +\xb9\x1e @\x91\xcd\x87\xd1\xdf!\x96.\x16@\x9d\xa7\ +\x93\xf3cc<\x08\x00\xea\x8d\x07\x03\xa8\xf3\xf42>\ +9\xc8e\x18\xa0<\xfe\xc6\xc3\x00T\xbd\xa0Q>\xbb\ +\x00S\x87\x0dp\xe3\xb0\x01\xaa\x18\x1c`\xe2\xb0\x012\ +\x87\x0dP\xc6\xe0\x00c\x87\x0d\x909l\x80\xf2\x0c\x1c\ +`\xec\xb0\x012\x87\x0d\x10t\x07\xb0\x0cp\xe9\xb0\x01\ +2\x87\x0dP\xc5\xe0\x00~\x06\x88\x00\x01T\x08^\xe0\ +\x01\xa8*P\xbf\xc6\x03\x98\xf9\x1b\xdc\x0a\x1c\xc0\xd6\xdf\ +\xdfL\xe0\x00\xea\xbe\xb7\xbd\xb8\xc2\x03\xb8\xf2\xb7\x97\x09\ +\x1c\xc07\xff\xb6\x97\x08\x1e\xc0\xc0?\x02\x14x\x00+\ +\x7fsK\x81\x03(:\xea\x08\x80\x07\x90\xf8{\xdb\x08\ +\x1c\xc0\xda\xdf\xdaX\xe0\x00T\x08\xec\x14x\x00\xaa\x13\ +\xba\x128\x00u\x06\xfes\x05D\x02Pg`\xf7E\ +\xe0\x00\x96\xfe\xbe&\x02\x07\xf0\xc3?\x03wK<\x00\ +u\x04H\x05\x0e@\xd5\x81\x07\x02\x07\xa0\xeb\xc09\x1e\ +\xc0\xfc\xa0\x0c\x84\x06\xb0\x8b\x0e\xca@h\x00C\x7fO\ +k\x81\x03P!h(p\x00\xea\x0a\x18\xed\xf0\x00>\ +\xf8;\x9a\x0b\x1c\xc0\xa9+ \x04\xc0\xf0\xb0\x10\x0e\x06\ +\xf0\xd9\xdf\xcf\x85\xc0\x01\xd4\xe7\xf7\x9e\x011\x00T\xfb\ +;\x118\x80B\x0d@\xec\xf0\x00\xc6\xf7\x94AP\x00\ +6\xee\x9fV\x18\x16\xc0\x9b\xfbS \x04\xc0\xb5\xbf\x97\ +N\x09\x07\xa0\xcb \x0b\x81\x03P\xb7\xc0\xb3\x0a\x0e@\ +\xdf\x02S\x81\x03P\xcfD\xf5j8\x80\xdc\x9d\xa8\x03\ +!\x00\xa8\x14\xd8\x178\x00=\x11~\x03\x07p\xdb?\ +U\x08\x04\x00\xf8\xe4\xf4D,\x1a\xc0\xaf\xb8)\x06\x1b\ +\x07P\xcd\xf0\xa31\xd86@\xd9i\x8c\xc1\xb6\x01f\ +\xcd1\xd84\x80>\x04\xcf\x04\x0e\xe0}@\x0c\xb6\x0c\ +\xf0\xdd\x05\xc4`\xcb\x00\xe3\x90\x18l\x18@\xa7\xa0T\ +\xe0\x00FA1\xd8.\xc06,\x06\xdb\x05\x18\x85\xc5\ +`\xb3\x00\xdb\xc0\x18l\x16`\x18\x18\x83\xad\x02lB\ +c\xb0U\x80ah\x0c6\x0a\xb0\x09\x8e\xc1F\x01.\ +\x82c\xb0M\x00}\x0b\xd8\xe3\x01\xbc\xf3_\xfc\xa5\xc0\ +\x01\xe4\xad\xaf\x00\xc6\x00\x92\xb6\xb7\x00c\x00;\xf5\xda\ +\xbf\xe2\x01LZ\x1e\x02\xad\x01\xec\xa3v)\xc0\x1c\xc0\ +\xac]\x0c4\x07P\xaa\x0f\xc05\x1e\x80\x1a\x88\xe9\xd6\ +p\x00U\xb7E)\xd8\x22\xc0*\xbc\x19d\x12\xe0\xf6\ +\xbcu\x0c\xb2\x05\xa0\x1e\x0b86\x16o\x1d\xc0\xff~\ +\x1c7\x128\x80\xb6\xa5Ps\x00\xe3\x07\x1d\x82\xec\x00\ +\xec\xdb5C\xec\x01\xa8SpO\xe0\x00\xf4!h\x8d\ +\x07\x90>\xfc\x03`\x03\xa0\xe9\xb7b\x1ey\x15/\x0d\ +\xe0\xe6y\xf7\x1f\xd2oz^\x80\x04\x1c`\xef\xc0\x01\ +\xe6\xe0\x00u\x17\x1c\xe0\xda\x81\x03\x0c\xc0\x01r\x07\x0e\ +0\x05\x07\xa8\x22p\x80\xbdC\xff\x17@\xff\x04\xc8[\ +^\x04\xc1\x01Rt\x80-:@\x89\x0e 1:@\ +\x82\x0ep\x85\x0e\xf0\x08\xaf\xc4\xe0\xb3\xc3\x04 \x00\x01\ +\x08@\x00\x02\x10\x80\x00\x04 \x00\x01\x08@\x00\x02\x9c\ +X\x0d\xbf;\x5c\x9b\x07h()V\xe6\x01vO?\ +\x10\xf6\xb2\x016\xa7\x01r\xf3\x00\x0d}\x95\xcc<@\ +Cgmi\x1e\xa0a\xc84\xb1\x0e\xd04^\xd0\xb5\ +\x0e\xf0\xb1\xa9\x07\x90\x1b\x07h\x1c\xb3\x9e\xd9\x06X7\ +v\x81\xba\x95e\x80*`\xce~i\x19 d\xba$\ +*\xec\x02\xac\x82Z\xa1\x83\xda*\xc0\x22\xb0\x19\x9c\xd4\ +&\x01\xf6\xa3\xe0v\xf8`g\x0e\xa0\xdeL\xda\xcc\x17\ +F\xd3\xfc\x15\x03\xac\x96\x07k1\xbdh?]\x19'\ +\xf3\xbb\xbfP\xbc*\x80'\x18%\xdd\x12\x80\x00\x04 \ +\x00\x01\x08@\x00\x02\x18(\x8a\xfe\xafE\x00\x02\x10\x80\ +\x00\x04 \x00\x01\x08@\x00\x02\x10\x80\x00\x04 \x00\x01\ +\x08@\x00\x02\x10\x80\x00\x04 \x00\x01\x08@\x00\x02\x10\ +\x80\x00\x04 \x00*\x00\xda\x22\x00\x01\x08p\x07\x80\xbb\ +\x08@\x00\x02\x10\x00z\xfd\x06\x0eL\xb1gp\xf4v\ +\x0b\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x09\x13\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01\x00\x00\x00\x01\x00\x08\x03\x00\x00\x00k\xacXT\ +\x00\x00\x00\xedPLTEx\x00\xf8\x80\x00\xf8\x80\x04\ +\xf8\x80\x08\xf8\x80\x0c\xf8\x88\x10\xf8\x88\x14\xf8\x88\x18\xf8\ +\x88\x1c\xf8\x88 \xf8\x90 \xf8\x90$\xf8\x90(\xf8\x90\ +,\xf8\x900\xf8\x980\xf8\x984\xf8\x988\xf8\x98<\ +\xf8\x98@\xf8\xa0@\xf8\xa0D\xf8\xa0H\xf8\xa0L\xf8\ +\xa0P\xf8\xa8P\xf8\xa8T\xf8\xa8X\xf8\xa8\x5c\xf8\xa8\ +`\xf8\xb0`\xf8\xb0d\xf8\xb0h\xf8\xb0l\xf8\xb0p\ +\xf8\xb8p\xf8\xb8t\xf8\xb8x\xf8\xb8|\xf8\xb8\x80\xf8\ +\xc0\x80\xf8\xc0\x84\xf8\xc0\x88\xf8\xc0\x8c\xf8\xc0\x90\xf8\xc8\ +\x90\xf8\xc8\x94\xf8\xc8\x98\xf8\xc8\x9c\xf8\xc8\xa0\xf8\xd0\xa0\ +\xf8\xd0\xa4\xf8\xd0\xa8\xf8\xd0\xac\xf8\xd0\xb0\xf8\xd8\xb0\xf8\ +\xd8\xb4\xf8\xd8\xb8\xf8\xd8\xbc\xf8\xd8\xc0\xf8\xe0\xc0\xf8\xe0\ +\xc4\xf8\xe0\xc8\xf8\xe0\xcc\xf8\xe0\xd0\xf8\xe8\xd0\xf8\xe8\xd4\ +\xf8\xe8\xd8\xf8\xe8\xdc\xf8\xe8\xe0\xf8\xf0\xe0\xf8\xf0\xe4\xf8\ +\xf0\xe8\xf8\xf0\xec\xf8\xf0\xf0\xf8\xf8\xf0\xf8\xf8\xf4\xf8\xf8\ +\xf8\xf8\xf8\xfc\xf8\x09\xd19\xc7\x00\x00\x00\x09pHY\ +s\x00\x00\x00H\x00\x00\x00H\x00F\xc9k>\x00\x00\ +\x07\xccIDATx\xda\xed\xddiC\xdaL\x10\x00\ +\xe0\x1cP\x90\xa3(-R\x81\xaax\x03\xe5\xa8\x82\x22\ +E\xa8\x81\x0a\x91d\xfe\xff\xcf\xe9\x87\xbe\xafr\xe4\xce\ +&f6\xb3\xdf#\xd9G\xc81;3+@\xcc\x87\ +@\x00\x04@\x00\x04@\x00 \xc4p\x10\x00\x01\x10\xc0\ +&@\xac.}\x04@\x00\x04@\x00\x04@\x00\x04@\ +\x00\x04@\x00\x04@\x00\x04@\x00\x04@\x00\x04@\x00\ +\x04@\x00\x04@\x00\x04@\x00\x04@\x00\x04@\x00\x04\ +@\x00\x04@\x00\x04@\x00\x04@\x00\x04@\x00\xac\x87\ +\xae\x0cZg\x95/\xf9tR\x96\x04)\xf1)\x9d-\ +V\xce[}E\x8f\x03\x80\xd2=\xfe,\x99\xa4,J\ +\x85Zg\xc63\xc0\xea\xae\x96\xb2M\xdcLUo_\ +\xb9\x04\xd0\xee\x0e%\x87\xc9\xab\xd2\xb7\xbe\xc6\x1b\xc0\xe4\ +Xv\x95\xc0\x9b8\x9fs\x04\xa0\xff,\xb8\xcfa\x16\ ++\x13N\x00^\x1b\x9f<\xe6qW\xe7\x1c\x00\xa8W\ +\x09\xef\x99\xec\xd2\xf9\x0a9\xc0\xab\x9f\xe9\x0b\x82 d\ +\xc6\x98\x01\xb4V\xd2w9\x83x\xa6\xa1\x05\xb8K3\ +\xa9\xe88X\xe2\x04P\xf7Y\xd5\xb4\xa4\x9fQ\x02<\ +\xb0\xab\xea\x91\xc7\x18\x01\xae\x18\xd65%\x9e\x10\x02\x1c\ +\xb2\xac\xecJL\xf1\x01$Y\x02\x08\xa9%6\x809\ +\xe3\xea\xbe\xa2\x8e\x0c\xe0\x8eu}\xe3\x052\x80s\xd6\ +\x00\xe2\x04\x17\xc0\x01\xf3\x12\xd7}T\x00\xba\xcc\x1c@\ +\xe8`\x02\xf8\x1d@\x95sJG\x04\xd0\x0d\xa2\xce\xfb\ +\x16\x11\xc0I\x10\x00yD\x00\xf9@J\xfd'h\x00\ +4\xd1\xf4n\x96\xab\x5cw\x87OSE\x99\x8e\x07\x9d\ +\xcb\xf2\x9e\x1b\x80K4\x00c\x93\x17\xdb\xb3\xe1N\x8c\ +k\xd9?q\x1c3\xcc\xa1\x01h\x19\x86yGf\xf7\ +\xcca\xd9\xa1\xc0\x1c\x0b@\xd5 \xc4k\xb9\xe8\xa5T\ +\x1c\x01\x0c\xb0\x00dv\xbe\xbc\xb61\x8dQ\xd6\x01\xc0\ +\x15\x12\x80\xe5\xf6\x89\x9f8\x88l\xaej\xf6\x00e$\ +\x00\xc3\xad_\x7f\xcf\xd9a\x0d[\x80\xcfH\x00n6\ +\x977\x86N\x8fk\xdb.\x13 \x01\xd8\x08\x87\x89\xf7\ +\xce\x0f\xbc\xb0\x01H\x22\x01\xd8\xb8\xb1\xf7\xdc\x1c\xf9\xc5\ +&(\x80\x03\xe0\xcf\xc6\xf5\xcf]$\xcdz)M\xc6\ +\x01\xd0_\x7f\x81\xd1\xfc\x5c>\x90\xfe\x04\xd6~\xc9\xa2\ +\xdbx\xf6\xca2\x9a\x9c\xc6\x01P\xf4\x13\xca\xb4\x0c&\ +\x16q\x00\xbc\x87\xc3\x92\xee\xf3\x9d\x9e-S&P\x00\ +\xacM\xe1\x07\x8b\xc7\xe8\xb5q\x83\x02\xa0\xe7/\x8ag\ +\x15L\x1a\xa2\x008};\xdf\x06\xebp\xe2\x12\x05\xc0\ +[J\x98\xacz9\xfc\x97\xf9\xfc\x0b(\x02\x22\xda[\ +>\xe4wO\xc7\xbf\x84\xf76\x1c\x0c\xc0\xd3\xdb\xf9z\ +\xcbkP\xcd\x01~\xa3\x00h\xfb|u\xd3C\x5c\x1c\ +\x0b\x04\xa0\xeas=W3\x05\xe8\xe1\x00\xc8\xfa\x8c\xe2\ +/M\x9f\x83\x91,\x8d\xfd\xec\xfd\x1b?=\x1e?\xe3\ +bq\x94]<\xed=\xae\xaa\xc7\x04\xc0,.\xf6\x0b\ +b\x02pl<\xff\x13\x88\x0b\x80\xf1\xcbPN\x8b\x0b\ +\x80qz\x99\x1cL\xbal\x14\x01\x9a\x86\xc1\xd0\x07\x88\ +\x0d@\xce\x08\xe0\x07\xc4\x06`d4\xff\x06\xc4\x07\xa0\ +\x18B\x1c(\xca\x00\x06I\xf6b\x07\xe2\x03\xf0\xba[\ +d\x22\x0f F\x00\xbb+\xe4{S\x88\x11\xc0nf\ +MI\x85\x18\x01\x0c\xb6s\xcb\xa4V\xc0\x9f\x18-\x80\ +\xbb\xed\xf9\xe7~C\x9c\x00\x1a[\xf3\x97\xae\x83o\xa8\ +\x10!\x80\xe5v\xa6\x5cQ\x09\xe1S\xa3\x03\xd0\xdbZ\ +\x14N\xdf\x85\xf2\xb1Q\x01\x18l\xa5\x16\xcbW\xdc5\ +P\xb0\xfa\xf2\xb7\xb6\xde\x7f\xa4\xfa2\xac\xcf\xfex\x00\ +\xa5U\x92vj\xe6\x07S\x95S\x00u\xf9\xdfX\xcc\ +\x95\xa7A\xab^4\xcd\x08J\xee\xd7\x1a\xc3\x05o\x00\ +\xaa\xe8\xb6l\xba\xda}\xe1\x09`\xe0\xa5H\xa2\xd0\x5c\ +p\x03\xe0\xb1\x8eF\xac\ +\x89\x92w\x81\x1aF\x80\x7f\xa9O\x99\xf2E\xe7a2\ +W5\x00\x00m9\x1b\xf5\xae\xca)\xf7\x02S\x84\x00\ +\xfae\xf1\xfa\xd1\xb8\x80fq[q\xf9\x94\x5c\xe1*\ +*\x0c\x00\xa0\xdf\x1f\xbayL\x10\xe7\xbc\x01\x00\xc0\xfc\ +\xd8\x05\xc1%\x87\x00\x00\xb3#\xe7-\x85\xb8\x04\x00\x18\ +8\xee&2\xe6\x13\x00\x96\xa5p{\xcbE/IJ\ +\xaf;\x03\xf8\xcc+\x80I\xa6\xe8\xeeP\xb9\x05\xb0\xa9\ +\x1f\xff\x7f\x8c\xf8\x05X+\xbc\xb4\x18-\x8e\x01t'\ +\xcd\x18O9\x06\x80\x85\x83'\xe3\x12\xcf\x00N\x96P\ +\xf2\x5c\x038\x08\xa0\xa6\xf8\x06\x18\xd9GE\xf8\x06\xb0\ +\xff\x0aH\x9c\x03\xd8\xe6R\x88\x9c\x03\xe8v\xad\xc9\x93\ +\x9c\x03\xd8F\xd13\xbc\x03<\xda\xa5\x0e\xf1\x0e\xb0\xb2\ +\x89\x0f}\xe5\x1d\xc0\xee>p\xc4=@=\xc6\xef\x02\ +\x00`\xdb\x5c\xb1\xc3=\xc0\xd0\x1a\xe0\x89{\x00\xc5\xfa\ +9H\xe3\x1e`\x11F\x8f\xe9(\x03\xbc\x0a!\xb4\x95\ +\x8b2\x80n\x09\xd0\xe6\x1f@\xb3\x04x\x89,\x80\xfa\ +\xc0\xa8\xd6}i5\x7fV=\xa5\x18\x03\xa8\xf7\xe7\x05\ +\x91U\xd3?\xcb\x9d\x9a\x1aQ\x04\xb8\xcc\x8b,\xff=\ +\x13+\x80Y\x14\x01\xde[\x1f0I\xe7\xec\x87\xb1\xd1\ +\x02S\x80\xb3\xb7\xf3;`qn\x8d\xe0\xef\x01\x8c\x01\ +\xd6v\x17c\xd1\xf3\xe5\xbbE4H\x8b$\x80\xc26\ +h\x9f\x0d\xa3\xb1$\xdb\xbb\xc0\xda\xeeZ\xfe\xb7D\xb2\ +\xb8\x0bJQ\xcd\x13\x5c[\xd2K\xfb\xfe\x92Z\x84\x85\ +\x19v\x15c\x0bp\xca\xf2[j\xbe\xdf\x864\x8f*\ +\xc0zC`\xf9\x8f\xcf\x07\xe1D(\xade\xd9\x02L\ +\x18\xe6t\x9b\xff\x02\xd2Zd\x016\xf7\xd7\xf2\xd7\x01\ +\xe1K8[\x0d1~\x17\xd8\xb8s%\xfd4\x01\x98\ +\x06\x9c\x17\x10\x10\xc0\xe6nQ\x87\xc0\xea/\xad/\x0a\ +\xcf\xa2\x0cp\xbdy\xb2M\xcf\x7f\xc8\xbc\xc2\xae\x0fQ\ +\x06\xd8\xbar\x89\x9e3\xb9\x0a\xc1\xae\x06\x04\x060c\ +T\xe1e\x9a*X\xd0\xa2\x0d\xa0oW\x81\xecy\x8a\ +\x5cM\xcc\x8aI\x12\xacw\xdbc\x1e\x12\xdb\xd9h3\ +\xeb\xe1\xb1]5\xdbcCb\xbd\xbf\x04{\x80\xddm\ +\x06\xb3\xae\x9f\x085\xb3,A1\x80\xdeJ\xac\x01\x0c\ +\x82\x18)\x97\xfdp\xf5r\x88\xad\xc5\x99\x03\x18=\xc0\ +&\xee\xdd\xfc\x85U)\xe88h\xa0\x00\xc6\xc5\x81u\ +\xe7\xd7\xee\xc5~\xc0\x05\x02\x01\x03\x80\xf1\xf5;\xeb\xb4\ +/\xfa\xd0\xb4b\xa4\x098\x00\xcc\xf6[\xae:\xb9\x16\ +\xae\xceLC\x00A\xf5\x96c\x0eP5\x9dB\xdd\xf6\ +\x91\xe0\xd6\xb4\x8221\x02,\x00\x16\xb1l\xa9j\x95\ +\xd3\xa0\xf7r\xe6\x11\x80g@\x03`\x9d\xe0\x99\xbd1\ +y6\x9e^X\xd4\xcf\x1e\x06\xd8\x5c\x8f9\x80m\x8d\ +x\xe6\xe4v\xeb\x85v\xd1\xaf[\xed8,\xfd\x00@\ +\x04\x00Nj\xc2\xe5B\xe5\xac\xd1\xe9v\xdb\x8d\xcb\xea\ +\x81M\xa5`6\xd0\xbe\xca\x01\x00\xe4\x05\xa6\xe3x\x05\ +\xc8\x00\xaa,\xa7\x9f\x1f\x03`\x03h\xb0\x9b~\xa2\x8d\ +\xb1\xaf\xf0\x03\xb3\xf9\xd7\xc2\xe8\xac\xca\x1e`\xceh\xfa\ +GS\x00\x94\x00\xeb+\xa4\x9e\x87X}\x06\xc0\x0a\xe0\ +\xbfa\x96X\x9b\x01\xe0\x05\xf0\xdb/)\xdb\x5c\x00`\ +\x06\x80\xc7o\xde\x9b\x86\xc9\xdf\xc7\x10\xea\x08&Qr\ +q\x93\xf34\xfbro\x05\xc0\x03\x00\x00L/2.\ +[\xa4\xd5\x1f5\x08\x7f\x04\x99*\xab\xb4J\xce\xee\x08\ +b\xae\xd6V\xe0cF\xc0\xb9\xc2\xfa\xb4]\xcd[)\ +\xc8\xd9Js\xb4\x82\x8f\x1b\xa1$K\xcf\x87\xdd\xab\xe3\ +\xc3b>\x9dL\xc8\x92 %R\x99\xfc\xfe\xd7\xf2i\ +\xb3?Y\xc0G\x8f(g\x8b\x13\x00\x01\x10\x00\x01\x10\ +\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\ +\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\ +\x10\x00\x01\x10\x00\x01\x10@\x80\x00q\x1b\x04@\x00\x04\ +\xf0\x0e\x10\xdfA\x00\x04@\x00\x04\x10\xeb\xf1\x17\xe9\x89\ +Gh\xda\x1b|\x00\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00\x06\xe8\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01\x00\x00\x00\x01\x00\x08\x03\x00\x00\x00k\xacXT\ +\x00\x00\x00\x8aPLTE\x00\xfcx\x00\xfc\x80\x08\xfc\ +\x80\x10\xfc\x80\x10\xfc\x88\x18\xfc\x88 \xfc\x88 \xfc\x90\ +(\xfc\x900\xfc\x900\xfc\x988\xfc\x98@\xfc\x98@\ +\xfc\xa0H\xfc\xa0P\xfc\xa0P\xfc\xa8X\xfc\xa8`\xfc\ +\xa8`\xfc\xb0h\xfc\xb0p\xfc\xb0p\xfc\xb8x\xfc\xb8\ +\x80\xfc\xb8\x80\xfc\xc0\x88\xfc\xc0\x90\xfc\xc0\x90\xfc\xc8\x98\ +\xfc\xc8\xa0\xfc\xd0\xa8\xfc\xd0\xb0\xfc\xd0\xb0\xfc\xd8\xb8\xfc\ +\xd8\xc0\xfc\xe0\xc8\xfc\xe0\xd0\xfc\xe0\xd0\xfc\xe8\xd8\xfc\xe8\ +\xe0\xfc\xe8\xe0\xfc\xf0\xe8\xfc\xf0\xf0\xfc\xf0\xf0\xfc\xf8\xf8\ +\xfc\xf8`;^\x10\x00\x00\x00\x09pHYs\x00\x00\ +\x00H\x00\x00\x00H\x00F\xc9k>\x00\x00\x06\x04I\ +DATx\xda\xed\xddaw\xa28\x14\x06`Ba\ +`\xa4\xba\xd0vtuQ*2Pb\xf8\xff\x7fo\ +;\x9d=g\xdb\x01\x14\x85$7\xe4\xcdw\xcf\xe9}\ +*\xe1\xe6\xe6&:\x8d\xe5\xc3\x01\x00\x00\x00\x00\x00\x00\ +4\x8e\x85\x03\x00\x00\x00\xc0W\x00\xab\xa6>\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00&\x1eU\x9e\xae\x93(\xf4]\x971\xd7\xf3\x830\ +J\xd6iV\x08\x1b\x00\xc4q\xf3\xe8\xf6u,\x06\xf1\ +\xf6\xc8\xe7\x0cP\xed\x1e\xd9\xd5\xbe\xcdp\x9d\x8bY\x02\ +\xf0\x7f\x16C{W\xd9\xea \xe6\x06P$\xec\xa6\xfe\ +]7\xc9\xe7\x04p\x8c\xee\xe8a\x0eR1\x13\x80\xe3\ +\xe2\xce6no\xcbg\x00PD#:\xd9\xdd\x9d\xe9\ +\x00u2\xb2\x99?8\x1a\x0d\x90\xba\xe3\xcf3,k\ +c\x01\xca\xc5$':\x1e2C\x016l\xaaC-\ +O\xc2@\x80\x89\xfe\xfd\xff\xcd\x04\x95q\x00S<\xfd\ +\x9f\xdf\x88\x85Y\x00<\x9e\xfah\x97{4\x0a\xe0\xdb\ +\xf4\x87\xdb\xd8\xc1 \x00.\xe3x\x1f\xcb\xcd\x01(\xa4\ +\x1cptO\xc6\x00\x1c\xe5\x1c\xf1\xf4*S\x00RI\ +\x87\x5c\xbf\x0bC\x006\xb2\x8e\xf9\xbe\x18\x02\x90\xc8\x02\ +p23\x00\x1e\xa5\x01x\xdc\x08\x80@\xdeY\xf7\x17\ +#\x00\x98<\x00V\x1a\x00\xc0\x1d\x89ci\x00\xc0\x80\ +<\x88\xb9w\x7fK\x0a\xfa\x00\x97\xf2 o\xb5\xcd\x8a\ +\x8f\x99L\xf0\x22\xdb\xae\xbc\x9b\x01\x12\xfa\x00\xbdy\xd0\ +b\xdb~\x82\xcbMx\xe3,\xc0\xc9\x03t\xe7A\xee\ +\xba/\x93=\xc57=\x0f\x7f\x93\x07\xe8\xca\x83\xbc\xdd\ +\xa54\xb6\x5c\xdeR\x1e\x22\x0f\xd0\xde\x09`?\xceW\ +>\x93\xdd0\x19T\xd4\x01ZyP8`\xe6\xae\x87\ +\x7f\x09v\xd4\x01\xfe|\xa2\xe3a\x8b\xb8\xe7\xa1\x00\x8f\ +\xc4\x01\xfe\xcc\x83\xd6C?\xb8\x1e\xfa\x1e \x0eP\xdc\ +\x19\xff\xf0U\xe4O\xda\x00\xaf_\xfe\xd8\xbf\xc6M\x9f\ +\x9d\xe3@\x1b\xe0K\x1e\xe4\xdf\x94\xb6\xd4\xc3v\x13\xd6\ +\xb4\x01\xbe<\xca\xfb\xdb>{\x18\x04\xb0\xa2\x0d\xf0\xf9\ +I\xf6\xc7\xe7\x10])5m\x80hL\xfd\xe24\x04\ + \xa4\x0d\xf09\x0f\xba}3cH>\xe4\xd3\x06\xf8\ +\x94\x07\xb1\xdb\xeb\xd8C\xf6\x14\x5c\xd2\x00|d\xf9\xc6\ +W\x99\x09\xc9\x00(Ff\xed/\xa6\x7f\x03^G\xa6\ +l\xf9\x80\xe28i\x80t\xec\x1f\xca\x14V\x04d\x00\ +\xac\xc7\x96\xef\xae\xa7\x02\x11i\x80dl\xce~}Q\ +\x98\x90\x06\xf8\xf4\x0f\xbc\xaf\xc3oo\xf8Z \x18\x9b\ +\xb0\xe5\x86\xaf\x06\xd9\xd8\x7fT\xa9poD\x02\x00\x1f\ +\x93\x07\xff^\x13\x9b]\x11*\xc6\xe4\xc1\x1fC\xa8{\ +\x09\xc8\x00\xc8\xc6oc^\x03\xd8\x90\x06H\xc7W\xaf\ +\xaf\x01\x1ci\x03\x04\xee\xc8\xa9\xea|m% H\x03\ +|Lc?\xf3C\xba\xbd\xfb\xd3\xca\x0abD\x8f\xce\ +VW\x00\xf6s\x078\x19\xbf=>rd\x97\x01\xe2\ +f\xee\x00;e\xef\x00\xa2\x00/\x8a\x0a\xa2d\x01.\ +\xd7\x03\xb6\xf3\x07\xb8\xd8*\xe1\xf2\xd9\x03\xd43\xe8\x14\ +\x95\xf7\x12`o\xf3\x07\xb88\x07>7\xf3\x07\xb8t\ +\xde\x90U\xf3\x07\xe0l\x06\x07&\xc6\x8c\xbd\xbaW\x00\ +M\x80XM\x7f\x1cY\x00\xe1\xaah\x0b \x0cp\xa9\ +G\xe6d\x03\xc0JQ\x9f\xe0\x00\x00\x00\x09\ +pHYs\x00\x00\x00H\x00\x00\x00H\x00F\xc9k\ +>\x00\x00\x08DIDATx\xda\xed\xddk[\xda\ +H\x14\x00\xe0@R\x01\x05T\xac\xc8J\x11a-V\ +\xa4\x5c\xaa`\x15\xb9\x88`\x00I\xce\xff\xff7\xfb\xa1\ +\xbb\xed\xb6\x0fs\x83\x990\xc9\x9c\xf9\xacy\x987\x99\ +\xfb\x99\x19\x0b\x0cO\x16\x02 \x00\x02 \x00\x02\x80e\ +`B\x00\x04@\x80\xdf\x01\x8c\xaa\xfa\x10\x00\x01\x10\x00\ +\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\ +\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10\ +\x00\x01\x10\x00\x01\x10\x00\x01\x10\x00\x01\x10`\xf7i\xe5\ +N\x86O\x0f\xdd\xce\xa3a\x00\xf3\xe7\xbb\x9b\xf2\xd9Q\ +2\xfe3\x96\xa7\xb84\x04\xc0\x1f\xb7/s\x1f\xd6D\ +3%\x9f\xa2\x0f\xe0\xf5\xafO\xe2\xe4\x80\xae\xaa\x17i\ +\x80y\xbb`3B\xda2\xe3\xc8\x02\xbcw\xf21\x8e\ +\xa0\xbex=\x9a\x00\xe3\xb2\xcd\x1b\xd7\x98\x9bE\x0f\xa0\ +w,\x12\xd9\xe9\xb8\xd1\x02\xf0;i\xb1\xd0\xd6F\xb4\ +\xbe\x80{\xc1\xec[\xb5H\xd5\x01\xfd\xachhs%\ +J\x95\xe0\xec\x9c#\xc7v6_\xba\xaa7Z\xedN\ +\xbbY\xff|\x1d\xa1f\xd0\xaf3j\xfeX\xa6\xf4\xb5\ +?\x8f\xec`hD\xff\xfa\xd3\x95\xdeR\xfd\x8f\xd8\x1d\ +\x80_\xa3u{\xb27\xaf\x11\x1f\x0e\x8f)\xaf\xdf\xa9\ +\xbcD~>\xa0A\x1e\xf0\xa4\xdb\x1e@\xc4\x01\x16g\ +\xc4\xec\x1f\xf5\x0c\x98\x11\x1a$I\xd9?\xe8\x9a0%\ +\xd6\x22}\xfeN\xc37`N\xd0\xbb \xbd\xfes\x17\ + \xfa\x00\xee\x11!\xfb{]\x00\x03\x00^H\xc5\xff\ +t\x0e&\x00\xf4\x1dB\xfe\xaf\x01L\x00\xb8'T\x7f\ +N\x0f\x8c\x00h\x10^\x7fr\x02F\x00\xd4I]\xbf\ +\x19\x18\x01pK\xc8\xff\xe1\x02\x8c\x00 \xe5?\xb3\xd3\ +\xfc\x07\x07@*\xff\xe99\x18\x01\xf0\x8d\x90\xff\xc4\x0c\ +\x8c\x00x\x22\xb4\x7f\xf6\x08\x8c\x00x!\xf5\x7f\xba`\ +\x04\x80K\xea\xffV\xc1\x08\x00\xef\x90\x90\xffc\xdf\x0c\ +\x802i\xf8?\x03#\x00\xda\xa4\xf1\x7f\x1b\x8c\x00\x18\ +\x93\xe6\x7f\xf2`\x04\xc02EZ\xf0\x9a\x99\x01P\x22\ +\x15\x80:\x18\x01\xf0\x9d\x94\xff}\xdf\x08\x80e\x82\x04\ +p\x0fF\x00\x14\x89\xeb\x1f`\x04\x00\xb1\x00X\x0fF\ +\x00x\x07\xc4\xc5_0\x02\xe0\x86\xf8\x01t\x8c\x00p\ +\x89\xf1\x1f\x09\xcf\x08\x80b0q^\xda\x02\x8c\xc8\x11\ +\x10S#\x00\xc81\x0090\x01`H\xfe\x00\x9aF\ +\x00\xe4\xc9\x00\xae\x09\x00\x94\x0f\xe0\x18L\x00(\x90\x01\ +\xaeM\x00\x98R\x82\x00\x07&\x00T)Q\x80\xbe\x01\ +\x00+\x87\x0c\x90\x07\x03\x00\x9aVH\xaa\x00U\x00\x19\ +\x0a\xc0\xa3\x01\x00cZ\x14\xf8\xc2\x00\x80+J\xfe\x93\ +\x10}\x00?i\x85\xa5\x0eT\x03\xf0D+\x01W\x06\ +\x00\x94h\x00-\x03\x00\xf6h\x00\xfd\xe8\x03\x0c\xa9[\ +\x81(+b\xb3n\xbd|\x9aM:v\xccN\xa42\ +'\x17\xf5\xee$\x94\x005\xeaF0BG\xf8\xadu\ +\xbe\xee\xc3q\x0a\x8dq\xe8\x00\xa8\x9b\xc1\xd6\xb6\x82\xab\ +V\x8e\xb6}\xac\xee\x86\x0a\xc0\xa5\x96\x805\x93\x01n\ +\xd5al\x9d\x8c\xe5\x07!\x02\xe8P\xf3R\xf8\xf3\xcf\ +\x17\xd58\xcf\x86\xd9\xfc04\x00ejF.\xff\xf8\ +\xeb\x96cq\xa6\xe2\x22$\x00i\x81\xad\xdfS\x91s\ +\x03\xf6\xeeB\x01\xb0\x10\xd8\xfb\xdf\xb6-\xa1t\xbe\x0a\ +\x01@\x8f\x9e\x87\xff\xad\x0az%\xe1[\xc1\xb2o\xfa\ +\x03\x5c\xd1\xb3\xf0ko\xc8\xfch\x83{\xd1\x12C\xed\ +\x01>\xd2s\xf0\xf3(\xa4\xd7\xd4F7\xc39C\xdd\ +\x01\xf6\xe8\x19\x18\xfd\xd7_v\xac\xcd\x923\xd6\x1b`\ +\xce\xf8\xfd\xff\xee\x8a\x7f\xb6\xadM\xd3\xde\xab\xd6\x00O\ +\x8c\x9f\xffc,\xd4\xdf<\xff\x96\x95Y\xe9\x0c\xd0`\ +\xfc\xfa9\x00\xc0p\x9b\xfc[VQg\x00V\xd3\xb6\ +\x04\x80\xc9\x87-\xef\xc8lj\x0cp\xc2\xf8\xed+\xca\ +\xf6\x01\xee$1\xccV:\x00\xabq\xf3\xe0=km\ +\x9d\xce\xb4\x05\xf0Y\x07\xc2\xf9\xfe\xa9\x8c\x8bb{\xba\ +\x02\xccX\xbf\xdc\xafH\xb9)7\xe5k\x0a\xf0\xcc\xfa\ +\xe5mIw\x05\xb75\x05\xb8c\x9e\x87(\x09\xe0\xc0\ +\xd7\x13\xe0V\xb4>?\xbd\xbe\x1f\xb9K\xdf\x9bO\xba\ +\xb5\x93\x98\xc0\x7f~\xd3\x13\xa0&\x92\xfb\xf8\xf9\xc3\xef\ +\xefq\xd1\xcap\xff\xf3\xa1\x9e\x00\x97\xfc\xd9\x8f\x95\xd7\ +\xb5\xe6=n\x82\x17-\x01\x8a\xfc=\xfa\x11\xa1!\xad\ +qV\x13U-\x01\xb8\x1b\xf9\x229^z\x98\xe0\x9b\ +\x1b\xf1u\x048\xb4$\xbc\xbe\x19_1x\xd4\x11\xe0\ +\x80/\xff%\xc6\xc4*\x97\xc0\x95\x8e\x00|\xf3\x5c9\ +\xd6\xd7;\xdf\xe7\xa9Et\x04\xe0*\xbe6;\x5c~\ +\xccS\x13\xba\x1a\x02\xec\xc9:\x17\x98\xa7\xcb\xdc\xd1\x10\ +\xc0\x966\x90)\x04s\xc0\xael\x80\xb8\xb4\x17\xf7\xc6\ +\xb6\xcci\x08 \xb1\xfd\xae\xb3g\xc8\xc3\xf9\x05|\xe6\ +|\x94\xc7\xaeP\xa7\xfa\x01p,wp\xc7\xfd\xb0G\ +\x96\x0f\xfa\x01\xb0\xdf\xda>\xf7\xb3VL\xcdV\x18;\ +B\x02U7s\xf6\xac\xa6\x1f\x00\xfb\xa8|\x81\xe9\xcc\ +\xf1\x96=\xea]\x00d\xa5v\xdfXO;\xd5\x0f\x80\ +\x19\xf2\x22\x14,\xfeE\xfdh@6\xc0Gf\xb4\x97\ +\xc8\xd3Xe\xe0 \x843B\x15\x99ujR?\x80\ +\xaa\x8c\x81\xd0\xaf\xf4\x89\xfe\xb0\x0f\xfa\x010\xfb\xafb\ +\xe7\xc7\xb5\x18\xd3\xca\xfa\x01|c\x01<\x83\xc4J \ +\xa6\x1f\x00+@\xc4\x12\x8bo\xf1\xe9c\x0b[?\x80\ +\x17\x16\x80\xe0\x11\xa2\xf4\xc9\xc1\x84~\x00\x0b\x16\x80\xe0\ +\xbd)\xe7ak\x06\x99\xc3A\xc1\xe3Sja\xeb\x08\ +1\xbb\x82\x82\xab\x19-\xd1\xcd\x07;\x07`\x05I\x09\ +>\x8e\x1ey\xfcQC\x80\xba\xdc\x220\xa0>\xec\x93\ +\x86\x00=v\x94\x98H\x9a\x86m>\x80\xf1\x8b\x85\xb7\ +N\xcfU\xc7\xc9H\x07`t]DWs\x96|\xa1\ +\xe7\x1a\x01\xb0\x9a\x01\xc1\xad\x90\x1eG\xe0\xb1f\x00\x8c\ +\xf1`\x7f\x83\x1fH\x1c\x0a\xf8:\x02te\x8e\x06\xc1\ +W\xbd<,\x1f\xc0\x95:\x93\xbd\xa2=\xab\xac%\x00\ +c\x16\xa7&\xb1\x12l\xeb\x09\xf0If\xac\xff\x5cb\ +\x85\x1a\x14\x00\xbd\xfb.x\x9c\xecD\xedl\x80\x12\x80\ +\x99\xcci\xbc\xbe\xda\x91\x80\x9a\xed\xf3\x19\x893\x22\xb4\ +6\xe5VW\x00\xfa\x18\xfe\xbb\xd0\xb3\x9aj\x17\xc7w\ +q\x84\x86\xd8IZ\x94n\x95\x9c\xb3\x89U\x00\xd0\xd7\ +\xc8\xc5v\xbb(?\x96P\x09\x00\xf5\x04\x01\xb1\xd3\xf4\ +(\xab\xcdc}\x01\xe8s\xe3\x22\xa7a\xac\xc8;\x08\ +\xd2\xa0/\x00\xec\xcb\xaa\x04\x06\xca\xf7\x0e\xaa\x01\xb8\x91\ +\xd5\x15\x22\xefCuV:\x03\xb81I\x8bC\x05\xc5\ +\xbb\x05\x94\x1d\xa8x&\xa7\x0c\xf8\xb6\xdaN\x80:\x80\ +\x9e\x9c8\xb1'\xf5[G\x15\x01\xd0\xbb\xc3\xdcqR\ +\xc4\x1dH\xb1\x89\xee\x00\xf72b|=\xe2:\xdb\x05\ +\xe8\x0e@\x8f\x97\x1bn\xa9h\xbb\xfa\x03\xdcI\xf8\x04\ +\xb2\x0a\x17D\x94\x03\xf8\xe9\xad\xa7F\x1f\x89\x1b\x0e\xde\ +C\x00@o\x08\xb8\xb2p\xa4p=$\x00\x00\xf8k\ +\xcb \xd7\x96\xea>\x90j\x00\xd7\xd9\xaa\x10\xb8\xa4\x83\ +F\xd2^H\x00\xa8\xb39\xcc\xfbf}\xd2\x19\x93\xf1\ +\x11\x84\x05\x00r\xd4\x00\xa7\xd9f} \xc9w4)\ +\x05\x98Q7\xd1\xa5h\xbd\xb9\xab\x00Z@\xf5\x00\xe4\ +\x86\xec\xc7\x88\x96\xb8PJ>h\xa4\x08\xa1\x02`l\ +\xfb\x89\xd5\xd6O\x8f\xcd\x89\x87\x11\xe5\xbc\x90\x01\xb0v\ +\xbdd\xd74\xe9~\x93\xd8|\x9c\x84\xe1D\xc9?\x12\ ++~>\xd7\xfb\xfd\xa5\xbe7\xc8\x8b\xabg\x0a\xeeh\ +S\x0e\xe03w\x108\xa5\xce\xf8GQX\x0e\xbe\xe6\ +)\x116E\x15\xb7\xb3(\x07\x00\xbf\xcc\xb3\x9f\xdaI\ +\xa5\x93\x8c \xd3\x8a\x92\xdbi\xd4\x030\xa6Hy\x93\ +\xad\xe8\x96\xd6 \x00\xa0ko\x9d\xff\xcc+\x84\x18\x00\ +^3[\xe6\xbf\xac\xec\x8a\xca`\x00\xc0\xfb\x1c\xdb\xe6\ +\xf5+\xbc\x94! \x00\x80\xe1\xe1\xc6\xa5\xffV\xe5\xdd\ +\x5c\x81\x01\x00\xb4\x13\x9bd?~\xa1\xf6v\xc2\x00\x01\ +`u+L`\xff\xad\xfar\xc6 \x01\x00\xbc\xb6\xd0\ +q\x9a\xc9/K\x80H\x01\x00\xc0\xe0\x92\xf3HY\xa7\ +\x1c\xc8}4\x81\x03\x00\xf8\xdf+\xccS\x06R\xa5^\ +@\xb7\x12\xee\x00\x00\x00`\xda\xb9\xcc\x12z\xfd\xb1\xcc\ +\xe5\xdd\x1b\x04\x96v\x04\x00\x00\xe0\xbfvo\xab\x85\x5c\ +&\xe9\xd8\xb1\x98\x93<\xc8\xe6\xce\xaa\xcd\xc7i\xc0\xf7\ +Q\xee\x10@\x8f\x84\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\ +\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\ +\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\x00\x08\x80\ +\x00\x08`*\x80i\x09\x01\x10\x00\x01~\x01\x98\x9b\x10\ +\x00\x01\x10\x00\x01\x8cN\xff\x00\xf3k\xd4\xa5uQ\x85\ +3\x00\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x09\ +\x0a\x84\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x001\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\x88\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x005\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\x87\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x004\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\x86\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x003\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\x85\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x002\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\x89\xa4\xa7\ +\x00s\ +\x00i\x00d\x00e\x006\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +\x00\x00\x00r\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x1c\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +\x00\x00\x00Z\x00\x00\x00\x00\x00\x01\x00\x00\x11\x05\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +\x00\x00\x00B\x00\x00\x00\x00\x00\x01\x00\x00\x0b\xc3\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +\x00\x00\x00*\x00\x00\x00\x00\x00\x01\x00\x00\x04\x18\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +\x00\x00\x00\x8a\x00\x00\x00\x00\x00\x01\x00\x00!\x08\ +\x00\x00\x01e\xaf\x16\xd2\x95\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/quick/customitems/painteditem/main.qml b/examples/quick/customitems/painteditem/main.qml new file mode 100644 index 0000000..d3404ca --- /dev/null +++ b/examples/quick/customitems/painteditem/main.qml @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import TextBalloonPlugin 1.0 + +Item { + height: 480 + width: 320 + + //! [0] + ListModel { + id: balloonModel + ListElement { + balloonWidth: 200 + } + ListElement { + balloonWidth: 120 + } + } + + ListView { + anchors.bottom: controls.top + anchors.bottomMargin: 2 + anchors.top: parent.top + id: balloonView + delegate: TextBalloon { + anchors.right: index % 2 == 0 ? undefined : parent.right + height: 60 + rightAligned: index % 2 == 0 ? false : true + width: balloonWidth + } + model: balloonModel + spacing: 5 + width: parent.width + } + //! [0] + + //! [1] + Rectangle { + id: controls + + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.margins: 1 + anchors.right: parent.right + border.width: 2 + color: "white" + height: parent.height * 0.15 + + Text { + anchors.centerIn: parent + text: "Add another balloon" + } + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onClicked: { + balloonModel.append({ + "balloonWidth": Math.floor( + Math.random( + ) * 200 + 100) + }) + balloonView.positionViewAtIndex(balloonView.count - 1, + ListView.End) + } + onEntered: { + parent.color = "#8ac953" + } + onExited: { + parent.color = "white" + } + } + } + //! [1] +} diff --git a/examples/quick/customitems/painteditem/painteditem.py b/examples/quick/customitems/painteditem/painteditem.py new file mode 100644 index 0000000..e89bf0b --- /dev/null +++ b/examples/quick/customitems/painteditem/painteditem.py @@ -0,0 +1,106 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +from PySide2.QtGui import QPainter, QBrush, QColor +from PySide2.QtWidgets import QApplication +from PySide2.QtQml import qmlRegisterType +from PySide2.QtCore import QUrl, Property, Signal, Qt, QPointF +from PySide2.QtQuick import QQuickPaintedItem, QQuickView + + +class TextBalloon(QQuickPaintedItem): + + rightAlignedChanged = Signal() + + def __init__(self, parent=None): + self._rightAligned = False + super().__init__(parent) + + @Property(bool, notify=rightAlignedChanged) + def rightAligned(self): + return self._rightAligned + + @rightAligned.setter + def rightAlignedSet(self, value): + self._rightAligned = value + self.rightAlignedChanged.emit() + + def paint(self, painter: QPainter): + + brush = QBrush(QColor("#007430")) + + painter.setBrush(brush) + painter.setPen(Qt.NoPen) + painter.setRenderHint(QPainter.Antialiasing) + + itemSize = self.size() + + painter.drawRoundedRect(0, 0, itemSize.width(), itemSize.height() - 10, 10, 10) + + if self.rightAligned: + points = [ + QPointF(itemSize.width() - 10.0, itemSize.height() - 10.0), + QPointF(itemSize.width() - 20.0, itemSize.height()), + QPointF(itemSize.width() - 30.0, itemSize.height() - 10.0), + ] + else: + points = [ + QPointF(10.0, itemSize.height() - 10.0), + QPointF(20.0, itemSize.height()), + QPointF(30.0, itemSize.height() - 10.0), + ] + painter.drawConvexPolygon(points) + + +if __name__ == "__main__": + + app = QApplication(sys.argv) + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qmlRegisterType(TextBalloon, "TextBalloonPlugin", 1, 0, "TextBalloon") + view.setSource(QUrl.fromLocalFile("main.qml")) + + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + + sys.exit(app.exec_()) diff --git a/examples/quick/customitems/painteditem/painteditem.pyproject b/examples/quick/customitems/painteditem/painteditem.pyproject new file mode 100644 index 0000000..0c70ebe --- /dev/null +++ b/examples/quick/customitems/painteditem/painteditem.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.qml", "painteditem.pyproject"] +} diff --git a/examples/remoteobjects/modelview/modelview.pyproject b/examples/remoteobjects/modelview/modelview.pyproject new file mode 100644 index 0000000..0b3a1b5 --- /dev/null +++ b/examples/remoteobjects/modelview/modelview.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["modelviewserver.py", "modelviewclient.py"] +} diff --git a/examples/remoteobjects/modelview/modelviewclient.py b/examples/remoteobjects/modelview/modelviewclient.py new file mode 100644 index 0000000..378a051 --- /dev/null +++ b/examples/remoteobjects/modelview/modelviewclient.py @@ -0,0 +1,61 @@ +############################################################################# +## +## Copyright (C) 2017 Ford Motor Company +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the remoteobjects/modelviewclient example from Qt v5.x""" + +import sys + +from PySide2.QtCore import QUrl +from PySide2.QtWidgets import (QApplication, QTreeView) +from PySide2.QtRemoteObjects import QRemoteObjectNode + +if __name__ == '__main__': + app = QApplication(sys.argv) + node = QRemoteObjectNode(QUrl("local:registry")) + node.setHeartbeatInterval(1000) + view = QTreeView() + view.setWindowTitle("RemoteView") + view.resize(640,480) + model = node.acquireModel("RemoteModel") + view.setModel(model) + view.show() + + sys.exit(app.exec_()) diff --git a/examples/remoteobjects/modelview/modelviewserver.py b/examples/remoteobjects/modelview/modelviewserver.py new file mode 100644 index 0000000..5c0bba5 --- /dev/null +++ b/examples/remoteobjects/modelview/modelviewserver.py @@ -0,0 +1,139 @@ +############################################################################# +## +## Copyright (C) 2017 Ford Motor Company +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the remoteobjects/modelviewserver example from Qt v5.x""" + +import sys + +from PySide2.QtCore import (Qt, QByteArray, QModelIndex, QObject, QTimer, QUrl) +from PySide2.QtGui import (QColor, QStandardItemModel, QStandardItem) +from PySide2.QtWidgets import (QApplication, QTreeView) +from PySide2.QtRemoteObjects import QRemoteObjectHost, QRemoteObjectRegistryHost + +class TimerHandler(QObject): + def __init__(self, model): + super(TimerHandler, self).__init__() + self._model = model + + def change_data(self): + for i in range(10, 50): + self._model.setData(self._model.index(i, 1), + QColor(Qt.blue), Qt.BackgroundRole) + + def insert_data(self): + self._model.insertRows(2, 9) + for i in range(2, 11): + self._model.setData(self._model.index(i, 1), + QColor(Qt.green), Qt.BackgroundRole) + self._model.setData(self._model.index(i, 1), + "InsertedRow", Qt.DisplayRole) + + def remove_data(self): + self._model.removeRows(2, 4) + + def change_flags(self): + item = self._model.item(0, 0) + item.setEnabled(False) + item = item.child(0, 0) + item.setFlags(item.flags() & Qt.ItemIsSelectable) + + def move_data(self): + self._model.moveRows(QModelIndex(), 2, 4, QModelIndex(), 10) + + +def add_child(num_children, nesting_level): + result = [] + if nesting_level == 0: + return result + for i in range(num_children): + child = QStandardItem("Child num {}, nesting Level {}".format(i + 1, + nesting_level)) + if i == 0: + child.appendRow(add_child(num_children, nesting_level -1)) + result.append(child) + return result + +if __name__ == '__main__': + app = QApplication(sys.argv) + model_size = 100000 + list = [] + source_model = QStandardItemModel() + horizontal_header_list = ["First Column with spacing", + "Second Column with spacing"] + source_model.setHorizontalHeaderLabels(horizontal_header_list) + for i in range(model_size): + first_item = QStandardItem("FancyTextNumber {}".format(i)) + if i == 0: + first_item.appendRow(add_child(2, 2)) + second_item = QStandardItem("FancyRow2TextNumber {}".format(i)) + if i % 2 == 0: + first_item.setBackground(Qt.red) + row = [first_item, second_item] + source_model.invisibleRootItem().appendRow(row) + list.append("FancyTextNumber {}".format(i)) + + # Needed by QMLModelViewClient + role_names = { + Qt.DisplayRole : QByteArray(b'_text'), + Qt.BackgroundRole : QByteArray(b'_color') + } + source_model.setItemRoleNames(role_names) + + roles = [Qt.DisplayRole, Qt.BackgroundRole] + + print("Creating registry host") + node = QRemoteObjectRegistryHost(QUrl("local:registry")) + + node2 = QRemoteObjectHost(QUrl("local:replica"), QUrl("local:registry")) + node2.enableRemoting(source_model, "RemoteModel", roles) + + view = QTreeView() + view.setWindowTitle("SourceView") + view.setModel(source_model) + view.show() + handler = TimerHandler(source_model) + QTimer.singleShot(5000, handler.change_data) + QTimer.singleShot(10000, handler.insert_data) + QTimer.singleShot(11000, handler.change_flags) + QTimer.singleShot(12000, handler.remove_data) + QTimer.singleShot(13000, handler.move_data) + + sys.exit(app.exec_()) diff --git a/examples/samplebinding/CMakeLists.txt b/examples/samplebinding/CMakeLists.txt new file mode 100644 index 0000000..cb61358 --- /dev/null +++ b/examples/samplebinding/CMakeLists.txt @@ -0,0 +1,231 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Enable policy to not use RPATH settings for install_name on macOS. +if(POLICY CMP0068) + cmake_policy(SET CMP0068 NEW) +endif() + +# Consider changing the project name to something relevant for you. +project(SampleBinding) + +# ================================ General configuration ====================================== + +# Set CPP standard to C++11 minimum. +set(CMAKE_CXX_STANDARD 11) + +# The sample library for which we will create bindings. You can change the name to something +# relevant for your project. +set(sample_library "libuniverse") + +# The name of the generated bindings module (as imported in Python). You can change the name +# to something relevant for your project. +set(bindings_library "Universe") + +# The header file with all the types and functions for which bindings will be generated. +# Usually it simply includes other headers of the library you are creating bindings for. +set(wrapped_header ${CMAKE_SOURCE_DIR}/bindings.h) + +# The typesystem xml file which defines the relationships between the C++ types / functions +# and the corresponding Python equivalents. +set(typesystem_file ${CMAKE_SOURCE_DIR}/bindings.xml) + +# Specify which C++ files will be generated by shiboken. This includes the module wrapper +# and a '.cpp' file per C++ type. These are needed for generating the module shared +# library. +set(generated_sources + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/universe_module_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/icecream_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/truck_wrapper.cpp) + + +# ================================== Shiboken detection ====================================== +# Use provided python interpreter if given. +if(NOT python_interpreter) + find_program(python_interpreter "python") +endif() +message(STATUS "Using python interpreter: ${python_interpreter}") + +# Macro to get various pyside / python include / link flags and paths. +# Uses the not entirely supported utils/pyside2_config.py file. +macro(pyside2_config option output_var) + if(${ARGC} GREATER 2) + set(is_list ${ARGV2}) + else() + set(is_list "") + endif() + + execute_process( + COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" + ${option} + OUTPUT_VARIABLE ${output_var} + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if ("${${output_var}}" STREQUAL "") + message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.") + endif() + if(is_list) + string (REPLACE " " ";" ${output_var} "${${output_var}}") + endif() +endmacro() + +# Query for the shiboken generator path, Python path, include paths and linker flags. +pyside2_config(--shiboken2-module-path shiboken2_module_path) +pyside2_config(--shiboken2-generator-path shiboken2_generator_path) +pyside2_config(--python-include-path python_include_dir) +pyside2_config(--shiboken2-generator-include-path shiboken_include_dir 1) +pyside2_config(--shiboken2-module-shared-libraries-cmake shiboken_shared_libraries 0) +pyside2_config(--python-link-flags-cmake python_linking_data 0) + +set(shiboken_path "${shiboken2_generator_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") +if(NOT EXISTS ${shiboken_path}) + message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}") +endif() + + +# ==================================== RPATH configuration ==================================== + + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Enable rpaths so that the built shared libraries find their dependencies. +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +set(CMAKE_INSTALL_RPATH ${shiboken2_module_path} ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= + + +# =============================== CMake target - sample_library =============================== + + +# Define the sample shared library for which we will create bindings. +set(${sample_library}_sources icecream.cpp truck.cpp) +add_library(${sample_library} SHARED ${${sample_library}_sources}) +set_property(TARGET ${sample_library} PROPERTY PREFIX "") + +# Needed mostly on Windows to export symbols, and create a .lib file, otherwise the binding +# library can't link to the sample library. +target_compile_definitions(${sample_library} PRIVATE BINDINGS_BUILD) + + +# ====================== Shiboken target for generating binding C++ files ==================== + + +# Set up the options to pass to shiboken. +set(shiboken_options --generator-set=shiboken --enable-parent-ctor-heuristic + --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --avoid-protected-hack + -I${CMAKE_SOURCE_DIR} + -T${CMAKE_SOURCE_DIR} + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ) + +set(generated_sources_dependencies ${wrapped_header} ${typesystem_file}) + +# Add custom target to run shiboken to generate the binding cpp files. +add_custom_command(OUTPUT ${generated_sources} + COMMAND ${shiboken_path} + ${shiboken_options} ${wrapped_header} ${typesystem_file} + DEPENDS ${generated_sources_dependencies} + IMPLICIT_DEPENDS CXX ${wrapped_header} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running generator for ${typesystem_file}.") + + +# =============================== CMake target - bindings_library ============================= + + +# Set the cpp files which will be used for the bindings library. +set(${bindings_library}_sources ${generated_sources}) + +# Define and build the bindings library. +add_library(${bindings_library} MODULE ${${bindings_library}_sources}) + +# Apply relevant include and link flags. +target_include_directories(${bindings_library} PRIVATE ${python_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${shiboken_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${CMAKE_SOURCE_DIR}) + +target_link_libraries(${bindings_library} PRIVATE ${shiboken_shared_libraries}) +target_link_libraries(${bindings_library} PRIVATE ${sample_library}) + +# Adjust the name of generated module. +set_property(TARGET ${bindings_library} PROPERTY PREFIX "") +set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME + "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") +if(WIN32) + set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") +endif() + +# Make sure the linker doesn't complain about not finding Python symbols on macOS. +if(APPLE) + set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(APPLE) + +# Find and link to the python import library only on Windows. +# On Linux and macOS, the undefined symbols will get resolved by the dynamic linker +# (the symbols will be picked up in the Python executable). +if (WIN32) + list(GET python_linking_data 0 python_libdir) + list(GET python_linking_data 1 python_lib) + find_library(python_link_flags ${python_lib} PATHS ${python_libdir} HINTS ${python_libdir}) + target_link_libraries(${bindings_library} PRIVATE ${python_link_flags}) +endif() + + +# ================================= Dubious deployment section ================================ + +set(windows_shiboken_shared_libraries) + +if(WIN32) + # ========================================================================================= + # !!! (The section below is deployment related, so in a real world application you will + # want to take care of this properly (this is simply to eliminate errors that users usually + # encounter. + # ========================================================================================= + # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link + # against a wrong python shared library. + + set(python_versions_list 3 32 33 34 35 36 37 38) + set(python_additional_link_flags "") + foreach(ver ${python_versions_list}) + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}_d.lib\"") + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}.lib\"") + endforeach() + + set_target_properties(${bindings_library} + PROPERTIES LINK_FLAGS "${python_additional_link_flags}") + + # Compile a list of shiboken shared libraries to be installed, so that + # the user doesn't have to set the PATH manually to point to the PySide2 package. + foreach(library_path ${shiboken_shared_libraries}) + string(REGEX REPLACE ".lib$" ".dll" library_path ${library_path}) + file(TO_CMAKE_PATH ${library_path} library_path) + list(APPEND windows_shiboken_shared_libraries "${library_path}") + endforeach() + # ========================================================================================= + # !!! End of dubious section. + # ========================================================================================= +endif() + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Install the library and the bindings module into the source folder near the main.py file, so +# that the Python interpeter successfully imports the used module. +install(TARGETS ${bindings_library} ${sample_library} + LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + ) +install(FILES ${windows_shiboken_shared_libraries} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= diff --git a/examples/samplebinding/README.md b/examples/samplebinding/README.md new file mode 100644 index 0000000..e84d1ef --- /dev/null +++ b/examples/samplebinding/README.md @@ -0,0 +1,236 @@ +# Sample bindings example + +This example showcases how to generate Python bindings for a +non-Qt C++ library. + +The example defines a CMake project that builds two libraries: +* `libuniverse` - a sample library with two C++ classes. +* `Universe` - the generated Python extension module that contains + bindings to the library above. + +The project file is structured in such a way that a user can copy-paste +in into their own project, and be able to build it with a minimal amount +of modifications. + +## Description + +The libuniverse library declares two classes: `Icecream` and `Truck`. + +`Icecream` objects have a flavor, and an accessor for returning the +flavor. + +`Truck` instances store a vector of `Icecream` objects, and have various +methods for adding new flavors, printing available flavors, delivering +icecream, etc. + +From a C++ perspective, `Icecream` instances are treated as +**object types** (pointer semantics) because the class declares virtual +methods. + +In contrast `Truck` does not define virtual methods and is treated as +a **value type** (copy semantics). + +Because `Truck` is a value type and it stores a vector of `Icecream` +pointers, the rule of three has to be taken into account (implement the +copy constructor, assignment operator, destructor). + +And due to `Icecream` objects being copyable, the type has to define an +implementation of the *clone()* method, to avoid type slicing issues. + +Both of these types and their methods will be exposed to Python by +generating CPython code. The code is generated by **shiboken** and +placed in separate ".cpp" files named after each C++ type. The code is +then compiled and linked into a shared library. The shared library is a +CPython extension module, which is loaded by the Python interpreter. + +Beacuse the C++ language has different semantics to Python, shiboken +needs help in figuring out how to generate the bindings code. This is +done by specifying a special XML file called a typesystem file. + +In the typesystem file you specify things like: + * which C++ primitive types should have bindings (int, bool, float) + * which C++ classes should have bindings (Icecream) and what kind of + semantics (value / object) + * Ownership rules (who deletes the C++ objects, C++ or Python) + * Code injection (for various special cases that shiboken doesn't know + about) + * Package name (name of package as imported from Python) + +In this example we declare `bool` and `std::string` as primitive types, +`Icecream` as an object type, `Truck` as a value type, +and the `clone()` and `addIcecreamFlavor(Icecream*)` need additional +info about who owns the parameter objects when passing them across +language boundaries (in this case C++ will delete the objects). + +The `Truck` has getters and setters for the string `arrivalMessage`. +In the type system file, we declare this to be a property in Python: + +``` + +``` + +It can then be used in a more pythonic way: + +``` +special_truck.arrivalMessage = "A new SPECIAL icecream truck has arrived!\n" +``` + +After shiboken generates the C++ code and CMake makes an extension +module from the code, the types can be accessed in Python simply by +importing them using the original C++ names. + +``` +from Universe import Icecream, Truck +``` + +Constructing C++ wrapped objects is the same as in Python +``` +icecream = Icecream("vanilla") +truck = Truck() +``` + + +And actual C++ constructors are mapped to the Python `__init__` method. +``` +class VanillaChocolateIcecream(Icecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) +``` + + +C++ methods can be accessed as regular Python methods using the C++ +names +``` +truck.addIcecreamFlavor(icecream) +``` + + +Inheritance works as with regular Python classes, and virtual C++ +methods can be overridden simply by definining a method with the same +name as in the C++ class. +``` +class VanillaChocolateIcecream(Icecream): + # ... + def getFlavor(self): + return "vanilla sprinked with chocolate" + +``` + + +The `main.py` script demonstrates usages of these types. + +The CMake project file contains many comments explaining all the build +rules for those interested in the build process. + +## Building the project + +This example can only be built using **CMake**. +The following requirements need to be met: + +* A PySide2 package is installed into the current active Python + environment (system or virtualenv) +* A new enough version of CMake (**3.1+**). + +For Windows you will also need: +* a Visual Studio environment to be active in your terminal +* Correct visual studio architecture chosen (32 vs 64 bit) +* Make sure that your Python intepreter and bindings project build + configuration is the same (all Release, which is more likely, + or all Debug). + +The build uses the `pyside2_config.py` file to configure the project +using the current PySide2/Shiboken2 installation. + +### Using CMake + +You can build and run this example by executing the following commands +(slightly adapted to your file system layout) in a terminal: + +On macOS/Linux: +```bash +cd ~/pyside-setup/examples/samplebinding +mkdir build +cd build +cmake -H.. -B. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release +make +make install +python ../main.py +``` + +On Windows: +```bash +cd C:\pyside-setup\examples\samplebinding +mkdir build +cd build +cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release +# or if you have jom available +# cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release +nmake # or jom +nmake install # or jom install +python ..\main.py +``` + +#### Windows troubleshooting + +It is possible that **CMake** can pick up the wrong compiler +for a different architecture, but it can be addressed explicitly +using the -G option: + +```bash +cmake -H.. -B. -G "Visual Studio 14 Win64" +``` + +If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file +will be generated, and can be used with `MSBuild` +instead of `nmake/jom`. +The easiest way to both build and install in this case, is to use +the cmake executable: + +```bash +cmake --build . --target install --config Release +``` + +Note that using the "NMake Makefiles JOM" generator is preferred to +the MSBuild one, because the MSBuild one generates configs for both +Debug and Release, and this might lead to building errors if you +accidentally build the wrong config at least once. + +## Virtualenv Support + +If the python application is started from a terminal with an activated +python virtual environment, that environment's packages will be used for +the python module import process. +In this case, make sure that the bindings were built while the +`virtualenv` was active, so that the build system picks up the correct +python shared library and PySide2 / shiboken package. + +## Linux Shared Libraries Notes + +For this example's purpose, we link against the absolute path of the +dependent shared library `libshiboken` because the +installation of the library is done via a wheel, and there is +no clean solution to include symbolic links in a wheel package +(so that passing -lshiboken to the linker would work). + +## Windows Notes + +The build config of the bindings (Debug or Release) should match +the PySide2 build config, otherwise the application will not properly +work. + +In practice this means the only supported configurations are: + +1. release config build of the bindings + + PySide2 `setup.py` without `--debug` flag + `python.exe` for the + PySide2 build process + `python36.dll` for the linked in shared + library. +2. debug config build of the application + + PySide2 `setup.py` **with** `--debug` flag + `python_d.exe` for the + PySide2 build process + `python36_d.dll` for the linked in shared + library. + +This is necessary because all the shared libraries in question have to +link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`). +To make the example as self-contained as possible, the shared libraries +in use (`pyside2.dll`, `shiboken2.dll`) are hard-linked into the build +folder of the application. diff --git a/examples/samplebinding/bindings.h b/examples/samplebinding/bindings.h new file mode 100644 index 0000000..ba42dc6 --- /dev/null +++ b/examples/samplebinding/bindings.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BINDINGS_H +#define BINDINGS_H + +#include "icecream.h" +#include "truck.h" + +#endif // BINDINGS_H diff --git a/examples/samplebinding/bindings.xml b/examples/samplebinding/bindings.xml new file mode 100644 index 0000000..9be9f1a --- /dev/null +++ b/examples/samplebinding/bindings.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/samplebinding/icecream.cpp b/examples/samplebinding/icecream.cpp new file mode 100644 index 0000000..8d40302 --- /dev/null +++ b/examples/samplebinding/icecream.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "icecream.h" + +Icecream::Icecream(const std::string &flavor) : m_flavor(flavor) {} + +Icecream::~Icecream() {} + +const std::string Icecream::getFlavor() +{ + return m_flavor; +} + +Icecream *Icecream::clone() +{ + return new Icecream(*this); +} diff --git a/examples/samplebinding/icecream.h b/examples/samplebinding/icecream.h new file mode 100644 index 0000000..1997fdc --- /dev/null +++ b/examples/samplebinding/icecream.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef ICECREAM_H +#define ICECREAM_H + +#include + +#include "macros.h" + +class BINDINGS_API Icecream +{ +public: + Icecream(const std::string &flavor); + virtual Icecream *clone(); + virtual ~Icecream(); + virtual const std::string getFlavor(); + +private: + std::string m_flavor; +}; + + +#endif // ICECREAM_H diff --git a/examples/samplebinding/macros.h b/examples/samplebinding/macros.h new file mode 100644 index 0000000..71b27c3 --- /dev/null +++ b/examples/samplebinding/macros.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MACROS_H +#define MACROS_H + +#if defined _WIN32 || defined __CYGWIN__ + // Export symbols when creating .dll and .lib, and import them when using .lib. + #if BINDINGS_BUILD + #define BINDINGS_API __declspec(dllexport) + #else + #define BINDINGS_API __declspec(dllimport) + #endif + // Disable warnings about exporting STL types being a bad idea. Don't use this in production + // code. + #pragma warning( disable : 4251 ) +#else + #define BINDINGS_API +#endif + +#endif // MACROS_H diff --git a/examples/samplebinding/main.py b/examples/samplebinding/main.py new file mode 100644 index 0000000..dc727c5 --- /dev/null +++ b/examples/samplebinding/main.py @@ -0,0 +1,101 @@ + +############################################################################ +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from __future__ import print_function + +"""An example showcasing how to use bindings for a custom non-Qt C++ library""" + +from Universe import Icecream, Truck + +class VanillaChocolateIcecream(Icecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateIcecream(self.getFlavor()) + + def getFlavor(self): + return "vanilla sprinked with chocolate" + +class VanillaChocolateCherryIcecream(VanillaChocolateIcecream): + def __init__(self, flavor=""): + super(VanillaChocolateIcecream, self).__init__(flavor) + + def clone(self): + return VanillaChocolateCherryIcecream(self.getFlavor()) + + def getFlavor(self): + base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor() + return base_flavor + " and a cherry" + +if __name__ == '__main__': + leave_on_destruction = True + truck = Truck(leave_on_destruction) + + flavors = ["vanilla", "chocolate", "strawberry"] + for f in flavors: + icecream = Icecream(f) + truck.addIcecreamFlavor(icecream) + + truck.addIcecreamFlavor(VanillaChocolateIcecream()) + truck.addIcecreamFlavor(VanillaChocolateCherryIcecream()) + + truck.arrive() + truck.printAvailableFlavors() + result = truck.deliver() + + if result: + print("All the kids got some icecream!") + else: + print("Aww, someone didn't get the flavor they wanted...") + + if not result: + special_truck = Truck(truck) + del truck + + print("") + special_truck.arrivalMessage = "A new SPECIAL icecream truck has arrived!\n" + special_truck.arrive() + special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream")) + special_truck.printAvailableFlavors() + special_truck.deliver() + print("Now everyone got the flavor they wanted!") + special_truck.leave() diff --git a/examples/samplebinding/truck.cpp b/examples/samplebinding/truck.cpp new file mode 100644 index 0000000..056abfc --- /dev/null +++ b/examples/samplebinding/truck.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +#include "truck.h" + +Truck::Truck(bool leaveOnDestruction) : m_leaveOnDestruction(leaveOnDestruction) {} + +Truck::Truck(const Truck &other) +{ + for (size_t i = 0; i < other.m_flavors.size(); ++i) { + addIcecreamFlavor(other.m_flavors[i]->clone()); + } +} + +Truck &Truck::operator=(const Truck &other) +{ + if (this != &other) { + clearFlavors(); + for (size_t i = 0; i < other.m_flavors.size(); ++i) { + addIcecreamFlavor(other.m_flavors[i]->clone()); + } + } + return *this; +} + +Truck::~Truck() +{ + if (m_leaveOnDestruction) + leave(); + clearFlavors(); +} + +void Truck::addIcecreamFlavor(Icecream *icecream) +{ + m_flavors.push_back(icecream); +} + +void Truck::printAvailableFlavors() const +{ + std::cout << "It sells the following flavors: \n"; + for (size_t i = 0; i < m_flavors.size(); ++ i) { + std::cout << " * " << m_flavors[i]->getFlavor() << '\n'; + } + std::cout << '\n'; +} + +void Truck::arrive() const +{ + std::cout << m_arrivalMessage; +} + +void Truck::leave() const +{ + std::cout << "The truck left the neighborhood.\n"; +} + +void Truck::setLeaveOnDestruction(bool value) +{ + m_leaveOnDestruction = value; +} + +void Truck::setArrivalMessage(const std::string &message) +{ + m_arrivalMessage = message; +} + +std::string Truck::getArrivalMessage() const +{ + return m_arrivalMessage; +} + +bool Truck::deliver() const +{ + std::random_device rd; + std::mt19937 mt(rd()); + std::uniform_int_distribution dist(1, 2); + + std::cout << "The truck started delivering icecream to all the kids in the neighborhood.\n"; + bool result = false; + + if (dist(mt) == 2) + result = true; + + return result; +} + +void Truck::clearFlavors() +{ + for (size_t i = 0; i < m_flavors.size(); ++i) { + delete m_flavors[i]; + } + m_flavors.clear(); +} diff --git a/examples/samplebinding/truck.h b/examples/samplebinding/truck.h new file mode 100644 index 0000000..3f213f9 --- /dev/null +++ b/examples/samplebinding/truck.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TRUCK_H +#define TRUCK_H + +#include + +#include "icecream.h" +#include "macros.h" + +class BINDINGS_API Truck { +public: + Truck(bool leaveOnDestruction = false); + Truck(const Truck &other); + Truck& operator=(const Truck &other); + ~Truck(); + + void addIcecreamFlavor(Icecream *icecream); + void printAvailableFlavors() const; + + bool deliver() const; + void arrive() const; + void leave() const; + + void setLeaveOnDestruction(bool value); + + void setArrivalMessage(const std::string &message); + std::string getArrivalMessage() const; + +private: + void clearFlavors(); + + bool m_leaveOnDestruction = false; + std::string m_arrivalMessage = "A new icecream truck has arrived!\n"; + std::vector m_flavors; +}; + +#endif // TRUCK_H diff --git a/examples/script/README.md b/examples/script/README.md new file mode 100644 index 0000000..6133f43 --- /dev/null +++ b/examples/script/README.md @@ -0,0 +1,9 @@ +# About QtScript + +The QtScript module is deprecated since Qt 5.5, +and hence is not being distributed through our wheels. + +However, it is possible to access the module +when using a local build of PySide2 which was built +against a Qt installation containing the Qt Script module +(ALL_OPTIONAL_MODULES in `sources/pyside2/CMakeLists.txt`). diff --git a/examples/script/helloscript.py b/examples/script/helloscript.py new file mode 100644 index 0000000..2f0379a --- /dev/null +++ b/examples/script/helloscript.py @@ -0,0 +1,60 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the script/helloscript example from Qt v5.x""" + +import sys +from PySide2 import QtWidgets, QtScript + + +app = QtWidgets.QApplication(sys.argv) + +engine = QtScript.QScriptEngine() + +button = QtWidgets.QPushButton() +scriptButton = engine.newQObject(button) +engine.globalObject().setProperty("button", scriptButton) + +engine.evaluate("button.text = 'Hello World from PySide2!'") +engine.evaluate("button.styleSheet = 'font-style: italic'") +engine.evaluate("button.show()") + +sys.exit(app.exec_()) diff --git a/examples/script/script.pyproject b/examples/script/script.pyproject new file mode 100644 index 0000000..5beba8c --- /dev/null +++ b/examples/script/script.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["README.md", "helloscript.py"] +} diff --git a/examples/scriptableapplication/CMakeLists.txt b/examples/scriptableapplication/CMakeLists.txt new file mode 100644 index 0000000..9992064 --- /dev/null +++ b/examples/scriptableapplication/CMakeLists.txt @@ -0,0 +1,213 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Enable policy to run automoc on generated files. +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +project(scriptableapplication) + +# Set CPP standard to C++11 minimum. +set(CMAKE_CXX_STANDARD 11) + +# Find required Qt packages. +find_package(Qt5 5.12 REQUIRED COMPONENTS Core Gui Widgets) + +# Use provided python interpreter if given. +if(NOT python_interpreter) + find_program(python_interpreter "python") +endif() +message(STATUS "Using python interpreter: ${python_interpreter}") + +# Macro to get various pyside / python include / link flags. +macro(pyside2_config option output_var) + if(${ARGC} GREATER 2) + set(is_list ${ARGV2}) + else() + set(is_list "") + endif() + + execute_process( + COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" + ${option} + OUTPUT_VARIABLE ${output_var} + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if ("${${output_var}}" STREQUAL "") + message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.") + endif() + if(is_list) + string (REPLACE " " ";" ${output_var} "${${output_var}}") + endif() +endmacro() + +# Query for the shiboken2-generator path, PySide2 path, Python path, include paths and linker flags. +pyside2_config(--shiboken2-module-path SHIBOKEN2_MODULE_PATH) +pyside2_config(--shiboken2-generator-path SHIBOKEN2_GENERATOR_PATH) +pyside2_config(--pyside2-path PYSIDE2_PATH) + +pyside2_config(--python-include-path PYTHON_INCLUDE_DIR) +pyside2_config(--shiboken2-generator-include-path SHIBOKEN2_GENERATOR_INCLUDE_DIR 1) +pyside2_config(--pyside2-include-path PYSIDE2_INCLUDE_DIR 1) + +pyside2_config(--python-link-flags-cmake PYTHON_LINKING_DATA 0) +pyside2_config(--shiboken2-module-shared-libraries-cmake SHIBOKEN2_MODULE_SHARED_LIBRARIES 0) +pyside2_config(--pyside2-shared-libraries-cmake PYSIDE2_SHARED_LIBRARIES 0) + +set(SHIBOKEN_PATH "${SHIBOKEN2_GENERATOR_PATH}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") + +if(NOT EXISTS ${SHIBOKEN_PATH}) + message(FATAL_ERROR "Shiboken executable not found at path: ${SHIBOKEN_PATH}") +endif() + + +# Get all relevant Qt include dirs, to pass them on to shiboken. +get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_GUI_INCLUDE_DIRS TARGET Qt5::Gui PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt5::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +set(QT_INCLUDE_DIRS ${QT_CORE_INCLUDE_DIRS} ${QT_GUI_INCLUDE_DIRS} ${QT_WIDGETS_INCLUDE_DIRS}) +set(INCLUDES "") +foreach(INCLUDE_DIR ${QT_INCLUDE_DIRS}) + list(APPEND INCLUDES "-I${INCLUDE_DIR}") +endforeach() + +# On macOS, check if Qt is a framework build. This affects how include paths should be handled. +get_target_property(QtCore_is_framework Qt5::Core FRAMEWORK) +if (QtCore_is_framework) + get_target_property(qt_core_library_location Qt5::Core LOCATION) + get_filename_component(qt_core_library_location_dir "${qt_core_library_location}" DIRECTORY) + get_filename_component(lib_dir "${qt_core_library_location_dir}/../" ABSOLUTE) + list(APPEND INCLUDES "--framework-include-paths=${lib_dir}") +endif() + +# Set up the options to pass to shiboken. +set(WRAPPED_HEADER ${CMAKE_SOURCE_DIR}/wrappedclasses.h) +set(TYPESYSTEM_FILE ${CMAKE_SOURCE_DIR}/scriptableapplication.xml) + +set(SHIBOKEN_OPTIONS --generator-set=shiboken --enable-parent-ctor-heuristic + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --avoid-protected-hack + ${INCLUDES} + -I${CMAKE_SOURCE_DIR} + -T${CMAKE_SOURCE_DIR} + -T${PYSIDE2_PATH}/typesystems + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ) + +# Specify which sources will be generated by shiboken, and their dependencies. +set(GENERATED_SOURCES + ${CMAKE_CURRENT_BINARY_DIR}/AppLib/applib_module_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/AppLib/mainwindow_wrapper.cpp) + +set(GENERATED_SOURCES_DEPENDENCIES + ${WRAPPED_HEADER} + ${TYPESYSTEM_FILE} + ) + +# Add custom target to run shiboken. +add_custom_command(OUTPUT ${GENERATED_SOURCES} + COMMAND ${SHIBOKEN_PATH} + ${SHIBOKEN_OPTIONS} ${WRAPPED_HEADER} ${TYPESYSTEM_FILE} + DEPENDS ${GENERATED_SOURCES_DEPENDENCIES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running generator for ${TYPESYSTEM_FILE}.") + +# Set the CPP files. +set(SOURCES + mainwindow.cpp + pythonutils.cpp + ${GENERATED_SOURCES} + ) + +# We need to include the headers for the module bindings that we use. +set(PYSIDE2_ADDITIONAL_INCLUDES "") +foreach(INCLUDE_DIR ${PYSIDE2_INCLUDE_DIR}) + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtCore") + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtGui") + list(APPEND PYSIDE2_ADDITIONAL_INCLUDES "${INCLUDE_DIR}/QtWidgets") +endforeach() + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Enable rpaths so that the example can be executed from the build dir. +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +set(CMAKE_INSTALL_RPATH ${PYSIDE2_PATH} ${SHIBOKEN2_MODULE_PATH}) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= + +# Declare executable so we can enable automoc. +add_executable(${PROJECT_NAME} main.cpp) + +# Enable automoc. +set_property(TARGET ${PROJECT_NAME} PROPERTY AUTOMOC 1) + +# Add the rest of the sources. +target_sources(${PROJECT_NAME} PUBLIC ${SOURCES}) + +# Apply relevant include and link flags. +target_include_directories(${PROJECT_NAME} PRIVATE ${PYTHON_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_GENERATOR_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_INCLUDE_DIR}) +target_include_directories(${PROJECT_NAME} PRIVATE ${PYSIDE2_ADDITIONAL_INCLUDES}) +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}) + +target_link_libraries(${PROJECT_NAME} PRIVATE Qt5::Widgets) +target_link_libraries(${PROJECT_NAME} PRIVATE ${SHIBOKEN2_MODULE_SHARED_LIBRARIES}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PYSIDE2_SHARED_LIBRARIES}) + +# Find and link to the python library. +list(GET PYTHON_LINKING_DATA 0 PYTHON_LIBDIR) +list(GET PYTHON_LINKING_DATA 1 PYTHON_LIB) +find_library(PYTHON_LINK_FLAGS ${PYTHON_LIB} PATHS ${PYTHON_LIBDIR} HINTS ${PYTHON_LIBDIR}) +target_link_libraries(${PROJECT_NAME} PRIVATE ${PYTHON_LINK_FLAGS}) + +# Same as CONFIG += no_keywords to avoid syntax errors in object.h due to the usage of the word Slot +target_compile_definitions(${PROJECT_NAME} PRIVATE QT_NO_KEYWORDS) + +if(WIN32) + # ============================================================================================= + # !!! (The section below is deployment related, so in a real world application you will want to + # take care of this properly (this is simply to eliminate errors that users usually encounter. + # ============================================================================================= + # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link + # against a wrong python shared library. + + set(PYTHON_VERSIONS_LIST 3 32 33 34 35 36 37 38) + set(PYTHON_ADDITIONAL_LINK_FLAGS "") + foreach(VER ${PYTHON_VERSIONS_LIST}) + set(PYTHON_ADDITIONAL_LINK_FLAGS + "${PYTHON_ADDITIONAL_LINK_FLAGS} /NODEFAULTLIB:\"python${VER}_d.lib\"") + set(PYTHON_ADDITIONAL_LINK_FLAGS + "${PYTHON_ADDITIONAL_LINK_FLAGS} /NODEFAULTLIB:\"python${VER}.lib\"") + endforeach() + + set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "${PYTHON_ADDITIONAL_LINK_FLAGS}") + + # Add custom target to hard link PySide2 shared libraries (just like in qmake example), so you + # don't have to set PATH manually to point to the PySide2 package. + set(shared_libraries ${SHIBOKEN2_MODULE_SHARED_LIBRARIES} ${PYSIDE2_SHARED_LIBRARIES}) + foreach(LIBRARY_PATH ${shared_libraries}) + string(REGEX REPLACE ".lib$" ".dll" LIBRARY_PATH ${LIBRARY_PATH}) + get_filename_component(BASE_NAME ${LIBRARY_PATH} NAME) + file(TO_NATIVE_PATH ${LIBRARY_PATH} SOURCE_PATH) + file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${BASE_NAME}" DEST_PATH) + add_custom_command(OUTPUT "${BASE_NAME}" + COMMAND mklink /H "${DEST_PATH}" "${SOURCE_PATH}" + DEPENDS ${LIBRARY_PATH} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Creating hardlink to PySide2 shared library ${BASE_NAME}") + + # Fake target that depends on the previous one, but has special ALL keyword, which means + # it will always be executed. + add_custom_target("fake_${BASE_NAME}" ALL DEPENDS ${BASE_NAME}) + endforeach() + # ============================================================================================= + # !!! End of dubious section. + # ============================================================================================= +endif() diff --git a/examples/scriptableapplication/README.md b/examples/scriptableapplication/README.md new file mode 100644 index 0000000..d359581 --- /dev/null +++ b/examples/scriptableapplication/README.md @@ -0,0 +1,170 @@ +# Scriptable Application + +This example demonstrates how to make a Qt C++ application scriptable. + +It has a class **MainWindow** (`mainwindow.{cpp,h}`) +that inherits from *QMainWindow*, for which bindings are generated +using Shiboken. + +The header `wrappedclasses.h` is passed to Shiboken which generates +class wrappers and headers in a sub directory called **AppLib/** +which are linked to the application. + +The files `pythonutils.{cpp,h}` contain some code which binds the +instance of **MainWindow** to a variable called **'mainWindow'** in +the global Python namespace (`__main___`). +It is then possible to run Python script snippets like: + +```python +mainWindow.testFunction1() +``` +which trigger the underlying C++ function. + +## Building the project + +This example can be built using *CMake* or *QMake*, +but there are common requirements that you need to take into +consideration: + +* Make sure that a --standalone PySide2 package (bundled with Qt libraries) + is installed into the current active Python environment + (system or virtualenv) +* qmake has to be in your PATH: + * so that CMake find_package(Qt5) works (used for include headers), + * used for building the application with qmake instead of CMake +* use the same Qt version for building the example application, as was used + for building PySide2, this is to ensure binary compatibility between the + newly generated bindings libraries, the PySide2 libraries and the + Qt libraries. + +For Windows you will also need: +* a Visual Studio environment to be active in your terminal +* Correct visual studio architecture chosen (32 vs 64 bit) +* Make sure that your Qt + Python + PySide2 package + app build configuration + is the same (all Release, which is more likely, or all Debug). +* Make sure that your Qt + Python + PySide2 package + app are built with the + same version of MSVC, to avoid mixing of C++ runtime libraries. + In principle this means that if you use the python.org provided Python + interpreters, you need to use MSVC2015 for Python 3 projects, and MSVC2008 + for Python 2 projects. Which also means that you can't use official Qt + packages, because none of the supported ones are built with MSVC2008. + +Both build options will use the `pyside2_config.py` file to configure the project +using the current PySide2/Shiboken2 installation (for qmake via pyside2.pri, +and for CMake via the project CMakeLists.txt). + + +### Using CMake + +To build this example with CMake you will need a recent version of CMake (3.1+). + +You can build this example by executing the following commands +(slightly adapted to your file system layout) in a terminal: + +On macOS/Linux: +```bash +cd ~/pyside-setup/examples/scriptableapplication +mkdir build +cd build +cmake -H.. -B. -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release +make +./scriptableapplication +``` + +On Windows: +```bash +cd C:\pyside-setup\examples\scriptableapplication +mkdir build +cd build +cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release +# or if you have jom available +# cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release +nmake # or jom +scriptableapplication.exe +``` + +### Using QMake + +The file `scriptableapplication.pro` is the project file associated +to the example when using qmake. + +You can build this example by executing: +```bash +mkdir build +cd build +qmake .. +make # or nmake / jom for Windows +``` + +#### Windows troubleshooting + +Using **qmake** should work out of the box, there was a known issue +with directories and white spaces that is solved by using the +"~1" character, so the path will change from: +c:\Program Files\Python34\libs +to +c:\Progra~1\Python34\libs +this will avoid the issues when the Makefiles are generated. + +It is possible when using **cmake** to pick up the wrong compiler +for a different architecture, but it can be addressed explicitly +using the -G option: + +```bash +cmake -H.. -B. -G "Visual Studio 14 Win64" -DCMAKE_BUILD_TYPE=Release +``` + +If the `-G "Visual Studio 14 Win64"` option is used, a `sln` file +will be generated, and can be used with `MSBuild` +instead of `nmake/jom`. + +```bash +MSBuild scriptableapplication.sln "/p:Configuration=Release" +``` + +Note that using the "NMake Makefiles JOM" generator is preferred to +the MSBuild one, because in the latter case the executable is placed +into a directory other than the one that contains the dependency +dlls (shiboken, pyside). This leads to execution problems if the +application is started within the Release subdirectory and not the +one containing the dependencies. + +## Virtualenv Support + +If the application is started from a terminal with an activated python +virtual environment, that environment's packages will be used for the +python module import process. +In this case, make sure that the application was built while the +`virtualenv` was active, so that the build system picks up the correct +python shared library and PySide2 package. + +## Linux Shared Libraries Notes + +For this example's purpose, we link against the absolute paths of the +shared libraries (`libshiboken` and `libpyside`) because the +installation of the modules is being done via wheels, and there is +no clean solution to include symbolic links in the package +(so that regular -lshiboken works). + +## Windows Notes + +The build config of the application (Debug or Release) should match +the PySide2 build config, otherwise the application will not properly +work. + +In practice this means the only supported configurations are: + +1. release config build of the application + + PySide2 `setup.py` without `--debug` flag + `python.exe` for the + PySide2 build process + `python36.dll` for the linked in shared + library + release build of Qt. +2. debug config build of the application + + PySide2 `setup.py` **with** `--debug` flag + `python_d.exe` for the + PySide2 build process + `python36_d.dll` for the linked in shared + library + debug build of Qt. + +This is necessary because all the shared libraries in question have to +link to the same C++ runtime library (`msvcrt.dll` or `msvcrtd.dll`). +To make the example as self-contained as possible, the shared libraries +in use (`pyside2.dll`, `shiboken2.dll`) are hard-linked into the build +folder of the application. diff --git a/examples/scriptableapplication/main.cpp b/examples/scriptableapplication/main.cpp new file mode 100644 index 0000000..3314179 --- /dev/null +++ b/examples/scriptableapplication/main.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" + +#include +#include + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); + MainWindow mainWindow; + const QRect availableGeometry = mainWindow.screen()->availableGeometry(); + mainWindow.resize(availableGeometry.width() / 2, availableGeometry.height() / 2); + mainWindow.show(); + return a.exec(); +} diff --git a/examples/scriptableapplication/mainwindow.cpp b/examples/scriptableapplication/mainwindow.cpp new file mode 100644 index 0000000..53aea3c --- /dev/null +++ b/examples/scriptableapplication/mainwindow.cpp @@ -0,0 +1,142 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mainwindow.h" +#include "pythonutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +static const char defaultScript[] = R"( +print("Hello, world") +mainWindow.testFunction1() +)"; + +MainWindow::MainWindow() + : m_scriptEdit(new QPlainTextEdit(QString::fromLatin1(defaultScript).trimmed(), this)) +{ + setWindowTitle(tr("Scriptable Application")); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + const QIcon runIcon = QIcon::fromTheme(QStringLiteral("system-run")); + QAction *runAction = fileMenu->addAction(runIcon, tr("&Run..."), this, &MainWindow::slotRunScript); + runAction->setShortcut(Qt::CTRL | Qt::Key_R); + QAction *diagnosticAction = fileMenu->addAction(tr("&Print Diagnostics"), this, &MainWindow::slotPrintDiagnostics); + diagnosticAction->setShortcut(Qt::CTRL | Qt::Key_D); + fileMenu->addAction(tr("&Invoke testFunction1()"), this, &MainWindow::testFunction1); + const QIcon quitIcon = QIcon::fromTheme(QStringLiteral("application-exit")); + QAction *quitAction = fileMenu->addAction(quitIcon, tr("&Quit"), qApp, &QCoreApplication::quit); + quitAction->setShortcut(Qt::CTRL | Qt::Key_Q); + + QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); + const QIcon clearIcon = QIcon::fromTheme(QStringLiteral("edit-clear")); + QAction *clearAction = editMenu->addAction(clearIcon, tr("&Clear"), m_scriptEdit, &QPlainTextEdit::clear); + + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + const QIcon aboutIcon = QIcon::fromTheme(QStringLiteral("help-about")); + QAction *aboutAction = helpMenu->addAction(aboutIcon, tr("&About Qt"), qApp, &QApplication::aboutQt); + + QToolBar *toolBar = new QToolBar; + addToolBar(toolBar); + toolBar->addAction(quitAction); + toolBar->addSeparator(); + toolBar->addAction(clearAction); + toolBar->addSeparator(); + toolBar->addAction(runAction); + toolBar->addSeparator(); + toolBar->addAction(aboutAction); + + m_scriptEdit->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); + setCentralWidget(m_scriptEdit); + + if (!PythonUtils::bindAppObject("__main__", "mainWindow", PythonUtils::MainWindowType, this)) + statusBar()->showMessage(tr("Error loading the application module")); +} + +void MainWindow::slotRunScript() +{ + const QStringList script = m_scriptEdit->toPlainText().trimmed().split(QLatin1Char('\n'), Qt::SkipEmptyParts); + if (!script.isEmpty()) + runScript(script); +} + +void MainWindow::slotPrintDiagnostics() +{ + const QStringList script = QStringList() + << "import sys" << "print('Path=', sys.path)" << "print('Executable=', sys.executable)"; + runScript(script); +} + +void MainWindow::runScript(const QStringList &script) +{ + if (!::PythonUtils::runScript(script)) + statusBar()->showMessage(tr("Error running script")); +} + +void MainWindow::testFunction1() +{ + static int n = 1; + QString message; + QTextStream(&message) << __FUNCTION__ << " called #" << n++; + qDebug().noquote() << message; + statusBar()->showMessage(message); +} diff --git a/examples/scriptableapplication/mainwindow.h b/examples/scriptableapplication/mainwindow.h new file mode 100644 index 0000000..ce61383 --- /dev/null +++ b/examples/scriptableapplication/mainwindow.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QPlainTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(); + + void testFunction1(); + +private Q_SLOTS: + void slotRunScript(); + void slotPrintDiagnostics(); + +private: + void runScript(const QStringList &); + + QPlainTextEdit *m_scriptEdit; +}; + +#endif // MAINWINDOW_H diff --git a/examples/scriptableapplication/pyside2.pri b/examples/scriptableapplication/pyside2.pri new file mode 100644 index 0000000..2da3bc8 --- /dev/null +++ b/examples/scriptableapplication/pyside2.pri @@ -0,0 +1,52 @@ +PYSIDE_CONFIG = $$PWD/../utils/pyside2_config.py + +# Use provided python interpreter if given. +isEmpty(python_interpreter) { + python_interpreter = python +} +message(Using python interpreter: $$python_interpreter) + +SHIBOKEN2_GENERATOR = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-path) +isEmpty(SHIBOKEN2_GENERATOR): error(Unable to locate the shiboken2-generator package location) + +SHIBOKEN2_MODULE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-path) +isEmpty(SHIBOKEN2_MODULE): error(Unable to locate the shiboken2 package location) + +PYSIDE2 = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-path) +isEmpty(PYSIDE2): error(Unable to locate the PySide2 package location) + +PYTHON_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --python-include-path) +isEmpty(PYTHON_INCLUDE): error(Unable to locate the Python include headers directory) + +PYTHON_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --python-link-flags-qmake) +isEmpty(PYTHON_LFLAGS): error(Unable to locate the Python library for linking) + +SHIBOKEN2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-generator-include-path) +isEmpty(SHIBOKEN2_INCLUDE): error(Unable to locate the shiboken include headers directory) + +PYSIDE2_INCLUDE = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-include-path) +isEmpty(PYSIDE2_INCLUDE): error(Unable to locate the PySide2 include headers directory) + +SHIBOKEN2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-qmake-lflags) +isEmpty(SHIBOKEN2_LFLAGS): error(Unable to locate the shiboken libraries for linking) + +PYSIDE2_LFLAGS = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-qmake-lflags) +isEmpty(PYSIDE2_LFLAGS): error(Unable to locate the PySide2 libraries for linking) + +SHIBOKEN2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --shiboken2-module-shared-libraries-qmake) +isEmpty(SHIBOKEN2_SHARED_LIBRARIES): error(Unable to locate the used shiboken2 module shared libraries) + +PYSIDE2_SHARED_LIBRARIES = $$system($$python_interpreter $$PYSIDE_CONFIG --pyside2-shared-libraries-qmake) +isEmpty(PYSIDE2_SHARED_LIBRARIES): error(Unable to locate the used PySide2 shared libraries) + +INCLUDEPATH += "$$PYTHON_INCLUDE" $$PYSIDE2_INCLUDE $$SHIBOKEN2_INCLUDE +LIBS += $$PYTHON_LFLAGS $$PYSIDE2_LFLAGS $$SHIBOKEN2_LFLAGS +!build_pass:message(INCLUDEPATH is $$INCLUDEPATH) +!build_pass:message(LIBS are $$LIBS) + +!build_pass:message(Using $$PYSIDE2) + +!win32 { + !build_pass:message(RPATH will include $$PYSIDE2 and $$SHIBOKEN2_MODULE) + QMAKE_RPATHDIR += $$PYSIDE2 $$SHIBOKEN2_MODULE +} diff --git a/examples/scriptableapplication/pythonutils.cpp b/examples/scriptableapplication/pythonutils.cpp new file mode 100644 index 0000000..c5e18f2 --- /dev/null +++ b/examples/scriptableapplication/pythonutils.cpp @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pythonutils.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* from AppLib bindings */ + +#if PY_MAJOR_VERSION >= 3 + extern "C" PyObject *PyInit_AppLib(); +#else + extern "C" void initAppLib(); +#endif + +// This variable stores all Python types exported by this module. +extern PyTypeObject **SbkAppLibTypes; + +// This variable stores all type converters exported by this module. +extern SbkConverter **SbkAppLibTypeConverters; + +namespace PythonUtils { + +static State state = PythonUninitialized; + +static void cleanup() +{ + if (state > PythonUninitialized) { + Py_Finalize(); + state = PythonUninitialized; + } +} + +static const char virtualEnvVar[] = "VIRTUAL_ENV"; + +// If there is an active python virtual environment, use that environment's +// packages location. +static void initVirtualEnvironment() +{ + QByteArray virtualEnvPath = qgetenv(virtualEnvVar); + // As of Python 3.8, Python is no longer able to run stand-alone in a + // virtualenv due to missing libraries. Add the path to the modules instead. + if (QOperatingSystemVersion::currentType() == QOperatingSystemVersion::Windows + && (PY_MAJOR_VERSION > 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 8))) { + qputenv("PYTHONPATH", virtualEnvPath + "\\Lib\\site-packages"); + } else { + qputenv("PYTHONHOME", virtualEnvPath); + } +} + +State init() +{ + if (state > PythonUninitialized) + return state; + + if (qEnvironmentVariableIsSet(virtualEnvVar)) + initVirtualEnvironment(); + + Py_Initialize(); + qAddPostRoutine(cleanup); + state = PythonInitialized; +#if PY_MAJOR_VERSION >= 3 + const bool pythonInitialized = PyInit_AppLib() != nullptr; +#else + const bool pythonInitialized = true; + initAppLib(); +#endif + const bool pyErrorOccurred = PyErr_Occurred() != nullptr; + if (pythonInitialized && !pyErrorOccurred) { + state = AppModuleLoaded; + } else { + if (pyErrorOccurred) + PyErr_Print(); + qWarning("Failed to initialize the module."); + } + return state; +} + +bool bindAppObject(const QString &moduleName, const QString &name, + int index, QObject *o) +{ + if (init() != AppModuleLoaded) + return false; + PyTypeObject *typeObject = SbkAppLibTypes[index]; + + PyObject *po = Shiboken::Conversions::pointerToPython(reinterpret_cast(typeObject), o); + if (!po) { + qWarning() << __FUNCTION__ << "Failed to create wrapper for" << o; + return false; + } + Py_INCREF(po); + + PyObject *module = PyImport_AddModule(moduleName.toLocal8Bit().constData()); + if (!module) { + Py_DECREF(po); + if (PyErr_Occurred()) + PyErr_Print(); + qWarning() << __FUNCTION__ << "Failed to locate module" << moduleName; + return false; + } + + if (PyModule_AddObject(module, name.toLocal8Bit().constData(), po) < 0) { + if (PyErr_Occurred()) + PyErr_Print(); + qWarning() << __FUNCTION__ << "Failed add object" << name << "to" << moduleName; + return false; + } + + return true; +} + +bool runScript(const QStringList &script) +{ + if (init() == PythonUninitialized) + return false; + + // Concatenating all the lines + QString content; + QTextStream ss(&content); + for (const QString &line: script) + ss << line << "\n"; + + // Executing the whole script as one line + bool result = true; + const QByteArray line = content.toUtf8(); + if (PyRun_SimpleString(line.constData()) == -1) { + if (PyErr_Occurred()) + PyErr_Print(); + result = false; + } + + return result; +} + +} // namespace PythonUtils diff --git a/examples/scriptableapplication/pythonutils.h b/examples/scriptableapplication/pythonutils.h new file mode 100644 index 0000000..21aef19 --- /dev/null +++ b/examples/scriptableapplication/pythonutils.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PYTHONUTILS_H +#define PYTHONUTILS_H + +class QObject; +class QString; +class QStringList; + +namespace PythonUtils { + +enum AppLibTypes +{ + MainWindowType = 0 // SBK_MAINWINDOW_IDX +}; + +enum State +{ + PythonUninitialized, + PythonInitialized, + AppModuleLoaded +}; + +State init(); + +bool bindAppObject(const QString &moduleName, const QString &name, + int index, QObject *o); + +bool runScript(const QStringList &script); + +} // namespace PythonUtils + +#endif // PYTHONUTILS_H diff --git a/examples/scriptableapplication/scriptableapplication.pro b/examples/scriptableapplication/scriptableapplication.pro new file mode 100644 index 0000000..8ebab94 --- /dev/null +++ b/examples/scriptableapplication/scriptableapplication.pro @@ -0,0 +1,85 @@ +TEMPLATE = app +CONFIG += no_keywords # avoid clash with slots in Python.h +CONFIG += console force_debug_info +QT += widgets + +include(pyside2.pri) + +WRAPPED_HEADER = wrappedclasses.h +WRAPPER_DIR = $$OUT_PWD/AppLib +TYPESYSTEM_FILE = scriptableapplication.xml + +QT_INCLUDEPATHS = -I"$$[QT_INSTALL_HEADERS]" -I"$$[QT_INSTALL_HEADERS]/QtCore" \ + -I"$$[QT_INSTALL_HEADERS]/QtGui" -I"$$[QT_INSTALL_HEADERS]/QtWidgets" + +# On macOS, check if Qt is a framework build. This affects how include paths should be handled. +qtConfig(framework): QT_INCLUDEPATHS += --framework-include-paths=$$[QT_INSTALL_LIBS] + +SHIBOKEN_OPTIONS = --generator-set=shiboken --enable-parent-ctor-heuristic \ + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero \ + $$QT_INCLUDEPATHS -I$$PWD -T$$PWD -T$$PYSIDE2/typesystems --output-directory=$$OUT_PWD + +# MSVC does not honor #define protected public... +win32:SHIBOKEN_OPTIONS += --avoid-protected-hack + +# Prepare the shiboken tool +QT_TOOL.shiboken.binary = $$system_path($$SHIBOKEN2_GENERATOR/shiboken2) +qtPrepareTool(SHIBOKEN, shiboken) + +# Shiboken run that adds the module wrapper to GENERATED_SOURCES +shiboken.output = $$WRAPPER_DIR/applib_module_wrapper.cpp +shiboken.commands = $$SHIBOKEN $$SHIBOKEN_OPTIONS $$PWD/wrappedclasses.h ${QMAKE_FILE_IN} +shiboken.input = TYPESYSTEM_FILE +shiboken.dependency_type = TYPE_C +shiboken.variable_out = GENERATED_SOURCES + +# A dummy command that pretends to produce the class wrappers from the headers +# depending on the module wrapper +WRAPPED_CLASSES = mainwindow.h +module_wrapper_dummy_command.output = $$WRAPPER_DIR/${QMAKE_FILE_BASE}_wrapper.cpp +module_wrapper_dummy_command.commands = echo ${QMAKE_FILE_IN} +module_wrapper_dummy_command.depends = $$WRAPPER_DIR/applib_module_wrapper.cpp +module_wrapper_dummy_command.input = WRAPPED_CLASSES +module_wrapper_dummy_command.dependency_type = TYPE_C +module_wrapper_dummy_command.variable_out = GENERATED_SOURCES + +# Get the path component to the active config build folder +defineReplace(getOutDir) { + out_dir = $$OUT_PWD + CONFIG(release, debug|release): out_dir = $$out_dir/release + else:out_dir = $$out_dir/debug + return($$out_dir) +} + +# Create hardlinks to the PySide2 shared libraries, so the example can be executed without manually +# setting the PATH. +win32 { + out_dir = $$getOutDir() + # no_link tell not to link to the output files, target_predeps forces the command to actually + # execute, explicit_dependencies is a magic value that tells qmake not to run the commands + # if the output files already exist. + hard_link_libraries.CONFIG = no_link target_predeps explicit_dependencies + hard_link_libraries.output = $$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + hard_link_libraries.commands = mklink /H $$shell_path($$out_dir/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT}) $$shell_path(${QMAKE_FILE_IN}) + hard_link_libraries.input = PYSIDE2_SHARED_LIBRARIES SHIBOKEN2_SHARED_LIBRARIES +} + +QMAKE_EXTRA_COMPILERS += shiboken module_wrapper_dummy_command +win32:QMAKE_EXTRA_COMPILERS += hard_link_libraries + +INCLUDEPATH += $$WRAPPER_DIR + +for(i, PYSIDE2_INCLUDE) { + INCLUDEPATH += $$i/QtWidgets $$i/QtGui $$i/QtCore +} + +SOURCES += \ + main.cpp \ + mainwindow.cpp \ + pythonutils.cpp + +HEADERS += \ + mainwindow.h \ + pythonutils.h + +OTHER_FILES += $$TYPESYSTEM_FILE $$WRAPPED_HEADER pyside2_config.py README.md diff --git a/examples/scriptableapplication/scriptableapplication.xml b/examples/scriptableapplication/scriptableapplication.xml new file mode 100644 index 0000000..7ef2e9f --- /dev/null +++ b/examples/scriptableapplication/scriptableapplication.xml @@ -0,0 +1,56 @@ + + + + + + diff --git a/examples/scriptableapplication/wrappedclasses.h b/examples/scriptableapplication/wrappedclasses.h new file mode 100644 index 0000000..d766142 --- /dev/null +++ b/examples/scriptableapplication/wrappedclasses.h @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WRAPPEDCLASSES_H +#define WRAPPEDCLASSES_H + +#include + +#endif // WRAPPEDCLASSES_H diff --git a/examples/sql/books/bookdelegate.py b/examples/sql/books/bookdelegate.py new file mode 100644 index 0000000..f7e219a --- /dev/null +++ b/examples/sql/books/bookdelegate.py @@ -0,0 +1,133 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import copy +from PySide2.QtSql import QSqlRelationalDelegate +from PySide2.QtWidgets import QSpinBox, QStyle +from PySide2.QtGui import QPixmap, QPalette +from PySide2.QtCore import QEvent, QSize, Qt + + +class BookDelegate(QSqlRelationalDelegate): + """Books delegate to rate the books""" + + def __init__(self, parent=None): + QSqlRelationalDelegate.__init__(self, parent) + self.star = QPixmap(":/images/star.png") + + def paint(self, painter, option, index): + """ Paint the items in the table. + + If the item referred to by is a StarRating, we + handle the painting ourselves. For the other items, we + let the base class handle the painting as usual. + + In a polished application, we'd use a better check than + the column number to find out if we needed to paint the + stars, but it works for the purposes of this example. + """ + if index.column() != 5: + # Since we draw the grid ourselves: + opt = copy.copy(option) + opt.rect = option.rect.adjusted(0, 0, -1, -1) + QSqlRelationalDelegate.paint(self, painter, opt, index) + else: + model = index.model() + if option.state & QStyle.State_Enabled: + if option.state & QStyle.State_Active: + color_group = QPalette.Normal + else: + color_group = QPalette.Inactive + else: + color_group = QPalette.Disabled + + if option.state & QStyle.State_Selected: + painter.fillRect(option.rect, + option.palette.color(color_group, QPalette.Highlight)) + rating = model.data(index, Qt.DisplayRole) + width = self.star.width() + height = self.star.height() + x = option.rect.x() + y = option.rect.y() + (option.rect.height() / 2) - (height / 2) + for i in range(rating): + painter.drawPixmap(x, y, self.star) + x += width + + # Since we draw the grid ourselves: + self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)) + + pen = painter.pen() + painter.setPen(option.palette.color(QPalette.Mid)) + painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight()) + painter.drawLine(option.rect.topRight(), option.rect.bottomRight()) + painter.setPen(pen) + + def sizeHint(self, option, index): + """ Returns the size needed to display the item in a QSize object. """ + if index.column() == 5: + size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1) + return size_hint + # Since we draw the grid ourselves: + return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1) + + def editorEvent(self, event, model, option, index): + if index.column() != 5: + return False + + if event.type() == QEvent.MouseButtonPress: + mouse_pos = event.pos() + new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width()) + stars = max(0, min(new_stars, 5)) + model.setData(index, stars) + # So that the selection can change + return False + + return True + + def createEditor(self, parent, option, index): + if index.column() != 4: + return QSqlRelationalDelegate.createEditor(self, parent, option, index) + + # For editing the year, return a spinbox with a range from -1000 to 2100. + spinbox = QSpinBox(parent) + spinbox.setFrame(False) + spinbox.setMaximum(2100) + spinbox.setMinimum(-1000) + return spinbox diff --git a/examples/sql/books/books.pyproject b/examples/sql/books/books.pyproject new file mode 100644 index 0000000..44a1ef2 --- /dev/null +++ b/examples/sql/books/books.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["main.py", "bookdelegate.py", "bookwindow.py", + "createdb.py", "books.qrc", "bookwindow.ui", + "images/star.png"] +} diff --git a/examples/sql/books/books.qrc b/examples/sql/books/books.qrc new file mode 100644 index 0000000..d6ad213 --- /dev/null +++ b/examples/sql/books/books.qrc @@ -0,0 +1,5 @@ + + + images/star.png + + diff --git a/examples/sql/books/bookwindow.py b/examples/sql/books/bookwindow.py new file mode 100644 index 0000000..31d2a05 --- /dev/null +++ b/examples/sql/books/bookwindow.py @@ -0,0 +1,137 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import + +from PySide2.QtWidgets import (QAbstractItemView, QDataWidgetMapper, + QHeaderView, QMainWindow, QMessageBox) +from PySide2.QtGui import QKeySequence +from PySide2.QtSql import QSqlRelation, QSqlRelationalTableModel, QSqlTableModel +from PySide2.QtCore import Qt, Slot +import createdb +from ui_bookwindow import Ui_BookWindow +from bookdelegate import BookDelegate + + +class BookWindow(QMainWindow, Ui_BookWindow): + """A window to show the books available""" + + def __init__(self): + QMainWindow.__init__(self) + self.setupUi(self) + + #Initialize db + createdb.init_db() + + model = QSqlRelationalTableModel(self.bookTable) + model.setEditStrategy(QSqlTableModel.OnManualSubmit) + model.setTable("books") + + # Remember the indexes of the columns: + author_idx = model.fieldIndex("author") + genre_idx = model.fieldIndex("genre") + + # Set the relations to the other database tables: + model.setRelation(author_idx, QSqlRelation("authors", "id", "name")) + model.setRelation(genre_idx, QSqlRelation("genres", "id", "name")) + + # Set the localized header captions: + model.setHeaderData(author_idx, Qt.Horizontal, self.tr("Author Name")) + model.setHeaderData(genre_idx, Qt.Horizontal, self.tr("Genre")) + model.setHeaderData(model.fieldIndex("title"), Qt.Horizontal, self.tr("Title")) + model.setHeaderData(model.fieldIndex("year"), Qt.Horizontal, self.tr("Year")) + model.setHeaderData(model.fieldIndex("rating"), Qt.Horizontal, self.tr("Rating")) + + if not model.select(): + print(model.lastError()) + + # Set the model and hide the ID column: + self.bookTable.setModel(model) + self.bookTable.setItemDelegate(BookDelegate(self.bookTable)) + self.bookTable.setColumnHidden(model.fieldIndex("id"), True) + self.bookTable.setSelectionMode(QAbstractItemView.SingleSelection) + + # Initialize the Author combo box: + self.authorEdit.setModel(model.relationModel(author_idx)) + self.authorEdit.setModelColumn(model.relationModel(author_idx).fieldIndex("name")) + + self.genreEdit.setModel(model.relationModel(genre_idx)) + self.genreEdit.setModelColumn(model.relationModel(genre_idx).fieldIndex("name")) + + # Lock and prohibit resizing of the width of the rating column: + self.bookTable.horizontalHeader().setSectionResizeMode(model.fieldIndex("rating"), + QHeaderView.ResizeToContents) + + mapper = QDataWidgetMapper(self) + mapper.setModel(model) + mapper.setItemDelegate(BookDelegate(self)) + mapper.addMapping(self.titleEdit, model.fieldIndex("title")) + mapper.addMapping(self.yearEdit, model.fieldIndex("year")) + mapper.addMapping(self.authorEdit, author_idx) + mapper.addMapping(self.genreEdit, genre_idx) + mapper.addMapping(self.ratingEdit, model.fieldIndex("rating")) + + selection_model = self.bookTable.selectionModel() + selection_model.currentRowChanged.connect(mapper.setCurrentModelIndex) + + self.bookTable.setCurrentIndex(model.index(0, 0)) + self.create_menubar() + + def showError(err): + QMessageBox.critical(self, "Unable to initialize Database", + "Error initializing database: " + err.text()) + + def create_menubar(self): + file_menu = self.menuBar().addMenu(self.tr("&File")) + quit_action = file_menu.addAction(self.tr("&Quit")) + quit_action.triggered.connect(qApp.quit) + + help_menu = self.menuBar().addMenu(self.tr("&Help")) + about_action = help_menu.addAction(self.tr("&About")) + about_action.setShortcut(QKeySequence.HelpContents) + about_action.triggered.connect(self.about) + aboutQt_action = help_menu.addAction("&About Qt") + aboutQt_action.triggered.connect(qApp.aboutQt) + + @Slot() + def about(self): + QMessageBox.about(self, self.tr("About Books"), + self.tr("

The Books example shows how to use Qt SQL classes " + "with a model/view framework.")) diff --git a/examples/sql/books/bookwindow.ui b/examples/sql/books/bookwindow.ui new file mode 100644 index 0000000..ce8f9f9 --- /dev/null +++ b/examples/sql/books/bookwindow.ui @@ -0,0 +1,164 @@ + + + BookWindow + + + + 0 + 0 + 601 + 420 + + + + Books + + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + + + + + 6 + + + 9 + + + 9 + + + 9 + + + 9 + + + + + QAbstractItemView::SelectRows + + + + + + + Details + + + + + + <b>Title:</b> + + + + + + + true + + + + + + + <b>Author: </b> + + + + + + + true + + + + + + + <b>Genre:</b> + + + + + + + true + + + + + + + <b>Year:</b> + + + + + + + true + + + + + + -1000 + + + 2100 + + + + + + + <b>Rating:</b> + + + + + + + 5 + + + + + + + + + + + + + + bookTable + titleEdit + authorEdit + genreEdit + yearEdit + + + + diff --git a/examples/sql/books/createdb.py b/examples/sql/books/createdb.py new file mode 100644 index 0000000..f8739b4 --- /dev/null +++ b/examples/sql/books/createdb.py @@ -0,0 +1,130 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtSql import QSqlDatabase, QSqlQuery +from datetime import date + +def add_book(q, title, year, authorId, genreId, rating): + q.addBindValue(title) + q.addBindValue(year) + q.addBindValue(authorId) + q.addBindValue(genreId) + q.addBindValue(rating) + q.exec_() + + +def add_genre(q, name): + q.addBindValue(name) + q.exec_() + return q.lastInsertId() + + +def add_author(q, name, birthdate): + q.addBindValue(name) + q.addBindValue(str(birthdate)) + q.exec_() + return q.lastInsertId() + +BOOKS_SQL = """ + create table books(id integer primary key, title varchar, author integer, + genre integer, year integer, rating integer) + """ +AUTHORS_SQL = """ + create table authors(id integer primary key, name varchar, birthdate text) + """ +GENRES_SQL = """ + create table genres(id integer primary key, name varchar) + """ +INSERT_AUTHOR_SQL = """ + insert into authors(name, birthdate) values(?, ?) + """ +INSERT_GENRE_SQL = """ + insert into genres(name) values(?) + """ +INSERT_BOOK_SQL = """ + insert into books(title, year, author, genre, rating) + values(?, ?, ?, ?, ?) + """ + +def init_db(): + """ + init_db() + Initializes the database. + If tables "books" and "authors" are already in the database, do nothing. + Return value: None or raises ValueError + The error value is the QtSql error instance. + """ + def check(func, *args): + if not func(*args): + raise ValueError(func.__self__.lastError()) + db = QSqlDatabase.addDatabase("QSQLITE") + db.setDatabaseName(":memory:") + + check(db.open) + + q = QSqlQuery() + check(q.exec_, BOOKS_SQL) + check(q.exec_, AUTHORS_SQL) + check(q.exec_, GENRES_SQL) + check(q.prepare, INSERT_AUTHOR_SQL) + + asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1)) + greeneId = add_author(q, "Graham Greene", date(1904, 10, 2)) + pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28)) + + check(q.prepare,INSERT_GENRE_SQL) + sfiction = add_genre(q, "Science Fiction") + fiction = add_genre(q, "Fiction") + fantasy = add_genre(q, "Fantasy") + + check(q.prepare,INSERT_BOOK_SQL) + add_book(q, "Foundation", 1951, asimovId, sfiction, 3) + add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4) + add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3) + add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3) + add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4) + add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3) + add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3) + add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4) + add_book(q, "The Third Man", 1950, greeneId, fiction, 5) + add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4) + add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3) + add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3) + add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3) diff --git a/examples/sql/books/images/star.png b/examples/sql/books/images/star.png new file mode 100644 index 0000000000000000000000000000000000000000..87f4464bd5ea7af0c0ff30aad5464569a5df1b31 GIT binary patch literal 782 zcmV+p1M&QcP)Gk7=GnC00006VoOIv0RI600RN!9r;`8x0-H%h zK~y-)W0*Q)9wR#D{PkJQ|JUdI z{@>o9^?yZ_>`xXJR_kdq=c5MV6N#Z+5elIEd5SEKu8pu z0ZdRV2E-Xad?Gu_@aO6I2LFNV13S0I?nr7X$Ip zs6gGHtqDpX1O5Q'33\x8b\xa5\x9e8gi\xb8\x9e\xc0f\ +&&\xa6D\x14\x03&N\x9d\xc7x\xef\xdeD\x96'\ +\x0f[E\x9f>j\xd6\xbdu\xb3\x22\xef\xd7\xb7=\xff\ +\xbe\x7f\xe8\xfb\x7f~S\xcc\xef\x05\xc5\xea\x9fNOQ\ +\xfb\x7f\xbaM\xed\xbf\x87\x1a\xefn5-\x1dV\x14\x03\ +f\xcf[\xce\xa8\xa4\xa9![W\xed\x9b}\xefJ\xcb\ +\xcew\xaf&\x7f\xfa\xfee\xc9\xff\xef\x1f\xfa\xff\xbf\xbf\ +\x95\xf2\xff\xc9^\x83\xffW\x17\xaa\xfdot\x12{\xc4\ +\xc7\xc7/\x8e\x12\x06Y\xb9\x85\xcc\xb2\x82\x1c\xf3\xa7D\ +\xab\xfe\xfa\xbe%\xe2\xff\x8fgm\xff\x7f|\x9a\x08\xd6\ +\xfc\xf5Y\xcd\xff\xd7\xe7\xfc\xfe\xdf\xde\xa0\xf5\x7fE\x94\ +\xecO\x16\x16V\xebi3\xe7\xa3\x06\xe2\xe4is\x18\ +\xe7/Z\xc1\xc8\xce\xc1i\x10\xe5\xa8\xd2\xbe\xa6\xcd\xe7\ +\xf6\xc3m\x99\xff~^(\xf8\xff\xe1j\xe0\xff\x17G\ +L\xff\xdf\xdf\xae\xf6\xbf\xc2]\xf4\xba\x9a\x9a\x06\x1bF\ +,\x00\x01#2\xe6\xe6\xe6`Q\xd6\x941_\xde\xe4\ +q\xfb\xc3y\xd3\xff\x1b\x8aT\xff\xbf?`\xff\xff\xdc\ +l\xe5\xff\xea\xc2\x1c9\xd3g-\xc0i\x00\x13\x10\x8b\ +\x03\xb1?\x10\xe7\xf5\x16\xd8\xde\xf8p\xc6\xe4\xbf\x9d<\ +\xf7t\x7fC\xe9\x95\xb7\x96\xd9\xff\x9b\x9c,\xfdN@\ +@H\x14\x9b\x01LP,\x06\xc4\x19@|\x22;\xca\ +\xf0\xe7\xe9\xf9\x06\xff\x81\xec\x03@\xbc^\x82\x9f\xf3\xf6\ +\x9e\x1a\xf3_az\x823P\xd2\x01T#3\x10\x0b\ +\x00\xb1\x1e\x10\x17\x03\xf1\xd1\xa8@\xdd\x9f\xad\x09J \ +\x03\xfe\x00\xf17 >\x0f\xb4kf\xb9\xa7\xea\x0d}\ +i>#d\x03\xb4\x808\x08\x88k\x81x\x09\xd4\xc6\ +\x1b\x11a\x06\xdf\xec\x94\xb8\xdf\x03\xd9;\x81x\x1a\x10\ +\xf7\x82\xd4\xb0\xb2\xb1G\xf9\xda\x99:L\x9d9\x9f\x09\ +f\x80\x0e\x10;\x02\xb1\x13\x10[\x00\xb1\x01\x10\x07\x06\ +{h\x9c\x02\xd2k\xa0\x86\x8b\x001\x17\x10\xf3\x80\xb0\ +\x88\x88(\xcb,hFC\xf6\x02\x08\xb3\x001+\x10\ +K122\xe4\x01i7 \x96\x01b6\xa88\x0b\ +T=cW\xef$\xb0\x01\x00\xceo{\xf5UL\xf0\ +\xac\x00\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x08\ +\x0a\x85X\x07\ +\x00s\ +\x00t\x00a\x00r\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01j\x965\xd3\xea\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/sql/books/ui_bookwindow.py b/examples/sql/books/ui_bookwindow.py new file mode 100644 index 0000000..dc53274 --- /dev/null +++ b/examples/sql/books/ui_bookwindow.py @@ -0,0 +1,129 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'bookwindow.ui' +## +## Created by: Qt User Interface Compiler version 5.14.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint, + QRect, QSize, QUrl, Qt) +from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QFont, + QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap, + QRadialGradient) +from PySide2.QtWidgets import * + +class Ui_BookWindow(object): + def setupUi(self, BookWindow): + if BookWindow.objectName(): + BookWindow.setObjectName(u"BookWindow") + BookWindow.resize(601, 420) + self.centralWidget = QWidget(BookWindow) + self.centralWidget.setObjectName(u"centralWidget") + self.vboxLayout = QVBoxLayout(self.centralWidget) + self.vboxLayout.setSpacing(6) + self.vboxLayout.setObjectName(u"vboxLayout") + self.vboxLayout.setContentsMargins(9, 9, 9, 9) + self.groupBox = QGroupBox(self.centralWidget) + self.groupBox.setObjectName(u"groupBox") + self.vboxLayout1 = QVBoxLayout(self.groupBox) + self.vboxLayout1.setSpacing(6) + self.vboxLayout1.setObjectName(u"vboxLayout1") + self.vboxLayout1.setContentsMargins(9, 9, 9, 9) + self.bookTable = QTableView(self.groupBox) + self.bookTable.setObjectName(u"bookTable") + self.bookTable.setSelectionBehavior(QAbstractItemView.SelectRows) + + self.vboxLayout1.addWidget(self.bookTable) + + self.groupBox_2 = QGroupBox(self.groupBox) + self.groupBox_2.setObjectName(u"groupBox_2") + self.formLayout = QFormLayout(self.groupBox_2) + self.formLayout.setObjectName(u"formLayout") + self.label_5 = QLabel(self.groupBox_2) + self.label_5.setObjectName(u"label_5") + + self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label_5) + + self.titleEdit = QLineEdit(self.groupBox_2) + self.titleEdit.setObjectName(u"titleEdit") + self.titleEdit.setEnabled(True) + + self.formLayout.setWidget(0, QFormLayout.FieldRole, self.titleEdit) + + self.label_2 = QLabel(self.groupBox_2) + self.label_2.setObjectName(u"label_2") + + self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2) + + self.authorEdit = QComboBox(self.groupBox_2) + self.authorEdit.setObjectName(u"authorEdit") + self.authorEdit.setEnabled(True) + + self.formLayout.setWidget(1, QFormLayout.FieldRole, self.authorEdit) + + self.label_3 = QLabel(self.groupBox_2) + self.label_3.setObjectName(u"label_3") + + self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3) + + self.genreEdit = QComboBox(self.groupBox_2) + self.genreEdit.setObjectName(u"genreEdit") + self.genreEdit.setEnabled(True) + + self.formLayout.setWidget(2, QFormLayout.FieldRole, self.genreEdit) + + self.label_4 = QLabel(self.groupBox_2) + self.label_4.setObjectName(u"label_4") + + self.formLayout.setWidget(3, QFormLayout.LabelRole, self.label_4) + + self.yearEdit = QSpinBox(self.groupBox_2) + self.yearEdit.setObjectName(u"yearEdit") + self.yearEdit.setEnabled(True) + self.yearEdit.setMinimum(-1000) + self.yearEdit.setMaximum(2100) + + self.formLayout.setWidget(3, QFormLayout.FieldRole, self.yearEdit) + + self.label = QLabel(self.groupBox_2) + self.label.setObjectName(u"label") + + self.formLayout.setWidget(4, QFormLayout.LabelRole, self.label) + + self.ratingEdit = QSpinBox(self.groupBox_2) + self.ratingEdit.setObjectName(u"ratingEdit") + self.ratingEdit.setMaximum(5) + + self.formLayout.setWidget(4, QFormLayout.FieldRole, self.ratingEdit) + + + self.vboxLayout1.addWidget(self.groupBox_2) + + + self.vboxLayout.addWidget(self.groupBox) + + BookWindow.setCentralWidget(self.centralWidget) + QWidget.setTabOrder(self.bookTable, self.titleEdit) + QWidget.setTabOrder(self.titleEdit, self.authorEdit) + QWidget.setTabOrder(self.authorEdit, self.genreEdit) + QWidget.setTabOrder(self.genreEdit, self.yearEdit) + + self.retranslateUi(BookWindow) + + QMetaObject.connectSlotsByName(BookWindow) + # setupUi + + def retranslateUi(self, BookWindow): + BookWindow.setWindowTitle(QCoreApplication.translate("BookWindow", u"Books", None)) + self.groupBox.setTitle("") + self.groupBox_2.setTitle(QCoreApplication.translate("BookWindow", u"Details", None)) + self.label_5.setText(QCoreApplication.translate("BookWindow", u"Title:", None)) + self.label_2.setText(QCoreApplication.translate("BookWindow", u"Author: ", None)) + self.label_3.setText(QCoreApplication.translate("BookWindow", u"Genre:", None)) + self.label_4.setText(QCoreApplication.translate("BookWindow", u"Year:", None)) + self.yearEdit.setPrefix("") + self.label.setText(QCoreApplication.translate("BookWindow", u"Rating:", None)) + # retranslateUi diff --git a/examples/texttospeech/texttospeech.py b/examples/texttospeech/texttospeech.py new file mode 100644 index 0000000..f9c32ed --- /dev/null +++ b/examples/texttospeech/texttospeech.py @@ -0,0 +1,107 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 QTextToSpeech example""" + +import sys +from PySide2.QtCore import Qt +from PySide2.QtWidgets import (QApplication, QComboBox, QFormLayout, + QHBoxLayout, QLineEdit, QMainWindow, QPushButton, QSlider, QWidget) + +from PySide2.QtTextToSpeech import QTextToSpeech + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + centralWidget = QWidget() + self.setCentralWidget(centralWidget) + layout = QFormLayout(centralWidget) + + textLayout = QHBoxLayout() + self.text = QLineEdit('Hello, PySide2') + self.text.setClearButtonEnabled(True) + textLayout.addWidget(self.text) + self.sayButton = QPushButton('Say') + textLayout.addWidget(self.sayButton) + self.text.returnPressed.connect(self.sayButton.animateClick) + self.sayButton.clicked.connect(self.say) + layout.addRow('Text:', textLayout) + + self.voiceCombo = QComboBox() + layout.addRow('Voice:', self.voiceCombo) + + self.volumeSlider = QSlider(Qt.Horizontal) + self.volumeSlider.setMinimum(0) + self.volumeSlider.setMaximum(100) + self.volumeSlider.setValue(100) + layout.addRow('Volume:', self.volumeSlider) + + self.engine = None + engineNames = QTextToSpeech.availableEngines() + if len(engineNames) > 0: + engineName = engineNames[0] + self.engine = QTextToSpeech(engineName) + self.engine.stateChanged.connect(self.stateChanged) + self.setWindowTitle('QTextToSpeech Example ({})'.format(engineName)) + self.voices = [] + for voice in self.engine.availableVoices(): + self.voices.append(voice) + self.voiceCombo.addItem(voice.name()) + else: + self.setWindowTitle('QTextToSpeech Example (no engines available)') + self.sayButton.setEnabled(False) + + def say(self): + self.sayButton.setEnabled(False) + self.engine.setVoice(self.voices[self.voiceCombo.currentIndex()]) + self.engine.setVolume(float(self.volumeSlider.value()) / 100) + self.engine.say(self.text.text()) + + def stateChanged(self, state): + if (state == QTextToSpeech.State.Ready): + self.sayButton.setEnabled(True) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/texttospeech/texttospeech.pyproject b/examples/texttospeech/texttospeech.pyproject new file mode 100644 index 0000000..69fc13f --- /dev/null +++ b/examples/texttospeech/texttospeech.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["texttospeech.py"] +} diff --git a/examples/tutorial/t1.py b/examples/tutorial/t1.py new file mode 100644 index 0000000..635fbbd --- /dev/null +++ b/examples/tutorial/t1.py @@ -0,0 +1,56 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 1 + + +import sys +from PySide2 import QtWidgets + + +app = QtWidgets.QApplication(sys.argv) + +hello = QtWidgets.QPushButton("Hello world!") +hello.resize(100, 30) + +hello.show() + +sys.exit(app.exec_()) diff --git a/examples/tutorial/t10.py b/examples/tutorial/t10.py new file mode 100644 index 0000000..12847a0 --- /dev/null +++ b/examples/tutorial/t10.py @@ -0,0 +1,191 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 10 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + forceChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.currentForce = 0 + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def force(self): + return self.currentForce + + @QtCore.Slot(int) + def setForce(self, force): + if force < 0: + force = 0 + if self.currentForce == force: + return + self.currentForce = force + self.emit(QtCore.SIGNAL("forceChanged(int)"), self.currentForce) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.translate(0, self.height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(QtCore.QRect(33, -4, 15, 8)) + + def cannonRect(self): + result = QtCore.QRect(0, 0, 50, 50) + result.moveBottomLeft(self.rect().bottomLect()) + return result + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("&Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange() + angle.setRange(5, 70) + + force = LCDRange() + force.setRange(10, 50) + + cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setAngle) + self.connect(cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + self.connect(force, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setForce) + self.connect(cannonField, QtCore.SIGNAL("forceChanged(int)"), + force.setValue) + + leftLayout = QtWidgets.QVBoxLayout() + leftLayout.addWidget(angle) + leftLayout.addWidget(force) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addLayout(leftLayout, 1, 0) + gridLayout.addWidget(cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + force.setValue(25) + angle.setFocus() + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.setGeometry(100, 100, 500, 355) +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t11.py b/examples/tutorial/t11.py new file mode 100644 index 0000000..cc39120 --- /dev/null +++ b/examples/tutorial/t11.py @@ -0,0 +1,263 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 11 + + +import sys +import math +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + forceChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.currentForce = 0 + self.timerCount = 0 + self.autoShootTimer = QtCore.QTimer(self) + self.connect(self.autoShootTimer, QtCore.SIGNAL("timeout()"), + self.moveShot) + self.shootAngle = 0 + self.shootForce = 0 + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def force(self): + return self.currentForce + + @QtCore.Slot(int) + def setForce(self, force): + if force < 0: + force = 0 + if self.currentForce == force: + return + self.currentForce = force + self.emit(QtCore.SIGNAL("forceChanged(int)"), self.currentForce) + + @QtCore.Slot() + def shoot(self): + if self.autoShootTimer.isActive(): + return + self.timerCount = 0 + self.shootAngle = self.currentAngle + self.shootForce = self.currentForce + self.autoShootTimer.start(5) + + @QtCore.Slot() + def moveShot(self): + region = QtGui.QRegion(self.shotRect()) + self.timerCount += 1 + + shotR = self.shotRect() + + if shotR.x() > self.width() or shotR.y() > self.height(): + self.autoShootTimer.stop() + else: + region = region.united(QtGui.QRegion(shotR)) + + self.update(region) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + self.paintCannon(painter) + if self.autoShootTimer.isActive(): + self.paintShot(painter) + + def paintShot(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.black) + painter.drawRect(self.shotRect()) + + barrelRect = QtCore.QRect(33, -4, 15, 8) + + def paintCannon(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.save() + painter.translate(0, self.height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(CannonField.barrelRect) + painter.restore() + + def cannonRect(self): + result = QtCore.QRect(0, 0, 50, 50) + result.moveBottomLeft(self.rect().bottomLect()) + return result + + def shotRect(self): + gravity = 4.0 + + time = self.timerCount / 40.0 + velocity = self.shootForce + radians = self.shootAngle * 3.14159265 / 180 + + velx = velocity * math.cos(radians) + vely = velocity * math.sin(radians) + x0 = (CannonField.barrelRect.right() + 5) * math.cos(radians) + y0 = (CannonField.barrelRect.right() + 5) * math.sin(radians) + x = x0 + velx * time + y = y0 + vely * time - 0.5 * gravity * time * time + + result = QtCore.QRect(0, 0, 6, 6) + result.moveCenter(QtCore.QPoint(round(x), self.height() - 1 - round(y))) + return result + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("&Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange() + angle.setRange(5, 70) + + force = LCDRange() + force.setRange(10, 50) + + cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setAngle) + self.connect(cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + self.connect(force, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setForce) + self.connect(cannonField, QtCore.SIGNAL("forceChanged(int)"), + force.setValue) + + shoot = QtWidgets.QPushButton("&Shoot") + shoot.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(shoot, QtCore.SIGNAL("clicked()"), cannonField.shoot) + + topLayout = QtWidgets.QHBoxLayout() + topLayout.addWidget(shoot) + topLayout.addStretch(1) + + leftLayout = QtWidgets.QVBoxLayout() + leftLayout.addWidget(angle) + leftLayout.addWidget(force) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addLayout(topLayout, 0, 1) + gridLayout.addLayout(leftLayout, 1, 0) + gridLayout.addWidget(cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + force.setValue(25) + angle.setFocus() + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.setGeometry(100, 100, 500, 355) +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t12.py b/examples/tutorial/t12.py new file mode 100644 index 0000000..4094529 --- /dev/null +++ b/examples/tutorial/t12.py @@ -0,0 +1,312 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 12 + + +import sys +import math +import random +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, text=None, parent=None): + if isinstance(text, QtWidgets.QWidget): + parent = text + text = None + + QtWidgets.QWidget.__init__(self, parent) + + self.init() + + if text: + self.setText(text) + + def init(self): + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + self.label = QtWidgets.QLabel() + self.label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + layout.addWidget(self.label) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def text(self): + return self.label.text() + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + def setText(self, text): + self.label.setText(text) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + forceChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.currentForce = 0 + self.timerCount = 0 + self.autoShootTimer = QtCore.QTimer(self) + self.connect(self.autoShootTimer, QtCore.SIGNAL("timeout()"), + self.moveShot) + self.shootAngle = 0 + self.shootForce = 0 + self.target = QtCore.QPoint(0, 0) + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + self.newTarget() + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def force(self): + return self.currentForce + + @QtCore.Slot(int) + def setForce(self, force): + if force < 0: + force = 0 + if self.currentForce == force: + return + self.currentForce = force + self.emit(QtCore.SIGNAL("forceChanged(int)"), self.currentForce) + + @QtCore.Slot() + def shoot(self): + if self.autoShootTimer.isActive(): + return + self.timerCount = 0 + self.shootAngle = self.currentAngle + self.shootForce = self.currentForce + self.autoShootTimer.start(5) + + firstTime = True + + def newTarget(self): + if CannonField.firstTime: + CannonField.firstTime = False + midnight = QtCore.QTime(0, 0, 0) + random.seed(midnight.secsTo(QtCore.QTime.currentTime())) + + self.target = QtCore.QPoint(200 + random.randint(0, 190 - 1), 10 + random.randint(0, 255 - 1)) + self.update() + + @QtCore.Slot() + def moveShot(self): + region = QtGui.QRegion(self.shotRect()) + self.timerCount += 1 + + shotR = self.shotRect() + + if shotR.intersects(self.targetRect()): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("hit()")) + elif shotR.x() > self.width() or shotR.y() > self.height(): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("missed()")) + else: + region = region.united(QtGui.QRegion(shotR)) + + self.update(region) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + self.paintCannon(painter) + if self.autoShootTimer.isActive(): + self.paintShot(painter) + + self.paintTarget(painter) + + def paintShot(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.black) + painter.drawRect(self.shotRect()) + + def paintTarget(self, painter): + painter.setPen(QtCore.Qt.black) + painter.setBrush(QtCore.Qt.red) + painter.drawRect(self.targetRect()) + + barrelRect = QtCore.QRect(33, -4, 15, 8) + + def paintCannon(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.save() + painter.translate(0, self.height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(CannonField.barrelRect) + painter.restore() + + def cannonRect(self): + result = QtCore.QRect(0, 0, 50, 50) + result.moveBottomLeft(self.rect().bottomLect()) + return result + + def shotRect(self): + gravity = 4.0 + + time = self.timerCount / 40.0 + velocity = self.shootForce + radians = self.shootAngle * 3.14159265 / 180 + + velx = velocity * math.cos(radians) + vely = velocity * math.sin(radians) + x0 = (CannonField.barrelRect.right() + 5) * math.cos(radians) + y0 = (CannonField.barrelRect.right() + 5) * math.sin(radians) + x = x0 + velx * time + y = y0 + vely * time - 0.5 * gravity * time * time + + result = QtCore.QRect(0, 0, 6, 6) + result.moveCenter(QtCore.QPoint(round(x), self.height() - 1 - round(y))) + return result + + def targetRect(self): + result = QtCore.QRect(0, 0, 20, 10) + result.moveCenter(QtCore.QPoint(self.target.x(), self.height() - 1 - self.target.y())) + return result + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("&Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange("ANGLE") + angle.setRange(5, 70) + + force = LCDRange("FORCE") + force.setRange(10, 50) + + cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setAngle) + self.connect(cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + self.connect(force, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setForce) + self.connect(cannonField, QtCore.SIGNAL("forceChanged(int)"), + force.setValue) + + shoot = QtWidgets.QPushButton("&Shoot") + shoot.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(shoot, QtCore.SIGNAL("clicked()"), cannonField.shoot) + + topLayout = QtWidgets.QHBoxLayout() + topLayout.addWidget(shoot) + topLayout.addStretch(1) + + leftLayout = QtWidgets.QVBoxLayout() + leftLayout.addWidget(angle) + leftLayout.addWidget(force) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addLayout(topLayout, 0, 1) + gridLayout.addLayout(leftLayout, 1, 0) + gridLayout.addWidget(cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + force.setValue(25) + angle.setFocus() + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.setGeometry(100, 100, 500, 355) +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t13.py b/examples/tutorial/t13.py new file mode 100644 index 0000000..5198bb4 --- /dev/null +++ b/examples/tutorial/t13.py @@ -0,0 +1,395 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 13 + + +import sys +import math +import random +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, text=None, parent=None): + if isinstance(text, QtWidgets.QWidget): + parent = text + text = None + + QtWidgets.QWidget.__init__(self, parent) + + self.init() + + if text: + self.setText(text) + + def init(self): + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + self.label = QtWidgets.QLabel() + self.label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + self.label.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + layout.addWidget(self.label) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def text(self): + return self.label.text() + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + def setText(self, text): + self.label.setText(text) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + forceChanged = QtCore.Signal(int) + hit = QtCore.Signal() + missed = QtCore.Signal() + canShoot = QtCore.Signal(bool) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.currentForce = 0 + self.timerCount = 0 + self.autoShootTimer = QtCore.QTimer(self) + self.connect(self.autoShootTimer, QtCore.SIGNAL("timeout()"), + self.moveShot) + self.shootAngle = 0 + self.shootForce = 0 + self.target = QtCore.QPoint(0, 0) + self.gameEnded = False + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + self.newTarget() + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def force(self): + return self.currentForce + + @QtCore.Slot(int) + def setForce(self, force): + if force < 0: + force = 0 + if self.currentForce == force: + return + self.currentForce = force + self.emit(QtCore.SIGNAL("forceChanged(int)"), self.currentForce) + + @QtCore.Slot() + def shoot(self): + if self.isShooting(): + return + self.timerCount = 0 + self.shootAngle = self.currentAngle + self.shootForce = self.currentForce + self.autoShootTimer.start(5) + self.emit(QtCore.SIGNAL("canShoot(bool)"), False) + + firstTime = True + + def newTarget(self): + if CannonField.firstTime: + CannonField.firstTime = False + midnight = QtCore.QTime(0, 0, 0) + random.seed(midnight.secsTo(QtCore.QTime.currentTime())) + + self.target = QtCore.QPoint(200 + random.randint(0, 190 - 1), 10 + random.randint(0, 255 - 1)) + self.update() + + def setGameOver(self): + if self.gameEnded: + return + if self.isShooting(): + self.autoShootTimer.stop() + self.gameEnded = True + self.update() + + def restartGame(self): + if self.isShooting(): + self.autoShootTimer.stop() + self.gameEnded = False + self.update() + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + + @QtCore.Slot() + def moveShot(self): + region = QtGui.QRegion(self.shotRect()) + self.timerCount += 1 + + shotR = self.shotRect() + + if shotR.intersects(self.targetRect()): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("hit()")) + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + elif shotR.x() > self.width() or shotR.y() > self.height(): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("missed()")) + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + else: + region = region.united(QtGui.QRegion(shotR)) + + self.update(region) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + if self.gameEnded: + painter.setPen(QtCore.Qt.black) + painter.setFont(QtGui.QFont("Courier", 48, QtGui.QFont.Bold)) + painter.drawText(self.rect(), QtCore.Qt.AlignCenter, "Game Over") + + self.paintCannon(painter) + if self.isShooting(): + self.paintShot(painter) + if not self.gameEnded: + self.paintTarget(painter) + + def paintShot(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.black) + painter.drawRect(self.shotRect()) + + def paintTarget(self, painter): + painter.setPen(QtCore.Qt.black) + painter.setBrush(QtCore.Qt.red) + painter.drawRect(self.targetRect()) + + barrelRect = QtCore.QRect(33, -4, 15, 8) + + def paintCannon(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.save() + painter.translate(0, self.height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(CannonField.barrelRect) + painter.restore() + + def cannonRect(self): + result = QtCore.QRect(0, 0, 50, 50) + result.moveBottomLeft(self.rect().bottomLect()) + return result + + def shotRect(self): + gravity = 4.0 + + time = self.timerCount / 40.0 + velocity = self.shootForce + radians = self.shootAngle * 3.14159265 / 180 + + velx = velocity * math.cos(radians) + vely = velocity * math.sin(radians) + x0 = (CannonField.barrelRect.right() + 5) * math.cos(radians) + y0 = (CannonField.barrelRect.right() + 5) * math.sin(radians) + x = x0 + velx * time + y = y0 + vely * time - 0.5 * gravity * time * time + + result = QtCore.QRect(0, 0, 6, 6) + result.moveCenter(QtCore.QPoint(round(x), self.height() - 1 - round(y))) + return result + + def targetRect(self): + result = QtCore.QRect(0, 0, 20, 10) + result.moveCenter(QtCore.QPoint(self.target.x(), self.height() - 1 - self.target.y())) + return result + + def gameOver(self): + return self.gameEnded + + def isShooting(self): + return self.autoShootTimer.isActive() + + +class GameBoard(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("&Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange("ANGLE") + angle.setRange(5, 70) + + force = LCDRange("FORCE") + force.setRange(10, 50) + + self.cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + self.cannonField.setAngle) + self.connect(self.cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + self.connect(force, QtCore.SIGNAL("valueChanged(int)"), + self.cannonField.setForce) + self.connect(self.cannonField, QtCore.SIGNAL("forceChanged(int)"), + force.setValue) + + self.connect(self.cannonField, QtCore.SIGNAL("hit()"), self.hit) + self.connect(self.cannonField, QtCore.SIGNAL("missed()"), self.missed) + + shoot = QtWidgets.QPushButton("&Shoot") + shoot.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(shoot, QtCore.SIGNAL("clicked()"), self.fire) + self.connect(self.cannonField, QtCore.SIGNAL("canShoot(bool)"), + shoot, QtCore.SLOT("setEnabled(bool)")) + + restart = QtWidgets.QPushButton("&New Game") + restart.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(restart, QtCore.SIGNAL("clicked()"), self.newGame) + + self.hits = QtWidgets.QLCDNumber(2) + self.shotsLeft = QtWidgets.QLCDNumber(2) + hitsLabel = QtWidgets.QLabel("HITS") + shotsLeftLabel = QtWidgets.QLabel("SHOTS LEFT") + + topLayout = QtWidgets.QHBoxLayout() + topLayout.addWidget(shoot) + topLayout.addWidget(self.hits) + topLayout.addWidget(hitsLabel) + topLayout.addWidget(self.shotsLeft) + topLayout.addWidget(shotsLeftLabel) + topLayout.addStretch(1) + topLayout.addWidget(restart) + + leftLayout = QtWidgets.QVBoxLayout() + leftLayout.addWidget(angle) + leftLayout.addWidget(force) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addLayout(topLayout, 0, 1) + gridLayout.addLayout(leftLayout, 1, 0) + gridLayout.addWidget(self.cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + force.setValue(25) + angle.setFocus() + + self.newGame() + + @QtCore.Slot() + def fire(self): + if self.cannonField.gameOver() or self.cannonField.isShooting(): + return + self.shotsLeft.display(self.shotsLeft.intValue() - 1) + self.cannonField.shoot() + + @QtCore.Slot() + def hit(self): + self.hits.display(self.hits.intValue() + 1) + if self.shotsLeft.intValue() == 0: + self.cannonField.setGameOver() + else: + self.cannonField.newTarget() + + @QtCore.Slot() + def missed(self): + if self.shotsLeft.intValue() == 0: + self.cannonField.setGameOver() + + @QtCore.Slot() + def newGame(self): + self.shotsLeft.display(15) + self.hits.display(0) + self.cannonField.restartGame() + self.cannonField.newTarget() + + +app = QtWidgets.QApplication(sys.argv) +board = GameBoard() +board.setGeometry(100, 100, 500, 355) +board.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t14.py b/examples/tutorial/t14.py new file mode 100644 index 0000000..2d5e1a1 --- /dev/null +++ b/examples/tutorial/t14.py @@ -0,0 +1,450 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 14 + + +import sys +import math +import random +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, text=None, parent=None): + if isinstance(text, QtWidgets.QWidget): + parent = text + text = None + + QtWidgets.QWidget.__init__(self, parent) + + self.init() + + if text: + self.setText(text) + + def init(self): + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + self.label = QtWidgets.QLabel() + self.label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) + self.label.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + layout.addWidget(self.label) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def text(self): + return self.label.text() + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + def setText(self, text): + self.label.setText(text) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + forceChanged = QtCore.Signal(int) + hit = QtCore.Signal() + missed = QtCore.Signal() + canShoot = QtCore.Signal(bool) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.currentForce = 0 + self.timerCount = 0 + self.autoShootTimer = QtCore.QTimer(self) + self.connect(self.autoShootTimer, QtCore.SIGNAL("timeout()"), + self.moveShot) + self.shootAngle = 0 + self.shootForce = 0 + self.target = QtCore.QPoint(0, 0) + self.gameEnded = False + self.barrelPressed = False + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + self.newTarget() + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def force(self): + return self.currentForce + + @QtCore.Slot(int) + def setForce(self, force): + if force < 0: + force = 0 + if self.currentForce == force: + return + self.currentForce = force + self.emit(QtCore.SIGNAL("forceChanged(int)"), self.currentForce) + + @QtCore.Slot() + def shoot(self): + if self.isShooting(): + return + self.timerCount = 0 + self.shootAngle = self.currentAngle + self.shootForce = self.currentForce + self.autoShootTimer.start(5) + self.emit(QtCore.SIGNAL("canShoot(bool)"), False) + + firstTime = True + + def newTarget(self): + if CannonField.firstTime: + CannonField.firstTime = False + midnight = QtCore.QTime(0, 0, 0) + random.seed(midnight.secsTo(QtCore.QTime.currentTime())) + + self.target = QtCore.QPoint(200 + random.randint(0, 190 - 1), 10 + random.randint(0, 255 - 1)) + self.update() + + def setGameOver(self): + if self.gameEnded: + return + if self.isShooting(): + self.autoShootTimer.stop() + self.gameEnded = True + self.update() + + def restartGame(self): + if self.isShooting(): + self.autoShootTimer.stop() + self.gameEnded = False + self.update() + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + + @QtCore.Slot() + def moveShot(self): + region = QtGui.QRegion(self.shotRect()) + self.timerCount += 1 + + shotR = self.shotRect() + + if shotR.intersects(self.targetRect()): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("hit()")) + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + elif shotR.x() > self.width() or shotR.y() > self.height() or shotR.intersects(self.barrierRect()): + self.autoShootTimer.stop() + self.emit(QtCore.SIGNAL("missed()")) + self.emit(QtCore.SIGNAL("canShoot(bool)"), True) + else: + region = region.united(QtGui.QRegion(shotR)) + + self.update(region) + + def mousePressEvent(self, event): + if event.button() != QtCore.Qt.LeftButton: + return + if self.barrelHit(event.pos()): + self.barrelPressed = True + + def mouseMoveEvent(self, event): + if not self.barrelPressed: + return + pos = event.pos() + if pos.x() <= 0: + pos.setX(1) + if pos.y() >= self.height(): + pos.setY(self.height() - 1) + rad = math.atan((float(self.rect().bottom()) - pos.y()) / pos.x()) + self.setAngle(round(rad * 180 / 3.14159265)) + + def mouseReleaseEvent(self, event): + if event.button() == QtCore.Qt.LeftButton: + self.barrelPressed = False + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + if self.gameEnded: + painter.setPen(QtCore.Qt.black) + painter.setFont(QtGui.QFont("Courier", 48, QtGui.QFont.Bold)) + painter.drawText(self.rect(), QtCore.Qt.AlignCenter, "Game Over") + + self.paintCannon(painter) + self.paintBarrier(painter) + if self.isShooting(): + self.paintShot(painter) + if not self.gameEnded: + self.paintTarget(painter) + + def paintShot(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.black) + painter.drawRect(self.shotRect()) + + def paintTarget(self, painter): + painter.setPen(QtCore.Qt.black) + painter.setBrush(QtCore.Qt.red) + painter.drawRect(self.targetRect()) + + def paintBarrier(self, painter): + painter.setPen(QtCore.Qt.black) + painter.setBrush(QtCore.Qt.yellow) + painter.drawRect(self.barrierRect()) + + barrelRect = QtCore.QRect(33, -4, 15, 8) + + def paintCannon(self, painter): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.save() + painter.translate(0, self.height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(CannonField.barrelRect) + painter.restore() + + def cannonRect(self): + result = QtCore.QRect(0, 0, 50, 50) + result.moveBottomLeft(self.rect().bottomLect()) + return result + + def shotRect(self): + gravity = 4.0 + + time = self.timerCount / 40.0 + velocity = self.shootForce + radians = self.shootAngle * 3.14159265 / 180 + + velx = velocity * math.cos(radians) + vely = velocity * math.sin(radians) + x0 = (CannonField.barrelRect.right() + 5) * math.cos(radians) + y0 = (CannonField.barrelRect.right() + 5) * math.sin(radians) + x = x0 + velx * time + y = y0 + vely * time - 0.5 * gravity * time * time + + result = QtCore.QRect(0, 0, 6, 6) + result.moveCenter(QtCore.QPoint(round(x), self.height() - 1 - round(y))) + return result + + def targetRect(self): + result = QtCore.QRect(0, 0, 20, 10) + result.moveCenter(QtCore.QPoint(self.target.x(), self.height() - 1 - self.target.y())) + return result + + def barrierRect(self): + return QtCore.QRect(145, self.height() - 100, 15, 99) + + def barrelHit(self, pos): + matrix = QtGui.QTransform() + matrix.translate(0, self.height()) + matrix.rotate(-self.currentAngle) + matrix, invertible = matrix.inverted() + return self.barrelRect.contains(matrix.map(pos)) + + def gameOver(self): + return self.gameEnded + + def isShooting(self): + return self.autoShootTimer.isActive() + + def sizeHint(self): + return QtCore.QSize(400, 300) + + +class GameBoard(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("&Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange("ANGLE") + angle.setRange(5, 70) + + force = LCDRange("FORCE") + force.setRange(10, 50) + + cannonBox = QtWidgets.QFrame() + cannonBox.setFrameStyle(QtWidgets.QFrame.WinPanel | QtWidgets.QFrame.Sunken) + + self.cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + self.cannonField.setAngle) + self.connect(self.cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + self.connect(force, QtCore.SIGNAL("valueChanged(int)"), + self.cannonField.setForce) + self.connect(self.cannonField, QtCore.SIGNAL("forceChanged(int)"), + force.setValue) + + self.connect(self.cannonField, QtCore.SIGNAL("hit()"), self.hit) + self.connect(self.cannonField, QtCore.SIGNAL("missed()"), self.missed) + + shoot = QtWidgets.QPushButton("&Shoot") + shoot.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(shoot, QtCore.SIGNAL("clicked()"), self.fire) + self.connect(self.cannonField, QtCore.SIGNAL("canShoot(bool)"), + shoot, QtCore.SLOT("setEnabled(bool)")) + + restart = QtWidgets.QPushButton("&New Game") + restart.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(restart, QtCore.SIGNAL("clicked()"), self.newGame) + + self.hits = QtWidgets.QLCDNumber(2) + self.shotsLeft = QtWidgets.QLCDNumber(2) + hitsLabel = QtWidgets.QLabel("HITS") + shotsLeftLabel = QtWidgets.QLabel("SHOTS LEFT") + + QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Enter), + self, self.fire) + QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return), + self, self.fire) + QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.CTRL + QtCore.Qt.Key_Q), + self, QtCore.SLOT("close()")) + + topLayout = QtWidgets.QHBoxLayout() + topLayout.addWidget(shoot) + topLayout.addWidget(self.hits) + topLayout.addWidget(hitsLabel) + topLayout.addWidget(self.shotsLeft) + topLayout.addWidget(shotsLeftLabel) + topLayout.addStretch(1) + topLayout.addWidget(restart) + + leftLayout = QtWidgets.QVBoxLayout() + leftLayout.addWidget(angle) + leftLayout.addWidget(force) + + cannonLayout = QtWidgets.QVBoxLayout() + cannonLayout.addWidget(self.cannonField) + cannonBox.setLayout(cannonLayout) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addLayout(topLayout, 0, 1) + gridLayout.addLayout(leftLayout, 1, 0) + gridLayout.addWidget(cannonBox, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + force.setValue(25) + angle.setFocus() + + self.newGame() + + @QtCore.Slot() + def fire(self): + if self.cannonField.gameOver() or self.cannonField.isShooting(): + return + self.shotsLeft.display(self.shotsLeft.intValue() - 1) + self.cannonField.shoot() + + @QtCore.Slot() + def hit(self): + self.hits.display(self.hits.intValue() + 1) + if self.shotsLeft.intValue() == 0: + self.cannonField.setGameOver() + else: + self.cannonField.newTarget() + + @QtCore.Slot() + def missed(self): + if self.shotsLeft.intValue() == 0: + self.cannonField.setGameOver() + + @QtCore.Slot() + def newGame(self): + self.shotsLeft.display(15) + self.hits.display(0) + self.cannonField.restartGame() + self.cannonField.newTarget() + + +app = QtWidgets.QApplication(sys.argv) +board = GameBoard() +board.setGeometry(100, 100, 500, 355) +board.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t2.py b/examples/tutorial/t2.py new file mode 100644 index 0000000..946a273 --- /dev/null +++ b/examples/tutorial/t2.py @@ -0,0 +1,59 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 2 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +app = QtWidgets.QApplication(sys.argv) + +quit = QtWidgets.QPushButton("Quit") +quit.resize(75, 30) +quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + +QtCore.QObject.connect(quit, QtCore.SIGNAL("clicked()"), + app, QtCore.SLOT("quit()")) + +quit.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t3.py b/examples/tutorial/t3.py new file mode 100644 index 0000000..65796ac --- /dev/null +++ b/examples/tutorial/t3.py @@ -0,0 +1,61 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 3 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +app = QtWidgets.QApplication(sys.argv) + +window = QtWidgets.QWidget() +window.resize(200, 120) + +quit = QtWidgets.QPushButton("Quit", window) +quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) +quit.setGeometry(10, 40, 180, 40) +QtCore.QObject.connect(quit, QtCore.SIGNAL("clicked()"), + app, QtCore.SLOT("quit()")) + +window.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t4.py b/examples/tutorial/t4.py new file mode 100644 index 0000000..c88943c --- /dev/null +++ b/examples/tutorial/t4.py @@ -0,0 +1,66 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 4 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.setFixedSize(200, 120) + + self.quit = QtWidgets.QPushButton("Quit", self) + self.quit.setGeometry(62, 40, 75, 30) + self.quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(self.quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t5.py b/examples/tutorial/t5.py new file mode 100644 index 0000000..4077c0e --- /dev/null +++ b/examples/tutorial/t5.py @@ -0,0 +1,77 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 5 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + lcd = QtWidgets.QLCDNumber(2) + + slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + slider.setRange(0, 99) + slider.setValue(0) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + self.connect(slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(quit) + layout.addWidget(lcd) + layout.addWidget(slider) + self.setLayout(layout) + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t6.py b/examples/tutorial/t6.py new file mode 100644 index 0000000..21c4ff3 --- /dev/null +++ b/examples/tutorial/t6.py @@ -0,0 +1,90 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 6 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + slider.setRange(0, 99) + slider.setValue(0) + self.connect(slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(slider) + self.setLayout(layout) + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + grid = QtWidgets.QGridLayout() + layout = QtWidgets.QVBoxLayout() + layout.addWidget(quit) + layout.addLayout(grid) + self.setLayout(layout) + for row in range(3): + for column in range(3): + grid.addWidget(LCDRange(), row, column) + + + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t7.py b/examples/tutorial/t7.py new file mode 100644 index 0000000..0e01a75 --- /dev/null +++ b/examples/tutorial/t7.py @@ -0,0 +1,113 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 7 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + self.setLayout(layout) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + grid = QtWidgets.QGridLayout() + previousRange = None + + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(quit) + layout.addLayout(grid) + self.setLayout(layout) + + for row in range(3): + for column in range(3): + lcdRange = LCDRange() + grid.addWidget(lcdRange, row, column) + + if previousRange: + self.connect(lcdRange, QtCore.SIGNAL("valueChanged(int)"), + previousRange.setValue) + + previousRange = lcdRange + + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t8.py b/examples/tutorial/t8.py new file mode 100644 index 0000000..e672689 --- /dev/null +++ b/examples/tutorial/t8.py @@ -0,0 +1,152 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 8 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange.setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + painter.drawText(200, 200, "Angle = %d" % self.currentAngle) + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange() + angle.setRange(5, 70) + + cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setAngle) + self.connect(cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addWidget(angle, 1, 0) + gridLayout.addWidget(cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + angle.setFocus() + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.setGeometry(100, 100, 500, 355) +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/t9.py b/examples/tutorial/t9.py new file mode 100644 index 0000000..ab37f8e --- /dev/null +++ b/examples/tutorial/t9.py @@ -0,0 +1,159 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# PySide2 tutorial 9 + + +import sys +from PySide2 import QtCore, QtGui, QtWidgets + + +class LCDRange(QtWidgets.QWidget): + valueChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + lcd = QtWidgets.QLCDNumber(2) + self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) + self.slider.setRange(0, 99) + self.slider.setValue(0) + + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + lcd, QtCore.SLOT("display(int)")) + self.connect(self.slider, QtCore.SIGNAL("valueChanged(int)"), + self, QtCore.SIGNAL("valueChanged(int)")) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(lcd) + layout.addWidget(self.slider) + self.setLayout(layout) + + self.setFocusProxy(self.slider) + + def value(self): + return self.slider.value() + + @QtCore.Slot(int) + def setValue(self, value): + self.slider.setValue(value) + + def setRange(self, minValue, maxValue): + if minValue < 0 or maxValue > 99 or minValue > maxValue: + QtCore.qWarning("LCDRange::setRange(%d, %d)\n" + "\tRange must be 0..99\n" + "\tand minValue must not be greater than maxValue" % (minValue, maxValue)) + return + + self.slider.setRange(minValue, maxValue) + + +class CannonField(QtWidgets.QWidget): + angleChanged = QtCore.Signal(int) + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.currentAngle = 45 + self.setPalette(QtGui.QPalette(QtGui.QColor(250, 250, 200))) + self.setAutoFillBackground(True) + + def angle(self): + return self.currentAngle + + @QtCore.Slot(int) + def setAngle(self, angle): + if angle < 5: + angle = 5 + if angle > 70: + angle = 70 + if self.currentAngle == angle: + return + self.currentAngle = angle + self.update() + self.emit(QtCore.SIGNAL("angleChanged(int)"), self.currentAngle) + + def paintEvent(self, event): + painter = QtGui.QPainter(self) + + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.blue) + + painter.translate(0, self.rect().height()) + painter.drawPie(QtCore.QRect(-35, -35, 70, 70), 0, 90 * 16) + painter.rotate(-self.currentAngle) + painter.drawRect(QtCore.QRect(33, -4, 15, 8)) + + +class MyWidget(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + quit = QtWidgets.QPushButton("Quit") + quit.setFont(QtGui.QFont("Times", 18, QtGui.QFont.Bold)) + + self.connect(quit, QtCore.SIGNAL("clicked()"), + qApp, QtCore.SLOT("quit()")) + + angle = LCDRange() + angle.setRange(5, 70) + + cannonField = CannonField() + + self.connect(angle, QtCore.SIGNAL("valueChanged(int)"), + cannonField.setAngle) + self.connect(cannonField, QtCore.SIGNAL("angleChanged(int)"), + angle.setValue) + + gridLayout = QtWidgets.QGridLayout() + gridLayout.addWidget(quit, 0, 0) + gridLayout.addWidget(angle, 1, 0) + gridLayout.addWidget(cannonField, 1, 1, 2, 1) + gridLayout.setColumnStretch(1, 10) + self.setLayout(gridLayout) + + angle.setValue(60) + angle.setFocus() + + +app = QtWidgets.QApplication(sys.argv) +widget = MyWidget() +widget.setGeometry(100, 100, 500, 355) +widget.show() +sys.exit(app.exec_()) diff --git a/examples/tutorial/tutorial.pyproject b/examples/tutorial/tutorial.pyproject new file mode 100644 index 0000000..09478e1 --- /dev/null +++ b/examples/tutorial/tutorial.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["t6.py", "t9.py", "t8.py", "t13.py", "t10.py", "t7.py", + "t3.py", "t4.py", "t1.py", "t12.py", "t2.py", "t5.py", + "t11.py", "t14.py"] +} diff --git a/examples/uiloader/uiloader.py b/examples/uiloader/uiloader.py new file mode 100644 index 0000000..1e6e72d --- /dev/null +++ b/examples/uiloader/uiloader.py @@ -0,0 +1,71 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""QUiLoader example, showing how to dynamically load a Qt Designer form + from a UI file.""" + +from argparse import ArgumentParser, RawTextHelpFormatter +import sys + +from PySide2.QtCore import Qt, QFile, QIODevice +from PySide2.QtWidgets import QApplication, QWidget +from PySide2.QtUiTools import QUiLoader + + +if __name__ == '__main__': + arg_parser = ArgumentParser(description="QUiLoader example", + formatter_class=RawTextHelpFormatter) + arg_parser.add_argument('file', type=str, help='UI file') + args = arg_parser.parse_args() + ui_file_name = args.file + + app = QApplication(sys.argv) + ui_file = QFile(ui_file_name) + if not ui_file.open(QIODevice.ReadOnly): + print("Cannot open {}: {}".format(ui_file_name, ui_file.errorString())) + sys.exit(-1) + loader = QUiLoader() + widget = loader.load(ui_file, None) + ui_file.close() + if not widget: + print(loader.errorString()) + sys.exit(-1) + widget.show() + sys.exit(app.exec_()) diff --git a/examples/utils/pyside2_config.py b/examples/utils/pyside2_config.py new file mode 100644 index 0000000..9734101 --- /dev/null +++ b/examples/utils/pyside2_config.py @@ -0,0 +1,372 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os, glob, re, sys +from distutils import sysconfig + +generic_error = (' Did you forget to activate your virtualenv? Or perhaps' + ' you forgot to build / install PySide2 into your currently active Python' + ' environment?') +pyside2_error = 'Unable to locate PySide2.' + generic_error +shiboken2_module_error = 'Unable to locate shiboken2-module.' + generic_error +shiboken2_generator_error = 'Unable to locate shiboken2-generator.' + generic_error +pyside2_libs_error = 'Unable to locate the PySide2 shared libraries.' + generic_error +python_link_error = 'Unable to locate the Python library for linking.' +python_include_error = 'Unable to locate the Python include headers directory.' + +options = [] + +# option, function, error, description +options.append(("--shiboken2-module-path", + lambda: find_shiboken2_module(), + shiboken2_module_error, + "Print shiboken2 module location")) +options.append(("--shiboken2-generator-path", + lambda: find_shiboken2_generator(), + shiboken2_generator_error, + "Print shiboken2 generator location")) +options.append(("--pyside2-path", lambda: find_pyside2(), pyside2_error, + "Print PySide2 location")) + +options.append(("--python-include-path", + lambda: get_python_include_path(), + python_include_error, + "Print Python include path")) +options.append(("--shiboken2-generator-include-path", + lambda: get_package_include_path(Package.shiboken2_generator), + pyside2_error, + "Print shiboken2 generator include paths")) +options.append(("--pyside2-include-path", + lambda: get_package_include_path(Package.pyside2), + pyside2_error, + "Print PySide2 include paths")) + +options.append(("--python-link-flags-qmake", lambda: python_link_flags_qmake(), python_link_error, + "Print python link flags for qmake")) +options.append(("--python-link-flags-cmake", lambda: python_link_flags_cmake(), python_link_error, + "Print python link flags for cmake")) + +options.append(("--shiboken2-module-qmake-lflags", + lambda: get_package_qmake_lflags(Package.shiboken2_module), pyside2_error, + "Print shiboken2 shared library link flags for qmake")) +options.append(("--pyside2-qmake-lflags", + lambda: get_package_qmake_lflags(Package.pyside2), pyside2_error, + "Print PySide2 shared library link flags for qmake")) + +options.append(("--shiboken2-module-shared-libraries-qmake", + lambda: get_shared_libraries_qmake(Package.shiboken2_module), pyside2_libs_error, + "Print paths of shiboken2 shared libraries (.so's, .dylib's, .dll's) for qmake")) +options.append(("--shiboken2-module-shared-libraries-cmake", + lambda: get_shared_libraries_cmake(Package.shiboken2_module), pyside2_libs_error, + "Print paths of shiboken2 shared libraries (.so's, .dylib's, .dll's) for cmake")) + +options.append(("--pyside2-shared-libraries-qmake", + lambda: get_shared_libraries_qmake(Package.pyside2), pyside2_libs_error, + "Print paths of PySide2 shared libraries (.so's, .dylib's, .dll's) for qmake")) +options.append(("--pyside2-shared-libraries-cmake", + lambda: get_shared_libraries_cmake(Package.pyside2), pyside2_libs_error, + "Print paths of PySide2 shared libraries (.so's, .dylib's, .dll's) for cmake")) + +options_usage = '' +for i, (flag, _, _, description) in enumerate(options): + options_usage += ' {:<45} {}'.format(flag, description) + if i < len(options) - 1: + options_usage += '\n' + +usage = """ +Utility to determine include/link options of shiboken2/PySide2 and Python for qmake/CMake projects +that would like to embed or build custom shiboken2/PySide2 bindings. + +Usage: pyside2_config.py [option] +Options: +{} + -a Print all options and their values + --help/-h Print this help +""".format(options_usage) + +option = sys.argv[1] if len(sys.argv) == 2 else '-a' +if option == '-h' or option == '--help': + print(usage) + sys.exit(0) + + +class Package(object): + shiboken2_module = 1 + shiboken2_generator = 2 + pyside2 = 3 + + +def clean_path(path): + return path if sys.platform != 'win32' else path.replace('\\', '/') + + +def shared_library_suffix(): + if sys.platform == 'win32': + return 'lib' + elif sys.platform == 'darwin': + return 'dylib' + # Linux + else: + return 'so.*' + + +def import_suffixes(): + if (sys.version_info >= (3, 4)): + import importlib.machinery + return importlib.machinery.EXTENSION_SUFFIXES + else: + import imp + result = [] + for t in imp.get_suffixes(): + result.append(t[0]) + return result + + +def is_debug(): + debug_suffix = '_d.pyd' if sys.platform == 'win32' else '_d.so' + return any([s.endswith(debug_suffix) for s in import_suffixes()]) + + +def shared_library_glob_pattern(): + glob = '*.' + shared_library_suffix() + return glob if sys.platform == 'win32' else 'lib' + glob + + +def filter_shared_libraries(libs_list): + def predicate(lib_name): + basename = os.path.basename(lib_name) + if 'shiboken' in basename or 'pyside2' in basename: + return True + return False + result = [lib for lib in libs_list if predicate(lib)] + return result + + +# Return qmake link option for a library file name +def link_option(lib): + # On Linux: + # Since we cannot include symlinks with wheel packages + # we are using an absolute path for the libpyside and libshiboken + # libraries when compiling the project + baseName = os.path.basename(lib) + link = ' -l' + if sys.platform in ['linux', 'linux2']: # Linux: 'libfoo.so' -> '/absolute/path/libfoo.so' + link = lib + elif sys.platform in ['darwin']: # Darwin: 'libfoo.so' -> '-lfoo' + link += os.path.splitext(baseName[3:])[0] + else: # Windows: 'libfoo.dll' -> 'libfoo.dll' + link += os.path.splitext(baseName)[0] + return link + + +# Locate PySide2 via sys.path package path. +def find_pyside2(): + return find_package_path("PySide2") + + +def find_shiboken2_module(): + return find_package_path("shiboken2") + + +def find_shiboken2_generator(): + return find_package_path("shiboken2_generator") + + +def find_package(which_package): + if which_package == Package.shiboken2_module: + return find_shiboken2_module() + if which_package == Package.shiboken2_generator: + return find_shiboken2_generator() + if which_package == Package.pyside2: + return find_pyside2() + return None + + +def find_package_path(dir_name): + for p in sys.path: + if 'site-' in p: + package = os.path.join(p, dir_name) + if os.path.exists(package): + return clean_path(os.path.realpath(package)) + return None + + +# Return version as "3.5" +def python_version(): + return str(sys.version_info[0]) + '.' + str(sys.version_info[1]) + + +def get_python_include_path(): + return sysconfig.get_python_inc() + + +def python_link_flags_qmake(): + flags = python_link_data() + if sys.platform == 'win32': + libdir = flags['libdir'] + # This will add the "~1" shortcut for directories that + # contain white spaces + # e.g.: "Program Files" to "Progra~1" + for d in libdir.split("\\"): + if " " in d: + libdir = libdir.replace(d, d.split(" ")[0][:-1]+"~1") + return '-L{} -l{}'.format(libdir, flags['lib']) + elif sys.platform == 'darwin': + return '-L{} -l{}'.format(flags['libdir'], flags['lib']) + + else: + # Linux and anything else + return '-L{} -l{}'.format(flags['libdir'], flags['lib']) + + +def python_link_flags_cmake(): + flags = python_link_data() + libdir = flags['libdir'] + lib = re.sub(r'.dll$', '.lib', flags['lib']) + return '{};{}'.format(libdir, lib) + + +def python_link_data(): + # @TODO Fix to work with static builds of Python + libdir = sysconfig.get_config_var('LIBDIR') + if libdir is None: + libdir = os.path.abspath(os.path.join( + sysconfig.get_config_var('LIBDEST'), "..", "libs")) + version = python_version() + version_no_dots = version.replace('.', '') + + flags = {} + flags['libdir'] = libdir + if sys.platform == 'win32': + suffix = '_d' if is_debug() else '' + flags['lib'] = 'python{}{}'.format(version_no_dots, suffix) + + elif sys.platform == 'darwin': + flags['lib'] = 'python{}'.format(version) + + # Linux and anything else + else: + if sys.version_info[0] < 3: + suffix = '_d' if is_debug() else '' + flags['lib'] = 'python{}{}'.format(version, suffix) + else: + flags['lib'] = 'python{}{}'.format(version, sys.abiflags) + + return flags + + +def get_package_include_path(which_package): + package_path = find_package(which_package) + if package_path is None: + return None + + includes = "{0}/include".format(package_path) + + return includes + + +def get_package_qmake_lflags(which_package): + package_path = find_package(which_package) + if package_path is None: + return None + + link = "-L{}".format(package_path) + glob_result = glob.glob(os.path.join(package_path, shared_library_glob_pattern())) + for lib in filter_shared_libraries(glob_result): + link += ' ' + link += link_option(lib) + return link + + +def get_shared_libraries_data(which_package): + package_path = find_package(which_package) + if package_path is None: + return None + + glob_result = glob.glob(os.path.join(package_path, shared_library_glob_pattern())) + filtered_libs = filter_shared_libraries(glob_result) + libs = [] + if sys.platform == 'win32': + for lib in filtered_libs: + libs.append(os.path.realpath(lib)) + else: + for lib in filtered_libs: + libs.append(lib) + return libs + + +def get_shared_libraries_qmake(which_package): + libs = get_shared_libraries_data(which_package) + if libs is None: + return None + + if sys.platform == 'win32': + if not libs: + return '' + dlls = '' + for lib in libs: + dll = os.path.splitext(lib)[0] + '.dll' + dlls += dll + ' ' + + return dlls + else: + libs_string = '' + for lib in libs: + libs_string += lib + ' ' + return libs_string + + +def get_shared_libraries_cmake(which_package): + libs = get_shared_libraries_data(which_package) + result = ';'.join(libs) + return result + + +print_all = option == "-a" +for argument, handler, error, _ in options: + if option == argument or print_all: + handler_result = handler() + if handler_result is None: + sys.exit(error) + + line = handler_result + if print_all: + line = "{:<40}: ".format(argument) + line + print(line) diff --git a/examples/utils/utils.py b/examples/utils/utils.py new file mode 100644 index 0000000..96421e4 --- /dev/null +++ b/examples/utils/utils.py @@ -0,0 +1,48 @@ + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +isPY3 = sys.version_info[0] == 3 + +if isPY3: + text_type = str +else: + text_type = unicode diff --git a/examples/webchannel/standalone/core.py b/examples/webchannel/standalone/core.py new file mode 100644 index 0000000..9fb0564 --- /dev/null +++ b/examples/webchannel/standalone/core.py @@ -0,0 +1,62 @@ +############################################################################# +## +## Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + + +from PySide2.QtCore import QObject, Signal, Slot + + +class Core(QObject): + """An instance of this class gets published over the WebChannel and is then + accessible to HTML clients.""" + sendText = Signal(str) + + def __init__(self, dialog, parent=None): + super(Core, self).__init__(parent) + self._dialog = dialog + self._dialog.sendText.connect(self._emit_send_text) + + @Slot(str) + def _emit_send_text(self, text): + self.sendText.emit(text) + + @Slot(str) + def receiveText(self, text): + self._dialog.displayMessage("Received message: {}".format(text)) diff --git a/examples/webchannel/standalone/dialog.py b/examples/webchannel/standalone/dialog.py new file mode 100644 index 0000000..45951de --- /dev/null +++ b/examples/webchannel/standalone/dialog.py @@ -0,0 +1,68 @@ +############################################################################# +## +## Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + + +from PySide2.QtCore import Signal, Slot +from PySide2.QtWidgets import QDialog +from ui_dialog import Ui_Dialog + + +class Dialog(QDialog): + sendText = Signal(str) + + def __init__(self, parent=None): + super(Dialog, self).__init__(parent) + self._ui = Ui_Dialog() + self._ui.setupUi(self) + self._ui.send.clicked.connect(self.clicked) + + @Slot(str) + def displayMessage(self, message): + self._ui.output.appendPlainText(message) + + @Slot() + def clicked(self): + text = self._ui.input.text() + if not text: + return + self.sendText.emit(text) + self.displayMessage("Sent message: {}".format(text)) + self._ui.input.clear() diff --git a/examples/webchannel/standalone/dialog.ui b/examples/webchannel/standalone/dialog.ui new file mode 100644 index 0000000..056a3f5 --- /dev/null +++ b/examples/webchannel/standalone/dialog.ui @@ -0,0 +1,48 @@ + + + Dialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + Message Contents + + + + + + + Send + + + + + + + true + + + Initializing WebChannel... + + + false + + + + + + + + diff --git a/examples/webchannel/standalone/index.html b/examples/webchannel/standalone/index.html new file mode 100644 index 0000000..7c042cd --- /dev/null +++ b/examples/webchannel/standalone/index.html @@ -0,0 +1,79 @@ + + + + + + + + + +
+ + + diff --git a/examples/webchannel/standalone/main.py b/examples/webchannel/standalone/main.py new file mode 100644 index 0000000..d311914 --- /dev/null +++ b/examples/webchannel/standalone/main.py @@ -0,0 +1,99 @@ +############################################################################# +## +## Copyright (C) 2016 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + + +import os +import sys + +from PySide2.QtWidgets import QApplication +from PySide2.QtGui import QDesktopServices +from PySide2.QtNetwork import QHostAddress, QSslSocket +from PySide2.QtCore import (QFile, QFileInfo, QUrl) +from PySide2.QtWebChannel import QWebChannel +from PySide2.QtWebSockets import QWebSocketServer + +from dialog import Dialog +from core import Core +from websocketclientwrapper import WebSocketClientWrapper + + +if __name__ == '__main__': + app = QApplication(sys.argv) + if not QSslSocket.supportsSsl(): + print('The example requires SSL support.') + sys.exit(-1) + cur_dir = os.path.dirname(os.path.abspath(__file__)) + jsFileInfo = QFileInfo(cur_dir + "/qwebchannel.js") + if not jsFileInfo.exists(): + QFile.copy(":/qtwebchannel/qwebchannel.js", + jsFileInfo.absoluteFilePath()) + + # setup the QWebSocketServer + server = QWebSocketServer("QWebChannel Standalone Example Server", + QWebSocketServer.NonSecureMode) + if not server.listen(QHostAddress.LocalHost, 12345): + print("Failed to open web socket server.") + sys.exit(-1) + + # wrap WebSocket clients in QWebChannelAbstractTransport objects + clientWrapper = WebSocketClientWrapper(server) + + # setup the channel + channel = QWebChannel() + clientWrapper.clientConnected.connect(channel.connectTo) + + # setup the UI + dialog = Dialog() + + # setup the core and publish it to the QWebChannel + core = Core(dialog) + channel.registerObject("core", core) + + # open a browser window with the client HTML page + url = QUrl.fromLocalFile(cur_dir + "/index.html") + QDesktopServices.openUrl(url) + + message = "Initialization complete, opening browser at {}.".format( + url.toDisplayString()) + dialog.displayMessage(message) + dialog.show() + + sys.exit(app.exec_()) diff --git a/examples/webchannel/standalone/standalone.pyproject b/examples/webchannel/standalone/standalone.pyproject new file mode 100644 index 0000000..b4fcdfa --- /dev/null +++ b/examples/webchannel/standalone/standalone.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["main.py", "core.py", "dialog.py", "websocketclientwrapper.py", + "websockettransport.py", "dialog.ui", "index.html"] +} diff --git a/examples/webchannel/standalone/ui_dialog.py b/examples/webchannel/standalone/ui_dialog.py new file mode 100644 index 0000000..873edba --- /dev/null +++ b/examples/webchannel/standalone/ui_dialog.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'dialog.ui' +## +## Created by: Qt User Interface Compiler version 5.14.1 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint, + QRect, QSize, QUrl, Qt) +from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont, + QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap, + QRadialGradient) +from PySide2.QtWidgets import * + + +class Ui_Dialog(object): + def setupUi(self, Dialog): + if not Dialog.objectName(): + Dialog.setObjectName(u"Dialog") + Dialog.resize(400, 300) + self.gridLayout = QGridLayout(Dialog) + self.gridLayout.setObjectName(u"gridLayout") + self.input = QLineEdit(Dialog) + self.input.setObjectName(u"input") + + self.gridLayout.addWidget(self.input, 1, 0, 1, 1) + + self.send = QPushButton(Dialog) + self.send.setObjectName(u"send") + + self.gridLayout.addWidget(self.send, 1, 1, 1, 1) + + self.output = QPlainTextEdit(Dialog) + self.output.setObjectName(u"output") + self.output.setReadOnly(True) + self.output.setPlainText(u"Initializing WebChannel...") + self.output.setBackgroundVisible(False) + + self.gridLayout.addWidget(self.output, 0, 0, 1, 2) + + + self.retranslateUi(Dialog) + + QMetaObject.connectSlotsByName(Dialog) + # setupUi + + def retranslateUi(self, Dialog): + Dialog.setWindowTitle(QCoreApplication.translate("Dialog", u"Dialog", None)) + self.input.setPlaceholderText(QCoreApplication.translate("Dialog", u"Message Contents", None)) + self.send.setText(QCoreApplication.translate("Dialog", u"Send", None)) + # retranslateUi + diff --git a/examples/webchannel/standalone/websocketclientwrapper.py b/examples/webchannel/standalone/websocketclientwrapper.py new file mode 100644 index 0000000..24505b0 --- /dev/null +++ b/examples/webchannel/standalone/websocketclientwrapper.py @@ -0,0 +1,72 @@ +############################################################################# +## +## Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import QObject, Signal, Slot + +from websockettransport import WebSocketTransport + + +class WebSocketClientWrapper(QObject): + """Wraps connected QWebSockets clients in WebSocketTransport objects. + + This code is all that is required to connect incoming WebSockets to + the WebChannel. Any kind of remote JavaScript client that supports + WebSockets can thus receive messages and access the published objects. + """ + clientConnected = Signal(WebSocketTransport) + + def __init__(self, server, parent=None): + """Construct the client wrapper with the given parent. All clients + connecting to the QWebSocketServer will be automatically wrapped + in WebSocketTransport objects.""" + super(WebSocketClientWrapper, self).__init__(parent) + self._server = server + self._server.newConnection.connect(self.handleNewConnection) + self._transports = [] + + @Slot() + def handleNewConnection(self): + """Wrap an incoming WebSocket connection in a WebSocketTransport + object.""" + socket = self._server.nextPendingConnection() + transport = WebSocketTransport(socket) + self._transports.append(transport) + self.clientConnected.emit(transport) diff --git a/examples/webchannel/standalone/websockettransport.py b/examples/webchannel/standalone/websockettransport.py new file mode 100644 index 0000000..4e42e76 --- /dev/null +++ b/examples/webchannel/standalone/websockettransport.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWebChannel import QWebChannelAbstractTransport +from PySide2.QtCore import QByteArray, QJsonDocument, Slot + + +class WebSocketTransport(QWebChannelAbstractTransport): + """QWebChannelAbstractSocket implementation using a QWebSocket internally. + + The transport delegates all messages received over the QWebSocket over + its textMessageReceived signal. Analogously, all calls to + sendTextMessage will be sent over the QWebSocket to the remote client. + """ + + def __init__(self, socket): + """Construct the transport object and wrap the given socket. + The socket is also set as the parent of the transport object.""" + super(WebSocketTransport, self).__init__(socket) + self._socket = socket + self._socket.textMessageReceived.connect(self.textMessageReceived) + self._socket.disconnected.connect(self._disconnected) + + def __del__(self): + """Destroys the WebSocketTransport.""" + self._socket.deleteLater() + + def _disconnected(self): + self.deleteLater() + + def sendMessage(self, message): + """Serialize the JSON message and send it as a text message via the + WebSocket to the client.""" + doc = QJsonDocument(message) + json_message = str(doc.toJson(QJsonDocument.Compact), "utf-8") + self._socket.sendTextMessage(json_message) + + @Slot(str) + def textMessageReceived(self, message_data_in): + """Deserialize the stringified JSON messageData and emit + messageReceived.""" + message_data = QByteArray(bytes(message_data_in, encoding='utf8')) + message = QJsonDocument.fromJson(message_data) + if message.isNull(): + print("Failed to parse text message as JSON object:", message_data) + return + if not message.isObject(): + print("Received JSON message that is not an object: ", message_data) + return + self.messageReceived.emit(message.object(), self) diff --git a/examples/webenginequick/browser.qml b/examples/webenginequick/browser.qml new file mode 100644 index 0000000..7814538 --- /dev/null +++ b/examples/webenginequick/browser.qml @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtQuick.Window 2.0 +import QtWebEngine 1.0 + +Window { + width: 1024 + height: 768 + visible: true + WebEngineView { + anchors.fill: parent + url: "https://www.qt.io" + } +} diff --git a/examples/webenginequick/quicknanobrowser.py b/examples/webenginequick/quicknanobrowser.py new file mode 100644 index 0000000..24e58ea --- /dev/null +++ b/examples/webenginequick/quicknanobrowser.py @@ -0,0 +1,59 @@ +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 WebEngine QtQuick 2 Example""" + +import os +from PySide2.QtCore import QUrl +from PySide2.QtQml import QQmlApplicationEngine +from PySide2.QtWidgets import QApplication +from PySide2.QtWebEngine import QtWebEngine + +def main(): + app = QApplication([]) + QtWebEngine.initialize() + engine = QQmlApplicationEngine() + qml_file_path = os.path.join(os.path.dirname(__file__), 'browser.qml') + qml_url = QUrl.fromLocalFile(os.path.abspath(qml_file_path)) + engine.load(qml_url) + app.exec_() + +if __name__ == '__main__': + main() diff --git a/examples/webenginequick/webenginequick.pyproject b/examples/webenginequick/webenginequick.pyproject new file mode 100644 index 0000000..dd90392 --- /dev/null +++ b/examples/webenginequick/webenginequick.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["quicknanobrowser.py", "browser.qml"] +} diff --git a/examples/webenginewidgets/simplebrowser.py b/examples/webenginewidgets/simplebrowser.py new file mode 100644 index 0000000..365e69a --- /dev/null +++ b/examples/webenginewidgets/simplebrowser.py @@ -0,0 +1,101 @@ + +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 WebEngineWidgets Example""" + +import sys +from PySide2.QtCore import QUrl +from PySide2.QtGui import QIcon +from PySide2.QtWidgets import (QApplication, QLineEdit, + QMainWindow, QPushButton, QToolBar) +from PySide2.QtWebEngineWidgets import QWebEnginePage, QWebEngineView + +class MainWindow(QMainWindow): + + def __init__(self): + super(MainWindow, self).__init__() + + self.setWindowTitle('PySide2 WebEngineWidgets Example') + + self.toolBar = QToolBar() + self.addToolBar(self.toolBar) + self.backButton = QPushButton() + self.backButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png')) + self.backButton.clicked.connect(self.back) + self.toolBar.addWidget(self.backButton) + self.forwardButton = QPushButton() + self.forwardButton.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png')) + self.forwardButton.clicked.connect(self.forward) + self.toolBar.addWidget(self.forwardButton) + + self.addressLineEdit = QLineEdit() + self.addressLineEdit.returnPressed.connect(self.load) + self.toolBar.addWidget(self.addressLineEdit) + + self.webEngineView = QWebEngineView() + self.setCentralWidget(self.webEngineView) + initialUrl = 'http://qt.io' + self.addressLineEdit.setText(initialUrl) + self.webEngineView.load(QUrl(initialUrl)) + self.webEngineView.page().titleChanged.connect(self.setWindowTitle) + self.webEngineView.page().urlChanged.connect(self.urlChanged) + + def load(self): + url = QUrl.fromUserInput(self.addressLineEdit.text()) + if url.isValid(): + self.webEngineView.load(url) + + def back(self): + self.webEngineView.page().triggerAction(QWebEnginePage.Back) + + def forward(self): + self.webEngineView.page().triggerAction(QWebEnginePage.Forward) + + def urlChanged(self, url): + self.addressLineEdit.setText(url.toString()) + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = MainWindow() + availableGeometry = app.desktop().availableGeometry(mainWin) + mainWin.resize(availableGeometry.width() * 2 / 3, availableGeometry.height() * 2 / 3) + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/webenginewidgets/tabbedbrowser/bookmarkwidget.py b/examples/webenginewidgets/tabbedbrowser/bookmarkwidget.py new file mode 100644 index 0000000..612c682 --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/bookmarkwidget.py @@ -0,0 +1,277 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import json +import os +import warnings + +from PySide2 import QtCore +from PySide2.QtCore import QDir, QFileInfo, QStandardPaths, Qt, QUrl +from PySide2.QtGui import QIcon, QStandardItem, QStandardItemModel +from PySide2.QtWidgets import QMenu, QMessageBox, QTreeView + +_url_role = Qt.UserRole + 1 + +# Default bookmarks as an array of arrays which is the form +# used to read from/write to a .json bookmarks file +_default_bookmarks = [ + ['Tool Bar'], + ['http://qt.io', 'Qt', ':/qt-project.org/qmessagebox/images/qtlogo-64.png'], + ['https://download.qt.io/snapshots/ci/pyside/', 'Downloads'], + ['https://doc.qt.io/qtforpython/', 'Documentation'], + ['https://bugreports.qt.io/projects/PYSIDE/', 'Bug Reports'], + ['https://www.python.org/', 'Python', None], + ['https://wiki.qt.io/PySide2', 'Qt for Python', None], + ['Other Bookmarks'] +] + + +def _config_dir(): + return '{}/QtForPythonBrowser'.format( + QStandardPaths.writableLocation(QStandardPaths.ConfigLocation)) + + +_bookmark_file = 'bookmarks.json' + + +def _create_folder_item(title): + result = QStandardItem(title) + result.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) + return result + + +def _create_item(url, title, icon): + result = QStandardItem(title) + result.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) + result.setData(url, _url_role) + if icon is not None: + result.setIcon(icon) + return result + + +# Create the model from an array of arrays +def _create_model(parent, serialized_bookmarks): + result = QStandardItemModel(0, 1, parent) + last_folder_item = None + for entry in serialized_bookmarks: + if len(entry) == 1: + last_folder_item = _create_folder_item(entry[0]) + result.appendRow(last_folder_item) + else: + url = QUrl.fromUserInput(entry[0]) + title = entry[1] + icon = QIcon(entry[2]) if len(entry) > 2 and entry[2] else None + last_folder_item.appendRow(_create_item(url, title, icon)) + return result + + +# Serialize model into an array of arrays, writing out the icons +# into .png files under directory in the process +def _serialize_model(model, directory): + result = [] + folder_count = model.rowCount() + for f in range(0, folder_count): + folder_item = model.item(f) + result.append([folder_item.text()]) + item_count = folder_item.rowCount() + for i in range(0, item_count): + item = folder_item.child(i) + entry = [item.data(_url_role).toString(), item.text()] + icon = item.icon() + if not icon.isNull(): + icon_sizes = icon.availableSizes() + largest_size = icon_sizes[len(icon_sizes) - 1] + icon_file_name = '{}/icon{:02}_{:02}_{}.png'.format(directory, + f, i, + largest_size.width()) + icon.pixmap(largest_size).save(icon_file_name, 'PNG') + entry.append(icon_file_name) + result.append(entry) + return result + + +# Bookmarks as a tree view to be used in a dock widget with +# functionality to persist and populate tool bars and menus. +class BookmarkWidget(QTreeView): + """Provides a tree view to manage the bookmarks.""" + + open_bookmark = QtCore.Signal(QUrl) + open_bookmark_in_new_tab = QtCore.Signal(QUrl) + changed = QtCore.Signal() + + def __init__(self): + super(BookmarkWidget, self).__init__() + self.setRootIsDecorated(False) + self.setUniformRowHeights(True) + self.setHeaderHidden(True) + self._model = _create_model(self, self._read_bookmarks()) + self.setModel(self._model) + self.expandAll() + self.activated.connect(self._activated) + self._model.rowsInserted.connect(self._changed) + self._model.rowsRemoved.connect(self._changed) + self._model.dataChanged.connect(self._changed) + self._modified = False + + def _changed(self): + self._modified = True + self.changed.emit() + + def _activated(self, index): + item = self._model.itemFromIndex(index) + self.open_bookmark.emit(item.data(_url_role)) + + def _action_activated(self, index): + action = self.sender() + self.open_bookmark.emit(action.data()) + + def _tool_bar_item(self): + return self._model.item(0, 0) + + def _other_item(self): + return self._model.item(1, 0) + + def add_bookmark(self, url, title, icon): + self._other_item().appendRow(_create_item(url, title, icon)) + + def add_tool_bar_bookmark(self, url, title, icon): + self._tool_bar_item().appendRow(_create_item(url, title, icon)) + + # Synchronize the bookmarks under parent_item to a target_object + # like QMenu/QToolBar, which has a list of actions. Update + # the existing actions, append new ones if needed or hide + # superfluous ones + def _populate_actions(self, parent_item, target_object, first_action): + existing_actions = target_object.actions() + existing_action_count = len(existing_actions) + a = first_action + row_count = parent_item.rowCount() + for r in range(0, row_count): + item = parent_item.child(r) + title = item.text() + icon = item.icon() + url = item.data(_url_role) + if a < existing_action_count: + action = existing_actions[a] + if (title != action.toolTip()): + action.setText(BookmarkWidget.short_title(title)) + action.setIcon(icon) + action.setToolTip(title) + action.setData(url) + action.setVisible(True) + else: + short_title = BookmarkWidget.short_title(title) + action = target_object.addAction(icon, short_title) + action.setToolTip(title) + action.setData(url) + action.triggered.connect(self._action_activated) + a = a + 1 + while a < existing_action_count: + existing_actions[a].setVisible(False) + a = a + 1 + + def populate_tool_bar(self, tool_bar): + self._populate_actions(self._tool_bar_item(), tool_bar, 0) + + def populate_other(self, menu, first_action): + self._populate_actions(self._other_item(), menu, first_action) + + def _current_item(self): + index = self.currentIndex() + if index.isValid(): + item = self._model.itemFromIndex(index) + if item.parent(): # exclude top level items + return item + return None + + def context_menu_event(self, event): + context_menu = QMenu() + open_in_new_tab_action = context_menu.addAction("Open in New Tab") + remove_action = context_menu.addAction("Remove...") + current_item = self._current_item() + open_in_new_tab_action.setEnabled(current_item is not None) + remove_action.setEnabled(current_item is not None) + chosen_action = context_menu.exec_(event.globalPos()) + if chosen_action == open_in_new_tab_action: + self.open_bookmarkInNewTab.emit(current_item.data(_url_role)) + elif chosen_action == remove_action: + self._remove_item(current_item) + + def _remove_item(self, item): + message = "Would you like to remove \"{}\"?".format(item.text()) + button = QMessageBox.question(self, "Remove", message, + QMessageBox.Yes | QMessageBox.No) + if button == QMessageBox.Yes: + item.parent().removeRow(item.row()) + + def write_bookmarks(self): + if not self._modified: + return + dir_path = _config_dir() + native_dir_path = QDir.toNativeSeparators(dir_path) + dir = QFileInfo(dir_path) + if not dir.isDir(): + print('Creating {}...'.format(native_dir_path)) + if not QDir(dir.absolutePath()).mkpath(dir.fileName()): + warnings.warn('Cannot create {}.'.format(native_dir_path), + RuntimeWarning) + return + serialized_model = _serialize_model(self._model, dir_path) + bookmark_file_name = os.path.join(native_dir_path, _bookmark_file) + print('Writing {}...'.format(bookmark_file_name)) + with open(bookmark_file_name, 'w') as bookmark_file: + json.dump(serialized_model, bookmark_file, indent=4) + + def _read_bookmarks(self): + bookmark_file_name = os.path.join(QDir.toNativeSeparators(_config_dir()), + _bookmark_file) + if os.path.exists(bookmark_file_name): + print('Reading {}...'.format(bookmark_file_name)) + return json.load(open(bookmark_file_name)) + return _default_bookmarks + + # Return a short title for a bookmark action, + # "Qt | Cross Platform.." -> "Qt" + @staticmethod + def short_title(t): + i = t.find(' | ') + if i == -1: + i = t.find(' - ') + return t[0:i] if i != -1 else t diff --git a/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py b/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py new file mode 100644 index 0000000..093eed6 --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/browsertabwidget.py @@ -0,0 +1,244 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from functools import partial + +from bookmarkwidget import BookmarkWidget +from webengineview import WebEngineView +from historywindow import HistoryWindow +from PySide2 import QtCore +from PySide2.QtCore import Qt, QUrl +from PySide2.QtWidgets import QMenu, QTabBar, QTabWidget +from PySide2.QtWebEngineWidgets import QWebEngineDownloadItem, QWebEnginePage + + +class BrowserTabWidget(QTabWidget): + """Enables having several tabs with QWebEngineView.""" + + url_changed = QtCore.Signal(QUrl) + enabled_changed = QtCore.Signal(QWebEnginePage.WebAction, bool) + download_requested = QtCore.Signal(QWebEngineDownloadItem) + + def __init__(self, window_factory_function): + super(BrowserTabWidget, self).__init__() + self.setTabsClosable(True) + self._window_factory_function = window_factory_function + self._webengineviews = [] + self._history_windows = {} # map WebengineView to HistoryWindow + self.currentChanged.connect(self._current_changed) + self.tabCloseRequested.connect(self.handle_tab_close_request) + self._actions_enabled = {} + for web_action in WebEngineView.web_actions(): + self._actions_enabled[web_action] = False + + tab_bar = self.tabBar() + tab_bar.setSelectionBehaviorOnRemove(QTabBar.SelectPreviousTab) + tab_bar.setContextMenuPolicy(Qt.CustomContextMenu) + tab_bar.customContextMenuRequested.connect(self._handle_tab_context_menu) + + def add_browser_tab(self): + factory_func = partial(BrowserTabWidget.add_browser_tab, self) + web_engine_view = WebEngineView(factory_func, + self._window_factory_function) + index = self.count() + self._webengineviews.append(web_engine_view) + title = 'Tab {}'.format(index + 1) + self.addTab(web_engine_view, title) + page = web_engine_view.page() + page.titleChanged.connect(self._title_changed) + page.iconChanged.connect(self._icon_changed) + page.profile().downloadRequested.connect(self._download_requested) + web_engine_view.urlChanged.connect(self._url_changed) + web_engine_view.enabled_changed.connect(self._enabled_changed) + self.setCurrentIndex(index) + return web_engine_view + + def load(self, url): + index = self.currentIndex() + if index >= 0 and url.isValid(): + self._webengineviews[index].setUrl(url) + + def find(self, needle, flags): + index = self.currentIndex() + if index >= 0: + self._webengineviews[index].page().findText(needle, flags) + + def url(self): + index = self.currentIndex() + return self._webengineviews[index].url() if index >= 0 else QUrl() + + def _url_changed(self, url): + index = self.currentIndex() + if index >= 0 and self._webengineviews[index] == self.sender(): + self.url_changed.emit(url) + + def _title_changed(self, title): + index = self._index_of_page(self.sender()) + if (index >= 0): + self.setTabText(index, BookmarkWidget.short_title(title)) + + def _icon_changed(self, icon): + index = self._index_of_page(self.sender()) + if (index >= 0): + self.setTabIcon(index, icon) + + def _enabled_changed(self, web_action, enabled): + index = self.currentIndex() + if index >= 0 and self._webengineviews[index] == self.sender(): + self._check_emit_enabled_changed(web_action, enabled) + + def _check_emit_enabled_changed(self, web_action, enabled): + if enabled != self._actions_enabled[web_action]: + self._actions_enabled[web_action] = enabled + self.enabled_changed.emit(web_action, enabled) + + def _current_changed(self, index): + self._update_actions(index) + self.url_changed.emit(self.url()) + + def _update_actions(self, index): + if index >= 0 and index < len(self._webengineviews): + view = self._webengineviews[index] + for web_action in WebEngineView.web_actions(): + enabled = view.is_web_action_enabled(web_action) + self._check_emit_enabled_changed(web_action, enabled) + + def back(self): + self._trigger_action(QWebEnginePage.Back) + + def forward(self): + self._trigger_action(QWebEnginePage.Forward) + + def reload(self): + self._trigger_action(QWebEnginePage.Reload) + + def undo(self): + self._trigger_action(QWebEnginePage.Undo) + + def redo(self): + self._trigger_action(QWebEnginePage.Redo) + + def cut(self): + self._trigger_action(QWebEnginePage.Cut) + + def copy(self): + self._trigger_action(QWebEnginePage.Copy) + + def paste(self): + self._trigger_action(QWebEnginePage.Paste) + + def select_all(self): + self._trigger_action(QWebEnginePage.SelectAll) + + def show_history(self): + index = self.currentIndex() + if index >= 0: + webengineview = self._webengineviews[index] + history_window = self._history_windows.get(webengineview) + if not history_window: + history = webengineview.page().history() + history_window = HistoryWindow(history, self) + history_window.open_url.connect(self.load) + history_window.setWindowFlags(history_window.windowFlags() + | Qt.Window) + history_window.setWindowTitle('History') + self._history_windows[webengineview] = history_window + else: + history_window.refresh() + history_window.show() + history_window.raise_() + + def zoom_factor(self): + return self._webengineviews[0].zoomFactor() if self._webengineviews else 1.0 + + def set_zoom_factor(self, z): + for w in self._webengineviews: + w.setZoomFactor(z) + + def _handle_tab_context_menu(self, point): + index = self.tabBar().tabAt(point) + if index < 0: + return + tab_count = len(self._webengineviews) + context_menu = QMenu() + duplicate_tab_action = context_menu.addAction("Duplicate Tab") + close_other_tabs_action = context_menu.addAction("Close Other Tabs") + close_other_tabs_action.setEnabled(tab_count > 1) + close_tabs_to_the_right_action = context_menu.addAction("Close Tabs to the Right") + close_tabs_to_the_right_action.setEnabled(index < tab_count - 1) + close_tab_action = context_menu.addAction("&Close Tab") + chosen_action = context_menu.exec_(self.tabBar().mapToGlobal(point)) + if chosen_action == duplicate_tab_action: + current_url = self.url() + self.add_browser_tab().load(current_url) + elif chosen_action == close_other_tabs_action: + for t in range(tab_count - 1, -1, -1): + if t != index: + self.handle_tab_close_request(t) + elif chosen_action == close_tabs_to_the_right_action: + for t in range(tab_count - 1, index, -1): + self.handle_tab_close_request(t) + elif chosen_action == close_tab_action: + self.handle_tab_close_request(index) + + def handle_tab_close_request(self, index): + if (index >= 0 and self.count() > 1): + webengineview = self._webengineviews[index] + if self._history_windows.get(webengineview): + del self._history_windows[webengineview] + self._webengineviews.remove(webengineview) + self.removeTab(index) + + def close_current_tab(self): + self.handle_tab_close_request(self.currentIndex()) + + def _trigger_action(self, action): + index = self.currentIndex() + if index >= 0: + self._webengineviews[index].page().triggerAction(action) + + def _index_of_page(self, web_page): + for p in range(0, len(self._webengineviews)): + if (self._webengineviews[p].page() == web_page): + return p + return -1 + + def _download_requested(self, item): + self.download_requested.emit(item) diff --git a/examples/webenginewidgets/tabbedbrowser/downloadwidget.py b/examples/webenginewidgets/tabbedbrowser/downloadwidget.py new file mode 100644 index 0000000..73b8d11 --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/downloadwidget.py @@ -0,0 +1,146 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2 import QtCore +from PySide2.QtCore import QDir, QFileInfo, QStandardPaths, Qt, QUrl +from PySide2.QtGui import QDesktopServices +from PySide2.QtWidgets import QMenu, QProgressBar, QStyleFactory +from PySide2.QtWebEngineWidgets import QWebEngineDownloadItem + + +# A QProgressBar with context menu for displaying downloads in a QStatusBar. +class DownloadWidget(QProgressBar): + """Lets you track progress of a QWebEngineDownloadItem.""" + finished = QtCore.Signal() + remove_requested = QtCore.Signal() + + def __init__(self, download_item): + super(DownloadWidget, self).__init__() + self._download_item = download_item + download_item.finished.connect(self._finished) + download_item.downloadProgress.connect(self._download_progress) + download_item.stateChanged.connect(self._update_tool_tip()) + path = download_item.path() + self.setMaximumWidth(300) + # Shorten 'PySide2-5.11.0a1-5.11.0-cp36-cp36m-linux_x86_64.whl'... + description = QFileInfo(path).fileName() + description_length = len(description) + if description_length > 30: + description = '{}...{}'.format(description[0:10], + description[description_length - 10:]) + self.setFormat('{} %p%'.format(description)) + self.setOrientation(Qt.Horizontal) + self.setMinimum(0) + self.setValue(0) + self.setMaximum(100) + self._update_tool_tip() + # Force progress bar text to be shown on macoS by using 'fusion' style + if sys.platform == 'darwin': + self.setStyle(QStyleFactory.create('fusion')) + + @staticmethod + def open_file(file): + QDesktopServices.openUrl(QUrl.fromLocalFile(file)) + + @staticmethod + def open_download_directory(): + path = QStandardPaths.writableLocation(QStandardPaths.DownloadLocation) + DownloadWidget.open_file(path) + + def state(self): + return self._download_item.state() + + def _update_tool_tip(self): + path = self._download_item.path() + tool_tip = "{}\n{}".format(self._download_item.url().toString(), + QDir.toNativeSeparators(path)) + total_bytes = self._download_item.totalBytes() + if total_bytes > 0: + tool_tip += "\n{}K".format(total_bytes / 1024) + state = self.state() + if state == QWebEngineDownloadItem.DownloadRequested: + tool_tip += "\n(requested)" + elif state == QWebEngineDownloadItem.DownloadInProgress: + tool_tip += "\n(downloading)" + elif state == QWebEngineDownloadItem.DownloadCompleted: + tool_tip += "\n(completed)" + elif state == QWebEngineDownloadItem.DownloadCancelled: + tool_tip += "\n(cancelled)" + else: + tool_tip += "\n(interrupted)" + self.setToolTip(tool_tip) + + def _download_progress(self, bytes_received, bytes_total): + self.setValue(int(100 * bytes_received / bytes_total)) + + def _finished(self): + self._update_tool_tip() + self.finished.emit() + + def _launch(self): + DownloadWidget.open_file(self._download_item.path()) + + def mouseDoubleClickEvent(self, event): + if self.state() == QWebEngineDownloadItem.DownloadCompleted: + self._launch() + + def contextMenuEvent(self, event): + state = self.state() + context_menu = QMenu() + launch_action = context_menu.addAction("Launch") + launch_action.setEnabled(state == QWebEngineDownloadItem.DownloadCompleted) + show_in_folder_action = context_menu.addAction("Show in Folder") + show_in_folder_action.setEnabled(state == QWebEngineDownloadItem.DownloadCompleted) + cancel_action = context_menu.addAction("Cancel") + cancel_action.setEnabled(state == QWebEngineDownloadItem.DownloadInProgress) + remove_action = context_menu.addAction("Remove") + remove_action.setEnabled(state != QWebEngineDownloadItem.DownloadInProgress) + + chosen_action = context_menu.exec_(event.globalPos()) + if chosen_action == launch_action: + self._launch() + elif chosen_action == show_in_folder_action: + path = QFileInfo(self._download_item.path()).absolutePath() + DownloadWidget.open_file(path) + elif chosen_action == cancel_action: + self._download_item.cancel() + elif chosen_action == remove_action: + self.remove_requested.emit() diff --git a/examples/webenginewidgets/tabbedbrowser/findtoolbar.py b/examples/webenginewidgets/tabbedbrowser/findtoolbar.py new file mode 100644 index 0000000..3557c2e --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/findtoolbar.py @@ -0,0 +1,99 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore +from PySide2.QtCore import Qt +from PySide2.QtGui import QIcon, QKeySequence +from PySide2.QtWidgets import QCheckBox, QLineEdit, QToolBar, QToolButton +from PySide2.QtWebEngineWidgets import QWebEnginePage + + +# A Find tool bar (bottom area) +class FindToolBar(QToolBar): + + find = QtCore.Signal(str, QWebEnginePage.FindFlags) + + def __init__(self): + super(FindToolBar, self).__init__() + self._line_edit = QLineEdit() + self._line_edit.setClearButtonEnabled(True) + self._line_edit.setPlaceholderText("Find...") + self._line_edit.setMaximumWidth(300) + self._line_edit.returnPressed.connect(self._find_next) + self.addWidget(self._line_edit) + + self._previous_button = QToolButton() + style_icons = ':/qt-project.org/styles/commonstyle/images/' + self._previous_button.setIcon(QIcon(style_icons + 'up-32.png')) + self._previous_button.clicked.connect(self._find_previous) + self.addWidget(self._previous_button) + + self._next_button = QToolButton() + self._next_button.setIcon(QIcon(style_icons + 'down-32.png')) + self._next_button.clicked.connect(self._find_next) + self.addWidget(self._next_button) + + self._case_sensitive_checkbox = QCheckBox('Case Sensitive') + self.addWidget(self._case_sensitive_checkbox) + + self._hideButton = QToolButton() + self._hideButton.setShortcut(QKeySequence(Qt.Key_Escape)) + self._hideButton.setIcon(QIcon(style_icons + 'closedock-16.png')) + self._hideButton.clicked.connect(self.hide) + self.addWidget(self._hideButton) + + def focus_find(self): + self._line_edit.setFocus() + + def _emit_find(self, backward): + needle = self._line_edit.text().strip() + if needle: + flags = QWebEnginePage.FindFlags() + if self._case_sensitive_checkbox.isChecked(): + flags |= QWebEnginePage.FindCaseSensitively + if backward: + flags |= QWebEnginePage.FindBackward + self.find.emit(needle, flags) + + def _find_next(self): + self._emit_find(False) + + def _find_previous(self): + self._emit_find(True) diff --git a/examples/webenginewidgets/tabbedbrowser/historywindow.py b/examples/webenginewidgets/tabbedbrowser/historywindow.py new file mode 100644 index 0000000..6ce7797 --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/historywindow.py @@ -0,0 +1,103 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import QApplication, QTreeView + +from PySide2.QtCore import Signal, QAbstractTableModel, QModelIndex, Qt, QUrl + + +class HistoryModel(QAbstractTableModel): + + def __init__(self, history, parent=None): + super(HistoryModel, self).__init__(parent) + self._history = history + + def headerData(self, section, orientation, role=Qt.DisplayRole): + if orientation == Qt.Horizontal and role == Qt.DisplayRole: + return 'Title' if section == 0 else 'Url' + return None + + def rowCount(self, index=QModelIndex()): + return self._history.count() + + def columnCount(self, index=QModelIndex()): + return 2 + + def item_at(self, model_index): + return self._history.itemAt(model_index.row()) + + def data(self, index, role=Qt.DisplayRole): + item = self.item_at(index) + column = index.column() + if role == Qt.DisplayRole: + return item.title() if column == 0 else item.url().toString() + return None + + def refresh(self): + self.beginResetModel() + self.endResetModel() + + +class HistoryWindow(QTreeView): + + open_url = Signal(QUrl) + + def __init__(self, history, parent): + super(HistoryWindow, self).__init__(parent) + + self._model = HistoryModel(history, self) + self.setModel(self._model) + self.activated.connect(self._activated) + + screen = QApplication.desktop().screenGeometry(parent) + self.resize(screen.width() / 3, screen.height() / 3) + self._adjustSize() + + def refresh(self): + self._model.refresh() + self._adjustSize() + + def _adjustSize(self): + if (self._model.rowCount() > 0): + self.resizeColumnToContents(0) + + def _activated(self, index): + item = self._model.item_at(index) + self.open_url.emit(item.url()) diff --git a/examples/webenginewidgets/tabbedbrowser/main.py b/examples/webenginewidgets/tabbedbrowser/main.py new file mode 100644 index 0000000..438dd5c --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/main.py @@ -0,0 +1,395 @@ + +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 WebEngineWidgets Example""" + +import sys +from bookmarkwidget import BookmarkWidget +from browsertabwidget import BrowserTabWidget +from downloadwidget import DownloadWidget +from findtoolbar import FindToolBar +from webengineview import WebEngineView +from PySide2 import QtCore +from PySide2.QtCore import Qt, QUrl +from PySide2.QtGui import QKeySequence, QIcon +from PySide2.QtWidgets import (QAction, QApplication, QDockWidget, QLabel, + QLineEdit, QMainWindow, QToolBar) +from PySide2.QtWebEngineWidgets import QWebEngineDownloadItem, QWebEnginePage + +main_windows = [] + + +def create_main_window(): + """Creates a MainWindow using 75% of the available screen resolution.""" + main_win = MainWindow() + main_windows.append(main_win) + available_geometry = app.desktop().availableGeometry(main_win) + main_win.resize(available_geometry.width() * 2 / 3, + available_geometry.height() * 2 / 3) + main_win.show() + return main_win + + +def create_main_window_with_browser(): + """Creates a MainWindow with a BrowserTabWidget.""" + main_win = create_main_window() + return main_win.add_browser_tab() + + +class MainWindow(QMainWindow): + """Provides the parent window that includes the BookmarkWidget, + BrowserTabWidget, and a DownloadWidget, to offer the complete + web browsing experience.""" + + def __init__(self): + super(MainWindow, self).__init__() + + self.setWindowTitle('PySide2 tabbed browser Example') + + self._tab_widget = BrowserTabWidget(create_main_window_with_browser) + self._tab_widget.enabled_changed.connect(self._enabled_changed) + self._tab_widget.download_requested.connect(self._download_requested) + self.setCentralWidget(self._tab_widget) + self.connect(self._tab_widget, QtCore.SIGNAL("url_changed(QUrl)"), + self.url_changed) + + self._bookmark_dock = QDockWidget() + self._bookmark_dock.setWindowTitle('Bookmarks') + self._bookmark_widget = BookmarkWidget() + self._bookmark_widget.open_bookmark.connect(self.load_url) + self._bookmark_widget.open_bookmark_in_new_tab.connect(self.load_url_in_new_tab) + self._bookmark_dock.setWidget(self._bookmark_widget) + self.addDockWidget(Qt.LeftDockWidgetArea, self._bookmark_dock) + + self._find_tool_bar = None + + self._actions = {} + self._create_menu() + + self._tool_bar = QToolBar() + self.addToolBar(self._tool_bar) + for action in self._actions.values(): + if not action.icon().isNull(): + self._tool_bar.addAction(action) + + self._addres_line_edit = QLineEdit() + self._addres_line_edit.setClearButtonEnabled(True) + self._addres_line_edit.returnPressed.connect(self.load) + self._tool_bar.addWidget(self._addres_line_edit) + self._zoom_label = QLabel() + self.statusBar().addPermanentWidget(self._zoom_label) + self._update_zoom_label() + + self._bookmarksToolBar = QToolBar() + self.addToolBar(Qt.TopToolBarArea, self._bookmarksToolBar) + self.insertToolBarBreak(self._bookmarksToolBar) + self._bookmark_widget.changed.connect(self._update_bookmarks) + self._update_bookmarks() + + def _update_bookmarks(self): + self._bookmark_widget.populate_tool_bar(self._bookmarksToolBar) + self._bookmark_widget.populate_other(self._bookmark_menu, 3) + + def _create_menu(self): + file_menu = self.menuBar().addMenu("&File") + exit_action = QAction(QIcon.fromTheme("application-exit"), "E&xit", + self, shortcut="Ctrl+Q", triggered=qApp.quit) + file_menu.addAction(exit_action) + + navigation_menu = self.menuBar().addMenu("&Navigation") + + style_icons = ':/qt-project.org/styles/commonstyle/images/' + back_action = QAction(QIcon.fromTheme("go-previous", + QIcon(style_icons + 'left-32.png')), + "Back", self, + shortcut=QKeySequence(QKeySequence.Back), + triggered=self._tab_widget.back) + self._actions[QWebEnginePage.Back] = back_action + back_action.setEnabled(False) + navigation_menu.addAction(back_action) + forward_action = QAction(QIcon.fromTheme("go-next", + QIcon(style_icons + 'right-32.png')), + "Forward", self, + shortcut=QKeySequence(QKeySequence.Forward), + triggered=self._tab_widget.forward) + forward_action.setEnabled(False) + self._actions[QWebEnginePage.Forward] = forward_action + + navigation_menu.addAction(forward_action) + reload_action = QAction(QIcon(style_icons + 'refresh-32.png'), + "Reload", self, + shortcut=QKeySequence(QKeySequence.Refresh), + triggered=self._tab_widget.reload) + self._actions[QWebEnginePage.Reload] = reload_action + reload_action.setEnabled(False) + navigation_menu.addAction(reload_action) + + navigation_menu.addSeparator() + + new_tab_action = QAction("New Tab", self, + shortcut='Ctrl+T', + triggered=self.add_browser_tab) + navigation_menu.addAction(new_tab_action) + + close_tab_action = QAction("Close Current Tab", self, + shortcut="Ctrl+W", + triggered=self._close_current_tab) + navigation_menu.addAction(close_tab_action) + + navigation_menu.addSeparator() + + history_action = QAction("History...", self, + triggered=self._tab_widget.show_history) + navigation_menu.addAction(history_action) + + edit_menu = self.menuBar().addMenu("&Edit") + + find_action = QAction("Find", self, + shortcut=QKeySequence(QKeySequence.Find), + triggered=self._show_find) + edit_menu.addAction(find_action) + + edit_menu.addSeparator() + undo_action = QAction("Undo", self, + shortcut=QKeySequence(QKeySequence.Undo), + triggered=self._tab_widget.undo) + self._actions[QWebEnginePage.Undo] = undo_action + undo_action.setEnabled(False) + edit_menu.addAction(undo_action) + + redo_action = QAction("Redo", self, + shortcut=QKeySequence(QKeySequence.Redo), + triggered=self._tab_widget.redo) + self._actions[QWebEnginePage.Redo] = redo_action + redo_action.setEnabled(False) + edit_menu.addAction(redo_action) + + edit_menu.addSeparator() + + cut_action = QAction("Cut", self, + shortcut=QKeySequence(QKeySequence.Cut), + triggered=self._tab_widget.cut) + self._actions[QWebEnginePage.Cut] = cut_action + cut_action.setEnabled(False) + edit_menu.addAction(cut_action) + + copy_action = QAction("Copy", self, + shortcut=QKeySequence(QKeySequence.Copy), + triggered=self._tab_widget.copy) + self._actions[QWebEnginePage.Copy] = copy_action + copy_action.setEnabled(False) + edit_menu.addAction(copy_action) + + paste_action = QAction("Paste", self, + shortcut=QKeySequence(QKeySequence.Paste), + triggered=self._tab_widget.paste) + self._actions[QWebEnginePage.Paste] = paste_action + paste_action.setEnabled(False) + edit_menu.addAction(paste_action) + + edit_menu.addSeparator() + + select_all_action = QAction("Select All", self, + shortcut=QKeySequence(QKeySequence.SelectAll), + triggered=self._tab_widget.select_all) + self._actions[QWebEnginePage.SelectAll] = select_all_action + select_all_action.setEnabled(False) + edit_menu.addAction(select_all_action) + + self._bookmark_menu = self.menuBar().addMenu("&Bookmarks") + add_bookmark_action = QAction("&Add Bookmark", self, + triggered=self._add_bookmark) + self._bookmark_menu.addAction(add_bookmark_action) + add_tool_bar_bookmark_action = QAction("&Add Bookmark to Tool Bar", self, + triggered=self._add_tool_bar_bookmark) + self._bookmark_menu.addAction(add_tool_bar_bookmark_action) + self._bookmark_menu.addSeparator() + + tools_menu = self.menuBar().addMenu("&Tools") + download_action = QAction("Open Downloads", self, + triggered=DownloadWidget.open_download_directory) + tools_menu.addAction(download_action) + + window_menu = self.menuBar().addMenu("&Window") + + window_menu.addAction(self._bookmark_dock.toggleViewAction()) + + window_menu.addSeparator() + + zoom_in_action = QAction(QIcon.fromTheme("zoom-in"), + "Zoom In", self, + shortcut=QKeySequence(QKeySequence.ZoomIn), + triggered=self._zoom_in) + window_menu.addAction(zoom_in_action) + zoom_out_action = QAction(QIcon.fromTheme("zoom-out"), + "Zoom Out", self, + shortcut=QKeySequence(QKeySequence.ZoomOut), + triggered=self._zoom_out) + window_menu.addAction(zoom_out_action) + + reset_zoom_action = QAction(QIcon.fromTheme("zoom-original"), + "Reset Zoom", self, + shortcut="Ctrl+0", + triggered=self._reset_zoom) + window_menu.addAction(reset_zoom_action) + + about_menu = self.menuBar().addMenu("&About") + about_action = QAction("About Qt", self, + shortcut=QKeySequence(QKeySequence.HelpContents), + triggered=qApp.aboutQt) + about_menu.addAction(about_action) + + def add_browser_tab(self): + return self._tab_widget.add_browser_tab() + + def _close_current_tab(self): + if self._tab_widget.count() > 1: + self._tab_widget.close_current_tab() + else: + self.close() + + def close_event(self, event): + main_windows.remove(self) + event.accept() + + def load(self): + url_string = self._addres_line_edit.text().strip() + if url_string: + self.load_url_string(url_string) + + def load_url_string(self, url_s): + url = QUrl.fromUserInput(url_s) + if (url.isValid()): + self.load_url(url) + + def load_url(self, url): + self._tab_widget.load(url) + + def load_url_in_new_tab(self, url): + self.add_browser_tab().load(url) + + def url_changed(self, url): + self._addres_line_edit.setText(url.toString()) + + def _enabled_changed(self, web_action, enabled): + action = self._actions[web_action] + if action: + action.setEnabled(enabled) + + def _add_bookmark(self): + index = self._tab_widget.currentIndex() + if index >= 0: + url = self._tab_widget.url() + title = self._tab_widget.tabText(index) + icon = self._tab_widget.tabIcon(index) + self._bookmark_widget.add_bookmark(url, title, icon) + + def _add_tool_bar_bookmark(self): + index = self._tab_widget.currentIndex() + if index >= 0: + url = self._tab_widget.url() + title = self._tab_widget.tabText(index) + icon = self._tab_widget.tabIcon(index) + self._bookmark_widget.add_tool_bar_bookmark(url, title, icon) + + def _zoom_in(self): + new_zoom = self._tab_widget.zoom_factor() * 1.5 + if (new_zoom <= WebEngineView.maximum_zoom_factor()): + self._tab_widget.set_zoom_factor(new_zoom) + self._update_zoom_label() + + def _zoom_out(self): + new_zoom = self._tab_widget.zoom_factor() / 1.5 + if (new_zoom >= WebEngineView.minimum_zoom_factor()): + self._tab_widget.set_zoom_factor(new_zoom) + self._update_zoom_label() + + def _reset_zoom(self): + self._tab_widget.set_zoom_factor(1) + self._update_zoom_label() + + def _update_zoom_label(self): + percent = int(self._tab_widget.zoom_factor() * 100) + self._zoom_label.setText("{}%".format(percent)) + + def _download_requested(self, item): + # Remove old downloads before opening a new one + for old_download in self.statusBar().children(): + if (type(old_download).__name__ == 'DownloadWidget' and + old_download.state() != QWebEngineDownloadItem.DownloadInProgress): + self.statusBar().removeWidget(old_download) + del old_download + + item.accept() + download_widget = DownloadWidget(item) + download_widget.remove_requested.connect(self._remove_download_requested, + Qt.QueuedConnection) + self.statusBar().addWidget(download_widget) + + def _remove_download_requested(self): + download_widget = self.sender() + self.statusBar().removeWidget(download_widget) + del download_widget + + def _show_find(self): + if self._find_tool_bar is None: + self._find_tool_bar = FindToolBar() + self._find_tool_bar.find.connect(self._tab_widget.find) + self.addToolBar(Qt.BottomToolBarArea, self._find_tool_bar) + else: + self._find_tool_bar.show() + self._find_tool_bar.focus_find() + + def write_bookmarks(self): + self._bookmark_widget.write_bookmarks() + + +if __name__ == '__main__': + app = QApplication(sys.argv) + main_win = create_main_window() + initial_urls = sys.argv[1:] + if not initial_urls: + initial_urls.append('http://qt.io') + for url in initial_urls: + main_win.load_url_in_new_tab(QUrl.fromUserInput(url)) + exit_code = app.exec_() + main_win.write_bookmarks() + sys.exit(exit_code) diff --git a/examples/webenginewidgets/tabbedbrowser/tabbedbrowser.pyproject b/examples/webenginewidgets/tabbedbrowser/tabbedbrowser.pyproject new file mode 100644 index 0000000..1d26848 --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/tabbedbrowser.pyproject @@ -0,0 +1,5 @@ +{ + "files": ["main.py", "bookmarkwidget.py", "browsertabwidget.py", + "downloadwidget.py", "findtoolbar.py", "historywindow.py", + "webengineview.py"] +} diff --git a/examples/webenginewidgets/tabbedbrowser/webengineview.py b/examples/webenginewidgets/tabbedbrowser/webengineview.py new file mode 100644 index 0000000..81b156f --- /dev/null +++ b/examples/webenginewidgets/tabbedbrowser/webengineview.py @@ -0,0 +1,91 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWebEngineWidgets import QWebEnginePage, QWebEngineView + +from PySide2 import QtCore + +_web_actions = [QWebEnginePage.Back, QWebEnginePage.Forward, + QWebEnginePage.Reload, + QWebEnginePage.Undo, QWebEnginePage.Redo, + QWebEnginePage.Cut, QWebEnginePage.Copy, + QWebEnginePage.Paste, QWebEnginePage.SelectAll] + + +class WebEngineView(QWebEngineView): + + enabled_changed = QtCore.Signal(QWebEnginePage.WebAction, bool) + + @staticmethod + def web_actions(): + return _web_actions + + @staticmethod + def minimum_zoom_factor(): + return 0.25 + + @staticmethod + def maximum_zoom_factor(): + return 5 + + def __init__(self, tab_factory_func, window_factory_func): + super(WebEngineView, self).__init__() + self._tab_factory_func = tab_factory_func + self._window_factory_func = window_factory_func + page = self.page() + self._actions = {} + for web_action in WebEngineView.web_actions(): + action = page.action(web_action) + action.changed.connect(self._enabled_changed) + self._actions[action] = web_action + + def is_web_action_enabled(self, web_action): + return self.page().action(web_action).isEnabled() + + def createWindow(self, window_type): + if (window_type == QWebEnginePage.WebBrowserTab or + window_type == QWebEnginePage.WebBrowserBackgroundTab): + return self._tab_factory_func() + return self._window_factory_func() + + def _enabled_changed(self): + action = self.sender() + web_action = self._actions[action] + self.enabled_changed.emit(web_action, action.isEnabled()) diff --git a/examples/webenginewidgets/webenginewidgets.pyproject b/examples/webenginewidgets/webenginewidgets.pyproject new file mode 100644 index 0000000..6bc12af --- /dev/null +++ b/examples/webenginewidgets/webenginewidgets.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["simplebrowser.py"] +} diff --git a/examples/widgetbinding/CMakeLists.txt b/examples/widgetbinding/CMakeLists.txt new file mode 100644 index 0000000..a557f90 --- /dev/null +++ b/examples/widgetbinding/CMakeLists.txt @@ -0,0 +1,275 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Enable policy to not use RPATH settings for install_name on macOS. +if(POLICY CMP0068) + cmake_policy(SET CMP0068 NEW) +endif() + +# Enable policy to run automoc on generated files. +if(POLICY CMP0071) + cmake_policy(SET CMP0071 NEW) +endif() + +# Consider changing the project name to something relevant for you. +project(wiggly LANGUAGES CXX) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +set(CMAKE_AUTOMOC ON) +find_package(Qt5 5.12 REQUIRED COMPONENTS Core Gui Widgets) + +# ================================ General configuration ====================================== + +# Set CPP standard to C++11 minimum. +set(CMAKE_CXX_STANDARD 11) + +# The wiggly library for which we will create bindings. You can change the name to something +# relevant for your project. +set(wiggly_library "libwiggly") + +# The name of the generated bindings module (as imported in Python). You can change the name +# to something relevant for your project. +set(bindings_library "wiggly") + +# The header file with all the types and functions for which bindings will be generated. +# Usually it simply includes other headers of the library you are creating bindings for. +set(wrapped_header ${CMAKE_SOURCE_DIR}/bindings.h) + +# The typesystem xml file which defines the relationships between the C++ types / functions +# and the corresponding Python equivalents. +set(typesystem_file ${CMAKE_SOURCE_DIR}/bindings.xml) + +# Specify which C++ files will be generated by shiboken. This includes the module wrapper +# and a '.cpp' file per C++ type. These are needed for generating the module shared +# library. +set(generated_sources + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/wiggly_module_wrapper.cpp + ${CMAKE_CURRENT_BINARY_DIR}/${bindings_library}/wigglywidget_wrapper.cpp) + + +# ================================== Shiboken detection ====================================== +# Use provided python interpreter if given. +if(NOT python_interpreter) + find_program(python_interpreter "python") +endif() +message(STATUS "Using python interpreter: ${python_interpreter}") + +# Macro to get various pyside / python include / link flags and paths. +# Uses the not entirely supported utils/pyside2_config.py file. +macro(pyside2_config option output_var) + if(${ARGC} GREATER 2) + set(is_list ${ARGV2}) + else() + set(is_list "") + endif() + + execute_process( + COMMAND ${python_interpreter} "${CMAKE_SOURCE_DIR}/../utils/pyside2_config.py" + ${option} + OUTPUT_VARIABLE ${output_var} + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if ("${${output_var}}" STREQUAL "") + message(FATAL_ERROR "Error: Calling pyside2_config.py ${option} returned no output.") + endif() + if(is_list) + string (REPLACE " " ";" ${output_var} "${${output_var}}") + endif() +endmacro() + +# Query for the shiboken generator path, Python path, include paths and linker flags. +pyside2_config(--shiboken2-module-path shiboken2_module_path) +pyside2_config(--shiboken2-generator-path shiboken2_generator_path) +pyside2_config(--pyside2-path pyside2_path) +pyside2_config(--pyside2-include-path pyside2_include_dir 1) +pyside2_config(--python-include-path python_include_dir) +pyside2_config(--shiboken2-generator-include-path shiboken_include_dir 1) +pyside2_config(--shiboken2-module-shared-libraries-cmake shiboken_shared_libraries 0) +pyside2_config(--python-link-flags-cmake python_linking_data 0) +pyside2_config(--pyside2-shared-libraries-cmake pyside2_shared_libraries 0) + +set(shiboken_path "${shiboken2_generator_path}/shiboken2${CMAKE_EXECUTABLE_SUFFIX}") +if(NOT EXISTS ${shiboken_path}) + message(FATAL_ERROR "Shiboken executable not found at path: ${shiboken_path}") +endif() + + +# ==================================== RPATH configuration ==================================== + + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Enable rpaths so that the built shared libraries find their dependencies. +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) +set(CMAKE_INSTALL_RPATH ${shiboken2_module_path} ${CMAKE_CURRENT_SOURCE_DIR}) +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= + + +# =============================== CMake target - wiggly_library =============================== + + +# Get all relevant Qt include dirs, to pass them on to shiboken. +get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_GUI_INCLUDE_DIRS TARGET Qt5::Gui PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +get_property(QT_WIDGETS_INCLUDE_DIRS TARGET Qt5::Widgets PROPERTY INTERFACE_INCLUDE_DIRECTORIES) +set(QT_INCLUDE_DIRS ${QT_CORE_INCLUDE_DIRS} ${QT_GUI_INCLUDE_DIRS} ${QT_WIDGETS_INCLUDE_DIRS}) +set(INCLUDES "") +foreach(INCLUDE_DIR ${QT_INCLUDE_DIRS}) + list(APPEND INCLUDES "-I${INCLUDE_DIR}") +endforeach() + +# On macOS, check if Qt is a framework build. This affects how include paths should be handled. +get_target_property(QtCore_is_framework Qt5::Core FRAMEWORK) +if (QtCore_is_framework) + get_target_property(qt_core_library_location Qt5::Core LOCATION) + get_filename_component(qt_core_library_location_dir "${qt_core_library_location}" DIRECTORY) + get_filename_component(lib_dir "${qt_core_library_location_dir}/../" ABSOLUTE) + list(APPEND INCLUDES "--framework-include-paths=${lib_dir}") +endif() + +# We need to include the headers for the module bindings that we use. +set(pyside2_additional_includes "") +foreach(INCLUDE_DIR ${pyside2_include_dir}) + list(APPEND pyside2_additional_includes "${INCLUDE_DIR}/QtCore") + list(APPEND pyside2_additional_includes "${INCLUDE_DIR}/QtGui") + list(APPEND pyside2_additional_includes "${INCLUDE_DIR}/QtWidgets") +endforeach() + + +# Define the wiggly shared library for which we will create bindings. +set(${wiggly_library}_sources wigglywidget.cpp) +add_library(${wiggly_library} SHARED ${${wiggly_library}_sources}) +set_property(TARGET ${wiggly_library} PROPERTY PREFIX "") + +# Needed mostly on Windows to export symbols, and create a .lib file, otherwise the binding +# library can't link to the wiggly library. +target_compile_definitions(${wiggly_library} PRIVATE BINDINGS_BUILD) + + +# ====================== Shiboken target for generating binding C++ files ==================== + + +# Set up the options to pass to shiboken. +set(shiboken_options --generator-set=shiboken --enable-parent-ctor-heuristic + --enable-pyside-extensions --enable-return-value-heuristic --use-isnull-as-nb_nonzero + --avoid-protected-hack + ${INCLUDES} + -I${CMAKE_SOURCE_DIR} + -T${CMAKE_SOURCE_DIR} + -T${pyside2_path}/typesystems + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + ) + +set(generated_sources_dependencies ${wrapped_header} ${typesystem_file}) + +# Add custom target to run shiboken to generate the binding cpp files. +add_custom_command(OUTPUT ${generated_sources} + COMMAND ${shiboken_path} + ${shiboken_options} ${wrapped_header} ${typesystem_file} + DEPENDS ${generated_sources_dependencies} + #IMPLICIT_DEPENDS CXX ${wrapped_header} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Running generator for ${typesystem_file}.") + + +# =============================== CMake target - bindings_library ============================= + + +# Set the cpp files which will be used for the bindings library. +set(${bindings_library}_sources ${generated_sources}) + +# Define and build the bindings library. +add_library(${bindings_library} SHARED ${${bindings_library}_sources}) + + +# Apply relevant include and link flags. +target_include_directories(${bindings_library} PRIVATE ${pyside2_additional_includes}) +target_include_directories(${bindings_library} PRIVATE ${pyside2_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${python_include_dir}) +target_include_directories(${bindings_library} PRIVATE ${shiboken_include_dir}) + +target_link_libraries(${wiggly_library} PRIVATE Qt5::Widgets) +target_link_libraries(${bindings_library} PRIVATE Qt5::Widgets) +target_link_libraries(${bindings_library} PRIVATE ${wiggly_library}) +target_link_libraries(${bindings_library} PRIVATE ${pyside2_shared_libraries}) +target_link_libraries(${bindings_library} PRIVATE ${shiboken_shared_libraries}) + +# Adjust the name of generated module. +set_property(TARGET ${bindings_library} PROPERTY PREFIX "") +set_property(TARGET ${bindings_library} PROPERTY OUTPUT_NAME + "${bindings_library}${PYTHON_EXTENSION_SUFFIX}") +if(WIN32) + set_property(TARGET ${bindings_library} PROPERTY SUFFIX ".pyd") +endif() + +# Make sure the linker doesn't complain about not finding Python symbols on macOS. +if(APPLE) + set_target_properties(${bindings_library} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup") +endif(APPLE) + +# Find and link to the python import library only on Windows. +# On Linux and macOS, the undefined symbols will get resolved by the dynamic linker +# (the symbols will be picked up in the Python executable). +if (WIN32) + list(GET python_linking_data 0 python_libdir) + list(GET python_linking_data 1 python_lib) + find_library(python_link_flags ${python_lib} PATHS ${python_libdir} HINTS ${python_libdir}) + target_link_libraries(${bindings_library} PRIVATE ${python_link_flags}) +endif() + +# ================================= Dubious deployment section ================================ + +set(windows_shiboken_shared_libraries) + +if(WIN32) + # ========================================================================================= + # !!! (The section below is deployment related, so in a real world application you will + # want to take care of this properly (this is simply to eliminate errors that users usually + # encounter. + # ========================================================================================= + # Circumvent some "#pragma comment(lib)"s in "include/pyconfig.h" which might force to link + # against a wrong python shared library. + + set(python_versions_list 3 32 33 34 35 36 37 38) + set(python_additional_link_flags "") + foreach(ver ${python_versions_list}) + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}_d.lib\"") + set(python_additional_link_flags + "${python_additional_link_flags} /NODEFAULTLIB:\"python${ver}.lib\"") + endforeach() + + set_target_properties(${bindings_library} + PROPERTIES LINK_FLAGS "${python_additional_link_flags}") + + # Compile a list of shiboken shared libraries to be installed, so that + # the user doesn't have to set the PATH manually to point to the PySide2 package. + foreach(library_path ${shiboken_shared_libraries}) + string(REGEX REPLACE ".lib$" ".dll" library_path ${library_path}) + file(TO_CMAKE_PATH ${library_path} library_path) + list(APPEND windows_shiboken_shared_libraries "${library_path}") + endforeach() + # ========================================================================================= + # !!! End of dubious section. + # ========================================================================================= +endif() + +# ============================================================================================= +# !!! (The section below is deployment related, so in a real world application you will want to +# take care of this properly with some custom script or tool). +# ============================================================================================= +# Install the library and the bindings module into the source folder near the main.py file, so +# that the Python interpeter successfully imports the used module. +install(TARGETS ${bindings_library} ${wiggly_library} + LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} + ) +install(FILES ${windows_shiboken_shared_libraries} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}) +# ============================================================================================= +# !!! End of dubious section. +# ============================================================================================= diff --git a/examples/widgetbinding/README.md b/examples/widgetbinding/README.md new file mode 100644 index 0000000..f58a496 --- /dev/null +++ b/examples/widgetbinding/README.md @@ -0,0 +1,74 @@ +# WigglyWidget + +The original Qt/C++ example can be found here: +https://doc.qt.io/qt-5/qtwidgets-widgets-wiggly-example.html + +This example shows how to interact with a custom widget from two +different ways: + + * A full Python translation from a C++ example, + * A Python binding generated from the C++ file. + + +The original example contained three different files: + * `main.cpp/h`, which was translated to `main.py`, + * `dialog.cpp/h`, which was translated to `dialog.py`, + * `wigglywidget.cpp/h`, which was translated to `wigglywidget.py`, + but also remains as is, to enable the binding generation through + Shiboken. + +In the `dialog.py` file you will find two imports that will be related +to each of the two approaches described before:: + + + # Python translated file + from wigglywidget import WigglyWidget + + # Binding module create with Shiboken + from wiggly import WigglyWidget + + +## Steps to build the bindings + +The most important files are: + * `bindings.xml`, to specify the class that we want to expose from C++ + to Python, + * `bindings.h` to include the header of the classes we want to expose + * `CMakeList.txt`, with all the instructions to build the shared libraries + (DLL, or dylib) + * `pyside2_config.py` which is located in the utils directory, one level + up, to get the path for Shiboken and PySide. + +Now create a `build/` directory, and from inside run `cmake ..` to use +the provided `CMakeLists.txt`. +To build, just run `make`, and `make install` to copy the generated files +to the main example directory to be able to run the final example: +`python main.py`. +You should be able to see two identical custom widgets, one being the +Python translation, and the other one being the C++ one. + +### Windows + +For windows it's recommended to use either `nmake`, `jom` or `ninja`, +when running cmake. + +```bash +cmake -H.. -B. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release # for nmake +cmake -H.. -B. -G "NMake Makefiles JOM" -DCMAKE_BUILD_TYPE=Release # for jom +cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release # for ninja +``` + +### Linux, macOS + +Generally using `make` will be enough, but as in the Windows case, you can use +ninja to build the project. + +```bash +cmake -H.. -B. -G Ninja -DCMAKE_BUILD_TYPE=Release +``` + +## Final words + +Since this example originated by mixing the concepts of the `scriptableapplication` +and `samplebinding` examples, you can complement this README with the ones in +those directories. diff --git a/examples/widgetbinding/bindings.h b/examples/widgetbinding/bindings.h new file mode 100644 index 0000000..d592226 --- /dev/null +++ b/examples/widgetbinding/bindings.h @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BINDINGS_H +#define BINDINGS_H +#include "wigglywidget.h" +#endif // BINDINGS_H diff --git a/examples/widgetbinding/bindings.xml b/examples/widgetbinding/bindings.xml new file mode 100644 index 0000000..07f1c89 --- /dev/null +++ b/examples/widgetbinding/bindings.xml @@ -0,0 +1,56 @@ + + + + + + diff --git a/examples/widgetbinding/dialog.py b/examples/widgetbinding/dialog.py new file mode 100644 index 0000000..e521559 --- /dev/null +++ b/examples/widgetbinding/dialog.py @@ -0,0 +1,77 @@ +############################################################################ +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtWidgets import QDialog, QLineEdit, QVBoxLayout + +# Python binding from the C++ widget +from wiggly import WigglyWidget as WigglyWidgetCPP + +# Python-only widget +from wigglywidget import WigglyWidget as WigglyWidgetPY + + +class Dialog(QDialog): + def __init__(self, parent=None): + super(Dialog, self).__init__(parent) + wiggly_widget_py = WigglyWidgetPY(self) + wiggly_widget_cpp = WigglyWidgetCPP(self) + lineEdit = QLineEdit(self) + + layout = QVBoxLayout(self) + layout.addWidget(wiggly_widget_py) + layout.addWidget(wiggly_widget_cpp) + layout.addWidget(lineEdit) + + lineEdit.textChanged.connect(wiggly_widget_py.setText) + lineEdit.textChanged.connect(wiggly_widget_cpp.setText) + lineEdit.setText("Hello world!") + + self.setWindowTitle("Wiggly") + self.resize(360, 145) diff --git a/examples/widgetbinding/macros.h b/examples/widgetbinding/macros.h new file mode 100644 index 0000000..224fada --- /dev/null +++ b/examples/widgetbinding/macros.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt for Python examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MACROS_H +#define MACROS_H + +#include + +// Export symbols when creating .dll and .lib, and import them when using .lib. +#if BINDINGS_BUILD +# define BINDINGS_API Q_DECL_EXPORT +#else +# define BINDINGS_API Q_DECL_IMPORT +#endif + +#endif // MACROS_H diff --git a/examples/widgetbinding/main.py b/examples/widgetbinding/main.py new file mode 100644 index 0000000..556eb26 --- /dev/null +++ b/examples/widgetbinding/main.py @@ -0,0 +1,61 @@ +############################################################################ +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +import sys + +from PySide2.QtWidgets import QApplication + +from dialog import Dialog + +if __name__ == "__main__": + app = QApplication() + w = Dialog() + w.show() + sys.exit(app.exec_()) diff --git a/examples/widgetbinding/wigglywidget.cpp b/examples/widgetbinding/wigglywidget.cpp new file mode 100644 index 0000000..ab549ef --- /dev/null +++ b/examples/widgetbinding/wigglywidget.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "wigglywidget.h" + +#include +#include +#include + +//! [0] +WigglyWidget::WigglyWidget(QWidget *parent) + : QWidget(parent), step(0) +{ + setBackgroundRole(QPalette::Midlight); + setAutoFillBackground(true); + + QFont newFont = font(); + newFont.setPointSize(newFont.pointSize() + 20); + setFont(newFont); + + timer.start(60, this); +} +//! [0] + +//! [1] +void WigglyWidget::paintEvent(QPaintEvent * /* event */) +//! [1] //! [2] +{ + static constexpr int sineTable[16] = { + 0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, -92, -71, -38 + }; + + QFontMetrics metrics(font()); + int x = (width() - metrics.horizontalAdvance(text)) / 2; + int y = (height() + metrics.ascent() - metrics.descent()) / 2; + QColor color; +//! [2] + +//! [3] + QPainter painter(this); +//! [3] //! [4] + for (int i = 0; i < text.size(); ++i) { + int index = (step + i) % 16; + color.setHsv((15 - index) * 16, 255, 191); + painter.setPen(color); + painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), + QString(text[i])); + x += metrics.horizontalAdvance(text[i]); + } +} +//! [4] + +//! [5] +void WigglyWidget::timerEvent(QTimerEvent *event) +//! [5] //! [6] +{ + if (event->timerId() == timer.timerId()) { + ++step; + update(); + } else { + QWidget::timerEvent(event); + } +//! [6] +} diff --git a/examples/widgetbinding/wigglywidget.h b/examples/widgetbinding/wigglywidget.h new file mode 100644 index 0000000..d08db05 --- /dev/null +++ b/examples/widgetbinding/wigglywidget.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WIGGLYWIDGET_H +#define WIGGLYWIDGET_H + +#include "macros.h" + +#include +#include + +//! [0] +class BINDINGS_API WigglyWidget : public QWidget +{ + Q_OBJECT + +public: + WigglyWidget(QWidget *parent = nullptr); + +public slots: + void setText(const QString &newText) { text = newText; } + +protected: + void paintEvent(QPaintEvent *event) override; + void timerEvent(QTimerEvent *event) override; + +private: + QBasicTimer timer; + QString text; + int step; +}; +//! [0] + +#endif diff --git a/examples/widgetbinding/wigglywidget.py b/examples/widgetbinding/wigglywidget.py new file mode 100644 index 0000000..50a0610 --- /dev/null +++ b/examples/widgetbinding/wigglywidget.py @@ -0,0 +1,97 @@ +############################################################################ +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtCore import QBasicTimer +from PySide2.QtGui import QColor, QFontMetrics, QPainter, QPalette +from PySide2.QtWidgets import QWidget + + +class WigglyWidget(QWidget): + def __init__(self, parent=None): + super(WigglyWidget, self).__init__(parent) + self.step = 0 + self.text = "" + self.setBackgroundRole(QPalette.Midlight) + self.setAutoFillBackground(True) + + newFont = self.font() + newFont.setPointSize(newFont.pointSize() + 20) + self.setFont(newFont) + + self.timer = QBasicTimer() + self.timer.start(60, self) + + def paintEvent(self, event): + sineTable = [0, 38, 71, 92, 100, 92, 71, 38, 0, -38, -71, -92, -100, + -92, -71, -38] + + metrics = QFontMetrics(self.font()) + x = (self.width() - metrics.horizontalAdvance(self.text)) / 2 + y = (self.height() + metrics.ascent() - metrics.descent()) / 2 + color = QColor() + + painter = QPainter(self) + for i in range(len(self.text)): + index = (self.step + i) % 16 + color.setHsv((15 - index) * 16, 255, 191) + painter.setPen(color) + painter.drawText(x, y - ((sineTable[index] * metrics.height()) / 400), + str(self.text[i])) + x += metrics.horizontalAdvance(self.text[i]) + + def timerEvent(self, event): + if event.timerId() == self.timer.timerId(): + self.step += 1 + self.update() + else: + QWidget.timerEvent(event) + + def setText(self, text): + self.text = text diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.py b/examples/widgets/animation/animatedtiles/animatedtiles.py new file mode 100644 index 0000000..b156351 --- /dev/null +++ b/examples/widgets/animation/animatedtiles/animatedtiles.py @@ -0,0 +1,259 @@ + +############################################################################# +## +## Copyright (C) 2010 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtGui, QtWidgets + +import animatedtiles_rc + + +# Deriving from more than one wrapped class is not supported, so we use +# composition and delegate the property. +class Pixmap(QtCore.QObject): + def __init__(self, pix): + super(Pixmap, self).__init__() + + self.pixmap_item = QtWidgets.QGraphicsPixmapItem(pix) + self.pixmap_item.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) + + def set_pos(self, pos): + self.pixmap_item.setPos(pos) + + def get_pos(self): + return self.pixmap_item.pos() + + pos = QtCore.Property(QtCore.QPointF, get_pos, set_pos) + + +class Button(QtWidgets.QGraphicsWidget): + pressed = QtCore.Signal() + + def __init__(self, pixmap, parent=None): + super(Button, self).__init__(parent) + + self._pix = pixmap + + self.setAcceptHoverEvents(True) + self.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) + + def boundingRect(self): + return QtCore.QRectF(-65, -65, 130, 130) + + def shape(self): + path = QtGui.QPainterPath() + path.addEllipse(self.boundingRect()) + + return path + + def paint(self, painter, option, widget): + down = option.state & QtWidgets.QStyle.State_Sunken + r = self.boundingRect() + + grad = QtGui.QLinearGradient(r.topLeft(), r.bottomRight()) + if option.state & QtWidgets.QStyle.State_MouseOver: + color_0 = QtCore.Qt.white + else: + color_0 = QtCore.Qt.lightGray + + color_1 = QtCore.Qt.darkGray + + if down: + color_0, color_1 = color_1, color_0 + + grad.setColorAt(0, color_0) + grad.setColorAt(1, color_1) + + painter.setPen(QtCore.Qt.darkGray) + painter.setBrush(grad) + painter.drawEllipse(r) + + color_0 = QtCore.Qt.darkGray + color_1 = QtCore.Qt.lightGray + + if down: + color_0, color_1 = color_1, color_0 + + grad.setColorAt(0, color_0) + grad.setColorAt(1, color_1) + + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(grad) + + if down: + painter.translate(2, 2) + + painter.drawEllipse(r.adjusted(5, 5, -5, -5)) + painter.drawPixmap(-self._pix.width() / 2, -self._pix.height() / 2, + self._pix) + + def mousePressEvent(self, ev): + self.pressed.emit() + self.update() + + def mouseReleaseEvent(self, ev): + self.update() + + +class View(QtWidgets.QGraphicsView): + def resizeEvent(self, event): + super(View, self).resizeEvent(event) + self.fitInView(self.sceneRect(), QtCore.Qt.KeepAspectRatio) + + +if __name__ == '__main__': + + import sys + import math + + app = QtWidgets.QApplication(sys.argv) + + kineticPix = QtGui.QPixmap(':/images/kinetic.png') + bgPix = QtGui.QPixmap(':/images/Time-For-Lunch-2.jpg') + + scene = QtWidgets.QGraphicsScene(-350, -350, 700, 700) + + items = [] + for i in range(64): + item = Pixmap(kineticPix) + item.pixmap_item.setOffset(-kineticPix.width() / 2, + -kineticPix.height() / 2) + item.pixmap_item.setZValue(i) + items.append(item) + scene.addItem(item.pixmap_item) + + # Buttons. + buttonParent = QtWidgets.QGraphicsRectItem() + ellipseButton = Button(QtGui.QPixmap(':/images/ellipse.png'), buttonParent) + figure8Button = Button(QtGui.QPixmap(':/images/figure8.png'), buttonParent) + randomButton = Button(QtGui.QPixmap(':/images/random.png'), buttonParent) + tiledButton = Button(QtGui.QPixmap(':/images/tile.png'), buttonParent) + centeredButton = Button(QtGui.QPixmap(':/images/centered.png'), buttonParent) + + ellipseButton.setPos(-100, -100) + figure8Button.setPos(100, -100) + randomButton.setPos(0, 0) + tiledButton.setPos(-100, 100) + centeredButton.setPos(100, 100) + + scene.addItem(buttonParent) + buttonParent.setTransform(QtGui.QTransform().scale(0.75, 0.75)) + buttonParent.setPos(200, 200) + buttonParent.setZValue(65) + + # States. + rootState = QtCore.QState() + ellipseState = QtCore.QState(rootState) + figure8State = QtCore.QState(rootState) + randomState = QtCore.QState(rootState) + tiledState = QtCore.QState(rootState) + centeredState = QtCore.QState(rootState) + + # Values. + for i, item in enumerate(items): + # Ellipse. + ellipseState.assignProperty(item, 'pos', + QtCore.QPointF(math.cos((i / 63.0) * 6.28) * 250, + math.sin((i / 63.0) * 6.28) * 250)) + + # Figure 8. + figure8State.assignProperty(item, 'pos', + QtCore.QPointF(math.sin((i / 63.0) * 6.28) * 250, + math.sin(((i * 2)/63.0) * 6.28) * 250)) + + # Random. + randomState.assignProperty(item, 'pos', + QtCore.QPointF(-250 + QtCore.qrand() % 500, + -250 + QtCore.qrand() % 500)) + + # Tiled. + tiledState.assignProperty(item, 'pos', + QtCore.QPointF(((i % 8) - 4) * kineticPix.width() + kineticPix.width() / 2, + ((i // 8) - 4) * kineticPix.height() + kineticPix.height() / 2)) + + # Centered. + centeredState.assignProperty(item, 'pos', QtCore.QPointF()) + + # Ui. + view = View(scene) + view.setWindowTitle("Animated Tiles") + view.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate) + view.setBackgroundBrush(QtGui.QBrush(bgPix)) + view.setCacheMode(QtWidgets.QGraphicsView.CacheBackground) + view.setRenderHints( + QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform) + view.show() + + states = QtCore.QStateMachine() + states.addState(rootState) + states.setInitialState(rootState) + rootState.setInitialState(centeredState) + + group = QtCore.QParallelAnimationGroup() + for i, item in enumerate(items): + anim = QtCore.QPropertyAnimation(item, b'pos') + anim.setDuration(750 + i * 25) + anim.setEasingCurve(QtCore.QEasingCurve.InOutBack) + group.addAnimation(anim) + + trans = rootState.addTransition(ellipseButton.pressed, ellipseState) + trans.addAnimation(group) + + trans = rootState.addTransition(figure8Button.pressed, figure8State) + trans.addAnimation(group) + + trans = rootState.addTransition(randomButton.pressed, randomState) + trans.addAnimation(group) + + trans = rootState.addTransition(tiledButton.pressed, tiledState) + trans.addAnimation(group) + + trans = rootState.addTransition(centeredButton.pressed, centeredState) + trans.addAnimation(group) + + timer = QtCore.QTimer() + timer.start(125) + timer.setSingleShot(True) + trans = rootState.addTransition(timer.timeout, ellipseState) + trans.addAnimation(group) + + states.start() + + sys.exit(app.exec_()) diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.pyproject b/examples/widgets/animation/animatedtiles/animatedtiles.pyproject new file mode 100644 index 0000000..08ee556 --- /dev/null +++ b/examples/widgets/animation/animatedtiles/animatedtiles.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["animatedtiles.qrc", "animatedtiles.py", + "animatedtiles_rc.py"] +} diff --git a/examples/widgets/animation/animatedtiles/animatedtiles.qrc b/examples/widgets/animation/animatedtiles/animatedtiles.qrc new file mode 100644 index 0000000..c43a979 --- /dev/null +++ b/examples/widgets/animation/animatedtiles/animatedtiles.qrc @@ -0,0 +1,11 @@ + + + images/Time-For-Lunch-2.jpg + images/centered.png + images/ellipse.png + images/figure8.png + images/kinetic.png + images/random.png + images/tile.png + + diff --git a/examples/widgets/animation/animatedtiles/animatedtiles_rc.py b/examples/widgets/animation/animatedtiles/animatedtiles_rc.py new file mode 100644 index 0000000..d081986 --- /dev/null +++ b/examples/widgets/animation/animatedtiles/animatedtiles_rc.py @@ -0,0 +1,6108 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x006\xe2\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00d\x00\x00\x00d\x08\x06\x00\x00\x00p\xe2\x95T\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\ +\x95+\x0e\x1b\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e\x1c$|\x1a\xa6\xff\x00\x00 \x00IDATx\ +\xda\xed\x9dw\x98\x9de\x9d\xf7?\xf7SN\x9f\x993\ +3\x99Lf\x122\xa9\xa4\x03\x91\x90\x10j\xe8H\xd9\ +\x05\xa5\x88\xc8\xba\xeb\xcb\xb2\xae\x04QW_W]]\ +v]EQVPqYu\xa5Y\xc0\x12:\x16\x88\ +\x94\x00\x09)\xa4M\xea\xb4L\xa6\xcf\x9c9\xbd=\xf5\ +~\xff8\xf3<\x99A\x944}\xdf\xeb\xbd\xb8\xaf+\ +W2\xc9\xc9y\xca\xf7\xfe\xb5\xef\xaf\xdc\xf0\xeezw\ +\xbd\xbb\xde]\xef\xaew\xd7\xbb\xeb\xdd\xf5\xeezw\xfd\ +\x7f\xbf\xc4\xb1\xfc\xe7\xba\xba\xba\xab\x0c\xc3\x08N\x992\ +\xe5s+W\xae;\xf4\xe8$\xdc\xa2\x8a\xeb\ +\xbaH)1\x0c\x03!\x04RJ,\xcb\xc2u]a\ +\x18\x06\x9a\xa6\x01\xb8\x7f\x11\x95U.\x97\x1b\x1a\x1a\x1a\ +\x08\x85B\xe4\xf3y\x0c\xc3\xf0o\xceq\x1c\x1c\xc7\xf1\ +o4\x10\x08T\xc0\x11\x82^{\x84\xf3bM\xb8F\ +\x90%KNa\xe7\xe4W\x89\x08\x89\xa2\xe8\xa4_\xae\ +\xa2\xb0'\x8c\x94\x12\xd7u\xff\xec D\xa3\xd1\xb3\xae\ +\xb9\xe6\x9au\xa5R\xa9\xf2B])C\xf5B\xb8)\ +\x9d\x19\xbbNat\x97\xacH\xf0[\xe4\xb4m\xef.\ +f\xcc\x98\xe1\x032^B\xca\xe5\xb2\xbf1\xa5\x94\x94\ +\xcb\xe5\x8fWUU]WUU\xf5@\x7f\x7f\xff\xa6\ +?\xab\x0d\xb1m\x1b\xc30|i\xf0n\xc4q\x1c\x7f\ +\xb7\x09!PU\x15\xcb\xb2\x90\xaeK}:\xc4\xc1\xa7\ +\x15N\x08.&W?\x05;1\x17\xac0I:)\ +\x0c\x988y\xc7\x07\xe4\xec\xb3\xcf\xfe\x1f)e \x99\ +L\x86{{{\xff6\x9b\xcd\xe6\x8f' R\xca\xb0\ +\xaa\xaa\x15\x89\x96\x92]\x93w\x8a\xf3\xaf\xac\xc3\x956\ +vVCd\xc3\xd8Y\x0d'\xabQ\xde\x1fA:\xc2\ +\x97\xa6r\xb9\x8c\xa2TT\x97\x07\x88'!\x8e\xe3T\ +\x9eWJ\xb9j\xd5\xaa\xab\x9b\x9b\x9by\xf0\xc1\x07\xd7\ +\x03\x7f\x1e@\xa6M\x9b\xb6\xb0T*\xcd\xb7m\x1b)\ +%\x8e\xe3LPY\x8e\xe3\x00\xf8*K\xd34\xff3\ +\x0b\x1bf\x13MU\x91$Aw\x7f7\xf1\xf7\x14\xd0\ +\xcc\x00\xd1D\x9cH\xbd\x86\xac\x11HC\x01W\x80\xe0\ +#\x00\xe1p\x98\xdd\xbbw\x7f\x148&@\x9a\x9a\x9a\ +\x18\x18\x18\x18\x0f\x884M\x13\xd341]\x9bX\xb5\ +\x0e\xb6\xc2\xf2\xc9\xef\xa7\xaa%\xc4K\x9d\xbfb\xfa\xbc\ +&\x86\x8c.\xf2\x1d*N\xa9\x02\x80\xf7\x9c\xe3\xed\x86\ +\xf7gO2\xc6\xde\x87\xc8f\xb3D\xa3Q\x14E\x91\ +\x7f6\x95U[[\xbbf\xd9\xb2e\xf3\xd2\xe9\xb4o\ +/\x1c\xa7\xb2\xb3=/+\x18\x0c2f\xf0\x09\x06\x83\ +\xb8\xae\x8beY\xbe\xb1WQ\xd8\x17\xee\xe0\xc2\x05\xd5\ +@\xf1-\x0a]\x92^WC\xb9-\x02\x80eY\xc7\ +E\x22\x06\x06\x06hjj\x9a\x04,\x01\x1c\xc30N\ +N$\x12d\xb3Yl\x5c\xec\x11\x9b\x9d\xcf\x17\xb8\xf2\ +}\xf3y\xfa\xd55\xcck\xbe\x82\xf7\xd4\xaf\xe4\xbf\xb6\ +\x7f\x8al*\x87.\xc3\xbe\x9b\xeb\x01\x02P(\x14p\ +\x1c\x07\xd7u)\x95J\x9e\xed\xc0\xf3\x1c=M\xf1g\ +\x03DJ\xa9\x14\x0a\x05\x1f\x08\xdb\xb6\xc9\xe5r\xd8\xb6\ +M>\x9f\xf7uk\xa9TBQ\x14\xc2\xe10\xb6m\ +c\xdb\xf6\xa1\x87\x91\x02\xc2\x15\xf1\xff\xc8\xc2\xbb\x91\x8a\ +K\xda\xedd\xe3\xd6.\x92U\xeb\x18\x1d\xfb\x9c\xb7#\ +\x8f\xd7*\x95J7\x9f\x7f\xfe\xf9w\xaa\xaa\x8a@\x90\ +03L?\xbd\x1aw8\x8c3\xda\x82H\xc3\x8f\xbe\ +\xf3S\x14U\xf0\x1a[xUn&\xa0\xcd'\x9fl\ +'\x1aU\x91Rz\xb6\xc1\x07\xa4X,\xfa\xef\x22\x9b\ +\xcd\x12\x8b\xc5|0\xc6IKc,\x16\x9b\x95\xcf\xe7\ +;\xff\x1c\x80\xf8/\xd8\xb2,l\xdb\xf6_\x9e\xa6i\ +>\x10\xaa\xaa\xfa\xdeK\xb1X\xf4\x8d\xbd'!X\x92\ +\xd1^\x83\xa9\xef\x99\xcbu?Z\xca\xcf>\xb2\x81\xa6\ +\x93\xd2\xac\xed\xc9\xb2'\xfb*\xf9\x9c\xe9\xab>\xa0\xce\ +\xbb\xfe\xf4\xe9\xd3\x93\x07\x0f\x1et\x8f\xd2nD\xbd\x0d\ +StM\xb4s\xfa\xa9\x9d\x1f\xc1\x92\x83H\x1bD6\ +\x86\x9dQqR:\xf9-\xd5\xa0H\x1ci\xfb\xb6\xc2\ +\x93\x90T*\x85\xaa\xaa8\x8e\xe3\xc5\x1f\x08!\xd04\ +\x0dEQ\xc8\xe5r\x04\x83A\x22\x91\x08\xa6i\xca\x93\ +O>\xf9\x9b\xaa\xaa\xde\xf1\xca+\xafT\xfd9\x00\x91\ +\x1e\x10\xdeNQ\x14\x05\xdb\xb6\x994i\x127\xddt\ +\x13\xdf\xf9\xcew\xa8\xad\xade\xfa\xf4\xe9tuu\x91\ +\xcdf}c\xed8\x0e\x96\x10\xa8\xdb\x5c\x8a\xf9\xa9\xdc\ +\xf4\xab\x0fP\x1b8\x95\x9b\xd6\xdd\x88\xae\xa9\xa8v\x08\ +Mk$^\xe3\xc7(\xf2\xca+\xaf\xdc\xe7\xfd\xff\xf5\ +\xeb\xd7\xcf\x07\xf6\x1d\xad\x94x*\xc4tM\xe2\xe1\x00\ +\x85\x8c\xcbM'\xdf\x81\xab\x16Y\xb3\xf7^&74\ +2\x9c\xefe\xf4\xd50J@NP\xc9\xde\x86TU\ +\xd5\x07$\x16\x8b!\x84\xf07\xa1\xa2(\xfe5\x02\x81\ +\x00\x96e\x09!\x04\xe1p\xb8p\xb8\xf7\xa8\x1c\xce\x87\ +\xa6L\x992i\xca\x94)/\xb9\xae;\xcd\xb3\x05\xd9\ +l%\x08\xbd\xea\xaa\xabhll\xe4W\xbf\xfa\x15\xcd\ +\xcd\xcd\x00\xac]\xbb\x96\xdbo\xbf\x9dP(\x84\xa6i\ +\xbeq7\x0c\x83r\xa9\x84\xd0\x04\xa1X\x90\xda\xdaZ\ +\xba\xd5!\x16|\xbc\xcc\xac\x8f\x16i\xb9u\x94\xc9\xd7\ +$\x89\x9fn\x10i\x16\x04\x83\x01\x11\x0c\x06\x09\x06\x83\ +\xd4\xd7\xd7\xe38\xce1\xe90\xc30\xbc\x00\x0eE(\ +\x9c\x14~?\xa1j\x9b\xe7\xdfx\x9dE\xda\xf5\xac>\ +\xe3njB\xf5\x94\xcb\xe5\xca\xbd\x96\xcb\x98\xa6I6\ +\x9b\xf57V \x10\xf0\xa5\xe1\xb2\xcb.#\x12\x89P\ +__\xcf\xdc\xb9s}`4M\xf3\xb5\x87\xe7}\x1d\ +W@\x92\xc9d\xed\x05\x17\x5cpn(\x14\x8aX\x96\ +\xe5_\xb8\x5c.\xf3\xe1\x0f\x7f\x18\xc30\xb8\xff\xfe\xfb\ +Y\xbe|\xb9\xaf;\xbd\x1b_\xb0`\x01\xb7\xddv\xdb\ +\x04\xe3\xee\xc5-\xa6a\xe2\x04L4M%\x9bt\xb8\ +j\xe1\xc7\xa8\x9b\x1a#\xb28K\xed\x15\xc3\xe8\x0bR\ +\x18\xa51o\xc84\x8f\xd8@644\x5c\x1e\x8dF\ +o\x8a\xc5b7J)\x97\x0c\x0d\x0d188Hb\ +h\x84\x817\xb3\xf4\xed\x18\xe0\xb95k\xd9\xf1\xfa\x0e\ +\xf6m\xda\xc3\xfd\x0f|\x97\x9d/v\x91/d}\xe0\ +<\x0f\xca\xf3\xa2\xce>\xfbl\xaa\xab\xab\x91R\x92H\ +$|\xa3\x9eH$\x18\x93\x06_ue\xb3Y_]\ +\x1fW\xa3\xee\xf9\xdf\xde\xc5\x15E\xe1\xfc\xf3\xcf\xa7\xb5\ +\xb5\x95\xc7\x1f\x7f\x9c\xba\xba:\x9ez\xea)\x9ey\xe6\ +\x19B\xa1\x10W]u\x15\xa7\x9f~:\xa9T\x8a\xfb\ +\xef\xbf\x9f\xbe\xbe>\x0c\xc3 \x99L\xfa\xd1\xb8i\x9a\ + Aj\x92r\xc9\xe1\xae\xf7>\xc5\xa3\xad\xdf\xe0\xa6\ +\xf9_e\xed\x8e\x17P\x1b\xfax\xcd\xdeV\xb1#J\ +eg\x1e\xe9\x9a\xf3\x99\ +\xcfP]]\xed\xe7>\xc6{\x22\xde\x9f\x93\xc9$\x81\ +@\xc0\x07\xe4\x87?\xfc!\x86a\xf0\xf1\x8f\x7f\xdc\xe7\ +\xbbTT\x96,YRQ\x89\xd2!9\xf7\x00s\x16\ +Fpr*\xd6p\x08{(\x885\x18DH\x05\xa1\ +\xbb\xfe5\x86\x86\x86\x0e\xdb\x90\xdb\x96\x8d\xab:\x08E\ +p\xdd\x82O\xb3\xbe\xf7I\x9c\x91i\x5c7\xf7K\x9c\ +\x7f\xea\x99\xdc\xfe\xe8\xe5\xbek\xab\xaa\xaa\x1f\x03yl\ +\xc3\x96-[*\xe4\xe3\x98s2i\xd2$\xa4\x94\x08\ +!(\x95J\xfe\xc6TU\x95P(D\xb1X$\x12\ +\x89\xf8\xa1\x80eY\xfe\xf7\x1f3 \xb5\xb5\xb5\xb7,\ +]\xba\xf4.\x8f.9\xe1\x84\x13H\xa5R\x04\x02\x01\ +\xd2\xe9\xb4\xaf\x82\xa4\x94(\x8a\xe2\xb3\x9f\xde\xee\x1a\xa3\ +\x16\x5ce,\x9a\x9a6m\x1a\x8e\xe3P(\x14\x10\x08\ +liQ,\x16)\x97\xcb\xf4YIZ\xa6;\xc8H\ +\x89\xc6I\xd3IM\xedC\x0a\x07\xd35QJa\x86\ +\x1e\x99\x5cIt\x1d\x01EbY\x16\xb6e!\x15\x89\ +\xa2\x09\x1a\xaa\x9b9X\xfa=\xc9$d\xdd~\xeaN\ +0\x08\x07#^\xcc3A\xe5x*\xb6\xa7\xa7\x87P\ +(\x84\xeb\xba\xac^\xbd\x9a\xad[\xb7\xd2\xd9\xd9\xe9{\ +R\xaaZa\x80kjj\xc8f\xb3\xa8\xaaJ,\x16\ +\xf3\xd5\x9e\x17\xbb\x1d\x8eS\xf2\x8e\x80\x98\xa69\xb5\xa9\ +\xa9\xa9\xa6\xa7\xa7\x07\xd34\xb9\xe7\x9e{\xd8\xb3g\x0f\ +7\xdex#?\xf8\xc1\x0fH$\x12\xd4\xd6\xd6\x12\x0c\ +\x06y\xe9\xa5\x97X\xb8p!\xbbv\xed\xa2\xa7\xa7\x87\ +\xb9s\xe7\xb2m\xdb6\xf6\xef\xdf\x7f\xfb\x82\x05\x0b\xbe\ +\xf3\xec\xb3\xcfr\xd1E\x17Q.\x97}\x95%t\xc5\ +\xf7\xbe\x5c\xc7EU\x04\xa1\xec|>q\xd1\x9dh2\ +\xca\x17\x9e\xf8\x08\x1f>\xfbF~\xb6\xfdn,\xcb\xac\ +\xe4R\xfe\xc8\x83\x0d\x0c\x0c0k\xd6\xac;\xa3\xd1\xe8\ +T\x00\xe9\xca)\xc9\xd1\x14\xd2uA\xb7\xe9\xfc\xa5\xc2\ +w_\xf8\x16i\xf7 F6\x88M\x89\xeeu\x9dt\ +\x0d\xe60\xcd\xb0\x0fH8\x1cf\xc6\x8c\x19\x0c\x0e\x0e\ +b\x9af\xaaT*\xf58\x8e\xb3DQ\x14q\xd7]\ +wI\xd7u\x85\xb7\x01=\x1b\x0b\xf8\x86\x1c \x95J\ +\x11\x8b\xc5\xfcMz\xb84\x8av8\x06\xdd4M\x0a\ +\x85\x02\xaa\xaa\xf2\xa3\x1f\xfd\x88o\x7f\xfb\xdb\xfc\xf4\xa7\ +?e\xfd\xfa\xf5\xa8\xaa\x8a\xae\xebh\x9aF*\x95b\ +\xef\xde\xbd\xe4\xf3y\xca\xe52\x89D\xc2S_!U\ +U\xd9\xb0a\x03\xaf\xbf\xfe\xba\xef\xab\x8f\xbd4\xdf\xdf\ +\xb7\xb1qqY\xd6p\x19\x8fl\xfb*\xb3\xb4\xf3\xb9\ +\xf6\xa4\xd5\xb4\xd4LA\xa0T\xd4\x9c\x22\xde\xc9\xb3\xfa\ +\xfb\xe9\xd3\xa7\xd7\x0b!(8eX8L}<\x8c\ +\xd3\x1f\xc1\xea\x0b\x93\x19M\x22\x88\x11\xaa\x98e\x8aC\ +\x92Fq\x22\x1df\x87\xcf8TWW\x13\x8f\xc7I\ +\xa5R\x98\xa6\xf9\xec\x9e={n\x8a\xc7\xe3\xd7Z\x96\ +5\xcb\xb2\xac\xaf]p\xc1\x05\xacX\xb1\x82G\x1f}\ +\xd4\xb7\xab^\x10\xe9QJ\x8a\xa20<\ +\xce\xc7\x7f}6_>\xe7ij\xecy\xa85)\xbe\ +\xb5\xe9\xab\x18\x86\x09\xa2\xc2Yy*T\xd3418\ +8\xd8988\xb8M\x08\xe1\x06\x02\x81\xb5o\xdd\xa0\ +\xabW\xaf\xc6\xb6mB\xa1\xd0\x045t\xf0\xe0\xc1\x09\ +?\x1f8p\xc0\xb7!\x85B\xe1\x0f>\x7fT\x80(\ +\x8a2\xc7\xb2,TU\xa5T*Q,\x16\x99;w\ +.o\xbe\xf9&K\x96,axx\x98\xda\xdaZ\xb2\ +\xd9,\xe5r\x99H$\xc29\xe7\x9c\xc33\xcf<\xf3\ +G/\xaei\x1a_\xfa\xd2\x97|C\xe8\xc5\x0b\x05\xa5\ +L\xa9TB\xa4\x05B\x08v\xe8\xfbx\xef\x195\xd8\ +\xd6x\xcfJ\xe2\x18\x0a\x99\x17\xea0\x87\x03\x80\xfc\x03\ +\xb0}\x9aE\x07\xc7\x86\x80\xae\xa3)\x01\x10\x90\xc8\x0f\ +\xf2F\xff\x03HW\x8e\xa9\xc0\x8a\x94744\xf86\ +@Q\x94_g2\x99\xd5o\x17\x8ey\xae\xbc\xb7\xeb\ +\x0f3\xed\xed\x7f\xff\xb1\x022\xbd\xb6\xb6\xf6F\xc30\ +\xa4\xa6i\xe2\xee\xbb\xef\xa6\xb1\xb1\x91\xbd{\xf7\xe2\xba\ +.\x83\x83\x83\x18\x86A8\x1c\xa6P( \xa5dt\ +t\x94]\xbbv\xfdI\xee\xa9X,\xe6\xa5\x94\xde\xb5\ +\x83\xe1pXw\x1c\x07\xddRq\xdcC*G\x09\x09\ +,\xc7fE\xf4\x16\x16\xcf\x5c\xc0\x96\xe4\xe3\xe4\x92\x1a\ +\xbb\xdd\xe7p\xb4\x18\x96\x09\x129\xc1\xa6\xb8\xae+}\ +\x03\x1a\x12\xc4'\x85(\x18e\x02!\x95\x9a\xaaZL\ +\xa5\x88\x16\xd2@\xa9\x00\x22\x91\xbe\xfamnnfh\ +h\x88\xb7+M\x02\x08\x04\x02\xed\x1d\x1d\x1d\x8d\xf3\xe7\ +\xcf\x1f\x9a2e\x0a7\xdcp\x03\x8f=\xf6\x98o{\ +\xbc\x80\xd7\xdb`\x1e\xc3\xa1\xeb\xba\xcf\x8a\x1f+ \x11\ +!\x04\xb9\x5cN\xd4\xd7\xd73<<\xcc\xe0\xc0\x10 \ +\x10\x02\x1f\xf1r\xb9\xec\x07T\xde6\x8e\xc5b\xa2T\ +*\xbdm\xf4,\x84\xf0+\xe9f\xce\x9c\xf9\xa0\xaa\xaa\ +\x1f\xbe\xfc\xf2\xcb\xfd\x00\xec\x90+)I\x0d\x0a\xfe\xee\ +\xe6\x9b\xb9\xe9gK\xf9\x97\xb3\x1f\xa3\x18/0\xd3l\ +\xe6'\xbfy\x02\xc3\x90\x9e\x0d\x08]t\xd1E#\x80\ +\x14\x8e\xa8\xb3,\x89\xa2\xc0\x22;\xc2\xf0\xc3\x0a\xd7?\ +t-R\x09q\xfd\x7f]\x83e[\x04\xb5\x08\xdb[\ +{\xa9\x8a\xc4}J\xdd#?\xff\x18\x18\xe3\xf2\x222\ +\x16\x8b\xf1\xe2\x8b/\xb2q\xe3FZZZ\xd8\xbau\ ++\xe1p\x98\xf5\xeb\xd7\xfb61\x12\x89\xd0\xd2\xd2\xc2\ +\xae]\xbb\x18\x1d\x1d\xf5\x93t\xc7\xac\xb2\xa4\x94\xe8\xba\ +\xce\xbe}\xfb\x90\xae\xa4f\xb1N$\xac\x92\xeb\xb7)\ +\x0e9H\xf7m\xd5\x9c(\x97\xcb\x9d\x8a\xa2|\xf3\xed\ +\x9c\x84\xb7\xb0\x00\xfa\x07>\xf0\x01\xe6\xcc\x99\xc3\x07?\ +\xf8An\xbd\xf5V?\xcf \x10T\x05\xe3\xd8\xb2D\ +\xbc\xaa\x8a\xe6\xda\xa9<\xbf\xe3\xd7<\xd1w\x1f\xb6\xd5\ +\x88i\xb9P\xd9\xe1\xa2\xa6\xa6f\x92@\xd05m\x0f\ +\xa7]\x14\xc6\x18\xac\xd4U\xd9\x83\x01\x9c\xac\x06\x96\x8e\ +[RPu\x0dMS)\xe5Ml#\xe5%\xddd\ +4\x1a\x15###\x84B\xa1w\xe4\xf8\x1c\xc7\xe1\x95\ +W^!\x1e\x8f\xe3\xba.\xfd\xfd\xfd~\xa2\xcaK\xc8\ +y\xeco]]\x1d\x03\x03\x03h\x9a\xe6\x05\x91\xb1\xe3\ +\x02\xc8\xec\xd9\xb3+\x14@\xb2\x22\x9aQ)\x89\xd4\xcb\ +\x09\xa5;\x9e\x975\xb6\xe3z\x06\x06\x06\xfe\xebp\xe9\ +\x8d\xb9s\xe7\xfaQ\xed!u'\xb0]\x13Eh\x80\ +\xa0d\x15\xd1T\x8d\xa0\x16\xc5q\x5cL\xd3\xf2\x839\ +\xcb\xb2(8ej\xa7)H[%Z\x1fF\x99b\ +a\xccO\xf8\x9b`\xe0\xa1IH[\xf1=A\x8f[\ +SUUtuu=\xe0\xed\x11]\xd7\x7f\xfd\xa7\xee\ +\xd7u]>\xf9\xc9O\xfa\xdf3~\xed\xdbw(\x7f\ +\xd6\xdf\xdf\xef{\xa1\xf1x\x1c\xc7q\xa8\xaa\xaa\xfar\ +:\x9d~\xe1\x98\x00Y\xb1b\x05\x97]v\x19g\x9f\ +}6\xdf\xfb\xde\xf7hmm\xe5\xe4\x93O\xe6\xf5\xd7\ +_g\xee\xdc\xb9d2\x19Z[[\x09\x87\xc3\xcc\x9c\ +9\x937\xdex\xe3\xb0)\xf2@ \xc0\x0b/\xbc\xc0\ +\xde\xbd{\xe9\xed\xed\xf5\x19T!\x04\x85\xd6\x1cCF\ +#\xff\xeb\xa5[\x18\xcc\xea|\xea\xb1O`\x186y\ +'\x8e]\x14D\x22\x87\xa4\xae\xa2\x1e%\xca\xeb\x939\ +\xf8\x86\xe0\xc1\x07~\xc4\xfe\x9e.~\xbb\xf7\xa7\xfc\xed\ +\xaa\x8fr\xf7\xba[1M\x0bi\x1f\x02B\xd7u\x9f\ +J\x1f\x19\x19\xf9\xc8\xe1\xdes>\x9f'\x12\x89\x1c\x02\ +\xc3\x01\xcbt\xc7\xee\x05\x84*P\xd41m0\xf6\x91\ +\xd1\xd1Q_=\x1e\x8b\x84\xb8\xde.\x88\xc7\xe3\x84\xc3\ +a\x9ft\x0b\x04\x02,]\xba\x94\xee\xeen\xaa\xab\xab\ +}\xa3\xa5\xeb\xfa;^\xf4-*+\xa0(\x0a\x07\x0f\ +\x1e\xf4\x8a\x06d\xb9\x5c\x16\x00\xe5b\x91i+f\x92\ +\xcb\xe5\x88iu\xa4g\x1c\xa0iF\x80\xaa\xb4\x8e\x93\ +\x1d\xfb\x95\xd6ps\x1ab\xecI\xc2\xe10\xe9T\x9a\ +\xf5=\xcf\xb2\xe9\xcd..>\xf9\x06\x1ac\xd3\x11(\ +\x95X\xc7\xaaH\xd4\xbcy\xf3\xfcl\xe6\xe1\x12\x95\x00\ +555#\x1d\x1d\x1dM\xa7\x9cr\xca@*\x95B\ +Hpg\x0b\x96_YC~\xc0\xa18l\x93\x1bp\ +(\x0e\xd9\x18\x19\x17\xcf$y\xef\xf0O\xd9\xa8w\x04\ +$\x1a\x8d.\x07\xd8\xb6m\x1b\x89D\x82\xe1\xe1a\x8a\ +\xc5J\xe9\xce\xee\xdd\xbb\xfd\xc0\xd0\x03\xcdu]^~\ +\xf9\xe5#J&%\x93\xc9/\x0e\x0d\x0d}w\xcc\x8d\ +\x9c\xbe`\xc1\x82\x87\x0fy#\x95\x0a\x96r\xb9L\xca\ +\xcd1u\xae\x89\xa8\xb2i\x9c\xd6D\xd9\xcdQr\x12\ +(\x0a\xd8y\x95\xe1\x9fN\xf6\x1f\x5cJ\x89W\xb2\x9e\ +)\x8d\x925\x12\x08EL\x00$\x93\xc9p\xf5\xd5W\ +\xf3\xf4\xd3O\xfb1\xc8\xe1\xacL&\x83\xae\xebR\xd3\ +4\x9a\x9a\x9a*6\xa2\x7f\x80\x8e\x07\x15,\xc7E(\ +:\xae\xab\xa2\x11@\x09\xbb~N\xc4S\xe5\xc7\x04\x88\ +\xae\xeb\x7f\xe3e\xf8\xfa\xfa\xfa\xfc\xa4\xcc\xf8\xdf\x8fu\ +\x15\x0a\x85\xbd\xc0\xde\xb1\x1f\xe7{\x8c\x80\x10\x02\xa5P\ +y\x89\xa6ab+\x0e\xaa\xaa\xd0\xa2\xae\xe2\xefV\xde\ +JM\xa0\x9e\x0f|\xef|n\xbb\xeaV~\xb1\xfe\xfb\ +\x13\xe8s\xdb\xb1Y0\xe94\x92ST\x06r\xdd\x04\ +\xd5\xd3QP0\xcd2\xaeU\x89\x832\x99\x0cO?\ +\xfd\xb4\xef\x96\x1e\xe9R\x14\x85\x07\x1ex\x80\xe1\xe1a\ +\x84\x10<\xfe\xf8\xe3\xc4\xe3q:;;innf\ +\xcb\x96-\xcc\x9a5\x0b\xc7q\xd8\xb7o\x1f\xcd\xcd\xcd\ +ttt\x1c\x1b\x97%\xa5Tc\xb1\x18{\xf6\xecA\ +\x08A\xf4|\x9d\x15\x17\xd5 \x01#'I\xee5\x18\ +m\xb7\xc8t\x98\x98\x85C\xf9\x90\x9a\x9a\x9a\x11\xe0}\ +G[\xa6\xfa\xd3\x9f\xfe\x94B\xa1\xc0\xe7?\xffy\xbf\ +0\xc1RM\x84\x90\x9c<\xe5l~\xd7\xfe\x00\xa9\xce\ +\x06\xaeX\xf8\xb7\xcc\xa8Y\x84\xedT\xaa`<\x09\xe9\ +\xee\xee\xe6k\xff\xfb\xbb\x95\xc4V)\xc5\xc6\x9f\xec\xe2\ +\xc0 dSy\x8f\x02\x92\x8a\xa2\x08\xaf\x8e\xea\x9dv\ +\xed\xdb\xd9U\x8f]\x9e?\x7f>]]]\x8c\x8c\x8c\ +x\xcf\xce\xc9'\x9f\xcc\xe6\xcd\x9b\x19\x19\x19a\xd1\xa2\ +E\xa4R)FGG\xd14\xed\xd8$\xc4\x8b\xaa=\ +\xef\xc9\xd9\xa9\xf1fG\x96|\xbf\x83U\x94(\x9e\xf1\ +RUTU\xfa\xb9\x91@ \xe0\x0e\x0c\x0c\x1cU\xd3\ +\xca\xbcy\xf3hnnftt\x94\xe6\xe6\xe6J\x85\ +\xbde\xe2\xe0\x00\x02M\x09`K\x0b\xdb\xb1\x18H\x0f\ +\xd3\x95\x0e\xa3\x09\xdd\x8f_4M\x03\xcd\xa1\xa4\xa6p\ +\xb2\x1a\x8a\xd4\xc9\xe6\xb2\xc4\xf48\xb9\x5c\x07\x8a\xa2\xa0\ +\xeb\xba(\x14\x0a;7m\xda\xf4OB\x08UQ\x94\ +#.\x91TU\x95\xaf|\xe5+\xcc\x9f?\x9f\xcd\x9b\ +7\xa3\xeb:\x1d\x1d\x1d\xb8\xae\xcb\xab\xaf\xbe\x8a\xa6i\ +$\x93I\xda\xdb\xdb\xc7\x9b\x00\xa4\x945\xc7\x22!H\ +)\xf9\xd1\x8f~\xc4\xacY\xb3\xb8\xf7\xde{+e\x93\ +sJ~\x92\xaaX,\x22\xa5d\xd2\xa4Ituu\ +\x91\xc9d\x8e\xb8:dB\x85y[\x1b/\xbd\xf4\x12\ +---\x1c8p\x80x<^I\xc3b\xa3k!\ +R\xc6 \xd3\xa7\xcc\xa3~Z\x1d\x9bz\xba\xa9\x8dL\ +\x1e\x8b\xba\x0f\xb9\xc0z\x5cR\xf7\xfe\x01F\x9e\xae\xc3\ +\xe8\xad\xd0+\x8e\xe3\xf8\xe5;c\xbf'\x8b\xc5\xe2\xf3\ +Gs\x8fc\x84\xab\xab\xeb\xba\xb2s\xe7\xceJ\x0b\x85\ +\x00UU\x90\x12b\x91\x18\x96kU\x1c,\x81\x1f\xab\ +\x8d\xd5x-8&\x09\x997o\x1e\xb3g\xcf\xe6\x84\ +\x13N`\xd9\xb2el\xdd\xba\x95e\xcb\x96\xf1\xe4\x93\ +Or\xf1\xc5\x17\xb3{\xf7n6l\xd8\xc0\x99g\x9e\ +Iss3\xcf>\xfb\xec\x9f\xa4\xc7\xdfiE\x22\x11\ +\xbe\xf5\xado!\x84`hh\xa8R\x01h\x98\xd8\xaa\ +\xcb\x86\xff\x1ed\x93\xf9U\xe65.\xc1\x95.;\xfa\ +6\xd1\xfah\x1b\x1d#\xbd\x14\x86\x0e\xbd,MSY\ +\xf7\xb5a\x8c\xd1Q\x9c\x92d\xc6\x8c\x19\xe8\xba\xce\xd1\ +\xaa\xa8\xb7\xf1\x0c\x87v\xee\xdcy\xf1\xacY\xb3^(\ +\x95J\xb8*L\xbd!\xca\xc9\xcbc\xd8\x8eCSx\ +\x1e\xc3F;\x8e\xe1r\xf0\xd5\x12\xfb\x9e\xc8\xa3\xa8\x15\ +\xa7'\xe2\xf9\xeaG\x0bHgg'\xbf\xfc\xe5/9\ +\xe5\x94Sx\xe5\x95W\xc8\xe5r\xf4\xf4\xf4`\x18\x06\ +O>\xf9\xa4_\x99\xf1\x9b\xdf\xfc\x86@ \xe0\xa7>\ +\x8fr\x8d\x0e\x0d\x0d}C\xd7uk\xec\xc1?\x98J\ +\xa5f\xe4\xf3y,S2+<\x83\x193\xa6W\xa4\ +T\x1a,\xbb~\x16U\x912\x0d\xc3'c\x0d\x06q\ +F+i'\xa1HP$L\x83\x5c.\xc7\xc8\xc8\x08\ +\xd1h\x94x<\xcei\xa7\x9d\xc6\xcb/\xbf|\x5c\x1c\ +\x12?\xcd+\xa1\xd4j\xb3c\x7f\x8e|\xaf\x83ml\ +\xc4.J\xecr\xa5?Q\x0fh\xbe#p\xac\xd4I\ +4\x1a\x8d\xf2\xf4\xd3O\xf3\xc4\xe3O\x1c\xf2F\x84\xc7\ +I)~O\x8bP*\x89\xac\xea\xeaji\xdb\xf6\xd1\ +\xea\xac\x91\xde\xde\xde\xff\xed\xfdP__\xbf\x5cQ\x94\ +\x19\xaa\xa2\x80\x03\xae\xe3\x92\xcf\xe7\x11\xc0f\xab\x8dK\ +Z\xa2\xb8J\x8e\xe0\xd4\x22\x8a,\xa1j\x0avZ\xa7\ +\xbc/F~[\xd4g\x01\xbc\xea\xc1|>_\xc9\xe5\ +\x8b\xe3\xd31gY\x16\xb7\xdcr\x0b\x00/\xae}\x11\ +QV\xd0\xb4\x02B\x17\x18\xba\x81\xac\x96~l\x94H\ +$\x0e+k\xa8\xbd\x83A\xaf\xf7\x92\xf9\xae\x0a\x93\xe6\ +\x05\xd0u\x81\xb4u\xe6N^HGj\x07(PN\ +9\xa4\xbb|\x1d.l\xdb\xee\xe0\xf8,%\x10\x080\ +}\xe1\xc2JF\xcf\x1a\xa3\xd6\xbd\x88X\x11\xac\xac\xbe\ +\x85\xf7\x9d~-;\x86_\xe6\x85-/\xa15\x0f\xd3\ +\xd67\xe0\x13\x85^\xc2\xca\x8b\x05\xd6\xaf_\xef\xf1U\ +\xc7\xbc\xce>\xfbl.\xb8\xe0\x02\xe6\xcc\x99C\xa1P\ +\xa0\xb7\xb7\x97\x8b/\xbe\x98\xc7\x1f\x7f\x9c\xf3\xce;\x8f\ +b\xb1\xc8\xab\xaf\xbe\xca\xfc\xf9\xf3\x89\xc5b<\xf5\xd4\ +S~\x09\xeeQ\x01\xa2(\x8a\xa8\xaf\xaf\xa7\x90/`\ +E$K?RGu\x8d\x86t%\xc9\xb6~\xea\xf6\ +U1\xbc\xdd\xc0\x1au\x88\xc5\x82\xbe'144\xf4\ +\xe6\xf1x`\xd7u\xb9\xfd\xf6\xdb\xa9\xae\xae\xe6\x8a+\ +\xae\xe0\xa2\x8b.\xaa\xe4 $\x10\x82L\xba\xc4eg\ +\x5c\xcf-\xbf<\x93\x9f\xff\xcd.N\x08-%\xe1\xec\ +g\xf7\xfa;0\x0c\xcd\x0fZ\xcb\xe52\xd1h\x94`\ +0xX\xae\xe7\xe1\xaem\xdb\xb61u\xeaT\x06\x06\ +\x06PU\x95\xda\xdaZv\xec\xd8\x81\x10\x82\x8e\x8e\x0e\ +\xbf\x16x\xe7\xce\x9d\xac\x5c\xb9\xf2\xd8\xe9w\x8f{)\ +\x95K\xe8\x8e\xce\x9bw\xa7\x91\x16X\xc5C9t\xa1\ +L\xd4\x8dGB\x9b\x1c\xce2M\x93\xfa\xfaz\xbf\xe2\ +\xdc\xb2\xacJ'o\x08\x0c\xc3%\x14\x0c\xe0R\xa9?\ +\xeb\x1e:\xc8\xc6\xfcc(\xa8\x13\x92G\x1e\xf7\xd4\xd6\ +\xd66\xb7X,\x8e\x00\xb2\xa1\xa1\xc18\x1e6\xe4\xea\ +\xab\xafF\xd3\xb4?HV\xb5\xb7\xb7\xfb\xc4\xa2\x94\x92\ +_\xfc\xe2\x17\x95\xf7u\xac\xf4\xfb%\x97\x5c\xc2\x87>\ +\xf4!\x5c\xd7\xe5\xc9'\x9f\xa4\xab\xab\x8bh4\xca\xc1\ +\x83\x07\x89\xc5bTUUq\xe0\xc0\x01r\xb9\x1c\x8d\ +\x8d\x8d\xf4\xf4\xf4\x1c\xb7\x1d(\x84\xe0\x87?\xfc!\xcb\ +\x96-\xe3?\xfe\xe3?\x0e\x05\x7f\x08\xa4\x0b\xf1x\x88\ +d&MM\xa0\xbe\xe2VJ\x9b\x80\x88 ]\x89e\ +\xd9~\xad\x98W\xd6\xa9\xebz\xceu\xdd\x0cpD\xfc\ +\xd5\x1f\x91^s|\xbe\xc7\x09@u\x5c\xc5q]&\ +\x87gPr\xd3\x14\xac,BH\x8c\xac\x8b[\x92~\ +\xf6\xf0\xa8\x01\x19k\xc0\xa4\xb5\xb5\x95\x1bn\xb8\x81m\ +\xdb\xb6Q*\x95\xa8\xab\xabc\xd9\xb2el\xdc\xb8\x91\ +`0H8\x1c&\x93\xc9\x1c\xf7\xb6f)\xa5[U\ +U%w\xec\xd8Q)Y\xf0JP%H!\x89E\ +\xc2<\xbe\xfb~\xbeu\xe5o\xf8\xcd\xfe\x87x\xa9\xe3\ +e\xce:\xe9t^s7b\x18\xa6\xcf\xe8zT\x8c\ +m\xdb\xb3\xea\xeb\xeb\x03\xa3\xa3\xa3=\xc7zo\xb6m\ +\xb7\x09!*\xc5\x82\x08F\x96H\xfe\xee\xf6f$.\ +Q3BP\x0frp\xb8\x80U\x90\xbc~W\x0a\xe9\ +T4\xce1\xb9\xbdB\x08\xbe\xf9\xcdor\xfb\xed\xb7\ +\xf3\xc9O~\x92\xb6\xb66\x5c\xd7\x9d\xd0_8\xd6\x9f\ +\x8d\x94\x92\x9e\x9e\x9e\xe3\x0aH*\x95\xba\xe8\xf9\xe7\x9f\ +\xa7\xa5\xa5\xa5}\xce\x9c9\xb3\xb3\xd9l\xa5nX(\ +\x14j$%3\xca~\xf9\x1c\xdfyVg\xd5\xe9\xa7\ +\x90Pv\xf0\xcc\xbe]\x0c\xb5\xe5H\xa5*\x01k(\ +\x14\xa2\xa5\xa5\x85R\xa9\xc4\xb5\xd7^\xfbz[[\xdb\ +\x86u\xeb\xd6\xad<\x1e\x0e\x87\xef\xfa\x0a\x85\xba\x83\x92\ +}O\x15\x18\xdan\x90\xef\xdb8A5\xa9B\x03\x8d\ +\xb7\xcd\x9f\x1c\xb1\x0d\x89\xc7\xe3\xdcw\xdf}~\xc2\xc8\ ++4\x00\xd05\x1d];\xe4\x0a{\xe5\xa3\xfb\xf7\xef\ +\x9fq<\xed\x88W-\xef\xbd\x00\x81@5\x5c\xb40\ +\xe4{\xe1\xf5\xce\x9f\xf3\xe4O~LyDb\x95\x5c\ +\xcai\xd7\x8f\x85TU%\x9dN\x13\x0a\x85\x18\x19\x19\ +9\xa2^\x8d\xc3!\x18/\xbc\xf0Bn\xbc\xf1F\xbe\ +\xf5\xado\xa1\xf6\xa9\x10\xcc\xd18\x1b\xbf\x7f\xbf\x5c.\ +SUUE*\x95\xc2\xeb\x8b?j@b\xb1\x98\xdc\ +\xb4iS\xa5\x92#\x06\x0b\xcf\x8f\xa1\x07\x04J\xa9\x9e\ +\x0b\x16_\xca\xef:\x1fA\x0b\xa8\x8c\xee3\x19\xd8\x5c\ +\xf6\x12NR\xd7\xf5)\xc7\x13\x10\xd7u\x1d/i\xa5\ +\xaa*\x8b\x17/\xa6\xb3\xbd\x83\xd7\xfe\xa9\x5c\xd9\x1b\x0a\ +\xa0T(\x12\xe1\xba\x84B\xd2\xa7*\xbc\x11\x18c=\ +\x7f\xc7\xb5\x91\xb4X,\xf2\xe9O\x7f\x9aT*\xc5'\ +?\xf9I\x1ez\xe8!N_y:\xdd\xdd\xdd\xcc\x9b\ +7\x8f\xdf\xfe\xf6\xb7\xac\x5c\xb9\x12]\xd7\xc9f\xb3\xec\ +\xd8\xb1\xc3\xaf\x9a?*@BcOf\xdb6\xb2\xda\ +e\xc695h\x08\xac\xb2\xc1\xeb#?C\xb5\xc3$\ +Z\x0d\x92\xfb+\xc1\xcf\x98\xdb+\x86\x87\x87\x8f\xc9\xaa\ +\xc7\xe3\xf1\x96\xb9s\xe7\x1e\x08\x04\x02\x15OOQq\ +\x84M\xa9T\xe2\xdb\xdf\xfe6MMM$\x12\x09~\ +\xf7\xbb\xdf\xf9\x05\x04\x00###L\x9d:\x95d2\ +\xc9\xc8\xc8\x08\xaa\xaa\x92L&\x09\x85B\x94\xcbe\x02\ +\x81\xc0q\x05$\x14\x0a\xb1c\xc7\x0ef\xcf\x9e\xcd\x0b\ +/\xbc\xe0\xf7\xd0\x8c\x8e\x8e\xfa\x95\x90\x83\x83\x83\xc4\xe3\ +q\xbfx\xf0\x9dX\x8cw\xb4!\x9e\x1b[\x9d\x83\x0d\ +wd\xdf2\xaa\xa8\xa2F\x82\x11}\x82\x18\x1f\x87\x9d\ +\x17\x98={6\xb6m\xa3\x0a\x95Vu?g\xdd\x10\ +d\xfd\x7f8\xbe+Eb(I\xae\ +\xdfa\xc37\x93>\xcb\x1c\x8dF\x87\x8f\x1a\x90`0\ +\xc8\xbd\xf7\xde\xcb\xe7>\xf79>\xf6\xb1\x8f\xd1\xdf\xdf\ +\xef\x8b\xbd7\xdb$\x95JaY\x16\xa5R\xc9\xcf\x85\ +\xc8\xb1\xc8\xf0\xad\x0d4G\x0a\x88a\x188(\xa8\xaa\ +Bo\xa7\xc1\xdd\xf7~\x95o<\xfb/|\xe1\xfc/\ +\x13\x8f\xc4\xf9\x9f\xad_\xa4\xfd79\x8c\x11\xc5\xaf\xec\ +8\xe1\x84\x13hlld\xfb\xf6\xed\xd45Uq\xc2\ +\xccF\x96OZ\x86\xea\xea\x15\x07@0G\x22\x1f\xf3\ +\xd2\xd0?\xfc\xe1\x0f\xff\x06\xe8:\x8a{\x94\xe3U\xb4\ +\x18\x81\xe1]e\x12{-\xbe\xfa\xdd{I\xee\xb3p\ +M\x89\xa2\x0b\x14M\xf15\x8e\x10B9&\x1b\x92H\ +$\xb8\xfd\xf6\xdb\x0f\xeb&\xbd\x1eC!\xc4\xa2\xa6C\ +\x9e\x9f\xf6\x00\x00\x16VIDAT\xa6\xa6S\x06\x06\ +\x06\xb6\x1dC\xe0U\x01]*\xa8B\x05\x14\x96.;\ +\x85\x86\xb6*\x96\xaf8\x8d)\xb5M\xac)\xa9Tm\ +\x8c\xa0\xe4\x85\xaf\xd3g\xcc\x98\xe1y\x88L:\xdd\xa5\ +\xf9\xec4\xd2M\xe3\x00\xc6@\x00\xa3-B\xb93\x82\ +\x10\x15\xdeMU\xd5\xa3v@TUe\xe1\xc2\x85\x9c\ +t\xd2Il\xd8\xb0\x81\x815\x15\xa3\x1ep\x1c&7\ +\xba~\xac\xe6mbo\xb0\xdbQ\x032<<\xdc\xe5\ +\xba\xee\x5c\xaf\x80\xa0\xe9\xac0\x91\x88\x82\xb4u\xdew\ +\xd2-<\xb3\xef\x87\xd8\x18\xd8\x86\xe4\xc0\xef\x8b~\x0a\ +\xb5\xaa\xaa*R,\x16\xe3G\xf2pS\xa6Ly_\ +\xb1X\xbc\x10p\xa5\x94\xf1\xce\xce\xce\x8a\xee\x97\x82\xb2\ +a2\xd0S\xe2\xab\x89o\xb2\xa7m\x98;\xb6\xfd+\ +\xb1P5\x1b\x0e\x1e\xc4\xee\x8b\xa2XA\x7f\x07\xb6\xb6\ +\xb6\xfami\x81b3w^\xf4#6\xf6\xfe\x96\x1f\ +\xbc\xf8\x9f\xcc\x9cQ\xc7P9Ovw\xa5\xb6W\xd7\ +\xf5c\xa2\xe2\x83\xc1 \xdf\xfc\xe67\x89\xc5b45\ +5\xb1c\xc7\x0e\xce=\xf7\x5c\xd6\xacY\xc3\xca\x95+\ +ikkC\x08\xc1\xacY\xb3\xc8d2\xbc\xf2\xca+\ +\xc7\xc6\xf6Z\x96\xd5\x16\x0c\x06/\xf6\xf2\xd5\xd3/\x09\ +\x13\x8fk\xe4\xfam~3p\x1f\xb6\x22(\x0c8\xa4\ +\xbb\x0f\x19M]\xd7}7\xf4\x08I\xc4[\xaf\xbb\xee\ +\xba\xf3\xa5\x94\xb8H2U\xa34M\x0f\xe0f\xbc\xfa\ ++\x9dt\x22\xc7\xa9\x0d\xe7`\x16m\x92\xc5$\xa77\ +]\xc9\xb3[\x9f!\x18t|\x09U\x14\x05\xe9J\xa4\ +%\xb8v\xf9\x87\xf8\xef\x0d\xff\xca\xf2\xd8\x87X\xd9p\ +#+\x17,\xe0;\xad_\x99\xd0\xfb~\xb4\x80H)\ +\x9d\xf1\x05\xe5\x9e\x93\xe3\xb9\xd9^\xc7Yww7\x81\ +@\x80\xda\xdaZ\x7f\x9c\xd3\xb1\x90\x8b\x0a@uu5\ +\xb6m\xb3\xe3kE\xac\x9cDh \x14\x10\xaaW\x81\ +\xa1\xa2i\x87\x22\xe3\xa3\x1c\xab\xa4'\x93I\x5c\xd7%\ +c\x17\x99sE\x06[\xad\xa8})ltM\x85\xa4\ +\x82q J\xfe\x8d\xb1\xe10c\xde\xd4\xf8\x12\xa0H\ +8L2\x98\xe3\xcc\x8fE8\xff\xfc\x0b\xf8\xd1\xce\xe7\ +\x18J\x8d\xb0\xb7\x7f'\xc5\x9a\xed\xa8Tjl\x85z\ +t\xe3\x93\x00\x1a\x1b\x1bO\x94R\xae\x08\x85B\x5cs\ +\xcd5\xc4b1\x7f\x13n\xdd\xba\x15EQ\xd8\xb3g\ +\x8f_\xf4100\xe0\x17\x18\x1e+ \x9c|\xf2\xc9\ +|\xe9K_\xc2\xb6m\x1e~\xf8a\x0e\x1c80a\ +\x8eG<\x1egpp\xd0\x8fF\xbd\xc14G\x9b\x81\ +s]\x17\xcb\xb1Q\x84B\xba'\xcc#\x7f\xff;\xfa\ +\x0b\xfb\xb9\xe3\xb7\x7f\xc7\xec\xc6yt\x96\xdb0\xca!\ +\x14\xfd\xd0D7\xdf\xf5\xf4\x8a\xf6\x14\x85@@\xc7\xb2\ +\x0c4%\x88\xaah\x04\xb4 !\xadB\x85\x1b\xa6\x81\ +\xa2\x8a\xa3\x9e\xc7U*\x95Z\x9a\x9b\x9b\xc3\x85B\x81\ +\xaa\xaa*\x9f2\x1a\xbf\xfeX\xb1\xa0\x170\x1e5 \ ++V\xac`\xf7\xee\xdd\xfc\xf5_\xff5g\x9cq\x06\ +B\x08\x22\x91J\x1b\xb1\x97\x0e-\x16\x8b\x0c\x0f\x0f\xd3\ +\xdc\xdc\xcc\xe0\xe0\xa0o\x97\x8f\xf4A\xbd\xb9\x8d\x16\x15\ +U\xb0z\xd5\xbf\xf2\xf3=_'y\xa0\x9a\x05\xdaU\ +\xdcr\xc6\xdf\xf3\x99\x9e\xf7W\x5c\x5c\xa7\xa2r\x82\xc1\ +\xa0?\xdb\xd1u]\x0c\xd3\xc4*\x18d\xd7,\xe6\x8b\ +\xbf\xfa\x22\x8e\xb4\xd9\xcb\xe3\x94\x0d\x8b\xcc\xcb\x02\xe4\x0c\ +f\xcf\x96 *\xb9\x8a\xcb/\xbf\xfc\x7f\x84\x10\xdf\x07\ +\xd8\xbcys\xc7\xde\xbd{\x97\x1c\xae'\x98N\xa7+\ +\x1d\xc4\x01\xb8\xe4\xdf\x1aPT\x01\xa84\xd7\x9f@\x7f\ +\xea\x00\xa3\xfbL\x0e\xbcX$\xd5^\x91\xe0\xaa\xaa*\ +\xf2\xf9\xfc\xfd\xc7\x14\x18\xfe\xfc\xe7?\xe7\x03\x1f\xf8\x00\ +w\xdf}7\xeb\xd7\xaf\xf7\xfd\xfd|>\xef\xd3%\xa9\ +TjB\xaaTJIcc\xe3\x97\x14E\xb9\xa5\xaf\ +\xaf\xef\xc0\x91J\x88\x83\x83\x22U\xa6\xd4Ma\xff@\ +\x91\xa2\x05\x1d\xc3\xfbyr\xef}\xd8\xb6\x85eUt\ +\xa9i\x9a\x04\x83AN=\xf5T\xf6\xee\xddK\x22\x91\ + \x9dNc\xba&V\xd9\xc60*S\x91v\xd7n\ +\xe6\x9ckc8\xb9\xca\x1cE7\x13\xc4\xc9j8\x19\ +\x0dk \x18@\xfa3\x15\x83G`C\xd0\xf5J=\ +\x98\xee*\x0cl6)\x0e;\x14\x86\x1c^\x1dHP\ +N\xb9\x95\xba5M\xf8\xb5\x08c6\xcb>&\x1b\xe2\ +\xba.\x0f<\xf0\xc0\xa1\x1b\xf1\x02M\x01\x99t\x06\xcf\ +\xad\x16\xa2\xc2\xdbxc\xfd\xe6\xcc\x99sQ&\x93\xa9\ +\x07\xfe( \xf3\xe6\xcd{\x8f\xae\xebBQ\x14gx\ +x8V.U&{Z\x8aM\xbe?\xc0\xae]\xbb\ +H\xe4\x0a\xa4\x07l\xb2\x89,\xa3\x07\x8b\xe4\x07-L\ +K\xa2\xc8\x0a\x80\x86a\xd0\xdc\xdc\xcc\x8e\x1d;P\x94\ +J\xeb\xb4#\x0fM\x1e2\x5c\x8bp-(\x8e\xc6\xb4\ +\xfa\x05\xc4gT\xb1sp\x03u\x91\xc9d\xe5\x10\x03\ +\x0f6\xe0\x14\x0e\xa9\xbc#I/WUU\xb1z\xf5\ +j\xf6\xec\xd9\xc3\x81}\x07\x08\x18eT\xc7!V\xef\ +b\xd7\xd8\xfe\x98\x0e/n\xf3\xbc\xbfc\x89C\xfe\xfb\ +\xe0\xc1\x83\x17\xdb\xb6=S\x08A1&9\xf5\xf2j\ +\xf4\x80\xa00R\xc5\xfb\xcf\xb8\x9eg\xf6\xfd\x00M\xd5\ +\x19\xdan0\xb8\xb5\x84P\x84?\xed\xe7\x1d\x1e\xb0\xe1\ +\xb4\xd3N\xdb\xac\xaa\xaa\x10B \x91P[\x82l\x10\ +\xe1\xa8\xb0\x11\x9e\xd8\xf8\xd4!\xde\x88\x1av\x1c\x18d\ +\xf4`\x0cG\xe6\xb0M\xe9\x1bs\xaf\x16\xcc\x9b\xec\xe6\ +\x9a\xae\xdfjmI\x07EU\xe8\xdeo\xf3\x95[\xbf\ +\xc2\x0f\xd6~\x97KZn\xe1\x8a%\x1f\xe4S\xcf_\ +\x80eZ\xd8\xa6sD\x80xi\xd9o\x7f\xfb\xdb$\ +\x12\x09n\xbe\xf9f\x9e{\xee9\xbfr\xb1\xbd\xbd\x9d\ +e\xcb\x96\x11\x0e\x87\xd9\xb6m\x1b\xdb\xb6mc\xe9\xd2\ +\xa5l\xd8\xb0\xe1\x1d\xbf\xfbO\x02\x92\xcb\xe5\xb667\ +7\x0f\x1b\x861S\x08\x81\xa1;\xb4\x9cW\x8d\x9d\x92\ +\xa4;\x0c\x1e\xfd\xed\x03\x14\x07\x04V\xd1\xa2\x9c\x92\x84\ +\xc2!\xdf\xf5}\xa7\xf60@/\x97\xcb\xc2\xb6m\x10\ +\xb05\xb2\x8b\xf7\x9e_\x87+]\x1c\xc3E\xb1\x83H\ +K\xc1\xc9\xab\xe4^\xab\xc1)\xaa>\xb1\x98L&\xfd\ +\xe0\xd1\xa3G\x5c\xd7\xa5\xb3\xb3S\xbe\xf1\xc6\x1b\xe2\xd1\ +G\x1fe\xdb\xb6m\x15\xc7C:\xa8\x9a\xc2\x09\xd5K\ +8\x98\xdf\xcdH\xf9 \xff\xeb\xc4\xdb\x09j!B\xa1\ + \x96cc\x99\xbe\x1azGDjjj>q\xde\ +y\xe7}\xa3\xb5\xb5\x95G\x1ey\x84/\x7f\xf9\xcb\xf4\ +\xf5\xf5\xb1w\xef^r\xb9\x9cO\xd3\xac]\xbb\x96\x99\ +3g\xd2\xd3\xd3\x83\xe38\x8c\x8e\x8e\x1e\x9f\xc1\x01\x95\ +\x0d!8\xe9\xa4\x93\xe8\xee\xeaf\xe3\xe7\xcaH{\xcc\ +!\x16\x1a\x08\x15\xe98\x84B\xba\xffr\xbc\x12\xfcw\ +\xba\x01\xbf<\x07I\xa0\xae\xd2\xd9t\xd6\xa4\x0f\xd32\ +\xb9\x85\xa7;\xbe\xc7\xcc\xaaS\xd8\x9a\xfa\x0d\xf6\xc60\ +\xb6u\xa8\x8ad|\x1bD\xa1P\xb8c\xff\xfe\xfd\xff\ +>i\xd2\xa4\x81\x91\x91\x91\xc6\xb5k\xd7\xb2h\xd1\x22\ +6n\xdcX\xe9\xc8R]\x92\xbf/\xd3;u\x90{\ +6?@2\x97\xe0\x0b\xbf\xfb\x12\xaa\xa2\xd2\x9d\x05+\ +\x7fH2&O\x9e|\xc2\xb4i\xd3^\x05T\xc7q\ +\xd8\xb9s\xe7u\xc9d\xb2\xe7-lD\xad\xa2(\x9a\ +\x94\x92M\x9b6q\xd1E\x17\xf9\xe4\xe6[\xd7\xfe\xfd\ +\xfb}\x82s\xeb\xd6\xad\xc4\xe3\xf1c\x07\xc4\xb2,n\ +\xbd\xf5V\xce;\xef<\x0c\xc3\xe0\xb1\xc7\x1e\xf3\x07A\ +z\x9e\xd6\x9c9s\xd8\xbbw\xafO\x0d\x0c\x0c\x0cx\ +7\xb9p\xda\xb4i\xc9\xde\xde\xde\xb7\xe3\x8a\x1c\x8f\xaf\ +\x92\x02\x14E\xd0\xbd\xcf\xe6\xdb\x7fu\x13\xff\xf0\xe3+\ +\xf8\xe2\xc5\xdf'\x1en`t{'\x83\xd6\x08\x86\xe1\ +\xf8\x80{\xc4\xe1\xb8*I\xa9\xaa*\xb7\xdez+\x9f\ +\xff\xfc\xe7\xb9\xff\xfe\xfb\xfd\x09<\xb6p\xd1\x8a\x1a\xb1\ +\x13\xaa(e,\x0a\x96`d\xd9V\xe2\xb1\x10\x93F\ +\xc2\xd8\xf5A\xdc\xb2\x8a4\x14\xa4\xa9\x84\x91\xe2L/\ +\xf7\xfd\xe6\x9bo\x86\xdeN]\x8dO[+\xaaJ\xb8\ +J#\x10\x14\x87:\xa6\x04\xd8%\x17\xbb\xa4\xf86W\ +Q\x14J\xa5\x92e\x9af\xe2\x98\x00q\x1c\x87\xd9\xb3\ +g\x93L&9\xe5\x94S\x08\x85B\x9cr\xca)D\ +\xa3Q\xa2\xd1(?\xf9\xc9O\xa8\xa9\xa9\xe1\xcc3\xcf\ +$\x9dN\xb3n\xdd:\x02\x81\x00\xb6m\xf3\x9e\xf7\xbc\ +\xe7\xe1\xf6\xf6\xf6\x1f\xf7\xf6\xf6\xde4F66\x01\xab\ +\x01\xd3u\xdd\xea\xde\xde\xdeJ\x012`Z&\xf9l\ +\x8c;\xef\xfc\x1a=\xedY\x1e\x1fz\x86L!\xc3+\ +}oR\xe8\x0a\x13\xd3k=\xb6\x94\xaa\xaa*r\xb9\ +\xdc\x84\xd1\x17B\x08\xda\xda\xda\xb8\xe9\xa6\x9b\xc8\xe5r\ +TUUUf\x09\x0b\x17\xdc\xb19\xed\xc0\x906\xc2\ +\xc2\x85\x01l\xcb\x84\xa6\x89#\x93\xb2\x9b\xc7*\x1e\x85\ +\xf4\x0b#\xfe\x18\xf1\xd9\xd0\xd00\xd6\x82\x00\xb5\xe7\x04\ +Y|Z\x8c\xa1\xedeF\xf7Y\x8c\xee6q\xed\xb7\ +u\x04\x0e\x0c\x0e\x0e\xdewL\x80D\x22\x11\xee\xbc\xf3\ +N\xce<\xf3L\xee\xb9\xe7\x1e\x8a\xc5\xe2\x84\xec\x97i\ +\x9a\xac]\xbb\x16\xdb\xaed\xf4\x82\xc1\xa0\xff\xef\xde\xf0\ +.o\x8d\x8c\x8c\xac\xba\xf2\xca+?\xefQ\xf4\x19\xb3\ +(kg;B&\xc3\xb8\xc9\x00\xd8\x92=ov2\ +YY\xc0\xa6\x8d\x95\xe9\xdc\xd3\xb4\xe5t\xba\x1d~\x8e\ +:\x12\x89\x10\x0c\x06\xfd\x91G\xe3\xa8\x97{\x86\x87\x87\ +\xab\x84\x10n\xb9\x5c^.\x84\xb8\xb8\x5c.\xe3(.\ +\xa1Px\xac\xe2Q\x80*1M\x87\x0f\xcc\xbc\x93\xee\ +\xec.N\x9a\xb5\x98\xffz\xee>\xec\xbav\x1c'\x82\ +eZ\xa0\xc8\xb7\x8d\xe2\x03\x81\xc0l)e\x9d7H\ +a\xd1\xa2E\x04\x02\x01\xfa^\xebe\xe7\xcb\x12I\x00\ +)ub\x91\x90\xafR\xbd_^a\xc81\xab,\xdb\ +\xb6\x83\x8a\xa2\xf0\xdak\xafU\xf4\xa1d\xc2d\x05!\ +\xc0\xb6\x1c\x84R1\xe6^.\xa2P(L\x18,\xec\ +=\x933nPrva\xa7\x98yF\x14\xcb5q\ +\x1c\x17%\x17\xab\xc4\x07\xde\xec\xdc1\xf7\xd2\x9b\x17,\ +\xa5\xf4\xe9\xfe\xfa\xfaz\x12\x89C\xd2\x9fL&\xbf\xe6\ +\x19\xfb\xc9\x93'\x7fL\xd3\xb4\x8b\xa5\x94\x08\x1b\xb0]\ +\xffP\x00\xcb4H\xec\x93T5W\xf3\xfc\x9b?\xc6\ +:\xf01\x16(g\x12SV\xf0X\xefO\xc9\x8d\x06\ +@Ho\xf0\xd8)\x81@\xa0^UUQ*\x95v\ +_r\xc9%\xed===X\x96%kkk\xc5?\ +\xff\xf3?\xb3x\xf1b\xee\xbd\xf7^\xf6\xed\xdb\xc7\xe2\ +\xc5\x8by\xf3\xcd7iii\xa1\xbf\xbf\x9ft:\xcd\ +\x94)S\x90R\xb2}\xfbv\xd2\xe9\xf4\xb1\x03r\xe0\ +\xc0\x81\xbf\xcb\xe5r\x9b\xd41~\x22\x1fr9\xff\x96\ +:\xcaY\x07\xbb$)\xa5\x5c\xd2]\x16\x99\x036\xee\ +8\xa0&M\x9a\xe4\xd1+U\xb1XlF>\x9f?\ +\x00\xb8\xe3wJ8\xa2a\x14%\x97\xcf\xfc'&\xd7\ +\xd5\xf2\xf3=\xdf V\xd7H\xa2\xf9\x00\xc9\xf5!_\ +\xf7:\x8eC:\x9dFJI8\x1c\xc6\xb2,\x06\x06\ +\x06\xbc\x06\x98\xb7\xf3\x1cTM\xd3X\xbdz5\xf9|\ +\x9e\x1f\xff\xf8\xc7~\x02\xad\xae\x5cEh\xeb\x1c\xee\xda\ +|\x17\xaa2\x87\xdf\x06\x9e \xa4\xebHCe\x8a\xb3\ +\x98\xa6\x13\xbd\x9d&\xb9\xfa\xea\xab\x7f\xeeU\x8e\xacY\ +\xb3f\xaaW\x13l\xdb\xb67\x8f\xd7\x1f6\xe3\xba.\ +\x93'Of\xfa\xf4\xe9\x94\xcbef\xcc\x98\xc1\xbau\ +\xeb\xfcd\xde\xce\x9d;\x8f\x8f\x97eY\xd6\xd6@ \ + =5\x13\x01v\xfe\xc0|Kn]'\xa4\xeb\xa0\ +\x1f\x8ab5M\xc3\xb2,\x1a\x1b\x1b\xffz\xc9\x92%\ +\x97\xbd\xf8\xe2\x8b_\xb5,\xeb\xe4\xbe\xbe\xbeCc\x9d\ +\xde(\xa0\xb5W\xb3\xeb\xc46\xbe\xb1\xf9\x19fN\x99\ +\x89\x1e\x9fB\xdb\xe0N\xf2C\xae_\x1c\xf0\x16\xd1/\ +wtt<4\x96\xf134M{\xe5\xedr)\xef\ +{\xdf\xfb\xa8\xaf\xaf\xe7\xb6\xdbn\xe3\xd1G\x1f\xf5S\ +\xba\xaet)\x9b\x15\xb5\xbb!\xdd\xca{o\x0dO\x18\ +3e\x0d\x070{\xc2\x98\x07\xc389\x8d\xf1\xb3T\ +\xbc*z/\xc6\xb9\xed\xb6\xdb\x08\x06\x83\x94J%\xa4\ +\x94|\xff\xfb\xdf\x9f\xd0\x7f\x22\xa5d\xf7\xee\xdd\xb4\xb6\ +\xb6\x1e6\x89yX\xed\xa7\xae\xeb\xf2\xd1\x8f~\x94s\ +\xce9\x87\x8e\x8e\x0ev\xee\xdcIgg\xa7?\xdb\xc3\ +4MN?\xfdt\xf6\xef\xdf\xcf\x9e={\x98={\ +6\x1d\x1d\x1d~&\xb1\x5c.\xeb\xe7\x9e{\xee\xbf*\ +BaX\x1b\x96\xd3O\x12\xc2\x1c\x0cc\x0f\x07qS\ +:;6\xee\xa5E=\x11g\xc4\xa5wx\x90&m\ +)\xeb\x13\xaf\xfb\xbd\xe0^q\xc0\x18\x91\x98O$\x12\ +\x1f\xfd\x93\x0f\xa5i\xbc\xf2\xca+\xacY\xb3\x86\x91\x91\ +\x11\x8a\xc5\xa2?O\xd7+\x0b\x02(\x0a\x93hm\x0c\ +\x92\xd3\xb8\xfd\x92/\xf1\x8b\xd6\xffd$2\x82=7\ +Kb\xb3E\xea\xe5*T\xad\xd2\xb2}\xd6Yg\xad\ +\xf3\x00)\x95J\x84\xc3\x95\xf3N\x8a\xb9J9\xa9P\ +\x15\x94?^\xd6,\x01\x91J\xa5\xa2\xc7\x05\x10)%\ +\xd7\x5cs\x0d[\xb6la\xd5\xaaU$\x12\x09\x16-\ +Z\xc4\xf6\xed\xdbihh\xa0\xb3\xb3\x93\x9a\x9a\x1a\x16\ +.\x5cH \x10\xa0\xbd\xbd\xdd\x1f\x00\xe9\xbd\x80\xfe\xfe\ +~\x1c)\xa9\xbe>/\xc2\x8bc\x84\x97fA\x91H\ +S\xc1Nk\xb8Y\x9d\xd4\xf3\xb58\x96\x8b\xe6\x1e\xaa\ +.\xf1\x06\xa7\xd5\xd5\xd5M\x985\xffN\x91t\xb1X\ +\xe4\x9cs\xce\xf1\xc1\xf4\xf4w]]\x9d\xff\xbdM=\ +*{\xbf\x5c\x87\xedf\xf8\x9b\xff\xfc\x18\x02\x9d@@\ +E\x1aQ\x14]\x22t\x13\xd5U\xbc\xd1\xb8\xb3\x0c\xc3\ +\xc0\xb6m\xaa\xab\xab+\xc9'\x04\xb5K\x82\xe8\x08\xf2\ +\x03\x0eF\xc6\x9d0\x9c\xc8\x93\x0aM\xd3D6\x9b}\ +\xc3\xb6\xed\xf7\x1e\x17@t]\xe7\xfa\xeb\xaf\xe7\xae\xbb\ +\xee\xe2\xeb_\xff:\xdd\xdd\xdd\x13N\xd2)\x16\x8bt\ +uu\x91\xcb\xe5\xfc)\x9d\xaa\xaa\x92\xcdf\xa9\xad\xad\ +\xc5u]\x7f\xc8\xc0\xc0\x036o(\xde\xb0Ie\x1c\ +eaR\xb4\xdahii\x99\x90\xb7\xf7&\xea|\xf4\ +\xa3\x1f\xe5\xfe\xfb\xef?\xac2#\xc30r\xb6mw\ +{u]B\x88\xe9\xaa\xaa\x0aO\xda\xfd\x89\xa8\x01\x8d\ +\x9aI1,\xcbb\xb4lS}\xe9\x10\xb5\x93td\ +I\xc3\x1c\x0aR\xec\x08@\x22\xeaWNz\xf1G(\ +\x14\xe2\x13\x9f\xf8\x04\xc9d\x92\xed\xdb\xb7W\x1a\x95j\ +-d\xfc\x90\xf3\xe1\xfd\xee\x15]\x94J\xa5r\x22\x91\ +H\x1d\x17@\xbc\xb9\x8a_\xf8\xc2\x17\xfe\xe8g\xf2\xf9\ +\xbcO\xcdK)\x19;\xb1\xccg\x81\x87\x86\x86*\x85\ +\xda\x93\xe3\xa8\xaaJ[[\x9b?\xcbw\xf1\xe2\xc5c\ +\xd4G\xd9\xcfq\xd8\xb6\xed\xe7\x0e\xaa\xaa\xaa\xfc\xf9\x86\ +\x87\x03H:\x9d~p\xd3\xa6M\x0fz?O\x9f>\ +\xddRUU;\xf1\xc4\x13\xe9\xee\xee\xf6\x81\xf6^\x98\ +a\x18${Fh^\x7f\x12\xd9R\x89u\xeb\xd6\xa1\ +i\x1a\xcb\x97/\xa7\xa1\xa1\x816\xa5}\xc2\x09:\x17\ +^x!\x93'O\xe63\x9f\xf9\x0c\x8f<\xf2\x08/\ +\xbf\xfc2\x97]v\x19\xbf\xff\xfd\xef\x995k\x16\xc3\ +\xc3\xc3l\xd8\xb0\x81X,\xc6\xa9\xa7\x9e\xcas\xcf=\ +w\xd8\xa4\xe5a\x01\x92J\xa5\xfe*\x9b\xcd~\xa3\xa6\ +\xa6fQ>\x9f\xf7\xcb\xfb\xc7\x1b\xaa\xb7\x1a-\xaf\xc8\ +\xce\x03\xc5\xcbuTUU\x11\x08\x04hjjb\xe6\ +\xcc\x99\x0c\x0c\x0cL8\xbfj\xfc1B\xe3\x8b\x93\xbd\ +\xe1hG\x93\xfc\x92R\xb2n\xdd:\x86\x86\x86X\xbd\ +z\xb5\x1fKyR\xe8yJ\xb6m\x93N\xa79\xeb\ +\xac\xb3\x88\xc5b$\x93I2\x99\xcc\xf8S\xd80M\ +\x93\xbd{\xf7r\xdbm\xb7122\xc2\x8e\x1d;p\ +]\x97\xed\xdb\xb7\xe3\xba.\xfb\xf6\xed\xf3\x9f\xbdP(\ +088xD,\xf2a\x01\x92L&\x7f]WW\ +\xf7\xcf\xcb\x97/g\xf5\xea\xd5tww\xb3y\xf3f\ +\xba\xba\xba\x08\x04\x02~\xe2~\xea\xd4\xa9\xf4\xf5\xf5\x91\ +N\xa7\x994i\x92\xcf~\xfa%=\xe3b\x10\xcb\xb2\ +\xc8\xe7\xf3>M>\xfe@\xb1\xf1\xb3s\xc7^\x5cj\ +``\xe0\xe1\xb1\xff7r4eE\x86a\xf8R\x9b\ +\xcdf\xfd\xef\x1f?t\xdfSK\xa6i\xfa\x07\xd5x\ +\xff\xe6\xfd\xbd\xe38\x8c\x8c\x8c\xb0j\xd5*_\x9dC\ +\xa5\x9b\xca\x1f\xeb1n\x83\xbe\xf1\xc6\x1bG\xd4Bw\ +$\xe7\x87\x88\x8f\x7f\xfc\xe3\x0c\x0e\x0er\xed\xb5\xd7b\ +\xdb6\xb3g\xcf\xa6\xaf\xaf\x0f\xdb\xb6\xa9\xab\xabC\x88\ +J2\xa6\xbd\xbd\x9db\xb1H0\x18\xf4\x87${\xb6\ +\xc0\x03\xc4/\xf3\x19\x03a\xbc$\xa9\xaaJ \x10\xa0\ +\xa5\xa5\xc5\x9b;5\xd2\xd9\xd9\xf9\x89\xf11\xce\xf8\xa0\ +\xf0pT\xee\xc5\x17_\xccE\x17]\xc4\xf0\xf0\xb0\xaf\ +\xb2B\xa1\x90\x9f\x8a\xf6\xd4\xd7x\x06`\xfc\xe1g\xde\ +\xdc\xc9\xb1\x0d:\x81L\x1c_r\xfbv\xd7\x96Rv\ +I)\xfb\x8e7 |\xfa\xd3\x9f\xe6\xa1\x87\x1e\xe2g\ +?\xfb\x19/\xbe\xf8\xe2\x84\xf38\x0c\xc3 \x1a\x8d\xfa\ +e\xf7\xde\x91\x0e\x9ek\xec\xa9\xaf\xf1\xa7\xd5\x8c?\xe9\ +\xcd{!\xc5b\xd1\xaf2\x9c:u*\xe9t\xfa\x0f\ +(\x87#\x01\xc3SYMMM\xec\xde\xbd\xdbW\xb7\ +\x9eZ\x1c\x7f\x14\x85\xf7gOZ\xc7\xd7T\x99\xa6\x89\ +\xae\xeb\xdcq\xc7\x1d\x5cp\xc1\x05\xfc\xfb\xbf\xff\xbb\x97\ +_\xf7YkO\xda\xab\xaa\xaa\xfcA=RJv\xed\ +\xda5\xeb\xb8K\x88\xe7>~\xf0\x83\x1f\x9c\xd0S8\ +\xdevx\x93\x9d=\xfdYUU\xe5\x9f\xc4\xe3\xedJ\ +\x8f#\xf2\xa4\xc5\xf3F<\x8a\xc4\xa3\xab\xa5\x94\x13\x06\ +\x80\x1d\xcbJ\xa7\xd3\xb36o\xde\x8ceY\xf9\xe9\xd3\ +\xa7w\xacZ\xb5\xaa\xf6S\x9f\xfa\x147\xdf|3\xf9\ +|\xde\xef\xb5\xf7\xdcZo\x1c\xdfx\x9a?\x93\xc90\ +{\xf6l\xce=\xf7\x5c\xa2\xd1(\xe7\x9cs\x0e\x1b6\ +l\xe0\x92K.a\xcd\x9a5\x5cy\xe5\x95<\xf9\xe4\ +\x93,\x5c\xb8\x90\xda\xdaZTU\xe5\xb9\xe7\x9e\x9b0\ +\xed\xfax\x03\xf2\x8b\xee\xee\xee\xed\x8a\xa2\xac~\xef{\ +\xdf\x8b\xa2(\xb4\xb7\xb7c\x18\x86?\xef\xdc\xd3\xb75\ +558\x8e\xe3\x0f\x94\x14B\x90J\xa5\xfc\x01\xf5\xe3\ +U\x96W\xd1\xe7}n\xacZ]:\x8e#l\xdb\xa6\ +\xa6\xa6\x86L&\xa3\x1e# ~N\xa3X,\xbaw\ +\xddu\x17\xeb\xd7\xaf\xa7\xba\xba\x9a\x91\x91\x11\x7f\xf7\x8f\ +\xb7g\x1e\xd52>\xd1\x96\xcb\xe5\xd8\xbd{7\x0d\x0d\ +\x0dx\xe7\xffzn\xef\xd6\xad[\xb1m\x9b\x9e\x9e\x1e\ +\x7f\x10\x8d7\x92\xe9\x88\xec\xdd\xe1|\xc8;\xab\x0f\xd0\ +\x96,Ybm\xdd\xba\x95\x9d;w\xd2\xd3\xd3\xc3\x96\ +-[X\xb1b\x05?\xf8\xc1\x0f\xb8\xf0\xc2\x0b\xe9\xec\ +\xec$\x18\x0c2\x7f\xfe|:;;y\xf5\xd5W\xc9\ +f\xb3\x0c\x0f\x0f\x13\x8b\xc5\xfcrS\xef\x04\x01)\xa5\ +\xdf\x9f\x18\x8dF\xfd\x03Q\x06\x07\x07\x13\xe5r\xf9\xe5\ +1\xbb\xb4gdd\xe4\x8b\x1c\x87u\xe2\x89'&n\ +\xbc\xf1\xc6\xfaK/\xbd\x94\xcf~\xf6\xb3\x0c\x0c\x0cP\ +*\x95\xfc9\xed\x85B\x81)S\xa6\xf8\x07\x9cy\xe3\ +oUUe\xe6\xcc\x99d2\x19\xff\xb4\x87\xb7s\x1e\ +\xde\x9a\xe6\xb5m\x9b7\xdf|S\x1cW\x09\x19\xa7\xc3\ +\x15\xcb\xb2x\xf8\xe1\x87\xb9\xec\xb2\xcbx\xf4\xd1GI\ +&\x93\xbc\xf0\xc2\x0bH)\x19\x1c\x1cd\xdf\xbe}\x95\ +\xb3\xa5\xba\xbb'd\x10\xbd\xc1/\xe9t\x9a`0\xe8\ +\x0fO\x8eF\xa3\xbe\xd4\x18\x86\xc1\xec\xd9\xb3\xc9d2\ +(\x8a\xb2+\x93\xc9\x5c\xc3q^\xba\xae\xf3\xe4\x93O\ +\xf2\xd4SO\x91\xcf\xe7\x99\ +\xbf\x059\x1c\x0e\xfb\xd3\x0dB\xa1\x90\x7f\x1cP&\x93\ +!\x97\xcbM\xe0\xb9\x82\xc1 \x17^x!/\xbf\xfc\ +2\xde\xbcu!\x04\xed\xed\xed\xaf\x0f\x0c\x0c\x9cy<\ +\xc1\x18\xb3G\xfe\xcfs\xe7\xce\xdd{\xed\xb5\xd7\xce\xbb\ +\xf9\xe6\x9b\xb9\xfc\xf2\xcbY\xb6l\x19---<\xf9\ +\xe4\x93\xbej\xfd\x87\x7f\xf8\x07\x1ey\xe4\x11\x0c\xc3\xe0\ +\x86\x1bn`\xd3\xa6M\x8c\x8e\x8e\xfa\xae\xb0\xd7\x93\xa2\ +\xeb\xba\x7f\x0cG0\x18D\xd7u\xba\xbb\xbb\x97\x1d<\ +xp\xcb\x91\xdc\xe3\x91\xf6\x9f\xd9]]]\x97\xb7\xb6\ +\xb6^\x17\x0a\x858\xf3\xcc3\xf9\xc2\x17\xbe@4\x1a\ +\xa5\xb9\xb9\x99\xa9S\xa7RUU\xc5\x8c\x193\xa8\xa9\ +\xa9\xa1\xae\xae\x8eH$\x82\xeb\xba~\xa0\xb5r\xe5J\ +\x02\x81\x00\x0d\x0d\x0d\xc4\xe3q\x82\xc1 \xd1h\x94\xb1\ +\x81\xcdon\xdf\xbe\xfd\x9f\xb6o\xdf\xfe\x19\xe0+\xc7\ +[:\xc6\x831&\xa1\xca\x0b/\xbc\xc0%\x97\x5c\x82\ +\x10\x82{\xee\xb9\xc7?\x9fp\xc3\x86\x0d\x18\x86\xc1\x15\ +W\x5cA\x22\x91@\xd7u~\xf9\xcb_\xd2\xdd\xddM\ +\xa1P\xa0X,N89\xc7s\xedC\xa1\x90\xf4\xcb\ +\x91\x5c\xf7\x88\xdd\xc3\xa3:-Z\xd3\xb4\x80\x10\x82\x07\ +\x1f|\x90\x87\x1ez\xe8\x0f\xfe\xfd\xe0\xc1\x83\x7f\xd49\ +x\xab\x1b\xeb8\x0e\xbf\xfd\xedo\xbdIo\xbbr\xb9\ +\xdc\x7f\x02\xefX\xb6\x7f\xf8 \x0f>\xf8 w\xdf}\xb7\xef\ +\xba{A\xafw\xc2\x90\x97\xbe\x1eSo\xa2\xad\xad\xed\ +\x5c\xc7q\xf6\xd4\xd5\xd5%\x8e\xf4\x9e\x8e\xca\xc1\x0f\x85\ +B\xb1\xba\xba\xba\xcf\x85B!\x17\xb8*\x1c\x0e/>\ +\x1c\xbd\xefMz\xf0\xa6<{\x996\xcf\xdfO\xa7\xd3\ +kzzz\xde\xcf_~E\x16/^\x5c\xf0\xfaE\ +t]g\xe9\xd2\xa5\xec\xdb\xb7\xcfw\xc9\x0f\xc7}\xf5\ +\xf8\xb1\xed\xdb\xb7\xcf-\x14\x0a\xedGs#\xc7<8\ +\xaa\xb9\xb9\xf9\xe7MMM\xd7\x1e\xce\x5cs\x0f\x14\x8f\ +\xce\xae\xa9\xa9\xa1P(\x14[[[\xa3\xe3\xbe\x8f\xfe\ +\xfe\xfe\xbf4 \xc1\x96\x96\x96m\xf1x\x5c\xe4\xf3\xf9\ +Hcc\xe3\x09RJ\x0a\x85\xc2a\x8f\x90-\x14\x0a\ +\x98\xa6y\x9f\xeb\xbaV\xb9\x5c\xfe\x8f\xa1\xa1\xa1\xd1\xff\ ++\x80\x00\x81\xb1\xef\x09\x86B\xa1\xa5\x87\x1b\xd7xQ\ +{8\x1cNd2\x99]\xfc?\xb2\x82\xc1`m8\ +\x1c\xfeG\xd7u\x9d#`\x08d \x10H\x9e|\xf2\ +\xc9\xff\xf3\xc2\x0b/H\xde]\xef\xaew\xd7\xbb\xeb\xdd\ +\xf5\xeezw\xbd\xbb\xde]\xff\x8f\xad\xff\x03!\xf6p\ +\xa0\xc1\x03\x97\x85\x00\x00\x00\x00IEND\xaeB`\ +\x82\ +\x00\x00:y\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00d\x00\x00\x00d\x08\x06\x00\x00\x00p\xe2\x95T\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\ +\x95+\x0e\x1b\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e\x1c\x1e\xba\x16\x7fM\x00\x00 \x00IDATx\ +\xda\xed\xbdy\x9c\x5cU\x99\xff\xff>w\xa9[\xd5\xd5\ +\xdd\xd5\xdd\xe9-Iw\xd2!\x1b\x09Y\x00Y\x02\x81\ +\x08\x88@@\x10F\x5cf\x1c\xc1\x19\x01\xf9\x02\x83\xdf\ +A\xe7\x0b\xe38\x83\xc8W\x04t\x5cXd@Q\x91\ +M\x04\xd9\x05!\x04\x08\x09\xd9C:\x0bM\xd6N\xa7\ +\xf7\xa5\xba\xf6\xed\xae\xe7\xf7\xc7\xed\xbaI\x005`\xc0\ +\xef\xcc\x8f\xf3z\xd5\xab\xb7\xeaS\xf7\x9e\xe7\x9cg\xf9\ +<\x9f\xe7\xb9\xf0\xd1\xf8h|4>\x1a\x1f\x8d\x8f\xc6\ +G\xe3\xa3\xf1\xd1\xf8h\xfc\x8f\x1f\xe2\x7f\xf2\xcd\x9dt\ +\xd2I;\xa7L\x992QJ\x89\x00\xa4\xad %\xa0\ +HP$B\xbcs\x05J\xa5Rx\xc9\x92%_L\ +\xa7\xd3\x0f\xff5\xaeY\xfb &\xad\xaf\xaf_\x94\xcf\ +\xe7'\x1d\xf4\xae\x10\x02\xcf\xf3\xa8\xa9\xa9ynpp\ +0q\xa8\xaeCU\xd5\xeaB\xa1\x10\x01\xd8c\x0f2\ +\xf3s\x05*\xa3:NJ\xc3K\x87\xf0r\xfe\xf7n\ +J\xc3M\x86\x00\xf0<\x0f)\xa5\xf6\xd7\xdaD\x1f\xc8\ +\x07\xd7\xd5\xd5\xdd\xf5\xd9\xcf~v6\x80'=\xdc\x0a\ +\x8b\xb0\xa1 \xad\xb1\x97\xad\x80\x1c\xdb\x9dc;\xd40\ +\x0c\x1e\x7f\xfc\xf1c\x81C&\x10)\xa5\xb4,\x0b\x01\ +\x8c\xb8)>\x16\xa9$$\xab8\xf6\x88\x05l\x1f]\ +O\x22\x93\xa4\xae*Bn\xd8f\xf8wu\x07l\x90\ +\xffQ\x02\xb1m\xdb\x18\x1a\x1a\x02`g\xbe\x9f\x85W\ +\x81\xed\xed\xbfP`\x0f\x86(\xee\x8cb\xee\x8e\x80\x90\ +TUU\x81/\xa6C6\x5c\xd7\xc5\xb2,\x90 t\ +\xf0\x84\xc3E3\xbe\xcfs=\xb7q\xeb\x99\xbf\xe7G\ +O\xfe\x90\x89\xad\x1eK\x06\x9e\xf1\xdf7&\x8c\xbf\xa6\ +@\x94\x0fh^\xcf4ML\xd3\xc4v]t]!\ +7P\xc5\xb7?\xfe[\xce\x9eq1\x8a\x13a\xdc\xe4\ +\x0aB\x93\xf3\x98%\x0b\xcb\xb20M\xf3\xa0\x17\xa2\xa5\ +\xa5\xe5\xe0.\xc2\xf3\xa4eY\xd8\xb6\x8d\x87$\x951\ +9\xfa\xf0#\xe9H\xaf@\x11\x0a\x9f8\xfa\x93TU\ +\xc5PB\x12\xc7q0M\x13\xc7q\xfe\xaavO{\ +\x1f\xea\xe8\xc2c\x8e9\xe6_\x1c\xc7\xf1$\x12U\xaa\ +\xb8\xb6\xf4E\xabH4]u;;;[M\xd3\xf4\ +w\xa9\xe7b\x96\x14\xfe\xed\xcc;\xf8\xe9\xfak8\xab\ +\xf9\x1bLQ\xe2\x9c4\xeb(\xee\xde~\xab/\x08U\ +\x12\x0a\x85\x90\xf2\xe0\x0eHoo/mmm\xab\x1a\ +\x1b\x1b)\x1bl<\x05\x89$\x95N\xd6M9l\xca\ +\x0cEQ@\x08\xa4+\x11\x86\xcb\xdc\xfc\x14r\xbf\x84\ +\xd3~\xf6q*B\xd39\xf9\x8e\x93\xd1U\x0d\x81F\ +(T\xc3\xce\x9d[hmmEJ\x89\xeb\xbaSC\ +\xa1\xd0\x82\xf7\xb2.\x15\x15\x15TWW\xaf\xe9\xee\xee\ +\x96\x1f\xaa@,\xcb\x9a{\xd8a\x87\x1d\x97H\xf8\xaa\ +\xbe\xaf\xae\x8b\xd9\x0bu\xac\x81\x08\xceH\x18\x91\x8b\xd0\ +\xdd\xa3b\xdb\xb6\xbfK\x85\x87kKf\xb5\xcd@\xd9\ +\x03E;K\xb6\x98\xe3\xa5\xdd\x0f\xe0y\xbeJ\x11\xaa\ +\x0c\xde\x7f\x90#\x5c__\xbf`\xda\xb4ix\x9eG\ +Q\x9ah\x87\xa7\xa8\x0c\x87\xe8\x5c\xe11\xae\xba\x1e\xcb\ +2\xd1\x84\xca\xf6\xf1[9\xe1\xecJ\x5c\xd7\xc3\x1e\xd1\ +q\x07\xa3X\xc3P\x93\x19\x87\x9dR(\x16J\xa8\xaa\ +@\xd34r\xb9\x1c\xae\xeb\xca\x93N:\xe9\xfa\xda\xda\ +\xda\xeb\x01\x1c\xe9\xa2Wy\xe0(`\x8f\xd9\xbf\xc0\xf6\ +\xc9@\xcd\xed\xde\xbd\x9b\xb5k\xd7F\x80\xd2\x87nC\ +J\xa5\x12\xa6i\x92sKD\x8e-\xa2V+D\xaa\ +s03\x87f\x08\xc4Z'\xd0\xc9\x9e\xe6\xa1\xaa*\ +\xa9\x5c\x1aEQQ\x15\x1d\xdb3\xa9\xd2+\xf1$X\ +\xa6\x89\xd0\x08\xde\x7f\xb0\x8e\x99\xe7y\x94J%\xf0$\ +\x9dz7\x0b\x8f\xd6\x81\x22F<\x83\xbd\xc7\xc2\xb2-\ +\x81\x93\x9b\ +\xbe\xcc7Oz\x88\x90jP2Kd2\x19\x86\x86\ +\x86\x18\x1a\x1abS\xecu\xe4\xc2\x1d8\xa6\x87i\x9a\ +X\xa6\x85\xa2K\x1c\xc7en\xf4\x5c\xbev\xe2\x8f\x89\ +DB\xd4\xb4TR}R\x12\xcf\xf07f\xf9>\xff\ +jF\xbd\xbc\x83,\xcbB\x08\x98\xa0\x1e\xc5\x8a\x9e'\ +\xf9\xed\xf2\xdf\xf0\xa5#\xbf\x89\xeb:\xa4\xd3iR\xa9\ +\x14\xf9B\x1e\xc7\xb3I\xd6.c\xeb\xee\xdd\xf4\xe46\ +Cm??Z{9\xe9d\x8eT:M:\x9d&\ +\x93\xc9 \x84\xf8\xb3\xc7d\xfc\xf8\xf1A\xbc\xe0\x0b\xd2\ +\x02!\xd1\xc3\x1a\x9f\x9cs>\xab\x07\x9fAz\xbe\x0a\ +\xb4l\x1b=\xac#\xac\x18\xbd\xc5\x1d\xb4\xf7\xaf\xe0\xb0\ +\xfay4\xd54\xa1\x0a\x1d\xd7uq\x1c'\xd8\x14\x91\ +*\x81\xaa\x8a\xe0\xf7\xb6m#tA\x85\xde\xc0\x95\x9f\ +\xf8&?|\xf6\x07\x5cz\xec\xad\x5c\xb3\xe8\x1e\xda\x1a\ +g\xe0\xb8\x0e\x8e\xe3\xbf<\xcfCQ\x94\x0f\xdf\xa8\x97\ +O\x88m\xdb8\xd8\x08\xa1\x10\xd6#\xb8\x9e\x8d+]\ +\x92\xc5a\x14E\x0b\xbc\x15\xd7q\x91\x8a\x87kI\x9e\ +\xeb\xba\x85\xd2V\x97\xe2\x80 \xdf\xa51\xb4\xb1\x88\x11\ +\xd1A\x82e\xdaTF\xabn\x9e;g\xee\xe8\x1f\xc3\ +\x0fR\xa9\xd4\xeb===w\x97\x05288\xe8{\ +f\xa3.\xabo\xcap\xfe\x0f\xcfc0\x91C\x9a\x05\ +$\x1e\x02\x81|\xdae\xad\xda\xc1\xe5\x8f\x5c\xc3h6\ +\xc1\xe5w_\xc1\x9a7^\xc3t\x8b\xbe]\xd9\xefd\ +j\x86\xc2\xf6\x9f\xbbT\xc7r`\xfafB_Q\xc5\ +\xeaW\x93\xcc\xbdv\x1e\xd5\x91\x18_\xfa\xd1Wq\xa5\ +\x8b\xa1F\xd0#\x1aB\xf8\x1bTU\xd5C\xe2.k\ +\xef\xf7\x84X\x96\x85-\x1c4Ec0\xbf\x973b\ +\x0b\xe8\x89\x99$\x0a~\xfc\xa1i\xfe\xd4u\x05\x95\xa5\ +\xd7\x8dbgd\x10\x04\xda\xb6\xcd\xa2E\x8bh\x98m\ +\xa2\x0a\x85Nm/G,\xd2\xb1\xfb*\xce\xb6\x07\x22\ +\xc8t\xe8]A\x9d-[\xb6\x00\xdc]VY\x93'\ +O&\x12\x89 \x84\xa0\xcf\x19\xa1\xee\xfc!&\xca*\ +\x9c\xfe\x0a\xac\xde\x0a\xdcx\x08\xe4\xbe\x89j\xaa\xc6\xb1\ +w\xef^\x22TQ\x1bn\xc4s\x07q\x1c'\xf0\xee\ +\xd4\x9cG}c=\xe3\xea\xc6\xa1(\x0a;\x0b\xfd\xcc\ +\xfc\x5c\x91XL\xc7M\xc7\xb0z#8\x835X\xfd\ +a\x14E\x04\xaa\x13\xa0\xbb\xbb\xfb\xaf+\x90R\xa9\x84\ +\xadI\xa4\x0cc\xd7l'1\xecp\xd2\xc7\x8e\xe4W\ +\x9bn\xa0/\xd9\xc7Yg\x9d\xc5\xa5\x97^\xca\xf2\xe5\ +\xcbiooghh\x08\xd7uq]\x97\x81\x81\x01\ +\xcaqJ\xca)\x10=9K\xa89\x8a\xd7\x90D;\ +J\x10\x12\x158%\x0fUh\x0c=\xd0\xe8cO\xfb\ +\xdd|\xf9\xfbr\xec\xa0\x08\x85-\xd6\x1e\xe6\xd56S\ +\xb2\x0a\xd4\xcc\x0bQ\x98\xdd\x0bH\x84\x13\x22\xbd\xaa\x9a\ +\xe2\x8e0\x00!\x11\xe6\xbaW\xcf#[\xca`\xd9V\ +\xa0r\x00*\x84\x82;6\xa7\x10\x82\xbe\xd2('7\ +\xd6Q,\xba\x1c9\xe38\xb6\xd6\xac@\xceu\x11\xa8\ +\xe46E\xc9\xac\xa9\x02!Q\x14\x05\xcf\xf3>x\x81\ +\x8c\x1f?\x9e\x81\x81\x81\x03\x8d\x8e\xa28\xc9d\x92T\ +*\x85\xady\x94\xac\x18\x8e\x90\xdc\xf5\xc6\xd7\xf9\xc6\x19\ +7#\xc3&\x96[\xe0\xfa\xeb\xafg\xd9\xb2e|\xfe\ +\xf3\x9fG\xd7u\x22\x91\x08;v\xec\xa0\xb2\xb2\x92\xf6\ +\xf6v_\xa0\xb6\x8d\xed\xda\x18\x9aJjH\xe5\x07\x17\ +>\xcd`z\x80\xfb6]\xcf\xe2y\x7f\xc3\xf3]\xf7\ +\x8e\xb9\xc5\xbcC e\xe1Z\x96\x85\x22\x04\x8a\xa2`\ +\xd96_=\xfcgdD\x17\x9a\xe1\x91\x1cuX\x91\ +\xf89I|{ \xa5\xc4\x93\x1e\xdd\xdb\x06H\xec\xb4\ +\xc9\xc6K8\xd5\xfb<\xc2\xa8P\x025&\x84\x00\x01\ +%\xd3\xe4\x82\xe6\xef1\xaa\xb7s\xcd\x82{xe\xf3\ +\xcbd\x22\x1d\xb4\xb3\x0b\xdb\xb6\x90H4M\xc3\xb6m\ +TU}\xcf\xce\xc9{\x12\xc8\xc0\xc0\x00mmm\xff\ +\xbb\xba\xba\xfah?\x00\x13\x8c&F\xe7\xab\xaa\x8a\xa2\ +(\xe8R\xc1\xc9Hr\x03.v\x9f\xe0\xeb\xff\xf2\xcf\ +\xa4wIJ\xa3\x82\xaf|\xe5+|\xfb\xdb\xdf\xe6W\ +\xbf\xfa\x15\xdb\xb7oGJI\x22\x91 \x16\x8b\xd1\xd9\ +\xd9I}}\xbd\x1f\x19K\x1b\x01\x1c\x1e^\xcc\x9a\xc1\ +\xa7\xd9\xd35\xca9\xe3\xff\x0f\x0b\x0f;\x965C\xcf\ +\xb2\xd3,\xbd\xab@\xca'\xc4q\x1c\x14\x04J\xa5\xa0\ +sg\x96#\xcf\x9b\xcde\xbf\xbd\x9c\xfb\xfev\x1d\xc3\ +u#x\x03#<\xe4\xfc\x0e\xd3\x1c\xfb\x7f\xcdc\xe5\ +wS\xa8\xba@\x11\x0a\xc5b\x91b\xb1\x08@\x95\x1b\ +\xc2uU\xff\xd4)\x0aBHF\x86J\x9c\xfd\xe9O\ +r\xe5\xd37p\xe6\xd4\x8b\x99\xde0\x8f\x94n\xb0\xc1\ +\xdd\x8ei\xfa\x0e\x85\x94\xfe\xebC1\xea\xe3\xc6\x8d\xfb\ +\xc2\xb4i\xd3\x8e\x07p\xa5\xc7\xfa=o\xa0\x0a\x95\x89\ +\x13'b\xdb6\xe9g-R\xd2CJ\x81\x94a4\ +@\xd3-\xfa\xfa\xfa\xb8\xf4\xd2K\xdfu\xce\x5c.G\ +,\x16\xf3]g\xe1 \x84B\xa5Q\x83\xe5\x16q=\ +\x97\xba\x86\x10]\xa9\xadd\xac\x04\x96\xa5\xa1h\xe2\x1d\ +\x02Q\x14%8%\x02\x81\xa2\xa8\xb8.h\xaa\x8a\x10\ +\xfe\xc28\x8e\xc3\xea\x9e\xdf\xe3\xb9.\x96\xe5\x05\xae\xf2\ +\x9c\xf9\xb3\xe9\xe8\xe8 \x16\x8b\x05\xaa\x13\xc0\xf1\x94}\ +\xa7NQ\xc0\xd8\x87~\x0aEA\x08A\xb6\x94e\xc3\ +\xc8\x92`.\xc4\xbe\xe0\xf0`\x91\x86\xbfH \x9e\xe7\ +\x09\xd34\x91R\xf2\x96\xd9K\xed\x14\x97\xe3\x9a\x8e\xe7\ +\x9cs\xce\xe6\xe4\x93O\xe6\xa7?\xfd)[\xb7ne\ +\xfe\xfc\xf9\xac\x5c\xb9\x92\x993g\xb2f\xcd\x1a\xe2\xf1\ +8\xe1p\x98|>\x1f\xec\x9c\x8cRb\xfc\x1c\x85\xfa\ +\xc4T\x8a\xd9\x9c\xef\x18(\x0e\x8a\xa22\x9c\xeba~\ +t.\x03\xc2d\xb4\xd0\xcf\x84\xc8D\x84\x14X\xa6\x85\ +p\xdfyB\xf6\x07\x0f\x05\x02\x0145E\xc8e\x1c\ +\xa4\xeb\xab&\x17\x9b\xb0R\x85\xebf0M\xb7\x0c\x8b\ +\x80\x84I\x93&\xa1i\x1a\xae\xeb\x06\xf3*\x1b$9\ +'\x03X\xbe\xca\x0aC}}\x84\xcd;w -\x1d\ +EQH\x17\xe3\x1cV}4;\xdc\x17\xb0,_e\ +\x95m\xc7\x87\x22\x10)\xe5>\xfd\xeb\xf9\xae\xa4\x10\x82\ +\x9a\x9a\x1a\x22\x91H\xe0\x7f\x87B!\x8e:\xea(\xf6\ +\xee\xdd\xcb\xd1G\x1f\xcd\xbau\xeb0\x0c\x83\x9a\x9a\x1a\ +\xd2\xe94B\x08R\x86\xc7\xb4OE\x08\xaf\x9e\xc6\x96\ +\xd5\xeb|\xf0Q\xf7PD\x98Ac9\x13\xf5\x8bh\ +\x9a?\x9d{\xd6\xff\x1b\xe7\x86\xfe\x91\xaap-%\xab\ +\x0f\xe5]\x04\x22\x84\x1f/\x94J%\x941,c\xc2\ +\xc4j~\xf2\xca\xb7\xb8\xeb\xc2e\xdc\xf4\xda\xc5H3\ +BcM3\xb6\xd3E\xa9d\xf9\xaa\xc5\x15\x8c?]\ +b\x0eU\xe1fu\x9c\xa4\x06\xb6\x82P\xfd\x135\xe2\ +$\x82\x13\xe2T\xbaTU\x86\xb9s\xdd\xff\xe6\xa7\x9f\ +[\xca\x7fm\xb8\x86\x1d\x99\x0eZ\xf4Vl\xd7\x22\x9f\ +/\x80\xf0\x05\xa2(\xca\x87vB(\x9f\x10Ox(\ +B\xa1\xbd\xbd\x9d\xd1\xd18\xc3\xc3\xc3\x14\x0a\x05\x00:\ +::\x02]\xea\xban\xb0kJ\xa5\x12\x86a\xf8I\ +(\xdd\xa3\xc20\xd84\xf4:\x89D\x8eb\xb1\x88\x19\ +\x92\x14\xad\x18F4\xc2\xb5\xbf\xbb\x98\xbb\xbf\xf2[2\ +\xde \x8fu\xfc\x88R\xcactd\x14\xcdP\xcaj\ +\xca\xdb_ \xc5b\x91T*\x85@P0%%\xcb\ +\xa4\xcb{\x85_/\xbf\x87\x86\xda\x09\xac\x8b/\xc5K\ +\x08\xba7&\xc9\xa7}\xf7V\xc3\xa0uA\x05\xfd\xf1\ +\xbd\xfeB\x86$\x89Wc\x14;\xa2A\x90X,\x16\ +\xfd\xf9\xab<,\xd7\x82\xaa8_\xfb\xed\xe79r\xc6\ +\x0cR\xb9a\x92\xf18;\x96$\xc9\xe7\xfd9\x85\x10\ +\x18\x86\xf1\xe1\xa0\xbd\xe5\x88\x18@\xea\x12\x90\xd4\x8f\x1b\ +G<\x1eGQ\x14*++\xffd\x10\xd9\xdf\xdfO\ +2\x99DQ\x14r\xc2\xa1dW\x10\xad\xcf\x93VU\ +TUEC\x82\x10\x08EPiH.\xfa\xe6\xa7\x19\ +\xed\xb0I\xed. \x14\x81Q\xa1\x07\xf3\x19\x86q\xf1\ +\x84\x09\x13\xf6\xf4\xf7\xf7\xdf*\x84@\x1d\x9bC\x11\x0a\ +F\xc1E\xba\x92d\x07<\xbc\xfd\x1e\x867[\x98i\ +\x171\x16/h\x9a\xe6g\x03=\x97\xd3&\xfc#b\ +\xa2CzX\xf0J\xf26Fl_\xf5\xb9\xae\x8b\xa2\ +(h\x9a\x86\xa2(D\xd3.\xe9^\x87\xfe\x0d&\x89\ +\x1d\x9bx~\xef\xfa\xfd\x5c[\x81\xae\xebH)\x83\xa0\ +\xf0P\x9c\x10\xf5\xcf\xbd\xa1\xa1\xa1\xe1RUU'\xba\ +\xaeKV\xb5\x98\xff\xe9(g\x1c\xfd\x0f\x94fl\xe2\ +\xb2\xcf\x5c\x87\xd1\xa20\xfe8A2\xba\x87\xee5\x19\ +\xf2\x85<\x85B\x81\x81\x81\x01+\x9b\xcdZ\xb6m\xab\ +\x8e\xe3\x08)%\xc5\x88\xc7\xec\x8fW\x92\xed\xb5)\xec\ +\xd1\x88D\x22\x18B\xa3\xd8\x01]/\x9a\x0c\xac\xb4\xc9\ +tJ\x9c\xac\x8f\xbe\xaa\xaaZN\xc5\x22\x84`\xe2\xc4\ +\x89$\x12\x89d8\x1cV3\x99\xcc\xceX,v|\ +\xb1XT\x9a\x9b\x9b\x09%%{_\xb2\x19\xdd\xecR\ +\xe8\x07\x5c\x05MS\xc7\xbc%\x7f>!\x04\x9a0\xc8\ +\x1f\xdd\xce\xff:\xf6{D\x8d*\x06\x0a\xbb\xd9\xbd\xb9\ +\x97\x5c\x9f\x87\xe38\x14\x0a\x05\xc6\x8f\x1f\xcfUW]\ +E\xbao\x84\xe4F\x0dg(D\xc8\xad R\x11\xa1\ +\xa2\xa2\x02EQ\x08\x87\xc3\x01\xa0h\x18\x06\xf1x\xfc\ +QUU\x1f+\x14\x0a\xde\x07.\x10`\xa2\xe7y\xe4\ +\x0d\x879\xa7V\x93t\x07\xb9\xee\x9c;\x18\x12o\xb1\ +1\xf5\x02\x0b\xe7\x9c\xca\x9e\xc4V\x06\xd6\xfa\xd8\x96\xa2\ +(L\x9f2S\x9du\xf8l=\x91J\x88R\xa9D\ +\xa9T\xa2\xca2\xc8t\xb9\xf4\xaf\xcb3g\xd6[d\xea\xe2j\xce\x9eq1\xd9B\x8e\xe7:\xef\ +\x22\xb1\xdd\x09\x04R,\x16y\xf9\xe5\x97\x91Rr\xd2\ +\xc9'\x91/\xe4\x995{\x16UUU\xcc\x9b7\x0f\ +\x80s\xce9\x87\xe9\xd3\xa7\x07s\x16\x8bE\xb6m\xdb\ +6\xe7/\x15\xc6A\x81\x8b\x8e\xe30::\xca\xe8\xe8\ +(\xe9L\x86\xa2U\xa4\x10\xd9\xc5\xf7\x9f\xfa.\x9a\xae\ +\x90U\xbay\xea\xad\xbb\xe9\xebH\x92L&H$\x12\ +\xa4S\x19\xd4\xd3v#>\xbe\x1d\x19)q\xc2\x09'\ +\xb0~\xfdz>v\xcc\xd1\xc4\xec\xf1Th\xd5L\x99\ +2\x85d2Iss3\xe3\xc7\x8f\xa7\xb6\xb6\x96\xa9\ +S\xa72}\xfat\x14Ea\xf2\xe4\xc9h\x9aF8\ +\x1c\xa6\xb1\xb11\xd8\x8d\xea\xcc8B\x11TTT\xe0\ +y\x1e\x8d\x8d\x8d\xc4\xe3q&M\x9a\x84\xeb\xbaL\x98\ +0\x81\x86\x86\x06f\xce\x9c\x19\xc04uuu\x9c~\ +\xfa\xe9\x14\x0a\x05TE\xa1R\xaf\xc5vM,\xcf\xa4\ +\xdah\x08\xbc\xb5\xb2\xda\xea\xea\xea\xc2u]\x86\x87\x87\ +\xf1<\x8f\xda\xdaZ\xf2\xf9<\x9a\xa6\x91L&\xe9\xeb\ +\xeb\xc3q\x1c\x9a\x9b\x9b)\x95J\xc1I\xfePh@\ +3g\xce\x5cc\x9a\xe6q\x8a\xa2\x90\xaat\xf8\xd47\ +\x1b1\x0cAj\xb7\xc3\xf0\x16\x93\xf8[\x16\xf9a\xf7\ +\x00lGU5\xce\xb9\xe2T\xf4y{x\xf1;{\ +\xf8\xc9\x0d?#\x9dNs\xef\xbd\xf7RSSCg\ +g'\xae\xebr\xec\xb1\xc7\x92L&\xe9\xef\xef\x0f\x9c\ +\x01\xcf\xf3\xde\xf1*\xbb\xa6\x95\x95\x95\x0cezPL\ +\x83\x193f2<\x14\xa3^\x1e\xcd\ +\xcd\xcd\x18\x89$\x1bo.\xe2\x94\xe4\x18kD\x22\xd1\ +0\x0c5\xb88\xcf\xf3P\x04|\xe6\xd8\xbf'\xde\xb4\ +\x89WBw\xf2\xfd\xef\x7f\x9fo~\xf3\x9bd2\x19\ +\x22\x91\x08\xb6mSUUE{{\xbb\x7f\xf3\x08<\ +W\xe2I\x17!\x14\xdf\xb0*\x1a\x9e\x94(B\x09\x22\ +u\xcb\xb2h\xaanedd\xc4\x8f\x01\xa4\xc4\xb1\x1d\ +\x96\xbd\xf2\x1a\xaet\xd0\x14\x1dO\xfaq\x8d\x82\x8a\x16\ +\xd2\x82m'<\x81\xebJ\x9c\xa2\xc7\xcf\x97\xdfIc\ +\xb4\x85\xcd\x85\xe5\x14m\x95=o\xc4)&\xfd 3\ +\x1c6\xd0\x09St\xf2DB\x11,\xdb\xf6m\x11:\ +\x8a.\x0f\xd8\xc2A|\x95\xc9|x9u\xdb\xb6\xb9\ +\xfa\xea\xabY\xb4h\x11\x8e\xe3\xf0\xe8\xa3\x8f\x92\xc9d\ +\x82\xa0\xafP(0}\xfat\xde|\xf3M\x12\x89\x04\ +\xf5\xf5\xf5l\xdd\xba\x15M\xd5X\xd3\xf3\x1c!\xcd \ +\x97\xcb\xf1\xf5\xaf\x7f\x9dB\xa1@MM\x0d\xd1h\x94\ +\xad[\xb7\xd2\xd8\xd8\xe8\xab\x0b\xc5e\xce\xe7\x22\x1c;\ +\xeeB\xccp\x1f\xa9\xbe0\xeb{^\xe5\xf4cNf\ +\xdd\x8eW\xd9\xf3\x8c\x83\xa2ACC\x03\xc5b1\xf0\ +\xfc\x5c\xc7\xa1\xdb\xebg\xde\x19\x95\x5cq\xc2\xcd\xfcb\ +\xe3\xb78\xa5\xf12V\xedz\x95|\xc56\xb6<\x90\ +!\x9f- \x10\xe4\xc6y,8;\x86\x18\xf6x\xfc\ +\xf9\x9f\x92\xeev1G \xdb\xe7`\xe7\xf7yJ\x9e\ +\xa5p\xfa\x1d-\xfc\xe8\xec\xdf\xf3\x99\xff\xfc$\xff\xf2\ +\xe9\x7fG\x91!6$\x7f\xc7\x0b\xff\xf5\x06\xa5>=\ +\x10\xcaK/\xbd\xd4\x0c\x0c\x1fJ\xb6\xccA\xb9\xbd\x93\ +'O\xa6X,2s\xe6L\x14Ea\xda\xb4iT\ +VVRUU\xc5SO=\x15\x18\xe2L&\xc3\xc6\ +\x8d\x1b\x09\x85B\x08\x04\xba\x88Pt\xf2\xec\xdd5\xe2\ +\xbb\x91\xd1h\x80\x13\x95\xed\x83m\xdbH\xcdc\xe2\x91\ +\xd5\xbc5\xf8*?\xb8\xe0\x01L%\xc5\x7f<\xbb\x86\ +\xc5'\x9fM\x9f\xdaN\xef\xf3i\xd4\x90O\xa6+\xc3\ +\xe5\x96e\x11\x0eG0\xea\x1cZ\xe6\xd7p\xc6\x19g\ +\xb0T\xf9!\xc7\xb7\x9e\xc8P\xa4\x8b\xe1\xe8^\xba\xaa\ +<\x0c=LCC\x03\xc3\x83Ct=\x06B\x11\xc4\ +U\x90c\xe6Sx\x1aFX\x04*S\x95\x1a\x8a]\ +\x85\xc4%K/M5\xcd<\xbf\xfaUv*\x1b\xf1\ +\xc6\xd4\x1e\xc2\xf7\xfc\xaa\xaa\xaa\xc8f\xb3\x87\x94\xba\xf4\ +g\x05\x12\x89D\xb8\xe9\xa6\x9b8\xf7\xdcs\xf9\xde\xf7\ +\xbeG\xa9T\x0atrY?\xf7\xf6\xf6\x1e`\x03\x14\ +\xa1\xb0\xec\xad\xa5\xcc=\xfeD\xd6\xb6u\xe3\x0c\x86\x89\ +F\xa3\xa4\xd3\xe9\x03\xd2\xb5\x89D\xc2\x0f\xc6B\x12\xcb\ +\x0dS\xd1X\xe2{\x7f\xb8\x86\x1b?\xf3\x13\x8cJ\x87\ +_n\xfc\x0f\xe2\x03&\xa9t\x12E\x13\xd8\xb6\x1d\xc4\ +\x13e\xbe\x95\x94\xe0x&\xb9b\x0e+k\xa0\x1a\x16\ +\xaa\xaaS\x1fj\xa3dn\xe0\xb6\x1f\xdfA}}=\ +\xabV\xadb\xe3\xc6\x8d\x84\xc3azzzhll\ +\xa4\xab\xab\x8b\xd9\xb3gcY\x16\x1b6l\xa0\xa2\xa2\ +\x82\xbe\xae\x01\x14\x0dTU\xc7q\x05\xaet\x89\xe8a\ +\xa4\xe7\xe1\xd8\x0e\xa6\xe5\x93\x1b\xca\xc1\xee\x87N\x03r\ +]W\xaf\xac\xacd\xe9\xd2\xa5\xc1\x05\x94\x8d^90\ +\x13\x12\xf6O);\xb6\xc7\xda\xc4#t\xf7EH\x0d\ +eI\xa7\x0bTUUQWW\x17\x08\xa4\x1cPy\ +\x9e\x87\x82D\x0b\x0b\x8a\x09\x97\xc1\x9d[9\xeb\xcb'\ +\x91\xeb\xf5\xb0\xf3\x12+\xe3\xa2\x85\xf6\xc5#\xe5\xcdP\ +*\x95\x90\x9e\xc4q<\x22Q\x95k\x9f\xfd,7\x9e\ +\xf90\xbf\xd8r\x1d\x83\xfaN\x1a\xf4\x06\xa4\x84q\xe3\ +\xc6\x91\xcdfimme\xdd\xbau\xcc\x9f?\x1f\xcf\ +\xf3\x98={6CCC\xe4\xf3y\xda\xda\xda\x985\ +k\x16\x0f<\xf0\x00BQp4?\xfa\xff\xdb\xa3\xff\ +\x89\xbc\xecG\xa2r\xc6\x94\x7f`\xabs'\xd6\x98@\ +\x0eU\x86\xf0={YUUU\x0b<\xcf\xaby\x9b\ +gQ\xdb\xda\xda\xfaP.\x97CHp\xa7\x08\x8e;\ +\xb7\x9a\xfc\x90K~\xd8\xa50\xe4\x11\xa9\xd2)\xa5=\ +\x92\xbbl<\xe92y\xf2dt]'\x97\xcba\xdb\ +6\xc3\xc3\xc3\x84B!\xe6\xcd\x9bG_o\x1f\x96m\ +\xe3\x99r\x8c\x08\xed;\x0c\xae\xeb\x1e\xa0:\xa3\xd1(\ +\xa5R\x89|>\xef_\xbc\x04s\x9a\xe0o\xbe\xd1\x84\ +\xebBK\xf8(\xc67\xd7\xb2z\xd7K\xe4\xfa]\xba\ +\x1e\x0c\xd12\xb1\x95c\x8f=\x96\x17^x!\x88\xa6\ +-\xcb\xc20|\xdbV\xcee\xf8\xfc\x00\x81]\xf08\ +\xed\xceJ\xf2C\x06?\xff\xfcRnZ\xf1e\xba\xd2\ +o\x22\xf1\xd8\xfc\xd3\x12\xc9N\x07\x90\xd4\xd6\xd6\xb2s\ +\xe7\xce\xe6d29\xf4\xa1\x0a\xe4\xdd\x86\xae\xebM\xf3\ +\xe7\xcf\x1fL\xa5R\xd4\xd4\xd4\x90\xcbfq,?_\ +\x82\x02\x8a\xcf\xb29\x00\xdbjiia``\x00\xcf\ +\xf3\x13@\xa6ir\xdf}\xf7\xd1\xd2\xd2\x82\xa2(<\ +\xf9\xe4\x93\xec\xde\xbd\x1b\xd7u\x03ol\xc2\x84\x09t\ +vv\x92L&\xd14\x8dt:M\x22\x91\xc04\xcd\ +@uy\x8d\x82\x93\xff\xb1\x96\xf8\x0e\x9bT\xa7\xcd\xe8\ +6\x0b3\xe5\xa1h\x82\xc6\xf1\xf5A*\xf9\xcfy\xaf\ +\xe5\xb5\xc8\xa5\x0a\x1c\xf5\x8d\x10NIR\xa1\xd6\xa1\xaa\ +\x1eY3I\xba\xc7a\xfb\x139<\xc77\x19\xd5\xd5\ +\xd5\xe4\xf3\xf93\xc3\xe1\xf0h*\x952{zz\xb6\ +\xfeU\xb9\xbdB\x08\x1e}\xf4Q\xa4\x94\xac\x5c\xb9\x92\ +\xdd\xbbw\xd3\xdb\xdb\xebg\x01\xc7^\xaa\xaab\x18\x06\ +\x9d\x9d\x9dD\x22\x11t]?\x80\xa11}\xfat^\ +\x7f\xfdu>\xfb\xd9\xcf\xd2\xda\xdaJ$\x12\xa1\xbf\xbf\ +\x9f\x193f\xd0\xde\xde\x8ea\x18444\x90\xcdf\ +I\xa5R\xe8\xba\xee\xa3\xbb\x8a\x82a\x18|\xf1\x8b_\ +\xe4\xe5\x97_\xa6\xe7\xa1\xb19]\x97q1\x0f\xb7\xd2\ +\xb7e\xfb{d\xb1X\x8c\xed\xdb\xb7\x9fR*\x95\xf6\ +\xbc\xedV\x8e>\xfc\xf0\xc3\x9f\xc8\xe5r\x14\x0a\x05\x16\ +-Z\x84\xb2\xbc\x92\x10P\xf0l\xb4:\x0b-5\x91\ +\x06\x04\x0d'\xbec\x19^PU\x95\x8e\x8e\x8e\x1d=\ +==3\xffj'D\xd3\xb4\xa6\xa3\x8f>z\xf0\x96\ +[n\xa1\xa9\xa9\x09\xc30\xb8\xe1\x86\x1bhhh@\ +UU\x16,X\xc0]w\xddEUU\x15MMM\ +\x84\xc3a^x\xe1\x85 \xc3\xd7\xd0\xd0\xc0\xde\xbd{\ +\x99>}:G\x1ey$\x83\x83\x83$\x93\xc9 \xe1\ +4V\x12\x80\xae\xeb\x14\x8bE\x1c\xc7!\x12\x89\x04d\ +\x02EQx\xf3\xcd7\xd9\xbcy3\x00\x1b6l@\ +\xd34V\xae\x5c\xc9\xe4\xc9\x93\xc9f\xb3L\x992\x85\ +b\xb1\xc8\xfa\xf5\xeb\x91R244\xc4[o\xbd5\ +}tttW\xf9>\x1a\x1b\x1b\xaf-\x14\x0a\xc7\xd4\ +\xd6\xd6^X\xbe\xf6l6\x1bD\xde\x83\xc5a*#\ +>\xac.\xed1\xe6\xbe#\x984i\x12U\xd5U>\ +\x89[\x08\x1c\xc7\xb1\x84\x10]c\xea\x5c\xdb\xb4i\xd3\ +}\xf1x\xfc;\x1f\xea\x09Q\x14\x85G\x1f}\x94\xe3\ +\x8f?\x9eg\x9f}\x96\x5c.\x17\xa8\x93\xce\xce\xce \ +g\x1e\x8f\xc7\xf1<\x8fH$B&\x93\xe1\x86\x1bn\ +`\xca\x94)\x5c|\xf1\xc5\x98\xa6\xc9\xca\x95+\x03\x1b\ +Q\x86G\xca\xc6\xb2\x9c\xdb\xd6u\x1d\xdb\xb6\x09\x87\xc3\ +A\x00\xbaq\xe3F\x9a\x9a\x9a\xd8\xb1c\x07\xa3\xa3\xa3\ +\x81\x0b]YY\xc9\xc6\x8d\x1b\x19\x1a\x1a\xa2\xa1\xa1\x01\ +]\xd7\xe9\xed\xedEUU\xa4\x94\xe2m\xc1\xee%\x0b\ +\x17.\x9cf\xdb\xb6D\x22\x8a\xd5i\xaab\x1a^*\ +\x84\x9b\xd6\x11R\x01\x05\x84\x90\x01\xc8d\x95,z\xd8\ +L\xf3\x94Z\xdc\x8c\x8e\x9b\xd2\xf0\xb2ZHh\xcc\x00\ +\x08\x87\xc3l\xd8\xb0\xa1\xf1\xc3\x88\xd4\xeb\x92\xc9\xa4>\ +V\x5c\xd3\xe0\xba.k\xd6\xaca\xf5\xea\xd5\xef\xf06\ +\xca\xbc\xdf\xb2j\xdb?\xc5YUUE\xa9T\xe2\x17\ +\xbf\xf8\x05\xf7\xde{/\xb6mSSSCcc#\ +/\xbc\xf0\x02\xad\xad\xad\xe4\xf3y\xb2\xd9,\x9e\xe7\x91\ +N\xa7\xc9f\xb3\xc4b1R\xc9\x14U\x95\xd5\x14K\ +\x05.\xbb\xec2b\xb1\x98\x8fO\x8d\xedh!\x04o\ +\xbd\xf5V\x90\xde\xdd\x1f\xde\x187n\xdc\xbb\xb2\xe3\x13\ +\x89\x04\xb6m\x8b\xbd\xf6\x10\xb3?i\x22\xa3\x0a\x1e\x0e\ +\xaa\xa6\xe0\xa5t\xac\x01\x03\xbb/L\xa9\xd3?\xa1\xd2\ +\x85\xdaya\xea\x16\x94(\xbaq\x14\x05\x9c\x9c\xca\xf0\ +C\x8d\xef\xb8\xe7\x0fT \x8a\xa2\xac\xb9\xf0\xc2\x0b\xa7\ +\xbd\x17\xcad(\x14\xe2\xc5\x17_|\xc24\xcd'\x01\ +\xea\xeb\xebo\xbd\xe9\xa6\x9b\x9a\xce:\xeb,V\xadZ\ +\x15\xa8\xa7r\x1c\xa3(\x0a\xbd\xbd\xbd\x07\xe0P\xd1h\ +\x94\xfa\xfaz\xc65\xd7\xc3\xbc!\xaa#!^\xb9m\ +7\xb1X,`\x9d\x1f\xcc\xd8?\x95\xfcv:\xaam\ +\xdbX\xd2FAA\xcfM\xe4\xe6\xf3\xee\xe1\x85\xdd\xbf\ +\xe6\xf9\xd1\xc7\x99<\xbf\x9e\xbe\xd8 \xd9\xedZpj\ +?1\xe1\x5c\xae8\xf5j\xbe\xf0\xd3\xd3\xf8\xa7\xf3\xaf\ +\xe4\xd1U\xf7\x049\xa3\xbf\x94\xe8p\xd0\x02\xf1<\xaf\ +\xaaL\xb1\x1cu3L\xbc M\xa4B\x01K\xc1\xb3\ +\x15\xdc\x94\x865`\xe0\x0c\x19\xb8\x19\x1d!\xfc\xaa\xa8\ +P(\xd4>00\xf0\xeb1(\xff?\xea\xeb\xeb\x1b\ +W\xae\x5c)\xf6\x8fct]\xff\x93\xe0]>\x97g\ +C~\x07g\xcc\xaa@\xd5-\x16\xdeX\x81\xa6\x14\xd0\ +U\x1d\xd7\x968q\x83\xd4\xd2\xda\xe0\x7f^{\xed\xb5\ +\xaf\xe6\xf3\xf9G\xde\xb6\xa1\xdc\xa6\xa6\xa6\xfc\xdb\xe77\ +M\x13\xc7v\xf0T?\x99\xf5\x99\xe9\xd7\xf0_\xab\xff\ +\x9d/\xcc\xfaWf-\xfc\x04z\xb4\xc4\xcd\xbb\xaf\xde\ +G\x06\xf7\x04\xaft?\x88\xf6l\x8cO\xcd\xfe2m\ +\xb1#p\x5c\xc7'~\x8f\x09\xe4C9!ep\xcf\ +\xb1\x1d\xb2J\x9e\xcajA6gr\xce\x11\x7f\xcf\xa8\ +\xd9\xcd\x9bC\xab\xa9\x9a\xe6Q\x18\xcd0\xf4p=B\ +\x0bj>\x82\xab\x8b\xc7\xe3\x09\xdb\xb6\xa7\x9a\xa6\x19@\ +1\xe5,[RI\xd18Q\xc7M\xebxY\x1di\ +\xa9d\x0b)\x8c\xb0\xc1\xb8\xbaq@\x06E\x15\xcc3\ +\xbe\xc0\xe2\xc5gc\x91\xe3{O\xfd;\xf3gOf\ +\xab\xb35\x98g,\xbf]\xf4^\x7f\x19\xcd\xb1:\x1a\x12G\xb1n\ +h;\x9f=\xf9B\x1e\x1f\xf4\xc9m\x8a\xa4\x1c\x91\xef\ +\x8f\xf5d\xc3\xe10\xae\xeb\xa2i\x1a\x13'N\xc4u\ +]\xd2N\x81Y\x17\xb9\x18a\x05\x17\x1b\xa18xy\ +\x85\xedw\xd7`\x88\x0a?J\xf0 \x95*r\xfe\xf1\ +\x17q\xdb\xda\xcb\xf8\xfc\xf4\xff\xe0\xdf\x17\xdf\x81\xad\x8f\ +\xd2\xbe\xf5\xaa`\xc1\xfeH\x04\xad\xb4\xb4\xb4\x8c\x94\x13\ +U\x00\x9e\xea\xa2i*\x9e)\x10R\xd0 \x1a\xc8=\ +\x067{\xd7\xa3+\x06?\xf5nCA\xc5\x99\xbb\x9b\ +I\xb3\x9a\xf6\x95\xbc\xa1\xd0\x1ai\xe5\xb0\xe6\xc3X\xdf\ +\xbb\x97\x1a\xa3\x11\x89\xc4\xb2\xec\x03(\xb4\x1f\x8a@\xca\ +\xc7\xdb\x15\x0e\x0aa\x16\xcd]\xc4\xca\xa1\x87\x19\xe9\xaa\ +\xc0p\xea\xb1\xbd\x12H\xe1\x03\x88\x1e\xe5\x9c\xf3\xa9\xe3\ +\xc7\x8f\x1f\x1c\x18\x18\xb8\xa7|\xc1\xe5\x8b.\xd3\xf8m\ +\xd7&\xa4k$\x06]~p\xc1\xe3tf\xd6\xf1\xe0\ +\xc6\xffDz\xc2'\x19H\xc0\x00\xab$\x89F*\xf0\ +\x84C\xb6\x90g\xdd\xce\x0dT\xb4\xf4\xa3)\xa1}\x05\ +B\xefN\xe94***\x88D\x22H\xcf\xa3G\x0e\ +3\xff\x22k\x1f\xe1n4\x843\x10\xa1\xd4m\x10N\ +T\x8f\x91\x8a\xc2\x84\x8d0\xf3\xa7\x9f\xc4&\xf7\x09,\ +k\xdf\xbe:\xa5\xedR&O\x8f\xf0\xfc\xf0*Vt\ +\xd9P\xe6h\x8d\xdd\xdf_rB\x0e\xda\x02\x95\x0d\xa0\ +eYx\xae\x07c\xa5\xcc\x08Q\xa6\x92Qrrc\ +\xef3\x83r\x85\xc3\x0f?\xfc\x14\xc30\xbeZ\x9e#\ +\x16\x8bq\xd7]w1~\xfc\xf8}u&\xb6\x83\x10\ +\x82\xaf\x1c\xf3m\xd6\x0c=\xce\xcem\x19f\xa9\x9f\xa5\ +\xd2\xa8\x0e\xe6AB\xac\xc6`$5J\xb5^\xcf\xf8\ +\xbaF\x5c\xcf\xc6vl\x84T\x02\xc2\xdb\x1f\xa3rJ\ +)\xc7j>l\xf2\x22\x0f\x12\x0a)\x95\x0bf\xff/\ +\xaa\x9bC\x18\xb3\xd3\x8c;7Nx~\x22\x98\xcbq\ +\x5c\x96t\xdd\x87c{$\x93I\x92\xc9$\xa5\x82\xc9\ +\xa3\x9b\xee\xc2\x949B\x95\x92\xce\xe2Z\x86w\xe7\x82\ +\xbf\x8fQ\x9e\x9c\x0f\xd5\x86\xb8\xae\x8b\x82\xc2\x8b\xed\x7f\ +\xe0\xe4\x8f\x9dLJ\xea\xbc\xd6\xf54G6~\x8d\x97\ +\xc5sXV\x1eE\xfa\xe8\xec\x98W\xe6\x95w\xefu\ +\xd7]G<\x1e\xa7\xa5\xa5\x85B\xa1\xe0\x9f\x10a\xa3\ +H\x95\xc3\x9a\xa6\xf2\xda\xe0JF\x0b%v\x0du \ +\xf0\x17Z \x90H*+\x22<\xb2\xe5\x87|y\xc1\ +w\xe8\xcc\xad\xe6\xcd\xfc\xf3\x9c\x119\x1b[\xeec\x1f\ +\xfe1\xb7\xb3\x1c\xb1KW\xe2\x85|\xa4\xe0\xc63\x1f\ +\xe6\xa9\xad?\xe7\xba\x85\x0f\xb0d\xe3\x12\xcc\xea\x9d,\ +Y\xff*\xa6\xe9s\x03\x8c\x90M\xffj\x8b=#\xa9\ +\xa0 \xc7qm\x92\x9b,n\xf8\xfa\xad(\xd2 \xdf\ +\xefa\xe7u&\x8e\xaf\x06!Q5\x85\x9a\x9a\x9a\xcf\ +\xcf\x9d;\xf7\xf8\xfd?\x7fpp\x90\xee\xee\xee\x8f\xe7\ +r9\xeb\x90\x09\xa4P(\xe0\xd86f\xc4\xc3\xc3e\ +\xb3\xf50\x87\xf5M\xa5\xaeQ\xa1m\x96\xca\x7f\xae\xba\ +\x04\xcb\x09\x91\xcb\xe5Qt\x7fa\xca\xc1\x5c\xd9\x03Y\ +\xb9r%\x9f\xf9\xccg\x02@\xcf\xf3\x81\xafL\xea\xeb\xe8\xe8P\x0e\xe9\x09\xc9\xe7\xf3\ +~N\xa0Bb\xbb\x16\x9a\xaa\xf2x\xe7w9\xa2t\ +\x0c\x96ma\xa5\x15\xb6\xfd>I\xc9\xb6\x10\xce\x81\xf6\ +\xa2<\x96/_\xce\xf3\xcf?\xcf\xe0\xe0 ---\ +~\xb5\x92\xea\xa7n\xef[v\x0f\xffr\xc1\xb5\x94\x1a\ +\xc4\xe7O\xfe<\x8d\x93\xa0\xc7\ +I\xe18\x0e\x93&M\xc2H$X{c\x1e\xb74\ +\x06\xce\x0a\x90h\x84\xc2\xfb\xf2\xf9\x7f\x8a\x81^\x16\x88\ +t%\xd2\xf3\x91\xe9T!\xce\xec\xdaS\x982q\x02\ +/\xae\xf78\xbe\xf9S\xbc\xe1\xfe80\xe0\xe1p\x98\ +hE\x94\xa6\xba\x094\xd6J\xde\xdc\xbe\x85\xb6\xb6\xb6\ +}\xf9\x1c\x1fW\xc1sB|\xef\x93O\xf2\xd2\x96\x17\ +p\xaa\xf7\x92\xd8\x1ba\x93\xfd\x80_\x16gyA\xeb\ +\x90\x83!\xd3\xbd'\x81\xb4\xb5\xb5q\xe1\x85\x17\xb2~\ +\xfdz\x06z\x06\xf1\xac\x0cn\xc8A\xea\x12+b\x05\ +\x09'\xcf\xf3\xc8\xe5r\xc1\xcf\x803\x06\xa9\x9c[\x86\ +Ub\xb1\xd8\x8b\xae\xeb~\xd2\xcf:z(\x86\xbfk\ +\xdbG~G\xc7\xfd\xaf0\xd8S\xc0*H\xee\xbc\xf3\ +N&O\x9e\xcc\xf0\xf00K\x96,\xc14M\x5c\xd7\ +\xa5P(\x90\xc9d\x980a\x02{\xf6\xecadd\ +\x84\xe6\xe6f\xba\xbb\xbb\xffh*:\x9f\xcf#]\x0f\ +\xcb\xf6\x09\x15\xdf}\xf5b\xae?\xf5\x11\x1e\xdat\x0b\ +;\xb4e\xf4wV\xe2\xd8.\xb9\x5c\xa1\x9cf\xa0\xc7\ +\x1b\xa1\xf9\xb2Q\x22\xba\x8e\xbcg\x14\xe14\x04 \xa8\ +\x8a\x82\x22\x04!k\x1c\xb1h\x8c\x1f\xbdt\x1d\xf7^\ +\xfc\x07\xeaO\xaa#\xd7\xbe\x85\x1ek\x17\x96\xa9|p\ +\x02\xf9\xf5\xaf\x7f\xcd\xab\xaf\xbe\xca-\xb7\xdc\xc2\xb2e\ +\xcb\xd8\xb8q#B\x08\xba\xbb\xbb\x994i\x12\x93'\ +Of\xf5\xea\xd5tttp\xec\xb1\xc7\xb2q\xe3F\ +\x8a\xc5\x22\xaa\xaa.8\xf1\xc4\x13e@\x92\xf6<4\ +]\x05GH\x84\xdf\x94\xa7\xfd[\x1e\x12P\x14\x1d\xa1\ +\xda\xa8z-\x8e\x19\x0f\xa2\xf8\xa9S\xa7\xf2\xc8#_\ +\x1c\x22(\x00\x00\x19\xedIDAT\x8fPWWG\ +ss3\x8d\x8d\x8d\xdc\x7f\xff\xfd\x14\x0a\x05\xc2\xe10\ +\xb1X\xac\x5c8\x8a\xe7ym\xb5\xb5\xb5\x1f\xdb\x8f\xa8\ +\x11v]7\xb0!\xb6\x09\x8e\xb4Q+m~\xb0\xfa\ ++\xb4\xd5\xcc\xa0\x94\xb6\xc9\x0f'\xe8|-E\xb1\xe8\ +\xab\x97H8\x8c]mQS\x15\xc6\xce\x87i\xac\x99\ +\x88=`\xe3I\x1f\x8dv\xa5@\x11\x02\xe9)8\x9e\ +\x0d\x02\x14\xdde\xf7\xc0.\xba\xd3\xdbpl\xb0m\x11\ +l\x88r\xa5\xd5!\x13\xc8\x13O<\xc1i\xa7\x9d\xc6\ +\x9e={\x18\x1a\x1a\xc2\xb6}\xa3\xabi\x1a[\xb7n\ +\xc5\xb2,\x92\xc9d@\xb0\x03\x02\xe2\xf2\xc4\x89\x13}\ +o\xa3\x94\xa2n\xf10\x13&\x86q\xb2\xaa\xb0\xfb\x22\ +8\x03a\xac\xbe\x08e\x07\xba\xcc\xc1*l\xc9s\xe3\ +\x8d7r\xc6\x19g\xf0\xfa\xeb\xaf\xe3y\x1e\xbbv\xed\ +\xc2\xb6mt]g\xc2\x84\x09\x14\x0a\x05t]\x0f\xc0\ +\xc3\xe6\xe6ff\xce\x9c\xf9\x1d\xe0;\xfb\x93\xfd\xb6l\ +\xd9\x82\xa6iHE\xa2\xc7a\xef\xcbEF\xb6\x9a\xa4\ +\xbaF\x11l; #Q\xb6{\xaa\xea\x17u\x96\x8a\ +.\xb7\x9c\xf9;\xfe\xfe\xa9\xf3(9.\x12\x9fl!\ +<@\x0a\xf4\x88CH5h\x8cN\x22Y\x1cB\x11\ +Q\xf0\x14l\xc7\x0a\xd4_\x99\x94}Hm\xc8=\xf7\ +\xdc\xc3C\x0f=D.\x97{\x87~\x06\xd8\xb9sg\ +\xf0\xbb5k\xd6P]]\x1d\xfc\xbd\x8c\xf5\x8c\x94R\ +\x1c9\xa5\x82b\xc9f\xf6\xe4\xe3\xd8S\xb3\x09gv\ +\x16\xcf\x93\x98{*\x18}1\x86Pe\x90\xcc\x8aF\ +\xa3A>_\x08\xe1\x97\xd2\xd96\x93'O\xc6\xb6m\ +\x14\x04;\xd4=\x1cs\xa1\x86\x90\x0a\xd2\x12x%\x15\ +'\x1e\xc2\xea7p\x86\x0d\x9c\xb1\xce7\xc7\x1cs\x0c\ +\x97^z)\xf7\xfd\xea>\xe4(Hu\x90\xba)^\ +`\x13L\xd3$\x1a\x8d2\x86\x00\xa3i*\x02\xbf\xe6\ +\xb1\xae\xaa\x96\x82\x95\xc3q\xfcf9\xa5R\x09E\x0a\ +B\x02l-\xc1\x8f\xff\xf0\x7f\xf9\xe5\xa5Op\xd3\xeb\ +\x17ax1\xaa#1L\xb3\x97R\xc9\x0b\xec\xe9\xc1\ +\x00\x8f\xef\x05\x5c\xdce\x9a\xa6aYV\xcd>\x86\xe2\ +\x810\xc5\xdbK\xce\xb2\xd9\xec\x01\xb9\x0d\xff\xf7\x1e\x9e\ +'9.t9-\x0d\x1agL\xba\x84_\xbc\xfe\x9f\ +\xcc\x98\xda\xcc\xaa=\xab\xb0-\x1b\xa1\xf95)u\x8d\ +1B^\xa5\xaf\xd3\x14I\xae\x90e\xfc\xf8\xf1D\xa3\ +Q\xb2\xd9l\xd0m!WY@\xd3\xab\x89)\x93X\ +8\xf7\x14^\xda\xfd0\xce8\x171/A\xfc\xd5(\ +\xf9-~\xb1\xcd\x1dw\xdc\xc1\x8a\x15+\xf8\xc1\x7f\xfe\ +\x80_\xfd\xeaW\xcc\x91G\xd0\xdd\xdd\xcd\xacY\xb3x\ +\xe1\x85\x17\x984i\x12\x96e\xa1i\x1a\xa1P\x88T\ +25Vk(\xf6\xabIq\xb0l\xcb/\x83p\xa1\ +\xb2\x14\xc2\xf6t:\xcc'Y\xdds\x18U\x15U\x0c\ +\xe6w\x93\x1ft\x89\xf7%\xb1\x0b\xfbR\xbe\x07C9\ +=h\x81\x8c\x8c\x8c\x9cT,\x16\x7fr\xce9\xe7\x5c\ +}\xdbm\xb7\x91\xcdfy\xf8\xe1\x87\xd9\xb5k\x17\x8a\ +\xa2\x90L&\x89D\x22(\x8a\xc2\xe8\xe8h\x90\xf5K\ +\xa5R\x94J\xa5\x00Zp\xa5G\xa9\xe8q\xf1y\x7f\ +\xcfM+\xfe\x1e\xadf\x02S\xab\x8eavC++\ +\xe5*L\xcbD\xb8>0\xd9tA\x96\xaa\x89\x05\xec\ +\x11\x03w0\x02\x1d\x02g\xd8\x0b\xa8H\xb6m\xe3J\ +\xdf\x08I\x04\xdf<\xe5^~\xf4\xf2\xbf\xf2\xefg<\ +\xc4\xea\x8do\xb2\xc9\xf95Cv\x1f\xb6\xed/\xe6\xd3\ +O?\xcd\x82\x05\x0bhoog\xe7\xce\x9d\xc1\x02%\ +\x12\x09J\xa5\x12\x89D\x22H;\x17\x0a\x05\xca\x0dl\ +\x5ci2\x9a\x1e\xa5\xda\xa8#\xed$\x02\xc6\x0d\x02\x94\ +\xbc\xa00\xe2\x91\x1bv\xb9\xf5\xd9\x1bI\xecpIu\ +: \xfd\xba\xf7\xb2\x0c\x0e\xb6\xa0\xe7=\xa9,!\x84\ +\xbep\xe1B\xd6\xad[\xc79\xe7\x9c\xc3\xe1\x87\x1fN\ +>\x9f\xc7\xf3\x155\x1d\xf7\x88\x86+\ +X\xd6\xf9\x04\xd7j7\xd3PW\x83\xd5o\xe18.\ +\xa6\xe9C3w\xdey'w\xdcq\xc7\x1f\xbd\xbf\xd1\ +\xd1\xd1\x03~\x8eU\x8f\xe5\x5c\xa2:\xff\xe7\xf7\x9f\xa5\ +64\x89\xed\xc5^\xa2\xd1(\x86a\xd0\xd4\xd4Dj\ +s\x8a-\x9b\xdd1\xb7\xdb\xefhT\x15\xf3\x0e\xa0\xd6\ +\x96\x0b\x98\x0e\xb9@\xa4\x94\xfc\xf6\xb7\xbf\xa5\x9c`\xea\ +\xe8\xe8\x08 \x8b\xb2\x8d\x10BP(\x14p]7\x10\ +VY?\x03\xb8a\x8fHX\xe7\xe5\x0d\xcb\x09QM\ +m\xb4\x9e\x81L\x17gU\x7f\x9c\xadr\x07\xa6UB\ +\xf1| \xb3:},\xe7\x1f\xfdE^Z\xbd\x8eq\ +\xd2\xe3\xf4\xd9\xa7\xf0}\xebv\xc2\xaa\xb1\x8f\x947V\ +a\xa8(\x82\x03m\xa6\xc0\xf6\x8ac'\xc9%\x95J\ +\xf9\xe9\x80\xb1`PJ\xe9\x7f\xaf\xf9|\xa2\xb0\x16\xa5\ +`gQ\x84\x8ak\xfa\x0b\x97N\xa5pZ\x1cL\xa7\ +\x84\x16\xf5\xd88\xb4\x02\xd7\x11466r\xf7\xddw\ +\xe3y\x1e\xabW\xaff\xd5\xaaU\xb4\xb6\xb6\xb2f\xcd\ +\x1a\x8e<\xf2H6m\xf27W]]\x1d\xf9|\x9e\ +\xde\xde\xde\x83\xe6\xff\xbeW\xacX\xd54\x8dg\x9ey\ +F\x0a!\x84\x22\x94\x80=\xe8J\x9f\xaf\xa4)!?\ +?\xae\x86p\x1c\x87\x8a\x8a\x0a\xa4\x94A\xe9\xb1\xa5\xd8\ +h\xba\xe0\xc1\xed\xff\xce-g?\xce\xda\xe1'\x085\ +\xf7\xd3\x93\xdf\x82\xedY\x14\xf2\x05\x14\xdd\x8f\x01\x8e\x9b\ +\xbe\x80\xee\xd4v\xde\xec_\xc7\xc2\x19\xa7\x11V\x8c\xb1\ +\xb23\x11\xb4\xf8P\xa4@\x22\xa8\xad\x0f\x91\xceg8\ +\xf7\x88\x7f Q\x1c \x97+1\xb5\xf6(\xda\x9d?\ +\xe0\xba\xd2\xf7\xf2\x5cA\xa9&\xc1\xb4\xd8\x5cJ\xa5\x12\ +\x03n\x8a\x19_4\x99V\xb1\x90\x8b\xcf\xf8\x125j\ ++7=~\x0d\xcf^\xbf\x0e\x0f_\xe0\x91\xa2\xce\xc0\ +\x1b&\x99^\x87\xd4\x9e\x02\xbaZ]\xce\xed0w\xee\ +\x5c\xaa\xaa\xaa\xc8\xe5rttt\xa0\xeb:\xb1X\x0c\ +)%\xc9d\x12\xd34ikkc\xdb\xb6m\x1f\x8c\ +\xcaR\x14\xe5\xd17\xdexc\xda\xacY\xb3N+\x14\ +\x0aX\xd2E\x9f\x9e\xa7\xae\xaa\x96\xb3\xe7~\x8e\x92i\ +\xb1t\xfb\x13\x9c9\xfb\x1c\x96\xee\xfe-\xe9\xf5a\x0a\ +\x85\x02B\x88`\x87\xe4\x85\x87\xedZ\x84\xaa<\xfe\xed\ +\xf7\x17\xb1x\xfe\xd9d\xf3)\xd6\xc7W\xb2\xf3\xe5,\ +\xd9\x82\x19\xec\xf4\x92i\xe2X*\xae\xe3\x91+\xa5\xf0\ +\x1c\x1f\xcd\x95xh\x9a\xe6\xcf-\xfd\xb8\x06\xe1q\xcd\ +\xd3\xe7\xf3\xc3\xf3\x9e\xe2\xc6\xd7/$S\x8a\xa3\xe9\x1a\ +V\xc9\x22\x97\xdb\x97+\x99\x14\x9dF>\x9f\xf7S\xb7\ +\xd8\xd8\xa6\xcb\xac\xc6E<\xd9\xfe3\x0eS?\xc11\ +\x0d\x8byF\xae\xa6\xbe\xa1\x9e\xe3\x8f?\x9e\xad[\xb6\ +\x12\xff\x83\x83\xe5\x98\xb8\x99\x0c\xd1j\x9dd2\xc9\xd7\ +\xbe\xf65Z[[\xe9\xec\xec\xdcW.'%;v\ +\xec\x08\x16?\x95J\x05,\x99?\x06\xe9\xfcE\x02\xc9\ +d2/UUU\x9d\xdc\xda\xdazZ2\x99\xa4\x88\ +E\xf5\xc9:\xc74\x9e\xc9\xdcc\x9aY\xb7\xb1\x93\xef\ +\x7f\xe6n\x8e\x9by\x0cC\xcf,cGO\x08\xe1\xaa\ +\xa4R\xa9\xc0\x80FJ.\xd9!\x87\xc1\x8d\x16\xa3\xdb\ +\xf6\xb0\xfa\x96\xbb\x83^UM\xa2\x99\xa6\xb9\xfb>\xef\ +\xf7\x0f?\x05c\xcdZ\xfbx\x09\x80\x09\x13\xc7S,\ +\x16\xc9f\xb3\xe4\xf3y\x84\x148\xa6\xf0\x85\x5cmq\ +\xe3k\x7fG$\x5cAA\xd5Hv\xdat\xaeL!\ +\x9d\x80\xe0\xc7\xb8\xeaq\xf4\xf7\xf7\xfb\xecy\xd5\x19\xab\ +\xf8\xf2\xf12\xd7\xf3H\x17\x13\xa8\xaa\xc6\xaaU\xabx\ +\xf1\xc5\x17\xf9\xd2\x97\xbe\xc4\xb2e\xcb\xa8\xa8\xa8\xe0\xfe\ +\xfb\xef\xa7\xad\xad\x8d\xae\xae\xae\xc0=\xae\xa9\xa99\xa8\ +\xb5\x8b\xc7\xe3\x1f\x0c\x0dHU\xd5i\xe5\xf6L\xb6\xf0\ +o\xa8R\x8fa\xbaEL\xa7\xc4P\xa6\x97\xbel,\ +\x80\xebq\xf6\xf9\xde\xd7^{-K\x96,\xa1\xe7\xbe\ +\x04\xaek\x13\x05\xf4J+(\x1c\xddY\xe8\xe7\x88\xcf\ +8T\x845\xa4\xa9b't\xdc\x11\x03\xab?\x8c\x97\ +\xd5\x10\x9a\x0c\x82\xc6l6\xeb\xefL\xd7#\xdc-\xd8\ +\xf6\xbb\x1c\xe9\xbd\x0eN!\x81]\x908E\x89\x94\xa0\ +\xa8jP\xb8g\x84\x22l\xeaZE\xb5l\xf6\xf3\x1d\ +\x86\x87\xae\x18\xec\x18\xdd\xc8\xf1G\x9f\xc0x\xedp6\ +\xed^\x13p\xbd\xda\xda\xda\xe8\xee\xee\xf6\x05?\x86\xd8\ +\x0e\x0c\x0cp\xc3\x0d70::\xca\x93O>\x19T\ +(\xe7r\xb9\xe0$\x94I\xe5\xb5\xb5\xb5\xe5b\xa4\xd1\ +\xe1\xe1\xe1\x85\x8d\x8d\x8dfoo\xef\xa1\x15\x88\x94\xf2\ +\xb0\x80\x9d\xa8\xb8\xa8Bc\xb48@St.5\x15\ +i\xb2V\x1a]\x0d\xa3\xa0`[&\xd2\x118\x8e\xc3\ +3\xcf<\xc3\xe8\xe8('\x9f|2\xbf\xff\xfd\xef\x03\ +,j\xd9\xb2e\x81\xc1\xef-\xc5Y4~\x1c\x85\xac\ +\xc7q\xd3?\xce\xa6\xc1e83rT\xa9\x92\xec\xe6\ +\x0a2\xafW\xfb\x86X\xf1\x8bz\x16/^\xcc\xec\xd9\ +\xb3yi\xc9Kx\x19\x09\x8cB\x05X\x9a\x85\x88\xf9\ +\x0b\xa8\xeb:\x99L\x06\xc7q\xd0t\x85d\xb7\x83^\ +_\xf4\x93U8x\x9e\xc1@\xe8U\xc2\xc5\xd3\xc9\xd7\ +\xf6\xb0\xdbz\x19]5\xb8\xe8\xa2\x8b\x98={v\xd0\ +\xe5\xc7\xf3<\x86\x86\x86\x98:u*\xdf\xf8\xc67\x10\ +B\x10\x0a\x85\xde5\x07S.2\xcdd2\xd4\xd4\xd4\ +P(\x14\x9c\xd1\xd1\xd1\xed\x1f\x14QN\x09\x1a\x98\xa9\ +~n\xb5P\xb9\x8d\xb6\xca\xeb8b\xf1\x09\x5c\xf3\xe4\ +\x05\xb4Ml\x06\x01\x96e\xe2\x8da9o\xbe\xf9&\ +\x8d\x8d\x8dd2\x99r\xd3d\x86\x87\x87\x0f\xf0\xc0\x84\ +\x10\x94l\x93\x0bZne\xc4\xdb\xc0?/\xb8\x9b\x97\ +\xda\x97\x90\x8el\xa5\xdd\xde\x15\xf4\x16)\x0b\xe4\xf2\xcb\ +/'\x97\xcbq\xdai\xa7q\xfb\xed\xb7s\xc2\x89\x0b\ +\xe8\xee\xee\xe6\xc8#\x8f\xe4\xd1G\x1fe\xf2\xe4\xc9~\ +{\xc1T\x8aT*\xc5\xe0\xe0 \x95\x95Q2\x99\x0c\ +\xa6iR\xf0\xfc2\x08O\x95\xfc\xf4\x8d\x7f\xe2\xaaS\ +\xbf\x8d\xed\x940M\x18\xd7TK___\xa0j5\ +M\xc30\x0czzz\x10\x9a@\xd5\xfcf\x0193\ +C\xa5Q\xedWiEM\xec0\xe6\xa2\x10\x82D\x22\xe1\xe7\x054I\xc9\x8aa\ +\xabp\xe5o\xcf\xe6\xd1\xaflD\x8bX\xdc\xb7\xe9\xdb\ +x.\xc4\x87\x92APt\xeb\xad\xb7\xbe#\xdf\xbd?\ +\x1b\xdd\x87F`x\xa0\xc4\xd9\xe7\x9e\xc6\x95\xcf\x5c\xcf\ +\xe2\x19\x173\xa9v\x06\x03\xa4\x91\xde\xce\xa0\xb7H\xb9\ +\x8e\xbc\xbb\xbb\x9b\x13O<\x91\xdf\xfc\xe67\x01\x15\xb5\ +\xdcL@J\x19\xb4\xf7\xd0u\xdd\x8f\xac\xc7>\xafl\ +\x84+\x8a\x1e\xa5\xb8G\xcf\xae\x12\xf1\xad\x16\xff\xf0\xdd\ +\xaf\xfb\xf9{\x05FFF\x0ep\xf7\xcb\xc5\xa4\x0a\x82\ +\xf8\x94\x0c\xc7\x9eY\xc5\xaf\xfev%g\xde9\x85g\ +\xaeX\xc1\xe6\xce\x0e\x9e\xea\xbd\x91\xad\x8f\x8f2\xba\xc9\ +7\xde\x86a\xb0}\xfbv\x1a\x1b\x1b?8\x81\x94\x17\ +XQ\x144O\xa2\xea\x02\xd7\xf1`Tr\xca\xa5\x87\ +\x93\xeb\xf2\xb0\xf2\x123\xe3\x05\x1c\xa5b\xb1(\xcb\xb5\ +\xeao\x17\xae\x10b\xdf\x0e2|\x17z\xff\xbf\xdb\x8e\ +\xcd\xae\xec\xc61\xd6\xbc\x15\xb0\x91\x15E\xe1[\xdf\xfa\ +\x16\xd1h4 \xc1\x95\xe7\xdf\xbcys\x80\x18\xec\xff\ +\x99\xe5\xfa\x12\xc30\xb8\xfa\xea\xabY\xbe|9\x83/\ +\x0e\xe2z\x1e!\xc7\xa6\xa9Q\xeek\xed7\xa6\xa6\xca\ +\xbd|\xcb\xc1\xad\x22\x05R\x08j\xeat\xe2\x99\x11\xae\ +8\xe9F\xfa\xb3\xbb\x18I\xa48~\xe2\xd9\xbca\xff\ +\x9c2\x85\xablS\xde\x0b\xe9\xe1}\x09D\x08\xc1\xb4\ +i\xd3H\xa5R\x0c\xdck\xd2c\x9a\x08E\xe2\xe7m\ +\xfd\xc0$\xa4J\xa4\x22\xcb\xa4i100\xb0ld\ +d\xe4\x94\xb7\xcf5g\xce\x9c\xb8i\x9a\xe3\x84\x10`\ +@MM\x98=}}x\x8e\x82\xa6\xe8d\xcd$M\ +\x916v\xbaqL\xd3\x0e\xba\xef\xd8\xb6M4\x1a\x0d\ +\xd2\xb6\xfb{re\xb8\xfb\x80\x93\xe8\x82e\xfa\xc4\xed\ +\xab\xae\xba\x0a!\x04\x0f>\xf8 \xdf\xfe\xf6\xb7\xe9\xea\ +\xeab\xe6\xcc\x99\x8c\x8c\x8c`\xdb6MMM\xbc\xf2\ +\xca+\x84B!\xc6\x8f\x1f\xcf\xbau\xeb\xb0m\xdb\xc7\ +\xe6<\xb0,p\xa5\xcd\xb5/\x9e\xc7\xff=\xf5)\xee\ +\xdd\xfc\xcf\xf4\xa4\xdeBK\xa8\x94\x0a&\x99\x8cy\xc0\ +&x/l\xc6\xf7c\xd49\xf2\xc8#\xb9\xec\xb2\xcb\ +8\xe2\x88#\xb8\xf9\xe6\x9b\xe9\xec\xec\xa4\xa6\xa6\x86\x91\ +\x91\x11t\xddo.988\x88\xae\xebh\x9a\xc6\xe0\ +\xe0 \xe9t\xda\xfbc\x89\xa3R\xa9\xe4\xef\xc8*\xc9\ +\xb8q\x95\xfch\xd9\xbfp\xd7\xdf-\xe3\x97o\x5c\xcf\ +\x9b\xa9-\x1c1i\x0e\xae7\xc6\x0e\x1c\xb3!S\xa7\ +N\x0b\xe2\x15UUY\xb1b\x05\xcd\xcd\xcd\xef\xea\xeb\ +\xab!\x08\xcdM\xd2\xb7\xb2H!\xe9\xb0k\xd7.\xae\ +\xbc\xf2J\xf6\xee\xddK\xb1X\xa4\xb1\xb1\x91\xca\xcaJ\ +t]g\xd9\xb2e\xd4\xd5\xd5\xd1\xda\xdaJOOO\ +PN],\x16\x83\xb8\xc7I\x0b\x92\xfd~1\xe9\xbf\ +>y>\x15F\x98l\xce%\xddc\xd2\xb9\x22\x8b\xaa\ +\xa8\x07l\x9a\xb1\xcd\x11\x06\x984i\x92\xdd\xdd\xdd\xed\ +\x1e\xb2r\x84\xda\xda\xda5MMM\xc7\x1d,\xa7\xb6\ +<\x5c\xd7\xa5\xbf\xbf\x7f\xc6\xc8\xc8\xc8\xce\xfd\x7f?}\ +\xfa\xf4x\xa9T\x1a\xa7(\x0a\xc3\x13\x5c\xfe\xf1[\x13\ +\xb1,\x97\x9a\xc2\xb1\x1c5g\x0aKw\xff\x06M\xd3\ +X\xf5\x83\x04\xa9._\x17TVT\xb1\xe8\x96*\x86\ +\xeeoD:\xbeZX\xbbv-\xd1h\x94p8\x1c\ +0\xef\xcbi]\xc7\xb51\xa2!\xdc\x92\x0c\x9a\x0b\xec\ +\xcfR\xf9S\x19\xd2\xe6\xe6\xe6\xfd\xaazd\x90\xb3\xf9\ +c\x9b\xb5\xa7\xa7\x87m\xdb\xb6!\x84\xa0\xb2\xb22(\ +\x8e-o\xbe\xb5k\xd7~)\x99L>pHO\x88\ +a\x18\xcc\x981\x03\x80~3\xc1\xe4\xb3\xf3D\xc2\x1a\ +\xc24\xb0\x87B8\xc3a\x9c\xe1\x03\x1bYF\x22\x11\ +\xee\xbd\xf7\xde\xf4\xbbMY&\x97\x85sP\xcax\x0c\ +m\xb1\xe8\xd8\xf3\x0a\xcf\xdf\xb9\x04\xcf\x14\xd8y\x0f\xd7\ +\xf4\x8d\xf1\xbe\xbc\xb9\xc0v\x1c\xa4\xed\xeb\xfa9s\xe6\ +\xd0\xda\xdaJ,\x16c\xdb\xb6m\x8c\x8e\x8e\xd2\xd4\xd4\ +\xc4\xd0\xd0\x10\xfd\xfd\xfdx\xa6\xaf\xbaL\xd3\x0c\xe8G\ +\x0a\x02\xc7\x94\xd8\xb2\x84B\x08\xcb-\xa1\xab\x1aH\x05\ +M\xd5(\x95\x8a\x0c\x0d\x0d!\x10\xac,m\xe5\x9c\xcb\ +b(R\xe0\x9a\x80\xa5\xfb\xd76`P\xda]\x81\x97\ +\xf5\xaf\xadP(P[[\x1bT\x1bG\x8c\x8a \xce\ +\x8aF\xa3\x7f\xd6\xe3z_\x02)\xe7\xb4\x15\x04\xa3Z\ +\x9c\xf9-a2\xd94\xedwXL\xac\x99\x82\xebe\ +\x11\x8a\xc0r\x1dt] M\x0dD\x82\xb3\xce\x5c<\ +T\xb6\x01e\xa3\xd7\xd5\xd5E(\x14\xe2\xf4\xd3Og\ +\xfd\xdau\xb4\xdf\xec \x85\x0eBG\x93n\xd9\xd1\xc6\ +\x88*\x81\x8b\x5cf\xa2X\xa6\xefV\xab\xaa\xca\xc0\xc0\ +\x00\xae\xebRYYI&\x93\x09X\x1e\x8e\xe3\x10\x0e\ +\x879\xef\xbc\xf3H\xa7\xd3,_\xbe<\xc8\x08\x0eG\ +\x8b\x9c~U\x15\xc7\x1aW\xd10\xc5dQ\xeb\x17\xb8\ +\x7f\xc5O\xf9\xf8\x91\x0b\xb9\xf3\xb9o\xd3\xff\x98\x87\xa5\ +\xfa\x0d\xd2\x0aX\x18\xbaB#Gr\xfaQ\xe7\xf0\xe4\ +\xb6\xbbP\x9dJr-\xbd\x8c\xe4%\xa5\xd1H\xe01\ +\x1es\xcc1l\xdf\xbe\x9d|\xa6\x8017IiW\ +\x04\xa1\xec\xf3\x0e\x0f\xa9@\xaa\xab\xab\x03\x86\xa0\x82\x00\ +Mb;.\x7f3\xf1&\x12\x8dw\x05\xbb \xe5f\ +\x19wA\x9cq\x0d:N\x1e\xec\xa1\x0a\xdc\x11\x03{\ +\xd0@\x16U\xdc\xbc\x8a\xa6i\x94J%~\xf3\x9b\xdf\ +\x00p\xc6\x19g\xb0|\xf9r\x1c\xc7!\x1e\x8fSS\ +SCOO\x0f\x8b\x16-bdd\x845k\xd6\x10\ +\x8dF\xd9\xbb\xa7\x1b\x81\xc0\xb2l<\x9b :\x0e\x87\ +\xc3\xa4R\xa9\xe0Z\xfb\xfa\xfa\x08\x87\xc3X\x96E\x22\ +\x91`\xca\x94)\x81k,\x84\xc0\x0d\xbb\xa8\x8a\xc6&\ +\xef~.\x09\xdd\xceS\xbb\x7f\xc4No);\xdfx\ +\x0eO*~\x1a\xda\x94~OGC08\x94\xe3;\ +\x17\xdc\xca\xff~\xf6\x0c\xee\xfe\xfc\x12\xf6\xf4\xf7\xf0t\ +\xef\xad\x0c\xda]\x81\x0a\xf4<\x8fx<>\x86\xe1)\ +x\x8e\x87k\x9a\x08\x95\x03\x02\xc9\xbf\x98J\x1a\x90d\ +\x0d#\xd8\x09%\xd3\xf4\xdb|\xdb\x06\xe7\x9d\xb8\x98\xbc\ +\x99\x09\xe8\xa1#N\x9a\x8aP\x083\xab\xb0p\xca\xf9\ +\xd4N\xd1\x88\x1e\x95\xa1\xf6\xec\x11*O\x89\x07\xdd\xb1\ +\xcb^\xd0\xc8\xc8\x08\xe1p\x18EQ\x983g\x0e\x86\ +a0i\xd2$l\xdb\x0e:D\x9cx\xe2\x89\xa4\xd3\ +\xe91WR9\xa0M\xb9\xeb\xbaA\xcb\xf0r\xb3\x9c\ +x<\x1e\xd4=vtt\xf0\xec\xb3\xcf\xa2\xaaj\xd0\ +\x81\xa2P,b;\x16(6w\xb4_\xc6p\xb6\x0f\ +\x89$?\xe2\xb2\xfe\xde8\xae\xb7\xaf\xeb\xb5\xa2(\x8c\ +\x0c\x98\xc4jB(\xaaKD\xaf\xa4\xa6\xb2\x86x\xae\ +/H\x96\x95\x89\x7f]]]~sNUA\xba\xde\ +\x014\xd7?\xe7\x02\xbf/\xb7\xb7\xac:\x04~\xa0U\ +\xf6*\xf6\xb5\xff\xb6q\x15\x17E\x15|z\xd27\xc9\ +\xc8]\x5c\xbf\xe81\x1e]\xfd \xcd\x93t\x9eXq\ +_p\x93\xd1h\x94+\xaf\xbc\x92\xc9\x93'\xd3\xdf\xdf\ +\x8f\xeb\xba,]\xba\x14\xcf\xf3hoo\xc7q\x9c@\ +\x1d\x95\x03\xcb\x90f\x04\xf1\x8bk\xf9I\xa0P(D\ +]]\x1dB\x08jkk\xdfv\xc1c$\x03E\x04\ +\xa5\xd0\x9e\xe7Q\x9dQ\xe9ZR \xd7\xedbe=\ +\xd6\x14V\xe2\x14\xc1\xb3%\x8a*p\x0dw_[C\ +\x14t]\xc1\x19\xe35\x83\xff\xf4 \x04\xb8\xae\x87i\ +\xfa\xfc3\xd7q\xa8m\xae'\x99\x8f\x13\x8a\x99\x84*\ +U\xd2\xb6\xdf7\xf2`J\x15\xdeW\xa4^^x\x81\ +\xdf0\xc0\xf1lJ\xa6\x89\xa6\xe8\xfb\x0a`\x0c\x0fO\ +\x0aZ\xabg\xf0\x9b=\xbf\xa0-t\x22\xf5\x91\x16\x0c\ +%\x83\xf4\x08\x04R*\x95d(\x14\x12\x9d\x9d\x9d\xfb\ +G\xefR\x08!\x5c\xd7E\xda`{\xde\x98C\xa8\x82\ +\x02\x96cc:\x92\xd1\x91\x04r\x8ce_\xceL\xe6\ +\xf3\xf9u\x1d\x1d\x1d\x0f\xd6\xd7\xd7\xffX\xd34\xbf\x0f\ +|\x9d\xc7\xe1\x0b+\xc0\xae\xa22WEuu5\x97\ +\x5cr\x09\xcb\x97/gxp\x18\xc5\xc9\xe1\x86\x5c<\ +\xcd\xc3\x8d\xba\x01\xe4Q\xdex\xcaXC\x9c\xa9\xd3k\ +\xd8\xd1\xb5\x97\xd3\x0f\xfb;\xde\x1c^M2Qdv\ +\xc3\x09\xbc\xe5\xfc\x01\xcb\xf2\xb3\x86\x85|\x81\x07\x7f\xf9\ +0?y\xea\xfb\xfc\xcd'N\xe5g\x8f\xfd\xc4\xcf\x82\ +\xaa|0'DJ\xa9J)e\xa9T\x12\x02\x81\xe7\ +\xb9TD\x15\xfe\xf9\xe1\x8b\x91\x9e\xc0\xb6}B\xb6\xa7\ +\xb9\x08\x11\x02$\xaa\xe2\x1b\xb3\x91T\x9c\x5ce\x7f\xa0\ +n\x00\x1a\x1b\x1b\xc5\x1bo\xbc\xf1\x95b\xb1\xf8\x10\xe0\ +E\xa3\xd1\xeb\xa7M\x9b\xf6\xcdd2\x89\xa3H\xa6\x7f\ +\xa5\x92\xd6\x960vAb\x17=R\x9d6\x99n\x87\ +%\xffl\x07^\xfb\xd8\xb3\xa6D,\x16C\xd3\xb4]\ +\xf9|\xfe\xce\x96\x96\x96\x1f\x97yXn\xb5\xa0\xed\xd4\ +(ZX\xf2\xd2\xfa~~\xf6\xfd_\xb1w\xef^n\ +\xbf\xfdvn\xb8\xe1\x06t]\xa7\xbe\xbe\x9eb\xb1\xc8\ +\xee\xdd\xbbY\xb4h\x11\xeb\xd6\xadc\xfd\xfa\xf5\xe4r\ +9\xc4\x98G\xa7\xeb*\xdfy\xf5\x0b\xdc~\xc1\x0b|\ +\x7f\xcd\x97\xc8Z\x09\x14]\x90\xcf\x9ad\xb3>\xea\xeb\ +X.#r3N\xddV\x96\xedN!]I\xb1T\ +D(>\x13\xf2\x90\x0bd\xd7\xae]\x9fjii\x19\ +H\xa7\xd3~\x13\xfdq\x02\xd3\x89\xe2\xd5\xeea\xb4\x90\ +%\x22k|\x81D \xa4\x84\xe8Jw0\xbf\xfe4\ +\x8e\x9e>\x8f\xd7w\xbc\xc2\x11\xb1\xa3Y\xea=\x8fe\ +9A\x8e\x22\x12\x89\xd8\xc5b\xb14\xf6\xb3\x13\x0e\x87\ +1\x0c\x03\x03\xe8\xff\x95C\xbf\x92{\x17Z\xab\xbe?\ +\xc5Ud\xb3\xd9m\xbbv\xed\xbaA\xd7\xf57\x01\xb5\ +LD\x90B\xe2\xb9>'\xca5!j\x84y\xfa\xe9\ +\xa7\xb9\xf6\xdaky\xe9\xa5\x97(\x95JD\xa3Q\xfa\ +\xfb\xfb\x89\xc5b\x0c\x0f\x0f\xd3\xd9\xd9I8\xec'\xd7\ +J\xa5\x12\x8aP\xb0]\x0f\xc7\xb3\xa9\xab7\xb8\xfe\xb5\ +O\xfb\xea\xafO2\xb4\xb9\xc8\x9eey\x14m\x8c\x9d\ +\xe8)$\xf2C\xa0\xba\x0c\x15\xf6\xb2wm\x9a\x5c\xae\ +\x04\x82C\xefe\x8d1\xef\x06\x03\xd6\x05\x10\xb2\xa0\x98\ +\xf6\x18y\xd3\xc4\xca{\xb8^\x0e\xc7q(\x19.\xb6\ +[\xc1\x92\xa1\x9fpN\xe3\xb7xx\xeb-\xec\x16/\ +\x92\xd8\xbe\x02O\xbad\xb3\xd9 >y;\x95\xa8\xad\ +\xad\x8d\x1bo\xbc\x91\x89\x13'\xf2\xcb_\xfe\x92\xae\xae\ +.\xc6\x8f\x1f\xcf\xb6m\xdb\xa8\xaf\xf7\xbb3tuu\ +a\x18\x06\x91H\x84\xae\xae.\x84\x10\x83\x89D\xe27\ +\xe5\xb0\xa7\x5c`4a\xc2\x04\xd2\xc3i^\xbf>\xe7\ +\xc7\x22\x8a\xca\xcb/\xbf\xcc\x86\x0d\x1b\x82\x16\x1d\xe5\xe8\ +\xbe\xfc\xb5\x9c\xb3(cv\xae\xebR\xdb\xa9\xb1\xe6\xc7\ +)\xac\x8c\x87S\x928y\x89\xf4|\xb7\xa8\xdc\x8bE\ +Q\x14\x8c\x90\xc1u_\xf8!n\xc1\x8f\x9f$\xa0\xee\ +\xc7u>\xa4\xd0\xc9\xfe\xf8\x90\xae\xeb,^\xbc\x98u\ +k\xd6\xb1\xe9f\x0b\x94\x10n\xd1\xc4t\x0b8\xb6C\ +\xa9R\xe2H\x0bCSyv\xe8&N\x98r\x1a\xf9\ +d\x89\x91\xb7z\xd9\xf3r\x81b\xf1\xdd\x9f\x8a\xe6\xba\ +.3f\xcc \x1e\x8f\xf3\xc9O~\x92\x193f\x90\ +J\xa58\xee\xb8\xe3hkk\xa3\xbf\xbf\x9fP(\x14\ +\xa4F\xcbMd\xde\x8e:\x94i?\xe5\xf4\xf1\xaaU\ +\xabH\xa5R\xbc\xfa\xea\xab\x18\x86A\xb1X\x0c\xc0\xbf\ +r\x92i,n\x19P\x14\xa5\xccH\x98\xfe\xb9\xcf}\ +N9\xf5\xd4Sy\xf8\xe1\x87\xc9f\xb3\xe4\xd4\x5c`\ +C\xcb\x0d0]\xd7'Q\x94\x89\xe5\xd5J\x03N\xd8\ +\xc1R,\x22\x91\x08\x85B!\xe8lqH\xb9\xbd\xfb\ +\x0bf\xcd\x9a5l\xd8\xb0\x81O}\xeaSl\xde\xbc\ +\x99\x81\x81\x01\x96.]J>\x9f\xc7u\x5c\xa2I\x85\ +\xa1\x0d\x16\x85>\x87\xe4\xce\x04\xcfu\xdf\x87\xa2\x0b\x14\ +\x15\x14m\x7f\xba\xa6\xfa\x0eDv\xd5\xaaU,X\xb0\ +\x80\xdbn\xbb\x8d\xa5K\x97\x22\xa5\xe4\x91G\x1e!\x9f\ +\xcf\x13\x0e\x87\x83\xee\x0e\xa5R\x89\xe5\xcb\x97\xbf+\xd5\ +\xbf\x0c\xb5K)9\xec\xb0\xc3X\xb2d\x09\xba\xaes\ +\xe2\x89'\xb2p\xe1B\xee\xbd\xf7^*++\xa9\xaf\ +\xaf'\x9f\xcf\xb3g\x8f\xdfqc\xeb\xd6\xadW'\x12\ +\x89\xc7\x00f\xcc\x98Q\xb8\xe4\x92K\x22\xa3\xa3\xa3\x5c\ +~\xf9\xe5\xdc{\xef\xbd\x9c\x7f\xfe\xf9\xb4\xb7\xb73g\ +\xce\x1c\x9e{\xee9f\xce\x9cICC\x03\xc9d\x92\ +U\xabV\xd1\xdb\xdb\x1b\xb8\xe7\x1f\xfb\xd8\xc7X\xbbv\ +-\xbbw\xef\xe6\xb0\xc3\x0ec\xd7\xae]\x1f\x8c@\xca\ +^H.\x97\xa3\xa1\xa1\x01!\x04\xb3f\xcd\xe2\xd5W\ +_\xa5\xb1\xb1\x91\xeb\xaf\xbf\x9e\x07\x1f|\x90\xc4\x8e\x04\ +\x8ai\x12\x8e94\xce\xf6K\xaa\xcb\xcc\xf1r\xd3\xe2\ +w\xab\x1d\x0f\x87\xc3\xdc|\xf3\xcd\xef\xfa\xd9e\x1ak\ +\xb9\x9b6\x10`Eo\xbf\xc6+\xae\xb8\x823\xcf<\ +\x93\xe5\xcb\x97\x07\xdea\xb9\xe1\x81\x94\x92\xd1\xd1Q\xf6\ +\xec\xd9\x13\x08tl\x9e\xa0\xc2\xa8\xb2\xb2R\xbc\xfe\xfa\ +\xeb\x9c{\xee\xb9\xdcp\xc3\x0dX\x96\xc5\xe6\xcd\x9b\xe9\ +\xea\xea\xa2\xae\xae\x8e\x5c.\xc7\xde\xbd{\xe9\xec\xec\xc4\ +\xb2,\x0a\x85\x02RJ\x8e8\xe2\x08\x1e{\xec1t\ +]'\x1a\x8dRQQA\x22\x918(\xd4\xf7}U\ +'\xb6\xb5\xb5\xc9\xa6\xa6&&O\x9e\xcc\xc0\xc0@\xe0\ +1\xc5\xe3q\x1e|\xf0A\xdex\xe3\x0d\xbe\xfa\xd5\xaf\ +r\xfb\xed\xb7388H$\x12\xa1\xbe\xbe\x9e\x95+\ +W\xd2\xdc\xdc\xcc\xae]\xbb\x18\x1d\x1d\xa5\xae\xae\x8e\x81\ +\x81\x01v\xef\xde}Q\x22\x91\xb8\x7flQfVU\ +U\xcd\x14B\xbc\x97Nm\x9e\xeb\xba]\x83\x83\x83o\ +\x96m\xc8\xe1\x87\x1f^hnn>\xa0\xcb\xf6\x1f+\ +w\xdb_\x0do\xd8\xb0\xe1\xcb\xc9d\xf2>\x80\x13N\ +8\xa1X(\x14\xc2e\x0cm\x7f\xd2\xf4\xfe_\xdfN\ +\xa5\x0d\x85BA\xccT\xee\xefUn:\xbde\xcb\x96\ +/%\x12\x89\x07\x0e\xb9\xca\xcad2ttt\x04y\ +\xeb2\xd7\xf7\xe9\xa7\x9f\xe6\xea\xab\xaf\xe6\xb5\xd7^c\ +\xc7\x8e\x1d\x81](C\x0a\xa1P(\xc8\xe2\xbd\xdbC\ +\x1c\xb3\xd9\xec\xf6l6\xbb\xfd\xfd\x5cW}}}\x99\ +\xdda\x0e\x0d\x0d-\xee\xe9\xe9y\xafS\xd8555\ +\x9b\xcb\x0c\xfe\xe1\xe1\xe1\xe7\xa3\xd1\xa8Z,\x16\x8fU\ +\x14e<\x80\xabB\xdd\x14\x8d\xe1\xad\x05\xa4+)\xd9\ +%\xc2Z\x05 \xc7\xf0\xbb\x12MMM\x07\x08o\xff\ +\xb6\xebB\x08\xfd\x90\x9f\x90\xfa\xfa\xfa\xdd\xabV\xad:\ +\xac\xbd\xbd\x9d\xa3\x8f>\x9a'\x9f|\xb2\x8c\xe6\x069\ +\xecp8\xfc\x0e\xaf\xe2\xddv\xaaa\x18l\xdb\xb6-\ +8!\xff/\x8e\xf1\xe3\xc7?\x1a\x0a\x85.\x04\xc8U\ +x\x9c\xf1\xcdF\x22\x06\xe4\x87\xab\xf8\xfay\xff\xc6\xed\ ++\xaf\x81\x92\xce\xc0\x86\x22o=\x96\xf5\x1f\xb0\xe97\ +F{\xa8\xbf\xbf\xff\x8b\xfb\xa9\xc1\xd2!\xf5\xb2\xf6\xc3\ +\xb3\xe4M7\xdd\xc4-\xb7\xdc\xc2K/\xbdDoo\ +\xaf\xff(\x87t\x1a]\xd7\x83'\xcd\x1cLr?\x9b\ +\xcd\xfe\xc9\xd6\x1a\xff\x8f\x0c%p\xf3m\x81\xe7IJ\ +IArG\x9c\xcb\xbe|\x15\x99.+\xd8\xdbF$\ +\x14\xe4\xed\x85(?h\xe3\xe0\x1f6\xf9\xbes\xea\xed\ +\xed\xed,^\xbc8h>,\xa5\xa4\xba\xba\xfa\x8f\x16\ +\x5c\xc6b1v\xee\xdcyl\x7f\x7f\xffz\xfe\x9b\x8e\ +SN9\x85\xae\xae.\xf6\xdc\x99\xc3s%R\x1a\x08\ +\xa9S]\x1d\xf1\x0bx\xc6lF9<\xb0m\xfb=\ +\xb7\xbc~_\x021M\xf3e\xd7u\xb7\x95\xbd\x93\x83\ +\xe9\x10\x94J\xa5l\xcf\xf3F\xff;\x0aBJi^\ +r\xc9%\x9cr\xca)\xb4\xb4\xb4p\xc7\x1dw\x90J\ +\xa5hhh\xa0\xb7\xb7\x97\x9a\x9a\x1a\xda\xda\xdaX\xb1\ +bE\x90\xa2\xd8\xb0a\x03\xb6m\xaf\xfb\xc0\x05R]\ +]\xcd\xf0\xf0\xf0e\xc3\xc3\xc3\xfc\xffh\xc82\x0e\x15\ +\x0e\xfb}\x80\xcb}\xbd\xa6L\x99\xc2\xe6\xcd\x9b\x990\ +a\x02S\xa7N\xa5\xa7\xa7\x87\xee\xee\xee2\xb9\xc1\xfe\ +\xc0\x05r(\xdbj\xffw\x19\x9a\xa6q\xff\xfd\xf7\xf3\ +\xc2\x0b/\x90\xcdf\x83\xb8\xa5\x1cxJ)\xe9\xee\xee\ +\x0e\xbe\xf7<\xef}7\xe8\xd7\xf8h\xfc\xd9\xe18N\ +\xc80\x0c\xd2\xe9\xf4\x01\x1e\xe2\x9f\x8ai\xc6\x82\xe7\xf7\ +\xec\xad\x88\x8f\x96\xfb\xcf\x8fH$\xd2T*\x95\xaa\xde\ +\xe3\xba\xbauuu\x83\xa3\xa3\xa3\x85\x8fV\xf0\xa3\xf1\ +\xd1\xf8h|4>\x1a\x1f\x8d\x8f\xc6G\xe3\xa3\xf1\xd1\ +8`\xfc\x7f\xa7\x8cK\xc9\xd0\xc3l\x1c\x00\x00\x00\x00\ +IEND\xaeB`\x82\ +\x00\x00\x1ax\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00d\x00\x00\x00i\x08\x06\x00\x00\x00\xcc|\x86\x8a\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x88&\x00\x00\x88&\x01\ +\xac\x91\x9d\x06\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e\x04:\x04\x0e\x03\xc5\x00\x00\x19\xf8IDATx\ +\xda\xed\x9d{tT\xf5\xbd\xe8?\xbf\xbdg\xcfd\x92\ +\x0cy\x12\xc2#\x01J(\x8fJ\x90\xa2\x16k\xc3\xa9\ +\xa0\x02\xf5\xd4.\xbd\xda.[\xee\xa5\x85z\xb4u\xf5\ +\xae\x16\xef\x83\xf6\xf6\x9cs[\xd0z{\xafK\xaf\xbd\ +\xb4\x97\xd5z=*\xb7\xd6\x1e=\xe7\xd4Z\xa1*x\ +\x05\x0fJ\x00Q\x08\xa4\x09\xaf\xc8#\x04\xf2\x9a$3\ +\x99\xcc\xec\xc7\xef\xfe1\xccf\x1e{\x87\x09L\x12p\ +\xe5;k\xafd\xf6\xfe\xfd~\xfb\xf7\xfb\xbe\xbf\xdf\xdf\ +c\x04@eee\x9d\x10b\x07c0\xea\xa0\x00\xaa\ +eY\xda\x18*\xae\x0e\xf0\x00\x85\xa6i\x16\xaa\xaa\x0a\ +\x80\x94\x12\xcb\xb2\xc603B \x84@Q\x94\x14\x82\ +\x94\x1b\x86Q\xe6\xf5z\x01\xc8\xcf\xcfg\xe5\xca\x95c\ +\x98\x1a!\xd8\xbf\x7f?{\xf7\xeeM!\xc8D\xc30\ +*\xd3\x0b\x9a\xa6\x89\xae\xebc\x18\x1bF\xc9\xf0\xf9|\ +\x08!2T\xd6\xf8\x0b\x97\x0dRJ\xfa\xfb\xfbik\ +k\x1b\xc3\xdc0A^^\x1eS\xa6LAJ\x99A\ +\x90\x80eY\x81\xf4\x0a\xc3eK\x84\x10((\x08@\ + \x88\x19&1\xcb@\xf5\x9b\xf1;1\x0f\xaa\xa5\x82\ +\x00\xa1H\x10 \x91\x9f8\x82\xa4\x13\x22\x99 ^!\ +\x84\xe6T0]\x9cr\x01A\xa3\x8f\x93\xfa9\xba\x8d\ +\x10\x032\xc6gn\xc8gvm\x01Iv\x8d\xfe\x1e\ +\x89l\xcf'v\xce\x87\xd5\xee\xc73\x90\x17'\x90\xdd\ +\xb1O6A\x14\xcb\xb2\xd4d\x22X\x96\x95S\x09\x11\ +@\x8f\x19\xa6a\xe0\x04\x1df\x0fB*L\x9d\x9e\xc7\ +\x8a\xa5e\xe4\xe5)\x98&H\x09\xe2\x824\x14\x94\x0a\ +(\xebG\xcc\x09\x83\x02\xb1\x01\x89\xec\xd30z5d\ +\x9f\x86\x19\xf2`\x854\xac\xb0\x07+\xa4\xa2\xe8\x9a-\ +M\xf1K^\x13\x04I\xe09\x9d \xc2I\x12\xdc(\ +x9\x10\xb2\x22\xfck\x7f\x03RJT\xa9R1\xc9\ +\xcb\x17\xbfT\x8a\xb4\xc00$B\x08\x12]\x10q\x1d\ +\x05R \x11`H4U\x81b\x13o\xb1\x09\x0c\x10\ +\xef\xda\x85r\xc0@Hb\x9c\xcf\xc3h\xf7\xa1\xb7\xf9\ +\xf0\x84\xf3mN\x10W\xa9D\x0d&!\xae\x94\xcb\x85\ +\x84\x18\xd2dW\xff\xa1\x0b\x12 \xf0\xe5\x09n\xbb\xab\ +\x0cie\xa9\x16\xed\xe7\xc2\xf1\x96\x04\xfcE\x02\x8a\x07\ +\x10\xb3\x07@\x01=fa\xf6z\xb0z\xbd\x18\xbd*\ +\xb2\xcf\x8b\x19V\x91!\x0fFHA\x89z\x11B\xc6\ +\xc3\xe2Q\x92\xa8\xc1$\xc4\xb5B.\xa4\xe4\xa4~\x0e\ +C\x9a(\x17\xb0X3\xb7\x00E\x11\xc8\x1c1\xae\xdd\ +\x86\x14H\x13\xa4\x09\x1e\xa1\xe0)\x92P\x14\xbd0\x96\ +\xfe\x14\x89\xd2\xa3\x92\x816\x0d\xeb\x9c\x9fH\x9b\x07O\ +w\xbe\xad\xeeFJ\xa2\xb2\x96\x90db\xe4\x82 \xed\ +FO\x8a\x14TN\xf6\x0e\xab]\x16N\xff%K\x94\ +\x94x\xfd\x02\xef\x0c\x1dQ\xa3S\xa2HL\xab\x83X\ +\x8f\x02=^b=*\xf4z1\xc2\x0a\x845b!\ +\x81\x12\xd1\x10jn%\xc9\x0d\xbf\xc3N\x90\x90\x8c\xa4\ +|/,RG= \x03\xc0\x8aK\xa94@\x11\x0a\ +y\x85\x12\x0ac\xe4M\x06I\x04d\xc2\x96\x81e@\ +\xd7\x9fK\x90]y9'HV*+\x97\x0410\ +\xe3\x86\xfa\x02\xf8|\xa3K\x10W\x02\xa5\xcbV\xc2c\ +\x93\xa0\xfa@\xd1\xc0\x90r\xe4\x09\x92K\xef\x8a\xf8x\ +l\xfb\x01\xa0\x88k,\x8c\x10I\x03\x19\x01\x18TB\ +\xc6\xb2\xbe\xc3\x97\xb9\x18\x92\x0d\xc9\xb5\xa4d\xb6%\x87\ +P\xf7\x82Z\x11\xf1zq\xc4H[\xdd\x08.\xc60\ +\xc3J\x90\x1c\x8b\xc8\x90\xbc\xac\x04'\xe4\x82#\x84\x88\ +\x1b\xcdTP\xb2\xaa\xab\xa8\xd0\xd5\xaes\xead\x1f5\ +\x15s\xb8a\xc6MT\x96N`z\xe5\xa7P\x15\xe8\ +\xeco\xe3d\xf0/\xb4\x85>\xe6xw\x03\x8aP\x1d\ +\xde\x953\x0c\xe6\x5cB\x86\x1c\x87\x0c\xb7cz)\xc9\ +x\xfbO\xdd\xf4\xb4\xc3\xab?\xfb\xbf\xcc\x9f>\x1f\x8f\ +\xeaq\xec\xa7)\x0d\xce\xf4\x1e\xe5\xd7{\xff\x96\xf3\xa1\ +\x93\xa8\x8as\xb9DF\xc0\x92V\x5c\xf2\x10Y\xe7\xeb\ +\xe40\xa8@'<+\xd9x\x01Wr]\x0e\xc4\x06\ +,^}\xb1\x0d-V\xc6G\xcf\xec`a\xcdBT\ +Eu\xf5\x92<\x8a\xc6\xd4\xe29l\xb8\xeden\xfd\ +\xd4}\x18\x96\xeeX.\xd4k\xb0\xedO\xedL\xb6\xea\ +\xb8\xbfv-K>\xf5U\xe6\x8c\xff\x5c\xd6\x0c\x92+\ +\x9c\x0c\x86\x97aw{\x11\x82\xf4f\x06k\xd7\xb2\xe0\ +\xf5\x7f\xec$\xe0/\xe5\xfd_\xbe\x89\xdf\xeb\xcf*\xc5\ +\x92\x90\x80\xfbk\xff#\xc5y\x15\xfcc\xc3\xff\xc4\xab\ +\xfa\xec\xe7\xaaG\xd0rd\x80\xe6\xc3=\xdc\xff\xf7\x7f\ +C\xcd\xc4\x99\x00\xb4t\x1f\xe6\xf0\xf9\xf7\xb3\xa0\x88\x95\ +S\xad\xe1\xa4\xae\x06UY\xb9\xf3\xf3\xe3\xaen2\xa7\ +*\x8a;r\x0f\x7f\xd0G\xa4\xdf\xe4\xe7\x0f>b\x13\ +#\x1d\xa2F\x84\xf7\xff\xb2\x1bM\xf8\xb9a\xd6\x02\xbc\ +\x1eo\x0aaV|z\x15M\x1d{i\xee\xfc\xe0\x22\ +AT\xc1\xc9c\x03TV\x94P3q\xa6M@\x04\ +)s\xdaW\xaajs\xee\xf6\xe6B\xe5\x5c\xb6\x1f#\ +\x05\x87?\x0cQ^\x12\xe0\xdf\xdev\xbfc\xa9s\xa1\ +S\xfc\xb7\x9d\xab\xe9\xe9\x0b\xb3\xf5\xe5N\xaa'T\xf1\ +\xde/\xde\xca\x08\xf4\xfe\xcdg\xfe=\x8f\xbd\xb3\xca\xfe\ +\x1e\x09[\xf4\xf5\x98\xdc\xa6e \x91tw\xe8H$\xd7\xd7\x5c\xe7\xe8\xd2\ +^\xf2\x93#|$.7/Kq2~\xb9\xe4\x06\ +\x91\xf6q\xba'\x10(B\xa1\xf9`?\x15\xe5E,\ +\xb9~\x89\xa3Q\xee\x8e\x9c\xa3\xb1\xbd\x1e\x81@ZP\ +P\xa82s\xf68\xde\xfbp?\xef7\xd6g\xd4Y\ +\xb3\xf0\xa7X\xc4\xd0T\x85sma\xf4\x98\xc1\xbcO\ +\xcd\xc9p\x9f\x84\x14\x5c\xea\x93k7+\xeb\xc00\xd9\ +\x1d\xcb\xdd\x8c\xa1\xc8 Q:t\xb4\xc5\xd0c\xb0\xe2\ +\xe6\xbfr\x8d%\xde9\xf1O\xa8\xc2\x13\xaf\x7f\xa1\x89\ +\x09\x93}\x9c<\x16\xe5\x9d\x8f\xfe\x95EsnJ\x19\ +G\xb1\x7f\xf8\x0c\x9a\xe2\xa3\xc0WHG\xf4cg\x82X\ +W\x81\x0d\x19I\xd0c\xf1\xc1\x96\x14\x16;?7\x07\ +\x5c\x93L\x9aO\x10\x899?/\xce\x1b\x8f\xc7\xa3\x90\ +\xe7\xc9\xc7225t\xc4\xe8\xe3@\xc7\x9b\xa92\xe2\ +\xb4\x0ag\xd8\xd5\xf8 ^Vn\xd7ee\x17\x80\x99\ +F\xbcc\xf9\xde\x80\xab\x84\xb8\x81\xd7\xab\x10\xeew^\ +\x87\xecU\xf3.\xa6\x0c\x84s\xf7D6\x19\xe2\xd1\xcc\ +\xf6&b\x91\x5c\xac\x5c\x8c\xe3A\xa4}w \x889\ +x\xf4\xac\x9bQW\xd2\xfa|\x0a\xbaa:>\xd3T\ +\xef\xc5\xf5s\x0e\xed\x0bW\xab\x96\x8d\xea\xcd\xb5*\x1f\ +d>d\xa4g\x0c\x0dC\x0e:\xdf\x1e\x1bTe)\ +\x18\xba\x85i\x99\x19YaM\xf1]\x94\x84+\xc8G\ +\xe5\x1a\x1f\xc9\x11\xfb\x88g{\xb3Q\xc0\x8a\x10\xf6L\ +\xe0P\xb8SB\xea\xaa\xc7a\xe2\xea8>\x86?R\ +WFB4\xb3\x01U\x15\xe8\x86;\x07\xda\xb6\xc0\x81\ +\xdez\xccBU\xe3;\x91\xd2\x07iZ\xc6\x05\x0c\x08\ +W\x09\x1b-\xc8Ze\xb9\xcdf]I.+\xcd\x8a\ +:\xbb\xaf\x03\xee\x8c\xa0\xa9>\xc7z\x08\x81\x11\x13h\ +\x9a\xc7q\x90\xba\x15\x03q1\x8b\xe6J\xd5Q\xca\xf6\ +fmC\x92\xb3\xb5#%!\x08\x88\x9a\x11|j\xe6\ +<\x88m\x0b\x5c\x5cf\xaf\xe6qq\x06b\xb9A \ +\x16\xb9DG\xd6\xd9\xde\x5cJ\x87\x9bMrJo\xfb\ +\xfcqus\xae\xfb\xbc\x8b\xca\xf29\xd6\x13\x02b1\ +I\x9e\xe6u\xce\x00\xc4\x82\x17\xd3\xfe\xd2\x0d\xd9\x97\xfe\ +\x0cG\xb6wH\x81a\xee\x88\x929C\xa88\x98\xae\ +\xfc\x02\x15EQ\xe8\xea\x09R]>\xd5Qe\x09\xe9\ +\x10\xb4I\xe2\xa9\x91|g\x1b\xd3\x1b\xed\x8e\xef\xd8\x12\ +\x02\xb7\x89A%\x8b\x94\x9e\xcc\xf1\x14\xee\x90\x92\x8b9\ +\x9d\x0f\x11\xd99\x0c\xfe\xfc\xb8\xbb\xda\xda\xd96\x88\x1d\ +\xf1f\x1am#\xfe\x8e\xc2\xbc\x80\x0bA:\x93\xe2S\ +qEJ+\xd70j\xb9\xacl\xa0p\x5c\x9c \xc7\ +[[\x5c\xcbT\x17\xcf\xe2H\xc7G))\xf8p(\ +\x1e\x10V\x8f\x9f\xe2X\xa7-\xd4\x92#\xe41\xba\xb9\ +,\xb7U\x11\x97=\x9a4\x9d\x9d\x0e%\xe5\x1aH\xc9\ +\xfe\xa3\x07\x5c\x9b\x99Q2\x9f\xa6\xf6\x0fRTL\x7f\ +\xc8\x02)\x19_R\xeaX\xe7l\xdf\x09\xdb\x068\x8e\ +'\xcbM\xa5r\x98V\x9ddm\xd4s\x16\x8b\x08\x01\ +\x8ab_\x82\xf8.\xdc\xf4Oi\xb9\x06\x8a\xc2\xa1\x13\ +\xcd\xae\x1c\xf4\xb9\xaa\xe5X\xd2L\xa9\x17\xec4@Q\ +X8k\x81\xe38N\x06\x9b\xe2\x04T\x04\xc2a\xb5\ +\x8b\xa6\xe6\xa1\xc8\xe4\x16\x9d\xfb7\x12i\x93AmH\ +2\x05Gb\xa1\x9c\xd7'\x982\xcd\xc7\xc1\xa3\xcd\x1c\ +=\xdb\x9c\xd1a)%\x13\x0a\xab\xa9,\x9c\x9a\x82\xf0\ +\xf3\xad1,\xcb\xa2\xae\xf6s\x19\x03n\x09\x1e\xe6|\ +\xe8T\xdc\xadV\x04\xb1hf\x02rBA\x15\xba\x15\ +E7tN\x9f\xee\xa37\xe8\x9c\x13\x93\x96\xcc\xe9B\ +\xb9\xac%\xc4-\x1e\xb9\xa2U'\xe9\x04r\x98\x903\ +\x0dX\xb0(\x80G\xd5\xf8\xbb\xff\xf3\xb8+G\xdd2\ +\xf5.L\xcbDQ\x05\xbdA\x83\xa3\xcd\xbd,\xbdq\ +\x11\xb5\xd3k3\xea\xbc\xd6\xf8\x1b<\x8a\x06\x12\xbc>\ +\x85H4\x13\xd9\xaa\xe2\xe1?\xd7=\xcb\xd4\xe8\xdd\xac\ +\xb9\xfeg\xac\xff\xebg\x1d\xfb7\x1c\xabN\xb2\xb6!\ +\x09$\xe6&\xdb\xeb\xb0:]8\xc7\x02\xf9\x85*S\ +\xa7\x17\xb0m\xdf{\x1cm=J\xcd\xa4\x9a\x8crw\ +\xd4\xac\xa4\xab\xff,\xbf\xdd\xf9\x02;\xdf\xe8\xe3\xcbu\ +\xb7\xf3\xcc\x7f\xf8_\x19\xe5Nt\x1f\xa2\xa9s\x9f\xbd\ +\xce\xb7\xb8\xd4CO\xb7A\xd3\xe9&fM\x99\x952\ +\xcei\xa5\xb3Y\xf7\xb5\xd9\x00\x9c\xeai\x1a$\xa0\x1f\ +\xfe\x94\x922\x98w\x95+\x09\x89\x13E\x5c\xdcV\xe0\ +p\xd9\x8b\x12n(\x04\x09?\xfb\xedS\xae\xb6\xe4\xfe\ +\xf9\xff\x89\x8d_{\x9d\xc3\xcf\xedd\xf3\x0f\x7f\x8dO\ +\xf3e8\x0co\x1c}!\xe5}Sk\xf2@\xc2?\ +\xed|mP[)P\x1c\xfb\x97Xu2\xe2\xeb\xb2\ +F\xc3\xe5M\x86\xf2J\x8d\x1bn\x19\xc7+\xdb\xff\xcc\ +\xaf\xfe\xb4)\x13a\x17\xbeW\x8f\xafbRIU\xc6\ +\x80\x04\x82W\x0e\xfd\x82\x03m\xef\xa6\xdc\x9fT\xed\xe3\ +\xc6\xc5\xe3x\xea\xa5g\xf8\xf5\x96\xe7\x1cm\xd4\xbb-\ +\x7f\xe0\xf9\x0f\x1f\xcd\xc6Q\xcc\x99\xdb\x9bU\xfa=\x97\ +\xfbC\x86\xec\x0e\x9a\x92\x9a\xb9~\x06\x06\x8a\xf9/\x9b\ +\xfe;\x05\xbe\x00\xff\xee\xb6\xfb]\x83\xbad\xc4\x1a\x96\ +\xce\x96\xe6\x7f`\xdb\xf1\xdf\xc5mG\xca\x98$3f\ +\xfb\x99>\xd3\xcf\x96\x8f\x7f\xc1\x9f6n\xe4\xf3so\ +\xa4\xbc\xa8\x9c\x96\xee\xc3\x9c\xedk\xc1\xa3x\xf0(^\ +g\xd54L3\x86#\x1e\x87\x88\xcb\xb09R\xc2\xdc\ +\xeb\xf3\x99\x5c\xed\xe3\xd1\x17\x1f\xe7\xb7o\xfc\x0b\xcf\xae\ +{\x8a\x89\xa5\x93\x5c\xeb\xedo}\x9b\xd7\x9b\x9f\xe5l\ +\xa8%\x83\x18\xc9\xed\x0a\x05\xa6T\x15\x02\x92\x93\xe1\x83\ +\x9c\x0cK\x04\xf19\xf7\xc1l\x845B\xabN\x94l\ +\xf3-#\xb9?$\x81\xc0\xe22\x0f\x7f\xfd\xb52*\ +\xae;\xc3\xc2\x87?\xcf\xb2uw\xd3\xdau\xd6\xb1\xfc\ +\xef\x0e>\xc1\xb9\xf0\xc9!\xec\xa0\x12\x17\xd6a\xa9\x17\ +\xed\xdb\x10\x82\xdb+\xc5\x99[\xc4~\xc9\x19C\xd34\ +\x87\x1c\xfe\xa7\xa4\xbf\x0d#e\xbf\xbdi\x19\x08K\xb8\ +\xe7\x8bdj\xe6\xc80\xa1\xb0\x04f\xce.f\xf7\x9e\ +\x8fxc\xef6\xbeyG\xe6\x89w\x9f\xa9X\xc4\xfb\ +\xa7^\xbfD\xe6If\x9d\xaa\x92i7#\xfd\x11\xfa\ +\xfb\x8d\xdcyS\x8a\x92\xbd\xca\xb2,\x0b]\xd7\x09\x87\ +\xc3W,\xa6Q\xdd@X\xa9\xf3\x13\xf22\xdc\xc7\x92\ +\xf1`\x18\x06\xef5\xec\xe5\x9bw\xac\x8c\xa7\xde\x93\x14\ +\xe2\x8aO\x7f\x93\xe6\x8e\x0f\xe8\x8b\x061\xa4\x8e1\xc8\ +*\x95ltk\xfa\x84V\xb4\xdf\xc00rG\x10\xc3\ +0\x18\x18\x18\xc88\xb5\xcfQ\xbec\xb1\x18\xb1X,\ +g6$\xd9\xedM\xec\xeb\x1b\xea5\xb1\xca\x87\xd7\xab\ +\xf0\xcf\x17\xdc\xd6t\x8e\x1e_0\x85\xbf\xbb\xf5\xb7\xfc\ +\xd7%\xbf\xe3\xceO\xaf\xc6\xb0bC{G\xc6*}\ +q1\x1eS\xa0\xaf-w\xc4\x18r\x1cb\x9afN\ +\xf7\x87\xe4*?y\xcb\xed\xc5\xb4w\xf5\xf1\xf7/l\ +p\xd4\xf9^O\x1e%\xf9\x15\x14\xfa\x8as\xb6\x8dY\ +Q\x05g\x0fE1BfN\xe3\x10\xb7\x88]\x19.\ +cn\x1b\xaf\x1c\x05\xb7\x96%\x99T\xed\xa3\xf6\xb3%\ +\xfc\x8f\xcd\x9bxk\xff\xf6\xac\xed\xd8\x151\x82\x80\xc3\ +/\xf6\xa2xs\x8b\x97\xcb\xf2\xb2\xae&HH\xc4\xe7\ +\x97\x141wA\x80o<\xb6\x9a\x97w\xbdD{\xef\ +yB\x03\xbd\xe8f\x94\xa8\x11!\xa2\x87\xe9\x8f\xf5r\ +\xa5\x9c\x90`\xa6\x13o\xf7\x13\x0b\x9a#6N\x8f{\ +\xfeI\xe4&w\x93c\x0e\xb6,XxK\x80y\x0b\ +\x0b\xf8}\xf3c\xfc\xf9\xf4FJ\x03%\xf8}~L\ +\xcb$fF\x08\xc7z\xd1\x14\xef\x15\xbdG\xf3+\x9c\ +\xd8\xd5\xcf\x91\x7f\x09\x0dK\x0e\xcb\x0d\xbf\x1e\xaeA\x90\ +\x16h^\x85\x12o\x1e\x10%\x18k#\x18\xbb\xccD\ +\xe0\x85UIR\x82\x11\x95\x981\x0b#\x229\xb6\xbd\ +\x9f3;\x22\xa8\x9a\x18V\x89w:\xb7wx%\xe4\ +jR{\x0a\x085n\xa8\x0dC\xd2sF\xa7\xb7\xc5\ +\xa0\xe7\xb4N\xff\x19\x13\xbd_\xa2\xf7[\xc4\xfa,\xa4\ +\x89M\x8c\xe1\xc2Cb\x0d\xf55/!\xd9\xc6\x13f\ +L\xdaW4d\x11\xd6\ +\xe9?i\xc6\xc39\x9b\xe3EJ\xf4\xa8\x5ce\xba\xc0\ +\x8d\xe9=C\xa5\xe0Pa\xdcy\x15\x8f.\xe8\xad0\ +\x11Rd\xc5\xf1B\x11H$\xbd\xe7MB\x1f'8\ +\xde$\xd6g\xd9\x1co\xf4K{\xa9\x95\x10\xe0\xf1\x89\ +\x1c\xe4\x9aG\x1f\x5c\x93\x8b\xb9[u\x02\x05\xdd\xf1\xb3\ +\xdcCe\x16\xc9{*-#\xae\xdf-]\xa2\x0fH\ +zZ\x8d8\xc7\x9f\xd4\x09\xb7\x98`\xe2\xaa\xe3\x15\x95\ +k\x1e\xb2^(\xe7fp\xae\x84(\x85\xdd*\xaa.\ +h\xffK\x8cp\x9bI\xf8\x94I\xb4\xcfB\x0fI\xf4\ +\xb0\x85\x1e\x96q[\xa3\xc49^\xf5\x88O\xa2\xcb\x91\ +\xa1\xb2\xb2\xf6\xb2r\xed\xeaI\x01\xfe\x90\xca\xa1_\x87\ +>\xb1\x1c\x9f\x0b\xc3>\xb2q\x88\x00E\x13\x8c\x81{\ +\xa4\xae\x8c\xa1\xe6\x1a0\xea9\xb7!cpen\xaf\ +\xc8r\x8b\x17\x80\xaa\xaah\x9a\x86eY\xf6to.\ +7Z^m^P.\xeb\x0d)\xb9\xe8\xa6\xe3,\xcb\ +b``\x80;\xef\xbc\x93;\xef\xbc\x93\xf1\xe3\xc7\x13\ +\x08\x04\x88\xc5b\x04\x83Av\xef\xde\xcd\xee\xdd\xbb\xd1\ +4-\xc5\x8bp\xfa\x9b\xed\xb3\xa1\x96K\xf43\x19A\ +n\xe5\xae\xf4]N\x7f\x13S\xe0\xb1X\xcc\x959\xdd\ +\xee{\xb2Ix%\xc3g?\xfbY~\xf9\xcb_R\ +\x96v&I\x22v\xb9\xf5\xd6[\xe9\xed\xed\xe5\xe9\xa7\ +\x9f\xe6\xe8\xd1\xa3\x19\x03O\xb4\x9d>[\x96>\xd8\xc1\ +\xbeg[n\xb0\xff\xdd\xbe[\x96\x95r\x88\xdb`\xfd\ +u\xeb\x97\xc7\xe3\xc1\xeb\xf5\xe2\xf7\xfb\xe9\xef\xef\xb7g\ +`\xb3\x91$\xe5R\xfa-q\x19\x86\xc1\x8f~\xf4#\ +^z\xe9%\x9b\x18\xe9\xcbE\x13\x10\x08\x04X\xb7n\ +\x1d_\xff\xfa\xd7]\x17\x06\xe4\xe7\xe7SWWG\xe2\ +\x07-\xaf\xc6 -]3\xdcz\xeb\xad\x8c\x1f?>\ ++5$\xa5DQ\x14\x0a\x0a\x0a\xc8\xcb\xcbs\x9d\xcb\ +\x1f\xb2\x97\x95\xa8\xf4\xfd\xef\x7f\x9fU\xabV\xd9\x1d\xaf\ +\xaf\xafg\xf5\xea\xd5l\xdd\xba\xd5.k\x18\x06?\xff\ +\xf9\xcfY\xb3f\x0d\x07\x0e\x1c\xe0\x8e;\xee\xe0\x9e{\ +\xeeq\x1c\xec\x8a\x15+\xf8\xcew\xbe\xc3M7\xdd4\ +\xea\x84P\x14\x85i\xd3\xa6\x0dZn\xee\xdc\xb9l\xd8\ +\xb0\x81\x87\x1ezh\xc8\xf6\xc1\xe7\xf3\xe1\xf3\xf9.\xcf\ +\xcb\xbax\x02\xb4\xb0\x7f l\xce\x9c9|\xef{\xdf\ +Ky\xd1\xb9s\xe7\xf0\xf9|L\x992\xc5\xae\xf7\xf4\ +\xd3O\xd3\xd8\xd8\xc8\xda\xb5k\x997/~2\xdc=\ +\xf7\xdc\xc3\xfe\xfd\xfbiiiI\xe9\xe4\xce\x9d;\x89\ +F\xa3\x1c;\ +(\x92\x1f~\xf8an\xb9\xe5\x16,\xcb\xc2\xe3\xf1\xb0\ +g\xcf\x1e\x1e}4uU{,\x16\xe3\xc1\x07\x1f\xe4\ +\xde{\xef\xb5U\xe8\xb2e\xcb\xa8\xaf\xaf\xe7\x87?\xfc\ +\xa1].\x12\x89\xb0q\xe3Fjjj\x88F\xa3\xfc\ +\xf8\xc7?f\xff\xfe\xfd\x19\xef\xd5u\x9d\xeb\xae\xbb\x8e\ +G\x1ey\x84\xda\xdaZ,\xcbBUU6l\xd8\xc0\ +\x1f\xff\xf8G\x9bX\xaa\xaa\xda\x8e\xc3eIHB\xc7\ +'W\x94R\xd2\xda\xdaJuu5;v\xec`\xfb\ +\xf6\xed\xdcw\xdf},^\xbc8s{\xc0\x85z\xb3\ +g\xc77\xc4tww\xb3j\xd5*\xf2\xf3\xf3\xe9\xec\ +\xect\xfd\xbd\xdd\xea\xeaj\x96,Y\xc2\xf2\xe5\xcby\ +\xf0\xc1\x07Y\xbe|9g\xce\x9c\xe1\xae\xbb\xee\xc2\xe3\ +\xf1\xb8z-k\xd7\xae\xe5\xb6\xdbnc\xe3\xc6\x8d|\ +\xe5+_a\xf3\xe6\xcd\xd4\xd5\xd5\xb1dI\xea\xd1\xb3\ +^\xaf\x97M\x9b6\xb1y\xf3f\x00\xd6\xad[\xc7\xd2\ +\xa5KY\xb7n]\x86\xa4=\xfc\xf0\xc3\xd4\xd7\xd7S\ +\x5c\x5c\xcc\xd9\xb3\xcek\x8bg\xcf\x9e\xcd\xf3\xcf?O\ +QQ\x11+V\xac\xa0\xb6\xb6\x96e\xcb\x96\xd9*.\ +\x81\x87K91\x97\xf4\xb2&L\x98\x90\xf1<\x18\x0c\ +\xd2\xd7\xd7\xc7\xc0\xc0\x00\x9b7of\xd9\xb2e\xdcu\ +\xd7]\x83\xfa\xd7%%%6\xd2JKKQU\x95\ +\x8f>\xfa\xc8\xb5\x83\x93&M\xa2\xa0\xa0\x80\xf5\xeb\xd7\ +\x13\x0e\x87\xf1z\xbd\xec\xde\xbd\x1b\x80\xb2\xb2\xb2\x0c\x82\ +\x18\x86\xc1\x82\x05\x0bX\xbcx1\x7f\xf8\xc3\x1f\xd8\xb2\ +e\x0b>\x9f\xcfV1EEE\x8e\x04\xac\xae\xae\x06\ +\xe0\xe4\xc9\x93\x83\xaa\xa2\xa9S\xa7b\x9a\xa6c9)\ +%?\xf8\xc1\x0fl\xf5\xdc\xd9\xd9Iaa!]]\ +]\x9c8q\x22\x15\xe1\x8a2t/+\xb9\xe0\xb8q\ +\xe32\x9e\x1f:t(\xbe\xd1\xb2\xae\x8eh4:\xe8\ +\x82\xec\x04$t\xb9i\x9a\xd4\xd6\xc6\xf7\x03\x1e\xd7\x17vtt\xd8\x03\xbc\xee\xba\xeb\xe8\ +\xea\xea\xc24\xcd\x0c\xc4&\x10\x0f\xa4\xa8\xb4\xd2\xd2R\ +\xc6\x8d\x1bGCC\x83c6!\xc1\x0cg\xce\x9ca\ +\xd7\xae]ttt\xd0\xd0\xd0@0\x18\xc4\xe3\xf1d\ +\x10CJ\xc9\xc4\x89\xf13\x82\xf7\xec\xd9\x93\xf1<\xb9\ +?\x8b\x16-\x02`\xf7\xee\xdd\x19\x041M\x93\x193\ +f\x00p\xe2\xc4\x89Kz\x81\xc9{\x1b/+R\xaf\ +\xaf\xafOi(\x12\x89\x10\x0e\x87\xed\xc1\xdct\xd3M\ +\x04\x02\x01\xdey\xe7\x1d\x0c\xc3p\xdc\xbb\x97 bB\ +\xff\xe7\xe7\xe7\xd3\xda\xda\xea\x8a\x80\xf9\xf3\xe7\x03\xa4\xa8\ +\x91\xc9\x93'\xdb\x08\x1fl\xa0G\x8e\x1c\xe1\xb5\xd7^\ +\xe3\xbd\xf7\xde#\x1c\x0e;r}\xfa{\xf6\xec\xd9\xe3\ +j\xcb\x0c\xc3\xb0\x1d\x9b\xa6\xa6\xa6\x8crB\x08\xa2\xd1\ +\xa8\xad6]O\xbeKK\xcd\xb8\xd9[\xe5R\xe9\xf7\ +}\xfb\xf6q\xe4\xc8\x11\xfb^\xc2\xddM6\xf6\xabV\ +\xad\x22\x18\x0c\xf2\xfb\xdf\xff\xde\xb1\xad\xd3\xa7O\xd3\xd4\ +\xd4d\x1bk7\xc9K\xc0\x9c9sl\x82%\xde\x9b\ +\x08@\xdd\x08r\xfe\xfcy[\x05y\xbd^T5~\ +\xbaPyy9\x85\x85\x85\x99\x87\xd6\x98&s\xe7\xce\ +MA\xb4\xdb\x8f4/X\xb0\x80\xd6\xd6V\xc7\xd5\xfc\ +\xaa\xaa\xda\xc1\xed\x97\xbe\xf4%;o\xa5i\x1a\xaa\xaa\ +\xa6HD\xe2\xd9`F\xfd\x923\x86~\xbf\x9f\xef~\ +\xf7\xbbl\xdd\xba\x15UU9u\xea\x14\x91H\x84\x8a\ +\x8a\x0a\xbb\xc3\xb5\xb5\xb5L\x9f>\x9d\xad[\xb7\xb2d\ +\xc9\x12*++St\xf0\x13ON\x9f\ +>\xed\x1a\xf7\xbc\xf1\xc6\x1b|\xe3\x1b\xdf`\xcd\x9a5\ +\xcc\x981\x83H$\xc2\xc2\x85\x0bY\xbf~=\xbbv\ +\xed\xb2\xddt]\xd7m\x95\xe6F\x10\x15\xb8A\xd3\xb4\ +\xea\xbc\xbc\xbc\xdaDG\xa7M\x9b\xc6\xc0\xc0\x00==\ +\xf1\xdf\xb1\x0d\x87\xc3tvvRWWGii)\ +_\xf8\xc2\x17\x985k\x96\x9db\x07X\xb8p!u\ +uu\x04\x02\x01;o#\xa5\xe4\xf9\xe7\x9f\xa7\xb1\xb1\ +\xd1.WTTD__\x1f\xf5\xf5\xf5\xf4\xf6\xf6f\ +t(\x10\x08 \xa5\xa4\xbe\xbe>\x05\xf9\xa5\xa5\xa5t\ +tt\xf0\xee\xbb\xef\xda*\x22\x9dS\x0f\x1d:\xc4\xbe\ +}\xfb(++#\x10\x08\xd0\xd0\xd0\xc0c\x8f=F\ +___f\x00\xa6(466\xd2\xd7\xd7GUU\ +\x15g\xcf\x9ee\xfb\xf6\xed\x0c\x0c\x0c\xa4\x94M\xb8\xcb\ +;v\xec\xa0\xa5\xa5\xc5\xd5\xf9y\xe5\x95W\x08\x87\xc3\ +L\x980\x81h4\xca\xaf~\xf5+\xf6\xee\xddkK\ +\x89\xae\xeb)R\xaai\x1a\xa5\xa5\xa5\x04\x83A\xba\xbb\ +\xbb/\xb6\x05<\xe8\xf7\xfb\xbfP\x5c\x5c\xbc2A\xf1\ +/~\xf1\x8b\x04\x83\xc1\x14\x9f\xdb0\x0c\xee\xbe\xfbn\ +\xd6\xaf_\x9fu\xd2\xee7\xbf\xf9\x0d;v\xec\xb0;\ +%\xa5\xc40\x0cL\xd3LQ\x11\xc9il\xd34m\ +NJ\xae\xa7\xeb\xba\x1dy;\xa5\xc7\x93\xf7D&r\ +FB\x08\x9b\xdb\xdd\xd2\xed\xb1X\xcc\xb6}\x89TM\ +r\xfb\x96e\x11\x8b\xc5R\xfa\xe3\x96~\x8f\xc5b)\ +\xefM\xd8\x1b]\xd7m\x07&9\xdb]SS\xc3\xf1\ +\xe3\xc7S\xd21\x9elS\xd2\x1e\x8f\x87W_}\x95\ +\xfa\xfaz6n\xdc\xc8\xf4\xe9\xd3\x1d\x0d\xa1eY\xb4\ +\xb6\xb6\xf2\xe4\x93O\xd2\xd9\xd9\x99Q&\x91>p\xdd\ +\xb0\xa2(x\xbd\x99\x07\x95\xa5#\xd65\xd2M\xaa\x9f\ +\xcd\xc9x\x9a\xa6\xa5D\xfeN\x99\x06\x9f\xcf\x97\xd5\xae\ +\xe2d\x977y\xa2j('\xf4\x0di\xc6P\x08\xc1\ +\xd9\xb3g\xf9\xf2\x97\xbfLmm-\xb5\xb5\xb5L\x9a\ +4\x89\x8a\x8a\x0aB\xa1\x10\xed\xed\xed\x1c;v\x8cc\ +\xc7\x8e9\xba\x99\x83\xcd\xd49\xfd\xbd\xd4\x0c\xa3[\xbb\ +C\xbd\x7f\xb9\xe5.5\xbb\xe84Wt\xd9\x04qk\ +(\xc1\xe1\xcd\xcd\xcd\xb6\xe7\x94\xf33\xb6>\x01\x0b\x18\ +.\x85\x8f!M\xe1f\xbb.k\x8c\x00WN\xb8!\ +g{\xc7`x\xa5h\xc8q\xc8\x18\x8c,Q\xc6$\ +dLB\xc6`LB\xae!O\xccUB\xc6\x8d\x1b\ +\xc7\xacY\xb3\xc607L\x90\x989tTY\xe9\x01\ +\x8fS\xaeh\x0cr\x0b\x96e\x11\x8dF3\x16\x12z\ +\x00K\x88\x8b\xfbd\x0d\xc3`\xdb\xb6mc\x18\x1b\xa5\ +X\xc4\x03\xe8@,]\x9c\xc6`\x94T\x19\x10\x16B\ +\x0c\x8cyT\xa3\x0fR\xc6w\x16/\x05&j\x9aV\ +!\xa5\xf4p-\xee%\xbev\xc0\x14B\xc4\x80^E\ +Q:TU=\xa7iZP\xd3\xb4\x88\xc7\xe31\x00\ +\xf9\xff\x01\xfa\x90K\xa0\xc0O~5\x00\x00\x00\x00I\ +END\xaeB`\x82\ +\x00\x00\x03|\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00d\x00\x00\x00d\x08\x06\x00\x00\x00p\xe2\x95T\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\ +\x95+\x0e\x1b\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e\x1c\x0e\xa7\xa1o)\x00\x00\x02\xfcIDATx\ +\xda\xed\xd6\xbfo\x1cE\x18\xc6\xf1\xef\xcc\xed\xda\xb1\x0f\ +\x9b\x93\x85\x90-\xb08\x12\x09wn\xac\x14n\x10\xe0\ +\x8b\x90K7\x14\xc8\x7f\x03\xfc\x01T'QB\x81(\ +\xdd\xd0\x906m0\x8ep*DD\x94 \x17\xc8\x0e\ +\x06d\x90\xec\xe4\x02\xde\xf3\xde\x9e\xf7\xd7\xecP\x1c9\ +\x892R\xaeX\xf1|\xa4\xedv\xa4\x9d}\xe7y\xdf\ +\x01\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\ +\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\x11\ +\x11y1L\x9d>vqq\xf1\x13cL\xf8\x9c\xcb\ +\xa6\x80\xcfNOO\xffVA^\xb0\xf5\xf5u\xdfn\ +\xb7\xf1\xdeSQQ\xbe\xf9\x94\x97\xaeLS>\x99\xc6\ +\x9d\xcd\x8c^\xb2`\xac\x1f\xef,\x8ec\xf6\xf6\xf6V\ +\xb2,;\xaa\xc3\x1e\x83\xbaE:MS\x0cp?\xff\ +\x85\xce\xf5\x19\x1a\xe1\x05\x99\xbb\xa4\x19^\x81$\xa0<\ +\x9f\x22\xfbu\x86\xe1\xe1,\x00eYb\x8c\xf1u\xd9\ +\x9f\xadS1\xaa\xaa\x22\xcfs\xf2\xbc\xc0Sa\x8d\xe1\ +\xaay\x9f\xcf;wx\xe7\xf5\x0f\x98\xe7\x1a\x8bW[\ +\xd8W2\x8a\xa2\xa0(\x0a\x9cs\xb5:p\xb5J\x88\ +s\x8e<\xcf\xc1\x8f&\xc3`\x90\xf2\xe1{\x1f\xf3\xd1\ +\xad\x1b|\xbd\xfd\x90w_;\xe3$}\xc0\x17\xf7?\ +%\xcfs\xbc\xf7\xcf\x12\xa2\x82L\x82\xf7\x9e,\xcb0\ +\x18\x98\x82\xe1\xc01\xd7l\x92W)\x00\x87\x7f\x1e\xf2\ +cr\x0b\xe3-Y\x96\x8dS\xa5\x82L\xb8e\x19\x00\ +\x0fs\xf3S\x0c\x86C\xa6\x1b\xa3yQ\xe1)]\x81\ +\xf7\x8c\x92\xf4\xec\xe6R\xa3\x82\xd8:&$\xcbr*\ +\x1d\xa0n3\xa4\xddn\ +srr\xc2\xe6\xe6&Q\x14\xb1\xb4\xb4\xc4\xda\xda\x1a\ +\xdb\xdb\xdbx\xefi\xb5Z\xac\xac\xac\xd0\xe9t(\xcb\ +\x920\x0ck\x95\x90Z5\xd9\xd5\xd5U\xbf\xbc\xbc\xcc\ +\xd6\xd6\x16\xbb\xbb\xbb\xa3\x01o\xed\xf8\xc7GQD\x18\ +\x86x\xefI\xd3\x14\xe7\x1c\xce9\x8e\x8e\x8e\xde\x1a\x0c\ +\x06\x8f\xd4\xb2&\xa0\xdf\xef\xb3\xb3\xb33\x9e\x13\xff9\ +]\xc6P\x14\xc5hcA@\x10\x04\x14E\xa1k\xef\ +\xa4\x1c\x1f\x1f?\x04\xca\xe7Y\x13\x86\xe1L\xb3\xd9L\ +\xe38FDDDDDDDDDDDDD\ +DDDDDDDDDDDDDDDD\ +DDD\xfeO\xfe\x01\xd1\xc0Q%\xbd%\x7f`\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00~\xd7\ +\xff\ +\xd8\xff\xe0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\ +\x01\x00\x00\xff\xdb\x00C\x00\x04\x02\x03\x03\x03\x02\x04\x03\ +\x03\x03\x04\x04\x04\x04\x05\x09\x06\x05\x05\x05\x05\x0b\x08\x08\ +\x06\x09\x0d\x0b\x0d\x0d\x0d\x0b\x0c\x0c\x0e\x10\x14\x11\x0e\x0f\ +\x13\x0f\x0c\x0c\x12\x18\x12\x13\x15\x16\x17\x17\x17\x0e\x11\x19\ +\x1b\x19\x16\x1a\x14\x16\x17\x16\xff\xdb\x00C\x01\x04\x04\x04\ +\x05\x05\x05\x0a\x06\x06\x0a\x16\x0f\x0c\x0f\x16\x16\x16\x16\x16\ +\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\ +\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\ +\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\x16\xff\xfe\x00\ +\x10Time for Lunch\xff\ +\xc0\x00\x11\x08\x02\x00\x02\x00\x03\x01\x22\x00\x02\x11\x01\x03\ +\x11\x01\xff\xc4\x00\x1b\x00\x00\x02\x03\x01\x01\x01\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x02\x03\x01\x04\x05\x00\x06\x08\xff\ +\xc4\x00D\x10\x00\x02\x01\x02\x04\x04\x04\x03\x07\x02\x04\x05\ +\x04\x01\x05\x01\x01\x02\x03\x00\x11\x04\x12!1\x05AQ\ +a\x13\x222qB\x81\x91\x14#R\xa1\xb1\xc1\xd1b\ +\xe1\x063r\xf0$C\x82\x92\xf1\x15Ss\xa2%4\ +5Tc\x93\xa3\xff\xc4\x00\x19\x01\x01\x01\x01\x01\x01\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x02\x03\x04\x05\ +\xff\xc4\x00!\x11\x01\x01\x01\x00\x03\x01\x01\x01\x00\x03\x01\ +\x01\x00\x00\x00\x00\x00\x01\x11\x02!1A\x12Q\x222\ +aqB\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\x11\x00?\ +\x00\xfas\xfc<\xe0\xa6#\x072g\x92\x16\xcc\xb9\xc5\ +\xcd\xbfZ\xb12\xca\xaa^\x17\xce\xa0z\x1f[\x0e\xd5\ +\x9f#\xb2\xc9\xf6\x98n\x1c\xa8\x0cGPt?:\xbd\ +\x82\xc5&)C\x0b\x09G\xa9:\xfbW\xca\x97\xe3\xd5\ +\x7f\xae\x86H\xa6\x8b5\x95\x18\x1b\x10O\xe9Dn\x0d\ +\x8d\xfe\xa6\xaaN\xf2a\x84\xb0\xe5\xf2Hn\x1a\x9b\x83\ +\x90\xcb\x85\xbbjP\xe5\xbfZtXo\x97\xa0\xa9\x0a\ +\x0d\xb5\x00\x93a\xae\xe6\x80\x9a\xe6\xf3D\xc8[-\xfd\ +'\xa1\xa8\x0dI\xd8\xb1\xa6!\x1c\xd40;\x83\xad\xe9\ +~s\x1a\x99J\x99-\xe6 \xef\xd0\xd0}\xe6k\xf4\ +\xfaT\x8d\xc3H\x22\x95\xf0\xb9\xf2\xe5o!\xd8Q\xba\ +F\xc7\xcf\x18\xbe\xf7ScY\xf8\xec\xdfk|\xdb\x93\ +z\xbb\x87\xb8\xc2G\x98\xdc\x90H=\xa9\x94\x9f\x11D\ +\x16\x8dB\xdfs\xcc\xfc\xe8\x89\x04RA\xa9V\x07K\ +\xfbS\xa0\xdc\xce\x08*\xda\x8a\xcb\xe2\x03\xc3\xc7J\x8a\ +l\x03m\xbdh\xc6\x0b8Q\xcc\xda\xb2\xb8\x8c\x82L\ +|\xae\xb7\xb1ntr\xf0\xc0\xeco{\x93\xce\x8b\x0d\ +'\x85\x88I\x00\x00\xab^\xf6\xabX<\x22\x18\x95\xe6\ +\x04\x97\xf4\xa86\xb0\xeaj1x\x03\x94\xbe\x1d\xf3\x00\ +.U\xb7\x1f\xcdg)\xd6\x932\xba\x87\x8d\xae\x8d\xa8\ +\xa5;\x00z\x9e\x95\x9d\xc3q\xde\x00\xf0\xa6\x1fvZ\ +\xc4sS\xd6\xb4\xbd:\x83p\xda\x86\x1c\xebr\xeb8\ +\x15\xb0\xf4\xefR\xa1lC*\xb0;\xdcW|\xbe\x94\ +$\xf7\x1fZ\x90\xd4B\xa3\xcb\x12\x0fk\xff\x005$\ +\xa9P\xa0\x00\x06\xc0\x0d\xa9W'\x9d\xbaiD\xa4\xfc\ +\xc5Z\x85\x1a\x90\xf76\xb5T\xe3\x99\x1b\x18\x12\ +./\xce\xd6\xfd\xa8\x93\xa5}T\xb8\x03z\xec\xca~\ +!K\xf8\x87j%\xbd\x0b\x13\xb9\x04\xec;nk\x9a\ +\x8a\xd4,9\xd4\x80G1\xbd\x060\xe6\xc0\xca\xed\x9b\ +:[\xce\xbb\x81\xad\xff\x00ja\xa8U\x0cY\x1a\xd9\ +dR\xa6\xf5\x12\x7f\xc3\xae5\x8d\xe4B\xc6E`\xca\ +-\x98X\xef\xde\xb4%[\x12\x1bMmX\x5c-\x12\ +>&`\x9dmsl\xc7MyV\xfc\x8b\x93\x10c\ +rX\x91tf\xdc\xf6\xa3\x87p_U\x9fCa\xa9\ +\xedCko\xb9\xab$\x03Ku\xa5i@Q\x90\x0a\ +ebt7R7S\xd4W\x05\xae\x22\xf5-I\xb6\ +\xedk~5\x1f\xa8\xe5C\xe2\xc4\x08P\xfe#\x1d\x95\ ++\x85\xd4\xdc\x13z% \x12B(b,X\x0dj\ +Ce/\x13\xa8\x8a@Y-\xc8\xfe\x95\x9a<\xad`\ +\xac\xec>\x1c\xa4\x0f\x995x\x12\x0d\xc6\xe2\xaaq\x04\ +d\x930'\xc3}F\xba\x03EQ\xc1\xb7\xbb\x06b\ +,H\x16\x00t\x02\xac\xf0\xd9\x15I\x85\x8e\x8e|\xbd\ +\x8dg\x83F\xadj%j\xc6\xb9\x1a\xd7\x0b\x83q\xca\ +\xab\xe1\xb1K\x22e\x93\xd6\x07\xab\xf1\x7fz1 ,\ +C\xe9m\x81\xad\xeb\x18\xa1\xc7\x11\x17\x1cLz\x19\x14\ +5\xba\x13V8,\xb7\x8d\xb0\xa7e\x05\x90\xfe\xb4\x9e\ +?(lLh-q\x18\xd7\x99\xbd\x17\x04\x04E4\ +\xa7se\x1dz\xd6?\xfak\xe2\xe3\x9a\x84\x01\x89B\ +M\x9fCBX^\xd7\xd7\xa5\x09n\x95\xa6A&&\ +1\x03\x86?|\x01Q\xa6\xe7\xad#\x86\xe1\x8c\x83\xc6\ +\x95\x88\x04\xd8-\xaeZ\x83\x8a\xa9\x13x\xc0\x8bJo\ +n\x95g\x0f/\x8d\x1a\xacJ\xd0\xaa\x8b3\xff\x00\x15\ +\x9fom|\x5cgU\xd6B\x16\xda\x05\x1a\x9f\xa5\x04\ +\x99\xe7P\xa6\xf1E\xbe\xbb\xb5\x02\x14\x8cZ!n\xad\ +\xf1\x1f\x9dq\x90\x03\xa97\xf6\xad\xeb#H\x9a1\xf7\ +\x13\x1e\xeb \xd0\xd1x\xae\x83\xfe\x22,\xa3\xf1\xa6\xd4\ +\xb5\x95v\xd4{\x8ab\xb8\xea\xba\xf2<\xeaFs\xd0\ +\xdc\x1d\x88\xe7R\x80\xad\xd0\x00\x5c\x1b\x12v_\x7f\xe2\ +\x94\x09Qh\xe6U^Kk\x95\xf64Hl\x81@\ +\xb2\x8b\x9bS\xa8\xdb\xc9\xcb\x10I\xfc,\xa3-\x03b\ +\x10>I\x94\xc4\xdd\xb5SBZ\xba@%\x89\xa3m\ +\xacH=-V\xa3\x1aED21\xba\x81}9\xd5\ +\x19\xe6\x97\x132\x85Q\xd1T\x1d\xaa\xd4f\xd8x\xd4\ +\x8f\xf9`\x10Ep\xc8\xa6\xe9\x1a!:\x5cQPb\ +\xc3(`\x1d\xf3\xb3hu\xda\xf5TH\xfe>C+\ +e$\xa9?\x95]\x8c\xfd\xea\xfb\x8a\xcc\x9c\xdaW\xff\ +\x00Q\xa2\xd3\x1d\xc3m\xf6\x93\x98\x5c\x05:u\xa5c\ +pF;\xe20\xacJ\x83|\xbc\xd6\xbb\x86\xb9\x18\xc5\ +_\xc42\x9f\xa5^\x85\xf2\xbd\xef\xd4\x1a\xcc\xee5U\ +\xa1\xe2\x90\xa2x8\xe9\x14\xc8y\xef\xcb\xe2\xa7`\xd3\ +&\x0e\xf9\x95\x83\xbd\xee\xa7Aa\xfd\xeb\x17\xfcI\xc3\ +\x8c\x0e1P\xa91\xc9|\xd67\xb1\xae\xe0\xd8\x99\xe1\ +\xe1\xb6\x8aB\xa1$\xb6R47\xd7Z\xcc\xe5e\xca\ +\xb3\xae\x9bn\xf6\xd1lhNk\xf9\xafz\xa0\x9cK\ +\x12\x18\x1f\x0e\x0f\xfb\x05\x13qLK\x10|8\x7f\xec\ +\x15\xaf\xd4\x18\xd3Cp\x0fZ+X\xd5|\x06&<\ +b\x15\x0b\xe1\xc8.r\x03pE4\xe7\xb5\x81\xd2\xb4\ +0sB\x93\x15.J\x95\xd2\xe0n(\xa2\x8d\xa2L\ +\xb1H\x1d\x7f\x03\x8b}\x0d\x04WS\xae\xa0\xfeT8\ +\xfc`\xc3\x1f\x0e4W\x92\xda\x96\xd4/j\x91\xe4\x82\ +\xac@*@\xf3)\xdc\x7fj5Fqp\x85\x87a\ +X\xd2q\x0cI\x95\x9f\xc4\xc8\xea\x97\x19t\x02\xda\xdb\ +\xfd\xf5\xa3\xc5bg2\x12\xd39\xb0\x07\xd5\xf3\xab\xf5\ +\x17\xe6\xb4q\xb8\x85\xc1\xc4Ky\xe4 \x80\xb7\xf4\xf2\ +\xd6\xb2\xf8r>'\x14\x91\x90<\xcd\xa9\xb5\x01\xbb\xef\ +}y_SZ\x9c\x1f\x0cp\xf0\x99\x9a\xf9\xdcYT\ +\xe9a\xd6\x8f\xf6\xa7\xc8\xb6\xe5s\x1c\xa2\xc3a\xedP\ +\x09\x0dplj\x06\xdb\x1f\xa5M\xbb7\xd2\xb6\xca\x8f\ +\x19\xc3\x02F*5\x16\xd9\xc0\x1e\x93\xd6\x83\x84\xe3\x15\ +A\x86fa\x1bzX\x8d\x14\xd6\x88;\x82\x0d\x98Y\ +\xae9VF;\x0c\xd8i\xb2\xda\xe8}'\xa8\xac\xde\ +\xae\xc6\xa7}5\x9dH\xb0\xb8 \xf3\x06\xe0\x8a\xebZ\ +\xb1\xf08\xa9\xb0\xc0\x04qnh\xfb\x1a\xbb\x17\x16\xc3\ +\xb8\x1e,EI:\xe5;U9A\x8bU#q\xdb\ +_\xf7\xfe\xf9P\xc5.\x1e`\x0cS)\xect4D\ +2\xee\x08'Z\xd0H6\xac\xfe8o\x8d_\xfe5\ +\xfd*\xfa\x02\xcc\x00\xdc\x9a\xcd\xe2\xb2,\xb8\xd3\x93P\ +\xa0(=mG/\x0c\xf5\x7f\x84\xa8^\x1c\x08\xbd\xdd\ +\xc9?/\xfc\xd3\xb1\x0b\x9e\x1cB\x87\xf4\xb6k[\x9f\ +J_\x0eB\x9c><\xc4\xf9\xae\xc0v\xd3\xf8\xa6\xb2\ +334L\x15\xddlA\xd8\xd6\xa7\x81\x9a\xa0X{\ +^\x8dEq\x8d\x94\x90E\x99|\xae\xbc\xd4\xd4\x81X\ +)\x14-r<\xba_\x99\xa2a\xa8S\xcfZ\x83P\ +-\x87\xbf\xd6\x81\xb5\xdf^\xc6\x98\xfb\xd4\x11ef\xcb\ +\x98\xa8\xbeQ\xce\xa3\x15x\xa6\x1c\xe2b\x13F\x01\x96\ +1f\x00\xea\xc3\x91\xab\x03\x12$h\x0b\xb1\x19r\x80\ +\xe0\xe9\xca\xd7\xe9\xd2\x83\x0d$\xf2D%\xcf\x0cw$\ +\x0f\xbb\xd6\xba|\x1e!\xf0L\xf0\xe4fk\xa9\xfa\xdf\ +J?\xec-\x19\x90\xac\x84\x11nc\xda\x82\xb3\xb8W\ +\x11\x950\x82,Jg\x11\xbeC}\xc0\xde\xb4\xe3\xc9\ +,bH[:\x1f\x91\x1e\xf4\xcb\xbe\x0b0\x04\x0a\x16\ +\x02\xd4\xc6h\xc7\xc4[\xba\xad\xc7\xd6\xa0\xa8\xb0 \x82\ +\x0e\xc7\xad@\xa2\x05\x08\xb51\x96\x84\x8bT\x90h]\ +\x16X\x8clm\xcc\x1e\x95\xcd\xa6\xa6\x87)'6\xa0\ +\xde\xf5\x15)P\xc7!F\xddM\xa8A\xe9W\xb1\x11\ +\x89\xd4\x5cY\xc6\xc7\xafj\xa2\xc0\xab\x15ab7\xac\ +Y\x8dJ\x90M>,I\xf4\xcb\xa8\xda\xe3qUo\ +]z4\xa7\x8f\xc8>\xd0\xb6\xd4xj\x01\x1b^\xd5\ +s\x87\x008T@\xf3f\xfd\xab3\x8a\xbb\xae\x1e,\ +J\x00B\xf9%\x16\xf5t\xbdh\xf0\xf9#n\x15\x1f\ +\x86I\x0a\xc7\x97Ze\xff\x00*>\x1a\xd6\xe5\xa1\xa8\ +\x0e\x08%\xae\x00\xde\x96\xcfn\xbfJ(\x88\xf2\x86\x1a\ +\xb4\x83\xf2\xb9\xfd\x85h%\xd5dp\xf3)'\xe1K\ +\xe8\xa3\xa5\x10`\x14(\x00\x01\xb0\x14\xbb\xeb]z\xba\ +C,m\xa5r0\xca)lm\xef\xca\xb8i\xa5Z\ +\x8e\x06\x89Z\x92\x0d\x12\xb5)eZ\x8c05]M\ +\x125L\x9f\x5c@$\xa6\xe0z\xf5\xff\x00\xeb\xfc\xd0\ +\x17*B\x8bgoH<\xbb\xd4\x82\x15\x02\x8fH\xff\ +\x00w\xa9\x08\x9b\x9b\xd4\x11\xde\x84=\xf6\xd6\xa0\xbd\xb7\ +#\xebR1H[\xb16\x0a\x09'\xa5c;\x8b\xeb\ +{\x9e\xd5\x7f\x1d.\x5c&PHi?!Yn\xc1\ +\x98\xef\xd0VyV\xb8\xc1\xe0d\xf0\xf1h\xcc5\x0c\ +4\xebZ9|\xe5\x17]mYN\x032\xdbB5\ +\xbdj\xc2VX\xf3\xa9\xf5\x8b6\xba\x8e\xbf\x90\xfc\xea\ +\xe2hdO\x1aB\xc5\xc0\x86\xd9\x00#\xd6:\x8a\xa7\ +/\x0c\xf00\xe5pe\xa5B\xd9\x9a\xfe\xa1\xa7J\xba\ +\xc71\xe9\xd2\xdc\xaa#,\xb2z\x8fcM\x92\x86;\ +\xa3\xa7\xad\x19}\xc5\xa8I\xb0\xbdox\xaeHV9\ +\xb9\xf9\x85\xff\x00Z\x5c\x98L\x14\xda\x98\x8cm\xf8\x90\ +\xfev\xac\xfe?\x87Y8Id\xc3\xe2\x04\xcb\xb87\ +\xb5la\xf1\x98LBf\x0f\xe0\xb70\xfb|\x8dR\ +\x9f\x86L\x83\xa7\xfe)\x9b\xc8u\x08\x83\x85F\xb1\xb0\x9d\ +\xdb3\xa9\xba\x0f\xad\x89\xf9U\xb6\x83\x0c\x14/\xd9\xe3\ +o(\xd5\xb5;Q/\x99H\xe6\xdeP}\xcd\xbf\x9a\ +\x97 \xb9#j\xdc\x923\xb4*\xb0+\x020\xd1)\ +\x1b\x10/M\xb9f$\x9b\x93K\x8f\xcc\xc4\x8e[S\ +)\x89\x1a\xe5\xa9\xb1\xae\x16\xe6k\x98\xd9I\xed\xa5)\ +\xd6\xa8:\xaeVP\xc3{\x11z\x9b-\xb6\xbfs\x5c\ +\xbb\x91\xc8T\x83h\xb6\xf0\x22?\xf4\xd4\x18\xb0\xcc|\ +\xf8HO\xfd4\xc0\xb6\xa8\x22\xf5bU\x93\x87\xe1\x1e\ +_\xba\xcd\x13[\xad\xc7\xf6\xa0d\xe28M\x98\xbcc\ +o\x89MZ7\x0d\x99E:76\x0c\xa4\x8b\xd1\x91\ +k*Lv%\x90\xa5\xd5/\xbeU\xb1\xaa\xca\x09k\ +\x0dI5\xb9,0K\xfed\x22\xfdWCA\x87\xc2\ +a\xe1\x93\xc4\x5c\xce\xc3`\xc0XQ\xf9\xa7N*\x11\ +U\x00\xb0U\x02\xdd+\x80\xa9\x00\x93s\xb9\xa3Qj\ +\xd8\x0c\xd8x\xe7\x00\xb1+\x22\x8b\x07Sb{\x1a\xa2\ +\xd1I\x1b\xb2L\xccYE\xc3m\x98u\xf7\xad 4\ +\xa9uW\xc8\x19C\x00\xd6\xb1\xe8\x7f\xf1U\xe3\xa2V\ +KXh\x05\xaa7\x15\xa3&\x16\x177\x19\x93\xdbQ\ +H\x93\x04\xc3\xd0\xe8}\xf4\xb5f\xf1\xa7T\x9cT)\ + \xdcU\x87\xc2\xce/x\xc9\x03\x98\xda\x97\xe1=\xfd\ +$w\x22\xb3\x94\xe9N\xa1sF\xa2\xc0y\xd7NG\ +\x7f\xce\xad\xe0\x98\xae\x0d,m\xe6o\xda\xaba\xe1\x97\ +\x13\x8a\x92e[F\xab\x91o\xa05qc\x11\xc2\xb1\ +\x83{^\xe7\xbd1Rx\x86\x14b\x90\x98\xc0YF\ +\xb6\x03G\xfe\xf5\x9d\x83\x90\xc3\x8b\x11\x9f\xf2\xd4^q\ +\xd7\xb5l\x00\xf9\x08\x8d\x82\xbf\x22k'\x1b\x1f\x87+\ +\x8c\x99K\xbec\xf4\x1f\xbd\xe8\xe5\xfdS\xf8\xd79\xd5\ +\x82\xa3\x10\xb6\xf2\xdbAjZ\x15q)Ke\x12y\ +l:\xd2p8\x94|\x11\x85\x9b,\x80dC\xd6\xfc\ +\xbfZ\xbb\xe1\xd9\x02F\xb9\x94m\x93Qz\xd4\xec*\ +\xc8r\xe9k\x93\xb5\x09N\xacj\xc1\x85\xefr\x8d~\ +\xcah\x1d\x0a\x9b\x10G\xb8\xa3\x11\x05\x05\xef\xb9\xeev\ +\xa8+M\x22\x81\x8e\xb4\x22\x8a\xd2\xe7\x84L\x08&\xce\ +=-\xd7\xb5<\xda\xd7\xa0a\xa5\xf9\xd4ef:\xb2\ +9V\xb8#{\xd0\x93W8\xa2f\x8cL7\x1eV\ +\xfd\xaa\x8b\x1b\x0a\xe7zn\x09TK\x14\xb0\x1d\x9d\x0f\ +\xc8\x8di_\xe1Y\xbe\xe9\xa1a\xe5g\xca;\x5cQ\ +\xc6\xc1#\x9aF\xf4\xa4d\x9e\xf5G\x81\xb6H\xd5\x94\ +\xf9\xbcqj\xcf\x96&\xe3\x1b\x1a\x82\xcc'\xc3\x007\ +rh\xa6S\xe3\xb2\x81\xf1\x1a\x01c/\x8a\x0f\x96!\ +\x95;\x9ef\xba23\xbfZ\x82u\xb0\xff\x00\xc5\x0d\ +\xeb\x97Fmw\xa9'\xda\xbb\x9dup\xde\xa4*\x90\ +j9T\xd3\x10\xd0\xd3\x03dB\xf6\xb9\x1a(\xeaN\ +\xd4\x90i\x80\xdaM\xae\x22\xd0wc\xfc\x0aRc\xfb\ +\xbb\x82\x09c\xbbnMH$\xea~@\xd0\x83z\x9a\ +\x90\x89\x07qR,\x06w\xb2\xa8\xde\x84\x15U.\xe6\ +\xca9\xd5<^ \xcc\xd6\x02\xc86\x14[\x83\x03\x89\ +\x93\xc6\x94\xb9\x03\xa0\x1d\x05!\x92\xcdu6\xa35\x04\ +\x8a\xc3e_\xcc\xb5g\x0d+\xc3,em\xacNM\ +\xc6\xf5]V\xee\x14jI\xb7\xbdLr\x07\xc4b\x82\ +j\x11\x15E\xba\x03D\xa9~<\x5c\x0f\xebVC\xdb\ +QOP\x1c^6W\x1d\x8dd\x0ab1\x06\xe0\xdb\ +\xda\xb59\x0cil\xda\xe9qaD\x06\x97\xa4a\xf1\ +\x80\x8c\xb3\xeb\xfd|\xfeud\xa8\xdcZ\xc4hF\x97\ +\xad\xb3\x5c\xb7\x07CcM\x129\xd4\xe5=\xca\x82i\ +,r\xdb\x98\xa9Wa\xa9\x1eSP\xc3s\xb1\x16&\ +\xc3\xa0\x16\x15\x22\x81[7\xa4|\xcd\x18\xbf6?A\ +Jt\x8f\x92H\x17\xf1=\xea\x09b\xd6\x1a\x8eu,\ +\xa0\xcb\x197%A5#z\x90\xb3\x05\xd0-\x16\xb7\ +\xd5\x8f\xca\x84m\x5c\x09\x02\xd7\x07\xde\x94\xe2\xa4\x9b\x96\ +\xa8(\xdb\x02*o\xad\x10\xd4\x8d\x0d\xc9\xe9Rr\xa8\ +U\xb5\x16\x8as;*)\x1b\xb1\xb5\x04\xf8\xa8 f\ +Me\x91wQ\xa0S\xd0\x9f\xda\xb3\xb1\x12\xc94\x85\ +\xdd\xd2\xe7\x90R@\xf9\xdcUn&\xceB@+f\ +\x07b\xa6\xf4\x8cw\x88\x90\x06\x8c\xb2\xeasZ\x83\x84\ +C|3\xb3\xb4\x85X\xf9G\xa7\xf4\xa7\xcb\x87q\x1b\ +\x08\xe5\xf2\x91\xaa\xb6\xa4S\xecJ\x8b\x8e!r\xcb\x15\ +\xcd\xbdk\xa7\xe5Vp\xe74!\x85\xf2\x9dErD\ +\x90\xc2-\xe6,u\xa6@\xb9p\xca\xa3\x935\xbd\xaf\ +T\xd4\xe1D\x05\xeb\x82\xd1(&\xf6\xd0mz\xd2H\ +[\x0b\xd4\x8e\xc0\x9e\xfbW\x05Q\xc8_\xa9\xd4\xd4\xee\ +ie\xda\xfe\x1f\xfe\xd5\xd7\xfb\xc4]\x8ebl{\x0f\ +\xefGk\x0d(^\xe6dQ\xba\xdc\xb5\xb9\x02*H\ +\xa8\x22\x8f'\xf5\x1f\xca\xa0\xa1\xe4~\xa2\xa4\x00\x0d\xe9\ +8\xecIE1+\x12\xe7C\xae\xd5en\x1bm}\ +\xeb9\x22\x95f\x0e\xf0;\x00nGZ\xcd\xff\x00\x86\ +\x1f\x02\xb2\xe1T5\xeeM\xcd\xeb\x88\xa3\x12\xac\xade\ +\xb8na\x86\xd5\x05:\xde\xa2V\xec@\xb0\xb6\xe6\x93\ +\x89\xc2\xfd\xa4\x12\x08\xf1SMF\x8e:\x1a\xb4\x16\xc2\ +\xc0\x0a\x122\xb6a}N\xb4bbH\x0a\xb5\x8d\xee\ +\xa7@\x16\xc0\x1bZ\xfdMD^=\xad\x11}9)\ +5\xbeX\x93r\x17\xe6\xa2\xa4;\x0fM\x97\xb8\x00~\ +\x95\x9f\xc1\xd6\x03<\xe0\x0c\xcf(\xbf\x22H\xa6a\xf1\ +\xf3\xc5\xe5s\xe2%\xad\x95\x8dk\xc8$-{\x86\x1d\ +\x1e\xc6\xdfZ\xcc\xe2\xf0*\x05\x964 1\xb3\x0e\x86\ +\xb3e\x9d\xc3.\xae\x12\xaf\x1a\xc8\x9e\x97\x17\x1d\xbbP\ +0\xa4\xf0\x96'\x0d$\x7f\x81\x81\x1e\xd4\xf76\x17\xa7\ +\xde\xd9\xa4\xbe\x8e\xbf3B\xe6\xf4\xc6\x16\xd4\xeeiF\ +\xa3\x09\xc7\xe9\x82=\xd8Vs\x5c\xe85&\xaeqw\ +\xb1HG\xc2.\xde\xe6\xa9b\xa7L\x14\x1e+\x1b\xca\ +\xeb\xf7Km\xbb\xd7>W\xb6\xa2\xaf\x1d\x9b\xc2\x85p\ +h\xd7k\xdeP\x0e\xe7\x90\xa3\xc3Db\x96\x08\x94]\ +\xa3!\x9d\xbb\x92\x0dg`\x95\xe7\xc6x\xb2\x02\xe1N\ +v\xef[\x5c1\x95\xf1\xf9\xdfQ\x18-o\xc4\xfc\xcf\ +\xcbj\xe7;\xbaj\xd3\xc8q9\xb2\x02\x88\xc6\xee\xe7\ +\x7faR\xcc,\x15E\x94\x0b\x01\xd2\x82\xe5\x9c\xb9\xe7\ +\xb5A5\xd7F\x08\xb5\x85\xcdp:w&\x80\xea@\ +<\xb55 \xd5\xab\x0c\x06\xa6\xf4\xbb\xd4\x83V\xac0\ +\x1a\x9b\xd0\x03\x5c\xc7\xc8mH66\xf3\x02>\xa6\xa3\ +\x0eO\x84bcw\x8d\x89:\xef~t1\x9c\xc4[\ +\x9dJ\x10Y\xa6\xe6\xf6\x0b\xfe\x91\xce\xa4`4Y\x95\ +\x10\xbc\x86\xca?:\x05\xb6\xb76\x00\x5c\x9e\x95K\x19\ +?\x8b-\x97\xd0\xbe\x9am\xc4|\xad\xe19\xf26\xdd\ +\x8dU\xd3\x99\x14.\x5c71\xd2\xad\xc5[\x0e2\xdc\ +0\xfa\xd1\x0bZ\xd5S\x09)\x9a\x1b1\xf3\xa0\xb6\xa7\ +qV\x86\x80\x03]\x18\xb0C\xb5M\xc2\xa9c\xb2\x8b\ +\xd4\x0aV9\x98a\xec\xa2\xe1\x8f\x98\xda\xa0l\x0d\x9e\ +\x1f\x14\xee\xe4\xdf\xb5\xb6\x14B\xa8\xe1\xa7\x96/*\xea\ +\xa7\xe1;V\x83\x03`v\xd3P)\x9d\x9a\xe0ju\ +\xa07\xb5\xaf\xad\x12\x85\x03\xaf\xb9\xa4\x08\x0b\xd3\x10\x12\ +\xac\x01\xb3[\xcao\xce\x81OsDF\x9b\x9f\xad1\ +1\xf1\x0a\xd0I\xe1\xce\xad\xab\x12\xb2\x01\xa1\xbe\xb6=\ +\x0d]\xc0`\x1d\x8a\xc9\x88\x5c\x89\xbd\xb9\xb5\x5c\x8f\xcc\ +\xb9\x5c\x93\xd6\xfa\xdb\xda\x8a\x16$4n\xc1\x9a3k\ +\xf5\x1c\xa8\x9ca\xd1F\xd7\x94 \x00(\x16\x00r\xa7\ +\x0d(\x10[[kF+q\x9a\x15H\xd5\x8b\x91`\ +5=\xab\x91m\x1a\x8bX\xda\xf6\xe9}i\x8c\xb7\x0a\ +\xa7bu\xee\x00\xbf\xebj\xe6\x1a\x9du\xa4\x16\xe3\xc8\ +z\xda\xa4\x0b\x00:W8\xf2\xdb\xae\x82\x8c\x81z\x92\ +\x02\xde\x88\x0bT\xd7T\x9c\xc4*\x96;(\xb9\xa8A\ +e\xd7\xd4uc\xd4\xd4M\xfeK\xdc\x5ce5&\xe0\ +\xdb\xa6\xf5$\xd4\x13j\x16\xbd\xea\x00&\xa4\xe3\xbdq\ +-\xc8\xfeu9M.P\xd2DR;\x00ws\xb7\ +\xb0\xebRU\xe2R\xa32\x847e\xdd\x87\xe9D\x98\ +\xd4\xca\x03\xa3\x16\xe7nt\xa90S/\xa4\x07\x03\xf0\ +\xd4p\xf4\x07\x17\xe6\xf8A65\xcfn\x95\xb5gq\ +u\x80\x01\xcb;\xd8\x9a\x0c\xe9\x98\xa4\x9fv\xdf\x85\xb9\ +\xd3\x8e\xa6\xe6\xb9\x80kfEkmq\xb5i\x00E\ +\xa6\x9f\x91\xa9)ng\xf2\xa9x\xe3e9\xa3]\xb7\ +\x02\xc4P\xc4\xd9\xe0F\xce=>k\x9aR\x0a\xeb\xea\ +4\xb9!W\x86D7b\xcaH\xbfZj\xb25\xc2\ +H\xacWp*P\x0c\xe3\xbe\x94\x16?\x0a9qL\ +\xa6\xded#^\xb5f\xe0\xc9\xa6\xc2\xa8\xc8L8\x9b\ +\x8b\x82\x8fqz\xbe\xb9Xg\x8c\xddH\xbd\xeb\x9c4\ +\x12R\x98\x84F\x91\xfd+\xaf\xbfjs\x8b\xd6o\x13\ +\x9c;xi\xe8S\xf5\xefE\xb9\x14!O\x8d\x8c\xcc\ +\xfa\xdc\x96>\xc3Z\xc1\xe2\x18\x891x\xb2\xe7[\x9b\ +(\xe89\x0a\xdb\xc3\xb0\x13\x1c\xc6\xc0\xa9\x1f\x95R\x8b\ +\x87M\x83f\xc4L\x97\x0am\x19\xe4OZ\xe3\xca[\ +\x1b\x82\xc2\xa1\xc3D\xaa\x06\xb1\x83$\x96\xeb\xc8U\xbe\ +\x10\xa0I>\x97)\x18[\xdf\xbe\xbf\x9dT\x04)\x8a\ +6\xf5Js\xb0\xe7\x94m\xf9\xd5\xae\x18$-:D\ +\xe3\xc4\xca\x0b\xb7%7\xda\x9e>\xaa\xb2\xc0\x8fP#\ +\xde\x84\xef@\x1ah\x0d\xb1\x0d\x9e6:8\xd6\xd4c\ +#\x1f,\xa8I\xd8f\xad\x00\x8b\x8b\xe9{\x9a\x91\xf4\ +\xa2de\x17*m\xd6\xa3B*(k\x01R\xa7\xad\ +D\xa6(UZ\x5c\xdem\x94oE\x04\xb1\xcfq\x1e\ +`G#\xce\xa0\x91n\xf5\xc4\x1256\xedS\xb5H\ +\xda\xb4\x10T\x88\x88]Y\xfc\x8b\xeei\xaen\xe6\xdb\ +\x00\x05@\x03\xc6N\xaa\x85\x80\xbf;\xefC#\xacQ\ +\xf8\x8d\xafA\xd6\xa4_\x10\x97\x22x*um[\xf8\ +\xaa`\x9a\xe7fw.\xc6\xe4\x9b\x93R9VkC\ +\x02\xa7\x95\x08:Q\x0d\xeb)\x04P\xb0`\xd7\xb5\xc0\ +\xa6\xd8t\xa8u\xb8\x22\xfb\xd3\x88\xef\x05\xf9!=\xc6\ +\xb5$\xac\x0c\x1aV\xb3\x0fJ\x0d\xc9\xac\xd7\x5cL\x1e\ +KH\x8c\xdb\x00w\xab\x98\x18N\x1d\xe7\ +\x95rjZ\xdf*\xeb\xf5\xe7\xbdM\xeaNQ\x94\x00\ +E\x8f^\xb5\x22\xba\xbb.\x9b\x9f\xad!1\xb9IC\ +\x8d\xc7:\xd2\x84\x89\x22\xce\x9a\x8b\xed\xccVQ66\ +:S \x91\xd1\xcbF\xc4Z\x99U\x8dKT\xa1\x00\ +\x12\xc7\xcbk\x9b\xf3\x15Iq\x92\x81b\x15\xbd\xc5A\ +\xc4\xcb#X\x90\x01\xd0\xe5\x00V\xb5\x9cX\xc2a\x85\ +\xbcV\x0drn\xa8>\x1e\x97\xa7\x15\xb1%\x9e\xc7\x9d\ +\xda\xb3VydFW\x91\x89\x89\xb2\x93\xd7\xa5@\xd7\ +[\xd1,X\xd4\x02\xfa\x06S\xff\x00P\xae`A\xda\ +\xb3\x056\x09\xe4\x8d\xb47\x1f\x84\xedO\xe9b\xfa\xd3\ +\x06\xd4\xb8\xd8:\x07]\x9b\xf2\xa6.\xd5\xa0 \x01\xde\ +\xa0i\xc4\xd4.\xc61q\xf2\xa2]\xaa \xb1\xe23\ +_p,\xbe\xd5\xa4\xb1\xa0RI\xb0\x1b\x93G\x1d\x9a\ +\xc5Ha\xd4\x1aN%Ka\xca\xdfB\xcb\x7f\xadH\ +\xc3\xc6\x8fe,\x17\x9a\xdfF\xa5\x91\xe6.\xf7C\xa6\ +\xc0\xf6\xbe\xff\x00\xef\xb5\x1eE\xb6\xda\xf5\xe7]\x1f\xa6\ +\xf6\xde\x8a\x94\x05\x8dCf\xd4\x9e\xf4Cz\x164J\ +t\xd6\xa4\x9a\xea\xeb\x8a\x1c\xc2\x94\xe9T\xb2\x15\x07^\ +U\xc0\xb1\x17h\xf5\xff\x00X\xa1,z\xd4f\xd6\x84\ +\x98\x9d\x1e\xfb\x02\x0e\xa0\x9d\xa8\xb3\x0byl\xdd\xf6\x1f\ +_\xe2\x80\xb2\x8f1\x03\xdf-\xeb\xb3\x12n\xdf.\xd5\ +!\x9b\x11\xad\xdf\xb5\xac\xbf\xef\xde\xf4.\xe6\xfe`-\ +\xd6\xf5\xd7\xbd\x0by\xc6P}\xcfJ\x92o\xad\x03\xa8\ +\xfbDrX\x5c\xddO}(\xc0\x00Xr\xa8'\xfe\ +*4\xe8\xa4\x9a\xaau\xaa@\xa3\xcbP\xc2\xc6\xa4\x5c\ +\xc8\xcd\x19U`\xb9\xb4$\xf4\xa4\xc7\x87\x857\x5c\xe7\ +\xabmV\x0d\x09\xd2\x8b\x09^\x16IC\xc4\xaa\x0d\xac\ +\xcb{\x5cQ3\x0c\xc0\x15t'k\xda\xc7\xe6*I\ +\xa8`\x0a\x95aph*|O\x04fc4c\xcd\ +o2\xdbSY*\xf3\xe1\xa5%KF\xdb\x11\xd2\xb7\ +F`\xc6'`@\x17Cm\xfbRx\x94i6\x19\ +\xdd\x96\xef\x18\xba\xd8z\x8fJ\xc7.;\xdc2\xa8\xcb\ +\x8eW\x87\xc1\xb8I\xd8\x02u\xdc\x7f5\x9d8*l\ +E\x88\xe5Y\xf8\xa9\x1d\xe5i\x09\xb3_\x97*\xbd\x04\ +\x87\x11\x82Y\x08\xf3)\xc8\xdd\xfaW\x1f\xd7\xe9\xbc\xc1\ +a 2\xbd\xce\x8a75|\xb9\x06\xc0\x0c\xbbe#\ +J\xe5\x8cC\x08\x8co\xbbw4'z\xdec,\xdf\ +\xf1\x07\x0e\xcf:\xe2\xa2\x94E\x1eP\xa7\xa8\xf6\xa6p\ +\x22\x829\xa1\x8c\x10\xa1os\xbb\x1b\xefW'\x8f\xc6\ +\xc2\xcb\x0d\xaeJ\xdd}\xc5e\xf0yD8\xd0\x1bi\ +\x01C\xafZ\xc5\x92r\xd3\xf1\xa2H\xcaT\x8b\xa9\xd0\ +\x8aP\x83\x0a?\xe4\x9f\xfb\xcd6E*\xc5H\xb5B\ +\x0b\xb0\x1dkU\x17\x88\xfb\x98\x0c\xb0\xb3&R\x01R\ +\xd7\x06\x811\x98r.\xca\xeaz\x0dA\xa1\xc5\xbb\xcf\ +)\xc3\xc2\x9a)\xd7\xa94qa\x22D\xfb\xe0]\x8f\ + l\x05\x1d\xefIY\xd9\xf1x\xbf(\xb6m\x85\xf6\ +\x14\xd9`l2\x89\x92K\xd8\xd8\xe9j`\xc3Eq\ +\xe13\xc6\xc0\xe8w\xae\xc7D\xde_\x1b\x13~\x8b`\ +\x09\xa3>\xa3\xa1\x94M\x00\x93.S{\x1a\x9b\xda\xa8\ +\xe08\xa6\x0f3aV\x1767R\xc6\xc4\x9ab\xf1\ +4\xccsa\x11\x11}D\xb1\xbd3\x94\xfe\xacZ\x9a\ +\xcb\x873\x92W\xc2 \x83\xfbULd\xad$\xd7a\ +k\x01\xa7J\xa9\x8d\xe3M\x89O\x0f\x09\x04j\x11\xae\ +\xaa\xe7\xd5\xdf^t/\xc5\x1d\x90\xc9\x16\x1a\x1c\xc3\xd6\ +\x18j\xa7\xb8\xac\xdep\xc9V*A\xe5I\xc0q\x11\ +\x89\xc4$2\xe1\xa3\x05\xcd\x8b.\x96\xf9S\xf2\x9f\x10\ +\xa2\x82M\xed\xa52\xcb\xe2\x12\xd1\xa8\xa7\xc1\x83\x00\x03\ +3[\xfaV\xadE\x1e\x1dv\x88\x1f\xf5\x1b\xd38\x8d\ +Q\x14h\x8c\xc2\xe0m\xb9\xab\x86\x08\x1e\xf6L\xa6\xc4\ +\xe8t\xdb\xa5gb\xa2\xc5b/\xe16t\x1b\x22\xe9\ +o\x956b\xd5\xec<\xb1J\xf3\x0c\xa1K\x1b\xc7\xdb\ +\xda\xa8\xc6\xcd\x98\xa9\xdc\x1a\xb3\xe2i\x1e\x1c\xc5\x95\xa2\ +m\x5c\x0eU]G\x9d\x18\x1b\xe6K\x93\xd6\x8a\xa0\xc5\ +\x10\xa8Z\x9a\x88\xb4\xb5\xedR7\xb6\x95\x0ahY\x19\ +\xd8\xb0\xd8\x9d)de\x14\x9b\x9b\xd7\x01\xc8\x0a\x88\x83\ +\xa9\xf3\x03o\xd2\x8cj47\xa5\x04\xae\xc3\xa9\xa2\x16\ +E\xcfm\x07\xa4u=\x05C\x0b.{\x85\x09\xa9'\ +\xa5p`\xe0J\xc4\xa9\x22\xc8\xbf\x84u\xf75'\x22\ +\xf8Q\xe5$f&\xec{\xd7f<\x87\xd6\xacC\x84\ +wP\xc6\xc8\xa7\x9bni\xc9\x84\x81F\xa5\x98\xfd)\ +\xca\xb5H\x13\xf8O\xca\xb9X\xb3\x10E\xb4\xab\xb2a\ +R\xc4\xc6\xc4\x11\xc8\xd5-L\x9a\x822\xe8oV%\ +\xae\x1f)V1\x9d\x9boz\xbd\x01\xba\xebX\xf9\xd8\ +?\x90lw\xad\xa5\xb1\x01\x80\xd0\x80E\xab\x5cE1\ +\x05\xcd\xaa\xb9\x97.=\xa6\xb1+\x9a\xd7\xb7*\xb5\x0f\ +\xa8w\xa1\x89\x8a\xc0\x97PW(\xfe\xf5\xb01\x22;\ +\xaa#\x06\xbf\x98\xf6\x03_\xd6\x8ck\xf3\xaa9\xbe\xcf\ +\x8b\xce\x05\xc1\x1b{\xd5\xd6`\xa0\x1e\xa0\x10)\x94%\ +Z\xea=\xa8\xaem\xbd-v\xb7M(\x81\xa4&\x88\ +\x11j\x1b\xd0\x96\xb5HLE\x094,\xff\x00*\x0c\ +\xe3k\x8f\xad\x1ap\xcb\xf7\xae,\x05)\x9a\xc3Z\x12\ +\xe4\xec>\xb4i\xc1\xca\xcdu\x03\xad\xeaskK]\ +\xfa\x93\xce\x88T\x86O\x97\xb5\xf54\xd4\x17\x00.\xdc\ +\xadB\x8aXX\x0b\xde\x80,\xda\xc5\x19\xd7b\xdf\x86\ +\x90\x99\xa7\x0a\x08\x89s\x11\xbbr\x14X$`\x8d,\ +\x9e\xb9?J\x88\xb0\x8c\x8b\xe6\x908\xbd\xec\x05\x81\xf7\ +\xa6\xc6|\xbb\x9b\x8ad\xbb\xda\x15\x03\xef\xbe\xd4gj\ +\x5c\x84\x09<\xc7K\x5cU@I\xb8\xb8\x04\xd03]\ +\x8a\xda\xdf:\xe9e\xb9\xb2}k\x88\x0a,>f\x83\ +\x11A#\x85[\xd4\xbbYI\xe9U\xee\xce\xf75\x9b\ +I\x81n\xa4\x1dX\x8b\xdf\xa1\xaax\xec@f@\x9b\ +/\xab\xdf\x9d[S\xf7\x83\xde\xb2\xb1\x0d|d\xebq\ +\x96\xf9\x94t\xbe\xf5\x9eW\xa3\x18\xdcj\x1f\x07\x18\xf6\ +[#\x1b\xafqE\xfe\x1c\x90\x0e!\xe1\xc8~\xed\x81\ +,:[\x9d^\xc5\xc2\xb8\xb8|\x22@u\xf4\x13\xfa\ +VV\x0dZ\x0e a\x95J\xb3\x02\xba\xf2\xbdp\xb3\ +9k\x7f\x1e\x8a`D\x876\xf4\xa3\xbdU\xc1\xe3\x8a\ +\x0f\x03\x11r\xb7\xd1\x8e\xebW\x19H \x8dA\xd8\x8e\ +u\xd3u\x90\x83\x95\x83\x0eU\x9d\xc5\xb0l\x926\x22\ +\x11x\x98\xdfO\x84\xd6\x8b)\x1a\x10Er\x12\xbbs\ +\xde\xfc\xe8\xb3T\xac\xfc\x169r\x88\xb17*6~\ +b\xad#\xc0\xd6)\x89\x8c\xdf]M\x88\xa8\xc4a0\ +\xb3\xfa\x94\xc4\xddPh~UVN\x16o\xf7X\x88\ +\xdb\xb3yh\xff\x00(W\xd7\xcc\x09Y\xa2\xb76\x0c\ +)\x12b\xb0HNi\xcb\x11\xc9S\x7f\x9dQ~\x1d\ +\x8bR\x09\x8b2\xdfR\xa6\xf5W\x1cx\x96\x1f\x10P\ +a~\xef\xe1\x1e\x1d\xc5\xa8\xbc\xac\xf8\xa4]\xc4qW\ +#&\x1a1\x10#V\xdd\xbe\xb5Q\xdd\x84\xb9\x14\xe7\ +\xc4\xb0\xccK\x1d\x10u4\x98\xb1,Ii\xf0\x91\x8c\ +\xbb\xe5&\xff\x00AT1\xd5\xd8\x13\x93\ +\x04\xad\xacb\xec\xcd\xd6\xdc\xa92\x9c\xc5p\xe8Ag\ + \xc9m@\x14\xeb\xac\x85\x93eq\x94v\x1c\xa9J\ +\x98\xb9\xd2F\x00*\xbe]\xd9\x86\xff\x00*Yfs\ +v7\xa5\xa0\x14\xc1XhB\xa4P\xd7|'\xda\xa4\ +3\xf8y\x9eB\x8f\x9d\x00\xd0\xd8h(\x97j`\xa2\ +\xe7PE\xcfz\xea\x95>`\x06\xa7\x90\x1b\xd2\x02\xaa\ +\xb2\xe2\x0c$\xb3\xacv9\x07\xc4\xd5\xa1\x87\xc3\xa4\x07\ +\xc5\x94\x03!\xe5\xc9j\xbc\x90}\x90}\xa8\x00%c\ +b\x06\xb9h\xf0\xb3O\x89>u@\xa3\x98\x16\xb53\ +\xaa\xaa\xcbH\xa4\xdc\xb1\xd7\x99\x15\xc4\x81\xb9\x1fZQ\ +Vg\x0aM\xc0\xfc\xaa|!\x9a\xf7\xb0\xe9K&\xd5\ +|r\x82L\x80\x00m\xafzp\x04h\x18\xfc\xeaU\ +A>}o\xa1\x1d\xaaL\xf1z\xd2\xe1m\x9b\x0c\xc2\ +\xf7(t\xf6\xac\xe90\xec\x98\x96A|\xbc\xb5\xb5\xe9\ +\xd8\x1c\xd0\xe2u\x07+\x0b\x1a\xb8\xf5Z\xadP\xc5A\ +=\x05\xc5\x14c-\xd0\xdb\xf1\x0f\xdc}\x7fZP\x0f\ +|\xadk_SE$\x81\x02;\x1b\x0c\xc5I\xecE\ +td\xae'\x1d\xd26Ro\xaa\xfc\xea\xc3\x00\xa7(\ +\xdc\x00\x09\xf9P\x0c\xb3H\x1a\xf7\x8e=\x8f&4N\ +u&\xa4\x90m\x5c\x1a\x80\x1a\xea\x92X\x96\xbd\xc9\x02\ +\xfbP\xb5\xed\xebo\xad@>Q\xdcW\x1a\x90lO\ +\xa8\xde\xd5$\x0e\x82\xba\xf5\x0chH \x03\xa5u\xea\ +*T\x5c\xda\x84%7\x15\x18\xccJ\xe1\x80E\x01\xe5\ +\x22\xf6; \xeak\x95\xd4\x11\x93\xef\x09<\x81\xb0\xf9\ +\xd6\x5c\xce\xcf3\xb3\x1b\xb31,z\x9a\xad\xc8\xa2\xcb\ +b\xf12\x8b>%\xb2\xfe\x18\xd7-\xe8\xb0\xb8\x89b\ +#\xc3b\x007\xb7Z\xab\x1dY\xc1Fe\x9dcQ\ +\xab\x1bQ\xde\x9a\xdd'\xee\xc3\x81\xba\x83j\x15M/\ +}N\xa6\x9c@\xd8l\x05\x85\x01\x16:m\xd2\xbb\xb0\ +[\xf9T\x9bl/Kh\xc1\xf5jz\xd3$\x04\xe8\ +N\x9d\x05A\xd3Z*!\xa2PAQ\xa8\xeb@\xf9\ +\xb7\x16\x14\xe6\xa5=f\x98S\x82}v\xf6\x14\x04\xd3\ +\x1c\xd2\x98\xd6iFb\x1a\xfd+7\x8a/\x83/\x8e\ +o\xb8Ry2\x9a\xd0\xaa\xdcMZT\x11x%\xd2\ +\xd7$u\xac_\x0cP\x93F mC<)\x8c\x8c\ +$\xa1\x83)\xf2\xc8\xa3Q\xefD\xe2d\x16C\x13\x90\ +,3\x8b\x11U'N\x22\xe4\xdcHG\xf4\x9f\xe2\xb9\ +\xd6\x88\xc4\x1cF\x1d\x8a\xe2b\xf1Ph$\x1b\xfdi\ +\xf8>'\x04p\x18\xb3\xba\x03\xb1a|\xbf:\x94\xc1\ +\xe2\xda/\xbe%T\xf2`I4\xb1\xc3\xb0\xef\x7f\x0a\ +D'\x98\x91\x8a[\xf5\xac\xf7<=5\xb0\xc6)0\ +\xaa\xd1\xe2RK^\xe6\xfa\xd7\x1c\x9c\xe4O\xfb\xab\xcf\ +bp\xf8\x9c\x0c\x99\xd6\xe8/\xa3+\xdc\x1f\xca\x8a>\ +-6\xd8\x80\xb3/2V\xcd\xf5\xa7\xf7>\x8cn\xbf\ +\x87k\xf8\xd1\xe9\xfdT\x99$\x85uiG\xfd:\xd5\ +($\xc3b\x85\xb0\xf2\x15{_\xc3}?:\x19\x94\ +\xa9\xb3\x0b\x11M\xe5\xd2\xc5\xa6\xc5\xc2\x86\xe8\xae\xc7\xbe\ +\x82\x82n!$\xa9\xe1\x95\xca\x84X\x8c\xc4\xfe\xb5P\ +\xd4V?T\x86L4\xa4\xfd\xd6:\xea\x0e\xceJ\xda\ +\x974\x18\xd4\x5c\xca\xe92\x0d\xf6 \x8e\xf7\xa7W+\ +\x14`T\xd8\xd1\x90\xeb5\x22\x84\xc8d\xc3\x01\x0c\x84\ +\x1c\xd1\x1fD\x9e\xdd\x0dV\xc4\xc7\x97\x12cA\xec\x08\ +\xd6\xb6q\x18\x13\x8b\x9d\x1a\x01\x95\x9fW\xe8+Qp\ +\xf8h\xe1\x10\x01\xaa\x8b\x09@\xd5M\x13\x86\xady\xdc\ +&\x0f\xc3\x0b.$X\x9dU9\x9fz\xbe\xb3\xc4\x8c\ +\xa9;dY\xd0Y\xc0\xd8\x82w\xfa\xd0c\xf0\xd2\xe1\ +\xe6\xb4\x870mC\xfe*V+\x0e\xf8\x98bX\x99\ +<\x80\xdf3X\xd1\xe7\x8b\xd6\xa6\x0b\x08\xe6p\xe5\xbc\ +\x8bf\x0c\xba\xde\xaef\x0f;*\x87v\xbf\x9b(\x00\ +/\xcc\xd6?\x0a3Y\xf4\x01\x01\x1c\x86\x99\xab\ +\x11\xa3J\x84\x17\x91\x85\xb9e \x93\xec+\xacJ\x12\ +0\xb3\xda\xdb\xdcT\x09[\x93(\xee\x00\x15\xd7\xb9\xb9\ +7\xfc\xe9\x06\xd9\xef\xe5\x855\xe4\xf2X\xd4H\xd9\x06\ +f\xc3N\x07[\x83@\xb7\xb0\x06\xa5K\x03qqJ\ +\xc0}\xa8\xb7\x97\x0d\x03\xbbuaz\xbf\xc3\x9a5\x16\ +\x95DS0\xbd\x8e\xdf\xf9\xa8\xe1\xea\xce\xc5\xdf\xd2\xbc\ +\x86\x975fx\xa3\x9cZT\xb9\xea45\xa9/\xa2\ +\xd0\xca\xab\x88!3^4\xd5\xcf\xe2=\x05\x1a\xe82\ +\x8d\x14l\x06\xc2\xb8!H\xc2 \xb2\x8d\xaf]f:\ +\x11a\xce\x96Q\x1f\xa3\xe7D\x05H\x15\xd6\xa98T\ +\xaa\xdc\xf4\x00\x5c\x9e\x82\x88!\x22\xf6\xd3\xa9\xaa\xdcG\ +\x12\x91Da\x8d\x83;\x8b1\x07\xd2)\xeaz\x99\x7f\ +\xe29\xde\x5cDo\x1b\x11\x1b\x0c\xaa:Z\x91\xc3\xb1\ +r\xe1\xa5\xf5\x96F\xf5\x03\xaf:,Y\xcf\x85\x0dc\ +\xf7l\x0f\xd7J\xaa\xbe\xabt\xae6\xf7\xad\xe3\xd9B\ +\xe2X\x04\x8b\xb7\xed\xca\xa2d\x12\xc2c&\xda\x82\x0d\ +f\x7f\x87\xb16\xc2\x80\x7f\xe5\xb1V\x17\xe4y\xd6\xa9\ +\xecn\x0e\xc6\xbd\x12\xeca+e\x01WE]\xab\x98\ +\xde\xa2\xba\x94\xea\xe1\xb8\xae\xae\xa9\x05=\x03\xda\xa1\x88\ +\x02\xa2C\x96\xe7\x91\xde\x96\x5cocn\xb4j\x135\ +\xea/C{\xed\xadp\xa1\x08\x7fs@\x5c\xca\xb9\x22\ +F*M\x99\xf9Z\x8bB\xac\xa4\x8f0\x22\x81\xa6\x8e\ +\x1c\x22\xc8\xdb\x81`\xbd\xeaI\xc7bW\x0d\x0eU>\ +r,\x8b\xd0u\xac\xe4k\xebI\x9eW\x9ac#\x9b\ +\x93MH\xe4E\x0c\xc8\xc0u\x22\xb1\xfa\xda\xd6a\xa9\ +\xbdnp|?\x81\x17\x88\xe3\xef\x1fn\xc2\xb0\xe1\xb6\ +q}\xaf\xadzS\xea\x1d,-\xf4\xae\x9c'l\xf2\ +0\x1d*\x0dJT\x91]Y)\xc5\x03\xfai\xac)\ +l9QQGz\x5c\x83\xa9\x03\xdc\x8a)\xdf\xc2\x89\ +\xa4<\xb6\xf7\xac\xa4\xbc\xd8\x91\x9c\x17\xccu\xb5c\x95\ +1y\xd7K\xddm\xfe\xa1I%N\xc77\xfa\x05\xff\ +\x00=\xa8\xcaF\x86\xe9\x1a-\xb9\xda\x85\x89;\x92h\ + !\xef\xea\x11\x8e\xdef\xfe(H\xb17y\x1b\xdc\ +\x81\xfbQ1\xa0cY\xa8\xb3\x06\x1b5\xfc\x22O;\ +\xb5B\xbcq\xe9\x1a\xe4\xf6\x1a\xd4\xb1\xa0&\x82#;\ +o\xe2=\xfd\xcd\x04\x92\x17[\x00\xbe\xf9\x05N\x9d?\ +*\x06\x00\xf2\xb7\xb5E\xca\xea\x17!\x8a6^a\x96\ +\xa9q\x0c\x0c\x0e\x9e&\x1f\x07\x11\xfcH\x14\xdcw\xab\ +z\xdb\xad@$\x1b\x8b\x82:Qd\xa9\x84\xcb\x00$\ +\x1c2\x0e\xb6\xb8\x22\xb4p\x03\x0f\x89\x83+\x02d]\ +\x02\x97\xd6\xdfJ\xb3\x89\x86\x1c@\x1e4va\xf1-\ +\x81\xaar\xf0\xdb11b\x00<\x83\x0b~u\xcf\xf3\ +eka\xcd\x86\xc3)\xb3@\xe0\x8e\xaeiX\x98p\ +\x91.b\x18_a{\xd4\x88\xf8\xbcc,r\x19\x07\ +\xf4\xb0kP\xcb>5|\x98\x8c\x1e}9-\xbfJ\ +z\xfe\x01a\xa3\xc2K\x19a\x1b\x12\xbb\xdd\xadN\x8d\ +c\x12\x00\xb0\xc6\xba\xda\xe0kUc\xe2\x10D26\ +\x19\x96\xfe\xa0\x0d\xa8\xcf\x11\xc1^\xf9'\xfa\x8a\xb6!\ +\xc4\xa03\xceE\x99\xd8\x81\xfd iR\x8a\xcc\xc0\x0d\ +I\xa0\x18\xec&c\xe4\x93+\xea\xb7al\xdd;^\ +\xaab\xf8\x94\x85Z(\xa2\x10\x83\xa1\xebF\xc8\x85\xc6\ +\xa6\x8d\x82@\x871\x8c\x9c\xcd\xcb\xda\xa9(\xa1\x07Z\ +5:W=\xde\xda\xc4\x93j\xe4b\xae\x19M\x88\xd8\ +\xd7\x1a\x8euD\xdd\xc3M\xf6\x9c\x1aLO\x9cy_\ +\xdf\xad\x1a\x9a\xce\xe0\xb8\x85\x8eF\x86V\xb4r\x0d\xfa\ +\x1eF\xb4\x8a\x95k\x1a\xed\xc6\xecf\xa5\x9f\xc3\x85\xe5\ +\xe6\xa3Oz\xce\x04\x93s\xa95w\x19\xff\x00\xed\xf2\ +\x7f\xa9k?R\xb6\x1b\xde\xaeJ,F\xaaP\xeb\x9a\ +1\xff\x00\xfd\x0f\xf1\xfa\xd11,\xd7cD\xe1\xcb\xf9\ +\xc5\x8fKZ\xd59hA\x17\xe5\xa5M\x8f;\x9a \ +\xbdh\x82\xd3\x8bB\xa2\x8a\xd4@W\x01H^\xc1\xae\ +\x5c*\xdb\xe2$\xd3\x00:\xd8km/\xd6\x87\x00s\ +a\xb2\xde\xe5\x0e\xdd\xa8\xe5\x0c\x19U\x05\xdc\xec\xbf\xb9\ +\xad\xb2\xab\x84\x5cD\xa5\x9b\xc6ePu7\xe7V\x82\ +\xb8\xf8\x8c\xab\xce\xfa0\xfeh\xa0\x87\xc2\x84%\xeeI\ +\xbb{\xd1\xaa\xda\x99\x10\x14\x06\x17S{n-b=\ +\xe8q2\xc7\x86\x8c3\x82\xcc\xde\x95\x15`\xda\xe1\xc8\ +\xdbF=\x8f\xf0j\x97\x1eShM\xb4\x00\x8f\xce\xab\ +\xd4J8\xbcD\xb3\xb9,H^J6\x15Vk\x86\ +\x03\x91\xa6\xb6\xf42\x8c\xc9\xa6\xe0\xd7+\xdbc+\x9a\ +9\x13|\xc8l+21j\xd6\xc3\xa4\x84$\x99\x18\ +\xaf3j\xcd\x992L\xeb\xd1\x88\xac\xf2\x89w\x807\ +\xdf\xc9\x17\xfe\xe2~cQ[8,F\x82)-o\ +\x84\xf4\xaf=\xc3\xa4\xf0\xb1\xd1Im\x98V\xcc\xca\x15\ +\xca\x8eF\xbap\xbd\x0a\xd2 \x8f\xe6\xa2\xb3\xe2\x9aX\ +\xfd\x0e@\xe9N\x18\xd9\x00\xf3\x227\xca\xd5\xd3\xf5\x19\ +\xc5\xaa\x83\xb5W\x18\xddu\x85~D\xd7\x1cbi\xf7\ +G\xbf\x9a\xad\x8b\x0c}\xe8\x0d)\xf1\x84\xe8\xb0\xaf\xd4\ +\x9aS\xe3\xa4\x07A\x18\xed\x96\x8d\x87\x0f\xc8;\xfdj\ +B\xad\xf6\xaa\x9fl\x97\xf1\xaf\xd0Q.2A\xba\xa3\ +\x0fj6,[\x05cF\x91\xb4T\x17\xf7\xac\x8cL\ +\xad,\xcd-\xaf}\xd0s\x1d\xbb\xd6\x9ab \x91\x1a\ +9\x03(u\xb1\xe9Y\x93\xc4b\x90\xad\xee\xa7\xd2z\ +\xd6y\x18\xb1\xc2p\xcb,\xa6V\xf3F\x9a\xfb\x9e\x95\ +\xab\x9f0*\xe02\x9f\x84\xedY<;\x10\xd0\xc8\xc0\ +e\xcb&\xe0\xecOz\xd5K2\x07_I\xfc\x8fJ\ +\xd7\x0f\x05Q\xc7A\xe0J\x0a\xff\x00\x96\xfa\xafn\xd5\ +\xb1\x80\x98O\x83G\xbe\xaa2\xb5R\xc7(l\x03\xdf\ +\xe1!\x85\x07\xf8~R'xN\xce\xb7\x1e\xe2\xb5:\ +\xa2\xf8\xd8\x8d\xb5\xb1\xa6\x83\xa5W\x06\xfa\xd3\x11\xb4\xae\ +\xac\x8d\xe9/\xbd0\x9b\xd0\xb6\xbaT\x95\xf1h\x1e\x02\ +\xa4hY\x7fZQE@B\x22\xa8\xec*\xcc\x80\x98\ +\xd8\x0d\xedq\xdf\x9d-\xc0:\x8d\x8e\xa2\xb1aU\x90\ +ij[iV\x1du\xa4\xc8\xa4Vi%\xa8\x1fJ\ +a\x14\xb7\x15\x84[\x9dhh\xce\xf5\x0c*2\x80\xef\ +C\xa5\xe8\x88\xd2\x84\xd4Phk\x89\xa8\xbd\x1a\x93B\ +\xdbWr\xa8k\x05,\xcc\xaa\xa3\x994 \x10/\xb5\ +Hi\x14Ydp;5Fh\x7f\xf7\xd0{\xd12\ +\x90;u\x07J\x93\xbcW\x1b\x90}\xd4\x1f\xda\x93$\ +xi.$\xc3G\xee\x83)\xa3a\xce\x85\xa8\xa6\x14\ +\xd8L\x13#(Y\x10\x1d\xfc\xc1\x81\xf9P\xae\x0b\x09\ +uR\xf2\xca>\x1c\xda\x11\xfd4\xebP\xca\xa4\x02\x14\ +}\xe3\x8f \xef\xd6\xb3\x90\x99\x19H\x85\xa1\x85#\xe5\ +\xe9\xb9\xa3\xce$\x19e\x8e7\x1d\x0a\x8f\xda\x97#\x03\ +&\xfa\xf3\xf7\xa9C\xad\x86\xf5\xa0\xa7\xc5p\x89\x08Y\ +\xa1-\xe1\xb97\x07\xe1=*\x90\xadN5*\xc7\x85\ +\x18`\xc0\xbb6g\x03\x90\xe5YC87\xbe\x9d\xab\ +\x9f94\xc3-\xa5Z\xc3q\x0cLJ\x130t\x02\ +\xc1\x5c\x5c\x0a\xa6\xcc.2\xde\xe3\xad\x19:_)\x17\ +\xa2t\xbdk\xc5\x8a\x87\x17\x87\x920\x9e\x1c\x85}7\ +\xd0\xfbUX\xe3fl\x80k\xfaR8ya\x89\x89\ +\x81\xd4\xb8\xd6\xb5\xf1P\x09\x99\xd6\x18\xec\xaa|\xe8>\ +=4\x1e\xdd\xab\xa4\xff\x00(<^l\xad\xe4\x91\x03\ +\x0e\xa7zT\xd8 |\xd0\xb5\xff\x00\xa4\xefV\x05\x88\ +-\x96\xc6\xe4\x10w\x16\xa9\xb7=/]q\x86k#\ +#e`A\x1b\x83Qj\xd2\x9d\x12X\xfc\xe8s[\ +F\xb6\xd5\x9f0h\xc9R<\xc3KVlj\x22\xa4\ +\x0a\x08\xcb\xde\xe7_z`d\x04)\x0e\xccu\x08\xa3\ +Z\x91\x98gh\x982\x9bf`\xbf\xef\xe5Z>\x81\ +h\xc5\xc1\xd776\xeek2\xc78g\x00e\xf4 \ +7\xd7\xa9\xabX\x09\xf4\xf0\xa4:|$\xf2\xadq\xa2\ +\xac\x80H\xe9]b\x07Z;[C][\x08\x16#\ +]T\x8b\x1aF\x22)\xe6\x84\xc2\x02\xb8\x02\xea\xd7\xb1\ +'\xa5?(\xde\xd5\x0c\x0a\xea\x9a\x1d\xedEL\x09K\ +G\x7f\xf8iI\x1c\x88\xfe+\x94\x87\x85d\x00\x8b\xe8\ +GB+_\x88a\x9aq\xe2\xc1\xfeg\xc4/\xbfq\ +TW\x0f+L\x10\xc6G\x8b\xdb\x98\xfeG\xe9\x5c\xef\ +\x1c\xadJ\xd2\xc2\x1f\x0f\x86!Q\xb4E\x88\xeb\xad`\ +q\xa8\xc0\xc5x\xaa4p\x09\xf7\xb5z\x0cS*\xe0\ +\xce]\xb2\x84QY\xfck\x0c\x17\xc2K\x82d\x8c\xe5\ +'\xad\xf4\xfe)\xe76\x08\xc4\xad\xd5\x7f\x17\x0f\x14\xa3\ +\xe2@\x0f\xb8\xacG_.p\x08\x04\x90A\xf8O1\ +Z| \x93\xc3\x98\x1f\x86M>\x95\x8e>\xe3Ua\ +E\xc8\x02\xa4\xa9\xcb}\x0d\xba\x1b\xd0H\xc50\xee\xe3\ +p,>u!\x12(\xe3\x91\x17\xd3l\xdf\xd4\x0dl\ +:\xb9\xb4\x15,2\xb1\x1d*\x18\x12E\xada\xca\xf5\ +\x00\x156\xd7Z\x19\x0a\xc7\x11v\x07(6\xd0S\x09\ +l\xd9B\xeb\xefC2\x13\x86\x931\xbf\x97kTA\ +\x19I\x14\xb4l\x0d\xb7\x16\xd4We\xe9J\xc1\xe1\xa4\ +\xc8%IB\x13\xe9\x16\xde\xacD\xfe `\xcb\x96D\ +\xf5/\xefD\xff\x00\xa8 u\x15$\x02,E\xc5\x16\ +\x95\x1fZQ\x7fgf\x04\xa0\xcc-\xa8\x1b\xd1\xe0\xb1\ +r\xe1\x9f,we\xb8\xcf\x13|^\xdd\x0d\x1c24\ +R\x07M\xc5\x5c\x9e\x1c>.!)\x05[\x9b//\ +z\xa4\xfe-Q\xe2\x1c`>Xc\x8c\x04'\xef\x05\ +\x8d\xea\xd7\x03\x8f6)gCx\xd0^\xff\x00\xb5J\ +p\x9c7\xda\x04\xcd;\x16\x03_.\xe7\xad\x5c\x8a5\ +\x89m\x0e\x97\xd4\x92=^\xe2\xb5%\xdd\xa2\xe7\xc5\x85\ +$S\x01\xb8\xa4#f!m\x95\xed\xe9\xeb\xdcu\xa3\ +\x0dc\xa9\xb5t`\xca\xeb\xd7\x02\x0dV\x9b\x14\xd1J\ +\xc8\xf1\x03m\x88;\xd5n%\x9b\xebB\xe2\xdee\x17\ +\xe6Ts\xf6\xefA\x87\xc4G0\xb0\xf2\xb7\xe1<\xe8\ +\xf3kV\xea)\x80oM\xc8;\x11H\x11\xda\xf9\x97\ +\xe7V%\xba\x13,jH\xf8\xd0~\xa2\xa1\xca\x90\x19\ +He;\x11\xce\x8b\x0cT\x91-\xb5-\x94\xf2\xb5Z\ +u\x06\x94\xc9X\xb0\xab2\x91\xc8|\x8d\x03\xe6\x03\xd2\ +j\xc3-\xa8mYJ\xb9\x81\xedB\xe5m\xbd\x14\xb1\ +\x95k[J\xe0\x05\xb6\x154C\xb0\x1dj\x01\xb8\xb8\ +\xd0Q\xca\x97:iKTe;\xdcVjI\x02\xdb\ +_\xde\x86P\x81\xa2v\x00\x05r\x09\xe9qDv\xae\ +\xd0\x82\xad\xaa\xb0\xb1\x15 \xc8[5\x9cf\x1c\xc1\xd6\ +\x80\x8f\x08\xf8\x90j\xa7\xd7\x1f\xf1D\x97\xcf\xe0\xbe\xac\ +\xa2\xea\xdf\x8cT\xae\x8c\x0e\x97\x15\x17+$\xa9\x9e2\ +H\xe6\x08\xda\x84\xadtQ\x04\xc4M\x97Eu\x0c\xa0\ +\x1e\xf5$tcB'\x15+@\xea\x88\x80\x16\xb7\x9d\ +\x85\xc51b`\xe5T4\x926\xef\xcc\xfbv\xa9\x0c\ +\x1a<\xb2\x00P\xee\x0dT\xe3\x12\xcd\x87\x850\xb8|\ +Y\x8dYs\x12E\xcd\x8d\x17\xae\xd2\xd4\x91\x88\x96\xf3\ +\xba\xc6\xbd\xcd\xefUf\xe2I\x1d\xd7\x0a\xa4\x9bz\xdf\ +\x97\xb5P\x88\xb1\xf2\xac\xcc\xe3\xf0\xcctoc\xca\xad\ +\xe18x\x95\x81\x934\x00\x9d\x15\xacK{Vv\xdf\ +\x0a\xb2\xe6\x91\xafb\xceN\xbc\xcd^\xc3p\xc9\x993\ +J\xcb\x08#L\xda\x93\xf2\xab\xf8h\xe2\xc3\x8c\x98h\ +\x80nn\xda\xb7\xf6\xaeyaV9\xe5$\x8d\xca\xae\ +k|\xe9\x9c'\xd1\xaa\x91\xf0`\xe4\x01\x8cK\x9d\x00\ +\xc8u\xaa3\x06\x8eF\x8d\xacr\x92/\xd6\xb7\xf0\xcd\ +\x1eQ\x88\x0dx\xd2\xecI\x16\xda\xb1\x1cx\xd2\xb1\x03\ +\xd6\xd7\x03\xde\x9e\x5cd\xf1Jw\x02\x84\xcb\x8d\x0c}\ +\x11\xf9\x9e\xb7 \x8c\x04\x90\xa9\xd5\xa4\xd7\xb5\xa98\x5c\ +2\xe10\x8b\x11\xf5\xb6\xb2i\xf9U\xc4\x06\xf9\x94\x8b\ +\x91b\x1bf\xe9\xeck|x\xe4\xc6mB\x92T\x16\ +>f%\x9b\xb5\xff\x00\xd8\xa9\x06\x93\x01\xcf\x96U\x1e\ +R\xa3\xf4\xb56\xb4\x04\x0dt\xa8&\x8f!\xb6a\xe9\ +n\x86\x86\xf5 \xd2\x99\xec\x0a\xb1\x07qRO\xfcK\ +\x8d\x8f\x82\xb6\xfa\xd5\xae \x83\xc38\x83\xb2\x0f8\xeb\ +X\xf1N\xff\x00k8\x86BU\xae\x0e\x9aZ\xb1z\ +j.\x8a5\xa1L\xae\x99\xa3`\xcb\xfaQ\x8e\x94\xa6\ +\x86\x0ao\x16<\xacFu\x1aw\x14\xda\xce\x81\xccr\ +\x87\x07cZL<\xdalu\x15\xb9Y\xa9\xa8\x22\xa4\ +m\x5ciE\x95*n\xbfO\xe2\xa6\xe5\xd3)sf\ +\xd8\xf4=h\x88\xa0e \xdd4=:\xd4\x95\xe3I\ +e\xc4*J\xbeUbI\xb6\xfa\xd4\x7f\x88\xd4\xb6\x06\ +9G\xc2\xf6=\xaa\xccW\x08\x01\xb8\xae\xc6(|\x04\ +\x88\xcbq\xa1\xac\xe7I\x82\xf8Id\x8f\xed\x09\x189\ +\xc7\xde\xa0\xdd\xba0\xefV\xb0\x91x\x185\x8c\x9b\xb3\ +\x9c\xe7\xf6\xa6f!\x81]-\xa5\xab\xac\x02\x15\x1b)\ +\xba\xff\x00\xa4\xff\x00\xb3X\x93\x1a\xd7\x05\x0e\x8c\x8cl\ +\x18Z\xfd*\xa3bLp\x18\x0a\xdc\xdb*\x91\xefV\ +t\xcc\x09\xda\xd5.\xb0\xbc\xaa\xcd\x18b9\xd5@\x97\ +;F\xac\xc1Ae\x04\xde\xa0\x829\xaf\xbd\xa8\x9d\xff\ +\x00.T\x05\xa9N\x1a\x0b\x0b\xf75(\x03]\x18h\ +\xc2\xc6\x82\xfa\xd7J\xe68\x19\xc6\xe3A\xda\xf5'F\ +-\x87A\xcc\x5c~t\x13\xab\xf8\xab\x88\x8c\xdd\x90y\ +\xd7\xa8\xa6@\x19\xf0\xf1\x04\x17%-\xa7Z\xb5\x86\xc2\ +(#\xc6$\x96\xd3(6\xb5\xea\xcdJnA\x01\x94\ +\xddX\x5cP\xd5\xfc:\xe1\x9e \x828\x83Gqf\ +<\xafJ\xc4\xc3\x87\x22\xf0\xc8\xa5\xbf\x00\xd6\x9cZ\xab\ +M\xc3\xcab{\xee\xa7B:\xd2\xb5\x04\x82,jw\ +4\x16\x9cF\xf1\xa9\x06\xe0\xech\xefT\xb8{\xb3F\ +P\x1fI$\x03\xd2\xad\x8a\xdc\xac\x982\xba\xe5qq\ +\xf9\x8e\xe2\x97,\xb2\xc5 I\xc9\x926\xd5_\x98\xf7\ +\xa2Zb>Srt:\x1aP\xa3\x7f(+\xe6\x1e\ +\xf5\xd8\x88\xd7\x11\x1f\xf5\x0d\x8f\xecj\xbe,\xf8\x0c\xb3\ +\xc4r\x82l@\xf4\x9an\x16_\x19Ke\xca\xcb\xbd\ +\xb9\x8a\xb7\xe5\x0aH\xae\xd2\x05OU\xf4\xab\xe2V[\ +.#\xca\xc7f\xf8[\xe7\xd6\x95,F,@\xc4G\ +r\xb7\xf3-\xefjk2\x11cb\x0e\xd7\xe7T\x98\ +\x85r\x06a\xb7QI\x90\xe4l\xcb\xa2\xc8lG,\ +\xddjV$V\xcc\x85\x93\xfd&\xd4\xbcD\x02ML\ +\xd2_\x95\xf5\x15]C\x06\xf4/B\x09\x03_P\x16\ +6\xd9\xbb\xd4\x92\x0a\xdf\xad\x04\x04\xde\x81\x85\x11\xde\x85\ +\xa8Aa\xa5%\xc6\xb4\xe64\xa65\x94L\x82\x96i\ +\xce9R\xd8kS@aBE\x19\xa1\xac\xa2\xe7B\ +\xf1fSi\x22\xd5O\xedR\xb9e\x8de]/\xbd\ +\xb9\x1a5\xd1\xae9R\x9e\x19Rc&\x1e@\x81\x86\ +\xa0\x9d\x8dE\xd3\x12\x98\xac9 \x9c\xcaA\x15\xd7c\ +{\x0f\x9d20\x14\x16\xbey\x1b\xd4\xe7\xf4\x1d\xa8X\ +\x00.6\xe9B,)\x1b\xd5O\xf1\x08o\x16'\x03\ +\xcac\x02\xfe\xd5|\xedJ\xe21x\xbc=\xf6\xcd\x17\ +\x98\x1e\xdc\xe8\xb3\xa5\xac\xfe\x0b\x1a\xcb\x8eQ \xb8\x00\ +\x9bV\xb3\xbf\x8a2\xc9\xe9\xf8m\xf0\xfbVg\x046\ +\xc7\x82\x7f\x09\xfd*\xfa\x99]\xc8\x81c\xc8\x86\xc5\x9f\ +\x99\xa3\x87\x8a\x8dVv\x19g\x99Z?\xe9\xf57c\ +MW\xd3.U\xc9\xf8m\xa5\x0a\xa9c\x94\x80\xaf\xbe\ +Pn\x1b\xb85\xda\x83b-[\x05q)F\x1f\x02\ +\xd8TV\x19\x9a\xe0\xf2*u\xa5\xff\x00\x87\xe2\x0d\x88\ +i\x98]b\x17\x00\xf3<\xa9\x9cc\xccrX\xe9\x11\ +\x00\xf2\xba\x9f\xe2\x8f\x81\x9f\xff\x00\x1d%\xbf\xf7G\xe9\ +G\xff\x00G\xe2\xf09\xef~t\xd8\x90\x0f\x88\xe9\xa9\ +\xa4GG\x88|\x98)\x9bc\x96\xc0\xf75\xb6\x04\xa5\ +@\x01T\x01\xca\xc2\x8a\x92\x9a\x0f.\x9d\xb9\x1a`a\ +`z\xd4\x85z\x91@\x0d\xe8\x85I\xd3X\xe0\xe6V\ +\x1a:e\xff\x00\x7fJ\xa2\x80\xc5\x12F\x0e\xca/\xde\ +\xaeb\xce\x5c\x04\xff\x00\x89\x92\xca;\xd5\x18$\x12\xc4\ +\xac\xcc\xaa\xca,\xe0\x9bZ\xab\xe9\x89\xca\xab\x8b\x81\x96\ +\xca^\xf9\x80\xd8\xd3N\xf4\x99\xd1\xe6d1\xb0DM\ +\x9c\xf3\xee\x05\x1f\x88C\x85\x94z\x8d\x84\x8b\xb1\xf7\xa2\ +\x13+O\x0c\xd9\xb0\xc8\xdamcY{\x1b\x1d\xc5_\ +\xe1\xcc\x0e\x19\x97\x9a\x9b\xd6\xb8\xfa)\xe4\xd7\x03Q]\ +[\x02\xae5\xc2\xba\xa4\x1a\x923D\xeb\xd5H\xa9\x22\ +\xba/X\x1dt\xa92i\x8b\xa8\xf7M\xbd\x8f\xf7\xa8\ +\x98e\x91\x97\xa1\x22\xa0\xb8F\x88\x9d\x03\x12\xa7\xe7\x5c\ +\xcb\x98\xe9`7\xae\xf4\x8bW5\xd5\x85\xc5\xb7\xa1&\ +\xf5$1\xae\xd0+3\x1b*\x8b\x9a\x93PP\xc0_\xf8\xa8\x82\x19\xe1\x95\xb2\xa1`y\ +\x06\xe7Wp\xf8L\xe8|m\x10\xfc6\xd4\xd0C\x85\ +\x18\x84\x0eUT!\xf2[O\x95[\xc3\xc8\xef\x9d%\ +[<|\xfa\x8ad\xfe\x8b]\x0cqa\x80H\x97,\ +o\xb1&\xe5[\xdf\xbd\x17\xa5\xaeF\xa0\xd4\x92,A\ +\x17\x07q\xd6\xa2\xc4(U\x90\x10?\x1a\xdfN\x97\xde\ +\xb6\x19\xb8\xf8rb,\xb7!\xc5\xc5\x0eY\xb0\xd2\xab\ +\xb2\x15#QqW\xd29<\x7f\x1aVK\x80B*\ +\xebj1{e6 \xee\x0e\xd5\x9c:\xcb\xc5\xe2\x13\ +\xc4\x0e\xf192\x0b\xf9\x0d\xea\x22x\xe5\x04\xc6Na\ +\xba\xb0\xd4S\xf8\xb8\x5c,\xb0\xcf\x1a\xddB\x90\xca\x0e\ +\xabz\xcdw\x93\x11\x8e\x0f\x87R\xadn\x7f\xa9\xac[\ +\x94\xc5\xfc\x1b\x14\xc4\xa9\x02\xe0\x9biW\xa3\xf13\x9b\ +\xdc\x0e\xf5G\x0eY]ZP\x8db\x09h\xf9|\xab\ +Q\xc7\x98\x90A[\xe8Eo\x88\xa1\x19\xba\x8f\xa5\x12\ +\xb6\xe0\x8a\x8a\xe5\xf5\x8fz\xd0\x06(,\xa5p\xcb\xa1\ +\xbd\xd8\x81\xb53\x0f\x141\xaeX\xc3+\x1d\xc95S\ +\x0d7\x87\x8dq)#5\xc15p\xd8\xe8u\xf64\ +O\xea\x10r\x0d\x8e\xff\x00\xad\x0e\x89\xa0\x07\xc3\xfa\xe4\ +\xfe\xd4\x19n\xc73\x1d\x0e\x95 \x10tf\xa5\x08\xf9\ +@ \xdd\x08\xd0\x8d\xa8X\xd0\xc8Y\x15\x98\x05*}\ +c\xf7\x15\xcel\x05\x8d\xc1\xd8\xf5\xa9!\xbdT'\x7f\ +z\xe6:{\xd0\xb16\xd3qYN4-D5\x17\ +\x1bP\xbd\x15\x16\xc7z\x07\xda\x88\xef@\xf4 \x9a\x17\ +\xa2\xa1j\x9a\x03\x0a\x13GBE\x15\x06\xd5\xc4\x03\xa5\ +I\xd0W\x0c\xdd\x85\x08 \x11\xa0\xd4T\x10I\xd6\xd6\ +\xa9bF\xeb\xf4\xa3X\x99\x975\xac\xb6\xf5\x1d\x05H\ +\xa5`\xd5\x18\x86X\xb0\x92\xbb\x91\xe6R\xaa\x0f3J\ +\xc4b \xc3|BW\xe4\x14\xe9\xf5\xaa8\xa9\xe7\xc5\ +8\x0eo\xaf\x95@\xd2\xb3ya\xc1\xf0x\xd9\xf1z\ +rF\xb9\xe9\xa5h\xc2\x99!d\xb5\x8a\xc9\xaf{\xed\ +C\x81\x80\xe1p\xc5Z\xde$\x9e\xa1\xd0S\x88b3\ +\xa2\xe6`,\xcb\xf8\x87\xf2)\xe32+C\xe5e\xc8\ +\xe2\xeb\x7f\x98\xf6\xa9\x80;\x19\x22c\x9aH\x9a\xdan\ +E(\xca\x89\xe6l\xe0wKR\x10\xc9\x89\xc7\xb1R\ +c\xcenH;\x0a\xb5b\xdf\x12* Ev\xca\xea\ +I#\xaa\xda\xc6\xff\x00-~U_\x81N#\x99\xb0\ +\xf2\x1b$\x9a{\x1eUn\x18\xa0\x89\x83\x14\xcey\xb3\ +\x9dMcq\xbcF'\x09\xc5\xa5\x82\x19YbCt\ +\x17\xe5\xca\x8e]v\xa7\xf1\xbcd\xcbp\x07\x9a\xfc\xc6\ +\xd4gX\xd5\x5c\x96V{\x9bt\x03_\xda\xab\xae5\ +%\x8e'\x926f\x960\xc0\x82/\xd3_\xa5XR\ +\xe0\x16u\xc8XeU\xe6\xa3\xbdt\x96VR\xba\x0a\ +\xeb\xdbm\xb9\x8aYk0\x1c\x88\xa9'CR\xc3\x97\ +\xda\x8a\xe1S3\x9b/z\xab,\xa20\x19\xda\xecF\ +\x8b\xfc\xd5w\x9aIH2\x1dF\x80\x0d\x80\xa3b\xc3\ +\xa6\x99\xa5\x92\xe3E\x1b\x0e\x94$\x86>uV=\xc5\ +,\x1a+\xd1\xa4E\xaeu\xa0\xc6\x100O~\xa2\xde\ +\xf4W\x19\x80\xe6j\x9f\x13\xc4#H\xb0\xa99W\x9f\ +\x22j\xb7\xa5\x17`r\xf8h\xdd\x8d\xc9\x1a\x9a\xbb\xc2\ +[\xef\x99\x09\xf5.\xddMd\xf0\xb7\xf2\x11\xda\xf4\xd8!iee\x03E\xb2\xdf\ +\xa73\xfb}*\x93b\xe7\xd1DJ\x19\xb4\x0dj\xd9\ +\xe1\xd1xX\x04Q\xab\x90K\x9d\xf5\xa7\x8ftQ\x80\ +\xaa\xa1\x14YWj\xed\x06 r/\x1f\xd6\xc6\xa4\x82\ +7\x04PI\xa6+\x0c{\x91]\x00\x8e\xd45&\xd6\ +$\x9b\x00.OJ\xa3\x89\xe2E^\xd0\x22e\x1f\x13\ +\x0b\x93E\xb2%\xda\xe1\xa9\xb5V\xe1\xf8\xdf\xb4J!\ +\x95P3zYE\xb5\xe9j\xb2\x18(.M\x82\x82\ +oT\xb2\xa5\x0e4|D\x9dA\x16KX\xf5\x02\x93\ +\x1ck\x04b4\xdc\x80Y\xb9\x9a\x949\x99\xcbZ\xc5\ +Ik\xed@\xaf\xe2C\x1c\x82\xc72\xebn\xdaV>\ +\xebFC\xa4\xab\xee+FB\xb0\xe2\x80\xd5c\x92\xe0\ +\xf4\x06\xa8`T>25apZ\xaf\xe2T\xc9\x87\ +q\xf1\x0f0\xd2\xb5<\x14l\x086<\xab\x85\xb5c\ +\xb2\x8b\x9a\xa7\x1e.a\x95\x06V;\x00V\xe6\x9b\x8a\ +\x13\xb4*\xc5\x95\x90\x1b\xba\xa0\xb5\xbd\xe9\xd0\x08\xf0\xc6\ +`f\x95\xca\x97$\x81j\xb6\x00>[\x82\xca5\xbe\ +\xf5\xceA \x8fI\x1e_j\x16\x8d\x1ee\x94\xb3\x06\ +Qo/:\xb1\x05\x1a\xc4\x8b\x12)\x9b\xebA\x89\xb7\ +\xa8is\xadDLr\xdb) s\x15!^\xc6\x84\ +\x00\xb9\xd1v\x048\x16\xd8\x1a\x92E\xed}h&W\ +b\xad\x1bZD\xd0\x03\xb3\x0e\x95T\x82hI\xa5}\ +\xad\x09*\xf0\xb0k\xec\xa6\x8f\xc4\x87\xf18\xee\xc8@\ +\x15\x9dC$\x8b\xb5\xc1R\x06\x9d\x08\xff\x00\xcd\x09R\ +v\xd6\x85\xf1\x18t\xff\x00\x98X\x8e@h~uJ\ +X\xf1\x0e\xc6a\xa6m@\x07QU\xa7\x16\xa4\xb20\ +V\x04\xb3l\xa3z\x16#6B\xa5\x09\xf4\xdc\xdc7\ +\xce\xab\x0cTXX\x8ep^V\xe5\x7f\xd6\xb98\x84\ +3D\xe9$E4&\xe0\xdc\x0a\xce\xac<\x8b\x1b\x1a\ +\x83A\x0c\xa1\x80I\x18k\xe8\x93\x93\x0a6\x04\x0b\xee\ +;kI\x06\x80\x16;(\xb9\xaa\xd8|S\xc9\x89\xc9\ +'\xa1\xcd\x80\xfc5e\xf2\xb4N\xa4\xd82\x91~\x95\ +\x99.\x1exN\x7f\x84\x1fP:Vyi\x8d\x09\x06\ +Q\xdc\x1a\xe1r.E\xa91\xe3\x22h\xc3J\xcd\x9c\ +\x0b\x1b\x0d\xe9\xb0I,\xaa\x1dc\x8e8\xfa\xb6\xa5\xa9\ +\xd0\x0c|\xc7\x0d\x84VP\x0b\xbbX_[\x0a\xc9\x96\ +Y$\xbew-}\xeek[\x89+\xbe\x04\x93\x87\x8d\ +\xb28\xb5\xa4\xeb\xde\xb2d1\x89\x04r+B\xcd\xe9\ +\xb9\xba\x9f\x9ds\xe7\xe9\x85\xac-,\x81bBI\xe5\ +[8,2ac\x1b<\xbc\xd8\x8d\xbd\xa9|\x163\ +\x16\x1eI4\xcc[(\xedO{\x8dG:x\xcc\xed\ +T\x9d\xf5:\x9a\x9fj\xe5QmE\xfb\xd7Y\xbbV\ +\xc0\x96G>]Z\xdc\x9bQU\xe7\x88A\x8f\x8d\x97\ +(\x0fk\xad\xce\x9dE>0U\xee\x0d\xef\xbf\xf3T\ +JH\xb8\xc0\xa430m\xba\xd1L_XJ\xcd\x96\ +\xf7\x0aM\xcf@+\x17\x8d\x83\x8f\xe3\xea\xb1\x82\x04\x81\ +~U\xa3\xc5x\xb6\x0e\x0c\xf0\xa5\xe4\x91\xbf\xcc\x03a\ +\xda\xaa\xe1ch\x10\xe2&\x00b'\xd4\x0b\xea\x8ak\ +<\xb2\xf4\xa2\xfe\x04\xabc\xceP2\xa4d.\x9d\x06\ +\xf5dX\xefTxA\xff\x00\x89o\xfe6\xfd*\xe0\ +5\xae>\x0a\x0035\xce\xc3n\xf4^UFv\x1e\ +U\x17\xb7SE\x90\xa9\x0au?\xadV\xe22\x02\xc2\ +% \x85\xde\xdc\xcd7\xa4D\xae\xd29f7&\xb8\ +T\x0a\x90+\x0d\x0dM\xa9\x80\xd2A\xb5Njt`\ +\xb1\x12\x98\x85\x94]\xdcYG\xefT\x1b\x09\x89\x92u\ +A\x13\x0d7#AW\xdc\xf9\xe6k\xf9\xae2\xf5\x0b\ +m(\x92F\x0b\x94\xb1\xef\xad\x16j\xd0\x88\xca E\ +M\xb7n\xb4\xf0u\xa0\x0dD\x0dn\x05\xac\x1e'\xc3\ +\x19\x1c]9[qZ\x09b\xb9\x94\xddz\xd6:\xd3\ +`\x95\xe27F#\xb5jQ\x8dE\xd3\xdb\xf4\xa2\x1b\ +\x8aF\x1f\x15\x1c\x9a?\x91\xbf#N\x22\xde\xd5\xb8\x04\ +E\xe8H\xa2]\xaamz@-}\x0e\xaat\x22\xb3\ +q1\x18\xa5+\xcb\x91\xebZ\x85t\xa0\x91\x12D\xcb\ + \xb8\xe5\xd4Vl\xd3+/\x99\xedR\x85\xafe\xd4\ +\x9a\xb8\xd88\x80\xb8w\xbd\xf4\xd2\x9d\x1cQE\xe8]\ +\x7f\x11\xde\x8f\xcd:\xa7\x88\x85\xd2\x14\x91\xf5`y\xfc\ +4\xcc,N\x22%\xdd\x95[e\x06\xd7\xa7\xcc\x03d\ +\x8d\xbe#\x98\x8e\xc2\x86G$\xf7\xab\x02\x02[D\x96\ +E\xf9\xde\x97\x1c2}\xa5d\x92\x5c\xc1u\xbf:,\ +\xda\x5c\x9a%4\xa2\xf8\xab\x95\xc0\x1b\x7f\xcckV9\ +\x17\xda\xb6\xb1\xe9\xe2\xe0\x1dF\xe9\xe7\x15\x8ck\x1c\xfd\ +18B\xcb\x8a\x8d\x94\x90C\x8dkk\x88\x9c\xb0\xcd\ +a\xb9\xcb\xf9\xd6\x18b\x08#q[x\xe1\x9f\x08\xc4\ +\x10n\xaa\xd7\xbe\xfak\xf9\xd5\xc7\xca\xaf\xac\xb2\x85\xe0\ +\x960E\xd9\x0d\xbf_\xda\x87\x0e\x99pq\x03\xcc\x16\ +\x16\xe8i\xd10RX\xe8\xa1M\xc9\xe5\xa5\x097\xca\ +\xb6\xb1\x08\x05\xbeU\x13xq\xb66\x22\xd6\xdfz\xd2\ +\xbeSs\xcbz\xc9C\x96E'\x91\xb9\xadI\x08c\ +\x9b\x93kZ\xe2*\xa3\xdb\x0d\x8fY\x009\x0bf\x1e\ +\xd5a\xb1\x10\xa4lC\x86&\xf6Q\xce\xf4\x18\xb4\xcd\ +\x11\x1b\x91\xaa\xf5\x15E-\x9dsm~tx\x9aX\ +\x5c\xdfd\x8f6\xfa\xdb\xda\x8a\xe6\xf6\x16\xbf~T3\ +\x92$\xb2\xb5\x94\xed\xd8W\x0b(\xb0\xf9\xd6\x82Xf\ +\xf5\x12}\xb4\xa9\x16\x0baC\x9a\xa4\x1b\xd4\x9c\xe7c\ +\xd0\xd0\xb07\xbdI`|\xa3s\xa5\x11\xb0\x1a\x9b{\ +\xd4\x80Y\xaf}\x01\xebm~\xb5\x05\xd8\x0f3\x5cs\ +\x07QRY:\x8e\xe7aI\x9f\x11\x85E9\xdeM\ +\xb4\xfb\xb2/\xf3\xa1*q\x18\xd5fS\x10\xb8\x93`\ +9\x1ad\xb8\x94\x8a \xcb\xe6\x90-\x89\xbf\x95,9\ +\x9a\xab\x89\xc6\x99/\x1a\xa6D\xe5f\xd4\xfc\xeb7\x1d\ +\x02*\xc7\xe13*\xc8\xd6*Z\xff\x00:\xe7yg\ +\x8dHc\xa9\x99\xcb\xa4\x89+\x1d\xf2\x9b\xd0\xba\xb4x\ +i\x8b\xa9\x19\x93(\xb8\xb5\xc9\xa3\xc9\x0c\x0f\x91 C\ +\x94\xd8\xb1\xbd\xcdA*\xba\xacD\x13\xb1r[\xe9z\ +\xcbH\xe1\xe2L<\x19'pP\x9b\x15\xdc\xa5\xf65\ +w\xc3\xc4a\xe3\xf1\x95\xac/ku\xaa1\x0f\x10\xbc\ +m\x7f:\x9b\x9b\xfc\xe9\xff\x00\xe1\xe9\xc60\x0c<\xcd\ +\xe6\x88]n}B\xa9\xfc\x15x\xd9\x91X\x8b\x07P\ +H\xe9B\x9eG\x22\xe3^\xb4\xd9\x83\x03f\x16=)\ +l\x9d\xf5\xae\x81^|(|u\x94\x05R\xa1\x9b\xb5\ +X6\xb0U\x16U\x16\x15(\xa0H\x0d\xcd\xda6\xbf\ +\xc8\x8b~\xf5\xce\xcb\x04Fil\x00\xf4\x83\xf1\x1a'\ +I[\x8c\xb8\x8f\x06 \xbf\x9aC\x98\x8e\xd5\x9b,&\ +`\x98{\xfaHwb==\x05\x14\xaf&'\x11\x99\ +\xdb\xcc\xc6\xde\xd5\xab\x81\x81S\x0e1\x0e\xbewve\ +S\xf9\x13\xf2\xae\x7f\xedO\x82\x0a#\x88&\x97>f\ +\xb5u\xafDA-s\xa94J-\xef]p\x01\x12\ +\xc6\xf7\xd3\xa5\x11\x14V\xae\xa9\x04!$\x00\x09'\xa5\ +T\xe3s[\x0c\xeb\x86e3\xc6\x9fx\xc3\x9a\xf4\x1e\ +\xd5g\x1f+A\x81,\x9a4\x8d\x92\xfd\x05\xab7\x05\ +\x1f\x8d!B3\x07\xd1\x87Q\xbf\xec\x07\xce\xb3\xca\xfc\ +0\x8f\xf0\xde\x03\xc5\xc5}\xa7\x14\xb6Fo('W\ +5\xb4\xf1E3\xf9\xb0\xebr~\x0d\x0d\x09\xc2\xb7\x88\ +\xae1\x08\x85=*\xaal\xbd\xab\xa6Lc\xbeQ*\ +\x88\xce\xec\xa2\xc2\x8e3\xf33\x15\xba\xad\x12\x18\xf8\xa0\ +\x8e'\x06\xcf`j\xe3j\xc7.\xd7\xd2\x97\x1e\x124\ +\x90\xc6\xb1\ +1\x89\xe1b^?\xc2H\xadh\xc9>\xe4\xda\xb2\xf8\ +\xc3+q\x19\x8a\x9b\x8c\xd4r\xf0\xf1\xf5^\xf5s\x07\ +\xc4\x0cqx2\xa0t\xd8\x1ej*\x8d\xcd\x1e\x1f\x0f\ +4\xe6\xd1\xa5\xc7S\xb0\xacKg\x8dU\x9c\xd0\xb3\x08\ +\xcb\xe4\xcbb\xca\xfaf'a~\x95\x0e\xcce!\xd4\ +\x8b\xebs\xce\x87\x89p\xb7\x91Q\xc4\xd1\x992ee\ +#G\xb6\xc2\xfc\xa98a\xc4p\xa9g\xc2F\xd1t\ +\x12\xde\xfe\xd7\xa7n\xf6\x16\x01\xab\xfc>l\xf1\xf8-\ +k\xaf\xa3\xbfj\xce\x8f\x11\x85\x90\xd9\xcb\xe1\xdf\xa3\xa9\ +\xb5\x19\x93\x0c\x84\x13\x8c\x86\xfc\x80{~\xb6\xadJ\x9a\ +\xc0\xd8\x827\x06\x96\xf8l36l\xac\xb77!N\ +\x87\xf8\xa4G\xc4\xb0\xf2X\x11c\xd4\x87\xf3{\x1bZ\ +\x8f\xed\x98[^\xed\xedc\x7f\xa5\xab[\x19\xcas\xaa\ +\x93\xd3KoQ\xcb\xb8\xa5.&\x16\xbd\x96@\x06\xec\ +\x086\xa1\x97\x13\x02Y\xbcL\xf7\xdc.\xf5lG\x0a\ +%\x22\x90\xb3\xc6\xe2\xe8I\x1c\xef\xb8\xa3\x92ha\x8b\ +\xc4\x95\xec\x0e\xca\x06\xa6\xadF\xb1_\x9fj\x8b\x80o\ +\xcf\xa9\xac\xe9\xb8\xab\xe6\xfb\x98\xa3U\xfe\xa1rk\x93\ +\x8a=\x8f\x89\x04o\xd2\xde_\xd2\x8f\xd49W\xa5b\ +\xaf\x98\x12;\x8aW\x15\x7f\x17\x86\xc8I\xb9\x0e\xb9o\ +\xb8\xaa\xe7\x89\x86[}\x95\x07\xfdf\x93\x8a\x9eLQ\ +\x16P\xaa\xa3\xd2\x0e\x9e\xf4^S\xe2\x92\xaa\x85,@\ +\x1b\xdcU\x9c\x16\x08\xe2\xe4\x13\xb0\x0b\x1cw\x11\xe6\x1a\ +{\xf7\xa8\xc2D\xcf2\xf8Vw\xbe\x83[\x03\xdc\xed\ +Z\xcf\x00\x8e4\x89\x1a\xe25\x03\xdc\xf35\x9e'\x07 \ +\x12)S\xf0\xb0:\x1fcZ \xda\x98\xcb\xf6\x9c\x1c\ +\xb8c\xa9\xcaZ=y\x8f\xf7\xf9QxO\x8bA\xc3\ +q_k\xc3\xb4R\xff\x00\x9b\x1a\xdd[\x9b\x0avj\ +\xc4\xc1Np\xf8\x94\x94|'^\xe2\xb7J\xab\xc2\xb3\ +\xc5\xacm\xff\x00\xd7\xb1\xab\x8d\xd8\xab\x81\xa3SK]\ +\xefD4\xad\xa3\x95\xc6\x5c\xac.\x0e\xe2\x95\x89\x86I\ +-\xe1\xc8\xce\xa3\xe1f\xd4{W^\xa4\x1e\x86\xa1\x83\ +\xc1&\x1eL>R\x80\xc8\xbe\xa1\xb3TO\x86`3\ +\xc2\xec\xd6\xd4\x83\xb8\xa2F%\xc3\x05\xbb\x01`F\xf5\ +o\x0b\x0b\xe6\x0f%\xd4t\xe7Z\x93U\xe8\x1c\x17\x14\ +\xf9\xb3O\xe6E\xd0\x13\xb8\xadeee\xcc\xac\x18\x1e\ +b\xb3\xe7\x846(\x22yU\x85\xfb\x0a8\xe2\x9e\x07\ +\xcd\x13\x09\x0709\xfc\xab|v3Wt\xb5\x0b\xca\ +\xaa\xf9\x0c\x8b~\xe3j\x1c\xd7P\xc0\x11~Gq]\ +\x98,\xb76\x02@\x06c\xc8\x8eG\xde\xb5\xa0\xacv\ + x^\x1aJ\xad\x9br\xbc\xa9\x1e\x22\xc4\xaa`\x91\ +\xb3\x11g\xb8\xa9\xe2Q\xa2\x15e\x00\x16\xbd\xc7*>\ +\x1c\x88\x22\xf1H\x05\xb3[^U\x9f\xa5j&I#\ +\x0f\x1f1\xa8\xe9I\x9do\xa8\x1a\x93F\xdeo2\xd9\ +\x5clmo\x91\xedI\xc6I)O\x0d!eo\x88\ +\x8d@\x1d\xa9\xa11\x80\x07#z#\xf9\xf2\xa4\xe1o\ +\xe0\xa5\x81\xf2\x5c\x1f\xf7\xf3\xa6\xa1\x0c\xc4\xd1\x10\xd0\x88\ +\xa3i\x0e\xbe\x1a\x96\xac)\x1b3\x96;\x93z\xd6\xe2\ +rx|9\xb6\xbc\x87'\xefU\xf8T(\xb0\xfd\xa1\ +\xd4\x16ce\xbf*\xcf.\xee5:\x80\xc1`L\x8a\ +$\x95\xb2-\xf4[jkDeT\x08\x8b\x95\x06\xc2\ +\x96\xceI\xb95\x19\xe9\x9d\x0bt\xc0\xd6\xda\xdf1C\ +*\x89.\xca\xc5$\xfcC\x9f\xbd\x0em*\x03T\x15\ +\xe7R<\x93F;\x159O\xc8\x8aW\x85\x87\xfc3\ +\x7f\xfe\xe6\xae\xbb#\xa6W\x19\x87nUVH\x98\x5c\ +\xa0,?1E\x87I8l\x16l\xc2\x19/\xd7\xc5\ +4f4\x90\x91\xe2\xba_k\xd8\x8f\x9d\xa8\x0b\xdb\x90\ +4%\xbb\x0a:!o\xb4aX0$\x03\xb1\x1b\x1a\ +\xbb\x82\xe2\x10\xc8\xbe\x1c\xa1\x22p=EFSU\xc4\ +\xc4\xc7\xe1\xbd\x99:\x1a\x19p\x0e\xcb\x9f\x0f\xf7\x8b\xd3\ +\x9dSg\x87\xff\x00V\xf1s\xc1\x14\x82h\xd9d\xcc\ +\x9a\xaalu\xb5g\xcf;\xca\xe5\xdc\xdd\x8dHVU\ +UpT2\xb2j9\xdc\x11\xfb\xd5v$\x12\x0e\x96\ +\xa3\x95\xaaA\x86\xa2\x07\xa5)N\xb4kY&\x03\xf9\ +\xd5\x84\x8c\xbc\x820\xb9\xb2\x90\x15m\xa36\xe4\x9e\xb6\ +\xa4D\x06`[\xd25>\xd5\xab\xc2\xa3)\x84\x18\x89\ +W\xef$b\xc9q\xa8\x07\x9do\x8c\xd1j\xd4\x00\xe1\ +\xe1\x11\x83\xe6\xb7\x9c\x8e\xbd*C\x03K\x1b\xd1\xa0\xd6\ +\xba0\xe2\x0fJ\x13\xa1\xa6i}\xea\x1b(\xd4\x91\xf2\ +\xab\x11zT\x15\xa6\x05\x0c.*J\x91R!\x85\x01\ +\x8b\xef!\x04x\x99\ +\x10\x03er\x07\xb5;\x05\x8a\x9f\x0a\xf7\x8aL\xb9\xbe\ +\x13\xb1\xad,F\x1f\x0b\x8b\x9c\xcd/\x8b\x1b\x9fQ@\ +\x0ec\xd7Z\x98\xb0\xbc>\x16\x0c\xb04\xac\x07\xaaV\ +\xd3\xe9X\x9cl\xa7J\x8b\x8b!\xb0\x9b\x08\x84\xfcE\ +\x09\x1f\x96\xd4\xf4\xc6\xf0\xf7[\xf8\xb2\xc6z2f\xfd\ +*Z<$\x82\xcf\x83\x8c\x5c\xef\x1d\xd4\xd4E\xc1\xe0\ +\xc4K\x9b\x0f#(\x06\xe5\x1fo`ks\xf4\x0f\x89\ +#\x98\x06\x86ee=t5m0\xf8D\x8d^Y\ +\x90\xdf\xab\x7f\x15\x9b\x8b\x86h\x9f,\x91\x14\x03am\ +\x00\xa4\xd3\xb9\xf06\x863\x05\x18\xca\xb3\x10\x07%\x8f\ +\x7f\x9dp\xc7\xe0\xd5\x0c\x85\xa4\xb2\xf3\x22\xb2\xe0\xc3K\ +*fX\xe4a{yV\xac7\x09\x92X\x8cR\xc8\ +\x89sq\xe6\xd4{\x8a\xd6\xf2\xf9\x06E\xa81\xf0)\ +- \x92\xf2\x0b\xdf\xa0\xa7G\x8f\xc0\xb7\xfc\xe6\x07\xba\ +U\x01\xc3\x8c\x91\xae|B)_!\xb0:\xda\xa3\xff\ +\x00M`r\xa6\x223a\xbe\xa2\xf5K\xc9dl\xa1\ +Y\x174R,\x83\xaa\x9b\xd7_u\x22\xe0\xee\x0db\ +\x9c\x166#\x9e?1\xe6ck\xfdi\x90\xf1LD\ +DG\x89\x842\xed\x98\x8b\x1f\xad?\xaf\xe8\xc6\x89\x86\ +\x03\xaeC\xa7\xf5iS\x9e5\x5c\xaa\x00\x1d\xa9\x11b\ +\xb0\xf8\x96\xc8\xb2\x80\xc0^\xcd\xa7\xe7OX\xd9E\xd5\ +.:\x8di\x9f\xf1\x09\x1e\xe3E5!\x9f6k\xdb\ +\xe7K\xcfj\x8c\xf7\xab@\xdaE\x8aG2\x12\x16B\ +\x18\x1066\xb5\xa8#\x99\x1a{\x05t\xcd\xe9\xcd\xb3\ +Q&v\xf4\x82~W\xa5b\xe4H\x94\xb4\xee;(\ +:\xdf\x95E_\xfcD\xf7X\xa0\xda\xc31\xf74\xdc\ +<\x80``\x04X\xe4\xe5\xefYSb\xa6\x93\x16D\ +\x90\xabHA*\xf9\xb4\xb7Z\xd2\x0d\x96\x18E\xf3\x11\ +\x18\xcd\xde\xb3.\xdbNtfu\xfcU\x19\xd6\xfa0\ +\xa5\xddM\xedj\x02|\xd6\x14\xeaX\xcdj\xe7c\x94\ +\xd8\xda\x96I\xa8k\xe54\xa3\x81\xb0\x16\xe9P\x5c\x82\ +\x08\xde\x96\xadqS\x98\xdc^\xa4\x99`\x8e\x7f19\ +\x1f\xa8\xd8\xfb\xd5\x82\xab\xe3\xd5\ +\xef\x0c\xab\xa1\x0d\x97\xde\xb3L\x1b\x95\x0f\xa6]\x09+\ +~T\x82\xc4\x9b \xbd\xb75bE\x01\x99@\xd2\xfb\ +R\x9b\xca\xa4\xa8\x1aP\x00z\x8a\x8a0\xa0\x0d.{\ +\xd0\xb0\x00\x5c\x9d*:\x12+\x90\x90t\xf9\xd4\xfbk\ +P\xdb[\xadE%\xcb\x02\xa2\xd6\xe7ak\xd0\xe2#\ +Y\xa1\x11\xb3\xe5\xb3\x5c\x1b^\xa4\xda\xdd\x85B\x92X\ +\x007\xa9\x13&\x0b\x0e\xb1\xb4\x9e$\x96Q\xcc\x00\x0d\ +P\x9c[\x13\xf6\x8f\x133\x0fM\x86\x8b\xf5\xab\x5cR\ +l\xcf\xe0\xaf\xa57#\x99\xaae\xack\x9d\xcd\xe8\xc0\ +\xe7b}c\xfe\x91@\xcc\x11\xb4\xdc\x8doD\xc06\ +\xbb\x1eD\x0a\xe8\xa1i\xb1H\xa4\x8b1\x02\xb3I\xf3\ +O<\xa9\x95\xa4%\x7f\x08\xa4S\x0dqS\xae\x97\xf9\ +\xd3\xa8\xba\x90(\x97Sc\xa1\xa2\x0aN\x9c\xea@\xb5\ +\x10Z$\x0d\x94\x92\x01\xb1\xd4s\xa3\xcaJ\x82\x96\xf9\ +\xd4\x8b\x17\xa9\xa6\x15\xe9P\x16\xacA\x15\xa9\x87O\x0b\ +\x0e\xa9\xf17\x99\xbfj\xa5\x84\x88I\x89D\xd8\x13\xad\ +h\xb0\xbb\x93\xca\xf5\xbe0Z\xe5w\xcb\x96\xf7\x1d\x0e\ +\xa3\xf3\xa8l\x84\xdd\xa1\x88\x91\xcc\xadH\xf6\xae\x22\xf5\ +\xa6P]\xed`\xc4\x0e\x83JS\x13z2-B\xd5\ +\x17\x06>!\x1f\x0c\x9a\x8e\xcd\xd2\x96X\xe753\x06\ +1\xa2%\xb3<\x82\xd7\xed\xadt\xa6\xf2\x16\x1dhB\ +\x0cF\xa0\xda\x8f\xc5c\xeb\xb3\x8f\xea\x17\xa4\x13]\x9a\ +\xadN\x97\x0b\x81\x94\xdc\xc1\x90\xf5\x8c\xd8\x0f\x95%p\ +S\xc4o\x85\xc7\x01m\x81%i\xads\xb3\x11P\xb9\ +\xc1\xd4\x82(\xe9%_\x8c\xaf4\x9b\xd8\x83K\x9b\x1b\ +\xc4\xd1\xb2\xb4EOh\xe9\xd7\xa2YdQe\x91\x80\ +\xe8\x1a\xac\xff\x00\xa9I\xa6\xe2s\xe8|s}\xbc\xa4\ +R\x8e\x0f\x1c\xceA\x85\xef\xcc\x9a\xd1\x92Wo)v\ +os\xb5C=\x97V6\x14~g\xf4\xea\xb4x'\ +EG\x9d\xd0\x04$5\xbc\xc7)\xdfm\xaa\xd6!F\ +\x7f.\xd6\xf2\xf7\x1c\xa9bQ}\x14\x91\xb1\xa8\x88\xe4\ +/\x16bFP\xe9~]E3'\x819\x0d\xaf{\ +\x1a\x94R\x0d\xc9\xbd\x0ej\x82\xd79A\xf7\xa9\x19z\ +\xeb\xd2U\x9b5\x81\xd0u\xa3,\xdf\x87\xe9V\xac\x1d\ +\xeco\xf5\xae\xbf*X%\xb4\x0b\xda\x89J3eY\ +U\x98| \xebV\xa1#\xdc^\xf4y\xcd'U;\ +{\x8a\x95k\x8au\x1a\x1a\xc6\xe3CI\xc5a\xd2b\ +]<\xaf\xd3\x91\xa2&\xc2\xf5\x19\x88;\x1a\x92\x83\x02\ +\xad\x94\x82\x08\xe4k\x81\xf3\x5chj\xf4\xea\xb3\x80\x18\ +Y\x86\xcdT\xa5V\x8eB\xae\xba\x8e\x87z\xc5\x8d.\ +\xe0\xb1l\x06I.\xc3a\xd4U\xdc\x19_\xb1!L\ +\xac\xba\x86\xd3\x9fz\xc5\x8c\xd9\x89\xd7Z\xb9\x86\x9d\xe3\ +|\xc8\xd6c\xa1\xbe\xa1\xbb\x1f\xe6\x99\xc8X\xb9.\x16\ +'l\xc8\xde\x19<\xadqR\x15\xf0jdW\x12'\ +\xc4\xb6\xb5\x0f\xdb $(VY\x0f\xfc\xb6?\xa1\xe7\ +Q6\x22\x16V[=\xd9mb+]3\xda\xe4l\ +\xae\xe0\xc7r\xac4\xa7\xa5\xf9\x8dj\xa6\x15U\xb0(\ +\x14X\xe5 \x1e`\xd3\xb8y\x90\xc0\xa5\xe5b\x0e\xc0\ +\x80kp,-\x10\x17\xa8\x19\xbf\x1c\x7f\xf6\x1f\xe6\x8c\ +\x1b\x0f0\x00~%:|\xfaV\x83\x80\xa9+pE\ +\x15\xba\xd4\xd8\xf4\xad\x05Ybe\xfb\xc3r\xa0Y\xc0\ +\xdc\x8e\xbf+\xd7\x10\xac\xb7R\x19z\x8a\xb5\x1f\xac\x03\ +\xb5\xf5\xaax8\xb2\x89\x7f\xd6@\x17\xe5z\xcd\x87\x5c\ +\x14\x0d\x86\xf4\xa6*\xd8\xd0\x83\xfeR\x93\xf3\xab%{\ +\x81\xef\xa5V\x96HS\x1b\xe2\x86\x047\x95\xc8\x1a\x5c\ +\xf3\xa2\x940\xa0+M\x0f\x13\x1b+\x8b\xf4:W:\ +\xdbqY\xc4AE\x1b(\xa0t\x0c-v\xfdi\xe4\ +P\xb2\xd0\x88\xc8\x14ipj\x08\xf3\x5c\x9b\xd3\x1a\x81\ +\xadz\x8c\x09\x1aZ\x82g\xf00\xed'\xc4|\xabM\ +Qso\xf6*\x87\x11\x97\xc5\x94\x85\xf4&\x8bG+\ +\x90\xab{\xd0\x91\xda\x8a\xa2\xb94\x1b\x0a\xe4\xcc\xac\x18\ +\x1b\x11\xb1\xa2\xa9\xb5:\x9cl\x05\xe8\xe3\xb3\x0f('\ +\xf2\xa2\xcb\xe5:_M\xa9\x9c:\x13#\x14\xb5\x94j\ +[\xa52\x22c\xc2\xcf4\xb9Q3\x13\xae\x9c\xaa\xf4\ +V\xd5I;\x1a\x22\xa6\x91j\x12\ +/N(y\xd02\xda\xac\x05e%\xac\x06\xa6\xabI\ +\x0f\x8b\x8b\x92r/\x18k\x8b\xfcV\xab\x8c\x0e]=\ +Ou]>\xa7\xe5B\xea-\x94h\xa0X\x0e\xd4X\ +b\xbc\x9a\xb1&\x94\xe2\xd4\xf9\x01Q\xa8\xbd\xb9\x8et\ +\xa3\xe6\xd2\xd6\xa8\x93mI\xa1aM\x22\xd4,+(\ +\x86\x16=\x8d\x0d\xc5\xedNe\x14!-\xb5\x18t\x9c\ +T\xb2F\xd1\xaa?\x86\x8e5{R\xb18\x86\x81\xc0\ +\x8f\x11\xe3\xa1\x1a\x83\xadZ\x9a!,&6l\xba\xdc\ +5\xb6\xa4\xe0\xe0\xf0&>-\xb3|\x04\xech\xba\x81\ +\x0c\x92\xcd\xacx[\x13\xbb5\xec)\xc4\xfd\xe7\xa8\xb1\ +\x03V\xfe:S$gm\x19\x8f\xb7*ZzmQ\ +q77\x22\xf5\xc2\xd6\xb5\x87\xd2\xa6\xd5\xd5'\x0e\xd4\ +Z\xda\x86\xe0\x1dj\x0b\x12l4\xa9\x08\xd4W\x1a\xea\ +\x93\xaaI\xbd\x095\x17\xbdHw\x05r\xba\x86^\x86\ +\x96#\x8e\x07\xfbDjJ\x8fR\x9dl:\x8a j\ +d\x91a\x81\xa4a|\xc3(^\xb5\x221\xb3\xc4e\ +\x8aH\xdb3)\xf3\x10-\xa5ZpX\xe7@J\xb6\ +\xa0\x8a\xcf\xc1\xe1\x9eo19Pn\xc6\x9f\x8a\x85p\ +\xf0\xe7\x8ei\x03_@M\xafD\xb7\xd4\xb1f\x02\xe5\ +H\x1dmQqUp\x12b\x1f\x14\xa3;0>\xab\ +\x9b\x8bU\xa2.\xf6Q}t\xa6v\x84\xa7\xa1\xaa\xdc\ +KI\xd5\xbf\x12\xebVB0\x17 }j\xb7\x12 \ +\xca\x88\x06\xa8\xba\x9a\xaf\x80\x9a4:P\x81sG\x10\ +\xf3\x009jh\x22\x96?\x16H\x16\xf6$5X\xc0\ +B`\x8d\xf3\x90]\x8d\xbeT\x97v\x8eH\x1d#.\ +\xc06\x80U\x9c9\x12G\x9dAR\x0d\x99N\xe2\x99\ +\xe8\xa6\xaf\xadGz\xbb\xc3t\xc5\xa8\x03F\xd0\xd55\ +\xbe`@'\xda\xb4\xb8|>\x18\xf1\x18\xf9\x88\xb2\x8e\ +\x95\xd7\x8f\xac\xd5\xc8\xb6\xa3t\x04\x5c\x0dM%\xa4\xf0\ +\xec\xc7a\xbd\x14\x18\x98\xa4uMT\x93\xa5\xf9\xd7M\ +\x9e2r\x5cyO*\xaf\xc5\x0d\xa1\x09\xf8\x8d\xea\xd1\ +\x037z\xa3\xc5\x9b\xefUz-\x5c\xba\x8a(\xb5-\ +\xbb\xd1\xb9\x16\xde\x96\xfbW&\xa1\x13\xa3\x11\x9e=\x5c\ +\x0dT\xec\xc2\xa3\x0ff\x80\xb0\x04\x10\xd6e\xe8h\xce\ +\xfaS\x06\x1aV\x1fhD\xd6\xde`t\x12\x0f\xe6\x8c\ +$\xf3\xa8j\xb0p\x93\x11\x99V\xe0\xea5\xd6\x97&\ +\x1ep\x0f\xdd\x9d*\xca\x95\x9c\xd0\xd3\x1a\x19\x83\x10b\ +m;P\x15`.T\x81\xd4\x8a\xc3H\xae\x22\xbb\xf2\ +\xfdh\x80\xf7\xff\x00\xb8\xd4\x83\x96\xb8\x8ab\x8f\xea?\ +=k\xb2\x83\xb9?-)\xc1\xa5e\xa9\x00\x027\xb9\ +\xda\x9b\x91O#\xefz\xe8\xe3\xc8sn?J\xb1k\ +c\x86\xa6\x5c\x1ek\x83\x98\xe8GAV\x00\xa4p\xf5\ +\xb6\x15Z2\x10\x96>_\x84\xf6#\xf7\xa7\x86\x05s\ +\x00E\x8d\x88;\xa9\xe8k\xb4\xf1\x87Z\xbaP\x91G\ +\xe2\xc8\xe1\x00\xd0_\xe2\xedQ4\xb1\xe1\xe2\xf1$\xd4\ +\x9fJ\xf5\xac\xdcd\xef\x89l\xd2\x01a\xb2\xf2\x15[\ +\x89nN%\x1a\xbd\xa2\x830\x1c\xdc\xd0/\x13|\xb6\ +xQ\xbb\x8d?J\xa4\xaa\xc4\x90\x01k}h\x95$\ +\xbf\xf9on\xb9M\xab?\xaar4b\xc6\xe1\xa4\xd1\ +\xb3D{\xea(\xe4H\xf1)\x95$F\xc9\xb1S\xad\ +\xfaVw\x81'\xfe\xd3\xff\x00\xdahLR\x03p\x8e\ +\x08\xe6\x06\xd4\xea\xc3\x9a\x09nT\xc6\xe6\xdam@\x90\ +\xc8\xad\x90\x8c\xa4m\x98\x81\x7f\xadT\xc6\x89\xe4R\x22\ +\x95\xc4\x8a/\xe5>\xa1\xfc\xd6n J\x04q\xbb3\ +<\xc6\xc0\x9b\x9b\x0b\xf2\xaew\x96|2=\x5c\x0e\x1d\ +\x0f\x88\xea\x19F\xa7\x91\xaepH>\x12g;f:\ +(\xaf=\x04\x86,lb+\x00\xac\x006\xf5\x0b\xd7\ +\xa2\xf1\xd6Y\x99\x0e\x8e\x09\x00r5\xd3\x8f-\x16a\ +yJ\x82]\x83;hH\xd8\x0e\x82\x81\x859\xc6\x96\ +\xa4\xc8r\xa7}\x85T\x16\xe5z\x8aC\xaa\xf8\x83!\ +\xf7\xa7 \x19M\xc8\xd7\xf2\xa1\xb0X\xaf\xd7z\xc9\x85\ +:\xebKk\x03nt\xf6\x04\x8eB\x96\xc8\x09\xd6\xf7\ +\xebQ(\x8a\x82\xb4\xc6\xd3\x7f\xad\x0d\x18\x80E\x04\xca\ +\x0e\x16U\x22\xf6RG\xbd:\xb9\x00,W\xf1\x02(\ +\xc4T\xc3\xcc\x17\x9d\x85\xf5\xedP\x16\x89\x980Ck\ +\x12\xa2\xff\x00J\x86 \x0b\x93A\x09\x1a\xd0\x9bW<\ +\x82\xfbP\x9b\x9dI\xb7aAqU\xbd\xcdJ\x82M\ +\x95o\xec*\x15\x030^\xa6\xabO\x88\x91\xa4\xf0`\ +,\x17m\x0e\xadE\xb8\x96\xe4\xc9\x18\xbc\xb2*v\xbd\ +\xcf\xd2\x85\xed\x942\xe6!\x86\x84\xad\xa8p\xf0$>\ +g\x01\xe5;\xdfP\xb4nK5\xc9\xb9\xa5\x16sT\ +D\x18\x9b\x93\xa5\x18\x17\xf6\xfdh\xd5I6\x03\xd8T\ +\x83j\xaf\xc5?\xcdE\xbe\xcb\xb7J\xba\x88\xc4}\xd2\ +\xab\x9el}+\xfc\xd4\xa4\x10\xc6\xe5\xdb\xefd;\xb3\ +m\xf2\x15f\x8df\xc3.\x22$\xb4l\xca\xb4\xdc>\ +\x1eLCx\xb31\xc9\xd4\x9dO\xb5h4\x84\xefo\ +kP\xc8\xdb\x17\xb9\xcd\xa2\xa8\xe7\xfcU\xf9Z\x04P\ +\x13$J\x11y\xff\x00sH\x9ab[\xc1\xc3\x0b\xb1\ +\xd0\xb7\xf1V\x99T\xaf\xdej\xa3R\xa3D\x1e\xfdi\ +\x18c\x0c\x0c\xeeT\xdd\xbd#\x98\x14\xd4\xe8Pa\x22\ +.\xdego\xd7\xa5U\xb3\xbc\x85\xc9\xb9cszl\ +\xce\xf3I\x99\xb4\x1c\x80\xe5\x5c\xaba\xa5f\x90\xaa\x91\ +\xfd\xaa\xce\x0f\x0c\xd2\xb5\x94X\x0d\xcf!L\xc1`\xda\ +O<\x9eT\xeb\xd6\xb4\x11\x00P\xaa,\xa3\xf3\xadN\ +?h\xb58`!\x5c\xb1\x0bw\xb6\xa6\x8c$G\x16\ +\x19\xa3\x5c\xd2!\xbfBF\xd5*\xb6\xda\x83\x17\x13\xb2\ +,\x88}\x1c\xbfz\xe8\xc1\xe9\x1a\x81e@\xbe\xc2\x99\ +\x15\x936v\xb0\x1a\xde\x86\x09ch\x95\xd9\xc6kj\ +\xa3{\xfbT\x82d\x901\x1a\x8fH\xe4\xbf\xde\xb4\x83\ +\x8bI\x5c\x092\xd9W@\xbc\xc7\xbd\x06\x10g\xc4\x22\ +\xf5aW\xa3\xf2\x8boK\x8a \x98\xd2\xc0yB\xe6\ +\x1d\xb9Ux\xf64\xf6\xcau\xb7:\xa1\xc5Tx\xe0\ +\xda\xfeQ\xbe\xb5t\x1a\xa5\xc55\xc4\xfb(\xa7\x97\x8a\ +*\xb1\xd2\x90I\x00\x8e\x86\xd4\xd9\x0d(\x9b\xfc\xcd\xeb\ +\x9bP\xec\x04A\x98\xc8\xc2\xea\xbb\x0e\xa6\x9f\x8ab0\ +\xce\xc4\xea\xdeQS\x87\x190\x88:\xdd\xab\xa4\xb1x\ +\x94\x81`\x0b\xeb\xcc\xedZ\xf8\x91|\xa0\x06\x16\xd0~\ +\x94\x12\x1e\x94R\x90\xd7\xccozQ\x1d\xcd\x14'3\ +l\x09\xd3\xbdH\x91\x8e\xfb\x0eGZ\x0b\x80,+\x94\ +\x92l\x01&\x84\xe9b\x86OR\x05'\xe2Z\xa7<\ +M\x0b\xe5apv#cW\xb4\x0c\x14\xba\x06;\x02\ +\xd4\x18\xb0\x87\x0cD\x92\x22\x95\xd5u\xbf\xe9E\x86)\ +\x0br\xa2PI\xb0\xd4\xd0#\xc1\xcf\x13\x17\xd4\xd0\x89\ +\x96i\xd3\x0f\x09!\x5c\xf9\xda\xda\x9f\xedF\x93\x90\xa6\ +l\xab\x9aF\x1f\x0a\x0b\xfet\xc1\x95E\xe4\x8aH\x87\ +\xe2k\x11\xf9T\x02\x02\xe5@\x15z\x0a4b\xbbs\ +\xe5LK\xdc9\xc3a2\xf3F\xbe\xfb\xde\x8f\x150\ +\x86E{\x5c\xb2\x80A6\x04\xeaE\xfeB\xa8`$\ +\x11b\xb3\x92l\xe3+\x0e\xd4\x7f\xe2X%\x93\x04\x92\ +F\x0b\x04\x7f5\xba\x01Z\xdf\xf1\x1fI\x96y\xb18\ +\x96X\xbc\xf2\xf3k\xf9S\xda\xb4!\xc1\xb4\x08\x1b\x13\ +1\x9d\x86\xad\x1d\xb6\xf9\xd5_\xf0\x8a4e\xf3\xad\x89\ +\xbb-\xc6\xfaoZ\xc4\x02\xc1\xb9\x8et\xf1\x9b5[\ +\xf0\x11\x95\xb2\xac*\xa8\x1bP@\xb1\xa6\x80\xe1n%\ +r\x07\x22i*\x8f\x1b\x05m\x81%\x1fqn\x86\x9d\ +\x1b\x07%C\xad\xf9\x81\xbdn2?\x12f_) \ +\x1e\xadC\x92[\x1b\xc8u\xdc^\xf7\xa6\x0a%Pk\ +X\x08XT\x91\xe2G\x1b\x01\xa8\xf2\xdb\xf4\xac/\xf1\ +\x06\x0da\xe2\x8f,`\xe5\xf0\x96\xc3\x90&\xbd\x134\ +HIy\x05\x97SmM\xab#\x12\xed\x89\x9d\x8b\xaf\ +\xf9\xc7\xd3\xd0r\x15\xcf\x9c\x99\x8dK\xdb\x1f\x83a\xdc\ +\xced\x91\x09\x8e=M\xfa\xf2\x15\xa4\xcd\x9c\x97\xd8\xdf\ +Z\xb4\xf8o\xb1\xc6\xb0\x0b\xdbrz\x9aD\x82\xcf\xee\ ++\x19\x9d\x1d\xd1\xc1\x8a\x01BM\xa8\x1b0\xde\x9a\xea\ +\x08\xb8\xb3)\xd8\xf2\xaaN5\xae\x8eW\x88\xdd\x0f\xb8\ +;\x1aub\xd3(\xbd\xec>\x94\x0fr\xc0[cr\ +h\xe3\x929c,\xba\x11\xea\x1d*\x06\xe4\xf5\xab\x01\ +L,h\x1cS\xa4\xda\x96\xda\x8a\x11F\x94\xc2\xccz\ +\x1au.ASA\xa8\xcd\x91\x1d\xf9\xaa\x93]n\xe6\ +\xa0\xd8\x5c\x1d\x98\x10k(\xb4\x92\x03\x021\x99\x14\x05\ +\x02\xd7\xd4P\xab\xc3-\xc4fY\x0fP\x9aU\x7f\xb1\ +D\x8f\x98\xb9q\xf8mjy&\xc0\x1d\x00\xd9F\xc2\ +\xb3\xb7\xe9\x10\x8a\xdf\x04\x97\xf6_\xe6\xa3(\xd6\xe0\xff\ +\x00\xd4\xc0~\x97\xa15\x16\xbd%3\x06(V)#\ +BE\x8d\x81\xfdj\xae\x12)`\xc7 e\x076\xc4\ +\x1d=\xea\xd2\xad\xcd\x80\xd4\xd1\xaf\x99\x83(\xb8\x00\xaa\ +w\xeah\xcd\xed\x00\xee@\xae\xb6\x94A,.\xcc\xa0\ +u,)\x89\x16r\x08\x05\x97\xae\x81O\xcc\xefV\x22\ +\xe3\x17Q\xa51\x14\x0dl>b\xa3\x10q\x10\xa0e\ +Hr\xed\xa1\xcdL\xb1\x08\xb9\xc8/o5\x86\xd5\xa0\ +\xe6b\xdb\x9d\xb6\xedBu\xa2\xae\xb7]j\x01\x02\xf4\ +k\x14\x9fk\xf13G\x95T\xaa\x0d\xcd\xbeU \x00\ +\xa5\x98\x85Q\xb95_\x11\x89\xcdt\x8b\xca\x9c\xcf3\ +U\xc8\x85\x8a\x91A\xca\xa7;\x0e\xdeQ\xfe\xfe~\xf5\ +W)&\xe7sF\x05\xa9\x98x\x9eV\xb2\x0d9\x9e\ +\x95\x9fZ\xf0\xb4BNU\x04\x93W\xf0\xb8\x05[4\ +\xda\xb7\xe0\x1f\xbd;\x0f\x1cp\x0b&\xad\xcd\xbf\x8af\ +j\xdc\x98\xcd\xa9\xb5\xed\xca\xdc\x85\x12\x8a\x1b\x82,j\ +V\xca\xb6\x17\xa5\x91\x8b^\xd7\xa6\xa1Q\xccw\xaa\xac\ +u\x00nh\xe3\x00noZ\x95\x1bh\xd4\xe5\x8d@\ +\xbe\xe7\xad\x14^Im{\xe9B\xac-cLR\x00\ +\xd3JP\xc3P\xcb#'\xde\x04\xcc\xa1l\xc0\x1dF\ +\xb5\x05\xa8Y\xc8F#s\xe5\x1e\xe7Ju\x1d\x04\xa9\ +*\x07P@&\xda\xd6~._\x12wn\xa6\xacJ\ +\xe2\x0c)Pv\x19W\xbfz\xce&\xe3S\xf2\xac\xf2\ +\xaaD;_@hKT3Z\x82#\x9etQ\xcd\ +\x85cZj1\xb2\xaa\xdf@\xa0~T\x8cc\x950\ +\xba\x9dC\xe5\xa2\x99\xc6cm\xafI\x91\x81@\xcc.\ +#p\xde\xc3\x9d6\x887o9\xe9z\x16z\x17\xbe\ +r\x07\xd6\x96Y\x7f\x18b>\x1475#\x01\x19K\ +1\xca\xa3sUq\x18\xdb\xdda\x05W\xaf3Mo\ +1\x0d \x04\x8d\x97\x92\xff\x00&\x97&\x1e)\x1f5\ +\xcau\x00iY\xbb\xf0\xacA\x1c\x22\x04&5r\xeb\ +\x98\x96\xde\x8e<>\x1a\xe7\xc8\xc2\xeao\xe6\xedB\x18\ +X(\x16\x0a,(\xe2\xdc\xff\x00\xa4\xfe\x95\xa4\xcc\x8b\ +\x0f\x85Q\xe8g\xff\x00Q\xb5\xa9\xb0\xc5\x04s,\xb1\ +\x87\x05v\x17\xb8\xa0Z%\x22\xf5\x89\x84\xe54W\xa5\ +\xa9\xa2\x06\xb5\x00\x85h`\x1dq\x18v\xc3Hu\xb7\ +\x94\xedY\xe0\x1264P\xb3#\x86\x06\xc4\x1a\xd4\xaa\ +\x8e\x09d\xc3cAcfC\x95\x815\xab\x81\x99\xb1\ +14\x99W-\x81\x16\xf8O0}\xa9\x18\xec2c\ +\xb0\xeb\x22\x0bKk\x829\xf5\x15\x9d\x85i0\xf2\x96\ +\x89\xca\xb6\xc7\xca5\xf7\xebN\xde5\x9f[\xeaH\xd8\ +\x91\xedQ\x1a\x83\x8b\x92O\xc22\xfb\x9bjj\x84<\ +NAa*D\xfa\xea@ \xd5\xdc\x06%19\xc0\ +9_1`\x87r9\xfb\xd6\xe5\x94a\xf4\x9ct\xb2\ + T_*\xb6\xed\xd7\xb5:\xab\xf1\x17UTV\xb1\ +\x0a\x0b\x9d\x7f*o\x82;\x8aL\x90a|\x08\xf7\x90\ +\x0b\x91\xd2\x93\xc2!\xb1\xfbK\xec\xa7\xc8-\xb9\xebT\ +s4\x85\x09\xdd\xc5\xfed\xff\x00z\xda\x08\x22\x81c\ +\x03\xd1a\xf3\xac\xce\xee\x9f\x112x\xb1\x956\xd7k\ +\xf25\x97*\x14%O\xa8\x1dkX\x9a\xa3\xc5\x96\xcc\ +\xae>!\xad\x5c\xe7\xd5\x14_jQ\xfd\xe9\x8fK\xae\ +m@\xe1\xdc\xa6-no\xae\xa3\xad_}\x18\xdb\xad\ +gF\xb9\xa5\x04\xef\x9a\xb4d\xd6C\xefT\xf1R\xdf\ +QK\x90\xe9jc\x02t\x1a\xd2dh\xc1\xb7\x88>\ +@\x90>u\x00\xd0\xbe\xd4K\x94\x93\x96Ekn\x06\ +\xe2\x84\x82\xc4\xdb\xff\x00\x154Y\xde\x85\xaa%\x95\x82\ +\xe6\x8a\x02\xe87s\xcf\xda\xa6\xe1\x91\x5c\x02\x03\x0b\xd8\ +\xd6QN5\xa8jc-\xecoP\x10f\x1c\xfa\xd1\ +\x87@\x14\x9a,\xb6\xa6e\xa9\xcbV-((*\xca\ +K.ak\x8d\xc5\x14q\xc6\xb1\xf8e\xe5u\xe8N\ +[})\x81h\x82\xd3\x80\x0a\xa9\x18\xb4Q*\x9eF\ +\xd75,^\xd7snW4\xc8\x94\x5c\xb1\x04\xf6\x1c\ +\xeap\xe2b\xec\xf3F\xcavO)!~\x94\xe2\x05\ +\xac\xc1\x9dH\xb7\xa1[\xf5?\xc5G:k[5\x83\ +\x02w\xb6\xb4\x06\x94\x1dzW;\xc7\x12\xe7\x96\xe3\xf0\ +\x8e\xb5.\xc9\x14^#\xeb\xf8GST&\x91\xe5\x90\ +\xbb\x1b\x9f\xd2\xb3n$\xe2q\x0d3o\xec\xa3aK\ +B\xc3s\xf2\xa8\xb6\xba\x1av\x16#+\x1b\x90\xaa7\ +5\x8e\xebF\xe10\xe6_;\x9c\xa89\xf5\xf6\xab\xc0\ +\x85\x5c\x882\xa8\xe5J\x04\x9bk`\x05\x80\xa2&\xba\ +H\xc8\xf3\x1a\xec\xc6\x97\x9a\xba\xe6\x95\x86\x86\xa9\xce\x00\ +\xb94\x9c\xe3\xdf\xb0\xa8\x05\xcb^\xd6\xa8b\xc4m\xb9\ +\xe6i\x81\xc5V\xbd\x10n\xf5,Y\x06\x8c=VW\ +\xa6#\x166\x02\xe6\x9d\x06\xe6\xbd\x0e\x22A\x14Q\xb9\ +\x22\xe6Aa}M&lT\x10\x86\xbbf+\xea\xb6\ +\xcbT\xa7\x9d\xe7\x91f\x94\xda\xc2\xf1\xa7\xe1\xee{\xd1\ +y\x19\x0e\xc5N\xd3I\xad\x85\xb4\x03\xa0\xa4\xbb\xd2\xf3\ +\x8044\xb7\x92\xb3y5\x83v\xbd\x1e\x00\xdf\x12\x0f\ +\xe1\x05\xaa\xa3\xc9\xad\x85\xc9\xab\x1c:\xe29\x1e\xfb\xd9\ +E\x12\xf6\xbe-\x96\xd2\xe7A\xd4\xd0\x19T^\xec\x08\ +\x22\xc6\xd4\xb6`5\xa0-}kZ\x12K\x15\xca]\ +\xddG':\x7fz\x92\xeeE\x89\xb0\xe8(\x0bP\x93\ +Y\xd3\x86s\x05M\xa8\x81k^\xff\x00QH\xbb\x5c\ +[\xe7FI#O\x9dZ\xb0\xe5bE\xf2\xe9O\x84\ +\xf9\x88\xec\x7fJ\xac\x5c\x11\xe5;\xd3bb\xa6\xd6\xb9\ +\xca\x7fJ\xd4\xa1H\x1a\x90u\xa5g\xca.A>\xd4\ +h\xc1\xb5\x17\xac4|f\x8cR\xe3\xa6-i\x94\x8b\ +t\xbfz$7r7\xb5V\x92kh\x01\x04\xefz\ +\x98K\x13\xa5\xea\xd3\x8d\x9e\x17)\xb1\x88\x9e\xeb\xefC\ +\xc4p\x8c\xef\xe3\xc0\xb7\xbf\xad@\xd8\xf5\xaaQKk\ +\x16$0=+W\x0f\x88Yb\xf1C\x00\xc3\xd4\x01\ +\xfc\xeb\xa4\xb2\xcce\x93\xa86:\x1a8]\xd2Ux\ +\xdb+\xae\xa1\xbb\xd6\xb4\xc9\x16%-*\xef\xa8`,\ +Ee\xe30\xef\x87\x97+j\x0e\xaa\xc3cE\x98\xa5\ +l\xc5\x8c\x8aX\x83\x94q&\xcc\x80s\xa8\xc4D\xad\ +\x85\x99\xe6[\xb9\x5c\xc7]\xba\x0a\xcb\xe1\xb8\xaf\xb3L\ +I\x17V\x16`7\xab\xd8\xbcv\x1d\xb0\xae\x91\xbb3\ +8\xb5\x8a\xda\xd5\xb9\xcbgc\x19\xc8\xe4H\xad\xa6\x84\ +V\xec\xad\xf7\x82\xfc\xc6j\xc0\x17,\x15E\xc9\xda\xb7\ +J\x02@:\x9c\xa2\xe4\xfbQ\xc1rC0.\x14\x1d\ +F\xa6\xaa\xf1fE\x85\x03\xba\xa9\xb9\xde\x89\x8b\x16&\ ++\xaa\xde\xc2C\xcf\xda\xa3\x1e\x8a0\xcc\xc85\x0d\xb9\ +\xd4\x9b\xf5\xa6\xdd\x81\x9d-\x94\xf9\x9dGMnO\xb5\ +-\x8a\x9f*,\x8c\xd6\xbf\xa6\xc0|\xcd\x1el\xb7*\ +\x02\xf5\xb0\xb5-\xdd\x8a\x9b\xb1\xd7\xbdslXP\xfe\ +8&8\xd9\x13R\x15\xaej\xdb2\x9b\x95\x0e\xc7\xba\ +\xe5\xfc\xcd'\x00\xb6\x89\x9f\xf1\x1b\x0f\x955\xc3\x91\xa2\ +\xb1\xaa\x0aS\x9b\xe8\xd6a\xf8~\x1f\xef@\xee\xd6\xd1\ +\x88\xf6\xa9\x9d\xa2\x89o4\xca\xbd\x86\xa6\x93\x16'\x0b\ +4\xa2$f\x0cv,45j\x826v\xb9\x16a\ +\xb3\x8d\xc5W\xc4<\xc9*\xa6\x22K\xc4\xc7R9\x8a\ +\xb6\x14\xe6 \xe9a\xafj\xad(I\xe5\x12\xbd\xcck\ +\xa4k\xf8\xbb\xd1H\x89\x12!\x0bp\x84X\xb5\xad\xa7\ +E\x1f\xbds\x9b\x9b\xec\x06\xc3\xa0\xaef\xb9\xeb\xd0t\ +\xae\xb5\xf7\xa9\x04\x02{\x0a5Kl*TQ\x9d*\ +\xc4\x10\x95\xd9E\x10\xa9\x03\xa5(9jr\xf7\xa3`\ +\x91\xaei\xa4X\xc7}\xea\xac\xfcJ$\x16\x82<\xc7\ +\xf1>\xdfJ\x91\xc1\x09\x16[\x9e\x82\xa5\xad\x10\x1e4\ +\x89\x1fB\xc6\xb3\xe5\xe28\xa7[fT\xff\x00B\xda\ +\xa8\xcd!$\xdc\x96'rk\x17\x9c\x87\x1bo\x8a\xc2\ +\xb9\x03\xc6g*\xe2\xc7.\xda\xf2\xa2L\x92\xdd\xa2\x91\ +Xs\xedY1\x00\x11F\x9f\x11\x07\xbd\x80\x1f\xa9\xaa\ +\xd2\xe3\x0e\x1aL\x98\x7f3\x83\xe6o\xda\x8f\xdez\xb1\ +\xa3\x8f\x90K?\x94\xddTXUrG3\xf2\x14B\ +H\xf1\x10\x09\xe1\x16\xbe\x8e\xbf\x84\xd0_\xf2\xa3\xd2\xe2\ +\xdd\xad\xf3\xad(PG\x02'\xc5k\x9a\xcf\xc3)\x93\ +\x10\x8b\xd5\xabI\xc8.H\xebZ\xe3\xd0\xa8.A\xf4\ +\xde\x84\xca/\xb5\xaav\xa5L\x09~\x80\xd3\xa0\xdc\xeb\ +\xd6\xa6\xf7\xdf\xe9HE\xb3\x5c\x9d\xa8\xcb\x81\xdc\xf4\x15\ +j0\x9e\xa6\xbb8\xef\xf4\xa5\xa9 k\xa9\xa3\x8c3\ +\x9b(\xf7\xedN\xa1\x06\x1d\x0f\xd2\x89nN\x83\xf3\xa5\ +<\xd8tb\xa2h\xe4\x90|\x0aj\x9e#\x19+\xdd\ +A\xc8\xbf\x84Q\xfaK\xf2\xcc\x90\xfa\x9dX\xfe\x10u\ +\xaa\xf3\xe3eq\x95>\xedz/\xf3Ts\x1a\x90\xd5\ +\x9bm8\xb05UF\x17\x04\x97=\xc0\xe5\xf55\xd9\ +\xd9\x98\x93IlB\xa6<\xc5!\xb2\xb2\x00\x1a\xf7\xb5\ +\x1b\x5c>]I\xed\xce\x8d)s@Ozb\xe1\xe7\ +qp\x84\x03\xcd\xb4\x14G\x0a\x8b\xebr\xe4\xf2]\x05\ +YR\xbc(\xd3Jr\xe8\x0f3\xc8U\xdb\x85@\x89\ +\xb2\x8a\x92HP\xa0\x05\x1d\x05,\x9a|\x0e&\xb8\x9a\ +\x12{\x9fj\x16c}\xf4\xa8\xa5\x9a\xa05\x05H\x1a\ +\xd1\xa8\xc5\xa6!\x03RiK\xbd\x1a\xd2\x8cPsf\ +[\x0e\x97\xa6@\xcc$\xcc\xc2\x96\xa7J4\xadFU\ +q\xe8\xd0\xb9\x16\xf2\xb6\xc7\xb5\x0e\x181\xd4[]5\ +\xad\x06A4F3\xbd\xbc\xa6\xa8\x94x\xd8\xad\xaco\ +\xb1\xe5E\x98bRV\x0dk\x0d\xfaSs\xbd\xafk\ +RaB\xad\x99\x88\xf6\xa3\xbd\xee:\xd1\x0atac\ +\xa8\xa7B\x86\xdeE6\xa5\xa2\xd8\xd8\x00[s}\x97\ +\xdf\xf8\xa2\x965\x93C4\x99\xb96\xc0|\xa9\x82\x9a\ +\x8a\x19\x8em\x02\xe9N\x85\xbc9\x03(\xb6\xba\xf7\xa4\ +\xa3\x1b(`v\xaa\xf2qY\ +\xb4\xcb\x14@\xff\x00\xa6\xf5d\xe00\xe93\x09]\x9c\ +\x8b\xf9F\x80Q\xa2A\x1b}\xd4\x08\xa7\xa9\x175\xc3\ +97\xd1\x7fm\xc5\xa4h\x04\xa5[(-n\xa6\x91\ +6'\x11&\x8f3\x90M\xce\xb5\xbc\xd6Q\x91Q\x00\ +\xb0\xd3(\xa4\xcb\x0e\x1d\xc1\xcd\x87\x8c\x9e\xa0X\xd6\xaf\ +\x1b\xfdZ\xf3n\xecX\xe9\xa9\xe7Qw\x8c\x82\xa7[\ +\xd6\xe8\xc3\xe1QH\x18T\xeeI\xbdV\xc5p\xe8\xe5\ +\xf3\xe1\xceV\xff\x00\xdb<\xfd\xab\x17\x85:\x9c>9\ +q\x11\xa4x\x80\x10\x1dY\xaf\xea\x02\xdb\xfdEX\x90\ +f[\xa1B\x08\xf2\xd9\x86\xd5\x910)\x9e3\xff\x00\ +-U-\xdc\x9b\x9aG\x85&\x5c\xd9\x18\x0e\xb6\xab\xf5\ +b\xc6\xc1x!\x07\xc6\x9d\x10\xf4\x1a\x9aK\xf1(\x14\ +\xda(\x19\xf5\xdd\xcd\xbfJ\xcc\xb5\x12\xa8\xe9G\xee\xfc\ +X\xd2N'\x11\xd2L>^\x99[\xf9\xa7\xae#\x06\ +\xc37\xda2\xf6#Z\xce\x87\x05<\xab\x9a8\x0b\x03\ +\xce\xd4\xd4\xe1x\x92\xd6x\x84c\xabZ\xb5/%\xd2\ +\xebc0j\x09\x12\xbb\x9e\x81m\xf9\xd2\xbe\xdd\x88\x98\ +\xe4\xc2A\x97M\xeds\xf5\xae\xc2\xf0\xec4c4\x8e\ +\xd27A\xa2\x8a\xb62\x85\xca\x8a\x15z\x0a\xd7c\xa5\ +\x13\x82\x9aC\x9f\x118V;\x86\xb94c\x87A\x94\ +\x033\x5cnr\xe8}\xaa\xdd\x8dq\x01W3\xb0Q\ +\xd4\xd5\x91j\xaf\xfe\x99\x87,-<\x84~\x1c\xbb\xfd\ +(\xfc>\x1d\x85\xda\x10\xcd\xd0\x9c\xc7\xfbR\xf1X\x92\ +\xdeX\xae\xab\xd7\x99\xaa\xc0X\x97c\xa2\xeaMf\xd9\ +<8l\xd34\xae[.Q\x1a\x8b[\x99'\xfbR\ +%\xc3\xe1\xf1k\x91\xd3$\x9f\x0b\x8d\x01\xf7\x15\xcc\xc5\ +W3z\xa49\x98t\x1c\x85u\xae4\xac\xd2\xcd\xc1\ +\xcb'\x0f\xc7\x94\x9c0S\xa3\xafQZ3 R\x0a\ +\x9c\xca\xc2\xe0\xf5\x15_\x8f\xa6|<\x13[\xcd\xaa\x13\ +m\xfaU\x8e\x03\x1c\xb3\xe1L3\x02\xa15Fm\xed\ +\xccQ=\xc5\xff\x00N\xe1\x91\xfd\xe9\x97\x92\x0f\xce\xad\ +\x11R\x02\xaa\x04Ae\x1f\x9dA\xda\xbafFPE\ +\x0b\x0b\xd4\x9a\x83R\x09],I\xb5Gm\xbeTD\ +\x8a\x8b\x83Rq\xd0\x0d\x0b\x13\xb2\x8euW\x17\x8dw\ +\x06=\x90\x1fB\xe8>z\xdc\xd3\xf1D\xae\x14\xb86\ +(A\x07oz\xcc{\xe67\xde\xf5\x9eW\x0c\x11H\ +\xe5\xb6H\xd29\x14\xddJ\x8b\x03\xd8\xd3$\x1e!2\ +*\x90o\xe7^ji\x17\x14x\x9c@\xc3\xe1Rk\ +\xa8\x99\x89\x11\xb1\x1b\x0e\xf5\x82\x91{^\xc6\xddj\xcc\ +\x18Wp\x19\xceE<\xce\xe6\xa8`1\xbcRfv\ +\x9b\x13\x85\xc8\x8b\xba\x1e|\xafW\xb0\xdcNS\x88H\ +10\xc4\xcb&\x89*\x8b\x0b\xf7\xa7\x8d\x95v\xb4p\ +\xf86\xb6x30\x16\xce\xc6\xe7\xe9L\x8d\xb2\x05\x88\ +\x15\x03d`\xb6\xbfc\xde\x80\x99\xd4ZH#$n\ +\x11\xac\xdfJ\x15\x9b\x0f\x22\xb24\x99:\xac\x9a\x11]\ +:d\xc6$\x9dw\xef@\xc6\xe7\xd8\xebJ\x93\x17\x1a\ +I\x91\x88\x91F\xce\xa7_\x9d\x13\x9d\x99Neaq\ +\xde\x8d8\x96j\x02\xd5\x04\xdf\x9d\xbbP\xb9\xb7;P\ +\x5c\xcdPj./\xa0\xbf\xb5F`v\xbe\xb4$\xeb\ +z\x82X[KQ\xc8\x22\x8d~\xf1\x82\x9e\x97\xb9\xa8\ +\xc3xS\x12\x15\xcenJt\xbdHq[.\x9b\xf3\ +\xa3\x03Z\x0f\x0b]\xed\xefF\xa2\xca\x05\xefJ\x1a\xd3\ +\x12\x821L\x02\xd5\xa8\xc8\xd2\x98\xf1\xac\xcb\x95\xf4<\ +\x9b\xa5)i\xe9\xbdi3\xe6\x8d\xe2r\x8e5\x1f\x9d\ +\x08\xad9#Y\x93#\xef\xf0\xb7J\xce\x91\x19$(\ +\xc0\x82\x0db\xcc2\xe9\xae\xb9O\x87\xbd\x8e\xa4\x9d\xcf\ +3\x5c\x05\x1c\xdf\xe77\xb9\xb5\x0d\xe9\x02Sp\x15\xaf\ +a\xb7Q\xdcS\x16\xecr\x9fX\x17\xb0\xd9\x87Q\xfc\ +R\x81\xa9\x92\xed\x87p/u\x19\x92\xdb\x83LG)\ +7\x16\xde\xb5\x0c\xf1\x05R\xee\x01 h5\xaf?\x06\ ++\x171\x11\xa1\x05\x8f\xc5m~\xb5\xbd\x87\x89a\x85\ +P\x85f\xb0\xccmz\xd7\x1b\xa2\x9aE\x8e\x86\xa4\x5c\ +\xd2\xd4\xaa}\xd9\xd1o\xe4'oj`\x16\xde\xb6\x04\ +*1\x04XD\x0d\x8b\xeez\x0a\x0cT\xf1\xe1\x94g\ +\xbb;\x0b\xac`jG^\xd5\x9d6&iY\x89\x01\ +.,\x15M\xc9\xf7\xaa\xf2\x90Hw\x10\x99\xb1X\x85\ +\x82\x1b\x95\x1a\x0e\xe6\x9b\x0cq\xe1\x90\xc6\x08\xb9\x1ef\ +\xebK\xc1\xc0b\x87;+\x09\x1fn\xc2\x98\xca\xbb\x9d\ +}\xe8\xff\x00\xa5K\x8a\x801\x02@,$\x17\xf9\xf3\ +\xaa\x97\xd6\xb41\xe9\x9f\x0d\xa0\xd63\x7f\x95g\x1d\xeb\ +\x1c\xbd1\xa6[2+\x8f\x89E,\x92\xcam\xa5\xff\ +\x00:^\x0d\xf3A\x97\x9a~\x94C\xa06\xa8\x16I\ +6\xb8\xd3\xad\x14zJ\xa7\xa1\xa2+\xe4\xca5\xcd\xce\ +\xb8Gv\x00Tu\x8f\xc4n\xb8\xa6p\x80\x17!\x9b\ +\xb9\x06\xa8\xe2#\x9de\xf1\xf0\xec\xc7[\x94\xbd\xed\xf2\ +\xadN-\x22\xc9\x8a|\xa3\xc9\x1a\xe4\xbd\xb7nuD\ +\xe6\x04\x10lo\xbdr\xe5;n\x22qcr\x02\x92\ +\xb7 r4\xce\x16\x10\xe3a2\x80\xc9\x9bQKu\ +\xcf\xb9\xf9\xd0FZ9\x01S\xa84yS\xd1JI\ +\x94\x8e\x9a\x1d-QcA\x81\xc4..0\x09\x02e\ +\x1a\x8bz\xbb\xd3\xc2\x9b_a\xde\xbb0U\xad\xca\x89\ +A'J\x87\x96\x04\xdeL\xc7\xa2\x8b\xd5y\xb1.\xc3\ +,c \xeb\xce\x8d]\xac\xcb$q\x03\x9d\x81o\xc2\ +7\xaa8\xdcC4-)L\xd9H\x01o\xa0\x146\ +$\xde\x89UJ\x95\x7fK\x0b\x1a-\xb4\xe4\x84G9\ +\x91n0\x8fnEM\xe9\x18\x99d\x98\x18\xa3\x85\x94\ +s\x16\xb9\xad\x08\xd4\xa4i\x116*,\xa4\x1d\x1b\xfb\ +\xd4\xb1k\xdc\x92\x1bk\xf3\xac\xe6\xc3\xaa\xb6&$.\ +,\xc5|\xc2\xd5\xd1\xa3\x19\x02\xa0'1\xb5\xa9\xae\x09\ +7&\x9f\x80\x0a\xaad\xb7\x9a\xf6\x14\xc8\x8a\xe21$\ +\x185\xcd\xe6\x7f\x13K\x8d/j\xa9\x81\x91\xd7\x88F\ +\xd9\x89%\xad\xa9\xab\xdcn\xc7\x07\x106\xf5\x1a\xad\xc1\ +\xe2\x0f\x8a\xf1\x18yb\x19\xbe|\xa8\xbf\xec\xa7\x8b\xd2\ +\x8c\xb20\x1b\x03Bh\x98\xdd\x89<\xe8k\xa0A\xa1\ +\x22\x8c\xd4\x11Y@\xcb\xda\xba\xdd\xa8\xab\x8e\xd5$\x04\ +\x8eU\xf0\xa4$\x03\xccr\xd2\xb3q\x11\x15\x95\xa3`\ +\x04\xa9\xb8\xe4\xc3\xa8\xad*\xab\xc4\xcf\xdf\xea\xc4\x1d\x19\ +\x1b\xa7oj\xcf)\xd1\x8c\xf2)|b1/\x08\x12\ +X\xe6\x81\xec5\xe4j\xd4\xaa\xa4\x16]4\xb9C\xb8\ +\xfeGqJ\xc5\xdb\xff\x00G\xc4\xdc\x1b\x1c\xb6\xb8\xef\ +\x5c\xec\xe8\xb3\xb8;^9\xe3\xfe\x90\xdfJ\xb2\x8c\xa5\ +2H\x09[\xdcX\xd8\x83\xd4V~\x12S\x06!d\ +\x1b\x0d\xfb\x8a\xd0\x9d\x02\xbf\x94\xf9H\xba\x9e\xd5\x89z\ +j\xb4\xe3\xc7Lp\xba\xb2\xbbGk1\x1e\xa5\xeb\xd8\ +\xd5Y\x1c\xc91w\xe6nmN\xe0 :N\x8e3\ +(PmV\xc48a\xa8\x83^\xecH\xae\xb3l\xd6\ +J\x9a,3\xe1\xcb@\x09`4\x02\xe4\xfc\xc5'\x0d\ +\x8ah\x87\x87\x22f^\x9b\x11Ws\x90\x00_(\x1b\ +\x05\xd0\x0a\x09\x95f\x89\xfcE\x04\xaa\x92\x18\x0di\xb3\ +\xf8\x80\xb8\x8c3\x9dY\x90\xf5#\xf8\xae\x027\x92\xd1\ +\xb7\x88m}6\x1e\xe4\xd5H\xb0\xd3I\x1et\x8c\x95\ +\xebW0Q48v\x0e\xb6w#\x9e\xb6\xa2[}\ +Tr\x00\xabr\x83/6F\xbd\xbd\xc5\xab\x92\x10@\ +(3\x03\xb1\x06\xf7\xa3\x8c\x957\x06\xb9\xa2\x85\xbe\x12\ +\x87\xf1!\xb5o\x02\xb62\x0f\x1b\x1a\xa9\x18\xf3\x103\ +\xdbaV\x06\x1a\x0b\x04U\x0aW\xd3';\xd3\x22H\ +\xe2\x8f$@\xd8\xfa\x98\xee\xd4V\xaaE\xa8aq\x98\ +\x80\x1a\xf9\x5c\x03\xb1\xa5\xa6l\xf6\xb0\xbfz\xb1\xb8\xcc\ +nT\x8b5\xb5\xb5\xb6?K\x83\x5c\x22\xb9\x00&k\ +\xecF\xb7\xfaS\x80*\xa7\xf1\x0f\xa5\x15\xb5\xb5\x19\x8e\ +E[\xb2\xb0\x1f\xd4\xbf\xbdB\x03{\x90\x05\xb6\xad'\ + \xa6\xa0\xa8QF*\x16\x8dWJO\x10\x8e\xea\xb3\ +\x00\x09\x0aF\xbc\xcf/\xd6\x9e\x9b\x0a\xecU\x86\x02R\ +v\x16\xf9kP\x8c\xccD\x8d\x98\xe4[\xd8t\xd8T\ +\x07\xba\x86\x1c\xe8\x1c\xb2\x5c\xdbQ\xb85\x03E\x03\xe7\ +X\xd6\xf0\xd5j4b\x0d\xc1\xd6\x90\x0d\x1a\xb6\xb5j\ +\xc5\xcc\x10\xf1'U\xb0\x00\x9b\xb5\x85i\x06\xb9\xbdS\ +\xc0\xc7\xe1E\x99\xbdn>\x82\xac)\xae\x93\xa8\xcd=\ +N\x96:\x83\xc8\xd2\xf1R\xb6\x16\x0c\xf1\xc8\x00&\xca\ +\xac/cR\xa6\xa9\xf12\xd3q\x05\x81nB\xd9@\ +\xef\xce\xb5oA\xd8<<\x98\x962;\xb6R|\xce\ +\xdb\xb1\xab\xf0\xc7\x0c+h\xd0\x7f\xa8\xeek\x88T\x02\ +4\x16U\xd0Z\xa2\xe6\xa91\x22F\xcb\xa1\xbd\xb9\x1a\ +\x02t\xa9\x90\xe9@\x08\xd8\xde\xfbUR\x01\xf3j.\ +\x0e\xe2\xb3q\x91\x18\xa6*v\xdc\x1e\xa2\xb4\x89\xd7c\ +I\xc5\xc4&\x87/\xc6\xba\xaf~\xd5\x9b4\xc6|2\ +\x98\xa5\x0e5\x1b\x11\xd6\xae\xddJ\x86Su;Vq\ +\xd0\xdb\xa5\x1e\x12s\x11\xca\xd7(w\x1d+\x12\x9b\x17\ +\xc6\xa2\xa5\xe5\xf0 y\x88\xcd\x94i\xf3\xa1[\x10\x1d\ +M\xd4\xd2\xe7\x99\xfcv\xc2\xb2\xab+\xecm\xafj\xd0\ +\x8c\xb9A\x22\xday\x18\x83\xae\xf7\xd4\x1f\xce\x94\xa3;\ +e\x22\xc0\x9d{U\x8cL\x18\x88\x03\x09\xf5wl\xd7\ +\x1bm\xa5 \xdcj-\x5c\xabmu\xe1\xd8E\xb4m\ +\x035\xc7\xac6\xf5\x9d\xc5\xf0p\xe0\x98frCj\ +\xa2\xda\xfc\xe8\xb0\xf8\x9cBYD\xec\x14k`k7\ +\x13<\xb3\xc9\x9aY\x19\xcd\xf9\xd3\xcb\x94\xcf\x04\x94\xc8\ +1\xd2\xc2\xe1\xa1\x0a\xb6\xfe\x9b\x9a\xd4y\x8e\x22$\x9e\ +\xe4\x86\x1a\x8b\xecy\xd6\x22)v\x0a\xa2\xe4\xec\x05m\ +a\x22hp)\x13\xfa\xaeI\x1d/\xca\x8e\x16\xd3b\ +\x10\x86\x17\x156\x14J\x8a\xa6\xe0W\x11[d&\xf5\ +\xd55\xd6\xa99N\x99H\x0c\xa7\x91\x1b\xd1|6\xb9\ +`6?\x10\xf7\xeb\xefCj\xed\x8dH.\xbaf\x04\ +\x10v \xdc\x1a\xb1\x82\x17\xc3\x9e\xaa\xd4\xab\x82nI\ +\x04\xeeG?q\xb1\xa6\xe0\x0d\xa71\xb6PYt\xe8\ +\xdd\xc5S\xd5|'\x8e\x1f\xf8XV\xda\x96&\xbb\x85\ +G\x93\x04\xd2_Y\x1a\xdfJW\x18\x94M\x89X\xa3\ + \xaa\x0b\x0fz\xbc#\xf0\xa1HA\x07\x22\xd8\xfb\xd5\ +?\xdbW\xc2\xce\xf5\x07j\x93s}(N\xf4\xd4\xeb\ +\x9a\xed\xeb\xaa9P\x9cM\x095&\x84\xd4\x90[\xa5\ +V\xe2\xba\xf8m\xd5H\xab\x06\x91\xc5\x01\xf0\x22\x16:\ +\xdc\xd6o\x85U\x1bA\x1bl\x0d\xc1\xe6;\x8a,R\ +\x99p\x18\x88U~\xf1mp6$k\xa7\xb8\xa4\xb0\ +$\xe5\xda\xd4\xd4kb\x1a;\xe5\x91\x95]\x0f\xca\xd6\ +\xacB\xc0e`\xcdqmv;\xd6\x86\x05\xbc\x5c\x0d\ +\x89\xf3Bm\xff\x00I\xab\xf3G\x06 \x9f\xb4\xc1g\ +\xe6\xe9\xa1\xfaPa\xb8w\x85$\x86\x09D\xa8\xe8F\ +]\x9a\xfc\xb4\xac\xce\x16S\xa7p\x01\xac\xe7\x96O\xde\ +\xae\x1d\xa9\x5c&\x16\x8b\x0b#:\x952\x10\xa0\x11m\ +\xa9\xc4v\xae\xb3\xc0\x00\x096\x02\xf48\xb7\x10\xe1\xdf\ +1\xb3\xb8\xb0\x1c\xed]\x888\x87\xc5\x88\x22\x93\x22\xb2\ +\x06\xf6\x16\xa1\x9f\x06\x83\x0e\xefy\x0b(\xbev\xd8\xf6\ +\xab\xff\x00\x01\x18,HH\xc4r)(5\x04n*\ +\xca\xcb\x86\x94\x12\x98\x80\x00?\x10\xb5\xeb9\x04\x92\x9f\ +\x06%,X\xedj\xb6\x9c9\x96\xe0\xcc\x99\xbf\x09\x16\ +\xfc\xeb2\xdc+H\x84\x0c\xc0\x82\xa7@A\xbd\xe8\xd4\ +iK\xc2D\xd0!\x8d\xca\x92\xc77\x94\xdf\x91\xa6\xd6\ +\xe0\xa9\x14LR8\xcc\xb2\xb6T\x1c\xedr}\xaa\x10\ +(S$\x87*/\xa8\xfe\xd5\x99\x8b\x9eL^#A\ +\xa06E\x1c\x85V\xe0[n&C\xe5\xc2\xc0/\xc9\ +\x9b\xccO\xca\x8aW\xc7\xaa\x91$\xb9!\x91o\x90\xb8\ +VS\xda\x9f\x84\xc3G\x83P\x02\x86\x9bvr==\ +\x85v5L\xd8b\xbe\xa6S\x98\x5c\xdf\xde\x9c\xb9\xda\ +&\x0c7\x14\x8c\xf8\x89\x88\x1a\x8fO\x8bv\xb7\xb5\x1a\ +c\xe6\x89\xc4x\xc8s\x10lX\xe8\xc3\xf9\xa6\xc3\x89\ +VDV\x8eB\xcb`\xc5u\xfc\xaa\xc3,s\xc6R\ +KJ\x9fFZd\xfeU\xbf\xd4\xc2c\x9dsA \ +q\xd0\xe8G\xca\xa4\x82\xa6\xc4[\xde\xa9bxl\x89\ +\xf7\x98f.\xa0{0\xae\x83\x88K\x1d\x93\x10\x9e\x22\ +\x8e\xba0\xf9\xd5\xbf\xd1\x9f\xc5\xe5&\x97\xc4\xcf\xfc\x1a\ +\xc2\x0f\x9av \xff\x00\xa7\x99\xa6F\xd1\xcd\x1ex[\ +0\x03Q\xcdj\xb7\x13\x90}\xa5#;\x04(\x18\xf2\ +k\xde\xd4\xdf\x14\xf5Q\x81\x92\x14c`Yu\xb7\x22\ +4\xa5\xc4\xc4\xa5\xb2\x93\x97M(\xf1\x09\x96Ic$\ +\x8b6p\x0e\xe0\x1f\xefS\x83\x86Y\x17\xd2\x04w\xf5\ +\x1a\xe7\xf5\xa4\x00O#\xfa\xd5\xdc\x16\x16\xd6\x92Qq\ +\xb8^\xbe\xf4\xdc,pD@R\xa2S{\x16:\xff\ +\x00jd\x88T\x16\x98e\x03v#Z\xdc\xe2-3\ +RF\xd7;\x0a\xec\xc0\x10\x0df\xcf6i\xfcA|\ +\xabl\xa7\xb7z\xd1#\xc4T\x90i\x9dsS(\xc3\ +\x90\xf45NV\xf0\xf8\xe1<\x84\xb5f%\xd4)'\ +S\xb5fb\x8en.\xcd`O\x8a6\xe7\xad6\xf4\ +\xa3fM$`9\x1a\x8b\xe9C5\x8c\xcf\xa0\xdc\xf2\ +\xa8\x0cG\x7f\x9dkB\x0b\x5c\x91D\xbc\xe8R\xc4t\ +#\xadp7\xedm\xe8H~}(/\xa5\xead6\ +]MF\xf4T\xa9\xc4`\xce\xa6d\x1a\x8fX\x1f\xad\ +Q\xb0\xadp\x1b=\xd4\x12{U|V\x0f1\xbck\ +\x91\xb9\xa9\xe7\xedY\xb3\xebR\xaaa\xe5xI\xcan\ +\x0e\xe0\xecj\xdc\x13G&$\x16!\x18\xc7\xe5\xbe\xdb\ +\xf5\xaaEH6;\xd4\xb0o#\x80NK\x86\x03{\ +\x1a%\xa6\xb4X9\x1e\x19L\xeaw\x04\x5cR\xfe\xc3\ +\x85c\x7f\xb2\xb0<\xf25\x87\xd2\xa8\xea#\x0f\x1c\xbe\ +^\xa0\xfe\xa2\xa0O#\xe8]\xaf\xefW\xea}\x18n\ +\x22\x0c4.Us=\xc5\x8f\x9bjTq\xe1\xd1\xc1\ +\x8f\x0a\xa0\xff\x00V\xb5\xc0Q\xa8\xd2\x82,\xc4\x9d\x95\ +@\xfc T\x85[\xfaE\x08\xa9\xbd V\xf7\xfa\xd4\ +\x1fz\x8b\xd7jjN;\xee>\x95\xd6=EM\xab\ +\xaaH\x1b\xdbc\x5ct\xa9\xde\xba\xc7\xb1\xa9 \x94H\ +\x8c\xb2\xb6T\x1c\xfa\xd5)\xf8\x89\x91\xbc(\x07\x86>\ +\x16'[\xf7\xae\xe3\xce\xde,q\x0d\x15P\x1bw4\ +\xee\x19\x86\x8e,2\xe2$PY\x86`O\xc0\xbd}\ +\xeb;m\xc8s\xad;\x04\xb0\x9cB\xe2f_\x0f8\ +\xcc\xaa\xdb^\xad\xcb|\xc6\xfb\xd2\xf0\x91\xc6\xf0\x09d\ +\x19\x9f19I\xd1o\xa8\xa6J\xda\x92kp}/\ +\xe1\x14$T\xee/\xb0\xaeS}A v\xa5\x04\x8e\ +\xd4\x07\xc4\xbe\xc2\xdd\xa8\xc99\xf2\xefP\xc6\xc4\x0e\xb4\ + \x9a\x13Fh\x1b@OJ\x10N\xa6\xf5S\x8a\x13\ +&$\x22| \x00\x073W\xa1\x1e#j<\xab\xa9\ +\x17\xde\xa8F\xc1\xb1\x99\xdb{\x97\xfakY\xe4\xd4*\ +\x00|gH\x99W\xc2\xb6yH\xbe\xbd\x05\x0e#\x06\ +&\x97\xc4\x8f\x16\xc5\xfa\xca,O\xcciO+\xe1@\ +\xa9k4\x87\xc4\x93\xdc\xf2\xa8U\xbe\xf5\x9c\xeb\xb4\x98\ +\xe3\x9f\xc1?hB\x19=.5\x0c*\xc7\x0bO\xf3\ +$?\x08\xb0=\xea\xae\xe0\xe5\x1bu5\xa3\xc3\x93\xfe\ +\x04X\x80Y\x89`\xcc\x05\xad\xa5j\x0a\x8cn! \ +\x11\x19\x95\x9f\xc4\x04\xe6\xcd\xa8\xd6\xd4P\xaaN\xb9\xb0\ +\xce$\xed\xb3\x0f\x95'\x8bdd\x80\x85\x0f\x95O\x99\ +\x9b*\x03\x7f\xce\xa9x\xe1\x08\xfb\xc7b\x0e\x9e\x19\xc8\ +\xa3\xdb\xadW\x96^\xd6to\x13\x90\x8ch1\xbd\x8a\ +(\x17\x1dE6\x18\x04\x98p\xf8\x89$\xcd&\xa3]\ +\x87\xb5W\x82\x07\xc6g\x95\x0a\xa9\x07\xcc\x09\xb7\xce\xb4\ +%>}5\xb0\x00w\xa2w\xdaV\xc0\xe1\xcc\x124\ +\x99\xd7.V\x02\xc7RM4\x0f\x95HP\xa2\xc3\xf3\ +\xa1\x93Sn\x94\xe6!\x8b\x16\xd3\x97:b\x85\x08^\ +F\xca\x8b\xbbTD\xaa\x22\xcf!\xca\x8a55C\x15\ +4\xb8\xe9\x84P\xa1\xc8\x0d\x95G\xeai\xb7\x10q\xd8\ +\x97\xc5J#\x8dH\x8c\x1b\x22\x0e}\xebC\x87\xe1W\ +\x06\xa1\x9e\xc6s\xff\x00\xd3\xfb\xd1a0\xf1\xe0\xd0e\ +\x0a\xf3s\x7f\xc3\xd8ST\x5c\xdc\xd38\xfd\xa3\x5cT\ +\xb0\xef\xde\xa7\x0cr\xb9\x16\xbeaj4Z`\x5c\xdf\ +\xcdhk\xa2Q\x1d\xfc$\x09}\xed\xbd\x0e%\x0a\xa3\ +N\xacU\x97\x9f^\xd4\xe8\xc1*o\xb865\x18\x98\ +\xcc\xb6\x86\xf6U7v\xfd\xaa\xc4N\x0f\x16$`\xae\ +\xb6c\xa0u\xda\x9b\x8a\x82,R\xdaQg\xd6\xce4\ +\xd7\xbd(`\xa3Y\x96E\x9a\xca\x1a\xe4\x15\xd4\xd5\x96\ +9\x98\x9bnoT\xdc\xed\x7f\xe3($\xfc6v\x95\ +\x80 !=C\x0a\x87\x03\x11\x11d$\xa4\xeaJ\xf6\ +==\xebG\x89F\xb3p\xf3\x03\xb1\x1e#YH\xe5\ +\xfd\xab\x0b\x86\xca\xd8Lca\xa5\xd1Y\xaco\xf0\x91\ +\xb1\xac^\xae\x19\xda\xc7\x09U\x9es\x1c\xceIx\xd4\ +\xa96\xb1\xb0\x1e[\xf5\xb8?\xecV\x8a\x07\x13\x08\x94\ +\x05|\xb7\xb7\xe0\x15\x93\x82\x85^\x18b\x11\x96w\xb3\ +\x02\xbb\x8dkhD\x90\xca\xcc\xacY\x88\xb1\xd0\x00O\ +3O\x1f\x15#\x11\x83R\xb7\x80\x5c\x8d\xc1\x1a\x9e\xe2\ +\xaa\x9f\x14\xb0F.\xdc\xacN\xbfJ\xd1\x04\x8a\x89P\ +L\xca\xf9\x8aH\x9b5\xafzl\x12\xa94m\x1d\xbc\ +E+\x7f\xc5\xa5hp\xe9VL:Dtt\x04-\ +\xf9\x8a^&\x19\xe6 /\x85e\xd7Ck\x9e\xba\xd2\ +\xf0\x0a\xc9\x8f\x8dX\x10Cs\xa6uSF\x1f\xf3T\ +\x9d\x81\xbf\xd2\xb1a\x19\xf1\xe0\xa9\xd1\xa5\xba\xdf\x90\xbd\ +l\xc2~\xf5}\xedX\xa2\xe9\x8e\x00[\xcb&\x976\ +\xb6\xb5r\xf8\xa3f}fo\xf5\x1a\x85\x153_\xc5\ +}G\xa8\xf2\xefC\xafa\xf9\xd6\x80\xd4),Xy\ +F\xa7\xe4+)\xb8\x96 L\xe20B\x83\xa0\xab\x9c\ +M\xcc|8\xda\xf7v\x00\xd6A:\xdf\xebX\xe5s\ +\xc6\xa4_\x87\x88,\x8d|L6\xe4\x0a\xff\x00\x15/\ +\xc4\xa0S\x95av?\xd4l+8\x11\xf8\x87\xd6\xb8\ +\xe6;X\x0eW\xa3\xf5NC\xf18\xccD\xd7\x19\xb2\ +/E\xd2\x82\x1cn*\x11e\x94\x95\xfc-\xa8\xa0\xe5\ +\xb8\xbf\xb5_\xc0\xe1\xa28A#\xc6$g&\xdd\xa8\ +\x9bj\xb9\x0b\x18\xcc6 \x85\x99|7\xfcCj9\ +0n\x144l$\x07\xf0\x9dh\xce\x03\x0d \xb9V\ +\x8c\xff\x00N\xb4\xb5\xc0\xe2\xf0\xe7>\x12Q'`l\ +~\x9c\xeb]\xfd\x1d+O\x01-\x9d3,\xab\xea\x1b\ +g\x14\xa5L\xc72\x03k\xfd=\xea\xf2\xe3\xca\x9c\x98\ +\xbc1\xb8;\x81cS+`\xe6\x91\x1e\x192;\x1c\ +\xadql\xdamFE\xb5]R\xdc\xc9\xf74@Z\ +\x9c\xf8YF\xa9g\x07\x9a\x9aS\xab!\xb3)\x1e\xf5\ +bEuE\xeb\xaaN\x22\xe6\xa4W\x0a\x9a\x92@\xae\ +\xae\xae\xa5:\xdd\xab\xad\xadMu\xaa\xc4\xa7\xc7c\xce\ +\xb1N\xa2\xc4\xaeF7\xe66\xd3\xfd\xefM\xc1\xb1\x97\ +\x0e\x80\x90R\x15\xd1m\xcc1\x02\xff\x00\x91\xa7I\x1f\ +\x8f\x87\x93\x0f\xcd\x85\xd7\xdcUn\x1e\xcc\x85\xe0sl\ +\xe8\x96\x1c\xb3j~Z\x00+9\xda\xf8\xbd\xc3\xc9+\ +*\x12/\xa3\x0b\xf3\xa2\x90\x5cX\xfeT\x8e\x1c\xc0c\ +,~ TU\x87\xb1\xadO\x05\xf5]\x94\x96\xcb\x5c\ +\x17!\x1a\xe8i\x84s\x1b\xfe\xb5\x04\xa8L\xee\xe1T\ +s5\x12\xda\xec\xd7^[\x9a\x9c\xba\xdc\xb5\xcdLo\ +\x0c\xa4\x84\x97nEmE\x94\x13et$n/o\ +\xd6\xa4Y\x15\xd9FRX\x85Q\xb9;S\x0cM\xb8\ +\x1au\xbe\x9fZ\x8b+\x1b\xe8\xc2-\x06\xb7\x05\x8dX\ +\x95\xe4VL$\x8c\x8c\xb6`\x00!\xc0\x1a\xf3\xfc\xaa\ +\x9c0\x9c\x99\x94\x11\x9bC+h\x00\xe7n\xb5\x7f\x1f\ +\xe4\x81]\x15C3X\xf9F\xbaU+\x97bY\x8b\ +\x1eu\x8eS\xb3\x13)\x0f)a\xb6\xc2\x84\x81mj\ +v\xae5\x92\x18\x904\x81T\x1b\x13\xa8\xbe\xf4\xec\x04\ +\x0a\xd238\xba\xc5\xa1\x1d[\xff\x004\xdc6\x1c\xa6\ +\x11\xe7&\xcd\x94\x95\x16\xe5V2,h\xb1\xa0\xd2\xc0\ +\x93\xd4\x91[\x9cF\x93\xc4\xd0\xe28y\x03x\x9b0\ +\x00r\xac`:\x0a\xf4\x11\xb1W\xb8\x17\xb6\xe3\xf65\ +\x9b\xc5\xb0\x9e\x0c\xbe*)1\xbe\xa0\x9eG\xa5\x1c\xf8\ +\xfdR\x87\x829\x18\xf5\x8c\x1b,\xbeS\xde\xae\x85\x02\ +R:\x0eu\x9b\xc3\xe3i1\xf1\x22\x9b\x12\xe3Z\xd8\ +\x97+H\xc5E\x81&\xd5p\x9d*U\xaaZ5\xf0\ +\xcc\x8d\xe5U\xdc\xd1H\xd1A\x18\x92r@>\x95\x1b\ +\xb5Qi&\xe28\x85\x88-\x90\x1d\x15t\x0a)\xb4\ +GL\xd3\xf1\x0cB\xc3\x12\x15\x8cl9{\x9a\xd0\x82\ +8\xf0\xb0\xf8P\x9dO\xad\xc6\xed\xfd\xaabT\x81\x0c\ +0\x8b \xe7\xcd\xbb\x9a\x9bS&v\x82\x06\xb4\xd8\xd7\ +\x95B\x8bS\x10V\x85\x12\x8dmLAP\x83J5\ +\x14\xc0\x9b\x84\x900\x17\xd2\xe4u\xa3(B\x05:\x93\ +\xe6c\xd4\x9dk\x94\x03\xa3lA\x14is\x18\xcf\xeb\ +_+Xt\xd8\xfd+Q\x14V\xc0\x9bl*\x02\xe5\ +P)\xd7[\xdb\xf2\xb5\x00\x07.\xa3QF%>(\ +@x\xd3\xa2\xdc\xfc\xeb#\x8f\xc7q\x16%E\x8by\ +X\xf7\x15\xaf\xc5t\xc4\x8f\xf4\x0f\xd2\xb3\xb8\xbe_\xfd\ +(\xe6\xdf\xc4\x19=\xf9\xfeU\xcf\x9c\xf5\xae-<\x1c\ +\x0b\x86\xc3\xa1\x0bi\x1d\x05\xcf\xe1\x16\xda\xb8\xdc\x9a~\ +(}\xe6Q\xb0\x00}\x00\x14\x83\xa5i\x97\x0a%4\ +5+R\x18\xda\x89\x81\x91@\x06\xce\xba\xa3_cB\ +\xb4@\xebLC\x0d\x9dD\x83Bw\xecy\xd6o\x1b\ +\x8d\x93\x18f\x1bK\xe6\x06\xb4\x09\xca\xcc\xe1K+j\ +\xe0n\x0fZ\x99\x169\x22\xc9 \x12Fv \xed\xed\ +U\x9b\x0c\xea\xaba\xb1\xf0\xc8\x80b.\x8e\x05\xb3\x01\ +{\xd3\xdal(\x5c\xc7\x13\x19\x03\xa6\xff\x00J\xac\xfc\ +2&k\xc7\x88\xca:2\x9b\xfeT\xa9\xb8d\xf1\xdc\ +\x96\x8f/\x22Z\xd7\xa3yE\xd0x\xa6)g\xcb\x1c\ +W\xc8\x97\xd4\xf3\xaa\x95c\xecs\x88L\x9e\x04\xae\xa3\ +\xf0.\x9fZB\x14u%C\x02\xbe\xa5a\xa8\xac]\ +\xfa\xd4\xc7\x0b\xd7X\xd4\x8a\x90<\xb7\xa0\x86\xc6\xb5x\ +m\x9f\x87-\xbe\x06 \xfc\xeb/\xe5W\xf8\x1c\x83\xc4\ +x\x0f\xfc\xc02\xfb\xd6\xb8\xfa/\x8bV\xae\xb5\x19\x17\ +\x14$k]\x18C\xdaE\xc9*\x89\x01\xd2\xcc/U\ +\x8e\x0b\x0e\xf2\xfd\xdeh\xc2\x12I\xbd\xc5\xc8\xb5\xaa\xd1\ +\x16\x89\x8el\xbb\x00}\xcd\xaa]B\x9c\x8a<\xab\xa0\ +\xa3\x16\xb3\x1f\x0b\x8b\xc1\xfd\xec\x12\xe6A\xbd\x8e\xde\xe2\ +\xad`1#\x15\xf7N\xa0H\x06\x9ah\xd5e\x09V\ +\xb8\xff\x00\xcdQ\xe2xQ\x1f\xfcL\x07(\xbf\x99\x7f\ +\x09\xa33\xc3\xba\xb0\xf8X\xe4\xbeQ\xe1\xb7>\x9f\xda\ +\xa9\xcc\x8b\x13e\x92DS\xca\xe7z\xb5\x83\x91\xf1\x8e\ +\xc9,\x8cr\x0c\xc5A\xb6pv?\xcf\xb5I\xc2\xc6\ +\xd8\x93\x11\x04\xc2\x101\x07R/\xd2\xac\xdf\x12\x93)\ +Sc\xf9W\x0a\xb1\x8d\x84\xc5/Ua\xe5\xb7JO\ +\xb5\x18\x5c\x05u\xaaF\x82\xa0\x1b\xd2\x93Pjk\x8e\ +\xa2\xa4\x10J\xb0a\xb8:U>4\x1a,D\x8e\x9e\ +Q\x94I\x19\x07\xa6\x9f\xb8\xabmS,Qb\x03D\ +\xe3\xccQB\xb5\xbd7\xfe\xe0Vl\xde\x908d\x8b\ +\x89\x9a)\xd2\xd9\x81\xb4\x8a9\x1e\xb5d\xd7\x9e\xc1\xb4\ +\xf8N&\xa2\x13f\x12e:\xdbJ\xf4\x122\xb4\xbe\ +\x22\xb7\x92A\x99}\xaa\xe1v\x1a\x9b\xd28\x92_\x07\ +\x985\xad%\xed\xd7J+\xf9\xf3\x0d@\xa6\xe4\xf1<\ +\x10\xc3\xca%$\xdc^\xfaS\xe8'\x0c|\x18\x11\x14\ +\x10\xc4]\x88\xefL,X\x11 \x0e?\xa8^\x80\x7f\ +\x9b\xf3\xe7L7\xbdQ\x06\xd1e\xcb\xe0Gn\x9a\xff\ +\x005 \x8b\x05\x00(\x1b(\xda\xa6\xc6\xa4\x0b\xd2\x89\ +\xe2Z`\xd0\x85\xbd\xa4?\xa5f\xc6r\xb5\xcf=\xeb\ +W\x1e?\xe1\x93\xff\x00\x90\xfe\x95\x9c\xa8\x19\xcfj\xc7\ +/LA\xd7P4\xefE\x86\x88\xcb\x88X\xee\x06c\ +\xc8^\x8a\xd5k\x85\xc6s;\x80n\x05\x87\xce\x896\ +\x9a\x9e \xfe\x1e\x1f\x22\x9d$\xd0\x0bk\x94T`\x09\ +\x93\x0cU\x8d\xccgK\xf4\xa8\xe2eO\x86\x80\xdd\x94\ +\x1b\xd8\xde\xd50\xc5.\x12\xd2\xba\x82\x8e,@5\xaf\ +\xac\xfc7-/\x89\x18\xd3\x07\xe0\xc8\xda\xca\xeam\xd0\ +u\xab\x12\xbcP\xe1\x8e \xd9\xd7\xe1\x1dMcb\xa5\ +y\xe62Hu?\x956\xa8L8\xf90\x9c\x5c\x09\ +\x11\x04q\xb7\xa4\x0d\xbb\xd6\x8c\xdcEP\x0c\xb8T7\ +\x17\x0d\x98\x91\xee+3\x8a\xa7\x89\x83I\x88\xbb#e\ +'\xb7*w\x0e\xe1\xdcV\xc1Q\x13\xc3\xb5\xfe\xf0\xf9\ +G\xf7\xaer\xf2\x97#]\x02w\x9b\x15\x88\xcc\xe73\ +\xb6\x80\x01\xfaV\xbe\x12\x0f\xb2a|/\xf9\x8f\xac\x9d\ +\xbbQ\xe0\xe0L9 F\x04\xfb\xdc\xdfo\xe9\xa2\xb5\ +\xeb|x\xe7u\x9bAkX\xd1\x01S\x96\xedo\x99\ +\xa3U\xad\x0dB\xad5V\xb9\x16\x98\x05A\xca(\xd4\ +kP\xbb\xda\x88\x9bh\xba\xb7\xb6\xd5\xa4$Zj\x8f\ +0\xe8\xfeS\xd8\x8d\x8f\xedI\x89\xb3\x1f1\xdb\x96\xd4\ +\xd8\x8f\xde*\x83\xe5\xccH\xee@\xdb\xf3\xadD\xe3{\ +nhZ\x9aF\x9a\xd00\xa93x\xb7\xff\x00\xaa\x1f\ +\xe8_\xd2\xb2\xb8\xf3\x11\x85\x82;h\xc4\xb9\xf7\xda\xb6\ +x\xba}\xea=\xfdK\xfaiY\x0d\x0e\ +\xcdp\x7f\xee\xae\x5c\xe7U\xae-\xc9\xbc\xc1_l\xea\ +\x1b\xda\x90\xc0\xde\x8b\x87\x16\x9f\x85\xc0Cge\x05\x0d\ +\xbb\x7f\xe6\x89\x81\x07Q\xaf\xb5j\xff\x00Y,/Z\ +!]Q~\xd4!\x0fz\x9a\x10jA5!\x02A\ +\x04n)DM\x16+,\x00\x15\x94f\x00\x8b\x81L\ +\x152\x5cF\xd2\xa5\xc3\xc6\xbe\xe0\x8e\x96\xa5\x03\x10\xf8\ +\xc8\xe2-\x9a5\x00\xeac\xb5\x1e\x192\xc2\xae|\xce\ +\xe2\xe4\xb6\xb6\xaa2K\x88\x9dns\xba\x83\xf0\x8d\x05\ +]I\x84\xa1r\x02\x0a\xd8\x15;\xe9T\xa4\xd0\xd2f\ +\xcd\x98\xdf\xad\xea\xbc\xb0&#\x89J\x19r\xda\xf7u\ +\x1a\xfc\xea\xc6f\x12\x00\xaas|+\xd7\xdf\xb5tq\ +\xac \x859\x8b\x1f3\x1eg\xb7j}\x0c\x9cf\x19\ +\xf0\xf2\xe5:\xa9\xd5XliV5\xbb<^>\x19\ +\xa2\xe7\xba{\xd61[\x12\x087\x15\x8e\x5cq\xa9A\ +m-V8@\xff\x00\xf2P\xff\x00\xaa\x92l7 \ +{\xd5\x8e\x12?\xfc\x8c'\xfa\xaa\x9e\xa6\x89\x02\xdaR\ +\xcd1\x98l\x01'\xda\x81\xae\x01\xd0V\xd9q\x00\xca\ +\xa9sd_\x10\x81\xcc\xec*\x05\xedm\xed\xce\xa1\x81\ +*\xac\x1a\xefke;0\xe9\xd8\xd3\x22\x0aE\x95\x80\ +#p\xda\x11R\x0d\x8d\x12s\xd02\x9d\x18r4\xc5\ +\x8c\xf2\x19\xbd\x8d\xe9%l\xe5FR\x06\xecN\x9e\xda\ +njL\xfe*\x92`\x18b\xa0>Tk.\xbb\x83\ +\xc8\xfc\xe9\xdc\x1b\x1d\x1e6Is0I\x99uRt\ +6<\x8dY\x9a\x05\xc4\xc2\xd8v\x94\x80\xe2\xd6\x0a\x00\ +\xbfZ\xf3\x85%\xc0c\xd9\x1d|\xcbp\xc3\x91\x15\x8b\ +o\x1b\xbf\x0c\xed\xe9\xa7\x89\x9e\x06F\x1c\xae\xa6\xb3-\ +G\x82\xc5\xbcyd\x8d\xd8\xc4\xc7U4\xdcZ\x05\x9c\ +\xd8h\xda\x8a\xd6\xea\x22\xc6\xbb-4-qZ\x16\xaa\ +\xe3\xe6\x92\x08\xd0Dr\x97\xb9'\xb7J\x94\xc5a\xde\ +0\xce\xf9Z\xde`\x16\xfa\xd3\xa7\x8e9#\xfb\xc4$\ +\xa0\xd0\x83jK\xe0bq\xe4c\x1b\x7fV\xa2\x8e\xf7\ +\xa3\xd3\x96H$l\xb1\xcbs\xfdB\xd4J\xd9\xe51\ +#\x03\x95,Ort\xb5V~\x1f8\x04\xfd\xd3v\ +V\xd7\xe9N\xc0\x14\x83\x06\xceHV\x8e\xec\xc0\xef\xdb\ +J;\xde\xd3;\x10VO\xf11\xc8C^O\xae\x95\ +\xb2a\x11\xc3\x1cm\xeaD\x00\xf65\x99\xfe\x1e\x84\xcb\ +\xc6\x17\x12\xea\x08MM\xf9\x9a\xd6\x931\xb9*nh\ +\xe1\xe6\xaaQ\xb2\xadB\xc8J\x94\x07)$\x10z\x11\ +\xb5\x11@9k\xd6\x81\xd4\x12,5\xad#4 H\ +\xabl\xdb\x8e\x87\x98\xa1f\xb1\xb5\xa8\x92\xd7$yI\ +\xdfK\x86\xf7\x1f\xb8\xa9\xb5\xcd\xadf\x1a\xe5\xbe\xfd\xc7\ +ZR(\xd4P\xae\xf4kP\xa0\xc7.l\x18#\xe1\ +}~u\x9c\x10.\xa0\xed\xbdi\xe2Al\x1c\x80n\ +,O\xb5QP-Y\xbe\x99B\x12\xe6\xdbs'\xa5\ +\x5c\xc0%\xf0\xcc\xc4\xb2)`\x02\x8d\x0b\x0b\x1dOJ\ +B\x80\x14+Z\xcer\xfc\x86\xa7\xf2\x1f\x9d\x5c\xc0\xdd\ +\xa0\x91\x8e\xe6K\xfeUH\xa8\xac\xa5r\x18\xd3/\xe1\ +\xcbP\xd8D\x98\x04\xf1dP=*u\x02\x99aL\ +\x87\xd6GU }\x0di\x96\x0e5\xc3HQI\xca\ +\xa4\xdb\xa0\x1b\x0f\xd2\xff\x00:\xb1\xc3\xb8xx\x84\xd8\ +\x82\xc1\x0f\xa5F\xedT\x9c\x10\xc5H\xd4\x1b\x1a\xdfm\ +Bd\xb6L\x82\xc4{V8\xf7u\xaaRA\x86\x8d\ +r$\x00\x5c\xdf19\x884\xb4y\x12_\xb3\xce\xd7\ +\x0d\xe8n_\xf8\xa7\xb0#\x98?\x95-\xf2\x99!r\ +@\xc9%\x89'`\x7f\xbdl9\x94\x98\xd8\x0dY|\ +\xcb\xae\xc4W@\xc92\xe7B\x01\xf8\x94\x9d\xa8\xe2\x17\ +\x97/3py\xf6\xac\xf8\x96!#\xac\x8c\xdeQ\xe5\ +\xcbE\xaa4\x02\x1b\x92t'\xb7*%[Ta\x03\ +\x8c\x22g7'Q~B\x9a\x10\x9f\xeemZ\xc0\x85\ +\x14\x5c\xab\x88#q\xa7#\xd6\xa4R\x9c\xbe\xaa8\xf4\ +[\x03\xcc\xdf\xebAmk\xaeCyM\x89:\x8a\x90\ +\xa6\xb6\x9dM\x1cyd\x87+r\xe69\x1e\xb5 \x8e\ +\x82\xb8\x1c\xa4\xe5\x1a\x1d\xc5i%$a'\x85=\xae\ +}/\xc9\xa8\xd9M\xedo\x95-\x99]2\xb4d\xaf\ +}\xc5\x04s\x98\xdf\xc2\x98\x92\xa7\xd0\xc7\x97j\x90x\ +\x9a_\x0c\xadoKkX\xfc`[\x09\x0c\xd9o\xe1\ +K\xa9\xe87\xfdks\x1a\xc8 x\xdd\xd41\x17\x00\ +\x9e\x95\x95\x8cH\xdf\x014fE7\x00\x8b\x1eco\ +\xd6\xb1\xce\x18\xff\xd9\ +\x00\x00*\x0f\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00d\x00\x00\x00d\x08\x06\x00\x00\x00p\xe2\x95T\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\ +\x95+\x0e\x1b\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e\x1c+\xec\xa5\xbbn\x00\x00 \x00IDATx\ +\xda\xed\x9dy\x94]U\x9d\xef?\xfb\x0cw\xae95\ +\xa5\x06*!!\x09\x14\x15\x84\x88\xd1\x00\x09\x08\xad\x08\ +\x1d[\xec6`\x0bH\xd3\xf0\x1ch\xc4\xf5\xda\xd5O\ +xH\x83\xda\x93\xadH\xabK\xb4\x15Q@\x9f\xd84\ +\xad\x08\xd8\x0e\xc8 $\x81\x8c\x18\x92\x9a\x92\xaaT\xaa\ +\xea\xd6p\xab\xea\xce\xc3\x99\xf6\xfb\xe3\xd6>\xb9\xc9\x13\ +\x03a\xce\xcb^+\x8b[\xdc\xe1\x9c\xbb\xbf\xfb7}\ +\x7f\xc3\x85\xe3\xeb\xf8:\xbe\x8e\xaf\xe3\xeb\xf8:\xbe\x8e\ +\xaf\xe3\xeb\xf8:\xe6\x97x3\xddLuuuW&\ +\x931\xa5\x94^]]\xdd\xfb\xd6\xacY\xf39\xd34\ +]\xd7u\xe5\xfe\xfd\xfb[V\xacX\x81\xe7y$\x93\ +IZ[[)\x95Jh\x9a\xc6\xae]\xbb\xb0m\xbb\ +\xfc\x85\x84@\xd3\xb4\x83_P\x08\x0bp\xd5c\xc30\ +\xfa\x00\x0d \x1e\x8f\x7f0\x1e\x8f\x8f\xa8\xd7\xb6\xb6\xb6\ +\x12\x8f\xc7\xdf\xd0=0\xde\xc8\x8b\xb7\xb5\xb5-\x9d\x9b\ +\x9b{\xa7\x94\xd2\x03X\xbe|\xf9\xb7\xdb\xdb\xdb\xc3R\ +J\x86\xf6\x0d\x11\x0c\x06\xa5\xa6i\xc2\x95.\x86a\xe0\ +8\x0eH\xc9D>A\x87\xd1A&\x93\x01]\x90v\ +\xf2\x9c\xbd\xea\x9d\x00L'\xa6\xd1\x84\x86\xae\xeb\x00\xe8\ +\xba\x1e\x90\x12D\xf9\xe8\x85\x813\xd5\xf5\x1b\x1b\x1bw\ +\xae\x5c\xb9\xd2\x11B\xb0g\xcf\x1e\x86\x87\x87\x1b\xdf\xe8\ +C\xf9\xba\x03RUUef2\x19\x1d`vv\xf6\ +\xba\x8f~\xf4\xa3\xd7\xab\xe7\xfa\xfb\xfb\xcb'\x5c\x08\xf2\ +\x94\xb0J\x96\x10\x9a \xe7\x14\xf0<\x0f\xcb\xb2\xc0\x83\ +\x9c[\xc4\xb2,,\xcb\xc2\xd6]\x1c\xd7&\x9dN\x03\ +p`z\x9c\xd3N\xea\xa6X*\xa1\xeb:;v?\ +OU\x93\xc0\x9b\x0b!\x84\x00I\xf9\x9f\x00\x04\xb5\xea\ +\xda\xd1h\x94\xee\xee\xee>@\xb8\xaek\xee\xd9\xb3g\ +\xd1\xff\x17\x80\xb4\xb5\xb5=\xb8x\xf1\xe2\x8b\xa4\x94\xf4\ +\xf7\xf7333S>\xf9@\xc9.o\xb2\x00\x8a\x9e\ +\x85\xed\xd8\x08!p\x1c\x07)%\x96e!=\x89\x94\ +\x1e\xb6mcY\x16\x8e!\x91\xe0\x7f\x86\xf4\x1a\ +\x8f\xc7\x07\x8e\x19@\x1a\x1b\x1b?X(\x14\x22\x80\x15\ +\x0c\x06\x97\xc7b1\xa4\x94\x98\x01\xd3\xdfX\x00\xc7s\ +(\x95J\xfe\xc6Z\x96U\x06BZx\x9eW~\xce\ +\x03)%\xa5R\xa9\x0c\x88\xe7\x95\x01,\x16\x01p\x1d\ +\xd7\xffLW\xd3\x91\xea}@\x7fo\x1f\xe77\x9eG\ +n4\x87)\xa0\x14M\xb3\xa0C\xc3\x89\x87\x909\x13\ +t\x09\x9aDh\xc8\xb3\xce:\xeb\xb7\x00\xa6i\xf2\xe8\ +\xa3\x8f\xde\x09|\xfc\x98\x01d\xc1\x82\x05\xf7\xbf\xedm\ +o\xd34Mc\xef\xde\xbd\x94J\xa5\xf2\xa6\xba6\xb6\ +eW\x80P\xdeh\x81@J\xcf\x07\xca\x96\xb6/!\ +x\x12\xcf\x93\x077}\xfeD\xab\xd7\xba^YzJ\ +\xa5\x12\xba\xa6\xfb\xcf\x09!\x90\x9e\x87\x87\x87+]\x12\ +\xb33\x88%3\xa4\xa4\x09\x0b%\xd2\x168\xc9\x00n\ +\xca\xc0K\x1b\xa2l\xd5\xc00\x0c\xea\xea\xeaNok\ +k\xbbE\x08\xc1\xec\xec\xec\xf3ccc\x0f\xbe\xe5\x00\ +\xe9\xe8\xe88\xa3\xa6\xa6\x86R\xa9\x84\xe7y^\xa1P\ +\xd0t]\xc7u\xdd\x83\x00H\x0f\xcb\xb6|\x0fI\xd9\ +\x09!\x04\x9eGY\xedH\x89\x8d\x8d7\xbf\xd1\xd2\xf5\ +\x90B\xfa\x9b\xeeI\x81@\x1c\x04\xc4=(!\xba\xa6\ +\xf9\xd2$\x84\xf0\xc1\xb1m\x9b\x03\xc3#\x9c\xbb\xe8\x5c\ +dR\xe2II6\x92\xa2a\xa9\x8e7\x17B\xda\x02\ +iiH\xab\xec\xaduvv\x9e\x09\x9ci\x18\x06;\ +v\xec\xb8\xa7\x12\x90W\xdb3{\xad\x00\x09477\ +o\xe9\xe9\xe9\xc1q\x1c6o\xde\x8cm\xdb\xb8\xae{\ +P\xf5\xcc\x03`[\x07U\x96\xe7yX\xae[6\xbe\ +\xa0\xc0\xc4\x16\x0eBB:\x9d.KQ\xb0D\xb1X\ +$\x9f\xcf#\x1d\x81DV|\xc6A@4\xa1\xe1y\ +\x15\x122\x0f\x88\xfa\xdcT*\x85\xe7yL\xa7f\xd1\ +\x16M23rX\x14`x\xd8\x89\x00\xd6\x810B\ ++\xbb\xd4\xb3\xb3\xb3+[[[o\x06t\xe0\xe1x\ +<\xfe\xdc\x9bVB\xda\xda\xda\x9a\xc7\xc6\xc6j\x80\xa0\ +\xfa\xc2\xae\xeb\xfa\x1b\xa1i\x1a\xae\xeb\xfa\x9b'=\x89\ +\xed\x1c\x04\xc4\xc5#\x9b\xca\xa0\x09\x0d\xdb\xb3\xc8\xd8\x19\ +\x1c\xc7\xc1\xd1=bf\xc4WY\x8ea\x93\xcdf\xc9\ +\xe5rHG\xe0x.sss\x00\xe4\xbd\x22\xb6m\ +Q(\x14\xd0\x84@\x9a\x07\xc1\x92\xe0{g\xbe\xd7\x06\ +\xe4\xe6\xd2,k<\xcd\xb7\xe1\xe3\xc1q\x16\xad\x08\xe2\ +L\x86qsAd\xa71o[$\x8b\x16-\xea\x01\ +z4Mc\xfb\xf6\xed\x8975 \x85B\xe1\x9eK\ +/\xbd\xf4\x82\x5c.\xc7\xe8\xe8(\xb6m\xfb\x1e\x92\x0a\ +\xe2*7\xc2\x93\x92\x5c.G.\x97+\x8bU8\xe8\ +\x9ffWs1L\x1d\xcf\xf30\xe4\xc1\x80\xafP*\ +\x10Lk\x18U\xe5[\x176\xe8\x9e@3\xca\xeaE\ +w\x05\x99L\x96t:\x8d@\x10\xaa\x8fP\xb4\x8b\xf3\ +\x12\xe2\xf9\xce\x80\xef\xb5\xc9\xb2\xfa+\x96\xca\xaf\xd9\x9f\ +\x9d\xa2\xed\xe2\x14\xd4\x070:%\x86\x06^Q\xc3M\ +\x1a83\x012\xcfU\x81&\xd14\x8d|>\x1f\x01\ +j\xe7\xf71\xf1\xa6\x03\xc4\xf3<-\x18\x0cR(\x14\ +|\xd5\xe48\xcea\xb6\xc1\xa3P(\xcc?v\xfd\x13\ +\x0b\x10\x8c\x84\xd0\xe6\xf5~ \xaf!\xea4\xce=\xf7\ +\x5cfgg\xe9\xeb\xeb\xe3\x82\x0b.\xe0\xf2\xcb/\xe7\ +\xce;\xefdpp\x90\xcb/\xbf\x9cX,\xc6\x9dw\ +\xde\x89\xa6itvvr\xe0\xc0\x01tC\xc70\x0c\ +\x04\xe0\x14lr\xb9LY:\x1d\xd7W\x91\xea\x9e<\ +\xcf\xf3\xed\x13\x80\x91\xb4\xf1\x1e]DB\x96%\xca\xd3\ +\x9d\xb2-\xb24\x04\x02\xdd\xf4|7\xb9\xa7\xa7\xe7\x9f\ +O=\xf5\xd4\x7f.\x95J\xfc\xeaW\xbf\x12o\x0a@\ +\x9a\x9b\x9b\x9b\x84\x10\x0f\x01\x05\xcb\xb2z\xd4\x06+\xa9\ +\xa8TY*\xa6\xc8f\xb3h\x9a\x86eY\x18\xba\x81\ +a\x94oC\x93\x82\xf7\xbc\xe7=\xdct\xd3M\x5c{\ +\xed\xb5\x9c{\xee\xb9\xbc\xfd\xedo\xa7\xbb\xbb\x9bu\xeb\ +\xd6q\xcb-\xb7\xf0\xfc\xf3\xcfs\xe5\x95W\xf2\x9d\xef\ +|\x87w\xbc\xe3\x1d\x5cp\xc1\x05\xdc\x7f\xff\xfd\xdcx\ +\xe3\x8dtvv\xf2\xcc3\xcfp\xcf=\xf7PSS\ +C4\x1aezz\x1a\xd70\xd04\x0d\xcd\x12d\xb2\ +\x19\xb2\xd9\xac\xaf:=\xcf\xf3\x1f;\x8eC8\x12&\ +\x181\xd14\x8dg\x8b{x\xef51\x04\xe5\x80\xd2\ +J\x988\x13a\xac\x91\x10\xeel`\xde1\x91\x04\x83\ +\xc17\x8f\xca\x9a\x9c\x9c\x5c\xf4\xfe\xf7\xbf\xff\xccX,\ +\xc6\xe6\xcd\x9b)\x16\x8b\xb2T*\x09\x05\x82\xeb\xba8\ +\x8e\xc3\xdc\xdc\x1cB\x08t}\xfe\xf4\x0a\x81\xe6iH\ +$w\xddu\x17\x89D\x82[o\xbd\x95\xab\xae\xba\x8a\ +\xbe\xbe>\xce9\xe7\x1cv\xec\xd8\xc1e\x97]\x86\xe7\ +\x95}\xd0o}\xeb[\xdcp\xc3\x0d|\xe1\x0b_ \ +\x91H\xd0\xd3\xd3C\xb1Xdff\x86\x93O>\x99\ +\xde\xde^:;;Y\xbcx1\x9f\xfa\xd4\xa7X\xb5\ +j\x15g\x9f}6\xae\xeb\xf2\x9e\xf7\xbc\x87\x87\x1ez\ +\x88R\xa9t\xd0Y8\xcc\xd1p\xe7\x1d\x0a\xdb\xb6I\ +&\x93\x94\x92s\xec\xb87\x87\xe7I\x14\xfd\x22\xca\x11\ +>\xd6\x8c\x815\x11\xf0\xf9\xb3\xea\xea\xea\xafK)\x09\ +\x87\xc3\xcfMMM}\xffu\x05\xa4\xb9\xb9\x99\xc9\xc9\ +I\xf5g\xde\xb6\xed\xcaS'\xd4\xc9S_XyP\ +\x0a\x90\xaa\xaa*.\xbd\xf4R~\xfc\xe3\x1f\xf3\xde\xf7\ +\xbe\x17!\x04\x17]t\x11\xdf\xf8\xc67x\xf0\xc1\x07\ +\xf9\xc8G>\xc2\xf6\xed\xdb\xe9\xef\xef\xe7\xea\xab\xaf\xa6\ +X,\xa2i\x1a\x0f>\xf8 ?\xfc\xe1\x0f\xf1<\x8f\ +E\x8b\x16q\xf1\xc5\x17c\x9a\xe5\xd3|\xc5\x15Wp\ +\xd9e\x97\xf1\xe8\xa3\x8f\xb2`\xc1\x02\xaa\xaa\xaa\x08\x85\ +B\xe4r9\xee\xbd\xf7^\x22\x91\x08###\xec\xdf\ +\xbf\xdfw\xa7\x93\xc9$\x8e\xe3\xf8\xae\xb2\xeb\xbah\x9a\ +F\xa9T\xe2\xc0\x81\x03\xac?\xff\xa22\x18H\xa6\xf4\ +\x04\x9d+L\xbc\x94\x89\x9b1\xf1\xaaMd\x87\x86\xd0\ +$\x18R\x22\xf9\xa4a\x18l\xdd\xba\xf5G\xaf; \ +\x93\x93\x93466\xfe\xd5\x89'\x9e\xf8\xdd|>\x8f\ +\xeb\xba\x12\x10\x95~~\xa5\x97%\x84@\x08\x81\xb2/\ +\xb7\xdf~;\xd9l\x96\xb5k\xd7\xf2\xf4\xd3O\xb3~\ +\xfdz\xf6\xec\xd9\x83\xe38<\xf6\xd8c<\xfa\xe8\xa3\ +\xe4\xf3yZZZ\xfc\xd3\x5c(\x14X\xb0`\x01\xa1\ +P\x88B\xa1@*\x95\x22\x1a\x8d\xfaj#\x10\x08\xf0\ +\xc0\x03\x0f077G\xa9T\x927\xddt\x93\x08\x04\ +\x02eoK\xd3H\xa5R\xe8\xba\xce\xc2\x85\x0b\xf9\xb7\ +\x7f\xfb7>\xf3\x99\xcf\x90L&\xfd\xf7+i\x0e\x04\ +\x02\xbe\xb4\xcc\xcc\xce \xa5$\xe7\x96\x08_\x18Gv\ +\x04\xd1\x84\x86\xa6yH\xcd\xc3\xc9\xe8\xd8\xe3!R\xbf\ +\xae\x13\xe8\x12\xc30\x90R\xda\xaf$F9j\x95e\ +YVW[[\x1bsss\xd8\xb6-\x94\xf1V1\ +\x80\x94\xd2?}\xae\xebr\xddu\xd7q\xf5\xd5W\xb3\ +a\xc3\x06v\xed\xda\xc5\xfa\xf5\xeby\xf2\xc9'q\x1c\ +\x87\xeb\xaf/\xf3\x8b\x13\x13\x13H)\xfdk\xec\xdb\xb7\ +\xef\x90k\x1e8p@m\xa0\xed8\xce\x01)%\xba\ +\xae[\xf9|\xfe\xf2\xb1\xb1\xb1)\x80@ pIs\ +s\xf3\xed\xb9\x5c\x8eB\xa1@,\x16\xe3\xdak\xaf\xa5\ +\xa3\xa3\x83m\xdb\xb6\xf1\xdd\xef~\x97\x91\x91\x11\x9a\x9a\ +\x9a|B\xd2q\x1c\x92\xc9$\xae\xeb\xd2\xd0\xd0p0\ + \x9d\x97\xfc\xfd\x07F0\xa7\x1c\x06\x83\xd0\x12\x5cJ\ + (8\x90\x1eD\x22\x11\x1e\x94\xe2c\x88y\xc6?\ +\x9f\xcf\xffIss\xf3c\x9a\xa6i\xf1x|\xdd\xeb\ +fC\xa4\x94V\xa9T\xc2\xb6m?\xbe\x80r\xf0\x96\ +N\xa71M\x13!\x04\xa5R\x89p8\xcc\xdf\xfe\xed\ +\xdf\xf2\xf4\xd3O\xd3\xdc\xdc\xcc\x8f~\xf4#\x1e\x7f\xfc\ +q\x06\x07\x07\x0f\x01 \x12\x89\xfc\xe1\xa4\x8d\x10X\x96\ +\xb5O\xd3\xb4!@:\x8e\xb3+\x1e\x8f\x7f\xfa\x0f\xbd\ +6\x12\x89|{\xeb\xd6\xad\xff\x09H\xdb\xb6\xb3\x8b\x17\ +/\x1emhh\x88(\x09\xb9\xef\xbe\xfb\xe4\x97\xbe\xf4\ +%\xf1\xbd\xef}\x8f\x0f|\xe0\x03|\xe8C\x1f\xe2\xf3\ +\x9f\xff<\xdb\xb7o\xf7=\xaeJ\xa7$\x91Hp\xf6\ +\x9a\xb3p\x1c\x07\x81`\xd4\x1c\xe3\x84\xf3\xa0mz9\ +N\x22\x84\x1d\x0f![\xe6\xe3\x14C\x02\xb4\x18\x86\xd1\ +\xb2q\xe3\xc6\xa3\x8a\xe0_6 uuu\xd7\xaeY\ +\xb3\xe6\x1f\x07\x07\x07C\x8eSfUu]?$\xde\ +\xb0,\x8b@ \xc0\x0d7\xdc\xc0\x8a\x15+\xb8\xe6\x9a\ +k\xb8\xfe\xfa\xeb\xb9\xf0\xc2\x0b\x19\x1e\x1ef>9D\ +,\x16;\x12\xe8. \x85\x10d2\x99o\xc4\xe3\xf1\ +\xaf\x1c\xe9\xfe\xd2\xe9t\x1e\xf0\x93N\xa3\xa3\xa3\xebG\ +FF\xccy\xe9\xf9\xc7\xf1\xf1\xf1\xd3.\xb8\xe0\x02\x12\ +\x89\x04\xb7\xddv\x1b\x13\x13\x13,^\xbc\x98\xe7\x9f\x7f\ +\x9e|>\x8fm\xdb\x14\x0a\x05\xd4ws]\x97B\xa1\ +P\xfeN\xc2\xa0\xd03\x81\xb6\xa0\x16\xad6G\xf4\x14\ +\x0d\xa9I\xa4\x0dN2\xc0\xec\xcf\xeb\xf1\x8a\x9aR]\ +\x1c\x8d\xea2\x8eBU\xb5-\x5c\xb8\xb0~ll\xcc\ +\xb7\x17\x954\x87J\x0c\x01\xac_\xbf\x9e\xbe\xbe>L\ +\xd3d\xf3\xe6\xcd<\xf5\xd4S\x04\x83A\x82\xc1\xa0O\ +\x8f\x1c\x8e\x81\xb2EUUUl\xd9\xb2\xa5=\x99L\ +N\xbc\x12\x9d\x9c\xc9d~\xa3\x1e\x87\xc3\xe1K\x0e\x1c\ +8`\x00\x9e\xeb\xba'\xdep\xc3\x0d\xd1\xaf|\xe5+\ +\xf4\xf6\xf6\xd2\xd1\xd1\xc1\x9dw\xde\xc9\xfa\xf5\xeb)\x14\ +\x0a\xbe]q\x1c\x07\xc7q\x98\x9d\x9d\xc5.Y\x94J\ +:/\xf4\xe7y\xfb\xc2\x0b\x89\x85\xa3<\xbe\xef?\x08\ +\xe9\xd5\xd8d\xc9\x1f\xb0\x91\x0eh\x9a\x86i\x9a\xf4\xf4\ +\xf4\xdc\x9dL&7\x8d\x8c\x8c\xdc\xf9\x9aI\x88RC\ +\x95\xbe\xbb\xd2\xc1\xb6m\xb3p\xe1B\xee\xb9\xe7\x1e>\ +\xfc\xe1\x0f\xf3\xaf\xff\xfa\xaf\xfc\xdd\xdf\xfd\x1d\xc1`\xb0\ +\xcc;\xcdK\x90\xe7y\xa8\xbc\x83R\x13\xf3\xf6@\xa4\ +R\xa9\x87\x80\x84\xae\xeb\xe9p8l+\xc3\xab\xa4\xea\ +\x95\xacD\x22qm\x22Q\x0e\xa8\xeb\xeb\xeb\x9f\x8c\xc5\ +bg\xdf|\xf3\xcd\x8c\x8f\x8fs\xfb\xed\xb7\xb3s\xe7\ +N\x02\x81\x80O\x5cV~\xbf\xe9\xe9i\xba\xbb\xbb\xcb\ +\x81\xab+y|\xfcq\xba\xcf\x09\xd2\xae\xb5\xe2N\x84\ +\xf0R\x0b\xa1\xed\x10r\x15]\xd7\xaf\xec\xef\xef\xd7_\ ++@B\xef{\xdf\xfb\xf6\x1e8p\xa0Z\x89\xb2\xa2\ +F\x94\xeb)\xa5\xe4\xd3\x9f\xfe4O=\xf5\x14\xf3\x5c\ +\x0f\x1f\xfc\xe0\x07\xa9\xa9\xa9yI\x170M\x93-[\ +\xb6|>\x93\xc9\xbc\xaa\xfc\xd0\x8bH\xfa\x8d\x03\x03\x03\ +\xf5\x9a\xa6YR\xca\xff\xf5O\xff\xf4Oko\xba\xe9\ +&,\xcbb\xdd\xbau\xec\xdb\xb7\x8f\xb1\xb11_\x8d\ +9\x8e\xe3\xb3\xc69\xafD\xdb{J\x84\xdb\xa1\xd0<\ +\x8b\x01\x04\xb5\x08n\x09(\x98L\xfd\xa4\x11ax\x18\ +\x86\xe1\xc7P\xaf\x05 \xf5\xd5\xd5\xd5\x0bu]\xf7%\ +\xa4P(P,\x16\x09\x04\x02\x84\xc3a4M\xe3'\ +?\xf9\x09W\x5cq\x05\xb5\xb5\xb5\x14\x8bE\xdf[9\ +\x5c\x1a\xd4\xdf\xba\xae\x93N\xa7w\x1a\x86\xf1\xb8\xeb\xba\ +N$\x12\x89g2\x99\xd7\x14\x0cM\xd3\xc8f\xb3\xbf\ +\xcbf\xb3\xea4_a\x18\x06\xb7\xdcr\x0b\x86a\xc8\ +\xbb\xee\xbaK\xac^\xbd\xda\x7f\xbdr\xe3\x95&\xc8\x14\ +sD\xb6\xe7\x98\xfa}\x9a\xcb\xcf\xf8[\x5c\xbd\xc0C\ +\xbd\xdf\xa6)\xdc\xc5Df\x88\xb9\xb1\x22\xc2(_g\ +fffQ4\x1a\xfd\xcb\x5c.w\xdf\xab\x02H\x85\ +\xdev\x95\xaf\xaeD\xd9\xb2,\xf2\xf9<\xed\xed\xed<\ +\xf4\xd0C\xbc\xff\xfd\xefg\xdf\xbe}\x5cw\xddu\x04\ +\x02\x014M\xfbCU \x87|~8\x1c&\x1e\x8f\ +?533s\xc3\xeb\x95F>\xfc\xd4\xa6\xd3\xe9\xcd\ +;v\xec\x08z\x9e\xa7\xb7\xb4\xb4\xbc\xff\xe9\xa7\x9fF\ +\xd7u\x84\x10\x84\xc3\xe1CT\x97i\x9a\x9c}\xda\x1a\ +\xa4\x07\xaet\xd9\xd6\xbb\x11\xd3\xd0Y\xea\x9c\x83;#\ +Xj/\x86\xd5\xaa\x9eG\x02\xac)\x14\x0ak\xee\xbe\ +\xfb\xeeW\x07\x90x\x9fg\xef\xde\xbd\xe1|>_\xe4M\ +\xb8\xea\xea\xea\x1e;\xe5\x94S\xce]\xbe|9[\xb7\ +nezz\x9a\xd6\xd6V\xa4\x94d2\x19\x16-Z\ +\x84\x8e\x86S\x82\xa2W\xc4\xa5\x84iG\xd0\x8dy5\ +m\x820\xfcxJ\x9a\xa6)\xb6o\xdf\xbezll\ +l\xf3+\xb5!1\xcf\xf3\xaa\xd4\xe9p]\xd7gk\ +\xe3\xf18\xe7\x9cs\x0e7\xddt\x13\xdb\xb6m#\x97\ +\xcb177G*\x95\x22\x10\x08\xd0\xda\xda\xca\xd8\xd8\ +\x18ccc\xacX\xb1\x82m\xdb\xb6Q,\x16\x7f5\ +>>~k,\x16K\xd7\xd7\xd7\x97\xf2\xf9\xfc\x9b\x11\ +\x0f\x84\x10\x01\xdb\xb6y\xe2\x89'\xe8\xee\xee\x96\x97\x5c\ +r\x89\xb8\xeb\xae\xbb\xa8\xad\xad\xc5\xf3<\x9fG\x1b\xd5\ +gh\xff\x8bY\x164\x06p\xf2V9\xcb8\x15\xc2\ +\x9a\x08\x22\x0b:^^\x07\x10\xd1h\x14\xc30\x9cW\ +\xac\xb2\xea\xeb\xebooll\xfcS\xe5\xea*@\xba\ +\xba\xbax\xf6\xd9g\xd9\xb4i\xd3\x8b\xbewtt\xd4\ +\x97\x9a\xde\xde^b\xb1\x18\x81@`r\xff\xfe\xfdO\ +\xcf\xcd\xcd\xf9i\xd77\xe3r\x1c\xe7\xf3\x03\x03\x03\xcd\ +\xb6m\xafY\xb3f\xcd\xb5CCC\x18\x86qH~\ +\x07 e\xe58\xb39J!/y\xd7\x09\xef\xa3\xaf\ +j3\xe9\x8e\x19@P\x186\x99\xf9E\x0d\xe8e\xf2\ +\xf3U\xb1!\xae\xebF\x94\xfb\xaa\x0a\x0b\xde\xfd\xeew\ +3::\xcac\x8f=F8\x1c\xf6\xcb<\x15\xbd\xae\ +\x0c~\x85k[.\x09u]\xd2\xe9t\x947\xf9\xaa\ +\xae\xae&\x9dN\xff\xf7<7\xe6\x0e\x0d\x0d]\x9bL\ +&QU3\x9e\xe7\xd1\xdf\xdfOUU\x15\x86g\xb3\ +\xedk6\x94\xa2\xcc\xd5\xedD\x0a\x93x\xca!`\xea\ +\x14\x0b\x19\x9cT9==55E,\x16\xfbaS\ +S\xd3\x0dSSS\x8f\x1e5 RJWI\x86\xb2\ +\x07\x13\x13\x13\xdcx\xe3\x8d|\xf5\xab_\xe5\xf6\xdbo\ +gxx\x98\x93O>\x99\x99\x99\x19\xe2\xf1855\ +5<\xff\xfc\xf3h\x9a\xc6I'\x9d\xc4\x96-[\xc4\ +\xe8\xe8\xe8\x13\xd3\xd3\xd3\xeb\x00\x16.\x5c\xc8\xf8\xf8\xf8\ +\x9b\x16\x10\xc5\x02\xcfK\xb7\xa9\xb2\x9c\xabV\xad\x92\xa3\ +\xa3\xa3\x22\x99L\xd2\xd0\xd0\xc0\xc9'\x9f\x5c&#=\ +\x1bN\x9a\xa1\xa6\xae\x80\x97\x0eP\x93Z\x84\x976q\ +S\x06\xb4\x80\xd0\xa5\x22>O\xba\xf7\xde{\x1b\x8eZ\ +B\x9a\x9a\x9a\x16\xbb\xae\xfbn\xe59\x05\x02\x01\x02\x81\ +\x00CCCl\xd8\xb0\xc1\xf7\x9a\x00~\xff\xfb\xdf\xfb\ +9\xf3\xcaxc\xd3\xa6M\x84B!\xffu\xc0\x9b\x1a\ +\x8c?\x10D>\xbae\xcb\x96\xb5\x81@\xe0\xea\xf3\xce\ +;\xef\x8a\x1f\xfc\xe0\x07~j!\x93\xc9 =\x8f1\ +\x99\xe0\x8c\xb79\xd8\x8eKU\xa8\x86\x82\x9bA\xe8\xe5\ +\x82\xbe\xfc\xae\x18\xe9gj@\x1ctr\xfe\xe8\xf5\x8e\ +@\xcc\xad\x89D\x22\x0b]\xd7%\x99L\x22\xa5\xe4\xfa\ +\xeb\xaf\xa7X,\x12\x0e\x87\x89D\x22>H\xa1P\x88\ +`0H8\x1c&\x1c\x0e\x13\x0a\x85\x08\x85B\xc4b\ +\xb1C\xbc\xab\xb7\xda\xcad2\x93\xa5R\xe9IM\xd3\ +F\xbe\xf5\xado\x1d\x22=~2N\xba\x80\xc6by\ +\x11\x9fY}7\x7f\x7f\xee\x8f\x18\xde\xe3\xd2\x11[\x8e\ +\x08\x96k\xcf\x14{|\xa4\x98\xe4\x8f>\x1b\x0e\x87\xaf\ +\x5c\xb2d\xc9\xdd\x00\xc9d\x92\xa6\xa6&~\xf2\x93\x9f\ +0==\xcdC\x0f=\xc4\xfe\xfd\xfbY\xb7n\x1d\x8f\ +<\xf2\x08+W\xae$\x91H088HOO\x0f\ +\x8d\x8d\x8d\xfc\xf0\x87?\xa4X,\xce\xbc\xf0\xc2\x0b\x8d\ +\xcd\xcd\xcd\x81\xc9\xc9\xc9\xd2[\x15\x98\x9a\x9a\x9a/\xac\ +^\xbd\xfa\xa6\xd1\xd1Q\x92\xc9$\xa1P\x88\xd3O?\ +\x9d@ \x80\x04\x02\x86\x86t\x028^\x09\xc30q\ +\xa4\x8d\xa6\x97k\xcfd\x0510<<\x1c\x7f\xfa\xe9\ +\xa7\x17\x1e\x95\xca\xd24-\xacT\x90\xae\xeb\x84B!\ +>\xf9\xc9O\xd2\xd9\xd9\xc9\x0b/\xbc\x80\x94\x92\xde\xde\ +^t]\xf7\xf3\x1c\x00\x8f<\xf2\x08\xae\xeb\xaa\x82\x06\ +\x09\xc8\xb72\x18\xf3t\xcb\xcf\x9ey\xe6\x99\xfd\x0b\x17\ +.\xbc\xbd\xbd\xbd=:::\xea\xf3y\x1e\x1e\xdb\xeb\ +\xfb8\xeb/\x22\x18\x19\x137m\xa0\xa7\x82\xb8)\x03\ +7m`\x8d\x85\x10\x02\xc5h\x9bGmCB\xa1\xd0\ +\xa7e\xd9\xaa\x8b%K\x96\xe08\x0e\xf9|\x9e={\ +\xf6\xf8\xd1\xab\xe2|\x82\xc1\xa0\x9f\x94Qe\x9b\x80L\ +\xa5R6\xc7\xc0\xcad2\xcf\x02\xcf\x1a\x86\xf1\x8f#\ +##QM\xd3\x0e&\xe5\xa4C\xfdB\x03\xe1\xea,\ +j<\x85\x9aEU\xbc0\xb5\x89X\xa0\x96\xbc>\xc5\ +\xc8W[\x11Z\x99PU\x99\xd5\xa3\x02DJ)\xa4\ +\x94\xa2T*\xf1\x89O|\x02\xc30\xb8\xe8\xa2\x8b\xf8\ +\xf2\x97\xbf\x8ci\x9a\x18\x86A*\x95bdd\x84\xee\ +\xeen\x86\x87\x87I\xa7\xd3\xf4\xf7\xf7\x93\xcdf\xc9d\ +2\x7f300\xf0\x0d\x8e\xa1\xa5\ +\xa4\x85B\xa1\xee\xa8mH}}}\x7fSS\xd3R\ +\xd7u\xa9\xab\xab\xe3\x8a+\xae\xa0\xb7\xb7\xd7/6\xf0\ +\xdb\x0aJ%B\xa1\x10\xa5R\x89l6K4\x1a%\ +\x95J\x91\xcdf\xaf;\xd6\x00iii\xf9\x8c\x10\xe2\ +\xb3B\x88\xba\x95+W\xfa\xb9\x9e\xa2g\x11:9\x85\ +\xe1\x18x\xd3\x11\x9c\xc90h\x1eB\x13*\xd7\x8e\x94\ +\x92\xe9\xe9i\x1e{\xec1q\xb4q\x88Pt\xb5\xae\ +\xeb\xdcu\xd7]\x87$\xa3*\xdd[\x15\xb9\x9a\xa6\x89\ +m\xdb2\x16\x8b\x89t:\xad\x1fK`TWW3\ +11\xf1\xa5\xd6\xd6\xd6k\x81:\xcf\xf3\xcaD\xa9\xd0\ +x\xac\xb8\x9d\xbf\x5c\xd5\x84#m,\xb7D\xcc\x08\xe3\ +ft\xbcT\x90\xdc\xce\x18V<\xf0\x07\xa9\xff\x97\xe5\ +\xf6\x02\xa6m\xdb\x5cp\xc1\x05466r\xf5\xd5W\ +\xd3\xd4\xd4\x84i\x9a,^\xbc\x98\x8e\x8e\x0eL\xd3\xa4\ +\xb1\xb1\x91d2I.\x97C\xd7u\xe2\xf1\xb8\xd8\xbd\ +{\xf7/2\x99\xcc/\x8f%@\x94\xcb+\xe6O\xa1\ +JEX\x96\x85\xd0\xca\xe5\xa6\xef\x8c\xfd5_\x5c\xf7\ +0\xcbj\xcfdy\xc3\xd9D;%\xc4J\x07\x1b\x8c\ +^\x89\x0d\x01\xc4|v\x8d{\xef\xbd\x97\xa1\xa1!\xf6\ +\xec\xd9\x83i\x9a\xd4\xd7\xd7\x93\xcdf\xd1u\x9d\xce\xce\ +Njkk\xd9\xbbw/===d2\x19\x0a\x85\ +\xc2\xe6x<\xde\xcb1\xb8\x1c\xc7\x91~W0\xa0!\ +\xd0C\x82}{\x93\xfc\xcb\xff\xb8\x9c\xeb\x1e|7w\ +_\xb6\x99\xc9\xb9i\x9eK\xfc\x17\xdf\xfb\xd5\xbdX\x96\ +\xe6\x07\x94\xaf\x88\xcb\xd24\x8d\x81\x81\x01.\xba\xe8\x22\ +\x0a\x85\x82\xaf\x0b+\xcb\x5c\xfa\xfa\xfa\xfc\xc7O?\xfd\ +\xf4!Q\xf9\xb1\xb8fff\xde\xd5\xd2\xd22\xa5x\ +-\x81@\x84\x05\x85\x9cG8t\xd0\xabu\x5c\x87\xc7\ +\x87\xfe\x03\xcf\x95\xbe\xbd}\xa5\x12B \x10\xa0\xbe\xbe\ +\x9e@ \xa0\xaa\x14\x09\x06\x83d2\x19jjj\xfc\ +\xbc\xba\xca\xa9g2\x19,\xcb\xb2\x81\xb1c\x15\x10\xd7\ +u\xb3\xf3\x92R\xa6C(\xe7\x80b1\x13\xdb\x02\xd7\ +\x9b\xef\x08\xc6\xc5\xf5\x1c<\xd7\xc5\xb2\xbcW\x0e\x88\xe7\ +y\xac[\xb7\x8e+\xaf\xbc\x923\xce8\x83\x87\x1f~\ +\x98\xdf\xfd\xeew\xe4\xf3y&&&8\xe3\x8c3\x98\ +\x9c\x9c\xa4\xaf\xaf\x0f\xcf\xf3hll\xe4\x85\x17^\xc0\ +\xf3\xbc}\xf1x\xfc\xdf\xdf\x0c\x93\x11^\xab5\xcfd\ +K\xcb\xb2\x84@ 4\x9d\xa5\xcb\xeayd\xeb\xcf\xf9\ +\xcc9\xdf\xe2\xbf\xf6|\x13'\x17\xe6\xbc\xc5\x1b\xe8u\ +\xbeC\xa9\xe4\x1c\xa2U\x8eZB6n\xdc\xc8\xf4\xf4\ +4555\x0c\x0c\x0c\xf8(K)\xf9\xe9O\x7f\xea\ +W\x92x\x9e\xc7\xd4\xd4\x94*\xae\x16\xc01\x0b\x06`\ +\x15\x0a\x85\xd9B\xa1P\x9fL&\xd1\x84F\xbe\xd9\xa3\ +hU\xf1\x1fC\x7f\xcf'c\xdf\xe3@\xae\x9f\xe7'\ +~\x87\x11\xd0\x98\x19K17W\xaeCP\x99\xd5\xa3\ +\x06\xc40\x0cFGG\x19\x1e\x1eF\xd7u\xdf\xe5\xd5\ +4\xcd\xff[E\xed*\x0f299\xd9\xd2\xda\xda\xfa\ +\xbex<\xfe\xc8\xb1\xaa\xb5\x84\x10\x96JW\xab\x86\x1e\ +#(\xa8\x22\xc2\x1d\x8f]K\xb2\xcfcfo\x81R\ +\xd2#7\xe9\x224\xe1\xef\xd3Q\x03\x12\x8dF\xf9\xc8\ +G>B\x7f\x7f?\x17_|1O<\xf1\x04CC\ +C\xd4\xd5\xd5\xe18\x8e\xef\x06\x8e\x8c\x8c\x90L&i\ +iiarr\x92\x5c.WM\xb9\x18\xe6\x98\x03\xa4\ +\xa5\xa5EU\xe9Ku\x08kkk1\x87\x8b\xf5\ +)\xa4\x94l\xdc\xb8\x91\xba\xba:jkkq]\x97\ +\xd1\xd1Q\xba\xba\xba\xfc\xc6\x97\xb6\xb66r\xb9\x9c\x02\ +\xca;\x16Ecbb\x82\xf6\xf6\xf6\xef\x06\x02\x81F\ +\xd7u\xb9\xe3\x8e;X\xb7n\x1d_\xfb\xda\xd78p\ +\xe0\x00\x9e\xe7\x91\xc9d0\x0c\x83\xd9\xd9Y\xaa\xab\xab\ +\x09\x85B\x0c\x0f\x0fS(\x148R\x0d\xc1\x91\xd8^\ +~\xf1\x8b_\xf0\xf3\x9f\xff\xfcE_Si'v\xed\ +\xdaE$\x12yI\xc6\xeb\xad\xbc\x02\x81\xc0\xdaU\xab\ +V\x19\xbf\xff\xfd\xefY\xb1b\x05}}}\xac]\xbb\ +\x96\xef\x7f\xff\xfb\xf4\xf4\xf4066FWW\x17\x8f\ +<\xf2\x08\xd5\xd5\xd5\xb4\xb7\xb7s\xdai\xa7q\xdf}\ +\xf7\x1d17\xf4G\x15Zkk\xebpUU\xd5\x09\ +\x95\x84Z\xa9T\x22\x12\x89\xf8\x95%\x91H\x84\x5c.\ +\x87\xe7y\xd4\xd5\xd5\xf9\xd2\xd2\xde\xden\xcf\xcd\xcd\xdd\ +\xb3g\xcf\x9e\xab\x8f5@\x16-Z4x\xea\xa9\xa7\ +\x9e811\xc1\x92%KX\xb3f\x0d\xbf\xfc\xe5/\ +)\x95J\x04\x02\x01\xb2\xd9,\xe1p\x98t:\xed\xef\ +\x9b\xe7y\xe4r9\x5c\xd7e\xe7\xce\x9dG\xc7eE\ +\xa3Q\xeb\x9b\xdf\xfc&\xa9T\x8a\x0f|\xe0\x03\xdc\x7f\ +\xff\xfd\xf4\xf6\xf6\xd2\xd0\xd0@UU\x15\xcf=\xf7\x1c\ +UUU\xf4\xf5\xf5111AWW\x17###\ +\x0c\x0f\x0f\xe38\x8e)\x840\x8fA0\xfe*\x10\x08\ +\xd4\xcd\xcc\xcc \x84`h\xdf\x10\x03\x03\x83\x18\xc6\xa1\ +'\xdf\x1f\x863\x1fw\x08!\x08\x85B\xfe\xff?*\ +@t]\xe7s\x9f\xfb\x1c_\xfc\xe2\x17\xb9\xf5\xd6[\ +\xd9\xb1c\x87_u\x91\xcf\xe7\xd1u\xdd\xafFq\x1c\ +\x87\xe1\xe1a?\x8a\x9fw\x8d\xbdyI;f\x5c\xe0\ +\xb6\xb6\xb6\x7f\x5c\xbati=\xc0\x8e]\xcf\xe35\xa5\ +\x89\x04Ld&\x80\xb44\xdc\xf6ENd\x0d\xdaD;n\xca$S\ +J\x91\x9c+3\xe0\xaa\xb7\xe4\xa5\xd4\xf8\xfeQ\x09\xb1\ +m\xbb\xdf\xb2,\xd6\xae]\xcb\xb2e\xcb\x18\x1f\x1f\xa7\ +T*177Gss3\xe9t\x9a\xda\xdaZR\ +\xa9\x14\x93\x93\x93TWW\xa3\xeb:\xaa\x87\xc4\xb6m\ +L\xd3\x94\x15N\xc2[Vu\xe5\xf3\xf9\x8f\xfd\xe9\x9f\ +\xfe\xe9\x97M\xd3\x04)\xc9\xd8E\xde\xbdh9\xa9\x9f\ +\x19\xcc\x15S\xfc\xc3\xc3_\xc6\xd0\x0d4C X\x80\ +\xae\xc1\x82F\x9d\xa1\xa1!\x1a\x1b\x1b)\x16\x8b\x04\x83\ +A\xe9y^\xf8\x15\xd1\xefcccl\xd8\xb0\x01\xc3\ +0\xfc\xfc\xb9Z\x83\x83\x83\xbe\xc1\x02x\xee\xb9\xe70\ +M\x93J\xe2\xcdu\xdd\xaa\x95+W\xde5555\ +\x18\x8f\xc7\xff\xe1\xad*!\x9e\xe7\xd5)\x16\xbb m\ +\xec5#,\xe8\x89\xe1\xe2\x22mp'\xa2X\x93\x01\ +\x9c\xc9 V\xdc\xf0\xab\xdeUCl*\x95\xa2\xb9\xb9\ +Y\x14\x8b\xc5\xab\xda\xda\xda\x18\x1b\x1b{\xf9*K\xd3\ +4O\xa9\x9eH$B0\x18\xf4\xeb\xb0T\xd7\xd4\xe1\ +5Xjz\x82j\x03\x03B===W\x01\x7fr\ +\x0c\xd8\x8fr\xff\xa1eQW\x13\xa2Tp8w\xc1\ +_\xf3\xde%W\x10h\xb5\xa8\x7f\x9bC\xd5y\x09J\ +y\xfb\xe0L\xc8\xf9z,U\xa0.\x84\x08\xbe\x18\x18\ +G\x94\x90\xaa\xaa\xaa{\xc7\xc6\xc6\xd6\x7f\xf6\xb3\x9f\xfd\ +\xf3\x9a\x9a\x1a.\xbd\xf4Rn\xbb\xed6\x92\xc9$+\ +W\xae\xc4\xf3<~\xf9\xcb_\xb2r\xe5Jv\xec\xd8\ +\x01@0\x18\xa4X,\x92\xcdf\xfd\xc1\x01\xf3\xae\x9e\ +\xfbVT]\xa1P\xe8/\xd6\xaf_\x7f\xff|%\x8d\ +t])\xc2U:\xde/\x1a\xc8\x08\xc9\x03\xdao@\ +\x80\xa6u\xfa\xef\xa9\xae\xd7\xd8\xbcy3\xcb\x96-\xf3\ +[\xe1\x94*?R\xd0\xfcG\x01\x99\x9a\x9a\x92\x8b\x16\ +-\xb2\x1ex\xe0\x01>\xfe\xf1\x8fs\xf3\xcd7\xd3\xd7\ +\xd7\x87\xa6i\xc4\xe3q?%\xb9e\xcb\x16\x0a\x85\x02\ +\xc9d\x92\xe6\xe6f\x9f|T\xee\xafm\xdb\x84\xc3\xe1\ +3.\xbc\xf0\xc2g\x06\x06\x06\xfe{pp\xf0\xd6\xb7\ +\x90\xaa\x0a)\x9bh\x08]\x0c\x9d\xb0\x8bw\x9c_\x85\ +\xeb\xb9\xd8)\x0d\xd2\x11\xdc\xb4\x81\x9b4)\x0e\x86\x91\ +\xae\x00\xb7\xac\xde+\xa7\xd7\x05\x02\x01\x12\x89\xc4\xf3\x86\ +a\xec{En\xaf\x94Rs]\x97/}\xe9K~\ +\xbd\x95\xf2\x16\xa4<\xb4]K\xd34\xa6\xa7\xa7}\xf1\ +T\xddF\xf3\x11lM}}\xfd;kkk\xf7\xbe\ +EH\xc4\xda\xfa\xfa\xfa%\x89Db\xd1|\xd2\x0d]\ +j\xe8\x96 5$\xa9\xd3N\xa4\xb5\xae\x9a\x01o;\ +\xa2JCT\x0br/T\xe3\x155\x7f\x22\xc5\xc1\xd9\ +\x92R\xb52|sjj\xea\x99W\x04\xc8\xec\xec\xec\ +W\xb3\xd9l\xe75\xd7\x5c\xf3\xaeB\xa1\xc0\xbb\xde\xf5\ +.\x1ex\xe0\x01<\xcfc\xc1\x82\x05\x8c\x8f\x8f\x13\x0e\ +\x87\x89\xc5b<\xf3\xcc3\xb4\xb7\xb7\xd3\xd2\xd2B\xb1\ +X\xf4I\xb6\xcaQ\x15/\xb7M\xf8\x8dZ\xc5b\xf1\ +\xe3\xa7\x9f~\xfa?(C^\x92\x16\xc1\x06\x87\xa6\xd9\ +\xb7#\x9e\x13\xe4\x80\x1c\x0e\x01N\xf5\xdf\xd3\xded\xb0\ +{\xf7n\xbf\x15CU\xe2\xa84\x05\xe59\x8dG\xaf\ +\xb2\x0c\xc3 \x9dNo^\xb8p\xe1\xd0\xbe}\xfb\xde\ +\xf5\xef\xff\xfe\xef\xf4\xf7\xf7\xb3t\xe9R\x0c\xc3\xf0\xdb\ +\xa3\x0d\xc3 \x1a\x8dr\xca)\xa7077GCC\ +\xc3!\x05e\xaaIt\x9e\x07\xfb\xe0%\x97\x5cr\xfe\ +\xcc\xcc\x8c\xd8\xbe}{w:\x9dN\xbcY@\xa8\xb4\ +m\x9e\xe7\x99\xf9|\x1e!\x04y\xb7\x04\xe7\x1e`\xf1\ +\xb20\xd2\x03i\xcfG\xe4\x96\x86=m\x92z\xbc\x0e\ +)\x5c\xbf\xa1G\x1d\xc0d2I0\x18D\xd34\x19\ +\x08\x04\x84eY\xe6+\x02\xa4\x22\x12\x17}}}\xac\ +[\xb7\xce7P\x87\x97\x8d*\xf5%\x84\xe0\xd7\xbf\xfe\ +\xf5\xc1!e\x9aF\xb1X\xf4\x01\x11B\x84\x0d\xc3\x08\ +\xd7\xd6\xd6bY\xd6\x9b\x8a\x16\x8e\xc7\xe3\x9cr\xca)\ +\xff\xa7\xb9\xb9\xb9\xb3T*ud\xd2i\xf04\x1c\xcf\ +\xc3x\xb2\x96\xa1\xcd\x82\xf9V\xe7\x0a^\xd6%;3\ +MuM\x95\xdfa\xe6\xcf\x1b\xb6mB\xa1\x10\xba\xae\ +\x8bM\x9b6\x9dX__?\xf1\x8a\x00Q\xabT*\ +M\x99\xa69\xaa\xebz{SS\x13\x86a\xf8\xdc\x8c\ +\x9a_\x15\x0a\x85|#\xaf\x8a\xe9\xd4\x00\x80\xd9\xd9Y\ +\x7f\xca\x8e\x9a\xdb\xeb8\x0e]]]\xd7\x04\x02\x81\xec\ +\xc4\xc4\xc4\xf3SSSO\xbe\xd1R1\xefY^\xb0\ +`\xc1\x82z\x80\x84\x9d\xa6z\xcd,\xf5\xd5!\x9c\xc9\ +0\xced\x08Y\xd2\xf1J\xe5\xb9\xbex\xe5\xc3\x18m\ +)w\x07TN]U\xd9SUt.\xa5\xdc73\ +3s\xc4\xfbyI\x95\x85\xf9|\xfe\xbf\xc7\xc7\xc7\x7f\ +\xdc\xd4\xd4\xf4?\xef\xbe\xfbnV\xadZ\xe5\xab\xa3\x0f\ +}\xe8CLNN\xb2|\xf9r\xba\xba\xba\x98\x99\x99\ +a\xed\xda\xb5\xac^\xbd\xda\x1fJ\xa6Z\xdb\x22\x91\x88\ +?$\xcc\xf3==}\xdbK\xbd\x97\ +\x97\x05\x88\xda\xd4D\x22!=\xcf\x13\xf3\x5c\x15\xba\xae\ +S,\x16\x0f\xe9QW4\x8bJh%\x93Iff\ +f\xa8\xa9\xa9\xc1\xb2,L\xd3T\x80\xc8\xce\xce\xce\x8f\ +,Y\xb2\xe4#\xba\xae\xf3\xab_\xfd\xea*\xe0\xee\xd7\ +AU\xb5\xa5\xd3\xe9\xf3<\xcf+\xe5r\xb9\xe5\xaac\ +8e\xe7\x09\xafL\xa1\x05\x83\xd0%\x91\x96\xc0M\x99\ +8I\x037i\x10\xf6j\xa9\xae\xa9Fz\xd2\xb7\x8b\ +\xba\xae\xfb\x83\xdc\x943T1(\xe1\xc0\xe8\xe8\xe8o\ +_\x0b@\xe2[\xb7n\x0d\x06\x83\xc1[>\xf1\x89O\ +\xdcx\xf6\xd9gs\xfe\xf9\xe7\xf3\xedo\x7f\x9b\xed\xbb\ +%_\xa5\x00\x00\x09\x83IDAT\xdb\xb7\xf3\x8ew\ +\xbc\x83t:\xcd\xe0\xe0 555>\xaf\xb5z\xf5\ +j\x9e{\xee9\x1f\xac\xc3g\xf8Z\x96%\x94s0\ +\xdf\x22\xd7\xd1\xdd\xdd}\x86\x94\x92\x99\x99\x99=\x13\x13\ +\x13\xafI#{\xa1P\xf8\xcb\xcb.\xbb\xec\x9fU\xbb\ +rQ+\x12\xad\x13`\xe9x%\x0d\x99.\xdb\x88\xb2\ +b\x97\xc8\x060\x9a\x0d\xb6\xef\xd8F\xc8:\x98bP\ +\x87+\x99L\x22\x84\xf0\x0f\x9ceY\x04\x83Al\xdb\ +~YsF^\x0e \x92\xf2\xcfM8\xdb\xb7oG\ +J\xc9\x8f\x7f\xfcc\xa6\xa7\xa7\xf1<\x8f\x07\x1ex\xc0\ +O^U\x8e\xca\xdb\xb4i\x93_\xfe\xa2NN\xa1P\ +8\xc4E\xac\x9c\xd5x\xea\xa9\xa7\xde\xd6\xd1\xd1q[\ +$\x12\xe1\xe1\x87\x1f^\x05l}\x15\xa5\xe2\x03\xc0i\ +\xe5\xbdt\xdf\xbds\xe7\xce\xf2\xc8\x0c\xcfA\x9c\x90\xa6\ +\xa6t\xa8Wj'u\xec\xf1 &!\x9a\x9b\x9b9\ +\xfc\xc7\x04\x0e?\x5c\xca3\x8d\xc5bd\xb3Y\x06\x07\ +\x07\xfbu]\x1fx\xad\x00\xf1\x1d\x81P(\xc4\xb6m\ +\xdb\xfci\xa4\xaa]AuTU&\xf2\x95d\xa8\xea\ +\x8b\x5c.G\xb1X\xf4\xd9\xe3J\xcfKM\x11M\xa7\ +\xd3x\x9eGGG\xc7\x7f\x9et\xd2IE\xd7u\xf5\ +\xde\xde\xde;\xe2\xf1\xf8\xd7^\xce\x8d\x1e6\xce\x96l\ +6{\xcde\x97]va6\x9bE\x08A\xa2v\x5c\ +v.3\x85\x15\x0f\xe3\xcc\x04\x91\x19\xd3\xf7h\xa5\xe7\ +!5Ixi\x98\x8d\x9b6R[[\xeb\x03R9\ +\xe4SM\xe9VqW0xp\x5c\xfa\xf4\xf4\xf4\xb2\ +\x97\xcb\xdd\xbdl@t]\xbf\xfb\xc9'\x9f|J\xd7\ +\xf5+/\xba\xe8\xa2\xcb\xd6\xae]K[[\x1b\x9b6\ +m\x22\x9dN\x93L&\x99\x9b\x9bC\xd7uN8\xe1\ +\x04\x86\x87\x87\x99\x98\x98\xe0\xf4\xd3O\xe7\x85\x17^8\ +\x044\xdb\xb6\xfd!6\xa5R\x89`0\xe8\x7fa\xdb\ +\xb6\xa9\xab\xab\xebT?\xfe\xb2k\xd7\xaeu\xe1px\ +\x06\xd0\x82\xc1`!\x99L>p\xa4{\x9d\x9c\x9c\xe4\ +\xe4\x93O~|\xd1\xa2Ek\x95]\xdb7\xb6W\x06\ +\x82\x9a\x90\x05\x03}&\x22\x0e\xf4\x83\xd0l\x84f\xe3\ +z\xae\x1f?\x00\xd4\xd4\xd4\xa0\xe9\x07\x8b;*\x01Q\ +\x01\xaf*\x5c8\xf1\xc4\x13\x89\xc7\xe3\x94J%\xaa\xaa\ +\xaa\x0e\x99R\xf1r\x88\xd4\x97\x0d\xc8\xdc\xdc\xdc 0\ +XSSs\xd6\xce\x9d;Y\xbe|9\x03\x03\x03\xfe\ +TO%\xca\xae\xeb266\xe6s];v\xec\xf0\ +\xdb\xe0T\x10977\xc7\xe1\xe3e+\xb8/\x7f\x13\ +\x00\xd9\xdd\xdd}\xc9\x8a\x15+.\x01\xd8\xbf\x7f\x7f~\ +tt\xb4e^E\xe8SSSO\xba\xae\x1b\x9f\xe7\ +\x8d\x16\xb5\xb5\xb5m\xac,\xd9\xac\xdc\x10\xe9I\xa1\xa4\ +@I)\xc0\xf4\xf44===~,1;;[\ +\xe6\xaf\xe6'ST\x8e\x16Q\x80T\xd2\x22K\x96,\ +azz\x9aR\xa947555R,\x16\x9d\xa3\ +Q\xab\xaf\xa8o\xa0\xad\xad\x8d\x8d\x1b7\x02\xfc\xc1Y\ +\x1eUUU\x87\xe7W\x08\x85B\xb8\xae\xcb\xd4\xd4\x94\ +\x1f\xd9+]\xac\x86\x84)\x09Q\x7f\x03\x22\x97\xcb1\ +11\xa1\xf4td\xc5\x8a\x15_W\xc4\xdd\xd6\xad[\ +\xa9\xae\xae\xf6\x83\xd0\xe9\xe9\xe9?X\xb2\xe98\x0e\x17\ +^x\xa1\xef\x11\x8d\x8f\x8f\xd3\xd8\xd8\xe8\xdf\xbfr]\ +\x95:R?\xb1\xa1\xa6\xe2)W]U\x8e\xa8a\x97\ +\xba\xae322\xa2\x00zx\xf7\xee\xdd\x97\x1f\xed\x9e\ +\x1e5 \x9e\xe7}\xed\xd9g\x9f\xfd\xb1eY+{\ +zz\xee\xbd\xf5\xd6[ikk\xe3g?\xfb\x19;\ +v\xec@\x08A6\x9be\xd9\xb2e\xf4\xf6\xf6\xfa\xcd\ +=\x8d\x8d\x8d\xec\xdb\xb7\xcf\xd7\xbb\x8a\xda><\xd2U\ +)`\xe5N\xab\x0dRA\xa6\xda\x14)%\xad\xad\xad\ +\xb4\xb5\xb5!\x84`rr\x92\xd6\xd6V?\x0e\xd8\xbb\ +w\xaf\x9f\xd7\xdf\xb5k\x97\xcf\xbf\xa9\x93\x7f\xb8\x81V\ +\xb4\x90\xf2\x9e\x0e\xf7\x0c\xd5\xf5\x01\x9fH\x1d\x1c\x1cd\ +nn\x8e\xaa\xaa**\x87v\xbe\xae\x80d2\x99)\ +`J\xd7\xf5*M\xd3\xf8\xdc\xe7>GCC\x03\x89\ +D\xc2\xffRRJ&&&\x0e\xa1\xeb\x15X\xb1X\ +\x8c\xee\xeen\xe2\xf1\xb8\xaf\x12*\x87k\xaa\x7fJ\x8a\ +\x94\xe1\xaf\xcc\xb1Tf\xf2\x14\x11\xa8\x0c\xadr4\x14\ +\xeb\xac\xdcT\xc58+\xf0\xd5\xe7\xa8\x83\xa0<\xc2\xca\ +\xc2\x84\xf9\xa19\xfe\xf7P\x0e\xcc\xb2e\xcb\xe8\xeb\xeb\ +\xc30\x0c\xe2\xf1\xf8\x1dB\x08\xafP(<\xf3\x86\x00\ +R\xa1\x86\x9cR\xa9T\x0c\x87\xc3\xc5d2\x19\x8dF\ +\xa3f0\x18D\xd7u\x7f4\xac:e\xca\xb0\xaaM\ +S\xd5\x8f*\x9a\xd7u\xddO\xffVf\xd6TO\xb8\ +\x92\x10!\x84/!\x95:^\x01\xa7\x1c\x05\xe5\xc1\xa9\ +MW\xaaG\x01\xa2\xc6\xc1V>\xa7\x0e@% \x95\ +?\xb7QUU\xe5\x17\x5c\xff\xf6\xb7\xbf%\x12\x89\x10\ +\x89D\xd8\xb7o\x9f?3\xb2\xa9\xa9\x89\xa9\xa9\xa97\ +\x06\x10\xdb\xb6\x9f\xdb\xbe}{\x18\xa0\xbe\xbe\xfe7\xdd\ +\xdd\xdd\xe7}\xecc\x1f\xe3\xc9'\x9fd``\xc0O\ +a*C\xaf6D\xd7u\xb2\xd9\xac\xcf\xf7\xd4\xd4\xd4\ +\xf8\x06_\xc53*\xda\xadT\x1b*\xd9\xa3\x00;|\ +\xde|\xa5$\x05\x02\x01\x7fc\xd5\xa6+\xe6\xf9p\x8f\ +I]Oy\x81J\x22T\x1b\x9f\xca\x8btvv\xb2\ +|\xf9r\x1e{\xec1<\xcf\xa3\xa5\xa5\xe5\xff\xe9\x1b\ +\x9f\xf7\ +\xd5\x92J\x03T\xb2\xd1J\xdbh\x9aFMM\x8d\xff\ +9\xea\xf5\x81@\x00\xd7uy\xea\xa9\xa70\x0c\x83P\ +(\xf4D*\x95\xba\xfc\xb5\xda\xb7\xd7\x0c\x90D\x22\xe1\ +\xcf\xea\xee\xec\xec\x1c\xe8\xec\xec\x5c\xf2\x12\xed\x90O?\ +x\x9e\xc7\xc2\x85\x0b\x19\x1c\x1c$\x12\x89\xf8S\xa6\xfd\ +\xde\xbe\x0a\x1aF\xd9\x1de\xaf\x14X\x87O\xd6V\x91\ +\xb9\xa6i\xbe\x87\xa7$\xa8\xb3\xb3\x13\xc30\x18\x1c\x1c\ +\xf4'\x1f\xcdW\xce\xa4ggg\x9f\x13Bx\x96e\ +m~-\xd3\x02\xafK\x87\x7f.\x97\xfb\xfe\xf8\xf8\xf8\ +\x02\xcamn\xef\x0b\x87\xc3\xcb\x8e\xd4\xaf=33C\ + \x10\xe0\x99g\x9e\xf17\xf0\xec\xb3\xcff\xe3\xc6\x8d\ +h\x9a\xe6\xf7\xa8$\x12\x09\xbf\x92R\xd9\x0a\xd34\x0f\ +\x99\xbc\x1d\x0c\x06}O\xaf\xb5\xb5\x95\xd9\xd9\xd9r\xea\ +5\x1ae\xe9\xd2\xa5\x0c\x0f\x0f\x93\xcb\xe5\xd04M\xfd\ +W\x0a!\x84\xe38\xaa#l\xdf\xd0\xd0\xd0\xf9/\x96\ +\xf6}K\x012?\x90\xfe\x0b*\x9f|\xc2\x09'\xb4\ +.X\xb0`YE\xe4+\xc5\x1f\xe09*\xd5\x98\x8a\ +i*\xf3\xf8\xd1h\xd4\x1f1X__\xcf\xf2\xe5\xcb\ +\xd9\xb3g\x0fuuu\xe4r9\x82\xc1 \xb9\x5c\x8e\ +\x13O<\x11!\x04\xa9T\x8aD\x22AGG\x07\xef\ +|\xe7;\xf9\xf5\xaf\x7fM\xa1P\xa0\xa1\xa1\x81\xde\xde\ +^4Mc\xff\xfe\xfdJ\x8d\x89\xc1\xc1\xc1o9\x8e\ +\xb3\x0fp#\x91\xc8\xc0\xe1\xc5\x10\xaf\xd5z\xddg\xae\ +k\x9a\xb6@\xd3\xb4\xc8\xfc\xe3\x0fvww\x7f\xe5H\ +\xf3?\x94>Wv'\x10\x08\xf8\x86\xd9\xb2\xca?\xb3\ +z\xd5UWq\xdf}\xf7\x11\x0e\x87\xa9\xad\xadez\ +z\xda\x9f>\xb1a\xc3\x06~\xfe\xf3\x9f377G\ +WW\x17\xdd\xdd\xdd<\xfe\xf8\xe3\xaa:\xdfWm\xea\ +\xf7\x15]\xd7%\x93\xc9\x9c\x1b\x8f\xc7\x1f\x7f\xbd\xf7\xe7\ +\x0d\x1d\x82\x1f\x0e\x87Okll\xbcL\xd7u\x07 \ +\x1a\x8d~*\x18\x0c\x1eq\xae\xaf\x9a`\xa7\xd4\xd3\xd8\ +\xd8\x18\xd5\xd5\xd58\x8e\xe3\xe7$\x14\xf1711A\ +]]\x9d?s8\x16\x8b\xf9\x81a\xa1P\xf0m\xca\ +\xfc\xe8\xf3Cf\xd1\xbf\x11\xe3l\xdf\xd0)1\x85B\ +a\xc7\xc8\xc8\xc8\x8e\x0a\xdd\xecE\xa3\xd1*)\xa5\xb4\ +m\xbb\xcb0\x8c?;R\xa3\xbd\xb2\x05\xcac*\x16\ +\x8b~\x90\xa9b\x09\xf5k\x9c\xd9l\x16\xcf\xf3vK\ +)u\xd7u\xddd2\xf9\xf7\xe3\xe3\xe3?y\xb1\xcf\ +~#\xc6\xd9\xbe\xa1\x12r$\xed\x06\xf8\x9c~,\x16\ +\xbbZ\xd3\xb4\xd8\x8b\x81\xa2\x96i\x9a>\x95!\x84(\ +\x00{\x8b\xc5bVJ)c\xb1Xfvvv\xfb\ +ai\xddcy\x04\xc8\xf1u|\x1d_\xc7\xd7\xf1u\ +|\x1d_\xc7\xd7\xf1\x05\xc0\xff\x05\xf4\xe6\xb0\x9e\xc6n\ +\xd0\xb8\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00?\xd1\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00P\x00\x00\x00P\x08\x06\x00\x00\x00\x8e\x11\xf2\xad\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\ +\x00\x00\x09pHYs\x00\x00\x0e\xc4\x00\x00\x0e\xc4\x01\ +\x95+\x0e\x1b\x00\x00\x00\x07tIME\x07\xd9\x03\x03\ +\x0e6\x08!\xa9\x064\x00\x00 \x00IDATx\ +\xda\x9c\xbci\x98$Wy\xe7\xfb;\xb1\xe6\x9eY\x99\ +Y[\xd7\xd2U]\xbd\xaa\x17I-\xb5\xf6\xd6\x0e\x12\ +\x12\x18\x8cm`|\x19l#\x1b\xcc\xb0\x08\xcf\x18\xdb\ +c?\x9e\xe5\xdeg\xbc\x8c\xf1x{\xbc\x8c=6\xc6\ +\xf6\x18\x06c\x1b\x0c\xd8\x80\x05Z\x11\x12\xddH\xa8[\ +\xea}QU\xd7\xbe\xe4\x16\xfbz\xee\x87\xac\xcc\xae\x06\ +\xc6s\x9f\x9b\x1f\xba\xb3\x9e8q\xe2\x8d\x13'\x22\xce\ +\xef\xfd\xff\xdf\x14\xefz\xd7\xbb\xa4\xe38\xd4j5^\ +\x7f\xfdu|\xdfgaa\xc1\xfa\xe8G?Z,\x97\ +\xcb\x84a\xc8\x8b/\xbe\x88\xaa\xaa\x84aH\x18\x86t\ +:\x1d\xd6\xd7\xd7\xa9\xd5j\x9c9sfuhh\xa8\ +\xf8\xfe\xf7\xbf?[\xab\xd5\xf8\xf4\xa7?\xcd\xf0\xf00\ +\x17/^dhh\x88\xf9\xf9yL\xd3\xc44MN\ +\x9e<\x19%I\x12\xfc\xe2/\xfebaxx\x98g\ +\x9ey\x06\xc7q\xb8r\xe5\x0a\x83\x83\x834\x1a\x0d\x86\ +\x87\x87\xd9\xd8\xd8`nn\x0e\xdb\xb6;\xb7\xdf~\xbb\ +x\xc3\x1b\xdeP\xac\xd7\xeb<\xf3\xcc3\xac\xac\xac\x90\ +\xa6)\x8e\xe3P*\x95\xb8|\xf92Q\x14\xe1\xba.\ +\xf3\xf3\xf3\xb3\xefy\xcf{\xb6?\xf0\xc0\x03|\xe9K\ +_\xe2\xca\x95+\x14\x0a\x05\x82 \x8a\x22fgg\ +\xa9V\xab4\x9bM.]\xbat\xee\xae\xbb\xee\xda\xf9\ +\xb3?\xfb\xb3\xcas\xcf=\xc7K/\xbd\xc4\xf4\xf44\ +\x97/_F\xd34l\xdbfrr\x92s\xe7\xce\xb1\ +\xb8\xb8\xb8\xb4\xb2\xb2\xb2\xfc\xeb\xbf\xfe\xeb7f\xb3Y\ +N\x9c8\xc1\xfa\xfa:\xb6m\xa3\x0c\x0d\x0d\x91\xcb\xe5\ +\x10B099\x89\xa6i\x08!\xc8\xe7\xf3\xfc\xc8\x8f\ +\xfc\x08\x83\x83\x83T\xabU\xa6\xa6\xa6\xd8\xb1c\x07\xc5\ +b\x91R\xa9\x84\xae\xeb\x8c\x8d\x8d\x01\x10\x86!\x0f<\ +\xf0\x00\xd7_\x7f=\xa6i255\xc5\xe0\xe0 \xdb\ +\xb7o\xa7^\xafc\x9a&\xfb\xf7\xefG\x08\x81\xef\xfb\ +\xec\xdf\xbf\xbf\xbfmll\x8cR\xa9\xc4\xbe}\xfb\xc8\ +\xe7\xf3\x14\x0a\x05v\xee\xdcI\xa1P@UUVW\ +W\xb9\xfd\xf6\xdb)\x95J\xa4iJ&\x93\xa1T*\ +\x11\x04\x01\xba\xae#\x84\xa0^\xaf\xa3i\x1aRJ\xf6\ +\xee\xdd\xcb}\xf7\xddG\xb1Xdpp\x90\xe9\xe9i\ +\x06\x06\x06\x98\x9c\x9c\xc40\x0c\x86\x87\x87\xc9\xe5r\x00\ +h\x9a\xc6\xbe}\xfb0\x0c\x83\x5c.\xd7\xdf^(\x14\ +0\x0c\x83(\x8a(\x16\x8b\xa8\xaa\x8a\x10\x82\xc1\xc1A\ +n\xbe\xf9f\xc6\xc6\xc6\xd8\xbbwow\xdc\x0e\x1f>\ +,\x01\xa4\x94\xfd\x00;\x9d\x8e\x95\xcf\xe7\x8b\x99L\x06\ +\xd7u\x11B \xa5\xa4\xf7\x91R\x22\x84@\x08A\xa7\ +\xd3Y\x1d\x1c\x1c,\xa6i\x9a\x05\x88\xa2\xa8\xbf=M\ +\xd3\xfe\xbeRJ\xe28\x8e\xa2(\x0a\xf2\xf9|\xa1X\ +,b\xdb\xf6\xf7\xf4\xbb\xf5\x7fM\xd3:\xedv[\x94\ +J\xa5b\x92$(\x8ar\xcd\xf1\xb7\xf6_\xadVy\ +\xed\xb5\xd7f\xaf\xbb\xee\xba\xed\x8e\xe3\x90\xa6i\xff\x9c\ +zmz\xfb\xe8\xba\xce\xec\xec\xec\xb9={\xf6\xecl\ +\xb7\xdb\x8a\xa6i\xd7\x1cw\xebGJ\x89\xa2(Kk\ +kk\xcbCCC7\x9a\xa6\x89\xef\xfb\x08!\xba1\ +\xa6\x89l\x08\x01\x08P\x14\x05\xcf\xf3R\xcb\xb2.g\ +\xb3Y\xdd\xb6m\x04\x824\x95\x80@\x08\x09\x9bm{\ +\x07\x8b\xe3x\xa5\xd3\xe9\xec\xd14\xad$\x10\x9b\x07\xdd\ +\xfcG\x00\x9b\xfbl\x1e0\xf4\xc4\x83 I\x12\xc20\xc4\xf7}\xa2\ +$\xa4\xb1\x16\xf2\x8e\xeb\xfe\x1d9o\x86\xf7\xdf\xfc\x9b\ +\xbc\xe7\x9e\x9f!\x90n\xbf}\x9a\xa6[\xf6\x8dyt\ +\xfb\x87\xd9\xad?\xcc\x8f\xdd\xf2K\xdc\xbf\xe31D\xd1\ +'\x08||\xdf'\x8ec\xa28\xc2s]\xa2$f\ +\xbc\xb0\x9b\xa3\xa3\xef\xe4\x07\xa7~\x81\x01\xefv\xee\xbf\ +\xe1\xcd\xb8I\x1b\xdf\xf3\x89\xa2\x08\x00?\xf0q]\x17\ +]\xd3\x98\xd2o\xe7\x81\xf1\x9f\xe0\x86\xf2\xdb\xf9\xafo\ +\xf9\x12\xb2\xe0\xe1\xfb>\x9e\xeb\x91\xa6i7n/ \ +\x11\x09\xae\x1b\xf0\xa1\x83\x7f\xc2\x1bv\xbd\x9b\x8f\xde\xfe\ +\xe7LL\x8f\x12\xe2\xe1{>a\x18\xf6\xc7$\x08\x03\ +\xa4\xf0\xb9]{\x9c['\xde\x80\xa2\xc4:n\xe0\x10\ +\x04\x11\xbe\xe7\xf5\x1b{\x9e\xd7}\xfd'\x01\xfb\x87n\ +\xe3\xb3\xaf\xfd.\xf3K\xeb\x1c\x1c\xb9\x15\x05\xa5;\xc0\ +\xbeO\x92$DQ\x84\xe7y\x84A\xc8\x80>\xc1\xb2\ +5\xcb\x8b\xb3Op\xc7\xf4Cx\x91C\x14\x84\xfd\xfe\ +\x92$\xe9\xefk\xaay\x06ru\x9e_\xfa\x1bn\xa8\ +\xbf\x81Zn\x84\x92^\xc7\xf3\xaf\x0e`\x12'x\xbe\ +O\x1cE\xe4\xf4\x02J\xc6\xe5[\xe7\xbe\x85HUl\ +\xbfI\x1c&x~w`\x00\x02?\xc0u=4U\ +\xc5i\x09\xbe~\xfe\xf3(q\x9ej\xa5@\x92$x\ +\x9e\x87\xe7y\xf4\xee\x1a\xcfsQ\x15\xc1\xc5\xb3\x16\x03\ +C*\x1b\xce2\xd7O\xdeL53F\x10v\xe3\x88\ +\xa2\xa8{\xe17\xbf\xb7:\x1e?\xf5\xc8c\xfc\xd3\xf9\ +O\xa0$2%\xa3\x94\x88\xe2\x88 \x08\xfa\x03\xd8\x9b\ +%\x0a*~\xe2P\xcf\x8e3P\xa82\xb7>\x8b\x84\ +\xef\x19\xc00\x0c\x89\x93\x18?\xb1\x19,lC\x13Y\ +Z\xde\x1aY-G\x14\xc7\x84ax5\x90 \xc0\xf7\ +}$)\x0a\x1a\x9e\x03\xa9\xea\xd1r\xdb\xac\xdb+\x84\ +\x9b\xdb\x93$!\x8e\xe3\xcd\x81OIdB\x1a\x19\xcc\ +\x8c\xee\xa2\xe3\xd8\x943C\x84q\xd0\x8f\x15 \x08C\ +|\xdfCQ\x14\xf2E\x9d\xbdC7b\xf9M2J\ +\x09M\x18\xdd\xb6a\xf7.\x8b\xa2\x08\xcf\xf7\x91RP\ +\x190I\x02\x1d)\x05H\x85\x86\xbbL\x12\xa7\xfd\x01\ +\x94R\xe2\xf9>a\x14b\xe8\x1as\xcb\xcb\x18J\x16\ +\xedX\xfb\xd3xJ\x03\xdf\xf3\xb0\xec\x88l\x9aAJ\ +\x89\xe38\xf8qD\x11\x83/\xbf\xfeG\xbc\xf7\xd0\xaf\ +r\xb2\xf3\x0f\x5crO\x10\x8b\x00\xc7qPU\xb5?\ +x\xae\xeb\x92\x1a0RW\xf8\xc6\x99\xe7\xf8\xf9G\xff\ +\x1f~\xeb\x9b\x1fd|t\x9c4Iq\x9c\xcd\x19\xb5\ +9\x0b\xa4\x94\x0ch\x82\xa7.\xfd\x1d?\xff\xc6\xdf\xe4\ +S\xaf\xfd\x1a\x96\xefP\xcaTp\xddy\xe2@b\x18\ +\x06a\x18b[\x16\xbe\x1e\xb3d_b\x89E\xf6o\ +\xaf!\x07/p\xa9\xd1] [\x96\x8fa\xea\x00\xb8\ +\x8e\x83\xdbq\xd1R\x9d\xa5\xe8;\xdc\x9b}+Qq\ +\x8e\x8f?\xfdA\x14\x15l\xdbF\xd3\xf4\xab\x93\xc4\xf1\ +\x89\xf21\xdb\xb7\x0f\xf2\xd4\xa9\xaf2\xb3}\x86\xdf{\ +\xf1q2F\x860\x0e\xb0\xed\x18\xdd\xd4H\xd3\x14w\ +sL\xca\xf9\x22\xbf\xf5\xcc\xe3|\xec\xc1?@[\x5c\ +\x9b\xa5\xd1Yc\xf9l\x9b\xc8M\x91\xa4\xa4iJ\xab\ +\xd5\x22H\x22\x8aA\x1eW[\xe4\xf7\xbe\xf58\x8f^\ +\xff\xc3\x9c]=\xc6\xea\x0b\x92v\xdbFQ\x14\xd24\ +\xc5\xb6m\xda\xed6R\x15\x08\xa5\xc2\xf3\x8dO0>\ +7\xcajg\x8e\xc5\xd59\x16\xce4\xf1\xdaI\x7f\x0d\ +\x16\x86!i\x9aRH\xf2\xcc\x06\xdf\xe2\xd9\x85\xcfb\ +\xf9MN/\xbc\xc2\xec1\x9f\x8d\x15\x07\x04\x94J\xa5\ +.\xf9D)A&%QJ<\xb3\xfaW\xb4\xd3\xa3\ +\xf8\x9e\xc5K\x17O\xb0r\xda\xc1wb2Y\x13\xe8\ +\x0e\x90m\xd9\x14\x92\x02\x8eX\xe5\x8b\xb3\xbf\x8deY\ +,\xaf-\xb0\xf2J@\xbbaad\xb5\xfe$\xb1\x1a\ +m\x9c\xa2$\x91\x15\xbe\xd5\xfc\x14\xcb\xfe\x8d\x5cn\xbd\ +\x8c\xe3\xb8\x5c\xfaf\x03\x99\xa6\xe4\x92\x1ci\x9a\xd2h\ +4\xe9\xc8\x8402q3\x97\xf9\x95\xaf|\x041=\ +\xb1S\x0a\x04f^#\x8cB\xb2\xd9,Q\x14Yi\ +\x9a\x16k\xd5:r\xacCiXg\xe5;\x1e\xeb\x17\ +]L\xc3D\xa8\xa0\x1a\xdd7Y\x10\x04\xab\x03\x03\x03\ +EEQ\xb2RO)\xdd,\x89\x97R\x16^\xe9\x80\ +\xa7!\x14\x81jv\xd7`i\x9aFB\x88\xc00\x8c\ +B\xa5RA\xee\xb1(\x19:W\x8e[8K\x09\x9a\ +\xa6\x81*QuA\x92$\x14\x0a\x85N\xb3\xd9\x14;\ +gv\x16\x1b\x9d\x06\xa37\x1b\xcc\xbfhc7B4\ +EC\x92\xa2gT\xe2$\xa6R\xa90;;\xfb\xec\ +\xce\x9d;\x8f*\xa8$C\x16j*X~\xd5!\x8d\ +%\xaa\xa2\x224P\xbakf\xc20\xa4\x5c.[\x02\ +Ql\xe2s\xe3[\x0a,\x1cwY?\xe7!C\x15\ +d\x8a\x96\xedN\x10\xc30\xe8t:\xc7\xf2\xf9\xfc\x11\ +3[d\xfb#\x12g!a\xfd\x9c\x8fv\xc7\xdd\xb7\ +\xd2l6\x19\x1d\x1d\xe5\xc2\x85\x0bx\x9e\xc7\xca\xca\x0a\ +?\xf6c?\xc6\xbe}{\x99\xbb<\xcf\xcb/\xbfB\ +}\xbb$\x9d\xec\xbe\x00<\xcf\xa3\xd1hP,\x16\xb9\ +t\xe9\x12\x9a\xa6\xf1\xd3?\xfd\xd3\x0cT\x06\xf8\xabO\ +\xfe5\x95j\x85\xf2\x9e%j\xb5\x1a\x0b\x0b\x0b\x18\x86\ +\x81\xa2(\x5c\xb8p\x810\x0c\xf9\xc0\x07>\xc0\xc1\x83\ +\x07\xf9\xe4\x9f\xfe\x05\xaa\xd40F\x97\x19\xbc\xbe\xce\xc6\ +\xc6\x06\x03\x03\x034\x9bM\x16\x16\x16\x08\x82\x80;\xef\ +\xbc\x93\xc7\x1e{\x8c0\x0cy\xe6\xc9\xe7\x18\xbdq\x19\ +US\xe9t:\x14\x0a\x05\x16\x16\x16p]\x97$I\ +PU\x95\x87\x1ez\x88\xb7\xbf\xfd\xed|\xe1s_\xe4\ +\x95\x13'\x98\xbeS#\x9f\xcf\xb3\xb0\xb0\x80\xe38d\ +\xb3Y\x9a\xcd&\xcb\xcb\xcbT\xabU>\xf2\xf8G\xb8\ +|\xf1\x12\xcf>\xf5M\xf6\x0cd\xd9}[\xca\xfa\xc6\ +:\x85B\x01!\x04KKKX\x96E\x92$|\xe0\ +\x03\x1f`jj;O\x7f\xed\x1b4\xd3\x06\x83\x13.\ +\xda\xe0\xe0 \x8e\xe3`\x18\x06SSS\x9c;w\x8e\ +$I\x98\x99\x99\xe1\xe8\xd1\xbb9U;\xc5Zc\x95\ +\xc1\xc1A\x14E\xe1\x95W^att\x14\x80\xe1\xe1\ +a.]\xbaD\x9a\xa6\xdcv\xdbmd\xb3Y\xbe\xfc\ +\x95/s\xfd\xf5\xd7s\xe6L\x16\xc30\xfaW\xfb\xc0\ +\x81\x03\x5c\xbcx\x11\x80\xc3\x87\x0f3>>\xce-w\ +\x1caee\x05/\xb2\xd9\xb1c\x07i\x9a244\ +\xc4\xae]\xbb\xf8\xcaW\xbe\xd2\x9b%\x94J%\x86\x86\ +\x86x\xf5\xd5W\x11\x9a$\x9f\xcfs\xfc\xf8q\xc6\xc6\ +\xc6h6\x9b\xe4\xf3y\xd6\xd6\xd6\x10BP*\x95\xd8\ +\xbd{7\x03\xf5\x0a\x95j\x89r\xb9\x8c\x94\x92Z\xad\ +\x86eY\x0c\x0d\x0d\x11\x04\x01B\x08\x0a\x85\x027\x5c\ +\x7f\x03\x193\xc3\x99\xb3g\xd9\xbbw/kkk \ +\xa0P(0::J6\x9b\xe5\xe4\xc9\x93\x00\xdcq\ +\xc7\x1d\x94J%:\x1d\x0b\xcf\xf38y\xf2$\xe2\xc6\ +\x1bo\xec\x03`\x8f\x85\xdb\xed\xb6U*\x95\x8aA\x10\ +\xf4\xf9\xf3\xfb}\x14E\xa1\xd3\xe9\xac\x0e\x0d\x0d\x15\x1d\ +\xc7\xc9\xf6\x10\xec\x7f\xf7\x89\xe38\x0a\xc30\xc8\xe7\xf3\ +\x85\xef\xc7\x9d\xdf\xcd\xda\x8a\xa2t:\x9d\x8e(\x95J\ +\xc5\xffS\xfbr\xb9\xcc\xa9S\xa7\x9e\xdd\xb9s\xe7Q\ +\xcf\xf3\xf8\xdf\xc5\x22\xa5D\xd34666\x18\x1c\x1c\ +\xb4\x82 (\xfeKq\xf7bY[[;644\ +t\xa4\xc7\xd6\xbd\x8f\xb65\xaeM\x16\xc6\xb2\xac \x9f\ +\xcfg\x15E\x91H\x90\x89\xd8\xc2\xb4\x9b\x8d\x05\xa4i\ +*\xe28\x8e;\x9d\x0e= G\x0ad\x17SA\x91\ +\xfd\xb6\x9b\xc1H\xdf\xf7\xe3L&\x13+\x8a\x22\x85\x14\ +]\x06\x15\x12\x94\xcdf[X\xd8\xb2,\xdf\xf7\xfd\x0d\ +!D\x19\x90$\xa2\xcb\xd9\xca\xb5\xb1H)\x85\xe7y\ +\x91\x94raccc]J\x19\x90\x8a.'\xa7\x02\ +\x94.\x0bo\xc6!6\x9f\xdd\x0d\xcb\xb2\xb6\x9b\xa6\x19\ +\x0b\x90i\xb2\xd9\xd9&7\xb3%\x96 \x08\x94$\xe9\ +6P\xc4&\xbf\xcb\xcdd\xc2\xf8\xae!\xa4\xa7v\x0f\ +\xd4\x1d\x14\x96\x96\x96.\xed\xd8\xb1\xe3\x80\xe7zi\x98\ +s\xc9\xef\x08\x10\xaeF\xd26I-\x1d\x19uwV\ +UU\x00rxxXd2\x19\x02\x11\xc2t\x8bR\ +A%\xee\xe8\xd0\xce\x90Z\x1a2Q@\x82\xe7yr\ +qq1\x1a\x1b\x1b\x0b\x14E\x91\x8d\xcc\x06c\xbb5\ +\xa2\xa6\x86l\x9b$\x8e\x0aI\xff\xea\x8av\xbb\x1d\x04\ +A0691Y\xf2\x93\x10uG\x9b\xac\xae\x934\ +\x0d\x12KG\x06\xdd~\x01L\xd3\xe4\xc9'\x9f\xbcp\ +\xe8\xd0\xa1\xba\x8c%\xab\xb9e\xb6\x1f\xd0\x08\xda \xdb\ +\x19\x92\x8e\x01\xbe\x8aL\xc10\x0c\x8e\x1f?\xbemb\ +bb\xde4L\xa5\x15\xdar\xe0\x90\x8f\x96\xea\xc4\x0d\ +\x9d\xb4\xd3e\xf2n\x92\x03aYV\x9c$\xc9\xc4\xf4\ +\xf44\x96\xef\x93\xd9cQ\xa8(\x04\x9d\x14\xad\xfe\x03\ +\x1b\xe8\x8aI\xf3\xc9.\xf7\x19\x86@U\xd5\x01\xd34\ +s\x9e\xe7\xa3n\xf7\xa9\xdc\xee\xa0\x87E\xc2x\x0d%\ +6\x90\x81F\xe3\x8b\xdd\x1c\xdc\xe6-\xae&I\x82\x9d\ +\xb1\x19\xbc\xbe\xc3\xee\xf1\xfd\x90\xa6\xcc\xad\x5cDUT\ +:\xcf\xd4\x09\x17u\xd24UTU\xcdi\x9a\x96\x17\ +B\xc0\x1e\x8b\x81\xdb5ri\x9dV{\x1d!\x15\xc2\ +s\x15\xac\x139\x84\x90h\x9a\x96z\x9e\x07R\xb2!\ +[\xec\xbf\xdfFK2\x04n\x03=\xcd\x10\xb9\x02\xfb\ +x\x99`QG\xc9*H)7\x1f\xba\xe0\xee]\xa7\ +t\xc3\x00Uu\x8auk\x0e\xcb\xb2\xd1:U\x1aO\ +\x14\xe9\xa5\xc6\x0c\xc3\xa8\xe8\xaa\x9e\xbf\x98\xac\xf2\xe6\xbb\ +sD\x81O\x96\x12\x1d{\x03C\xe4\xe8|\xa3L\xb8\ +l\xf4r\x8d\x91L%V\xea0z8\xc0S\xda\xbc\ +q\xe7\x0f\xa2<\xba\xfbq\x8a\xd5\x22\xb1\xec\xf2\xec&\ +\x0bK\xdf\xf7\xf1|\x9fT\x84Lr7\x1f\xbc\xf3\xbf\ +\xf2\xaf\xaf\xfb\x0d\xf6\x0c\x1dex\xdb`\x9f&\x92$\ +\x91\xbdLu\x9cF$\xcd\x0a\xf7\x8e\xbf\x93C\x85\xb7\ +r\xcf\xf6w\xf3\xa6[\xdeAx-\x0b\xcb\xdeq\xe2\ +4\xe1\xd1\xed\x1faRy\x80\x07\x0f\xbc\x8b\xa33\xef\ +\xc2\x11\x1b[)G\xc6q\x8c\xe7\xfa\x84I\xc8Hv\ +\x9aG&>\xca\xcf\xdd\xfdI\xbcf\x9d\x1d\xd3S\x84\ +\xd2\xed\xf3j\x8f\x85=\xcf\xc50T\xa6\xd5\xbbx\xcb\ +\xd4\xe3\x1c\xaa\xbc\x95_y\xcb\xdf\x93\xe6\xec\xcdU\x84\ +\x8f\x94\x920\x0c\xa5\xefzD2\xc2s#>|\xfd\ +'\xb8\x7f\xf7\xbb\xf8\xd0\x1d\x7fHe4G$\x83>\ +gK)\xf1=\x8f8\x89hvZ\xfc\xeeCO\xb3\ +\xb4\xbe\x862^\xd8\xc3\xc1\x91;7\x07\xa4\xcb\xc2B\ +\x08<\xcf\xc3\x0f|\xc28\xe0\xba\xa1[y~\xe1\xef\ +y\xe1\xe4\x09n\x9fz\x08M\xd1\xfbL\x99$\x09A\ +\x10tY8\x0a\x19+\xeef\xb1s\x91\xf3k'\xb9\ +m\xfa\x01\x924!\x0ec|\xbf{\x92[\xdbg\xd4\ +<\x95\xcc \xaf{/\xb0\xbf|?;\x87\x0eP\xd2\ +\xeb\xf8\xbe\x8b\xe7y\xc4qL\x1c\xc7\xf8~\xf7{)\ +S!WLx\xf6\xc4\xf3\x1c\x1c\xbd\x83\xdd\xb5\x9bp\ +\x03\xe7{Y\xd8\xf3QU\x15\xa7-xq\xee\x9f\xc9\ +\x8a*C\x03C\xa4I\x17A\x03\xdf\xef'\x13<\xcf\ +CQ\x15.\x9f\xb3\x18\x1a\xc9\xe2G.7L\xdc\xc2\ +d\xe9:\xfc\xb0\x1bG\x0fA=\xdf'\x0a#4\x99\ +a\xb8:\xc4Fz\x06\xcd\x09l\xce\xae\xbcJ\x14\xc5\ +\xf8^\xda}\xa0Cw\xc6\xf8\x01\x86\x14\xb8\xa1\xc5`\ +i\x02Y\xc8\xf3\xfa\xfa\xb9\xfevUU\xfb,\x1c\xc7\ +1i\x92\xd2\xf4\xd7\x18-?Ls=e\xc5\x9d\xc5\ +T\xb3DQD\x10$}\x02\xe9etuR\x14E\ +\xc1w%F\xceg\xfe\xd2\x02\x1b\xf6\x0a\x81o\xf6_\ +\xf3\xeaos9x\x8e\xacV\xc0q]\ +\x1c\xc7\xe9_\x18\xcfu\x09\xc3\x88e\xfbu\xd6[-\ +(\xb4H\xab\xb3\x04i\x17\xee\x1d\xc7\xe9gX\x1c\xc7\ +\xc1\xeaX$i\xca|\xf4m4\x91\xc1\xcf]\xe4w\ +\xbe\xf93\xa8\x9a\x8aeYX\x1d\xab?\xd8\xae\xe3\x12\ +\xc7)SS\x15\xbe\xfc\xca\xe7\x19*\x8d\xf0;/\xfe\ +\x9b\xae&\x12\xfb8\x8e\xd3\xcf\x22Y\x9d\x0e\xae\xeb\x91\ +\xcfe\xf9\xb5\xa7\xdf\xcf/\xdd\xf3\xe7h\xae\xb2\xce\xdc\ +\x859\x96\xce\xb5\x08\xac\x84\x84\x04\x80f\xb3I\xab\xd3\ +!\xef\xe6\x09U\x95\xbf\xbb\xfck\xbc\xe5\xf0;\x99\xbb\ +\xf8\x1ak/I\xda\xedN\x7f\x8d\xd8\x9b\x85\x94\x14\x14\ +\xd5\xe0x\xe7S\xd4\xd7\x14\xda\xd12\xf3_\xd9`\xfe\ +D\x9b\xc8N\xbf/\x0b/\xf8\xdf\xe1\xb9\xa5\xffE\xa0\ +\xd9\x5cz\xfd\xe5\x90v4\xf4\x9c\x82\x96\xed\xb2p\x1c\xc7\ +\xb6\xaa\xaaf.\x97\xd3c#b\xec\x1e\x83`!a\ +\xe9\x94\x83s\x05\xb4\x8c@\xcf\x8a>\x0b+\x8a\x12\xa8\ +\xaaZ\xc8\xe5r\x18\x87\x22j\x15\x9d\xc5\x93\x0e\x1b\xa7\ +bD\x22\xd0s\x02a\x80L%\x85B\xa1\xb3\xb1\xb1\ +!\x86\x86\x86\x8a\x9d\xd8\xe6\xd0\x0f\x17Y;\x15\xb2|\ +\xd2\xc6_VP\x0c0\xf2]}\xa2Z\xad2;;\ +\xfb\xec\x8e\x1d;\x8e\x8aT\x90N8\xe42\x1a\x8b/\ +;x\xeb\x09\xba\xa9\xa2\x1a \xb4\xee\xda.\x0cCJ\ +\xa5\x92\x15\x87q\xb1cF\xdc\xfc\xd6\x22\xab\xaf\xf9\xac\ +\x9e\xf6\xf0W\xba\xed\x8cB\x97\x85M\xd3\xc4u\xdd\xf5\ +|>_\xcf\x97\x8bT\x0eDt\xe6#Z\x97C\xb4\ +;\xee\xbd\x05\xc7q\xa8V\xab\x5c\xb9r\xa5\xa7\x0b\xf3\ +\xe0\x83\x0fr\xf0\xe0A:-\x8bc\xdf:\xce\xd8H\ +\x96\xf1L\x83b\xa9\xc0\xd2\xe2\x12\xcdf\xb3\xa7\x0b3\ +==\xcd#\x8f<\xc2\xf0\xd00\xff\xf3/?\xc5\xde\ +\xc9\x09J\x13\x0b\x8c\xde:\xca\xca\xca\x0aa\x18\x92\xcb\ +\xe58y\xf2$i\x9a\xf2\xde\xf7\xbe\x97\x83\x07\x0f\xf2\ +\x99O\xfd\x0d\x197\x8b\x9a\x9b\xe7\xae\x1f\x9e\xdc\xd4\x90\ +\x0dTU\xe3\xdc\xb9s\x84a\xc8\xe1\xc3\x87y\xdb\xdb\ +\xdeF\x12'\x9cx\xf9U\x0aj\x8bm\xfb}\xb4\x1b\ +\xbbi\xfc\xd7_\x7f\x1dEQp]\x17UUy\xe3\ +\x1b\xdf\xc8\xdb\x7f\xa8\xcb\xc2\xaf\x9e|\x95\xd1\x1bT\x86\ +\x86\x079w\xf6\x1c\xae\xeb\x92\xcb\xe5h\xb5Z}\x16\ +\xfe\xc9\x9f\xfcIV\x96Wx\xfa\xc9\xe7\xd8;Xe\ +\xfb\xf5\x1e\xcdV\x83r\xb9\x8c\xa0\xcb\xc2\x8dF\x03!\ +\x04\x1f\xff\xf8\xc7\x11B\xf0\xd4\xd7\x9e!-'\x5c\xc8\ +\x9cG\x1b\x1b\x1b\xe3\xd2\xa5K\x14\x8bE\xb6m\xdb\xc6\ +\xe5\xcb\x97I\x92\x84={\xf6\xf0\xf6\xb7\xbf\x9d\xb9\xb9\ +9V\xd7W\xa8T*\xb8\xae\xcb\xf2\xf22\x03\x03\x03\ +X\x96E\xa5R\xe9\xeb\xab\xefx\xc7;P\x14\x85c\ +\xc7\x8f1==M\xa1\x9cG\xd7u\xb2\xd9,\xcb\xcb\ +\xcb\xec\xd9\xb3\x87\xd7^{\x8d(\x8a\xb8\xe7\x9e{\xb8\ +\xe9\xa6\x9b8\x7f\xfe<\xcdf\x13\xcbm399\xd9\ +\xcfZo\xdf\xbe\xbd\xcf\xcd\xdb\xb7o\xef\xeb\xbc\xae\xe7\ +\xb2\xb6\xb6F\xa5R\xe1\xc5\x17_dhp\x88j\xb5\ +\xda\x17\xfc\x01j\xb5\x1a\x07\xf6\x1f\xe0\xf9o\x9f\xa7V\xab!\x84\ +\xa0\xd5j\x91\xa6)SSS\x84a\xc8\xd0h\x1d)\ +%\x8bK\x0b\x88\x1bn\xb8\xe1\x1a\x16\xcef\xb3\xcc\xce\ +\xce\x9e\x9b\x9e\x9e\xde\xddK|\xaa\xaa\xfa=\x9am\x0f\ +\xb7<\xcf\xb33\x99\x8c\xa9\xaa\xaa\xbe\xb5\xcd\xa6|\xd8\ +o\x9b$\x09R\xca(\x8a\xa2@U\xd5B>\x9f'\ +\x8e\xe3~?\xbd7c\xef\x99\xaa(\x0a\xba\xaew\x1a\ +\x8d\x86\xa8\xd5jE\xdf\xf7\xd1u\xbd\xdfVQ\x14\xe2\ +8FQ\x14\x92$\xa1V\xabq\xea\xd4\xa9g\xa7\xa6\ +\xa6\x8e\xb6\xdbm\xb2\xd9\xec5\xcc\xba\xf5\xbba\x18\xac\ +\xae\xaeR\xaf\xd7\xad0\x0c\x8b=Q\xbe\xa7%\xf7t\ +\xe4^L\x9b\xcc\xbf^,\x16\xeba\x18b\x18F_\ +\x17\xd7\x0a\x85b*\xb6\xf0j\x18\x86\x8a\x10B\xc9\xe5\ +rd2\x19\xc4&\xdb\xf6\xf4\xd2Ma\xb6\x1f\x94\xeb\ +\xba\x81\xa6ij&\x93Q\x85\x10\x90n\x8a\xf0\xdf\xc5\ +\xcd\x9bK\x9fh}}\xdd\xaf\xd7\xeby!\x84\xcc\x9a\ +Y\xd2dS\x0f\xde\xc2\xc2\xbd\xcf\xfa\xfaz\x92\xcdf\ +\xf5L&\x93f2\x99.\x93\xb3E?\xde\xd2~s\ +\xad\x16FQD\xbe\x90OE\xda\xe3l\xfaK\xb3^\ +,\x9bYt\x99$IR,\x16\xbb*\xf6\xbf\xd0\xb7\ +eY\x22\x08\x02\xafT*\xc5\xa6iJR\x90IW\ +o\xd6Fv\x97\x93\xc4\xd2 \xee\xbf\x14\x12\xdb\xb6k\ +\x13\x13\x13\x84QDR\xf4\xc8\x8d\xc4\xa4\xbe\x02\xbeN\ +\xea\xa8\xa4\xae\xda\xbf\xa2\xb6m\xaf\xd7\xeb\xf5\x9ai\x9a\ +Z$b\xc4\xa8M.\xabu\xb5[\xd7 \xb1UD\ +\xd2\x1d\x1d\xcf\xf3\x9c \x08\xd6\xea\xf5\xfa\x80\xaa\xaai\ +;\xd3dhR%v\x14\xf0t\x12WE\xfa*=\ +\x81>\x0c\xc3(\x9b\xcd\x16k\xb5Z\xe2\xa4\x1e\xa5]\ +\x01$\x0a\xa9\xabv\xdb\xdb*$\x0a 1MS\x5c\ +\xbat)>x\xf0 i\x94&\x8d\xfc*\xdbvi\ +\x846\xe0\x99\xa4\xaeB\xea\xe8\xc8P`\x9a&\xedv\ +;\x19\x1e\x1e\x8es\x99l\xd2\x0cmY\xdb\x17#\xd2\ +n\xdf\xd2\xd3Im\x15\x19+(\xaa\xc00\x0c\xc5\xf7\ +}g\xef\x9e\xbd\x81\x1f\x86\xa9\x1c\xb6)\xd6\x15\x12O\ +\xa2\x95\x1e\x5c\xd5UU\xa5\xf1\x85\x1a\xb1\xd5e[!\ +\x84n\xdb6\x96\xef\x92\x8c\xad\x91\xd9\x1f\xb1-?\xcd\ +J\xebu4\xa9\x90\xba:\x8d/\xd6zo\xb3,\x90\ +I\xd3T\xef\x18\x16CG\x9a\x8cV\x07Q\x114:\ +\xcb\xe8\x19\x95\x8d/\xd6\x88\x9b\x1aI\x92d\x85\x10\x85\ +4MU@\xf5w\xacS\xbe%KM\x1fg\xa9y\ +\x05E\xa8x\xa7\x0b\xd8\xaf\x14\x00\x89\xae\xeb9@\x13\ +\x09,i\xebl\xbfKb\xa4%d\x9a\x10\x04m\xd2\ +@\xa1\xf3b\x89`\xde@\xcd\xa9$I\x92\xf3<\x8f\ +\xd4M\xf5\xd5\xa99\xa6\x0f\x0e0\xaeM\xb3b\xcd\x11\ +y)q[c\xe3\xcb\x15\xc20B\x08\xa1\xab\xaa\x1a\ +\x93\xa2\x9d\xf2\x17x\xeb\xd1<\x2260D\x86\xb6\xbd\ +\x8e\xae\x99\xb4\x9e*\x13.\x19\xbd[\xba\x1eEQ~\ +\xd5\xea0\xfd\x88\x8dZ\xf6\x98*\xedFyd\xe7\xe3\ +\x0cT\x86\x08\x93\xb0\xbf\xa2\x07d\x10\x04\x84AH\xac\ +\xfa\xdc^{7wo\x7f'\xff\xe9\x0d\x7f\xcbt\xe5\ +6\x06\xea\xa5\xfe\x83\xbb\xc7\x94A\x10\x10\xcb\x90\xd6\x1a\ +\xbc\xeb\xe0\xcf\xf3\xd0\xc4\xe3\x1c\x9a8\xca\xdd\x07\x1f\xc6\ +\x0f\x9d^{\xd9\xd3\x91\xc30$\x8c#\xde<\xf3A\ +\x86\xd2\xdby\xd3\x0d\xef\xe2\xc8\xe8\x0f\xe1\xd2\xc2\xdf\x8c\ +\xa3\xc7\xc2\xbe\x1f\x90\xc8\x88\x89\x81\xdd\xfc\xc8\xde\x7f\xcf\ +\xbf;\xfa\xdfY\x9e\xd7\xd919C\x94\xfa\x04\xfeU\ +U\xae\xcb\xc2\x1e\xba\xa12c\x1c\xe5\x8d\x13\xff\x86\xbd\ +\x85\x87\xf8\xc57~\x92\xd8\xb0\xfb\x9a\xf3\xa6*'}\ +\xcf'%\xc6\x0fB\xdew\xf0\x0f\xb9w\xe7;\xf9\xe0\ +\xad\x7f@\xa9\x96#\x96]\x1a\xbb\xaa&\xfa\x04QH\ +\xa2z\xdc[\xfaY\xf6\x0e\xde\x8a\xb2\x7f\xe40#\x95\ +\xb1.\x1dx.\xfe&'\xf6\xde\x88q\x1c\xb0\xb7~\ +\x84\xaf\x5c\xfcs._Y\xe4\xd0\xb6\xdbPdw\xd9\ +\xd0\xe3\xd5>\x0b\x87!\xbb\xaa7q~\xfd\x15\x8e\xcd\ +=\xc9\x1b\xa6\xff5\xba\x92!\x0c\xbb\xf6\xb3^\xdf=\ +\x12\xc9\xe9E\x8af\x95\x0b\xce\xb3\x5cW\xb8\x9f\xd1\xca\ +$\x06\x19<\xcf\xed\xaa|i\xda\xd7n\xd3$%\xa3\ +dI\xf4\x16O|\xfbI\x0e\x8d\xdcA-\xb3\x0d?\ +\xf0\xfaq\xf7X\xd8s]4U\xc5j\xc2K\x8bO\ +RT\x87\x19\xa9\x0eA*\xf0=\x1f\xdf\xef\x0a\xebA\ +\x18\xe0y.B\x11\x5cw\ +\xf1\xe3x\xda:A\xe0\xe3\xba)\x19\x99^u&\xc4\ +\x11e%\xcb\x17.\xff.?}\xf8\xe3<\xb9\xf8\xdf\ +\x99\xeb\x9c\xc7O\xec.\xcbn.!zY\x16\x19C\ +\x98\x9f\xc3\xee$\x1c\xd9s#\x7fs\xea\xb7\xa8\x0c\x16\ +\x88\xa2\x18\xd7\x0d\x89\xe3\xb8o\x91\x00\xc8\x18\x0aO\x5c\ +\xf8_|\xe4\xde\xff\xc2_\x9c\xfaE\xe2X\xa2\xa2\xe1\ +\xba]YS\xd7\xf5n\xf0\x91$M%\x0b\xed\x0b,\ +\x8aUJ%\x03mx\x8e\x85\xb6N\x1cwm\x19\x99\ +\x9c\xd9\x8d\xdb\xf5p-\x17Cj\x5c\x09_b\xc6\xbb\ +\x81\x96\xf6\x1a\xbf\xf9\x8d\x0f\xa0\xeb\x1a\xb6\xd3FW\xf5\ +\xbe\xb0\x1e\xba\x01iQ255\xc0WO~\x81\x99\ +\xc9Q~\xfd\xf9\x1f'\x106Q\x1c\xe1\xba\x11\xaa\xae\ +\x5c\xbd+\xe3\x88r\xa1\xcc\xef|\xf3q>r\xf4\xd7\ +\xd1l}\x99\xf5\xc5\x16+\xaf7\x89\x83\x94\x5c\xd4\xd5\ +@\x9b\xcd&~\x12\x91ws\x84\xea:\x7f\xf0\xed\x8f\ +r\xc3\xcc\x8d\xb4ZW8\xffO\x01\xad\x96\xdb\xd7\x85\ +\xdb\xed6q\x1cCN E\x95\xcf_\xfeo<\x9c\ +\xf9W4\xd3y\x16\x8f\xe9\xac\xce6\x89\x9c\xee\xbaJ\ +\xd3\xb4\xbe\xff&\x17\xe5X\x8e^\xe5\xef\xce\xfe\x0e\x8e\ +l\xd2\xf6\x9a,]\xb4hnaa\xcf\xf3H\xfc\x98\ +pP\xe0\xcb\x0c__\xf8S\x0ekGI\x0b\x1d\xe6\ +/\x84,\x9cn\xe1\xb5c4\xa3\xbb2\xb0,\xab\xcb\ +\xc2q\x81@Y\xe3E\xfb/H\x8c\x80\x85S\xeb\xbc\ +\xfe\xb4K\xa7\xe9~\x17\x0bw\xe8\x14RbJ\x1ck\ +~\x86\xf9x'M\xed2\xeb\x97\x5c.|\xa3+0\ +e2\x19\x92$ac\xa3AG&\x04\xa1\x8e\xa5\xbc\ +\xce\xc7\x9f\xfe\x08b\xfb\xc4\xb4L<\xc8T\xba\x9d\xe6\ +r9\xa2(\xb2\xa4\x94E\xdd00'\x13\x8a\x83*\ +\xf6RDc\xd6#j\xa8h\x86\x82\x9a\xe9/\x90\xe7\ +4M\x1b0M\xb3\x18\xeb\x11C\x87\x0d\xe2F\xc2\xc6\ +\x15\x07\x7fY%\xf1%fY%M\x13\x00\x0bh\x1a\ +\x861\xa9i\x1a\xe6\x9e\x84rQ\xa71\xe7a\xcf'\ +\xf8\x1b\xa0\xe7\x15\x14\xbdko+\x16\x8b\x96\xe7y\xc5\ +\x8ca\xe2\x19\x013w\xe6h\xcf\x854\xe7]\xfcU\ +\x95\xd8\x97dJWYxnn\xee\xd9\x89\x89\x89\xa3\ +I\x94\xa2\x8c\x85\xe4s*\x8d\xd7\x03\xac\x85\x10\x81\x8a\ +f\x8aM[\x9eJ\x10\x04\x94\xcbe+\x0a\xc2\xa2e\ +\xc4\xec\xbf\xa7@s6\xc0Z\x0ap\x16$i\x04f\ +E!M\xba\xba\xb0\xe7y\xeb\x86a\xd4Qu&\xef\ +\xd6\x88\xec\x14w-F;r\xcbM4[M\x0a\x85\ +\x02\xedv\x9b \x08XXX\xe0\xb1\xc7\x1e#\x9f\xcf\ +\x93\x84)/\xbd\xfc2ZM\xc5\xcd9(\xaa\x82\xe3\ +8\xac\xae\xaeR\xadV9{\xf6,333\xdc\x7f\ +\xff\xfd\x0c\x0f\x0d\xf3\xe9\xff\xf9\x19vMM\xb0\xe0.\ +\xb0\xed\xe0(\x1b\x8d\x0dl\xdb\xa6R\xa9\xf0\xca+\xaf\ + \xa5\xe4}\xef{\x1f\xf5z\x9d'\xbe\xf25t\x0c\ +2\xc6\x22\xe3\xf7\x8c\xb1\xba\xb6\x82\xd1\xb5\xa9\xf5\xfd\xda\ +w\xdey'7\x1e>\x8c\xa1\xe9|\xfb[/3\x5c\ +\x0ah\x8f\xb7\xd1\xa6U\xaa\xd5*g\xce\x9c!\x93\xc9\ +lZ64\xee\xbb\xef>\x1e}\xf3\xa3\xbc\xf0\x8d\x17\ +y\xe9\xa5\x97\x98\xda\x97\xa1|{\x89\xd9\xd9Y,\xcb\ +\xa2\x5c.\xb3\xbe\xbe\xce\xd2\xd2\x12\xd5j\x95w\xbf\xfb\ +\xdd466x\xe6\xa9\xe7\xd9W\x1f\xc0\xcfz4\x06\ +\x1a\x0c\x0e\x0e\x12\x86!+++\xb4\xdbm<\xcf\xe3\ +\xc3\x1f\xfe0\x99L\x86W_9MKi\xe2\x97=\ +\xb4\xa9\xe9)\xdcS.\x9a\xa6133\xc3\x993g\ +H\xd3\x94]\xbbv\xf1\xc8#\x8f\xf0\xe2\x8b/\xb2\xde\ +\x5c\xa3V\xab!\xa5\xe4\xfc\xf9\xf3\xd4\xebu<\xcfc\ +``\xa0o\x9b}\xec\xb1\xc7\xf0}\x9f\x13'O0\ +33C\xa1\x94\xa7\x5c.S\x1f\xacs\xfa\xf4in\ +\xba\xe9&N\x9c8A\x10\x04\xdc\x7f\xff\xfdLMM\ +\xd1n\xb7\xd9\xd8\xd8\xc0\x0b\x1d\xf6\xee\xdb\x0b\x02\x5c\xd7\ +e\xf7\xee\xdd\xcc\xcf\xcf\x03\xb0m\xdb6\xde\xf9\x8ew\ +\xe0y\x1e\x17.^@\xd7\xab\xec\x1f\xb8\x8eo\x7f\xfb\ +\xdb\xd4j5\xea\xf5:\xba\xae\xf7\xb3\xe3\xbbw\xef\xe6\ +\xbe{\xef\xe3\xe4\x89\x93\xd4\x06\xab\x98\xa6I\xb9\x5c\xa6\ +\xd5j\xf5/\xa4eY\x00\x94\xcbe\xde\xf6\xb6\xb7\xf1\ +\xc2\x0b/p\xfe\xc2\x05\xf6\xee\xdd\x8beY\x5c\xbcx\ +\x91\x81\x81\x01J\xa5\x12\xa6i\xf2\xdak\xaf!\xa5\xe4\ +\xc8\x91#LLL\xf4f$\xaf\xbd\xf6Z\xd7#\xdd\ +c\xbf(\x8a\xc8f\xb3X\x96ee2\x99\xe2\xb6m\ +\xdbXZZB\xd3\xb4\x1e\xcb\xf6Y\xb4\xb7\x8f\xeb\xba\ +s\xd9lv`dd\xa4\xd8K>\xf6\xb6\xa7i\xda\ +\xff\xbe\xe9\xdf\xb3\xc20l\xe6\xf3\xf9\xc9\xf1\xf1q\x16\ +\x17\x17{\x0b\xf7\xee3t\x93\xa3{\x8c\xabi\x9a\xe5\ +\xbanqff\xa6\xefpH\xd3\xb4\xcf\xca=\x96N\ +\x92\x84j\xb5\xdag\xe1\x9eQ`+\xe3\xf7r\x97\xbd\ +\x9cd\xa3\xd1`hh\xc8\xca\xe5r\xc5\xad+\x84\xad\ +\xb1\xf7X^Q\x14\xda\xed\xf6z\xb5Z\xad\xd7j5\ +\x9a\xcdf\x9f\x99\xb5l&\x1b\xf4\x98o\xf3\xf9'm\ +\xdbn\xd4\xebu\xa3\xd1h\x90\xcd\xe6 \x05]\xdd\xc2\ +\xc1[\x18\xdd\xb6m?\x93\xc9H\xc7q\x10B\x905\ +s}\xdfr\x9f'\xaf\xb2\xb0\xf0<\x8fL&\x13\xae\ +\xaf\xaf\xcbl&K\x9a\x82@\xa2k\xc65\xcc*\x13\ +j\x82&\x00\x00\x1fEIDAT\x84`uu\xd5\ +\xca\xe5r\x99v\xbb\xad\x17\x8b\xc5.\x93\x7f\x9f~{\ +\x03\x93\xa6i\x1b\xe8\x14\x8b\xc5\x10I\xbf\xfdw\xf3\xb0\ +\xaa\xaa\x04A\x10\x85a\xa8\xab\xaaj\x02RSt4\ +E\xbf\xf6\x1c\x05\x08\x04\xb6m\x8b$IVr\xb9\x5c\ +\xd9\xb6\xed\xd4\xd0\xcd\xbe\x9c\xaa\x8d\xec-\x99\xf1\x86\x81\ +H\x05\xa8]\x9d\xe0\xf2\xe5\xcb\xcd\xb1\xb1\xb1\xed\x9e\xe7\ +\x93\x16=\xb2c\x11i\x92\x82\xab\x93\xb42$-\xad\ +\xef\x91v\x1c\xa7011\xa1\xaa\xaaJ\xac$$\xdb\ +\xda\x94\xcb*I$Q\x82\x0cQCC::\x02\x81\ +\xe38\xba\xe7y\xa5z\xbdn\xa8\xaaJ3\xdb`b\ +\x87N\xe4'\xc8N\x96\xa4\xad!]\xb5\x9f\xf4t]\ +7\xc9d2\xf6\xf6\xc9\xc9\x017\x0e\xc8\xefuP\x84\ + uU\xd2\x8eI\xd2\xd4!\xa5\xeb\x916\x0c\xce\x9c\ +9\xa3OLL\x94d\x22i\xe66\x18\x99\xd6\x88\xfc\ +\x14l\x93\xa4\xad\x93t\xbaq\x1b\x86\xce\xca\xca\x0aC\ +CC\xcd\x5c6g\xac\x07\x1d\x86\x0ft\x0d\xec\xa9\xab\ + -\x93h\xa3\x1b\xb3\xa2w\x97S\xedv{nh\ +pp\xbf\x17F\x88m6\xc5\xaaB\x1c&h\xe57\ +\xae\xa2H\x9d\xd6\xd7\xabD+F\xaf\xf6\x22\xafi\x1a\ +q\x9a Gm\xb4\xc3-\xf6\xd5nf\xc5\xbe\x8c\xed\ +6P\xbc\x0c\x8d/\x0c\xf6\xec\x17Z\x1c\xc7J\x18\x86\ +X\x9a\x83\xb9c\x89\xfd;\x0f2Y\x9d\xe6\xe9s\xff\ +@%Wc\xfd\xab9\x82\x05\x13\xd7u\x15EQ\xb4\ +\xde\xed\x14\xeflR\xbc9\xc3t\xe9\x00\xe7WN\x92\ +\xa6\x92\xe8t\x15\xfbD\xbe\x97 P\xa3(\xd2}7\ +`!]\xe1\xe0M\x0e%1\x8c$\xc0\xf6V\x89,\ +\x81s\xacJ\xb0\xa0\xf7n\xd1\x9c\xaa\xa9\xc8PbO\ +\xad1p{\x99\xaa6\xc1\xba3\x8fe;\x18\xd6\x00\ +\x8d\x7f.\x03\xa2\x97.\xd3U)8\x1f.\xb2\xffh\ +\x19-\xc9\x923\xb2\xcco\xbcNE\x14\xe8<;@\ +\xb8d\xf4\xd2hu\x10\xb4\x02\x8f\x1d\xb7\xfaPls\ +\xd3\xf0=(o\xde\xf1\xb3\x8c\x0cN\x11\xa7a\xdf#\ +\x0dH\xdf\xf7\xf1=\x9f\x98\x80]\xc6\x03\xfc\xab\x1b>\ +\xc6\x8f]\xf7\x9b\x5c?\xf8(\xa3c\xa3}\xed6\xde\ +t\x9f\x06A@\x9cD\xac\xaf\x06\xfc\xe8\xc1\x9fC\xb6\ +\x07\xf9\xa9#\xbf\xce\x0f\x1dy\x1fA\xe2_\xe3P\xf5\ +<\xaf\xef\xfc|\xf3\xcc\x87\xd8\xa1?\xc8\xdd;\x7f\x90\ +7\xed\xfc \xa1f\xe3yW\xfb\xee\x89VQ\x1a1\ +\x9c\x9f\xe2\xa1\x89\x0f\xf1sw\xfd\x19\xf6\xd2 7\xee\ +\xb9\x95 \xb5\xaf\xd5\x85\xfd\x00\xd7u\xd1t\xc1\x8e\xdc\ +\xed|\xf8\xc8\x1fp\xa0\xfaF~\xe9\xbeO\x11g\xba\ +m\xb7x\xa4\xa5\xebz$\xa4x\x81\xcf\xfb\x0e\xfc\x01\ +\xf7\xed\xf8Q~\xe6\x96O26\xbe\x8d0\xbd\xd6#\ +\xed\xf9\x1e~\x10\x10\x0b\x97\xbbs\x1f\xe3\xc0\xf0\x9d(\ +5s\x9c\xa1\xfcX\x9fg{\xce\xa5\xfeI\xc6\x01\xd7\ +\x0d\x1f\xe1\x89K\x7f\xc1\x97_x\x8a\xbdC7\xf4l\ +\x1a\xfd7_\xdf#\x1d\xfa\xd4\x8cI\xe6\xdb\x17xu\ +\xe5\x05n\x99x\x00?\xb6\xfb\xfa\xebV\x8f\xb4\xe7y\ +d\xf5\x22\xe5L\x95g\x16>\xcd\x91\x91G)dJ\ +h\xa9\x89\xe7y\xb8\xae\xbb\xc5\xc7\xec\x11G\x11\xe5\xec\ +\x00J\xa1\xcd\x17_\xfc\x12;k\x07)h\x15\xfc \ +\xc0\xf3\xbd\xab\x16_\xdf\xbf\xea\x91n\xe8|\xe6\xe5?\ +$\x9f\x8e33>\x09\xa9\x8a\xe7_\xf5Hw\xe3\xea\ +z\xa4/\x9c\xb6\xa8\x0d+\xac;\x8b\xec\x9f8DN\ +-o\xb2\xb2w\xcd\x85\x8f\xc2\x90v\xdb\xe3\xa7\x1e\xfd\ +q\xbez\xe9\x93(a\x1ccy\x9dM\x16\xbe\xeav\ +\xefy\x89\x91\x02'\xb4\x19.lg\xa82D\xcbm\ +\xf5\xf5\xd5\xad\xbc\x1a\x86!q\x94\x12\xa4\x0e\xb5\xdc\x08\ +\x05}\x80\x8e\xdf$o\x94\xfb\x09\x87\x9e\x1a\xd7\x9b\xb1\ +\xa9L\x10(hi\x9eX\xb3\xf0\xbc\x08?\xf2\x09C\ +\xbf\xdfw\x92$\x04\xa1O\x12\xa7\xa4R\x22c\x9d\xb1\ +\xda\x04\xab\xad5\xc24\xd8\xe4\xd5-\x1e\xe9M\x83\x80\ +\xa2\xa8d\xb3\x1a\xe3\xe5\x19,\xbf\x89!\xf2H\xb9\xe9\ +\xcf\x0e\xbaI\x8d^\xa6GJ(WL\xe2@CW\ +\x0c\x04\x0aa\xe2\x13G\xc95\x1e\xe9\x1e\x17\x1b\xba\xc6\ +\xdc\xd2\x12E\xa3\x8ar\xac\xf9i|\xd1\xda\xf49{\ +\xdfW\x17\xfe\xc6\xca\xa7\xd9n\xdc\xce\xf8N\x85\x13\xcd\ +\x7f\xc2\x89\xdb\xb8n7c\xd2\xbb\x85]\xd7%\x08C\ +\x0a\xb5\x90\x97_\xff6\x8f?\xfcK|\xfc\xf9\xf7\xf1\ +\xed\xc5'I\x93\xf4\x9alL\xafo\xd5H\xf9\xfa\x85\ +\xcf\xf2\xf8\xbd\xbf\xc2\xe7N\xfd\x01g\xec\xaf\xa1\xa2\xe2\ +\xba\xd7\xcen\xd7\xf5\x88\xe2\x88%\xeb\x12\xed\x8eMm\ +\xd8@\xd6/\xb2a\xaf\x10'\xddLO?\x9d\xe5\xfb\ +\xb8\x8e\x8b\x94\xd0\xe0,{\x86n\xc0\xcb_\xe4w\x9e\ +\xf9\x18\xba\xa6_3\xbb\xbbq;$I\xca\xd4\xd4\x00\ +O\x9d\xfeg\xc6k\x93\xfc\xc6s\xef\x07\x91\xf4\xfb\xee\ +]x\xd7\xeb\xde\xc2\x95|\x99\xdfx\xe6\x83|\xf0\xa6\ +\xdfAk'\x8b\xb4\xa3\x15\x96\xce5\xf0;)q\x9a\ +G\x08A\xb3\xd9\xa4\xdd\xb1(\xb89\x84\xa9\xf2G/\ +?\xce\x1b\xf6\xfe\x10\xab\xf1y\xd6\xbf\xd3\xe5\xdf^2\ +\xc1\xb6mZ\xadV7\x87/*<\xbb\xf6g\xa8\xaf\ +%\xb4\xc3eZ\x97WY8\xd3\xc0o\xa7\xdf\xc3\xc2\ +\xf9(\xc7B\xf82\x9f?\xf3\x87XA\x93\x96\x7f\x9e\ +\xd5y\x9bV\xd3\x05!\xb7\xe8\xc21\x81\x96\x12\x93\xe7\ ++\xaf\xff\x0f\xee\xd1\xde\x02\x19\x87\xb3\xf3'X9\xdb\ +\xd5\x855C\x05\xa0\xddnc7m2Q\x81f\xf2\ +:_\xb8\xf4\xbb\xb8q\x93\x8b\xceKl,\xf8l,\ +71\xf2]\x0d\xc4\xb6m\xacF\x07\xbb\xd8\xd5\x85\x9f\ +_\xfbK.\xd9{X\x8b\xcf\x11X>\xe7\x9f^C\ +\xd1\xe9\xeb\xc2\xcdf\x93N\x9a\x10D\x06\xe6\xc0\x02\xbf\ +\xfc\xa5\x9f@\xec\xd8\xb9C\xc6\xb6\xc4,h$iB\ +.\x97c}}\xfd\xdc\xe0\xe0\xe0n]\xd3\xd1\xb6\x85\ +\xe4\xea\x82\x8d\xb3>v#@z:\xc8\xae\xde\xbb\x99\ +\x91^\xadT*E \x8b.\xc9_\x97\x12-\xa7\xb4\ +\x96\x1c\x12W#\xf1@\xcf\x0aR\x99\xf6=\xd2\xa6i\ +\x16r\xb9\x1c\xca\x8cO^UY9\xef\x10u \xf1\ +\xe8V\x11\xe9\xddu]>\x9f_l\xb5Z\xa5\x91\xe1\ +\x91\x82\x15Z\xcc<\x98c\xf9\x84Gk\xc9E\x09\x0c\ +\x02'\xc1\xc8w9\xfb\x1a\x16\x0e\x12\xf4\xbd1\x85\xac\ +\xca\xcai\x9b\xd0\x92\xa4\x9e\x82LA\xcb\x82\xd8L\xc7\ +U*\x15K\xa6\xb2\xd8\xc1g\xef\xbdyVN\xba\xd8\ +\xab!\xa9\xaf\x10:)fI%\x89\x93\x9e\xe9\xf4X\ +>\x9f?b\x98Y\xc6\xeeV\xb0\x97#\xdas!\xda\ +\xa1\x03\x87z\x86n\xe6\xe6\xe6H\xd3\x94\x85\x85\x05\x1e\ +~\xf8a\x0e\x1c8@k\xa3\xcds\xcf~\x83\xc9]\ +\x196\x1a\x1b\x14\x8b\x05666h4\x1aT\xabU\ +\xce\x9d;\x87\xa6i\xbc\xef}\xef\xa3\x90/\xf0\x99O\ +}\x96\xda\xb6*W\xd29\x86\x86\x87XZZ\xc24\ +\xbb\x0e\xfa\x8b\x17/\x12\x86!\x8f?\xfe8\xf5z\x9d\ +/~\xfe\x1f\xbb%WC\xcb\x8c\x1c\x1aauu\x95\ +l.\xdb\xd7\xa6=\xcf\xe3\xd6[o\xe5\x91G\x1e\xc1\ +\xd0\x0d\x9e}\xeay\x0a\x03\x0d\xe2RD\x14\xc7\x0c\x0e\ +\xd6\xb9p\xe1\x02\xaa\xaavMB\x8a\xc2\xbd\xf7\xde\xcb\ +\xfd\xf7\xdf\xcf\xd3_\x7f\x86\xd3\xa7\xceP\x9b\xd412\ +&\xcdF\x03\xdb\xb5\xc9f\xb2t:\x1dVVV\xa8\ +\xd5j\xbc\xef\xfd\xefc~n\x9e\xe7\x9ez\x9e\xebF\ +\xf3D\x83\x01\x8df\x93Z\xadJ\x14E,//\xf7\ +-)\x1f\xfa\xd0\x87\xa8\xd7k|\xeb\xf9\x97X\xd5W\ +\x88\xb6\x07h;v\xec\xe8\x83u\xa1P\xe0\xf4\xe9\xd3\ +$I\xc2\xde\xbd{\xb9\xfb\xee\xbb\x09\x82\x80\x95\xf5e\ +\x06\x07\x07\xd9\xd8\xd8\xe8\xdf\xba\x96e]\xe3\xa9~\xe0\ +\x81\x07PU\x95\xaf?\xf5un\xbb\xf56\xf4\xe3\x1a\ +\xa3\xa3\xa3\xfd[\xf6\xe6\x9bo\xe6\xd2\xa5K$I\xc2\ +\xad\xb7\xdeJ\xa1\xd0\xbd\x10\xcb\xcb\xcb\xf8\x91\xcb\xee=\ +\xbb13&\x8e\xe3p\xd3M7\xf1\xb9\xcf}\x0e\xdf\ +\xf7\xd9\xb1c\x07\x87\x0e\x1db\xdf\xbe}\xb4\xda-\xd6\ +\xd7\xd7)\x16\x8b<\xf7\xdcs\x8c\x8d\x8d\xd1\xe9t\xd0\ +u\x9d+W\xae\xa0(\x0a\xd3\xd3\xd3<\xfa\xe8\xa34\ +\x9bMl\xcf\xa2V\xab\x01\xb0R\xc8s\xee\xdc9f\ +ff\xb8p\xe1\x02\xab\xab\xab\x14\x0a\x05\xee\xb8\xfd\x0e\ +N\x16Nr\xf6\xfcY\x0e\x1d<\xc4\xfa\xfa:\x97.\ +]\xa2^\xafS\xadV\xb9x\xf1\x22'N\x9c\x00\xd8\ +R\xb7\xdcM\xae\xbe\xf4\xd2KW=\xd2=\x1d\xb4\xa7\ +\x0b\xcf\xcc\xcc\xec\xce\xe7\xf3}\xee\xdb\xaa\xdbn\xf5\x09\ +[\x96\xb5:88X\xccd2\xd9^\x8emkm\ +\xee\xd6\xbe\x93$\x89\xc20\x0c\xaa\xd5j\xa1R\xa9\xf4\ +\x8d\xe1[u\xe1\xad5\xbeB\x88\xc5N\xa7S\xda\xb5\ +kW\xa1\xd5j]\xc3\xcb[u\xe74M\x19\x18\x18\ +\xe0\xd4\xa9S\xcf\x1e8p\xe0\xa8\xa2(\xddg\xf2\x16\ +\x9f\xf3V\x8e\xd74\x8df\xb3\xc9\xd0\xd0\x90\x95\xc9d\ +\x8a\xbd\xaa\xa8\xad\xbc\xdf\xd3\xa7{\xe8\xb7\xb6\xb6vl\ +dd\xe4H\xb9\x5c\xee\xd6\xc4\xf4j\x9a\xd3Dn(\ +\xaa\x10B\x88\x1e#\xca4M\xd7=\xcf+\xb6\xdb\xed\ +T\x11\x8a\x90\xa9\xb8\xea\x1d\xde\xc2\x9fB\x08\x91$\xc9\ +|\xa7\xd3\xa9\xd8\xb6\x9d\xefZ\x8c\x95n\x9d\xadr\x0d\ +3\xf7N\xc4\x0f\xc3\xd0u]\xb7\xe68\x8eT\x85J\ +\x9a\xf2}\xfb\xde\xac\x17^T\x14E\xac\xac\xacD\x02\ +!\xb7\xb2\xad\x10\xb2?\xf8\xaa\xaab\xdb\xb6\x04V\x1a\ +\x8d\xc6F\x92$\xc1\xbf\xd4\xf7\xe6R\xcaq\x1c'\xef\ +\xfb~\xac d*\xaf\xd6\x0b\xf7\xda\xab\xaa\x0a \xa2\ +(\x0a\xe38v\xd34moll$H\x01\x12T\ +M\xd5\xb4\xf1\xbd\x83\xb5\xa4\xa9#\xd4nmlwm\ +\xe4\x8f\x0e\x0e\x0e\xc6I\x9c\x10\x16\x1dr\xdb\x03he\ +H\xd6M\x92\x8e\xd6}\xd9\x1a\x12@I\x92\xc4\xa9\xd5\ +jYM\xd321\x09\xd1x\x83\x81\x5c\x96h\xcd \ +\xd90\x91\x91\x82bv]\xe7A\x10\xb8\xc0\xda\xe0\xe0\ +\xe0\x80\xa2(\xe9\xba\xba\xce\xe4u*\xc9\x86I\xbcb\ +\x92::B\x93\x08\xad;cr\xb9\xdc6EQF\ ++\x95\x0a~\x1c\x92\xb9\xae\x83\xa1*\xc4-\x83\xb4\xd1\ +\xe5[\xa1KP$\xba\xd6\xbd\x8dGFF\x22\x99\xa4\ +\xc9\x9a\xb2\xc1\xf6\xeb\x15\xc2U\x83h\xd5D\xda:B\ +\x91\x08\xbd\xeb\xd2o4\x1a\xb9\xc9\xc9\xc9\x11$\xcab\ +\xd0`\xeaf \x12$M\x9d\xa4\x91!\xb14TS\ +\x22\x14A\xb3\xd9\x5c\x0f\xc3p\xdf\xb6m\xdb\xca\x8e\xef\ +c\xee\xb4\xc9U\x14\xc2\x0eh\xf5\xb7\xae\xa3\xa5\x19\xda\ +OU\x89\xd64\x0c\xc3@\xd7\xf5\xc1r\xb9\x5c\xb0=\ +\x0fe\x8f\xc5\xe8m\x11x\x0a\x9e\xdf\x22'\xca\xa4m\ +\x93\xd6S\x15\x14E\xa1\xd1h\xa4\x85B\xa1\xaa\xebz\ +\xbem\xb4\xd9v\x9fJ!\x17\x90\x84\x1ez\x9c'I\ +\x13\x9c\xa7F\x88;\x0a\xaa\xaaV-\xcb*\x17\x8b\xc5\ +1!\x04\xdeu\xab\x8c\xde.I]A\xea\xc7\xc8X\ +\x12\x9f\xaf\xe1\x9c\xc9\xf4<7Q\x18\x86dt\x93\x0d\ +\xddb\xc7\x83!9Y\xc5\xf7=H#\xbc\x86\xc4\x7f\ +\xa9\x8a\xbf\xa4S,\x16\x10B\x8cT\x06*#\xd2\x95\ +4\xf7.\xb2\xed\xee\x0c\x8d\x8d\x0d\x0aJ\x85\xc0\x0b\xd1\ +\xdbUZ\xdf(b\x9a&\x9a\xa6\x91\xcb\xe5\xc2\xc8\x8f\ +\x0c\xbbj3~o\x91\xd8W)h\x05\xe6\xd6.R\ +R\x86\xd8\xf8\xc722P1\x0cC\x13B\xa4\xa6a\ +\xd0L\x5c&\xef\x04O_\xe3\xd6\xd1{Q\xde\xb6\xeb\ +\xe7\x19\x1f\x9b!\xc6\xc7\xf7\xaf\xf51{\x81G\xa4x\ +\xec\xd2\xdf\xc4/<\xf0\xa7\xfc\xc2\x83\x9f`b\xf0 \ +\xe5\x09\xf3\xbb=\xd2\xa9\xef\xfb\x04I@\xa7\x19\xf1\xe1\ +[\x7f\x9f\x8f\xde\xf1\xa7L\x8c\xec\xe6\xae[\xee\xc1K\ +\xec\x1e\xb9\xa4I\x92\x5c\xf5H\x13q\xef\xc8{y\xd7\ +\xae_\xe5\xd6\xbd\xf7sd\xe6Q\ +wl\x7f\x94\xdf\x7f\xe1c\x84V\x86\x1f\xb9\xe1\x03d\ +\xd4\x5c\x9f\x95{2\xa5\xbfY\x0a:]\xb8\x99Sk\ +\xcf\xf3\xe5\x93\x7f\xc3;\xf7\xfe{&*{\x88\xa3\xb8\ +\xcf\xc2=]\xd8\xf3w\xfe\ +\xb7\xb9\xa1\xf8\x83<\xb0\xf7\xad\x0cf'q\xbd\xab\x9a\ +sO\x17\x8e\xa3\x84rv\x00\x91\xed\xf0\xc4KO\xb0\ +\xb3v=\xa3\x85\x1dx\x81\xb7\xd5\x1cO\xe0\xfb8\xae\ +\x87\xae)\x04\xad<\x9f<\xf6\x1bL\x9aGx\xf0\xba\ +\xb7`\xaay\x5c\xdf\xc5s\xb7\xb2\xb0\x07H\xf2\xe1\x14\ +\xeb\xe9\x19*\xf9\x12\xdbJ;\xa8g\xc7\xf1}\xaf\x8f\ +o[=\xd2D\x1a7\xee>\xc4\xf3\xeb\x9fBs|\ +\x97\xb9\xe6%\xa2(&\xf0#$z_z\x0c\xc3\x80\ +,\x0aq\x12R\xd0+\xe8\x8a\xc9\x8b\x17\xbfB\x9cv\ +\x1d\xfd[eM\x80$\x9f\x10$\x1e\x05\xa3\x8c*:\ +8,\xd3p\x97\xf1}\x97\xc0\xd7\xae\xa9\x17\x060\x00\ +U\xa8\x04^BuP\xe5\xc5\xb3\xc7\x98k\x9c%\x08\ +\xba\xd6\x0eM\xd3z\xcfd\x12#F\x002Q\xa8\x97\ +\x07y\xe9\xf2K\xc4%\x1f\x91v\x8b\xbf3\x81\xb9\xe9\ +L\x08\x08\xbc\x00Ch\x98\x19\x9dJf\x88\xe5\xf6<\ +1\x1eN`\x11\xf8\x062\x95W\xb5o\xdfG \xf0\ +\xd2\x0e%}\x90\x86\xf3<\x0a\x0a\xeb\xce\x12Q\x18\x11\ +\xf9\xd15rl\xac\xc5\xa4\xa4\x90\x82c\xa5(\xc7[\ +\x9f\xc5\xc8H\x82\xc0\xc3q\x9d\xfe\xf4\xee\x95\xfck\x22\ +\xcbW_\xff3\xdes\xf0?s\xca\xfd\x12\x1b\xf1\xe5\ +\x9eQ\xa8\xcf\xab\xbd\x92\xff$J\xe9h\x17\xc8\xc8A\ +\xee;x/\x9f?\xfbG\xf8\xa9M\x12_Mam\ +-\xb8\x16Z\xc2\x8bsO\xf03\xf7\xfe\x06\x7f\x7f\xfa\ +\xf7\xb1\xb8B5;\x8a\xe7]u\xc7\xf7\x060\x8ab\ +\x96\xad9\x9cN\xc2\xe8\xb6\x02qa\x96\x91\xe2v\xbc\ +\xa0;\xa3\xae&\x13||\xcfE\x22\xb0\xb5\xcb\x1c\x1e\ +?JG?\xc3\x17O\xfe\x15\x05\xb3\xd8\xcd\xc6\xb8^\ +\x7f@\xba>\xef\x94\xfad\xc4K\xe7^e\xa2>\xce\ +\x9f\xbc\xfc\x0bT\x8bu\xdc\xc0\xc1\xb6\x9d\xbe\xee\xed8\ +\x0e\x81\xefS*d\xf9\xbf\xff\xf1#\xfc\xe6\xa3_D\ +k\xf9\x8b,.\xcd\xb2|\xb1\x8d\xdf\x8e\x89\x93\xf7o\xf9\ +\xa3\x1f\xfd'\xce6\xbe\xc9\x95\xd5\xf3\xac\xce7\xf0[\ +W=\xd2=\xa7A.\xc9s\xb2\xf5U\x0ex\xb7\xe1\ +&\x1d\xce.}\x89\xb9K\x0e\x8du\x17\xa1B\xa5R\ +\xe9\x9e`\x10\x13i\xe0\xc9\x0cO\xcc}\x92\xf7\x8c|\ +\x0cQj\xf0\xf5W\xbeHc\xde\xa1\xd5\x0cQ\xf5n\ +\x92\xb6\xd9hb\xaf\xdb\xe8Q\x91\xa5\xe0\x14\xc7\xd6\xfe\ +\x81b1\xcb\x17\xce\xfc1\x8d\xc5\x90\x8d\x95&z\xa6\ ++\xe1Z\x96E\xb3\xd9\xea\x96\xe5\xaay\x9e\x5c\xfec\ +&\x9dC\x9cY\xf9\x06~'a\xe1\xd5&z\x01L\ +\xb3\xab\x0b7\x9bM\xfc\xbc$NM\x16\xd2\x17\xf8\xcd\ +\xaf\xfd\x1cb\xfb\xd8\x0e)\x10\xa8\x99\xae?\xaeW/\ +\x1cEQ1\x9b\xcd\x91\xbf!flo\x8e\xd5\x93\x1e\ +W^\xea\x80e\xa2\xe8\xa0\x9a\xe2\x1a]X\xd7\xf5b\ +\x92\x8f\xd8\xfd\xf6\x02\xe1|\xca\xe5\xe3\x1b\xf8\xb3]\x9d\ +C\xcb\xf4\xcb\xc8,EQ\x9aR\xca\xc9|>O\xfe\ +h\xca\xd8h\x86\xd9\xe3m\xd6\xbf\x93\x90\x86\x02\xd5\x00\ +E\xeb.\xc2+\x95J\xd8n\xb7\x8d\x5c6\x87\xad\xb8\ +\xdc\xf5\xc1\x1a+'|f\x8f\xb5\x09\xe6u\x10)Z\ +FErU\x17\x1e\x1d\x1d=\xea[\x01\x957*L\ +N\xe5\x98}\xb1\xcd\xda\x89\x08\xe9u\x7fzE5\xe9\ +\xeb\xc2\xb5Z-\x94\x894\xa2\x91\x88\xe9\x1b3,\x1e\ +wh^\x0c V\x91H\xb4\xac MRt]o\ +z\x9e'3\x99L5W.\xb0\xed^\x89u%f\ +\xe3\x9c\x8fv\xe4\xf6\xc3XV\x17yfgg\x09\xc3\ +n\xd9\xc0[\xde\xf2\x16v\xed\xda\xc5\xc2\xdc\x22\xa7\xbf\ +y\x96\xba\x22)\xed\xf4QT\xa5_/\x5c(\x14\xb8\ +r\xe5\x0a\xd5j\x95w\xbc\xe3\x1dh\xaa\xc6\xe7\xff\xf6\ +\x8bTk\x03L\xe4\x1bT\x8f\x0e\xd0n\xb7\x09\xc3\x10\ +\xd34\xb9p\xe1\x02q\x1c\xf3\xde\xf7\xbe\x97\x1d;v\ +\xf0\x0f\x7f\xf7\x05\x94\x15\x8d\xaa\xbd\xce\xce\xdb\x06h\xb5\ +[\x18\x86A\x92$,..\x22\xa5d\xdf\xbe}<\ +\xf2\xe8#\xf8\xae\xcfw\x9ez\x95\x9c\xd5f\xa6\xea\xa3\ +\x8fjd\xb3Y\x16\x16\x16\xfa\xd4 \x84\xe0\x8e;\xee\ +\xe0\xce\xbb\xee\xe4\xb9\xa7\xbe\xc1\xe5\xaf\xceR\xd7\x87\x99\ +\xbc!K\xb3\xd5\xec\xfe\xd0\x85ibY\x16+++\ +\x8c\x8d\x8d\xf1\xe1\x0f\x7f\x98\xe7\x9e~\x8eWO\x9e\xe2\ +\xfa\xf12\xd6@\x870\x0aI\xe2\x84b\xb1\xc8\xfc\xfc\ +<\xcdf\x13\x80\xff\xf8\x1f\xff#\x00/>\xceC\x0f=\xc4\xd0\ +\xd0\x10\x17/]\xec\x0e\xfcf2`ll\x8c\xa5\xa5\ +%FFF\xb8|\xf92\x00\x0f?\xfc0{\xf6\xec\ +\xa1\xd3\xe9\xb0\xb6\xb6\xc6\xb9s\xb0o\xdf>._\xbe\ +\x8c\xef\xfb\x8c\x8f\x8f\xb3\xb2\xb2B\x1c\xc7\xdc|\xf3\xcd\ +\xdcy\xc7\x9d\xec\xdc\xb9\x93\xbf\xfc\xcb\xbfd~a\x9e\ +\xd1\x91Q\x9ex\xe2\x09\xea\xf5:\x00kkkDQ\ +\x84\xa6i\x1c?P\xadV\x8b[\xcd\xde[\xf9\xb9\xf7\ +=\x8ec+\x0c\xc3f\xb1X\x9c\x1c\x18\x18\xa0\xd3\xe9\ +\x5c\xc3\xab=\x1d\xb9\xf7\xb7a\x18\xa1\xe38\xc6\xf0\xf0\ +0\xb6m\x7f\x8fwy\xeb\xefcU*\x15N\x9f>\ +\xfd\xec\xee\xdd\xbb\x8fn\xb1\xfc^\xb3O\xef\x7fM\xd3\ +X[[c||<\xb4m\xdb\xf8\x97j\xa27\xcf\ +\xb7iY\x96,\x97\xcb\xd5\xef\xde\xae\xa5I\x1am\xf5\ +1;\x8e\x83eY^\xb5Z\xcd\xb4Z\xdd\xf4\xbdL\ +\x05\x8a\x10\x08\xe5{xUX\x96\x95h\x9a\xd6\xcd^\ +#\xd0\x84\xde\xd5\x85\x95\xab5\x19[\xfc\xd7\xd2u\xdd\ +P\xd7u\x1c\xc7AW\xf5k\xea\x85\x15]\x5c\xd3\x7f\ +\xa7\xd3\x91\x8a\xa2D\xbe\xefk\x9a\xa6\x09\x12\x81\x14\xa0\ +j\x12E\xb9\xb6\xed&\xf8\xcb$Id\x9a\xa6\xb1\x82\ +\xd25^#Q\x94>\xd7\xf6\xab\x0a\xe28N,\xcb\ +JUU\x15\x02\xf8\x17\xea\x85\xc5\xe6z7\xcaf\xb3\ +q\x9a\xa6R\xc8\xcd\xbae@\xdb69\x12\xc8H\xd9\ +,\x90\xee\x16/\xaf\xae\xae^\xaa\xd7\xeb\x07}\xcf\x97\ +\xa1\xd1\xd5\x85qM\xd2N\xb7FWF\x0aB\x93\xbd\ +<\x9cQ*\x95\xf4L&CDD:\xde\xa6\x985\ +HZ\xbd\xba\xdb\xab\x81\x87a\x18\xb8\xae\xbbZ,\x16\ +gt]\x17-\xb5\xc5\xf0\x1eHm\x8d\xb4e\x22\x1d\ +m\xd3H\xde\xbf\xfa\x9e\xeb\xb9\xb2Z\xad\x0e\x04I\x88\ +\xb2\xa3MN3\x88[:i[GFj\xf7\xc7\xc5\ +\x90d2\x19.^\xbcX\x19\x1e\x1e\x0e|\xd7\x8f\xdb\ +\x99\x16#\x13*\xe1\x86Ajk\xdd\x1a\xe7D T\ +\xd0u]\x18\x86\xe1\x8f\x8c\x8c\x04\x193S\xfe?\xd4\ +\x0bc\xdb\xb6~\xe5\xca\x95\xb5r\xb9\x5c\x0c\xe38\x0d\ +\xca\x16\x95\xbaJ\xda\xd1\xd1F~\xa4U\xd05\x9d\xe6\ +S\x15\xa2U\x1dE\x15\x08!j\xa5R)\x9fJP\ +v9\x8c\xde\x11\x11\x05.\x22\xd2\xd0E\x864Ph\ +\xfec\x1dUU\xd1u]\x98\xa6\xa9\xea\xba\x8ec\xb8\ +\x0c\xde\xe5S/j\x10\x87\x84\x9e\x0b\xba\xa4\xfd\xe5!\ +\xe2\x96\x8a\x94Rh\x9a\xa6\x1b\x86!4M\xc3\x1d\xeb\ +0|\xbfFQ\x8e\xb2\xdaXA\x93\x1a\xf1B\x91\xce\ +\xf1\x022\x06\xd34\xd5>\x0b\xab\x1d\xf6\xbf)BK\ +T|\xc7\xc1$G\xe4\x82u\xacD\xb0h\xf4~\x03\ +\xb1R.\x973A\x94\x90\xb9\xc5e\xdb!\x13\xabm\ +\x91\xa1@\x10\x06\xe8N\x99\xc6\xd7\xcb\x98\x86\x81\xa6i\ +y\xd34\xed\xff/\xf5\xc2\xaa\xaa\xa2\xaaj\xb5\x90\xcf\ +\xe7\x96\xfd\x16\x13o\x94\x14\x06}\x22\xcfG\xb9c\xea\ +\x1d\x88<\xc4\xd2\xff.\xa6\xec\xfe\x9d\xaa\x015y\x80\ +\xff\xf0\xe0\xa7x\xef\x91_\xa5V\xdcA}\xdb\xc05\ +5\xbd}\x94K\x03\xec5\x9dw\x1f\xfae\xde\xbc\xe3\ +c\x1c\x9c\xb8\x87{nx#^\xe4\x5c\xf3\xdbY\xbd\ +\xe3\xf8I\xc0}#?\xc1\xb0r#\x8f\xdd\xf1\x1f\xb8\ +e\xf2\xedxz\xa3\xef\x22M\x92DvQ1$L\ +#j\xe66\x1e\x19\xfb\xb7\xfc\xa7\x87?\xcd\xeb\xf3\x1e\ +\xa3\xe3\xc3\xc4\xe2\xaa\x8fYv\xa7,\x9e\xe7c\xe4\x04\ +\xdb\x94\xdb\xf9\xbd\x1f|\x9aJf\x86_~\xdb\x1f\xe3\ +e\x1a\x04\x9bu\xd0\xff\x7f\xea\x85=\xcf'\x88\x02\x94\ +L\xc0\xee\xf4\x9d\xfc\xe8M?\x87rx\xf8A\xee\x99\ +\xf9\x81M\x16\xbeV\x17\xf6<\x9f(\x0a8\x05/\x9c\x07\x1f\ +\xaf='&\x8e\xec\xa0\x08\xc1R\xbd\x81*b\xc8\xa7\ +\xea/\x93\xeeNa\xbbvD\xda\xaf4\xa8E\xa0r\ +r\xfe\xcflI\x1d\xa0o\x83\xcbD\xebT8\x98\xff\ +\x93Xw,\x17#>\xc1\xd2\x92\xc9\xce\xa1a^9\ +\xff+&\x97\xcf\xe2\xd8N\x94\xe9]I\xe9\xab\x9a\xe0\ +\xed\xcb/r\xf8K\x8f\xf1\xfb\xd1\xc7\xb8l\x1e'\x9d\ +\xc8\xa3_\x97\x176\x8dp\xd7gn\xf9\x0a\xf5\x86E\ +\xae(\x90\xf23\xa8R\x02\xdb\xb5>3n\xd340\ +m\x0b\x09A]\xb9\xc8p\xff\x97\x99\xf2N\xf0\xd73\ +\xcf\xd1\xa5u\x87\xe3\xd6\x8d\x08\xb93L\x13\xcf\x87\x8d\ +\x1b\xf3\xbc\x7f\xee}\xfa\xb2\xfd<\xfd\xe1#d\xe2\x85\ +hN\xae\x91\x09a\x8b\x5c!\x93\xe1\x89\xa3?\xe5\x81\ +\x9d\xbfDi*\xd3\xcc.M3[\xaa\xa0\xd7<\xba\ +\xdd\xd0\x17.\x97\xcb\xd4\x1b\xcb\xc4\x9bIl\x15\x9e:\ +\xf10\xf7\xec\xb9\x8f\xe9\xb9\xd3,\x9d\x81j\xb5\x1ei\ +\xe1\xce\x15HRB\xa8\x05\xfex\xe6\x09~\xb1\xfe\x19\ +f\xec\xb3\xcc\x8df)_\xada\xd5\xfd\xce\xbb]\x84\ +Vt\xdb1\xaa\xfe%^=\xfb\x0cn\xa2\xce\xe5\x85\ +\xb3\x94>0\xa8\xce\x1b\x91/l\x18\x06\x8e\xe9`\xc9\ +>\x86\x1f\xe3\xd8\xe4\x1f\xd8\xbf\xf9n\xc8T879\ +\xcf\xfc\xe5:\x8d%\x07I\x84\xefl\xe5r\x99J\xbd\ +A\xbf\x9dc\xd2\xf8\x98w'\xffD\x90h\xf2\xaf\x99\ +\x97Y\x982)\xcf\xd7P\xe3J\xa4\x85\x97\xab\x0d\x1a\ +\x09\x1f/H\xf1\xce\xdcsl\xf5\xf70\xee|@c\ +\xd1\xe0\xca\xa92\x8e\xee\x13O\x84Z\xb8\x5c.c$\ +|L[P\xe9\x1e\xe5\xb9\xe3O\xa2<\xff\xc3\xd3\x98\ +\x8b\x10\xcbH\xa8\xaa\x125\xd6\xca\xb2LL\xd3p\x17\ +\x02\xe6\xff\xe3\xd1\x98\x9a\xe3\xc7O=\x8a>\xaeA\x10\ +\x10K+\x91\xb1\xd3n\xc0\xc0\xb7|\x96\xce\xb9\xc8\xad\ +n\xee{\xe9\xfb\xe8%\x0d\xb3^&\x91\x15\x88pu\ +\x8f\x8e\x9d\xcf\xe7\xb1g[L\xbd\x1d\xf0\xe1\xe8\x9b,\ +\x8e\xda\xf8\x96\x84\x92\x04-\xa6FPd\x10\x04h\x09\ +\x0d\xcf\xb0\x99?\xed\xb2<;\xc3\xb1_?\x8e~Y\ +\xc5\x5cr\x89g\x15\x14ED\x81H\xa1(\xc4d\x15\ +}\xdc\xa7Z\x87\x17/\xbe\xc4\xd2y\x9f\xc6\x15\x1f-\ +)\xa3%\xd5\xa8\xd2Y\x08\x81\x1aS\xe9\xd6}\x16G\ +\x1d\x96\xe7\x179~\xee\x05\x96\xce\x05\xb8z@<+\ +PT9\x823%I\x22!i\xd4.\xb84\x15\x9f\ +\xb3\x93\xef\xa0l\xda\xb0\x05\xe9&\xd0\xd40\xc1\xe8\xfb\ +>333\xec\xd9\xb3\x87\x81\x81\x01,\xdd\xe6\xf4\x07\ +\x9f\xb0*\x19CJ,R\xdc\xd7\xc3\xfc\xc2<\x8dz\ +\x83B\xa1\xc0\xd8\xd8\x18\xbd\xbd\xbd\xec\xdb\xb7\x8fTw\ +\x8a\xbf\xff\xed\x0dz\xfbzY\xe5\xcc\xd3\xbb{\x15\xf5\ +F\x8dVK'\x9dNs\xe1\xc2\x05\x0c\xc3\xe0\xfe\xfb\ +\xefg\xe7\xce\x9d\xbc\xf5\xfa?\xb0\xaa6\x922\xc3\xb6\ +\x039\x9a\xcd&\xb9\x5c\x8eZ\xad\xc6\xf4\xf44\xadV\ +\x8b\xe1\xe1aFFF\x88i1>9\xf5)\x9e\xd1\ +\xe2\x06\xa9El\xabF&\x97\xe1R\xe9\x12\xf1x<\ +L'\xa9*###\xdc|\xf3\xcd\x9c\xf8\xe7I\x16\ +/V(j\x82\xbeA\x19w\xadC\xb5R\xed\x10\xb8\ +Ql\xf6\xd0\xa1C,U\xaa||\xec4\x99T\x8a\ +x\xcc$\x7f\xd32\xb9|\x0e\xcb\xb2\xa8T*\xb4Z\ +-t]\xe7\xc8CGh5\x9b\x8c\x97&Y\xaa\xd5\ +\xc8:\x16\xca\xf0\xf06\xce\x9f?\xcf\xe0\xe0 \xa9T\ +*\x12\xfc{\xf7\xee\xe5\xf6\xdbo\x0f!\x1f~G.\ +\x97\xc3\xb6\xed\x08\xcb\xb5L\x8bb\xb1\xc8\xd8\xd8\x18\xf9\ +|\x9eC\x87\x0e\x91\xcf\xe7\xb9:s\x95\xa1\xa1!&\ +&&\xe8\xd4(_\xb9r\x85\xad[\xb7R*\x950\ +M\x93;\xee\xb8\x83M\x9b6111\x11.\x00\x9e\ +\xc1\xf6\xed\xdb9}\xfa4\xe9t\x9a\xfe\xfe~\xe6\xe6\ +\xe6\x00\xd8\xb1c\x07\x07\x0f\x1ed\xfd\xfa\xf5<\xfb\xec\ +\xb3,,,P(\x148y\xf2$}\xbd}\xed\xc6\ +\xca\x90\xd1Q\x14\x85\x91\x91\x11\xee\xbd\xf7^\x1c\xc7\xa1\ +T*144\xc4\xa5K\x97\xc8f\xb3\x1c=z\x94\ +\xb5k\xd7255E\xb9\x5c&\x97\xcbq\xf8\xf0a\ +FGG)W+l\xde\xbc\x19]\xd7\xb9p\xe1\x02\ +\x99L\x86b\xb1H\xa9T\x8a|\xe1#G\x8ep\xee\ +\xdc9\xc6\xc7\xc7\x99\x9d\x9d\x0d\x19\xe9]\xbbv\x05\x1d\ +\x9d\xe88\x0e\xc9d\x92\xc9\xc9\xc9\x8bk\xd6\xac\x19\xda\ +\xbcy3ccc\xd1\xce\xf3\xf5\xdd\xcc\xed\xf8SS\ +\xd3\xb4\xd8\xd6\xad[\xd5j\xb5\xca\xf2\xf2r\xa4U;\ +^k'b/IR\xd9u\xddq`W6\x9b\x8d\ +h\x82\x95\xbb)+\xfdgUU\x1b\xb3\xb3\xb3\xd2\xfe\ +\xfd\xfbSccc\x916\xed<6:\x15-\xae\xeb\ +v\x18\xe9\x89\x91\x91\x91\x1bm\xdb\x8e\xbc\xdb\xcen\xf2\ +\xca\xa6\x8e\x95\xbep\x87\xed^\xb9X\xac\x1c\xbb\xef\xfb\ +\x08!\xa8\xd7\xeb\xe5b\xb1\xd8388\xc8\xe4\xe4d\ +tK+\xa9\xeet\xa4)\xa5v\x96\xd6u]\xaf\xbd\ +\xbfF2\xd1\x15b\xb4\xda\xf5\x5cr\x88\xf8Z\x96\xe5\ +\xa6R)uvv\x16Y\x96\xdb\x8c\xf4\xf5\x1cs\xd0\ +\x99DyffFZ\xbdz\xb5'\x84\x90bZ\xec\ +\xb3Yd\xaey\xbd\xed\x1a\xe4\xa0X,*SSS\ +$\x12\x09:ZXj\x7f\xb7\xab\xab;\xfaM\xfb\x8f\ +\x9a\xba\xaec;6q-\x8e\xefC\x5c\xfb\xfc\xf1\x85\ +\x10\x94\xcbe\x84\x10R\xbd^GBB\x1514%\ +\xb6\x82\x91\x96\x22M\xdch4\xf0}\xbf\x99N\xa7{\ +\x16\x16\x16\xe8Jt\x11\xf8a}\x96\x92\x1b\x8cGZ\ +\xb1s6eYv\xf3\xf9<\x86n\xe0t\x99$\xfb\ +\xed\xb0\x94\xd0\x10\xf8\xba\x1a\xe6\x85\xdb\x98l\xa5Ri\ +\x15\x0a\x05U\x08\x11\xf3\xf0\xf0V-\xd3\x9dRB\xd6\ +\xb8\x93\xe9u\xe5N\x0d|\x22\x16\x8b\xe5\x93\xc9\xa4\xa3\ +(\x8ah\xcaMr\x03\x12\xbe)\x11\xb4T|]!\ +\xb0\xe4\xd0\xeb\x0d\xaf\x02!\x84H\xe6r9Z\xbeA\ +z\xa3\x05\xaeL\xa0+\x04\xa6\xd2\xee\xda\x92\x91\xa4\x10\ +kS\x14e\xb2\xa7\xa7g\x93\xa9\x9b\xd4\xe2U\xfa\x06\ +\x05N\xb3\x9ds\xd6\xc3\x9cs'\xb1.\xcb2}}\ +}j\xe0\x07\x94\x9d:}[ \xb0$|C!0\ +\x04~3\xe4\xafe!wV\xf7K\x99Lf\xd0\xb2\ +\x1d\xfcUMR\x05\x19W\x07%{\xa0\x8c,\x04K\ +oeq\xe6\xb5N\x0b[\x5c\x08\x81\xe3{\xf8\xfd\xcb\ +$w\xb7\xe8M\x0c\xd04\xeb!ti+T^)\ +Fw\x9a\xa2(\xb2\xe7y\xe8\xaaAl{\x95\xe2\x9a\ +\x1c)5\xcbLu\x8aX\x5c\xa5~,\x8f=\x13\xc3\ +\xf7}YQ\x94d,\x16\xd3\x14E\x91\xe7VO\xb3\ +\xe5N\x8dDP`\xa9YA\xc8\x02w\xaa\x9b\xe5\x8f\ +R\xf8n\xd8 bY\x16\xb2/\x05sJE\x1a\xdc\ +\x1b\x10\x0f\xb2Xv\x0b\xd7\xb1\x09\x0c\x95\xfa\xf1\x0c\xce\ +\xa2\x8a\xa6i\x04A\x10\x97e\x19\xd9\x95Y^\xb7\xc0\ +\xe6=i\x12A\x9e\xa6^\xc3\xb6\x1dh$\xa9\xbe\x99\ +]Y\xaf'9\xb6\xc3|r\x91\xe1\xbdI\x02+\x8e\ +*K4Z\x15TEc\xf1\x95<\xbe\x11\xed\xe4\xa4\ +\x09\xa0j\xe8\xac\xbbMG\xc9\x18\x0c\xa4\x86\x90\x0f\xac\ +{\x80dW\xbb;\xcb\xba\x96\x17\x0e+\x92,<\xd9\ +f}\xec\xab|o\xc7\xa3|\xe7\x0b\x8f\xb3.\xb3;\ +*1\xec\xd8\x9aQ\xfe\xd7sX\xa84\xf8\xd1\xee'\ +\x19\xce\xde\xc57\xb7?\xc0\xb7n\xfd\x01\xa6\xdbZI\ +\xa8\x06\x1dYg\x05\x06\xbbz\xeffw\xf1\xbb\xdc\xb3\ +\xfbA\xbe\xb8\xea\x1b\xe8\xa2\x82q\xadG\xba\x93\x17\x96\ +\xbc\xc0amn\x13_\x1f|\x88\x9f\xdf\xf9[2\xe6\ +m\xac\xea\xed\xc1\xf6\xcc(E\x19\xf5_\x1b&\x8a&\ +\xb11\xb9\x87\x07oy\x9a\xa1\xfc^~\xb2\xf7\x19l\ +m\xf934k\xc7s\x96U\xb82Q\xe3\xd1}\xcf\ +\xb3!\xbb\x9b\x9f\xed\x7f\x01'\xd9\x88>\xbf\x96\xd6l\ +\xe7\x85e\x83}\xa9v^xMj\x13\xeb\x0b\xdb\xb0\ +\xedPyt\xb4p(\xf8M\x5c\xd7dS\xe1\x16\x8e\ +\xcf\xfc\x85\xf7N}\xc4\xce5\xfb\xc2d\xf9\x0am\x1b\ +ia\xdb\x22+\x06\x98\xaa\x958q\xf9u\xbe6t\ +\x08\x81\xc0u\xbdHgw\x1a\x83\x0c\xc3 p\x15\x06\ +s7q\xd6|\x95\x1d\xf9\xbb\xd8X\xdcF_\xd7z\ +\xcc\xeb|a\xd34\xc2\xbc\xb0\x92\xa4\xeaL\xf3\xdf\xd2\ +(\xb7\xae\xdbK>\xbe\x1a\xd32\xaeS\x22\xa1\xe7\xac\ +\x08AsI\xf0\xda\xd9\xe7Y\xadmc\xfb\xda\xedh\ +R\x22\xd4\xca\xc6\x0aMn\x1a\x04\x81G\xd6\xdb@\xd5\ ++\xd1\x97\xed\xa7\xb7{\x80\xde\xe4@\x14\xde\xeeHP\ +\xbd\xcdH7\xday\xe13\x95\xf7\xf8\x1f\xcb\xb6\x8e\xf6\ +\x8f\xf1\xef\x16\x00\x00\x00\x00IEND\xaeB`\x82\ +\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x0b\ +\x08R\xaa\xc7\ +\x00f\ +\x00i\x00g\x00u\x00r\x00e\x008\x00.\x00p\x00n\x00g\ +\x00\x0a\ +\x0bSG\xc7\ +\x00r\ +\x00a\x00n\x00d\x00o\x00m\x00.\x00p\x00n\x00g\ +\x00\x0b\ +\x0a\x12^\xc7\ +\x00k\ +\x00i\x00n\x00e\x00t\x00i\x00c\x00.\x00p\x00n\x00g\ +\x00\x0c\ +\x05\x8f\xe2\xc7\ +\x00c\ +\x00e\x00n\x00t\x00e\x00r\x00e\x00d\x00.\x00p\x00n\x00g\ +\x00\x14\ +\x00\x22\x00G\ +\x00T\ +\x00i\x00m\x00e\x00-\x00F\x00o\x00r\x00-\x00L\x00u\x00n\x00c\x00h\x00-\x002\x00.\ +\x00j\x00p\x00g\ +\x00\x0b\ +\x07P1G\ +\x00e\ +\x00l\x00l\x00i\x00p\x00s\x00e\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x00(X'\ +\x00t\ +\x00i\x00l\x00e\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x82\x00\x00\x00\x00\x00\x01\x00\x00\x8f_\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00\xcc\x00\x00\x00\x00\x00\x01\x00\x018M\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00d\x00\x00\x00\x00\x00\x01\x00\x00\x8b\xdf\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00\xb0\x00\x00\x00\x00\x00\x01\x00\x01\x0e:\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00H\x00\x00\x00\x00\x00\x01\x00\x00qc\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00.\x00\x00\x00\x00\x00\x01\x00\x006\xe6\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg b/examples/widgets/animation/animatedtiles/images/Time-For-Lunch-2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c57a555490fc98478ffabac51a9a5d9df7635829 GIT binary patch literal 32471 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/animation/animatedtiles/images/centered.png b/examples/widgets/animation/animatedtiles/images/centered.png new file mode 100644 index 0000000000000000000000000000000000000000..e416156a0ed1e6931f2b1f1a55cca015def7057f GIT binary patch literal 892 zcmeAS@N?(olHy`uVBq!ia0vp^DIm1LhE&{o zdu@NdjH|@4kMGaCy|s~l_T<(Hx*IHnILq_ah~x=8=$_zhE^?xt`43}=dZ1II#@!1O z%yJF-3bb5YrYMM?;A2af@a75Az0ddNeZT%DK*qAuC}>^8$C@Q?%a+WoeO`H=QIG(r zH1wHkS5{c~Q8?M>$DGs48qWLq`~MGfjN9<_Yw7*G?H}(22L|r@Ic54fpJ2P0$L5~x ziQAO0M*h7{U-Gwa-@-QOSg$%P*SyQs$~Ty&!2W;hxv!E^4_RmKULqOSsItIjzS8f~ zwucXO7*ZpXdOnukoWC~MaMdcM^TnU`90*SAeYmP}{(0;2isxVXXFQkc4v)SOZq&7C zfd{mOSFyYg~YWdF>*Gkvy{X3yN-ukgh?E&%c_NwQL_k2Gu zw5Z9a>H9pL(*_bVnjRi7yq+^DT$7=_UhY$J5%*)=$Z5U7OPhRlq)IaI7k>`sX>(pC zy|^;)p=NC3_nt{#-aHFh+;qcAP33fvmW}>-^PPV``|dK&`}E+8-uHh$rft7}W0A(^ z`unG^Y*JgP!S%@En3T6sc;QUbp9gDQOY{4}*Qd%%zyIO4f3-`$@VWECd%mAJcP?pd zsH2)#X11Y(4{L9x^WnCd@3*JN+%dGNoHF6xQx7@o9>c9(Zn@l#<|HR3Hh#!C@%=8h z-uy5L=3{+w`8b^H95KY@84QJKE4-UtEQxShK9NXx~#scab1}Geu<2{ygkdQ=aIr~4}CV@^m%OI g=0X7c^Z&pVAf#pboFyt=akR{0Lqn(^8f$< literal 0 HcmV?d00001 diff --git a/examples/widgets/animation/animatedtiles/images/ellipse.png b/examples/widgets/animation/animatedtiles/images/ellipse.png new file mode 100644 index 0000000000000000000000000000000000000000..2c3ba881c5bed13a1f509518f2a6759a7fad6951 GIT binary patch literal 10767 zcmYkCWmHt(-^D5EE>RjmsUO`fAsy04Dx%b?2_Wtbsy|H>asw9LD2{AA*NYvGo^}(mz-48x4_}l$Ynj!eW z^wL*V#DI)4Y=M8^zSLAz#<;!v^R=xs1$;x`u4d+ifkE1H_k)?nLrM?6#Pe3yR>7Oa z#wKOp*(q*$i-Ey{p|1SY&~I)x*FV+LD0ff(lGqm_DO!xn&B{tZO%wTH9D@MA3ZKz@ zN6dyu4ZhFty61RqO4m;%~*u+$&dP*?X~ZgzHHY3c;FX?xIl z!~Fbwx4uU72?+%;ZgGjzuQa}B+Z72?wE<JTe-B z!q{wP`b?>Oz8MuRJatS@Pwxw{Xquo<{NV^=ijIk)U*1$YZ^qU)GO~9NdcbJ&?%hdq zV#rY;q5^qwc{%jN0{<}ehekSi77LPkUxsX`rZXbPyr+hjcj(u&B?IDdt`4@lO+XG@ zXS>9dy8tC6{Z3xjD5W!-h&2*J{X8E7r*3<0{B`QTfB)nZ8X?aAW@{bCZ|{fwtgDl4 z^gH+ySCo2mdMYd|Y#?{8Fu>o)tv#4izD5hRW>%2sowRK8Epb<(n@Ib zk&MfHSG{WylA`QmO{1;g%W#&Y%x)>C)O$X*In|serueJdX&*1yxj6JSk_Y}a6V}N+ zOzgu;c%bl*o?hORlbS7zh8Q=a@1K9D-vMENN7iXHr&F>fKM!1SE{PIjfMzOg# ziuKEgKOoaEd1*1-84RXW*uCLVEwO^IGV`Dx`Qh5_(DZlQo z9hE{gV3ar=ZWbmk5d>X*!L;jofA6$o*VPR!qWx-bsV!Bb_^_l|tlr)vOmFFRxPk@@ zZ!o={pVf~NmVzf9e4|`}Xtpv7&?u&CF1dseuzt>qiHYH{q^uSGz#&{zL_owbK`SwU z@piCNlm45_RHp#(_V%`po3nF^3Vzql&JOz3t5;<0>lj;`n-Ya3CDHn2kw|~50=+SB z%RZmQ2n;o{q52>)^;rT|oIF*tUA5Twc=3+$iQ~_T7uo;R!xb2CdSp3Sn@i3o*dzD5 zs$H|OyC3DWY+Bgq|4~;LOa5kCmLPs#aSqGLNv&e1%IDp?Jc1l2I$Y^@JB_83pH1e4 z1FJ9yM8w72wzjsqJQ&2>mOi=8H$npSj)$>r%<+uUk^ZI-bFucXojtUqii%RXe45XH zC|8@Z=ffT`hASHf{eG$-Qn2bzLn%b|;bOs%I|}KqRq8NKt1Tq#X-aM5Hxr979WJ2A z(=u6GTgzi^ZtjNby|U^jbF+|btT;C}m(}V93jdE*w1?MIyHY_nbM`pe|F$s$z~j9<*^Lz!WrJ9=-y*SERJS?_wuluY=CTl`l_vIUe;P zM{onsK5 zTk~Iy2oBcbQIL33X(=*aSN3=^lrK%=YTKlP(v46dD?2+olAH|l-cU`zBrZ?ccSAGo zl75HU*ICi_W^~QrwyADPDeq5Pk+KWkaBYjg-MXB>e@(5|yKbc|E!jS(X^)}*8uqWy zFt7DAlf&G-pcvoQHAV~fu6qlix7Q1PYw_S}4~KySst1;vzxc45_ERoQ?u)v^*?;U(|L>Ru|q{i;M=yN|- z`MtSYTUrIA`D1&#+^8gy;oZ(mmwkq1G%_uC%qUrd&o*1e%|%nufWpbqm+TVrCF0zT-Md5@V%43E1b842g> z)gPy%CVTBPipL<;sjt}vDdeUO+^>_} z`K`S@$RLA^94?z8q82S5aCY`U<@ z%ggbj6#sfk{%bq6VoSn*^ytyfa>uf7Y03b5!rB?62G#sJ>sguMpU!aXO8MJwLUd{+ zM>x4WTCJ(E*@6e<+IBI~W9)SLZ0AL`bS{g{$Er|imXwqf5izlwsn{oZXNy5{iKu2u z^0bhU;tY;R1^nix)4h z;1-j3-mrH7ASD1u|15xc=L!Hf4>u(Oh8;*wahSCe9=1v9|z0cO%twGtiRbj z`YVd)ydm^bTn?QH`>gf&`jp3s6bGyQ=kV|-OEEh#9p9Qx^&JlI-4cJbk?w)bnKf4Z z4hYpIWw*d*{W&Q6Gs!n;_GZQ==H~Q3Zf5HLOFb|a3`?Dm4~C#T7kv;O$5SS?w%xez zcISF8j#2)H15Z2{Vo*?ibQ~2Gl^WNz^Ui$3-e+ef33mn8ue%bXm|Psq5cBh(o5Skr zYOXK^7I$?oFZ6DcMFO}dUfQ)eXJ~O@VT9{^{lVg1NJdf;MOIc;km7^~L-GJS1T`@> z<}SdJn{joG_e`La0XJfd(n5oUQ{pp|G8+X`>YrC1{C~^m!*1{X(^pv~P6vKLizo-B zqEzED!(a8T^6g=s`{_ERg4$H9IK}$0?h?bxH@nMs%MM>y7zP~ih$-~S0~ZgE43mX2 z_G+~#p4>FOP8a@@RY5ADmIqMJ1zDRIWo%F&YP#x{KyALhHts$@lk4l(A2S+e|X7MWVmD21x3# zMKY4Hns2O8D`EYliyp7>So>Z0am8AU1>hP2VphAsjE9G(lwjas}Ay{}<5%CME|tNo8JIY06DLmMC&Np-i`)wF4-_*3HD0H`9KK zPGMmoO7+>ZVgIf3zJr4UIA7xm7G*3>!{R%7@Vt1fTE8IkL-W8Mb)Basyf^9VWtpK^ zpm(G5>+6_sc>Pz}Dlyd~YLYVbA`%^;&K(%);A57)B}4qSP=caS-G3I1KSEqwh8ymu ziNt6SV^&&s}tMr4jB4R9i!zVG^~o5+w5UZY}UWaKhiQ!JaQrPE58n=@b+ zQpgn3y{bvdAYp@%hiZPZ1oUPc8nn)HbaFB=KHdd{eE{q+E^5MdOAiLTK94WCxxIX5 zsTxxJM@aw6UqrD{g);4X^7va*Gj;>aKaxm+Ks#j}9UU#?YCRT@|MY3$JWKt9zEWCy z%LHJuTK84Oe@#dxIiLz?=UcuuZbmh?uBbb2H{n3fs*C#62CHJJUL_l};_7K)Q3W|Gy%a|SY0h>9WR-%R{L8LsyrX45jkHlCKHE=Q-}YSfb)yi zbrFTFA6@inpC0rc%kk9I6p@eRDMyhWryegY0S;DVx2=fw+7tP60uu|5dv$en)Nv}y z=8_fyIg^#7Pa&)4GK}7t>Ha9m)YIjl{p$yYQ4SQb6jo@wgA?JgM}%geW_%`5)%|6 z!SI+VQC?J7*sB|r_Dt?-vIM?00)P)cAg{FH=g-#LtMIlQ{{Q8Se0O}Isa?F{AYsq*-u8t*%@V4?;5JmOT$em z{z-_;$iSc*SgW9RO0Kjo6IQ3DMjj59+iOXE?zCp?Mr?d=oEneBL($?|IyyB#B%7O? z&;I##XjYr@*8b{cJMd#*#i2K7yP7SnII!3c`qA}}NPjclHvS&w`AgE_@rp`4&Lf0l zp8rN#y1hEWC#qQzhL+fCMbESair;zN=JxiXYaC%Carb_q4cE|kX6AM>q^QK0MY%Mia>oJ&IViwQ>18QI?|hm*{V_ z2>GEs<5&icrHKh5n8&#C?1$?-aKHT5A{sJG$dvpmc1A|VtD%l7qE+`96ZOH)z&sNN zGbEZNjn6|a-w`B+)gU?RzuJw!$C;$pQw>Hf+k+&{8{Pt%$(o)vE=si%dO-W%i^zm% zgZJM|dWs{RRLA1|MP1(uT={8am2lO&Ew=}_xVWHs>R1I~=<>-ecT0q$^V)#~GRKP) zm>bo6z3ZclAwl4F!2ihc$L8h+XJ+U?j;J)Peh*CJIWKLfsGMAgGcTTI-@o(>3(wd_6r|;QRaGxqCSR3)%JKDWoEfbMuKS^}SZ}0(bDxlUtuY!!B>g0&mlzu+L_5~*I*X-#8=l%# zCQR`gWVP9*CVG%#C@Cu|DyqUudueN604FgpFi2z)Wzp9#QID>{16FWHr9sCP*6Szp zZjOF_U+y?BGxNcp0|`-4QJLE-G-wCZpXBzW|7YH_xw%ONhr>}Aw0su*XJ=>GwB)^5 zFwKUtnw$#bs$}3fY?)fXxjP4*n-UcpPWBNbV1eLAxr zev&6wmTR^jO0Nr7SlLE{IPmdKF+<+4rVOyiCJJV*d}@%KNzgR<9{oQ1>E`e}#U?Z;JajBK(YLORW1zhC-OpfFFs zPj`k<2L=^=`I{(5PZ|TYsIePZ#2BzkE-85&a+s1YAS*kfL?+tj461Z5n zu6(WnOBfDTbhI~?gcU)zfJae$Nrp4b?w+84j0{8Q#a8KkrnJEck^d?UKSNMp5#`PY zbSGwK2Z;Dv!%~yMUiP*;MKfUBT?YhJ{vMa0zd?u&?L7noQj~d3bf2%at*uQ~N=j-Q z?a#zCkGhmV@w3rApb~feTKc|`3tQaPCO(QBtM_%bs;iP>!C0yNYIPwT3p8$ii#t2a==kK6MHl^) zJME>NUF5%iZ$WRQUJ3`r&0T!96ABd;5ZEV4C@7ZE=0u(qr#7m|9Lls*^ndexcd(Dv zC9g=N{J`gc7`DTc$MkJ&r15RKH+!6Hn>G46&yAFa{@IhF{uorSKn$t98mBhNv3(>~KdP`L?YuXr^ zmJ36ZK#@Ttc#g|`JRu&ilVbre;KbfT=!A6F@q!1HAmjHze>tTa$%HB_d*&L%u8nkp>~{@#Du5YoCO_Y36{0XZ&7qn|1s0Lq;-PJSI~44ESaSJK$4L;?llvR3 zz4V(t?Mh{T8NL|-AryPN(0_C!0wkB1nD~rSlk0p-H+0)1*)Okeax#@0Lfa`wglj`X z7&QwhJzwkbc;vJ8*}~UG2h2*LuqUsU*AyW6$R{B&6k}f=XbOs(K$P^rp~3ADAbzH* z3eo~Vq2=`{k&#<-m0fN!AxX*EiMhFpcF<7uSC`jClBa8!R75j9;{49`i!sqsvj+Cc z!7W^W;*t0ko5<=O{5dvd{Ik2Xtr!|Af8RPtP*>&v2Z;6L)YPg(!X9qIr%xbsf>U7Y z=?VHI6YVCtjW5_m#lx{;ud)<>{pY*$hUKV+%;C!!-ig}LCG$N1 zl>(xoy`^%;;Doy@G$u7SOM#8#VVME64tVg@?~M9-G0&zPtU+m7l~*rczCSrR*~7&O z2RGHUmLP2kq}2Ly4k6*bf{}+z8n6=}j+mV_E3c>^h*BgbBQxNnme42ZN}90>If%2~ z2Py4J#oEB>35c>P?3DiMzfo1KSmB*>Mis^nIsk5(RlmFk6rj?wC4DdS_7cPj0Wq;> zCMNgqbP}NR&xQuCIj2&O<=|6BLGdG1niqf<-HnW<2+|^7lo_&7#-62dB&kJO@Wmkg z!3v#EOe`(E1+1`G>j=xMNEB57Xe8pdT~?YWAt>0D%%N#o>p;?RwayQ^c)++dv%IVB zU%aJu_p*`xprNop*ds@CRr~B!3ZJ90m#-d|8GgLWoOhklU1Ay=Qvmi48YKphw2qFC z1qB74f~y7U3T}Q)B7rMXAn~cd4L3Rdzum0R`I-WM4t$r0_?UMvUj{7V^pMku;x@s%`G2b`7&0k&G!D0oB z1VSyEy`5w`6D(nCqQ$W|T6T}aeu~IwD$PAqRI|QS;~GGsQ#Ck3)qe4OoOEkH-?+c# z9b{e@P^VPzIaEkQyTx;BqWC@uF|h~}59Ld2Iu1D0f}*bR2)5HLUIcyDmr!~bIQ_h2iXlYl5%*2 zSIQgy7EhktJSV7jZCS42orYKr)z}ZwF*BDMa^C@|mzVICch=n83;i-`(D(qME<{O{ z$Mn>@YQa-!bbgr|`>dnS6R)@OZ?-bD;W%6aGb&4MuO-X!9}LqNTy=L_{~jX|QDQL- zgLJ)rmJ5UwOaMS_2SW3fzttJd_#U`FfI*nu0#{c}FCro$+Pkp)K!63AP~*>t&tf_7 zm?a<;qI8LUx2sj$ta->OF4`6r*B#MEyqmGBf7o2zpL{b-!OR(8F<#iOSTa&_;ZFP3 z)MQ2-*INPVXgYfOz;kX*xQK39o*KKN0NoMlhaqBeRn+uN!237Y*or{FO)x_}iDwc$ zZwu_7n^1i-beHh$vPLg)n2^7&`yQIDH04jA;eWZJ)qftqYxI>b62F~}PBj%2cIAPf z?4Axism;GeXJtLStMA^n?1}+s0jvY6-;nbm>l)8>4bVDbDhSX4*hwC7xbDJ4L-H<- z4J`}wHuFg&q-yBM>nqPCaWL@*GX}L$riZSb)SfHXQPU4F5r0 z=Rq(O<^!1Jh>MGR6X@=~Ki%-ToRBN~HNGWr?vFU%9P21l(+n5M1jWM7@N5w-(&!`z zMnmNiPbmVxDrIaBI@)$8P~|N&RUecm{J~qAA#G`gv_&#MEy2o`l$Hh`7%o0TQ@Cgc z2VYAA2|R6AQR|rlUd9ot{Bk^Kg2eL8W;%-~dl_7(s1A~a=_dV6L&=cHlizTSMl_VI zw`(?8zfLH~>&=_(OcR`bFh?<|opnKqA}r7l#e&Y3rDMLk+m(U60^=M|N>Bli?R_bO z9u@`)1)rEutTsJTuOEC)!{4BN7XPC6<-uBMe#nJ9r;=4NZ5M7#$!x=;JgUE845XMk z$II{~yB~q4Z#!s|jQ)HVxwkGEuL`Xp?q>1a8>KQr4O>` zd?86U%foojL9WufT2e`=oAsW3xw>~A-sK7hNMAR@!=Gl_g9Ck~a&=nG6u$p-%|m9M z2QjhY_&4AnnQRVf1SYVZV5)!9qh(!_16oPBEIJBQ89M=^2+%3RMIPYeMB1Be@L(0O zQQp5(Wb=kmalM#~cNX zmNqpt)f#g9*iAU?i!i{t{c6$+M&6$rBMGghIi!WPeYDe-Z8u=_^{xQxnjvx8*FMb~gMg*mKCUmgXJ+-ort5t`SY&QVzzFa06e|G1Q9FFIi35%Grgp#eZaP;k zUpzw{OQTr>BX7Rq1#wVj^j!L@r$vF*w4<-DFLYsY@<<+Zjc<*sUaVIXk_B%n-8BqB z=bpe8zhq|G?#|WS^)1XAB`@aLl0L|@52IzkOc%Ddy&bUpZ?Odp9y-YYpF^z~_*S~2 zynM+RjDufiZKxKfc7Z(v`Ae>;E6PdB%kU`1B>R`M8e6s_m#M$!+L_TV_q`;Y(%>2+ zk~y%efRl8v!w&6f^r945A#Eow08Rl#RMi*&zXdey!IvlJBwX^>Te`ubB~DpxZmFC+ zR;4d(9O6ryG%>5)SAU&tZob|)#^InQT&#IBRo=m^I`~j{xcaN503FNJ{V2&XiEc7Iz{)c~b@{dloR!5Z4U3j95q&HWcJs?F8A^ z&6-Hz4`?|^a3i|RAj&IS*wOmCcqP2T3O1{D+#C8U45dStRv)Gtc^^zP!|n;Q=`|a-S^6-VB(B%Y2BL z*E1_pmgGa2wgf1m!P7|$y?OWNrtU~& zX?lFz!Yht5P4OS>PN(%Y@8vcxO`%;1_sdgNRqYGS^PW&wLHHamEiFm^IXFXDjm9&Hji$SZ1&)BZ)H_?T zY!&>c-`-ig;}edeAzK^9NqPW3eO-)X6;=0h`VyZlrf+VJ!q%7kYoNVl>|r9{=WcNU zu&pLzXtB)&KuyObC?tY35XU_H&70qbfTL@IIY+jbD_gEkiq_-I>}-&TbR<@BKzz*n z@?`}~36Oy2C2&OM>#teGK;E+v*bKFuuLp4uWhj4BfCRu!A47ksd{ixkNgw1wfePF(xM`zi#2hNpoX9 z$AofQNF4M~#rCZMNCMVLnyG)_`C&4Hq<>*yfknX7z`$#IG*{XTv}>SWx-rz{7=)mN z#KbndEJ4?~Kfhu~E-5bFx4LG})5sr6g)s|u(*T$i@L|q$gocKAd;hezQrWzdq-F?x zJ~EybRJ*Q~yt9=H*`;o@lq-Sxu%DfB$If)npLwI@9nk@;^`&NDhdld1BiSU`3&E*bH%QPu{ z`Ram_KU^l3MhV|-Gnyg7LPFm#0{l+@EoLz9=7HiW4;j2W>zIFCZEwaC7!dHU4PdI1 zv-6sx{N)3%BntRX#j@>ZYwQ6SUyR6tLIsrLFhtA8IXRgLBQBeDoeC2DrzLaLTpU$Z zRp4C@)<_!=SwLqgPdd}$3(ZF?*EwgvI?7T)8^eu%em=}2Jtdwx#>`h^WMHs+`!)d# zB)MbWwL`+d$c4)WY$1}yf@gmU`90#R%&);;k>>@HH>Y}}!vHupQK)VK zVsIQ774e~ZoHFQW4E=)W9Q`sw;+XDUkZ9wd6*>T)MEHb?R7%+o{wUWrm`dc%LijA| z-Woeh8|pSDle0$hv!+Q|VU{x7Tkk5*frBMYzTvr%(fWOh+mnV4 z4$4^aSml`pw|sfwnzFK3FoqDvC7-X)p9c<32g3A?_~POsGI-||^BOo!b~ZMhy0+X( zP%&@;U~COL1^fC8*Sc4jd#=imo_n?sLpo?FsF)qFQs}Fx5}u87_e6C|UH@6j52NZ<^s)U%%{x%Xye*@Ca0&FDE*9aozp1w&5jEc450=X67_KRDgATz_H}d9u}Ev1gAk z2{9Tmeggfw62!#PQXA|(Ft#m%JAE7HgrJg#)=763TTabbBZ+Y%I{fP->k*Zqvp$Qf zH#av7D+H`MV?K+O;4qQ|_l9LD5&N+vfd|YqUk{v~*RnZvvBmeYT&awn#u1S4JQ$5@YscS8ZXbs$U?6<_frEh14W<~%U?Or=H`jn5{;bTl z3fum-v%|2tvtw~cx%*jH9<&)?PW^y^0Yv^YgOcl|cEX3xW*P0F)TS}I)5b|nB~I-z zrR?8pYpJ>g=olD|o-mJ?j240HmrteWmu~MG@*f-vsu>f?mvMOm`e&>`*SC8_G2KH6 zlTcYywl}yLH1M&TxTA0Jy?|1+@r{CEr2|AMXX9?jVWSOmu#JIt_(7L*`+1Xjo zZPADJAbtY20S{+PMElx=kTr5mqWqD|^4QqeIe+>|uqLLE{O21Y?);!%1W$hQfvLQi z%3q#d<`qfqsV^U$xY1|huP2!W0W-o5*N4C>WMp8H3o`rrE*3E9rqY$6V8sD(U778v zsw&=I5K{X57#gZwp!c<)ARP3s;QbshN6?6m?ds}slT4^3bAOc7-?`dL4xI{Ebc8r( z)r0r(`mff=-ue25uB)NtQ{_zFJt4=%Brfs@MSJvt{Tjr zLT=Fc!hpy@3jofn%+1+axzw_W>-H&_L~^7I)_QUTFGI& zgJKOV7?)s_qHSM)e}4ku;*Lt;I5$`EPuG?qflu<%`h{&Z_Xb~a)5e8-E_+FE?3^>} zLJLE`)8z62Vr3_Ee!8}{ChuPj3wiW=w!MJTlYJNWEGLAQw&ex<=S*Dqw{)j0xir>D zPK>~~-j~K2T;Sk1ynFZV($;D5l|N4Zflm;lbsysYKJIni-aFd(k@x%USR;5_6GL4^ KM;W4M^ZtKZa6j1q literal 0 HcmV?d00001 diff --git a/examples/widgets/animation/animatedtiles/images/figure8.png b/examples/widgets/animation/animatedtiles/images/figure8.png new file mode 100644 index 0000000000000000000000000000000000000000..6b058041c4bbbc48754c9bc4bb82f93cac4ce7ca GIT binary patch literal 14050 zcmY*gbvT{x{}+=}Gm~e!o9Uirjy}V5&vZ?9Gu_>F7$4ouG&3{Ibj@@(-`nrMAI@A{ zyN>hR&pTdqB2<;-urWz75fBit738JW!FRK#2RbVF*I_ML6MRE-R+p1RsG5N6fFDpz z-pNTLJU)Hqb(AK8-(Wb%>o_AI;PgK|5R+MO$iOerToj-(X!FR(I1pNI(vn961WE)2 z>9?BhzxT7<(z4C7FU2o4lylSHyh&HGz~?S6LXMBa`}9|S9;G;ZsC9R=w(6OhmZ6ru z{%3s|wfCxyIOhwRt^-3j^S%Mv+=e~~ury}WZlX!fVcRQM^S+ux^ zhdo9v9~us;{~R57x^=WI=^s|P&9?0>o`WCn{kr;V?zUT7TPv{o(3R7XRV#JWoJivB zihRTsjs37A1StTay6d5}&ZsA_x4T=yW;BIunr&2(d|&kA;0Zz$A=}OBSo)h?e)}b* za?RdG+kd;eRv$k~pug=(Hu;Sr11}I#779;GTU32vv`?|Q3(rY5Zi zI*BqkywzwR@|CrVKL6{%@}0x|Y1`+))Lfhx1J7#npmR!+=obfzqd$t@bwr1hSk-8= zhVHhOhDheyfD5V$2ng8AeH|wgMOfo@xD>Z8z!4VIv zJlFSjPa4mXC;SU$Q8^`B@yQP!Y#59S`cg*CL7%9PlM||8;5q~AdLeoA+qzmG;qGA) zM_x{DFl$;_`0Llk#uUkXf2)j_2*-BHY6K-pw$u=uLiD#4j{chzff5ouN?zYM^abY1-JyTa? z9qo11Hzr2SC_!xYdyx!dPbDKIB}EUB+&J~X>N~QZaD+exkL`Kz&^5bX1R8h+pPE3M zW#j1HDI0HZXhon$6#OkRtSb1A;Y$+!tn1?*rF7v`T~*6ghHJ5U`H7@HlhnCnGgCH6 zo3gP>YNh;A7*wjTSEIFYRquR+`g=-WDWkK~Yl))>a}iZ?DhM%Qr3rWpqHXNeO+HXC znNy}Kg?f2;J@RFaZ^bfDs*n5!hrfzQNzhMpi#)Ba>`UhR{9ekeZ%zlBp+aqm;;m3` zYKc?JmjX@ARJ3pgs+e`n94*C`Pc!g}%*;%WqaL(bWIu9=5@=@Qf11qWO}1oAbTR8n zsyZ?22v^MSrgCnRKBVflRy~UouQrx6NX{*8KFxPQ5(`q_nn9l!JvBi`(J|12w3* zD#~1^vqnp8j_6>e7iC7`m<>}u!9Yu@g$>EyTxU>*8Wk1wKMcOcjvG;Xm?jjmI&}Lnkk`;6I zyH6pa&|^zvX~l8^OcVrOrG2peuVg6 zam>}S+ALfc=9E~8;lbfIOYds5&!RgRsI(KN41&rJ(??y!Ka5O@)drL#{;1p^u4TAo zzRudI5X+lrdpO&fPDH~ccZvOBC*6Uq;R3C9zA4Y9=t&5YCzIw2%~o?%7rJJf$&-gz z-8S|n#%VH#z~KTh>jM<%RNr~9Wz>c?ot_1~rH)50u^LHK5xdTW!a*qbxM0^H|~YFS@*3zMgO^`})=V=4{8s)ir+H!pC%904D{nY(X#by8O>s1+FTY zKyv1<#qg@~vd`#HYg&W#LBd@@ad|3vW z2rE%a=e8P2V&Z725+1KZnYW=s@AwC=_-JFZq1AQsYJ7Ygp;EssWx>8HTa_`m#H!Pg zA1lbIJox*weC@d3zdy9jP!W2!k5$GJTD7<)4bRd>htI9?7F}N z*A8bNXFCFp3}Y67uXz5a%X{ z%1(nHp=xM2`KQI%$A|}d+7Pzw^IA(HVc2XRg-FlAj*%czJ7v?bS&#j671xirkF)vl z;Z~>9yQNyVgUs+hBgCe~&kN7i4+hvujMtti@j&S^U7A0w4whw-($osP+ke&f_qjT8 zF_--iPwboo9}kZnd9Iw3+-i0~xw8V+1hOXvyI)?fbT7?JK%S!{V zWLED^CrcX|k_RdLvRYe(ayASuv&Gi*3*NnV9?8@!z6vOHRlkH}z z*(!tb?WY8%;nk{3v4O&`%PS?L_AKKQrUF*Mr&C$ z^HnRAN3|R1|5V0g|J+&N!$SJkVD+WMnbs_&q#N@hwo_UoZ`dzB2U^b>B~QEN6;H-* z2TCMfp0=#2N*2AR-fEhdoSZ&)@|J5MUcS+(+27rWAW8=#XzIcDPAMBCBX zNe-R|&I#(sYp~GZ!bP z1TDVt$B*cPj(-miFL(Yo93*`tR zlVM92H}f_r*QeWV9tTI?zklz-#=`n@tZa~vR>H(aKrp1V6*Jl;=jHik+3R{)yWI?D z(KXx5&8m}!IP@)Z@=5gR`K;k&2Cwyy8TZc_SXSrMl-eWd`T030YXOJ_cs(#!#Nhhh zR%P~7WTS&WEqlKkMg`gZwNqe626+XH;E=^m(2O+OkvegSBv;TC3uP8OepK%#Qe(v-HS1tmsnaJCBN-~H#9U9XCZDO zCAvZgUB+QCP^GT(QXwneN{|2YU6$X!^gj=OH#@B>;BX3L51YOeHeKe8^)zR0s~@yQ zN$6CJ$%+r(G-1iAjM6pQwD=KM`CyGaTvEKDY-ng`V%2XwV~=GQTn&CHU#$KN2@&k1 z>cFBTfT8Mgmkvk^3H8ibGcx#WNn_T*`oKfCu~K6tWJ(=9(^2?PB0MA?@l9b`0lF`R zi8jrvrf3{Wp020h@)}XbM2E1^oa$9X0R|~NQ&9UxbePs`(f6M+CpsF9!PuL(o9@hw zrKMqD2JN<18gyiQ)ouDQKfmLp4*y{6Z~f^LSeRvSMOMPonH-|F*D)F=G5%>Kf(_;6 z=N{ldpW_1Gy+)oym6YWuuj0RBLW^LDN6 z0^h~qvfphW%Ja@sfHa(@WQf$*Q+<-@Tm~*X^#)~N&+_-Y#T=)yKXQ){eXvBeQ zwhQ(a=lFlP@}NMzeIdcZ!7<6OfNL_J3&hk(s}VTP>boh-x`s3%ijqCQ3WZQ6E53*t zxPy8&^F)3YKwad4Vum2W;U|R@_u=+_w+nY?rQ+uIH|J&W$g16s8M4gDCWlKM0N(*f z8zJ4RVMqmo&HrbN{DjUAD`Go%mY17q936FjIgrHK+%nhIpSD~S&D8%?dYh;DGmCm@ zxbEh5XS#IuITfRTxwe3kkI0v4ik^SZ6G@=d;VeGqQpZgN^P+F zAHs3xnDe=^@IH?rTXYkJB)X@U*S$D}fJ66b`;Xhp!^eu6zn~z`t|Az6%6yNb3^$x} zZy_aC?@yTE(Rg^@sRgQ{jWf*5BCC|v@It7L+_o0jVna~eX}WTERjPYxos&MGmjCKS zmy;o79uQSKSumkw78Xrbyq*QsUZh@*F`1@Z>W7%s43J>;qQ`dj-_{soVz8cTTz1rb zuSX3}Ixjn7*>oHKvz#Pn?>JKjEvDV}`D<4>5v%r*g|+oA+=j1hGmWnQjYA@X3h4Er zrdLbQwyNF76Zgs*G;hh-^Nzm0zG~0q`5!;1bG;4(4ZM$KQaB7JLb1u1+gLZa>nGN( zucn8F81F~Oh~G!RNwb5bP(up#mo-=kh24(V1`Lscjfp?&>Mm%BbPiv}gh*5CP*zzE zcqvoaUep;cTboJVGNIbAj!IKc@r*NY>(3^`;h2Mt;e+d-iI4xXNJ&ZUEp=pWZCQw< zdai$qMrgnIZJjh~?xMflFl$hlpWoAE*vDB`ULK*7QcO{iN(cBK3`XvIWn7}1Jwg*J z(mRnYj1eM9o2XDQ#TXP61e)KZhM0zi#*CZf#}1FJt*utqBD?R!yk+^{5}~gy+h{1JlQ2%kt0axGQY5Ebr;|oNzV~=IwHKQh z^z-2}6x+7?wC7RA%hcJhQ$ZYxQP8X7!K?`&w1B{zpnyO#6nzyHDWJiAF|R_a`dg!| zWd8SOye>y8JsAI2HBD3@lB>94ewzM_k=%n|DZ+|1nZX=N7j|Q}@4Tjem%?i7?w$tV zOYJ->*hccSy@K0WeQzd3PUSeNtVj)Sex!O!{T+CYQVbZXWD$xa`scs5?uR72bHCgt z71xL{(~16Zh9UdkA^+!-A%iv;>R(mJgoqb6gnJ_Uh%B!aQ{Ek!#LvTX#V4VbWN68q zK4VW5<5AV#w2S*@f8X!128p|)vGGE-kF%)6YVDxyu%xCYzQgNst(6^|EZ8RkkP=l! z%3?DYmn8kR&-V%k<=U)U#YsyIL8}hhZVl+EA zZHwCu^~5O{_<}tp%~dQu$fWrF3?Yof=15e@8SoEE#o>fMB+3z}<2!F`?d(9MhBvW5 zkBghPL!vl#YS}~6T;huvFe%Vv?yx;$4L)Mov6#rZ&I3E9^X_Ey9$_zzg-HP$ z^Wk7Cvt`Hf-F0dmMIkW<=d{fhLzf3qUtA70y1vVl42?fQOj#XkL_s&TaPLtc=B&62 zn>vQ$y`O%Nx$d(D^aWk7^2mN4#YGzNM`Ggj6KZb4sN=OLj#|fc*$*E+%(c3*0Qv<$ z@+}`1e#G}5KYFY5+lXJkK2LNRtgJ0c`rA6u>2n)bRb)}4Ok0_-+r)$;D1T`?lf{@i znjKl-eY&3&-1Hy94Vu^y;?`JtADZ~pTf2_)_u`Y3c$z5dbG6d#@W`#-}1Cm~eni8X{uIh>n)nM9$+R$v$Et>I= zz5*>1ESc}NaRnJ%P1Z7?B9C2fWxv0__bnKCH{`Krudn|a85#Lw#uiF^%{tQ1-h3Sk zfkZ8Jh8k1E&rytG;ha?7#&u6X>mGI;cA~+;x>4Jwa%K2W|E0`F|2(r-Q<~9vgaeLx zO4BDnf}^!ybbl&klGmmCKp~rMVmzjDm1(q+uOP2`Ec!N9R|5tEb53++|Aqdn-+k%9 ztgF7*^{~p#@*Cg%1vf^&U(3sfUiruFkU>WvyWBVlW&5tCA?VbYprq=5Cb7)*;ak34 zy8LKsySb65vIP*3B|tV{B7D%*#R%&g%Mwfk8+ZLbrV|Ou?&los-Af%_JNx_RB$`yu zLViJ{WN99Ei*<>|{(1kaQ86Os^I(Y4Cy=HNE2=6WryJQ#6ub&u=|S`Df5>6?ZM!VJ z+lR+GUAF3SL7!VuAW6=;<|s0nF}GSiE~9Y;eZL%#z2533%XHB&u199wEY} zNxT({MZ)N2xRq;>B_z*E)*oIUllb~J`Imz;smY!Kpu0Po8Rw#twL9bN>|)obq^8p^ z7?ZUJ;qpJ*Jx=dzwpQ_z5qNodX+UQ|OS7CtB$$&W^ zR8>*%LIR`BSGiwfbMRSs)vn*V`PI$M&0W#h)pD%sE6k9N?xh-vZLcr>cu2*n9uXzR zCM-B``1gXUwZr#IiqO0qT<=3~yS9JteQO?WU;cGosL|ov;YrZYM0HwxHZ!fJ$~n$m z1&avcPRCLazpp<`A>UCa2tgxv_Xh_Mj3@GNwcfw(C?qUw1qK$-62~%lpAS0DHQ7@D zcIx8d0wGJKE7mlvA@;i1dyD?|%scxP(F`Rb4THh~FR^XYkV{%xh}3l)xUd&1K61Jx zH`BQfNs{^9+v1NNU7S7Y(BQZ%kxd)l*$0I33Dhd>tERCso#1^#j8llQ7;DG_MIO&DDsiYKjr=*h zRoj0i(4vPHS&+Be%1D4I%y0YqOhpnMrj|s*9uL5Lwf82=Sgv^PcqV`0t`Mll=Bm+( z>dwd#E3nRgFDwjZA`~U@4pLLeGhI)``u11q)HPo&d9j!$IxG4nz_nSai_Lx%DLe@l z!)7tfLS~X79=c>49cTD#Y-|t#2Y+`F1BE`5LTf7ZZPHqLiR5k)qn9X8qviWGrF_<|{#{)!lUYB-!HgnzS zmN^Q}&Tl5gZufGF2A8d5s9$uRf3>FyHv0InOdauK+8lf|^pV^w@fx|EiDuj8uB$K;w@|*j2GqN5DI3VkeL`bYRTeC2^M1{4vv9C-#Y%^V&grw-t0+53 zTKKCYT>C|3WoO7`wlAA-sNq%!8%I7b?({GIm6ss~y(3X5zp4!nk70xDPht#v^9mB! z-%|Oic}-2JQ5>CVPpZr5gmA1$%@8R3k-O{DhyfFk^Pd{N7zb*I1&onp)zzhO97Zy< z@5I&RT%$u>=!P48|6Rbi+84V?UBd?gI~llmc+R$t-Hm2lTkbCw%B!ljB3Y_d3ZmHI z8*dvgJJfiW>SU4-u26WNt|Ehlq3Zn0iW$?yKgOk}#1#uI7}NC~>+ zEB%a?lgxxna6=PsZallz{?t|~GT5VI_0bVvt*Doa?~)4*eY-PdEPI(CM}7$?E?<*2 zYYajy!1n^=d>j8Ns%59^#pT~OG&SA!7bGPZ-mMWOU%FPF-O{D%^@fR^QR&TYf(ces zQ4#f#XQU?x4V;rE4Cc7fjp)<@iH?p2bqr~G%^1A$BujvCye|H*E{=oZhhFsj*gf2g z9tzFtTzjvW=^sw1A7MW4`!!ALSNX2zgzF-fgY?}DMZAHtcjq96gsa|wqdt9@rK;03 zK_#oC{Fllo-2~r@qcTJi>+T{Tl#$sr2Y_=@V@@uss4#u%`ajL_Mx1~v(|XWC_;Q z&D#{)X)_XhqNRH?;(HBQ_IPhOvr`(U`uS+AQy;5gQ@)rP(VCH*DebHi)(d?NRBL&aCgL)s)+Z^UXgHbfIf zm#zE~GlZCgM6kdhx{r#Oqy0$IuKif{X@5+`Ahk{z<~5 zChbqXl}2#_4eImB*nG5Sisd=a2@OXMg(%)WFZ*)vhGb6f0$*8u_MB<(CEl#-YYwYo zICB&cM@d~r(CkCG-aHv*o+cyyYHP6Mk5cCL7sRHbeuEA1_1df_J1Tw|n#=)mLK?_P$(@v zhVNzD@-@mc1c1qvvW1e(xQD?^g~Jn+=mFIQ>=-Ga+YyD90JFw)5XWLNXBZ{ATdQ)Hc^_W7hj`oA!hP> zS8>ZlJhOX0fld|?`y~-_uRX4e%uGO*&6nCe{y0yHe$4pR8}fY0HQVs6${IsNdF*~iW*~u1`6{9WLyxE+pAm&d%L)&F<#!nIvRiBCg|gl_7@@!c z((~LYzI(XrvII5%L<^m_l%DRNi@qhm3-052gMFi<;`wswOp=U5bl3H7r8RWg8r2ue zE8Y@(Rj1kFMez9C8#UCi(9u_H9y!c#V`2fuGPtCDY0u)NZ?e6}Er<8&9mmVq{_EVY zhDG=Mf?r+?RPPA@r4yJTX15pnKY3w}y<@T|Dj!1s{dgar)!C_}wb*BkEtF zNUx-ISUqvTs=hhC7hC7eqL;!!odYzY;5h;Gm^TJbQjneu_yf&gb>QyOcaTd_^%s;# z<>X!Xn=jt_*!ZOhN#b6CW%6j!Y&*V+Q^(zEfCGr0Ig&y*R=hTw-Hi3 zZ3$dek8mZS#p3Hdo*&S4gl`fEg=~^7Zvydv?gX1D{4AjfGhgiu$#VIjU^Dk$KmhNn zLUIQPJ%6ij<(939{eKH;$lM|#e>PhW^s4>yb}BjJ!vpJGm)w4^iPRm2%@NOqZgd|; z`C>M};mqo+gzIuA4jLs&9)>mA?RXBwNyift6Ojk0fwjim-!;}MBJ68RZPSDs?^$Y8 zdC73d`wyZDwBP!nH8wWh*jfdcym2!)qv5-FNTF!I${ov68&nlk`RrEQs5N_TTCf(> zL%Dpn#Saz@4=?Xir%i}n>iw$J=^IIAv9h+7Lhk|43#jVtzy%xpcJU!)h7b#tn4sJU6V62a3C5(SE~{ z?Ls|Rj=gO}XqzxVTgtCLT&J5$MeO2@0V6=!Q7ocs{(K#Fb%^~qaxxdDJ?}unLd3cv z{M9i1`>k)izdTd+G0J96;(E)x!Jv+t8-IX=KiJ-WS<^LfQJ500uDp%5b?eqLm08js zDGBi4S^@b5R$Et`!Z*)vTh^QW2KT;sxTGv_j!+TYf0yQ8K0k}RAPA9= z7_7zOp$mt9d{$3M^;I&2tR$cyvM^^5#+>{CjIzEE$pBC;x!j~(585?(M4aTjlq~Nn zjV=!s@6HV$c|m*vRT7;#UXiRO6^D&53JVu^`p=)Sm6bgE)Y!AP9WBv>uVDXq&UBre ziW)L_3(Knvsu=ysID98nELtA^(5@5 zu~DQAEQ`q$O6HbG0EX}Ug7KEo=Gr}+2Z8923aMfMA}`D9e#GXDWl~j5#4?`QTnWE_ z2!*#wIPKcBGY0W1;KiR@-`x)q5I@{)i*F-STp@rh%fCBYeR+THEp|9fSFZU<60WJJ zU~0OaN+8oxTwQ(G9j_Q36hsXx`3W_Cl!z}tdEIyG;dJOT*BD|Bb1ApV0Oqi==(#3{ zq`ae!r_5G1ZKZ!d|BaJbBmVQO-By;hsX)sJM27!m|L`XP5^QTqVu_nKuY%-^q`sdk zil!YfW7+UA;Rq9iLJVHZt17o7xAH=-8qiJoM#bpKfMAF#a@3tqc8ml?Om{(@{7P8R zyWnnm574i(8hv6p+5;oy>DIVcY}GEX=q=sd1>Up6=)FEfLOaE~fjB0=fmwuRQyalr zh!(Yh#-{YHUuGSI1bIJIP{Oh5Vd>2EB5Oiu@` z3joMMp4)?%j7=r5Qty})KRK+yy;4ghDa z!)CSHY&Ozg3m7w!5}=uUj=*rc-q_NeeYn5%33LXCxPSfF6s^CO^+}AK5Iz*a>RYK9 zBtJ!a>zVT_OVD|)&8=DmxNcbP{4EY3C^if@Y}0xqB(^#Mi9qIi$K=+6pX@ayugzFNUCB=%K4u{$Bm7&CCkraOS2ZPnO)ryX_VbBe=&9X>^#1B&~S~XEbNU zOffQ>f4^3PmnhpicmDQIZ6pstQF(Cuni9w5{Z^)Z=#sL2w2CeZT(Mb^29F?2sN~rk z9Z_4+6`z(Gfnsrjd4|PW8UnDM=j$vJmFS;D0WiFQBFF?nKEO>82Z}3jURKB6Owwj6 z*V!!!fuKgC?P<&^p;y-Y8iiq4sALy@bz6c-Qk&5o? zkW+YuDpB>Z_}Hue#e6w!E!vm_rkPXApWrDXNpz6ZYu+iz1S$leaxe>w=R|*M1oyk+ z_xF#&wu~U`702iVf&em_lGa}`{uHjI$sX>9QT`C zpWy(Pa>-4}Uz+;GLHnulgvhDVLCZFI;w~kJCNp$kgpXvHdm)6(5F+%tecvz_S@p9{B zsa^oWR|MnPwdfhJ2RDP9$2uc>zN&lWnwmc|7c>latUd8yk6k&VA??xgKy0t|GlU_~ z{6pSQQ}h~gK(`H(c{acNlLQBxsvCn{^X*Z51q3EnllZu5^$tS=;~}mJ)`iBP$bzRR z9_%dNtk(>Ms=E;qtj@J%z+Rxrs6@=VCz|-iPSxqNacP=|EWs$RBZP>KsG=WjY3~o$ z<&R7v*5b3B2SCK}Bcy)hD$#dsk=%krpr6uoeN=H0I@y2vkE#fxJo0;qn!H-4cbVef zgpRlf87=WO-XCcnstiY?O32$E%`pW?O zmoGJili*{D(1;FN8!c0@-Vc4kbY#8*fjoL>#>Ny2tVY{LRxDQ>p?Td+QJ}z>fG&0N zj)8u52JGHt%J;MK1=k3}=TwH5LNQW8*|Lft!T_R?0H3y_rZt^HG@;Yl9iF_`-Z>PH zSA)JtU#s+FKJG#eetQ$axx(WYIc4X7HfXJxd0W1dKI19MeOPhs8 z{@7UxKHz&i*`*)~1*jHC3ihSdIh@T(2z2DjCGZgLS zQAC>XLi=i20S0>X98RE1?YLTtGHhVo-RSJ>lrqg;V$5sMs@v`7>#VsZu~1HrAkURt zSW!NasxpKe5l(Tqxwwe%q#VEDfqHH3J24%4E#Cs=XS;F1ZXL|tbB)$27pBZt4Q*75 zBVP8{D#UNhvC%ladehMQ1O%gx>onV$JvqL$>^Cl;qXvQ0Xi<{)=wg;M)+S4tR>ALuV432gIcf+A^Bok+h`zAwFLrZ}qqk++eOZ0mv0~uZO&p)5 zLW@svpNLy*^@NPU*@ni)zlaer(gEq9ip0hJIef{jm4yY)z zSC?MczQtAM;~g6S9adj=qb+c4ScVy%HM|S_i++NPBl|6z zGixXj6FM!;m+8~jxPM7bBmrFQo89W|sCk1TNW9cJLY!UCb2vAeicV=n~Zbw3I!MB*Hag zmH}a*q0Aw_6W2kmMOQadeDo;=VER*Te$sKSaeo_FEbzPQ&@g0qV97a5mq2kn#Z_{} z7S&-e;p6_7z__>wxG+dFCZ_e0{b=BaKd&AEq@{c-($Q3o()|1YzG9zV3?U)|cPh|= zTW@l&v0_C|&;e}belqsD9`6s+d94XSXyJ)IYO{VTFU=VN8im_j(WWtCf@1LlbLO~j zA@DubKmv61c90C-M9Nk@G=V%Y>I#<33-o6ob!q}&DA>wM0$rc(xFpx35<6Bu$|c?< zsMmrW_Y|V&@NA%X=b`@BL$T2|QMpubx3VsLzyz2Q-05Ri8grb`MBs`$E!Z}3adYgNi*!)Ew724;tuwGBR3Ot$E~k;xU&A zHNH~M9JjbXq!4#m)_7N9b%QqJ{>&Zsf(!S$9;U zyH(4jKf^WHLIFw;L#Nx%vnlGI6_{>g_$j@C$F-FoM!se#eoMm9d9@aNDgZKtq|rC# zmrLKj;g^(AX@Ll$3-j(HD}_Q2HttYO}V2 zcRLUPI#}A;ngM35-(_r*CHV}u*i_2s=3IvtKQ=bD`}U)!-QlmVx;3_$IXUEhc+va` zJK=katKLJx6}aC)c+bQZxL4W2ZUC4+rSG(Xm;RJUYd-3IzO%PS3zFS_58lA;^Z@oO zkURlPehETfP8x^L5SfaXbBUv6?~&C|(a>IQI$dvawbfginQcTt!d!s@NDnmJZ#VBa zI+7-RFX}+&sWK&`Kh52Ke?SQ;=%nCzq|$swSC-or?Sz5 z>yEj60Bws;`dlt<$D*7KDXV19&dh-S3_@f)e0)Hj0wv)SS+McQ$~>x@uNv-k&=Pig z&^8(SQp9z7aWNXNm*Vr*q74j|tTN!mz~m^QcLAJ2gX;Tqo>-P8e zAtLT^A9)n*?GHD>7FmcbdcGq6wV2O&YmA|A>Z8Q$`EwPKV`-4$g~My@m&LkJ1R*%L z)7YR*{UECJiBzeh(3O_J9?GXl`!rpb+Fhxhf#^L0>l1Efv);*HnCv0)elRKlURDz zwY9A+^|gq*!)W}U_4te2dEiHi~{ij!Ce^?&vobv#Rf(2N=pwU;U#8WpHg!_78jwwfzxJH77!eC-j~XcI~$GH zy9{6KD->e;FkSDD7l=mT9Tx@!W88;(pbYr^6m+j3+ZDj+y5G0&P_S zY0}VFhLFQR@90Jb2-!dc*js3tbQ{JU^f|w(0sCi?jR13B&Y5OVL;&8>a=i_v_infQjmPr)zvLr?~HwTc`6&Uu|0Oz+c>?J2g(tKI;gE)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L0Ei|40Ei|5tdX4t00007bV*G`2iXGy z4g@*`4g7Jw3pR-Ju0`>9zEyOTA?a<1rJI9Q3#|7 zugD_=@|q+wnau3R@BT5&W*&Qo2}}}jYxCsWm(!7Dy|Oj0EMP$7OJWWfRqx;vc@noLLh`dQIr&dlpBUo=Jk33$j{Gb<;s;~ zm>MD2zkfe__wG$0$V9_1D$@&^rirfWV;CDo$?*An2q7|5*7ysT4N^+_`}=8YYa7Gd zFhO2k9#f`FK}wlHkbq@bf%FQ)WlMw*C@2U(Acz?zG0Q;poAEm_52~et0HH__Ad#Oq zf}|57nIK*vgyvK*U7T_OL8Fh8`Z>Cd5CbyCXKu)6c5MMkc8&fXiEPg&cFu>@?#DBb z7blS2u}?NZ6w9*IWFlCWl~V~3K#v)wVc-NEW)DItOr4&`ilt@bFnTp)pN1LoV1+cSum>xoqUf3}P4P=!69h@%Ih`QFNfO*BcsUTV zBK&KA15!#@PzYiP7qhAL=7e(u9VA#gc#CfSO1|45+Ly932wWq3~6Pl7VYQ4@sqzN9O;3<+&6umH({uGJQqmqF(4eOkrNSg;wcfPIe zMoOZxmXKs(|W0T@(5#SP}^6?3>@#!Xa~PGEZFr%)B>>~G^_@GrE5 zKIV9L1By@`-jy>9=3GLC9ES|IV|ppcc>7P?^t8jPKl{JTpFSUt>T&F+DGko_9_812 z|CaNilc(T@J(sEM9%F4J}s2N6+kFVa-BR zMRoO(Jc`ED;yG-%?PYHL)O{G1?pQ9=Yq0H4?M$}nxW9HSOFs2g=8XSb)(ny>oD7DS zVRw5Gg7jtvYuB>i^?&Rn;4kI(461l8}J=YyTs~c@_L)!~evq`t0YbN6>O) zfab$J-2eA~L(RmQ0JL-;=J5IVv!IBTQ?22ot_D?Ex%2bmu5L1?DvCRD4}Z`{q~GM{ z4?bcOBORhfg!lil8%_ARVb%h?9&ZX^R(yIDO&xn_?)=~)K~%xXV*^xHlu$EqrcFQu zDRbIas%mrY_U1z6T(%!01&2QjQCx9tm6Y^_bi|Z((*x&0)&zT}lfngNc)6Syy}|T*kyF{d?l0sDg%l zeRTJP`QMK`;c5h5`0!C8Mwq;O!R>dKaPUYIcmDX^3+S zT<7T0Uh%cJC9n0N} zp~xUnI&`$f&||RT=D%`{CEhvlPpHBZuYaM536p)CJQn4hkN%ZKb8bo*N3nlAO*>0y zI(CZfzj&Gcug91(C6yonUkRV9TF!tGK{q3`hg<3BKjSDxxsF3d$IHqRy4rPwfCV$> zxt3|}`~X#?y1yl5@#O#qjx{(Y4d+$Or{OOjGpS@UB~!{X+APbT$f^Z@8&B*?i~o1x zWnMY-^wniUh9eJ@`f{0Zg?de-lvGtrbZzH!PcuR&DfJ2hDpE?$cD6g#nLG6}Sp{~2 zct$}>C=Zpab#DPl{rW6X4DapswbZQ2uCB%5;C)z zul-FW6YrZvSy2&3{^3xn8{Kz`e?IsOn&P9tS4c=;J`go2fG5v%M!aMB z-hiuwxPjNJ5bk$ghwN4JE~X5GbN56x8RF5*_9kMHT&!G-<3Xf-cOZy4c=W8BQCHIX zd@5S|V4($t9tCo%G&9y2YWIkl1XABKP4m#f+8&qW}7`laNnHgDOP4Qin zge%BL|%& zs5qFe`~nq4QRwOkQe8gPQDq6~5VT3+sgZnV8`B%@j_=qK0=J1lC5x1v%<&ZNkdliz zoevS&ISl^%xVzfg**1tB@n#xrBmR!UynqWqI+Nm4aYafi*Dz|itZblgT$~`sTU%Vq zR2R?UNXJJhDfn@+}8SU78e<2X(Ro8kmi1j1ppi>BtG$mABC`!^D4lR<4r zG6hFsp`6zzm@>`B!K2L_J=>hoVJRgO3ahCsoSK60^Q|!~%c8FKa~T6}2_EKr=v3UT zRs^wVW&(0TK^3|cMK^R#pYEeK=$sRimdxowxvV9`Egrd|RVV2La+r`a4Op-!fJfE% zyZ`gJD@WZj^)5`yL{SC3L4%{sy)3;ZybFg<$Y6Y@<75r?R;%eTPaW+`L}!>ZND+^_J%xZPdFh zf8hBKAI-*5%$eJpRr)=b`$LB84w{mhxqb!)iuo^_{yPP}0RQf``(1;&WW*Yl&X(qX zVB7KE#cfB*m?Sf1`+_jh?c>oGALqAk{0q;ndy0vrlU(cVZ+)BBo1f)us3n6K$?XaSrc@OI zl9SO=!*t1 zq>eGjDwS+>Yx;y%wBNumaz_xuFc=sZ$T+pnQNClb7_nF^XEr3+?M>|K8|pQ&%7@ph z@Xr_A)^v^@UoeHgyY;vH*CoH>&QGt#uwp}dN5(3BaWNiKpsy`=#29iMVwz@7_lM*v zKY7dT#k6jV{RL-90j+Q zC7D$1qxQ2U{Ey9>cx(UmtnJtpF@k`@FZQB%bBmYD^0KZbNJzxzmlQE~L4a>OwwjlB zy+nKOc|rrd=w_6t5h0?7>5uhtrJRsprW0@X6APLnHcpRw{z>E}cavidwk%k9OMrO` z3;2EWWBmE_MoI%E_(iNAoM3*wxRGe+dms4$BR{9I6$bsaSckz)AHn6x=w5tvfad)A<@#h~YmLHM*mEG#j?7O{Sb z8HumqN~kDL-st-?S=*3YifDe9LZsN@ve%v`bG$CGViHrA#QG({(>lG!47xtn=|5@4 z!#SJdMN0IjTxGhzjp;o@rQlFu+<6s`F6gZ=5mIEu@j?+uB)#WNLLVnM-Xzv%*&J{5 zOM9u65a98N9ORluA6%1*xm$Gt1>Nzp+(Ts+$$Kg-Bd*^qU7`<2dRmP*$Dh;*x0qn! zs^b-vYaX&*DCcHyu7oIs-72asX#Y!$aGOc^lu5MDLJvvwu!SC$aa*IrIbQXMPom3_ zp|Y~}vU2U}Ndf+l%AsF}KCv913&TFLafkp#6O4g-q^^vi<{B{SIkzEWaAj_<$a0Gp zfU2r!nucXr_H=J9H(Fk8UQjOU4Joak@Tb7k_h}&TO zb?cYMWpgL{St93JS=}%X6K}AF`K~sPz5s zf1g#WR@oh|udiqI>eX!By45ag7zRK8`OjIiW(@}p9N>;S?%%>V!}fg=y2K4O(vQ+_`Mnuz`mjdT7Y@!RPbg^Z72%%er_1w6K35Y|flHeD8bT zOL@_`bLa5+d`y`##jf}C(@)db*vQ(oYneAMelpxW_uRw&{rhQYX-Vni&Ye4nMxz`& zcyLq+5{*WA=%I(W`R1E>;DHBR%N;*{oF|`rk^=`0Tvp)c^Z76g!+8PvP$a}K3^r}r zlyU#uxpPPQe@7q?prD|@of|zKs;jG6xpF1V&CTTJ=i~Qh?veNT ze0aTHwrttL@#Dt_l{QsXDJ(2x+_-TR78cqnSqS0Sc2-6``C7DS5fdg%$VfQ0wY4FH zprWFJ7himlH{X1d2OfBUy1KdyU0PC7!rZxYX>M+&q@;wWo_fkA#J9iwZAUwD@4ffp z@p$O!>f)#n{E+S*zy%R*IEHf-3yAOHAAn^>x<+K$6zNk~G+Cs&kG(%RZeb#*m6cI;sL_U+tv z-+e4zyf|}vz=e9VXU8|hba!{NYSk+8^YiKK>~#IT-RkOUmMmGq^5x5U@WBUJzI-`n z&Ya<{yY9l{@wj>|YuB#jw%cxFMj|^JW0n zty{;^rAt}2Ze50?J^b*))YsQjTwKiAv(9UaXV0F^^Ups|QBe^qR;-}5ww7hfmf0#U zfrm>uF_-kRCQO)+@jMs|(%09=z`y{TH*aRyvSr+L*Ik49*Ciz-HquH2=u1q)cbcrkzY!ynkPWeYx^&sH%- zMMaJTtgfyG;N;1ZgQ}vbQ>S8@reirNB|rGV4{Y_^+1W{9VIf^zU7R>^A{F6^GITF1 zx!|~Q<1(HfI&>($(Xy_NXf!(Lg6sq&bh&Ao)YiuL10FnhFoPfoL{FSJk(QPgPMkPl zI~P?|RRFZNw`U$QqwBWg@ys*NP*_+aM+S=OKuwerY4Gnlao{ZRH`t<2EHa4Q`y8W*7G6^ZFudmNw zAj2?NzI-_VFTL~gvKY%?!jQ5D%oNw9?X2#*G_CLqmgOHX*?bXU?2q*REZ3bac?r z&_FO4#N+W~5JO7I#EJ1Ug7@s%lkq&cKZ_PE0$}&<-5CTiO_LcjW&m*F#EDCKfysLt zFDp{7udh#OC=!Vf4u|c*+;r1T1OfrxdFLGr!*JZYmmp$7|L5oD)7skVih%j^=L4ju zk;#)M+Xx?Qphu1z;kDOZuz=Rq zR>#%+s;b(-?U%mvB|C4WX&S1krbtBM*(&Hf-3T&i(j-(>rL8UXRG@@GcOyu9 zdpplP_Z;8)*0*^4@y9uH<_zWK<;B0JWOAaS*dEwVfBI7l!{GJTUuWmeohj;T z%9JVid_GQ}KJ6O!yz#~xeB&G6V9lB}%$PBQNF>6-g$r4~em%Q(?Xul;UDs`u=0*?| zxIxpj>b$(X+C)dEO`FERzyLix@!zoxhr@Jsc2ZYYM`>v(U--fom^Evboni-AxNsqL zb#(*+0XuIarR4eNpQo|0(Joh1R7782ANBS1^!D~Ne)TK%?%iukiLUD@QmSbhrKP0= zgF(8xyDzo{Jm~lPzffFUyfQ)YFMjch1cSj8pW84D?!NnO)~{cmb<*xPzxfS2cI>b_ zC8fkL3{2BZQ4z^$Y|}JtPD-w)>$)9zJEg~y_e3UgMnVXi+uhRbu~^KueTh^}a{HEL z5sSrA`s0>C+tzp=DXLwzl%*lTXsw*_lx$kv?$Uu%akJwY5x|G>M9e3PPa}?d|OxJ9dm? z$BsF=nS;&LIsLuV45M4SL%n~w)&CRywl=CyTJ^>3DE`^UF zP2py{E^CYcS5CMgXM4wBc%^8_amW~qEK$ZJWK2TFU`#@;Ay3RzLdK07$E;bi#xOTb zkeE4iR9Wc(k5jH_3~~#WWf6@=GZqqh085CA`(zEnVB5BBV;CEySi}S9KrCIH#$c3G z84wmi42*eHqYqNXcNQ-NCTf~iA*J+iE$$`0cEA)u#DHE!Q94vrJ*R0}P}8)C$Kx>o a`Tqg>kV~MzPkuE30000-qlv@1E0{=FH5CnOoQO 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/animation/animatedtiles/images/tile.png b/examples/widgets/animation/animatedtiles/images/tile.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f39d8d409c0033bd50b6471138af3c0f1f7c89 GIT binary patch literal 16337 zcmWlg1ymbb6h&!~;suJk1gE&WySr1|p}0dSR@|X@ad-FPRtS)y!JXpn@aM0r5Sf+C z%p>#ezUQ15sj4i4hD?YI0|SF5Co8EAJgWYGM??Vr#$jGo0}t=q)MdnBYNm(}ffop7 z3Nn%~Z~xzZb(bas?;w4Z)pLV^K_C48{w|dfod|gIgS(uP)Q2TlSafbgigE-_7#MOG zIY}{1@8#?++n*pEpZzC+`n_De3_XK|SuLaP3Ou>b&A0RDSXlTmj$ix<9H@x?)FFcL zq2?mFyKB~6F&Ex`T`@x3!?*Yd=0vEA-{AEzu~ucv4E_bEX)W~Z;6C}DMpXT&K^S(+ z%OdM&%;k02iv2`OId%5(wvK(~yU}uGX9n4o(SB+;rV80fT^WU)khYBWJ z<{2n2kEzPis0)mmeBMo*Kv9z(OMmEZu|G*PQ7rCejd2 z2dI^+Ym(dkRDD}pTT??r!}C$^>k*Gtqn>g$Z{Oo1e~V)wDjHhi#4d(7D<5BEi7g_< z=>FC7X#6uGaNwGiS|ueVi}mIohRhPx%R_69Vq#<8VT4nB6g-DnFbNVWv1RAt8rs+( zhqgMG8rPa<(mdUr$sh)wJsq$2_VzkDIK-%z5B3B+0bdFnyyxkPT)wKPmX@}TPW#I( zls;9y$X1>vIbV|j6YgC{4OQqbm1w(AOGlQ|50Eh}n>A@jnzF&#GWj4p}}H@d7M3gdfUpO{n6gVpfx@M5Qzv)2kb znK0A4qLddHftc@v}r;Xm;-NRcl#O9IhFxlUfR-kMZv`AAojpNhm8G(>-$wEHz>R%MK;iqUWpGftHMdoSgHKvjigI3TOzkIi;0XMu3QRfx3sX>d5pm8*ZkvZrZ3;EpplbOxJ96x4&d-xpjf=U_ z>?BFOurf>NOKd4afAel|e61XASs`U+$&)Hdn3}IMo}w}z-E~zfg<#rdH&7Tj2pqH8 z9ZNto_U4%}yf|0PwVvV8Agqb%R7ovV z_9ZmtCesJ>(AP~su{g+fxkIrFW8)0-SC;)az@_nyE~`Y21Mz1E(I2ralCUh*K=<|9 zuLE%ck(S@~AK=8krC_b!U4(p7?O0KJa5;s(DhKZNvAA6Ad{iYm5*`d8Czr$OXC1r? zC;%1J<6g!cy^`=bhu^I~XLar8=20X#^#){?7~IDCxIaZKRg3(IU%gaV>D^|NoS{YZ z_g|-tGcVxncQYygS#{NA6&9ZDd?*bJes|`1+PgW~CP%b>6iehGc3b$-BV*w}m$&OJ&jvE^}MA;(0jAv(_w3F;^E?9Pf`d)-%5jK|vA^b4op$hCxbq6Bv6%WD$o@XWr#2f@`N*W{7NsjN3x z-zhZ7c;u=U{Rq26a1?2%AYZ>|LL-**8ZdSt>}*z$ifuFxtdV`vsM8AK7cJsGSbXCY2V@F(W9 zV0$rzLn72=Iv$4{QNn*+LJj*;DyLh5$Lv9gT^>mZf3?N*jybvj5e!U{ssyZZ?@8$4 zWy8Wd6|qWR-leE-JqVj(n;j6kO-$g+Q**RSf1e>h}{$wzMU-n&R*hOqR$ z%5>dL*Sa=beKd4c!H9+#aZ%N37V)k*N+M)c*SR0g*uQ^}c_Rxv$|AGychBaObIG10 zXy!vHN

xUdsGJBJwu8zN1n5LYQ`@I8FhqTec#4J+k*14AA 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

$X42+zdA=Ial;=4HI+cL1w?xFy?oa28Z) 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%0D6n<2k3-2LA6Av9Zn+fdKaQ6H6wi9tjL}3 z_BFHK-rk$dSR!wAnl=RB+k`d(yl%O7*@-pxwqN<^bv093+EgVir85b)rlws=aulQey_sR~0 zKkslD`o}#H$%wxy^LPXSx6C|DfN=pu6=L5o)T0SDdMN7N_~D@6HS5Ht)l|`%_wL<$ zH-KLq>yD7HykOjF8wm{p2pkEIhXJgRW%-|cKHv6KDz(t#^}gJ3`ql5xKIQDM2`&Z< zLsR0BaQEIF8+UK~&6A_5n)X3geTESX2;EyHxK>4>6J$cKmzmz+mW=5 zcbd!XHM8yeUAyWqltY&qPx>24DM?q8GG%XBqn2k=?lCRx z860B^-ObA$-P!dzB!&k&red1_9cqxcOzFg>-aahYTTiYZn|0x`S2%_aH{RGi$(DwI1=E-ioWtNkH|R*^hME!Ew(Y2fw|ec~y`RkM?CjhQ z;7o%4j{w#!21|{DMPrbA6YMOy^Le-1-R$*xRce{b<#LmO$Qto@e7~Y7YXSUP2+>_Y zyqpJ=2nmf4At;0zx_&(^Prq~M z&>{b(O`FE)+Ft?4651wwr#8V0lZ4%bPC|;1u_i??N4j(f9RGbXA>i?NzD*vmoWfw` zsi&U0o|2=RT$53PEgs self.orig.size().width(): + self.p = self.orig.scaled(rect.size().toSize()) + else: + self.p = QtGui.QPixmap(self.orig) + + +def createStates(objects, selectedRect, parent): + for obj in objects: + state = QtCore.QState(parent) + state.assignProperty(obj, 'geometry', selectedRect) + parent.addTransition(obj.clicked, state) + + +def createAnimations(objects, machine): + for obj in objects: + animation = QtCore.QPropertyAnimation(obj, b'geometry', obj) + machine.addDefaultAnimation(animation) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + p1 = Pixmap(QtGui.QPixmap(':/digikam.png')) + p2 = Pixmap(QtGui.QPixmap(':/akregator.png')) + p3 = Pixmap(QtGui.QPixmap(':/accessories-dictionary.png')) + p4 = Pixmap(QtGui.QPixmap(':/k3b.png')) + + p1.setGeometry(QtCore.QRectF(0.0, 0.0, 64.0, 64.0)) + p2.setGeometry(QtCore.QRectF(236.0, 0.0, 64.0, 64.0)) + p3.setGeometry(QtCore.QRectF(236.0, 236.0, 64.0, 64.0)) + p4.setGeometry(QtCore.QRectF(0.0, 236.0, 64.0, 64.0)) + + scene = QtWidgets.QGraphicsScene(0, 0, 300, 300) + scene.setBackgroundBrush(QtCore.Qt.white) + scene.addItem(p1) + scene.addItem(p2) + scene.addItem(p3) + scene.addItem(p4) + + window = QtWidgets.QGraphicsView(scene) + window.setFrameStyle(0) + window.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) + window.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + window.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) + + machine = QtCore.QStateMachine() + machine.setGlobalRestorePolicy(QtCore.QStateMachine.RestoreProperties) + + group = QtCore.QState(machine) + selectedRect = QtCore.QRect(86, 86, 128, 128) + + idleState = QtCore.QState(group) + group.setInitialState(idleState) + + objects = [p1, p2, p3, p4] + createStates(objects, selectedRect, group) + createAnimations(objects, machine) + + machine.setInitialState(group) + machine.start() + + window.resize(300, 300) + window.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/animation/appchooser/appchooser.pyproject b/examples/widgets/animation/appchooser/appchooser.pyproject new file mode 100644 index 0000000..14bc351 --- /dev/null +++ b/examples/widgets/animation/appchooser/appchooser.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["appchooser_rc.py", "appchooser.py", "appchooser.qrc"] +} diff --git a/examples/widgets/animation/appchooser/appchooser.qrc b/examples/widgets/animation/appchooser/appchooser.qrc new file mode 100644 index 0000000..28a3e1c --- /dev/null +++ b/examples/widgets/animation/appchooser/appchooser.qrc @@ -0,0 +1,8 @@ + + + accessories-dictionary.png + akregator.png + digikam.png + k3b.png + + diff --git a/examples/widgets/animation/appchooser/appchooser_rc.py b/examples/widgets/animation/appchooser/appchooser_rc.py new file mode 100644 index 0000000..c96fe80 --- /dev/null +++ b/examples/widgets/animation/appchooser/appchooser_rc.py @@ -0,0 +1,1424 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x13\x09\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x06\x00\x00\x00\xaaiq\xde\ +\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09pHYs\x00\x00\x1b\xaf\x00\x00\ +\x1b\xaf\x01^\x1a\x91\x1c\x00\x00\x00\x07tIME\x07\ +\xd7\x09\x17\x17\x15\x19I\x86pA\x00\x00\x12\x96ID\ +ATx\xda\xed[\x09t\x5c\xd5y\xfe\xee{\xb3k\ +\xb4Z\xb2%\xd9\x96dcl\x8316\xb6\x81\x00\xe1\ +\xb04\x14\xc2\xda\x94\x86\x04\xd2\x90Br ] \x14\ +h\x08KH\x09\x87\xda\xadsRR\x02$\xad{ \ +\xe4\xb0\x95\xcd@\xb0\x1bV/\x80\xb1-\xdb\xd8\xb2l\ +l\xd9\xb2,\xc9\x1aK\x1ai\xf6\xe5m\xf7\xf6\x7f3\ +\xef\xf0\xf4:\x9a\x19\x1b&=\xc9i~\x9dO\xf7\xbd\ +\xfb\xee\x9by\xdfw\xff\xe5\xbe+\x1b\x7f\xb4?\xda\xff\ +oc8\x0e\x1b\xbb\x05uR\xed\xf4\x8b]3\x97\x5c\ +\x06\xb7\xef<\xa1\xa4<\xd0\xb3\xc3B\xcd\x0cq5\x15\ +\x12J\x22\xc4S\xe3!\x91\x8d\x85\x84\xc0\x10\x80\x10\xe1\ +\xe8\xd4\x9fC\xf9\x83\x16@\xfc\xd8\x7f\x95h]v7\ +\xe7X\xc6\xd3Q\x99\x08Bp\x01\xe1\x0e\x12\xaa\xc0e\ +?\x84\xec\x81`n\x82\x0b\x90\x5c\x10\x82\x03\xdc\x00\xd7\ +\xd2\x02\xba2.\x0cmH\xe8jHhJH\xe8\xd9\ +\x10W\xd3$T|Hh\xd9\x900\x85\x12\x08M\x7f\ +\x0c\x99\xdf;\x01\xc4\x03\x9e?\xc7\xf9\xf7\xbf\x88\xe6E\ +\xcc$\x04\xae\x03&9C\x052\x11\x80\xc4\x80\x9a\xcc\ +C\xcf@h\x19\xf0l\x82\x90\x02W\x92\xe0\xa6P\xb2\ +\x0f\x5cH\x04S\x13N\xd0\xc1u-'\x14@\xd7\x0d\ +\x03$\x0aA\x8d\x0a\xae\x87\x08C\xc2\xa06\x07\x95\x04\ +3\xa1\x0c\x09n\x84\x00\x84:\x1eG\xf2\xffN\x80\xa7\ +.\xee\xc4\x99\xb7,\x85\xb0\xc8s#\x07\xc7\xb9(\xd6\ +\xa7\xe7\xa1\x98\xe2d\xed>\xd3\x84\x00W3\xa4\xa3B\ +\xc8\x82s\x0e\x03np\x12\xd6P29\x01\x0d\x12R\ +\xcf\xc4\x01\xba&\xcc\x1fn\x80<\x89\xa0'h`N\ +\x90\x1c\x04\x0f\x01<\xc4d\x98\xd8\xd9q)\xba\xd9\xc5\ +\x10\x95\x11\xe0\x85kSXxm ?\xf3F\x09\x01\ +\x9cb8\xc6\x8b\xdc5\x1b\xa2\xc8X\xf2\x1e@\x00\x14\ +N\x90\xdc\x80\xcbG\xf0\xe7\xcd\ +\xf4\x96\xd4\xa7\xe2H4\xc6c\x0b\x95\x0f?\xd9\x0b\xd4\ +\xd7\x00\xb3.\x85\xde4\x97\x9c\xec\x03\xe8C\xab\xc1\xb3\ +\x06\xd48\xae\xc8\x8c\x88U\xa2\x1b_c\x0bP\xd2$\ +\x945\x0e\x88\x89\x04x\x01\x81\xa2\xd7E1\x91\x8a|\ +\xd6\xb1~\xb6iZ\x1aH\x1c\x01\x0e\xbf\x0f\xd7\xbe5\ +\xa8Z\xba\x02\x9e\xe9\xcb\x00\x96\x1f\x0a\xce\xbe\xda\xf38\ +N\x00>\xaf\x00BLp\xdd\x223iyD\xd9\x87\ +\xe7\xe5\xbd\x80P\xfe\xb3\xedky\x11\x0e\xbc\x09\xac\xbd\ +\x13zf\x16RC\x02\xe9a\x015)\x98\xa1bI\ +%\x04(|8\xce\x8b\xccl1a\x8e\x918/\x15\ +Z\x93\x08\x13'\xf2\xe91\xe4\xec\x93\xd50\x12^\xa4\ +\x8f\x9a\xe4\xf3\xb7B\xc0_\x81\x1c \x0a\xc9\xd8\x84J\ +\x92q\x1e\x97\x0a%^F\x9cB\xf1l\xf2\xf6D1\ +\xdd,\xaf\xd6#\xc3\xb2\xcf-@\xa1\xdb\x15xA\xb1\ +\xd8u\x1e\x17\x0f\x95\xc2DY\xc6\xc3\xe2\x83D>\x8c\ +\x02\xe3\x1a\x84\xc5\xbcr\x02@\x14\xcd\xe86\x81\xe3M\ +\x88E\xae\x17\x92-\x1c\x1f\x1bp\x90w\x98\xa1C\xa0\ +\xd2\x02\x08A0\x8e=\xa3\x17\x86J\xf9$\xc8\x8f1\ +)\xc6K\x90'\x13\xa6\x07L\x9c\xb7\x0a\x09\xe0$[\ +\xbe\xd4\x95_\x03\x94\xff\xacB\x0f\x8b\xf5\x03\xa9Q\x94\ +4C\xb7\x89W8\x04,\x18\x05\x0fW\x9eL\x91k\ +(\xa8&\xc5E\x8d\x1d.O\x1e\xc8/\x93\xe1\x14\xa0\ +\x12e\xd0A\xb6\x10E26l\xa2\xb9~\x10\x98u\ +\x0en\x9d\x13`\xf7M\x9a\x10\xcb\xcf\xbc3\x09\x026\ +D%\x04@\xc9D5\xb9\x10\xb0\x88\xb1c$n\xc2\ +>\xb6\xbf'j\xce\xfc\x08\x8e\xd5\x04\xd7-\xe2\x16*\ +\xe4\x01eVz\x0e\x22\xc5\x88\x95\x12\xc3\xeas\x0a\x87\ +X_\x01\xf9\xb2f8\xca`%\x05(\x1f\xdbN!\ +\x9cd\x0a=\xc2&n\x0bdX\xe0@\x9c\xc8g\x88\ +\xbcT\xe4}\xb5t\x15p\xa0\xd2+\xc1\x828\xb7`\ +\x93\x13\xff\xdb\x0b,b\xc2\xe1\xe66Y\x82\xe38~\ +\x88\xc8\x0f\x03\xb25TX\xe0(g\xf6:\xc0\xf6\x82\ +\x0a\xaf\x04=U@\xfd\x09\xf9\xa7\xd1\xd3@&\x0c$\ +\x8f\x02Z\xd2\x99\xe8\xecX.\x14\x889\x12\xa3S\xa8\ +xo\x9e\xbcd==\xb3E\xb0\xfd\xbat\x15\xb0\xcb\ +`\xe5\xd6\x01\xb6\x08\xfe)\xc0\xdcK\xe14\x91\x17a\ +l/\x10\xfa(\xe7\xbe\x85\xeeO\x10\x13\xfa\x84\xc3\xe5\ +\xf3m\xe2\x90\x93\xbcM\xd6\xd9\xf2\x12\xcc\xac$X\xe9\ +u\x80#\xbb\x17\x1a\x03\x82-y\xb4_\x98\x17\xe0\xe0\ +k\xc0H\xa73\x1c\x18\x016y\xb3\xb5\xc9\x9b3\x7f\ +\xd4r\xfb2\x02\xc0\x1eSr\x1d \x08\x15M\x82\xb0\ +P\xcej:\x80\xd3n\x05\xce\xb8\x17\xa8\x9e>!\xce\ +\xed|`\x9f[\xe4\xb3\x16y\x09\xd4Z\x90\xca\x80\xa1\ +\xf8\xcb\x90\xa8d\x15\xc0$\x19\xdfP\xca\xaf2\xea\xe7\ +\x01\xe7,\x07:.s\x84\x84\x0d\x93\xfcA\x22\x1f\xb2\ +I\x95\x03+-\x820\xf4\xcaW\x01\x22j'\xaaH\ +\x0f\xb0\xeen@\xe8\xf9so5\x10l&\xb2'\x02\ +\xd3\x96\xd1y}\xc1v\x22N\xba\x01\xa8\x9b\x03\xec\x5c\ +\x09\x18\x9a\x95\x00\x09\x89\x03\x80b\x91\x17\x93\x00\x8eD\ +h\x1b\xb7\xa7\xad \x1c\xb8\xe6\x8c\x16Q\xe92\x88\x89\ +\xe5O\x07\xb2a\xc200\xba\x1d\xe8y\x16h\x5c\x04\ +\xcc\xfe3\xa0\xba\x1d\x0ek9\x17\xf0\x90X\x9d\x14\x16\ +\x9a\x0a${\xec\x99\x17%\x92\x9cp\x10v\x92f\x13\ + \x9c\x1e\x90\xfbU\xb1\x10`\x02\xce\x9a?Y\x19\xb3\ +\xb6\xbaG\xb6\x00\x9b\x7f\x00|\xb2\x8a\xba\xb2p\xd8\x94\ +\xc5\xc0\x92\xfb\x81t\x9fI\xbex\xcc\xdb\xfd\xc7\x17\x1a\ +\xa6\xd9e\x90P\xa9$\x08QX\xd7m\xf2\x85\xab>\ +S\x88\x815$\xc4\x1d@j\x10\x0ek:\x138\xf5\ +\xfb\x05d\xcb\x82M\x1a\xff\xce~\xf6;]\x09Z\x04\ +\xfd\x8d@\xfb\x05\x80\xbb*\x17oH\x0f\x01\xf1\x83\xc0\ +x\x17`\xa8\x13D\xa06u\x18\xd8J\x22,y\x10\ +\xa8\x99\x8bOm\xfe\xdf\x00\xa3\x1f\x00\x87\x9e\x01P&\ +\xfeQ\xc2\xf5%G\x9e\xc8\x83\xeb\xf6\xed\xa22\xeb\x00\ +\xe7\xcc\xfb\xea\x80\xd6\xb3`\xdbR\x02\xf2+\xc1\xa1w\ +\x80\xbe\xd5t\x1c\xb1\x17;Z\x14\xd8~\x17\x89\xf0\xcf\ +N\x11\xce|\x04\x18y\xd7\xac\xfd\xc5\xe3\x9f\x17\xf5O\ +'i\xc9>\x17\x10\x16\xf1\x8a\x87\x80\xed\xee\x93\x9a;\ +\x08\xb4_\x05\x9c\xf5S\xa0q\xa9\xf3\xe5f|+\xb0\ +\xfer@\x8b\xd9\xe3=\x0d\xa4\xddO\xca\xd7|f\xb7\ +6\x8a\x84\x06\x9b\xc4\xa1*#\x80s%X\xd2<\xf5\ +\xc0\xe2\xfb\x80\xb6+\xf2^\x90\xd8\x07(G\x80T\x0f\ +\xb0\xfdV8\xac\xfdZ\xa0\xe1\xb4\xcfP\xfbK\xc2\xb1\ +\x12\x14\xa2b\x02p\x0b\x02Pb@x\x170\xb2\x0d\ +H\x0eN\xf2-\x0c\x98\xfb]\xa0\xf1L ;h?\ +x\xffSt\xcf;\x13\x86Q\xe7)\xf7\x1dg\x22,\ +q\xcc\x9c\xc4\x05*\x97\x03\xec\xfa?\xbe\x17\xd8p\x1b\ +\x00\xdd\x0a\x09\xeb\x05\xa9\xe3J`\xc6\xc5\xce\xa5\xd9\xc2\ +\x1f\x11\xe1\xdf\x02\x91N\xfbAw\xdf\x05\x5c\xb8\xd5\x1e\ +\xd7Ja\x13l\x03\x92\xfd\xce\xd8g6\x0ac\xbd\x04\ +\x80\xcf\xb6'\xf8\xe0}7-\xdc\xf2\xf6O\xa5\xd2U\ +\x80\xc0U\xe7\x92\x18\x84L\x08\xd8\xfb\x18\xb0\xfd\x87\x80\ +\x91\x99\xf0\xc9n\xe0\x0b\xbf\x06\x5c.{\x16\xe3\xdb\x80\ +\xd1\x89^ \x03\xed\xdf,;\xf3N\x14\xef\x17\xec3\ +\xe6\x80\xb77\xf7\xae~k\xc3\xbe_\x90\x08\xach\x0e\ +(\xdc\xf3s.\x90\xc6:\x81\x0fo\xb4\xfa,\xab\x9e\ +\x0f\xb4]\xe7\x8c\xe3\xfe_\xc2a\xd3\xaf.A\xbaL\ +\xdc\xa3\xe0\xdc\x0e\x83\xe3\xc9\x01\xe3\x8a\x9e\xed\xdc58\ +\x7f\xc7\xee\xc1\x7f%\x11Jo\x89\x81;\x84\xb0wo\ +\xf7\x00\x87\x9f\x03\xf6\xac\x84\xc3\xe6\xdd\xe5$7\xba\x06\ +0\xd2\xf6\xf5\xda\xc5\x80\x7fj\x01\xe9\xe3$n\x0b \ +>\x83\x07$3\x19C\x81\xfb\xce\xd7\xdf\xec\xba\xe6P\ +\xff\xd8C\xc5\xdf\x06\x09\x81\x16\xe0\x8c\x1f\x03\x17=O\ +\xed\x0a 83O>=\x80\x9c\xed\xa5\x9a\xaf\xc5'\ +x\xc1\xc9@\xcd|\x9b\x94 \xf2\xd1\x0f\x9dIs\xca\ +\xd9\x85\xa4Q6\xde\x0b\xc93'q!\xb9\xe5c\x12\ + \x95\xc9\x1a)\xdd\xc8\x8eE\x92\xb7<\xbbz\xeb=\ +k_x\xf0\x9e\xc2?\x8d\xf1|\xe6^r'Po\ +\x12r\x01u\xd4\x9e\xbe\xc2v{\x86\xfc\xe2\xe7\xc8\xab\ +p\xd8\xd4\x8b\x9d3\x1b\xdb\x0c\x87\xd5.:\x0e\xa2e\ +D\x80\x05\xfa\xb5\xcbw\xfa/\x96?p\xeb\xeb\x8f=\ +\xfc\xc3\xef\xfc\xec'\xf7N/Z\x052\x8a\xa2'\xd2\ +\x19\xff\xf6M\x9b^Z\xbat\xe9k\xcf\xbc\xbc\xf9\xa1\ +\x0f\xff{\xe5\xc8\xd9\x97\xfc\xc3*G\x12\xac\x99\x0dT\ +\xb5\xc0a\xee\x1a\xe0\xe4\xef\x01\xdb\xbfo\xf7\x8dn\x00\ +:\xbe9\xc1\x0bNq\xbawf\x1f\x1cVu\xc2\xf1\ +\x91G\x89\xbe\x09%p\xe3\xa6.\xcf\x86\xa1\xfd\x977\ +\xd4\xd7^>sf\x8b\xf8\xea\xd5W\xec\x9a6m\xda\ +{UU5\xeb3Y\xf5\x83\x7f{\xe4\xe7\xa39\x01\ +\x14M\xe3\x14\x06~\x90q\xce\xffvgw\xff\xb9/\ +\xbd\xb1\xedq\xca\x07\xc38\xfc\xa4-\x80\x96)\xb2\xf9\ +q\x0a\x1c\x96\x19\x80\xc3|\xcd\xce\x87V\x87\xe00o\ +KY\x82\xe5\xc9;c\x9f\x83aj\x9d\xf7\xad\xdaT\ +\xed\x02&\xb9Z\x87G\xa2ll<\xb9\xa8\xb7oh\ +\x91,\xcb\xb7\xa9\xaa\xca\xe7\xcc\x99s{N\x00]\xd7\ +Y:\x9b\x0d\x80l\xc7\x8e\x1d\x83\x0b\x16,\xf8\xbb5\ +o\xef|\xbaeZ\xeds'\x9d0S\x0er\xc3\xda\ +\xc1\xe9\x07\xd2G\x81@3\x1c\x96<\x0c\xe7\x02\x5c\x86\ +\xc3\x5c\xb5\xce5\xbf\x91\x82\xc3\xe4*\x1c\x97\xb1\xc9\xfb\ +F\xb2>\xbc\x1f\xa9\xc3\xc1L-\x0egk0\x1eK\ +_\xa4\xebI\xc4b1(\xe4\xe5\x84}\xc4\xb5\x95s\ +^o\xf9\xe2,\xf3\x17\xb8\x10\x8c\xf2@\x10\x96uw\ +w?c\x18\xc6\xd3\xff\xf9\xf4\xba\xc0k\x91\xb9rZ\ +x\x00n\xfd\xe3\xc8\xf5\xb7\xe5W\x83\xb0,;\x0a\xec\ +|\xc8I\xb0\xaa\x03\x0e\xd3\xe3p\xee\xef{P`\xf6\ +\xfd\xc7e\xe3Y7~\xb5\xb7\x19\xd7\xbf\xbd\x00\xcb\xfb\ +\xcf\xc5{\xb1\x99\xd8\xdc\xaf\xe0\xc0\xde.\xd4%\xbaQ\ +\xa7\xf4?ZSSs\xe1\xca\x95+g\x90\x00Kg\ +\xcf\x9e\xdd#I\x12\xacoz\xcb\x05\xb2\x80\xcf\xd3\x94\ +U\x95FL0\x12\xe0&U5N^\xfe\xd8\xda\xd3\ +<\xb7\x5c\x86\xcb\x9b\xfa\xe03_{\x93}$\xf5&\ +`\xee\xd7\xf3\x1a\xf6<\x01\xa8$\x82<\xe1\xe1[.\ +\x83\xc3R\xbd6yF\x90\xeb\xe10m\x1c\x10\xc7!\ +\x82\x99\xe0F\xaa\xf0\xec\xee\xa9\xd8\x12\x9e\x06M\xd7\x10\ +\x8f\x8fCD\xdf\xc3\xe5s\x0d\xccY\xe4\xc3\x89\xb3\xda\ +\xe0\xadm\xa6<}A_\xfb\x95\xf7\x0c\x03\x10\x0f?\ +\xfc0#[,D.k_Mx\xc3u\xcf\xdf_\ +\x83\xc7\xd6\xeelJ\xa6\xd5\x16\xcb-8\x01\x07\x0f\x1e\ +L\xb7\xb5\xb5}%\x1aIl]\xf1\xcb\xdf6\xc97\ +~\x11\x97d\x87\xe0\x96\x00\x16\xeb\x07\xdb\xfe/\x80y\ +,\xe3\xd3\xedl\xc6\xac\x87\xdf\xf9\x03\xe0\xc0\xa3f\xc9\ +\xcc#\xfc.\xc0'\xb8\xafo\x0e\x1c\xa6Z\x028E\ +\x98\xb4o\xf3`\x10\xab\xb65c\xd3a/\xa2\xd1\x08\ +b\x91\x8f\xf1\xa59\x0a~t\x9e\x84\xf3\x17\xce\x04\xab\ +\x9b\x87=\x83@d\xe8\x10\xa2\x07;\x11\xee\xddy\xf0\ +\x9dp\xf3\x01\x00|\xc5\x8a\x15\xcb\xc8\x1b<$\xc0\xeb\ +\x00r\xa5\xca\xd5\xd8X#e\x15\xad\xdf\xd05\x0e\xa0\ +\x86\x90&h\x041\xbb\xbf\xffp\xf4\x84\xa6\xeb\x87\x8e\ +\x8c\xacY\xf1\xe4&\x96\xb9\xfaj\x9co\xbc\x08\x8f\xac\ +A\x96\xcdJH\xa0V\xa6\x96Y\xe7\x8c\x13\xc2]`\ +\x11\x82\x9c\xaf\x9c)]\xc6\xa1\xb1\x00\x8e\xc4<\x18\x8a\ +z\x10z\xf5\xbf\x10\xd3\xd7!\xcd\xa6#e\xd4\x01$\ +l-\xef@\x8d\xcf\xc0\xd4j\x0ds\x9b2X6#\ +\x85)~\x1d\xa6\x0d'\xdc\xd8p\xb0\x1a/uM\xc1\ +\xc7\x83\x12\xc2\xe10\x22\xe3\xe3\xf8\x8b\xa5\xc0\x037\x07\ +p\xe2\xbc/\xe4\x12\xb1\x88\x1d\x811\xb4\x1d\x91}1\ +\xa4\x14\x91O7n\xb75E`---\x17\x9b\xf9\ +\x80\xecyX\xe6\xba\xfd\xdeU\x1c^\xff\x12\xa8Y\x93\ +\xfc\x14B\x15!F\xc8\x10\xf8\x99\xd3G\xd7m<\x5c\ +\xf7`o\xdf\x91\xfb\x1f~IB\xf4O\xaf\xc22u\ +5<.\x1d.W\x9e\xbc\xcb\x12\x81\x13\xdbP\xda\x8b\ +\xc1\xb8\x17\xfdQ\x1f\x8e$\x83\xd8?\xecBoHC\ +:\x93E6\x9b\x85\xaaf D\x1a>_\x06\x81\xc0\ +(\x82\xf2\x18\xd4\ +7\xf0\x97O\xbc\xc9\xb0\xff\xa4\xf35ytK\xca`\ +\xae\xa0\xaf\xaa\xc6\xe5\xae\x9e\x82\x81\xa8\x84\x811\x8eh\ +<\x8dT*\x83D2\x8d\x804\x88\x93Zu\x5c\xbb\ +T\xc2\xbc\x19@[\xb3\x84\xf6\xd6 \x9a\xbf\xf4\x22$\ +3Q\xbaH\xf3\x9d7\x83\x99\x9b&\xba\x02(I0\ +5\x85\xa7\xd6\xeb\xb8\xf1?R\x18\x19\xe1\x85\xc9\x9e\x01\ +\xabo\x0b\xe0\xbc+\xbe\x05\xe1i\x82H\x0eC\xdb\xf7\ +\x12\x90I\x12a\x19\x0c\xc8\x91\xe7\xd6\x96\x92\x90h\xa6\ +\x00\xf6\xca+\xaf\xdc\x10\x08\x04fG\xa3\xd1U ^\ +\xc5\x0a\x8a\x8b\x10$4\x10\xbc\x84ds\x10\x89\xf3\xe7\ +\x815\x04Q\xfb\x9b\xfd\x0dw)\xdc\xfd\xdd\xd6\xd6V\ +\xf4\xf7\xf7\xa1*\xe0\x0574\x84\x86#0\x0c\x8ei\ +\xb5\x14\x87\xf3%\x9c;\x8f\xe1\x82\xa5Mh\x9f=\x8b\ +*\x5c\x13\x98\xbf\x01\xcc[\x0b\xe6\x0e\x82A\x03\xb8\x92\ +\x033\xb2\x10j\x14,=\x08\xa4\x87s\xdb\xecL\xcb\ +\xe2\xd0Q\x81\xb3\x97\xd7b$\x1c\x01Yn\xc6;\x1a\ +%\xec\x09\x01\xa7\xb5\x09|\xf0\xb3\x0b \xd1\xeb7O\ +G\xa0\xedy\x06\x22\x9b\xb47\xaau\x81M\x078\x14\ +\x8d\x83\x09\xae'\x1b\x16/|\xba\xa7N'\xf2[>\ +\xfa\xe8#\xcf\xc0\xc0\xc0\xa9\x00z\x8b\xed\x07\xe8\x848\ +A\xb5D\xa8\x1dN\x22\xf0z\x17\xa2'5#|\xde\ +\xac\xc8\x9d\xef\xf65\xb3\xde\xde\xde\x9b\xcdX\x22o\xb4\ +f\x85\xe1\x9c9\xae\xc8\xbd_\x9f\xe5\x9f\xb5\xe8Bo\ +\xb0u!s\xfb\x82H\x0b\x05\xc4\x90\xa0\x101\x82\xaa\ +\xd0a\x14<\xd9\x9f\xdb,\x91\x94\x10$=\x01\x99\x09\ +\xc8B@\x12f\xcb\xd0=\x5c\x0d\x0e97\xdb7\x9e\ +\x03|\xeblPh\x00\x7f\xfdB-f4$\x10\x97\ +\xdb\xe0J+H\xedZ\x0d\x91\xce\xd0}f\xfc\x09\x08\ +\x9d#\x95\x11T\x1a\x01\xb3'e\xf8\x1eyd}\xba\ +\xbauz\xfd\xbf\xf7\xf4\xf4\xd4\x11\xf9\x1bL\xf2\xe56\ +D\xb8\x15\xff#\x04E\x00\x8d)\x15S;\xfb\x11\xdb\ +\xd6/\xc6[\x1b\x95\xefi\x9a6\x04\xe0\xdb\x846\x02\ +\xbcn\xb9w\xd9\x895\xf7\xb6_\xf9\xe8u5SZ\ +\xdaT%-\xa53\x09\xb7\xa6\xa6]Jr\x14\xa3\xfd\ +\xbd\x99p\xff\xc7n#\xbe\xbfZ6\xe2\xbe\x80WT\ +y=\xc2\x13\xf0\x08)\xe0a\xb9\xca\xe2\x22\xb8\x19\xc0\ +\x0d\xe0\xdd\x819H$\xba0\xb3\x1e[\x82n\xecy\ +m\x07j=.Q'\x04?\xefp\x18\xfa\xc7=\x11\ +\xc9\x88\xbf*\xf3x\x04\x01\xb7\xcc\xdf\xf6T*\xb5\xd0\xe3\ +\xf5\xbe\xdcq\xfa\xd5\xef\xcf>\xe5\xec\xaf\x09.\x06\x0c\ +CS\xe2\x91p\xf7\xde\x1d\x1bwo\xfc\xcd\x93\xa3\xaa\ +\x9a\xf6AW}\x86\x11\x0c\x08\xdd[%\xb8VE\xa1\ +\x13dB\xaf\x97\x99\xde\xe0\x96\x8c\xdaj\x9fA-\x0f\ +\xc6\xa4\x99\xf3;\xfb\xa4*UQ\xe2\x0b\xe6\xe0\x0e\x83\ +#\xab\xab\xf0eT\xe1\xf3\xbb\xb8\xa7\xfb\x88\xb1d\xcd\ +;\x9d\xcf\xca.\xd6\x00x\x83\x0c\xc2\xc7`\xb8\x05\x87\ +\x94H\xc3\x08\xa7\xb8r$*\xbc\x9ag\xda\x17;\xe6\ +\xcc\x98\xd1\xd5\xd5\x95\x08\x85B\xf7\x00x\xf4\xb3l\x89\ +\x19\x84\x84%\xc2\x14\x0b3\x08\x11\xc30\xc6\x1a\x1a\x1a\ +\xb6d2\x99\x85\xfe@p\xd7Wn\xbcw\x9a\xcb\xed\ +5\xb3\xed\xfb]\xbb\xf7\xbc\xb1\xa3sk\x94C\x97\x1a\ +O\xfa2\xe3\x5ce\xa4\x89\xc4\xf5,3\xd4\xb4\xa4+\ +)IW\x932eoY\xa3\x96gS\xee1-\xed\ +\x19\x1cc\x0b\xdd\xcd\xcb\x1e\xdd\xd9\xf5:$\x86\x07;\ +\xa6b\x9b\x00\x1dj\x90\xb8L\xe9\xc4\xa5\xde>,\xd8\ +[O\xae\x1f\x9bu\xe1\xb2Y\xcf\xb74\xf8\xd3\xe3\xb1\ +\xd4\xb4\xd1h\xfa\x84pL\x9foH\xfe\x99\x9e@]\ +\xa3\xab\xc6\x1f\x8c\x86\xc3\xea\xce\xee\xf7^\xd6u}9\ +\x80]\x04\xed\xf3\xfc\xaf1f\x89UK\x98j\x95\xca\ +$\xd5\xd5\x9b\xa8&\xdf\xd6\xdc\xdc\xfc\x0dz\x87P\xd2\ +\xe9t\xe2\x8d7\xde\xd8=\xc9\x96\x86\x80\x05\xd3\x98\x10\ +\x9c\xc3\xe0B7\xe8H\xe5\x86\x9a\x11\xdb\xb6\xed\xa8\x86\ +\xb7z\xed\xde\xbd\x9f\xcc\xeb\xec\xec\xdc\x0e\xe0L\x82\xfe\ +\x8f\x00\xd6-\x06K\x8d\x83Ec\x90{\x13\xec,\xba\ +\xf3y\xb7\xdb\xdd\xec\xf5zUj\x99\xcb\xe5r\x93\x81\ +\xc8\x1a\xf1x|\xbf\xa2(k\x01\xfcZ\x08\xd1]@\ +\xbc\x9c\x07\x94\x08\x09\x8d\x10!(\x84&\xc2\x14UU\ +\xe3\xe6\xba\x9a\xda\xa6\x97\xc9\xc8+8\x00\x97S\x00\xe7\ +\x9f=\x18c\x1c\x8cA\xa2\x1fx\xdc\x02\xf0\xf1w7\ +|\xd4\xee\xf7W=\x91\x88\xc6\xe6m\xdb\xb6m\x14\xc0\ +5\xd6x\x99\x04\x90\xf01d\xab*\xd5\xe4wTp\ +\x0b\xe5\xa1\xb3\x08\xb5\xd6s\x85\x09\xfb\x09\xa6p}\xd6\ +bNTfW\xb80$\x92\xd6\x97fi\xc67\x92\ +\x00J\x22\x918\xe3\xc0\x81\x03\xafQy\xe4t.\x13\ +I\x13\x92U!r\xe4\xf3\x13/\x0c\xab\x95H,\xb1\ +n\xdd\xba6\xba~=-O\xbfs\xe8\xd0!\xff\xa6\ +M\x9b\xc6\xe9\xda_\x01\xc8\x12\xda&|\xa76\xc1\x0b\ +\x93\x84\xdd\x84NB\x8a\x90\xb1&E/G\xbat\x08\ +\x1c\xff}2!\xe0\xf1x\xbeM\x1e\xb0\x9c\xc2`\xe5\ +\xa9\xa7\x9e\xba\x9e\x92\xa3\x9b\x5c\x93Q\x82\xe4\xe4\x9a:\ +\x09\xa2r\xce\x0d\x1a#(_\xc8\xe3\xe3\xe33\xfc~\ +\xff)4\xe6\x22j\x97Q\x82b\x94\xa1\x0d\xea\xff\x10\ +\xc0*\xc2Q\x8bP\xc2*\xc9\xb1\x1cQ'AnA\ +\xe0s\x1a\xab\xc0\xfd&\xaec\x8c=L\xa4j\xab\xaa\ +\xaa\x86\x89X\x8a\xda\x0c\x09 \x12\x0c\xa0\x90\xa8\x9e~\xc4\x0dM\ +a\x1d\x1c(f\xc3\xfd\xe5\xcb\x97\xf1\x07\x98\x13\xfb\xbc\ +\x0e\xad\xba\x1cN\xf4\x1f===\xff\xda\xbf\x7f\xff\x89\ +\x9838b\x00v\xec\xd8\xb1\xf4\xe6\xcd\x9b_\xc5m\ +\xcb\xe2\xc5\x8bo\xd6\xd6\xd6\xd6\x04\xa1\x8bz{{[\ +\xcf\x9f?\xdf\xc8&\xa8$\x92\x84Q\x18\xc0c\xf3\x8c\ +m\xbfz\xf5\xca\xae'wi\xa4\xce8D\xd2\x99\xcf\ +\x18L\x0c\x1b\x0e\x01-hQ\x0bx?c\xd8\xe7\x90\ +z\x8a\xe8\x82\xf9\x00>~\x22\xdb;\xe8\xeeloo\ +\xff&\xf6\xfd2\xe6\xdc\x1e\x12\x80\xdd\xbbw\xa3\x8b\xbf\ +{\xf8\xf0\xe1_\x8e\x1f?>;\xd4\x88\x97\x0d7\x10\ +\x08\xe1y\x06\x91\x1e\x1b\xdb\xdfxFBt\x1bk\xe0\ +\xd0d\x9e=`\x8c{\xae\xf9n\xf3=\xaf\xac\xeb\x95\ +\x0e\x00y\xe7\x19\x1a\x09\x08\x00\xc5\xfa8O\xfcH\xe6\ +gB\x1b\xae\x1f=z\xf4\x937\x00\xd8\xb5kWM\ +\xd8\xd0\xd7\xa1\xaa\xebb\x92L\xb2\x10\x1d\xc6\xd8\x14\xbb\ +\x858\x09\x18\x16\x006\x869\x1b\xce\x0b-\x810\xc6\ +\xed#\x01\x80.\x93y\x10X\xcb\x88\xe0\xef\x87\x0f\x1f\ +f\x1f\x98V\x08\xdc\xd3\xfb\xc3$\xebo\xdf\xbe\xdd[\ +\xf4\x85\x9d;w\xb6D8\xfa6T\xb9\x96\xd0\x93'\ +\x02d\x91\x18\xe3a\xf3i\xee\xdc\xb9)^\x06\x086\ +\x960\x89\xcb\xe6\x00`\xe4\xea? \xd6\xe6\xfa\x00%\ +\x08j\x80\xfb9\xce\x9a9@\x87\xd4\x00;\xcc\xf1\x1e\ +\xfe\x06\x8d z`V\x08\x12 B\xab\x11$\xeb\x17\ +\xc3\x17\xfd\x09_\x9d\x01\xb0o\xdf\xbe\xc6\x90\xca\xb5(\ +2\xaad:\xcf\xbc\xd7\x17\xd9\xf3\x0d\x0d\xe0\ +e\x88\xd0\x86\xe9\x82\x90\x0f\x7f\x02a\x1e\xfe\x86]j\ +\x7f\x02\xa0Y\xd8\xc8\xed/^\xbc\x08hH\x1d\x89\x03\ +\x00>\x08i\xb2/\x84\xeb\x00\xe92\x8b\xf4U[\xe6\ +@\x07k\xe0\xf0X\x83\x88\xc3<\x0b&S\xebaS\ +\xec\xa2*\xf4\xaeM/\x9dk\x10\x85\xa4J\xd3V\x9c\ +\x1c\x0c\x10&\x91\x0cs\xd0\x06\x00\x83\x01\x1c\x14k\xe1\ +\xb1\xd1\x1e\xf3\x07\x01a]hEs\xb8G\x0b\x99\x03\ +\xe3\x80\x00\xf3\xbc\x8bC%\x04\x1a\xc5\xb8\xda\x87\x01\xa0\ +L\x0d\xc2`\xc0\x06QH\x18U\x85P}G\x14F\ +\x5ca\x1c\x8d\xc11\xf2\x1e\x0c\xb3\x06\x0cA\x1b\x0c\xd2\ +\x01M\xed\x831\xd6\xa5\x94\xc6yZ\x1a\xb3G6~\ +\xff\xfe}\x9c\xec\xb0\xf5\x05> \x95\xbbi2F\x15\ +\x98\x8ac+31M\x0bF\xa8\xe02\x82\x97,Y\ +B\xb1\xc4\x19_iF\x88\xb4a\x1e\xa6Y\x03\x86\x01\ +\x8e\xe8\x01\xd3\x5cq\xd0\xac\xc9\x95u\x19\xc3TL\xb3\ +\x05\xe2\xfdk\x80\x9b\xda\xb0G\xc2(\x04@\xac!\x92\ ++\xb6\x8f9\x00\x00\xe6\x01\xe1\xe6\x0d\xe6!&/\xfa\ +\x03}\x92v\x0e8\x80\x82\xc6\xa8%\x8c\x13\xfaX\x1f\ +\xad\x1a\xd6\x07\x94\xb3\x11&!\x02P\xb5A\xd4\xbf\x94\ +yT\x17\x82\x91&~@M\xe4\x1d#\x8ay\x88\xe9\ +0s`\xd4\xb9\xccC[\xe4\x819\x00\x05 y\xc7\ +m\x1b\x15\x0d0\x03cc%D\x83Y\x01\x80\x09\xa4\ +M\xb9\x8a\xad2fJ\x8cd5\x15\xcf\x0ed\xce\x08\ +\x01\xc8\x98\x0b\x8e\xd5\x04\x88\xf7\xd4\x06C&\x9a\x85\x1f\ +a\x9d\xd1\xd2\x00\xe36\x1d\x86pJ\x84\xaf|\xa6\x08\ +\xf1\x84]=9\x0c\xe8\xd4\xb0a\xa3\x00\xa01nx\ +\x86y\xde\xb1\xe0\xa1\x13\x05\x04>\x9f\x00\xc1\xb4{Q\ +gp\xffV'XV\x0d\x90Q\x9a\xea\x8e\x9a\xe7U\ +\xd2:\x9d(\xc0\xb8g\x06\x8c1\x17\xa6\xb8\x1a\xfb\xcd\ +\xf4\x90<\xcf\xfa\x05\x8b\x1f\x9a\xd9\xa2i5`\xd0\x0c\ +\x9bh\x1c\xfb\x8e\xaa\x06h\xabJ\xd11\x98p\x1e\xfb\ +C8\x04\xeb\xe1q`\xf3f,IM\xd3>I\x03\ +\x13B\xdd\xbbo\xa3)0l\x8d`\xdeo\xea\xab\x84\ +\x87\xca\x1e\xc91\x00\xd5|\xe2\xfd\xfa\x80\ +J\xb5U\xf5\xa9>\xca\xd8\x89u\x93S\xfd\xec\xc8\x19\ +\x1a\xa68\xcf\xf7\x5c\xc3\xee\xfev5\x0d\xb0\xde\x04\xa0\ +\xdc> O@\xbe\xa2\xf3\xdeL\xd0\xef\x7f0\xeb\x5c\ +\xfb\xf71\xbf\xa77u\x84\xeaw\xb5\xb7\xa5\xee\xb6\xf6\ +\xd4\x1bj[e\xc0\x18\xeb\xad\x05\xb4e\ +A\xf0\x9c2>\xdbq@+\xd0\xcc\xc9;B\xb5\x84\ +=GO\x03LG\x05\x82g\x08\xf1h\x8b1\x99\xf6\ +\xd0\xd3\x12\x1a\x10Pyk\x04\xabA\xdf\xf1\xec\x12\x9a\ +\xa9 9\x12\xf3\x5c\xd03J\x80\xf5\xd3\x1d\xe6\x05\xf3\ +\xa3u b\xfd\xaf\xf3\xd3\x0c`\xcajM\x02!\x1a\ +@\xf2\x1fG\x19\x83!\x8b\x17\xa4\xed<\xc3'_w\ +\x00\x94J\x12\x06\xd9\x03\xe65\x09\xfd\x0fB\xe0X\x8c\ +\xdfF\xd7\x07X\xcf\xeb\x84Tw+@\x982\x13\xb4\ +t6\x1c\xf2\x9bE\x8b\x15\x9d\x1fRaD\x8f\x1e_\ +\xaa\xd1\x0eO\x95\x00\x8f\xf73\xa0<)jnn6\ +\xed\x1dU\x1f \xc3\x1eE\xeb\x18\x01\x85|\xdc\x83N\ +\xf3z\x011\xf4\xe1 aT\xd3\x00\x00\xde\xa1\xf6g\ +\x1d\xd7\xd4!ZL\xb1'ct\xd6\xc0\xf9\x01\xfa\x88\ +\x00\xe0\x0bq\xb9\x01\xc0\xa1i\xbfflH\x0b\xf5\xd5\ +W\xc0\xb8\xde\xdeR\xd7DJ\xa6Js\x0bU\xde\x22\ +'\x9f\x0cyb\x84\xf41\xbb\x11)l1P\xaea\ +\xd1rT\x7f6\x88\xb3\x04.\x05\x06\x10 T\xe7\x05\ +\x13\xac\x81\xdd#q\xa5jm`FI\xb7\xb6'\xf9\ +\xf1T)\xffu\x8aw\xf9\xd6\xc0\xbc\xb5k\xd7r\xec\ +\xa6\x06\xe9$\xf9.!\xdd\x00\xde\x87\x064\xf0\xf0\x0e\ +\xcd\x8c\xeemZ\x80-*9\xbb\xc7\xde\x10\xe7\x87\x0d\ +\x08\xf1K\x8e\xa7\xba\x1e\x8cp\xc6\x0fS\x00\xc5\xf19\ +k\xc8\x98\xef m\x00c=+N*@\xd6\xf6=\ +@\xf5\xbc\x01\xba\xa0\x01 o\x15\xf9\xdb[\xff\x14\xed\ +\xc7\xb6|\xf5\xa5\xbd\xea\xfd\xd9\xc0\xdfJ\x9bN\x12\x8f\ +\x0eQH\x15\xa2\xf3i34\xd1y\x9fd\xc7F\xe6\ +gh3)\xe2}K]\x01\xf8\xee\xbb\xef\x86\x22Y\ +\x00\xd1\xd0\xb3\x11I\xfe[\x8c\x81\x9bdZl\xca\x22\ +\xf9\xd8\x9b\xaf\xeb\xed,nM\x0fa~\xa8\x90(\x8f\ +\xb8\xecn\xea\xb5\xa4y\x86\xef\x91\xd8pi\xb9f\x82\ +\xcf\xf0\x0b\xb6\xe7\x83#1W\xfd\xc7\x85\xf8\xfb\x86/\ +c\xa8\xad\x18R\xea\x08oy(\x08_\xef_X\x04\ +\x832\xe2U\xe2e\x12/?\x10D|\x1b\x8f\xcf\xf2\ +i\xae\xcd\xf8>\x82&8\x95\x01\xe8\xd4Xcz\xd0\ +P\x13\x9d\xbfW\x80>\xf6\x1b\x88\xf1\xbe\xb8\xbc\x88\xa9\ +\x8f\xc3A>\x09\xa0~l\x02\x83\xd0:\xc2\x9c.E\ +8\xfe:\xd6\xbb\xc0)~!\xfe\xf6~R,\xbc:\ +T\xf6\xf3@wY\xfc\xf0\x13\xfe\xcc\x8d\xf9y\xc9K\ +g4\xa0\xbe\x1d\xb6t$\x88\xf8_\xbc\xdb\x99\xdeO\ +s\xc3B\xb4\xd7e\xc8O\x90\x0e\xb4\x12\x1b\xefE\x7f\ +\x12\x7fq\xfa:\x0b\x81\xf1\xf7}\xd3\x02\xed\x96`f\ +n<\x83~}\x00A\xfd\xca\xefH\xb2\x10\x9d{\xfa\ +`\xdc\xb3P{\xcc\xb9\x16\xd7\xa7il4@\xec#\ +h\x04\xe3}\x0e\x9a\x03\x00B\x15\x99l\xf4\x9a\xe8\x18\ +\xa2\xfa\xeb\xb5@g!T\x07\x7fD\x07\xc54\x86\xdb\ +\xf8\xbf\xce\xa64\xfe_c\xe3\x00\x8c\x03\xf0\x11\xb7\xff\ +\x03\x7f\x19\x0a\xe4\xd7bc\xda\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x15\x14\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x06\x00\x00\x00\xaaiq\xde\ +\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\ +\x00\x00\x00\x09pHYs\x00\x00\x06\xec\x00\x00\x06\xec\ +\x01\x1eu85\x00\x00\x00\x19tEXtSof\ +tware\x00www.inksca\ +pe.org\x9b\xee<\x1a\x00\x00\x14\x91ID\ +ATx\xda\xe5[y\x8cd\xc5}\xfe\xbd\xa3\x8f\xe9\ +\xee9v\xa6\x97\xdd\xb9\x96=fa\xef\x05al\xae\ +\xa08\xb6 N,\x22'2\x09\x92\x0f\x14 \xc6\x81\ +\x18\x84\x92\x08Y\x8a0\x7f\x18\x04\x09\xe0\xf8\x08G$\ +\xa2$v\x14\x9b\x80\xf3O\x0e'\x86\x80\xc3a`1\ +\xe6\xb0!\xbb\xec\xb2\xf7\xce\xf4L\xcf\xf4\xdd\xfd\xae\xaa\ +|\xbfz]\xf3\xfa\x98I\xef\xb4\x90e)e}T\ +\xbdzG\xd7\xf7\xbb\xabfmH)\xe9\xffs\xb3\xe9\ +\x97\xb8\xbdt\xed\xb5\x03\x9e\xebf\x09\xf0\x84\x18#\xe9\ +g\xa5/\xb3B\x88\xac\x14\x18cN\x04\x22-\xfd\xe0\ +\xdf\x7f\xf3\x95W\xfe\x8a\xfah\xbf0\x0bx\xefK_\ +JT=/\xebH7k\xf8A\x96\x04\x88\x04\x04\x02\ +AV\x92\xc8R CRR\x8c\xc9@\xe0\x9e`\x82\ +)\x89\x87pM\x18\x87\x08\x02\x12\xd1\xb8\xd9\x8b\xc6F\ +!\x86.:p\xc0\xfb\x85X\xc0\xcf\xef\xbe;n\xd5\ +jY\xd7\xf3\xc6L\xc3\xc8\x0ab\x12\x06/\x18=\x8d\ +\x19\x22\xc8\x0aIY\x92LB\x86} \xd3 G\x06\ +n\xa0\x03\xd0\xf3\x80\x00&!\x19\x12d\x00\xdc#\xd9\ +\x84z\xae\x1d\xb4\x0c\xd2s\xc9cR\xee\xbc\x88\xe8\xcd\ +\x0fD\x00\xef\xdcy\xe7\xed\xe5\xb8\xbd)y\xe2\xe4\x88\ +\xb1n$&\x0d\xca\x1ad\x8c\x11H\x12I\x80\x06}\ +\xe2&\xa18\xeeB2za\x22\xecC\xed\xf0\x98\xfb\ +\xe6u\x04\xb92\xa4\x86\x88\xde\xd7\x08\xafC\x88\xf6\xdf\ +4\xa4\x7f\x01}\x10\x02x\xec\xc2\x0b\xbfr\xc5\x95\x97\ +\xdf\xe5\x98C\x94\x1a\x18\xa0@\x88\x90\xaa\xc1\xffU\xff\ +\xa1P\xf4z(\xc3a\xa4\x9d\x88t4V\xefZ\xa9\ +4\x05\x8d:\x5c\x99\xcd\xdae3P0c6\xe6\x1b\ +\xe1\xb5\xd0\xc4\xf1F2A\xa4\x85U\xa9\xb4\x0b\xa3\xc3\ +*\x840.0\x0c\xe3\xef%Z_\x020\xd0\xee\x98\ +\x9eN\xce\x0c\x0f\xdf^/\x95\xa9T,Sv|\x9c\ +\xfcr\x89\xc84i\xb5f&\x12$\xea\xf5H\x10\xe1\ +\xe2\x99\x8c\xd6TH\xcc`\x01\x0c\xa0\xc7;\x98\x0bj\ +\xfc\xb2\xa5\xe6\xfcZ\x83\xac\xc1!\xf45\xb2\x86\x06\xc9\ +\xcd\xcd\x13\xa5S\xca\xf7\x85\x03\xc1`^\x13\xee\xd6\xbe\ +\xb6\x00\xb1\xbf\xa9\xa1\xb5\x0b\x80\xc9\xf3r<\xa2mA\ +\x10\x0c\xd7\xf0\x83\x85\xa5\x22\xc5v\xee\xa4Zn\x8e\xcc\ +dRKIk]u\xf1l\x96\xbcB\x81\x12\x1b6\ +RP\xad\x84k\xf1=2b1\xe2O\x06\x9eG\xd6\ +@J\x09\xa81?\xaf4\xeb\xd7A6\x99\xc4;\x1b\ +\xc8\xc9\xe5H\xb2e\xc0\xd2\xbcz\x95\xc82\xc9\xaf\xd6\ +\xc8\x84P\x02\xd7\xa3\x00\xe4\xf9]\xe9\xba\x91\xf6\x05\xf7\ +\x1d\xae\x80\x1e*\xda\xcb+\xec\xd7\x05\x0c 1W\xaf\ +\xaf\x9fI\xa5\xa8\x86\x1fu\xaaU\xb2\x86G(`\xe9\ +\xc7\xe2x\xa2\xfd\xeb\x120,\x1b\x8btH\xb8\x0e4\ +\x08\xcd-,(r6\xb4\xe9,.\xc2\xb4\xe3\xea\x9e\ +\xa4\xd0\xff\xb5\x00\xdd\xa5%\x08n\x89\x04\x5c!X*\ +4M\xbe3>\x04\xaa'\xdb\xc27\xbc\xe8\x9e\xd4q\ +\xa5E\x18\x00\xfe\xb3\xfe\x9b\xdb\xb7\x8fC\xf0\xa7\xd6\xe2\ +\x06vS\xfb\x16\x90.\x04\xc1\x04\x07\xb0\x06\xfc13\ +\x98!{\xdd\x08I\x98\xa7\x1c\x0c4\xe9\xb6\xe6,\xcc\ ++\xc2\x0dh\xd2J$\x95\x86\xdcR\x99M[I\xab\ +~\xfaTK\x1c\x90T;qB\xbb\x84&\xdaA^\ +2\xda\xef5|\xfd\x8d.\x17\x00\xda,c\x90\x88\x03\ +\xe1\xa9~,\xc0\x04R\xaeTE\x069\x8eK\xe7l\ +\x9f!\xd7\x07q\x19\xe6\xdb\x95L\xc0\x87\x95\xe8\x00(\ +<\x8fG\xa1\x99W\xca\xad\x011\x22-#\x82:K\ +D\x02\x88\xae\x89\xc1\xf9\xde\xf7)\xf0\xb9\xf7\xd4\xd8\xc7\ +\x98\x94\xba,2\x01\xb8Z(l\xdc\x93X\x0b\xc8\xec\ +\xc3\xdd\x7f\xe9W\x001C\xca\x14/\xd2\x81\xcfM\xcf\ +l\xa3\xea|\x8e\xccx<\x5cTw\xd3\xe4\xa3l\xa0\ +S\x22\xe94\x18\x09\x81\x05 \x02\xc1q!\x04/\x1a\ +@\xaf\x82\xacaY\x80\x0d`\x8c\xdf4l\x9bl\xcc\ +\xc7\x00\xa4`\xf0\xe4\x9e\xf8y\x951\x82:\xe08\xe1\ +\x98\xdd\x8c\xb3\x89\x94\xfbt \xec'\x0d\x9a\xf0\xd1\x18\ +/\xd6\xf3|\x15|*\xe5\x1a\x0d \x1a;\xda\x02\xba\ +\x9a\x04\x09\x90\x0a<(\xc1g+\x08\xb5\x16\x04LF\ +\x91\xb0\x00\xee\xc9\x8e!cX\xb8\xb6\xe0\xd66\x00\xc2\ +&`\x19\xca\xc7\x03\xfc\x9e\xd0\x84\x18\xd0\xa8\xaf-\xa4\ +7\x94\x0bX:\x10\xf6\x15\x04\x81y\xdf/\xa2Wd\ +<\x04\xb1R\xb5N\x83\x08\x84\x8d\xc5<\xd5\x0aE\x12\ +,\xa5x\x8cMOY\x86e\xa1\xcf\xc4\xc8B\xb0\x8b\ +\xc7\x98\x5c\x1c\x81/\xd4\xa2l\x92\x11\x8a\x90C>z\ +Y\x87\x90\x9a\xe6\xee\xb7\xb9@8\xa6h\xdc\x01\xd9\x1b\ +R2\x89\xed\x9f\xdb\xb0!\x89\xb0V\x93hk.\x84\ +\xde\xaf\xd7\x17\xf1\x96\xd2`\xad\x5c\xa6B.O\xe7^\ +\x22\x06\x88\xff\x1bb\x19\xb1\xcb\xe2\xf1\xdd\ +\x7fG\xf4j?. \xabA\xe0\xbaB\xa0\x0b\xd2\xb5\ +Z\x9dJ\x88\xee\xf6\xc8\x88\xd2b\xf5\xd8Q\x8a\x9a\xe2\ +\xd4Q\x15F\xe4iEA\x88\x96\xba\xbe\x83\xb0\x5cQ\ +\x00m\xe4h\x19\xb2\x1b2B\xd2\x90\xfb\xa9\x0f\x01H\ +@\x00~-\x08\x0a\x83B\xa4Q\x0b\xf0\x02\xb8\x16P\ +Z6\x06\x92\xd4\x91\x06\xda;)\xb504\xe9\xae\x80\ +\xa8\x02,J\xda\x0a\xfc{\xdd\xd8\xd8\xea\xfb\x85\x8e1\ +E\xa6\xde\x919\xbaa\x0a\xc4\x8154\xb3\x85\x8d\x0f\ +x,\x00]\x0b\xf0\x22%\x071!\x9b[\xd2 D\ +\xc0\x10\xcbs\x22\xda\x96\x02<\x0e\xafEsN\x00|\ +]\x02\xf9\xe9\xcf_OW=\xf1O=\x82Z\x07\xf9\ +\x88\xb4\x86\x16R\x17\x8c0\x15\x9ak\xb2\x00\xad}\xc0\ +\xad\x0a\xb1\x14\xd6\x02\x1eM\xef\xddM\xd5\x85y\x15\xf0\ +|\xd1\x91\x09\xb4\xb6\xa3\xb1JQ%T\x83#\xe7\x9c\ +\xb3\xe2&\xe9C\xbf\xf3\xdb4u\xc3\x0daN\xe72\ +\xd90u1\x13\x91m\x89\x0d\xb4z\xb1\xc4X\xd9\x02\ +\xa4T\x99\xa0\x1f\x0b\xf0\x00\xa7\xe4\xfb\x0bJ\x00\xaeK\ +\xe3[6C\x00y\xb22\x19\x12Z\xbb\x80PP\x1a\ +nZD\xd8\xdb\xdbf\xe8#\x7f\xf9u\xf28@\x0a\ +\xfd|\x84\xc3\xdf\xfd.\xcd~\xff)2m\x9b+G\ +m)\xcd\xf7WD7\xf9\xd5\xef\xeb\xc04z\xcf\xc6\ +\x8dS\x06\xdaY\x09@\xa2\xb5\xb8\x80[\xf4\xfd\xbcN\ +\x85A\xb1He\x04\xc2\xf8\xc8:m\xd2\x0a2\x22\x17\ +\xb9\x01\xfa\x0b\xef\xb8\x83&.\xbb\x8c\xec\x89\xc9\xe5\xc5\ +\x89\x96\xde\x01\xe9\xd2\x1b?%n\x89\xb1Q}\xef,\ +\xd1\xed\x0a\xd19A\xd8\x8b&\x91u\xa6\xb9\xbf\x1f\x0b\ +\x08\x007\x1f\x04\xf3M\x01\xe0\x22O\xc53g8\x13\ +p^o\xd7\xa8^\x8c\xb6\x06<\x9f\xc0s\xdc\xce\xbf\ +\xe9&e\x05\xd1\xf3\x91\x96\x1b\xc7O\x10\xb7\xf4\x94\x12\ +\x92\x16`o\xd2\x00\xbbM\x19\xbbO\x07uH\xd5\x0f\ +\xa8\x5c\xa9D\xf7#\x22\xaa$\xee'\x0b(\x01\x9ct\ +\xdd9-\x80J\xa5Jelc\xedK/!b\x01\ +tX\x95l\x19\xc7\xb0qZx\xe6iJ\xc2]&\ +\x7f\xfd\x13\xf4\xf3\x8d\xe3$r\xf8TG=P\x9f;\ +C\xdcR\x9b6\x93\xfc\xef\xe7\x95\xf6<\xc7Q\xd6`\ +Y\x5c\x8c\x1aQ\x0ch\xf1\x7f\xc7\xb2i\xc7\xcd7\xd3\ +\xf8\xee\xdd\x94\x9a\x9c\xa0\x81-[\xa8\x84\xcd\xd5\x0f\xaf\ +\xbaZ\x0b@[\x00\x7f\xe3\xacKb\xb3#\x0dzg\ +\x1c'\x1f\x80?/\x88Saei)\xac\x05\x5cW\ +\xbb\xc0\x8a\xae0\xb8e+\x15_\x7f\x8d\xe6\xfe\xfaQ\ +\xe2\xb6\xeb\xd6[a\x05N\x97\x1b\x94\x17\xf2\xaadN\ +\xcf\xccP\x15[\xe1z\x22A\x9b\x10\x18g\xf0\xfc\xd8\ +'~\x83\x8a\xd5*\x07\xd3\xb6\xb8 \xd6\x8d\xd2\xd5\x88\ +\x1f#\xcf\xfd\x90\xde\xfd\xccu\xf4\xda\xaf^I\x87.\ +\xff\x08\xd1\xf3\xcfa\xc5\x1e/>\x82a\xe8\xb3\x01s\ +\x0d.\xd0\x96\x09\x9c\x1aJb^l\xbdV#\x1b\x87\ +\x15F\x12\xd0d;\xd1\x9c\x1f\xde\xbb\x8fj\xef\x1d\xa6\ +\x93g\xe6h\xe1?~@\x93W^I\xf1\xe9\xe9v\ +\x17\x00\x1ciP\xf9\xf0a\x9a\xfa\xd8\xc7\xe8\x92\xfb\xef\ +\xa7_\xf9\xbdkik\xadD[\xb7o\xa3+\xee\xbd\ +\x97~\xf7\xc0k\x14\xdb\xb6M\x93W\xc2\xf8\xe8\xe3\x8f\ +S\xe1\x1f\xbeM\x07~\xf2\x16\xe5\x92i\xca%R\xf4\ +\xe6\xdc\x22=\xff\xe5?\xa3\xa0\x9d\xbc\xb6\x80\x99\xcf\x8c\ +\x8e\xa6\x0c\xb4\xb5\x08@g\x02\xb7.DA\xb0\xbf\xc2\ +47LOQ\x0d\xfb\x02+\x91\xe8\xf6Q\xf6\xfd\xe6\ +1\xf5\xe8\x85\x17\xaax\x11\x90As\x8f>L\xdc\xf6\ +\xdcv\x1b\x9bw\x18$\x01\xd9D\xf5\xd0A\xb2\x90Z\ +\xe7\x1f\xf9\x16\x1dx\xe4Qz\xfe\xdb\xffH\xaf\xdct\ +#\x9d\xbe\xe5\x0b\x14\x1f\x1a\xa2\xab\xbf\xf3\x1d\x92\xc3\xc3\ +\xea\xd9\x91}\xfbh\xddy\xe7\xd1\xd1\xe7~DB\xca\ +6\x9f\xafZ\xf62y\x11\x92\xd7\xb0\xf6\x0d\x0c\xec^\ +\xab\x05\xc8e\x0b\x08\x82%\xa1\xb6\xc5\xa8\x05v\x9cO\ +ul\x86\xect\xbaM\xf3\x82\xa1\x83\x97eq\x90\xc4\ +\xf3\xbe\x9a;\xf2\xde\xfb\x94{\xee9\x9a\xb8\xe2\x0aJ\ +l\xdd\xd6n\xce@\xfd\xbd\xf7\x88[\x11\xd6\xe0A`\ +0x*&S\xf4\xda\x7f>C\xb3O|\x8f\xe28\ +]\xda|\xcd5\xea\xd9\xb1\xcd\xe7\xaa\xa55\x82\xa0\x8d\ +\xbc\x86\xe8 \xaf\x91 \xda\xdf\x8f\x0bx\x80S\x0e\x82\ +\xbc>\x18\xd901\x8eT8Oq\xf8\xa1\xce\xfd\xdc\ +\xcbe\x044\xb4y39\x88\xfa\xd6\xf9\xe7\xd3\xf0G\ +\x7f\x8d6\x7f\xf1\x8b\x94\xda\xba\x95\xb8\xed\xbd\xfdvX\ +A\xa3\xcd\x0d\xea\xcd}Erj\xaa\xadbt\x0d\x93\ +rO>Ah\xecBj\xce2\x0d\x15@\xd3\xbb\xf7\ +\xa8^\x10\xb5Av\x93Ws\xb10\x13\x9c\x9d\x0b\xb4\ +\xd6\x02Z\x00\xcb\xa9\x90\xb7\xc5ssd\x8f\x8e\xf2\x81\ +\xa7.u#`\x91#\xf0\xff1\x04\xb5\x8b/\xb9\x98\ +v\x0a\x97\xb2/\xfc\xd6\xdbT|\xf5\x15\x1a\xbf\xf4R\x1a\ +\xdc\xb7w\xb9\xe0\xa9\x14J\xe4\xe0\x9bSW]\x15\x1e\ +\x8c\xa8o\x85\xef\xc5\xd9\xd20\x97\xff\xdb\xbfQ\xbd\x87\ +\xf5\x1f\xbe\xe5fr \xb4\xed\x9f\xfe4}\xea\xc7/\ +\xd1\x87\x1e\xf8s\xda\xf5\xa7\x7fB\xd7<\xfb_4\x99\ +\x1d\xa1\xf7_~\xb5\xcb\x15p=r\xe7\xfa\xf5\x9b\xd6\ +j\x01\x02\xf0\x8e;\xce\xac>\x18\xe1Z\xa0\xc6G\xe4\ +\x99A\xf6\x95v\x0b\x10\xf0\xffm[\xa9|\xe8\x10y\ +\xbe\xafI,\x9b\xb5\x83\xcf\xcf~\xf3\xeb\xc4\xed\xc3_\ +\xbd\x87\x5c7\x14\xa0OR\xbd\x93\x04\xd9\xf1O~\x92\ +\xaa\xa52y\xaeKU\xa4\xdd\xf3n\xb9\x85\x16\x1e{\ +\x98\x0e\xbe\xfe\xc62\x99\x83\x85\x0a\xfd\xec\xea\x8fS\xe9\ +\xbe\xaf\x92<~\x8c\xa6\xf6\xef\xa7-\xd3\x93\xe4\xdfs\ +7\xbd\xf9\xb5\xaf\x93o\x9az\xf1mAq]\x22\xb1\ +o\xad\x7f\x1a\x93\xcd-q\xd5\x05\xe2R\xa6kXT\ +\x06\x0bu\x0aK*\x15z\x22h+\x03\xc7\x90\xfe\xaa\ +G\xdfW\xd6\x80\xd6~&\x80\xf6\xb3g\x7fD\xd3H\ +\x8f\x9c\xca\xf6\xddu\x17\xbd\xf9\x8do\x90\x84Ky \ +\x22/\xba\x88\xae|\xe8!\xda{\xe3\x8d\x94;p\x80\ +\x86Q\xe1\x89'\xbfG/>\xf1\x14\xb9v\xac\xad\xbc\ +=X\xf7\xe8\xc8c\x8f\xd3\xc8\xb7\x1e&[\x08\x95\x02\ +\x17\xe3Ih\xda\xea\x8a\x0bzl\x87\x99\xe0\x9f\x01\xd9\ +K\x00\xdd\xc5\x10j\x81\xb4\x10i\xce\x04\x93\xe7\x9f\x87\ +Z`\x89bHOu\xc4\x04\xdd\x1a\x8d:M^\xf3\ +[4\xff\xfa\xebT\xc4\xbea\xa8\xb9\x17\x90\xa1\x10T\ +\xae\xbf\xf0\xa1\xaf\x91\x09\xed\x96\x9f}\x86&\x93q\xca\ +\xdet\x03\xfd\xcf\x93OQ\xee\xa1\x07\xe8\xc4\x1f\xfd!\ +e\xb0u\x8ee\xd2\xe4\x97+\xf4\xf6\x99Y\xca\xc7\x07\ +\xc8g\xf2\x11!-\x04\x95%\xe6p\xbf\x93(\xb0\xe2\ +\x1cY\x96\xca\x04k\xb6\x80\xa6\x00\xb8\x16\x98\xe4m\xf1\ +\xae];i\xfe\xf8I\x8a\x83\xa0\xc0\xde\x80\xdb\x10\x0a\ +\x94K`\xae\xe9\xc1\x0c\xc5!\xa0\x8f?\xf8\x00\xbd\xfc\ +\x95\xbbI\xb6\x1e\x93\xc3u\xe6o\xbd\x99\x8e\xc15\x1a\ +VL\x11\xf0\x0dC\xf5\xa7\xf8\xbe\x95 \xca\x17I\x02\ +\xdcd\x22\x15-~\x05\x82\xd4\x83x\xe7\x9c\x85\xb3\x81\ +f \x14\x12m-\x16\xe0V[j\x81a\x90<\x82\ +\xa8<\x9e]O\xf4\xee;a\x9e}\xfbM:\xf5\xd9\ +\xeb\xe8\x10L\xdf3-\xf2-\x8b\x84\x1do;0\xf4\ +\xd0\x1f\x89\x0d\x10\xd9\xd1f\x08-\x1c\xb7\x12[\x85$\ +\xadN\x94[OK\x00\xf1-\x9f\x1a\x19I\x7f\xbfP\ +(\xf6\x0a\x82Q-\x10\x15C\x8b:\x13p*,\xcf\ +\x87\xa9\xd0\xf0\xc2\x8d\xca\xbc\xe3\xd1\xfb 7\x8b\x0a.\ +\x1fKP\xd1\xb4[\xff\xd5FtL\xa6{)\xdbv\ +l\xa2c\x8cE3t\x00\xeb\x0ej\x8c\xee\x0a\xb0\xbd\ +(\xd2\xcfFs&J\xe2=ku\x01}0\xb2\x5c\ +\x0b8\x5c\x0b\x14\x8bds}\xce\xa9\x90\xba\x1b\x18\xb6\ +~d\xf5q\xb7\x06;\xe7\xba\xdd\xa0\xb7\xd6\xf5|\xd7\ +\xb5\x1d\x8fs |\x11\xe8\xe1\x02\x1d\xe7\x02\x8bA\x90\ +\xd3\x02\xa8Tka*\x5c\xb7\x8eL\xbd\xb7_\xa1\xc9\ +\xce\xeb\xd5\x84\xd0i\xe2\x9d\xcf\xf7p\x83h\xae\xb7\x1b\ + \x0e\xb0\x00\x8c\xb5X\x80\x00\xbc\x13\xa8\x05\xd0\x87\x9b\ +\x17\xd4\x02u\xd4\xfan\xa9D\x16o\x8a\x5c\xb7\x9bp\ +/\xad\x1b\xc6*\x82\xe9\xd6x7\xf1\xfe\x83\x22\x22`\ +[ \xec!\x80\xc8\x0dN\xe3`\xc4\x97\xd2\x8fIi\ +s-\xb0\x1e\x1b\x9e\x06\xbb\x01\xb6\xabba\xa1\xb7\xf6\ +\x99p\xffn\x10\x8d{\xb9A\x8f\xe7A\x5c\x95\xc4=\ +\x83\xe0J\xbbBlA\x8b:\x13l\xday>UQ\ +\xbe&\xb2Y\x0e4]\x90\x8c\xd6k\xa2^Ao\xd5\ +\xe0&\xa3\xfb\xd15\xa3\xc7\x0e\xb0+(\xe2\x1a\x02\x18\ +\xbcmbb\xf3\x1a\x04\x10\x05\xc2\xba\x10\x8b\xfa\x88\xfc\ +\x5c\xe4\xfa*4\x9fX\xbf^\x9f\xf9wG\xeb\xce\xb9\ +UH\xa9~5\x01u\x13\x8f\xc6-\xef\x8a\x1e1\x80\ +Z,p\xd0\xb6\xf7\xafI\x00\xda\x02P\x0b,\xc1m\ +T\x0d\x9fBUW\x99\x9fW\x81\x90\x84h'\xbd\x1a\ +qM\xb8\x9d\xd4J}\xf4\xdcZ\xac\x81\xe7z\x90\xe7\ +\x167\x0c\x15\x08{\x06A\x89\xc6\xc1B\x97\xc3\x95\xd6\ +s\x81|>L\x85\xd8\x17\x18R\xf2\xa2\xd6\x16\x08\xf5\ +\xb8g6\xe8]\x10Q\x0f\xadw6\xcc\xeei*[\ +\x9cu\x10\x04\xdc\x12\x04\xa0\x8b!\xa7P\xa0z\xa5\xc2\ +\x16\xa0\xbf\xd4;\x10v\x8d5\xe9\xde\xd9\xa07\xf1n\ +a\xea\xac\x85\x8d\x9c\x82\x0f8\xbe/\xc84\xe7\xf8\x09\ +n\x12\xad\xa7\x00t-Ph\xad\x05*U\xaa;\x0e\ +y\xd5\xaa:)\x16\x98\xa3^\xda\xd7V\xd2\xcb\x12z\ +\xa4A]V+b\xf8]\x0f\xbd'\x84\xf4\xd9Z\x13\ +\x89\xc0\x1aH\x0a;\x95\x96\xf6\xf0\x90L\x8e\x8e\xd1\xe0\ +\xe4\x84\x1c\x9d\xdeDS\xbbv\xc8\xbf\xb8\xf3\xcb\xd7\xfd\ +\xdb\xbb\xef\xbe\xdc\xb3\x0eX\xf1`\xc4\xf3\xe6Zk\x01\ +\xe5\x17p\x83\x18R\xa1\x5cZ\xea&\xdd\x87\x1b\xb8M\ +\x8dy\x00\xf7\x0e\x88Ac\x81\x88\xc7\x03#\x91\x10F\ +&\xc3\xffxR\x9d\x1d\x0c\x8c\x8f\xcb\xd1\xc9Icd\ +z\xda\x1e\x99\x18\xb7m;f\x99\xf8\x9fm\xd9\x14\x8b\ +\xc5\xc8\xb6-\xf4q\xe2\xebd2ICX\xe7y\x93\ +\x93\x15\x08\xa0\xce\x9cz\xd4\x01\xdd\x81\xf0x\xa31+\ +\xf0\x8e\xfe#\xc9\xe4\xf6\x19j\xa0\x18J\x8e\x8d\x91\x80\ +\x00V{\x11\xefh-isd\x0d\x0a\x11\x12c\xad\ +\x09\x99JI+\x931l\xa4\xd5\x01l\x893\xe3\xe3\ +\xe6\xf0\xf4\x94\x99\xc9fm2\xd4\xc6\xc2\xe6\xe5Z\x96\ +EqE\x0e$\xe3q5\x8e'\xb8\x8f\x87\xa4c\x98\ +\xb7c\xfc\x9cz\x06\x02a\x01\xa8g\xd2\xa94\xed?\ +wR\xe9\xadg)\xbc\xd2\xae\x10Y\xa0\x02\x12\x15\x14\ +C\x19\x95\x0aw\xec\xc0\xb6\xf8\xb8\x0a\xa7\x8b\xb5Z\xe8\ +gx6\xb0\xac@\xc4bB&\x12R\x0e\x0cH\x99\ +\xce X\x8e\xc9\xc4\x86s\xcc\xd4\xf8Fc\xdd\xe4\xa4\ +=8:fAU&/\xce4\x94C\x92\xc9\x8b\x06\ +L\x1e\x9b&\x19\x80&\x8c{!i\xc0b\xe0\x1e\xae\ +\x19\xeaY\x0d}\xe4\x87y~W\x83\x05\xa4\xe6&\x92\ +\x99\x18n\xf7\xda\x0e\xaf\x9e\x0a\xf9\x8f$I!2\xae\ +\xe3\xd1\xb6\xa9)\xf9\xea\xf1\x13\x1e\xcd\xccH\xfb\xe2\x0f\ +\x1b\xa3\x9b6\xd9\x03\x83\x83&~\xc8\xd4\x0bd\xad`\ +\xac4\x80Y\xb2\x15\x19s\xf9\xf8\x1b\xd41\x0ex\xcc\ +\x8bW\xe0\xb5\x99\xfc\x0e4\x0c\xe89u\xf8\xc9\x827\ +\x00|\x97c\x11\xf7\xfc\x0c\x93\x0c\x85\xd8\xfc]4\xbe\ +\xd6\xd9,\xdc\xc5\xd6\xebn\xcc\x94\xa95\x9c\x08ug\ +\x82\x1a\x8a\xa1\x11)\xa78\xf2\x9f)\x14\xbc\x89\xcf}\ +\x1e\xe7\x22#\x94I\xa7@2\xc1\x0bQ\x84AE\xbd\ +&\x98\x8c\x8e\xe2\x18\xa3\x0f\x17iY\xbcx\x8c-@\ +\x11l\x03\x04\xa2\xc7\x9a\x84z>\x11Z\x85&\xac5\ +\xdd\x9a\xbaY0<\xd7\xf6\x0d\xbe\xae\x17\x8be\xcb\x13\ +\x995l\x87\xa3Z@[@\xa5y.\xb0\x1e\x01\xe5\ +\xe4\x9e}\xd6\xa6\xe9i\xca\x8e\x8d\x92\xdd\xd44\xb1\x16\ +\x0c\x93;m\xaa\x9aDD\x8e\x11\x04\xbc\xd00\xa5:\ +.kW/XC\x9b4\xa3m\x8e\xdf\xd1B@k\ +\x8e\xb5@W.\xf3\xf9\xdb\x8d|\xbeJ\xc2O\xb3q\ +\xf4k\x01,\x00\xb5\xf3\x09V\ +\x8dBC\x93\xd3\xd2\xd7Z\xd4\xda\xd7d;\x03\x9b\x16\ +N\x9b&u\xd3\x04\xb5\xf6\xf4\xb3:#t\xb6r>\ +\xef\xce\xbe\xf3N=\x7f\xf4\xa8S:y\xc2\xaf\x9e\x99\ +\x95A\xa1`X\x8d\xba= E|\xc8\x8e\xa52\xa9\ +d2\x96\x88\x0f\xbf\x9e[\xfc\xd7>\xb2@\x94\x0aO\ +9\xce\x82\x90\x92=;\xd0\x8bn\xd5\xa8\x16\x82\xd6\x1a\ +4\xd2\xb5h\x5ck\xb4\xa5\xaf\xd6\xc6\xefq+\xe6r\ +\xce\xe9#G\xea\x0bG\x8e\xb8\x85\xe3\xc7\xfd\xf2\xe9\xd3\ +\xd2YX0\xfcb\xd16\x1a\x8dD\xdc\xf7S\xb6i\ +\xc6\xf1\x8d\xb8\x0a\x90\x86Q\x0bL\xa3\xe4\x1a\x0a\x05`\ +\x09\xa2\x9cC\xd1u\xe8\xe9\xd3\xb3O\xbe\x9d\xcf\x1f\xeb\ +W\x00:\x134\xea\xbe_\xf2\xa4\x8ckr\xda\x84[\ +\xcdUC\x13]\xa9\x15fg\x9d\x1c\xc8-\x1d;\xe6\ +,\x1e=\xeaWggy\x97\xb9L.!D\xca\x84\ +,\x08\xc0\xef5\x1c)K|(\x83Z\xa4X\xc7\xd6\ +\x9c\xff\x0dcY\x88|\x01\x9b\xb4<\x14s\xd4u\xe7\ +0_gWe\xe8\xcc\x05\xd4\x80\x02P\x0c\xe7\xfb\x17\ +\x80\x0b\xd4q@zl|qqG\x12\x02\xb0Y\x83\ +\xb6\xddE\x12\xe4\x1a\xb9C\x87\xeay\x90\xc3_\x7f\x83\ +\x0ak\x0e\xe4D\xa9\x14S\x9a\x13\x22\xcd\xe4\x02d\xd9\ +\x86\x10~C\xcaJ\x93\x9c\x22V\xf1\xfd|\x11\xc4\x16\ +|?\x87\x12|\x1e;\xd12\x13\xea \xc7\xf0[\x10\ +\xb4\xf7z\x1c=\xab\xab\xc0\x1e\x02X\xb5\x16p\x80\xd2\ +{\x8d\xc6K\x9b\x97\x96\xf6\xbe\xf4\xe0\x83\x8b\x89z\xd5\ +<5\x9f\xaf\xe1\x80T\x82\x9cm6\x1a\xc9\x18\x8a_\ +\xfe\x16od\x80:\xffY\xad.e\xa1\xe6\xfbK\x15\ +h\xac\xe8y\x0b\x8b8f?\x89\xcd\xd5\x82\xeb\x964\ +\xa1>\x881\x04 \xcf\x06\xdc\xfa\xfe\xbf\xceB\x00&\ +\x85\xe6\xb8\x11R\xda~\xf3\xe4\xe4\x1foL&w\xa7\ +\xd2)\xff\x8d\xb9\xdcO\xaa\xa8\x0fJ@\x1e\xc4p\x80\ +\x9a;\xe3\xba\x8b\xdd\xa4\x80\xde\xa4\xb8\x17\x8c\x1e\xe4(\ +\x1aw\xb7\xd5\xc8\xf6+\x00-\x04\x1b]\x1a\x18\x05\x86\ +\x81\x18 \xceF[k\xd4\x18}0\xc4>x\x01\x18\ +\xe8,&\xde\x84\xa1k\x84_.b\xfd\xb7\xff\x05\xc7\ +\xfd\xe7\xdb#]\x138\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00 \x1c\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x06\x00\x00\x00\xaaiq\xde\ +\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09pHYs\x00\x00\x1b\xaf\x00\x00\ +\x1b\xaf\x01^\x1a\x91\x1c\x00\x00\x00\x07tIME\x07\ +\xd7\x08\x12\x149()\x91|\x0e\x00\x00\x1f\xa9ID\ +ATx\xda\xe5\x9b\x09\xb0\x5cW\x99\xdf\xff\xb7\xf7\xbd\ +_\xbf\xfd\xe9\xe9=I\xd6.\xd9\xda,y\xc1x\xc0\ +vB\x81\xc1\x03d\x0c\x13\x1cBe\x02N\xb1\x84x\ +\x5c\xc5\x14UI*TH\x05*\x03\xc3\x14\x03U3\ +\x13C*\xae!\x9e\x01&\x05C\x80\xd8\xb2\x0dx\xc3\ +\x96%k\xb1\xf5\xb4=k}\xd2\xdb\xb7\xde\xb7\xdb\xb7\ +\xf3;\xa7\xbb5\x12\x1a\x0a\x18\xb0\x81J\xcb\x9f\xcf\xed\ +\xbb\x9cw\xbe\xed\xff-\xf7\xb4\xfe\x7f\xff8\xaf\xe7\xdf\ +Y\xb3f\x8d\xaf\xab\xab\xcb\xd7\xdb\xdbk)\x91H8\ +\xd5jU\xb9\x5c\xce[XX\xf0\x96\x97\x97\xbd\x0b\x17\ +.x\xd9l\xb6)\x09\xfa-\x16@$\x12\xf1m\xdd\ +\xba5\xb0{\xf7\xee\xf8\xddw\xdf\xbd\xb5\xaf\xafog\ +4\x1a]\xcf\xf9u~\xbf\xbf\xd7q\x9c\x04\x14o\xf2\ +i4\x1a\x05C\x08c\xa6\x5c.\x9f*\x16\x8b\xe3\xd3\ +\xd3\xd3\xfb\xbf\xfd\xedo\x9fK\xc1\ +`P\xdcg\xcfW*\x15\x15\x0a\x85I\xac\xe1\xd9\xa9\ +\xa9\xa9o=\xca\xe7[\xdf\xfaV\xdeX\xca\xafR\x18\ +\xce\xafJ\xdb\xd7_\x7f}\xf4\x13\x9f\xf8\xc4\xaem\xdb\ +\xb6}4\x9dN\xdf\x0d\xd3)\xc3\x08\x1a\x15\x1aU\xa9\ +TR\x15\xa6j\xb5\x9a\xdcz\xbd%\x00\x08\xa1@\xad\ +\x95\xc0\xbc\x15B8\x1aU*\x95\xb2\x14\xe5\xb8\xce\xfd\ +\x8b\x8b\x8b\xf3333\xff{ll\xec\xcf>\xf7\xb9\ +\xcf\x8dONN\xbaF\x10\xbfn\x018\x1b7n\x8c\ +~\xfa\xd3\x9f\xbey\xc7\x8e\x1d\x7f\x94\xc9d\xde\xe2\xe7\ +\x03\xd3\xc6\xafU,\x14T\xe1\xd8P\x15*#\x04\xc8\ +\x0a\xa2\x8e \x1aX\x82\xe1\xde\xe78\xf2\x07\x02\x0a\x05\ +C\x0a\x86B\x0a\x84C\xf2\x9bc\xc6h<\xae\x9e\xbe\ +>\xf5A!\xae---\xd5/]\xba\xf4\xcd#G\ +\x8e|\x96\xbf{\x22\x9f\xcf\xbb\xbf\x16\x01\xa0\x9d\xe0\x87\ +?\xfc\xe1\x91\xf7\xbf\xff\xfd\xff~hh\xe8\x03\x98p\ +\x10M[\xc6K0n(\xbb\xbc\xac\x85\xb9y\xcd\xce\ +\xcdjnvVK\x8bK\xca\xe6\xb2\xd6\x1a:\x02\xf0\ +I\x0a\xfa\xfc\x8a\x84\x82J\x18\xcd'\x12\xeaJ\xa7\xd5\ +\x95\xe9V*\xd3\xa5h*\xadP\x22\xaep,\xa6n\ +\x840\xbcr\xa5b\x1c\xcf\xce\xce\x96\xcf\x9c9\xf3\xc5\ +o|\xe3\x1b\x9f\xfb\xfa\xd7\xbf\xbe,\xc9{\xbd\x04\xe0\ +\x8c\x8e\x8e\xc6\xbe\xf4\xa5/\xbdc\xcf\x9e=\x7f\x8a\x89\ +\x0e]\xd6x>\xaf\x1cLOOM\xe9\xfc\xb9\xf3:\ +s\xf6\x8c&&&4\x03\xf3\xf8r\x87qk\xfa\xc2\ +=\x1c\xa3}I\x01\xc7\xa7\x00\x18\x10\x0a\xf8\x15E\xcb\ +\x89HT\x19\xcc\xbf\xaf\xa7[\x83\x83\x83\xea_\xb1B\ +\xe9\x81\x01E3\x19\x85\xcdy\xce\xadZ\xb5J\xc2r\ +\xce\x9d;\xf7\xea\xc1\x83\x07\xff\xf5'?\xf9\xc9\xe7]\ +>\xaf\xb5\x00|\xb7\xdcrK\xf7\x97\xbf\xfc\xe5\xff@\ +H\xfb\xb7f\xed\x98\xa0\x0aPvqQ\x13\x17.\xe8\ +\xc4\xf1\x13\x1a;~Lh\xc72^.\x96\xd4\xdb\xdb\ +\xa3\x95+\x86\xd5\xc7\xd8\xdd\xd5\xa5X$\xa20\xbe\xde\ +lx\x06\x0f\xb8\xa7\xa0\x02\x02\x5cZX\xd0\xfc\xf4\x0c\ +4\x8d`\x9a\x8a\xe0\x06)\x5c\xa0\xbf\xa7G+V\x0e\ +k\xc5\xea\xd5\xca\x8c\x8c*\xda\xdb\xab8\xc2\x19\xe5{\ +_\x7f\xbf\xc0\x86*\xd8\xf0\x1f\x1f|\xf0\xc1/\xe3\x22\ +\x95\xd7J\x00\xfe\xb7\xbf\xfd\xed+>\xff\xf9\xcf\xff\x05\ +Z\xb9\x1b`\xb2\x8c\xe7\xd0\xec\xe4\xc5\x8b:\xfa\xca+\ +:\xf0\xd2K:~\xf2\xa4f\xa6\xa6\xf1\xd9^m\xdb\ +\xbaU\x9b7mR\x22\x1c\x91\xaf\xe9\xc9\xef\xb5\xc81\ +\x04\xf3b\x84\xacE4\x0cq\xecr_\xb5Z\xb3s\ +\x9e>vL\x0b\x08\xd1\x80c\x12\xb3\xef\x87\xf1\x950\ +\xbdb\xfdz\xa5V\x8d*\xc2\xf7\x01\x5cb\xf5u\xd7\ +Y\xa0E\x08_\xf9\xd4\xa7>\xf5\xe0\xc9\x93'\x8b?\ +/@\xfa\x7f^\xe6?\xf0\x81\x0f\xac\xf9\xccg>\xf3\ +H\x7f\x7f\xff\x9d&D\xe5\xdb\x1a;16\xa6\x1f\xfe\ +\xf0\x87z\xe2\x07?\xd0\xcb/\xbf\xac\x01\x16\xf5\xcew\ +\xdc\xa3\xbbn\xbf]\xd7\xa1\xf5\x0c\xbe\x9d\xc4T\xd3j\ +Q\xaaC\x9cKJJt\x88sq\xc6\x18n\x11\xe7\ +Zo2\xa5u\x1b\xd6i\x04\x06k\x08\xb9\xb0\xb0\xa8\ +\x12\x02/\xf27kKK\xf2U\xaa\x0a \x98J\xdd\ +U\xae\x84\x95\x81\x0f\x03\x03\x03\xbbn\xb8\xe1\x86\xadX\ +\xc4c\xe7\xcf\x9f\xaf\xfe\xaa\x04\xe0\xbf\xf3\xce;W~\ +\xf6\xb3\x9f\xfd_\xc4\xf5[\x0d\x8a\x1b\xb3\x9f\xc3L_\ +\xda\x7f@\x8f=\xbeW\xcf>\xfb\xac\x5c|\xfb\xbd\xbf\ +\xf7{\xba\xe3\x8do\xd4 \xc0\x95\xc2\xa7\xd3N\x87\xe9\ +\x0e\xb3\x0e\x0c\xc2\xa4\xa4\xa81\xf1&$\x99\x11\xe2\x9c\ +\x19\xa1\x98\xbd\xc6y\xac\x22\x01&\x5c\xb7n\xbd\xba\x01\ +\xc4\xfc\xf4\x94\xaah\xba\x9c\xcb\xab\xba\xbc$\x87\xb5\x84\ +\x88\x1e\x0d\x9f\xa3<\xc7\x19\x5c\x05!l\x02\xa36\xee\ +\xdb\xb7\xef\xbb\xe0R\xfd\x97\x15\x80\x8f0\xd7\xff\xd0C\ +\x0f}\x85\x89\xef\x00\xc4\xac\xd9O]\xba\xa4\xe7\x9f\x7f\ +^\xff\xf7\xb1Gu\xe8\xe0A\xed\xda\xb1C\xff\xfc\xde\ +{\xb5\xb2\xa7W\xe9\x0e\xe3Wh8\x0a\x85a\x0c\xaf\ +W\x00\xc6\x02\x8c\xfe\xa6 F\xafu\xec3\xc7\xf6\xba\ +!)\xc8\x18\x16\xe4\xf1\x9c[\x07;\x12\x1a\xc1\x22\xaa\ +3s\xaa\xb1\x86Z\x89\xd0JD\xb1B\xf03#\x96\ +\x96\x03\x8c\xbb\x00JB\xe6&\xb2\xd0\x81\xef\x7f\xff\xfb\ +\x8f\xe3Z\xee?V\x00\x0ey{\xea\xe1\x87\x1f\xfe\xcf\ +k\xd7\xae\xbd\x8fXn23M\xc3\xfc\x8f\x9f{N\ +\x8f\xed\xdd\xab\xb3\xa7O\xeb\xdd\xef|\xa7n\xdb\xbdG\ +]\x80Z\x86\x85t\x18\x8fY\xa6a\xb6\xcd\xa4E|\ +3\x1a\xbfoB\x1c7m$h\x8dj\x9fw\xec\xbd\ +\x8c\x1d\xe1X0l2Y\xddZ\xcf\xf0\x9a\x0dj\x10\ +N\xddB\x8e0ZS=W@\x08e,!\x88\xa4\ +#*\xd6j\xd6\x1dX\xfb.\x92\xb3e\x84\xb0_\xcc\ +\xfe\x0b\x0b\x80\xb8\x1e\xf9\xc2\x17\xbep\xefm\xb7\xdd\xf6\ +_\x00<\x1f\xcc[\xb3\x7f\xe1\xf9\x17\xb4\xf7\xf1\xc7u\ +\x11\xc4\xbf\xef\xf7\x7f_\x1b\x09G]\xf8b\x06\xcd\xe3\ +\xd7v\x91!\x18hi\xb5\xcdX\x9b\xa9\xa6e\x9a\xb1\ +}\xac\xf6\xb1\xda\xc7\xba\xea\xd8\x8e\xac\xc3S \x0d@\ +:\x9eBE\xc9)\xd75\xb4\xf6:5\x96\xc1\x027\ +'\xa7\xee\x22\x84\xa2\xfc`B\x08\xb0m\x1a!\x10\x0d\ +\x07\x08\x95\xe4\x0b\xbfC\x8e\xf2\x14.:!f\xfcE\ +\x04\xe0\xa7\x80\xd9\xf4\x91\x8f|\xe4\xaf@\xe0\xa4\xc9\xe8\ +\x96\x09s\x07\x0f\x1c@\xf3\x8f\xeb($\xc7mX\x06R\x83\ +CV\x83\xfcU\xc34t%\xf3\x8d\xd6\xb1q\x11\x09\ +\x0d\xaf\xd3\x10\x89\x12\xcc\x9bs\x96<\xa8\xf3\x8c\xb8\xbf\ +\xd1,+\x90\xea\x95\xcf\x0aQ\x10\xff\xb3\xd7 \xc6\xfa\ +rN\xabo\xbcI\xc9\xe1^%\x03\xb8 \xcf\x08W\ +uO\x9fU\x1dA\xd4\xb39\xcd\xce\xcc\xa8\xbb\xbb;\ +z\xeb\xad\xb7\xfe\x91\xa4\xf0\xcf\x12@\xe0C\x1f\xfa\xd0\ +\x1b0\x99\xdb\x0d\xf3\xb5r\x19\xb0\x9b\xd0\x91\xc3\x874\ +KN\xffO\xde|\x87\x92\x86Q(\x0e\x85x\x9a\xe5\ +KV\xe3\xaee2\x92Ljh\xcbf\x05\x11V\xc7\ +\x0a:\xccs\xc0\xf9\x80\x86wnSzh\xa8\xe3\x16\ +\x1d!]\x1e\xbd\xf635\xaf\xa6h\xba[\xf8\xc85\ +Vd\x05V\xab*Fj\xdd{\xfdv\xd2\xeb\x16w\ +\x81Z]M\xc0\xba\x81\x00<\xb2\xc8\x02\x0a4%\xf8\ +\xca\x95+\xdfs\xdf}\xf7m\x90\xe4\xfcT\x01P\x8b\ +'\xdf\xf6\xb6\xb7\xddO\x1d\xef3\x0f\xe5\xc9\xc0\xc6O\ +\x9e\xd0\x19\xd2\xdb5\xc3+\xb5\xb2;\xa3d\x87y\x16\ +\xe4s\x01\xa6\x96j4s\xfc$~X\xb1LS\xda\ +\xe2\xab\xa4\xc0}\xbdW\xb9Cr \xad\xe4\x86!\x85\ +\x13!\xfb\xbd\x01hM\x1dyE.\xc2\xbe\xc6m\x9a\ +\x8c\x12\xf7\xa6%\xe6k\xaa~\xf9\x9a\xd7\x06S_\x90\ +hC\xe1\xd4\xbdy\xbb\xc2q\x8a),/d\xc2-\ +\xb9\x81&\xa7\xe4R\x8c\x09%.\x92=\xd2\xa3\x08\xdd\ +~\xfb\xed\x1f5l\xfe\x14\x01\xd8\xa4g\xd5\xf0\xf0\xf0\ +\x9bm\xd3\x02\x9aE\x92\xe3\xc7\x8f+73\xab=\xdb\ +\xb7+\xe1\xb5\x98\x0f{m4\xae\xd4D\x1b\x0b3n\ +\xa8\x92]\xd6\xa5#GT^Zj#\xbb\xd4C\xde\ +\xde\x0b68\x8e\x0f\xd7X\xad\xae\xf5\x83r\x9d\x966\ ++\xa4\xd2\xe7_xAY\xf2\x8a+5\xebY\x17`\ +l\x0b\xc3O|\x0f\xf6\xad\x92\x17\xc8\x09n8Wc\ +\xee\x9a\x821O\x91\x95\x09\xa5F7*>0\xc2\xf7\ +\xa0e\xc6/Y\xc5\x80\x8ej^\xbcd\xb1\xa0\x8a@\ +\x5c\xce\x01\xea\xef\x06\x13\xd3?M\x00\xa1\xfb\xef\xbf\xff\ +\x1e\xc2^\xcc\xdc\x5c\x06\xfd/\x9e;\xa7KP\x17h\ +\xba\xb2\xaf\xcf2\x1f1\xc9\x89\xf5A4X\xc2\x02\xaa\ +,\xcao\x17k59\x05^,\x9d\xbf`\x90\xdd2\ +\x11'=\x1d\xdd\xbdK\xc9\x15]*\xe3\xef1\xc2\xd4\ +\xf2\xc4\xa4.\xec\xdb\xafj\xbe\xd06\xfdF'b@\ +\xae%\xbe[l\xa9\x15s\xea\x1e\xdd,gx\xbdj\ +\xf1\xaa\xea\xe1\x05y\xf1\xac\xbanZ\xa3\xfe7\xbf\x13\ +\xdcY\x05X\xc28@\xe9H\x90\xcd*\xad\xe6\x1d\x98\ +\xaf\x9d?/\x1f\xf3\x93\xbe\x1b+\xe8\xff\xd8\xc7>\xf6\ +\x96+\xf9\x0et\x0eL\xbc_\xb7n\xdd?\xb5\xfd:\ +\xc8\x80\xdf\xc4\xd9s\xca\xcf\xcdi#\x05\x89a>j\ +\xd2R\x99,\xcd\x11\xff\xc1\xb0\xf19O5\xbf\x83\x96\ +\x1bb\xdd6~/\xf2\x5cyiY}\xeb\xd6\xcaG\ +\x8d/\x01X*)\xda\xb7Z\x0b/=\xa5\xec\x899\ +\xee\xbd::t\xa2\x87\xeb\x95\xe4sL\x1e\x11V\x80\ +FIa\xfa\xacb=\x03\xea\xb9\xee\x065\x86\xd7\xa9\ +^)\xda{\xd3<\xeb\x0f\x84T/\xcdk\xf9\xcc\x01\ +\xf98\xbe\xaa\xbcu\x11\x22\x19ccrR>\x5c\xb3\ +\x1a)\x8b.\xb4FFF\xee\x91\xf4\xb7P\xf5J\x01\ +\xf8\xe8\xeb\xf5Q\xeclC\x00\xb6F_\x9a\x9f\xd7\x0c\ +\xc0\xe7\x15\x8a\x1a\x1d\x18\x84yO\xe0}\x0b\xf4\xd4\x12\ +\x00\xa7\x14*K\x95LB=#a\x92\x91\x90\xb8l\ +\x85 \xa8\x00\x08%\xfa\xfbY\x5cU\x0d\xe2}\x94\x92\ +6h\xd2e\xaaD\x0b\x1d\xedL\x11\x8bi\x9b\xbd\xcb\ +\xbc\xf4\x06\xca\x05%\x82CjT)tf/\xa8\xd0\ +3\xc8<+i\x93\x05\x99+m\x05@o\x0d!V\ +U\xbc\xf4\x8c\xca\xf3\x17\x98,pu\xaag\xc0\xb5\x84\ +0\x97\xb3\xaa\xd3\x91\x0af\xba,\x18\x92\x22\xdf*)\ +~\x8d\x00\xde\xf7\xbe\xf7\xed\xa4\xe7\x962u~\x1d\xbf\ +^d\xf1\xb9\xf99\x85x\xa8/\x95\xb4\xa6\x1f\xb8B\ +\xfb\x12\xa3DN\x8ee\xf4\xd3\xcc\x1c\x1aT\xaa\xe6\x80\ +\xcc-!HV\x10-\xcd:\x15\x852\xd7Y\xbbK\ +v\xf7\x90\xae&a\xfc\xef\x05\xb5l\x05\xd0\x10\x12\xc0\ +\xd7\xc1\x1f\xa7.\xa9\xc6\x5c\x01B E\xce\xd8\x8f\xd1\ +\xf4\x0dJ\xaf$\xc4\xcai'W.e\xf2i\x15'\ +\x9eC\x18\x01k\x8dWI\x80c8\x96C\x16[\xa3\ +?\x11\xdb\xb8\xd1\xe2U2\x99\x1c}\xef{\xdf\xbb\x96\ +V\xda\x92\xb9\xab\xe3\x0b\xc1\xcd\x9b7\xefhX\xe0\xf1\ +l\x03syvNU\xe2h\x8c\xefi\x906\xc8\x1f\ +\xf5u\x90\xda5\xe4Zr+\x1cg\xb308H\xd2\ +\xe2Z\xc1\xe2\xfbh\xc7\xf8\xb1\xa1\xba\xdc&\x85Lw\ +\x9f\xd5x\xc7\xd4\xbd\xcbs\xb9\x1dt\x87`<\x880\ +\x09}\xccc\xaec\x05~\xf9\xf2!\x95O\x1d\xd0\xc2\ +\xab\x879\xc7\xf9\xa6\xc1\x9e%\x15\xce?\xa6\xc2\x1c\xbd\ +\x01\x04_\xcf_[\xf9\xda9\xc1\x19\x17k\x0eJ\x82\ +?\xdb~\xa7H\xba\xd1(\xfdJ\x0b\x08c\x1a\xd7\x99\ +\xf0\x02Y\xd4,\x90P\x08A$\xda\xa5l\x80\xf3r\ +\x98T\x90s\xd9\xd3l\xde\xdfX2\xa5\xe9\x9c\xa2\x83\ +k\x94=\xf4\x8c*\x97j\x1d<\xb0\xc5LxuL\ +\x99pT$\x16Z\x9a\x9c\xe0\xba\x07\xe3\xcd\xcb\xe9\xb0\ +[\xad\xd1\xe8\x98W\xe0bE\xd1\xeb\xd7`\xe6a-\ +\x1e;\xa2\xca\x82\x1f\x86[\xf7\xf8\xfc5\x85\xce\x9dV\ +\xa3VQ\xd7\xaa\xf5\x98\xfe\xb3\xaa\xcc\x8f\xa9\xb4\x80[\ +\x16\xa5z\xe1\xda\xfe\x07\xcc\xd8\xf4\x98WNVy\x00\ +\x9d=\x0d\x18\xaeo\x0b\xa0a\x05@\xba\x18\xe5\xe4h\ +[\x006\x01*\xe7s\xf2\xd7\xea\xb6;\x13p\xeb\x98\ +b\xf8\x1f,\xa8<\xa8V\xc0\xdf'N\xabg\xe3\x0e\ +\xe5\x87F\xc9\xc2\x9eWy\xc13\x8b\x87\x19hh\xc0\ +@3\xa1*\x8e5\xc0,\x9d\xe2F\xa5S\x00Y7\ +\xc1\xda\x96T\xca\xe4\x94\x19\xb8\x9dgi\xa2^\xbc\xa0\ +\xfc\xc5\xc6U@\x19\x8cs_\xed\xbb\xf2n\xbdY\x95\ +\xc9\xa7T^\xac\xa9Y\x8c\xaa\xe7\x96\x0b\xb8\x90\x09\x93V\x8b\x00\x1eR\x07\x89\x0b\ +S\x17\x94\x1aY\x85\x80|\xea\xdd\xb8U\x8d5h\x5c\ + \xbc1{\xeb\xaf55\x8c\xf6K\x05\xc6 \xb1\xbf\ +d\x05P\xcb\x17H\x84z\x94Y\x13\xa3){\x09,\ +\xc1\xdd\x96\x22\xcc[G\x00\xb3\xed\x90\x07\xb9\x0e.\xd4\ +\xb4\x02\xa8\xe6l\xc8\xb2\x82\x11\x14\x08\x87m\xe9\xcdw\ +S\x17\x94\x0c\xcfW\xba\x80\x0b\xff\x95\x8e\x00\x02\xc1\x80\ +\xc2\xc1\x90\x15@\xb3\xcc\x12\x17\xa7\xd4\xe08\x944<\ +\xa3\xd5+\xfc\x1f\xe2$\xa3\x9f>},i\x05Q[\ +\x9c6\xa6\xd9\xbe\xee\xb6\xcc\xb9\xe8\xd3\xd2\xf1\x83h\xc6\ +0U\x13\x92\xc4Mp/\x88c\x90\xd8\x1690K\ +1U*\xa3\xd5\xcb\xee\x86\xe6\xfd\xa4\xc3!U\xaa\x13\ +\xe4\x13E\x04\xd0$\x22\x04@\xff)\xee\xab\xb5u\xd0\ +\xae\x03\x1c\xc1,~\xcf\xd8\xd6&k\xf3)\x9cL^\ +\x16\x00\xd6^\x96\xe4]i\x01U\x8a\x85,\x17\xe4\xf0\ +/\x88\xb4\xa2\xd4\xf3\x05S\x86V\x1cU/M*\x0a\ +j\xbbKS\x0a\xa7C\xaa.\xb9\x1d\xe5c\x15\x14H\ +]R3\x19U\xbc\xb7Ou\xb4_\x9e\xba\x88\x00\x0c\ +\x006!\xd7,\x02\x018*-\x9eRa\xc3F\xac\ +`\xd4j\x85\xa7\xda\xebh\xf97D\xec\x9fF\x0eM\ +\x0b\x82\xa3\xb7\xdcl\x05\x10\x8c\xfa\x15\x88\xcf\xca\xf5\x16\ +PBYq\x94Q\x9e\xe182\xafj\x10\x86\xeaj\ +\x15D0nJ\x82\x9a\x8dm\x86\xe0\x06\x1e\xcb\xe0^i\x01\x15^7_h\xa7\x8a\ +V\x00q:-a\x80\xcaqr\xaa.7\x95;\xfa\ +\x8a\x86n\xbcY\xdd\xeb7\xca\xb9~7\xfe\x99g\x81\ +\xb8E\x22i\xcd+\xc4\xbd\x1e\x0c\x94.\x9e\xc5\x05L\ +b\xd2\xb0!\xc8F\x08\x00\x94\x0f~KY\xfa\xea\xb8\ +J7lSjhX\xb0)b\x94\x05N\xdb\xe2\x22\ +o\xaf\x13J\xddR\xc8\x0a\x8e\x05\x83\x17u\xc6Y\xc5\ +z\xa9'\xd21\xd6\xd3$\xaf\x99Pb\x10T\xc7\xdf\ +\xb3\xb1\xba\x92\x83\x8eUT\xac\xdf\xa36\xc1\xcc\xc9\xf0\ +\xf9\x87\xc9\x1b\xcb\x89\xcbGc\xc6o\x92 \xe6\xe7c\ +6[\x9cfh\x5c\x89\x01\xb51>n\xfb\x8f\xfa\x90\ +Z\x82\xfa?\xc2\xc3LbM\xac|>\xaf\xe9\xe7\x7f\ +\x04C%\xf9\x9d\x0a\x85\xc9\x08L\x0c!q\xeeql\ +\x1eO<\x9e!\xef\x9e\xc5\x8fm(m\xbd\xf4\xb4\x16\ +\x00\xd5M\xdd@\x9a=WPi\xf2\x02\xf7W\xed3\ +\x1e\xd4tI\x9d\x99\xb7x\xe1\x04\xe8^6\xf7\xd9n\ +\xd1\xf9g\x9f\xd3\xf4\xb1\x1f\xab\xb4|F\xd1\x01?\x16\ +f\xc2\xd5\x8c\x22\xe9\xb8B\xa9\xa8b\x03A\xf5mu\ +\xd4\xb3\xc9S\xcf\x96\x06\x02\x90M\xd6\x1c\xd7G\x04\xf3\ +\xb56\x5c\xa0\x9c8\x1dg\xe1\x0a\x9dL\xf7\xa5\x97^\ +:r\x0d\x08>\xf9\xe4\x93\x87y\x97V278\x94\ +\x9dq\x04\x10\xc5\x0a\x8c\x095%\xea{)w\xf8\xa8\ +\xe6\xc7\x0ea\xdeyb\xef\x84\x8d\xd9\x96\xbc\x9a\x05\xb7\ +\xfc\xe9c\xc4\xe6&\xd7=\xcb|\xc7\x05:\x84P\xb8\ +\x86 \xb0\x1e\x98\xb7f\xcf\x09\xc2$\xf5\xc1\xf4^\xcd\ +\xef\x7f\xc2j\xd0\xabY\x90E\x08\x15\x18h\xd0\xf1\x09\ +q\xef\x12\xe7/\xe2\xe70\x97HQ|\xf5p-N\ +\xe1\x14\xa2\x90\xf1\x81\xfc\xed0XC\xf75\xbf\x22N\ +\x00\x1c\x8b\xc9\x0b\x85\x08\xbb\xf4\x12L\x94\x810\xffi\ +\xb6\x1b\x9d\xfcI\x10\xf4\xf8\x5cd3\xc3\xab\xd4\x04\xdb\ +H\x15If2JP\xe2\xe6\xe9\xa8\xd8\x5c\xda\xe5\xe1\ +\x0b5\xcd=\xff\x14\xdd\x9d!\xc5\xfa\xfaU]0f\ +i\xea\xfd\x10\xe05\xa7:UW-\x171\xcc\xb6\xa3\ +\x83\xc9\x0f`\x1eWA\x8a\x9cs\xad\xc9\xe3\x9b0X\ +\x80\xa1yy\x953\xb8\xd8Q\xacb\x99\xe2\x8645\ +\xe0\xb4\xdcG\x02\xe9#X\x98A\xf5ypaI\xa1\ +\xae\x1e\x1a\x17q\x14\x94\xa0Y\x02@\xc3\xa4pQ\xb1\ +6a1n\x1d\xedW\xc0\x8c\x0a\xd1\x05s\xf1'S\ +\xaat\xa5q\xdb\xf5\xca\xb67f\xcd\xcf\xcf\x1f\x94\x94\ +\xfd\xc9\x96X\x13\x9a\xc7\x0b\x9e\x05!\xad\x99\xf81\x9d\ +\xf4\x9a5\x0a\xa6R\xed\xa6\xa4\xd0\x9c\xa3\xfcI\x1a%\ +\xfb\x9eFq\x86\x812B\xb8\x00\xd33\xaa-/\x81\ +e\xa1\xab\xc2\x97\x07\xb5\xcd\x1fB\xe3j\xa0A\x97\x89\ +.\xaa:\xbf\x17\xac\xd8\x8b\xc6\x8f2OVE\x84\x0b\ +\xd6\xd8\x8c\xceA`\xe4\x06<_g\xfe\xf3\xcc;K\ +h\x0e\xc2xD\x0e\xc2\xf6\x05\xad\x10\xf0\xeb.\xe6\x8b\ +\xf3\xbd\xdd\xaa\xc9\xe1\xf7eBx\x1d\xed\x93p\x053\ +\x19\xa5\xae\xdf*_\x81v\x22a\xae\xdb\x82\x04\ +\x90B3i\xa8/ \xc0\xc5v\x8b\xb9\x04\xb3.\x89\ +H\x85P\x9b'\xf5\xbe\x84\x15\xd4Z\xcf\xf8Mv\x88\ +@\x8a\x97k\x14\xdc\xa3l\xdd\x11\x0d\xb5\xdc\xac\x0eU\ +\xb87\x8f\xd5,\x04\x14\xc8\x13&\x11\x8cG\xdc\x0fl\ +\xda\xa0$/o\xe7\x0ay\xdb\x0db\xd3\xc4\xe3\xf9b\ +q\xcaJ\xf2Z\x01\xd8\x93\xb3{\xf7\xee}\x84\xf6\xb8\ +\xd9\xdc\xe8\x04\x89\x02I\x04P\xe4\xbd\xa0ry(g\ +\xb5Z+8\xca\x9d\x9e\xd7\x12\xe7\xfb\xf7\xec\x84\x11Y\ +\x8d7\x1d\x17\x01\xd5)T\xa6h^Vl\x1c\x0fc\ +\xce\x84\x22P\x1b\xad$s\x8a\x0fa]2a\xcf\xb1\ +Y\x9c\xc7\xc2\xb2/_\xd2\xfc\xcb\x0d0\xc6\xa7df\ +\xb0S\x9e\xd8fK\xad\x14\xc6]|\x8a\x90\x03x\x80\ +&!\x02\xa1v\xf3\xf7\x10\x08.\xa8\xb2\xd1\x08\xb82\ +\x8b\xf6\x970\xff2\x18\x80\xdb\x9e%\xc3\xdc\xf0\xcf\xde\ +\xad\xba\xcf\xe9\xecUt\xbf\xff\xdd\xef~\x05&K\xe2\ +s\x8d\x00:I\xd2\xfe\xfd\xfb\x1f\xc7\x0a^\xd9\xbe}\ +\xfb6\xfag\x0a\x00\x84]\xbbviy\x0e\xf3\x86\xa9\ +&\xa4\x860Yr\x83S\xa7\xd4\xbdi-\x0cF\xf0\ +\xd7\x12=\xfeW\xb44\x0ec-\x03\xb3\xa6\x7f\xfe\x99\ +\xe7\x8cU\xab{\xa3\xc7\xcbM\x97L.\x88\xb5\xa0y\ +\x00\x8bf\x08\x02\x80\xc9,\xe93\x9a\xf3\xc8\x00'^\ +\xdc\x7f\xe5\x0e&\xee\x97Fv\x01\x8e\xfdT\x99}0\ +i\xe6u\x0a\x08\x1d\xa0-\x928!w\xf9\x15\xb0\xa0\ +,\x8c\x11\x80t\xacic\xe1$URz\xb5\xa7\xde\ +U\xaezw\x05@r\x98\x08\xf9\xb0\x0e#\x00!\x08\ +\xfc\xff\xac\xa7\xec\xb4\x0f0u\xaei:\xe1]`\x90\ +\xa3D\xccS\xa8\xa7\xfdr\xd4\xb6\xa1X\xc32\xda\x9f\ +\x02W&\xb9\xe7\x22 Y\x00$\xfb\x07u\xaa/\xa5\ +\x1d\x0f\xfe\xa1j\x91\x90IzD\x92W\xfb\xc6#\x8f\ +<8~\xf6\xec13\xe5\xcfz=\xee\xb2\x0du\x86\ +wi\xdb\xd9j\xb2&\x12\x8d\xb2\x80\x98\xc2Pin\ +\x16\x90\xa1/\x8f\xd9\xa2=\x00\xad\x81\xc4'\x15\x0c\x9d\ +\xc5\xa5+\x80\x95\x09\x18\xd4\x06\xa4\xa6\x804\xcd\x89\xa6\ +\xba`\xbege\x83f\x87\x0f@\x0d`\xbeA\x9b[\ +\xd8\xac\xa6-\x80\xfa\x82G\xb2\xe3Si\xde\x0a\xa5\xa3\ +\xfdN%k)\xc1\x5c\xb1>\xb5\xdc\xad\xc1\x89<7\ +\xceP\xfa\xe2\xd1\xc1i|?k6G\xf4\xea\x04\x09\ +\xd2\xba\x7f\xf7QEy\xf9\xbaHd\x9a\x9b\x9bc/\ +\xd3\xfe\xaf\xfd\xcd\xc3\x0f?d\xf2\xb9\x9fw\x83D\x89\ +\x0d\x88\xb3\xec\xb8z\x07\x1b\x0c\xc20o\x22\x01B\x88\ +\xabD\xf9\xe9\x00\x88\x04][v\xc6\xd3\x15\x16\xd6\x80\ +)\x07@t8\x86\xf1\x98\xc7\xf9\xa6R}\x9e\xd2\xc3\ +M\xa5\xb7\xf81_|3\x12\x82\xa2X@\xbc\x85\xe0\ +MY`\x13\x0c\xb9\xcb\x9e\x0a\x0b>\xacG\xd7~\x9a\ +\xcc\xdb\x83\x10\x98\xd3f\x83&\xdd]\xa0\xc4\x9d&\xde\ +\xcf`U\xb90\x80\x99\xd1Y\xf2\xfd\xf0\xbb\xde\xae\x91\ +\xb7\xbdU\xd9r\xc9h\xde\x00\xdf\xe4\x9f\xfd\xf1\x1f\x7f\ +\x14\x0c\xb8\xe42\xd3\xcf+\x80\x06~3\x07r:\xec\ +\xc8\xbc\xdd\xb8B\x10!\x180\x0bCe\xfas\xbeJ\ +\x99\xa2\xa4\xa6D\x0f\x9d\xa3^\x13\x8d\xa0\xa0lF\x16\ +\xee\xf6Q,\xf9\x14\x1d\xf6\xa3u?\x11\xc1h>\x0c\ +\xf3\x09\xf0 E\x0c\xa74\x05\xc5e0\xc0\xad\xdb\xf6\ +\x99\x93m\x08x\xa4\xd1i1\xe4\xca\x8f-a\xa3\xcc\ +\x99I\xca\xbe-\xf2-\xa2\xf1Y\xfc}\x0e\xca\x86\xb9\ +\x9e\xd6\x85DF\xb9\x9bvk\xcb\x07\xff@E\x22\xce\ +,\x9a'\xb3s\xbf\xfd\xcd\xbf}`\xec\xd0\xa1\xa7\x8b\ +\x92\xfb\x8bn\x922\xfb\xf4\xcf\xd0._\xcb\x0b\xc5\x8d\ +\xc6\x15\x82&\xb4%\x13\xb6\xf8\xa9\xd0\xc5M\xc6K\x8a\ +g\xaa\x14DM+\x00'\xe0 \x04S\x81\xf9\x18a\ +:\x1c\xe0\xd8j\x1dJ\xf2=\x0d\xf3\x90/\x81*Z\ +M\x10\xe2\x9a\xb5\x82\x00V\x13,!\x04bw5'\ +\xce1\x9f\x98\xcbA\xd3\xe0E\x17\x00\x98\x89\xa0\xf1:\ +\xf9\xfdBX!(\x987\xf9FZ\xe7H\x17g\xe8\ +\x18\xedx\xe0\xe3\xaa\x04\xfc-\xe6\xd9\xd4\xf1\xdc\xd3\xcf\ +\xfc\xf9\xb7\xbe\xf6W\x7f\xcet\xc5\x7f\xcc.\xb1&T\ +8v\xec\xd8\x89\x15+V\xec!\x22\x0c!\x04k\x05\ +\x81T\xca6)k\xe5\x9cR\xdd\xe6]^\xcd4%\ +!A~\xcc\xd1o\xb23\x98\x07\x94\xc21L>\xc1\ +\xf7\x14\xe7\x93\x5c\x8fsS\xa8\x95\x83\xd9\x1e\xa3k\xdd\ +\xc9q\xc0\x93\x18~^G\x10)\x1fX@7\x0a\x0a\ +\xd3\x0cIg\x82\x1a\xec\x0e(\x19 E\x07\xe8B\xf8\ +{\xa0L\xc78\xd8\xa3\x13\xfe\x08\x9a\xbfI;>\xfe\ +1U\x10\xfa\x0c\xcc\xa38\xb3\x9f\xe9\xd1\xbf\xfc\x93/\ +|\xb2[\x9a[\xfe%\xf6\x09zhi\xe1\xf8\xf1\xe3\ +c\xbc6\xbf\x0d<\xe8\x09\x1bP\x8c\xc7\xa1$\x05\xd3\ +\xb0\xf2K\xa00\xd5\xa1\xdf\xd6\xf6\x08Ab\x0c0\xfa\ +\xa1\x90\x80>\x04\x84 \xcc\xc8y5\xfc&w\x87\xcc\ +f\xa7\x06c\x83\xb1.Q\x00\xc16\xd6\xe4(\xe9I\ +]4c\xbb2\x01\xf5v\xc3<\x05O\x97/\xacp\ +\x93\x88T\x04C\xdc\x84\xaa\x80\xcd\x8b<\x1f}\xd7\xbb\ +\xb4\xf9_\xfdK\x15\xb1\x94\xe9\x99\x19\xcb\xfc\xcb\x87\x0f\ +\xbf\xf0\x97\x9f\xff\xc2\xbfI6\xea\x13\xe7\xe0\xe1\x97\xdd\ +)J\x16\xeb\xce\x8c\x8f\x8f\x1f#*\x98\x04\xa9'\x1c\ +\x89\xd8L\xaf\x19\x89S\xa7\xaf\x22\xcbJ\xab\x9c\xaf\x90\ +\x81\xd5-S\x0c\xb6*s\xaaP\x05C.\x0b\xe0\x84\ +\xd9\xa2+\x15\xb0\x96b\x95\xe3\x0aTkQ\xc1\x05\xd8\ +\x1a\x8c\xb8P\x09\xcc\x00\xe9\xa2P\x02\x9cH\xf9\xe8M\ +@\xa1&\xd6W\x8f#\xdb\x8c&|Q\x1df\x0d\x9b\ +\x1f|PCw\xdd\xa1,Qijz\xda\x00\x1e\xbb\ +Y\x0e\xbf\xf8\xb5\xbf\xf8\xef\xf7G\xf2\xd9\xf1\xb3\xac\xfd\ +W\xb9Y:\x82\x05\xdc\xc4\xcfa\xfe\x94$i\x17\xdb\ +hD\xe5h7H\x85\xca\x00b~^\xc5\xf1\x17\x15\ +)\x8f)\x1d\x98W\xa8Qm\xed\x0a5\x8dU\xfe\xf9\ +\x9a\x10\xff\x1cK\x9d\xfdN\xed7\xc4\xed\x1e#\x9e\xd4\ +)g\xa1 \xc2\x0c\xa2mF/,LN4\xc14\ +V\xa6\x17q\xd7]\xda\xf8\x9e{\xd5\xc0\x12\x17\xb3\xcb\ +vW:\x95\xac\x8e\x1c<\xf4\xf8_?\xf4\x95\x8fw\ +WJ\xa7\x8fK\xeek\xb1]>D\xc7h+{\x08\ +?\xc5o\x05~\x97\x5c\xc1a\x03\x92\x22!\x80\x093\ +\x8e\x19\x7f\xa6\xa7W>}\x08?=\xa5\x1ee\x11H\ +I\x81j\xc3\xee#\xf0\xd7\x01K[\x11C\xcdv\xba\ +k\x81\xc3ic\x82\x9f\xf3\x86`\xda\xe4\xfah\xde\xa3\ +\x08\xbaXqu\xae\xe1\xd1\x97\xdc\xa3M\xecG\x0e\xb2\ +\x1b-GB\xb6@\x92\xc3\xfe?\xa3\xf9\xc6\x81}\xfb\ +\xfe\xc7\xf7\xfe\xfao\xfe\xebH\xd3\xbbx\x04\x91\xbe\x96\ +?\x98\x08@\xc3;w\xee\xfc\x837\xbd\xe9M\x0f\x12\ +&S\xec \x17 \xa9\xb0\xc9\xfdYh\xdcAa\xc5\ +\x9c\x0a\xaf\x9e\x94&\xc7\x15\x9a\xbf\xa4\x1e\x9a\x1b\x09\xf2\ +\xf6@\x89\xd4\xb5J\xeen\x84\xc0?\xf1\x8c|P \ +\x88y\x87`8\xa2\x1a\xe3T\xa9\xaaY\xee\xa9bi\ +\x03ox\x83F\xd8}\xeet\xa5\xf1\xa0\xaa\x96\xb2Y\ +\x9b\xe1Mc\xf6g\xcf\x9c\x99{\xe6\xc9\x1f\xfc\xa7\xa3\ +\xcf=\xff\xcd\x95\xd4s\x07%\xef\xf5\xf8\xc9\x8c\x03\xa5\ +\xf9\xdcz\xc7\x1dw|\x82\xd7\xcdo\xc6%|\x84K\ +\xc5c1\xbb\x83;,)\xee\x0f(\xe6C\xb3\xe4\xe3\ +EL\xb4:5\xa9\xe6\xec\x8c|0\xa0\x82ywP\ +\xb7U^\xc3T\x85\xe1\x88\x5c\x00\xd6KS\xe3\x0f\xf4\ +\xab\x7f\xcbV\xf5n\xdd\x22\x1fnF\xd9\xa0y\xe4\xc5\x17\xffO\xadTy5\xe8\ +\xd5\x97\x03\xa6`\x93\x9a\xbf\xa9?\x9du\xd4*\x0d\xa2\ +\xb0\xd7\x8d\x81\x0f\xaf\xdd\xb0\xfe\xc6\x15\xc3\xc3\xd7\x03\x94\ +\xab\x12\xc9\xd4\xcap$\x9c\xa6\xf1\x8aW\x04\xc3\xdcl\ +\x18\xaf\xd0\xb2*\xc1\xfc2m\xab\x0b\xecN?79\ +1q\xf8\xec\xa9\xf1\x83\x5c\x9f\xa6\xfa\xcb\x8a>\xd1\xb2\ +\xe4\xfd6\xfex\x9a\xba\x0f\xb7\x97\xc8\xf2\x15\x91\x15\x8c\ +\xc3\xe8\x84\x9a\x9c\xc7\xfc=G\xb8=\x90\xc8\xf52\x9b\ +T\xcb\xa0\x80\xcd\x08\x0c\xd7\xaf\xf5\x8f\xa8\x9d\xdf\xb0_\ +\xad7\xf5:\x7f\xfe\x1f_\xbc\xdd\xe6\x1aS\x0c\xc2\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x0d\ +\x0b4-\xe7\ +\x00a\ +\x00k\x00r\x00e\x00g\x00a\x00t\x00o\x00r\x00.\x00p\x00n\x00g\ +\x00\x0b\ +\x01\xad\xabG\ +\x00d\ +\x00i\x00g\x00i\x00k\x00a\x00m\x00.\x00p\x00n\x00g\ +\x00\x1a\ +\x08\xdd\xe1\xa7\ +\x00a\ +\x00c\x00c\x00e\x00s\x00s\x00o\x00r\x00i\x00e\x00s\x00-\x00d\x00i\x00c\x00t\x00i\ +\x00o\x00n\x00a\x00r\x00y\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x0e\x95W\x87\ +\x00k\ +\x003\x00b\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00 \x00\x00\x00\x00\x00\x01\x00\x00\x13\x0d\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00<\x00\x00\x00\x00\x00\x01\x00\x00 \x17\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +\x00\x00\x00v\x00\x00\x00\x00\x00\x01\x00\x005/\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/animation/appchooser/digikam.png b/examples/widgets/animation/appchooser/digikam.png new file mode 100644 index 0000000000000000000000000000000000000000..9de9fb2f8034a9bae6f4c40ab2d1f713fcfaa08b GIT binary patch literal 3334 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 1.0: + easedProgress -= 1.0 + elif easedProgress < 0: + easedProgress += 1.0 + + pt = self.m_path.pointAtPercent(easedProgress) + self.updateCurrentValue(pt) + self.valueChanged.emit(pt) + else: + super(Animation, self).updateCurrentTime(currentTime) + +# PySide2 doesn't support deriving from more than one wrapped class so we use +# composition and delegate the property. +class Pixmap(QtCore.QObject): + def __init__(self, pix): + super(Pixmap, self).__init__() + + self.pixmap_item = QtWidgets.QGraphicsPixmapItem(pix) + self.pixmap_item.setCacheMode(QtWidgets.QGraphicsItem.DeviceCoordinateCache) + + def set_pos(self, pos): + self.pixmap_item.setPos(pos) + + def get_pos(self): + return self.pixmap_item.pos() + + pos = QtCore.Property(QtCore.QPointF, get_pos, set_pos) + + +class Window(QtWidgets.QWidget): + def __init__(self, parent=None): + super(Window, self).__init__(parent) + + self.m_iconSize = QtCore.QSize(64, 64) + self.m_scene = QtWidgets.QGraphicsScene() + + m_ui = Ui_Form() + m_ui.setupUi(self) + m_ui.easingCurvePicker.setIconSize(self.m_iconSize) + m_ui.easingCurvePicker.setMinimumHeight(self.m_iconSize.height() + 50) + m_ui.buttonGroup.setId(m_ui.lineRadio, 0) + m_ui.buttonGroup.setId(m_ui.circleRadio, 1) + + dummy = QtCore.QEasingCurve() + m_ui.periodSpinBox.setValue(dummy.period()) + m_ui.amplitudeSpinBox.setValue(dummy.amplitude()) + m_ui.overshootSpinBox.setValue(dummy.overshoot()) + + m_ui.easingCurvePicker.currentRowChanged.connect(self.curveChanged) + m_ui.buttonGroup.buttonClicked[int].connect(self.pathChanged) + m_ui.periodSpinBox.valueChanged.connect(self.periodChanged) + m_ui.amplitudeSpinBox.valueChanged.connect(self.amplitudeChanged) + m_ui.overshootSpinBox.valueChanged.connect(self.overshootChanged) + + self.m_ui = m_ui + self.createCurveIcons() + + pix = QtGui.QPixmap(':/images/qt-logo.png') + self.m_item = Pixmap(pix) + self.m_scene.addItem(self.m_item.pixmap_item) + self.m_ui.graphicsView.setScene(self.m_scene) + + self.m_anim = Animation(self.m_item, b'pos') + self.m_anim.setEasingCurve(QtCore.QEasingCurve.OutBounce) + self.m_ui.easingCurvePicker.setCurrentRow(int(QtCore.QEasingCurve.OutBounce)) + + self.startAnimation() + + def createCurveIcons(self): + pix = QtGui.QPixmap(self.m_iconSize) + painter = QtGui.QPainter() + + gradient = QtGui.QLinearGradient(0, 0, 0, self.m_iconSize.height()) + gradient.setColorAt(0.0, QtGui.QColor(240, 240, 240)) + gradient.setColorAt(1.0, QtGui.QColor(224, 224, 224)) + + brush = QtGui.QBrush(gradient) + + # The original C++ code uses undocumented calls to get the names of the + # different curve types. We do the Python equivalant (but without + # cheating) + curve_types = [(n, c) for n, c in QtCore.QEasingCurve.__dict__.items() + if isinstance(c, QtCore.QEasingCurve.Type) \ + and c != QtCore.QEasingCurve.Custom \ + and c != QtCore.QEasingCurve.NCurveTypes \ + and c != QtCore.QEasingCurve.TCBSpline] + curve_types.sort(key=lambda ct: ct[1]) + + painter.begin(pix) + + for curve_name, curve_type in curve_types: + painter.fillRect(QtCore.QRect(QtCore.QPoint(0, 0), self.m_iconSize), brush) + curve = QtCore.QEasingCurve(curve_type) + + painter.setPen(QtGui.QColor(0, 0, 255, 64)) + xAxis = self.m_iconSize.height() / 1.5 + yAxis = self.m_iconSize.width() / 3.0 + painter.drawLine(0, xAxis, self.m_iconSize.width(), xAxis) + painter.drawLine(yAxis, 0, yAxis, self.m_iconSize.height()) + + curveScale = self.m_iconSize.height() / 2.0 + + painter.setPen(QtCore.Qt.NoPen) + + # Start point. + painter.setBrush(QtCore.Qt.red) + start = QtCore.QPoint(yAxis, + xAxis - curveScale * curve.valueForProgress(0)) + painter.drawRect(start.x() - 1, start.y() - 1, 3, 3) + + # End point. + painter.setBrush(QtCore.Qt.blue) + end = QtCore.QPoint(yAxis + curveScale, + xAxis - curveScale * curve.valueForProgress(1)) + painter.drawRect(end.x() - 1, end.y() - 1, 3, 3) + + curvePath = QtGui.QPainterPath() + curvePath.moveTo(QtCore.QPointF(start)) + t = 0.0 + while t <= 1.0: + to = QtCore.QPointF(yAxis + curveScale * t, + xAxis - curveScale * curve.valueForProgress(t)) + curvePath.lineTo(to) + t += 1.0 / curveScale + + painter.setRenderHint(QtGui.QPainter.Antialiasing, True) + painter.strokePath(curvePath, QtGui.QColor(32, 32, 32)) + painter.setRenderHint(QtGui.QPainter.Antialiasing, False) + + item = QtWidgets.QListWidgetItem() + item.setIcon(QtGui.QIcon(pix)) + item.setText(curve_name) + self.m_ui.easingCurvePicker.addItem(item) + + painter.end() + + def startAnimation(self): + self.m_anim.setStartValue(QtCore.QPointF(0, 0)) + self.m_anim.setEndValue(QtCore.QPointF(100, 100)) + self.m_anim.setDuration(2000) + self.m_anim.setLoopCount(-1) + self.m_anim.start() + + def curveChanged(self, row): + curveType = QtCore.QEasingCurve.Type(row) + self.m_anim.setEasingCurve(curveType) + self.m_anim.setCurrentTime(0) + + isElastic = (curveType >= QtCore.QEasingCurve.InElastic + and curveType <= QtCore.QEasingCurve.OutInElastic) + isBounce = (curveType >= QtCore.QEasingCurve.InBounce + and curveType <= QtCore.QEasingCurve.OutInBounce) + + self.m_ui.periodSpinBox.setEnabled(isElastic) + self.m_ui.amplitudeSpinBox.setEnabled(isElastic or isBounce) + self.m_ui.overshootSpinBox.setEnabled(curveType >= QtCore.QEasingCurve.InBack + and curveType <= QtCore.QEasingCurve.OutInBack) + + def pathChanged(self, index): + self.m_anim.setPathType(index) + + def periodChanged(self, value): + curve = self.m_anim.easingCurve() + curve.setPeriod(value) + self.m_anim.setEasingCurve(curve) + + def amplitudeChanged(self, value): + curve = self.m_anim.easingCurve() + curve.setAmplitude(value) + self.m_anim.setEasingCurve(curve) + + def overshootChanged(self, value): + curve = self.m_anim.easingCurve() + curve.setOvershoot(value) + self.m_anim.setEasingCurve(curve) + + +if __name__ == '__main__': + + import sys + app = QtWidgets.QApplication(sys.argv) + w = Window() + w.resize(600, 600) + w.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/animation/easing/easing.pyproject b/examples/widgets/animation/easing/easing.pyproject new file mode 100644 index 0000000..2677e28 --- /dev/null +++ b/examples/widgets/animation/easing/easing.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["easing.qrc", "ui_form.py", "easing.py", "easing_rc.py", + "form.ui"] +} diff --git a/examples/widgets/animation/easing/easing.qrc b/examples/widgets/animation/easing/easing.qrc new file mode 100644 index 0000000..7e112d3 --- /dev/null +++ b/examples/widgets/animation/easing/easing.qrc @@ -0,0 +1,5 @@ + + + images/qt-logo.png + + \ No newline at end of file diff --git a/examples/widgets/animation/easing/easing_rc.py b/examples/widgets/animation/easing/easing_rc.py new file mode 100644 index 0000000..26c3165 --- /dev/null +++ b/examples/widgets/animation/easing/easing_rc.py @@ -0,0 +1,361 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x14\x1d\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00.\x00\x00\x007\x08\x06\x00\x00\x00s`xd\ +\x00\x00\x13\xe4IDATx\x9cb\xfc\xff\xff?\xc3\ +\xdf\x7f\x7f\x99\x99\x99\x98\xff>x\xf1Xf\xe9\x9eU\ +\x09\x87/\x9e\xb6y\xf7\xe9\xad\x98\xa4\xf2?~Q\xb9\ +\xbf\xfc\xcc\x1c?\xf8\xfe\xfd\xff\xc7\xca\xc5\xc6\xf7F\x9c\ +[\xf6\x96$\xaf\xd25)>\xa5\xcb\xd2\xbcJ\xd7\xc4\ +xd\xef\x08p\x8a>ccf\xff\xc5\x80\x05\xfcg\ +\xf8\xcf\xf4\xef\xff?&\x06\x86\xff\x0c\x8c\x0c\x8c\xff\x19\ +\x19\x18\xff30Bi\x0a\x00\x00\x00\x00\xff\xffb\xfc\ +\xfb\xf7/3\x13\x13\xd3\xdfY\x9b\x17\xa6T\xcfm\xed\ +}\xf3\xe6\x0d\x1f\x17/\xdb\x7f{/aFYEN\ +\x06\x86\x7f\x8c\x0c\x0c\xff\x99\x18\x18\x18\x18\x18\xfe\xfd\xff\ +\xc7\xf0\xe7\xdfo\x86\x7f\xff\xff00002\xb00\ +\xb12p\xb2\xf0|\xe3c\x17z&\xcc%u_\x9c\ +G\xee\xa6\x04\x8f\xc2u\x09^\x85\x9b\xa2\x5cR\xf7\x05\ +8\xc5\x9e\xb1\xb3p\xfc\xc0n\xf5\x7f\xc6\x7f\xff\xff1\ +\xc39$z\x08\x00\x00\x00\xff\xffb\xfc\xff\xff?\xc3\ +\xa4\xb5\xb3s\xf2\xbb\xf3&s\xf2\x09\xffcgc\xfb\ +\xef\x1e,\xc4 !\xc3\xc6\xf8\xed\xeb?FF\x889\ +\x8cp\x0b\x18\x99\xfe320\xfcg```\xf8\xff\ +\xff?\xd3\xbf\xff\x7f\x19\xff\xfc\xff\x03\xf1\xd0\xbf?\x0c\ +\xff\x19\xfe3\xb00\xb22\xb0\xb3p\xff\xe5g\x17~\ +!\xcc%y_\x8cG\xee\xa6\x14\xaf\xe2u\x09\x1e\x85\ +\xeb\xa2<2w\x859%\x9ep\xb0r}\xc5\xe7\xa1\ +\xffpK\x19\xff1b\xf1\x10\x00\x00\x00\xff\xffl\x92\ +\xbd\x0a\xc20\x14F\xbf/\x16\x7f\xd2\x06!\x83\xc6A\ +\xc5]p\xec\xa8\xbb\xcf\xe2k\xbavp(\xa8\x83\xe0\ +\xd6\xb1\x88 $\xf7:\x88[^\xe0\x1c\x0e\x1c6\xb7\ +\xcbv\x7f:\x9e\x85\xea\xe2\x87\xb2\xabKS\x1f\xa6x\ +\xbf\x04f\x90\x03gL\xa0\xfe\x0a\xa9\xc4\x7f\x8fd\xa2\ +D$\x89H\x1a\xa1*0,0.\xac\xb8\x91\xef\xfc\ +$\xac\xef\xed?\xf7\x00\x00\x00\xff\xff\x22\xd9\xe1\ +\xff\xff10pp23|\xfb\xfa\x87\xe1\xf4\xc9\xc7\ +\x0cR\x5c\xea\x0c^&>\x0c\xc6\xaa\x86\x0c\xa2\x02\x22\ +\x0c\x8c\x8c\x0c\x0c_~}`x\xf6\xe9\x1e\xc3\xb5\xd7\ +'\x19\xae\xbe:\xc1\xf0\xf5\xf7'\x06nV>\x9c\x8e\ +gdd`\x80\x95JL\x8cL\x0c\xff\xff\xffg\xf8\ +O\xc0\x13\x00\x00\x00\x00\xff\xff\x22\xc9\xe1\xff\xffC\x1c\ +}\xe7\xc6\x17\x86\xa3\xfb\xde2T\x84T0\x14\x85g\ +0\xb0\xb3\xb32\xfc\x87T\xe9p\xb5Zb\x16\x0c\xae\ +*\xd1\x0c\xcf??`Xsu\x22\xc3\xe9';\x19\ +\xb8\xd8\xf8\x180\x8bM\x06\x86_?\xff1\xb0\xb0\xb0\ +002\xfde\xf8\xf6\xfb\x0b\x03\x0b\x13\x0b\x03+\x13\ +;^\xc7\x03\x00\x00\x00\xff\xff\x22:;\xfe\xff\xc7\xc0\ +\xc0\xce\xc1\xc4p\xe3\xf2W\x86\x9dk_0\xcc.\x9c\ +\xceP\x19\x97\xcb\xc0\xc2\xca\xc4\xf0\xf7\xdf_\x86\xff\xff\ +\xff\xc1+\x9b?\x7f\x7f3\xfc\xfe\x03)\xd2$y\xe5\ +\x19r-\xfa\x19Bt\xf2\x19\xbe\xfd\xfa\xcc\xc0\x04-\ +\x01\xfe\xffg``ecdx\xf5\xec\x0f\xc3\x92Y\ +\x0f\x18<\xc4K\x18\xba\xbc62\xd4\xd8/f0\x94\ +td\xf8\xf1\xe7\x1b\x5c-6\x00\x00\x00\x00\xff\xff\x8c\ +\xd4!\x0e\xc2@\x10@\xd1?3\xbbu\x0d\x06\x01\x0e\ +S\x82D5X$\xa6\x12\x8d \xe1\x04xn\xc4\x01\ +\xb8\x0ci\x10\x08\x0cI1]\xb6\x83B\x92p\x82\xff\ +\xd4\xff\x0b\xfe\x8d<\xee\x99\xcb\xf9\xcai\x7fd\xbbn\ +\xe8SBE15D\x14\xd3\x80I X\xa4\x08\x05\ +\x0e\x0c\xeed\xcf4\x8b\x03\x9b\xf9\x8e\xae\x7f\xa2b\xb8\ +;\xaa\xc2\xad}\x11\xbd\xa4\xaeV\x8c\xe2\x94j\xbcd\ +R\xcex\x0f\x09\xf8\xfd\xe4\x0f\x00\x00\x00\xff\xff\x22:\ +\xc4\x19\x19\x99\x18\x0e\xee~\xce\xa0\xa9\xac\xcbP\x16\x95\ +\xcb\xc0\xc0\xc0\xc0\xc0\xca\xc2\xc2\xc0\xc8\xc8\xc8\xf0\xff?\ +$\x99\xdcx{\x92\xa1fC:\x83Oe\x04\xc3\xda\ +C[\xa0!\xc6\x08\x0f\xb9\x10\xed<\x06EAm\x86\ +\x9f\x7f\xbe10313\xfc\xff\xc7\xc8\xf0\xf4\xf1\x17\ +\x06m%U\x06\x19Qi\xa8c\x19\x18\xfe\x13Q\x12\ +\x01\x00\x00\x00\xff\xff\x84\xd4+\x0e\xc2@\x14F\xe1\xf3\ +\xdf\xa6L\x05\xeb@\xa0P,\x02\x0dIu\x05\x0e\xc9\ +\x1eX\x09\x8a-\x90`p$x\x12\x14b\x12\x02\x02\ +\x0c\x8f\xb6w\xb0\x18\xc2\x0e\x8e\xf8r\xfe\x86\xa7\x04\x9d\ + \xe2\xe9M<\xde\x99M*B^\xd0\xb4\x0d\x92\xf0\ +\xe4H\xe2p\xdd\xb3\xd8L\x89\xb6\xe5\xd6\xdd1\x9e\x97\ +,\xd7+L\xc2\xdd\xf1\xd4\x92g\x81Q\xaf\xa2\xf6\x1a\ +\x99x=\xc4\xe5\xfcd\xd8\x1f\x00|\xed4\xc3d\x98\ +\x0c\xfd\xe0\xf2\x01\x00\x00\xff\xff\x22\x1c\xe2\xff!e\xf5\ +\x8d+\x1f\x19\x04\x84\xc4\x19\xfc\xad=\x19\x18\x18\x18\x18\ +\x98\xa1-0Xdn\xbe1\x8b\xe1\xdf\xff\xbf\x0c\xec\ +\x0c\x02\x0c\xa6\xe6\x92\x0cr\x9a\x22\x0cU3\xda\x18\xbe\ +\xff\x82\x84.#\xb4\x086\x94t`\x90\xe1Wf`\ +b\xfd\xc5\xf0\xf2\xc5g\x86\xdf/\xdf3X\xe9\x98 \ +,c``\xf8\xf5\xf7;\xc3\xd7\xdf\x9f\x18\xbe\xff\xf9\ +\xca\xf0\xeb/\xf6V1\x00\x00\x00\xff\xff\x22\xe8p&\ +f\x06\x86\x9f\xdf\x19\x18\xee\xdf\xfb\xc8`\xa9c\xc4 \ +%,\x09\x0f\xe5\xff\x0c\xff\x19\x18\x19\x99\x18>\xfcx\ +\xcd\xf0\xe0\xfdU\x06\x0e\x16.\x86?\xff~3\xfc\xfe\ +\xf3\x87ASG\x90\xe1\xe1\xe3\xfb\x0c\x07.\x1c\x85\x84\ +\xe6\xff\x7f\x0c\x7f\xff\xfde`g\xe1d\xe0\xfdd\xc4\ +\xb0b\xfeC\x86d\xd3F\x86\xcd3v0\xb8\x988\ +@\x03\x03R\xc8)\x08j3\x98\xc9\xb83h\x88\x98\ +0H\xf2(`u\x17\x00\x00\x00\xff\xff\xc2[\x1c\xfe\ +\xff\xcf\xc0\xc0\xc2\xc2\xc8\xf0\xfe\xdd_\x86\xef\xef\x7f0\ +X\xe9\x9aB\x1c\xf1\xef\x1f\x03\x133\xa4\xbcedd\ +dx\xf9\xe5!\xc3\x97_\x1f\x19\xd8Y\xb8 \xc9\xe2\ +\xef\x7f\x06a16\x06\x06\xe6\x7f\x0c\xa7\xae\x9dc\xf0\ +4s\x85\xe7\x03\x06\x06\x06\x06MQ3\x86w\x8f\xfa\ +\x19T\xc5\xb4\x194\xe5\xd5\x18\xfe\xfe\xfb\x0bu8$\ +\x16-e\xbd\x19,d<\x19\x18\x19\x99\x18\x9e\x7f\xbe\ +\xcf\xd0\xb0/\x02\xc3m\x00\x00\x00\x00\xff\xff\xc2\x1f\xe2\ +\xff\x19\x18\x98\x98\x19\x19\xde\xbf\xfd\xcd\xc0\xf0\x8f\x99A\ +_E\x8b\x81\x81\x81\x81\x81\x11\xde\x02\x83D\xed\x9bo\ +\xcf\x19\xfe\xfc\xfb\xcd\xc0\xc8\xc0\xc8\xc0\xc8\x08I\xab\x9c\ +\xdcL\x0c\xcc\x5c,\x0c7\x1f\xdf\x83\xebad\x82\xe8\ +\xd3S\xd1d\xe0\xe2\xe3g\xf8\xf3\xf7\x0fn\x8b\x09T\ +@\x00\x00\x00\x00\xff\xff\x22\x98T\x18\x19\x19\x18>\xbc\ +\xff\xc5\xc0\xc4\xce\xc9\xa0 !\x07\x11\x83\x86\x1c\xcc\xe8\ +O?\xdeB\x9a\xa1P\xfe\xbf\x7f\x0c\x0c\xac\xac\x0c\x0c\ +\xdc\xdc\xac\x0c\xcf\xdf\xbc\x84X\xc4\xc8\x04\xd7'%,\ +\xc1\xa0\xa9&\xc5p\xf1\xfe%\x86\xa7\xaf\x9f\xc3C\x1a\ +\x06\xfe\xfc\xfd\xcb\xf0\xfb\xcf?\x14\xbb\xd0\x01\x00\x00\x00\ +\xff\xff\x22\x5cs\xfeg`\xf8\xfc\xe97\x03/\x177\ +\x83(\xbf0\xd43\xd0N\x15T\xc9\xb7\xdf\x9fQ<\ +\xc2\xc0\x00\xc9\x1b\x1c\x1c,\x0c\xef?\x7f\x82\xeb\xf9\x0f\ +\x0dINvN\x86\x88(-\x86\xd4\xced\x06\x13i\ +\x17\x86\xc3S72\xfc\xff\xff\x9f\xe1\x1f\xc3?\x06f\ +Ff\x86\xed7\x172\xec\xba\xbd\x82A\x84[\x92\x01\ +\xa9\xef\x80\x02\x00\x00\x00\x00\xff\xff|\x95M\x0a\x80 \ +\x18D\x9f\xf9C\x88P\xf7\xbf['\x886-41\ +\xfdZ\xb8\x11\x8a\xf6\x03\xf3\x86\x19\x98\x7fp\xd5w\x9e\ +b!\xf8\x85\xe0\xc3\xa7,\xdf\x91\xf1,DzS\xce\ +i\xe2\x95(\xb5`\xb5\x05\x81\x860)\x85\xb7+\xd6\ +\x18\x8c\x1e\x11z\xf4\xd4N\xf6\xbc\x91\xe4\xa0\xb6\x8a\xd3\ +\xf3\xcb\xf3\x01\x00\x00\xff\xff\x84\x97\xc1\x0a\x800\x0cC\ +_\xb7\xae\x9b\xc5\xff\xffW\xad\x16\x0f\x9ed\x03\xef!\ +y\x10\x08\xe4\x7f\xc7\x81\x88d\xb3AW[j\x22c\ +:\x1e\x22\xa0Z8\xe2\xe4\xbac\x82\xf3\xb6\x93\x99|\ +{zM\x8aT\x9a\x0c\xac:]}\x99\xf9\x00\x00\x00\ +\xff\xff\x22\xaa\x1c\xff\xfb\xf7?\x03\x0b33\x03\x13\x13\ +\x13\xb2\xf9p\x00i\xf5\xa1\xbb\x1c\x92\xb1\xff\xfe\xfb\x0b\ +u *`eb\x83&\x1dli\x18\xd2:\xfc\xff\ +\xff\x1f\xceZ\x14\x00\x00\x00\xff\xff\x22\xb2\xad\x02)\xf6\ +\x18q\xf6\xe7\xb0\x97\x00\x8cP)l\xb2L\x8c\xc4\x0d\ +!\xe0\x02\x00\x00\x00\x00\xff\xff\x22\xca\xe1LL\x8c\x0c\ +\x7f\xff\xfdc\xf8\x87\xa5I\xca\xc0\xc0\x80\xbdZ\x86:\ +\x98\x91\x11{\xb9@i\xcf\x08\x00\x00\x00\xff\xff\x22\xaa\ +8da\x85\xa4\xd5\xdf\x7f~\xc3\x1d\x85\x0cX\x18Y\ +\xb1\xb6\x9d\xff\xfd\xfd\xcf\xc0\xcc\xc4\xc4\xc0\x84e\x80\xe6\ +\xf7\xbf\x9f\xd0\xa2\x8e\xbc\x918\x00\x00\x00\x00\xff\xff\x22\ +\x1c\xe2\x8c\x0c\x0c\xec\xec,\x0c\xdf~|g\xf8\xf1\x0b\ +{\xbb\x81\x95\x99\x1d\xc3\xfe\xff\x0c\x0c\x0c\x7f\xfe\xfec\ +`eee`aFv8$\xfc\x7f\xfc\xf9\x06-\ +\x22\xc9\x03\x00\x00\x00\x00\xff\xff\x22Xs2220\ +psC\xfa\x96\x1f\xbf~\x82\x0a\xff\x87;\x8e\x81\x81\ +\x81\x81\x93\x95\x9b\x012\xa8\x89p\xda\xff\x7f\x0c\x0c\xbf\ +\x7f\xfde\xe0d\xe7\x80\x14\x85P\x09X>\xf9\xfa\xeb\ +#$\x89\x91\xe9r\x00\x00\x00\x00\xff\xff\x22*\x8d\xf3\ +\xf2\xb12|\xff\xf1\x8d\xe1\xe5\xfb\xd7\x10\x07\xffG8\ +\x90\x81\x81\x81\x81\x87M\x80\x81\x81\x01)\xf4\x18!\x0e\ +\xff\xf9\xf3/\x03\x1f\x17/D\x0e\xaa\x89\x91\x81\x91\xe1\ +\xcf\xbf\xdf\x0c\x9f~\xbec`fd!\xd8\xb7\xc4\x05\ +\x00\x00\x00\x00\xff\xff\xc2\xefp\xa8\x03\xf8\x05\xd9\x18\x18\ +\xfe\xfcd\xb8\xf7\xec!\xd4\xe1\xa8\x96\x09p\x88\xa2t\ +\xb3\x18\x19\x19\x18\xfe\xfc\x81T\x5cb\x82B\x0c\x0c\x0c\ +\x90\x9e\x10\xcc\x8d\x9f~\xbe\x838\x9c\x89\x85\x81\xdc \ +\x07\x00\x00\x00\xff\xff\x22\x18\xe2\x7f\xff\xfdg\xe0\x17d\ +a``a`\xb8x\xe7*\x9a\xbf a.\xc2%\ +\xc5\xc0\xc6\xc2\x09))\xa0\xed\xf7\x9f?\xfe3\xfc\xfc\ +\xf6\x87A^B\x06\xeeYX\xe8\xbe\xfc\xf2\x88\xe1\xeb\ +\xaf\x8f\x0c\xcc\x8c\xccd\xa7q\x00\x00\x00\x00\xff\xff\xc2\ +\xebpFF\x06\x86\xbf\x7f\xfe3\xf0\xf011\xf0\x0a\ +s2\x9c\xbcz\x8e\x81\x81\x81\x81\x81\x19^\x11A\x1c\ +.\xca-\xc3 \xc0.\xc2\xf0\x17\xdaOdbf`\ +\xf8\xfc\xe1\x0f\x03\xc3\xaf\xff\x0c\xba\xca\x9aP\xd3\x10-\ +\xbe{\xef.3\xfc\xfe\xfb\x0b\x9a\xc6\x91\x9d\x8eHN\ +L\x8cL\x0c\xac,,\x0c\xcc\xcc\xd8\xcb{\x00\x00\x00\ +\x00\xff\xff\x22\x5c\xe5\xffc``eg`PP\xe2\ +g8{\xe32\xc3\xa3W\x8f\xa1]6H\xfb\xfa\xdf\ +\xff\x7f\x0c\x9c\xac<\x0cJB:\x0c\xbf\xfe\xfdd`\ +d`b`bbdx\xfa\xe8;\x03+'/\x83\ +\x8d\xae\x05\xc4\x22\xa4n\xd8\xb5W'\x18X\xa0\xc9\x04\ +\xa5<\x87\xfa\x81\x87M\x90\xe1\xeb\xef\x8f\x0c/\xdf\xbd\ +ax\xf7\xf1#\xd6\x16\x22\x00\x00\x00\xff\xff\x22\xaa8\ +\xfc\xf7\xf7?\x83\x9a\x06/\xc3\xe7\x8fo\x186\x1f\xdb\ +\xc9\xc0\xc0\xc0\x80Q\x8d\xdb+\x860\xfc\xfb\xfb\x97\x81\ +\x99\xed\x1f\xc3\xcfoL\x0c\xa7\x8e>`\x08u\xf2f\ +P\x93Qa\xf8\xf7\xef\x1f\x03##$$\x9f|\xba\ +\xc3p\xfb\xedE\x06\x0eV.\x06V6&\x86\xcf\xdf\ +\xbe000@jfXmj%\xef\xc5`-\x92\ +\xc0\xa0\xfc'\x80!Uw\x02\x83(\x8f4$\x86\x90\ +<\x00\x00\x00\x00\xff\xff\x22\xaa\x02\xfa\xfd\xeb?\x83\x84\ +\x0c\x1b\x83\x84\x12\x1f\xc3\xf4\xf5\x8b\x18~\xfd\xf9\xc5\xc0\ +\xc2\xcc\xcc\xf0\x9f\xe1?|\xe4I[\xcc\x82!L/\ +\x9f\xe1\xd3\xa7\xef\x0c[\xd6=d\xb0\xd5sa\x98\x98\ +\xd7\x0a5\x83\x91\xe1\x1f\x03\xc4\xa3\xfb\xef\xadb\xf8\xfa\ +\xeb\x13\x03\x0b\x0b3\x83\x98\x18'\xc3\xc3\x17O\x19\x9e\ +\xbf{\x01\x0dpH\x90\xf3\xb2\x093\x14\xb9\xb60\xb4\ +%\xb418\xe9:3\xc0\x87\xe7\x90\x9a\x1c\x00\x00\x00\ +\x00\xff\xff\x22\xae\xad\xc2\xc0\xc0\xf0\x9f\xf1\x1f\x83\xad\x93\ +\x04\xc3\xd5[\x17\x19\xa6\xac\x9b\xcd\xc0\xc0\xc0\xc0\xf0\xfb\ +\xcf\x1f\xb8\xc3\xfe\xff\xff\xcf\xe0\xa7\x91\xc1Pg\xb7\x86\ +aM\xf9F\x86\xbd\x13\xd70\x88\xf0\x8b@\xc6V\x18\ +\xfe203\xb20\xdc{w\x99\xe1\xd0\x83\xf5\x0c\xdc\ +l|\x0c\xbf~\xfdfP\xd7\xe1g\xf8\xf8\xf1\x15\xc3\ +\xca=\x9b \xf6\xfc\x83\xe5\x03\xb4!8,9\x18\x00\ +\x00\x00\xff\xff\x22j\x08\x8e\x91\x91\x81\xe1\xf7\xcf\xff\x0c\ +\x122,\x0c\xd6\xee2\x0c\x95S\xdb\x18L5\x8d\x18\ +lu-\x19~\xff\xf9\xcd\xc0\xc4\xc4\xc4\xc0\xcc\xc4\xc4\ +\xf0\xff\xff?\x06U)U\x06U)H)\x02I\xbf\ +\xff\x19\x98\x19Y\x18>\xfd|\xc70\xe7l-\xc3\xdf\ +\x7f\xbf\x19\xd8Y8\x19~\xff\xfe\xc7 $\xc6\xcc\xe0\ +\x1a(\xcb\xd0\xb1\xaa\x9bA\x5cX\x94!\xc4\xde\x9f\x81\ +\x99\x81\x91\xe1\xff\xff\x7f\x0c\x9f\x7f}`x\xf8\xe1:\ +\xc3\xa9';\x19\xde|{\xc6\xc0\xca\xcc\x86\xd2R\x04\ +\x00\x00\x00\xff\xffb\xe4\xf1\x90\xfb\xcf\xc8\xc8\xc0\xf0\xeb\ +\xe7\x7f\x06YEv\x06\xb7@\xdc\x03\xfb\xff\xff30\ +pp03\x9c:\xf2\x96\xe1\xe6\xf9\xbf\x0cKkf\ +3xY:B\xcauh\x1a\xfe\xf7\xff\x1f\xc3\xff\xff\ +\x90\x92\x076\x9e\xf8\xe4\xe3m\x86\xe9\xa7\xca\x18\x9e~\ +\xba\xcb\xc0\xc9\xca\x03\x1f\xfc\xfc\xff\x9f\x81\x81\x9d\x9d\x89\ +\xe1\xcb\x97_\x0c/_~eP\x93Qf\x10\x17\x12\ +c\xf8\xf1\xe7\x1b\xc3\xfb\xef/\x19>\xfex\x03\xcf\xfc\ +\xe8\x19\x14\x00\x00\x00\xff\xff\x22\xc9\xe10\xcb89Y\ +\x18\x1e\xde\xff\xccp\xf1\xf4G\x06o\xfdP\x86d\xcf\ +x\x06\x1d%M\x06Vho\x06\xe6\xe0o\xbf?3\ +\xac\xbd:\x99\xe1\xf0\x83\x0d\x0c\x7f\xfe\xfd\x82\x8c\x02\xa0\ +\x8d\xd8\xc2\x86\xacYX\x98\x18~\xfc\xfa\xc1\xf0\xfb\xcf\ +\x1f\xc8\x8c\x03\x13+\xb4\xe4a\xc4:\xca\x0b\x00\x00\x00\ +\xff\xff\x22y\x0e\x82\x91\x91\x81\xe1\xfb\xb7?\x0c2r\ +\xdc\x0c~\xe1\xd2\x0cw\x1971\x18%X1\xb4.\ +\xeec````\xf8\xfb\x17a\xc9\x9f\x7f\xbf\x18\x0e\ +\xde_\xcb\xc0\xc0\xc0\xc0\xc0\xc5\xca\x8b\xd5\x01\x8cL\x90\ +Q\x81\x9f?\xff203\xb01p\xb0r3\xb0\xb3\ +p203B'\x0b\xb0\x0fM\xff\x07\x00\x00\x00\xff\ +\xff\x22k\xf2\x84\x91\x89\x81\xe1\xd7\xaf\x7f\x0c?\xbe\xfd\ +ePS\x15g\x10\x94\xe0e\xd8zl\x0f\x03\x03\x03\ +\x03\x03\x1333<\xc9\xf0\xb1\x0b3\xb8\xa9\xc60|\ +\xf8\xf1\x8a\xe1\xe3\xcf\xb7\xd04\x8f=*\x19\x19\x19P\ +z=x\xdb0\xff\x19\xfe\x00\x00\x00\x00\xff\xff\x22k\ +F\x02n\xd1?\x06\x86\xff\x8c\x7f\x18\xd45\x04\x19\xce\ +\x1c\xbd\xcap\xe9\xde\x15\x06=%\x1d\xc8\x80\x11\xb4v\ +\x0d\xd4\xcaf\x90\xe1Sex\xf1\xe9\x11\xc3\xb1'\x9b\ +\x19>\xfcx\x85\xb3\xfdN\x84\xad\xff\xff\xfd\xff\xc3\xc8\ +\xcf.\xfa\x0c\x00\x00\x00\xff\xff\xa2l\xba\x8a\x91\x81\xe1\ +\xf7\xef\xff\x0c\xea\xba\xbc\x0c\x7f\xfe\x7fc\x98\xb1q!\ +\x03\x03\x03\x03\xc3\x9f\xbf\x7f\xe0\x0d1\x16FV\x06+\ +9\x1f\x86 \x9d,\x06^6\x01\x86\xbf\xff\xfe0\xe0\ +\xcc@\x04\x00\x13#\xe3\xbf\xdf\x7f\x7f2\xa8\x0a\x1b\xed\ +\x07\x00\x00\x00\xff\xff\xa2\xc8\xe1\x8c\x8c\x0c\x0c\x7f\x7f\xff\ +g\xe0\x15`dpt\x97e\x98\xb9v1\xc3\xf6\x13\ +{\x19\xd8X\xd9\xe0\x0e\xff\xcf\xf0\x9f\x88\xf9\x1f\xa2\xc0\ +\xff\xff\x0c\xff\x99\x98\x99\xd8~;(\x06\xcf\x02\x00\x00\ +\x00\xff\xff\xa2x\x82\x90\x91\x89\x81\xe1\xe7\x8f\x7f\x0c\xda\ +\x86<\x0c\xf6>\xc2\x0ci\x932\x19fl\x9a\xcf\xf0\ +\xe1\xf3g\x86\xff\xff\x11m\x94o\xbf?3\xfc\xf9\xff\ +\x1b\xe7\xc8\x14\x0e\xd3\xff322\xfdcbd\xfe\xc3\ +\xc2\xc4\xfa\xfb\xfd\xf7W\x8c\x0e\x0a\xa1S\xd4E\x8d\x8e\ +\x03\x00\x00\x00\xff\xff\x22\xb98\xc4\x05`e\xfc\xb7\xef\ +\xbf\x19\x9e<\xfd\xc0 ) \xc5\xa0()\xc7\xc0\xce\ +\xc6\xce\xf0\xfd\xf7g\x86\x8f?\xdeAG\xbc0\xd36\ +db\x16\xba\x82\x02\xba\xd8\xe0?\xc3?\xe6\x7f\xff \ +\x0b\x1c\xfe\xfe\xfb\xfd\xef\xf7\xdf_L\xb6\xf2A+R\ +M[bX\x98X\xfe\x02\x00\x00\x00\xff\xff\x22;s\ +bX\xce\xc8\xc0\xf0\xe3\xfb_\x06\x16ff\x065\x15\ +1\x86_\xbf\xbf1\xdc\xffx\x09>\xb5\x0d\x9df\xf9\ +\x0fY\x09\xc1\x04o\xe3\xfeg\xf8\xc7\xfc\xf7\xdf_\xc6\ +\xbf\xff~3\xfe\xfd\xf7\x87\xe1\xef\xbf\xbf\x0c\x8c\x0c\x90\ +~,\x17+\xdf\x17qN\xb1\xc7\xa2\x5c2\xb7\xcdd\ +\xdc\x97\x9a\xcbz\xac\x82\x0c\xb4\xffg\x04\x00\x00\x00\xff\ +\xffb\x81\xacz\xf8O\x95\x09pH\xf3\xfa?\xc3\xcf\ +\x1f\x7f\xfe32\xb2\xfc\xe7de\x83/\xd7\xf8\xf7\xff\ +/\xf3\xdf\x7f\x7f\x18\x7f\xff\xfb\xcd\xf8\xe7\xdf\x1f\x86\x7f\ +\xff k^\xd8 \x0e\xfc*\xc0!\xffX\x94[\xe6\ +\xb6$\xaf\xc2uI^\xc5\xab\x92\xbc\x0a7E\xb8\xa4\ +\x1e\xf0q\x08\xbdfbd\xfe\xc7\xc0\xc0\xc0\xf0\xff\xff\ +?&\x06h\xac\x00\x00\x00\x00\xff\xffb\xf9\xf3\xe7\x0f\ +\x03\x1b\x1b\xdb?\x06\x86\xdfL$%?\x88S\xff3\ +22\xa0\x85\xe0\x7f\xe6\x7f\xff\xff0\xfe\xfe\xfb\x8b\xf1\ +\xef\x9f\xdf\xf0\x10dafg\xe0f\xe5\xfb*\xc6!\ +\xffX\x94[\xfa\x0e\xc4\x81JW%x\x14n\x8ar\ +K\xddGv :\x80,\xc8\xf9\xcf\xc0\xc4\xc8\x0c\xcf\ +\xe5\x00\x00\x00\x00\xff\xffb\x11\x13\x10~\xf2\xf4\xeds\ +Yvf\xee\xbf\xff\xff30cw<\xe3\x7f\xa4\xc5\ +.(i\x10\x11\x82\x103Ya\x0e\xe4\x16}\x22\xca\ +-s[\x82W\xe1\xba\x14\xaf\xe25\x09\x1e\x85\x9b\x22\ +\xdc\xd2\xf7\xf99\x84^\xe1r\xe0\xff\xff\xff\x98\xff\xc3\ +c\x1f\xba\x18\x81\x91\xf1?\x13\x96![\x00\x00\x00\x00\ +\xff\xffb\xd9\xd3\xbf\xc1.\xa4.n\xd3\xc5+\x97t\ +Y\x98\xa5\xfeB\x06S\x99\xfe31\x22V\x01\xfd\xfd\ +\xff\x87\xf1\xcf_\xc8\x0a\x86\xbf\xff\xa1!\xc8\xc4\xce\xc0\ +\xcd\xc6\xf7]\x94C\x0e\x12\x82<\x8a\xd7$y\x15\xaf\ +I\xf0\xca\xdf\x10\xe5\x96\xb9\xcf\xcf.\xf4\x8a\x89\x09\xb7\ +\x03\xffA\x17\xcc@\x03\x05\xb2\x04\x84\x91\xe9/\xb1\x91\ +\x0e\x00\x00\x00\xff\xffb\xfc\xff\xff?\xc3\xeb\x8fo\x84\ +\xbdJ\xa27?\xfev\xd928F\xee\xdf\xd7o\xdf\ +\x99\xfe3@\x062Y\x99\xd8\x18\xb8Xy?\x09p\ +\x88=\x11\xe1\x96\xbe#\xc1\xa3pC\x92W\xe1\x9a8\ +\x8f\xfcMQn\xa9\x07\xfc\xec\xc2x\x1d\x88-\x04\x89\ +t\x1b^\x00\x00\x00\x00\xff\xffb\xfc\xf3\xf7\x0f33\ +\x13\xf3\xdfW\xef\xde\xf3f\xcfN\xde.\xa1\xfdVO\ +\x96O\xfd\xac\x04\xaf\xc2ui>\x95KR\xbc\x8a\xd7\ +\xc4\xb8e\xef\x08p\x8a\xbedfb\xc6\xde\xe2\xf9\xff\ +\x8f\xf9\x1f\xc3?h\xc3\x96\x11i\xa9\x13\xd9\x9dx\x82\ +\x00\x00\x00\x00\xff\xff\x03\x00<\x1e\x17\xa6\x18\xe4\xa8\x9e\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x0b\ +\x05R\xbf'\ +\x00q\ +\x00t\x00-\x00l\x00o\x00g\x00o\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x99\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/animation/easing/form.ui b/examples/widgets/animation/easing/form.ui new file mode 100644 index 0000000..61a7921 --- /dev/null +++ b/examples/widgets/animation/easing/form.ui @@ -0,0 +1,205 @@ + + + Form + + + + 0 + 0 + 545 + 471 + + + + Easing curves + + + + + + + 0 + 0 + + + + + 16777215 + 120 + + + + Qt::ScrollBarAlwaysOff + + + QListView::Static + + + false + + + QListView::IconMode + + + false + + + + + + + + + Path type + + + + + + Line + + + true + + + buttonGroup + + + + + + + Circle + + + buttonGroup + + + + + + + + + + + 0 + 0 + + + + Properties + + + + QFormLayout::AllNonFixedFieldsGrow + + + + + Period + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + Amplitude + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + Overshoot + + + + + + + false + + + -1.000000000000000 + + + 0.100000000000000 + + + -1.000000000000000 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + false + + + + diff --git a/examples/widgets/animation/easing/images/qt-logo.png b/examples/widgets/animation/easing/images/qt-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..14ddf2a0289e64c686b34712b8754bc4baac2726 GIT binary patch literal 5149 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/animation/easing/ui_form.py b/examples/widgets/animation/easing/ui_form.py new file mode 100644 index 0000000..c2279c5 --- /dev/null +++ b/examples/widgets/animation/easing/ui_form.py @@ -0,0 +1,152 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'form.ui' +## +## Created by: Qt User Interface Compiler version 5.14.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint, + QRect, QSize, QUrl, Qt) +from PySide2.QtGui import (QColor, QFont, QIcon, QPixmap) +from PySide2.QtWidgets import * + +class Ui_Form(object): + def setupUi(self, Form): + if Form.objectName(): + Form.setObjectName(u"Form") + Form.resize(545, 471) + self.gridLayout = QGridLayout(Form) + self.gridLayout.setObjectName(u"gridLayout") + self.easingCurvePicker = QListWidget(Form) + self.easingCurvePicker.setObjectName(u"easingCurvePicker") + sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.easingCurvePicker.sizePolicy().hasHeightForWidth()) + self.easingCurvePicker.setSizePolicy(sizePolicy) + self.easingCurvePicker.setMaximumSize(QSize(16777215, 120)) + self.easingCurvePicker.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) + self.easingCurvePicker.setMovement(QListView.Static) + self.easingCurvePicker.setProperty("isWrapping", False) + self.easingCurvePicker.setViewMode(QListView.IconMode) + self.easingCurvePicker.setSelectionRectVisible(False) + + self.gridLayout.addWidget(self.easingCurvePicker, 0, 0, 1, 2) + + self.verticalLayout = QVBoxLayout() + self.verticalLayout.setObjectName(u"verticalLayout") + self.groupBox_2 = QGroupBox(Form) + self.groupBox_2.setObjectName(u"groupBox_2") + self.verticalLayout_2 = QVBoxLayout(self.groupBox_2) + self.verticalLayout_2.setObjectName(u"verticalLayout_2") + self.lineRadio = QRadioButton(self.groupBox_2) + self.buttonGroup = QButtonGroup(Form) + self.buttonGroup.setObjectName(u"buttonGroup") + self.buttonGroup.setExclusive(False) + self.buttonGroup.addButton(self.lineRadio) + self.lineRadio.setObjectName(u"lineRadio") + self.lineRadio.setChecked(True) + + self.verticalLayout_2.addWidget(self.lineRadio) + + self.circleRadio = QRadioButton(self.groupBox_2) + self.buttonGroup.addButton(self.circleRadio) + self.circleRadio.setObjectName(u"circleRadio") + + self.verticalLayout_2.addWidget(self.circleRadio) + + + self.verticalLayout.addWidget(self.groupBox_2) + + self.groupBox = QGroupBox(Form) + self.groupBox.setObjectName(u"groupBox") + sizePolicy1 = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred) + sizePolicy1.setHorizontalStretch(0) + sizePolicy1.setVerticalStretch(0) + sizePolicy1.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) + self.groupBox.setSizePolicy(sizePolicy1) + self.formLayout = QFormLayout(self.groupBox) + self.formLayout.setObjectName(u"formLayout") + self.formLayout.setFieldGrowthPolicy(QFormLayout.AllNonFixedFieldsGrow) + self.label = QLabel(self.groupBox) + self.label.setObjectName(u"label") + + self.formLayout.setWidget(0, QFormLayout.LabelRole, self.label) + + self.periodSpinBox = QDoubleSpinBox(self.groupBox) + self.periodSpinBox.setObjectName(u"periodSpinBox") + self.periodSpinBox.setEnabled(False) + self.periodSpinBox.setMinimum(-1.000000000000000) + self.periodSpinBox.setSingleStep(0.100000000000000) + self.periodSpinBox.setValue(-1.000000000000000) + + self.formLayout.setWidget(0, QFormLayout.FieldRole, self.periodSpinBox) + + self.label_2 = QLabel(self.groupBox) + self.label_2.setObjectName(u"label_2") + + self.formLayout.setWidget(1, QFormLayout.LabelRole, self.label_2) + + self.amplitudeSpinBox = QDoubleSpinBox(self.groupBox) + self.amplitudeSpinBox.setObjectName(u"amplitudeSpinBox") + self.amplitudeSpinBox.setEnabled(False) + self.amplitudeSpinBox.setMinimum(-1.000000000000000) + self.amplitudeSpinBox.setSingleStep(0.100000000000000) + self.amplitudeSpinBox.setValue(-1.000000000000000) + + self.formLayout.setWidget(1, QFormLayout.FieldRole, self.amplitudeSpinBox) + + self.label_3 = QLabel(self.groupBox) + self.label_3.setObjectName(u"label_3") + + self.formLayout.setWidget(2, QFormLayout.LabelRole, self.label_3) + + self.overshootSpinBox = QDoubleSpinBox(self.groupBox) + self.overshootSpinBox.setObjectName(u"overshootSpinBox") + self.overshootSpinBox.setEnabled(False) + self.overshootSpinBox.setMinimum(-1.000000000000000) + self.overshootSpinBox.setSingleStep(0.100000000000000) + self.overshootSpinBox.setValue(-1.000000000000000) + + self.formLayout.setWidget(2, QFormLayout.FieldRole, self.overshootSpinBox) + + + self.verticalLayout.addWidget(self.groupBox) + + self.verticalSpacer = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding) + + self.verticalLayout.addItem(self.verticalSpacer) + + + self.gridLayout.addLayout(self.verticalLayout, 1, 0, 1, 1) + + self.graphicsView = QGraphicsView(Form) + self.graphicsView.setObjectName(u"graphicsView") + sizePolicy2 = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + sizePolicy2.setHorizontalStretch(0) + sizePolicy2.setVerticalStretch(0) + sizePolicy2.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth()) + self.graphicsView.setSizePolicy(sizePolicy2) + + self.gridLayout.addWidget(self.graphicsView, 1, 1, 1, 1) + + + self.retranslateUi(Form) + + QMetaObject.connectSlotsByName(Form) + # setupUi + + def retranslateUi(self, Form): + Form.setWindowTitle(QCoreApplication.translate("Form", u"Easing curves", None)) + self.groupBox_2.setTitle(QCoreApplication.translate("Form", u"Path type", None)) + self.lineRadio.setText(QCoreApplication.translate("Form", u"Line", None)) + self.circleRadio.setText(QCoreApplication.translate("Form", u"Circle", None)) + self.groupBox.setTitle(QCoreApplication.translate("Form", u"Properties", None)) + self.label.setText(QCoreApplication.translate("Form", u"Period", None)) + self.label_2.setText(QCoreApplication.translate("Form", u"Amplitude", None)) + self.label_3.setText(QCoreApplication.translate("Form", u"Overshoot", None)) + # retranslateUi + diff --git a/examples/widgets/animation/states/states.py b/examples/widgets/animation/states/states.py new file mode 100644 index 0000000..1a85924 --- /dev/null +++ b/examples/widgets/animation/states/states.py @@ -0,0 +1,264 @@ + +############################################################################# +## +## Copyright (C) 2010 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtGui, QtWidgets + +import states_rc + + +class Pixmap(QtWidgets.QGraphicsObject): + def __init__(self, pix): + super(Pixmap, self).__init__() + + self.p = QtGui.QPixmap(pix) + + def paint(self, painter, option, widget): + painter.drawPixmap(QtCore.QPointF(), self.p) + + def boundingRect(self): + return QtCore.QRectF(QtCore.QPointF(0, 0), QtCore.QSizeF(self.p.size())) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + # Text edit and button. + edit = QtWidgets.QTextEdit() + edit.setText("asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy " + "asdf lkjha yuoiqwe asd iuaysd u iasyd uiy!") + + button = QtWidgets.QPushButton() + buttonProxy = QtWidgets.QGraphicsProxyWidget() + buttonProxy.setWidget(button) + editProxy = QtWidgets.QGraphicsProxyWidget() + editProxy.setWidget(edit) + + box = QtWidgets.QGroupBox() + box.setFlat(True) + box.setTitle("Options") + + layout2 = QtWidgets.QVBoxLayout() + box.setLayout(layout2) + layout2.addWidget(QtWidgets.QRadioButton("Herring")) + layout2.addWidget(QtWidgets.QRadioButton("Blue Parrot")) + layout2.addWidget(QtWidgets.QRadioButton("Petunias")) + layout2.addStretch() + + boxProxy = QtWidgets.QGraphicsProxyWidget() + boxProxy.setWidget(box) + + # Parent widget. + widget = QtWidgets.QGraphicsWidget() + layout = QtWidgets.QGraphicsLinearLayout(QtCore.Qt.Vertical, widget) + layout.addItem(editProxy) + layout.addItem(buttonProxy) + widget.setLayout(layout) + + p1 = Pixmap(QtGui.QPixmap(':/digikam.png')) + p2 = Pixmap(QtGui.QPixmap(':/akregator.png')) + p3 = Pixmap(QtGui.QPixmap(':/accessories-dictionary.png')) + p4 = Pixmap(QtGui.QPixmap(':/k3b.png')) + p5 = Pixmap(QtGui.QPixmap(':/help-browser.png')) + p6 = Pixmap(QtGui.QPixmap(':/kchart.png')) + + scene = QtWidgets.QGraphicsScene(0, 0, 400, 300) + scene.setBackgroundBrush(scene.palette().window()) + scene.addItem(widget) + scene.addItem(boxProxy) + scene.addItem(p1) + scene.addItem(p2) + scene.addItem(p3) + scene.addItem(p4) + scene.addItem(p5) + scene.addItem(p6) + + machine = QtCore.QStateMachine() + state1 = QtCore.QState(machine) + state2 = QtCore.QState(machine) + state3 = QtCore.QState(machine) + machine.setInitialState(state1) + + # State 1. + state1.assignProperty(button, 'text', "Switch to state 2") + state1.assignProperty(widget, 'geometry', QtCore.QRectF(0, 0, 400, 150)) + state1.assignProperty(box, 'geometry', QtCore.QRect(-200, 150, 200, 150)) + state1.assignProperty(p1, 'pos', QtCore.QPointF(68, 185)) + state1.assignProperty(p2, 'pos', QtCore.QPointF(168, 185)) + state1.assignProperty(p3, 'pos', QtCore.QPointF(268, 185)) + state1.assignProperty(p4, 'pos', QtCore.QPointF(68 - 150, 48 - 150)) + state1.assignProperty(p5, 'pos', QtCore.QPointF(168, 48 - 150)) + state1.assignProperty(p6, 'pos', QtCore.QPointF(268 + 150, 48 - 150)) + state1.assignProperty(p1, 'rotation', 0.0) + state1.assignProperty(p2, 'rotation', 0.0) + state1.assignProperty(p3, 'rotation', 0.0) + state1.assignProperty(p4, 'rotation', -270.0) + state1.assignProperty(p5, 'rotation', -90.0) + state1.assignProperty(p6, 'rotation', 270.0) + state1.assignProperty(boxProxy, 'opacity', 0.0) + state1.assignProperty(p1, 'opacity', 1.0) + state1.assignProperty(p2, 'opacity', 1.0) + state1.assignProperty(p3, 'opacity', 1.0) + state1.assignProperty(p4, 'opacity', 0.0) + state1.assignProperty(p5, 'opacity', 0.0) + state1.assignProperty(p6, 'opacity', 0.0) + + # State 2. + state2.assignProperty(button, 'text', "Switch to state 3") + state2.assignProperty(widget, 'geometry', QtCore.QRectF(200, 150, 200, 150)) + state2.assignProperty(box, 'geometry', QtCore.QRect(9, 150, 190, 150)) + state2.assignProperty(p1, 'pos', QtCore.QPointF(68 - 150, 185 + 150)) + state2.assignProperty(p2, 'pos', QtCore.QPointF(168, 185 + 150)) + state2.assignProperty(p3, 'pos', QtCore.QPointF(268 + 150, 185 + 150)) + state2.assignProperty(p4, 'pos', QtCore.QPointF(64, 48)) + state2.assignProperty(p5, 'pos', QtCore.QPointF(168, 48)) + state2.assignProperty(p6, 'pos', QtCore.QPointF(268, 48)) + state2.assignProperty(p1, 'rotation', -270.0) + state2.assignProperty(p2, 'rotation', 90.0) + state2.assignProperty(p3, 'rotation', 270.0) + state2.assignProperty(p4, 'rotation', 0.0) + state2.assignProperty(p5, 'rotation', 0.0) + state2.assignProperty(p6, 'rotation', 0.0) + state2.assignProperty(boxProxy, 'opacity', 1.0) + state2.assignProperty(p1, 'opacity', 0.0) + state2.assignProperty(p2, 'opacity', 0.0) + state2.assignProperty(p3, 'opacity', 0.0) + state2.assignProperty(p4, 'opacity', 1.0) + state2.assignProperty(p5, 'opacity', 1.0) + state2.assignProperty(p6, 'opacity', 1.0) + + # State 3. + state3.assignProperty(button, 'text', "Switch to state 1") + state3.assignProperty(p1, 'pos', QtCore.QPointF(0, 5)) + state3.assignProperty(p2, 'pos', QtCore.QPointF(0, 5 + 64 + 5)) + state3.assignProperty(p3, 'pos', QtCore.QPointF(5, 5 + (64 + 5) + 64)) + state3.assignProperty(p4, 'pos', QtCore.QPointF(5 + 64 + 5, 5)) + state3.assignProperty(p5, 'pos', QtCore.QPointF(5 + 64 + 5, 5 + 64 + 5)) + state3.assignProperty(p6, 'pos', QtCore.QPointF(5 + 64 + 5, 5 + (64 + 5) + 64)) + state3.assignProperty(widget, 'geometry', QtCore.QRectF(138, 5, 400 - 138, 200)) + state3.assignProperty(box, 'geometry', QtCore.QRect(5, 205, 400, 90)) + state3.assignProperty(p1, 'opacity', 1.0) + state3.assignProperty(p2, 'opacity', 1.0) + state3.assignProperty(p3, 'opacity', 1.0) + state3.assignProperty(p4, 'opacity', 1.0) + state3.assignProperty(p5, 'opacity', 1.0) + state3.assignProperty(p6, 'opacity', 1.0) + + t1 = state1.addTransition(button.clicked, state2) + animation1SubGroup = QtCore.QSequentialAnimationGroup() + animation1SubGroup.addPause(250) + animation1SubGroup.addAnimation(QtCore.QPropertyAnimation(box, b'geometry', state1)) + t1.addAnimation(animation1SubGroup) + t1.addAnimation(QtCore.QPropertyAnimation(widget, b'geometry', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p1, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p2, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p3, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p4, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p5, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p6, b'pos', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p1, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p2, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p3, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p4, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p5, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p6, b'rotation', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p1, b'opacity', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p2, b'opacity', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p3, b'opacity', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p4, b'opacity', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p5, b'opacity', state1)) + t1.addAnimation(QtCore.QPropertyAnimation(p6, b'opacity', state1)) + + t2 = state2.addTransition(button.clicked, state3) + t2.addAnimation(QtCore.QPropertyAnimation(box, b'geometry', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(widget, b'geometry', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p1, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p2, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p3, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p4, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p5, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p6, b'pos', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p1, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p2, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p3, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p4, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p5, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p6, b'rotation', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p1, b'opacity', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p2, b'opacity', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p3, b'opacity', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p4, b'opacity', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p5, b'opacity', state2)) + t2.addAnimation(QtCore.QPropertyAnimation(p6, b'opacity', state2)) + + t3 = state3.addTransition(button.clicked, state1) + t3.addAnimation(QtCore.QPropertyAnimation(box, b'geometry', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(widget, b'geometry', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p1, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p2, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p3, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p4, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p5, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p6, b'pos', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p1, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p2, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p3, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p4, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p5, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p6, b'rotation', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p1, b'opacity', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p2, b'opacity', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p3, b'opacity', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p4, b'opacity', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p5, b'opacity', state3)) + t3.addAnimation(QtCore.QPropertyAnimation(p6, b'opacity', state3)) + + machine.start() + + view = QtWidgets.QGraphicsView(scene) + view.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/animation/states/states.pyproject b/examples/widgets/animation/states/states.pyproject new file mode 100644 index 0000000..d94cf2e --- /dev/null +++ b/examples/widgets/animation/states/states.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["states.py", "states_rc.py"] +} diff --git a/examples/widgets/animation/states/states_rc.py b/examples/widgets/animation/states/states_rc.py new file mode 100644 index 0000000..fe8a05c --- /dev/null +++ b/examples/widgets/animation/states/states_rc.py @@ -0,0 +1,2221 @@ +# -*- coding: utf-8 -*- + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# Resource object code +# +# Created: to lokakuuta 14 16:08:44 2010 +# by: The Resource Compiler for PySide (Qt v4.7.0) +# +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x1b\x48\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\ +\x01\x1e\x75\x38\x35\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x1a\xc5\x49\x44\ +\x41\x54\x78\xda\xcd\x7b\x0b\x5c\xcf\xf7\xf7\xbf\xf9\xee\xc6\x30\ +\x14\xdb\xd7\xfd\x32\x66\xc6\x66\xc3\xd8\xec\x8a\x51\x51\x2a\x42\ +\xae\xb9\x35\x84\xb9\x33\x86\xe6\xba\x94\x6b\xc9\xa5\x74\x2f\x11\ +\xa9\x24\x95\x8a\xe4\xbe\xdc\x72\x0b\x45\x49\x4a\x4a\xf7\xcb\xa7\ +\xcb\xe7\xf9\x3f\xcf\xd7\x47\xf3\xdd\x77\xdf\xff\x77\xfb\x7d\xc7\ +\xf0\x78\x9c\xf5\xde\xfb\xf3\x7e\x9d\xf3\x3c\xe7\x75\x5e\xe7\xf5\ +\x7a\x9f\x73\xde\x35\x00\xfc\x65\x5a\xbf\x7e\xbd\xbe\x87\x87\xc7\ +\x48\x77\x77\x77\xcb\xad\x5b\xb7\xb6\x5f\xb0\x60\x41\xcd\xff\xf6\ +\xfc\xa6\x4d\x9b\x6a\xb9\x07\x44\xce\xf1\x39\x7a\xcf\xca\x3b\x26\ +\x65\xa2\x47\x40\xf8\x4f\x32\x76\xd2\xce\x9d\x3b\xad\x5c\x5c\x5c\ +\xc6\x0a\x4d\x12\x9a\xbc\x63\xc7\x0e\x5e\x8f\x70\x75\x75\xed\x2d\ +\xfc\x9b\x71\xec\xd3\xa6\xbf\x34\x38\x28\x28\xa8\xf6\xee\xdd\xbb\ +\x8f\x87\x87\x87\x17\x47\x47\x47\xe3\xe8\xd1\xa3\x90\xbf\x15\xb1\ +\xb1\xb1\x5a\xf9\x2d\xf3\xc0\x81\x03\x39\x01\x01\x01\x09\xfb\xf7\ +\xef\x4f\x15\xba\x11\x12\x12\xf2\xe0\xd0\xa1\x43\x05\x31\x31\x31\ +\xda\x5b\xc9\x77\x50\x5c\x56\xa9\xe8\xc6\xad\x64\xc8\x18\x35\xf6\ +\xd4\xa9\x53\x88\x88\x88\x28\x38\x71\xe2\x04\xc2\xc2\xc2\x1e\xc9\ +\xb3\xfc\x5b\x10\x19\x19\x09\xa1\x22\xe1\x1b\xb7\x61\xc3\x86\x56\ +\x2f\x84\x01\xbc\xbd\xbd\x03\x05\x60\x85\x28\x19\x2b\x33\x64\x2d\ +\xb3\x38\xd5\xc7\xc7\x67\x9d\xbf\xbf\x7f\xe0\xae\x5d\xbb\xa2\x45\ +\xe1\xdb\x02\xf8\x4a\x58\x70\x60\x8e\xb7\xdd\x92\x87\x7b\xf7\x05\ +\x95\xee\xda\x1d\x58\xe6\xe2\xb9\xb7\x6c\xf9\xd6\xb0\xf2\xb9\xce\ +\xa7\x2a\xe7\x6f\x3b\x53\xb9\xd6\x3d\xae\x6c\x93\x67\x4c\xe1\x36\ +\x8f\x43\x99\xde\x1e\x81\x57\xc3\x67\x98\xaf\xda\xe3\xb0\x6c\xa2\ +\xf0\x1c\xec\xe7\xe7\x37\x55\xe4\xcc\x17\x9e\xbb\xf6\xed\xdb\x77\ +\x4e\x8c\x53\x29\xc6\xaa\x14\x6f\x19\xf2\x5c\x0d\x20\xb3\x50\xff\ +\xd8\xb1\x63\x5a\x01\x75\xea\x3f\xfd\x7e\xd2\xb0\x51\x97\x63\x03\ +\x1a\x6e\x3a\x32\x50\x2f\x39\x66\x60\x43\xed\xd1\xc1\x4d\x71\x39\ +\x25\x1f\x57\xd3\x0a\x90\x78\xaf\x08\xc9\x19\x45\xb8\x9d\x49\xd2\ +\x5d\x27\x09\xdd\xb8\x57\x88\xab\x77\x0b\x70\x6d\x58\x6b\x24\x98\ +\xbc\xa5\xfd\xc5\x50\xff\x97\xf3\x06\x7a\x0b\xe3\xfb\xe9\x75\xa8\ +\xe6\x2b\x4b\xac\x63\x70\x70\x70\x8a\x78\x5d\xce\x73\x35\x00\xd7\ +\xac\xb8\x6c\x95\xa7\xa7\xa7\x55\xf5\xbd\xab\xfd\xeb\x35\x8c\x37\ +\xd2\x5f\x15\x6f\xa0\x77\xfb\xe2\x80\x46\xb8\x36\xb8\x09\x6e\x8d\ +\x68\x89\x3b\x56\xef\x20\xcd\xe6\x43\x64\xe7\x97\x21\xb7\x50\x83\ +\xfc\xe2\x72\x14\x94\xe8\xa8\xb0\xa4\x82\x7f\xd5\xbd\xdc\x22\x0d\ +\x72\x0a\x34\xb8\x3f\xf3\x63\xa4\x59\x77\xe0\x38\x8e\x57\x7c\xce\ +\x0d\x68\x7c\x9b\xbc\x29\x43\x8c\x1e\x15\x17\x17\xa7\x7d\xae\x06\ +\x10\x97\xdc\x2d\x6b\x1c\x02\xa6\xd9\x49\x8b\x66\xb5\xe2\x0d\xf4\ +\x17\x9d\x33\xd0\x2f\xb8\x6c\xfa\x36\x6e\x5a\xb6\x40\xca\xf8\x76\ +\xb8\x3f\xf5\x7d\x3c\x9c\xd5\x05\x39\x0b\x7b\x20\x6f\x65\x5f\x54\ +\x54\x56\xa1\xb2\x4a\x8b\x2a\x92\x56\x0b\xad\x22\x5e\xab\x7b\xfc\ +\x4d\x3d\x93\xb7\xd6\x08\xb9\xb6\x5f\x72\x1c\xc7\x93\x0f\xf9\x29\ +\xbe\x97\x4c\xdf\x2e\x88\x99\x63\x71\xed\x60\x70\x60\xf1\x73\x35\ +\x80\xaf\xaf\xef\x51\x59\x9f\xda\x0b\x03\xdf\x9a\x28\xca\x3f\xa0\ +\xe2\xb7\x46\xb6\xc2\xdd\x49\xef\xe2\xc1\xf7\x1f\x20\xe7\x07\x51\ +\x7a\x45\x6f\x14\x38\x0c\x40\xd1\x96\x21\x28\x71\xb3\x42\x59\x05\ +\x50\xa2\x01\x8a\x84\x0a\xcb\x74\x54\x50\xaa\xfb\x5b\x24\x54\x2c\ +\xf7\x4b\xcb\x85\x7c\xbf\x43\x89\xcb\x48\x8e\xe3\x78\xf2\x21\x3f\ +\xf2\x25\x7f\x25\xe7\xfc\xf0\x76\xda\xf3\x06\x0d\x27\xec\xb1\xa8\ +\xf1\x8f\xe7\x62\x00\xb7\x2d\x9b\x6e\x6e\x75\x72\xc2\xa5\x81\x8d\ +\x38\x33\x0a\x58\xd6\xcc\x0f\xf1\x68\xc9\xe7\xc8\xb7\x33\x50\xe0\ +\x4b\xdd\xc7\x42\xe3\x3f\x19\x15\x41\xb3\x50\x19\xb9\x04\x0f\x0b\ +\x81\x07\x05\x40\x46\x3e\x70\x3f\x0f\x48\x57\xa4\xbb\xce\x10\xca\ +\x94\xfb\x59\xf2\x4c\xd5\xd1\x15\xa8\x0a\xff\x81\xe3\x38\x9e\x7c\ +\xc8\x8f\x7c\xc9\x9f\x72\x28\x8f\x72\xb9\x34\xae\x9c\x37\xaa\xdf\ +\xf2\x6f\x35\xc0\x39\xc3\x06\x9f\x3b\xaf\x58\xa4\xdd\xb0\x7e\x3d\ +\x6e\x5b\xb5\x45\xe6\xf4\xce\x78\xb4\xf8\x53\x9d\xe2\xce\x43\x51\ +\xe6\x33\x11\x15\xfb\x67\xa2\x2a\x62\x11\x10\xb3\x0c\x88\x5e\x02\ +\xed\xe1\x1f\x71\xfb\x21\x90\x94\x05\xdc\x7c\x00\xdc\xc8\x04\x12\ +\x9f\x90\xba\x77\x4b\x7e\x4b\x96\x67\xb4\x11\x0b\x80\xc8\x85\x1c\ +\xc7\xf1\xe4\x43\x7e\xe4\x4b\xfe\x94\x43\x79\x94\xab\xe4\x27\x98\ +\x35\xcd\x25\xa6\xbf\xc5\x00\xbf\x18\xea\x4d\x3c\x6f\xa8\x5f\xe1\ +\xb2\x6a\x11\xdc\x76\x6c\x45\xf6\xdc\x8f\x65\x7d\xf7\x41\x91\xd3\ +\x60\x94\x79\x4f\x50\xb3\xa6\x7d\xac\x34\x22\x45\x91\xb0\x19\x40\ +\xd0\x04\x68\x03\x46\xe0\xd2\x3d\xe0\xc2\x5d\xe0\x5c\x2a\x10\x9f\ +\x02\xfc\xf2\x84\xd4\xbd\xf3\xf2\xdb\xc5\x34\x40\xeb\x63\x02\xec\ +\xb6\xe0\x38\x8e\x27\x1f\xf2\x23\x5f\xf2\xa7\x1c\xca\xa3\x5c\xca\ +\x57\x01\x33\x71\x58\xf3\x0a\x62\x7b\x66\x06\x90\x47\x5f\x3a\x6b\ +\xa0\xb7\xe9\x82\x91\xbe\x8a\xcc\xbe\x9b\xed\x10\x12\x1c\xa4\xd6\ +\x68\x89\xeb\x28\x94\xef\x9d\xc6\x59\xd6\x29\x1e\x31\x0f\x08\xf9\ +\x4e\xa7\x84\xdb\xd7\xc0\xe6\x0e\xa8\x5a\xd3\x08\xc7\x93\x80\x63\ +\x37\x81\xa3\x37\x80\x23\x42\x31\x89\x5a\x44\x5f\xd7\xf2\x5a\x51\ +\xac\xfc\x76\xfc\x16\x50\xb1\xec\x75\x60\x65\x5d\x8e\xe3\x78\xf2\ +\x21\x3f\xf2\xad\xf6\x26\xca\xa3\x5c\x25\x3f\x67\x51\x4f\xa4\x4f\ +\xe9\xa8\x70\x9d\x35\x6c\xb4\x89\x58\x9f\xba\x01\x4e\x19\x34\xb6\ +\xbb\x38\x40\x1f\x49\x12\x80\x32\xa6\x75\x82\xff\x16\x3b\xec\xf7\ +\xf7\x56\xb3\x51\x19\x3a\x57\xb4\x59\xaa\x73\xdb\x03\x53\x00\xff\ +\xc1\xc0\xb6\xee\xc0\x9a\x86\xa8\x5a\x5c\x03\x9a\x85\x35\x51\xb4\ +\xe0\x0d\x04\x9e\x2b\x83\xff\x99\x12\x78\x9f\x28\x82\x47\x5c\x21\ +\xdc\x8e\x15\x28\x72\x97\x6b\x2f\xb9\xe7\x77\xaa\x18\x7b\xe3\x4b\ +\x51\x30\xaf\x0e\x4a\xe6\xfe\x83\xe3\x38\x9e\x7c\xc8\x8f\x7c\xc9\ +\x9f\x72\x28\x8f\x72\x95\xfc\xc2\x4d\xa6\x78\xb4\xf4\x0b\xe2\x52\ +\xf8\x4e\x19\x35\xb6\x7b\xaa\x06\x38\x6d\xa8\x37\xe2\x82\xa1\x1e\ +\x99\x73\xdd\xa9\x2d\x2a\xd8\xcf\x1d\xe1\x07\xf6\x73\x7d\xea\x66\ +\x3d\x7c\x36\xb0\x77\x24\xe0\xda\x0b\x58\x5d\x1f\x95\x8b\x5e\x42\ +\xe9\xfc\x9a\x28\x9c\xf5\x32\xb2\x6c\xea\xe0\xe6\xc4\x36\xd8\x28\ +\x67\x97\xb5\xa1\x59\x58\x15\xf4\x00\x3f\x05\x66\xc0\x76\x5f\x06\ +\x96\xed\xbd\xaf\xae\x57\x06\x65\xe2\xe7\x90\x2c\xac\x0f\xcb\x46\ +\xe2\x84\x36\xc8\x9c\x5c\x17\x79\x33\x5e\xe1\x78\xf2\x21\x3f\xf2\ +\x25\x7f\xca\xa1\x3c\xca\x55\xf2\x35\xbb\xbe\xe3\x92\x20\x2e\xe2\ +\x53\x38\x89\xf9\xa9\x18\xe0\xac\x91\x7e\xb7\x73\x06\x7a\xe5\x37\ +\x2d\x5b\xd2\xc2\x14\xa2\x22\x72\x58\xa0\x3f\x0e\xf8\xb9\x00\x51\ +\xe2\xf6\xa1\x36\x80\x9f\x09\xb0\xa1\x2d\xaa\x7e\xac\x81\xb2\xc7\ +\x8a\xdf\x9b\x5c\x1f\x97\xc6\xb6\xc1\xa9\x51\x9d\x71\x7a\x54\x27\ +\xcc\xf1\xbe\x8b\x99\x3b\x2e\x6b\xa7\xd9\x47\x95\x58\x2d\xd9\xf5\ +\xd0\x74\x86\xd3\x6d\xb3\xe9\x4e\xb7\xc7\x2d\xf1\xcb\xb6\xb1\x8f\ +\x2c\x9d\xb1\x2d\x41\x3b\xd3\x33\x85\xcf\xaa\x31\x17\xc7\xb4\x45\ +\xea\xc4\x06\xc8\x9d\xf6\x2a\xf9\x91\x2f\xf9\x53\x0e\xe5\x51\xae\ +\x92\xaf\x8d\x5a\x02\xcd\xee\x29\xc4\x45\x7c\x0a\xe7\x75\xcb\x96\ +\xe5\xc4\xfe\x97\x0c\x10\xdf\x5f\xff\x9f\x67\x0c\xf4\xb3\x13\x87\ +\x36\xe3\x1a\x53\x5b\x50\x91\xa3\x39\x72\xbd\xac\x71\x3c\x2e\x0e\ +\xe1\x5e\x1b\x80\x10\x6b\xc0\xa3\xaf\x9a\x9d\xf2\x1f\x5e\x42\xf1\ +\x9c\x7f\x20\x6b\x6a\x6d\x9c\x1d\xd5\x16\xc7\x2c\x3b\x2a\x8a\x1b\ +\xde\xae\xd2\x75\x60\xbb\xb4\x6f\xbe\xec\x73\xe0\xe3\x8f\x3f\x76\ +\x16\x5a\x2f\xb4\xea\xa3\x8f\x3e\x5a\x4a\xe2\x35\xef\xf1\xb7\xde\ +\x5f\xf5\x3e\xb0\xd5\xa8\x5d\xca\x91\xa1\xed\x2b\xaa\xc7\x9f\x19\ +\xf9\x0e\xd2\x27\xd5\x41\xde\xf4\x57\xc8\x9f\x72\x28\x8f\x72\x75\ +\xf2\x0f\x2f\x62\x80\xa4\x11\x88\x8f\x38\x15\xde\x04\x8b\xe6\xd9\ +\xd4\xe1\x7f\x36\xc0\xf1\xfe\x8d\x4e\x5f\x31\xfb\x27\xf7\x5c\x75\ +\x10\x29\xdc\x38\x08\x65\x7e\xd6\x38\xed\xb7\x06\x91\x11\x11\xb8\ +\xea\xbb\x10\xd8\xf9\x25\x60\xfb\x0a\x34\x0b\x64\xd6\x67\xbe\x8c\ +\xd4\x49\xf5\x70\x74\xf8\x3b\x88\x1e\xd6\x0e\xe1\x43\xda\x94\x2c\ +\xeb\xd3\x2e\xbe\x6b\xd7\xae\x1b\x44\xb9\x39\xa2\xec\x10\xb9\xfe\ +\xec\x43\xdd\xbf\x76\x5d\xba\x74\x69\x4a\xe2\x35\x6f\xf0\x37\x3e\ +\xc3\x67\x39\x66\xda\x57\x1d\x8f\x1f\x1c\xdc\xa6\x98\xbc\xc8\x33\ +\x79\x5c\x7d\xe4\x4c\x7d\x8d\x72\x28\x8f\x72\x75\xf2\x83\x27\x01\ +\x51\x8b\xe9\x09\xc4\x47\x9c\xc4\xab\x70\x9f\x19\xd4\xe4\xf4\xff\ +\x64\x80\xb8\x7e\xfa\xc6\x8c\xf8\xc9\x63\xda\x20\x7b\xce\x47\xc8\ +\x5f\x6b\x88\x52\xcf\x71\x28\x0d\x5b\x8c\xa8\x88\x30\x84\xca\x12\ +\xd0\xee\xfc\x1a\x58\x56\x53\xb9\x66\xfe\xf7\xaf\xe0\xfa\xb8\x06\ +\x38\x64\xd1\x06\x91\x16\xad\xb4\x73\xbe\x69\x7f\x56\x94\x58\x2b\ +\x0a\x0e\xa7\x72\xa2\x94\xbe\xd0\x2b\x7f\xe4\x92\x7c\x86\xcf\x72\ +\x0c\xc7\x92\x87\xcd\x97\x1d\x4e\x46\x0c\x69\x5d\x45\xde\x97\x47\ +\xeb\xe1\xe1\xe4\xd7\x28\x8f\x72\x29\x9f\x3b\x05\x3d\x81\x31\x81\ +\x07\x28\xe2\x24\x5e\xe2\x56\xf8\xe3\x0c\xdf\x36\xfe\xbf\x19\xc0\ +\xb6\x46\xcd\xe3\xfd\x1b\xa7\xca\xde\xaa\x5b\xf7\xcb\xbf\x91\xa3\ +\xe9\x08\x54\x84\xcc\x46\xd4\x3e\x0f\x99\xfd\x70\x9c\x71\x9e\x0c\ +\x2c\x7f\xfd\x57\xe5\xcf\x8f\xd6\x47\xc8\xe0\x96\x08\x1d\xdc\x5c\ +\x63\xdc\xb3\x93\xb7\xcc\xe4\x58\x51\xa4\xb3\xd0\xeb\xff\xeb\x29\ +\x8d\x63\xc9\x83\xbc\x8c\x3e\xe9\xec\x15\x6a\xde\xa2\x92\x32\xce\ +\x8e\x68\x84\xac\xef\x5e\xaf\x36\x82\xc2\x01\xaf\xfe\xc0\xc1\x69\ +\x34\x02\x71\x12\x2f\x71\x2b\xfc\xf1\x43\x5a\xa6\x52\xa7\x3f\x6d\ +\x80\x98\x7e\x8d\xa7\x26\x18\x37\xe6\x0b\x08\x5f\x48\x64\x9b\x31\ +\x83\x66\x8f\x0d\x0e\x07\xec\x54\x89\x8b\x88\x1d\xb6\xa8\x5c\xdd\ +\x48\xb9\x61\x81\x80\xb8\x39\xae\x2e\xf6\x99\x35\x83\xe7\xc0\x66\ +\x0f\xbb\x75\xe9\xb2\x46\x66\xee\x2b\x01\x5e\xf7\x69\x25\x2d\xc8\ +\x8b\x3c\x47\x0f\x1b\x7a\x29\xd0\xbc\xb5\x96\xb2\xae\x8e\xac\x47\ +\x23\x50\xbe\xc2\x81\x9f\x1b\x01\x7e\xa6\x40\xf8\x1c\x9e\x1e\x89\ +\x97\xb8\x89\x5f\xe9\x71\xd4\xe8\xed\xa9\x7f\xca\x00\x47\xbe\x6e\ +\xf5\xfa\x29\x83\x46\x8f\x6e\x0c\x6f\x81\xcc\x19\x9d\x91\xbf\xe6\ +\x5b\x14\x7a\x4c\x40\xa0\xef\x4e\x04\xf8\xfb\x21\xcc\xdd\x1e\x9a\ +\xf5\x1d\x50\x21\x81\x88\x91\x39\x53\x40\xec\x37\x6b\x2c\xca\x37\ +\x79\x24\x20\x17\xca\x6c\x75\x11\xc0\x2f\x3f\xed\xd4\x15\x79\x3a\ +\x38\x38\xc4\x2e\x5e\xf4\x03\x7c\x07\x34\xc9\x0f\x34\x7d\x0b\xa9\ +\x63\x6b\x73\x39\x10\x87\xc2\x03\xc7\x8e\x40\xe0\x18\x06\x45\xd9\ +\x1e\x65\x29\x78\x8c\x25\x7e\xa5\xc7\xc5\xa1\xad\x1e\x51\xb7\x3f\ +\x34\xc0\xa1\x7e\x8d\xe7\x5d\xaa\x9e\x7d\x9e\xb0\x9c\xc7\x62\xfb\ +\xe6\x75\x70\x74\x74\xc4\x41\xd7\x35\x28\x75\xee\x05\xed\x92\x1a\ +\x28\x96\x83\x4a\xce\xd4\x57\x11\x65\xd1\x00\xfe\x26\x8d\xca\x7b\ +\x7c\xd4\xd9\x56\x40\xbe\x23\xa4\x4e\x61\xcf\x82\x24\xf7\xb0\x55\ +\xa8\xf8\xf3\x5e\x9f\xae\xf3\x1c\xf0\x56\x59\x84\x59\x43\xa4\x8f\ +\xaf\x45\x1c\xc4\x43\x5c\x8c\x07\x8f\x97\xc2\x52\x94\x07\xce\xe0\ +\xf9\x80\x7a\x28\x7d\x82\xe6\x8e\x4a\x92\xd7\xf8\x63\x92\xad\xf2\ +\x93\x3c\x66\xad\xff\x68\x80\xf0\x7e\x6f\x5d\xe1\xb6\xc7\xb5\x93\ +\xb0\x61\x12\x7c\xbc\xbd\xb0\x6d\xeb\x56\x1c\xdb\x3e\x4f\x82\x8b\ +\x29\xb0\xf6\x6d\xba\x9c\x3a\xa4\x5c\x1e\xf3\x06\xbc\x06\xd6\xd7\ +\x8e\xe8\xf5\x9e\x97\x04\xab\xce\xcf\x52\x79\x92\xa4\xc8\x4c\x0e\ +\x1e\x3c\x88\xd5\xab\x57\x7b\x9a\xf4\xe8\xec\xea\x31\xa0\x81\xf6\ +\xdc\xb0\x7a\xc8\x9c\xf4\x3a\xf1\x10\x97\xc2\x87\x3d\xc3\xd5\x69\ +\xb1\x2a\x72\xb1\xf2\x82\xbc\xd5\x7d\x95\x3e\x31\xe3\x3f\x45\x68\ +\x68\x68\x16\x73\x96\x7b\xf7\xee\x8d\xfa\x9d\x01\x0e\x7e\xd1\xf4\ +\xcd\x78\x43\xbd\x4a\x46\xce\xa8\x8d\x0b\x21\x09\x4c\x04\xf8\xb8\ +\x23\xd1\x7b\x36\x2a\x82\xac\xb9\xe5\xa8\x83\x48\xd1\xec\x97\x95\ +\xeb\x05\x0e\xaa\x8b\xc5\xbd\x9b\x9f\x13\xe5\x3f\x17\xe5\xd5\x7b\ +\xf9\x33\xa6\x9a\x32\x7b\xd9\x92\x84\x29\x96\xe5\x70\x7b\x89\xf1\ +\x47\x8f\x02\x8c\xeb\x21\x4d\xb7\x14\x88\x8b\xf8\x88\x53\xe7\x05\ +\x31\xe2\x05\x01\xd3\xd4\x51\x39\x7b\x7e\x37\xdc\x1c\xdd\xa6\x92\ +\x3a\x06\x06\x06\x9e\x92\x94\x5a\xe9\xef\x0c\x10\xf0\x6d\x13\x9b\ +\x4b\x66\x4d\x64\x9d\x3b\x21\x3a\xe2\x10\x22\xf6\xf9\x22\xdb\x7b\ +\x12\xb4\x3c\x7b\xef\x1b\x05\x38\x34\xa7\x95\xd5\x81\x24\x6d\x5c\ +\x6d\xb8\x18\xd4\xad\x10\xc5\xc7\x09\x29\x77\xfa\x3b\x48\x92\xae\ +\xef\x4b\x32\xe6\xba\x64\xa3\x35\x4b\x96\x2c\xd1\x6c\x37\x68\x80\ +\x5b\x96\x75\x90\x31\xa1\x16\x71\x11\x1f\x71\x12\xaf\x3a\x1b\x54\ +\x1e\x9c\xaf\xdb\x11\x96\x7d\xa9\xde\x1a\x83\x8c\x9a\xd9\xc8\x32\ +\xd8\xca\xac\xb3\xa4\xdb\xbb\xfc\x86\x79\x88\x49\xfb\xb3\xa1\x5e\ +\xdb\x21\xc9\x4e\x1c\xdd\xb9\x1a\xf9\x2e\xc3\xb8\x96\x74\x91\xd5\ +\xdb\x88\x6b\x4c\x9d\xc4\xb2\xa7\xbc\x86\x93\x43\x6b\xe1\xe7\xde\ +\x8d\xae\x75\xeb\xd6\xad\x2d\xc7\x3e\x0f\xea\xd5\xab\x57\xbb\xc5\ +\x5f\xbe\x7d\xf1\xe8\xa0\x37\xe8\x05\xc4\x45\x7c\xc4\x49\xbc\xd5\ +\x3b\x82\xca\x23\xe4\xff\xdc\x5f\xbd\x27\x44\x9a\xb6\x3a\x21\xf9\ +\xcc\x91\x92\x6a\xcf\x17\x03\x8c\x79\x92\xe1\x59\x35\xad\x76\xb0\ +\xe7\x0e\x6d\xe4\xa1\x30\x9c\x58\x37\x1d\x79\xeb\x0c\x51\xbe\x47\ +\x05\x13\xdd\x1b\xd8\xd6\xae\x8c\xb4\xdc\x76\xd4\x9a\xf3\x1f\xf0\ +\x5a\x95\x51\x8f\xce\x56\xd5\x87\x9b\xe7\x41\x94\xfd\x59\xf7\x0f\ +\x47\xee\xfc\xb6\xb6\xe6\xce\xc8\x3a\xc4\x45\x7c\xc4\x49\xbc\xc4\ +\x4d\xfc\x5c\x06\x3c\x1d\xaa\x83\xd1\x95\x91\x6d\x4a\xdd\x5d\xb6\ +\x7e\x45\x0f\x90\x98\x62\xfb\x2b\x33\x2f\x57\x97\x98\xa8\xc8\x70\ +\xc4\xba\xac\x46\xde\x8e\xc9\x28\xde\x6f\x8b\xb2\x38\x67\x94\x9c\ +\x71\x43\xe1\x61\xb9\xe7\x31\x14\xe9\xf6\x5f\xe1\xfa\xb2\xaf\x70\ +\x66\xf6\xd7\xd8\x34\xa0\x69\x56\xf7\xee\xdd\x55\x81\xe2\x79\x12\ +\x31\xd8\xf5\x6b\x9e\x71\x64\x72\x6f\x9c\x9f\xf7\x0d\x92\xe4\xf0\ +\x93\xb5\xfe\x1b\x14\x78\x0e\x45\x71\xd4\x6a\x68\xce\xba\xa1\xfc\ +\xb8\x33\x4a\x83\x6c\x91\xbb\x7d\x0a\xee\xac\x18\x0e\xd7\x85\x53\ +\x4c\x59\x74\x91\x7a\xc3\x7a\xdd\xec\xbb\xb9\x19\xf1\x80\x13\x7e\ +\x38\x86\xe9\x69\x66\x68\x99\xa4\x64\xee\x8e\xa9\x2a\x66\x6b\x54\ +\x12\xc3\x57\xde\xd7\xd7\x84\x3c\xc0\xd4\x9d\xb7\x31\x7a\xd4\x8c\ +\x48\x99\x81\x3a\xcf\xdb\x00\xc4\x30\x76\xd8\xd4\x18\x2b\xe7\x5b\ +\x58\x12\x70\x1f\x2e\x47\xf3\x11\x71\xa5\x12\x67\xee\x00\xd7\xee\ +\x03\x69\x8f\x80\xdc\x12\x40\x92\xcd\x28\xd5\x54\x22\x3d\xa7\x04\ +\x01\x1b\xec\x1c\x58\x71\x92\x78\xe2\xa1\x98\x48\x76\x37\xea\xe0\ +\xc1\xd0\x8a\xc4\x94\x2c\x14\x95\x56\x00\xd0\x65\x6b\xd3\x73\x81\ +\xc4\x0c\x95\xb2\x62\xe6\x86\xc9\x0b\xf5\x0e\x3f\x7e\xdb\x2d\xf4\ +\x1a\x64\x33\x53\x84\x73\xfc\x73\x25\x62\xf8\xca\xc4\x7a\xee\xf0\ +\x4d\x89\x98\xef\x97\x86\x2d\x87\x73\x71\xe0\x62\x39\x4e\x26\x03\ +\x97\xd3\x81\x94\x1c\x20\xa7\x08\x28\xaf\x04\x34\x15\x55\xc8\xca\ +\x2b\xc3\x01\x27\x87\x7d\xb2\xc3\x15\x8a\xde\xbe\x8a\xc9\xe1\xc3\ +\x87\x35\x41\x7b\xf6\x14\xdf\xcb\x2e\x41\x89\x58\x49\x1c\x00\x79\ +\x25\xb4\x9e\xce\x8a\x67\x6e\x03\xe1\x62\xd5\x1d\x47\xf2\xb0\x78\ +\x77\x3a\x46\x3b\x5e\xc7\x07\x9f\x7e\xdb\x89\x63\x5f\x04\x22\x96\ +\xc1\x0e\x09\x98\xe5\x95\x8a\x0d\x87\xb2\x99\x79\x62\xfa\x8d\x39\ +\x48\x26\x62\x25\x1b\x4d\xe5\x69\x84\x2a\x55\x9c\x89\x74\x75\x3a\ +\x23\x75\x46\xad\x18\x60\x6f\x0d\x9f\x98\x3b\xd3\xf2\x0a\x4b\xb5\ +\x73\x37\x86\x97\xdd\xcf\x29\x45\xa9\x98\x8a\xee\x92\x5b\x0c\xa4\ +\xe6\x00\x57\xd2\x81\x53\x62\x80\xd0\x4b\xe5\x70\x8e\xca\xc5\x82\ +\x5d\x69\x18\x63\x77\x5c\x23\x96\x7f\xfb\x45\x31\x00\xb1\x8c\x5e\ +\x1e\x5d\x35\xdd\xfd\x0e\xec\x43\x1f\x62\xcf\xd9\x52\xc4\xdd\x62\ +\x82\x55\x97\x65\xce\x2a\x50\xf5\x06\x16\x5d\x54\xe5\xc9\x6b\xef\ +\xb1\xbc\xf4\x07\xb9\xd8\x15\x1c\x73\xb2\x86\x94\xa8\x67\xb2\x42\ +\x3b\x7f\x63\x74\x69\xe6\xa3\x52\xba\x89\x3c\x08\x3c\x2a\xa6\xfb\ +\x28\x37\x52\xee\x14\x22\x6e\xe5\x18\xf9\x08\xf3\x7c\xef\x62\xc4\ +\xb2\x90\x1c\x11\xaa\xf7\x02\x19\x40\x6f\xd2\x42\xdf\x32\x1b\xb7\ +\x3b\xb0\x3b\x90\x85\x5d\xa7\x4b\x98\x7c\x65\x06\x5a\xa5\xe1\x1f\ +\xfc\x8b\x01\x1e\x15\x6a\xe0\x19\x1c\xaf\xa1\x21\xfc\x0e\xc4\x9d\ +\xf8\xd5\x00\x0b\x36\x46\x56\x3d\x31\x00\xd7\xcd\x6f\x0d\x10\x7c\ +\x41\xa3\x0c\x30\xd7\xe7\x2e\x46\xae\x88\xc8\x17\xa1\xf5\x5e\x20\ +\x03\xd4\xb3\x5a\x1c\x58\xce\xe0\xcc\xbc\x22\x0d\x10\xfb\x6f\x06\ +\x28\xf9\x57\x03\x04\x9d\x2d\xa7\x01\x7c\x82\x8f\x45\xd1\x00\xb5\ +\xf7\x05\x06\x6e\x3e\xb8\xd3\x55\xfb\x67\x3d\xc0\xd2\xfe\x5c\xa5\ +\x08\x7d\xe3\x05\x32\xc0\x1b\x83\x57\x9e\xd6\xd2\x00\x7f\xc6\x03\ +\xc2\xbd\xdd\xb3\x25\x06\x94\x78\x78\xf9\xac\xa9\x7e\xcb\x0a\x0e\ +\x72\x74\xa8\x62\x0c\x28\xfb\x4f\x31\x20\xf9\x49\x0c\x60\xa4\x65\ +\xc4\xfd\x6c\xac\x7d\xdb\x17\xc5\x00\x5d\x87\xd9\xb7\x35\xb1\xbb\ +\x8c\xea\x18\xb0\xfb\x4c\xc9\x7f\x8d\x01\x41\xae\x5b\x1e\xf0\x20\ +\xb4\x7d\xfb\xf6\x41\x8a\x81\xbc\x5c\xdc\xf5\x72\x58\x55\xf6\xef\ +\xbb\xc0\xdd\x7f\xd9\x05\x0e\x5d\xae\xc4\xf6\x98\x3c\x2c\x92\x5d\ +\x60\x94\xd3\x0d\x18\x4e\x71\x35\x7f\x51\x0c\x60\x69\xf5\xd3\x78\ +\xf3\x75\x57\x7f\xdd\x05\xf6\xc5\xff\x7e\x17\x28\x7b\xb2\x0b\x48\ +\x3d\xc3\xaf\x58\x5e\x88\xd2\xbd\xbc\xbc\x6a\xd5\x90\x7e\x9e\x97\ +\xa5\xcc\xad\xd9\xbc\x62\xd9\x9d\x3b\xf1\xa7\x91\x97\x78\x1e\x95\ +\xf7\xae\xa1\xf0\x5e\x12\x1e\xa6\xa5\x21\x25\x39\x15\x57\x2f\xdf\ +\xc0\xd9\xb8\x93\x08\x0a\x3a\x82\xad\x6e\x87\xb0\xd4\x3e\x10\x8b\ +\x26\x4c\x77\x79\x51\x0c\xf0\xc3\x28\x6b\x9f\x39\x2b\xf6\x62\xdd\ +\x96\x50\xec\xf2\x8f\x46\x6c\xd4\x09\x24\x9c\x3e\x8d\xa4\xc4\x1b\ +\xc8\x48\x4d\x45\x7e\x46\x1a\x34\x99\x49\x28\x4d\xbd\x82\xb8\xb0\ +\x03\x38\x79\xf2\x24\x0f\x41\xfe\x1c\xcb\x46\x87\xc9\x62\x8d\xaa\ +\x79\x53\xac\x9d\x98\x34\x48\x9d\xd8\x5e\xa5\x95\x8b\x77\x58\xa2\ +\x32\x6c\x01\xb3\x2b\x7c\xbf\x56\x69\xe8\xd2\x79\xba\x24\xc8\x3d\ +\xab\xda\x38\x66\xaa\x77\xfd\x45\x31\x40\x48\xbf\xb7\xcf\xde\x1c\ +\x5a\x8f\xb8\x88\x8f\x38\x89\x97\xb8\x89\x5f\xe9\x51\xec\x32\x42\ +\x8e\xf9\xab\x10\x19\x7e\x08\xfe\xde\xee\xf7\xc5\xfd\xd5\x3b\x0c\ +\x5f\x2f\x83\xa5\xc7\x47\x6b\x6e\x6e\xde\xf3\xaa\x55\x7b\x0d\xbb\ +\x32\x72\x16\x7e\xc2\xfc\x3a\x2b\xb2\x4c\x32\xb2\x48\xc9\x3a\x1d\ +\x4b\x55\x4c\x3c\xa8\x57\xcf\x24\xcb\xba\x38\x6d\xd4\xa0\xc3\xf3\ +\x56\x3e\xb6\x6f\xa3\xd6\x17\x07\xd5\xaf\x4c\x16\x3c\xc4\x45\x7c\ +\xc4\x49\xbc\xc4\x4d\xfc\xc9\xbb\x97\x22\x6c\xaf\x0f\x22\xc2\x0e\ +\x62\x97\xb3\x03\x46\x0d\x1e\xd4\xa3\x7a\x3c\x1b\x9d\xa2\xe4\x44\ +\x74\x5f\x22\x69\xe3\xfd\xa6\xed\x92\xef\x8c\x6b\xc7\xfa\x3b\x8b\ +\x8e\xac\xcd\xf3\x75\x92\x15\x5a\x95\x64\xa8\x94\x3a\x1d\xf3\x6f\ +\x4c\x46\xa6\x8e\x7e\x03\xa7\x4c\xf5\xdc\x9f\xaf\x01\x58\xbb\xd0\ +\x0f\x4a\x1c\xfc\x26\xf1\x10\x17\xf1\x11\xa7\xe0\x95\x17\xb7\xc0\ +\x95\x88\x3c\xb0\x17\xf2\x96\x87\xb0\x03\xc1\xf0\x5f\x38\x92\x29\ +\xfb\x02\xea\x5a\x3d\x9e\x3b\x40\x9c\x2c\x81\x12\xb9\xf9\x9a\xf5\ +\x67\xef\x39\xdf\x95\x25\xc0\x96\x14\x96\x9e\x99\x4e\x62\x5a\x89\ +\xe5\x69\x55\x98\x5c\x51\x5b\xb9\xd7\x23\x9b\x57\x91\x2e\x09\x91\ +\x6b\x43\xeb\x95\xc6\x1b\x37\xa9\xfd\x77\x29\x2b\xff\x5e\x92\xbe\ +\xc1\x0f\x25\x78\xb5\xe0\xff\x5f\xea\xaf\xff\xf1\x65\x93\x06\xda\ +\xa4\x61\x75\x15\x9e\x1c\x9b\xd7\x70\x6d\x79\x0f\x84\xb9\xd8\x22\ +\x60\xb7\x1f\x82\x83\xf6\x23\x78\xff\x5e\x04\xad\x9b\x8f\x13\x53\ +\x3f\x46\xca\xe4\x0e\xf0\x30\xef\x14\x46\x5d\xab\x79\xf2\x4d\x70\ +\x8f\x78\x40\xc6\xf1\xe3\xc7\x5f\x92\xe4\x86\xe1\x0d\xab\x76\x15\ +\xa9\x13\xda\xa9\x06\x84\x22\x67\x0b\x54\x04\xeb\x8a\x90\x08\x9e\ +\x08\x6c\xf9\xe0\xd7\x9c\xc0\x03\xeb\xd7\x91\x32\x4a\x79\x81\xff\ +\xb3\x56\x7c\xcb\x96\x2d\x75\xa4\x2d\x2e\x4a\xfe\x56\xd8\xd9\xd9\ +\x55\x3a\x3b\x3b\x63\xdb\xb6\x6d\x05\x5e\x2e\xdb\x2a\xfc\xd6\x2f\ +\x87\x9f\x93\x1d\x5c\x36\xdb\xc3\xc1\xde\x1e\xab\x56\xad\xc2\x36\ +\xe7\x2d\xd8\xe5\xe6\x8c\x18\xa7\xd9\x48\x5a\x67\x82\x07\xf6\x46\ +\x4a\x9f\xdb\x93\x3b\x56\x0e\xfa\xbc\xeb\x6f\x76\x2f\x06\xc1\xb5\ +\x92\x1f\x63\x7a\xe8\x13\xf9\xd7\x3c\xdc\xac\xcd\xfd\x54\x09\x86\ +\x6c\x4e\xe2\x32\x60\xa9\x89\xcb\x40\x65\x57\x7c\x06\xb0\x12\x23\ +\xa5\xeb\x27\x5e\x90\x3c\xbc\x2e\x2e\x19\x37\x18\xfd\xac\x94\xb7\ +\xb5\xb5\x7d\x55\x26\x29\x63\xe5\xca\x95\x55\xa2\xf4\x5d\x31\xc4\ +\x0e\xc1\xec\xef\xeb\xb2\xf5\x56\x80\xb7\x07\xf6\x78\xbb\x21\x28\ +\x70\x2f\x02\x77\x79\x22\x54\x82\xdc\x29\x87\x21\xc8\xd8\xd4\x1b\ +\x79\x5e\xa3\x50\x16\x3a\x97\xf8\xa9\x87\x5a\xd6\x97\xc7\x77\x28\ +\xa4\x8e\xff\x6e\x80\xfe\x92\x23\xcb\x67\x76\x44\x5c\xa3\xf6\xf4\ +\x2f\x3a\x78\xdf\xb5\x7e\x17\xf7\xbe\x7b\x8f\x95\x56\xdd\x6e\x10\ +\x3a\xef\x49\x30\x74\xea\x84\x0a\x29\x55\x17\xce\x64\x2c\x78\x0d\ +\x77\x25\x33\x9c\x68\x51\xaf\xec\xaa\x71\xc3\xf7\x9f\x85\x01\x44\ +\x61\xb7\x35\x6b\xd6\x60\x9b\xfc\xab\xbe\x77\xc1\xa8\x51\x97\x0b\ +\xc6\xfa\xf9\x49\x96\xf5\x91\x36\xbe\x9e\x2a\xbf\xe7\xcf\xa9\x85\ +\xb2\x45\xaf\x40\xeb\xd8\xa9\x3a\xf8\x11\x37\xf1\x53\x0f\xa9\x54\ +\xbf\x07\xf7\x41\x1d\x63\xa8\xe3\xef\xea\x02\x92\x1d\xd1\xc8\x4e\ +\x70\x9d\xef\xd6\xb2\x0c\x4c\x8e\x0d\x69\x9d\x9f\x32\xa1\xbd\x4a\ +\x21\x15\xac\x1b\xc8\xfa\xbb\xce\x0b\x22\xe6\xb2\xfa\xc2\x2d\x86\ +\x25\x29\x46\x5c\x95\x86\x4a\x95\xa5\x90\x60\x5e\xff\x2e\x7b\xf8\ +\x9e\x81\xfb\x67\x6d\xde\xbc\x39\x8b\xd7\xa4\x8b\x06\x0d\x3e\xbf\ +\x38\xb0\x41\xd1\x8d\x21\xf5\x28\xb7\x3a\x25\x4e\x3c\xc4\x45\x7c\ +\xc4\x49\xbc\xc4\xad\xf0\x3f\x90\xd9\xbf\x31\xfe\xdd\xf2\x1e\x5d\ +\xbb\x0e\xa2\x8e\xbf\x33\x80\xa4\x9a\x4f\x48\x96\xf5\x21\x83\xcb\ +\x07\x1f\x7c\xd0\xc4\xb2\x67\x47\x4f\x9e\x09\x68\x35\xe5\x05\xdb\ +\x87\xb3\xde\xa6\xf3\x82\xd0\xa9\xdc\x11\x98\x78\xac\x5e\x0a\xdc\ +\x7e\x24\x1e\xd4\xc1\xd5\xc1\x6f\xde\xbf\x62\xac\xd7\xfd\x69\xae\ +\x7d\x49\x7f\x43\x02\xdf\x21\x35\xf3\x06\x8d\x8c\x2e\x0d\x68\x50\ +\x46\xe5\x29\x8f\x72\x29\x9f\x38\x88\x87\xb8\x88\xaf\xba\x3e\x48\ +\xdc\xb9\xcb\xbe\x50\x55\xe2\x9f\x0d\xde\x0f\xa7\x6e\xff\x2e\xa3\ +\x3a\x25\xd6\x9b\xcd\xc8\x7b\xf6\xec\x09\x14\x0b\xd5\x94\xc2\xac\ +\x41\xa8\x49\xeb\x07\x29\xe3\x24\x16\xcc\xee\xc2\x4a\x2b\x5b\x51\ +\x74\x3d\x40\x87\x7f\x00\xf6\x5b\x31\x20\xca\x76\xc3\x7e\x00\xdd\ +\xe1\xe8\xfe\x63\x23\x24\x0e\x79\xb3\xe2\xa2\x71\xfd\xe9\x4f\xc3\ +\x00\x12\x97\x7a\x4a\xd0\xab\x90\xae\xf1\x95\xf1\x86\xfa\x23\x13\ +\x06\x36\xac\xa8\x56\x9e\xf2\x28\x97\xf2\x89\x83\x78\x88\x8b\xf8\ +\x88\x93\x78\x89\x9b\x05\x91\x4b\xa3\xdb\x95\x50\x27\xea\xf6\xff\ +\x2d\x8d\xc9\x12\x48\x0a\xdc\x1f\x98\x25\xef\x05\xcd\xf9\x7e\xdd\ +\xbf\x5b\xe7\xf5\x49\x63\xda\x68\xb9\x14\x18\x41\x0b\x37\xab\x02\ +\xe9\xe3\xa5\x30\x4f\x77\xca\xda\xd4\x9e\xf1\x80\x05\x09\x9d\x27\ +\x4c\xac\xa5\xf6\xe3\x5b\x72\x2a\x4b\x18\xd4\x30\xf0\x82\x41\xfd\ +\x56\x7f\xb1\x19\x7b\xdc\xc6\x8d\x1b\xe1\x3a\x69\x40\xe6\x35\xd3\ +\xfa\x5a\xf2\x25\x7f\xca\xa1\x3c\xca\xa5\x7c\xe2\x20\x1e\xe2\xaa\ +\x2e\x8c\x12\xef\xc3\xf9\xdd\x71\x67\xdc\x3b\x98\xdb\xe7\x7d\x1f\ +\xea\xf4\x5f\x8b\xa3\x4e\x4e\x4e\x9f\x47\x47\x47\xb1\xf9\xf9\x32\ +\xd7\x89\x14\x3a\xbf\xd8\xd6\xbf\x6d\xe2\xed\xb1\x6d\x75\x01\x71\ +\xf9\xd7\x74\x29\x9e\x0e\x59\x71\x61\x8f\x8e\xee\x6c\xb0\xbe\x15\ +\x41\x70\x26\xd8\xca\xc2\x35\xa9\x72\xf4\xb7\x2d\xe9\x0d\xf5\xb4\ +\x97\x4c\xea\x87\x5f\x34\x6a\x30\xb0\xba\x3c\xfd\x67\x89\x81\x2e\ +\x78\xc1\xd8\xd8\xf5\xeb\x1c\xb0\x63\xec\x17\xe4\x47\xbe\xe4\x4f\ +\x39\x94\x47\xb9\x94\x4f\x1c\xc4\x43\x5c\xc4\xa7\x70\xe6\x48\xd3\ +\xd4\x1d\xe9\x21\x8c\xb6\x78\x27\x8b\xba\x50\xa7\x3f\xac\x0e\x4b\ +\x0c\x08\x0e\x0a\xda\x5f\xec\xe1\xe1\xbe\x49\x06\xbc\x29\x25\xaf\ +\x59\x87\x8c\x5b\xe5\xb0\x54\x96\x61\xd3\x49\x55\x5a\x4b\x76\x8e\ +\x46\xe5\x81\x39\x40\xf4\x13\x23\x70\x06\x78\xfa\xe2\x5a\xcc\x97\ +\x80\xc4\x32\xd5\xfd\xf1\xca\x1b\xd4\x36\x49\xb7\xbd\x68\xaa\x77\ +\x6f\x9c\x8d\xe3\x69\x93\x29\x9e\xab\xdf\x9f\x73\xb2\xff\xfb\xb3\ +\x4e\xbe\xd3\xd5\x3a\xfe\x15\x12\xaf\x79\xcf\x78\xb2\xf7\xaa\x31\ +\x93\x1d\x4f\xc7\x9b\xe8\x27\xc9\x8c\x23\x76\xb6\x21\xa4\x2b\x1d\ +\xde\x13\xbf\x24\x3f\xf2\x25\x7f\xca\xa1\x3c\xca\xad\x56\x9e\x78\ +\x88\x4b\xe1\xcb\x5b\xd5\x17\x3c\xd1\x5e\x1c\xf9\x4e\xe9\x67\xdd\ +\xbb\xce\xa5\x2e\x7f\xaa\x41\x82\x27\x2d\xf1\x80\x34\x59\x0a\x5a\ +\x59\x7f\xbe\xb2\x23\xbc\xdb\xb3\xdb\xc7\x6b\xe2\x87\xb4\x28\x4b\ +\x1e\xd5\x1a\x59\xb3\x3e\xe4\xba\x62\xeb\x2a\x5b\xd4\x9e\x54\x8d\ +\x02\x2c\x01\xe7\x2e\x0c\x44\x2c\x4d\xf1\x38\xca\x59\xe2\xd1\x94\ +\xc0\xd5\x56\x79\x4b\x3a\x3b\xcc\x1c\xae\x62\xc0\x9a\x04\x7c\xbb\ +\xe2\x22\xbe\xf9\xe9\x02\xbe\x5e\x76\x4e\x4b\xe2\x75\x5f\xb9\x67\ +\xb8\x3a\x01\x83\xd6\x5e\x41\xa2\xa5\x3e\x58\xe8\x38\xb5\xa0\x2f\ +\xd6\xda\xd9\x21\x60\x5a\xdf\xea\x46\x29\xf2\xa7\x1c\xca\xa3\x5c\ +\xca\x27\x0e\xe2\x21\x2e\xc1\x67\x80\x94\x89\xed\x70\x63\x64\xeb\ +\x2a\x93\x4f\xbb\x6c\x94\x72\x7d\xbb\xff\x53\x8b\x8c\xbc\x25\xd5\ +\x96\x60\x78\xd3\xd3\xcb\xa3\xd2\xd1\x69\x73\xf9\xac\xd9\xb3\xce\ +\x9b\x7d\xd3\xeb\xd0\xb5\x61\x2d\xaa\xd8\xa4\xfc\x60\xa6\x1c\x90\ +\xec\x8d\x28\x8c\x91\xf6\x71\x7f\xe0\x7c\x20\x68\x3c\xe0\xde\x9b\ +\x8d\x0a\x0c\x4a\x72\x64\x7e\x62\x08\xce\x5c\xfa\x77\x6f\xe2\x7b\ +\xcf\x14\x4c\x71\xbd\x8d\x09\xdb\x92\xc0\x3c\xfe\x98\x2d\x37\x15\ +\x8d\x75\xbe\xa9\x52\xed\xdf\xb9\x24\xab\xa4\x46\xda\xc4\xfa\xca\ +\xd5\x2f\x2d\xfa\x0c\x3f\xfd\xf4\x13\x42\xe6\x1b\x49\xf9\xbb\x26\ +\xf9\x92\x3f\xe5\x50\x1e\xe5\x52\x3e\x71\xe8\x94\xff\xd9\x00\xa9\ +\x12\xb3\x6e\x8d\x68\x85\xe9\x5f\x75\xdc\x2f\x51\xbf\xdb\x1f\x55\ +\xac\xff\x5b\x29\x7a\xba\xaf\xaf\x4f\xe6\x5a\x7b\xbb\x8a\x61\x96\ +\x43\x31\x63\xd0\xd7\x9a\xeb\xc3\x5a\xe0\x86\x34\x28\xa7\x73\x39\ +\xd8\x19\xb0\x53\x53\xd6\xdc\xf7\x0c\x3c\x2c\x44\xb2\x22\xcb\xae\ +\x4e\x36\x35\xb2\xd3\x93\xbd\x7d\xdc\x9f\x75\xf1\x61\x76\x1d\xac\ +\x0b\xcb\x56\x85\x95\xe5\x81\x99\x58\x2a\x45\x8c\x1f\xf7\xa4\x93\ +\x58\xd0\x60\xbd\x81\xfd\x83\x2a\xa3\x93\xf3\x7d\x5d\x5d\xe7\xc9\ +\xb2\x2e\x90\x5d\x00\x11\xcb\xcc\x50\xb9\xbc\x2e\xf9\x92\x3f\xe5\ +\x50\x1e\xe5\x52\xbe\xc2\x91\xb3\xbc\x37\x92\x46\xb7\x11\x7c\x2d\ +\x61\xff\x6d\xfb\xb3\xb2\xee\xfb\xfe\x99\xb2\xdd\x9f\x39\x89\xbd\ +\x2b\x5e\xb1\xcb\xfa\x3b\xeb\xdc\xe9\x66\xdf\x6a\x13\x2c\x5a\x80\ +\xfd\x03\xb4\x74\xee\xaa\x3e\x28\xde\x3a\x8c\xed\x69\xaa\x23\x03\ +\xd1\xca\x1b\x74\x0d\x4b\xbb\xcc\x80\x1d\x3d\x58\xaf\xd7\x2d\x8d\ +\x1f\x6b\x21\xe0\x97\x52\x56\x97\x54\x97\xe8\xce\xd8\x02\x56\x71\ +\x14\xb9\xc6\xaa\x6e\x51\x76\x90\xaa\x74\x56\xe9\x0f\xb5\xd5\x3b\ +\xc7\xfd\x55\xed\xe1\xe4\xb8\x19\x51\x6b\xad\x50\xe5\x33\x88\x7c\ +\xc9\x9f\x72\x28\x8f\x72\x95\xfc\x07\x0b\x7b\xe2\xc6\xf0\xe6\xb8\ +\x3e\xac\xb9\x76\x69\x9f\x77\x4f\x8a\xdb\x0f\xe5\x89\xef\xa9\xb6\ +\xca\x0a\xc3\xfa\xfd\xfa\xf5\x9b\x3e\x6c\x40\xff\x6b\x27\xa5\x4f\ +\xe7\xba\x45\x53\x24\x8d\x6a\x85\xec\xc5\x9f\xa9\xfa\x7b\xa9\x87\ +\x15\x23\xf0\x93\x46\x69\x6e\x49\x3c\x94\x70\x9d\x7a\x19\xa0\x6a\ +\x47\x2f\xe6\xe9\x98\xad\x55\x7d\xc1\x51\xd7\xaa\x10\x79\x55\x47\ +\x87\xe5\x9a\x7d\xc3\x2c\xbf\x31\x99\x59\xb5\xe9\x5d\x35\xdb\x59\ +\x9e\x23\x20\x81\x19\x47\x9c\xe7\xa0\xfc\xc0\xf7\xd5\x0d\xd3\x94\ +\xa3\xe4\x15\x6c\x30\xc1\x5d\x9b\xce\x10\x2c\xec\x09\xac\x18\xdd\ +\xab\x23\xcf\x31\xc3\x88\xf5\x99\x74\x8b\xb3\x0e\x27\x3b\x43\xbf\ +\xee\x5d\x3f\xda\x14\x32\xa0\x45\x36\x3f\x65\xb9\x2e\x94\x32\x5e\ +\xce\x0a\x2b\x7a\x57\xb7\xca\xab\x37\x48\x2d\xbd\x41\x88\x19\x19\ +\x06\x2a\xed\xc1\xef\x55\x92\xf2\x7c\xaa\xae\xd4\x76\xf6\xce\x6f\ +\xa9\xba\x63\x9c\x99\x5c\x6d\xb0\xb5\x32\xde\xa3\xd0\x1f\xb1\xdb\ +\xdf\x0f\xb1\x6e\x4b\xa0\x91\x3a\x3f\xf9\x92\x7f\xd1\x16\x0b\x64\ +\xcc\xe9\x0e\x76\xb1\x11\xc3\x49\xb3\x16\xc5\xbd\x3f\xf9\xd0\x99\ +\xd8\x88\xf1\x99\xb6\xcb\x8b\x80\x57\xc5\xc5\x7a\x08\xd9\x3a\x7c\ +\xdd\xfa\xea\x25\xf3\xa6\x55\x6c\xa6\xbc\x2a\x40\x52\xad\x3b\xca\ +\x56\xd9\x5f\x19\xa2\xd4\x6b\x3c\xca\xf7\x4d\xd7\xa5\xd5\x8e\xd8\ +\x42\x7b\x64\x39\x92\xb3\x80\x5b\xd5\xdf\x0a\x64\x00\xd7\x9f\x50\ +\xf5\x37\x03\x4c\x63\xcb\x2c\xff\xa4\x82\x5b\x4e\xc4\x6a\x7e\x32\ +\x87\x38\x37\x5b\x14\xee\x1c\xa5\xf8\x66\xfe\xf0\x19\x12\xa5\x81\ +\x8b\x32\xaf\x98\x37\xd1\xfa\x18\xb6\x4e\xed\x2a\x58\x88\x89\xd8\ +\xfe\x96\x0f\x26\x78\xa4\x94\x08\xfb\x9e\x58\x7c\x5a\xcf\xae\x5d\ +\xdc\xbd\xfb\xb7\xbc\x77\xd9\xf4\x9f\xda\xcb\x83\xde\xc2\x55\x01\ +\x76\x5b\x3c\x22\x73\xc1\xa7\xe2\xa2\xa6\xec\xce\x50\xc7\xd2\xb2\ +\x7d\x33\x91\xf5\xaf\x5f\x8b\xe4\x02\xf7\x14\xc9\x35\x29\x8f\xbf\ +\xe9\x72\xf8\xe5\x21\xf3\xd4\x69\x2e\xcd\x73\x26\x22\x24\x89\x79\ +\x62\xe3\x34\xa4\x4d\xff\x40\x29\x4e\x19\x97\xa5\x43\x2c\x74\x60\ +\x8b\xec\xfe\x9f\x7c\xe8\x4b\x0c\xc4\x42\x4c\x7f\xeb\x27\x33\x8f\ +\x4f\x8b\x8d\xc4\xf2\x7d\xe4\xbc\xb0\xa0\x4f\xf7\xce\xbb\x43\x0c\ +\x9b\x65\x13\x60\x82\x49\x63\x92\x02\x7a\x4b\x1a\x9e\xd3\x67\x77\ +\x43\xae\xbd\xb1\xca\xcd\x17\x69\x9e\x7c\x2b\x94\xaf\x88\xd7\x8a\ +\x54\x49\xbe\x44\x23\xd7\x8e\x16\x78\xb0\xe4\x4b\x1c\x5f\x31\x01\ +\x52\xb8\x45\xec\xf7\xfd\x65\xb6\x75\x7c\x8f\x18\x37\x2d\x1c\xde\ +\xf3\xfd\x60\xca\xa4\x6c\x62\x20\x96\xe7\xf0\xe1\xe4\x6f\xbc\xa1\ +\xa9\xcc\xc4\x40\x01\x63\x3b\xb0\x7b\xa7\x60\x97\xbe\xad\xd3\x4e\ +\x98\xb6\xc0\x25\x93\xb7\xf8\x4d\x91\xa2\x04\xf3\x66\x2c\x4c\xfc\ +\xe6\x8b\xb1\xea\x7f\xbc\x26\x55\x7f\x39\xc6\x67\x39\xe6\xe0\xe6\ +\x95\x60\xd3\xc6\x59\x8b\x96\x9a\x3d\x86\x2d\xee\x8f\xfc\xb4\x63\ +\x38\x65\x50\x16\x65\x52\xf6\x5f\xc5\xff\x54\x1b\x19\x85\x5a\x0b\ +\x99\x09\xc0\xd9\xd2\xbf\xe3\x3a\xc2\xc2\x3c\xcf\x71\xf0\xa7\x88\ +\x36\x6e\x59\x79\xde\xac\x79\x55\x4e\x6e\x11\xf2\x8a\x1e\x7f\x2f\ +\x58\x5a\x81\xa2\x27\xc4\xef\x07\x75\xdf\x0e\x16\x94\xe1\x82\x79\ +\xf3\xaa\x83\xd6\xdf\x6a\xa2\xa2\x0e\xc3\xd3\xdd\x2d\x4f\x66\xda\ +\x81\x3c\xc9\x9b\x32\x28\xeb\xf9\x7e\x3a\xfb\xc7\x86\xd0\x97\x99\ +\xfa\x40\x8c\x60\x6e\x6d\x6d\x7d\x6e\xd2\xa4\x49\x45\x42\x55\x43\ +\x87\x0e\xcd\x1e\x6d\x39\x3c\x75\xe9\xc4\x11\x29\x9b\x57\xda\xe7\ +\x3a\xba\x86\x6a\x1c\xdd\xc2\x35\x5b\xd6\x6f\xcb\xb5\x9b\x63\x73\ +\x73\xde\x8c\x69\xf1\xf3\xe6\xcf\x3f\x2f\x87\xb0\x6c\xf9\x3a\xb4\ +\x54\x52\x75\x9a\x3e\x7d\xfa\x0c\x27\x2f\xf2\x7c\x16\x1d\xa8\xcf\ +\xba\x68\x59\x53\xa8\x81\x8d\x8d\x8d\xa9\xb4\xb4\x1d\x95\x63\x6d\ +\x16\x5f\x6e\x98\xb8\x0c\x8b\x88\x42\xae\x78\x03\x29\xf1\x66\x32\ +\x1b\x18\x8b\x1f\x7f\x30\x5d\x2a\x5f\x85\x56\x49\x9a\x2e\x41\x0c\ +\xd6\x82\x3c\x9e\x25\x46\xfe\xe7\x6f\xa5\xe5\xcb\x97\xff\x53\xd2\ +\x7b\xc3\xb6\x7b\x07\xad\xde\xb1\xe7\x88\xf7\xce\x7d\xb1\xfe\x2e\ +\xbe\xc1\xeb\xe5\xde\x2c\x49\x7c\x4c\xe2\xa7\xf2\xac\xd9\xfd\x5d\ +\x78\xfe\x1f\x54\xc7\x67\x32\x0b\x29\x7c\xe5\x00\x00\x00\x00\x49\ +\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x13\x17\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\ +\x01\x1e\x75\x38\x35\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x12\x94\x49\x44\ +\x41\x54\x78\xda\xed\x9b\x09\x90\x5c\x47\x79\xc7\xff\xdd\xef\x9a\ +\x73\x67\xf6\xd2\xae\x56\xbb\xba\xbd\xb2\x84\x0e\x0b\x1b\x51\xb2\ +\x1d\x0a\x6c\x8e\x40\x9c\x40\x48\x0a\xca\x54\x80\x70\xe4\xa8\x8a\ +\x53\x60\x08\x15\x8a\x22\x45\x48\x02\x14\x47\x01\x45\x05\x63\x28\ +\x53\xa9\xd8\xd8\xb1\x62\x82\x6d\x8e\x02\x0c\x54\x30\x92\x15\x09\ +\xc9\x96\xac\xd3\xd2\xae\x76\x25\x4b\x7b\x68\xaf\x99\xdd\xd9\x9d\ +\x79\xf3\x8e\xee\x7c\xaf\x5f\xc7\x33\x7b\x69\x25\xb0\x1c\x57\xa1\ +\x4f\xfa\xeb\xeb\xd7\x3b\xf5\x66\x7e\xff\xef\xeb\x7e\x6f\x34\xb3\ +\x4c\x4a\x89\xdf\xe5\xe0\xa4\x6b\x06\x5c\x33\xe0\x9a\x01\xd7\x0c\ +\xb8\x66\xc0\x35\x03\x5e\xfa\x60\x51\xe0\xff\x39\xae\xca\x7d\x00\ +\xbb\xee\x73\xad\x46\xd2\x79\x95\x44\x78\x13\x24\xef\x92\x12\x79\ +\xce\xd1\x68\x9a\x46\x63\xd2\x36\x9a\x52\x09\x33\xcf\x18\xcf\x80\ +\x49\x37\x0c\x51\x0c\x05\x0a\xbe\x2f\x0a\x55\x5f\x4c\x54\xaa\xfe\ +\xf8\xb6\x75\xa9\x83\x87\x1f\xff\xab\x7b\xf1\x12\x84\xf9\xdb\x97\ +\x11\x0c\xaf\xf8\xda\x2d\x8d\x59\xeb\x35\x89\x84\xb5\xa3\x54\x0e\ +\xb6\xb7\x2c\x6f\x59\x99\x72\x2c\xa4\x93\x26\x32\x29\x0b\xd9\xb4\ +\x85\x5c\xc6\x42\xc2\x31\x60\x5b\x06\x4c\x83\xc3\x88\xc4\x59\x86\ +\x31\x64\x00\x74\x0a\x01\xb8\x5e\x88\x3d\x87\xc6\x83\xa1\xbe\x5f\ +\x5a\x00\x5e\xde\x06\xb0\x1b\xee\x5d\xd1\xdd\x95\xff\x9b\xed\xef\ +\xb0\xdf\xdd\x37\x90\xeb\x5c\xd7\xd5\x00\xce\x01\xc7\xe6\x24\x03\ +\x09\x3b\x86\xa5\x63\x3d\xa6\xf9\x48\xb6\xa9\xc6\x96\xc9\x94\x11\ +\x8c\x01\xa1\x00\xaa\x04\xbf\xef\xe8\x04\x5a\xf3\xe1\x91\xde\xfd\ +\x67\x72\xa0\x78\xd9\x19\xc0\x5e\xf7\x4b\x33\x17\x0e\xbf\x6d\xd3\ +\x9a\xdc\x5d\xc9\x64\xc3\xad\x4d\x8d\x0d\x46\xa1\x54\xc5\xaa\x8e\ +\x26\x30\x82\xb1\x6d\x05\x1c\x03\x92\x6c\xc7\xd0\x63\x03\x96\x1d\ +\xcf\x99\x26\x87\x11\xc9\x60\xaa\x7d\x04\x24\x02\x21\x31\xed\x4a\ +\x4c\x56\x8c\xca\xc9\xbd\x8f\x77\x02\x38\xff\xb2\x33\xc0\xda\xf9\ +\xdd\xd7\x6e\x5f\x9b\xbf\x2f\x9f\x6d\x5f\x37\x34\x56\x41\x7b\x6b\ +\x0e\xe3\xd3\x8c\x40\x12\x90\xdc\x80\x50\x30\x1c\x81\x34\xc0\x25\ +\x03\x17\x1c\x2c\xe0\x90\xe0\x08\x49\xbe\x60\x70\x7d\xc0\xe0\x91\ +\x24\xb1\x4b\x48\x09\x25\x3f\x94\x38\xda\x57\x46\x02\x13\xc7\x67\ +\x4a\x85\x9b\x40\xf1\xb2\x31\x80\xdd\xf2\xe8\xb2\x5c\x22\xf9\xd5\ +\x1b\x36\xb4\xdd\x79\x71\xc2\xc5\xc8\xa4\x4f\x00\x16\x38\x67\x08\ +\x25\x00\x82\x05\xc1\x8a\x00\x04\xca\xe0\x4b\x0e\x2f\x8c\x2a\xcd\ +\x60\xfa\x24\x83\xc5\xd0\x06\xc0\x19\x03\xe7\x50\xf0\x00\x53\xf0\ +\x42\x4a\x94\x5d\x81\x54\x32\x39\xf5\xd4\x4f\x1f\xee\x06\x38\xc0\ +\xf8\xcb\xc3\x00\x76\xf3\xcf\xb7\xb4\xe6\x1a\x7f\xd1\x90\xb6\x5a\ +\xcf\x0c\xfa\x04\x61\x13\x0c\x83\x90\x04\x24\x19\x01\xc5\xe3\x80\ +\x80\x0d\xca\xbe\xe0\xe0\x3e\x08\x32\x12\x81\x2b\x78\x46\xc0\x0c\ +\x94\x94\x50\x77\xe5\x13\x92\x91\x00\xd7\xe3\xc8\x89\x9e\xd3\x9e\ +\x57\xbd\x09\x64\x2e\x98\x81\x28\x3e\x73\xf3\xcd\x2b\x66\x86\x87\ +\x1f\x19\xef\xef\x3f\x2c\x81\x43\x9c\x64\x03\x47\xbf\x26\x65\xf5\ +\x6a\x1b\x40\xf0\xbb\x77\x80\x27\x7e\x5c\xaa\xf2\xa6\x42\x59\x2a\ +\x78\x53\x30\xbd\x7b\x03\x66\x54\x51\xc9\x09\x54\x57\x56\x12\xa8\ +\x40\x04\x4b\x42\x2c\x30\x5d\xcc\xd8\x84\xfa\x90\x32\x9e\xf7\x42\ +\x89\xed\xeb\xec\xb1\x1f\xdd\xbf\x6b\x73\x0d\x9e\x44\x91\xe4\xfc\ +\xb3\x76\x5b\xdb\xce\xd6\x15\x2b\x76\x7a\xd3\xd3\x70\x4b\x25\xb8\ +\x53\x53\xc1\x47\xd3\xe9\x43\x7e\xb9\xfc\x98\x00\x1e\xff\x57\x29\ +\x8f\xbf\xe8\xf7\x01\xec\xf7\x7e\xdd\x0d\x66\x1c\x04\x43\xb6\x6e\ +\x76\x56\xd6\x70\xaa\xc2\xbc\x2e\x73\x65\x80\x56\xfc\x40\x95\x05\ +\xe2\x6a\x0b\x11\x29\x5a\x3e\x92\xb2\x44\xf7\x0a\x0b\xd6\xe4\xbe\ +\x83\x87\xf7\x7e\xef\x26\x05\xcf\x38\x28\x3f\xfe\x8d\x2d\x85\x4f\ +\xd2\x39\x0e\xe5\x57\xad\x32\x79\xf4\xd8\x30\x44\xe8\x79\x4a\x81\ +\xeb\x62\x66\x6c\x0c\xa5\xc1\xc1\x28\x9f\x71\xa7\xa7\xff\x0b\xc0\ +\x3d\x5f\x92\xf2\xdc\x8b\x63\xc0\xeb\x8e\xff\x84\xd2\x9b\x66\x41\ +\xb3\x7a\x23\x2e\x31\x66\x97\xff\x73\xc7\x62\xf8\xe3\x9d\x7c\xf0\ +\xe1\x7b\x3e\xd2\x4e\xe0\xfc\x05\x03\x38\x7f\xfc\xdf\xb6\x15\x13\ +\xcb\xb7\x6d\x7b\x53\xaa\xa5\x05\x22\x82\xae\x54\x40\x55\x87\x4f\ +\x39\xa0\xac\x8f\x95\xca\x64\xc6\xe4\xb9\x73\x81\x5b\x2c\x3e\xc4\ +\x84\xf8\xfc\xa7\xa4\x3c\xf1\x1b\x2f\x01\x76\x5b\xff\x1f\xc1\x48\ +\x12\xfc\xd5\x8f\x1d\x1b\x4c\x3c\xf3\x3f\x3f\xba\x08\x6e\x76\x28\ +\x78\x70\x44\x79\x67\x93\x68\xc9\xe7\x72\x37\x37\xe4\xf3\x90\x42\ +\xc0\x64\xd1\xd2\x33\x60\x58\x16\xcc\xa8\x13\x48\xc1\xff\x49\x08\ +\x38\x4d\x4d\x68\x48\x26\x4d\x32\xe0\x3d\x33\x83\x83\xef\xfe\x22\ +\x63\x0f\x13\xd8\x5d\x77\x4b\x39\x71\xe5\xef\x05\x0c\xf1\xa7\x58\ +\x34\xd8\x8b\xa6\xe6\x2c\xc7\xca\xe6\xa0\xff\xf4\xb3\x4f\x6e\x07\ +\xb3\x00\x66\x02\xdc\x52\x7a\xdf\x3a\xb9\xb9\xa1\xa9\x89\x85\x13\ +\x13\xf0\x49\xa2\x50\x00\x68\xfd\x73\xaa\xb6\xe9\xba\x30\x7d\x1f\ +\x16\xc1\xdb\x11\xbc\x94\x48\x02\x48\x32\x86\x6c\x22\x81\xd6\xe5\ +\xcb\xd9\xb2\xf6\xf6\x3b\x93\x86\x71\xf4\x9b\x8c\xbd\xe1\xca\x37\ +\x41\xc9\x6e\x04\xd8\x6f\x7c\x5f\x7c\x39\x61\x19\xc0\x6b\xb6\x5a\ +\x78\xf2\x89\x07\xcb\x0a\xba\xb6\xf6\xf1\x86\x65\x21\xd6\x58\x7e\ +\xce\xa0\x16\x97\xd1\x9a\x8f\xaa\x0f\xa8\x4e\x00\x41\xb3\x20\x00\ +\x27\x03\x98\xe7\x29\xf1\x6a\x15\x06\x1d\x0b\x9a\xd7\xdd\x01\xdb\ +\xb6\x91\x68\x6c\xec\x08\x8a\xc5\x9f\xde\xcf\xd8\xa7\xde\x23\xe5\ +\x3f\x5f\xbe\x01\x8c\xad\xfc\x4d\x0d\x58\x1a\x9c\x61\xeb\x5a\x13\ +\x5b\x56\xb3\x99\x91\xe1\xa1\xc3\x17\xce\x9e\xb8\x45\x19\xa0\x5b\ +\x9f\x73\x13\x7f\x7d\xbd\x07\xa3\x58\x06\xfc\xf8\x7a\x2a\xb4\xa9\ +\x4c\xc6\x3b\x28\xd3\x26\x48\x12\x27\x03\x84\xef\xc7\x46\x91\x11\ +\x26\x29\xa4\xb1\x3a\x8e\x1e\x63\x59\x8c\x8c\xf9\xa7\xef\x31\x56\ +\x7a\xbb\x94\x5f\xbd\x3c\x03\x44\x70\x0e\xdc\x7e\x05\x5e\xc4\xb0\ +\x4d\x46\xd0\x1c\x5b\xd7\x18\xd3\xbd\xfd\x43\xa7\x1f\x7c\xf8\x99\ +\x0d\x5d\xcb\xcc\x3c\xd8\xec\xea\xbf\x77\x8d\x40\xdb\xf8\x05\x84\ +\x53\x53\xe0\xa6\xa9\x3a\x4a\x72\x0e\xae\xaf\x9b\x4a\x64\x80\xd4\ +\x42\x5c\x79\x95\x8d\xc8\x0c\xea\x1a\x83\x96\x89\x88\x96\x09\x1d\ +\x2b\xc3\xa0\xe2\xcb\x4f\x30\x36\xf4\x46\x29\x77\x2d\x6d\x40\x50\ +\x2c\xc1\x5e\xb6\x64\x7b\x2f\x1d\x8c\xc0\x11\x41\x63\xcb\x2a\x3e\ +\xdd\x7b\x6e\xe8\xf4\x77\x76\x1d\xda\xe0\x07\xc1\x2b\x09\x96\xc0\ +\x1c\xa9\xaa\xaf\xe1\x13\x06\xc7\x07\xbb\x09\xec\xbf\xcf\xa8\x0d\ +\x8f\x93\xf4\x6d\x23\x0c\xe8\xd0\x5d\x00\x82\xa6\x2a\x2b\x50\x10\ +\xb0\xa4\xca\xf3\x48\x35\xe0\xb9\x99\x31\x32\xe1\xc7\x8c\x3d\xf6\ +\x66\x29\xab\x97\x36\xa0\x74\xba\x19\x2d\xed\x1e\x00\x1b\x60\x57\ +\x04\xac\x93\x06\xe7\xd8\xb2\x92\x4f\xf7\xf4\x0f\x9f\x7e\xe0\x3f\ +\x0f\x5d\x1f\x04\x82\xc0\x39\xc0\x13\x0a\x3a\x84\x49\x39\x92\xa1\ +\xf4\xf1\x2d\x0c\x89\xa7\x7e\x0e\xb7\xb7\x17\x1a\x5c\xc9\x27\x31\ +\xe8\x3d\x40\x8b\x49\xa9\xe6\x8c\x39\x5b\x33\xe6\x1f\xd7\xe7\x8e\ +\x0c\xf0\x01\x00\xf7\x2c\xb1\x04\xaa\xd7\xc1\x1b\xdd\x03\xa7\xfd\ +\xd6\xcb\x02\x06\x66\x5d\xd7\xb7\xae\x66\xd8\xbc\x8a\x97\x7a\xce\ +\x0e\xf5\x3c\xf0\xc8\xb3\x1a\xdc\xc0\xac\xcd\x0e\x1c\x42\x9a\x1c\ +\x7a\xae\x25\x61\xe0\x5d\x6b\x25\xa6\x1f\x3d\x86\x14\x50\xdf\xba\ +\x98\x21\x25\xe7\xc1\xe8\xbc\x18\xf0\xe2\xa6\xdc\xb9\xb4\x01\xdc\ +\x01\x26\x8f\xec\x40\xeb\xb2\x13\xe0\xe6\xa6\xc5\x80\xe7\x83\x43\ +\x81\x9f\xee\x1b\xea\x7d\xe0\x91\xe3\x04\x1e\x12\xb8\xa9\xab\xa9\ +\x85\xda\x58\xc8\xd0\x89\x0d\xb0\xf0\xc5\x9d\x16\xda\xb6\xad\x41\ +\xc3\xfb\xdf\x8f\xd2\xc3\x0f\x43\x96\xcb\x2f\x00\x0c\x91\x12\xaa\ +\xda\x2f\x4a\xb4\x2e\xbd\x07\x18\x0e\x10\xc2\xc6\xe8\x2f\x96\x37\ +\xaf\x7d\xe3\xb1\xf1\x19\x73\xf3\xa2\xe0\x36\x03\xbd\x6e\x6c\xea\ +\x44\xe9\x54\xdf\x85\xfe\x07\x1e\x39\xd5\x1d\x04\x72\xbb\xaa\xb4\ +\x41\x70\x52\x90\x02\x40\x90\x64\x08\x1a\xe8\xb9\x10\xfe\xd4\x64\ +\x13\xfd\xa3\x9e\x6f\xef\xd3\xfd\xe8\x5a\xd5\x80\x1d\x7f\x70\x07\ +\x52\x3b\x77\x62\xea\xbe\xfb\x50\xdd\xbf\x1f\x13\x00\xce\x92\x9e\ +\x27\xa5\x49\x59\x52\x86\x94\xd7\x62\xb8\xb2\x28\x02\x4d\x4b\xde\ +\x0a\xb3\x57\xff\x40\x22\xac\x02\xc2\x85\x69\x04\x6e\xd0\x78\xfb\ +\xb3\xe9\x74\xea\xd5\x33\x6e\x7d\xc5\x63\xf0\x8d\x2b\xc2\xe9\x53\ +\xbd\xe7\xcf\x1f\x38\x7c\x66\x5d\x18\x4a\x1b\xc2\x05\x44\x05\x08\ +\x23\xcd\x90\xaa\x75\x9b\x27\xd3\xe3\x58\x2d\xe9\x69\x77\xec\xe2\ +\x40\x22\x32\xeb\x6d\x23\xbf\x42\x8b\x37\x81\xfc\x96\x1b\x70\xc7\ +\xbb\xfe\x04\x37\x6d\x5e\x0b\xef\xa9\xa7\xf0\xab\x6f\x7e\x13\x63\ +\x85\xc2\x82\x3d\x68\xe9\x72\xb6\x20\xa6\xe2\x58\x3a\xf6\x00\x07\ +\xfe\x4c\xca\x1d\x97\x36\x60\xe7\x13\x52\x1b\xa0\x55\x95\xd7\x6f\ +\xe8\xde\x5f\x4d\xbe\x62\xcd\xc5\x49\xde\x76\x03\x81\x5f\x4f\xe0\ +\x27\x4e\xf6\x0f\x1d\x38\xd2\xbf\x3a\xac\x4e\x5a\x08\x26\xe3\xc7\ +\x4a\xe8\x16\x67\x7a\x5c\x03\x9e\x3b\xd7\xe8\x14\xbd\xc2\xf8\x45\ +\x3b\x32\xe0\x9d\xc3\x3f\xc7\xb2\xea\x18\x04\x24\x42\x00\xcb\xb6\ +\x6e\x9c\x7c\xd3\x7b\xdf\x69\x74\xac\xec\xcc\x9c\xfe\xd6\xb7\x30\ +\xf8\xb3\x9f\x5d\x72\x21\x9a\xa4\x0e\x52\x27\xc9\xc6\xe2\xf1\x61\ +\xe0\x17\x8f\x4a\xf9\xfa\x4b\x1b\x70\xcb\x93\x92\xa0\x81\x50\xc1\ +\x93\x5c\x35\xb6\x2d\x39\xfd\xd6\xdf\xbf\x75\x60\xa4\x50\xb6\xf6\ +\x1c\xe8\x59\x19\x56\xa7\x4c\x04\xa5\x79\xd5\xd5\x9a\x33\x37\xdf\ +\x8c\x9c\x39\xea\x4f\x16\xc7\x2d\xc0\xc4\xbb\x07\x7f\x88\x76\x77\ +\x34\x32\x80\x04\x84\x94\x07\x10\xa0\x65\xf3\x86\xe0\xad\xef\x7d\ +\x17\xeb\x12\x81\xf1\xdc\x57\xbe\x82\xca\xf0\xf0\xa2\x46\x30\xad\ +\x36\xd2\x4a\x52\x02\xb3\x63\x0c\x28\xbe\x03\x48\xf6\x48\x99\x58\ +\x7a\x13\xd4\xd7\x5c\x3d\x50\xf2\xfc\x6a\x66\x7a\xf8\x40\xe7\xa9\ +\x3e\x99\x0e\x2b\x25\xfd\xae\x2d\x15\x83\x31\x00\xb2\x76\xe9\x8a\ +\x83\x2f\x0c\xaf\x0d\x90\xbc\x04\xf0\x34\xc9\x80\x03\x13\x49\x30\ +\x08\x25\xa0\x80\x10\x06\x8d\x27\x8e\x9d\x36\xbf\xfd\xb1\x7f\x44\ +\xdb\x96\xeb\xc3\xb7\xfc\xed\x87\xd0\xd9\x73\x8a\x0f\x3e\xf6\x18\ +\xf3\x8a\xc5\x05\x4d\xd0\xa0\x28\x90\x56\xeb\xae\xd0\x11\x7c\x16\ +\xd6\xd3\x19\x88\xdb\x97\xde\x04\x79\xa2\x0e\x5c\x67\xe1\x83\xaa\ +\x4d\x29\x6d\x05\x22\x0d\x98\x99\x39\x40\x57\x38\x86\x80\x80\x0d\ +\x98\x91\x81\x26\x1c\x52\x02\x5c\xc1\x07\x91\xd9\x90\xda\x10\x28\ +\x15\x8e\x3e\x67\x7c\xe7\xe8\x67\xb1\x6c\xcb\xc6\xf0\xcd\x1f\xff\ +\x04\xd6\x8f\x8f\xf2\x81\x5d\xbb\x58\xe5\xf9\xe7\xb1\x58\x5c\x20\ +\x4d\x93\xd6\x91\xee\x45\x62\x5f\x05\xec\xf6\x2c\x02\xa8\x58\xba\ +\x03\x64\x9d\x77\x53\xf1\x86\xc6\xcd\xa8\x2e\x3c\x60\x29\xc0\x08\ +\xe7\x54\x96\xcf\x69\x77\x3e\x07\x5c\x46\x7f\xe3\xac\x25\x85\x23\ +\xe3\x67\x8f\x0d\x48\x6a\x03\x26\x10\xc0\xa2\xb1\xa1\x97\x83\x54\ +\x99\x45\x59\x19\xf1\xe0\xc7\xff\x05\xad\x5b\x37\x85\x7f\xf8\xd1\ +\x8f\x61\xbd\x5f\x35\x86\x1e\x7a\x08\x93\xcf\x3c\xb3\xe0\x5d\x4a\ +\x25\x99\xc4\xe7\x2b\x62\xcc\x83\x7d\x6b\x16\x21\x04\x0c\x30\x0a\ +\x49\x71\xe9\xcb\x20\xa4\x92\x82\x07\xa3\xb9\x14\x25\x03\x92\xd9\ +\x2c\x40\x64\x80\xa8\x01\xab\xcc\x6b\x63\x15\x6c\x76\x07\x49\x12\ +\xc3\xac\x39\x21\x38\x60\x64\xd5\x79\x2d\xdb\x81\xe3\x5b\xf0\x45\ +\x08\x57\x32\x24\x04\x87\x50\xc8\x40\xa8\xb3\xa8\xcb\x53\x47\x4e\ +\x1a\xf7\x7f\xe8\x93\x68\xdd\xb6\x29\xbc\xe3\x2f\x3e\x88\xed\x77\ +\x67\x8d\xe1\x07\x1f\xc4\x38\x6d\x96\x32\x0c\xc1\x1d\x07\xc3\x9e\ +\x1f\xec\x66\x59\x0f\xa8\xb6\x78\x90\x48\x13\x7c\x58\x63\xf6\x17\ +\x34\x80\xcc\x31\x70\xfb\x19\x7d\x2f\x50\x06\x98\x45\xe3\x34\x65\ +\x53\x49\x70\x2e\x95\x01\x26\x16\x00\x17\x80\x9c\x05\x59\x4b\xac\ +\x56\x79\xc6\x38\x72\x59\x07\xd9\x95\x67\xf9\xf9\x0d\x5f\x07\xeb\ +\xdf\x86\x7c\x49\x56\x93\x70\x9c\x29\xcf\x85\x15\x98\x30\x24\xc1\ +\x4a\x42\x15\x0a\x5a\x65\x01\xd2\x1c\x23\x4a\xcf\x9e\x34\x1e\xbc\ +\xeb\x13\x68\xde\xba\x51\xdc\x71\xd7\x07\xe4\x8d\x77\xdf\x6d\x0c\ +\xef\xda\x85\x27\x4f\xf5\x54\x2f\x1c\xeb\xb7\x5a\xdc\x20\x55\x81\ +\xa1\x1e\x1d\x92\x32\xe0\xa0\x48\x13\xe7\xa4\xee\x02\x98\x35\x78\ +\x45\x91\x56\x40\x32\x88\x97\x82\x29\x55\xeb\x23\x24\x89\xa8\x03\ +\x04\x42\x9e\xa5\xf9\xd9\xa0\xb5\x2a\x2f\x54\xf9\x48\xea\xfc\xc8\ +\x65\x6c\x34\xae\x1d\x01\x5f\xbf\x07\xd5\x65\x07\x4d\x24\x0e\x81\ +\x75\x1f\xc2\x0f\x6e\x58\x66\xbd\x7e\x4f\x13\xf2\xbb\x4d\x64\xc6\ +\x5d\x50\xf1\x20\x94\x01\x80\x50\x26\x48\x1a\xeb\x63\xc8\x59\x86\ +\x48\x52\xe9\xc8\x29\xfe\xd0\x5f\x7e\x0c\x4d\x64\x84\x63\x04\x41\ +\x43\x71\xc6\x69\x4a\x25\x51\x81\x1b\xbf\x06\xcf\xc7\x34\x24\x9c\ +\xb8\x0d\x9b\xf5\x1d\xb6\x3f\xcb\x00\x3d\xce\x93\x74\xdb\xdb\xba\ +\xf2\x5a\x64\x82\x60\x2e\x42\xe9\x00\x5c\x43\x83\xcd\x06\x55\xa1\ +\x8d\x90\x52\x57\x1c\x04\x6e\x21\xb7\x7a\x08\x7c\xdd\x41\x84\xd9\ +\x01\x54\x05\xe0\xf9\x02\xb0\xa0\xe4\xa6\x05\xdf\x73\x7b\x09\x89\ +\x9d\x1c\x1b\xf7\x25\xb0\x72\x77\x0a\x95\x02\x19\x11\x90\x11\x61\ +\x0c\x2c\xd5\xb2\xd1\x63\x49\x63\x59\x1b\xab\x63\x30\x4c\x93\x11\ +\x99\xee\xe5\x3c\x99\xb4\x11\xb7\x89\x54\x99\x51\x96\x41\x6c\x9e\ +\xbe\x77\x1a\x5e\xcc\x80\x56\x30\x56\x9b\x36\x74\x07\x08\x65\x82\ +\x5a\x8f\x82\xd9\xb3\x61\xa3\x21\xc7\xbc\xca\x33\x03\x68\x48\xdb\ +\xc8\xad\x3a\x0f\xb6\x66\x5f\x0c\x1e\x02\x41\x55\xc2\x0f\x24\x08\ +\x0d\x70\x30\x2b\xdc\x94\xc0\xa1\xdb\xca\x38\x41\x46\x6c\xde\x97\ +\xc4\xaa\xbd\x69\xb8\x13\x51\x47\xf8\x11\xac\x86\x86\xee\x0e\x0d\ +\xae\x40\xc5\x0b\x86\x24\x6c\x0b\x29\xc7\x89\xc1\x69\x0e\x42\xab\ +\x2c\xe1\x89\x10\x14\x0d\x24\x63\xa1\x3d\xc0\x8a\x3b\x80\xe9\xc2\ +\xc6\x15\x56\x24\x3c\xa1\xc6\x7e\xe0\xaa\xe3\xf9\xff\x3f\x20\xeb\ +\x8a\xcf\x90\x4d\x73\x34\x74\x9d\x05\x5b\xbd\x17\x41\x7a\x00\x41\ +\x08\xf8\x33\x92\x32\xc1\x87\x42\x19\x20\x24\x4d\x5a\x50\x26\x94\ +\x11\x20\x2b\x6c\xf2\x3b\x3e\x67\xd5\x16\x78\xfa\x35\x33\x38\xf6\ +\x2a\x8e\x2d\x4f\xa7\xb1\x66\x6f\x12\xd5\x42\x15\xbe\x1f\x10\xeb\ +\xec\xea\x0b\x95\xd5\xf2\x50\xc7\x8e\x63\x43\x75\x80\x36\xa0\x5e\ +\x46\xd9\x13\x90\xea\x59\xf9\x3c\x03\xf4\x24\x91\x4a\x2c\x6c\x82\ +\x03\x2f\xe4\x34\x5e\xf8\x1e\x4c\x81\x67\x4c\x64\x57\xf4\x01\x5d\ +\x7b\x10\xa4\x06\xe2\x4a\x97\x22\x68\x0d\x1f\xc4\x2f\x16\x20\xd9\ +\x5e\x44\x0e\x91\x92\xe8\x61\x45\x8c\x99\x2e\x3a\xbd\x0c\x72\x01\ +\x19\xa1\xcf\x5b\x35\x05\x0e\xee\x28\xe1\xe8\x36\x86\xad\x87\x33\ +\x58\xbf\x3f\x09\xaf\x58\x55\x7b\x84\xea\x88\x08\x1a\x22\x36\x41\ +\x2b\x99\xa0\x0e\x48\x38\x60\x02\x1a\x5c\x73\x48\x60\x4a\x88\x49\ +\x54\x10\x00\x10\x8b\x5d\x06\x05\xaa\x43\x13\x70\x3a\x9a\x74\x95\ +\x67\x99\xe0\x4b\x4b\x8d\xeb\x42\x81\x67\x52\x26\x32\x1d\x04\xde\ +\xb1\x07\x5e\x62\x20\x86\x9d\x22\x68\x55\x6d\x20\x14\x42\x9f\x27\ +\x04\x8c\x0a\xd0\x78\x02\xc8\x9f\x04\x26\x24\xe0\xc6\x97\xba\x71\ +\x54\x50\x60\x2e\x1a\x99\x85\xce\x4a\x0a\x39\xdf\xaa\x75\x04\xe9\ +\xc0\xa6\x2a\x8e\xac\x63\xb8\xe1\x78\x16\xdd\x87\x93\x74\xfe\x80\ +\x0a\x22\x5e\xe8\x08\xa8\xac\x0d\x48\x39\x0a\xbc\x26\xa9\x0c\xa9\ +\x7a\xee\x79\x00\x25\x52\x30\xcf\x00\x3d\x39\x8d\x99\x33\xe7\x90\ +\x58\xd1\x04\x39\x77\x43\x03\xc1\xf0\x1a\x38\xe7\x0a\x3c\xdd\x76\ +\x06\xb2\x8d\xc0\x9d\x0b\xb5\x8a\x07\x71\xd5\x75\x5f\xc6\x86\x1b\ +\x33\x31\x74\xc3\x73\x00\xf7\x01\x3f\x2a\x09\x00\x7d\x53\x29\x01\ +\x6d\x84\x87\x82\xe5\xa3\x51\x18\xe8\x9a\xb6\x91\xf3\x0c\x70\x05\ +\xc1\xe0\x01\xd8\xbf\xb6\x8c\xc3\x5d\x1c\xdb\x4f\xe5\xb0\xf1\x64\ +\x06\x7e\x19\xf0\x24\xf4\x72\x10\x64\x80\x8d\x54\x52\x1b\x80\xb8\ +\xf5\xa1\x3b\x61\x64\x26\x3c\x00\x60\x6c\xc1\xfb\x00\x3d\x39\x81\ +\xe9\x13\xc7\xd0\xfc\xda\xed\xca\xb2\x59\x26\x00\x55\x5f\x2a\xf0\ +\x74\x92\x5c\x5e\xd6\x0b\xd9\xb2\x1b\xae\x15\x55\x5c\xe8\x8a\x4b\ +\x84\x24\x40\xc1\x6b\xf0\x32\x41\x9f\x20\x9d\xaa\x81\x57\x01\x4c\ +\x92\x5c\x52\x1f\xa9\x61\x21\x23\x02\x14\xd2\x01\x1a\x39\x47\xd7\ +\x24\x43\xde\xd5\x9f\x3d\x02\xb1\x11\x5d\x33\x38\xdc\x4e\x46\xf4\ +\xe5\xb0\xb9\xa7\x11\xbe\xb4\xc9\x08\x03\xb6\x41\x45\x89\x0c\x00\ +\xf4\x12\x60\x0a\x7e\xc8\x75\xcf\xee\x2a\x5e\xfc\x0f\xc5\x08\x04\ +\x8b\x19\x30\x8a\xb3\xf7\x7d\x1f\xed\x6f\x7f\x0b\x9c\xf6\xe6\xb9\ +\x26\xf8\x21\x60\x27\x27\xd1\x7c\xdd\x5e\x54\x93\xbd\x98\xae\x96\ +\x51\x75\x43\x9a\xd7\x55\x96\x75\xe0\x5c\x83\x67\x4e\xd7\xc0\x3d\ +\xdd\x80\x2e\x6a\x11\xea\x9a\x14\xb4\x09\xa9\x7a\x23\x80\x71\x43\ +\xa0\x90\x07\xf2\x15\xa0\xb3\x08\xe4\x5c\xc4\x4b\x43\x02\x15\x84\ +\xd8\xb7\x6a\x1c\xcf\xad\xa8\xe0\xc6\x63\xcd\x58\x35\xd9\x04\xce\ +\x39\x12\x8e\xa5\x0c\xe0\x92\x04\x46\x45\x11\xde\x03\xc3\xe7\xbf\ +\xa0\xed\x2e\x2d\x78\x2b\x4c\x73\x82\x31\x36\x05\x6f\xf4\x38\x9e\ +\xfb\xe4\xd7\xb1\xf5\x1b\x9f\x00\xb3\xcc\x7a\x13\xbc\x40\xca\xc0\ +\x18\xc2\xc5\xf1\x43\x70\x8c\x75\xc8\xa7\xb2\x90\xf6\x08\xa6\xc3\ +\x22\x66\xfc\x69\x04\xc2\x8f\x5b\x3d\x43\xe0\xa9\x08\x3c\x88\xfb\ +\xd3\xd7\xef\x4c\x3c\x2c\x1e\x81\x5e\xec\x05\x6d\x42\x72\xb6\x11\ +\x13\x06\x50\x6c\x02\x72\x15\xa0\xab\xc4\xd1\x11\x64\xd0\xe1\xe5\ +\x90\x1c\x91\xe8\x2d\x8d\xe2\x38\x2b\x61\x83\xdd\x06\xcb\x30\x24\ +\xe7\x2c\xba\x12\x28\xf8\x6a\x10\x7a\x0f\x0d\x9c\xfb\xf2\xa1\xc9\ +\xc2\x2f\x01\x5c\x24\xf9\x97\x7a\x33\xe4\x91\x86\x30\xf2\xd3\x9f\ +\xe0\xfc\xbf\xaf\xc7\xca\x0f\xde\x09\x70\xa6\x4d\x88\x37\x34\x3a\ +\x0c\xbd\x00\x2e\x3f\x85\x49\x5f\x22\x65\xb5\xa0\xd1\x5e\x87\xd5\ +\x0d\x5c\xb6\xb5\xf7\x4a\x2f\x39\xc8\x47\x2b\xc0\x68\xb9\x11\xe5\ +\xe8\x83\xcb\xc9\x32\x84\x27\xb0\x60\x30\x2c\x18\x7a\x89\x28\x13\ +\xac\xa4\x85\xb4\x93\x46\x73\xb2\x19\x4d\xc9\x26\x91\x43\xc3\x70\ +\xa5\x38\x53\x1e\xee\xbb\xd0\x74\xfe\xe2\x40\x53\xa6\x12\xef\xf0\ +\xcd\x3c\x03\x87\x2a\x6f\x70\x0e\x93\x71\x44\x31\x63\xb0\xd2\xa7\ +\x9f\x3e\xf4\xf9\x1f\x9f\x3b\xf7\x43\xfd\x06\xb1\x22\x29\x16\x35\ +\x40\x77\x41\x09\x40\x0f\x4e\x7d\xfa\x1e\x54\x47\xa6\xb1\xfe\x23\ +\x7f\x0e\xe6\xd8\x60\x80\x1f\xea\xfb\x5a\x11\xaa\x04\x29\x50\xc6\ +\x19\x94\x13\xdf\xc7\x40\xa2\x97\x25\x7c\x03\xd7\xd9\xd7\x8d\x6c\ +\xcc\x6d\xc4\x6d\xcd\xb7\xa5\xda\xd3\xed\x4e\x73\x43\xb3\x59\x0d\ +\xaa\xcc\x0d\x5c\x94\xbd\x32\x66\xaa\x33\x98\xaa\x4e\xa1\xe4\x96\ +\x30\xe5\x4e\x51\xc5\x2c\x64\x9d\x2c\x92\x56\x12\x29\x3b\x85\x84\ +\x95\x80\x63\x3a\xb0\x0d\x5b\x8a\x40\x84\xe3\xa5\x71\x6f\xa4\x32\ +\x52\xee\x2f\xf5\xbb\x3d\x17\x7a\x1a\xc7\xa6\xc6\x3a\xe0\x23\xde\ +\x0f\xf2\x40\x83\xcd\xd0\x56\x62\x90\xe0\x48\x70\x1b\xb6\x61\x84\ +\x64\x82\x75\xf8\xe2\xe8\x91\x7f\xd8\xbd\xf7\x2b\x07\x86\x47\xf7\ +\x01\x18\x24\xcd\x48\x8a\xcb\xfb\x78\x9c\x31\x8b\x52\x8e\xb4\x16\ +\xad\xaf\x7f\x23\x36\x7d\xee\xc3\xb0\xdb\x9a\x4d\x7f\xc8\x0d\x32\ +\xa5\x04\xb2\xf7\x03\x56\x19\xc8\x1c\x03\xb2\xbd\x34\x0e\x48\xba\ +\xa2\x7e\x9d\xb5\x24\x27\xe1\xa0\x23\xd1\x21\x3a\x8d\x4e\xd1\x68\ +\x37\xca\x8c\x9d\x61\x79\x3b\x2f\x73\x66\x8e\x35\xd8\x0d\x08\xc2\ +\x00\xc5\x4a\x11\x85\x4a\x41\x96\xaa\x25\x4c\xba\x93\x6c\xa8\x32\ +\xc4\x2e\x94\x2f\x18\x85\x72\x21\x3e\x5f\xa0\xd7\x01\xaf\x7b\x0e\ +\x2d\x16\x90\x3c\xa0\x79\xc2\x7a\xf6\x73\xe5\x1b\x8d\xce\xce\x16\ +\xf3\x91\xbe\xfe\xef\x7e\xfb\x59\xf5\x11\x7f\xbf\x5e\x54\xd5\xa8\ +\xb8\x57\xf0\x45\x49\xfd\xce\x90\xf0\x48\xed\x30\xb2\x1b\x71\xfd\ +\xa7\xde\x87\xa6\x5b\x77\x22\x3b\x98\x42\xfb\xdf\xa7\x90\xee\x07\ +\x6c\x05\x1e\x87\xd0\xd9\xaa\xc1\xc3\xaa\xcb\x86\xce\x24\x15\x41\ +\x9d\x7c\x0d\xe8\x2f\x31\xa7\x8d\x50\x21\x6b\x3f\xd3\x7b\xcc\xa3\ +\x78\x02\x9f\x41\x1c\x45\xd2\xb8\x7e\xd3\x13\x48\x8a\x2b\xfe\x8a\ +\x8c\x94\x32\x54\x9b\x22\x50\x45\x58\x2a\xe0\xf8\xdf\xf5\x23\x7f\ +\xd3\x2a\xac\x3f\xde\x8d\x55\x95\x2f\x80\xe9\x17\x13\x90\x58\x1d\ +\x28\x27\x19\x5a\x7c\x4e\xd6\x52\x21\xb5\x84\x9e\x93\x3a\xcf\x9b\ +\xd3\xc7\x5c\x4b\xd4\x81\xd7\x63\x71\x35\x7b\xaa\xee\x55\x85\xaa\ +\xea\xbf\xcd\x97\xa4\xf4\x09\x2a\x64\x84\x47\x79\x0a\xc5\x83\xcf\ +\xa3\x01\x36\x84\xde\xa8\x78\x0d\x5a\x4b\x03\xcf\x85\x5e\xc2\x00\ +\x39\xe7\xb8\x06\x3d\x5f\x4c\xe7\xfa\x02\x08\x25\x5b\x43\x57\x5e\ +\xdc\x2f\x4b\xeb\x6e\xd0\x27\x2e\xe1\x24\x7e\x8d\x7e\x7c\x0d\x33\ +\x18\x9c\x0b\xba\xc4\xf1\xa2\xaa\x19\x37\xcf\xcc\xa5\x4d\x90\x70\ +\x31\x41\xcd\xff\x3c\xee\x8d\x66\xa2\xb8\x6a\x5f\x96\xa6\x73\x73\ +\xfd\x21\x4d\x3b\x69\x0d\xb6\xe0\x76\x6c\xc2\x5b\xd0\x89\x6e\x24\ +\x60\xc3\x9a\xb7\xf6\x6b\x32\x17\xd8\x03\xfc\xd9\x59\x8f\x97\x3e\ +\xf6\x20\x09\x7a\x04\x17\xb0\x1b\xc7\xf1\x18\x5c\x9c\xd0\x97\xb9\ +\x22\xf1\xf8\x57\xcb\x80\x7a\x13\x1c\x6d\x44\x63\xbc\x49\x62\x39\ +\xb6\xe1\x55\x58\x87\x57\x62\x05\x36\xd0\x51\x3b\x1c\x18\x57\x6c\ +\x80\x7f\x89\xb9\x22\x8a\x84\xdc\x87\x21\x1c\xc1\x69\xec\x47\x01\ +\x7d\xfa\xc6\x66\xb4\x76\x7f\xa9\x37\xbc\xab\x66\xc0\x7c\x23\x4c\ +\x6d\x46\x52\xdf\xd1\xe7\x95\x29\x49\xb4\xa0\x9b\xec\xe8\xc4\x1a\ +\xb2\xa2\x03\xcd\x68\x27\x35\x23\x8d\x04\x92\xb0\x55\xaf\x18\xda\ +\x16\x17\x02\x15\xf8\x2f\xa8\x0c\x0f\x93\xf4\xa7\x40\xb8\x13\x18\ +\x24\xbc\x73\x78\x9e\x60\xc7\x30\x00\xa0\xa0\x55\x24\x95\xf5\x4e\ +\xe4\x91\x84\x06\x7f\xe9\x7f\x5f\x40\xaf\xb9\x48\x46\x9d\x21\x36\ +\x29\x51\xbb\xa9\x55\x39\x51\xd7\x0b\x86\x16\xab\xdb\xfa\x82\x5a\ +\x56\x60\x95\x08\x52\xe7\x19\x0d\x4a\xd2\xbd\xb1\x14\xf4\xd5\x37\ +\x60\x69\x43\x16\xd9\xce\x50\xcb\xda\x80\x38\x44\x2d\xab\xb9\x50\ +\x8f\x43\x2d\xb9\x10\xf0\xcb\xc9\x80\xa5\x8d\xb9\xcc\x50\xa0\x2f\ +\x51\x5c\xfb\xd5\x59\xe0\xda\x6f\x8d\x5d\x33\xe0\x9a\x01\xbf\xc3\ +\xf1\xbf\x9d\xd2\xae\xe2\x5a\xef\x69\x4e\x00\x00\x00\x00\x49\x45\ +\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x0d\x06\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\ +\x01\x1e\x75\x38\x35\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x0c\x83\x49\x44\ +\x41\x54\x78\xda\xed\x9b\x5b\x68\x55\xd9\x19\xc7\xd7\x49\x4e\xa2\ +\x26\x26\x1a\xe3\x35\x31\x5e\xc6\x54\xad\x97\x4a\x95\x29\x38\x14\ +\xc4\x22\xb6\xcc\x73\x9f\x2a\xf4\x61\x5e\x7c\x10\xc4\xc2\x0c\x08\ +\x7d\x28\xf8\x54\x4a\x1f\x15\xa4\x4f\xf6\x51\x0a\x52\x90\x4e\x07\ +\x41\x94\xfa\xe0\xfd\xd6\xaa\x03\x5e\xc6\xfb\x35\x51\x63\x2e\x46\ +\xcd\xc5\x7e\xbf\x0d\xbf\x61\xcf\x31\x92\x8c\x1c\x83\xc1\x2c\x58\ +\xec\xbd\xd7\x59\x7b\xad\xef\xfb\x7f\xf7\xb5\x93\xc2\xeb\xd7\xaf\ +\xd3\xc7\xdc\x2a\xa2\x8f\x03\x30\x0e\xc0\x38\x00\xe3\x00\x8c\x03\ +\x30\x0e\xc0\x47\xda\x8a\x1f\x1a\x41\xc7\x8e\x1d\xdb\x53\x5d\x5d\ +\xfd\xb3\x69\xd3\xa6\x7d\xe1\x98\xad\xad\xad\xed\x8f\x95\x95\x95\ +\xf3\x57\xaf\x5e\xfd\x8b\x72\xed\xf7\x41\x24\x42\xdb\xb6\x6d\x5b\ +\x50\x2c\x16\xff\x10\xb7\x9f\xcd\x9e\x3d\xbb\x65\xf2\xe4\xc9\x93\ +\x18\x87\x36\xaf\xb6\x81\x81\x81\xc1\x4b\x97\x2e\xdd\x1a\x1c\x1c\ +\xbc\xd4\xd1\xd1\xf1\xb7\xbd\x7b\xf7\x1e\x1a\xd3\x00\x6c\xd9\xb2\ +\xe5\xb3\xfa\xfa\xfa\xc3\x21\xf5\xaa\x21\x09\x2c\x14\xd2\xdb\xc6\ +\x03\x84\x74\xfd\xfa\xf5\x43\x15\x15\x15\xbf\xd9\xb3\x67\xcf\xab\ +\xb1\x64\x02\x32\xff\xcb\x9a\x9a\x9a\x43\x21\x84\xe2\xcb\x97\x2f\ +\x87\x63\x78\xc8\xb1\x96\x96\x96\xf5\xd7\xae\x5d\xfb\x26\x1e\x7f\ +\x35\x96\x9c\xa0\x0c\xfc\xb3\xbf\xbf\x3f\x13\x42\x00\x91\xaa\xaa\ +\xaa\x52\x98\x02\x3d\xbb\xb7\x3b\x6e\x9f\x38\x71\x62\xc6\x3c\xa0\ +\xd1\x9b\x9a\x9a\xd6\x6f\xd8\xb0\x61\xdd\x98\xd2\x80\xcd\x9b\x37\ +\xff\x39\x98\x69\xec\xeb\xeb\x4b\xcf\x9e\x3d\x4b\x0f\x1e\x3c\x40\ +\xa5\x47\x0a\x5c\x0a\x27\x99\x1a\x1b\x1b\x93\xad\xae\xae\xee\xaf\ +\x71\xf9\x74\xac\x00\x00\xb3\x5f\x04\xf3\x48\x10\xef\x9e\x16\x2d\ +\x5a\x94\xc2\xf9\xa5\xe7\xcf\x9f\x23\x65\xe7\xa4\xce\xce\xce\xd4\ +\xd0\xd0\x90\x31\xfc\xf4\xe9\xd3\x34\x69\xd2\xa4\x74\xfa\xf4\xe9\ +\xf4\xe4\xc9\x93\x44\x0b\xff\x91\x68\x53\xa6\x4c\xf9\xf9\xc6\x8d\ +\x1b\x8b\x07\x0e\x1c\xe8\xff\xe0\x01\xd8\xb4\x69\x53\x75\xb4\xe9\ +\x71\x0b\xc3\x78\xf6\xb4\x6a\xd5\xaa\x34\x61\xc2\x84\x74\xe3\xc6\ +\x8d\x34\x6b\xd6\xac\x74\xea\xd4\xa9\xd4\xda\xda\x9a\xe6\xcf\x9f\ +\x8f\x9d\xc3\x60\xba\x7a\xf5\x6a\x5a\xb8\x70\x61\x3a\x7b\xf6\x6c\ +\xf6\x4e\x77\x77\xb7\xe6\x00\x68\x95\x2f\x5e\xbc\xd8\x14\x4b\xfe\ +\xfd\x83\x88\x02\xdb\xb7\x6f\x6f\x7c\xf4\xe8\xd1\xba\x20\xbc\x3f\ +\x88\x9d\x17\xd2\x5b\x31\x73\xe6\xcc\xdf\xde\xb9\x73\xa7\x2b\x88\ +\x9e\x1c\x63\xd3\x83\xe0\x84\x16\x00\x42\xc4\xf7\x77\xd1\xa2\x4c\ +\x33\x02\xcc\x0c\x84\x5b\xb7\x6e\xed\x0b\x8d\xd9\x4f\x38\x8d\x7e\ +\x34\xd6\xfc\xf7\x89\x13\x27\x1e\xbc\x17\x00\x7e\x1d\x6d\xc5\x8a\ +\x15\x95\xc1\x54\x6d\x30\xd3\x7a\xe6\xcc\x99\xdf\xaf\x59\xb3\xa6\ +\x39\x18\x7d\x10\xd2\x68\xba\x70\xe1\x42\xed\xb2\x65\xcb\xd2\xdd\ +\xbb\x77\xd3\xd4\xa9\x53\x53\x57\x57\x57\x7a\xfc\xf8\x71\x46\x6c\ +\x84\xad\xc4\xbe\xd8\x3e\x12\x0c\xa0\x90\xa8\x9e\x7e\xc4\x0d\x4d\ +\x61\x1d\x1c\x28\x66\xc3\xfd\xe5\xcb\x97\xf1\x07\x98\x13\xfb\xbc\ +\x0e\xad\xba\x1c\x4e\xf4\x1f\x3d\x3d\x3d\xff\xda\xbf\x7f\xff\x89\ +\x98\x33\x38\x62\x00\x76\xec\xd8\xb1\xf4\xe6\xcd\x9b\x5f\xc5\x6d\ +\xcb\xe2\xc5\x8b\x6f\xd6\xd6\xd6\xd6\x04\xa1\x8b\x7a\x7b\x7b\x5b\ +\xcf\x9f\x3f\xdf\xc8\x26\xa8\x24\x92\x84\x51\x18\xc0\x63\xf3\x8c\ +\x6d\xbf\x7a\xf5\xca\xae\x27\x77\x69\xa4\xce\x38\x44\xd2\x99\xcf\ +\x18\x4c\x0c\x1b\x0e\x01\x2d\x68\x51\x0b\x78\x3f\x63\xd8\xe7\x90\ +\x7a\x8a\xe8\x82\xf9\x00\x3e\x7e\x22\xdb\x3b\xe8\xee\x6c\x6f\x6f\ +\xff\x26\xf6\xfd\x32\xe6\xdc\x1e\x12\x80\xdd\xbb\x77\xa3\x8b\xbf\ +\x7b\xf8\xf0\xe1\x5f\x8e\x1f\x3f\x3e\x3b\xd4\x88\x97\x0d\x37\x10\ +\x08\xe1\x79\x06\x91\x1e\x1b\xdb\xdf\x78\x46\x42\x74\x1b\x6b\xe0\ +\xd0\x64\x9e\x3d\x60\x8c\x7b\xae\xf9\x6e\xf3\x3d\xaf\xac\xeb\x95\ +\x0e\x00\x79\xe7\x19\x1a\x09\x08\x00\xc5\xfa\x38\x4f\xfc\x48\xe6\ +\x67\x42\x1b\xae\x1f\x3d\x7a\xf4\x93\x37\x00\xd8\xb5\x6b\x57\x4d\ +\xd8\xd0\xd7\xa1\xaa\xeb\x62\x92\x4c\xb2\x10\x1d\xc6\xd8\x14\xbb\ +\x85\x38\x09\x18\x16\x00\x36\x86\x39\x1b\xce\x0b\x2d\x81\x30\xc6\ +\xed\x23\x01\x80\x2e\x93\x79\x10\x58\xcb\x88\xe0\xef\x87\x0f\x1f\ +\x66\x1f\x98\x56\x08\xdc\xd3\xfb\xc3\x24\xeb\x6f\xdf\xbe\xdd\x5b\ +\xf4\x85\x9d\x3b\x77\xb6\x44\x38\xfa\x36\x54\xb9\x96\xd0\x93\x27\ +\x02\x64\x91\x18\xe3\x61\xf3\x69\xee\xdc\xb9\x29\x5e\x06\x08\x36\ +\x96\x30\x89\xcb\xe6\x00\x60\xe4\xea\x3f\x20\xd6\xe6\xfa\x00\x25\ +\x08\x6a\x80\xfb\x39\xce\x9a\x39\x40\x87\xd4\x00\x3b\xcc\xf1\x1e\ +\xfe\x06\x8d\x20\x7a\x60\x56\x08\x12\x20\x42\xab\x11\x24\xeb\x17\ +\xc3\x17\xfd\x09\x5f\x9d\x01\xb0\x6f\xdf\xbe\xc6\x90\xca\xb5\x28\ +\x32\xaa\x64\x3a\xcf\x3c\x49\xca\xca\x95\x2b\x13\xed\xc8\x91\x23\ +\x20\x9d\x81\x10\x7e\x00\xe9\xe6\x01\xc8\x88\x8e\x82\x86\x8d\x01\ +\x8d\x35\xb2\x4d\x6d\x6a\x14\x8d\xb9\x30\xc7\x1e\xd3\xa7\x4f\xc7\ +\x79\xf1\x9b\x1a\x02\xe1\x43\x81\x24\x20\xa5\x20\xc8\x38\xe0\x2b\ +\x79\xd6\xc0\x0c\xe8\xd6\x0f\xfc\x86\xe3\xfd\x2a\x9e\xf7\x64\x00\ +\xdc\xbb\x77\xef\x3f\x11\x77\xab\x54\x53\x99\xd7\xfe\xc9\xb8\x02\ +\x31\x9c\x48\x46\xa4\xf3\x24\x16\xfb\x82\x10\xcd\x23\x22\x00\x8c\ +\xf2\x2c\x00\xae\x9b\xad\x41\x13\x00\x12\x20\xd6\x46\xa3\xc8\x01\ +\xf2\x4e\x50\xa6\x35\x3d\x9b\x29\x71\xe9\x6f\xac\x8d\x83\xc4\xe1\ +\x42\x07\xeb\xd2\xb6\x6e\xdd\x9a\xdd\x9f\x3b\x77\x0e\x67\x4d\xa4\ +\x40\x0b\x2b\x02\x88\x4f\x8b\x21\xfd\xda\x50\x8d\x9f\xe6\xbd\xac\ +\xc4\xa9\x8a\x84\x29\x50\x43\xa2\x80\x81\x84\x4f\x9e\x3c\xc9\x34\ +\xc6\xd9\x54\x00\x40\x18\x86\x95\x8e\x25\xec\x0f\x34\x80\x36\x6f\ +\xde\x3c\x9c\x2a\x5a\x04\x31\xec\x07\xb8\x86\x34\x9e\x5d\x03\x1a\ +\x74\xb6\xec\x87\x76\x71\xcd\xfb\x09\xe6\xb0\xaf\xeb\x93\x1f\x08\ +\x36\x91\x20\xfb\x7d\xce\x9c\x39\x19\x38\x57\xae\x5c\x31\x5a\x4d\ +\x2b\xc6\x4b\xad\x11\x8f\x0b\xbc\xa8\x63\x73\x41\x91\x9e\x31\x63\ +\x46\xb6\xb0\xa9\xea\xc1\x83\x07\x9d\x87\x8a\xb1\xd1\x1b\x6a\xc9\ +\x06\xda\xbf\x44\x0a\xc4\xf2\xe5\xcb\x49\x65\x31\x27\x18\x05\x54\ +\xcc\x0a\xa2\x19\xd7\x9e\x95\x24\xb4\x20\x41\x34\x0d\x3a\x98\x03\ +\xb3\xa8\x3c\x57\x23\x13\x82\x50\x20\x8c\xab\x45\xf8\x37\xae\xbc\ +\x57\xea\x5c\x0b\xc5\xd8\xa0\x10\x8d\x7c\x9b\x8d\xf3\x5e\x7f\x48\ +\xc6\x68\x10\xc6\x6f\x3c\x03\x00\x0b\x43\x30\x44\xd2\x35\x0d\x43\ +\x9f\xef\x31\x8e\x2f\x21\xa5\x25\x09\x82\x69\xf6\x05\x60\xd6\x40\ +\xc3\xb8\xc2\xb4\x0e\xcf\x7d\xd5\x4a\xf6\x31\x17\xc0\xff\xb0\x26\ +\x6b\x01\x12\x7b\xd2\xa0\x01\x3e\xbc\xd7\x17\xd9\xf3\x0d\x0d\xe0\ +\x65\x88\xd0\x86\xe9\x82\x90\x0f\x7f\x02\x61\x1e\xfe\x86\x5d\x6a\ +\x7f\x02\xa0\x59\xd8\xc8\xed\x2f\x5e\xbc\x08\x68\x48\x1d\x89\x03\ +\x00\x3e\x08\x69\xb2\x2f\x84\xeb\x00\xe9\x32\x8b\xf4\x55\x5b\xe6\ +\x40\x07\x6b\xe0\xf0\x58\x83\x88\xc3\x3c\x0b\x26\x53\xeb\x61\x53\ +\xec\xa2\x2a\xf4\xae\x4d\x2f\x9d\x6b\x10\x85\xa4\x4a\xd3\x56\x9c\ +\x1c\x0c\x10\x26\x91\x0c\x73\xd0\x06\x00\x83\x01\x1c\x14\x6b\xe1\ +\xb1\xd1\x1e\xf3\x07\x01\x61\x5d\x68\x45\x73\xb8\x47\x0b\x99\x03\ +\xe3\x80\x00\xf3\xbc\x8b\x43\x25\x04\x1a\xc5\xb8\xda\x87\x01\xa0\ +\x4c\x0d\xc2\x60\xc0\x06\x51\x48\x18\x55\x85\x50\x7d\x47\x14\x46\ +\x5c\x61\x1c\x8d\xc1\x31\xf2\x1e\x0c\xb3\x06\x0c\x41\x1b\x0c\xd2\ +\x01\x4d\xed\x83\x31\xd6\xa5\x94\xc6\x79\x5a\x1a\xb3\x47\x36\x7e\ +\xff\xfe\x7d\x9c\xec\xb0\xf5\x05\x3e\x20\x95\xbb\x69\x32\x46\x15\ +\x98\x8a\x63\x2b\x33\x31\x4d\x0b\x46\xa8\xe0\x32\x82\x97\x2c\x59\ +\x42\xb1\xc4\x19\x5f\x69\x46\x88\xb4\x61\x1e\xa6\x59\x03\x86\x01\ +\x8e\xe8\x01\xd3\x5c\x71\xd0\xac\xc9\x95\x75\x19\xc3\x54\x4c\xb3\ +\x05\xe2\xfd\x6b\x80\x9b\xda\xb0\x47\xc2\x28\x04\x40\xac\x21\x92\ +\x2b\xb6\x8f\x39\x00\x00\xe6\x01\xe1\xe6\x0d\xe6\x21\x26\x2f\xfa\ +\x03\x7d\x92\x76\x0e\x38\x80\x82\xc6\xa8\x25\x8c\x13\xfa\x58\x1f\ +\xad\x1a\xd6\x07\x94\xb3\x11\x26\x21\x02\x50\xb5\x41\xd4\xbf\x94\ +\x79\x54\x17\x82\x91\x26\x7e\x40\x4d\xe4\x1d\x23\x8a\x79\x88\xe9\ +\x30\x73\x60\xd4\xb9\xcc\x43\x5b\xe4\x81\x39\x00\x05\x20\x79\xc7\ +\x6d\x1b\x15\x0d\x30\x03\x63\x63\x25\x44\x83\x59\x01\x80\x09\xa4\ +\x4d\xb9\x8a\xad\x32\x66\x4a\x8c\x64\x35\x15\xcf\x0e\x64\xce\x08\ +\x01\xc8\x98\x0b\x8e\xd5\x04\x88\xf7\xd4\x06\x43\x26\x9a\x85\x1f\ +\x61\x9d\xd1\xd2\x00\xe3\x36\x1d\x86\x70\x4a\x84\xaf\x7c\xa6\x08\ +\xf1\x84\x5d\x3d\x39\x0c\xe8\xd4\xb0\x61\xa3\x00\xa0\x31\x6e\x78\ +\x86\x79\xde\xb1\xe0\xa1\x13\x05\x04\x3e\x9f\x00\xc1\xb4\x7b\x51\ +\x67\x70\xff\x56\x27\x58\x56\x0d\x90\x51\x9a\xea\x8e\x9a\xe7\x55\ +\xd2\x3a\x9d\x28\xc0\xb8\x67\x06\x8c\x31\x17\xa6\xb8\x1a\xfb\xcd\ +\xf4\x90\x3c\xcf\xfa\x05\x8b\x1f\x9a\xd9\xa2\x69\x35\x60\xd0\x0c\ +\x9b\x68\x1c\xfb\x8e\xaa\x06\x68\xab\x4a\xd1\x31\x98\x70\x1e\xfb\ +\x43\x38\x04\xeb\xe1\x71\x60\xf3\x66\x2c\x49\x4d\xd3\x3e\x49\x03\ +\x13\x42\xdd\xbb\x6f\xa3\x29\x30\x6c\x8d\x60\xde\x6f\xea\xab\x84\ +\x87\xca\x1e\xc9\x31\x00\xd5\x7c\xe2\xfd\xfa\x80\x3c\x21\x82\x9b\ +\xaf\xda\x54\x55\x88\xb7\xb4\x05\x00\x41\x50\x0b\xe6\xcf\x5c\x9a\ +\xfa\x6b\x1f\xa7\xe6\xa6\x96\x54\xdd\x96\x85\x4c\xed\x1d\x46\x74\ +\xb6\xac\xc7\x3b\xae\x6f\x04\x92\x27\xfd\x0a\xa6\x88\x29\x00\x40\ +\x59\x35\x60\xd8\x23\x2b\x01\xb0\xa9\x01\xee\x2b\xd1\x8c\xe5\x35\ +\xa1\x50\xf7\x32\x2d\x58\xb4\x34\x15\xeb\xfa\x52\xb1\xba\x39\x75\ +\x90\x2a\xc7\x3b\x66\x99\x9e\x31\xa2\x19\xac\xaf\x29\x5b\xd0\xe5\ +\xa3\x10\xe1\xd0\xcc\xb3\xb4\x55\x94\xd3\x07\xc8\xa8\x04\x20\x95\ +\x52\x60\xf2\x67\x0e\xf9\x7b\x9f\x3d\x23\x7c\xde\xdf\x1e\xcc\x3e\ +\x4a\xb5\x55\xf5\xa9\x3e\xca\xd8\x89\x75\x93\x53\xfd\xec\xc8\x19\ +\x1a\xa6\x38\xcf\xf7\x5c\xc3\xee\xfe\x76\x35\x0d\xb0\xde\x04\xa0\ +\xdc\x3e\x20\x4f\x40\xbe\xa2\xf3\xde\x4c\xd0\xef\x7f\x30\xeb\x5c\ +\xfb\xf7\x31\xbf\xa7\x37\x75\x84\xea\x77\xb5\xb7\xa5\xee\xb6\xf6\ +\xd4\x1b\x6a\x3c\x21\xbe\x9c\x0f\xe6\x34\x8c\xf5\x2c\x99\x05\x54\ +\xe9\x6b\x86\x66\x93\xac\x5b\xda\x8a\x12\x53\x6e\x00\x8c\xdd\x3a\ +\x2d\x9a\xa1\xd1\x33\x02\x55\x9f\x79\x3a\x35\xed\x1b\x6f\x5e\xc5\ +\x07\x8f\xfa\xba\xd4\xf7\xbc\x27\x3d\x8d\x32\xb9\xb3\xa7\x3b\xf5\ +\x15\x99\xfb\x7d\xc5\x0a\x00\xbc\x83\xa7\x57\xd2\xa5\x25\x38\x7b\ +\x50\x83\x70\x1d\x1d\x00\x24\x40\x00\x2c\xb9\x75\x4a\x82\xc2\xbd\ +\x85\x92\xcc\x6b\xe3\xcc\xc9\xca\xe3\xca\x42\x7a\x45\x32\x55\x5d\ +\x91\xba\xba\x3b\x23\xb7\x4e\xa9\xab\xb3\xcb\x13\x6b\x22\x06\x60\ +\x19\xf7\x65\xdc\xc6\x98\xc5\xd2\x90\xad\xa8\x57\x2e\x57\xf3\x24\ +\x57\x42\xcc\xe3\x21\x42\x7f\x03\xb1\x66\x7e\x48\x0e\xdb\xa4\x9b\ +\xfe\xe6\x6d\x96\x10\x56\x37\xb3\x21\x4d\xa8\x9c\x98\xba\x7a\xbb\ +\xd2\xa3\x2b\x0f\x01\x0c\x2d\x61\x4d\xee\xcd\x1a\x3d\x87\x54\xab\ +\xbc\x1f\xdd\x54\x18\x06\xf2\x84\xc0\x84\xa0\xd0\x4c\x7a\x90\x9a\ +\x80\x51\x10\x91\x12\x23\xfd\x7c\xf1\x83\x60\x3c\x95\xce\x67\x82\ +\xda\x33\x8c\x73\x82\xb4\x60\xc1\x02\xcf\x27\x05\xd8\xc4\x89\x44\ +\x69\x74\x8b\x21\x9d\x9a\xcd\xb3\x3a\x80\x80\x60\x6d\x14\xd5\x67\ +\x0c\x66\x01\x8a\xda\x3d\x3e\x5b\x65\xc0\x18\xeb\xad\x05\xb4\x65\ +\x41\xf0\x9c\x32\x3e\xdb\x71\x40\x2b\xd0\xcc\xc9\x3b\x42\xb5\x84\ +\x3d\x47\x4f\x03\x4c\x47\x05\x82\x67\x08\xf1\x68\x8b\x31\x99\xf6\ +\xd0\xd3\x12\x1a\x10\x50\x79\x6b\x04\xab\x41\xdf\xf1\xec\x12\x9a\ +\xa9\x20\x39\x12\xf3\x5c\xd0\x33\x4a\x80\xf5\xd3\x1d\xe6\x05\xf3\ +\xa3\x75\x20\x62\xfd\xaf\xf3\xd3\x0c\x60\xca\x6a\x4d\x02\x21\x1a\ +\x40\xf2\x1f\x47\x19\x83\x21\x8b\x17\xa4\xed\x3c\xc3\x27\x5f\x77\ +\x00\x94\x4a\x12\x06\xd9\x03\xe6\x35\x09\xfd\x0f\x42\xe0\x58\x8c\ +\xdf\x46\xd7\x07\x58\xcf\xeb\x84\x54\x77\x2b\x40\x98\x32\x13\xb4\ +\x74\x36\x1c\xf2\x9b\x45\x8b\x15\x9d\x1f\x52\x61\x44\x8f\x1e\x5f\ +\xaa\xd1\x0e\x4f\x95\x00\x8f\xf7\x33\xa0\x3c\x29\x6a\x6e\x6e\x36\ +\xed\x1d\x55\x1f\x20\xc3\x1e\x45\xeb\x18\x01\x85\x7c\xdc\x83\x4e\ +\xf3\x7a\x01\x31\xf4\xe1\x20\x61\x54\xd3\x00\x00\xde\xa1\xf6\x67\ +\x1d\xd7\xd4\x21\x5a\x4c\xb1\x27\x63\x74\xd6\xc0\xf9\x01\xfa\x88\ +\x00\xe0\x0b\x71\xb9\x01\xc0\xa1\x69\xbf\x66\x6c\x48\x0b\xf5\xd5\ +\x57\xc0\xb8\xde\xde\x52\xd7\x44\x4a\xa6\x4a\x73\x0b\x55\xde\x22\ +\x27\x9f\x0c\x79\x62\x84\xf4\x31\xbb\x11\x29\x6c\x31\x50\xae\x61\ +\xd1\x72\x54\x7f\x36\x88\xb3\x04\x2e\x05\x06\x10\x20\x54\xe7\x05\ +\x13\xac\x81\xdd\x23\x71\xa5\x6a\x6d\x60\x46\x49\xb7\xb6\x27\xf9\ +\xf1\x54\x29\xff\x75\x8a\x77\xf9\xd6\xc0\xbc\xb5\x6b\xd7\x72\xec\ +\xa6\x06\xe9\x24\xf9\x2e\x21\xdd\x00\xde\x87\x06\x34\xf0\xf0\x0e\ +\xcd\x8c\xee\x6d\x5a\x80\x2d\x2a\x39\xbb\xc7\xde\x10\xe7\x87\x0d\ +\x08\xf1\x4b\x8e\xa7\xba\x1e\x8c\x70\xc6\x0f\x53\x00\xc5\xf1\x39\ +\x6b\xc8\x98\xef\x20\x6d\x00\x63\x3d\x2b\x4e\x2a\x40\xd6\xf6\x3d\ +\x40\xf5\xbc\x01\xba\xa0\x01\x20\x6f\x15\xf9\xdb\x5b\xff\x14\xed\ +\xc7\xb6\x7c\xf5\xa5\xbd\xea\xfd\xd9\xc0\xdf\x4a\x9b\x4e\x12\x8f\ +\x0e\x51\x48\x15\xa2\xf3\x69\x33\x34\xd1\x79\x9f\x64\xc7\x46\xe6\ +\x67\x68\x33\x29\xe2\x7d\x4b\x5d\x01\xf8\xee\xbb\xef\x86\x22\x59\ +\x00\xd1\xd0\xb3\x11\x49\xfe\x5b\x8c\x81\x9b\x64\x5a\x6c\xca\x22\ +\xf9\xd8\x9b\xaf\xeb\xed\x2c\x6e\x4d\x0f\x61\x7e\xa8\x90\x28\x8f\ +\xb8\xec\x6e\xea\xb5\xa4\x79\x86\xef\x91\xd8\x70\x69\xb9\x66\x82\ +\xcf\xf0\x0b\xb6\xe7\x83\x23\x31\x57\xfd\xc7\x85\xf8\xfb\x86\x2f\ +\x63\xa8\xad\x18\x52\xea\x08\x6f\x79\x28\x08\x5f\xef\x5f\x58\x04\ +\x83\x32\xe2\x55\xe2\x65\x12\x2f\x3f\x10\x44\x7c\x1b\x8f\xcf\xf2\ +\x69\xae\xcd\xf8\x3e\x82\x26\x38\x95\x01\xe8\xd4\x58\x63\x7a\xd0\ +\x50\x13\x9d\xbf\x57\x80\x3e\xf6\x1b\x88\xf1\xbe\xb8\xbc\x88\xa9\ +\x8f\xc3\x41\x3e\x09\xa0\x7e\x6c\x02\x83\xd0\x3a\xc2\x9c\x2e\x45\ +\x38\xfe\x3a\xd6\xbb\xc0\x29\x7e\x21\xfe\xf6\x7e\x52\x2c\xbc\x3a\ +\x54\xf6\xf3\x40\x77\x59\xfc\xf0\x13\xfe\xcc\x8d\xf9\x79\xc9\x4b\ +\x67\x34\xa0\xbe\x1d\xb6\x74\x24\x88\xf8\x5f\xbc\xdb\x99\xde\x4f\ +\x73\xc3\x42\xb4\xd7\x65\xc8\x4f\x90\x0e\xb4\x12\x1b\xef\x45\x7f\ +\x12\x7f\x71\xfa\x3a\x0b\x81\xf1\xf7\x7d\xd3\x02\xed\x96\x60\x66\ +\x6e\x3c\x83\x7e\x7d\x00\x41\xfd\xca\xef\x48\xb2\x10\x9d\x7b\xfa\ +\x60\xdc\xb3\x50\x7b\xcc\xb9\x16\xd7\xa7\x69\x6c\x34\x40\xec\x23\ +\x68\x04\xe3\x7d\x0e\x9a\x03\x00\x42\x15\x99\x6c\xf4\x9a\xe8\x18\ +\xa2\xfa\xeb\xb5\x40\x67\x21\x54\x07\x7f\x44\x07\xc5\x34\x86\xdb\ +\xf8\xbf\xce\xa6\x34\xfe\x5f\x63\xe3\x00\x8c\x03\xf0\x11\xb7\xff\ +\x03\x7f\x19\x0a\xe4\xd7\x62\x63\xda\x00\x00\x00\x00\x49\x45\x4e\ +\x44\xae\x42\x60\x82\ +\x00\x00\x15\x14\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x04\x73\x42\x49\x54\x08\x08\x08\x08\x7c\x08\x64\x88\ +\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\ +\x01\x1e\x75\x38\x35\x00\x00\x00\x19\x74\x45\x58\x74\x53\x6f\x66\ +\x74\x77\x61\x72\x65\x00\x77\x77\x77\x2e\x69\x6e\x6b\x73\x63\x61\ +\x70\x65\x2e\x6f\x72\x67\x9b\xee\x3c\x1a\x00\x00\x14\x91\x49\x44\ +\x41\x54\x78\xda\xe5\x5b\x79\x8c\x64\xc5\x7d\xfe\xbd\xa3\x8f\xe9\ +\xee\x39\x76\xa6\x97\xdd\xb9\x96\x3d\x66\x61\xef\x05\x61\x6c\xae\ +\xa0\x38\xb6\x20\x4e\x2c\x22\x27\x32\x09\x92\x0f\x14\x20\xc6\x81\ +\x18\x84\x92\x08\x59\x8a\x30\x7f\x18\x04\x09\xe0\xf8\x08\x47\x24\ +\xa2\x24\x76\x14\x9b\x80\xf3\x4f\x0e\x27\x86\x80\xc3\x61\x60\x31\ +\xe6\xb0\x21\xbb\xec\xb2\xf7\xce\xf4\x4c\xcf\xf4\xdd\xfd\xae\xaa\ +\x7c\xbf\x7a\x5d\xf3\xfa\x98\x49\xef\xb4\x90\x65\x29\x65\x7d\x54\ +\xbd\x7a\x47\xd7\xf7\xbb\xab\x66\x6d\x48\x29\xe9\xff\x73\xb3\xe9\ +\x97\xb8\xbd\x74\xed\xb5\x03\x9e\xeb\x66\x09\xf0\x84\x18\x23\xe9\ +\x67\xa5\x2f\xb3\x42\x88\xac\x14\x18\x63\x4e\x04\x22\x2d\xfd\xe0\ +\xdf\x7f\xf3\x95\x57\xfe\x8a\xfa\x68\xbf\x30\x0b\x78\xef\x4b\x5f\ +\x4a\x54\x3d\x2f\xeb\x48\x37\x6b\xf8\x41\x96\x04\x88\x04\x04\x02\ +\x41\x56\x92\xc8\x52\x20\x43\x52\x52\x8c\xc9\x40\xe0\x9e\x60\x82\ +\x29\x89\x87\x70\x4d\x18\x87\x08\x02\x12\xd1\xb8\xd9\x8b\xc6\x46\ +\x21\x86\x2e\x3a\x70\xc0\xfb\x85\x58\xc0\xcf\xef\xbe\x3b\x6e\xd5\ +\x6a\x59\xd7\xf3\xc6\x4c\xc3\xc8\x0a\x62\x12\x06\x2f\x18\x3d\x8d\ +\x19\x22\xc8\x0a\x49\x59\x92\x4c\x42\x86\x7d\x20\xd3\x20\x47\x06\ +\x6e\xa0\x03\xd0\xf3\x80\x00\x26\x21\x19\x12\x64\x00\xdc\x23\xd9\ +\x84\x7a\xae\x1d\xb4\x0c\xd2\x73\xc9\x63\x52\xee\xbc\x88\xe8\xcd\ +\x0f\x44\x00\xef\xdc\x79\xe7\xed\xe5\xb8\xbd\x29\x79\xe2\xe4\x88\ +\xb1\x6e\x24\x26\x0d\xca\x1a\x64\x8c\x11\x48\x12\x49\x80\x06\x7d\ +\xe2\x26\xa1\x38\xee\x42\x32\x7a\x61\x22\xec\x43\xed\xf0\x98\xfb\ +\xe6\x75\x04\xb9\x32\xa4\x86\x88\xde\xd7\x08\xaf\x43\x88\xf6\xdf\ +\x34\xa4\x7f\x01\x7d\x10\x02\x78\xec\xc2\x0b\xbf\x72\xc5\x95\x97\ +\xdf\xe5\x98\x43\x94\x1a\x18\xa0\x40\x88\x90\xaa\xc1\xff\x55\xff\ +\xa1\x50\xf4\x7a\x28\xc3\x61\xa4\x9d\x88\x74\x34\x56\xef\x5a\xa9\ +\x34\x05\x8d\x3a\x5c\x99\xcd\xda\x65\x33\x50\x30\x63\x36\xe6\x1b\ +\xe1\xb5\xd0\xc4\xf1\x46\x32\x41\xa4\x85\x55\xa9\xb4\x0b\xa3\xc3\ +\x2a\x84\x30\x2e\x30\x0c\xe3\xef\x25\x5a\x5f\x02\x30\xd0\xee\x98\ +\x9e\x4e\xce\x0c\x0f\xdf\x5e\x2f\x95\xa9\x54\x2c\x53\x76\x7c\x9c\ +\xfc\x72\x89\xc8\x34\x69\xb5\x66\x26\x12\x24\xea\xf5\x48\x10\xe1\ +\xe2\x99\x8c\xd6\x54\x48\xcc\x60\x01\x0c\xa0\xc7\x3b\x98\x0b\x6a\ +\xfc\xb2\xa5\xe6\xfc\x5a\x83\xac\xc1\x21\xf4\x35\xb2\x86\x06\xc9\ +\xcd\xcd\x13\xa5\x53\xca\xf7\x85\x03\xc1\x60\x5e\x13\xee\xd6\xbe\ +\xb6\x00\xb1\xbf\xa9\xa1\xb5\x0b\x80\xc9\xf3\x72\x3c\xa2\x6d\x41\ +\x10\x0c\xd7\xf0\x83\x85\xa5\x22\xc5\x76\xee\xa4\x5a\x6e\x8e\xcc\ +\x64\x52\x4b\x49\x6b\x5d\x75\xf1\x6c\x96\xbc\x42\x81\x12\x1b\x36\ +\x52\x50\xad\x84\x6b\xf1\x3d\x32\x62\x31\xe2\x4f\x06\x9e\x47\xd6\ +\x40\x4a\x09\xa8\x31\x3f\xaf\x34\xeb\xd7\x41\x36\x99\xc4\x3b\x1b\ +\xc8\xc9\xe5\x48\xb2\x65\xc0\xd2\xbc\x7a\x95\xc8\x32\xc9\xaf\xd6\ +\xc8\x84\x50\x02\xd7\xa3\x00\xe4\xf9\x5d\xe9\xba\x91\xf6\x05\xf7\ +\x1d\xae\x80\x1e\x2a\xda\xcb\x2b\xec\xd7\x05\x0c\x20\x31\x57\xaf\ +\xaf\x9f\x49\xa5\xa8\x86\x1f\x75\xaa\x55\xb2\x86\x47\x28\x60\xe9\ +\xc7\xe2\x78\xa2\xfd\xeb\x12\x30\x2c\x1b\x8b\x74\x48\xb8\x0e\x34\ +\x08\xcd\x2d\x2c\x28\x72\x36\xb4\xe9\x2c\x2e\xc2\xb4\xe3\xea\x9e\ +\xa4\xd0\xff\xb5\x00\xdd\xa5\x25\x08\x6e\x89\x04\x5c\x21\x58\x2a\ +\x34\x4d\xbe\x33\x3e\x04\xaa\x27\xdb\xc2\x37\xbc\xe8\x9e\xd4\x71\ +\xa5\x45\x18\x00\xfe\xb3\xfe\x9b\xdb\xb7\x8f\x43\xf0\xa7\xd6\xe2\ +\x06\x76\x53\xfb\x16\x90\x2e\x04\xc1\x04\x07\xb0\x06\xfc\x31\x33\ +\x98\x21\x7b\xdd\x08\x49\x98\xa7\x1c\x0c\x34\xe9\xb6\xe6\x2c\xcc\ +\x2b\xc2\x0d\x68\xd2\x4a\x24\x95\x86\xdc\x52\x99\x4d\x5b\x49\xab\ +\x7e\xfa\x54\x4b\x1c\x90\x54\x3b\x71\x42\xbb\x84\x26\xda\x41\x5e\ +\x32\xda\xef\x35\x7c\xfd\x8d\x2e\x17\x00\xda\x2c\x63\x90\x88\x03\ +\xe1\xa9\x7e\x2c\xc0\x04\x52\xae\x54\x45\x06\x39\x8e\x4b\xe7\x6c\ +\x9f\x21\xd7\x07\x71\x19\xe6\xdb\x95\x4c\xc0\x87\x95\xe8\x00\x28\ +\x3c\x8f\x47\xa1\x99\x57\xca\xad\x01\x31\x22\x2d\x23\x82\x3a\x4b\ +\x44\x02\x88\xae\x89\xc1\xf9\xde\xf7\x29\xf0\xb9\xf7\xd4\xd8\xc7\ +\x98\x94\xba\x2c\x32\x01\xb8\x5a\x28\x6c\xdc\x93\x58\x0b\xc8\xec\ +\xc3\xdd\x7f\xe9\x57\x00\x31\x43\xca\x14\x2f\xd2\x81\xcf\x4d\xcf\ +\x6c\xa3\xea\x7c\x8e\xcc\x78\x3c\x5c\x54\x77\xd3\xe4\xa3\x6c\xa0\ +\x53\x22\xe9\x34\x18\x09\x81\x05\x20\x02\xc1\x71\x21\x04\x2f\x1a\ +\x40\xaf\x82\xac\x61\x59\x80\x0d\x60\x8c\xdf\x34\x6c\x9b\x6c\xcc\ +\xc7\x00\xa4\x60\xf0\xe4\x9e\xf8\x79\x95\x31\x82\x3a\xe0\x38\xe1\ +\x98\xdd\x8c\xb3\x89\x94\xfb\x74\x20\xec\x27\x0d\x9a\xf0\xd1\x18\ +\x2f\xd6\xf3\x7c\x15\x7c\x2a\xe5\x1a\x0d\x20\x1a\x3b\xda\x02\xba\ +\x9a\x04\x09\x90\x0a\x3c\x28\xc1\x67\x2b\x08\xb5\x16\x04\x4c\x46\ +\x91\xb0\x00\xee\xc9\x8e\x21\x63\x58\xb8\xb6\xe0\xd6\x36\x00\xc2\ +\x26\x60\x19\xca\xc7\x03\xfc\x9e\xd0\x84\x18\xd0\xa8\xaf\x2d\xa4\ +\x37\x94\x0b\x58\x3a\x10\xf6\x15\x04\x81\x79\xdf\x2f\xa2\x57\x64\ +\x3c\x04\xb1\x52\xb5\x4e\x83\x08\x84\x8d\xc5\x3c\xd5\x0a\x45\x12\ +\x2c\xa5\x78\x8c\x4d\x4f\x59\x86\x65\xa1\xcf\xc4\xc8\x42\xb0\x8b\ +\xc7\x98\x5c\x1c\x81\x2f\xd4\xa2\x6c\x92\x11\x8a\x90\x43\x3e\x7a\ +\x59\x87\x90\x9a\xe6\xee\xb7\xb9\x40\x38\xa6\x68\xdc\x01\xd9\x1b\ +\x52\x32\x89\xed\x9f\xdb\xb0\x21\x89\xb0\x56\x93\x68\x6b\x2e\x84\ +\xde\xaf\xd7\x17\xf1\x96\xd2\x60\xad\x5c\xa6\x42\x2e\x4f\xe7\x5e\ +\x3c\x4d\xf2\xd4\x29\x1a\xdb\xb5\x8b\xcd\x34\x24\xa5\xc9\xb9\x0e\ +\x08\x42\x73\x24\x55\x40\xf6\xa8\xc5\x0d\x80\xee\x9e\xc9\x74\x8e\ +\x55\xdf\x4d\x3e\x22\x06\x88\xff\x1b\x62\x19\xb1\xcb\xe2\xf1\xdd\ +\x7f\x47\xf4\x6a\x3f\x2e\x20\xab\x41\xe0\xba\x42\xa0\x0b\xd2\xb5\ +\x5a\x9d\x4a\x88\xee\xf6\xc8\x88\xd2\x62\xf5\xd8\x51\x8a\x9a\xe2\ +\xd4\x51\x15\x46\xe4\x69\x45\x41\x88\x96\xba\xbe\x83\xb0\x5c\x51\ +\x00\x6d\xe4\x68\x19\xb2\x1b\x32\x42\xd2\x90\xfb\xa9\x0f\x01\x48\ +\x40\x00\x7e\x2d\x08\x0a\x83\x42\xa4\x51\x0b\xf0\x02\xb8\x16\x50\ +\x5a\x36\x06\x92\xd4\x91\x06\xda\x3b\x29\xb5\x30\x34\xe9\xae\x80\ +\xa8\x02\x2c\x4a\xda\x0a\xfc\x7b\xdd\xd8\xd8\xea\xfb\x85\x8e\x31\ +\x45\xa6\xde\x91\x39\xba\x61\x0a\xc4\x81\x35\x34\xb3\x85\x8d\x0f\ +\x78\x2c\x00\x5d\x0b\xf0\x22\x25\x07\x31\x21\x9b\x5b\xd2\x20\x44\ +\xc0\x10\xcb\x73\x22\xda\x96\x02\x3c\x0e\xaf\x45\x73\x4e\x00\x7c\ +\x5d\x02\xf9\xe9\xcf\x5f\x4f\x57\x3d\xf1\x4f\x3d\x82\x5a\x07\xf9\ +\x88\xb4\x86\x16\x52\x17\x8c\x30\x15\x9a\x6b\xb2\x00\xad\x7d\xc0\ +\xad\x0a\xb1\x14\xd6\x02\x1e\x4d\xef\xdd\x4d\xd5\x85\x79\x15\xf0\ +\x7c\xd1\x91\x09\xb4\xb6\xa3\xb1\x4a\x51\x25\x54\x83\x23\xe7\x9c\ +\xb3\xe2\x26\xe9\x43\xbf\xf3\xdb\x34\x75\xc3\x0d\x61\x4e\xe7\x32\ +\xd9\x30\x75\x31\x13\x91\x6d\x89\x0d\xb4\x7a\xb1\xc4\x58\xd9\x02\ +\xa4\x54\x99\xa0\x1f\x0b\xf0\x00\xa7\xe4\xfb\x0b\x4a\x00\xae\x4b\ +\xe3\x5b\x36\x43\x00\x79\xb2\x32\x19\x12\x5a\xbb\x80\x50\x50\x1a\ +\x6e\x5a\x44\xd8\xdb\xdb\x66\xe8\x23\x7f\xf9\x75\xf2\x38\x40\x0a\ +\xfd\x7c\x84\xc3\xdf\xfd\x2e\xcd\x7e\xff\x29\x32\x6d\x9b\x2b\x47\ +\x6d\x29\xcd\xf7\x57\x44\x37\xf9\xd5\xef\xeb\xc0\x34\x7a\xcf\xc6\ +\x8d\x53\x06\xda\x59\x09\x40\xa2\xb5\xb8\x80\x5b\xf4\xfd\xbc\x4e\ +\x85\x41\xb1\x48\x65\x04\xc2\xf8\xc8\x3a\x6d\xd2\x0a\x32\x22\x17\ +\xb9\x01\xfa\x0b\xef\xb8\x83\x26\x2e\xbb\x8c\xec\x89\xc9\xe5\xc5\ +\x89\x96\xde\x01\xe9\xd2\x1b\x3f\x25\x6e\x89\xb1\x51\x7d\xef\x2c\ +\xd1\xed\x0a\xd1\x39\x41\xd8\x8b\x26\x91\x75\xa6\xb9\xbf\x1f\x0b\ +\x08\x00\x37\x1f\x04\xf3\x4d\x01\xe0\x22\x4f\xc5\x33\x67\x38\x13\ +\x70\x5e\x6f\xd7\xa8\x5e\x8c\xb6\x06\x3c\x9f\xc0\x73\xdc\xce\xbf\ +\xe9\x26\x65\x05\xd1\xf3\x91\x96\x1b\xc7\x4f\x10\xb7\xf4\x94\x12\ +\x92\x16\x60\x6f\xd2\x00\xbb\x4d\x19\xbb\x4f\x07\x75\x48\xd5\x0f\ +\xa8\x5c\xa9\x44\xf7\x23\x22\xaa\x24\xee\x27\x0b\x28\x01\x9c\x74\ +\xdd\x39\x2d\x80\x4a\xa5\x4a\x65\x6c\x63\xed\x4b\x2f\x21\x62\x01\ +\x74\x58\x95\x6c\x19\xc7\xb0\x71\x5a\x78\xe6\x69\x4a\xc2\x5d\x26\ +\x7f\xfd\x13\xf4\xf3\x8d\xe3\x24\x72\xf8\x54\x47\x3d\x50\x9f\x3b\ +\x43\xdc\x52\x9b\x36\x93\xfc\xef\xe7\x95\xf6\x3c\xc7\x51\xd6\x60\ +\x59\x5c\x8c\x1a\x51\x0c\x68\xf1\x7f\xc7\xb2\x69\xc7\xcd\x37\xd3\ +\xf8\xee\xdd\x94\x9a\x9c\xa0\x81\x2d\x5b\xa8\x84\xcd\xd5\x0f\xaf\ +\xba\x5a\x0b\x40\x5b\x00\x7f\xe3\xac\x4b\x62\xb3\x23\x0d\x7a\x67\ +\x1c\x27\x1f\x80\x3f\x2f\x88\x53\x61\x65\x69\x29\xac\x05\x5c\x57\ +\xbb\xc0\x8a\xae\x30\xb8\x65\x2b\x15\x5f\x7f\x8d\xe6\xfe\xfa\x51\ +\xe2\xb6\xeb\xd6\x5b\x61\x05\x4e\x97\x1b\x94\x17\xf2\xaa\x64\x4e\ +\xcf\xcc\x50\x15\x5b\xe1\x7a\x22\x41\x9b\x10\x18\x67\xf0\xfc\xd8\ +\x27\x7e\x83\x8a\xd5\x2a\x07\xd3\xb6\xb8\x20\xd6\x8d\xd2\xd5\x88\ +\x1f\x23\xcf\xfd\x90\xde\xfd\xcc\x75\xf4\xda\xaf\x5e\x49\x87\x2e\ +\xff\x08\xd1\xf3\xcf\x61\xc5\x1e\x2f\x3e\x82\x61\xe8\xb3\x01\x73\ +\x0d\x2e\xd0\x96\x09\x9c\x1a\x4a\x62\x5e\x6c\xbd\x56\x23\x1b\x87\ +\x15\x46\x12\xd0\x64\x3b\xd1\x9c\x1f\xde\xbb\x8f\x6a\xef\x1d\xa6\ +\x93\x67\xe6\x68\xe1\x3f\x7e\x40\x93\x57\x5e\x49\xf1\xe9\xe9\x76\ +\x17\x00\x1c\x69\x50\xf9\xf0\x61\x9a\xfa\xd8\xc7\xe8\x92\xfb\xef\ +\xa7\x5f\xf9\xbd\x6b\x69\x6b\xad\x44\x5b\xb7\x6f\xa3\x2b\xee\xbd\ +\x97\x7e\xf7\xc0\x6b\x14\xdb\xb6\x4d\x93\x57\xc2\xf8\xe8\xe3\x8f\ +\x53\xe1\x1f\xbe\x4d\x07\x7e\xf2\x16\xe5\x92\x69\xca\x25\x52\xf4\ +\xe6\xdc\x22\x3d\xff\xe5\x3f\xa3\xa0\x9d\xbc\xb6\x80\x99\xcf\x8c\ +\x8e\xa6\x0c\xb4\xb5\x08\x40\x67\x02\xb7\x2e\x44\x41\xb0\xbf\xc2\ +\x34\x37\x4c\x4f\x51\x0d\xfb\x02\x2b\x91\xe8\xf6\x51\xf6\xfd\xe6\ +\x31\xf5\xe8\x85\x17\xaa\x78\x11\x90\x41\x73\x8f\x3e\x4c\xdc\xf6\ +\xdc\x76\x1b\x9b\x77\x18\x24\x01\xd9\x44\xf5\xd0\x41\xb2\x90\x5a\ +\xe7\x1f\xf9\x16\x1d\x78\xe4\x51\x7a\xfe\xdb\xff\x48\xaf\xdc\x74\ +\x23\x9d\xbe\xe5\x0b\x14\x1f\x1a\xa2\xab\xbf\xf3\x1d\x92\xc3\xc3\ +\xea\xd9\x91\x7d\xfb\x68\xdd\x79\xe7\xd1\xd1\xe7\x7e\x44\x42\xca\ +\x36\x9f\xaf\x5a\xf6\x32\x79\x11\x92\xd7\xb0\xf6\x0d\x0c\xec\x5e\ +\xab\x05\xc8\x65\x0b\x08\x82\x25\xa1\xb6\xc5\xa8\x05\x76\x9c\x4f\ +\x75\x6c\x86\xec\x74\xba\x4d\xf3\x82\xa1\x83\x97\x65\x71\x90\xc4\ +\xf3\xbe\x9a\x3b\xf2\xde\xfb\x94\x7b\xee\x39\x9a\xb8\xe2\x0a\x4a\ +\x6c\xdd\xd6\x6e\xce\x40\xfd\xbd\xf7\x88\x5b\x11\xd6\xe0\x41\x60\ +\x30\x78\x2a\x26\x53\xf4\xda\x7f\x3e\x43\xb3\x4f\x7c\x8f\xe2\x38\ +\x5d\xda\x7c\xcd\x35\xea\xd9\xb1\xcd\xe7\xaa\xa5\x35\x82\xa0\x8d\ +\xbc\x86\xe8\x20\xaf\x91\x20\xda\xdf\x8f\x0b\x78\x80\x53\x0e\x82\ +\xbc\x3e\x18\xd9\x30\x31\x8e\x54\x38\x4f\x71\xf8\xa1\xce\xfd\xdc\ +\xcb\x65\x04\x34\xb4\x79\x33\x39\x88\xfa\xd6\xf9\xe7\xd3\xf0\x47\ +\x7f\x8d\x36\x7f\xf1\x8b\x94\xda\xba\x95\xb8\xed\xbd\xfd\x76\x58\ +\x41\xa3\xcd\x0d\xea\xcd\x7d\x45\x72\x6a\xaa\xad\x62\x74\x0d\x93\ +\x72\x4f\x3e\x41\x68\xec\x42\x6a\xce\x32\x0d\x15\x40\xd3\xbb\xf7\ +\xa8\x5e\x10\xb5\x41\x76\x93\x57\x73\xb1\x30\x13\x9c\x9d\x0b\xb4\ +\xd6\x02\x5a\x00\xcb\xa9\x90\xb7\xc5\x73\x73\x64\x8f\x8e\xf2\x81\ +\xa7\x2e\x75\x23\x60\x91\x23\xf0\xff\x31\x04\xb5\x8b\x2f\xb9\x98\ +\x76\x0a\x97\xb2\x2f\x3c\x4b\xf9\x9b\x7f\x9f\x4a\xaf\x1d\xa0\x89\ +\xcb\x2f\xa7\xd4\x8e\x9d\xad\x6e\x00\x01\x1c\x0b\x53\x21\x22\x79\ +\xe7\x5f\x7e\x4e\x1f\x3c\x48\xaa\x35\x35\x5e\x7b\xe9\x45\x95\x48\ +\x66\xbe\xf0\x07\xe4\x0a\xd1\x45\x94\xd7\x68\x66\x32\x5d\x71\x80\ +\x4c\x53\x95\xc4\xfd\xb8\x80\xbb\x84\x5a\xa0\x55\x00\x95\x85\x05\ +\x95\x09\x60\xe3\x6a\xb1\x11\x42\x52\x59\x14\x3f\x07\xaf\xff\x2c\ +\xfd\xf8\xe1\x47\xe8\x85\x1f\x3c\x4d\xaf\xbc\xf5\x0e\xfd\xf4\x64\ +\x8e\x4e\xdf\x77\x2f\x71\xdb\x87\x02\x89\x33\x82\x7e\xaf\x78\xf2\ +\x64\x28\x80\x6d\x33\x1d\x55\x20\x22\xc8\xba\x31\xe2\xe6\xe7\xe6\ +\xd4\xdc\xc9\xa3\x27\xa8\xf8\xc2\xf3\xb4\xfe\x82\x0b\xe8\xa2\xfb\ +\xef\x23\xc7\xe0\xc0\xef\xa9\x2d\x7b\x1d\x19\x63\xe6\xfa\xeb\xe9\ +\xdc\x5d\x3b\xda\xc8\x03\x4c\x6c\x37\x77\x06\xda\x5a\x04\x10\x00\ +\xde\xac\xeb\xe6\x42\x25\x04\x61\x2d\x80\x54\x68\x8d\x0c\xf3\x2f\ +\x33\xe1\x08\xbc\x78\x32\x68\x74\xcf\x1e\x3a\x8e\xe8\xef\xe1\x73\ +\xa2\xa5\x34\x3e\xfc\xd6\xdb\x54\x7c\xf5\x15\x1a\xbf\xf4\x52\x1a\ +\xdc\xb7\x77\xb9\xe0\xa9\x14\x4a\xe4\xe0\x9b\x53\x57\x5d\x15\x1e\ +\x8c\xa8\x6f\x85\xef\xc5\xd9\xd2\x30\x97\xff\xdb\xbf\x51\xbd\x87\ +\xf5\x1f\xbe\xe5\x66\x72\x20\xb4\xed\x9f\xfe\x34\x7d\xea\xc7\x2f\ +\xd1\x87\x1e\xf8\x73\xda\xf5\xa7\x7f\x42\xd7\x3c\xfb\x5f\x34\x99\ +\x1d\xa1\xf7\x5f\x7e\xb5\xcb\x15\x70\x3d\x72\xe7\xfa\xf5\x9b\xd6\ +\x6a\x01\x02\xf0\x8e\x3b\xce\xac\x3e\x18\xe1\x5a\xa0\xc6\x47\xe4\ +\x99\x41\xf6\x95\x76\x0b\x10\xf0\xff\x6d\x5b\xa9\x7c\xe8\x10\x79\ +\xbe\xaf\x49\x2c\x9b\xb5\x83\xcf\xcf\x7e\xf3\xeb\xc4\xed\xc3\x5f\ +\xbd\x87\x5c\x37\x14\xa0\x4f\x52\xbd\x93\x04\xd9\xf1\x4f\x7e\x92\ +\xaa\xa5\x32\x79\xae\x4b\x55\xa4\xdd\xf3\x6e\xb9\x85\x16\x1e\x7b\ +\x98\x0e\xbe\xfe\xc6\x32\x99\x83\x85\x0a\xfd\xec\xea\x8f\x53\xe9\ +\xbe\xaf\x92\x3c\x7e\x8c\xa6\xf6\xef\xa7\x2d\xd3\x93\xe4\xdf\x73\ +\x37\xbd\xf9\xb5\xaf\x93\x6f\x9a\x7a\xf1\x6d\x41\x71\x5d\x22\xb1\ +\x6f\xad\x7f\x1a\x93\xcd\x2d\x71\xd5\x05\xe2\x52\xa6\x6b\x58\x54\ +\x06\x0b\x75\x0a\x4b\x2a\x15\x7a\x22\x68\x2b\x03\xc7\x90\xfe\xaa\ +\x47\xdf\x57\xd6\x80\xd6\x7e\x26\x80\xf6\xb3\x67\x7f\x44\xd3\x48\ +\x8f\x9c\xca\xf6\xdd\x75\x17\xbd\xf9\x8d\x6f\x90\x84\x4b\x79\x20\ +\x22\x2f\xba\x88\xae\x7c\xe8\x21\xda\x7b\xe3\x8d\x94\x3b\x70\x80\ +\x86\x51\xe1\x89\x27\xbf\x47\x2f\x3e\xf1\x14\xb9\x76\xac\xad\xbc\ +\x3d\x58\xf7\xe8\xc8\x63\x8f\xd3\xc8\xb7\x1e\x26\x5b\x08\x95\x02\ +\x17\xe3\x49\x68\xda\xea\x8a\x0b\x7a\x6c\x87\x99\xe0\x9f\x01\xd9\ +\x4b\x00\xdd\xc5\x10\x6a\x81\xb4\x10\x69\xce\x04\x93\xe7\x9f\x87\ +\x5a\x60\x89\x62\x48\x4f\x75\xc4\x04\xdd\x1a\x8d\x3a\x4d\x5e\xf3\ +\x5b\x34\xff\xfa\xeb\x54\xc4\xbe\x61\xa8\xb9\x17\x90\xa1\x10\x54\ +\xae\xbf\xf0\xa1\xaf\x91\x09\xed\x96\x9f\x7d\x86\x26\x93\x71\xca\ +\xde\x74\x03\xfd\xcf\x93\x4f\x51\xee\xa1\x07\xe8\xc4\x1f\xfd\x21\ +\x65\xb0\x75\x8e\x65\xd2\xe4\x97\x2b\xf4\xf6\x99\x59\xca\xc7\x07\ +\xc8\x67\xf2\x11\x21\x2d\x04\x95\x25\xe6\x70\xbf\x93\x28\xb0\xe2\ +\x1c\x59\x96\xca\x04\x6b\xb6\x80\xa6\x00\xb8\x16\x98\xe4\x6d\xf1\ +\xae\x5d\x3b\x69\xfe\xf8\x49\x8a\x83\xa0\xc0\xde\x80\xdb\x10\x0a\ +\x94\x4b\x60\xae\xe9\xc1\x0c\xc5\x21\xa0\x8f\x3f\xf8\x00\xbd\xfc\ +\x95\xbb\x49\xb6\x1e\x93\xc3\x75\xe6\x6f\xbd\x99\x8e\xc1\x35\x1a\ +\x56\x4c\x11\xf0\x0d\x43\xf5\xa7\xf8\xbe\x95\x20\xca\x17\x49\x02\ +\xdc\x64\x22\x15\x2d\x7e\x05\x82\xd4\x83\x78\xe7\x9c\x85\xb3\x81\ +\x66\x20\x14\x12\x6d\x2d\x16\xe0\x56\x5b\x6a\x81\x61\x90\x3c\x82\ +\xa8\x3c\x9e\x5d\x4f\xf4\xee\x3b\x61\x9e\x7d\xfb\x4d\x3a\xf5\xd9\ +\xeb\xe8\x10\x4c\xdf\x33\x2d\xf2\x2d\x8b\x84\x1d\x6f\x3b\x30\xf4\ +\xd0\x1f\x89\x0d\x10\xd9\xd1\x66\x08\x2d\x1c\xb7\x12\x5b\x85\x24\ +\xad\x4e\x94\x5b\x4f\x4b\x00\xf1\x2d\x9f\x1a\x19\x49\x7f\xbf\x50\ +\x28\xf6\x0a\x82\x51\x2d\x10\x15\x43\x8b\x3a\x13\x70\x2a\x2c\xcf\ +\x87\xa9\xd0\xf0\xc2\x8d\xca\xbc\xe3\xd1\xfb\x20\x37\x8b\x0a\x2e\ +\x1f\x4b\x50\xd1\xb4\x5b\xff\xd5\x46\x74\x4c\xa6\x7b\x29\xdb\x76\ +\x6c\xa2\x63\x8c\x45\x33\x74\x00\xeb\x0e\x6a\x8c\xee\x0a\xb0\xbd\ +\x28\xd2\xcf\x46\x73\x26\x4a\xe2\x3d\x6b\x75\x01\x7d\x30\xb2\x5c\ +\x0b\x38\x5c\x0b\x14\x8b\x64\x73\x7d\xce\xa9\x90\xba\x1b\x18\xb6\ +\x7e\x64\xf5\x71\xb7\x06\x3b\xe7\xba\xdd\xa0\xb7\xd6\xf5\x7c\xd7\ +\xb5\x1d\x8f\x73\x20\x7c\x11\xe8\xe1\x02\x1d\xe7\x02\x8b\x41\x90\ +\xd3\x02\xa8\x54\x6b\x61\x2a\x5c\xb7\x8e\x4c\xbd\xb7\x5f\xa1\xc9\ +\xce\xeb\xd5\x84\xd0\x69\xe2\x9d\xcf\xf7\x70\x83\x68\xae\xb7\x1b\ +\x20\x0e\xb0\x00\x8c\xb5\x58\x80\x00\xbc\x13\xa8\x05\xd0\x87\x9b\ +\x17\xd4\x02\x75\xd4\xfa\x6e\xa9\x44\x16\x6f\x8a\x5c\xb7\x9b\x70\ +\x2f\xad\x1b\xc6\x2a\x82\xe9\xd6\x78\x37\xf1\xfe\x83\x22\x22\x60\ +\x5b\x20\xec\x21\x80\xc8\x0d\x4e\xe3\x60\xc4\x97\xd2\x8f\x49\x69\ +\x73\x2d\xb0\x1e\x1b\x9e\x06\xbb\x01\xb6\xab\x62\x61\xa1\xb7\xf6\ +\x99\x70\xff\x6e\x10\x8d\x7b\xb9\x41\x8f\xe7\x41\x5c\x95\xc4\x3d\ +\x83\xe0\x4a\xbb\x42\x6c\x41\x8b\x3a\x13\x6c\xda\x79\x3e\x55\x51\ +\xbe\x26\xb2\x59\x0e\x34\x5d\x90\x8c\xd6\x6b\xa2\x5e\x41\x6f\xd5\ +\xe0\x26\xa3\xfb\xd1\x35\xa3\xc7\x0e\xb0\x2b\x28\xe2\x1a\x02\x18\ +\xbc\x6d\x62\x62\xf3\x1a\x04\x10\x05\xc2\xba\x10\x8b\xfa\x88\xfc\ +\x5c\xe4\xfa\x2a\x34\x9f\x58\xbf\x5e\x9f\xf9\x77\x47\xeb\xce\xb9\ +\x55\x48\xa9\x7e\x35\x01\x75\x13\x8f\xc6\x2d\xef\x8a\x1e\x31\x80\ +\x5a\x2c\x70\xd0\xb6\xf7\xaf\x49\x00\xda\x02\x50\x0b\x2c\xc1\x6d\ +\x54\x0d\x9f\x42\x55\x57\x99\x9f\x57\x81\x90\x84\x68\x27\xbd\x1a\ +\x71\x4d\xb8\x9d\xd4\x4a\x7d\xf4\xdc\x5a\xac\x81\xe7\x7a\x90\xe7\ +\x16\x37\x0c\x15\x08\x7b\x06\x41\x89\xc6\xc1\x42\x97\xc3\x95\xd6\ +\x73\x81\x7c\x3e\x4c\x85\xd8\x17\x18\x52\xf2\xa2\xd6\x16\x08\xf5\ +\xb8\x67\x36\xe8\x5d\x10\x51\x0f\xad\x77\x36\xcc\xee\x69\x2a\x5b\ +\x9c\x75\x10\x04\xdc\x12\x04\xa0\x8b\x21\xa7\x50\xa0\x7a\xa5\xc2\ +\x16\xa0\xbf\xd4\x3b\x10\x76\x8d\x35\xe9\xde\xd9\xa0\x37\xf1\x6e\ +\x61\xea\xac\x85\x8d\x9c\x82\x0f\x38\xbe\x2f\xc8\x34\xe7\xf8\x09\ +\x6e\x12\xad\xa7\x00\x74\x2d\x50\x68\xad\x05\x2a\x55\xaa\x3b\x0e\ +\x79\xd5\xaa\x3a\x29\x16\x98\xa3\x5e\xda\xd7\x56\xd2\xcb\x12\x7a\ +\xa4\x41\x5d\x56\x2b\x62\xf8\x5d\x0f\xbd\x27\x84\xf4\xd9\x5a\x13\ +\x89\xc0\x1a\x48\x0a\x3b\x95\x96\xf6\xf0\x90\x4c\x8e\x8e\xd1\xe0\ +\xe4\x84\x1c\x9d\xde\x44\x53\xbb\x76\xc8\xbf\xb8\xf3\xcb\xd7\xfd\ +\xdb\xbb\xef\xbe\xdc\xb3\x0e\x58\xf1\x60\xc4\xf3\xe6\x5a\x6b\x01\ +\xe5\x17\x70\x83\x18\x52\xa1\x5c\x5a\xea\x26\xdd\x87\x1b\xb8\x4d\ +\x8d\x79\x00\xf7\x0e\x88\x41\x63\x81\x88\xc7\x03\x23\x91\x10\x46\ +\x26\xc3\xff\x78\x52\x9d\x1d\x0c\x8c\x8f\xcb\xd1\xc9\x49\x63\x64\ +\x7a\xda\x1e\x99\x18\xb7\x6d\x3b\x66\x99\xf8\x9f\x6d\xd9\x14\x8b\ +\xc5\xc8\xb6\x2d\xf4\x71\xe2\xeb\x64\x32\x49\x43\x58\xe7\x79\x93\ +\x93\x15\x08\xa0\xce\x9c\x7a\xd4\x01\xdd\x81\xf0\x78\xa3\x31\x2b\ +\xf0\x8e\xfe\x23\xc9\xe4\xf6\x19\x6a\xa0\x18\x4a\x8e\x8d\x91\x80\ +\x00\x56\x7b\x11\xef\x68\x2d\x69\x73\x64\x0d\x0a\x11\x12\x63\xad\ +\x09\x99\x4a\x49\x2b\x93\x31\x6c\xa4\xd5\x01\x6c\x89\x33\xe3\xe3\ +\xe6\xf0\xf4\x94\x99\xc9\x66\x6d\x32\xd4\xc6\xc2\xe6\xe5\x5a\x96\ +\x45\x71\x45\x0e\x24\xe3\x71\x35\x8e\x27\xb8\x8f\x87\xa4\x63\x98\ +\xb7\x63\xfc\x9c\x7a\x06\x02\x61\x01\xa8\x67\xd2\xa9\x34\xed\x3f\ +\x77\x52\xe9\xad\x67\x29\xbc\xd2\xae\x10\x59\xa0\x02\x12\x15\x14\ +\x43\x19\x95\x0a\x77\xec\xc0\xb6\xf8\xb8\x0a\xa7\x8b\xb5\x5a\xe8\ +\x67\x78\x36\xb0\xac\x40\xc4\x62\x42\x26\x12\x52\x0e\x0c\x48\x99\ +\xce\x20\x58\x8e\xc9\xc4\x86\x73\xcc\xd4\xf8\x46\x63\xdd\xe4\xa4\ +\x3d\x38\x3a\x66\x41\x55\x26\x2f\xce\x34\x94\x43\x92\xc9\x8b\x06\ +\x4c\x1e\x9b\x26\x19\x80\x26\x8c\x7b\x21\x69\xc0\x62\xe0\x1e\xae\ +\x19\xea\x59\x0d\x7d\xe4\x87\x79\x7e\x57\x83\x05\xa4\xe6\x26\x92\ +\x99\x18\x6e\xf7\xda\x0e\xaf\x9e\x0a\xf9\x8f\x24\x49\x21\x32\xae\ +\xe3\xd1\xb6\xa9\x29\xf9\xea\xf1\x13\x1e\xcd\xcc\x48\xfb\xe2\x0f\ +\x1b\xa3\x9b\x36\xd9\x03\x83\x83\x26\x7e\xc8\xd4\x0b\x64\xad\x60\ +\xac\x34\x80\x59\xb2\x15\x19\x73\xf9\xf8\x1b\xd4\x31\x0e\x78\xcc\ +\x8b\x57\xe0\xb5\x99\xfc\x0e\x34\x0c\xe8\x39\x75\xf8\xc9\x82\x37\ +\x00\x7c\x97\x63\x11\xf7\xfc\x0c\x93\x0c\x85\xd8\xfc\x5d\x34\xbe\ +\xd6\xd9\x2c\xdc\xc5\xd6\xeb\x6e\xcc\x94\xa9\x35\x9c\x08\x75\x67\ +\x82\x1a\x8a\xa1\x11\x29\xa7\x38\xf2\x9f\x29\x14\xbc\x89\xcf\x7d\ +\x1e\xe7\x22\x23\x94\x49\xa7\x40\x32\xc1\x0b\x51\x84\x41\x45\xbd\ +\x26\x98\x8c\x8e\xe2\x18\xa3\x0f\x17\x69\x59\xbc\x78\x8c\x2d\x40\ +\x11\x6c\x03\x04\xa2\xc7\x9a\x84\x7a\x3e\x11\x5a\x85\x26\xac\x35\ +\xdd\x9a\xba\x59\x30\x3c\xd7\xf6\x0d\xbe\xae\x17\x8b\x65\xcb\x13\ +\x99\x35\x6c\x87\xa3\x5a\x40\x5b\x40\xa5\x79\x2e\xb0\x1e\x01\xe5\ +\xe4\x9e\x7d\xd6\xa6\xe9\x69\xca\x8e\x8d\x92\xdd\xd4\x34\xb1\x16\ +\x0c\x93\x3b\x6d\xaa\x9a\x44\x44\x8e\x11\x04\xbc\xd0\x30\xa5\x3a\ +\x2e\x6b\x57\x2f\x58\x43\x9b\x34\xa3\x6d\x8e\xdf\xd1\x42\x40\x6b\ +\x8e\xb5\x40\x57\x2e\xf3\xf9\xdb\x8d\x7c\xbe\x4a\xc2\x4f\xb3\x71\ +\xf4\x6b\x01\x2c\x00\xb5\xf3\x09\x3c\x4f\x66\xa6\xa7\x51\x06\x8c\ +\xd0\xf0\xf0\x30\xff\x78\xf3\xbb\xa1\xf6\x74\xbd\x00\x62\x7a\xcc\ +\xe0\x7b\x0a\xda\x2c\xd1\xba\xc9\x47\xd0\x1a\xe6\xbe\x6d\x0c\xa2\ +\xda\x0a\xf8\xdd\xd0\xc4\x9b\xbb\x52\xad\x71\xfd\x8c\x16\x4a\xe5\ +\xf4\xa9\x1a\x1e\x4c\xaf\xc1\x02\xba\x53\x61\xc9\xf7\x95\x00\x6a\ +\xae\x1b\x0c\x25\x93\x76\x22\x9e\x20\x5d\x1b\x60\x31\x6d\x64\xb5\ +\x00\x22\xd2\x91\x70\xb4\x56\x5b\x7d\x94\x7b\x4d\x46\x2f\x5e\x9b\ +\xb4\xe3\x38\xfa\x0f\x20\xda\xf4\xbb\x02\x1d\xe6\x75\x1c\x50\xdf\ +\xd1\xef\xeb\x00\xb9\xf8\xea\x2b\x0d\xc3\xf3\xfa\xb6\x00\xd1\xfc\ +\x17\x23\x73\xfc\xb6\x67\xdb\x42\xfd\xa8\x69\x68\xcd\x6a\xad\x69\ +\x82\xda\x2c\x79\xac\x89\x30\xb4\x50\x34\xda\xde\xd1\x66\xaf\xef\ +\xe9\x6b\xf4\xfa\x5b\x3c\xcf\xdf\x60\x8d\xab\xf9\x0c\x6a\x83\x81\ +\x81\x01\x95\xeb\x13\xcd\x38\xd4\xd9\x1a\xa5\x62\xc3\x39\x72\x78\ +\xc4\xf5\x7c\xd9\x87\x05\x44\xa9\x10\x07\x23\x67\x78\x11\x3e\x56\ +\x8d\x42\x43\x93\xd3\xd2\xd7\x5a\xd4\xda\xd7\x64\x3b\x03\x9b\x16\ +\x4e\x9b\x26\x75\xd3\x04\xb5\xf6\xf4\xb3\x3a\x23\x74\xb6\x72\x3e\ +\xef\xce\xbe\xf3\x4e\x3d\x7f\xf4\xa8\x53\x3a\x79\xc2\xaf\x9e\x99\ +\x95\x41\xa1\x60\x58\x8d\xba\x3d\x20\x45\x7c\xc8\x8e\xa5\x32\xa9\ +\x64\x32\x96\x88\x0f\xbf\x9e\x5b\xfc\xd7\x3e\xb2\x40\x94\x0a\x4f\ +\x39\xce\x82\x90\x92\x3d\x3b\xd0\x8b\x6e\xd5\xa8\x16\x82\xd6\x1a\ +\x34\xd2\xb5\x68\x5c\x6b\xb4\xa5\xaf\xd6\xc6\xef\x71\x2b\xe6\x72\ +\xce\xe9\x23\x47\xea\x0b\x47\x8e\xb8\x85\xe3\xc7\xfd\xf2\xe9\xd3\ +\xd2\x59\x58\x30\xfc\x62\xd1\x36\x1a\x8d\x44\xdc\xf7\x53\xb6\x69\ +\xc6\xf1\x8d\xb8\x0a\x90\x86\x51\x0b\x4c\xa3\xe4\x1a\x0a\x05\x60\ +\x09\xa2\x9c\x43\xd1\x75\xe8\xe9\xd3\xb3\x4f\xbe\x9d\xcf\x1f\xeb\ +\x57\x00\x3a\x13\x34\xea\xbe\x5f\xf2\xa4\x8c\x6b\x72\xda\x84\x5b\ +\xcd\x55\x43\x13\x5d\xa9\x15\x66\x67\x9d\x1c\xc8\x2d\x1d\x3b\xe6\ +\x2c\x1e\x3d\xea\x57\x67\x67\x79\x97\xb9\x4c\x2e\x21\x44\xca\x84\ +\x2c\x08\xc0\xef\x35\x1c\x29\x4b\x7c\x28\x83\x5a\xa4\x58\xc7\xd6\ +\x9c\xff\x0d\x63\x59\x88\x7c\x01\x9b\xb4\x3c\x14\x73\xd4\x75\xe7\ +\x30\x5f\x67\x57\x65\xe8\xcc\x05\xd4\x80\x02\x50\x0c\xe7\xfb\x17\ +\x80\x0b\xd4\x71\x40\x7a\x6c\x7c\x71\x71\x47\x12\x02\xb0\x59\x83\ +\xb6\xdd\x45\x12\xe4\x1a\xb9\x43\x87\xea\x79\x90\xc3\x5f\x7f\x83\ +\x0a\x6b\x0e\xe4\x44\xa9\x14\x53\x9a\x13\x22\xcd\xe4\x02\x64\xd9\ +\x86\x10\x7e\x43\xca\x4a\x93\x9c\x22\x56\xf1\xfd\x7c\x11\xc4\x16\ +\x7c\x3f\x87\x12\x7c\x1e\x3b\xd1\x32\x13\xea\x20\xc7\xf0\x5b\x10\ +\xb4\xf7\x7a\x1c\x3d\xab\xab\xc0\x1e\x02\x58\xb5\x16\x70\x80\xd2\ +\x7b\x8d\xc6\x4b\x9b\x97\x96\xf6\xbe\xf4\xe0\x83\x8b\x89\x7a\xd5\ +\x3c\x35\x9f\xaf\xe1\x80\x54\x82\x9c\x6d\x36\x1a\xc9\x18\x8a\x5f\ +\xfe\x16\x6f\x64\x80\x3a\xff\x59\xad\x2e\x65\xa1\xe6\xfb\x4b\x15\ +\x68\xac\xe8\x79\x0b\x8b\x38\x66\x3f\x89\xcd\xd5\x82\xeb\x96\x34\ +\xa1\x3e\x88\x31\x04\x20\xcf\x06\xdc\xfa\xfe\xbf\xce\x42\x00\x26\ +\x85\xe6\xb8\x11\x52\xda\x7e\xf3\xe4\xe4\x1f\x6f\x4c\x26\x77\xa7\ +\xd2\x29\xff\x8d\xb9\xdc\x4f\xaa\xa8\x0f\x4a\x40\x1e\xc4\x70\x80\ +\x9a\x3b\xe3\xba\x8b\xdd\xa4\x80\xde\xa4\xb8\x17\x8c\x1e\xe4\x28\ +\x1a\x77\xb7\xd5\xc8\xf6\x2b\x00\x2d\x04\x1b\x5d\x1a\x18\x05\x86\ +\x81\x18\x20\xce\x46\x5b\x6b\xd4\x18\x7d\x30\xc4\x3e\x78\x01\x18\ +\xe8\x2c\x26\xde\x84\xa1\x6b\x84\x5f\x2e\x62\xfd\xb7\xff\x05\xc7\ +\xfd\xe7\xdb\x23\x5d\x13\x38\x00\x00\x00\x00\x49\x45\x4e\x44\xae\ +\x42\x60\x82\ +\x00\x00\x20\x1c\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\ +\x1b\xaf\x01\x5e\x1a\x91\x1c\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xd7\x08\x12\x14\x39\x28\x29\x91\x7c\x0e\x00\x00\x1f\xa9\x49\x44\ +\x41\x54\x78\xda\xe5\x9b\x09\xb0\x5c\x57\x99\xdf\xff\xb7\xf7\xbd\ +\x5f\xbf\xfd\xe9\xe9\x3d\x49\xd6\x2e\xd9\xda\x2c\x79\xc1\x78\xc0\ +\x76\x42\x81\xc1\x03\x64\x0c\x13\x1c\x42\x65\x02\x4e\xb1\x84\x78\ +\x5c\xc5\x14\x55\x49\x2a\x54\x48\x05\x2a\x03\xc3\x14\x03\x55\x33\ +\x13\x43\x2a\xae\x21\x9e\x01\x26\x05\x43\x80\xd8\xb2\x0d\x78\xc3\ +\x96\x25\x6b\xb1\xf5\xb4\x3d\x6b\x7d\xd2\xdb\xb7\xde\xb7\xdb\xb7\ +\xf3\x3b\xa7\xbb\x35\x12\x1a\x0a\x18\xb0\x81\x4a\xcb\x9f\xcf\xed\ +\xbb\x9c\x77\xbe\xed\xff\x2d\xf7\xb4\xfe\x7f\xff\x38\xaf\xe7\xdf\ +\x59\xb3\x66\x8d\xaf\xab\xab\xcb\xd7\xdb\xdb\x6b\x29\x91\x48\x38\ +\xd5\x6a\x55\xb9\x5c\xce\x5b\x58\x58\xf0\x96\x97\x97\xbd\x0b\x17\ +\x2e\x78\xd9\x6c\xb6\x29\x09\xfa\x2d\x16\x40\x24\x12\xf1\x6d\xdd\ +\xba\x35\xb0\x7b\xf7\xee\xf8\xdd\x77\xdf\xbd\xb5\xaf\xaf\x6f\x67\ +\x34\x1a\x5d\xcf\xf9\x75\x7e\xbf\xbf\xd7\x71\x9c\x04\x14\x6f\xf2\ +\x69\x34\x1a\x05\x43\x08\x63\xa6\x5c\x2e\x9f\x2a\x16\x8b\xe3\xd3\ +\xd3\xd3\xfb\xbf\xfd\xed\x6f\x9f\x3c\x70\xe0\x40\x0d\xa1\x34\x8c\ +\x40\x7e\x1b\x04\xe0\x6c\xda\xb4\x29\x74\xef\xbd\xf7\xf6\xbe\xf5\ +\xad\x6f\xbd\x07\x2d\xbf\x3d\x16\x8b\xdd\x1c\x0e\x87\xfb\x60\x5a\ +\xf0\x2a\xd7\x75\x2d\xc1\xb0\x3c\xcf\xb3\x0f\xf9\x7c\x3e\x4b\xc1\ +\x60\x50\xdc\x67\xcf\x57\x2a\x15\x15\x0a\x85\x49\xac\xe1\xd9\xa9\ +\xa9\xa9\x6f\x3d\xca\xe7\x5b\xdf\xfa\x56\xde\x58\xca\xaf\x52\x18\ +\xce\xaf\x4a\xdb\xd7\x5f\x7f\x7d\xf4\x13\x9f\xf8\xc4\xae\x6d\xdb\ +\xb6\x7d\x34\x9d\x4e\xdf\x0d\xd3\x29\xc3\x08\x1a\x15\x1a\x55\xa9\ +\x54\x52\x15\xa6\x6a\xb5\x9a\xdc\x7a\xbd\x25\x00\x08\xa1\x40\xad\ +\x95\xc0\xbc\x15\x42\x38\x1a\x55\x2a\x95\xb2\x14\xe5\xb8\xce\xfd\ +\x8b\x8b\x8b\xf3\x33\x33\x33\xff\x7b\x6c\x6c\xec\xcf\x3e\xf7\xb9\ +\xcf\x8d\x4f\x4e\x4e\xba\x46\x10\xbf\x6e\x01\x38\x1b\x37\x6e\x8c\ +\x7e\xfa\xd3\x9f\xbe\x79\xc7\x8e\x1d\x7f\x94\xc9\x64\xde\xe2\xe7\ +\x03\xd3\xc6\xaf\x55\x2c\x14\x54\xe1\xd8\x50\x15\x2a\x23\x04\xc8\ +\x0a\xa2\x8e\x20\x1a\x58\x82\xe1\xde\xe7\x38\xf2\x07\x02\x0a\x05\ +\x43\x0a\x86\x42\x0a\x84\x43\xf2\x9b\x63\xc6\x68\x3c\xae\x9e\xbe\ +\x3e\xf5\x41\x21\xae\x2d\x2d\x2d\xd5\x2f\x5d\xba\xf4\xcd\x23\x47\ +\x8e\x7c\x96\xbf\x7b\x22\x9f\xcf\xbb\xbf\x16\x01\xa0\x9d\xe0\x87\ +\x3f\xfc\xe1\x91\xf7\xbf\xff\xfd\xff\x7e\x68\x68\xe8\x03\x98\x70\ +\x10\x4d\x5b\xc6\x4b\x30\x6e\x28\xbb\xbc\xac\x85\xb9\x79\xcd\xce\ +\xcd\x6a\x6e\x76\x56\x4b\x8b\x4b\xca\xe6\xb2\xd6\x1a\x3a\x02\xf0\ +\x49\x0a\xfa\xfc\x8a\x84\x82\x4a\x18\xcd\x27\x12\xea\x4a\xa7\xd5\ +\x95\xe9\x56\x2a\xd3\xa5\x68\x2a\xad\x50\x22\xae\x70\x2c\xa6\x6e\ +\x84\x30\xbc\x72\xa5\x62\x1c\xcf\xce\xce\x96\xcf\x9c\x39\xf3\xc5\ +\x6f\x7c\xe3\x1b\x9f\xfb\xfa\xd7\xbf\xbe\x2c\xc9\x7b\xbd\x04\xe0\ +\x8c\x8e\x8e\xc6\xbe\xf4\xa5\x2f\xbd\x63\xcf\x9e\x3d\x7f\x8a\x89\ +\x0e\x5d\xd6\x78\x3e\xaf\x1c\x4c\x4f\x4f\x4d\xe9\xfc\xb9\xf3\x3a\ +\x73\xf6\x8c\x26\x26\x26\x34\x03\xf3\xf8\x72\x87\x71\x6b\xfa\xc2\ +\x3d\x1c\xa3\x7d\x49\x01\xc7\xa7\x00\x18\x10\x0a\xf8\x15\x45\xcb\ +\x89\x48\x54\x19\xcc\xbf\xaf\xa7\x5b\x83\x83\x83\xea\x5f\xb1\x42\ +\xe9\x81\x01\x45\x33\x19\x85\xcd\x79\xce\xad\x5a\xb5\x4a\xc2\x72\ +\xce\x9d\x3b\xf7\xea\xc1\x83\x07\xff\xf5\x27\x3f\xf9\xc9\xe7\x5d\ +\x3e\xaf\xb5\x00\x7c\xb7\xdc\x72\x4b\xf7\x97\xbf\xfc\xe5\xff\x40\ +\x48\xfb\xb7\x66\xed\x98\xa0\x0a\x50\x76\x71\x51\x13\x17\x2e\xe8\ +\xc4\xf1\x13\x1a\x3b\x7e\x4c\x68\xc7\x32\x5e\x2e\x96\xd4\xdb\xdb\ +\xa3\x95\x2b\x86\xd5\xc7\xd8\xdd\xd5\xa5\x58\x24\xa2\x30\xbe\xde\ +\x6c\x78\x06\x0f\xb8\xa7\xa0\x02\x02\x5c\x5a\x58\xd0\xfc\xf4\x0c\ +\x34\x8d\x60\x9a\x8a\xe0\x06\x29\x5c\xa0\xbf\xa7\x47\x2b\x56\x0e\ +\x6b\xc5\xea\xd5\xca\x8c\x8c\x2a\xda\xdb\xab\x38\xc2\x19\xe5\x7b\ +\x5f\x7f\xbf\xc0\x86\x2a\xd8\xf0\x1f\x1f\x7c\xf0\xc1\x2f\xe3\x22\ +\x95\xd7\x4a\x00\xfe\xb7\xbf\xfd\xed\x2b\x3e\xff\xf9\xcf\xff\x05\ +\x5a\xb9\x1b\x60\xb2\x8c\xe7\xd0\xec\xe4\xc5\x8b\x3a\xfa\xca\x2b\ +\x3a\xf0\xd2\x4b\x3a\x7e\xf2\xa4\x66\xa6\xa6\xf1\xd9\x5e\x6d\xdb\ +\xba\x55\x9b\x37\x6d\x52\x22\x1c\x91\xaf\xe9\xc9\xef\xb5\xc8\x31\ +\x04\xf3\x62\x84\xac\x45\x34\x0c\x71\xec\x72\x5f\xb5\x5a\xb3\x73\ +\x9e\x3e\x76\x4c\x0b\x08\xd1\x80\x63\x12\xb3\xef\x87\xf1\x95\x30\ +\xbd\x62\xfd\x7a\xa5\x56\x8d\x2a\xc2\xf7\x01\x5c\x62\xf5\x75\xd7\ +\x59\xa0\x45\x08\x5f\xf9\xd4\xa7\x3e\xf5\xe0\xc9\x93\x27\x8b\x3f\ +\x2f\x40\xfa\x7f\x5e\xe6\x3f\xf0\x81\x0f\xac\xf9\xcc\x67\x3e\xf3\ +\x48\x7f\x7f\xff\x9d\x26\x44\xe5\xdb\x1a\x3b\x31\x36\xa6\x1f\xfe\ +\xf0\x87\x7a\xe2\x07\x3f\xd0\xcb\x2f\xbf\xac\x01\x16\xf5\xce\x77\ +\xdc\xa3\xbb\x6e\xbf\x5d\xd7\xa1\xf5\x0c\xbe\x9d\xc4\x54\xd3\x6a\ +\x51\xaa\x43\x9c\x4b\x4a\x4a\x74\x88\x73\x71\xc6\x18\x6e\x11\xe7\ +\x5a\x6f\x32\xa5\x75\x1b\xd6\x69\x04\x06\x6b\x08\xb9\xb0\xb0\xa8\ +\x12\x02\x2f\xf2\x37\x6b\x4b\x4b\xf2\x55\xaa\x0a\x20\x98\x4a\xdd\ +\x55\xae\x84\x95\x81\x0f\x03\x03\x03\xbb\x6e\xb8\xe1\x86\xad\x58\ +\xc4\x63\xe7\xcf\x9f\xaf\xfe\xaa\x04\xe0\xbf\xf3\xce\x3b\x57\x7e\ +\xf6\xb3\x9f\xfd\x5f\xc4\xf5\x5b\x0d\x8a\x1b\xb3\x9f\xc3\x4c\x5f\ +\xda\x7f\x40\x8f\x3d\xbe\x57\xcf\x3e\xfb\xac\x5c\x7c\xfb\xbd\xbf\ +\xf7\x7b\xba\xe3\x8d\x6f\xd4\x20\xc0\x95\xc2\xa7\xd3\x4e\x87\xe9\ +\x0e\xb3\x0e\x0c\xc2\xa4\xa4\xa8\x31\xf1\x26\x24\x99\x11\xe2\x9c\ +\x19\xa1\x98\xbd\xc6\x79\xac\x22\x01\x26\x5c\xb7\x6e\xbd\xba\x01\ +\xc4\xfc\xf4\x94\xaa\x68\xba\x9c\xcb\xab\xba\xbc\x24\x87\xb5\x84\ +\x88\x1e\x0d\x9f\xa3\x3c\xc7\x19\x5c\x05\x21\x6c\x02\xa3\x36\xee\ +\xdb\xb7\xef\xbb\xe0\x52\xfd\x97\x15\x80\x8f\x30\xd7\xff\xd0\x43\ +\x0f\x7d\x85\x89\xef\x00\xc4\xac\xd9\x4f\x5d\xba\xa4\xe7\x9f\x7f\ +\x5e\xff\xf7\xb1\x47\x75\xe8\xe0\x41\xed\xda\xb1\x43\xff\xfc\xde\ +\x7b\xb5\xb2\xa7\x57\xe9\x0e\xe3\x57\x68\x38\x0a\x85\x61\x0c\xaf\ +\x57\x00\xc6\x02\x8c\xfe\xa6\x20\x46\xaf\x75\xec\x33\xc7\xf6\xba\ +\x21\x29\xc8\x18\x16\xe4\xf1\x9c\x5b\x07\x3b\x12\x1a\xc1\x22\xaa\ +\x33\x73\xaa\xb1\x86\x5a\x89\xd0\x4a\x44\xb1\x42\xf0\x33\x23\x96\ +\x96\x03\x8c\xbb\x00\x4a\x42\xe6\x26\xb2\xd0\x81\xef\x7f\xff\xfb\ +\x8f\xe3\x5a\xee\x3f\x56\x00\x0e\x79\x7b\xea\xe1\x87\x1f\xfe\xcf\ +\x6b\xd7\xae\xbd\x8f\x58\x6e\x32\x33\x4d\xc3\xfc\x8f\x9f\x7b\x4e\ +\x8f\xed\xdd\xab\xb3\xa7\x4f\xeb\xdd\xef\x7c\xa7\x6e\xdb\xbd\x47\ +\x5d\x80\x5a\x86\x85\x74\x18\x8f\x59\xa6\x61\xb6\xcd\xa4\x45\x7c\ +\x33\x1a\xbf\x6f\x42\x1c\x37\x6d\x24\x68\x8d\x6a\x9f\x77\xec\xbd\ +\x8c\x1d\xe1\x58\x30\x6c\x32\x59\xdd\x5a\xcf\xf0\x9a\x0d\x6a\x10\ +\x4e\xdd\x42\x8e\x30\x5a\x53\x3d\x57\x40\x08\x65\x2c\x21\x88\xa4\ +\x23\x2a\xd6\x6a\xd6\x1d\x58\xfb\x2e\x92\xb3\x65\x84\xb0\x5f\xcc\ +\xfe\x0b\x0b\x80\xb8\x1e\xf9\xc2\x17\xbe\x70\xef\x6d\xb7\xdd\xf6\ +\x5f\x00\x3c\x1f\xcc\x5b\xb3\x7f\xe1\xf9\x17\xb4\xf7\xf1\xc7\x75\ +\x11\xc4\xbf\xef\xf7\x7f\x5f\x1b\x09\x47\x5d\xf8\x62\x06\xcd\xe3\ +\xd7\x76\x91\x21\x18\x68\x69\xb5\xcd\x58\x9b\xa9\xa6\x65\x9a\xb1\ +\x7d\xac\xf6\xb1\xda\xc7\xba\xea\xd8\x8e\xac\xc3\x53\x20\x0d\x40\ +\x3a\x9e\x42\x45\xc9\x29\xd7\x35\xb4\xf6\x3a\x35\x96\xc1\x02\x37\ +\x27\xa7\xee\x22\x84\xa2\xfc\x60\x42\x08\xb0\x6d\x1a\x21\x10\x0d\ +\x07\x08\x95\xe4\x0b\xbf\x43\x8e\xf2\x14\x2e\x3a\x21\x66\xfc\x45\ +\x04\xe0\xa7\x80\xd9\xf4\x91\x8f\x7c\xe4\xaf\x40\xe0\xa4\xc9\xe8\ +\x96\x09\x73\x07\x0f\x1c\x40\xf3\x8f\xeb\x3c\x21\xce\x30\xbf\x66\ +\x60\x00\xcd\xfb\xd4\xed\xf7\x29\xe9\x39\xd6\x7f\x03\x2d\x2d\x42\ +\xad\x58\xaf\x0e\xa3\x57\x33\x79\x95\x15\xa8\x6d\x05\x96\x38\xee\ +\x8c\x1c\x28\x18\xa7\x2e\xe8\x8a\x28\x56\x73\xe5\xe5\x4c\xf4\x80\ +\x88\x40\xfd\x6b\x56\x03\x86\x17\xb9\xa7\x2a\xaf\x84\x80\x8a\x65\ +\xf9\x39\x1f\x8a\xc7\xd4\x20\xcc\xba\x92\x86\x56\xac\x08\x90\xa7\ +\xdc\x76\xe2\xc4\x89\x47\x00\xc6\xf2\xcf\x2d\x00\x24\xd7\xf5\xc5\ +\x2f\x7e\xf1\xb3\x84\xbb\x5b\x08\x2f\x36\xc1\x39\x41\x48\x7a\xfc\ +\x89\x27\x34\x06\xd2\xbf\xfb\x77\xef\xd1\xda\xa1\x15\xea\x86\xf9\ +\x54\x44\xea\x92\x8f\xe4\x25\x2e\x11\xbe\x3a\xcc\x59\x26\x1a\x10\ +\x82\x40\xcb\x57\x6a\xfe\xaa\x31\x68\xb4\xe6\xba\xc4\xf7\x11\xad\ +\xba\x79\x8f\xfa\xd6\xae\x55\x1f\xbe\xde\x47\xa8\xeb\xdf\xb8\x56\ +\xf1\x35\xbd\x0a\xf7\xf4\x6b\xd5\x75\x5b\xd4\xbf\xe1\x06\x0d\x6e\ +\xde\xac\x9e\xd1\x51\x2d\x9c\x1a\x57\xdf\x48\x9f\x16\x16\x27\x14\ +\xab\x53\x64\x95\x5d\x35\x89\x4e\x01\x39\x0a\xa6\x92\xaa\x01\x9e\ +\x41\x04\xd1\xc3\x07\x2b\xf0\xbe\xf7\xbd\xef\x3d\x2d\xa9\x71\x8d\ +\xa5\xeb\xda\x4f\xf0\x81\x07\x1e\x78\x13\x7e\xff\x1e\xc2\x9d\xcd\ +\xe3\xa7\x88\xc9\xa0\xaa\x8e\x1e\x79\x59\xb7\xec\xd9\xad\x75\xc3\ +\xc3\x4a\x4b\x84\x38\xc1\x78\x40\x41\x98\x1b\x20\x16\xa7\x07\xfb\ +\x5b\x0c\x37\x5a\xc4\xf1\x15\x82\xb8\x96\x12\x84\xcc\x55\x37\xed\ +\x91\x83\xfb\xa8\x69\xdc\xe4\xea\xcc\xc4\xf1\xd7\x55\x27\x19\x8a\ +\x45\xc3\xdc\x1f\x30\x67\x3a\xff\xc9\x2b\x57\x14\x4b\x74\x6b\x64\ +\xeb\xf5\x44\x08\xbf\xe2\xc2\x32\x4c\x74\xc0\x3a\x6b\x27\x4e\xca\ +\x9b\x5f\xd0\x0c\x19\x29\x25\xb7\xe0\xe5\x81\x0f\x7e\xf0\x83\x9b\ +\xcd\x04\x3f\x4b\x00\x0e\xda\xcf\x50\xca\xfe\x21\x26\x18\xb0\xf1\ +\x9e\xd4\x76\xec\xe8\x98\x8e\x1c\x3a\xa4\x34\xfe\x75\xeb\xce\x5d\ +\x4a\x35\x05\xd8\x11\xaf\xc3\x3e\x28\x24\xc7\x6d\x58\x06\x52\x83\ +\x43\x56\x83\xfc\x55\xc3\x34\x74\x25\xf3\x8d\xd6\xb1\x71\x11\x09\ +\x0d\xaf\xd3\x10\x89\x12\xcc\x9b\x73\x96\x3c\xa8\xf3\x8c\xb8\xbf\ +\xd1\x2c\x2b\x90\xea\x95\xcf\x0a\x51\x10\xff\xb3\xd7\x20\xc6\xfa\ +\x72\x4e\xab\x6f\xbc\x49\xc9\xe1\x5e\x25\x03\xb8\x20\xcf\x08\x57\ +\x75\x4f\x9f\x55\x1d\x41\xd4\xb3\x39\xcd\xce\xcc\xa8\xbb\xbb\x3b\ +\x7a\xeb\xad\xb7\xfe\x91\xa4\xf0\xcf\x12\x40\xe0\x43\x1f\xfa\xd0\ +\x1b\x30\x99\xdb\x0d\xf3\xb5\x72\x19\xb0\x9b\xd0\x91\xc3\x87\x34\ +\x4b\x4e\xff\x4f\xde\x7c\x87\x92\x86\x51\x28\x0e\x85\x78\x9a\xe5\ +\x4b\x56\xe3\xae\x65\x32\x92\x4c\x6a\x68\xcb\x66\x05\x11\x56\xc7\ +\x0a\x3a\xcc\x73\xc0\xf9\x80\x86\x77\x6e\x53\x7a\x68\xa8\xe3\x16\ +\x1d\x21\x5d\x1e\xbd\xf6\x33\x35\xaf\xa6\x68\xba\x5b\xf8\xc8\x35\ +\x56\x64\x05\x56\xab\x2a\x46\x6a\xdd\x7b\xfd\x76\xd2\xeb\x16\x77\ +\x81\x5a\x5d\x4d\xc0\xba\x81\x00\x3c\xb2\xc8\x02\x0a\x34\x25\xf8\ +\xca\x95\x2b\xdf\x73\xdf\x7d\xf7\x6d\x90\xe4\xfc\x54\x01\x50\x8b\ +\x27\xdf\xf6\xb6\xb7\xdd\x4f\x1d\xef\x33\x0f\xe5\xc9\xc0\xc6\x4f\ +\x9e\xd0\x19\xd2\xdb\x35\xc3\x2b\xb5\xb2\x3b\xa3\x64\x87\x79\x16\ +\xe4\x73\x01\xa6\x96\x6a\x34\x73\xfc\x24\x7e\x58\xb1\x4c\x53\xda\ +\xe2\xab\xa4\xc0\x7d\xbd\x57\xb9\x43\x72\x20\xad\xe4\x86\x21\x85\ +\x13\x21\xfb\xbd\x01\x68\x4d\x1d\x79\x45\x2e\xc2\xbe\xc6\x6d\x9a\ +\x8c\x12\xf7\xa6\x25\xe6\x6b\xaa\x7e\xf9\x9a\xd7\x06\x53\x5f\x90\ +\x68\x43\xe1\xd4\xbd\x79\xbb\xc2\x71\x8a\x29\x2c\x2f\x64\xc2\x2d\ +\xb9\x81\x26\xa7\xe4\x52\x8c\x09\x25\x2e\x92\x3d\xd2\xa3\x08\xdd\ +\x7e\xfb\xed\x1f\x35\x6c\xfe\x14\x01\xd8\xa4\x67\xd5\xf0\xf0\xf0\ +\x9b\x6d\xd3\x02\x9a\x45\x92\xe3\xc7\x8f\x2b\x37\x33\xab\x3d\xdb\ +\xb7\x2b\xe1\xb5\x98\x0f\x7b\x6d\x34\xae\xd4\x44\x1b\x0b\x33\x6e\ +\xa8\x92\x5d\xd6\xa5\x23\x47\x54\x5e\x5a\x6a\x23\xbb\xd4\x43\xde\ +\xde\x0b\x36\x38\x8e\x0f\xd7\x58\xad\xae\xf5\x83\x72\x9d\x96\x36\ +\x2b\xa4\xd2\xe7\x5f\x78\x41\x59\xf2\x8a\x2b\x35\xeb\x59\x17\x60\ +\x6c\x0b\xc3\x4f\x7c\x0f\xf6\xad\x92\x17\xc8\x09\x6e\x38\x57\x63\ +\xee\x9a\x82\x31\x4f\x91\x95\x09\xa5\x46\x37\x2a\x3e\x30\xc2\xf7\ +\xa0\x65\xc6\x2f\x59\xc5\x80\x8e\x6a\x5e\xbc\x64\xb1\xa0\x8a\x40\ +\x5c\xce\x01\xea\xef\x06\x13\xd3\x3f\x4d\x00\xa1\xfb\xef\xbf\xff\ +\x1e\xc2\x5e\xcc\xdc\x5c\x06\xfd\x2f\x9e\x3b\xa7\x4b\x50\x17\x68\ +\xba\xb2\xaf\xcf\x32\x1f\x31\xc9\x89\xf5\x41\x34\x58\xc2\x02\xaa\ +\x2c\xca\x6f\x17\x6b\x35\x39\x05\x5e\x2c\x9d\xbf\x60\x90\xdd\x32\ +\x11\x27\x3d\x1d\xdd\xbd\x4b\xc9\x15\x5d\x2a\xe3\xef\x31\xc2\xd4\ +\xf2\xc4\xa4\x2e\xec\xdb\xaf\x6a\xbe\xd0\x36\xfd\x46\x27\x62\x40\ +\xae\x25\xbe\x5b\x6c\xa9\x15\x73\xea\x1e\xdd\x2c\x67\x78\xbd\x6a\ +\xf1\xaa\xea\xe1\x05\x79\xf1\xac\xba\x6e\x5a\xa3\xfe\x37\xbf\x13\ +\xdc\x59\x05\x58\xc2\x38\x40\xe9\x48\x90\xcd\x2a\xad\xe6\x1d\x98\ +\xaf\x9d\x3f\x2f\x1f\xf3\x93\xbe\x1b\x2b\xe8\xff\xd8\xc7\x3e\xf6\ +\x96\x2b\xf9\x0e\x74\x0e\x4c\xbc\x5f\xb7\x6e\xdd\x3f\xb5\xfd\x3a\ +\xc8\x80\xdf\xc4\xd9\x73\xca\xcf\xcd\x69\x23\x05\x89\x61\x3e\x6a\ +\xd2\x52\x99\x2c\xcd\x11\xff\xc1\xb0\xf1\x39\x4f\x35\xbf\x83\x96\ +\x1b\x62\xdd\x36\x7e\x2f\xf2\x5c\x79\x69\x59\x7d\xeb\xd6\xca\x47\ +\x8d\x2f\x01\x58\x2a\x29\xda\xb7\x5a\x0b\x2f\x3d\xa5\xec\x89\x39\ +\xee\xbd\x3a\x3a\x74\xa2\x87\xeb\x95\xe4\x73\x4c\x1e\x11\x56\x80\ +\x46\x49\x61\xfa\xac\x62\x3d\x03\xea\xb9\xee\x06\x35\x86\xd7\xa9\ +\x5e\x29\xda\x7b\xd3\x3c\xeb\x0f\x84\x54\x2f\xcd\x6b\xf9\xcc\x01\ +\xf9\x38\xbe\xaa\xbc\x75\x11\x22\x19\x63\x63\x72\x52\x3e\x5c\xb3\ +\x1a\x29\x8b\x2e\xb4\x46\x46\x46\xee\x91\xf4\xb7\x50\xf5\x4a\x01\ +\xf8\xe8\xeb\xf5\x51\xec\x6c\x43\x00\xb6\x46\x5f\x9a\x9f\xd7\x0c\ +\xc0\xe7\x15\x8a\x1a\x1d\x18\x84\x79\x4f\xe0\x7d\x0b\xf4\xd4\x12\ +\x00\xa7\x14\x2a\x4b\x95\x4c\x42\x3d\x23\x61\x92\x91\x90\xb8\x6c\ +\x85\x20\xa8\x00\x08\x25\xfa\xfb\x59\x5c\x55\x0d\xe2\x7d\x94\x92\ +\x36\x68\xd2\x65\xaa\x44\x0b\x1d\xed\x4c\x11\x8b\x69\x9b\xbd\xcb\ +\xbc\xf4\x06\xca\x05\x25\x82\x43\x6a\x54\x29\x74\x66\x2f\xa8\xd0\ +\x33\xc8\x3c\x2b\x69\x93\x05\x99\x2b\x6d\x05\x40\x6f\x0d\x21\x56\ +\x55\xbc\xf4\x8c\xca\xf3\x17\x98\x2c\x70\x75\xaa\x67\xc0\xb5\x84\ +\x30\x97\xb3\xaa\xd3\x91\x0a\x66\xba\x2c\x18\x92\x22\xdf\x2a\x29\ +\x7e\x8d\x00\xde\xf7\xbe\xf7\xed\xa4\xe7\x96\x32\x75\x7e\x1d\xbf\ +\x5e\x64\xf1\xb9\xf9\x39\x85\x78\xa8\x2f\x95\xb4\xa6\x1f\xb8\x42\ +\xfb\x12\xa3\x44\x4e\x8e\x65\xf4\xd3\xcc\x1c\x1a\x54\xaa\xe6\x80\ +\xcc\x2d\x21\x48\x56\x10\x2d\xcd\x3a\x15\x85\x32\xd7\x59\xbb\x4b\ +\x76\xf7\x90\xae\x26\x61\xfc\xef\x05\xb5\x6c\x05\xd0\x10\x12\xc0\ +\xd7\xc1\x1f\xa7\x2e\xa9\xc6\x5c\x01\x42\x20\x45\xce\xd8\x8f\xd1\ +\xf4\x0d\x4a\xaf\x24\xc4\xca\x69\x27\x57\x2e\x65\xf2\x69\x15\x27\ +\x9e\x43\x18\x01\x6b\x8d\x57\x49\x80\x63\x38\x96\x43\x16\x5b\xa3\ +\x3f\x11\xdb\xb8\xd1\xe2\x55\x32\x99\x1c\x7d\xef\x7b\xdf\xbb\x96\ +\x56\xda\x92\xb9\xab\xe3\x0b\xc1\xcd\x9b\x37\xef\x68\x58\xe0\xf1\ +\x6c\x03\x73\x79\x76\x4e\x55\xe2\x68\x8c\xef\x69\x90\x36\xc8\x1f\ +\xf5\x75\x90\xda\x35\xe4\x5a\x72\x2b\x1c\x67\xb3\x30\x38\x48\xd2\ +\xe2\x5a\xc1\xe2\xfb\x68\xc7\xf8\xb1\xa1\xba\xdc\x26\x85\x4c\x77\ +\x9f\xd5\x78\xc7\xd4\xbd\xcb\x73\xb9\x1d\x74\x87\x60\x3c\x88\x30\ +\x09\x7d\xcc\x63\xae\x63\x05\x7e\xf9\xf2\x21\x95\x4f\x1d\xd0\xc2\ +\xab\x87\x39\xc7\xf9\xa6\xc1\x9e\x25\x15\xce\x3f\xa6\xc2\x1c\xbd\ +\x01\x04\x5f\xcf\x5f\x5b\xf9\xda\x39\xc1\x19\x17\x6b\x0e\x4a\x82\ +\x3f\xdb\x7e\xa7\x48\xba\xd1\x28\xfd\x4a\x0b\x08\x63\x1a\xd7\x99\ +\xf0\x02\x59\xd4\x2c\x90\x50\x08\x41\x24\xda\xa5\x6c\x80\xf3\x72\ +\x98\x54\x90\x73\xd9\xd3\x6c\xde\xdf\x58\x32\xa5\xe9\x9c\xa2\x83\ +\x6b\x94\x3d\xf4\x8c\x2a\x97\x6a\x1d\x3c\xb0\xc5\x4c\x78\x75\x4c\ +\x99\x70\x54\x24\x16\x5a\x9a\x9c\xe0\xba\x07\xe3\xcd\xcb\xe9\xb0\ +\x5b\xad\xd1\xe8\x98\x57\xe0\x62\x45\xd1\xeb\xd7\x60\xe6\x61\x2d\ +\x1e\x3b\xa2\xca\x82\x1f\x86\x5b\xf7\xf8\xfc\x35\x85\xce\x9d\x56\ +\xa3\x56\x51\xd7\xaa\xf5\x98\xfe\xb3\xaa\xcc\x8f\xa9\xb4\x80\x5b\ +\x16\xa5\x7a\xe1\xda\xfe\x07\xcc\xd8\xf4\x98\x57\x4e\x56\x79\x00\ +\x9d\x3d\x0d\x18\xae\x6f\x0b\xa0\x61\x05\x40\xba\x18\xe5\xe4\x68\ +\x5b\x00\x36\x01\x2a\xe7\x73\xf2\xd7\xea\xb6\x3b\x13\x70\xeb\x98\ +\x62\xf8\x1f\x2c\xa8\x3c\xa8\x56\xc0\xdf\x27\x4e\xab\x67\xe3\x0e\ +\xe5\x87\x46\xc9\xc2\x9e\x57\x79\xc1\x33\x8b\x87\x19\x68\x68\xc0\ +\x40\x33\xa1\x2a\x8e\x35\xc0\x2c\x9d\xe2\x46\xa5\x53\x00\x59\x37\ +\xc1\xda\x96\x54\xca\xe4\x94\x19\xb8\x9d\x67\x69\xa2\x5e\xbc\xa0\ +\xfc\xc5\xc6\x55\x40\x19\x8c\x73\x5f\xed\xbb\xf2\x6e\xbd\x59\x95\ +\xc9\xa7\x54\x5e\xac\xa9\x59\x8c\xaa\x3c\x57\x27\xa7\xa8\xf2\xb7\ +\xac\x17\x5d\xbd\x4c\x5c\x5a\x46\x08\xf4\x26\xa9\x8c\xac\x52\x00\ +\xc3\x75\x6d\xe5\xd7\x6d\x82\xcd\xc9\x08\xfe\xdf\xdd\xa9\xc4\xea\ +\xa0\xa6\xcb\x03\x41\xd3\x91\x09\x88\x73\x39\x72\x11\x34\x68\x7c\ +\xfc\x27\xd2\x69\x66\xc4\x4c\x9b\xf4\xec\x12\xe4\xe7\x45\x0d\x6c\ +\xd8\xae\xd2\xf8\x51\x98\x58\xb4\x02\x18\xde\xb3\x4b\x4e\xb7\x2b\ +\x07\x21\x86\x58\x40\x64\xc5\x88\x4a\xaf\xce\x6a\x74\xcf\x1b\x25\ +\xaf\x85\x01\x67\x9e\x79\x56\x7e\xea\xfd\x08\x7d\xbe\xee\x61\x22\ +\x45\x31\xcf\xf5\x9b\x55\xdf\x1c\x63\x0e\x33\x7f\x15\x4d\x2f\x68\ +\xe1\xf4\xb8\x8a\x67\xa6\x34\xe1\xfe\x9d\x32\x83\x39\x84\x44\xb4\ +\x28\x86\x55\x99\xcb\x2b\x10\xa9\xcb\x09\xb3\xf6\x25\x3f\x56\x72\ +\x79\x6d\xd6\x0d\x7d\x75\x97\x90\x5d\xc4\x00\xfa\xad\x1b\xc0\x6b\ +\x7f\xc7\xfa\x2f\x63\x00\xbe\x11\x45\x00\xd6\x02\xdc\x3a\x92\x05\ +\x40\xa8\xeb\x61\xcc\x91\x8b\xf9\x05\x42\x36\x5e\x5f\x4d\xae\x6b\ +\x47\xaf\x8e\x58\x08\x87\x15\x6a\xf4\x10\x5a\x0e\x0f\x0e\x81\xd8\ +\xd6\xcf\x6d\xb8\x13\x0c\xd4\x8b\x59\xeb\x42\x19\xac\x24\x3c\x14\ +\x15\x27\x3b\x58\x80\xe6\x5c\xc5\x46\x42\xea\xd9\x76\x8b\xfc\xa1\ +\x20\xf3\x56\xed\x73\x16\x6b\xcc\x75\x4c\x37\xde\xdf\xa7\x91\x9b\ +\x6e\x26\x5b\xcd\xc0\x64\x5e\xf9\x19\xae\xe5\xfd\x58\x4e\x90\x28\ +\xb0\x48\x32\x86\x9b\x76\xb9\x8a\x64\x58\xcb\x95\x3a\x6a\x97\xe6\ +\x5e\x0d\x1e\x02\x81\x4e\xc8\x8f\x9b\xe1\x2a\x01\x70\x32\x72\xb9\ +\x16\x77\x5b\x80\x17\x96\x14\x89\xf9\x31\xdd\x28\x8b\xd4\x15\x49\ +\xcb\xb5\x82\xf0\x4c\x49\x5a\x5a\xb6\xb1\x21\xdc\x3d\x80\x46\xdb\ +\x80\xe7\x1a\xe1\x34\x31\xfb\x49\xc1\x15\x89\xcb\x0a\x65\x76\xdd\ +\x22\x5f\x2c\xcb\x12\x4a\x24\x31\x45\x25\x56\x39\xca\xec\xbe\x55\ +\x99\xd5\x6b\xdb\x00\x57\x62\xc1\xb8\xa3\x4d\xa6\xda\x64\xc1\xd2\ +\x53\xff\xa6\x75\xd6\x2a\x4a\x53\x92\x9b\x8d\x20\xd8\xba\xaa\x26\ +\xde\x57\x1d\x18\xa4\x14\xee\x62\xed\xc1\xab\x2c\x14\x62\xe4\x79\ +\x9a\xa8\x1d\x01\xc4\x7e\x12\x04\x1d\x4c\xc3\xf1\x0c\x83\xf6\x4a\ +\xd3\x5e\x08\x3a\x52\x18\xb2\xe8\x0f\x98\xd9\x30\xe5\x75\x26\xbe\ +\x3a\xe6\x34\xeb\x46\xca\x06\xa1\xeb\x36\x7d\xc5\x96\xda\xd6\x01\ +\x92\x97\x7d\xf2\xa6\xcf\xab\xb1\x9a\x50\x18\x0a\xab\xff\x86\xdd\ +\xca\x12\x59\x34\x77\xc6\x3c\x49\x65\x78\x17\xf8\xb1\x0d\x2d\x8a\ +\x79\xd0\x7e\x39\xaf\x06\x02\x38\xfd\xa3\xa7\x2c\xd3\xe1\x78\x5c\ +\x83\x37\x5c\x8f\x55\x31\xab\x93\xc5\x22\x82\x6a\xe4\x04\x78\x86\ +\x55\x26\x5a\x79\xf8\x39\x38\x06\xcc\x98\x05\x7b\xf8\x7a\x93\xe7\ +\x9d\x2b\x85\x60\xad\x08\x2b\xef\x84\xe7\x4e\xd2\xd8\x11\x00\x42\ +\xe7\xc3\x85\x76\x3b\xcc\x4f\xa3\x11\x62\x45\x7e\x18\xf0\xe1\x54\ +\x75\xb7\x80\xb6\x42\x52\xbd\x3d\xe7\x55\x42\x68\xb6\x42\x98\x5a\ +\x3e\xe7\x96\x0b\xb8\x90\x09\x93\x56\x8b\x00\x1e\x52\x07\x89\x0b\ +\x53\x17\x94\x1a\x59\x85\x80\x7c\xea\xdd\xb8\x55\x8d\x35\x68\x5c\ +\x20\xbc\x31\x7b\xeb\xaf\x35\x35\x8c\xf6\x4b\x05\xc6\x20\xb1\xbf\ +\x64\x05\x50\xcb\x17\x48\x84\x7a\x94\x59\x13\xa3\x29\x7b\x09\x2c\ +\xc1\xdd\x96\x22\xcc\x5b\x47\x00\xb3\xed\x90\x07\xb9\x0e\x2e\xd4\ +\xb4\x02\xa8\xe6\x6c\xc8\xb2\x82\x11\x14\x08\x87\x6d\xe9\xcd\x77\ +\x53\x17\x94\x0c\xcf\x57\xba\x80\x0b\xff\x95\x8e\x00\x02\xc1\x80\ +\xc2\xc1\x90\x15\x40\xb3\xcc\x12\x17\xa7\xd4\xe0\x38\x94\x34\x3c\ +\xa3\xd5\x2b\xfc\x1f\xe2\x24\xa3\x9f\x3e\x7d\x2c\x69\x05\x51\x5b\ +\x9c\x36\xa6\xd9\xbe\xee\xb6\xcc\xb9\xe8\xd3\xd2\xf1\x83\x68\xc6\ +\x30\x55\x13\x92\xc4\x4d\x70\x2f\x88\x63\x90\xd8\x16\x39\x30\x4b\ +\x31\x55\x2a\xa3\xd5\xcb\xee\x86\xe6\xfd\xa4\xc3\x21\x55\xaa\x13\ +\xe4\x13\x45\x04\xd0\x24\x22\x04\x40\xff\x29\xee\xab\xb5\x75\xd0\ +\xae\x03\x1c\xc1\x2c\x7e\xcf\xd8\xd6\x26\x6b\xf3\x29\x9c\x4c\x5e\ +\x16\x00\xd6\x5e\x96\xe4\x5d\x69\x01\x55\x8a\x85\x2c\x17\xe4\xf0\ +\x2f\x88\xb4\xa2\xd4\xf3\x05\x53\x86\x56\x1c\x55\x2f\x4d\x2a\x0a\ +\x6a\xbb\x4b\x53\x0a\xa7\x43\xaa\x2e\xb9\x1d\xe5\x63\x15\x14\x48\ +\x5d\x52\x33\x19\x55\xbc\xb7\x4f\x75\xb4\x5f\x9e\xba\x88\x00\x0c\ +\x00\x36\x21\xd7\x2c\x02\x01\x38\x2a\x2d\x9e\x52\x61\xc3\x46\xac\ +\x60\xd4\x6a\x85\xa7\xda\xeb\x68\xf9\x37\x44\xec\x9f\x46\x0e\x4d\ +\x0b\x82\xa3\xb7\xdc\x6c\x05\x10\x8c\xfa\x15\x88\xcf\xca\xf5\x16\ +\x50\x42\x59\x71\x94\x51\x9e\xe1\x38\x32\xaf\x6a\x10\x86\xea\x6a\ +\x15\x44\x30\x6e\x4a\x82\x9a\x8d\x6d\x86\xe0\x06\x1e\x3c\x53\x84\ +\x51\x94\x75\xde\x99\xa1\xec\x79\x06\xb7\x63\x01\x4d\x88\x28\xb3\ +\x30\xe9\xb5\x93\x9d\x40\x84\xbc\x9d\xc2\x21\x84\x69\xca\x63\xc2\ +\x19\xfa\x82\x17\x4f\x29\xb3\x69\xbb\xe2\x1b\x57\x28\x71\x5d\x58\ +\xb1\x15\x94\xc6\x2b\xa5\xd4\xfa\xa8\xd2\x3b\x37\x72\x6d\x27\x9a\ +\x0a\xa8\x34\x37\xad\xda\xec\x02\xe6\xd9\xd2\x1e\x02\x80\x18\xb1\ +\x82\xf2\xa5\xa2\x96\x8e\x1e\xe0\xb8\x24\x54\x67\x1b\x9a\x6a\x6b\ +\xbe\x69\xc8\xa5\x09\x33\x8f\xb5\x95\x1c\x2e\x5b\xf4\xc7\xa4\x03\ +\x54\x7a\xa4\xb3\xd5\x29\x3a\x3f\xe4\x23\x7c\x0f\xc5\x68\x84\xa4\ +\x27\x94\x1c\xad\xaa\x6b\x6d\x43\xd1\x6e\x62\xfb\x30\x58\x91\xa0\ +\x44\x4e\x19\x16\x3a\xd6\x60\x5c\x22\x24\x7f\x3c\x81\xe2\xd2\xea\ +\x58\x38\xca\x3e\xcb\xe0\x5e\x69\x01\x15\x5e\x37\x5f\x68\xa7\x8a\ +\x56\x00\x71\x3a\x2d\x61\x80\xca\x71\x72\xaa\x2e\x37\x95\x3b\xfa\ +\x8a\x86\x6e\xbc\x59\xdd\xeb\x37\xca\xb9\x7e\x37\xfe\x99\x67\x81\ +\xb8\x45\x22\x69\xcd\x2b\xc4\xbd\x1e\x0c\x94\x2e\x9e\xc5\x05\x4c\ +\x62\xd2\xb0\x21\xc8\x46\x08\x00\x94\x0f\x7e\x4b\x59\xfa\xea\xb8\ +\x4a\x37\x6c\x53\x6a\x68\x58\xb0\x29\x62\x94\x05\x4e\xdb\xe2\x22\ +\x6f\xaf\x13\x4a\xdd\x52\xc8\x0a\x8e\x05\x83\x17\x75\xc6\x59\xc5\ +\x7a\xa9\x27\xd2\x31\xd6\xd3\x24\xaf\x99\x50\x62\x10\x54\xc7\xdf\ +\xb3\xb1\xba\x92\x83\x8e\x55\x54\xac\xdf\xa3\x36\xc1\xcc\xc9\xf0\ +\xf9\x87\xc9\x1b\xcb\x89\xcb\x47\x63\xc6\x6f\x92\x20\xe6\xe7\x63\ +\x36\x5b\x9c\x66\x68\x5c\x89\x01\xb5\x31\x3e\x6e\xfb\x8f\xfa\x90\ +\x5a\x82\xfa\x3f\xc2\xc3\x4c\x62\x4d\xac\x7c\x3e\xaf\xe9\xe7\x7f\ +\x04\x43\x25\xf9\x9d\x0a\x85\xc9\x08\x4c\x0c\x21\x71\xee\x71\x6c\ +\x1e\x4f\x3c\x9e\x21\xef\x9e\xc5\x8f\x6d\x28\x6d\xbd\xf4\xb4\x16\ +\x00\xd5\x4d\xdd\x40\x9a\x3d\x57\x50\x69\xf2\x02\xf7\x57\xed\x33\ +\x1e\xd4\x74\x49\x9d\x99\xb7\x78\xe1\x04\xe8\x5e\x36\xf7\xd9\x6e\ +\xd1\xf9\x67\x9f\xd3\xf4\xb1\x1f\xab\xb4\x7c\x46\xd1\x01\x3f\x16\ +\x66\xc2\xd5\x8c\x22\xe9\xb8\x42\xa9\xa8\x62\x03\x41\xf5\x6d\x75\ +\xd4\xb3\xc9\x53\xcf\x96\x06\x02\x90\x4d\xd6\x1c\xd7\x47\x04\xf3\ +\xb5\x36\x5c\xa0\x9c\x38\x1d\x67\xe1\x0a\x9d\x4c\xf7\xa5\x97\x5e\ +\x3a\x72\x0d\x08\x3e\xf9\xe4\x93\x87\x79\x97\x56\x32\x37\x38\x94\ +\x9d\x71\x04\x10\xc5\x0a\x8c\x09\x35\x25\xea\x7b\x29\x77\xf8\xa8\ +\xe6\xc7\x0e\x61\xde\x79\x62\xef\x84\x8d\xd9\x96\xbc\x9a\x05\xb7\ +\xfc\xe9\x63\xc4\xe6\x26\xd7\x3d\xcb\x7c\xc7\x05\x3a\x84\x50\xb8\ +\x86\x20\xb0\x1e\x98\xb7\x66\xcf\x09\xc2\x24\xf5\xc1\xf4\x5e\xcd\ +\xef\x7f\xc2\x6a\xd0\xab\x59\x90\x45\x08\x15\x18\x68\xd0\xf1\x09\ +\x71\xef\x12\xe7\x2f\xe2\xe7\x30\x97\x48\x51\x7c\xf5\x70\x2d\x4e\ +\xe1\x14\xa2\x90\xf1\x81\xfc\xed\x30\x58\x43\xf7\x35\xbf\x22\x4e\ +\x00\x1c\x8b\xc9\x0b\x85\x08\xbb\xf4\x12\x4c\x94\x81\x30\xff\x69\ +\xb6\x1b\x9d\xfc\x49\x10\xf4\xf8\x5c\x64\x33\xc3\xab\xd4\x04\xdb\ +\x48\x15\x49\x66\x32\x4a\x50\xe2\xe6\xe9\xa8\xd8\x5c\xda\xe5\xe1\ +\x0b\x35\xcd\x3d\xff\x14\xdd\x9d\x21\xc5\xfa\xfa\x55\x5d\x30\x66\ +\x69\xea\xfd\x10\xe0\x35\xa7\x3a\x55\x57\x2d\x17\x31\xcc\xb6\xa3\ +\x83\xc9\x0f\x60\x1e\x57\x41\x8a\x9c\x73\xad\xc9\xe3\x9b\x30\x58\ +\x80\xa1\x79\x79\x95\x33\xb8\xd8\x51\xac\x62\x99\xe2\x86\x34\x35\ +\xe0\xb4\xdc\x47\x02\xe9\x23\x58\x98\x41\xf5\x79\x70\x61\x49\xa1\ +\xae\x1e\x1a\x17\x71\x14\x94\xa0\x59\x02\x40\xc3\xa4\x70\x51\xb1\ +\x36\x61\x31\x6e\x1d\xed\x57\xc0\x8c\x0a\xd1\x05\x73\xf1\x27\x53\ +\xaa\x74\xa5\x71\xdb\xf5\xca\xb6\x37\x66\xcd\xcf\xcf\x1f\x94\x94\ +\xfd\xc9\x96\x58\x13\x9a\xc7\x0b\x9e\x05\x21\xad\x99\xf8\x31\x9d\ +\xf4\x9a\x35\x0a\xa6\x52\xed\xa6\xa4\xd0\x9c\xa3\xfc\x49\x1a\x25\ +\xfb\x9e\x46\x71\x86\x81\x32\x42\xb8\x00\xd3\x33\xaa\x2d\x2f\x81\ +\x65\xa1\xab\xc2\x97\x07\xb5\xcd\x1f\x42\xe3\x6a\xa0\x41\x97\x89\ +\x2e\xaa\x3a\xbf\x17\xac\xd8\x8b\xc6\x8f\x32\x4f\x56\x45\x84\x0b\ +\xd6\xd8\x8c\xce\x41\x60\xe4\x06\x3c\x5f\x67\xfe\xf3\xcc\x3b\x4b\ +\x68\x0e\xc2\x78\x44\x0e\xc2\xf6\x05\xad\x10\xf0\xeb\x2e\xe6\x8b\ +\xf3\xbd\xdd\xaa\xc9\xe1\xf7\x65\x42\x78\x1d\xed\x93\x70\x05\x33\ +\x19\xa5\xae\xdf\x2a\x5f\x3c\x66\x9b\x21\xa6\xd7\xc1\xde\x81\xc7\ +\x84\x4a\xff\xa1\x9e\x60\xe9\x3b\xdf\xf9\xce\xf7\x30\x91\xaa\xc1\ +\x02\x87\x50\x18\xe7\x0d\x4c\x64\x90\xb4\x36\x16\xb5\x21\x05\xb9\ +\x80\xf2\xd2\xf2\xe1\x63\x5a\x3a\x31\x66\x72\x76\xa8\x26\x37\x3f\ +\xa7\xe5\xb1\x7d\x2a\x4d\x2f\xb0\xc0\xa0\x01\x1c\x8b\x1d\x3c\x70\ +\xd9\xfc\x1b\x90\xcf\xef\xa2\x4d\x63\xf6\x27\x08\xaf\x17\x44\xc5\ +\xc5\xb1\xc9\x14\x49\x6d\x67\xc8\xeb\x0b\x71\xc1\x91\x15\x58\x85\ +\x0c\xaf\x1b\x8c\x49\xf6\x0d\x12\x96\xbb\x15\x80\xe9\x96\x19\xc9\ +\xb6\xcd\x85\xf6\x1d\x5f\x08\x0e\x18\x9b\x30\x8e\xe9\x8b\x42\xc8\ +\x57\xc0\xfc\x3d\x08\xe4\x5f\x0e\xfa\xb4\xfa\xce\x3b\x55\x67\x1d\ +\xed\x0d\x1d\xcb\xff\xf3\xab\x5f\x7d\x54\x92\x7b\x4d\x4f\x50\x2c\ +\x85\xed\x25\x63\x48\xe8\x50\x3c\x1e\xbf\x85\x92\x51\x41\xd0\x33\ +\x45\x27\x25\x4b\x77\x55\x24\x27\xcc\x62\x2b\xad\xdc\xb9\x3a\xfe\ +\xba\x4f\x09\x5c\x21\x94\x4e\x09\x75\x63\xa2\x05\x15\xcf\x03\x82\ +\xe5\x59\xe5\xa7\xd1\x98\x79\x3e\x81\x76\x22\x61\xae\xdb\x82\x04\ +\x90\x42\x33\x69\xa8\x2f\x20\xc0\xc5\x76\x8b\xb9\x04\xb3\x2e\x89\ +\x48\x85\x50\x9b\x27\xf5\xbe\x84\x15\xd4\x5a\xcf\xf8\x4d\x76\x88\ +\x40\x8a\x97\x6b\x14\xdc\xa3\x6c\xdd\x11\x0d\xb5\xdc\xac\x0e\x55\ +\xb8\x37\x8f\xd5\x2c\x04\x14\xc8\x13\x26\x11\x8c\x47\xdc\x0f\x6c\ +\xda\xa0\x24\x2f\x6f\xe7\x0a\x79\xdb\x0d\x62\xd3\xc4\xe3\xf9\x62\ +\x71\xca\x4a\xf2\x5a\x01\xd8\x93\xb3\x7b\xf7\xee\x7d\x84\xf6\xb8\ +\xd9\xdc\xe8\x04\x89\x02\x49\x04\x50\xe4\xbd\xa0\x72\x79\x28\x67\ +\xb5\x5a\x2b\x38\xca\x9d\x9e\xd7\x12\xe7\xfb\xf7\xec\x84\x11\x59\ +\x8d\x37\x1d\x17\x01\xd5\x29\x54\xa6\x68\x5e\x56\x6c\x1c\x0f\x63\ +\xce\x84\x22\x50\x1b\xad\x24\x73\x8a\x0f\x61\x5d\x32\x61\xcf\xb1\ +\x59\x9c\xc7\xc2\xb2\x2f\x5f\xd2\xfc\xcb\x0d\x30\xc6\xa7\x64\x66\ +\xb0\x53\x9e\xd8\x66\x4b\xad\x14\xc6\x5d\x7c\x8a\x90\x03\x78\x80\ +\x26\x21\x02\xa1\x76\xf3\xf7\x10\x08\x2e\xa8\xb2\xd1\x08\xb8\x32\ +\x8b\xf6\x97\x30\xff\x32\x18\x80\xdb\x9e\x25\xc3\xdc\xf0\xcf\xde\ +\xad\xba\xcf\xe9\xec\x55\x74\xbf\xff\xdd\xef\x7e\x05\x26\x4b\xe2\ +\x73\x8d\x00\x3a\x49\xd2\xfe\xfd\xfb\x1f\xc7\x0a\x5e\xd9\xbe\x7d\ +\xfb\x36\xfa\x67\x0a\x00\x84\x5d\xbb\x76\x69\x79\x0e\xf3\x86\xa9\ +\x26\xa4\x86\x30\x59\x72\x83\x53\xa7\xd4\xbd\x69\x2d\x0c\x46\xf0\ +\xd7\x12\x3d\xfe\x57\xb4\x34\x0e\x63\x2d\x03\xb3\xa6\x7f\xfe\x99\ +\xe7\x8c\x55\xab\x7b\xa3\xc7\xcb\x4d\x97\x4c\x2e\x88\xb5\xa0\x79\ +\x00\x8b\x66\x08\x02\x80\xc9\x2c\xe9\x33\x9a\xf3\xc8\x00\x27\x5e\ +\xdc\x7f\xe5\x0e\x26\xee\x97\x46\x76\x01\x8e\xfd\x54\x99\x7d\x30\ +\x69\xe6\x75\x0a\x08\x1d\xa0\x2d\x92\x3c\x65\x6b\xf2\x2f\x32\xd7\ +\x14\x82\xce\x05\x01\xbf\xa8\xf2\x7d\xdd\x8a\xdc\xb2\x5b\x29\xc0\ +\x6f\x1e\xed\x9b\x8d\x1d\x67\x4e\x9f\x7e\xe2\x99\xa7\x9e\x3a\x20\ +\x56\xff\x53\xdf\x0e\x77\xb2\x42\x5e\x8b\xf9\xb6\x6c\xd9\xf2\x16\ +\x3a\xc5\x8e\x49\x8a\x82\x50\x9d\xee\x6a\x93\x56\xb7\x8c\x00\x6c\ +\xda\xea\x90\xa2\xd6\xd0\x68\x17\x3e\x38\x21\x77\xf9\x15\xb0\xa0\ +\x2c\x8c\x11\x80\x74\xac\x69\x63\xe1\x24\x55\x52\x7a\xb5\xa7\xde\ +\x55\xae\x7a\x77\x05\x40\x72\x98\x08\xf9\xb0\x0e\x23\x00\x21\x08\ +\xfc\xff\xac\xa7\xec\xb4\x0f\x30\x75\xae\x69\x3a\xe1\x5d\x60\x90\ +\xa3\x44\xcc\x53\xa8\xa7\xfd\x72\xd4\xb6\xa1\x58\xc3\x32\xda\x9f\ +\x02\x57\x26\xb9\xe7\x22\x20\x59\x00\x24\xfb\x07\x75\xaa\x2f\xa5\ +\x1d\x0f\xfe\xa1\x6a\x91\x90\x49\x7a\x44\x92\x57\xfb\xc6\x23\x8f\ +\x3c\x38\x7e\xf6\xec\x31\x33\xe5\xcf\x7a\x3d\xee\xb2\x0d\x75\x86\ +\x77\x69\xdb\xd9\x6a\xb2\x26\x12\x8d\xb2\x80\x98\xc2\x50\x69\x6e\ +\x16\x90\xa1\x2f\x8f\xd9\xa2\x3d\x00\xad\x81\xc4\x27\x15\x0c\x9d\ +\xc5\xa5\x2b\x80\x95\x09\x18\xd4\x06\xa4\xa6\x80\x34\xcd\x89\xa6\ +\xba\x60\xbe\x67\x65\x83\x66\x87\x0f\x40\x0d\x60\xbe\x41\x9b\x5b\ +\xd8\xac\xa6\x2d\x80\xfa\x82\x47\xb2\xe3\x53\x69\xde\x0a\xa5\xa3\ +\xfd\x4e\x25\x6b\x29\xc1\x5c\xb1\x3e\xb5\xdc\xad\xc1\x89\x3c\x37\ +\xce\x50\xfa\xe2\xd1\xc1\x69\x7c\x3f\x6b\x36\x47\xf4\xea\x04\x09\ +\xd2\xba\x7f\xf7\x51\x45\x79\xf9\xba\x48\x64\x9a\x9b\x9b\x63\x2f\ +\xd3\xfe\xaf\xfd\xcd\xc3\x0f\x3f\x64\xf2\xb9\x9f\x77\x83\x44\x89\ +\x0d\x88\xb3\xec\xb8\x7a\x07\x1b\x0c\xc2\x30\x6f\x22\x01\x42\x88\ +\xab\x44\xf9\xe9\x00\x88\x04\x5d\x5b\x76\xc6\xd3\x15\x16\xd6\x80\ +\x29\x07\x40\x74\x38\x86\xf1\x98\xc7\xf9\xa6\x52\x7d\x9e\xd2\xc3\ +\x4d\xa5\xb7\xf8\x31\x5f\x7c\x33\x12\x82\xa2\x58\x40\xbc\x85\xe0\ +\x4d\x59\x60\x13\x0c\xb9\xcb\x9e\x0a\x0b\x3e\xac\x47\xd7\x7e\x9a\ +\xcc\xdb\x83\x10\x98\xd3\x66\x83\x26\xdd\x5d\xa0\xc4\x9d\x26\xde\ +\xcf\x60\x55\xb9\x30\x80\x99\xd1\x59\xf2\xfd\xf0\xbb\xde\xae\x91\ +\xb7\xbd\x55\xd9\x72\xc9\x68\xde\x00\xdf\xe4\x9f\xfd\xf1\x1f\x7f\ +\x14\x0c\xb8\xe4\x32\xd3\xcf\x2b\x80\x06\x7e\x33\x07\x72\x3a\xec\ +\xc8\xbc\xdd\xb8\x42\x10\x21\x18\x30\x0b\x43\x65\xfa\x73\xbe\x4a\ +\x99\xa2\xa4\xa6\x44\x0f\x9d\xa3\x5e\x13\x8d\xa0\xa0\x6c\x46\x16\ +\xee\xf6\x51\x2c\xf9\x14\x1d\xf6\xa3\x75\x3f\x11\xc1\x68\x3e\x0c\ +\xf3\x09\xf0\x20\x45\x0c\xa7\x34\x05\xc5\x65\x30\xc0\xad\xdb\xf6\ +\x99\x93\x6d\x08\x78\xa4\xd1\x69\x31\xe4\xca\x8f\x2d\x61\xa3\xcc\ +\x99\x49\xca\xbe\x2d\xf2\x2d\xa2\xf1\x59\xfc\x7d\x0e\xca\x86\xb9\ +\x9e\xd6\x85\x44\x46\xb9\x9b\x76\x6b\xcb\x07\xff\x40\x45\x22\xce\ +\x2c\x9a\x27\xb3\x73\xbf\xfd\xcd\xbf\x7d\x60\xec\xd0\xa1\xa7\x8b\ +\x92\xfb\x8b\x6e\x92\x32\xfb\xf4\xcf\xd0\x2e\x5f\xcb\x0b\xc5\x8d\ +\xc6\x15\x82\x26\xb4\x25\x13\xb6\xf8\xa9\xd0\xc5\x4d\xc6\x4b\x8a\ +\x67\xaa\x14\x44\x4d\x2b\x00\x27\xe0\x20\x04\x53\x81\xf9\x18\x61\ +\x3a\x1c\xe0\xd8\x6a\x1d\x4a\xf2\x3d\x0d\xf3\x90\x2f\x81\x2a\x5a\ +\x4d\x10\xe2\x9a\xb5\x82\x00\x56\x13\x2c\x21\x04\x62\x77\x35\x27\ +\xce\x31\x9f\x98\xcb\x41\xd3\xe0\x45\x17\x00\x98\x89\xa0\xf1\x3a\ +\xf9\xfd\x42\x58\x21\x28\x98\x37\xf9\x46\x5a\xe7\x48\x17\x67\xe8\ +\x18\xed\x78\xe0\xe3\xaa\x04\xfc\x2d\xe6\xd9\xd4\xf1\xdc\xd3\xcf\ +\xfc\xf9\xb7\xbe\xf6\x57\x7f\xce\x74\xc5\x7f\xcc\x2e\xb1\x26\x54\ +\x38\x76\xec\xd8\x89\x15\x2b\x56\xec\x21\x22\x0c\x21\x04\x6b\x05\ +\x81\x54\xca\x36\x29\x6b\xe5\x9c\x52\xdd\xe6\x5d\x5e\xcd\x34\x25\ +\x21\x41\x7e\xcc\xd1\x6f\xb2\x33\x98\x07\x94\xc2\x31\x4c\x3e\xc1\ +\xf7\x14\xe7\x93\x5c\x8f\x73\x53\xa8\x95\x83\xd9\x1e\xa3\x6b\xdd\ +\xc9\x71\xc0\x93\x18\x7e\x5e\x47\x10\x29\x1f\x58\x40\x37\x0a\x0a\ +\xd3\x0c\x49\x67\x82\x1a\xec\x0e\x28\x19\x20\x45\x07\xe8\x42\xf8\ +\x7b\xa0\x4c\xc7\x38\xd8\xa3\x13\xfe\x08\x9a\xbf\x49\x3b\x3e\xfe\ +\x31\x55\x10\xfa\x0c\xcc\xa3\x38\xb3\x9f\xe9\xd1\xbf\xfc\x93\x2f\ +\x7c\xb2\x5b\x9a\x5b\xfe\x25\xf6\x09\x7a\x68\x69\xe1\xf8\xf1\xe3\ +\x63\xbc\x36\xbf\x0d\x3c\xe8\x09\x1b\x50\x8c\xc7\xa1\x24\x05\xd3\ +\xb0\xf2\x4b\xa0\x30\xd5\xa1\xdf\xd6\xf6\x08\x41\x62\x0c\x30\xfa\ +\xa1\x90\x80\x3e\x04\x84\x20\xcc\xc8\x79\x35\xfc\x26\x77\x87\xcc\ +\x66\xa7\x06\x63\x83\xb1\x2e\x51\x00\xc1\x36\xd6\xe4\x28\xe9\x49\ +\x5d\x34\x63\xbb\x32\x01\xf5\x76\xc3\x3c\x05\x4f\x97\x2f\xac\x70\ +\x93\x88\x54\x04\x43\xdc\x84\xaa\x80\xcd\x8b\x3c\x1f\x7d\xd7\xbb\ +\xb4\xf9\x5f\xfd\x4b\x15\xb1\x94\xe9\x99\x19\xcb\xfc\xcb\x87\x0f\ +\xbf\xf0\x97\x9f\xff\xc2\xbf\x49\x36\xea\x13\xe7\xe0\xe1\x97\xdd\ +\x29\x4a\x16\xeb\xce\x8c\x8f\x8f\x1f\x23\x2a\x98\x04\xa9\x27\x1c\ +\x89\xd8\x4c\xaf\x19\x89\x53\xa7\xaf\x22\xcb\x4a\xab\x9c\xaf\x90\ +\x81\xd5\x2d\x53\x0c\xb6\x2a\x73\xaa\x50\x05\x43\x2e\x0b\xe0\x84\ +\xd9\xa2\x2b\x15\xb0\x96\x62\x95\xe3\x0a\x54\x6b\x51\xc1\x05\xd8\ +\x1a\x8c\xb8\x50\x09\xcc\x00\xe9\xa2\x50\x02\x9c\x48\xf9\xe8\x4d\ +\x40\xa1\x26\xd6\x57\x8f\x23\xdb\x8c\x26\x7c\x51\x1d\x66\x0d\x9b\ +\x1f\x7c\x50\x43\x77\xdd\xa1\x2c\x51\x69\x6a\x7a\xda\x00\x1e\xbb\ +\x59\x0e\xbf\xf8\xb5\xbf\xf8\xef\xf7\x47\xf2\xd9\xf1\xb3\xac\xfd\ +\x57\xb9\x59\x3a\x82\x05\xdc\xc4\xcf\x61\xfe\x94\x24\x69\x17\xdb\ +\x68\x44\xe5\x68\x37\x48\x85\xca\x00\x62\x7e\x5e\xc5\xf1\x17\x15\ +\x29\x8f\x29\x1d\x98\x57\xa8\x51\x6d\xed\x0a\x35\x8d\x55\xfe\xf9\ +\x9a\x10\xff\x1c\x4b\x9d\xfd\x4e\xed\x37\xc4\xed\x1e\x23\x9e\xd4\ +\x29\x67\xa1\x20\xc2\x0c\xa2\x6d\x46\x2f\x2c\x4c\x4e\x34\xc1\x34\ +\x56\xa6\x17\x71\xd7\x5d\xda\xf8\x9e\x7b\xd5\xc0\x12\x17\xb3\xcb\ +\x76\x57\x3a\x95\xac\x8e\x1c\x3c\xf4\xf8\x5f\x3f\xf4\x95\x8f\x77\ +\x57\x4a\xa7\x8f\x4b\xee\x6b\xb1\x5d\x3e\x44\xc7\x68\x2b\x7b\x08\ +\x3f\xc5\x6f\x05\x7e\x97\x5c\xc1\x61\x03\x92\x22\x21\x80\x09\x33\ +\x8e\x19\x7f\xa6\xa7\x57\x3e\x7d\x08\x3f\x3d\xa5\x1e\x65\x11\x48\ +\x49\x81\x6a\xc3\xee\x23\xf0\xd7\x01\x4b\x5b\x11\x43\xcd\x76\xba\ +\x6b\x81\xc3\x69\x63\x82\x9f\xf3\x86\x60\xda\xe4\xfa\x68\xde\xa3\ +\x08\xba\x58\x71\x75\xae\xe1\xd1\x97\xdc\xa3\x4d\xec\x47\x0e\xb2\ +\x1b\x2d\x47\x42\xb6\x40\x92\xc3\xfe\x3f\xa3\xf9\xc6\x81\x7d\xfb\ +\xfe\xc7\xf7\xfe\xfa\x6f\xfe\xeb\x48\xd3\xbb\x78\x04\x91\xbe\x96\ +\x3f\x98\x08\x40\xc3\x3b\x77\xee\xfc\x83\x37\xbd\xe9\x4d\x0f\x12\ +\x26\x53\xec\x20\x17\x20\xa9\xb0\xc9\xfd\x59\x68\xdc\x41\x61\xc5\ +\x9c\x0a\xaf\x9e\x94\x26\xc7\x15\x9a\xbf\xa4\x1e\x9a\x1b\x09\xf2\ +\xf6\x40\x89\xd4\xb5\x4a\xee\x6e\x84\xc0\x3f\xf1\x8c\x7c\x50\x20\ +\x88\x79\x87\x60\x38\xa2\x1a\xe3\x54\xa9\xaa\x59\xee\xa9\x62\x69\ +\x03\x6f\x78\x83\x46\xd8\x7d\xee\x74\xa5\xf1\xa0\xaa\x96\xb2\x59\ +\x9b\xe1\x4d\x63\xf6\x67\xcf\x9c\x99\x7b\xe6\xc9\x1f\xfc\xa7\xa3\ +\xcf\x3d\xff\xcd\x95\xd4\x73\x07\x25\xef\xf5\xf8\xc9\x8c\x03\xa5\ +\xf9\xdc\x7a\xc7\x1d\x77\x7c\x82\xd7\xcd\x6f\xc6\x25\x7c\x84\x4b\ +\xc5\x63\x31\xbb\x83\x3b\x2c\x29\xee\x0f\x28\xe6\x43\xb3\xe4\xe3\ +\x45\x4c\xb4\x3a\x35\xa9\xe6\xec\x8c\x7c\x30\xa0\x82\x79\x77\x50\ +\xb7\x55\x5e\xc3\x54\x85\xe1\x88\x5c\x00\xd6\x4b\x53\xe3\x0f\xf4\ +\xab\x7f\xcb\x56\xf5\x6e\xdd\x22\x1f\x6e\x46\xd9\xa0\x3c\x6e\x96\ +\xe3\x99\x2c\xcf\xd2\xd4\x10\xd9\xaa\xcb\xa6\xcd\xbf\xfb\xc1\xf7\ +\x1f\xfd\x6f\xde\xe2\xe2\xd1\xf5\xf2\x2a\x3f\x92\x9a\xaf\xf7\x8f\ +\xa6\x82\xd0\x8a\x0d\x1b\x36\xdc\x73\xe3\x8d\x37\xde\xbf\x7e\xfd\ +\xfa\x1b\x00\x4a\xb3\xc9\xda\x6e\x47\x09\xe3\x1a\x21\x63\x15\x50\ +\x14\x0d\x47\x8c\x60\x10\x4a\xc0\x74\x6b\x3b\x11\x83\x63\x87\xeb\ +\xe2\x9a\x82\x41\x46\xbf\x5c\x47\xb6\x86\x2f\x03\x6e\x14\x26\x2a\ +\x96\x4a\xc8\xab\xd0\xc9\xeb\xbd\xd3\xe3\xe3\x2f\x1c\xdc\xf7\xe2\ +\x97\xce\x1d\x1d\x7b\x22\xd3\x6c\x2c\x8d\x4b\x8d\x5f\xe7\xcf\xe6\ +\x1c\x28\x02\x0d\xaf\x5b\xbb\xf6\x2d\x3b\x76\xee\xfc\x17\xb8\xc5\ +\x6e\x04\x11\xc2\x42\xac\x20\x00\x4f\x11\x3d\x14\x0c\xc0\x3c\xcc\ +\xf2\xfb\x20\x2c\x3f\x00\x01\x78\x68\x9f\xff\xd9\xa4\xa8\xe1\x79\ +\x96\xea\x00\x62\x0d\xe6\xcb\x30\x6f\x18\xe7\x17\xa5\x26\xa7\x2f\ +\x4f\x9c\x3f\xff\xdc\xe1\xfd\x07\xbe\x7a\xe1\xd4\xf8\xd3\x51\xcf\ +\x9d\x0f\x49\xb5\x73\xbf\x41\x3f\x9c\x74\xa0\x30\xec\xf4\x26\x62\ +\xb1\x2d\xdb\x77\xee\x7c\xc7\xc8\xe8\xe8\xef\x80\x0f\x1b\x32\xec\ +\xd4\x64\x07\xea\xdf\x0b\x02\x4d\x07\x10\x46\xe7\x5d\x9d\xda\xbb\ +\x37\x08\xb7\xb6\x75\x45\x35\x6a\x4b\xd8\xa5\xc5\xc5\xc2\xfc\xdc\ +\xdc\x31\x36\x6b\x3e\x79\xe4\xc5\x17\xff\x4f\xad\x54\x79\x35\xe8\ +\xd5\x97\x03\xa6\x60\x93\x9a\xbf\xa9\x3f\x9d\x75\xd4\x2a\x0d\xa2\ +\xb0\xd7\x8d\x81\x0f\xaf\xdd\xb0\xfe\xc6\x15\xc3\xc3\xd7\x03\x94\ +\xab\x12\xc9\xd4\xca\x70\x24\x9c\xa6\xf1\x8a\x57\x04\xc3\xdc\x6c\ +\x18\xaf\xd0\xb2\x2a\xc1\xfc\x32\x6d\xab\x0b\xec\x4e\x3f\x37\x39\ +\x31\x71\xf8\xec\xa9\xf1\x83\x5c\x9f\xa6\xfa\xcb\x8a\x3e\xd1\xb2\ +\xe4\xfd\x36\xfe\x78\x9a\xba\x0f\xb7\x97\xc8\xf2\x15\x91\x15\x8c\ +\xc3\xe8\x84\x9a\x9c\xc7\xfc\x3d\x47\xb8\x3d\x90\xc8\xf5\x32\x9b\ +\x54\xcb\xa0\x80\xcd\x08\x0c\xd7\xaf\xf5\x8f\xa8\x9d\xdf\xb0\x5f\ +\xad\x37\xf5\x3a\x7f\xfe\x1f\x5f\xbc\xdd\xe6\x1a\x53\x0c\xc2\x00\ +\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\ +\x00\x00\x13\x09\ +\x89\ +\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\ +\x00\x00\x40\x00\x00\x00\x40\x08\x06\x00\x00\x00\xaa\x69\x71\xde\ +\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\ +\x1b\xaf\x01\x5e\x1a\x91\x1c\x00\x00\x00\x07\x74\x49\x4d\x45\x07\ +\xd7\x09\x17\x17\x15\x19\x49\x86\x70\x41\x00\x00\x12\x96\x49\x44\ +\x41\x54\x78\xda\xed\x5b\x09\x74\x5c\xd5\x79\xfe\xee\x7b\xb3\x6b\ +\xb4\x5a\xb2\x25\xd9\x96\x64\x63\x6c\x83\x31\x36\xb6\x81\x00\xe1\ +\xb0\x34\x14\xc2\xda\x94\x86\x04\xd2\x90\x42\x72\x20\x5d\x20\x14\ +\x68\x08\x4b\x48\x09\x87\xda\xad\x73\x52\x52\x02\x24\xad\x7b\x20\ +\xe4\xb0\x95\xcd\x40\xb0\x1b\x56\x2f\x80\xb1\x2d\xdb\xd8\xb2\x6c\ +\x6c\xd9\xb2\x2c\xc9\x1a\x4b\x1a\x69\xf6\xe5\x6d\xf7\xf6\x7f\x33\ +\xef\xf0\xf4\x3a\x9a\x19\x1b\x26\x3d\xc9\x69\x7e\x9d\x4f\xf7\xbd\ +\xfb\xee\x9b\x79\xdf\x77\xff\xe5\xbe\x2b\x1b\x7f\xb4\x3f\xda\xff\ +\x6f\x63\x38\x0e\x1b\xbb\x05\x75\x52\xed\xf4\x8b\x5d\x33\x97\x5c\ +\x06\xb7\xef\x3c\xa1\xa4\x3c\xd0\xb3\xc3\x42\xcd\x0c\x71\x35\x15\ +\x12\x4a\x22\xc4\x53\xe3\x21\x91\x8d\x85\x84\xc0\x10\x80\x10\xe1\ +\xe8\xd4\x9f\x43\xf9\x83\x16\x40\xfc\xd8\x7f\x95\x68\x5d\x76\x37\ +\xe7\x58\xc6\xd3\x51\x99\x08\x42\x70\x01\xe1\x0e\x12\xaa\xc0\x65\ +\x3f\x84\xec\x81\x60\x6e\x82\x0b\x90\x5c\x10\x82\x03\xdc\x00\xd7\ +\xd2\x02\xba\x32\x2e\x0c\x6d\x48\xe8\x6a\x48\x68\x4a\x48\xe8\xd9\ +\x10\x57\xd3\x24\x54\x7c\x48\x68\xd9\x90\x30\x85\x12\x08\x4d\x7f\ +\x0c\x99\xdf\x3b\x01\xc4\x03\x9e\x3f\xc7\xf9\xf7\xbf\x88\xe6\x45\ +\xcc\x24\x04\xae\x03\x26\x39\x43\x05\x32\x11\x80\xc4\x80\x9a\xcc\ +\x43\xcf\x40\x68\x19\xf0\x6c\x82\x90\x02\x57\x92\xe0\xa6\x50\xb2\ +\x0f\x5c\x48\x04\x53\x13\x4e\xd0\xc1\x75\x2d\x27\x14\x40\xd7\x0d\ +\x03\x24\x0a\x41\x8d\x0a\xae\x87\x08\x43\xc2\xa0\x36\x07\x95\x04\ +\x33\xa1\x0c\x09\x6e\x84\x00\x84\x3a\x1e\x47\xf2\xff\x4e\x80\xa7\ +\x2e\xee\xc4\x99\xb7\x2c\x85\xb0\xc8\x73\x23\x07\xc7\xb9\x28\xd6\ +\xa7\xe7\xa1\x98\xe2\x64\xed\x3e\xd3\x84\x00\x57\x33\xa4\xa3\x42\ +\xc8\x82\x73\x0e\x03\x6e\x70\x12\xd6\x50\x32\x39\x01\x0d\x12\x52\ +\xcf\xc4\x01\xba\x26\xcc\x1f\x6e\x80\x3c\x89\xa0\x27\x68\x60\x4e\ +\x90\x1c\x04\x0f\x01\x3c\xc4\x64\x98\xd8\xd9\x71\x29\xba\xd9\xc5\ +\x10\x95\x11\xe0\x85\x6b\x53\x58\x78\x6d\x20\x3f\xf3\x46\x09\x01\ +\x9c\x62\x38\xc6\x8b\xdc\x35\x1b\xa2\xc8\x58\xf2\x1e\x40\x00\x14\ +\x4e\x90\xdc\x80\xcb\x47\xf0\xe7\x3c\x46\xd7\x75\x18\x9a\x96\xf3\ +\x20\x9d\x33\x12\x27\x09\x3d\x35\x06\x75\xa4\x07\x7a\xa2\x0f\xae\ +\x00\x03\xf3\xe4\x6f\x37\x14\xf1\x3a\x35\xdf\xe8\x58\x81\x04\xca\ +\x98\x0b\x65\x8d\xb9\x72\x0f\x97\x8b\x69\x82\x63\xc6\xb9\x89\x82\ +\x63\xc7\x78\x61\x58\x2d\xb7\xfa\x8b\x8c\x35\x21\xc9\xf9\x3e\xcd\ +\xf4\x96\xd4\xa7\xe2\x48\x34\xc6\x63\x0b\x95\x0f\x3f\xd9\x0b\xd4\ +\xd7\x00\xb3\x2e\x85\xde\x34\x97\x9c\xec\x03\xe8\x43\xab\xc1\xb3\ +\x06\xd4\x38\xae\xc8\x8c\x88\x55\xa2\x1b\x5f\x63\x0b\x50\xd2\x24\ +\x94\x35\x0e\x88\x89\x04\x78\x01\x81\xa2\xd7\x45\x31\x91\x8a\x7c\ +\xd6\xb1\x7e\xb6\x69\x5a\x1a\x48\x1c\x01\x0e\xbf\x0f\xd7\xbe\x35\ +\xa8\x5a\xba\x02\x9e\xe9\xcb\x00\x96\x1f\x0a\xce\xbe\xda\xf3\x38\ +\x4e\x00\x3e\xaf\x00\x42\x4c\x70\xdd\x22\x33\x69\x79\x44\xd9\x87\ +\xe7\xe5\xbd\x80\x50\xfe\xb3\xed\x6b\x79\x11\x0e\xbc\x09\xac\xbd\ +\x13\x7a\x66\x16\x52\x43\x02\xe9\x61\x01\x35\x29\x98\xa1\x62\x49\ +\x25\x04\x28\x7c\x38\xce\x8b\xcc\x6c\x31\x61\x8e\x91\x38\x2f\x15\ +\x5a\x93\x08\x13\x27\xf2\xe9\x31\xe4\xec\x93\xd5\x30\x12\x5e\xa4\ +\x8f\x9a\xe4\xf3\xb7\x42\xc0\x5f\x81\x1c\x20\x0a\xc9\xd8\x84\x4a\ +\x92\x71\x1e\x97\x0a\x25\x5e\x46\x9c\x42\xf1\x6c\xf2\xf6\x44\x31\ +\xdd\x2c\xaf\xd6\x23\xc3\xb2\xcf\x2d\x40\xa1\xdb\x15\x78\x41\xb1\ +\xd8\x75\x1e\x17\x0f\x95\xc2\x44\x59\xc6\xc3\xe2\x83\x44\x3e\x8c\ +\x02\xe3\x1a\x84\xc5\xbc\x72\x02\x40\x14\xcd\xe8\x36\x81\xe3\x4d\ +\x88\x45\xae\x17\x92\x2d\x1c\x1f\x1b\x70\x90\x77\x98\xa1\x43\xa0\ +\xd2\x02\x08\x41\x30\x8e\x3d\xa3\x17\x86\x4a\xf9\x24\xc8\x8f\x31\ +\x29\xc6\x4b\x90\x27\x13\xa6\x07\x4c\x9c\xb7\x0a\x09\xe0\x24\x5b\ +\xbe\xd4\x95\x5f\x03\x94\xff\xac\x42\x0f\x8b\xf5\x03\xa9\x51\x94\ +\x34\x43\xb7\x89\x57\x38\x04\x2c\x18\x05\x0f\x57\x9e\x4c\x91\x6b\ +\x28\xa8\x26\xc5\x45\x8d\x1d\x2e\x4f\x1e\xc8\x2f\x93\xe1\x14\xa0\ +\x12\x65\xd0\x41\xb6\x10\x45\x32\x36\x6c\xa2\xb9\x7e\x10\x98\x75\ +\x0e\x6e\x9d\x13\x60\xf7\x4d\x9a\x10\xcb\xcf\xbc\x33\x09\x02\x36\ +\x44\x25\x04\x40\xc9\x44\x35\xb9\x10\xb0\x88\xb1\x63\x24\x6e\xc2\ +\x3e\xb6\xbf\x27\x6a\xce\xfc\x08\x8e\xd5\x04\xd7\x2d\xe2\x16\x2a\ +\xe4\x01\x65\x56\x7a\x0e\x22\xc5\x88\x95\x12\xc3\xea\x73\x0a\x87\ +\x58\x5f\x01\xf9\xb2\x66\x38\xca\x60\x25\x05\x28\x1f\xdb\x4e\x21\ +\x9c\x64\x0a\x3d\xc2\x26\x6e\x0b\x64\x58\xe0\x40\x9c\xc8\x67\x88\ +\xbc\x54\xe4\x7d\xb5\x74\x15\x70\xa0\xd2\x2b\xc1\x82\x38\xb7\x60\ +\x93\x13\xff\xdb\x0b\x2c\x62\xc2\xe1\xe6\x36\x59\x82\xe3\x38\x7e\ +\x88\xc8\x0f\x03\xb2\x35\x54\x58\xe0\x28\x67\xf6\x3a\xc0\xf6\x82\ +\x0a\xaf\x04\x3d\x55\x40\xfd\x09\xf9\xa7\xd1\xd3\x40\x26\x0c\x24\ +\x8f\x02\x5a\xd2\x99\xe8\xec\x58\x2e\x14\x88\x39\x12\xa3\x53\xa8\ +\x78\x6f\x9e\xbc\x64\x3d\x3d\xb3\x45\xb0\xfd\xba\x74\x15\xb0\xcb\ +\x60\xe5\xd6\x01\xb6\x08\xfe\x29\xc0\xdc\x4b\xe1\x34\x91\x17\x61\ +\x6c\x2f\x10\xfa\x28\xe7\xbe\x85\xee\x4f\x10\x13\xfa\x84\xc3\xe5\ +\xf3\x6d\xe2\x90\x93\xbc\x4d\xd6\xd9\xf2\x12\xcc\xac\x24\x58\xe9\ +\x75\x80\x23\xbb\x17\x1a\x03\x82\x2d\x79\xb4\x5f\x98\x17\xe0\xe0\ +\x6b\xc0\x48\xa7\x33\x1c\x18\x01\x36\x79\xb3\xb5\xc9\x9b\x33\x7f\ +\xd4\x72\xfb\x32\x02\xc0\x1e\x53\x72\x1d\x20\x08\x15\x4d\x82\xb0\ +\x50\xce\x6a\x3a\x80\xd3\x6e\x05\xce\xb8\x17\xa8\x9e\x3e\x21\xce\ +\xed\x7c\x60\x9f\x5b\xe4\xb3\x16\x79\x09\xd4\x5a\x90\xca\x80\xa1\ +\xf8\xcb\x90\xa8\x64\x15\xc0\x24\x19\xdf\x50\xca\xaf\x32\xea\xe7\ +\x01\xe7\x2c\x07\x3a\x2e\x73\x84\x84\x0d\x93\xfc\x41\x22\x1f\xb2\ +\x49\x95\x03\x2b\x2d\x82\x30\xf4\xca\x57\x01\x22\x6a\x27\xaa\x48\ +\x0f\xb0\xee\x6e\x40\xe8\xf9\x73\x6f\x35\x10\x6c\x26\xb2\x27\x02\ +\xd3\x96\xd1\x79\x7d\xc1\x76\x22\x4e\xba\x01\xa8\x9b\x03\xec\x5c\ +\x09\x18\x9a\x95\x00\x09\x89\x03\x80\x62\x91\x17\x93\x00\x8e\x44\ +\x68\x1b\xb7\xa7\xad\x20\x1c\xb8\xe6\x8c\x16\x51\xe9\x32\x88\x89\ +\xe5\x4f\x07\xb2\x61\xc2\x30\x30\xba\x1d\xe8\x79\x16\x68\x5c\x04\ +\xcc\xfe\x33\xa0\xba\x1d\x0e\x6b\x39\x17\xf0\x90\x58\x9d\x14\x16\ +\x9a\x0a\x24\x7b\xec\x99\x17\x25\x92\x9c\x70\x10\x76\x92\x66\x13\ +\x20\x9c\x1e\x90\xfb\x55\xb1\x10\x60\x02\xce\x9a\x3f\x59\x19\xb3\ +\xb6\xba\x47\xb6\x00\x9b\x7f\x00\x7c\xb2\x8a\xba\xb2\x70\xd8\x94\ +\xc5\xc0\x92\xfb\x81\x74\x9f\x49\xbe\x78\xcc\xdb\xfd\xc7\x17\x1a\ +\xa6\xd9\x65\x90\x50\xa9\x24\x08\x51\x58\xd7\x6d\xf2\x85\xab\x3e\ +\x53\x88\x81\x35\x24\xc4\x1d\x40\x6a\x10\x0e\x6b\x3a\x13\x38\xf5\ +\xfb\x05\x64\xcb\x82\x4d\x1a\xff\xce\x7e\xf6\x3b\x5d\x09\x5a\x04\ +\xfd\x8d\x40\xfb\x05\x80\xbb\x2a\x17\x6f\x48\x0f\x01\xf1\x83\xc0\ +\x78\x17\x60\xa8\x13\x44\xa0\x36\x75\x18\xd8\x4a\x22\x2c\x79\x10\ +\xa8\x99\x8b\x4f\x6d\xfe\xdf\x00\xa3\x1f\x00\x87\x9e\x01\x50\x26\ +\xfe\x51\xc2\xf5\x25\x47\x9e\xc8\x83\xeb\xf6\xed\xa2\x32\xeb\x00\ +\xe7\xcc\xfb\xea\x80\xd6\xb3\x60\xdb\x52\x02\xf2\x2b\xc1\xa1\x77\ +\x80\xbe\xd5\x74\x1c\xb1\x17\x3b\x5a\x14\xd8\x7e\x17\x89\xf0\xcf\ +\x4e\x11\xce\x7c\x04\x18\x79\xd7\xac\xfd\xc5\xe3\x9f\x17\xf5\x4f\ +\x27\x69\xc9\x3e\x17\x10\x16\xf1\x8a\x87\x80\xed\xee\x93\x9a\x3b\ +\x08\xb4\x5f\x05\x9c\xf5\x53\xa0\x71\xa9\xf3\xe5\x66\x7c\x2b\xb0\ +\xfe\x72\x40\x8b\xd9\xe3\x3d\x0d\xa4\xdd\x4f\xca\xd7\x7c\x66\xb7\ +\x36\x8a\x84\x06\x9b\xc4\xa1\x2a\x23\x80\x73\x25\x58\xd2\x3c\xf5\ +\xc0\xe2\xfb\x80\xb6\x2b\xf2\x5e\x90\xd8\x07\x28\x47\x80\x54\x0f\ +\xb0\xfd\x56\x38\xac\xfd\x5a\xa0\xe1\xb4\xcf\x50\xfb\x4b\xc2\xb1\ +\x12\x14\xa2\x62\x02\x70\x0b\x02\x50\x62\x40\x78\x17\x30\xb2\x0d\ +\x48\x0e\x4e\xf2\x2d\x0c\x98\xfb\x5d\xa0\xf1\x4c\x20\x3b\x68\x3f\ +\x78\xff\x53\x74\xcf\x3b\x13\x86\x51\xe7\x29\xf7\x1d\x67\x22\x2c\ +\x71\xcc\x9c\xc4\x05\x2a\x97\x03\xec\xfa\x3f\xbe\x17\xd8\x70\x1b\ +\x00\xdd\x0a\x09\xeb\x05\xa9\xe3\x4a\x60\xc6\xc5\xce\xa5\xd9\xc2\ +\x1f\x11\xe1\xdf\x02\x91\x4e\xfb\x41\x77\xdf\x05\x5c\xb8\xd5\x1e\ +\xd7\x4a\x61\x13\x6c\x03\x92\xfd\xce\xd8\x67\x36\x0a\x63\xbd\x04\ +\x80\xcf\xb6\x27\xf8\xe0\x7d\x37\x2d\xdc\xf2\xf6\x4f\xa5\xd2\x55\ +\x80\xc0\x55\xe7\x92\x18\x84\x4c\x08\xd8\xfb\x18\xb0\xfd\x87\x80\ +\x91\x99\xf0\xc9\x6e\xe0\x0b\xbf\x06\x5c\x2e\x7b\x16\xe3\xdb\x80\ +\xd1\x89\x5e\x20\x03\xed\xdf\x2c\x3b\xf3\x4e\x14\xef\x17\xec\x33\ +\xe6\x80\xb7\x37\xf7\xae\x7e\x6b\xc3\xbe\x5f\x90\x08\xac\x68\x0e\ +\x28\xdc\xf3\x73\x2e\x90\xc6\x3a\x81\x0f\x6f\xb4\xfa\x2c\xab\x9e\ +\x0f\xb4\x5d\xe7\x8c\xe3\xfe\x5f\xc2\x61\xd3\xaf\x2e\x41\xba\x4c\ +\xdc\xa3\xe0\xdc\x0e\x83\xe3\xc9\x01\xe3\x8a\x9e\xed\xdc\x35\x38\ +\x7f\xc7\xee\xc1\x7f\x25\x11\x4a\x6f\x89\x81\x3b\x84\xb0\x77\x6f\ +\xf7\x00\x87\x9f\x03\xf6\xac\x84\xc3\xe6\xdd\xe5\x24\x37\xba\x06\ +\x30\xd2\xf6\xf5\xda\xc5\x80\x7f\x6a\x01\xe9\xe3\x24\x6e\x0b\x20\ +\x3e\x83\x07\x24\x33\x19\x43\x81\xfb\xce\xd7\xdf\xec\xba\xe6\x50\ +\xff\xd8\x43\xc5\xdf\x06\x09\x81\x16\xe0\x8c\x1f\x03\x17\x3d\x4f\ +\xed\x0a\x20\x38\x33\x4f\x3e\x3d\x80\x9c\xed\xa5\x9a\xaf\xc5\x27\ +\x78\xc1\xc9\x40\xcd\x7c\x9b\x94\x20\xf2\xd1\x0f\x9d\x49\x73\xca\ +\xd9\x85\xa4\x51\x36\xde\x0b\xc9\x33\x27\x71\x21\xb9\xe5\x63\x12\ +\x20\x95\xc9\x1a\x29\xdd\xc8\x8e\x45\x92\xb7\x3c\xbb\x7a\xeb\x3d\ +\x6b\x5f\x78\xf0\x9e\xc2\x3f\x8d\xf1\x7c\xe6\x5e\x72\x27\x50\x6f\ +\x12\x72\x01\x75\xd4\x9e\xbe\xc2\x76\x7b\x86\xfc\xe2\xe7\xc8\xab\ +\x70\xd8\xd4\x8b\x9d\x33\x1b\xdb\x0c\x87\xd5\x2e\x3a\x0e\xa2\x65\ +\x44\x80\x05\xfa\xb5\xcb\x77\xfa\x2f\x96\x3f\x70\xeb\xeb\x8f\x3d\ +\xfc\xc3\xef\xfc\xec\x27\xf7\x4e\x2f\x5a\x05\x32\x8a\xa2\x27\xd2\ +\x19\xff\xf6\x4d\x9b\x5e\x5a\xba\x74\xe9\x6b\xcf\xbc\xbc\xf9\xa1\ +\x0f\xff\x7b\xe5\xc8\xd9\x97\xfc\xc3\x2a\x47\x12\xac\x99\x0d\x54\ +\xb5\xc0\x61\xee\x1a\xe0\xe4\xef\x01\xdb\xbf\x6f\xf7\x8d\x6e\x00\ +\x3a\xbe\x39\xc1\x0b\x4e\x71\xba\x77\x66\x1f\x1c\x56\x75\xc2\xf1\ +\x91\x47\x89\xbe\x09\x25\x70\xe3\xa6\x2e\xcf\x86\xa1\xfd\x97\x37\ +\xd4\xd7\x5e\x3e\x73\x66\x8b\xf8\xea\xd5\x57\xec\x9a\x36\x6d\xda\ +\x7b\x55\x55\x35\xeb\x33\x59\xf5\x83\x7f\x7b\xe4\xe7\xa3\x39\x01\ +\x14\x4d\xe3\x14\x06\x7e\x90\x71\xce\xff\x76\x67\x77\xff\xb9\x2f\ +\xbd\xb1\xed\x71\xca\x07\xc3\x38\xfc\xa4\x2d\x80\x96\x29\xb2\xf9\ +\x71\x0a\x1c\x96\x19\x80\xc3\x7c\xcd\xce\x87\x56\x87\xe0\x30\x6f\ +\x4b\x59\x82\xe5\xc9\x3b\x63\x9f\x83\x61\x6a\x9d\xf7\xad\xda\x54\ +\xed\x02\x26\xb9\x5a\x87\x47\xa2\x6c\x6c\x3c\xb9\xa8\xb7\x6f\x68\ +\x91\x2c\xcb\xb7\xa9\xaa\xca\xe7\xcc\x99\x73\x7b\x4e\x00\x5d\xd7\ +\x59\x3a\x9b\x0d\x80\x6c\xc7\x8e\x1d\x83\x0b\x16\x2c\xf8\xbb\x35\ +\x6f\xef\x7c\xba\x65\x5a\xed\x73\x27\x9d\x30\x53\x0e\x72\xc3\xda\ +\xc1\xe9\x07\xd2\x47\x81\x40\x33\x1c\x96\x3c\x0c\xe7\x02\x5c\x86\ +\xc3\x5c\xb5\xce\x35\xbf\x91\x82\xc3\xe4\x2a\x1c\x97\xb1\xc9\xfb\ +\x46\xb2\x3e\xbc\x1f\xa9\xc3\xc1\x4c\x2d\x0e\x67\x6b\x30\x1e\x4b\ +\x5f\xa4\xeb\x49\xc4\x62\x31\x28\xe4\xe5\x84\x7d\xc4\xb5\x95\x73\ +\x5e\x6f\xf9\xe2\x2c\xf3\x17\xb8\x10\x8c\xf2\x40\x10\x96\x75\x77\ +\x77\x3f\x63\x18\xc6\xd3\xff\xf9\xf4\xba\xc0\x6b\x91\xb9\x72\x5a\ +\x78\x00\x6e\xfd\xe3\xc8\xf5\xb7\xe5\x57\x83\xb0\x2c\x3b\x0a\xec\ +\x7c\xc8\x49\xb0\xaa\x03\x0e\xd3\xe3\x70\xee\xef\x7b\x50\x60\xf6\ +\xfd\xc7\x65\xe3\x59\x37\x7e\xb5\xb7\x19\xd7\xbf\xbd\x00\xcb\xfb\ +\xcf\xc5\x7b\xb1\x99\xd8\xdc\xaf\xe0\xc0\xde\x2e\xd4\x25\xba\x51\ +\xa7\xf4\x3f\x5a\x53\x53\x73\xe1\xca\x95\x2b\x67\x90\x00\x4b\x67\ +\xcf\x9e\xdd\x23\x49\x12\xac\x6f\x7a\xcb\x05\xb2\x80\xcf\xd3\x94\ +\x55\x95\x46\x4c\x30\x12\xe0\x26\x55\x35\x4e\x5e\xfe\xd8\xda\xd3\ +\x3c\xb7\x5c\x86\xcb\x9b\xfa\xe0\x33\x5f\x7b\x93\x7d\x24\xf5\x26\ +\x60\xee\xd7\xf3\x1a\xf6\x3c\x01\xa8\x24\x82\x3c\xe1\xe1\x5b\x2e\ +\x83\xc3\x52\xbd\x36\x79\x46\x90\xeb\xe1\x30\x6d\x1c\x10\xc7\x21\ +\x82\x99\xe0\x46\xaa\xf0\xec\xee\xa9\xd8\x12\x9e\x06\x4d\xd7\x10\ +\x8f\x8f\x43\x44\xdf\xc3\xe5\x73\x0d\xcc\x59\xe4\xc3\x89\xb3\xda\ +\xe0\xad\x6d\xa6\x3c\x7d\x41\x5f\xfb\x95\xf7\x0c\x03\x10\x0f\x3f\ +\xfc\x30\x23\x5b\x2c\x44\x2e\x6b\x5f\x4d\x78\xc3\x75\xcf\xdf\x5f\ +\x83\xc7\xd6\xee\x6c\x4a\xa6\xd5\x16\xcb\x2d\x38\x01\x07\x0f\x1e\ +\x4c\xb7\xb5\xb5\x7d\x25\x1a\x49\x6c\x5d\xf1\xcb\xdf\x36\xc9\x37\ +\x7e\x11\x97\x64\x87\xe0\x96\x00\x16\xeb\x07\xdb\xfe\x2f\x80\x79\ +\x2c\xe3\xd3\xed\x6c\xc6\xac\x87\xdf\xf9\x03\xe0\xc0\xa3\x66\xc9\ +\xcc\x23\xfc\x2e\xc0\x27\xb8\xaf\x6f\x0e\x1c\xa6\x5a\x02\x38\x45\ +\x98\xb4\x6f\xf3\x60\x10\xab\xb6\x35\x63\xd3\x61\x2f\xa2\xd1\x08\ +\x62\x91\x8f\xf1\xa5\x39\x0a\x7e\x74\x9e\x84\xf3\x17\xce\x04\xab\ +\x9b\x87\x3d\x83\x40\x64\xe8\x10\xa2\x07\x3b\x11\xee\xdd\x79\xf0\ +\x9d\x70\xf3\x01\x00\x7c\xc5\x8a\x15\xcb\xc8\x1b\x3c\x24\xc0\xeb\ +\x00\x72\xa5\xca\xd5\xd8\x58\x23\x65\x15\xad\xdf\xd0\x35\x0e\xa0\ +\x86\x90\x26\x68\x04\x31\xbb\xbf\xff\x70\xf4\x84\xa6\xeb\x87\x8e\ +\x8c\xac\x59\xf1\xe4\x26\x96\xb9\xfa\x6a\x9c\x6f\xbc\x08\x8f\xac\ +\x41\x96\xcd\x4a\x48\xa0\x56\xa6\x96\x59\xe7\x8c\x13\xc2\x5d\x60\ +\x11\x82\x9c\xaf\x9c\x29\x5d\xc6\xa1\xb1\x00\x8e\xc4\x3c\x18\x8a\ +\x7a\x10\x7a\xf5\xbf\x10\xd3\xd7\x21\xcd\xa6\x23\x65\xd4\x01\x24\ +\x6c\x2d\xef\x40\x8d\xcf\xc0\xd4\x6a\x0d\x73\x9b\x32\x58\x36\x23\ +\x85\x29\x7e\x1d\xa6\x0d\x27\xdc\xd8\x70\xb0\x1a\x2f\x75\x4d\xc1\ +\xc7\x83\x12\xc2\xe1\x30\x22\xe3\xe3\xf8\x8b\xa5\xc0\x03\x37\x07\ +\x70\xe2\xbc\x2f\xe4\x12\xb1\x88\x1d\x81\x31\xb4\x1d\x91\x7d\x31\ +\xa4\x14\x91\x4f\x37\x6e\xb7\x35\x45\x60\x2d\x2d\x2d\x17\x9b\xf9\ +\x80\xec\x79\x58\xe6\xba\xfd\xde\x55\x1c\x5e\xff\x12\xa8\x59\x93\ +\xfc\x14\x42\x15\x21\x46\xc8\x10\xf8\x99\xd3\x47\xd7\x6d\x3c\x5c\ +\xf7\x60\x6f\xdf\x91\xfb\x1f\x7e\x49\x42\xf4\x4f\xaf\xc2\x32\x75\ +\x35\x3c\x2e\x1d\x2e\x57\x9e\xbc\xcb\x12\x81\x13\xdb\x50\xda\x8b\ +\xc1\xb8\x17\xfd\x51\x1f\x8e\x24\x83\xd8\x3f\xec\x42\x6f\x48\x43\ +\x3a\x93\x45\x36\x9b\x85\xaa\x66\x20\x44\x1a\x3e\x5f\x06\x81\xc0\ +\x28\x82\xf2\x18\x3c\x48\x23\x6f\x12\x09\xe4\x42\x46\xf7\xc0\xef\ +\xaf\xc7\xec\x66\x2f\x3d\x5a\x35\x14\xe1\x43\x86\xee\x1f\x0a\x8d\ +\x20\x3c\x36\x86\xa0\x17\x78\xed\x8e\x7a\x5c\xf2\x27\xe7\x03\xb5\ +\x27\x43\x28\x29\x18\x07\xd7\xe6\x04\x10\x06\xc0\x49\x79\xc1\x04\ +\x84\xe0\x74\xec\xca\x15\x5f\xf3\xbb\xeb\xeb\xeb\xaf\xef\xeb\xeb\ +\xcb\x80\x6e\x77\xbe\x0d\x2a\xf4\xe9\x00\xb7\x50\x47\xf0\x13\xa2\ +\x9b\x81\x44\xbb\x0e\x76\x61\x7b\xf4\xb9\xf7\x0e\xd7\xce\x3e\xd4\ +\x37\xf0\x97\x4f\xbc\xc9\xb0\xff\xa4\xf3\x35\x79\x74\x4b\xca\x60\ +\xae\xa0\xaf\xaa\xc6\xe5\xae\x9e\x82\x81\xa8\x84\x81\x31\x8e\x68\ +\x3c\x8d\x54\x2a\x83\x44\x32\x8d\x80\x34\x88\x93\x5a\x75\x5c\xbb\ +\x54\xc2\xbc\x19\x40\x5b\xb3\x84\xf6\xd6\x20\x9a\xbf\xf4\x22\x24\ +\x33\x51\xba\x48\xf3\x9d\x37\x83\x99\x9b\x26\xba\x02\x28\x49\x30\ +\x35\x85\xa7\xd6\xeb\xb8\xf1\x3f\x52\x18\x19\xe1\x85\xc9\x9e\x01\ +\xab\x6f\x0b\xe0\xbc\x2b\xbe\x05\xe1\x69\x82\x48\x0e\x43\xdb\xf7\ +\x12\x90\x49\x12\x61\x19\x0c\xc8\x91\xe7\xd6\x96\x92\x90\x68\xa6\ +\x00\xf6\xca\x2b\xaf\xdc\x10\x08\x04\x66\x47\xa3\xd1\x55\x20\x5e\ +\xc5\x0a\x8a\x8b\x10\x24\x34\x10\xbc\x84\x64\x73\x10\x89\xf3\xe7\ +\x81\x35\x04\x51\xfb\x9b\xfd\x0d\x77\x29\xdc\xfd\xdd\xd6\xd6\x56\ +\xf4\xf7\xf7\xa1\x2a\xe0\x05\x37\x34\x84\x86\x23\x30\x0c\x8e\x69\ +\xb5\x14\x87\xf3\x25\x9c\x3b\x8f\xe1\x82\xa5\x4d\x68\x9f\x3d\x8b\ +\x2a\x5c\x13\x98\xbf\x01\xcc\x5b\x0b\xe6\x0e\x82\x41\x03\xb8\x92\ +\x03\x33\xb2\x10\x6a\x14\x2c\x3d\x08\xa4\x87\x73\xdb\xec\x4c\xcb\ +\xe2\xd0\x51\x81\xb3\x97\xd7\x62\x24\x1c\x01\x59\x6e\xc6\x3b\x1a\ +\x25\xec\x09\x01\xa7\xb5\x09\x7c\xf0\xb3\x0b\x20\xd1\xeb\x37\x4f\ +\x47\xa0\xed\x79\x06\x22\x9b\xb4\x37\xaa\x75\x81\x4d\x07\x38\x14\ +\x8d\x83\x09\xae\x27\x1b\x16\x2f\x7c\xba\xa7\x4e\x27\xf2\x5b\x3e\ +\xfa\xe8\x23\xcf\xc0\xc0\xc0\xa9\x00\x7a\x8b\xed\x07\xe8\x84\x38\ +\x41\xb5\x44\xa8\x1d\x4e\x22\xf0\x7a\x17\xa2\x27\x35\x23\x7c\xde\ +\xac\xc8\x9d\xef\xf6\x35\xb3\xde\xde\xde\x9b\xcd\x58\x22\x6f\xb4\ +\x66\x85\xe1\x9c\x39\xae\xc8\xbd\x5f\x9f\xe5\x9f\xb5\xe8\x42\x6f\ +\xb0\x75\x21\x73\xfb\x82\x48\x0b\x05\xc4\x90\xa0\x10\x31\x82\xaa\ +\xd0\x61\x14\x3c\xd9\x9f\xdb\x2c\x91\x94\x10\x24\x3d\x01\x99\x09\ +\xc8\x42\x40\x12\x66\xcb\xd0\x3d\x5c\x0d\x0e\x39\x37\xdb\x37\x9e\ +\x03\x7c\xeb\x6c\x50\x68\x00\x7f\xfd\x42\x2d\x66\x34\x24\x10\x97\ +\xdb\xe0\x4a\x2b\x48\xed\x5a\x0d\x91\xce\xd0\x7d\x66\xfc\x09\x08\ +\x9d\x23\x95\x11\x54\x1a\x01\xb3\x27\x65\xf8\x1e\x79\x64\x7d\xba\ +\xba\x75\x7a\xfd\xbf\xf7\xf4\xf4\xd4\x11\xf9\x1b\x4c\xf2\xe5\x36\ +\x44\xb8\x15\xff\x23\x04\x45\x00\x8d\x29\x15\x53\x3b\xfb\x11\xdb\ +\xd6\x2f\xc6\x5b\x1b\x95\xef\x69\x9a\x36\x04\xe0\xdb\x84\x36\x02\ +\xbc\x6e\xb9\x77\xd9\x89\x35\xf7\xb6\x5f\xf9\xe8\x75\x35\x53\x5a\ +\xda\x54\x25\x2d\xa5\x33\x09\xb7\xa6\xa6\x5d\x4a\x72\x14\xa3\xfd\ +\xbd\x99\x70\xff\xc7\x6e\x23\xbe\xbf\x5a\x36\xe2\xbe\x80\x57\x54\ +\x79\x3d\xc2\x13\xf0\x08\x29\xe0\x61\xb9\xca\xe2\x22\xb8\x19\xc0\ +\x0d\xe0\xdd\x81\x39\x48\x24\xba\x30\xb3\x1e\x5b\x82\x6e\xec\x79\ +\x6d\x07\x6a\x3d\x2e\x51\x27\x04\x3f\xef\x70\x18\xfa\xc7\x3d\x11\ +\xc9\x88\xbf\x2a\xf3\x78\x04\x01\xb7\xcc\x3c\x4c\x80\x71\x01\x45\ +\x15\x62\xdf\x30\xd4\xa3\x09\x36\x7a\x28\xea\xde\xf8\xe1\xa0\xdf\ +\x35\xeb\xc4\xa6\xd5\x54\xd1\x9a\xf7\xee\xdd\x7b\x37\x80\x5f\x1d\ +\xeb\x8e\x90\xb0\xbc\x60\xdc\x6a\x1b\x09\x0d\x02\x08\x1c\x09\x8f\ +\x87\x01\xac\x90\x65\xf9\x9f\x7c\x3e\xdf\xf6\x54\x2a\xb5\xd0\xe3\ +\xf5\xbe\xdc\x71\xfa\xd5\xef\xcf\x3e\xe5\xec\xaf\x09\x2e\x06\x0c\ +\x43\x53\xe2\x91\x70\xf7\xde\x1d\x1b\x77\x6f\xfc\xcd\x93\xa3\xaa\ +\x9a\xf6\x41\x57\x7d\x86\x11\x0c\x08\xdd\x5b\x25\xb8\x56\x45\xa1\ +\x13\x64\x42\xaf\x97\x99\xde\xe0\x96\x8c\xda\x6a\x9f\x41\x2d\x0f\ +\xc6\xa4\x99\xf3\x3b\xfb\xa4\x2a\x55\x51\xe2\x0b\xe6\xe0\x0e\x83\ +\x23\xab\xab\xf0\x65\x54\xe1\xf3\xbb\xb8\xa7\xfb\x88\xb1\x64\xcd\ +\x3b\x9d\xcf\xca\x2e\xd6\x00\x78\x83\x0c\xc2\xc7\x60\xb8\x05\x87\ +\x94\x48\xc3\x08\xa7\xb8\x72\x24\x2a\xbc\x9a\x67\xda\x17\x3b\xe6\ +\xcc\x98\xd1\xd5\xd5\x95\x08\x85\x42\xf7\x00\x78\xf4\xb3\x6c\x89\ +\x19\x84\x84\x25\xc2\x14\x0b\x33\x08\x11\xc3\x30\xc6\x1a\x1a\x1a\ +\xb6\x64\x32\x99\x85\xfe\x40\x70\xd7\x57\x6e\xbc\x77\x9a\xcb\xed\ +\x35\xb3\xed\xfb\x5d\xbb\xf7\xbc\xb1\xa3\x73\x6b\x94\x43\x97\x1a\ +\x4f\xfa\x32\xe3\x5c\x65\xa4\x89\xc4\xf5\x2c\x33\xd4\xb4\xa4\x2b\ +\x29\x49\x57\x93\x32\x65\x6f\x59\xa3\x96\x67\x53\xee\x31\x2d\xed\ +\x19\x1c\x63\x0b\xdd\xcd\xcb\x1e\xdd\xd9\xf5\x3a\x24\x86\x07\x3b\ +\xa6\x62\x9b\x00\x1d\x6a\x90\xb8\x4c\xe9\xc4\xa5\xde\x3e\x2c\xd8\ +\x5b\x4f\xae\x1f\x9b\x75\xe1\xb2\x59\xcf\xb7\x34\xf8\xd3\xe3\xb1\ +\xd4\xb4\xd1\x68\xfa\x84\x70\x4c\x9f\x6f\x48\xfe\x99\x9e\x40\x5d\ +\xa3\xab\xc6\x1f\x8c\x86\xc3\xea\xce\xee\xf7\x5e\xd6\x75\x7d\x39\ +\x80\x5d\x04\xed\xf3\xfc\xaf\x31\x66\x89\x55\x4b\x98\x6a\x95\xca\ +\x24\xd5\xd5\x9b\xa8\x26\xdf\xd6\xdc\xdc\xfc\x0d\x7a\x87\x50\xd2\ +\xe9\x74\xe2\x8d\x37\xde\xd8\x3d\xc9\x96\x86\x80\x05\xd3\x98\x10\ +\x9c\xc3\xe0\x42\x37\xe8\x48\xe5\x86\x9a\x11\xdb\xb6\xed\xa8\x86\ +\xb7\x7a\xed\xde\xbd\x9f\xcc\xeb\xec\xec\xdc\x0e\xe0\x4c\x82\xfe\ +\x8f\x00\xd6\x2d\x06\x4b\x8d\x83\x45\x63\x90\x7b\x13\xec\x2c\xba\ +\xf3\x79\xb7\xdb\xdd\xec\xf5\x7a\x55\x6a\x99\xcb\xe5\x72\x93\x81\ +\xc8\x1a\xf1\x78\x7c\xbf\xa2\x28\x6b\x01\xfc\x5a\x08\xd1\x5d\x40\ +\xbc\x9c\x07\x94\x08\x09\x8d\x10\x21\x28\x84\x26\xc2\x14\x55\x55\ +\xe3\xe6\xba\x9a\xda\xa6\x97\xc9\xc8\x2b\x38\x00\x97\x53\x00\xe7\ +\x9f\x3d\x18\x63\x1c\x8c\x41\xa2\x1f\x78\xdc\x02\xf0\xf1\x77\x37\ +\x7c\xd4\xee\xf7\x57\x3d\x91\x88\xc6\xe6\x6d\xdb\xb6\x6d\x14\xc0\ +\x35\xd6\x78\x99\x04\x90\xf0\x31\x64\xab\x2a\xd5\xe4\x77\x54\x70\ +\x0b\xe5\xa1\xb3\x08\xb5\xd6\x73\x85\x09\xfb\x09\xa6\x70\x7d\xd6\ +\x62\x4e\x54\x66\x57\xb8\x30\x24\x92\xd6\x97\x66\x69\xc6\x37\x92\ +\x00\x4a\x22\x91\x38\xe3\xc0\x81\x03\xaf\x51\x79\xe4\x74\x2e\x13\ +\x49\x13\x92\x55\x21\x72\xe4\xf3\x13\x2f\x0c\xab\x95\x48\x2c\xb1\ +\x6e\xdd\xba\x36\xba\x7e\x3d\x2d\x4f\xbf\x73\xe8\xd0\x21\xff\xa6\ +\x4d\x9b\xc6\xe9\xda\x5f\x01\xc8\x12\xda\x26\x7c\xa7\x36\xc1\x0b\ +\x93\x84\xdd\x84\x4e\x42\x8a\x90\xb1\x26\x45\x2f\x47\xba\x74\x08\ +\x1c\xff\x7d\x32\x21\xe0\xf1\x78\xbe\x4d\x1e\xb0\x9c\xc2\x60\xe5\ +\xa9\xa7\x9e\xba\x9e\x92\xa3\x9b\x5c\x93\x51\x82\xe4\xe4\x9a\x3a\ +\x09\xa2\x72\xce\x0d\x1a\x23\x28\x5f\xc8\xe3\xe3\xe3\x33\xfc\x7e\ +\xff\x29\x34\xe6\x22\x6a\x97\x51\x82\x62\x94\xa1\x0d\xea\xff\x10\ +\xc0\x2a\xc2\x51\x8b\x50\xc2\x2a\xc9\xb1\x1c\x51\x27\x41\x6e\x41\ +\xe0\x73\x1a\xab\xc0\xfd\x26\xae\x63\x8c\x3d\x4c\xa4\x6a\xab\xaa\ +\xaa\x86\x89\x58\x8a\xda\x0c\x09\x20\x3c\x79\xf3\xd1\xf5\x06\x42\ +\x8d\x39\xfb\xe4\x39\x88\x44\x22\xc6\xd0\xd0\x50\x2f\x79\xc2\x06\ +\x6b\x69\x3a\x60\x11\x4d\x12\xd2\x96\x08\x9a\x4d\xf6\x77\x63\x0c\ +\x95\xb3\x2a\xc2\x97\x09\xa7\x13\xda\x2c\xc2\x75\x04\x37\xe7\x5c\ +\xb2\x5e\x41\x23\x84\x83\x84\x6e\xc2\xfb\x84\x7e\x6b\xa6\x8d\x72\ +\x7f\xd6\xfb\x03\x10\xa0\xf0\xf3\x1c\xff\x0a\xc0\xf9\x17\x56\x81\ +\xdf\x13\xfb\x1f\x84\xaf\xe2\x02\x22\xe6\xe9\x93\x00\x00\x00\x00\ +\x49\x45\x4e\x44\xae\x42\x60\x82\ +" + +qt_resource_name = b"\ +\x00\x10\ +\x0f\xad\xca\x47\ +\x00\x68\ +\x00\x65\x00\x6c\x00\x70\x00\x2d\x00\x62\x00\x72\x00\x6f\x00\x77\x00\x73\x00\x65\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0a\ +\x08\x99\x64\x87\ +\x00\x6b\ +\x00\x63\x00\x68\x00\x61\x00\x72\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0b\ +\x01\xad\xab\x47\ +\x00\x64\ +\x00\x69\x00\x67\x00\x69\x00\x6b\x00\x61\x00\x6d\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x1a\ +\x08\xdd\xe1\xa7\ +\x00\x61\ +\x00\x63\x00\x63\x00\x65\x00\x73\x00\x73\x00\x6f\x00\x72\x00\x69\x00\x65\x00\x73\x00\x2d\x00\x64\x00\x69\x00\x63\x00\x74\x00\x69\ +\x00\x6f\x00\x6e\x00\x61\x00\x72\x00\x79\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x07\ +\x0e\x95\x57\x87\ +\x00\x6b\ +\x00\x33\x00\x62\x00\x2e\x00\x70\x00\x6e\x00\x67\ +\x00\x0d\ +\x0b\x34\x2d\xe7\ +\x00\x61\ +\x00\x6b\x00\x72\x00\x65\x00\x67\x00\x61\x00\x74\x00\x6f\x00\x72\x00\x2e\x00\x70\x00\x6e\x00\x67\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x01\ +\x00\x00\x00\x40\x00\x00\x00\x00\x00\x01\x00\x00\x2e\x67\ +\x00\x00\x00\x26\x00\x00\x00\x00\x00\x01\x00\x00\x1b\x4c\ +\x00\x00\x00\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x3b\x71\ +\x00\x00\x00\xaa\x00\x00\x00\x00\x00\x01\x00\x00\x70\xa9\ +\x00\x00\x00\x96\x00\x00\x00\x00\x00\x01\x00\x00\x50\x89\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/codeeditor/codeeditor.py b/examples/widgets/codeeditor/codeeditor.py new file mode 100644 index 0000000..331069f --- /dev/null +++ b/examples/widgets/codeeditor/codeeditor.py @@ -0,0 +1,141 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot, Qt, QRect, QSize +from PySide2.QtGui import QColor, QPainter, QTextFormat +from PySide2.QtWidgets import QPlainTextEdit, QWidget, QTextEdit + + +class LineNumberArea(QWidget): + def __init__(self, editor): + QWidget.__init__(self, editor) + self.codeEditor = editor + + def sizeHint(self): + return QSize(self.codeEditor.line_number_area_width(), 0) + + def paintEvent(self, event): + self.codeEditor.lineNumberAreaPaintEvent(event) + + +class CodeEditor(QPlainTextEdit): + def __init__(self): + QPlainTextEdit.__init__(self) + self.line_number_area = LineNumberArea(self) + + self.blockCountChanged[int].connect(self.update_line_number_area_width) + self.updateRequest[QRect, int].connect(self.update_line_number_area) + self.cursorPositionChanged.connect(self.highlight_current_line) + + self.update_line_number_area_width(0) + self.highlight_current_line() + + def line_number_area_width(self): + digits = 1 + max_num = max(1, self.blockCount()) + while max_num >= 10: + max_num *= 0.1 + digits += 1 + + space = 3 + self.fontMetrics().width('9') * digits + return space + + def resizeEvent(self, e): + super().resizeEvent(e) + cr = self.contentsRect() + width = self.line_number_area_width() + rect = QRect(cr.left(), cr.top(), width, cr.height()) + self.line_number_area.setGeometry(rect) + + def lineNumberAreaPaintEvent(self, event): + painter = QPainter(self.line_number_area) + painter.fillRect(event.rect(), Qt.lightGray) + block = self.firstVisibleBlock() + block_number = block.blockNumber() + offset = self.contentOffset() + top = self.blockBoundingGeometry(block).translated(offset).top() + bottom = top + self.blockBoundingRect(block).height() + + while block.isValid() and top <= event.rect().bottom(): + if block.isVisible() and bottom >= event.rect().top(): + number = str(block_number + 1) + painter.setPen(Qt.black) + width = self.line_number_area.width() + height = self.fontMetrics().height() + painter.drawText(0, top, width, height, Qt.AlignRight, number) + + block = block.next() + top = bottom + bottom = top + self.blockBoundingRect(block).height() + block_number += 1 + + @Slot() + def update_line_number_area_width(self, newBlockCount): + self.setViewportMargins(self.line_number_area_width(), 0, 0, 0) + + @Slot() + def update_line_number_area(self, rect, dy): + if dy: + self.line_number_area.scroll(0, dy) + else: + width = self.line_number_area.width() + self.line_number_area.update(0, rect.y(), width, rect.height()) + + if rect.contains(self.viewport().rect()): + self.update_line_number_area_width(0) + + @Slot() + def highlight_current_line(self): + extra_selections = [] + + if not self.isReadOnly(): + selection = QTextEdit.ExtraSelection() + + line_color = QColor(Qt.yellow).lighter(160) + selection.format.setBackground(line_color) + + selection.format.setProperty(QTextFormat.FullWidthSelection, True) + + selection.cursor = self.textCursor() + selection.cursor.clearSelection() + + extra_selections.append(selection) + + self.setExtraSelections(extra_selections) diff --git a/examples/widgets/codeeditor/main.py b/examples/widgets/codeeditor/main.py new file mode 100644 index 0000000..14c2e08 --- /dev/null +++ b/examples/widgets/codeeditor/main.py @@ -0,0 +1,52 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtWidgets import QApplication +from codeeditor import CodeEditor + +"""PySide2 port of the widgets/codeeditor example from Qt5""" + +if __name__ == "__main__": + app = QApplication([]) + editor = CodeEditor() + editor.setWindowTitle("Code Editor Example") + editor.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/dialogs/classwizard/classwizard.py b/examples/widgets/dialogs/classwizard/classwizard.py new file mode 100644 index 0000000..d0e970f --- /dev/null +++ b/examples/widgets/dialogs/classwizard/classwizard.py @@ -0,0 +1,404 @@ +# -*- coding: utf-8 -*- +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import unicode_literals +from PySide2 import QtCore, QtGui, QtWidgets + +import classwizard_rc + + +class ClassWizard(QtWidgets.QWizard): + def __init__(self, parent=None): + super(ClassWizard, self).__init__(parent) + + self.addPage(IntroPage()) + self.addPage(ClassInfoPage()) + self.addPage(CodeStylePage()) + self.addPage(OutputFilesPage()) + self.addPage(ConclusionPage()) + + self.setPixmap(QtWidgets.QWizard.BannerPixmap, + QtGui.QPixmap(':/images/banner.png')) + self.setPixmap(QtWidgets.QWizard.BackgroundPixmap, + QtGui.QPixmap(':/images/background.png')) + + self.setWindowTitle("Class Wizard") + + def accept(self): + className = self.field('className') + baseClass = self.field('baseClass') + macroName = self.field('macroName') + baseInclude = self.field('baseInclude') + + outputDir = self.field('outputDir') + header = self.field('header') + implementation = self.field('implementation') + + block = '' + + if self.field('comment'): + block += '/*\n' + block += ' ' + header + '\n' + block += '*/\n' + block += '\n' + + if self.field('protect'): + block += '#ifndef ' + macroName + '\n' + block += '#define ' + macroName + '\n' + block += '\n' + + if self.field('includeBase'): + block += '#include ' + baseInclude + '\n' + block += '\n' + + block += 'class ' + className + if baseClass: + block += ' : public ' + baseClass + + block += '\n' + block += '{\n' + + if self.field('qobjectMacro'): + block += ' Q_OBJECT\n' + block += '\n' + + block += 'public:\n' + + if self.field('qobjectCtor'): + block += ' ' + className + '(QObject *parent = 0);\n' + elif self.field('qwidgetCtor'): + block += ' ' + className + '(QWidget *parent = 0);\n' + elif self.field('defaultCtor'): + block += ' ' + className + '();\n' + + if self.field('copyCtor'): + block += ' ' + className + '(const ' + className + ' &other);\n' + block += '\n' + block += ' ' + className + ' &operator=' + '(const ' + className + ' &other);\n' + + block += '};\n' + + if self.field('protect'): + block += '\n' + block += '#endif\n' + + headerFile = QtCore.QFile(outputDir + '/' + header) + + if not headerFile.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(None, "Class Wizard", + "Cannot write file %s:\n%s" % (headerFile.fileName(), headerFile.errorString())) + return + + headerFile.write(QtCore.QByteArray(block.encode("utf-8"))) + + block = '' + + if self.field('comment'): + block += '/*\n' + block += ' ' + implementation + '\n' + block += '*/\n' + block += '\n' + + block += '#include "' + header + '"\n' + block += '\n' + + if self.field('qobjectCtor'): + block += className + '::' + className + '(QObject *parent)\n' + block += ' : ' + baseClass + '(parent)\n' + block += '{\n' + block += '}\n' + elif self.field('qwidgetCtor'): + block += className + '::' + className + '(QWidget *parent)\n' + block += ' : ' + baseClass + '(parent)\n' + block += '{\n' + block += '}\n' + elif self.field('defaultCtor'): + block += className + '::' + className + '()\n' + block += '{\n' + block += ' // missing code\n' + block += '}\n' + + if self.field('copyCtor'): + block += '\n' + block += className + '::' + className + '(const ' + className + ' &other)\n' + block += '{\n' + block += ' *this = other;\n' + block += '}\n' + block += '\n' + block += className + ' &' + className + '::operator=(const ' + className + ' &other)\n' + block += '{\n' + + if baseClass: + block += ' ' + baseClass + '::operator=(other);\n' + + block += ' // missing code\n' + block += ' return *this;\n' + block += '}\n' + + implementationFile = QtCore.QFile(outputDir + '/' + implementation) + + if not implementationFile.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(None, "Class Wizard", + "Cannot write file %s:\n%s" % (implementationFile.fileName(), implementationFile.errorString())) + return + + implementationFile.write(QtCore.QByteArray(block.encode("utf-8"))) + + super(ClassWizard, self).accept() + + +class IntroPage(QtWidgets.QWizardPage): + def __init__(self, parent=None): + super(IntroPage, self).__init__(parent) + + self.setTitle("Introduction") + self.setPixmap(QtWidgets.QWizard.WatermarkPixmap, + QtGui.QPixmap(':/images/watermark1.png')) + + label = QtWidgets.QLabel("This wizard will generate a skeleton C++ class " + "definition, including a few functions. You simply need to " + "specify the class name and set a few options to produce a " + "header file and an implementation file for your new C++ " + "class.") + label.setWordWrap(True) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(label) + self.setLayout(layout) + + +class ClassInfoPage(QtWidgets.QWizardPage): + def __init__(self, parent=None): + super(ClassInfoPage, self).__init__(parent) + + self.setTitle("Class Information") + self.setSubTitle("Specify basic information about the class for " + "which you want to generate skeleton source code files.") + self.setPixmap(QtWidgets.QWizard.LogoPixmap, + QtGui.QPixmap(':/images/logo1.png')) + + classNameLabel = QtWidgets.QLabel("&Class name:") + classNameLineEdit = QtWidgets.QLineEdit() + classNameLabel.setBuddy(classNameLineEdit) + + baseClassLabel = QtWidgets.QLabel("B&ase class:") + baseClassLineEdit = QtWidgets.QLineEdit() + baseClassLabel.setBuddy(baseClassLineEdit) + + qobjectMacroCheckBox = QtWidgets.QCheckBox("Generate Q_OBJECT ¯o") + + groupBox = QtWidgets.QGroupBox("C&onstructor") + + qobjectCtorRadioButton = QtWidgets.QRadioButton("&QObject-style constructor") + qwidgetCtorRadioButton = QtWidgets.QRadioButton("Q&Widget-style constructor") + defaultCtorRadioButton = QtWidgets.QRadioButton("&Default constructor") + copyCtorCheckBox = QtWidgets.QCheckBox("&Generate copy constructor and operator=") + + defaultCtorRadioButton.setChecked(True) + + defaultCtorRadioButton.toggled.connect(copyCtorCheckBox.setEnabled) + + self.registerField('className*', classNameLineEdit) + self.registerField('baseClass', baseClassLineEdit) + self.registerField('qobjectMacro', qobjectMacroCheckBox) + self.registerField('qobjectCtor', qobjectCtorRadioButton) + self.registerField('qwidgetCtor', qwidgetCtorRadioButton) + self.registerField('defaultCtor', defaultCtorRadioButton) + self.registerField('copyCtor', copyCtorCheckBox) + + groupBoxLayout = QtWidgets.QVBoxLayout() + groupBoxLayout.addWidget(qobjectCtorRadioButton) + groupBoxLayout.addWidget(qwidgetCtorRadioButton) + groupBoxLayout.addWidget(defaultCtorRadioButton) + groupBoxLayout.addWidget(copyCtorCheckBox) + groupBox.setLayout(groupBoxLayout) + + layout = QtWidgets.QGridLayout() + layout.addWidget(classNameLabel, 0, 0) + layout.addWidget(classNameLineEdit, 0, 1) + layout.addWidget(baseClassLabel, 1, 0) + layout.addWidget(baseClassLineEdit, 1, 1) + layout.addWidget(qobjectMacroCheckBox, 2, 0, 1, 2) + layout.addWidget(groupBox, 3, 0, 1, 2) + self.setLayout(layout) + + +class CodeStylePage(QtWidgets.QWizardPage): + def __init__(self, parent=None): + super(CodeStylePage, self).__init__(parent) + + self.setTitle("Code Style Options") + self.setSubTitle("Choose the formatting of the generated code.") + self.setPixmap(QtWidgets.QWizard.LogoPixmap, + QtGui.QPixmap(':/images/logo2.png')) + + commentCheckBox = QtWidgets.QCheckBox("&Start generated files with a " + "comment") + commentCheckBox.setChecked(True) + + protectCheckBox = QtWidgets.QCheckBox("&Protect header file against " + "multiple inclusions") + protectCheckBox.setChecked(True) + + macroNameLabel = QtWidgets.QLabel("&Macro name:") + self.macroNameLineEdit = QtWidgets.QLineEdit() + macroNameLabel.setBuddy(self.macroNameLineEdit) + + self.includeBaseCheckBox = QtWidgets.QCheckBox("&Include base class " + "definition") + self.baseIncludeLabel = QtWidgets.QLabel("Base class include:") + self.baseIncludeLineEdit = QtWidgets.QLineEdit() + self.baseIncludeLabel.setBuddy(self.baseIncludeLineEdit) + + protectCheckBox.toggled.connect(macroNameLabel.setEnabled) + protectCheckBox.toggled.connect(self.macroNameLineEdit.setEnabled) + self.includeBaseCheckBox.toggled.connect(self.baseIncludeLabel.setEnabled) + self.includeBaseCheckBox.toggled.connect(self.baseIncludeLineEdit.setEnabled) + + self.registerField('comment', commentCheckBox) + self.registerField('protect', protectCheckBox) + self.registerField('macroName', self.macroNameLineEdit) + self.registerField('includeBase', self.includeBaseCheckBox) + self.registerField('baseInclude', self.baseIncludeLineEdit) + + layout = QtWidgets.QGridLayout() + layout.setColumnMinimumWidth(0, 20) + layout.addWidget(commentCheckBox, 0, 0, 1, 3) + layout.addWidget(protectCheckBox, 1, 0, 1, 3) + layout.addWidget(macroNameLabel, 2, 1) + layout.addWidget(self.macroNameLineEdit, 2, 2) + layout.addWidget(self.includeBaseCheckBox, 3, 0, 1, 3) + layout.addWidget(self.baseIncludeLabel, 4, 1) + layout.addWidget(self.baseIncludeLineEdit, 4, 2) + self.setLayout(layout) + + def initializePage(self): + className = self.field('className') + self.macroNameLineEdit.setText(className.upper() + "_H") + + baseClass = self.field('baseClass') + is_baseClass = bool(baseClass) + + self.includeBaseCheckBox.setChecked(is_baseClass) + self.includeBaseCheckBox.setEnabled(is_baseClass) + self.baseIncludeLabel.setEnabled(is_baseClass) + self.baseIncludeLineEdit.setEnabled(is_baseClass) + + if not is_baseClass: + self.baseIncludeLineEdit.clear() + elif QtCore.QRegularExpression('^Q[A-Z].*$').match(baseClass).hasMatch(): + self.baseIncludeLineEdit.setText('<' + baseClass + '>') + else: + self.baseIncludeLineEdit.setText('"' + baseClass.lower() + '.h"') + + +class OutputFilesPage(QtWidgets.QWizardPage): + def __init__(self, parent=None): + super(OutputFilesPage, self).__init__(parent) + + self.setTitle("Output Files") + self.setSubTitle("Specify where you want the wizard to put the " + "generated skeleton code.") + self.setPixmap(QtWidgets.QWizard.LogoPixmap, + QtGui.QPixmap(':/images/logo3.png')) + + outputDirLabel = QtWidgets.QLabel("&Output directory:") + self.outputDirLineEdit = QtWidgets.QLineEdit() + outputDirLabel.setBuddy(self.outputDirLineEdit) + + headerLabel = QtWidgets.QLabel("&Header file name:") + self.headerLineEdit = QtWidgets.QLineEdit() + headerLabel.setBuddy(self.headerLineEdit) + + implementationLabel = QtWidgets.QLabel("&Implementation file name:") + self.implementationLineEdit = QtWidgets.QLineEdit() + implementationLabel.setBuddy(self.implementationLineEdit) + + self.registerField('outputDir*', self.outputDirLineEdit) + self.registerField('header*', self.headerLineEdit) + self.registerField('implementation*', self.implementationLineEdit) + + layout = QtWidgets.QGridLayout() + layout.addWidget(outputDirLabel, 0, 0) + layout.addWidget(self.outputDirLineEdit, 0, 1) + layout.addWidget(headerLabel, 1, 0) + layout.addWidget(self.headerLineEdit, 1, 1) + layout.addWidget(implementationLabel, 2, 0) + layout.addWidget(self.implementationLineEdit, 2, 1) + self.setLayout(layout) + + def initializePage(self): + className = self.field('className') + self.headerLineEdit.setText(className.lower() + '.h') + self.implementationLineEdit.setText(className.lower() + '.cpp') + self.outputDirLineEdit.setText(QtCore.QDir.toNativeSeparators(QtCore.QDir.tempPath())) + + +class ConclusionPage(QtWidgets.QWizardPage): + def __init__(self, parent=None): + super(ConclusionPage, self).__init__(parent) + + self.setTitle("Conclusion") + self.setPixmap(QtWidgets.QWizard.WatermarkPixmap, + QtGui.QPixmap(':/images/watermark2.png')) + + self.label = QtWidgets.QLabel() + self.label.setWordWrap(True) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(self.label) + self.setLayout(layout) + + def initializePage(self): + finishText = self.wizard().buttonText(QtWidgets.QWizard.FinishButton) + finishText.replace('&', '') + self.label.setText("Click %s to generate the class skeleton." % finishText) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + wizard = ClassWizard() + wizard.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/dialogs/classwizard/classwizard.pyproject b/examples/widgets/dialogs/classwizard/classwizard.pyproject new file mode 100644 index 0000000..1c1fe99 --- /dev/null +++ b/examples/widgets/dialogs/classwizard/classwizard.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["classwizard.qrc", "classwizard.py", "classwizard_rc.py", + "classwizard_rc.pyc"] +} diff --git a/examples/widgets/dialogs/classwizard/classwizard.qrc b/examples/widgets/dialogs/classwizard/classwizard.qrc new file mode 100644 index 0000000..41a5ddc --- /dev/null +++ b/examples/widgets/dialogs/classwizard/classwizard.qrc @@ -0,0 +1,11 @@ + + + images/background.png + images/banner.png + images/logo1.png + images/logo2.png + images/logo3.png + images/watermark1.png + images/watermark2.png + + diff --git a/examples/widgets/dialogs/classwizard/classwizard_rc.py b/examples/widgets/dialogs/classwizard/classwizard_rc.py new file mode 100644 index 0000000..e79a959 --- /dev/null +++ b/examples/widgets/dialogs/classwizard/classwizard_rc.py @@ -0,0 +1,3892 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00:@\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\xa8\x00\x00\x01w\x08\x03\x00\x00\x00\x06\x8a\xf0\xc8\ +\x00\x00\x02\xd9PLTE\xad\xac\xff\xc4\x90\xc4\xe2Z\ +c\xe6\xc1\xd5\xe9\x9c\xa7\xb8\xb6\xfe\xc8\xc6\xfe\xcb\xcb\xfe\ +\xbb\xbb\xff\xc0\xbe\xfe\xc3\xc3\xfe\xd2\xd2\xff\xd8\xd7\xff\xdc\ +\xdb\xfe\xb3\xb3\xfe\xe2\xe2\xfe\xb0\xae\xfe\xd0\xce\xfe\xeb\xeb\ +\xfe\xf3\xf3\xfe\xfc\xfb\xfe\xdd\x06\x08\xda\x22,\xdc\x0d\x12\ +\xb7\x8f\xd1\xe0\xde\xfe\xeaZZ\xdd\x09\x0b\xdd\x19\x1e\xfc\ +\xec\xec\xde\x00\x00\xf0\xef\xfd\xe1\x13\x13\xbf\xa1\xde\xbb\xb2\ +\xf4\xe3##\xe522\xe6::\xe6AB\xcc\xc3\xf4\ +\xe9SS\xdc\x14\x1a\xbd\x81\xbb\xecll\xedrr\xee\ +{{\xf2\x9b\x9b\xf2\xa2\xa2\xd2\x81\xa2\xf4\xac\xac\xf6\xb9\ +\xb9\xfa\xdb\xdb\xfa\xf5\xfa\xfb\xe2\xe2\xdd\x10\x15\xbd\xab\xeb\ +\xfd\xf2\xf3\xe4,,\xebcc\xf0\x8b\x8b\xf5\xcd\xd1\xd6\ ++<\xd8-;\xd8FX\xcaV{\xd9%1\xd94\ +C\xd9BR\xd9m\x83\xda\x1b%\xcau\x9e\xda1=\ +\xdaRd\xdb\x1a\x22\xdb\x85\x9d\xb2\xa9\xf5\xdc\xd3\xf5\xcc\ +i\x8d\xcc\x84\xad\xcc\x8b\xb4\xbb\xa3\xe3\xcdJi\xddP\ +^\xb7\xb0\xf7\xdf07\xcdZ{\xcd\xa1\xcd\xe2\x1a\x1a\ +\xceq\x94\xce\xc0\xef\xe4\xaa\xbd\xcf9T\xcf@[\xcf\ +\xba\xe7\xd0_~\xe8EE\xe8LL\xd0\xad\xd8\xe9o\ +t\xbe\x8a\xc3\xd1Vq\xea\xe6\xfb\xd2z\x9a\xc4\xab\xe3\ +\xd2\x89\xab\xecvx\xd2\xcb\xf7\xc5\x83\xb4\xee\x8f\x91\xef\ +\x81\x81\xf0\x84\x84\xf8\xcb\xcb\xd3D\x5c\xf1\x93\x93\xd3S\ +m\xd45I\xd4Kb\xd4i\x84\xf4\xe2\xe9\xf5\xb3\xb3\ +\xe0\x0b\x0b\xd4\xc2\xeb\xf6\xd8\xdc\xf7\xc3\xc3\xd5b{\xf9\ +\xd4\xd4\xc8\xbd\xf3\xd5\xa5\xc8\xd6'7\xbe\x9a\xd5\xd7I\ +]\xd4Zs\xca\x86\xb2\xcbt\x9b\xf8\xc5\xc5\xd69L\ +\xce\x80\xa6\xcba\x85\xcd\x9a\xc4\xdf\xa8\xc0\xd3\x9a\xbe\xcb\ +z\xa2\xe4y\x84\xd4Ng\xd5@T\xe6s|\xc4\xba\ +\xf4\xe6\xc6\xda\xe7jp\xe7\xb8\xc9\xc5f\x92\xe8^`\ +\xe8\x84\x8c\xc5s\xa1\xcd\x92\xbb\xb6\x9b\xe0\xcd\xb0\xde\xeb\ +\xad\xb7\xeb\xe2\xf4\xc5\x8a\xbb\xd7\xb5\xd8\xcd\xac\xda\xc5\xa0\ +\xd5\xed\xa3\xaa\xcd\xba\xea\xceUv\xc6\x5c\x86\xc8\x92\xc1\ +\xd9Ym\xf0\xac\xb1\xc8\xb3\xe8\xd9\x87\xa1\xf1\x9e\xa1\xc0\ +\xb6\xf4\xb9\x87\xc6\xf2\xbf\xc5\xda)5\xc2\x9b\xd3\xca\x5c\ +\x81\xf4\xe9\xf1\xd0m\x8d\xdbKZ\xd0\xa6\xd0\xcad\x8c\ +\xdc:F\xc2\xa2\xda\xde\x98\xaf\xd1\x8d\xb1\xd1\xc5\xf1\xb9\ +\xa6\xe9\xd2\xbb\xe5\xd2\x9d\xc2\xcc\xa5\xd2\xde\xb1\xcc\xd3t\ +\x92\xe1\x87\ +\xa7f\xd1\x13T\xa2\xca>>Y\x8cb\xf2\x80\x90\x19\ +\xba\xe2\x97O/\xff\xbd\xc5\xc5\x1f50\xdcc\x96*\ +f\xe2\xcf4\xeb\xa8\x8a\x9fz@\x18\xe6\x11L\xc4\xea\ +\x0b\x1f\x03g\x85\x15\x97|!4&\xc2\xea\xd8y\xeb\ +e{F\x8b\x8e\x0e+\xfd\x10\x0fq\xb2#\x8d\xe3Q\ +\xa1\x1eB\xb50]\xb4\xe7\xa1\xe4\x98\x94<\xbe\xc0D\ +\xefT\x050+\x01Yf\xee>\x7f\xfd\xa2\xd0\xcdM\ +\xe0\xa7\x04%\x14\xe2'\xdcS\xe0\xf2\x99\xa3\x8cP\xa0\ +\xe2-K(\xad\xf6\xc4Pg\xfb\x08\x12\xde\x9a\xb2r\ +\xf9S\x8b>\xad\x19\xa8\xa8Y\x8c>b)X\x12C\ +\xed!O\x0b\x5c\xf3{p\x19\xac\x80\x10C\xd1B,\ +Ig#\xd6\x972GaQR:j\x9f\xa7\xa7\x14\ +\xce\xd1\xfea*\xc2O\xaf\xf5\x9a\xa1\x05\xf2\x14\xf5\x13\ +m\x89)G[\xa2t\x84\xd9Y)\xc9+\x8e>}\ +\x96H\xffp\x87ov\xcb\x8e\xc3\xb6\x1e0_W\x19\ +\xa0\x19a\x9cP\x09\x1e9|\xb4\xa7&\xc5\xf7\x82\x15\ +\x90\xe2\x12\x8a0EI\xc5\xe6I\xf2\xb5\xc7Os\xb9\ + \x9f\xc3\xa6\xaa|\xfb\xe2\xe8\x1b5\x1a\xfd\xcf\x00\xe6\ +\xe6\x85A\xab2\xeaz\xe6\x9aM\xc3>\x02%\xb0\x88\ +6N\xef\xd8\xe6e\x0d5\x18\x1dG%(\x01\x80Q\ +\xb2\x0c\xaf\x5cY=F\xf8\x10;\xdf\xf8\xa5\xbb>7\ +5\x7f\xf4\xd4h\xb4\xaa\x8f,=\xdf\x02\xdd\xc3[\xb9G\xb3\x05\x09\xff^1\xa3\x91\xfd\x19\x9d\ +s#\x85yO\x1f~\xccr\x0a\x9b\xff\xf5x\xcb\x82\ ++\x87\xa50\x94\x0b:I\xd1{.\x1f\x82{\x0aJ\ +\xec\xf3\xa7\x82dc?\xcfa\xbd'\x98\xef8Z\x9b\ +\xc5\x8e\x1cyzFd1s\xff\x04\x1c\x05\x1e^x\ +\xcaYYv\xee\xaf\x8eZ\xef$\xb1s\xe0gwl\ +Gq\x98\x17\x97\x9ep\x09\x05\xac\x17[0\x93o\xdd\ +\xbf\xe8\x94T`\xe6\xf5\x0d#\xc6\xb1l\x19x\xf2>\ +\xad\xf6'FH/|\x0f\xf0t\xb9\xc3=?\xc5\xce\ +\xeb\xe0\xb0jg^r\xa7\xd7\xcf\xb6\x02\xcarw\x84\ +%\x1d'\xfc\xde\xe5\x7f\xbfc\xf7\xb0\xff\x1a\x0bd\xa1\ +G\x09\x09\xa8\xe8\xe1\x0e\xc2\xfe?_\x18\xf4\xaf\xff\xa9\ +\xfd|<\xc7 \xbfl L\x0e\xf0\x83\xca\xb3\ +\x88\x1e\xeef\xe0I)\xb9\xeb9G\xfa\x0a\x8b\xe3\xc1\ +\x16\xc0$\xba\xc2\x0an\xf6\x85a\xbfa`\x7f\xc0\x02\ +\xd8\xd2\xaa*\x84\x9a\xbf\xf1\x83[\xb6\xef\xb8\xf3\x91\x07\ +\x06\xfd\xf7\xfc\x0d\xb0{PZ:Y\xe1\xbcj\xf7\x00\ +\xfc=3\xb4\x8b\x0bRLA\xfd\xa1\xa0\xb5\xbe\xd0%\ +\xb2\xb5s\xb0\xbe\x007\xc9\xe6\xeb\xc7~zpa\xd0\ +\xc9\xf3\x1b\xcf<\xfd\xb5 \xec\xd9~U\x8a\xd7\xaf\xf2\ +\xdaeM{\x17!\xa0\x83\xea\xc3\xf9\x02s\xf2\xb6\x07\ +\x06\xad\xb2-@M\x0e\xda%cJ\xc5\xa3Q\x94\x07\ +i\x88\xc3\xcau\xdcc\xac\x90\x07\x06\xa5\x8f\xb5\xd12\ +\xcc<\xf3\x17\xcc\xa1\xf9!U\xa0\xce:\xff\xd5\x1c\x91\ +~\x1dl\xee\xc0\x10\xbc\xd3Y{\x16\xe7o;\xb8y\ +\xd3m;v\xef\xea\x14\x921\x8bAq\xf0\xf4\x92\x0e\ +\xbf\xc0\xb5\x1eU\x14\xa2g\xb8\xef\xb7@\xf6\xf5\x1cD\ +\x11\xff\x13_R\xb2\xdcY\xd4P&\xfb\x80\xf1\xe4\xd7\ +<\x01\x01\xe9\xad\xc78\xe3\xde\xdd\xcf\xc0\x91\xee\xbdd\ +a\x00\xf1\x17\x96q\xb9\x92\xdb\x05\xd9\x8b~\xa6E\xaf\ +\xa2\x12L\xebTu\xf4\xbb\xa8\xa4\xc0O\x96\xfe\xf7\x0c\ + \x9f\xeen\xb9\xfa\xe8\x09\xa0\x81'\xde\xf3\xba\xa7p\ +9\x18\xdd6\xcc3\x8b\x14\x88\xb7F\xb2\x92-^r\ +;J\xee\xe2J\x89NF\x5c\x1e\xfa\x9b\xbf\xff\xacN\ +\xeeF\xa4\xa4\x9e\x96^0\x85\x99\xcf\xec\xe6\xadw^\ +\x08J\xea*z/c\xe8\x8c\xb3\x99a\xed\x81\xb1\x96\ +\xc8QOIU\xe0lP+\xa0\xd1\x96\xd8\xc5O^\ +\xf0\xbe\x8b\x0d\xae\xed\x066\xc2d%\x05\x98Dk'\ +\xc1\xfdl\xde=\xec\xb4\x1a\xc5]\xe6{\xfd\xd0\x19\xd2\ +r\x8ds\xe5\x9d\xc3\x1e\xaeL\xeeAi\x03_\xe1\x9b\ +\xcd\x9e\xd7%\xf3\xf9Ry\xfd-\x9f<\xc6\x09\x0b`\ +\xf5\x84\xa3\xa0\xa4\xa3\x85\xc2\x07z\xba\x05\xb1\xea\x91a\ +\xc3\xe6JO\x80.\x1e|\xec\xba\xbdF\xf6\xd5\xbcD\ +\xa3\xa3u\x0f\xee\xea\xe7\x94\xddY\xc2\xdd\x06E\xac\xa5\ +\x13\xe4H\x85\xb4\xe8\x9b\x86\x97\x0f\x1f\xb7^\x99F\x83\ +\xac^<)!\xad\xcdm\x19:\xbf{`\xff\xa3\xfa\ +\x8dI\xc0e\xa3\xac\xd3\x0cWO7\xe6s\xd5\xea\xfd\ +\xfb\xd7\xdd\xbcuaW\xab\xa6\xea\x13p\x95D\x0f7\ +\x9b\x12\xe0\xa4]\x11z\xd2y}\xf3UAT\xbbu\ +\xc6O\x95\xd1\x93\x8a{\xba\xd1ej6z\xae\xce\x9c\ +\x12}|\xb4a\x84\x7f\xc3\xcd;\x87\xcdV\xa7\xd3\xea\ +\xe5T%\x13\xc1\x13G\xc1\x942\xcdR\x854\xad\xa3\ +\x88S\xe8\xc0\x120\x94=),\xf79\xd3\xbb :\ +\xbe\xbe\xce\xdfp\x03\xb0\x13i\xfdB\xcb\xba\xcf\xbc\x97\ +s-O(\xcb\xd8\xf0A?\xe1B\x94\x8c\xd3|\xcb\ +Z\x1f\xeb\xe8\x93\x0e\xe7\xfc\xcd[\x1f}a\xeb\x95P\ +o\x19\xfa\x1c}\x0c\x94\xb4'F\xff\x06\xa7\xc9_;\ +b\xca3\xef\xf5\x9bv\x0esH\x9b!\xabWH}\ +\xbb\xa7M\xc6Lk(\xd7G\xa3\xb5\x9e\xddho\x19\ +\x18\xd0\xd6\xe1\xd2L\xd3\xb8\xa8/\x1bT\xab\x86EA\ +\xf5\xdc\x1c\x95\xb4\xe9\xb1\xf4>m\xda[\xd6\xaf\xbb\xfb\ +q\x93}\xd4\x5c\xc6\xab\xecU\x97B\x82T\xf6\x982\ +eN,\xfa\x908e\xfaM\xf0#\x0b\x03\xfb]\x18\ +\xa4\xe7-\xeeytHi\x93^\xee\x89~\xbe\x07\x02\ +j\xc7\xca\x8d\xfb\x96\x8a~\xab\xa8\xad\xcd\xfbe\x9d@\ +\xf2X\xc6\xe7\xed0\xb5\x19*\xdb7\xdd\x08(\xc7\xf7\ +G\x1a\x18S;\x87\x16&\xacN\xb7\xbc\xef\x81]\xba\ +\x82\xef\x944_\xfe\xb2g&\xe7O\x82\xbd\xd0O\xfc\ +h\xd1\xe1\x5c\xb6\xf1\xb0a\xabv\x05\x9d\xaat\xafR\ +\xa0\x0a3\x19&`\xa3_^\x95\xba\xe8\xf0\xbb\x00\x18\ +I\xd7\xf0\xbf5g83;\xb4:\x80d?\xd4\xde\ +2(\xe9\xec\xbc\x83v[\x03\xd6\xa6'\xdf\xb6n\xcd\ +O\xae\xf9\xf8\xae\xa5&U\xcaJ\xfb\x01\x18\xe9\xf2L\ +\x8a\xb7AK\xf7\xab\xc5.\x85\xbct!\x17nX\xcb\ +w\x0c\xdc\xe62Raof\xe9\xbb\x9eeu\x04\x1d\ +@gZ\xb4:\xcdFO*zuI\xc2G\xb6*\ +\x8b\xf7wB3xH\xee\xba\x09B\xa0\xeaB.\xaa\ +\xe8\x9d\x1d\x17?)\xa4\x00\xf2\x86g\xe6uf\xb1\xb3\ +\x9f\xe3n\x98j\xd6\xb0FT\x0bJ\x8d\xb4$\xa0`\ +\xf3\x8c0\xf3\xc2Q\x00\xa9\xb2\xa60\xc2\x7f\x128\xda\ +\x81\x22>\xd1\xe5'=\xf6p\xcf\xc2\xfc\xdaH\xa1\x9c\ +\x9f\xdd:\xec\xf7 \xb1\xcf\x0b]#\xb3\xbfeE\x84\ + +VR\x14\xbd(@h\xf4\xdd k\x12\xa3\xa2\ +\xc2\xd3w`\xa5\xee\xcb\xb6H\xaf\xb8\xda\x18\xf5\x89\x1d\ +\xe3\xf0\xef\x1b\xc9\xc2=?\xbbe\xe7\xb0?\xd3\xe00\ +\x9f\x8bO\xf6&\xa0\x22w6%x\x891\xc1\x0d\xec\ +\xf4c\x12\xe5\x9d\xdai\xf7dE\xbbr\x094\xd4\x81\ +\xbdz\xbd\xc5\xb6\xafY\x14\xaf#y\x9f\x83 \x11%\ +<\xb5G\x95\x88\xbed\xb0\x0a*\xb9'\xe1\xa8\xc7T\ +\xde\xb9\x83\x8fqe\xc7?\x842L\x0b\xf9Y|\xf7\ +\xcbs\xb0\x00\x0c\x0d\xd0\xcb\x8d~\x1e\xff\xd6-;\x07\ +K\x9d\x06xQBJ\xdc\x14\xaap\xd7\x8e\xc0\xaaE\ +\x94\x8c\x09\xe0\x91\xd5\xc7\x1b\xf6\x91\x86Ns\x84\x0f\xfe\ +\xe9!([|\xff[\xbd\xc6w^u\x1c&\x18\x0f\ +\xbd0\xb4\xe6\xf4\xa17\x9ad\xb2\xd3\xc0\xfd\x86\x00\xa9\ +{J,\xe7aw\x0e\xa4u\xf0(\x0dE3\x02\xb8\ +\x98\x85\xa4q\xb6\x13V\x8fW\xe31\x0a*$6\x19\ +m\x1d6\xf5^\x83 \x05S\x8a8Z\xd6\xdc\xf8\xc0\ +\x18+\x96<\x00%\xd9;\x8efq<\xaa\xeb\x8e\xba\ +\xb1\x00^\xe7,\x06\xb4\xe6\xf1a\x8b J\xcdY\xb1\ +\xd4\xdbe\xc2\xce\x07D\x0b8\xb5\xc3\xa7\x95I\xb4\xd3\ +\x92J\xeb9\xc2\x8f;u\xfc\x12\xd9\xc7\x14\xcc\xd5\xdb\ +MiAsSeL\x96\x22~R7QM\x1a\x0a\ +8\xc5\x96\xd0\xdfg\xa2\xa6\xf1\x16#/N\xe3w\xee\ +>\xb9\x9fP\xae:h\xec\xbb\x09\x05\xbd\x90\xa7\x92\xd7\ +\xe3%0\x81*\xe4(\x1bS\x15YS\x96\xd1*\x0f\ +\xfce\xd1#\xdc\xe4n\x83\xceA\x9bo\xbe{\xe3\xc6\ +M\x07w\x98jR\x93:\xca\x98\x04\xa4\x92\xbd\x904\ +\xbe@\xed!\x82\x097\xb0Q\xaeR[\x93\x94t\x92\ +\xc6\xa4\xa853\x03\xc8\x99\x9b\x0d\xdah\xd2\xb2g\x94\ +\x9ap\xbb\xbe*EI\x85\x9f,{\xbd\xcc\x97Xx\ +\xf2\x9aJ\xe2\x1a~\x5c)\x91\xa0D\xc2<\xa1\x9a/\ +Y=\x0b\xf6\xf7hM\xd2\x9d\x17\xb6@\xf0K\xc1\x14\ +\xa2\x08?\x1d\x8f*\xac\x02So\x84\xe6\x82\x8f6\xeb\ +\xe1\xd2\xed\x8e(z\xba<\xca\xbc\x9e\xa2D\xbf#2\ +Q\xfd\xb4=\xff\x048\x83]P\x07S\xdaG\xf56\ +85B\x8c\x93zU\xd9\x07A\xd6\x9a\xa1\xa0\xa4m\ +\xe6h\x92\xc4\x87\xc6\x05\x88@K{\x08\xb70\x17H\ +_pR\xd7(w\x96\x08\xe2\xaab\xab\xb7\xdf,v\ +\xc2\x9c\xb1{*i\xed\x04\xbc!S\xc7\xafLz\x9f\ +\x09u\x94\xf7\xc2t;\x11\xf4\x8f2>\xe5\x9e*\xb8\ +J\x04j\x11\xeaN\xd76\xbe\xb3R\xf0e\x8a\x93\xa2\ +\xa4\x09jF\x9b\xa1\xb2{G\x85G\xd1Q{\xe7\xac\ +\xa9E\x91\x0aI\x80\x91\xc0a\x0f%\x1b{\x09\xcc\xa4\ +NR\x88L\x05*_\xd1\xe6\xcd4\xea\xa8\xaa:\x02\ +5\x02%\xad\xf1E\x1c\xe5\x1e\xe7BG\xf8\xd29\x9c\ +h\xca\x04\x80\xe0N\xa9@\x96\xb0y\xb5-\x12\x17r\ +\xd1u\xba\x08\x9f7\x1b\xe2\x1e\xe7:\xd6\xce\xdc\x13=\ +\xf7\x91Ql\x02\x97G\x80\xd2\x01\x0e1\xa2\xf0YI\ +5\xe9\x8d\x06xs\xda\xa4vli\x1b\x5cP\xc2C\ +puv\xc7b\xafk\x95/e(\xf1d\xa3\xeb\x04\ +\xde\x02RsTYSQ0O\x0dF\xf3\x08KE\ +Q-L\x81\xaaq\x026\x88L\x04d\x9djw,\ +\xd3._\xdc(\xfc&Z\xde\x84@\xea\xc8Ol\xd4\ +\x02\xddt\x0f^\x8e\xab\xa0\xa3\xd1\xb9\x060\xfd\x9a \ +FY(\x94\xc4\xa9\x92W\x0a;%\x9dO\xd5u\x02\ +[\xe2\xe6Q\x92}D\x0c\xb2\xce\xfd\x0e\x88\x92\x8c\xc9\ +WQx+\xb3\x07K\x027\x1a\xf7c3dB\x19\ +\xaf\xf5\xc0Ua\xa7\x18\xbc\x94\x1ft\xf7\xa0\xbct4\ +J\x1c\xc5d\x04\x81\xc6\x8b\xbdJ\xef\xe2E)\xf6\xa4\ +\xa1\xe8\x0b|\xa0N\x86\x15|\xc1I\xbf\x04\x98H\x15\ + \xd89U\xe2\xee\x85P7\xd5\xaa\xc4\xd2W\xebS\ +*]\x16\x12\x93Jr\xd4\xf7\xa7\xfc\xa1\xa1\x02\x91n\ +\xd61J\xf9HI\x1d\x10\xa63{\xcc\xed\xd8\xdd[\ +\x88\xa8\xa5\x88V\x88\xd7z\xf7&\xb2\xa0\xd1\xe8I\xde\ +t\x0a\x038+\xe82O\xec\xca7\x95~\xd7S\x8a\ +\xa1\xd3\xe1~=\x8b\x1f.\xe0\xac\x8eE\xc1\x99\xe2\x8a\ +$\xf6\xa4\xe2\x12\xdf\x8c\xea\xb4\xe0\xe1\x8a\xce\x08\x09P\ +\xe4g\xc8QE\xc4P\xca\x97\x84rVP\x8a\xf3\xc2\ +\xe4\x8e\xac^\xae\x04X\xc1\xe9p\xeb\xc5\x9e\x1d\xe9\xa1\ +\xdb\xdb\x85\x9f\xda\x960\x22\x09\xda\xdbE\x078\xb8\xa7\ +W*\xc2\xcf\xda^\xe8\x9c\x0eE\xe9\x15\x10\xad\xf4h\ +\xea\xa8\x9e\x80\x13\xff\x87\xa1\x86\x1f\x8f\xb2\x97\xd2\xbaZ\ +\xe2\x8bx\x89wP\x1a\x0f\xdcSIv\x1f\x83\x8d\x9a\ +\xb1\x05\xa7\xb8'\x87\x91 6$p\x16\xa4\xc2\xd2B\ +\xbbR\x11=\xacN\xc2L\xbd\x84\xea\xf5S<}\xd2\ +\x95N\x8b\xe8c=\xa5HO\xf5\x8eJ,*P5\ +N\x0fi\x85\xa2\xaf\xb5r\xf2\xaf\xc2{\xc8F\x9d\xc8\ +\x94P\xd6\xccQ\x9f\x1cR\x12{\x1afpH\xa8J\ +\xe4\xa0\x9e\xe0C\xb9\x13Oc\xa8\x0d\xedH{\x08\x17\ +\xfd\xa8@\xad\xa3e\x94o\x8d\x95q\x92\x13\xadb\xaf\ +\x9fTN\xd5\x8e\x1bS\xea\xf8EA\xbeT\x13\xb5e\ +2R\xfa\x12\x9cdM^rW{k\x91X\x13\xfb\ +\xfc\x90\xa5\x11\xa59\xeaL^N\x0b\xe1\xe5\x91\xc4\xa3\ +1/E\xf4\x08\x14\x9e\xf8\x80\x98hg\xe2\x00\xeb8\ +\x0acQ\xdf\xe3\x17r\xde\x92\x97N\xfc\xc0(/\xc2\ ++\xa2'\xf1\x87\x82G/\x9a\xce\xed\xd3R\x9f\xe6T\ +D\xa3\x05\x98\x12\x98h\xaa\x95\xf0\xe3EI^\x88\xb6\ +\xf2\xc5\xdf&\xac\xc4N~O\xa4\x81\x8e_\x99\xe4\xec\ +MOg\xf5\x124I^/Kh\xecE\xeb\x14K\ +\xdb\x1c\xe5'\xad\xe9\x10\x1c\x85[\x05%\xe8\x9f\xe0\x1d\ +\x87\xa3y\x8d\xa018\xd1:\xcaX+x\x02\x94\x0e\ +\x9f\xb2}q\xf8\x87\xe4hLdL1G\xc9\x90\x88\ +\xa7\xf0\x0e\xd9*\xc2\xaf\xf4Z/*\x10\x1bS\xda\xec\ +\xd3k=\xf3\x13\xcc\x1e\xef\x98(\xa9\x8b2\xd1\xb2\x14\ +\xa6\xf2\x86}\x1c\xe6\x89\xe0\x15\xcc\xd8\xe8\xd3~T\x83\ +%\xa4\xeeu\x8bW\xcc\x8b0\xeaBI)w*\x1a\ +\x95\xf3\xf5xK\xdc\xcc\xfe>\xbd\x17\x1aUr\xf5\x15\ +\x14\xc6Y?Q\x0d\x04\xafl\x83\xfbqS%X5\ +W\x05\xa6f\xea\xf8\xf3L\xc2N\xc1* u\xc6\x9c\ +\xf3R\x9f\x0aJ*\x08\x98\x08' V\x06\xc5b\xd7\ +\x09\x09\x92b)\xfc&\x0f\xb5\x08D\x85\x14P\x22\xd4\ +\x5cJz>\xcc \xbb+\xc9\xa28\xb9\xab\x12\xf1\xbd\ +\xc0\xa4\x97\xf2\xa5c\x8bdL\x92+\x93\xcb'\xe1\xcb\ +\x81+\xf0P\xb9d\xf6\x01\xd1\x22O\x1f\x1a$?*\ +t\x8ee\x1f\xbbT\xda\xb8\xd3:\xca\x87\x03\xd1\x90\x98\ +\x10\x1f\x97\x1e\x85\xa7`H\xc2\xd12&\x02\xa8\xa3\x91\ +8j\x86W\xca\xeay\x09-\x84\xab=\x8cH\xb41\ +I.O\xfe)\xd4Q\x0c\x9f\x88\xa7\xc2\xe0v`L\ +\xa1oJo\x8a\xa4\x83\x12\x01\x8b(\x1dC\xb7\xcd\x9f\ +|R\xa3\xc8\xd5\x091\x92:|\x855\xe7\xf4)[\ +\x119k\xa8\xe4\xccA@\x0a7\xe7#\xd3R\x1fM\ +\xa4\xcbT$[\xfb9\xbb\xcb\xfc\xc1Fx\xda\xb2\xe0\ +\x1d\xf0B/\xa1\xbc\xc5\xcc\xbb\xa0U\x00Xl>\xb4\ +z%\xf9v\xcc\xd1\xc8\x9c\x0a\x00\x0a\xce\xe9X\xb7\x1d\ +\xde\xc7B.\x9f\xb9#\xb4\xbe\x1b-\xf9\x06\xab\xc7\xae\ +\x0d\x0f)\xaf\xf3\x826\xb2\xfa4\xcei\x0eJ\x84z\ +\x00\x169\xfa\x8f\x8b\x96\xce\xdb\xdd\xc7\x14\x14\x80\xfa\xbb\ +\x22L\xc2N\xb1\xf68(\x01\xa0^\x8c\x1f\xc5yA\ +\xcfx;\x88\xf0\xe3h\x14\x9b\x89\xfe\xcd\xf2s\xd3\xbe\ +\xa5\x1e\xc0D\xd1sj\x1f\xc3\xac\x18,\xbcu;\x11\ +\x82D\x94\xfc\xa1\x84?\xd6?\x05\x82\xc7b\x0eo\x86\ +\x9dd\xb7\xc4wu\xa4\x88_\xa3I\xd5)7*\xce\ +^\xf8*lU\xc6\xa4\xf3\xfa\xd8\x96\x22\x8e\xb6|\x96\ +\x16\x08V6mm\xaf\xc1\xca\x81>\xba\x0c\x9a)\x0b\ +S\xa1\x22|x\xe8[:\xf3b\xeb\x97\xd0$aN\ +\xf0\x95\xce\xeb\xb5\xe8\x01d\xcf\xfa&\xab\xa2\xbb\x1b\xfe\ +\x12\xea\xa5M\xc0\xda \x17\xf1\xfd=J\x1fI\xe2\xa6\ +\xf1y=\x8b_\x9d\x0c\xe4cB\x1a&\x00\xc5T\xe4\ +jw\x84J\xf6\xeb\x83\xe8\x9e\xa9\x0c\xda\x89\xf0W\x82\ +\x12\xc1\xaa3\x91\xb4\x86&*\xce\xadV\xe0\x9e\xf4x\ +\xa2)\xdbB\xdcG\x98\xf0\xca\xe1\x85*\x9a\xee)\xa0\ +\x10_\x93\xb6y\xb8\xd3\x05\x9d\xf4\xbc\xa7\x98\xa46\xda\ +p]d+\x87\x80S\xf5\xe8X\xae&Iq\xb3N\ +T\xc5\x03\x96\x96A\x22\xe2~\xc2(\x8f: \xe2|\ +\x99\xe0\xfe@\x94\x14\x91:*8\xcdG\xc8\xa5.\x92\ +\x0aQA_b\x9208\x89\x1d\xber\xa3\xe9\x02D\ +\x11\x8c\xd0\x02\x8f\xbf\xb5\xa3\xfa\x9e\xdc\xb9\xabt\xe5\x01\ +\xb0bG\xd9\xd8\x15\x1f9\xaa\x1c\x14\xd9<\xde\xb1\x1f\ +\xb5*\x1a\xa4K\xea\x94\xed\x1e\xe8j-B\x96\xd2\x18\ +\x00A[\xaa(\x9f\xca\x0f\xda\x94\x10\xa0\xd8Q\xa9\x94\ +T\xb0\xb6c\x8e*\xa3\xd7\x11>|\xd8\xa0d\xdd@\ +\xb8\x89H\xbd\xa9T\x85@\xad\xb0CK\xf2&y\xda\ +q\x8c_\xa6\xa3<\x0dvZ8\x9a6&\xc7\xd0'\ +\xad\xd9\xcf\x0e\x91\x9fbN2\xb5@/\xa1%< \ +tnp\x1f\x9f0\x87\x86\xafX\x1aY}\x0b\x1f\x01\ +*\x11\xa9\xeb,\xdc>(\xc47\x01\xa1\x8e\x86\x8aZ\ +\x09D):V\xc9l\xb9\x8cMI\xe7\xa1\x01\xd6\xd4\ +\xd6\xb2\xa8\xe8\xd3#\x00:{=\x00en\xe2q`\ +\xf2\xfa\x9a\xd2\x85'_\xee)\x98\xb2\xce'\x19:\x0d\ +y}\x94\x87\x16\x04\xf7\x95s8\xa5\xc3\xf3O\xcc\xd4\ +\x90\x9db\xe8\xfc#\xad:\xa4\x9bHdF\xd1r\xcf\ +,\x8d7\xc4b\x12\xb0\xc5\x7f;\xa0S\xfb\xd8\x94\x04\ +d.\xf3\xd3\xf4\xa6\xad\x18{\xcc\xd4\xb6\x96|zp\ +^\xbc\x86*\x87\xdf,\x18\xa28\xd2\xf7}\xfc\x00\x9e\ +\x11!kB\xf1S\xef\xa8\x22\xe9\xc3\xaf\xb5\x0f\xadT\ +\xaa\x9c,>\x012B\xaa\xc5\xae\xf3z\xfe-\xd4^\ +h\xef[n\xb9\xa7E\x94\xdc\x13<*\x19\xad\xd0\x9a\ +X\xe2\x22\xf6\xa4g*#w\x8f\x97\xc3\x9bn~\x11\ +\x90\x8c\x92\xfbt\x8e\xc5\xe5>\xeau5\x97\xe6%\xde\ +\xe2\xf1\xe3:.\x82d\xc4!\xe9\x13\x18\xf1\xf8\x8ft\ +y\xd4q\x15\x97{\x030n\xc5\xd6\x06%9\x88T\ + \xd3.T\xf3SH-J\x11G#\x88dL\xae\ +\xf2\xf4\x15w\xac\x8d&\xaah\xacQD\xaa\xf6\xc3\xd2\ +-Z\x0a\xb3\x80e\xa1'\x9ar\xa7\x13~\xb4Ge\ +\x1d\xae\x8f\xedA%\x05\xe2\x11\x10E\xbc\x11^U\x15\ +>\xd8_\x10((\x1f\x18\x80\x83W\xf8(v\xa6\xe3\ +Q\x89\xf0\x9b\xd2\x98\xc9\xfbL\xe6\x17\x93QP\xd2]\ +4w\xd4\xfe\x00\xce1\xed\xed\x95\x01\x08\x0f\xad\xf5\x95\ +\x9a\xa0%~\x89\xe6\xe6iv*=U\xee\x89-\xde\ +\x81\xf4Z5\x80PIG;\x1b~\x83\x1e\x1b;C\ +-\xcb\xa8\x15\x1f\xdeu\xb8\x0f\xae|i\x16j(\xbd\ +\xe2\xf9\xa3\xa11\xe9\xe0\x09\xa4\xff=8\xae\xf8\xca\xf7\ +\x17\x82\x93Cf\x04[\xe9lDi\xa9j*\xd1y\ +St\x8eU\xc7\xa3q\xffhj\x9f\xc9\xdehN8\ +\xeba\xcfw\x84\x9d\xbc\xd5\x14\xee4E\xbbLq\xda\ +4.\xcaS!\x1e~\xa4\xfdhA\x0c\x15\xb8`O\ +7-\xe2\x01\xc0\x0eg \xb2\xdb\x90'\x12\xbc\xd8\x8f\ +\xb2\xa5\x8b\x92\x86k\xfd\x84\x02+\xa47\x1b\xd2\xdb\xf6\ +T\x1a\x7f\xcc\x01\xbdy\x00\xc2\x0f\xba\xf3\x94n\x0a[\ +K\xd2\xd4\x80\xb07\x8f\x8e\xb3\xfd\xba\xf1h3\xa1\xa0\ +\xe2\xa2x6\x11\x9cyX\xbd\xbb\x0fV\x0f(\x99\x99\ +\x9a\xa5\xf1&\xa3@\x95\xeaC\x86\xef,S\xec\x1c\x1b\ +\x8fN\xf3\x86\x98\xc0\x0c\x92;n{\xfb\xe7?:l\ +\xd0\x07\x86\xb2\xf85L\x01\x18\xe6\xcaq\xa9$\xcdP\ +\xd9\x0f9\xd4t\x22\x81\x9b\xdef\xa2\xf2xT#\x8b\ +\xcdi\xfc\x1cg\xf7\xc2\xf3\xcb1\x8d\x8fG\xd5\x06\x0e\ +q\xd27\xfc\x9en{\xd2\x00\x8bx\xdb\x96d\xae\x0d\ +Jbf9\xff\x1f\x99\xbd\xeax\x8c\xfbGc\xe21\ +J\x8a\xa7\xb2s';c\x22~N\xe5%\x8eJ\xda\ +\xbdpTw;\xea\xcax\xba-S\x8fL\xf4\xb6k\ +\xb1}\x98\xa8\x06|\xaa\x0f\x1f_z\xe84\xa2\xc4w\ +\xe5\xc5\xf6\x19<\x08\x94mI\x80\x8e\x8fG\xc3\xce\xe1\ +\x82\x9br\xa9KK\xb15W\xebR\x11\x04%x\xe4\ +\x8a\xa2\xbd\xa8@\x8aS \xc0Ae\xeeV\x91\xf3\xf8\ +\x99\xe8A\xed\xa9\x90^\x22\xb7\xd5\xe4q\xb4\x96\xd8\xa9\ +fs\xf2O2\x96\x12\x92\xaa\xc1\xe8U2\x0b5\x10\ +\x11\xa7\x0f\xd5sK\xc4\xd3\xe9t\xb5\x0d\x8e\x97\x82*\x91\xb3>\xc9\x86V/\ +wj\xf9\x14\xb41\xb5y\xe60\xcd\xf2U\xe7\xd6\xbb\ +\x80\xb2\x0b4\xbe\xe5-\x91\xdb\xab\x09\xa4\xb9\xbfs\x07\ +O\xc8\xd4`\x82\xb3p6l\xd2\xe2Y\xbe\xf6F\x94\ +H0\xa1\xc4\xe0\x0c\xe3\xbc\xa6\xee\xd2a\xff\xc9 \x1b\ +z\x847\x0a\x9f&d'Y\xea\xa0\x92\x8e*\xc1g\ +e\xcd\xc1\x93\xa7\x9f\ +@\xb2.\xd1\x14\xef\xee;\x8f\xde\xb8}a\xd01\x9f\ +\xf1h\x05\x0d\x936m\x81\x95z@2/L\xbc\x82\ +\x0aT\x9d\x92\x00\xbe\xb0@\xc6\x0e\x0a\xe8\xd4k\x8f\xba\ +6\x8c\xf2\x00k3\xcf\x92\x87\xac5R*<\xf4\x0a\ +\x16\xbbn'\x92C\x18\xda7U^\xfeA\x0e*\xdc\ +\x0ce\xa0\xe7n8\xff\x1fL\x95\xf8'3\x08R\xd6\ +\xa66{{]q\xd6\xee\x9ef;\xf2\xf4\x0f\xe5\xee\ +\xd1\x96\x08\xac\xee\x22\xd3\xbd\x1a\x08R\x9f\xbcb\xfd\xdc\ +p\xefh\x84\xc3\xaf<\xabww\xd7\xca|\xc3\x17\x0e\ +?\xbbT\xa2oic*\x88\xa1\x05^\xc2\xd2\x9c\xa7\ +\xf9\xca91@\x1c\x9eg*i\xe6O\x5c%A\xa8\ +\xbf-3\x11\x16\xca\x8c[ \x1c7O\xddp\xd4\xe1\ +#\xa8t\x0aC\xdf\xc9\x8d\x05\xe1\xf04\x22mJ \ +yuxYSE'Bi\x8a{\x5c\xcb\x03\xab\xbf\ +k\x91\xe9\xc1\x86\x96}\xf7\x0b<\xc4\xeb/\xcb\xb8#\ +W[\x93\x93\xbc\xb0\x15\x89L\x09\xde\x14\x94\x84X\x01\ +\xe8\xb8\x92\x0e\x99\xfd_\xb9\xe9\xb8s\xe6\xbd\xb1\xe3\xa3\ +\xecv\x7f\xe6\x0d\xf0\xeau\xe3\xf1\xc8*n&\x05\x05\ +\xa4\xb1\xe8E\xe6E\x98\x89\x94\xfa\xc8\x00,\xa5\x02R\ +\xbc\xe8\xad\xaf\xb9}\xc7\xbe\xc1\xb1\xa0\xa4\x8a\xa3\x13\xa2\ +\x15\x8b\x07:\x8cr|\x0d?\x15\x96\x00P\xbc\xf3\xc4\ +\xe10\xe9{\xc3)%\xf0\x1b\x85$\xf0TE\x9ee\ +_\x85\x11\x9c\xda\x9aN\xb5\x03\x18Wo^m\xde\x93\ +\xa2\xa4\xf1x\xe4\xa2`\xa4x+\xd1Ku\xbc\x8e\x04\ +\x0f\xf8\xc0\xa2\x90\xcaOo\xd8\x80}:\x82\xd3\xde\x14\ +\xe6\xfd\x0e(i\xcf\x83\xd95H/8\xec\x8bK\xad\ +\x8b\xacn\xec\xce\x14G\xd3\xe5\xfb\x18f\xa16\x9a\xd8\ +\x9e\x94\x83*+\xda\xbc\xa96\x5cal\x17fwW\ +:\xb5\x93\xa5\xfe\x5cT\xd2L\x8d\xff\x98\xb0\xdf\xd3\xa0\ +\xa4\x85\xe2\xa804LG\x10*\xa3\xcdUcA.\ +\x1c\xd53\x92-=}\xb4\x9d\x016\x1a\xed\xab\x83a\ +\x15~@\x92\xdd\x0b3\xb9\xa2\xf1i]CS\xa1\x92\ +j\x8c\x85\xdc2\x85\xb2\xe7\xf3S\x80\x06\xc92\x1f`\ +\x05\xa4\x97\xd1\xd8\xdc\x86\x8f\x13c'F\xfar\xa7\xa4\ +\x99r\xf8\xf0t/\x85>&\xd5\x01\x91LF\xa8\xee\ +\xa8U\x14X*:\x0aH\x99\x9bp\x13G\xef\xc3\xa9\ +\xc3\xaf\xef(\x97\x1f\xccG\xbe\x16\xb6\xae\xc9\x93\xca\xe4\ +\x17\x03\xf4-\xb0g\x94)\x8e\xa6\xcbd\xc4P\xae<\ +\x22R\xad\xa3\xb9\xea\xc4\x16CZ1\xb987\x85\x03\ +g+\x07r\xc5\x0agL\xa8\xa4\x107[%\xbdf\ +F\x80\xf2\x907QR\xed\xf0\x95j\x8a\xd5\xa7\xdc\x13\ +\xf0\x94t\x14\xb54\x97\xe3\x96xU+N[z=\ +\xcc\x8b\xca\x0d\xc8\xff\xfd\x8f\xc9\xf5Fc\x8f=aE\ +\x99P\xd2%\xc8D\xbb]\x1eP\x04aI\xa8\xa4\x02\ +Skj\xaaF\xa6\x9a\x1fdk\xb9\xd0\xe7\xd6yD\ +\xee{GNI\xffkR&\x10\xff\x89u\xfd\x02\xf5\ +\xe5n\xb9g\x86\xe2=a\x80\x1a%\x1dM\x0e&>\ +\xf3\x91{\xa7\xe6\x8eY\x11\x0eJ\x05xR{\x12\xc1\ +KO\x09\x22\xd5}:\xc2Q\x91~\xbd\x02f\xabv\ +,\x18\xa1\xd7\x03PBz\xed\xc8*iO\x1b\x93\xd1\ +SR\xd2+\xb1_`s\x09\x1c\xc5\x08\x8aHJ\x0f\ +R\xc5\x07b\xb8\x1c<\xeb\xe2x\xc5\xa3?*\x1e9\ +\xbe\xfaM\xc1l\xd7sjQQ\xe7I7u\xb4\xcb\ +\x87\x22\xc9g s\x92\xa1\xdc\x13\x89\xdeQ\xd6Q\xc5\ +R\xd5T\x02n\x1e\xf5T\xac\x1e\xed\x9e\x07}\xc9(\ +\xe4\xb9uwl\xd9z`\x19\xb8\x82O\xe5\xa5\xa4v\ +\xbf\x90\xe5\xbeKP'\xa6?bbj\x9fV>r\ +\xbd\xf3\xa3qC\x11|D\x89\x08M*\x81\x07\xf3\x10\ +\x86\xfa\x06t\xf8{\x9f\xbb\xee:TR\xc2i\x86\xd3\ +\xb6\x8a\xba\x5c{\x0e\xc4\xca}\x96\xbcSRY\xeeA\ +A\x7f\xf5\x94\x96\xc1\xaa\x8d\x97,\xb5\xda\x108\xc7]\ +\x84\xe1\xc0i\xed\x9f\xc0\xd7\x03\xd2\xa8Uc\xc3\x87\x8f\ +6L\x9b\xdbU\xc3Z\x8fc\xec\xb6\x0c\xd1\xedg\xf7\ +\xc1\xea\x9e\xa3\xe8K\xf2\xa4=\xe4'\x5c$s\xc8E\ +m\x9a\xd7\xa2\xbe\xa7\xa6gO\x85\x84O\xa4\xa31O\ +\x81\xab*\xb3C\xb8\x9f~\x0a\xa1\xdd\xd9\x03\x96\x1e\x01\ +87\x01NX\x99\xf6Z\x91\xae\xe9x9=.\xf7\ +\xdd\x0d/\xbf\xec\xd2\x0d\xb0\x80\x9eM\x9c\xdc\xf4\xa0\x9d\ +\xbbM\x8b\xd3\x98R\x1e\xfd\xc6\x1c5\xa0\x98\xa3\x05I\ +\xbe\xda\xb0\xd7\x02}\xd9\x08\x81\x1e\x9c\xa9JV\xd2\xdd\ +\x1d\x09\x9f\xee\xb1\x9d4C\x1e\x96\xda\xce\xac\x92N\xbe\ +\xedp\xd0\xc9\xa9\x7f\xb7HO\x9d4\xea\xb1\xd1\x80l\ +\x15\xedx\x1b\x7f\xbe\ +\x9b\xf7|\xc7\xd0\x85z\x1b>\xf8\xd9}\xfdNQ\xea\ +\x02\xa9\xcb\x9c 0\xd5P\xc5\x94\xb4\xf8\x03\x1d\xbd\xfc\ +\xfeI\x8bn\x13\x951\xf6 \xd2\xd9\x86\xed\xd6\xd8&\ +Jj\xa0\xee\x05%mU\x86x\xb9\x1f\xb1yo\x1c\ +\xb62G\x86\xc9\xfe\xc0\xcc.*\xa8\xa3d\x07D\x9c\ +\xd4sD\x8a\xb4v\xd2\x0f\x11n\x7f|\xd7\xe0=o\ +\xfe!\x00x\xc4\xfa\xfcO$\x95\xd4P\xf9\xdcb@\ +\x07\x863<\xbb\x9f\x07\x93e\xac\x9e\xbc\x17\x9a\xee$\ +k\x0aNe\xf9\x05\xe9\xe8\x05\x9e#\xb9}\xd8o\xe5\ +\x96\x8e\x03\xe1\xcfX\xa4\xc7\x83\x92\x82\xd9\xe7U9\x09\ +\x9e\xd4\xc0\xfc\xfc]#\x0ds\xfe\x8ea\x87\x0b\xb8\xe1\ +\x0coD\x8b\x08\xe3\xde\xbcV(v\xb9\x00\xa8\xbd\xd6\ +\x1e\xcd8\xef\x1e\xce\xe4H_\x83*\x81\x05JJZ\ +\xd9\xeb\x0a`\xf5\xe6\x1b\xbeN\x7f\x8d\xe9\xa1\xd58\x7f\ +\xd3\xce\x00\xa6\x94\xa9\x1c7\xd6\xd3^\xddxx\x7fX\ +\x19/\xf4\x81\x01\xa2\xcb\xcfy\xd3\xed\xae\xa09\xec\xc8\ +_Bp\x07I\x8c\x96\xbe\xda~\x1d\xd6\x03\x9c\x1f%\ +.^\xf8}\xd4\xcf\x87\xf6\x9d\xf6\xee\xdb\xb6?\xfa\xc0\ +\xb0SdD\x96\x95\xc0P\x01\x0a\x0f%$\xd1\x96\x18\ +\x80l\xc5~4\xcaE\x9a-\xd0\xd3O\x0de\x00\xe9\ +\x13\xa0\x09}R\xd2u\x1d\xbbos\xc2\xbc\x94\xe3\xce\ +\x81\xa2\xdd\xcd;v\x15e\x96\xd7T\xd0)K\xa7\xa3\ +j\xfa,\xf1\x14)\xde\x06Ow\x91\xe1\x1c\x15\x9d\x86\ +>\x03\x15\x85~\xceTCP\xdc\xb7\xb2\x7f\x1d \xbd\ +\xe9\x8c\xfb\x09&t\xc9\xfd\xcb\x0f\xb6\xec0.\xa8Q\ +\xa3\xbf\xf7J%$\xf5\x0c\x7f\xd9\x93\x22Kc\x1dm\ +y\xc9\xb2\xb6\xfc0(9\x05\x80v\xa4%\xf7\x9b\xa0\ +\xb3\x00\xf4\xc7*s\xb8\xdb\xc2\xbc\xca\x0c\x7f\xaf\xf2<\ +\x18\x94J$GZDM'\x88\xa5\x13)\xf7\xa4\xfb\ +\x89\xc6\xc7\xa3f\xaa<\xb8\xc1\x19\x89\x9e\x8e\x00c\xea\ +\xd4\x96^\x14\x9cS\x8f?p\xc4fS\xfe\x9c\xd1m\ +\x99\x99\x7f\xc9\x9f\xeb\x10\x1dE\xacpu\x0f\x1d\x94\x14\ +*\xb1W\x7f|\xd7\x8au\xee\x11.<\x1eiQ\xfd\ +\xe7\xae\x9ek}\xf9\x18\xc5B\xf3;\x86y\xddl$\ +k\xe3\xd1\x9f\xb0/\xc7\xcd\x1fMo\xdf\x8c=\xb6\xae\ +\x07\xe2C\xc6\xb3\xfe\x92\x1c\xe8\x1d'\x02\xac\xcf\x0ej\ +\xa4\x9b\xd6\xb6\xedK\xcf\xe2R5;h\ +\xd5L\xa7\x99\xb9\xd4K\x9d\xc2\x95\xf1\xd3'\xacCF\ +fc\x1b\xb4\xa2\xf6\xf6\x06\x99S,\xffp\xd2\xd7\xbb\ +\x9c1\x8f\xfc\x05\xb1\x13\x96\x9c+\xda\x08\xaf\xeat\xa3\ +\xab\xcf\xd9,:o\xc9W\xba\xa7$\x92|\xd8T\xd2\ +\x80\x18\xefx\xc4'\x01F'*=\x01X\xfa\xab\xe0\ +\xf6C\x13\xfa\xcf,q\xe4\xeeP\xf3G\xc5=\x05y\ +H\xbce\x0fJJ\x0c\x1d\xcd\x1efV)\xcdN\xc0\ +*\xfai\x91\x0a\xd4L\xba\xdb\xb3\x8c`\xfe?\xe6\x8f\ +\xaa\xb2\x93\x7f\xb1/e\xa0\xa0\xa4w\xbe{\xe3\xca\x95\ +\xab\xd7\xdd\xbe0\x9c\xe1:\xa9\xae9;\x91\xcb\xb0q\ +\xbd\x85c\xc1\xa2{J\xd9\xfc\xb8^|\xa9>h\x0d\ +E\xa4z26(\xe9\xdd\x9d\xbc\xd1\xe9wf\x1a\xc1\ +\xbc\xe9*\x9a>ko\xe9}Q#\xbc\xc5\xee\x7f\xfd\ +\xf9\xa3\x96Z\x0a\xa5b\xa9 \xad\x9d'\x9d\xf5\x17Q\ +\x9f*,\xe5\x12\xc9f}\xdcD\x8a\x5c\xcd\x12\x83\xa9\ +\xa4-3\x0c\xf30rN\xfbQE\xf53&\xd1\xd9\ +3,\xb8\xfe\x10\x9e\xaf\xafb\xa4\x95\xc6\xa8\x8e\x08e\ +\x8995\xda\xdd\xeb)o\xcd\xf46S\x02\xe96k\ +I\x7f\xdb\x90\xbc><\x80\x810ev{\xd2\xec\x05\ +j<\x22UK>\xfe+\x18a\xb1$m\xfa\xcb-\ +\xd0-\x1d\x84\xa9\xaa\xce\xfc\x87%4KE\xf2\xd8:\ +\xe8\x9dcU\xf3\x9e\xb4\xed\x87\xb2\x8f9J\xf8\xd8\x8e\ +\xf4\xd4\xe1y\xc89^\xf5\xbbW\xdc\x94\xe7\xaa<\xca\ +\xc2\xb7T\x0bW\xd3\xc7W\xe5\xe0\x95f)_\xe3\xfd\ +h2gjDJj=\xe9\x9c\xcd(G\x97\x80\xe4\ +s\x0f$\xf2\x95Q\x8a\xc7\x97M&\xb6z\xff\xef\xdf\ +\xc4\xcd\x8e\x81=\xa5G+D\x03\x7f\x04\xec\x13\xdbd\ +m\x9a\xed\xa7\x8e3Eb\xd7'\x9a2\xf6\xa5lN\ +\x91\xdd\x8f\x9f\xed\xa8\xa2\xd1\xa8\xddQ\xb0\xd6\xf5\xd4h\ +\xe4%y\xa93w%\xfeE!\x0dVO\xf3\xf5T\ +4\xd3\xf3G\xf5!\x0c}\x9e)\xb2%\xbd\xdd\xa0j\ +d\xcfs@2Z\xb3}8C8\x8b\xc4\x80\xbf\x0a\ +\xa7\xb8\x07m\x99\xed\xd0G\xbd\xe4\xfc\xd1C\x8e\xfaJ\ +\xebgn\xb2\xfb\xd1\x08\xaaZ;\x16\x06\xd7\xf7\xf2\xe8\ +(\x9b4:\xa2n\x02GC\x12\xa4@\xbf\xee\xfcQ\ +\xd8d\x8a\xfb\xf0\xc9C1Ks{\xddt\xe4\xbaM\ +&\xc7\xe8\xcb\xdf\xe7\xfa\xbf\xca\xce\xddU\xb2\xac\x0a\xe3\ +\xbe\xea\x81\x9f\xb9\xbe|\xfb\xf6i\ +\x8e\x86I\x1c\x05\xd4Wk@\xf8\x8b\xb8y\xd6\xd7^\ +\xe1\x8f\x12\xd7\xf3\xc4NW\xf14\x8d\x8a\x5cv2\xe3\ +\xec2\x14\xbe\xce\x9d\xc3\xc0k\xdas\xa7c\x97J=\ +\xd4\xf8\xa3A\x92\x14\x85\x96X\x15\x11\xc8y\x12\xa5\xf6\ +\xc0\x84\xaei\xb0ehM0\x8f\xddKb\ +\x9d\xa5\x9c\xb1n$\xd7\xa7k\x9dX\xce\xd9\x82\xd2t\ +\xf4'xy\xb5\xd2O\x8bM\xdd2q\x0eC|d\ +\xb4\x9c1j\xe8\x91\xf2\x91\xd4\xe3\xe4\xfb\xc7\x19j9\ +\x1d\xce\x82\xbb\xad\x17uYEa8\xf0\xe0\x98\x9e\x8a\ +\x98\x0f\x0b\x86oj\x8e\xa2\xbb]t\xc6\xfc\xc3e\x98\ +\x170\x96Z[\x09\x9a\x86E\xa5\xc8\xb4\x111\x0c\xde\ +\x01,\xb5&T\x1c\xf5\xb3\x9f\x93\xd6\x8f\xdd\xc3\xa2q\ +\xce\x87\xcf\xc7\x85)\xbay\xa2n\x87\x88\xff\xff@\xcf\ +\x92\xa1\xe2\xa4\x84\xdf\x1f\x0d\x87a-W\xf2G\xf2\x1e\ +\x04\x22\xbaf\xf0\xf6$M\x84\xa3\xa2z\x82\x0d\x15G\ +\x01C9\xe7\xe5\x5c@\xff\xc8\x92\x8f\x87\xe0\xed\xba\xa1\ +\xcf\x06\x8f\x9c\xb0g\x85\x8f\xdb\x7f72\x8fI\x8f\x8a\ +\xd2a\xf7\xb0\xa2e\xc1dn\xdc\xc5\xa0%p\x9c1\ +r7\x1ee+\xa6\x18mg\x07\xcd\xa7\x1f\xfd\xdc\xa6\ +\x1d\x9dMt\xaeF\x22`\xde\x00\x00\x11y\x9a\xe3%\ +\xc6L\xbe\xb8>6:R\x8d\xba~\x1a\xe2\xe6\xad\xd6\ +Jv~u\xa9\x82\xa9'P\xaa\xfee\x14\x8e\x13z\ +X\x0dn\x01\x93\xc84\xa1\xcfM\x846\xc5\xa8\xe6'\ +9P\xfd\xe3ns\x95\x7f\xc8`\xa9\xcc\x93\x10B\x8b\ +\xeb:f\xbd3\xa4\xab4\xa8\x9b\xd0\xd6I\xdd\xabQ\ +?\xf6\xed\xcf\xfb\xf1/(K\x05\x84\x92\x18[-6\ +\xa5\xcc\xd3\x84j\xe6\xae\xa3\xbe\xcc\xb6\x87\x11\xf9\xbc\x04\ +\xa2\x04f\x8a\x8f\xf1\x93\x9eg\xc3\xcd\xbb\x94]*:\ +3\x9b\x06\x04\x030\x15\x12z\xf2D\x8d\x9bu&\x9f\ + J:\xf6\xf8C\xf5\x94\x9ed\xe5/\xf3&\x84\xd6\ +\x8f_\x93w\xda\x1c\x19\xb2\xa3M\xa7\xcf\x11F\xfdE\ +\x86\x22\x0a\xd57\x07w7\xd5\xba\x0e\x89|\x9c\xb9\xd3\ +\xa3\x9b\xa97-g[\x0c\xe5-\xce/\xc3\xd4\x8b\xbc\ +:\x0a-\xb6\x04\xa7\x15=\x9e/A\x17\xbe\xff\x13[\ +\xf9\x88S\x03\x99\xcf\xbe\xa8C})O\x92WI!\ +A:*\xdd\x043\x8fMw-\xaf\x91\x9a\x87p:\ +t\x9b\xf5t\xd2\xdc\x85\x1e\xca\xd2`\xbc\xbe\xc4\xc3\xd7\ +\x0c\xa3\x87\xcc\xde\xdf\x1e\x81\xd1G\xbct\x81\x0a5\x11\ +\xf0\xb5^\x7f\x12$\xca^\xe5\xf4M\xa85\xc5\x99P\ +\xfd\xf8H\x8b\x1a\xc7\xa7\x9cv\xf2\x08\x14\x04&\xb6\xba\ +\xc5\x87\xb1G\x8cG<|\xd9y\xf3\x9d0(d\x18\ +\xdem\xca0%\x04\x01\x91\x83\xbf\xaei,\xd8\xeei\ +\xa2\x92c\xeb5\x1e\xfe%\x86\xc1\xa5\xa5\xb2\xa1o>\ +\x1c\x98Wse\xf4~c\xa8\x11I\xc7\x99\x00\x10\x22\ +5\xe9\xd3\x9br\xe3\x95\xd0\x15.\x153agd\xb3\ +\xa5gP\xf8!\x06\xa5\x97\x87d\x9e\xf4\x14\x00U\xe0\ +:\x0d\xf1\xf0\xf3\x9c\x10\xb6\x09\xb5\x16oi#\xfa\xb0\ +R\xf8\x1a\xbc\xc2\x93r\xf8,\x89\xd95\xa5e*\xba\ +\x08\xb9Ud\xd27\x0aR\xf6H\x17\xc7{Z\x85\xf7\ +\x04\xe3t\x91m>\xcf~h?o\xd0\x9bgZ\x14\ +\xa5\xbb\x84\xa14M\xb8\xa3\xf9\xf8\x97\x0a\xefI\xb2$\ +b\xc7\xb5\xd0\xb1\x1eU\x1a\x175\x11o\xd5p\x1a\x13\ +\xdc|\x9b\xc1\xd1\x12\xefI\xc4e\x04-\xc2\x94\xf8\x1f\ +\x8d(\xb3\x8e\x8c\xeb\xb1F\xcc\x912\xe7\x12\xda\xd1\x7f\ +(\xf7\xb1z\xc7\xbc8\xd5h\x8dX bq\xf06\ +\x0c,\xf4\x97\xf0\xb8\xac\x1b\xb5\xdc{\xc3\x12#a\xfb\ +\x81?Y\xe0\xe1\xcfsY\xb2\x8d\x147a,`[\ +\xa8\xb3\xb4\xae\x83\xba\x81\x22\x92\x8e\xe7\x9d\x89\x91Kv\ +\xe6\x0b\x90Yj|\xa5\xef\xec\xed\x0f2\xfb\x9c\xaf\xf7\ +*#Y\xeaZ4RY\x03S\x01&7\x90\x9a\xa4\ +\x9e\xab%Db\xfc[M\x96R\xd3\x93G\xcc\xa7\xaf\x9b*z\xf7~\xec\ + Wz\xb4\xde}\xc3\xdc\xd3\xd1\xd4(!jj,\ +\x9d3q\xb1rK\xae\x8a\xa1\xd8d\xfd6\xe7\xa8}\ +P\xb4E$b\xd2\x0f\x8e\xb6\x04\xef\x98\x1b\x9fD\x9f\ +#\xd2)\xf5\xc8E\x9c\xe2*\xf3\x8du\x83\x16\x92\xa3\ +I\xecG\xf9\xf1\xe0.\x03\x13]\x12\xbf\xaeK\x81\x91\ +\xea\xae^\x115E\x97\x84\x96\xc9\x1c\xd2\xa8\xe8\xf3\x1d\ +\xa5\x8a\x02z\xfb\xe2\xc4\xea\xdb\x92\xad\xbf\xb0\x9aH\xb1\ +\xd5\x96{M\x89\x87O\xc1\xf7\xdcc4\xf2\xa2R1\ +\x13\x8f]/\xe6\xf3\x12\xb5\xb1\xe7-\xb5=9\x95\xe3\ +\x94\x0e\xd4h`\xed\x11q=\xe0\xfd&d \xf4\xb2\ +\x95\x91tI\xa3\xa5_\x90\xc5\xa7\xe8\x1b\x1e>\xc5\x09\ +\xc2\xa4\xaf;%J\x91E\xa7\xc49\xba:\x863a\ +\xbc\xb1\xcd\x1aq=\xa4\x89$F\x90\x5c\xa2\xa5\xb6\x94\ +\xd2\x11\x91\xd0\xa5\xbeq\x9d[\x9a\x9c\xa34\xf3\xbc\x9f\ +\x84LL\xdd\xe3\xfa\xc6HD\x1b\xac\x0d\xddO%&\ +c\xa8[OG\xcd#|{VM\x14\xa8\xa4P\xfd\ +au\x99x\xf8\xd5\x96\xe0\xfe\x07'/\x06wc+\ +\x9aj\x22\x5cik\xf24\xdc\xb6\x0e\xb7\x84\xce=C\ +\x12\xd9\xa5(\xf7\xdcg\xdc\x82(e\xfd\xc4\xd0.m\ +\xb8\xd4/\x12\x10\x84\xc2\x07\xa5\xb2\xed\x0d\xbb\xac'\xb2\ +t\xd1o\x10zVmM\xe9\xb3|\x03\x13Z\xf9\xa3\ +\xfa\x83Yr4\xba\x9c\x18\xf7Dn\x0c\xf1\xea&\xc2\ +H-\xb6\x09\xf5/\x9e!\xfahY_n\xc12Y\ +\x85\xd1\xde+j\xa1\x0d+\x1b\xcc\x86\x9a\x19\x85z\x02\ +3\xb9\x8b\x11m\xae&\xf5\x99\xad\xcd\x5c\xbei\xce\x9d\ +\x0f\xab\x1d\xfc(5\x0e\xd3D\xe3\xa97\xf3y\x1c\xbb\ +J\x10\xa4\xf4\x9e$L\xc6IjQ\xe3i\x94\xaa\x8b\ +$R\xceU\xda\xa6\x02\xce\xf7\x08\x5cO\x80\xd4\xd0\x1f\ +M\xe4\xce\x11\xf6\xa59\x81e\xbdV\xa2$\xc6\xc2\xcb\ +c\xf6Iz\x14\x93\xcb\xc1\xc9#G\x13\x9d\x1e-O\ +\x86\xa7\xb2\xae\xa6\xfa\x09\xdd\x0eABt\x07~\x16\x99\ +\x12 \x92Q\x9e\x1c\x1f\x95\x81\xbd\xfa^\x1c\x83\x90\x86\ +\xc9UT\x08\x9a\x197\x81\xd2J=\x1dK\x7f\xd4\x02\ +f8O\xab\xfeB\xe7Kc\xc5\x16#\x18\x00o\xf7\ +\x10\x94G\x7f+I\x92\x91j2o!H\xf4\x9e\xf4\ +q\xc8\x1f\xc7\xf64\xc1\x876\xc5\x8a\x9ee\xc8L\xe6\ +\x9e\xf2%52K\x7f\xd4\x93\x0f\x8c\xeeDi\xd8a\ +\x0eC\x8f\xbd\xf0z\x11\x18\x9dR?:\xfb\xca\x1f\xd5\ +\x91\xfboz$H\x1e\x8c0\xa6O\xf5\xda\x05\xf9f\ +\xb0\x12\xe5\x9b\xa1\x22u`\x15\xab\xdd\xe8\xdf\xc4\xa1t\ +\x86F\xef~\xcd\xc2\x94\xd4=\x15>\xb1\xe6/*\xa7\ +d\x06\xdeS\x1af\x9b\xe2\xc2\xc8\xe4;/F\xa9@\ +\x1dE\xab\x9f?#\xbc\xe0\xe6a\xe76\x1el5\xd5\ +\x17\xc5\x9bH,\xfdQ\xdfk\xeaa\x93\xaaw+\x89\ +\xcc\xb7\x94iG\x90J0_\x17'\x16n%\xf4B\ +O\xcb:t\xb6\xd5\x5c\xd96\xb5\xe2\x92\xa6,>Y\ +Z\xb4\x13U\x0b\xf9\x98\xc9u\xc9\x97\xecO3\x90\xe6\ +\xf3v\x89b\x8a\x11\xd9\xbch\xe9\xf5.=|\x96\x99\ +\xce_:\xf7A\x98\xd8\xeb(A\xd2\x0b+\x1b\xf4f\ +\xad\xc1EI\xe7N\x0f\xbf\x1ac\xac#\x11?\xfa\xcd\ +\xe73^\xea\x92n\xe5\xfa5D\xcb,\x85\x22/^\ +W\x1a|l\x9d\xe5P:zN\x9e\xd7\xee\x82\xd0{\ +vL\xf5\x06\x81M\xafh\x22\x14?\x99\x1cO\xa5\x86\ +\xbah\x9bu\xbd\xe7\xf3y\xf4\x22\xb9pH=\xe1\xbc\ +\x9e\xbf\xc5f\xae\xc3AT\x82\xa9\xa50\x9d\xb0\xd3\xd6\ +\x19\x0a\x15\x15\xf1\xf0'u\xea\xa4LI\x8eA\x1b\x05\ +\xa9\x0f3\xd948i\xd4g4x\x05\xb1\x17C\xe3\ +\xb1\x1f\xa3Q\x8aQ\xe8 \x08\x8dm/\x8d\x93\x0d\xa2\ +\xf6L,-\xbd\xf2\xf8l\xd0\xaa'm\xed\x86\x0e\x02\ +\xe6\x14\x87\x92\xccX\xc4\xb1\x1eg\x9b\x0cs\xd9\xdf\xc6\ +1\xe0\xdf\xfb0\x9b\xd7\xc3n\x1c\x14\x9d\xbehe\x9b\ +\xb0Z\xc0I\x15q\xbew{\xcd+\x8f\xf2\xf0M?\ +\xfd\x83(e\x0e\xaa\xb0L\xd8\xd5!\x99\x02;\xfd-\ +\x8b\x0fy\xf2\x15\xeb\xabF.\xe9\xe3K\x8a\x80\x01\xe1\ +\xe3\xab\x85\x9bw\x0b\xf5zT\xc4\x9c\xd6\xa0\xa4r\xfb\ +plu\xd3\xec2\x5c=\xcd\xb1\x99e*z\x09\x19\ +8\x11R\x83\x1dO\xd4\xf7\xda\x86\xc0\x1c\xbe\xf5\xe6\x89\ +\xab\x1aj\xa1@\xe9\xb3\x1b\x07OC\xebL\x8d\x9b8\ +\x89@\xd1\xaa\x1f\xe6I<\x18A\x12\xd7$I\x13\xc1\ +\x99B\xed\xe4\xca\x90*\xf5\xd2m6c\x9f\xeaz=\ +{_Z\x0c\xed\xf4\xdaiRA@\xf4O\xc6\x1a\x8f\ +uP\x09\x162d\x91N\x17}\xa6\xf2\xf6\xd9\xa7\xf4\ +\xf8\xb9[\xd16d\xc9\xd4\xee\xa6\x1d\xac\xc2\xc5\xe7\xb9\ +\xdb\x86CVmwm\xce\x8cB\x8b\xd1\xe5\x0c\xfbc\ +Bd\xed\x99\xadq\x93\x94\xfa\x07\xd3\xd9\xb3\xda \xcd\ +\xb4\x8cC\xbb\xa2\xdb\xf1\x04A\xaa\xc6\x05L\xf6}(\ +\x10`\x00^\x14\x03\x99\xd6\xf9\x10\x91*\xb8\xdfp\x98\ + \xad\xcaL\xac\x89\xb5\x9c U\x97;\xd5\x93\xad\xeb\ +\x00D\x0d\xf9\xd5\xe3\xe7\xee\xfd\xf9\xf2\xec@w:\ +\xd9\xe5ZN6\x88\xa5\xd5v&\x90\x1a\x15)\x82&\ +\xa9\xfc7>\xb79'\x9f\xba\xb3K\x92<\xe9\xf0\xc9\ +\xd7gBu\xfaP\xf9~\xf0\xd9\xe5\xbbU\x8e0\xa2\ +]\x83\x86ijPN\xdb5}\xf0h\xc3\xf0\xbe\x8a\ +\x8e\xde\xd9\xcf\xeb\xbb<\xaeWA\xcf\x16\xf9\xd1\xa1q\ +b\xc7[n,aX\x1f\xb2\xb9TN\xdamx\xff\ +l\xd6?\xfe\xd1\xeb[\xb9r\xd7W\x06\xde\xfd\xfeU\ +\xc0\xc3\x87\x19\xad\xb2O\xb0JDn\xcf\xb4\xb6\xd0\x9f\ +\x83+\xaa\xa4x\xeb\xdb\x10\xde\xba\x9a\xbb\xca\x0f\xd2\xf4\ +\x9d\x8e]{[\x10\xde\x05\x9aJ\x91\x1f%\x84Vt\ +\xf6\x98\xc3M;\xf6]\xeaW1u;\xfe\xb7wB\ +\x8fN\xa6H\xfdW\x87\xf4?\x9ei\xce3bz\xa1\ +\x0eZ\x83P\xce\x9e,+\x0ab~\xf4\x91\xa5\x0e\x01\ +q\xbe\x96\xafo\xe6^\xc6\xde\x95\xfd\xd9\x14\xfc\xf5\xba\ +Sg\xe1\x1d*#\xbe\xc6\x1c`\x15\xd1\xdc\xcf\x97\x12\ +%\xe4\x1d\xf3*cS\xa2~\xf4a\x8d\xd4\x06\xa6+\ +\xf84'\xf5\xef\xe7E\xc5W\xb6\xbf\xbeh(\xe1\x15\ +\xe5\x1d\xe5\x16\x0c\xc2\xd4\xe4\xfd\xf5\xceP\x1d}[\xe5\ +\x93~\xedZ%F\x0f\x95\xcf\x8b\xc1~~[\x10\xa4\ +\x16\x86d\xe7\xbe\x94\xfa\xec\x95\xd8\xfez\xd1(j\xeb\ +\xfd\xf5Y\xdb\x0bO\xa7\x9b\xfb{/M9A\xda\xf7\ +Y\xde\xbd>:\xa8\x0a\xfd\xe6\x90\x1f\xad\x11]\xad\xb4\ +\xb8\xed\xb5e!\xbc\xa58\x94\xfdY\x0e:\xfcG\xbf\ +\xa4\xcb\xea\x0a\xff\xe9\xde\x89\x0f\x5c\xb7\x8d\xcc\x03\xda2\ +U\xb1\xf7KJ$B\x7fr`\x8f&B\xee\xaf\x0f\ +\xcd\xd8\x01\xa1F\x97t\xd9Y\xd0W\xcf\xdb>\xcc'\ +Y\x08\xa8R\xcf\xdf\x88J\x0c\x0d\x140J\xd8_O\ +\xb8\xc4\xad\xd9\xf5g}3\xe9\xbe\x17\xff\xd5M\x8b\xca\ +\x85\xaa\x0a8,/K\x98\x88\xf4\x95\xb1\xde\x9c\xa5\xd8\ +_\x9f\xf7\x19{ks\xfbb\xdf\xd4\xb3\xbb\xa4\xcb\xfd\ +\x9f\xber=\x8b\xc8C\x17}\xd8\xa4z\xe6\x0e\xf1\x92\ +\x1f=\x19\x8a\xfd\xf5\xc0\xa0T&\xf7\xcb}c\xd4$\ +,%O\xe3\x9e\x8e\x9b?\xea\xd0\xd84\xa0\xb5z\xc2\ +%\x1d.b\x8cft2\xf34e\x85\xbf\xa1g\xbd\ +\xdc\xf7\xb1}\xe3\x13\x93\xc8\x0c\xb3\x96\xf2\x9b\xe5\x90p\ +\xc2\x1eW\xd48\x0a\xa0\x0a'\x96R/e\xaf7\xe2\ +z\x81}\xb5\x17\xde\xbb9O\xec&2\xf7~9\x14\ +\x08\x10\xfe\xad'\x1b\xc8T\x91\xea\xd9f\xdb_\xcf\xb8\ +\xde7\xc5>\xe8\xa0\xbf\x1f|x\xb2FR/7x\ +\x1c\xd2\xcf~!\xe0tQ\xaf\xd7J\x99\xb2^\xaf\xdf\ +\x96\xf2\xa3d\xa8\x88\xdc\x08]\x9e\xee\xdd\xbd\xfb\x9e\x87\ +w\xf63-\x87\x0b\x0b\x99\x95.\xa1\x83W!\xa8\xd1\ +\xbbwy*\xbb\xde\x9a-\x8d\xcc\xf4\x1a\xee\xc7\x1b\x1f\ +y\xe5\xa5\xab\x93\xcd\xb0\xe6\xda\x9d\x09\x13\x8ch\xbc\xa8\ +\xe0(S%\xe8}\x81\x9f\x97[\xf3\xe6\xec:o\x95\ +\xdbi\xb6>g>Z{\x84\xe6\xf6\xac\xed\x19\xd7W\ +hO\xe8x\xd3\xd1cD,Y\xfb\xb8\xc0Z\xe5p\ +\xcc\x09m\x17\x94\xaa\x09\xa1\x1d\xd4\x13\xbd\xd1\xf3\x0b\xf5\ +\xfa\xc9\xea\xf5\xc3\xb8I\x97t\xe9o+\x80K\x91\xaa\ +\x06*;\xdf\xdf\x1e\xdc\xb1\x7f\x94\x8d\xae'H\x0d\xc1\x89R\xc0LL\ +2\xd9N\xf0\xb4\x13\x9ag\xc4x\xf4\xe5\x8c\x98\x0e\xbe\ +\x1c\xc1\x18\x91Yx\xa4V\x06\xf7\xfd\xf5l\xcc\x14\xa9\ +\x00\x9c\xde\xcd\x88\x1dF\xb4\xa6\x81\xa6\x1aZ\xc1\x13y\ +\x9cg\x9a\xbcV\x1b\x00\xc9&\x00+D\xa9O\x11\x93\ +\x84\x88P\xa9\xc4r\x05?\xb1\xc4<\xdf\xd4\xc2.\xb9\ +c\x929*\xe2\xd4Q&\xb6\x8a\xd6tE\x87 \x84\ +.\xf8\xcf\x84\xa5C\xa4'$ L\x8a\xe6V\xf7\x8f\ +\xb6\x15\xe3\x02\xd4\xa2\xba\xa8\x98b$O}\xb1)E\ +\x89q}\x8b\x80\x9e\x04\xcd\x0b\xe0\xf2\xba\x02\x9c\x0a\x15\ +\x1e\xba\x1c\xe7q\x11~\xf1p\xa3-\x87\x03yG\xcd\x86N\xe1\x9b9\ +\xba\xed\x0c\x15K9\xd6Ph{\xf0\x14cB\x99N\ +h|\xb1Rb\xeft\x22\x8b\xbb\x8aRUn0\xdd\ +\xb0\x1b\x0c\x1d\xfa\xce\xd5\xd1\x0fL\x93(\x06\xad1I\ +6\x8fQ\x9c]\x94V\xd8P\x15\x16\xb1\xa3\xc7\x98\x09\ +\x93\xf4\xac\xc0\xfd<})Q\x8e\x83w*\x9d\xa3\xb6\ +\xf4\x88\xa0\x1a\xfe\xa1\xbe/9\xfa_\xc1*\xd8\xa0\xc5\ +Q\x93\x08\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x06S\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ +\x00\x00\x02\xebPLTE\x00\x00\x00\xff\x00\x00\xff\xff\ +\xff\xff\xff\xff\xbf\x00\x00\xff\xff\xff\xcc\x00\x00\xff\xff\xff\ +\xdf\x00\x00\xe2\x00\x00\xe5\x00\x00\xff\xff\xff\xe7\x00\x00\xff\ +\xff\xff\xd4\x00\x00\xff\xff\xff\xd7\x00\x00\xda\x12\x12\xff\xff\ +\xff\xdd\x00\x00\xe4\x00\x00\xff\xff\xff\xff\xff\xff\xda\x00\x00\ +\xff\xff\xff\xdc\x00\x00\xe2\x00\x00\xff\xff\xff\xda\x00\x00\xff\ +\xff\xff\xdb\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +\xff\xdc\x00\x00\xde\x00\x00\xe4GG\xff\xff\xff\xff\xff\xff\ +\xdc\x00\x00\xdd\x00\x00\xdd\x00\x00\xff\xff\xff\xff\xff\xff\xdd\ +\x00\x00\xff\xff\xff\xdf\x00\x00\xff\xff\xff\xdd\x00\x00\xfa\xd5\ +\xd5\xff\xff\xff\xff\xff\xff\xe488\xdd\x00\x00\xff\xff\xff\ +\xff\xff\xff\xff\xff\xff\xdd\x00\x00\xff\xff\xff\xff\xff\xff\xdf\ +\x00\x00\xdd\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xdd\x00\ +\x00\xde\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +\xde\x00\x00\xde\x00\x00\xff\xff\xff\xdf\x00\x00\xebpp\xdd\ +\x00\x00\xe0\x02\x02\xde\x00\x00\xff\xff\xff\xdf\x00\x00\xff\xff\ +\xff\xf0\x8c\x8c\xde\x00\x00\xff\xff\xff\xdf\x00\x00\xff\xff\xff\ +\xdf\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xde\x00\x00\xff\ +\xff\xff\xecuu\xdf\x00\x00\xe8QQ\xde\x00\x00\xf9\xdc\ +\xdc\xff\xff\xff\xde\x00\x00\xdf\x00\x00\xff\xff\xff\xde\x00\x00\ +\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf5\xb2\xb2\xff\ +\xff\xff\xdf\x00\x00\xff\xff\xff\xdf\x00\x00\xdf\x00\x00\xde\x00\ +\x00\xde\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xedqq\ +\xde\x00\x00\xff\xff\xff\xe3''\xde\x00\x00\xde\x00\x00\xfd\ +\xf4\xf4\xf0\x87\x87\xff\xff\xff\xff\xff\xff\xe3$$\xff\xff\ +\xff\xe3\x1f\x1f\xff\xff\xff\xfa\xd9\xd9\xff\xff\xff\xe2\x1a\x1a\ +\xdf\x00\x00\xde\x00\x00\xde\x00\x00\xff\xff\xff\xff\xff\xff\xdf\ +\x00\x00\xde\x00\x00\xea\x5c\x5c\xff\xff\xff\xe2\x1b\x1b\xe0\x0a\ +\x0a\xdf\x03\x03\xde\x00\x00\xff\xff\xff\xff\xff\xff\xde\x02\x02\ +\xff\xff\xff\xdf\x02\x02\xff\xff\xff\xff\xff\xff\xebcc\xdf\ +\x00\x00\xdf\x01\x01\xff\xff\xff\xdf\x00\x00\xe0\x08\x08\xde\x00\ +\x00\xff\xff\xff\xecmm\xde\x00\x00\xe1\x10\x10\xf4\xae\xae\ +\xdf\x00\x00\xdf\x00\x00\xff\xff\xff\xff\xff\xff\xf6\xbd\xbd\xfd\ +\xf4\xf4\xdf\x00\x00\xde\x00\x00\xe3\x22\x22\xf6\xc1\xc1\xff\xff\ +\xff\xe9ZZ\xf0\x8b\x8b\xff\xff\xff\xdf\x00\x00\xff\xff\xff\ +\xe3\x22\x22\xdf\x01\x01\xe522\xe8HH\xf6\xb7\xb7\xfc\ +\xea\xea\xfd\xf0\xf0\xfd\xf2\xf2\xff\xfe\xfe\xdf\x02\x02\xe9L\ +L\xe2\x1a\x1a\xe0\x04\x04\xe4&&\xe4''\xe0\x05\x05\ +\xe533\xe655\xe6;;\xe7>>\xe8DD\xe0\ +\x06\x06\xe2\x19\x19\xe9OO\xe9RR\xeaWW\xeaX\ +X\xeaYY\xebaa\xebbb\xecff\xecjj\ +\xeett\xeeuu\xee{{\xef~~\xef\x81\x81\xf1\ +\x8f\x8f\xf3\x9e\x9e\xf3\x9f\x9f\xf3\xa2\xa2\xf4\xaa\xaa\xf4\xab\ +\xab\xf5\xb0\xb0\xf5\xb1\xb1\xf6\xb4\xb4\xe0\x09\x09\xf7\xbe\xbe\ +\xf8\xc4\xc4\xf9\xd0\xd0\xfa\xd4\xd4\xfa\xd5\xd5\xfa\xdb\xdb\xfb\ +\xde\xde\xfb\xe0\xe0\xfc\xe4\xe4\xe0\x0b\x0b\xfd\xec\xec\xe1\x0e\ +\x0e\xe2\x15\x15\xfe\xf7\xf7\xfe\xfb\xfb\xff\xfc\xfc\xe2\x16\x16\ +\xe2\x17\x17f\xeer`\x00\x00\x00\xb6tRNS\x00\ +\x01\x01\x03\x04\x04\x05\x08\x08\x09\x0a\x0a\x0b\x0b\x0c\x0d\x0d\ +\x0e\x0f\x0f\x13\x13\x14\x15\x15\x16\x1b\x1b\x1c\x1c\x1d\x1e\x1f\ +!$%''*+,-./2669;\ +<=@ADEHKLMNOPTTU\ +Z\x5c]]`acegghkllmp\ +qsx|~\x80\x81\x83\x84\x8a\x8b\x8c\x8c\x8d\x91\x93\ +\x95\x95\x95\x96\x98\x99\x9c\x9d\x9e\xa4\xa6\xa7\xa7\xa8\xa8\xa9\ +\xaa\xac\xad\xad\xb0\xb3\xb3\xb4\xb7\xbb\xbc\xbd\xbd\xc0\xc1\xc4\ +\xc6\xca\xcb\xcc\xcd\xcd\xd0\xd2\xd4\xd7\xd8\xd9\xdb\xdc\xdc\xdd\ +\xde\xe0\xe1\xe4\xe5\xe6\xe7\xe8\xe9\xe9\xea\xef\xf0\xf0\xf1\xf3\ +\xf3\xf5\xf6\xf6\xf7\xf7\xf7\xf8\xfa\xfa\xfb\xfb\xfb\xfb\xfc\xfc\ +\xfd\xfd\xfe\xfe\xfe\xa0\xb1\xff\x8a\x00\x00\x02aIDA\ +Tx^\xdd\xd7Up\x13Q\x14\xc7\xe1\xd3R(\xda\ +B\xf1\xe2^\xdc[(\x10\xdc\xdd\xdd\xdd\x0aE\x8a\xb4\ +\xb8{p)^$P\xa0\xe8\xd9\xa4*\xb8\xbb\xbb\xbb\ +\xeb#\x93=w\xee\xcb\xe6f\x98\x93\x17\xa6\xbf\xd7\xff\ +\xe6\x9b}\xc8\x9c\x99\x85\x14R\xfaR9]\xfa\xf9\x80\ +(\xc4\x95A&60\x10\xa9\x19\xd9x\x80\xc7N\x14\ +\xed\xaa\xca\x02r\xa3\xec`%\x96\xb0\x1ee\x1b3p\ +\x80\xfa6\x09\xd8F\x00\xa7^\x17\xbe\xa0\xe8h\x19\x96\ +P}\xca\xeeh\x02\xae\xb6\x03^\x9e}\x08\xb0\x8e\x02\ +fE\x098a\xe6\x02y\x05\x10\xf9?\x03n.\x01\ +%G/9\xb0*4\x90\x0d4\x8f\xa2}2\x13\xf0\ +\xb3\xa0h*\x0f\xe8\x84\x22\xbc\x5c\x97\x05\x8c\x95\x80u\ +<\x0b\xe8-\x81sf\x16`\x92\xc0\xdd\xe9\x0a\xc0\xd7\ +)\xe06\x0b)k|7\x05\x90\x8e\x80\xa4\xfd\x8e\xe7\ +,\xcb.\xda\xe7+\x1f\xcd>\xa0h3\x09\x87\x147\ +\xc9\xbb\xdf\xbeG\xb1\x9f\xb4q\x85@\xd5B\x02bZ\ +\xa8\xfe\xb19*7\x0a(\x08\xea\xc2P\xb4\xa2\x95\x17\ +p\xaa\x85\xb2m\xc5X\xc2<\x94\xed\xc8\xc7\x01\xca\xa2\ +,\xb9'\x07\xe8\x81\xb2\x9b!\x0c\xc0o\x8f\x04l\xaf\ +\x870\x80`\x14\xe1\x9f'\xc7\xaa0\x80\xf9\x04\x1c\xbf\ +\xf7.q]\x03`\xb4\x89\x80\x17\xab\xbb\x96p\x07F\ +Y\x91\x8a\xab\xe1\xe2U\xd6r9\x9c\xfd\xbb\x88\x9a2\ +\x8fj(\x8a&4c\x01^\x16\xa4N\xfdl\xcc\x02\ +\x02Q\xf4tQj\x16\xd0\x17\xa9\xe8\xc4:\xc0\x02\x96\ +\x22\x15;\xd7\x9d\x05\x14A\xea\xbc\x16\x00,\xa05R\ +o\xa6\x01\x0f\x98Hc\xb2V\x81\x07\xa4\xddN\x17\xfb\ +m\x08\xf0\x00\x7f\xda\xae\x1f.\x0d\xea\xca\x13\xf0*R\ +yjN\x7f\x18\x0eN\xea@\xc0\xd9\x080\xb6@\x9f\ +n\xed-\xac\x04|\xeb\x05o%\xe0\xf6L\xe3\x9a\x9f\ +\xde\xed\xf3 P\x949\x08e\x8f\xfb\x1b\xf7&\xfar\ +'\x22\x8f\x0a\x18\x8c\xb2\xefq\x0d\x8d\xfb\x18\xfb\xf2\xed\ +kwP\x94\xc6\x82\xb2g\xe1\xc6s\xe0\xa1\xdf\xaa\x07\ +[\xb2\xff\xc3\xf7\xc25\xad\xb6q\xaf\xa8\xbfZBG\ +P\xb6\x16E7\x12F\x82\xb1\xb6\xf6\xe9a\xb8\xb7\x1a\ +0%\xe9\xc0\xef\xe7\xdaPGO\xb5D\xc4\x93?\xda\ +\x80\x93\xda\x1f9\x13s\xffe\xfc\x86\x9a\x0e\xd7\x8c\xcb\ +\xf1\xd2\xfb\xc5\x9e\xe0\xacr\xc3fO\xea\x5c\xcdG\xb1\ +f\x9a\xf3kMqp\xa9\x02\xa9 %\xf7\x17\x09\xba\ +99\xea\xb1au\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00X2\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\xdc\x00\x00\x01|\x08\x06\x00\x00\x00\xa41\xd5\xdb\ +\x00\x00W\xf9IDATx^\xec\xdd\xc1KUi\ +\x18\xc7\xf1\xdf\xb9\xd7\xeb\x95\x0b\x95a\x10:\xad$P\ +P\x08\x12\x0aqV!\x83%H\x10\x11-lQ\x11\ +B\x81\x04\xddjF\xbc\xaf`P\xa3\xb6(\x89 r\ +q!\x5c\xb4\x90\xac\x08\x936\xcd\xb4r\x06#b\x86\ +\x1a7R\xdc\xc8\x82\xb1\xc2l\x91\xf2\xf4l\x82\x10\xbc\ +HYi~?\xf0\xe5\xf9\x0b~\xbc\x8b\xb38\xfa\x11\ +\x00\x00\x00\x00\x00\x00\x00\x00\x82\xf4\x8b\xb7Cy\x001\ +}\x11\x9c\x94\xd6\x06\xa9_\xd2\xed\xa8\xa0\xa0E_\x0f\ +\x18\x1c\xafZRzh\xd2\x9e\x9f\xb6n\x1dJOL\ +<0\xb3\x94\xe6\x01\x14\xe8s0\xb4\x94I\xbfK:\ +\x1cO$&\xea\xbb\xbb\xfbj[[\x9fJ\xba\xeb\xbd\ +\xd3\xa2\x01\x18\xdb\x16\xef\x91g\xbd\x15\x15\x7fL\x8e\x8f\ +\x9f6\xb3\xc3^\x99\x16\x07\x80CR\x22H\x1d\x19\xe9\ +}G,69|\xfcx\xd6\xcc\x82\xb7\xdd+\xf8d\ +\x90E\xde!\xafr\xb7\x14\xf7;\xe4\x1d\xd3\xc2\x00\x08\ +R\xa57\xe2YOi\xe9\xdf\xb9\xd1\xd1\xb3fv\xd4\ ++\xd7\x1c\xbfJ\xeb\x834\x15\xa2\xe8IF\xea\x0c\x92\ +\xf5\xd5\xd5uiA\x00\xc6v\xd0\x9b\xf6\x01M\x0f4\ +7_\x9d\x9d\x9d\xed0\xb3]^\x91\xe6q\xa7\xad\xad\ +\xcb_\xc1\x99 Yg2\xf9\xf6\xbf[\xb7\xbaB\x08\ +1\xe5\x07\xc0\x87v\xfdLI\xc9\xfd\xb1\xe1\xe1sf\ +v\xc2\xabV\x1e\xedR\xcd\xa9T\xea^\x90lN7\ +\x95\x1f\x003\xab\xf1\x82\xd7\xec\xadV~\xcaH\x17}\ +\xa4S\x17\xaa\xaa\xfe\x0a\x92]\xae\xad\xbd\xdf\xdf\xd4t\ +c`\xdf\xbe\x1e3K(/\xf0Y\x00\x8f\xbd\x97Q\ +\x14=\xd1\x02\x1c\x18\x19\xe9.\xdb\xb4\xe9\xc5\x9b\x5c.\ +q\xbe\xbc\xbc&Y\x5c\xfcz\xef\xe0\xe0\xa0\xa4Bo\ +\x95\xf7\xbfV,DZT0\xb3\xa4\xa4jo,[\ +_\x9f\xdd\xd8\xd0\x90\xfb9\x9d>\xa2\xaf\x0e`|\xdb\ +\xbc\x16}\x13\x00\x83\x8b\xb4R\x01\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf8\ +G\x1f\x80\x8c\xd4\x16\xa4W~\xc3\xca\x18\x1eb\xfan\ +\xb0z\xc3\x86\x7f$\xad\x89EQ&#\xdd\x0bR\x8b\ +\x96\x130\xb8 \x15\xfe&\x95j\x19\x98z\xfe\xfcH\ +,\x1e\x9f)\xdd\xbc\xf9\xdf\xd4\xbau%Q\x14\xf5\x06\ +ig\xbbT\xb7[\x8ak)\x022R:H]\x92\ +\x22\xbf\x97\xbcgZ\xe2\x82\xd4\xe4\xd9\x95\xc6\xc6?\xcd\ +,\x5c\xdb\xbf\x7f(H\xf6\xb1\x8c\x94\xd5R\x04|h\ +\xef*\xa0\xaa\xca\xda\xf6\xbe\xa2\x82\xd9\x1d`\x8c\x9dc\ +\x8d\xdd\xdd9\xea\x98c\xd7\xd8\x8d\x88\x08\x16\x12ba\ +\xa0\x98\x01\x82\x8d\x05\x82\x01\x8a\x8aXX\x18\x08b\x22\ +) \xa1\xf2?\xef]\xfb\xacu\xbf\xfb\xe3\xcc\xe0\x10\ +\xd7\x99\xf7Y\xebY\x87\xb3\xcfa>\xef\xb7y\xef\xde\ +\xfb\x8d\xe7]\x96#\xc7z\xf9Gz\x08\xd7\xaf\x1bk\ +\xd5\xa2?\xe2\xc2:jhy\xc1\xc9`\xa0y\xae\x5c\ +Q\xd1\xaf^\x99{[ZV\x82\x81\x85\xad.Z\xf4\ +\xbd\xfb\x82\x05\x07\xb66n\xecKF\xb7,g\xce\xea\ +B\xd7\xc0`\xc4\x85\x855\xb4.S\xe6\x95\xb2:\xec\ +\xeb\xd1\xc3{G\xdb\xb6\xddt\xd4\xe0\x9a\xc0\xb8\xbe\x90\ +A\xed\xea\xd0\xc1\x17\xab[\x07\xdc\xdb\xd2\xfd\x15[\xdb\ +=\xb8\x1f\xb3\xaej\xd5\xeb\xa6*\xd5\xd7\xd7\xfe\xfe\xad\ +1^\x07\xdcm\x22DO\xc1`\xe8\xc0\x8a\xf1\x13V\ +\x87[\xd2\xd8\xb4\xf9\x93\xd0A\x5c\xb5\xb5]gU\xaa\ +\xd4\x9b5\xa5J\x85Z\x97-[\x1b\x06\x95\xb4\xbez\ +\xf5\x070\xb6)f\xfa\xfam\xc9\xf8\xb6\xb7h\xe1\x8f\ +\xfb\xe6x\xd6Pc\x9bi/\xb2\x12\x0cv\x9a|\x11\ +\x22Wv}\xfdl?u\xe9\xe2\x9a\xa7X\xb1\xb0|\ +\xa5K\xbf\x1d\xe4\xea\xba\xb9\xd7\xf6\xed\x9b\xe6DD\xe4\ +\x12:\x88&3fl\x9d\xf1\xf2\xa5\xed\x8c\xe7\xcf\x1d\ +\x12\xa2\xa3\xcd1\x94#o\xc9\x92q1aa\xee_\ +\x13\x13\xad\xb3\xe5\xc8\xf1\xa9\xfb\xa6M\x1e\x18\x7f\x96\xb7\ +D\x89\x10\x01\xe4)^<\xac\xec/\xbf\xe4\x81\x11\xaa\ +\xe7,\xcb\x9c*\x0c\x06V\x82\xd9\xe0\xc2\x0d5j\xf8\ +\xaf\xc8\x9f?\x1a\xf7]\xc0\xbe`\xa5\xbfX\x1d\xaba\ +\xd5p\xc4\xb5I\x16\xfc\x9bs\x81\xb5.YYU\xd9\ +\xd3\xa5\x8b\xb7\xf3\xc0\x81G\xb0\x82\x8d\xa3\x95\xccu\xe8\ +Pw<\xeb%W\xf0\xf24vh\xd0\xa0\xf3\x18[\ +\x02\x16\xc1\xbd3\x9d\xf9\xc0IY\x11\xbfc\xb0\xc1\x15\ +\x02sz,\x5c8\xe0\xc6\x96-\x8e\xb8/+\xfe\x1c\ +\xe4\xcd\x9c\x06\xc6\xe3\xac\x14\xbb\xbdy\xf3_\xb3\xf0\xdf\ +^\x18\x1c\x06\x1a\xc3\x89\xe2D\xc6e_\xaf\xde]\xdc\ +\xe7\x95\x06W\x8b\xc6\x5c~\xfb\xed0\xc6r\x90\x81\xad\ +,Xp\xab\xc66s\x8a\xc8\x220\xd8\xf0\xf2\xc9?\ +\xde\xc2\x7f\xb2\xaa\x95\xc5\xca\xe0\x8ek\xca\xca\xc2\x85\x03\ +\x9e_\xb8`\x8b\xf7G\xea\xc0*\x9d\x13\xac\xe3\xbf}\ +\xfb\xf6\x9b\xdb\xb6Y\xe2>\xbb\x00L\x84hJ\x86u\ +t\xec\xd8=\x8b\x85\xa8\x0d\x03\xf3\xa1{r\x12\x9d\x9a\ +1\xe3\xd8\xfd#G\x86\xcb\xcf\xe3\x02V\x14:\x04\x06\ +\xc7\xeb\x86\x82\x91\xe4\xa4\xd8\xdf\xb3\xe7\x91\xe4\xc4D3\ +\x18\xdbo`^\x1dY\xa9\xf5\xc0\xa6\xe0\x100\x874\ +\xb8\x8ed`p\xb0<\xc15i\xa9J\x15w\xb0_\ +?\xe7\xe4O\x9f\xe8\xdf>\x09\xecb\xae\xaf\xef+W\ +\xbb\x8f\xb8V\x11Y\x09\x06c\x81\x10E`h\xea\xed\ +\x9aE\xee\xdc\xcf\x03\x9c\x9c6\xc2\xc8\x16\x81\x0d\x85\x8e\ +a\xa1\x10\xc5\xb0\x92U\xd7X\x91'*\xdb\xc75%\ +K\xde|\xe1\xedM+\xf2\x02\xb0\x11\xa8\x12\x80\xb9\x81\ +\xc1\xdbU\x85\x0bG8\x0d\x18p\xea\xd1\x993\xd5D\ +\x16\x82\xc1a\x83.06\x8a\xd1}\xdd\xf6\xcb/g\ +\xe2\xc2\xc3-(\xd6\xa5\xc3\x81q\x17\xf03\xb8\x19\xdc\ +D1;\x9c\xedb\xdd\xe7\xcfw\xa5\x8c\x14p\x10\x98\ +O\xe3\xfd\x1a`\x0a\x1c/W.-_\xbeme\xa1\ +B7\xe4\xd6\xd3\x09\xf4\xa1-\xe9\xb7R\xe0Dz\x81\ +\xc1\x98\x0dO:\xfd\xc1\x82_\x91\x89\xf2\xe6\xea\xda\xb5\ +\xdb`d&`+Pg\xc3!^\xa6\xa6\xf5\x90)\ +\xe3\xaf\xacj\xcb\xf3\xe6}\xf3\xe1\xf1\xe3\xd50\xb2Y\ +`\xf5T\xb6\xc9\xb3\xe9\xbd\x0d\xd5\xab?\x96\x86\x9a\xb2\ +\xb2H\x91)\xab\x8a\x165\xa1q2\xd8\xd4\x82\xe6x\ +\xe6\x09\xee\x98/D\x01\xc1`\xfc\xd3m\x19\xa5N\x81\ +)\xc8\xda\xb8\x1c\xf9\xe2\xc5J\x0a*\x83\xa5\x7f\x10\xc7\ +\xcfx\xf2\xb6Z\x95.\xfd\x86Vf\x04\xca\xa7a\xcc\ +@\xa4\x02xY=\x14\xe34\xcb\x91#\x96\xae\xa7\xa7\ +O\xdf\x82\xb4\xb0\x17\xb8O\xda\xdd\xa9\xd3\xe5\x8b\x16\x16\ +\xbd5\xd2\xcar\x92\x91-\xd3\xd7\xf7\xc1\xf6:\xc8q\ +\xe4H\x03\xf1\x0f\xc1\xe0m\xa4\xc1\x8a\x02\x05\xce!L\ +\xb0Sn\xc3\xba\x82\xd9\x7f o\xab\x0a\xac\x9f\x94\x90\ +0\xef\x99\xa7\xe7:r\xa4|\xebs\xc2\xe0\x12\xd4\xe9\ +l\xdd\xbb{\xef\xea\xd4I\xed<\xc1\x99.\x0a\xce\x95\ +\xc4+66\x8e\xf2\xbc\xd7_\xbe\x7f\x17+^\x108\ +099\xb9\xdf\xdb\x80\x805\xf4\xbf#\x18\x8ctX\ +)\x86\x833\xc1\x8a?\xf0g0\x00[\xff\xd9\xca\xec\ +\xbep\xe1\xcc\xf3&&\x87\xf0\xceb8U\xae\x92\xc1\ +-\xcd\x96\xed\xf3\xc5\xe5\xcbwcl\x9a\xe6y\xcf\xa1\ +y\xf3\xd1X\xd5\xc2\xe9\x1d\x18\xeaAX\xe4\xc9\x13\xfb\xca\xdf\xbf\xb7`0\ +\x18\x7fY\x06\xd4-\xfc\xe9\xd3\x15\xbb\xda\xb7\xbfFN\ +\x95%\xb0C\x13!zk\x18\xdcQ\x8c'\x5c47\ +\xdfGa\x94\x88g\xcfV\x91a\xca\xca\xf4\x93`\xca\ +\xa9i\xd3\x8e\xe1Y'\xf1\xb7\xc0`\xb0\xe1\x15\x07\x87\ +?>qb#\xca\x7fn\xed\xed\xd9s\x94\x90@\xcc\ +\xee\x93\xad\x91Q\x88\xf4lV\x03\xeb\x86=~<\x1e\ +!\x04u }M\x89\x12/\xe1d\x99\x9bv\xcf/\ +\x83\xc1\x86W\x15\xfc\x03\x9c$$\xb0\xdd\x8c\xa2\xac\x96\ +W\x01\x01\x86\x1a\xefe\xc7\xf9/\x8e\xb6\x99\xe4\xf9\xfc\ +\xfe\x009\x83\xc1F\x97M3\xf3\xc6\xben\xddc\xb4\ +\x92\xc1\xc0v-\x10\xa2\x90,\xd0\x9dEcp\xb2\x04\ +\xe0\xdd\x09\xa0\x8a\xb6\xa1\xe4\xf5\x04\xef\xe0\x99\x03\x1c*\ +UE\xda\xc0`0\x9eyx\xb4D\xce\xe93\x0dg\ +\xc9\x07\xba\xc2;\x99\x18r\xf5*\x05\xc8\x8dp?U\ +f\xb1\xc4\x99e\xcf\x1e\xa9\xfeY\xa5z\x89kZ\xf3\ +S\x19\x0c^\xf1\x12?}\x1a\xebcm\xbdwO\xd7\ +\xae\xc7Q\xa1@\x86\x94\x02}\xcc;x6\x80\x92\x9d\ +q\x9f\x00o\xe5\x0b\xd4\xe3\xad\xc5\x98\xe9\xdd}\xfb\xb6\ +\xc2\xf0\x92`\x80\x81\xb2\x0a\xbd\xb1\xf8\xdb`0\xd8\xe8\ +\xb2\x83\xed\xc0\xb1\xa8\xab\xdbKbLjQ\xddz\xf5\ +Z+*\xd1\xa4\x0e-\xab\xd1\xcb\x83\xf5\xf7v\xeb\xe6\ +\xa5\xa1\xad\x92,k\xef\xd2\x08\x06\x83\x8d\xaf\xe4\xc7w\ +\xef\xcc|\xd7\xad\xdb\x99\x98\x98X\x1f\x06\xd5\x01L9\ +\xd0\xa7\xcfI\xa1\x01$K\xef\x95\x82\xb6\xd7\x8e\x8c\x1a\ +u\xf2\xd9\x85\x0b\x8d\xc4w\x81\xc1`\xa3+\x00\xf6\x04\ +\x7f\xfaC\x08}\xacxQ8\xd3\xd1*\xd6\x9fr2\ +\xc1\xc18\xc3E\xd3x\xec\xfb\xf7T\x025\xea}`\ + \xad\x86\xe3\xb1\xda\x1d\xc1\xf5(\xaeSp\xcd/\xd2\ +\x06\x06\x83\x81\xf3\xddR%.\xa7I\x0fcc\x17\x18\ +[\x9b\xf1B\xe4\xa0\x940\xe9X\x89\x05\xe3\xe5;\x81\ +\x7f\xd3\x9b\xc9\xca\xcb\x0c\x06\xadn\xa4\x1cVo\xe4\xc8\ +m\x93\xee\xdc\xb1\xe9de\xb5\xabl\x93&\x9e\x02(\ +X\xbe|H\x1b3\xb3+d\x8f%\x85\xf8M%D\ +\x17\xbd\x9c9\x13\xbb\xad_\xef2?<\xdc\xba\xd9\xec\ +\xd9GU\xd9\xb2U\xcc\xa1\xa7w85\xa5h\xf2p\ +\x82y\x05\x83\xc1P\x8cB\x8c\x90N\x91\x9b\xebk\xd6\ +\x1c\x1c\xe0\xec<\xca\xba\x5c\xb9\x07\xd4l\xe4\x9e\xb3\xf3\ +\x16R\x8f\x96\xef\xed\xc5\x16\xf3\x8be\xc9\x92\xef\xe8\xd9\ +\xaa\x22E\x0e#\xabe\xb0\xcb\xd0\xa1\xe7\xe8\xf7-\x8b\ +\x15\xeb\x22$4*\x19\xde\x81\xd6r\x88\xc1`\xf8\xf9\ +\xf9\xe5\x80\xcc\xfaa$5\xc7)\xdbH\x18T\xfc\x99\ +Y\xb3\xa8\xca|\xb4\x90\x80Z\xd8\x0ez\x16\xe4\xe5\xb5\ +\x16\xc9\xd2\xc7\xf0~4\xe9d\xae*T\xe8<\x8d\xef\ +\xef\xd3g\xb9\x14=\x1a\x88{_\xf0\x14\x8d_X\xb6\ +\x0c\x17M0\x18\xec@\xe9\x0c\xe5\xb0U\xc7\xc6\x8c9\ +\xe9\xd8\xba\xb5\xdb\x03WW\x8a\xc5\xcd\x01K\x08\x89\xfd\ +}\xfb\xf6\xa2\x95\x0dN\x94GO\xcf\x9d\x1bB\xc9\xd2\ +;Z\xb5\xba\x801\xb5\x92\x18V\xc6Y\x02030\ +h\xa9\x04\xceQ\x81\x10\xf3\xe8\xf8\xf1%\xe2\xff\x83\xc1\ +\xe0P\x018\x00\x9c\x0d\x8e\x00\xf3i=\xcf\xed:l\ +\x98\x1b\x19\x1d\x18\xb1<\x7f\xfe\x9d>VVf\x8f\xdd\ +\xdc6bu\xbb\x84\xe7}\xe4{\xf9\xd7V\xaa\xf4\x9c\ +<\x9e\xa4\xbd\x82w\x93`|Vs\x85\xc8'\xd2\x04\ +\x06\x83\x8d\xb2\xd1u{\xfb\x9d\xd0\xc8\xbc-\x0d)\x05\ ++\x9e\xa7L\x96\xfeI\x9e\xf5\x06\xd08\xe4\xda/\x04\ +\x9e9\xb3a]\x95*\x8f\xe4\x19\xd1]\xa4\x19\x0c\x06\ +\x1b]mp\xf6\x87'OV\xe3,w\xf4\xd4\x1f\x7f\ +,\xc3}.E\xd6\x8fd\xfaH9\x8c\x02\xeb\x18\xff\ +\x19\x9c\x0a\x91\xde\xddW\xd7\xad[\xf1_(\xffQ\x89\ +t\x06\x83!\xa5\xf7*\x82u\xc0b\xe0A\x15\x82\xe4\ +\x14,\xc7\xfd\x81\xa63g\x1e\xeblcc\x871/\ +\xf9\xee/\xe0O\xa0+\xc6\xe2\xc5?\x07\x83\xc1\x90\x1e\ +\xca\x14\xc76m.\x07\x04\x04d\xa4b\x18\x83\xc1\x08\ +\x0c\x0c\xd4'\x99\x07\x19^x\x01\x03\x5c\x8fk\x8f\xef\ +m\x9f\xbcX\x88\x9f\xf1\xfb\xfd\xbe\xb1Sc0\x18\x90\ +X\xefzb\xf2\xe4\x93V\xa5J\xddW\x9a\x8f\x98\x08\ +\xd1\xf6;\x83\xf2\xbb\xa5\xf1zS ]\xa4\x0a\x06\x83\ +\xcfx\x1d\xc1E\xd4\x15(\xf8\xca\x15+\xdc\xb7\x11\xdf\ +\x81\xb3\xf3\xe7\xb7\xa3\xec\x16\xd4\xe9\x05~\x08\x0c\xfc\x93\ +$i\x06\x83\x8d.\x87\x14,\xea\x00\x96\x15\xdf\x81\xa5\ +zz\xfb\xd4\xc2\xb6\xbbv9\x90\xf0\x91H;\x18\x0c\ +\x06U\x8f\x93J\xb4\xb1\x10\xe5\xfe\xe4\x9d&\xe0\xd7\x0d\ +5j<|p\xe4\x88\x89\xf3\xc0\x81z\xe2\xbb\xc0`\ +\xb0\xc1\xed\x04S\xccr\xe6\xdc.R\x87\x0a\x06\xa9v\ +\xbe(\xc4}0\xae\x15\xb9}.\x0f=\ +u*\xe4\x1b\x069\x5c\x85U\xd0\xb0U+\xff\xee\x1b\ +7:\xa0th\x97^\x8e\x1c\xc5Tzzg\xfe\xf3\ +)b\xb2\xea7eu\xb1bKq\xcdo,D%\ +\xc1`\xfcu_\xbc1\xe0 \xcdq*r\x85\xb1\x15\ +\xa7\x9e\xed\x10:\xfa\x10\xfb\xe1\x03U\x9a\x0f\x04\xfba\ +K\xa9.\x03\xb2*W\xae\xe3\x7fu[P\x1f\xac\x02\ +\xc6\xa26*46,l\x1e\x8c\xcf\x0b\xf7\x97\xc4\xf7\ +\x81\xc1\x81s\xd2\xcfL\x02S<\x97,q\xa6~\xed\ +B\x02\xe9b\x97(!\xfa\xe5\x8d\x1b\x03\xfes[J\ +\x18\x15\xb9yo\x82w\x85Je\x80e\xdfm\x7f\x8f\ +\x1e\xe5T\x18\xaf\xde\xb7o\xc4\xf7\xf4%c0\x0c\x9b\ +5\xdb\xae\x9f?\x7f\x98\x00\x9e\x9e9c\x84\xcb\x15P\ +\x98\x08\xd1=9>\xbee\xa5N\x9d\xae\x97m\xd80\ +B\xfc\x17a[\xb1\xe2u\xe5@k\xf7\xd3Ow\xb0\ +\xba}B\xb0\xf39\xfaV\x1b\xcb\xd2\x8e\xb4\x82\xc1[\ +\xcd\xd2\x09\xb1\xb1\x8b\xa8\x1b\xd0\xb9\xb9s\xad\x97\xe5\xcb\ +W\x15\xab\xde\x1a\xf01\xfa\x9aGG\x86\x84X\xe0\x9d\ +\xc2\xff\xa5md^\x18\x96\x19);!F\x92\x00\xbd\ +\xfa\xd7\xdb[\xb4\xb8\xa9\x18\xde\x8e\xd6\xad\xfd\x92\x92\x92\ +\xfe\x89\x94\x1a\x83\x8d.7\xd8\x03\x9c\xba\xb2H\x11\x92\ +^OVK\xb2\xd7\xaf\x7f\x1fY,\x9d\xffk\xe7\xb6\ +\xf2\xa8\x83\x8aR\x0c\xec\xfa\xc6\x8d;\x0f\xf6\xed{\x82\ +\xee\x91\x0d\x10A{l\xe8\xd7W\x10@*\xcd\x00/\ +\xa6U\xbd\x97\xc1}\xdc\xef\xbb\xb8l\xb4\xabT)\x08\ ++\xdc'\xc7n\xddJ\x8a\xff\x1avw\xeatR1\ +8te\x89\xc35\xc1\xb6|\xf9g_\x92\x93\x97F\ +\x04\x05\xad\xc2\x92\xdfD\xbb<\x88\xb4\x0c)Egy\ +\xbe|\xcbD\xda\xc0`\xa3\xab\x02N\x8f\x0b\x0b\xb3\xc0\ +\xf5g\xf1_\x02\xb5\xa7\xc5\x0a\x97`cd\xf4\xf2\xda\ +\x86\x0d\xbb\xc8\x88\xd4\x8aM\xc5\x8b\xbf{x\xe4Hg\ +\x18[\x03\xb0\x80<\xe8\xb6\xc4\xaa\x16\x86\xe7K\xaen\ +\xdbV\x02\xda\x16\xeb\xe3\xc3\xc3\xe7\xcb\xae.i\x05\x83\ +e\xda\xeb\x81\xb9\xffkn[\x1f\xea\xa4\xf9\xf4\xec\xd9\ +\xf5\x10\x9b\xd9\xa7n\x08\xd1\xa4\xc9\x9du\x95+\x07\xee\ +\xeb\xd1\xa3\x9a\xb6L\x1a\xb6\x99\xb7\x95R\x8d\xc3\xa3F\ +\x0d$\x83\x14\x7f\x0f\x0c\x06\x03\xc1\xc8c\xe7\xe6\xcds\ +\xf1\xdf\xb1c\x11\xb5\xb5\xc5V\xf2\xf1\xe7\xcf\x9f\x17\xc1\ +\x90\x16\xa7\xd6\xae6).n\x0aIe/\xd3\xd7\x8f\ +\xbd\xb0jUu\x91f0\x18\x5cv1\x17\x86gK\ +\xba\x84\xb2\xb5Qm0\x0f\xa8\x12Z\x80\x03\xe5\x0fZ\ +\xe1\xc8\xcd\x8b\xe7]\xffJ\x01\xf8\xff\xab\xf42\x18\xbc\ +\x97\xce\xfb\xf0\xe8\xd1\xd2\xef\x1f>\x5c\x8d\xfb\xc1Z\xde\ +\xc8n\x147Y D\x11\xfc\x5c\x18\xfc\xb0\xbaH\x91\ +\xd7I\xf1\xf1\x0b\x14\xa1\x19\xad\xf7\xf3\xcbt\x9e:\xb2\ +\xebf\x12x\x05\x1c%\xfe\x07\x0c\x06\x1b^KP_\ +\xeb\x8c7Wfv\x87\xe3z\x01L\x81Z\xd3n\xbc\ +\x97Z8@\x85\xe7\xa1\x14\xd4\xc4\xf5-\xc4CC\xe0\ +\x01u\x86xh\xb0<\xf7\xed\x07\xff$S\x86\xc1`\ +C,O\xdeK\xe8\xcc\xbf\x92a\x83\xc4\x8b+V\xac\ +\xc3x\xaa\x86\xb3\xa3M\x9b\xe9f9r\xc4\xd3\xbb6\ +\xe5\xca\x85\xa2\xee\xc9\x22>\x22\xc2tg\xbbv\xd7i\ +\xcb\xba\xaaT)C\xf1\xa7`0\xd8\xe8\x1a \xbdk\ +\xc1\x89\x89\x13OZ\xe4\xca\x15\xa7\xacV\xa9\x09\xc9\x5c\ +03\xebJ\xc1r\x0a\x9a#s\x85\xf4/\x92p\xee\ +\xb3\xfa\x9c\x988\x98\xe2z0\xd4\xa6\xe2/\xc1`\xb0\ +\xd1\xe5\x02\xbb\x86?\x7f\xbebw\xc7\x8eW\xd0\xf0\xe1\ +\xbe]\xe3\xc6\xf9S\xcd\x0e\x876}\xe0\xa9S\x1b\x9e\ +yz\xae\x83\xa2\xef}l-\xa3\x97\xe7\xc9S\x82\x94\ +|\xd3\x96\x93\xc9`\xb0\xe1\x15\x03\x87\x81\xa6`\x03\x19\ +\x10\xa7\xfc\xb8\x91\xb8v\xa6\xd5og\x87\x0eW\xe4;\ +\x95\xc0\xc9\xc9\x9f>\x99)g><\xef\x03\xfe\x1d\x01\ +\x1a\x06\x83\x1b2Be7\x0c\xdc\x8b\x9b\xcd\xa0\xbf\xcc\ +\xf5\x1a\x05\xee\x04O\xa2\xb9_l\xcf\xad[/`\xf8\ +,\xde{F\xefe70p\xc2\xf5\x1e\x0c-'\xae\ +kAO\xfc\x91-n\x93p\xfdL[\xd0\xb4\xc7\ +\xea\x18\x0c\x96O\xeb\xf96 \xc0\x92J{\xd4\xed\x8f\ +\x84\x88\xa1,\x95\x035\ +nkjzY?o\xdex\xfd|\xf9\x12\xc7\xfb\xfb\ +\xc7\x08]\x05\x83{{mi\xd0\xe02\xa4\x13\x1a\xe1\ +g_\xb0J\x16m3\x0d\xe5\xb9m62Q\xfa*\ +\x15\xe6\x07\xfa\xf6\xbd(\xcb\x80\x94\xda\xbcx\x94\x0b\x1d\ +\xa4J\xf3\x1b\x9b7;\xa2\x8a!\x0ac\x1f\xa4\xb2\xaf\ +\x22\xb5\xd6Z\xe8\x10\x18lh\xd60\xac3\xb8\x86A\ +\xfb\xef\x03\x94\x91V \xd3\x83\xee\xbf\xec\xef\xdb\xb7\xbb\ +\x0e$I\xab\xdc\xa6N=\x80\x7f\xd3G\xa8\x82\xbd\xc4\ +\xbd\xfeB!J\x90\xc7rK\xc3\x86we\x13\xf8_\ +\xc0\x8ew\xf6\xec\xb1\x92^\xcf\x14\x92}@\xad\xdeL\ +\x9d\xaa0g0\xe0\x09\x9cC\xeev0\x05\x8d\x13\x02\ +w\xb6ooO?#s\xdf\x9b\x14ou\xc4\xb1\xd2\ +\x02=\xa3\x97E\xbfzE\xfd\xa4\xa9\xf4\xa7(\x98\xb2\ +\xadi\xd3\xdb\xb8/($|\xd7\xad\xab@\xe3dt\ +\x10\x9f\xd9\x8cg5\x85.\x80\xc1\xa0s\x1a\x0e?\xa5\ +\x1c\x9a7'\x83KYY\xa8P\xa4\x868P,\xfe\ +\xb8I\xb4\xa5\xa4\x0ey3\x0b\x83M\xe4\x8a\xa5ZS\ +\xb2\xe4S\xf9E\xf1\xab\xc6g\x9a\x01\xa6lo\xd5\xea\ +&\xde\x1b%uXjb\xcc\x02+\xb6-8\x08\xcf\ +\x0dD\x16\x80\xc1\x06\xe7L\xe2\xad\xb8Fa\x95{\xf7\ +\xf1\xcd\x9b\xe56\x86\x86\xa1\x8a\xd1\xad\xabV\xcdE\xe8\ +0|\xac\xac\xa6\xe0\xcc\x16CF\x07Cz\x09\xde\x94\ +_\x16\xf1\xef\x1f<\xa0\xe2\xd8\x92\x18\x9b\xa0\xac\xde\xca\ +\x15c\xcf2\xdd\x13\xcb`\xb8\x8e\x1c\xd9\x84\xfe8\xc9\ +\xb8 _\x17cW\xa5\xcaI\xb5\xdb\xbd{w\x9f3\ +3g\x1eE]\xdb\xec\xbf0\xd8\x8a\xf3\x85(\x90\x85\ ++^\xfe\xd77o.w\x1d6\xec,T\xc4|\x10\ +J \xe3K9\xd8\xbf\xff\x05\xcad!\x0dM\xf03\ +m/ON\x9e|\x0cFh\x89\xeb\x09\xbc\x97\x04\xc7\ +\xca\xbbLM\x11c0\xb0%\x9bH\x06\xb6\xa9N\x9d\ +\x87\xcav\x92d\xef w\xb7\x01\xabCop$\xa8\ +G\xb19\x8ae\x81m5\xb7cX)\xa2\xc1w\xe0\ +\xb8,\xdef\x0e\x07\x17\x1e\xe8\xd3\xe7\x22\x0c\xe9\x0b\x09\ +\x86\xba\x0e\x1dZV&<\xa7\x90\xb3\x85>\x17\x9c(\ +\x87_\xf8\xf8\x0c\xf7X\xb4\xc8Iv\xfb\x99\xfb'\xab\ +\x7f\xc1tK\x1fc0(\x03\x03\x86\x12\xb9\xb2`\xc1\ +\xd7\x10\xd8\x5c\xb6\xaeJ\x95@\xfac\xa5,\x0e\xc8\x97\ +{\x0b\x09\x18Y{%\xebC2\x82\xceA\x02ph\ +\xd6l%\x8da;z\x5c\x07\xcew*\xb0\xe9\xe3\x13\ +'6\xc2\xa3\xe9\x14\xf7\xe1C\x19\xd4\xd5\xa9\xbfP.\ +,[v\xf0\xf0\xf0\xe1'\x11^\xf8H\x9f\xd9\xbal\ +Y{\x1a\xdf\xd2\xa8\xd1q\xa1\x01\xd2a\xa1\xab\xdc\x86\ +\xc6J\x99\x88\xc3\xe9\xb1\xfddp(`\x12\x0c,\xf1\ +\xf6\xde\xbd\xdbv\xb5o\xbf\x86\x0c\xc7i\xe0@/j\ +\x82\x1e\xfb\xee\xddB\xea\xdf\x851C\x90\xe2Z\x9f\xa0\ +9ylO\x97.\x9eH\xad\x0a\xc5j\x91H\x86\x88\ +jn\x7fd\xfc'\x85^\xbbf\x83\xf7\x8b\x0a\x1d\x80\ +\xec)=\x16\xac\xb4\xa9a\xc3\xaa0\xba$T\x93\x07\ +?>}z\x14\x9d\xeb\xb66n\xecM\xdbL\xa9$\ +\xe6\xa4\xb1\xa2\xb5\x93g\xe4\xeaU[\xad\x9e\x00\x02[\xb0\xcddT!W\ +\xae\xccS\xa4\x0ep5\xd8\xd7\xb3\xe7I\x1a\x87\x870\ +\x22\xf6\xfd{S\x8c\x15\xd0\xe1\xcfY\xf3\xea\xda\xb5\xbb\ +\xe1}U\x87\x10\x88p\x10]\x87l\xdf,\x0a\x94\x0b\ +\x0d\xec\xea\xd8q?\x19\x1b\x04\x90\xdeK\xc3\x0bE\xf9\ +\xd0\xb0\xcfII3e\xc5z\xba9Y\x18,\xee:\ +P[\xc8\x15N\x86%\xd2\xa9\xb2_s\x1cN\x88\xa3\ +4~\xde\xd8\xf8\x10~\xa7\x8d\xd2\xc6J\xc6\xbb\x0cu\ +\xd1\xe8\xc0\x05/.]Z\x0b\xc7\xca\x99\xcd?\xff|\ +(2(\xa8\xa0\xa6\xc4\x9fL\x82\xfe\x88\xad\xe4\x8b/\ +_\xbe,\xf5Z\xba\xd4\x09\x8a\xd1a0\xce\xa3R\x9f\ +\xa5\x0a\xa8'2\x0a\x0c\xc6\xbd\x03\x07\xca\x91\x9a\x96\x8c\ +s\xed\x01IEy7\x98\x82f\x8c\xc1H\x9b\xa2U\ +\x82D\x5c\xe7\x81Q\x1a\xb1._\x13!\x1a\xe8`\xd1\ +km\xa9\x9db\x0cV\x95\x95\x11\x0bd)\xcf.\xfa\ +\x9ct\xa6\xc5\xb3\xfa`K\xac\x82\xc6X\xddL2m\ +ec0^\xf9\xf9M\xb7\xaf[\xf7\x01\x9c\x0f\xb1d\ +PJ\xda\xd4=g\xe7-t\xde\xc3\xfdh\x1aC\x0e\ +\xe6K\xac\x1e\x87\xe0\x94\xb8\x88w?\xe2\x1d\x8a\xef\xb5\ +\xd0\xd1\x15=\x9b\xc6\xaa\x16\x89\xebg\x99\x97y\x8b\x1c\ +.\x1a\xef\xe5\x03\xab\x89\xcc\x02\x83A\xe73p\x02i\ +D\x92{\x9d\x8c\x8bt$\xb1\x9d\xb4\x95[1\x7f\x1a\ +\x83\x91%\xef\xeb\xde\xdd\x1d\x8e\x86\xd9\x10s\xb5'=\ +J\xc4\xc3\xee\x09\x1d\xc7\x93s\xe7f\xdb\xd7\xabw\x97\ +>\x03\xc5\xef\xac\xcb\x95[J\xd2\xeb\x22\x0b\xc1`\xa3\ +\xd3\x03\x0d\xc1\xa6\xd77m\xda\x8c\xb3]\xb0C\x8b\x16\ ++\x05\x80\xac\x8d\x08J\x07C\xd8\xe0\x12\x85\x0b\xc8\xd1\ +\x00o\xdf4\xc4\xb8\xfc\xc8\x10ON\x9aT\xe8\x1ba\ +\x89\xa1\xa0+8\xddX\x88\x0aY\xf8\xd9J\x82\x13n\ +l\xd9\xe2\x88J\x84W2\xf5\xcb\xeb;S\xe5JK\ +\xd9\xf6\xb5`A\xf1O\xc1`\xc8\xf3\xcd\x1cp\x81\x00\ +,K\x94\xb8\x8dVT\x09\xf7\x0f\x1f\x9e\x1bt\xf1\xa2\ +\x1d\x02\xe8\xfer\xdb\x99@J\xca/}}\x9bh\xf6\ +\x1d\x00\xed\xf0|\x83\xccy\x0c\x92\xe7\xc38pL\x16\ +{l\xebC-z\x1e\xa5\xb4\x1d\xe8\xd7o\x07\xee\xf5\ +\xbf'\x19\x1c\xab\x7f\xb4\xdcz\xa7_\x1e*\x83\xfb.\ ++\xa1\x80\xb3\xf3\xe6M@p\xf83\xb6\x99\xe1(\x5c\ +\x9d\x1a\x17\x11\xf1\x07Jdv\x22U\xec\xe5\xc6Z\xb5\ +\x1ek\x86\x1a\xd0+@\x1d`\x97\xfd\xc0CH\xf0\x95\ +2C\xd6\x94(\xf1J\x8e\xb7\xd2\x81\xcf\xd5I\xd6\xd7\ +\x95\xf8\x0e\x83\x1b\xa0|\xbe\xad\x8d\x1a]&G\x8dH\ +g0\xd8\xf8\xf2\xa1:|\x1b\x9c&1J\xea\x17\xb6\ +\x9c.8\x1bY\xbe\xbd{w\x0d)si\xbc[O\ +\xb3\x1aa\x99\x81\xc1S\xa7\xfe\xfd\xc7\xc5\x86\x85\xcd%\ +7|\xd0\x85\x0bm\x7f\xe0\xca\x0b\x03\xac\xd2At\xbe\ +\x95\x95\xe9\x94@\xadR\xf22\x97\xe0\x92^[g\x06\ +\x1b]\xe5\x84\x98\x18\xe3\x0b\xe6\xe6\x07\xd0z\xd8\x8f\xce\ +r\xc8\xccX\xac\xdd\x88C\xca\x96\xa7\xc0\xb9\xe2}b\ +\xf2\xe4\x93\xd8\x8a\xaaKk\x90\xc9\xd1J&K7\x14\ +\x1a0\x11\xa2+U$\xfc \xa9r\xc6dhH\x93\ +\xbbFW\xb4W>\x22\x8d\xad\x15\xf8B\x9e\x0d?\x81\ +\x83\x04\x83\x91.Y\xfbr;\x96\xf8\xf1\xe32\x5c\xa7\ +\x08\x80<~$\x87 c^O\xe1\xbd\x8cDa\xab\ +9\x9e\xf7\x08\x7f\xfat\xc5\xb9\xf9\xf3\x0fE\x05\x077\ +He\xc5\xc8K\xc9\xc3`\x1c\xf5\x0a\xd7\xf5Dp\x19\ +4\x0f\xf241\xd9A\xc6\xe5\xf6\xc7\x1f\x8e\xb8Z\x80\ +\x9f5\xb6\xd1\xef\xb0\xcd6\xc7\xfd\x1cp\x98Z\xf5\x9d\ +\xc1\xf8\xa71.\xd9\xf5\xc6H\x1a\xcef\xf9\xcd~\x9e\ +V\x80\xb3s\xe6\x1c\xc1\xb3\xf6\xf2\xdd\xa2\xe0\xaf`=\ +\x0dC\x1b\x8dw\x7f\xc75\x9b\xcb\xb0aS\x91\xaby\ +\x8a\x12\x91\x85\x8eB&=\x1f$\xfd\x97\xbb\x07\x0el\ +E\x1c\xd2T\x86\x18\xa2\xa5\x91=\xc1\xd95\x11ip\ +\x1f\xa3CCW\xc4~\xf8\xb0\x04\x0e\xa5\x00\xb9\xe2]\ +LWu4\x06c\x7f\xaf^?\xe3\x9b\xff\x81Rk\ +wz\xfa\xf4\x03\x81\x81\x81\xdf\xf4\x00\xe2\x9d\xb3r\xfb\ +u\xf3\xe8\xef\xbf\xff.\x93\xa6K\x0a\x1d\x84\xb1\x10F\ +R\xfb2\xc5\xb6B\x85\xe7\xc8\xbc\x19k\x9a-\xdb\x22\ +%9\x00\x09\xd0gP\x97\xe7N\xf7\xe4\xfd\xc4\xe7\xe8\ +\x0c\xe6\x83\xca\xf4^Y\x91\xe0\xef\xd8\xad\x9b\xfa\xb3\xc9\ +\xdey\xff\x1c\x0c\x0e\x9c\xe3\x0fq\x9a\x97\x99\x99\x13U\ +\x19Hc\xba\xaa4\xef\xd0\x06d\x1e\xda\xec\xee\xdc\xf9\ +*\xbd\x87\xd2\x9f\xd3\xba\xae\xb8ur\xea\xd4\x158\xaf\ +\x86\x93\x01\xc1\xdbj\x8d\x1a\xc1\xaa\x0eM\x9b\xde\xban\ +o\xbf\xf3\xed\xbd{+\x11\x1a\x89\xc5\x195\x04)b\ +s\x94P\x83U\x992\xd3\xe9}Z\x11\xe9\x9c\x8b\x9f\ +;\x81Q\xe0\x22\xdaz\x8b\xf4\x00\x83\xfb\x81\xa3\x95\xb0\ +\x89\xcb\x90!\x1e\x88\xbf\xc5\xac.Qb\xd07\xde\xcd\ +i]\xa6\x8c\x1f\xc5\xf0\x9e\xb9\xbb\xdb\xe2\xbe\xa0\x8e\x7f\ +\xb6\xba\xf4\xb9P\x06\xe4\x86\xaa\x84\xc9\xb8\xcf\x85x\xe4\ +\x02\xa4\xc4-\x5c\x91/\xdf>r\x0a\xf9;:n\xc7\ +\xf8\xcfB\x02\xdb\xcb~dp\x90{0\xa5\xf3-V\ +\xc9mt/WvW\x91^`p\x08\x01\xecK\xd9\ +\xf8\xb8\x8e\xd48\x07\xd5\x07\x0d\x149s\xa5\x1e\x0d\xef\ +\x0cI\xe5\xcc\x94SG?W\x1fp\x84\xfc\x0c\x0f\xc8\ +\x89\x02~Al\xf2\xb6\x14\xb4Ui|\x86f\xea\xf3\ +]\xd1\xa2\x8fp\x8dW\xb6\xa4G\xc7\x8e=}z\xe6\ +L\x1b\xac\x8aN\x18;\x07\xd6\x11\xe9\x04\x06w\xcd)\ +\x22\xcfA\x95\x14%-\xa9\xfc\xfc\x88\x1c\x0e\x10\xa3\xb5\ +P\xdeQ@\xed\xac\xe4\x1f\xf2e\xbc\xa7\xb3I\xc5'\ +\xa6L\xe9\x8b4\xb1\xe7dH\xc8\xbcy\x06c+\xa7\ +\xe5hiB\xcfdH\xe4\xaa\xdf\xd6\xad\x9bd\xbd\xdd\ +\x14\x22b\x9a\xe7\xe8\xb9\xec\x87\xb7\x5c\xa4'\x18\x0c\xe8\ +\x8d\xac2\xcf\x95+B\xd9V9\x0f\x1a\xe4I!\x86\ +\xd4\x1a4\x22v\xf7\x9a\xde\x81\xe7\xef$\xae[\xc1f\ +:\xb8\xe2\x95\xc6\x99m\xb6\xc7\xc2\x85.\xa7g\xcc\xd8\ +G\xdbd\x0a\x8f(1E\x18\x11I7$\xdf\xda\xb5\ +\xcbA\x1a\xdah\xb0\xb2\x12@G\x22x\x94e\xc9\x92\ +\xefP\xa5q\x0f\xe7^?\x8d&+\xe9r\x9ee\xf0\ +\x8a\xd7\x10\xce\x12\xb3\xfd\xbd{SiO2y3a\ +P[\xb4e\xecp?XQ\xe1ZS\xaa\xd4\x13*\ +\x01\x92\xba\x9a\xedt\xd0\xe8r\x82\xed\xc0?\xc0\x22$\ +'\x0f&\x83\xc7\xe4\x96\xd9Gn5\x8d\xb4>\xe3(\ +z\xee6m\xdaq8\x9bf\xa37\x9e9\x85Y\xf0\ +{\xb7h\xab\x0av\x11\xe9\x00\x06\x1b]A\xf0\xd7\x17\ +\xde\xdek\xe9\x9b]\x86\x11\x96k&\x06\xc3\xb8\x82-\ +\xf2\xe4\x89\x80\xe4\xf9rZ\x19B\xaf_\xb7\x81\x870\ +\x12F\xfaF\xe88\x8e\x8d\x19\xf3\xd3\xfaj\xd5\xfc\x94\ +U\xdc\xf9\xd7_=\xde<}Z<\x95\x8c\x95\x1b\xa4\ +\x15\xfa\xe1\xc9\x13c|\xfe=\xf8lA&B\xfc\xb2\ +\xa9n\xdd)\x18\x8f\x91\xdb\xef-\x22\x9d\xc0`\xc3+\ +\x0fN$\xa1\x1f\xe8\xa5P1(\x89\x19\xcd\x07\xf7\x91\ +\x11\xba/X\xe0\x8a\xe7\xdd\xc1\x22`\x05x4_P\ +\xed]ttt\x11\x1d\xff\x5c\xb9\xc0q\x14.\xc0\xea\ +\xfcV\x1a\xde2\xa1\x012,\x1a\xa7\xb0\x02D\x9d\x14\ +\xe3\xa4\xea\xfa\x09\xc8WmM+;\x09\xf6B\xc6}\ +3%\x18\xe0Y\xe1\xf4\x12\xb3e\xb0\xc0Q\x03\x19\xa3\ +2\xc0\xd6\xf1\x85,\xe7I@B\xb4\x89\x92\x85\x8f\xb1\ +64\xbe\xabS'_\x8c\xd5\xd4L\xb5\x82\x83\xa56\ +\x9e\xe5\xd7\xc1\xcf\xd5\x10e@\xf3\xcf\x9b\x98\x1czt\ +\xfc\xf8X\xad\xed\xe4n\xe5s\x92\x87\x13a\x85p\xba\ +\x0f8t\xc8\x04\xd7K8\xf7%\xdd;x\x90*\xed\ +\x17\x82%1\x16\xa8\x08\xf1\xa6\x9bh-\x83\xf1\xfa\xf6\ +\xed\x11\x14\x0c\xa72\xa0\xed\xcd\x9b/U23`P\ +\xb7\xa9\xe9\x08\xb44W\x91k~\x81\x10\x85\xb0\x12\x9e\ +\xd0\xe8!\x10\x87\xab\x83\xae\xad\x02\xa4|&\xb3N\xfa\ +\x0a\x09\xca\x17\x85\xd1$(\x15\xf5p\xb8\xec\xb5\xfb\xe9\ +\xa7gT\x85n_\xbf\xbe+\x8d\x1f\x1b7\xee8\xad\ +\x92J2\x00*-\x86\xad,P\xe0\xb5\x5c\x09\xfd\xd3\ +\xb3\xd3+\x83e\x1e\x86B\xbea\x05\xae#aH\xb3\ +\xc1h\xd9\x92\xf84m1\xe5\xf9\xc7\x8b\xc6P\x02\xe4\ +\x8b\x1cLgl\xc5\xee\xc84+\x7f]\xcf\xe0\x80\xc1\ +\x8c\x00S\xcc\xf5\xf5?\xd1\xb6\x93\x1c&\xa4#CJ\ +\xd8\x14>@\xd23u\x03\x9a\xaf\x99\x08@[\xeag\ +\x9e\x9ek\x94~xD\xdaz\xcf\x16\x22\x8fH\x070\ +\xd8\xf0*\x81F\x96e\xca\xd4A\xb6\x86\xba\xaenw\ +\xc7\x8eT\xe8\x99[J\xf4\xa5\x10!\xf8\x1a\xee\xbep\ +\xa1=\xc6\x17(\xb9\x8c\x88m\xcd\xd5\xf5l\x9c\x8b\xcb\ +\x97\xefxx\xf4(\xc5\xe4\xa6 \xdf\xb2\xa1bD(\ +\xe6}G\x89\xcf\x18\xaf*\xb4\x00\xa3}\xfa#\x8d+L\x13\x92\xf0\xcbjg\ +\x0b\xadV\x1aAq'\x8d\x15\xeb-\x82\xfeoI\xda\ +\x82V\xfbT\x02\xe8\xea\xb3\x1dmG\xf1\xf9\xadm\x8d\ +\x8c\x14\x99\x87\x99\x22\x1d\xc1\xe0\xf8]\xf77w\xeeX\ +Q?8\xfcA>\x87\xd1\xc5\x1e\x197\xaeYZ\x15\ +\x94ap\xeb\xa4\xd7\xef\x09\xaee\x85\x0e\xe0]@@\ +=\xac\xd8\xe7i\xc5\x22\xe3Y_\xb5\xea\xd3\x07\x87\x0f\ +\xf7H\xe5l\xd7\x9a\x9e;\xb6n}]6\xd5,G\ +\x0dY\x90\xa5\x13\x8b\x5c\xd4\x0f\xe9\x1e\xb3c\xb0\xa8\x11\ +8\x08\x5c,\xf5U\xd2\x1c\x9f\x82\xa7\xf3\xa0\xe2%\xdc\ +\xdf\xbf\x7fC\x1d\xca\xcf\xecG+\x16\xa4\x1c\xeeJM\ +\xcfh\xe5|\xa6\xc4'1v\x0b\xc5\xbb\xb1\xef\x1f>\ +\x5c\xad\xc8\xfd\xe1\xaa\x8f3\xe1e2\xc4\x8bVV\xe5\ +\x04\x83\x91A\xe9Tu\xc0|\x22\x0d@\x88\xe1gE\ +:\x81\x88\x9ex\xbd\x84\x04b\x0b\x14`/\x92\xc5\x86\ +W\x0e\x1cwk\xe7N\x07\xc8\xb4\xdfp\x1e8\xb0\x8b\ +R+\x08\x8e\xd7\x88O\xf6\x10\x1a\xc0\x0aw\x9d<\xb6\ +X)[h\xac\xe4u\xc0\xb1\xd4\xf55+Vr\x06\ +C\xa5N\xa3\xd2\xd3K@\xeb\xe57\xd4\xe1\x95\xdc\xf5\ +\x1aulOe+\xe2\xb1:\xb0\xe2\xd5\x03g\x82C\ +(\xd8-k\x05\x93\xd5g\xbb\xd8\xd8E\xd2I\xa4\x18\ +VIl\xaf\xe3\xa81\x0b\xc6\x1bK\x1dM'%+\ +G\xa3\xfen=\xeb\xab02\xd3\x1d\xff\xab\xd2\xd9\xd5\ +\xa6\x5c\xb9\x17\xa4\xc3\x12\x1b\x19Y\x0fcK(\xc4\xa0\ +\xaczr\x05,\xad\x0b\xe2\xae\xb2o\x9dj}\x8d\x1a\ +\x9b(\xdf\x12\xfc\xb2\xb6R%\x8a\xc1\x15\x97E\xbe\x15\ +`H\xf7)#\xc5\x7f\xfb\xf6\xed\xb1\xb1\xb1\x94\x87\xe9\ +\x02\xa6 \x91\xfa6r:\xd7\x93\xbe\x0a\xad\x96\x8aL\ +;\x15\x03\x8b\x0c\x06\x83\x8d-7\xf8\x02\xf1\xbbp\xea\ +\xecj\x9e;w(\xf5\xc7C\x96\x8a\x9f\x145\x8a\xa5\ ++Je\x1eRsG\xbbJ\x95\x1c\xa4\x01\x1e\x05K\ +\xeb\x80\xe1\xb5\xa2\xfe\x0e\xf4\xef\x93\x86\x93@\x82M`\ +8\xdd\xbb\x0e\x1bF\x92\x83c\x95/\x95mM\x9b^\ +\x91\x81\xf2\x81`[p\x02T\xd6.+_(\x14<\ +\x17\x19\x04\x06\x1b\xdb2\xac\x02o4;\xbb\x92\xe2\x96\ +\xb2\x9aAQ\xf9,\x0cL-eN\xc6\x86\xe7]\x1f\ +\x9f=[\x8fV\x0d\x99\x11\xb2UG\xce\xad\x15\xc1I\ +t\xbeC\xbf\xbb\xab\xe8\xe2\xfa\x002\x0e>>\xd6\xd6\ +;e\x95Aq\x0a+\xa0\xa4):.,\x8c\x8c\xad\ +\x81\xd0\xc0\xd9\xb9s'Kc\xa4\xdc\xcdF\xf8y\x15\ +\x8coe\xbaV^0\x18\xab\x8b\x17\xef\x85\x00\xb9:\ +!\x1a[+\x7f\xe7\xc9\x93\xf3\xae.Z\xf4\x1e\x09\xb8\ +^\xb5\xb3\xdbu\xd1\xdc|\x1f=C\x7f\xf3K\xe4\x01\ +U\xf2\x1f\x91\xcd\x1f\x83\xc2\xd2\xa7\x90T\x98\x86{\x15\ +u\x08R\x84l\xb3X\x8c\xb7\xa1\xd4H1\x95\x9c\x04\ +\x1aQ\xe5\x04\xf8\x15\xf1\xc9k\xb8o#\xab.zQ\ +\xa5\x85R\xb5\x80\x8a\x0c\xef\x88\xe7\xcfW\x92T\x04\xbe\ +Hv\xcb\xd5\xf2-8:]>\x17\x83A\xee\xf3\xb0\ +\xc0\xc0\xe5\x08\x94\xfb\x22$\xf0\x1c\xa51\xc5\x92\x93\x93\ +{Q\x85B\x5cd\xe4\x0c\xaclA\x1a2\xed\x85\x84\ +\x04\x0aB\x83q^zA+\x05y\x09\x11lV\xb6\ +s\xbe`q\x1d\x91\xa0\xcf\xaf\xd1X\xc4\x80Ve\xfb\ +\x9f\x7f\x0e /.%}\xcb,\x940<\x9bH\x06\ +(\xd3\xe5:\xcb\xec\x1d+28\xc4\xef\x94\xd5\xfe\x86\ +\x89\x10\xcdE:\x80\xc1FW\x0c\x1c.W\x84&X\ +\xddZ\xe2\xfc\x16\x08'\x84\xab\xb6L\xbb\x02\xa4N\xdd\ +\xa6\xea\x04\xd4\xa5\xcd\xc5;!`\xca\x8a\x02\x05\xa2\xf0\ +\xbb\xefV\x97,I\x92\x7f\x8b\xa5\xe8\xad\xce\x00+\xf2\ +Ei<\xa6\x02p_\xb4h5y6\x15\x83RV\ +;\xba\x92!\xe23\xbe\x87\xe6\xcc\xf2\xc3#F\x9c\xc3\ +96^\xaex\xfb\xd3\xebs1\xd8\xf0J\x83\xd9H\ +\xc2\x0f\xf5i\xc1dD8\xcf%\xbd\xbc~\x9d\x82\xe8\ +9\x85\x06,\x8b\x17?\xaf\xd1~\xeb9*\x18\xf6$\ +\xc6\xc5\xd1{\xa6\x10\x022S\x0aaA\x13]Q\xdd\ +\xba{\xf0`\x1fH8\x84I\x03\xdbup\xc0\x80\x09\ +\xa8\xb2P\x1b!*-n\xec\xed\xd6M\xe9\x0b\xb1\x96\ +\xc6\xce\xcc\x9au\x14\xfa1\xbd\xae\xae_?\x1d\x15\xf7\ +\x96x'\x88\xc6\x97f\xcf>_0\x18\xe9y\x16\x8a\ +\x8f\x8c\x9c\x874\xb1sp>D\x1d\x1e9r\xa2\x90\ +PV\x00j\xb9\x8cz\xb5H$K\xef\xa5>\xe82\ +.\xd6\x04,\x05\xbd\x95\x81dp\x088+\xbd\xf3&\ +\xeaJ\xed]\xe4\x8b\x17sQA\x11\xa0\x19\x87\x93\x1a\ +\x9a\xa6`+\xd2\x00\xc5X\x92t\x08%RX\x01\xbc\ +\x15\xe4\xe5U\x9e\x1c.\xb4\xaaS\xf3M\xbc\xabh\xce\ +\x0cJ\x972 \x06\xd7\xde\x81\xbd\xc0%\xe0\x10\xd9F\ +\xeb\xac\x5c\xb16\x83)T\xfc)\xe5\xf0\xea\x83z\x1a\ +\x09\xc4\xa7\xc9\xab\x89\xf2\x19K\x92;\x8f\xfb\xf0\x81$\ +\xce\xab\xd1\xaa\x82k}\x1d(o\x1a\xf5\xcc\xc3c\x1d\ +*\x0eNoo\xd1\xc2\xeb\xb1\x9b\xdbF\xa4\xc2\xd5\xa1\ +\x95\x98\xfe\xed8\x8f&S\xa3L\x88\xda\xbe$\xc3\x83\ +\xcc\x85\xc73?\xbf\x02\xb8?I^P\xfc~s\x8c\ +W\xc1\xbb\x89\xd2h/\xa5\xd7\xe7b\xb0\xe1\x15\x07\xf3\ +Q\xf5\x00\x9c'\x17\x95U\x01\xabX\x08\xe4\x10\xa6\xa4\ +R\xafFZ\x92_\xb66ir'\xf2\xe5\xcb\xfe8\ +79\xa1\xf1\x07iN6\x83c%\x8e\x9eI!\xdb\ +\xdcY\xec\xcd\xac\x0d\x8e\x00g\x81\xc3a0{I\x98\ +Hm`\x9d:]\xc1\xd88h\xaa\xdc\xa0\x15^:\ +\x8c\x0a\xca/\xa0\x89 y8O\x92a\xd2\xbb\x94\x9d\ +#\xb3U\xb6\xa5[\x0c\x8f\xc1\x80\xf7\xb2?\xc5\xea\xa0\ +\xaa\x15IF\x07O\xe5eRV\xd6*\x8f\xb1\xa6g\ +\x97W\xae\xdc\x8fp\xc3u\xa9\xad\xf2\xc1\xcb\xcb+;\ +\xa4\xfe\x9c\xe4}\x92Y\xce\x9c}\x85\x0e\x01\xd9*\xbd\ +\xb0eT\x9f\xef\xd0::\xd8\xa1U\xab\xb6W\xd6\xad\ +kL\x1a\xa0A\x97/\xf7%\xcf\xab\xac\xd5\xcb\x81\x03\ +\x5c\x01Z\xddp\xe6\xa3P\xc9l\xca\xce\xd1H\x13\x8b\ +\x02\xe7\xa4W/\x08\x06w\x03jC\xd9(H\x1c\xf6\ +D\xce\xa5\x1f\xae\x0543V\xb0\x8aE\x22F\x17\x8f\ +\x95\xe1-\xadf\xb2\x9c&\xd0\xdb\xd2\xb2\x1eV\x82\xb7\ +d\xacH\x8a^C\xd9\xff&B4\x92\x0d+{\xe8\ +\xc0g+\x83\xcf\xb5\x84\x8c\x87\xcen\xb4b\xe1K\xc1\ +\xf1\xe1\xf1\xe3\xbf\xe13\xdd\xa3\x15Mh\x00\xa9b\xd3\ +\x92\xe2\xe3MON\x9f^\x1d\xde\x5c\xea\x02\xfb\x0a\xbd\ +\x12v\xc0\x99\xf4J\x1a\xde:\x91\x1e`0d|k\ +\x00h\xaa\xd9\x9f\x5c\xa9\xc6\x96\x0e\x87OT\x9bG\xf7\ +\x946\x05\xaf'\x15\xc8&\xcb3\xd0\xaf`q\xd2\xd0\ +\xc4{\x8a\xd7\xf0,\xae5t@%\xad\x7f\xe8\xb5k\ +6p\xac\xdc&\xc7\x8a\x92G\xea:b\xc4NZ\xdd\ +\xb4J\xa1jI9B\xa55W\x1ft\x03zJz\ +,\x81g\xce\xcc\x90\xe7\xda\xf4\x03\x83e\xfc\xb4\xb6\x93\ +\xb7\xa4w2\xf6\xee\xfe\xfd[\xdc\xa6L\xd9C\xf7H\ +\xb1z-s\x1a\xdd\xe4\x19(\xbb\x92|\x1c\x15\x12\xb2\ +dC\x8d\x1a\x8f\xa5\xa1&\xc1\xf0\xech\xcb\x96\xc5\x86\ +g\x08\x8e\xa7\x84g\xcb\x12%B\xd0p\xf2%Dl\ +\xe7i\x87F\xb0B7\xd0h\xcd5\x0e\x8e\xa2\xf6d\ +\x9c\x07\xfb\xf5\xbb\x80\xfb\x0cM\x82f0T\x9b\xea\xd5\ +[\x84\xf3O\x08\x5c\xe8v\xf4\x07\x8b\xad\xa5\xbd\xb2\xe2\ +\xc1yr\x07N\x96\x85\xda\xad\xb8|\xb7n-\x8b\xb3\ +S8U'l\xa8Y\xf3\xbe\x92\x14\xad#U\xf4?\ +#um.U\xd2\x93'V\xa3\x9bOy)E\x7f\ +\x99\x1c&t\xce\xa3Z=\x8c\xe7G\xee\xe9\xb1\xf8\xa8\ +(SZ-\xff\x8b\x89\xb9\xadD\xa6\x81!\xc3\x03\x8b\ +e\xd6JN\xc5iB\xc6\x14\x11\x14\xb4J\x91e\xd7\ +Z\x15\xcd\xe9\x1dj\xcd\x8c\xe7\xf3nl\xde\xec\x18\xe0\ +\xecL\xa1\x88\x1c\x187\xcc\xeat*\xaa\x18\x07\x9bi\ +\xa4\x88m\x92+\xb1\x1b}6:\xcb\xd26T\xe3\xfd\ +Q`\x13\xf1_\x04&\x98'2\x1bl|\xadC\xae^\ +\xb5\x95b\xadz\xd2\xc8\xf2\xa6\xa6\xb0\x85\xe7\xd5\x85\x16\ +\xd6U\xab\xb6@\xd9\x92\xca~xK\xc1l:\x108\ +\x9fx\xc5\xd6v\x0f<\x92\xef\xff\xe9\xdf\x16\xad\xe2\xa4\ +\x92\xf6\xaf\xe8\x06D[\x14\xc8\xa9-A\x90\xf6\x15\xf6\ +\xda\xf1\x9c\x82\x93%\x01\xe6\xc6`Ail\x0d)~\ +\x05\xba\x82#\xc9\x90\x90\x95\x7fM\xe9{\xae@1L\ +\xc4\xeb^\xa3\x106\x9cVHZ\x05\xa5\xe1\x1d\xd0\x91\ +\xcf\xf5\x0b\xc99P\x5c\xf2\x99\xbb\xfb\xd0\x7f`p\x13\ +\xa5\xd1\xbe\x06{\x89\x1f\x1d\x81\x81\x81\xfa\xc8b\x7f\x09\ +F\xc5\xc7\xc7\x1b\x8a,\x03\x83\x82\xc1\xeb\xabWw\x85\ +!}\x96\xc2\xb5_B||l\xa4\xc2\x96\xf6\xbb+\ +\xc0\x14(I\x1f\xa0\x98]Bt\xf4L\x1b#\xa3\x97\ +4f\xa6\xaf\xdfVGV\xf0\xdc`W\xb0\x9b\xf8N\ +\xe0\xefr\x86l\xd5\x15\x87R \xf2\xf2fG\xb8\xa4\ +\xaa\xf8Q\x81\xe5z\xb8tI\xbbk\x1e\xda\xe5\x81\xbc\ +=)U\x89L\x03\x83bU\x08&oZ[\xb1\xa2\ +z\xc5\x82'3\x1c\xf3\xd0[\xcb\xd8*\xd2\x16\x12\x95\ +\xe6\x81x\x7f\x1a\xa8G\x843e\xb6\xf4x\xee\x11:\ +\x864\x0b\xe7j\x97\x01\xa1\xbb\xed\xa7\xc8H\xb3UE\ +\x8bZ\xca:=\x0a\xa9\x94\x14?\x12`Lu1q\ +\xaf\x90\xf5\xf0\x9e\xe4\xbf\xa9?\x99T\xa7Z\xa7\x044\ +%\x1fd\xaa\xe1\xb1\xd1UC\x88`\xfa\x05\x0b\x8b\x83\ +\xa8G{\x07\xe7\xd6c-\xcf\xa5z\x15$\xc3\xd4\x14\ +\xb2E\xc8\xe1\x17\xf56\xb4U+/\xa1\x85\x99B\xe4\ +\xca*\xd5-Z\x95@opVZR\xba\x942\xa0\ +ss\xe7\x1e\xa6zC\xf0\xe73\xc6\xc6\xe5\x10N\xf9\ +(S\xe0\xae\xfch[\x98\x14\x8d\x0f\xd4BN\xa6\x09\ +\x8da\xa2\x9f!\x13\xe2\xb0C\xf3\xe6>\xd4C\x1a\x13\ +\x1c\x83gC\xa8TV\x0f5'\x12\x86\xc9.\xcb/\xc2 \ +\x91\x16\x14\x17\x1en!\xf5.fQy\x06*\x95\x95\ +\xda-\x17\xadI\xee\xa31\x99C\xd9\xf1\x92\xfe=\x04\ +\xc0\x06`\x0er\xa4(\xf9\x97H\x0c\xbe\xfc\xe4\xcc\x99\ +r\x1a\xbb\x95\xaax\x16\x8cy\x8aF=\xdaT\x12\xa6\ +\xc5\xbdZ\xde\x0e[2\x7f\xa8+\xbb\xc2k\xf8P\xae\ +\x0c\x1eR\xfcG\x95\xc9\xe5L}\x82.]\x9a\x8cj\ +\xf9\x032NW\xedO\x16\x8338\xc3R\xc7W\x17\ +8\xf5\x94\xfe\x07\xcf\xc0\x97\xa4\x9e\x86/!\xaa1\x1c\ +\x0c\xe6\xfa\x91&s\x04mK\xa0\xb8;\x9f\x0c\x8e&\ +I\xc9\xed\x93\xf2h*\xf9^\xc9-\x8d\x1a\xf9\xd1\xb3\ +\xcb\x96\x96\xf6\x14\x03\xd2\xf4H\xa1\xc8r\xa7\xa2mA\ +\xfa\xf5\x22\xc3\xc0R\x0f\xa4\x13\x89\x06\x1c!r\xc5\x0a\ +\xc6u1\xae3\xc1pr\xb2\x5c\xb1\xb1\xd9#{\xa0\ +\xef\x00\xbf\xee\xeb\xd1\xc3SJ\xde\xcd\x02\x17\xa1\xda\xfc\ +8mGe\xdbe\xcb\xacH\x82\x06G]03\x9b\ +\x86\xa4\xe6\xcb0 [\x18SA\x8d\xed\xf2|\xdc\x87\ +j\x94\x01\x8d\xa7\xae\xaf\xe7\xe6\xcd;\xac\xfc\x8d\x91\x11\ +b\xbc\xcd\x8f:\x89\xb5\xc1N\xb2nK\x85\xf3\xdck\ +|\x03\xc5R\x1e\x9c\xd0\x00V\xc1\xf9\x94)N\xab\x9e\ +\xd0\xc2U[\xdb~\x08+|\xc6a\xfd\x09\x19\xaa\xc8\ +H\xb0\xd1\xd5\xc46s\x16Jy\x5c\xa1\x1e\xa6\xfe\xe6\ +\x97^\xbcw\x1e\xc6\xc6N\xe4D\xb1\xaaP\xa1\x8a\xcc\ +a\xa4\x9d\x8b1\xf8\xb3\xfc\xdd\x1c`+l\xed\x9e\xcb\ +,\x10\x0b\x5c\x0d\xc0\x1eTF\x94\xd9\x7fw0\xa4\x89\ +;\xdb\xb7_L}\xc8\xc1\xb1R\x9a\xa2\x03\x0cK\x1d\ +\xbfC\x0ei`LLL1\x0a\xf2\xdfwq\x19\x84\ +\xb3l\x22\xa5\xc6\xd1\xe7\x97\x89\xd2?>NN\x99\xb2\ +\x8c\x14z\xe9\xcc\x86\x89\x18\x06\xe6T\xfaF\x83&`\ +\xf9T<\x9d\xc7h\xf9\x0f\xe6\xbdQo\xa7|\x81\ +z\xac\xabU\xab\x1a\xcd\xb1\x9c\xc3\x0e4\xee\xd0\xb4\xe9\ +-h\x93xcw\x93,\xb5Hl\xc0\x82:\xa0\x1b\ +\xa3w\xdd\xde~\x1b\x1cy\xea\x12\xa6}\xdd\xbbw\xfe\ +\xd7\xd6r\x81\xedd\xd2\xac)8A\xb6=\x9a\xa6D\ +\xfa11\x7f\xd0d\x9d\x98<\xf9$\x9ew\xd12\xc6\ +*\xe0\x92\xcco\xe1\xc4\x88\x8c\x8c,H2\x08\xd2\xc0\ +6_\xb6\xb1\xa9\x89\x04bs\x94\xf9\xc4\xc9\xe2\xd7=\ +\x02\x90^\xe9{8\xff\xc5~x\xfcx\x159\xd1H\ +<\x08g\xf1\x07\xca\xee\x86j\xeft\xc1\xcf\x802\xa0\ +yO\xcf\x9e]O\x0e\xa1\xffL!%\x09|RL\ +G)\x84\x04\xc3-\x8b\x15{\x85\xd5\x90\xbc\x9c\x06Z\ +\x067Zz\xd2\xc23\xbf\x84\x84\xf1\xfe\xf1\xe3!\x90\ +f\x7f \xe7 \x19FvG)\x97\x91N\x072\xb6\ +)2\x9b%~W\xa7N[p\x7f\xcbu\xe8\xd0\xbe\ +W\xac\xad\xd7\xd28z\x10\x90\xb7\xba\xb4\x94=o\xa6\ +\x03e@\xad\xc12\xe2\xbf\x84\x80C\x87\xe6\xc3\x1b\xa9\ +\x8e\xe7\x101Q\xbeqQQ\x8d\x05\xa0\xa5iQ\x0c\ +\xe7\xc0hx<\xa3\x1e\xba\xb9\xd5V\x14\xabD\xa6\x81\ +\x9bN\xc2\xb0FR\xb6\x0a\xbc\x92\x01X\xc5\xde\xa3\xee\ +N\xe9\xfd]O\x06\xc5? \xc1\xe1=*\xce\xdf*\ +\xf3y\xb0o\xdf\xc1p\xa4,\xc1\xbcEC\xc6o5\ +\xe9hj$\x10;\x83\xe5E\xa6\x82'\xb2,8\x05\ +]W\xf6j\xa8\xf4\xde\xd2>hc\xcc\x98\x9e\x9d\x9d\ +=\x9bd\xc0;\xe0~\x88\x9c\xb4\xe3x\xb7\xb2\xc8,\ +p5B+p.h\xfa\xe5\xcb\x97\xa5\xd8\x96u\xa5\ +m&\xe6\xe3\x08\xcd\x07\xc5\xed^\x5c\xbch-\x9b\x95\ +\x04PC\x92\xa0k\xd7JB\x10\x96\x9av\xf4T\xf2\ +\x19)\x06Fq>\xca\xe1\x04\xcd3?\xb3\x88'\xb2\ +\x09\xbe-\x17Q\x0b[\xea\x8f\x86o\xcaEB\x82\xb4\ +\x07i\xeb\x09\xd5\xaa`\xec\xbd\xe7\x90w\x13\x8d\xdc\x0d\ +\x10\xff\xb9.\xcf\x10\x0e\x22\xb3\xc1jbe\xc0\x1a\x88\ +\xddU\x86\xe1\xa8\xbf()\xde\xfa\xdc\xd3s\xc9\x95m\ +\xdb\x0a\xc3i\xe2%\xd5\xc2\xca\x83*Y6\x94C\xa9\ +8\xa7\xfa\xb6\x87G\x8fn\xc2J\x99@\xf728=\ +\x8c3\x8b2\xbf\xfc\xa2\x072\x19\x96\xe2:M\xe3\xfc\ +6\x0dL\xf1^\xb3f\x1fm_\xe4X6\xa4\x18=\ +\x83\xb7\xec\xd3\xeb\xdb\xb7M\xc9\x08\xff\xa2\x97\xf6\x90\x8c\ +)\xa6d\xbc\xb9{w\xbec\x9b67h\xc5\x02\xa9\ +puYdp\xf0(d\xb1\x8c\xa7F\x8d\x9a=\xbd\ +W\x16-\xda\x0a\x95$'hW\xb3\xbbc\xc7iJ\ +\xe3I\x1c\x17\x94\xdd\xcd\xd5\xac\x11we\xf5\xe1rB\ +\x02g\x80Y4\x19h`\xb1\x03\xe3*M'\xca\x91\ +\x91#\xcf\xd2VE)\xbf\xc0\xd8Tp\x19\xd8G\xc9\ +v\xc0$*\xe2:~\x19\xd2A\x94\xe7\xab(8\x92\ +\x02\xe3$[\xa7\x91\x0b{\x93Dh\x0f\xfe\xfak}\ +-o\xf5\xbc\x97\xfe\xfe\x95\xa9\x8f9V\xc5Ht\xcc\ +Y\x16\xec\xe3\xb3\x9a\x12$P\x00\xfb\xf4C``V\ +6ed\xb8\x9b\x9a\x1ab;\xf9\x9a\xb2O\xe8\xcc&\ +57\xa2\xa8\xd4D\x1e\xda\xf3H\x095ulH!\ +M8\xe5szYX4\x91\x93\x19\x14|\xf7n!\ +\x91Q`\xc3\xab\x0eN\xa7>\x01P\x89\x0eS\x92\xa2\ +\xbf\xa1\xaf\xb2@\xb35\x17\xcet;q\xaf\xee\x0d.\ +S\xc7\x18Y)\xa1\x16z\xe3\xc6\xac\x1d-[\xde\x80\ +\xd1\xdc\xa6N24Y\xc8\xf5s!\x85'\xe9f~\ +\x01\xa3\x8a\x876\xa3\xd3\x8d-[\x1c\x0f\xfd\xf6\x9b;\ +\xa5\xee`\x8c\xae\xbb\xe9}\x1a\x97\xado3\x16|\xbe\ +k\x19\xfb\xe1\xc3\x12\xea\xf3\x16\xfd\xf2\xa59\xee\x0b\x0b\ +\x0d\xe0pN\x9e\xca\x18\x9c\xc9_P\x221\x1d\x07p\ +\x96sF\x89\x90:\xb9\x18\xd4\x91s\x1c\x9f\xef\xc6\x91\ +g\x0c\x1dXn\xd2\xb7!\xca\x81\xae\xcbF\x0f-\xc0\ +\x14\xa7\x81\x03\xbdp?\x07\xec\x0c\x0es\x19:\xf4\x1c\ +\x8dK\x8f\xd9]\x0a\xb6g\xeadr\x19P_\xb0\x83\ +\x5c\xd1\x0a\x82\x1e\xd8u,\xc4u/\xf8\xf5\xf6\xee\xdd\ +\xdb\xf0\xbc\xae|\xbf!\xb8\x04\xe4\xe6\x8b:\x98\xb1\xd2\ +\x9a\xce\x0ba\x0f\x1f\xce%\x83S\xd2\x89\x8e\x8d\x1bG\ +\x85\xafy\x85\xc4\x89)SFJ/f\x12\xb4\xb3\xa9T\xe1\x94\xa1\xae(\xf5\xe2\xf0\x1e\x05\ +\xc1\x18*\x98\xa4-\xcd\x0c\xa5\xcc^\xf2\xablZh\ + 2\x0b\x5c\x06\xd4\x1e^I\xb3\x03}\xfa\x5c\xb4*\ +[\xf6\xea);;}\xf1\x1d C\x05\xdfK\xe1\xe1\ +N\x22\xd3\xc1\x93Y\x83\xb2\x1c\xec\xeb\xd6\xf5Cl\xee\ +\xa5R\x82\xe1>\x7f\xbe+\xd5HQ\xfe%\x8d\x91^\ +\xa6\xc7\xe2\xc5\xfb)\xf0\x8as\xdd-)\x1f\xe7*2\ +\x1b\xac\x16\xfd+h\xfaOj\xd1\x10R\xb8\xab|q\ +fv\xed\x1d\xc0\x90\xdb\xccy\xe4XQ4\x15\x91\xe5\ +\xfeD\xea\xe6\xaf\x93\x06\xf7\x19[\x9a\x08\x97\xdf~[\ +\x85\xac\x95\xc9p\xc0\xf8\xd3{\xd8\x8e6\x14\x99\x0en\ +\xc3%\xbe\x13\xca\xb9}[\xd3\xa6\xb7OL\x98p\xfc\ +\xc1\xb1c\x1de\x8b\xe65\x99_\x91\xc0\x13Y\x04\x15\ +\xcb\xc3\xd0z\xf7\x04Z\x199\x91\xdb\x19\x07\xf6\xedd\ +p~\x0e\x0e;\xd6V\xaa\xa4h\xd5{ok\xd6L\ +\x1d2\x80L\xbb\x89\xc8t0L\x84\xe8\x89y\xf8-\ +-)]J\xdd\xa4F\x19\xd0\xb0O\x1f?\xb65\xcf\ +\x95\xeb\x8c\xa2\xaa\x9c5\xe2\xae\x5c\xbd\xdc\x05\x9c\x07\x96\ +\xda\xda\xa8\xd1\x1f2\x8d\xe84V\xb6)\xd8R\xeeF\ +:Q\x08\x8d\x11\xcf\x9b\x98X\x88L\x07\x83\xb2\x83\x90\ +\xc0@=\xc8/P\x87\xd6\xbfipS\xe5\xae$\xee\ +@\xbf~\xb6\x8a\xe3\x05\x9d_\xcf\xd2.\x06\xbb\x9a\x87\ +\x07z\xf7n)\xb2\x0e\x8c\xa8\xa8\xa8B\x1bk\xd5z\ +\xac\xc8\xba9\xf5\xef?\x07-o\x17\xa3;\xcbq*\ +'\x81L\xc0\x08\x91U\xe0/\xc6\xa1~\xdb\xb7OA\ +\xf8\x86\xb6\x84\x8e\x14\x18\xff\x13c+L5\x91\x90,\ +\x0fC\xb7\xa0p\x9aO)\xdf7\x1e\xd7/\xf8b\xbd\ ++\xcf\x86\xfdD\xd6\x82\x91\x10\x17\xd7\x17\x92}\x97\xa0\ +\xd6\x14'\x9d%aP\x15\xde\x01w5MP#\x91\ +\x95`\xc3\xab\x02\x8ew\x192d.\xe6\xe5&\xc9\xdb\ +i\xca\x99S^,\xc6L5\xcb\x80>EG\x9bA\ +\x5c\xf8\x1c\xaaK\xe2iL\xa3Y\xe3O\xa0\x8e\x84\x0b\ +8\xed\xa8\x0f\x89\xd2BM\xd8\x09\x89\xb6\xfe\xd6\x86\x86\ +;1VBgd\xd2X\x1d\xba\xe9\xa7\xa8\xa8\xc9(\ +J^M\xb9\xb0\x8aP\x11\xaeE\xb13Q\xcb\xddA\ +\xb8\xf5c\xd8\xe3\xc7se\xef\xf3^nS\xa7\x1e\xd7\ +j\xd6\xa8c\xe0\x89-\x0dvU\x0a)S\xe9&\xc3\ +\xc8\xfa\x9ep=\xb1ZM\xc69\x9b\x9al4\x11@\ +\x88\xaf\xef\x14J\xeb\xa3x\xab]\x95*V\x18\xcf\x0f\ +\x16\xc6\xca\x16J\xaap\xc8\xdf4\x95\x9eO]\x05\x17\ +\xbe\xea\xf4\x04\xf1\xfc\x94\x02G\x82\xcd\x15\xef3\xf8\xfb\ ++??k\x1c\x03Fc\x05|\x08\xaa\x8f\x07\xd47\ +\x0e\xcf\xfem*\xdd\x0c\x92\x02\xa0\x8c\x15L\xf4\xef\xb8\ +\xf6!)v\xea\x1a\x841CJ5\xe2\x8a\xe5\x8c\x91\ +\xb7\xd3Nr\x00k\x22\x943\x1a\xdbKu\x19\x10\x14\ +\x00.\xfdK\xcfm\x0c\xc4\x7f\xb6\xd2$\x7f\x83\xb1\x94\ +\xaf)2\x03l\x88\x95i\x1bI\x8e\x93\xd33fX\ +\xfdK+A\x18\xd8\xd2t\xa2\x0e\xaf\xd4\x01\x08}\x10\ +\xec\xd1Hb\x13\x0e\xee[\x0e\x0d\x1e\xbc\x0d\x9a,V\ +Q\xc1\xc1\x15\x05 \xeb\xf4\xeaSp\x17FXId\ +\x088[\x05\xec\x07\xce\x00s\x89\xff\x10T\xff\xa5\xb3\ +\xdf\x85\xa5Km`h\xd3+t\xe8\xb0\x7f\xa4\xbb\xbb\ +\x0b\x86\xf5\xc1\x9c`v\xd0{\x89JU\x06\xd1X;\ +\xdck\xe6\x0a^\x04\x07\x98\x09\xf1A\xa4\x0d\x0c\x06\xeb\ +\xae -\xcc\xdfLO/Q[\x1f\x13+ZS\x92\ +\x7f#I\x88=]\xba\xb8\x5cZ\xb1\xc2\x01\x9a\xf6\xe7\ +e\xec\xef\xdewt\x0ee0\x18\xc1\x97/\xf7\xa4m\ +%\xb2\xd6\xbd5Wx\x18\xdbcdM\xc4@\xc3\x9e\ +b|\xf3ef\xfc\xa8mM\x9a\xa8s8\x91!\xf1\ +\x9bH;\x18\x0c\x0e+\xa0\xfcG\xad\x08\x86\x92\xa0.\ +\xb2\xc0\xb5\x92T\x18;IRp\x9az\x1e\xc1\xbe\xbe\ +\xbde\x9f2\x17\x8d\x96\xbe\x07\xd3p\xbec08\x88\ +\xeeme\xb5\xfb\xdd\xc3\x87\x9d\xa5\x11\x8d\x07S\x1e\x1c\ +>\xbcF\xbb?\x02\xda\xf4\xe6\xa3g\xdb[\xb6\xf4\x16\ +\x00\xb6\x97vt\x0f&\x80K\xff^\xf53\x83\xc1F\ +\xd7\x04l,\x00S=\xbdndD\xf0Z\x9a\xa4\x92\ +x;@J\xc39\x09\x00\xdbQ\x1f\xe4\x01&\xa1\x1d\ +\xd4cdK\xc4\xa4\xb13\x10\x83\xc1\xf0\xda\xb0!/\ +\x95\x8dX\xe4\xc9\xf3\x8a\x82\xe4Z\x05\x93\x11\xa8\xd9\x8a\ +\x89\x0c\x09\x99\x8d\xfbj\xe0W*\x80\x85\xb1.F\x22\ +\xae9\xae\xa4\xadi\x8d\xf1+\x7f\xd1]\x86\xc1`\x90\ +\xf7\x91<\x94\xd0\xdbW\xf7\xbc\x86\x07\xf3*\x0c\x88\x8c\ +k\x9dl\xf1\x14Ez\xfa\xd4\xc0\x9d\xc6\xc0\x94{\x07\ +\x0elF\x1b\xdc\x89\x10\xd4\xb9gch\xd8nU\xb1\ +b#\xb1\xda\xc5J\xbd\x95m\xbc\xcdd0\xbe]\xab\ +\xb5\x0aL!B3\xf3\xbeu\xd9\xb2\xf7\xd5\xdd?U\ +\xaa\xd7H\xb6u\x97=\xb2\xc7 \xab\xbd0\xc6b\xd0\ +\x1b;tO\xb7n\x07\x15\xfd\x15l1\xed\xa2\xde\xbd\ +\xab\xb4\xaeJ\x95g\x10\xb0\xfd\x8c:=o4,I\ +Md\x87\xc1`l\xaa]\xbb\xc1\xa6:u|Po\ +GF\xf6\x15\x86\xe5\x0e\xc5\xb0\xe5\xa4\xb1\x22\xab\x12F\ +\x82\xfa0\xc2IRQ,\x86\xaeH\x15\xfbHW\x8f\ +E\x8b\xf6\xe1\x99\x19\x8d\x1d\x195\xea\xac\xfc\x9d:\x1a\ +\x06\xddI:Wr\x0b5\x18\x0c\x16\xa9\xfd#:4\ +t\xc5\x8e\xd6\xad\xaf\xc8\xda\xad\x9b\x90\xf4>t\xc9\xce\ +N\xe9W\xae\xa2\xb6\xbc\x1a\x8a\xd0\x97\xa9\x09%\xddC\ +\xeao7U-C*\xe06\xb2\xe1\x17jw\xe7T\ +\x8a/M\x84\xe8+\x140\x18\x82\x0d\xcf\x90DOI\ +[\x1f]B\x9fA\xc0\xe8\xce\xd6\xc6\x8d\xcb\xcaU\xaa\ +\x89bl\xa4\xcdH\xd5\xe68\xf3\xdd\xa5VOX\xe9\ +\xa8\xc3\xeb[\xd9\xbc\xb0\xa6|\x7f\x18\x0c\xcd\x1dF\xf6\ +K\xd8\xa3G\xd5<\x16.tI]>\x80\xc1`\xc3\ +k\x0f\x9aJ*\xb5Z\xaa\xe3\x13&lr\x9b6\xed\ +8\xc6\x8c\xa1.V\x13\xe7\xb5X\xe9dI\xbew\xf0\ +\xe0\x16\x8cw\xd5\xa8L\xe8\x85\xe7qt\xce3\xcb\x99\ +s\xdf\x9b{\xf7\x06\xe1yu\x91:\x18\x0c\xae\xe5\x02\ +\x0d\xc1l\x1acm\xc0\xd9\xa0\x11\x0c\xa9\x86\xb2\xe2\x1d\ +\x9f8\xd1\x0dc\xe3@=\xcd\xdek\x81nn\xeb\xe8\ +L\x88\xed\xe9s/S\xd3\xb4\xaaD3\x18\x0c\x8d\xc6\ +\x92Eqf\xbb\xba\xa5A\x83{2\xef\xb2\xa0\xd0\x02\ +r/\xb7\x93A^]\xbbv7\x9e\xd7\x17\xff\x08\x0c\ +\x06\x1b\xdf\x88/\xc9\xc9\xe4\xc9\xac*\xab\x0d\xfa\x82]\ +\x05 W\xc0\xa4\x0d5k\xde\xc7\xf3\xc9\xe0_\xc6\xe5\ +\xa4c\x86:\x07\xd5\x12\xa9\x82\xc1\xe0n@\x86\x1a\xee\ +\x7f_0E6%\xb9\x883\x5c\xf23O\xcfux\ +\xa7R*\xb1\xbf\xfa\xe0b\xbcg\xbcX\x88\x9a\x8a\x0c\ +\x04\xee\xc30\xfe\x19\x5c%\xfe\x1c\x0c\x06W\x94# \ +\xeeM\x86F\x86gU\xa6L\xe8\xfb\xfb\xf7G\x0b-\ +\xc0\xa8\x96+As\x85\x18[(\x80\x9d\xed\xda\xed\xa6\ +{xG\xd7\xfe\xf5\xaa\xc8`\xb0L\xdc\x10Z\xd5\x14\ +\xb5h\x18_8\xae\x03\xb4\x9bY\xa0\x05\xf3\xb3[\x8e\ +\x8e\xdb.\xaeXq\x00Z\x8e\x0feJ\xd8t\xbc\x1f\ +\x81pCXBl\xec\x22\xea\x1e+\xfe\x12\x0c\x06\x1b\ +^%\x90\xfa \xec\x81a\xbdFB\xf4%\x0d\x83\xdb\ +\x01\xa6\x84^\xbbfCg@\xb0\xd7\xc7\xb7og`\ +5|M\xe3D\x9f5k\xf6b\xbc\x89H\x13\x18\x0c\ +\xd6\xce\xfc\x05\x0dH\x16$'&\x92c\xa5\xa8\x00\x10\ +L?D\xabYxP\xd0\x10\xc5\xe3\x89\xab\xde\x96\x86\ +\x0d=\xc9\xd8\xd6W\xaf\xfe\x08\xf7S\xbfo;\xc9`\ +\xb0\xe1\xe5\x06\xab\x83*\x99\xb7\xa9\xce\xb9\x5cS\xaa\xd4\ +iE\xde\x81\xfa\xa2!\x8f\xf3>%>?uw_\ +O2r\xb2\xb5\xd3`p\x198\x99\xda3\x8b\xb4\x81\ +\xc1`\xbc\xf4\xf5-\x8b\xb6L\xc1r\xfb\x18\x80s\xdb\ +>\xf0\x19\xddC\xb8\xe8\x0a\x8c\xed7\x12\xa6\xc5\xd8\x0d\ +-\xa7\xca;\x5c\xcb\x8b\xb4\x81\xc1`\xc4GD\x8c@\ +\xb7\x19\x0f$G\xdf\xa1\x8aq2(\x14\xb8\xc6\x22\x17\ +s9\xc9\x82\xe3~+\x8dm\xfb\xe5\x97\x0b\x0f\x8f\x1f\ +\xdfDr\xe0H\x15\x8b\xc7\xbb\x8f0\xbe\xc4X\x08#\ +\xf1\xef\x03\x83\xb65\x22\xa3\xc0M\xea\xfb\x83&\xb7\xf7\ +\xee\xdd\x06cR\x97\x05\x1d\xe8\xdb\xd7\x8a\xb6\x92H\x88\ +\x8eFM^0=\x07{\x80}\xdc\x17,\xd8\xa7\xb1\ +\xe2\xc5\x9b\x08\xf1/\xeb6\xc3\xc6\x96\x8d\xb6:\xa0\x17\ +i\xf0\x8b\x8c\x02\x1b\x9e\xd1k\x7f\xffU\xbb;w\xbe\ +zv\xde\xbc1T)N\x15\x08\x1b\xeb\xd4!\xe7I\ +5!\xb1\xbbc\xc7\x81dl\xf0x\xc6\x22\xa5\xec>\ +\xb45g\x8a\x7f\x17\x18\xf0\xa8\xf9K\x11\xd4g\x22#\ +\xc1\x86W\x06\x1cM\x14\x80e\x89\x12\xf7\xc9\xe8V\x97\ +(\xd1C\xee4r*\xe1\x04\xa5Z\x01\x9c+3S\ +\x86`|\x22V\xbc\xe6?\xb6\x8a6\xafp\x0d\xa9\xa8\ +\x92&\x19\x9a\x1d\xc1\xd2\xad\x9d\x09`x-]:\x09\ +\xe1\x83x\x18\x1de\xac<\x00\x03\xc1\x14\xabR\xa5^\ +%%$\xcc\xa3\x00;\x1c/\xad0\xf6A\xcb\xb1r\ +\xcbX\x88\x0aB\xa7\xc1H-\xde\xa3J\x11\xc2NO\ +O/I\x00\x06\x85\x0a\xc5\xd3{\xd2\x10\xf3\x92B\x95\ +L\xd2\xcd\x00\xf0\xb9\xb9\x8d\xa9\xe9\xdeAG\x8f\xdaW\ +\xe9\xd9\xd3;O\xc9\x921*\x95\xcaH\x00m\xcc\xcc\ +\xce\xe6\xd0\xd7\xf7\x98\xa6R}\x8ez\xf1\xc2\x05CE\ +*u\xea\xe4\xd1w\xef^\x87\xea\xfd\xfa\x9d\xcf\x96-\ +[\xed\x1c*\x15U\xac\xffH\xbd\xf3\xd8\xe00aC\ +TB4\xab\xd4\xa5\x8b\x9f\x00r\x15*\x14\x8bK\x1c\ +\x8c\xac\x11\xae\xfex6\x0b\xbfD\x09\xbav\x22=\xc1\ +\xc6F\xbb\x88\xb7X\xd9\xf6\x04\xec\xdb\xe72\xe4\xd8\xb1\ +\x03\xed\x96-\xbb\x8f\xb1\xec\xa5 n\xd4`\xdc\xb8k\ +x~\xab\xb0\x10\xedq-\x96-{\xf6\xcfA\x9e\x9e\ +\xado\xac_\x9f\xa7\x8b\x9d\x9ds+ccW\xac~\ +%\xf1\x059'\x95\xfc\xcd\xb9\x98\xd7\xa3B\xb7\xc0\x90\ +\xe7\x82\x97\x10\xca\x09{t\xec\x98Zax\x7f\xef\xde\ +\x94\xf9nL\xe5&tO\xb4,^\xfc\xdd\xb6\xa6M\ +\x1d\xd2\xb7\xb7\x17;\xaa\xd6V\xa8\xe0h\x8a\x15\x8c\xe4\ +\xf9p\x7f\x1b\xd7\xc4\x95\x05\x0a\xbc\x96M\xe7\x8d\xe4{\ +}\xc0\x94\xe3\xe3\xc7\xbbAW\xe5<\x0c4\x91\xe6\x0c\ +\xd9*\x0b\xe9\xec\x87\xdc\xcc\xcb\x02\xa0x\x1e\x85\x11L\ +\x84\xe8M\xff\x9d5%J\x5c\xd1\xa1\xe6\x87\x0c\xda&\ +b\x826\x83)\x9e\xa6\xa6\xce\xe7\xe6\xce\x9d(\xd5\xa9\ +\x12\xe8\xba\xb2`\xc1'+\xf2\xe5\x8b\x86NcR\x88\ +\x8f\x8f-&o\x09XP\xa4'\xd8\x81\xd2\xf1\xb1\x9b\ +\xdbF\xc4\xe0\xaeC~/\x18r{\x1e\xd1\xaf_\xaf\ +\xd0\xd4CY$D)R\x18\xc3\x97^\x10*\x14\xc6\ +\x05yy\xd9A\xa2\xef\x16\xcd\x91\x0c\xa0{\x0b\x00\xde\ +\xe5\xca0\xb4\x8f\xca\xb8\xbf\xa3\xe3v\xccWY\xa1\x13\ +`\xa80)o\xa5\xeb9\x06\xcd\x09\xe7C\x89\xb8\xaf\ +\x9c\xac\xaf\xdb[\xb5:\x8fX\x90+\xdd#^t1\ +><|\x08&\x9d\xcaL\xa6\xa6{\xbc\x8e\x8d\xae\x0a\ +8\x054\x95\xec\xa4\x9d[\xe9\xf2\xdbo\xea\x9cL\xac\ +\x86\xcf7T\xaf\xbe8\xec\xe1\xc3\xb9W\xed\xecv\xad\ +.^\xfc\xcd}\x17\x97\x8d\x8a\xdc\xc3\xf1q\xe3\xf6\xd0\ +\x9c\xc9\xc6%\x1fuh\xbe\x18\xd7\xb7l\x19\x8e\xc9S\ +\x97\x95`\x1b\xe3\x8d\xab\x014\x1a\xdd\xbc\xd7\xac\xd9\xf7\ +)2\xd2\x0c\x9e\xb3\xd7P\xa7\x8a\x80f\xa3\xd9\xd3\xb3\ +g\x8bc\xb2C\xa4w\xecf\x86\x1c\xd4\xd9\xf0\x8a\x81\ +E\xbe\xf1\xac\x86\xe7\x92%\xce\xe8\xe8\x1a\xa64\x16\x81\ +\x00\xed\xb9\x98\xb7o\x17S\x89\x90\x00\xc6\x0b\x91\x03\xbb\ +\x91@\xccY\xecE\x0b\x8b\x03\x96\xc5\x8a\xbd\x92\xef\xfa\ +I9\xf7,\x06OpIp\xea\xb5\xf5\xebw\xa1G\ +\x9a9\xee\xf5\x1f\x9d<9\xc6o\xdb6\xeb5\xa5K\ +\xaf\xa6\xc9\xa2U\x0e\xe3m\x05\x007\xf5\xfde\xfa\xfa\ +\x09\x08\x1b\xdcq\x1d:\xb4\x94\xf8\x062\xac\x91!\xcf\ +W\x03\xc8\xf5\x99\xf8o\xdf\xbe}K\xa3F\x97\xa0\xa1\ +\xe2{v\xf6\xec\x0a\x8a\x91R}\x1d\xcd\xd9\xc9\xa9S\ +O`l$B\x0a\x0b\xa8\x1d\x17\xcex\xde\xa7\x16.\ +,\xa6yv\xcc\xda\x86$\x5cV\xd2\x04\x1c\x0a\xe6\xc6\ +d\xec\x97[\x92$\xd4l\x05a\x82I\xb5*\x87\x00\ +\xb0\xda=@>\xe0\x1b\xb9\xedi)\x83\xb0oq%\ +\xe3\xcc+'\xd3\x8a\x0e\xf4\xe0\xd0\x0c\x0b\xccr\xaf\xec\ +\x16\xe0d9\x0f\xcd\x95\xd5\x8d\xe4\x1ahU\x83\xa1\x91\ +\xc8\x91\x01\x98\x0b\xec\x0a\x9a\x80\x0d5\x0cn4\x18\xa5\ +\x039\x9a\x8c\xeb\x0e\x0e\xb5\x1c\x9a7\xf7%\xef\x17\xa5\ +\x15\x85\xdc\xb8\xd1XH \xe16\x18\x0d-^\xc8\x82\ +K\x95\x99\x81Ak\x0d\xe9\x803\x02\xc0\xef\xac\xa4{\ +I\xcf\x0c\x95\xfbf\xe3+\xa8\xe9XQz%$%\ +%5\x14\x1a\xd0\xee\x7f\x07\xc7L1\x1c\x17\xa2pf\ +\xf7\xd2\x8d/E\xae\xe7\x1a\xf9\xc0\xd5\xd5\x1e]C]\ +\xe9\x5c\xa1!v\x1a\x06U\xaa\xc0\x9b\xfb\xf7\x97\xc6\xe4\ +Z\x90\xeb\x99\xbcg\xe4T\xf123\xb3\xc2\xbb9!\ +\x82\x1a\x80\x950\xcey\xf0`\x0flA\xef\xec\xef\xd9\ +\xb3\xc4\x1fB\xe8g\xf8\x16\x86\xa1\x82.\xca92:\ +\x9c\xb5\xcf\x90\x1a\xd8\xb7j\xea(\xb4\x83\x941\xb5\xa4\ +\xdf\xd2\x1c9\xc6\x08\x9d\x00\x1b^\x0dp\x0ch$$\ +\xa08\x1cG\xf18\xc4\xe8\x82h\xb2\x90\x03x\x1d\xe1\ +\x02k\xbc\xb3\x80\xde\xb524lO\xe3\xfb\xbaw\xf7\ +&\xaf\xdb\x87'OV\xe3\xda\x14c\xce`\x0c\xb8\x80\ +\x8cOd\x08\x18\xc9\xc9\xc9m\xf6\xf7\xeau\x09\xded\ +%4@\xba)&\xdf\x98\xdf\xb2h\xa9\x1c\x08'\x0b\ +\xcdKi\xa1\x13\xe0\xb0A\x0d\x8d}\x7fA*)\xa1\ +\x89\xc4$E\x9c\x999s\xb7\xa4\xdfB\xe9z\xd1\xdc|\x17\x9e\ +9\xd1\xe4R|\x0f\xbf7O\xcbP\xc7\x82\x9e\x8b\x85\ +\xc8\xe0\xc6\x17\x9cF\x06\x89\xbe9\x88\xe5\xad?9i\ +\xd2\x96\x83\x03\x06\xectl\xd7n\xbfc\x9b6\xe7\x90\ +\xe4p\x13\xce\xb0#Y\x1c gP\x95\xb2Zs\xb1\ +f\xcd\x87d<\x10==\xa5(\x0fkBV-\xbf\ +R\x0c\xf3\xd8\xd8\xb1\xce\x108\xf5\xa5{\xf4_;)\ +\xd3\x8f<\xf1\xbb\xd3A\x03\xf9;\xca\xd5\x8a~\xc7\xd6\ +\xc8\xa8\x8d\xc8P0d\xf8\xa7\x0f8\x04\xfc\x1d\x9c\x04\ +\xce\x04\x17\x82\xc6\xbaS\x92\xc5\x9a\x8b\x93\xa9=S\xec\ +\xfb\xf7\xa3\xbf\xf1\xedY\x8f\x12j)\xe7\x922\x1c\xa8\ +\xd9\x05\xf2\x02\xef\xd2v\x85VH\xeb2e\x1e'\xc5\ +\xc7\xd3\xcaXZ\xae\x86\x0b)\x0e\x04\xce\x89x\xf6\xac\ +\xce\x0booR\x1d\x1e&\xb2\x1a\x1c\x8f\xd5\xa1\x15\x8e\ +'\xa3\x11\xd8L|\x03O\xce\x9c1\xbe\xbbo\xdfV\ +\xfa\xc6\x0c\xbey\xb34\x8c-A\x8a\xe5\xc4\xbc\xf2\xf7\ +\xb7\xa6\xdf\x17\x12k\xabU\xab\x853\xddSz\x0e\x06\ +\xde9x\xb0\x954\xc6\xbf\x09\x06\x83\x8d\xb2\x82\xf4X\ +\xe6\xc7y\xecg\x19\x0f\xfa\x0a/\x19y3\x07h\xf7\ +b\x0b\x9a\x08\xd1S0\x18\xec4\xf9\xdb2\ +\x01\xb5.m\xdc\xe8;\xfe\xe6M\xcb\xce66{+\ +w\xef\xee\xaa\x87\xa2W\x95\x9e\xde\x97\xaevv\xe7\xf0\ +\xca\xd9\x05*U>\x5c\xb7\x82\xaaj\x90\xef[\x1c\x1f\ +\xbf\xa6\xdb\x86\x0d\xbb\xf5\xf3\xe6\xfd\xa2\xa7R\x1d\x86\xf1\ +\xfd$\xb4@y\x9a\xb2u\x14\x83\xc1\x90\xc6V\x18\xfc\ +L\xaa\xce\x88\xd3\x8d~{\xf7n_\xe7_\x7fU\xab\ +D\xef\xed\xda\xd5\x87d\x034[;A\x06<\x9c\xae\ +\xe8\xfes\x03g\xc0\xb1\x0f\x0e\x1f^C\xf7\xd0\xe3w\ +L\xc5\x90w\x82\x81\x1aC\x0c\x06\xe3\xe8\xef\xbf\x1b\xc3\ +\x80\xdek\xc4\xe9R\xec*W\xbe\x81f#\xcb\x14}\ +}\x13!:*q\xbb\xcb\x96\x96{\xf1~(\x19\xea\ +\xf28~\xbc\xbe\xc8\ +X0\x18\x8c\x13\x93&m \x99>\x18\x1e\x85\x19\x1c\ +\xc0>\x19\xd4\xb7\x9c\xc1\x99&\x8c\x1e\x9b6ml\xbf\ +r\xe5\xfe\xc2\x15+\xbeC\xb9\x0fU\x98\x1f\x01W\x88\ +\x8c\x03\x83\xc1q=pAth\xe8\x8a\x9b\xdb\xb7o\ +\x8b\xfd\xf0!\xdd\xbb\x812\x18*P\x82!cr\xe5\ +\xc1*`\x14V\xbb\xab\xe2\xc7\x00\x83\xc1=\xd82\xe1\ +\x0b\x8d\xc1`P \x1dA\xf3'0:?0#E\ +j\x19\x0c\x06y8\x91F\xf6\x1a\xfc\xb4\xadI\x93\x9f\ +D\xc6\x82\xc1`\xbc\xbd\x7f\x7f\xe2+??\x92ao\ ++$\x18\x8c\x0c\x92\x08g\x94\xa8Q\xc3\x19\x97\xfa\xe0\ +u\x91\xfe`0\x18$T\x0b\xdadB\xc23\x83\x03\ +\xdf\x8c\x14!\x16\xe22S/\x07T\x1a2\x16\x0c\x06\ +\xc3}\xc1\x82\xa6\xa8D\xb8\x06\x09\x87\x8c\xd6\xc2d\xf0\ +\x19\x8e\xd1a\xe5\xca{\xb8\xec\x01\xa3\xc5\x0f\x01\x06\x83\ +\xcf\x81'\xb1<^\xc4\xb5\xa1\xf8\xd7\x81A\xba\x8d\x13\ +H\x1aN\xe8\x04\x18yK\x96\xf4U\x09\xd1J\xa8T\ +\x9e\xd4\x09\xc8X\x08#\xf1\xef\x01C\x0a\xa3>\xc4\xb5\ +\x8b\xc8r0\xd0\xffn#\xcd\x89\xa6\xb8-\xb8\xef_\ +\x92\xb1\xc289u\xea\x09H\x85G\xcb\x09>\xb9X\ +\x88\xca\x22K\xc0\xa0^w0\xae8\x8b\x5c\xb9>\x9e\ +\x9d=\xfb\x08\xfa\x228l\xaaS\xe7\xa6T\x8d>)\ +\xfe\x15\xe0\x0c\xf9N\x90\x17x\x0ea\x9d\xcf\x10\xceI\ +\xc6\x84\x93\xf1\x15\x9d)D.\x91\xa9`\xc8\xde\x07J\ +\xff\xbb\xd9`\x8f\xcf\x9f?Ouh\xda\xf4\x16\x8d\x9b\ +\xe5\xca\xd5H\xfc\xf0\xe0I\xee\x07\xa6\xec\xeb\xd1\xc3\xfb\ +\xa9\xbb\xfb\xfa\xd33f\x1c@\xbb\xdf=\xd4\xe8\x10\x1c\ +7P\x08=\x91\xe1`\x98\x08\xd1\x5c\x11\xb4u\x1e8\ +\xf085.\x11\x12\x07\xfa\xf5\xb3\xa5\xf1=]\xba\x18\ +\xcb9\xdb\x8a\xb9\xb1\xc3\xb5\xb0\xf8\xe1\xc0\x06\xf7\xdc<\ +W\xae\xa8\xe8\x97/\xcd\xa9\xbf\x1a\xf8\xfb\xc9\xc9\x93G\ +\x91\xce\x87\xdcf\xfa\x83\xadDF\x82\xe7\x80\x9cW7\ + F\x1b\xbf\xb1V\xadG\xe8\xe6\x9a\x8c\xb1nx\xa4\ +\xc2\xd5\x00sq\x90\xe6\xe2\xfa\xe6\xcds\x05\xb0L_\ +\x7f\xaf\x9c\x9bG?`\x09\x10;M\xce\xcc\x9au\x14\ +\x86\xd6AHX\x95+7\x8b\xc67\xd6\xac\xf9\x18\x7f\ +\x04\xb1R\x18\xd5)}=f\x0c\xf2\x0e\xc3\xd0\xc6\x80\ +\x0bi\x1e\x0e\x8f\x18q.\xe6\xed[c\x9br\xe5B\ +\xa5A\xbd\xc7\xb3`\xd9\x11\x88T\xc5\xfa\x0b\x00[\xcc\ +M4vd\xd4\xa8\xfd\x18\xa36]M\xc06B\x03\ +\xd2X\xe7\x80\x1d\x84\xce\x80\x91-_\xe9\xd2!\x1dV\ +\xad\xf2\xc6\xcde\xa5\x96+\xe6\xe5\xcb\xf9\x06\x05\x0b\x86\ +\xfd\xee\xe3\xb3\x7f\xd2\xdd\xbb\x1b\x0d[\xb6\xf4\xcb\xa6R\ +\x0d@\x94\xfc\xe1\x12z%]\xc0(%\x84\x91J\x88\ +\x8d\xe0\x0a\xbd\x9c9\x13\xda\x9a\x9b_\xc9W\xa2\xc4\xfa\ +\x81\xce\xce\x96\x95:u\xf2\xd1\xcf\x9f?)g\xee\xdc\ +\x02?\x9f\x1f\xe9\xe9yH\x08\x11\xb0P\x88\x12!W\ +\xaf\x0eE\xf8\xe0M\xf7\xcd\x9b\xef`,6E\x08s\ +\x5c\xbd`\x5cG\xc9\xf1\x22WM:\x83O\x03\xdd1\ +g\xdb\x84n\x80\xf1\xcc\xd3s\x1dV\xb7zB\x02\x93\ +cM\xab\x1b\xf4\xfa\xef_]\xb7n\x10\xd4\x88\xd7\xe3\ +\xf9(\xe7A\x83\xb2\ +C\xa83\xc5\xed\xb4\xb7CX\x19?,\xcf\x97/&\ +\xfa\xd5\xab\xe9x/\xa7L\x8a\xde@gD\x91\x11\xe0\ +\xf9R\x81\xa3>EF\x9ac%\x9b\xaa\xb9\x85\xdc\xdd\ +\xb9\xf3U<3\x12\x12\x8fO\x9e\xfcE\xc6\xf3\xae\x0a\ +-$%%5Bg\xd8s\xf4\x1c\x0e\xb3\x0b\x22\xd3\ +\xc1\x93X\x17\x9e\xb39\x94@\x8bmK \xbc\x5c\xf3\ +1f\x80\x09\x99\x01\xa6<9{v)\xbd'\xb4\x80\ +j\xe7\xb5d\xacx\xd6N\x06]\x95\x8c\xf7p\x5c\xa7\ +\x82\x19S\xf0\xca\xf3U\x03,td\xf4\xe8\x0d\xd8^\ +F\x91\x97\x19\xd9C\xf1\xe4u\xd6H\x1d\xebIs\x81\ +\xad\xa8g*s\x9e\x0d\xe7uojh\x02\xc3\xdc\x80\ +\xfb\x12\x22\xf3\xc1\x07x\xb0\xbd\x8c\x015\x14\x00\xb6#\ +\x03i\xd2\xb65k\xb6\xfd\x1b\xbf\xd3\x08\x1c\xbf\xfe\xe7\ +\x9fK\xd3\x96\x14\xee\xeb\x90k\xeb\xd7\xef\x82\xdb\xfa\x8d\ +4\xbe\x00jt/2\x0aZ\x0e\x93\xec\x98\x8f{X\x15?\x86?}\xba\ +\x02\xcf\x8b\xfd\xa9|{\xe6\x82\xe1\xe7\xe00we\xc1\ +\x82\x91\x14\x06\xc0\x04\x5c\x00\x17\xc8\xec\x14\x03\xad\x89\x9f\ +\x00\x8e\xc56e\xb8\x12\x94\x8d\x08\x0aZE\x8d\x0f\xe9\ +\x1eq\xa3\xa1\x22\xa3\xc1m\x96\x17\x04]\xbch\xf7\xe2\ +\xd2\xa5\xb5_\xbe|Y*\x83\xe5\x06Z!\xa1)4\ +\x1f\xc7'Nt\xc3\xb3\xae\xe2O \xe7\xfa\x84\xb1\x10\ +\x15D\xe6\x81\xdd\xd2\xef\xee\xdd[\xea\xd8\xa6\xcd\x0dd\ +\xb5\xab3Rh\xeb\x82B\xc9ZZ\xef\x15\xc1\x19\xb0\ +\xb8fP\xd6\xd3\xc4\xa49\xe1\xdb\xf0\x09\x9eM\x07\xb3C2\ +\xa0 \xbc`4a\xbf\x8b,\x03o5\x03O\x9d\xda\ +`W\xb9\xf2c26\xaa\xbdC\x0co7\xe6&U\ +\x0f2\xe2y\xcd\xb1C\x09\x91g\xc1\xdb\xafn\xdfn\ +A%ABg\xc0ib\x07\xe4\xe4\xc4b\xfb\xf1\xe5\ +\xe1\xd1\xa3\x9b0A\xd5\x85\x84\xdc\xde\x14\x14Y\x096\ +\xba\xca\xe0\x1f\x97W\xad\xda\x8fj\x90\x0f\xd2\x91uY\ +[\xa8HI\xa0\x86\x03F\x9d\xca\xb7\xaeJ\x15\x1f\x1d\ +\x9b;Fdhh=*\xa4\xa4\xeae\xf2fR\xa0\ +u\xae\x10\xf9\x84.\x82\xb3\x8b\x9a%\xc4\xc4\x18\x1f\x19\ +9\xf2,J\x84n\xb8\x0e\x1b\x96ZO\x04\x15\xb6\xa1\ +\x97\xe9\xec\x1dz\xed\x1a\xa5\xf2\x19\x0a\x9d\x03g\xbe\xf7\ +|{\xf7\xae\xe5\xf6\x16-n\xd2*\x87\x04\xe7\x81B\ +W\xc1\xf3\x95\x07\xec\x05.\x01\x1b\xcb]\xcaz\xd0D\ +\xa6\xf2\xfd*\x03\xe6^\xb2\xe2\x5cG\xc1\x13Y\x0a\xfc\ +=2$d%\xae:np\x0c\xa5\xac\x87\x80\xd5\xec\ +\x18\x19\x99\x94w\x08]\x9e'Ox\xec\xfb\xf7\xa6\xe4\ +,K\xc51V\x16\xef\xcd\x05\xcd\xa8d+\xeb\xcb\x80\ +x\x22\xab\x83e\xc5\x8f\x04\x9e\xb3\xf6\xe7\x8d\x8d\x0f\xa1\ +\x0cH}\xbeC\xc6\xd0[\xaf\xa5K\xc7\xa5\xa24\xd6\ +\x9f\x0a\x94\xb5\x84ko\xca\x8a\x844\x80\xc1\xe0\xf3]\ +kZ\xd5\x9c\x06\x0e\xf4\xc2y}\xf5\xa7\xa8\xa8\x8a\xdf!\xb9\x9f\x1b\x1c\x0dZ\ +\xc0hg\xe3ZQ\xfc\x0b\xa1\x12\xff\x10\x0c\x86<\xdb\ +\xd5\x06\xeb\x80_\xc1\xf3*\x95\xeay\x1a:\x07uV\ +\x09\xb1\x03,\xad1\xfc%E\x88q\xcb\x84p\x14\xe9\ +\x06\x06\x83\x9b\xc9\xd4\xc3\x8a\xf6\x11\xb1\xbb\xc4\x13\x13'\ +\x1e\xa4\xcc$*\xdfB\x91\xf3\x07\xa9,\xd0L\xfck\ +\x90\xc5%\xf3\x0c\x06V1\x13===\xd1k\xc7\x8e\ +\xbd=\xec\xed\xfd\x0a\x96+w\xaaz\xbf~{\xda\x9a\ +\x99\xed\x15*\x95\xc8]\xb4\xa8\x89\x90\xf8gic\x0c\ +\x06\xafn\xd9Q\x89\x10M\x82\xb5\xd8\x96N\x02\x0bj\ +*\x06\xd8\x18\x19\x05[\x96(\x11\x8aq\x15\xe9e\x82\ +\x91\xf8\x9d\xc5\xdf!X\xcb`0\x16\x0b\xf13y6\ +\xd1\x00\xf4\xb8\x12\xe3\xd3\x04tN\x9f\x93\xdc\xbe\xba\x07\ +\x9e\x9e^7zW\xf2y\x1aE\xa8\x18\x0c\x06)s\ +C\xad;nc\x9d:WSq\xa4\xa8\x85k\xd1\xe3\ +\xe2\x12U\x9e@\xf5m\x0b\xdd\xbb\xfc\xf6\x9b\x07\x8c0\ +\xd0\xa1eKj\xdf\xa5ZDm\xf6\xfe\x1e\x18\x0c\x06\ +\x8c\xed\x92\x5c\xb5zi\x18[w\xd25%YE(\ +\x8eY\xed\xee\xdb\xb78\x82\xeb\xb1\xb6\x15*\xbc\xa0J\ +u\xc8\xf9Y\xe0\xfa+\xde\x99\x09~\x01\xb7P{.\ +\x91:\x18\x0c\x06)\x81\x81c\xa1\x97rSvbJ\ +\xc4\xf5\x0c\x8c\xc7\x1d\xd7\xcf\xa8\xc9\x8b\x86\xb7\x92\xe49\ +\xfaa\xec\x0fz\x87z\xe8\xd9\xff\xfc\xf3<}\xbcd3\xcbV\x1a\xc6V\x87\x0c\x95\ +\x82\xea\xb8e0\x18T\xe4\x0a\xcezp\xe4\x88=5\ +!\xa1\xfe\x07\xe8S\xfe\x02\xdb\xc5\xf6\x1a*pG\x94\ +\x95\x105y\xdeg\xe7\xccQ\xdfc;y\x99\xde\xb7\ +)W\xee!\x9a\xcd\x98\x90\xfc\x9f\xd2RM\xfe\xdeP\ +\x18\xf2'\xcb\xe2\xc5\x8d\x05\xc0`0d\xe7\x1e\xb0\xda\ +3w\xf7Uh\x02\xeaa\xf7\xd3OgN\xcf\x99\xd3\ +A9\xe7\xc1h\xdej\x88\x18-\xc1\xf6s\x9f\xd4\xd3\ +\xa4^\x15\x11\x10\xabZ\x83\xf1\x06\xf2\xfd\x0eR\xe0v\ +\xe3\x91\x09\x13\xca\xbf\xbaqcMBl\xec|\xd9\xa8\ +\x92\xc1`h\x06\xba\xc1q\xa0\x09\xd8[H\xbc\xb9{\ +w\xa0\x8f\xb5\xf5^\xb9e\xac\x0aI\x87\xab\xd2\xc9\xf2\ +\xe5\xba\xbd\xfdNM\x15h\x8c\xe7G\x13Q\xc5\xeb\x19\ +\xb1\xb3c\xc7\xbe\x7f\xa1\xf0\xcd`\xb0\x9eJ*\x868\ +\x00,GN\x10\xacx\xf1dP\x87\x06\x0d:\x8f\xb1\ +)\xda}\xd1\xd1\x9c\x92<\x9fQ\xd8\xa2F?ts\ +\xab-\xbe\x1f\x0c\x06\xe3\xf8\xf8\xf1\x0b\xd0\xf8\xf3\xc6\xe7\ +\xa4$\xe3\xd4Zk\x99f\xcb6\x8f\x0c\xf2\xcc\xacY\ +Ge\x97^\x9d\xc2\x0f\xb5\xb7e0zn\xd9\xe2\x86\ +K\x0ax\x06%@a\x94c\xa9\x12\xa2+\xee\x97&\ +a\x81K\xf9\xfa\xd58\x1f\x1a\x81vX\xb5\xca\x1bc\ +\x97\xfefLp\x16.\xc5\xc1\x15fB\xc4hI\x8d\xcd\x140\x10,\x8a\x98\xdeL\xba\xdf\xd1\xaa\ +\x95\xfb_\xf77g0\xd8\xe8\xaa\x81\xd3\xbd\xcc\xcc\x9c\ +V\x15*\x14A\xc6#W\xb1\x9c\x02\xa0\x8e\xad\xb4\xf2\ +\xa1\xd4\xe7\xc9+??\xeb\x8f\xef\xde-\xa7\x9e\x85\x14\ +p\xc7\xeav\x1d\xef>1\xcf\x95+\x06\xc5\xaf\x16\xe4\ +\xa4\x11\x7f\x09\x06\x83\x8d.;\xd8\x92:\xed:\x0f\x1e\ +\xec\x81\xd6\xd6\xbe\xe8\x0aTP\x9e\xd1&\x83)\x90k\ +w\xa2>\x17`\x0d\xb0\xed\xe1\xe1\xc3O\xd38\xd1m\ +\xda4*\x11\xea$\xd2\x06\x06\x83\x9b\x92\x80}AS\ +\xb0\xbe\x00\xb0\xcd\x1c+\xeb\xee\xb6\x08\x0dl\xfd\xe5\x97\ +\xc54N5w\xc8V\x99'\xcf\x86\xff\x04\x0c\x06w\ +\x03Z[\xa3\x86!\x9d\xed\xc0\x8f\x8b\x85\xa8+\x00*\ +\xe7\xc1V\xf2\x22\x19\x9c\xdf\xd6\xad;\xc88\xa9\x8f!\ +\xee\x17\x81\xe7\xf0\xcc\x0d\xd7Q\x22\xed`0\x18\x88\xcb\ +\xedD\x02t\xb2<\xdf\x85\x11\xe9\xe7\xcd\xf5\xeb\x07\xc0\ +\xd8&\xac)Q\x22\x0f\xee}i\x0cg\xbbX\x0d\x9d\ +Mc\x16\x11J#\x18\x8c\xce\xd6\xd6+\x87\x9c8a\ +_g\xd8\xb0\x93E*Uz\xa4\x12\xa2\x88\x00Z\x19\ +\x1b_&{\x84#e*\xae\xbfT\xea\xd4\xe9\xc2\xc2\ +\x8f\x1fmf\x85\x86\xae,\xdd\xa0A\x00\xde3\x87\xe1\ +yR\x0f<\xe9\x84\xf9\x9b`0x\x9bY\x01\x1c\x1e\ +\x15\x1a\xba\x84\x9a\x8d\xa8\xcfoe\xcb\xde\x16\x00\xc2\x05\ +\x17\xb1\xb2}\xc1Y\x8e:\xc16\x03\xebD\x04\x07\x8f\ +\xa0\xad\xa8\xc6jwZ|\x17\x18\x0c6\xbe\x01\xfe\xdb\ +\xb7o\xbf{\xe0\x8099K\x90\x7f\xe9\x8d\xea\x83\x84\ +\x97\xbe\xbe\xed\x84\xc4\x86\xd6\xad\xf3R8\x81j\xf1\x8e\ +\x8d\x1d{\xea\xf8\x84\x09\xeb(w\x93S\xbb\xd2\x0e\x06\ +\xc3\xf5\xe7\xd1\xa3_\xe0Z\x09\x14\xc5j\xd5\xf2\x0a\xbd\ +r\xa5\xf9\xde.]\x16\x1a#.\x07\xc3\x88\x0c\xbbx\ +q\x1d\x1e\xa9\xaa\xf6\xee}\xa5\xd7\xb6mnt\x04;\ +\xf4\xeb\xaf?Q\xad\x1d\xc6\x0d\xc1\xb7_\x85\xd8k!\ +\xc4\x1d\xf1\xf7\xc1`0^\x05\x04\x18\xa2\xc0\xf5\x8e\x86\ +\x14\xdfg\xbaB\xaa/\x22.,l)5\xa7$Y\ +?\x127\x92\x1d\x83\xe2\xe56\xf3K\xda\x1c+\x0c\x06\ +\x0b\x1a\x19\x92\xdc^rrr?\x7fG\xc7\xed\x90\xe2\ +s^\x9e/\xdf+E\xb8\x08\xc6\xd6F\x00\xb2\x7fy\ +\xca\x86\x1a5\x1e\xc5\x85\x87[<<~|\x93\xad\x91\ +\xd1\x0bi\xa0\x83\xbf\xf1\xdf.\xfd\xbf^J\x06\x83q\ +2\x07\xb6\x91\x16\xfa\xfa\xb5r\x15,x\xb4X\x8d\x1a\ +O\xbe$$\x14-X\xbe|H\x1b3\xb3+x\xee\ +C-\xb8TB\xd47(T(\xea\xc3\xa3G\x95\xad\ +K\x97\x1eqo\xcf\x9e\xa0\xd1\xde\xde\xb69\xf3\xe6\x8d\ +\xd5\xcf\x9f\x7f\x89\xd0\x02\x06&\xa4\x08\x11\xa4at\x0c\ +\x06\xc3m\xfa\xf4>Ve\xca<\xd3\xd8N~]\x91\ +/\xdfS\xa9\x1cVK\x00\xd4hR\xc6\xed\xee\xd1\xca\ +f]\xb6l\x80\x8c\xd9y@\xd8\xe8\x0d\xb6\x9e1x\ +\x97\xf4TT\x18?\x08Z\x914;\x9e=\x8f~\xff\ +\xbe\xb2\x00\x00\x06\x83A\x02D\xe8q7\xcb{\xcd\x9a\ +}\xdb\x9a4\xb9\x88\x02\xd7\xc3\xb4e\xc4\xf8`\xa1\x01\ +\xd2\xc0\xa4\xd0\xc1\x96\x06\x0d\xa8\xf8u\x1a\x12\xa0\xf7\xa3\ +\xe5\xf2\x1b\xb9\xcd\x0c\xc4\x98\x91\x00\xcc\x0d\x0c\x8e)\xc6\ +\xbb\xb7kW\x9f\xc4\xd8\xd8\xfa\xe2\x7f\xc0`\xb0\xd1\xe5\ +\x90*b3\xc0\x85`\x1bP%4p\xd7\xc9\xe9\xd7\ +\xd5\xc5\x8a\x85\xd1\x0a\x08\xa7\x89\x07\x8c\xc9\x22,0\xd0\ +\xdcu\xe8Pw\xef\xd5\xab\xf7)\xcaa\x97--'\ +\xd0;\xa8D\xf8,\x0d\xef\xba\x89\x10ME\xda\xc0`\ +p_\xf3\xf0\xe7\xcf\xe7\xef\xed\xde\xdd\xc7\x5c_?\x5c\ +z+c\xd1vy\x11\xe9\xab\xc8\xd7T\x18\xbb@\xb1\ +\xbb\xa7\xee\xee\xebQ\x91p\x0e\xc2G\xf1\xb2\x06\xaf\x9d\ +H\x13\x18\x0c6\xba<\xe0\xb0\xe4O\x9f\xcc\xae\xd8\xda\ +\xeeql\xd3\xc6\xed\xa2\xb9y+2F\xa9(\xdd\x9f\ +\x0c\xf1@\xdf\xbe\x1706\x04\xec\x0d)?K\xd7\xe1\ +\xc3O=>q\xa2\xa5J|\x0f\x18\x0c6\xbc\xc2\xb8\ +\xd4\x05k\x83O\xa0\xafrZz&\xaf\xe600\xa8\ +1#8xm\xde\xe2\xc5m1\x1eE\xdd\x7f\xf0\xa8\ +#\x18,\xd2\x0f\x0c\x06\x03\x0e\x93\xfb\xcb\xf3\xe4\xf9x\ +m\xfd\xfa\x91\x19\x5c-\xc0`0\xda\x98\x9aZ\x93\x9a\ +\xf4\xe9i\xd36\x99\x0aq\x18\x1c\x85\xa0z\x99\x0c0\ +8\x06\x83\xd1b\xc1\x82\xe3}\xf7\xec\xd9\x5c\xaa~\xfd\ +G*==\xd2\xc5tDP\xfd\x84\xc8\x180\x18\x0c\ +R\xfe\x02g$\xc6\xc5-#\xc9\xbe\xb0\xc7\x8f\xe7*\ +\x15\xe8\x19\xe74a0\xd8\xf0J\xe3RM\xda\x99\x0f\ +\x1c(\x09\xe2_\x09\x06\x83\xc1`0\xfe\x0f\x1d\x9b\x1f\ +\x99f\xa1:\xad\x00\x00\x00\x00IEND\xaeB`\ +\x82\ +\x00\x008\xb4\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\xa8\x00\x00\x01w\x08\x03\x00\x00\x00\x06\x8a\xf0\xc8\ +\x00\x00\x02\xc1PLTE\x7f\x00\x00\xa3m\x93\xa4u\ +\xa1\xae\x96\xd0\xbb\xb2\xec\xcb\x9d\xa4\xd7\xcd\xed\xbb\xbb\xfe\ +\xcb\xcb\xfe\xd0\xce\xfe\xd2\xd2\xff\xc8\xc6\xfe\xc3\xc3\xfe\xdc\ +\xdb\xfe\xc0\xbe\xfe\xb8\xb6\xfe\xd8\xd7\xff\xb3\xb3\xfe\xe2\xe2\ +\xfe\xeb\xeb\xfe\xf3\xf3\xfe\xfc\xfb\xfe\xb0\xae\xfe\xf0\xef\xfd\ +\xad\x80\xa3\xf9\xf7\xfb\xaa\x9b\xe0\xad\xac\xfe\xa4b{\xbc\ +{{\xbd\xb9\xf5\xbf\x80\x80\x911=\xa7PP\xa9S\ +S\xca\xc4\xf2\x95,,\x96@S\xcc\x9b\x9b\xcf\xcb\xf7\ +\xae\xa6\xf1\x9cSm\xdc\xb9\xb9\xe0\xdf\xff\x9cZ{\xb5\ +\xb0\xf4\xee\xe0\xe1\xb7pp\x9eAB\xf5\xec\xec\xbb\x83\ +\x8f\x8f !\xbe\xb1\xe4\xd5\xac\xac\xce\xa0\xa1\xbe\xa8\xd3\ +\xb2lr\xd7\xb0\xb0\xdd\xc2\xc8\xed\xe3\xeb\xa9v\x99\x8b\ +\x22,\xb6\xa9\xe4\x9dj\x98\x89\x13\x14\xb9ss\xb9v\ +x\xb9\x9f\xcc\x9fh\x90\xa3\x81\xbb\xbc\xa2\xcb\xbc\xaa\xdb\ +\x9c::\xa6q\x94\xc1\xbb\xf3\xa6\x88\xc2\xc4\x91\x98\xc5\ +\xba\xea\xc6\xba\xe5\xc6\xc0\xf4\x95Ji\xa8\x85\xb9\x960\ +1\xcb\xaa\xbd\xb5ll\xaa\x84\xb3\xcd\xa3\xaa\xb5\xa0\xd5\ +\x8b\x1a\x1b\xd0\xa2\xa2\xacZ[\xd1\xac\xb5\xac^b\xac\ +\x84\xad\xaddm\x97V}\x9833\xb6\x99\xc4\xdf\xdb\ +\xf7\x99FY\x9a=D\xe4\xcd\xd1\xe6\xd0\xd2\xe8\xe6\xfb\ +\xea\xd7\xd8\xaf``\xec\xda\xdb\xb3\x92\xbb\xaf\x8a\xb5\x9b\ +J\x5c\xf1\xe3\xe3\xf3\xed\xf3\xb1cc\xb1\xa3\xe2\xf7\xf0\ +\xf0\xf8\xf3\xf3\x8c&2\xb3\x89\xab\xba\xaf\xe8\x8d,;\ +\xb6\x84\x9a\xac\x8a\xbb\xba\xb4\xf4\x89\x1a\x22\xa1P\x5c\xcb\ +\xc1\xec\xd9\xb3\xb3\x85\x10\x13\x95C\x5c\xc1\x83\x83\xa3T\ +a\xc2\xb4\xe2\xb0\x9e\xdb\x99CR\xb1\x86\xa9\xc7\xa8\xc0\ +\xb1\x8b\xb3\xa3\x87\xc6\xb2\x9c\xd3\xa5LL\xa5h\x84\xb4\ +s|\xb4\xa1\xdb\xb4\xae\xf3\x9aLb\x94Eb\xa6\x8e\ +\xce\xd5\xb8\xc5\xd6\xc1\xd5\xb6x\x83\xa6\x8f\xd1\xd8\xd3\xf5\ +\xb6\x90\xb2\x9bWx\xd9\xc6\xda\xa7`p\xa7\x90\xd1\x9b\ +d\x91\xdd\xcf\xe2\x8d0D\x8e8R\xe1\xc4\xc4\xb9\x8b\ +\xa3\xe4\xcb\xcb\xa9\x8b\xc3\x8b'9\xe6\xe1\xf4\x9d`\x85\ +\x90.;\xea\xe4\xf2\xbb\x9a\xbe\x905I\x9fEM\x96\ +Id\xa1DD\xad\x90\xc7\xa1MV\xaer\x86\x924\ +C\xa3j\x8d\x91,4\xc0\x86\x8a\x83\x0a\x0b\x9fRf\ +\xbc\x93\xac\xc4\x8b\x8b\xc3\x9c\xb0\x89\x16\x1a\xcf\xc2\xe5\xe9\ +\xd4\xd4\xb1\xa6\xe9\xb5\xab\xeb\xc9\x94\x94\xa1n\x98\xae\x99\ +\xd4\x9eXs\xd5\xbc\xcc\xbf\xa1\xc3\xae\xa9\xf5\x9bUs\ +\xafx\x92\xc1\xab\xd4\xc1\xb7\xec\x87\x19#\xb6\x9b\xcb\xa4\ +r\x9d\xaal\x83\xb7{\x87\xaar\x8d\xc4\xa9\xc9\x92=\ +S\xaa\x98\xdc\xb1\x92\xc1\xc7\x91\x92\xa4z\xab\xba\x95\xb5\ +\xe8\xda\xe3\xba\x9c\xc3\xca\xb1\xcc\xba\xab\xe2\x94;L\x9a\ +\x5c\x82\xae\x95\xcd\x959F\xa2Ym\xcf\xbb\xd7\xb4\x85\ +\xa1\x9dc\x8c\xbc\xa5\xd1\x99Om\xa6x\xa3\x91$$\ +\x9fo\xa1\x86\x14\x1a\x8e)5\x0d\x87*p\x00\x005\ +\xaeIDATx^\x84]S\xb7,\xcd\xb2\xed\xb7\ +r\xb5\x17\xb6m\x1b\x1fm\xdb\xb6\x8dc\xdb\xb6m\xeb\ +\xda\xb6m\xfd\x8a\x9b\x19\xe8YQQ=NveV\ +\xed\x97=\xe6\x08gDd\xae^\x9e\x0fr\x8c,O\ +\xc3\x1af\x1a\x7f\xfc\xe8(u-i\xca\xab,J\x19\ +u\x9c5=e\x12\x9e2\xb1\xa3\x1f\x9e\xb8\x0c\x87\xf2\ +\xc4\xa5\x1f~:V\xc6ge|\xe2W\x5cW\xf2X\ +\x11f/\x1f\x0c\xf2\x01\xd0f9C\x15\xb0\xadQ\xd2\ +\x14\xa8a\xa5Y\x16\x0a\x97A\xd64\x02\xb22\xfe\x04\ +p\xcdP\xfb\x01]\x12'#\x0d3\xe0\xec\xf7\x814\ +\x0c\x8bR\xb1\xf6\x22\xc80\x05iF3\x8d8\xe9\xc9\ +,E\x89\x8c\xf4\x13z\x82\xa2\xb5<4\x93\x004\xac\ +4JK\xd6\x00\x92\xa0\x0aA\xe9\xb14%\xa2:\xac\ +=\xa0\x04=\x99\x98Yx\xe2\xa2X-`\xb0\xde0\ +\x9f\xa9\x19I\x9b\xcc\xa89\xa3(\x91S\x99\x1ef\xe0\ +;Q\xb3\xcf(\x01\x95\xb8opF\xd6\xc7_\x03i\ +\x84E\x88\x09-\x81\xcd\x0dD\x85\x09\x82\x02(C\x8d\ +\x13\x1c\xa7\x85\xc9)\xbc\x0f\x0c'\xa22Z\x82\x89!\ +\x10\x15%(\xda\xa5MY&\x8a\x94\x1bBB\x99\xf8\ +\xc5\x98\x0b\x03S\xa5\x94\xe8\x19\x95\x0a\x5c\xe7IH\x03\ +8a\xbf\xd1%\xd6# 5\x14\x8d\x9c\x07\xd4\x8c9\ +O\x22\xaa\x04M1\xbc\xef\xac\xe5\x91A\ +\x09b\x1aO\x0f\xd6\x03e\x84\x19'\xe1D\xdc\x5c(\ +R\x0e\xf4\x09\xab\xc0,\x14%\xbb%%iR\x9fv\ +\xce\xab\xbf\xd0[G\x0c\x1e\x0b\xf7w\x11\xceINf\ +4\xcc<\x1f&\x80\x09\xa2z\xcd7\x14e\xc6\xe7\x02\ +\x94!\xd2\x9aAD\x05\xa8be\xa00K`\xfe\xad\ +\xff\xd0\xc3\xf8\x5c\xc9@o'\x05z\xd3\x95K\x9f\xb8\ +\xfd\x8a\xf7l\xde~\xfb9\xefJ\xa0K\x82qnP\ +b\xed\xa8\x1a\xd2HM\x11\xd3\xa6&\x15\xc2zF\xe9\ +\xa3\xf9\x95\xf1x<\x1a\xe5\x83\x94\x90\ +NK\xe8\x03\xaf\xa7(t?{x\xf3\xc7\x08\xa9\xb2\ +~\xabXRr\xf1EA\xef\xf29\x8d\x80nZ}\ +\xe3\x89\x97\x91\x90\xf2V\xd9\x19\xd2_Y\x1e\x04\x94\x0c\ +\x95\xf3\x99\ +\xeb\xdeF^o9\xcd\x80\x94\x85\x94\x08J#]\xc3\ +\xae~spJ\x18?\xdb\xfb\xd0\xb4\xd0\xf2\x8d$\xa0\ +\x0cF\xc9;jQ\xccr\xde\xc8\xa87\xf8q\xe6\xd9\ +A\x8a0n\x9e.\x8e\x06y\xba\xf5\xdb\x91~Sx\ +\xa6\x22;\x9b\x22\xb9\x8aq\x92\x8b\x8a\xd016\x1d\xe9\ +\xddt\xc9\x03\xd3qU\xa2 F\xe4\xac\x81\x92\x9f(\ +\xa3\x022|\x01&=]\xbb\xa6m\xdb\xb6!\x01\xf1\ +UR\xe1\xa7\xa6\x03\xb1\xf5\xc1\xef}n\xda\xd8\xd3s\ +\xc0\xb7:ZR\x0d\xf5\x8c\xb9\xdf\xfb\xf4\xb8\x18W\x99\ +\xd6B\xc9\xe1\xd7`=\x8a\x0d\xc0\x0b}\xc2\xb0\xe9\x07\ +\x0c\xe4\xf0\xef&=\x9f\xcc|\xd3\xd6\x8f~e\xc2E\ +\x11E\xfa\xcfQ\x1a\xc6a\x9f\xf7\xe8\xa9\xbdUY\xdc\ +\xd4\x1dz\xb9\xc2<\x16T\xc7T\xee\x08d\x0d\xd6\x0b\ +V\xd5v}h\xf2@\x1c\xca\xd3\x85yb\x99(w\ +\xb5\xda\x1d\x81\xd2oD\xf4\xab\xb3\xd8\xe0\x1b\xde\ +\xe2\xc8-Np]\x80Z\x9c\xe8)\x89\x8f\xa5\xe7\xb0\ +\x0f\xd6K\x82\x84\x16\x97\x86P\x80\x06+2\xceh\x22\ +\x94'\x95\xaa\xad\x89JJ~\x19\xd6\x17f\xbb,\xbd\ +O\x08I\xbc\x17\xa5\x1f}\x1a\xeb\x84\xbe\x17\xb7\xafg\ +\xcf\xe4\xdb\xdb\x09g\x06\x19\x05-\xad\xa4:\xbe\x87\x07\ +\xca\x94\x04\xe4]\xee\x93\x1f$\xc5\x13c\xee\x8d\x15\xb5\ +\xad\x1a\xae\xdb\x91\xbb\xc53\x18|\xab\xf7\x82O\xdf\xfc\ +\x82\xd6\xaby\xf22\x0a\xb4\xbaW\xa6o/\xa8p\xf9\ +6\x1e\xb5\x03\xfd\xcd\x99\x97Q\x905Ut\xa9\xd1\xa3\ +\x1a\xa6IVk\x99\xb0\x9fw\x18\xfd\xbe\xde\xfb\xfa.\ +\xb4qi\xf9P\xeb\xe8IT]\x96\xc4\x91\xd4\xb5\x0e\ +\xc3\x86\xd2b\x15\xc9\x1fl\x98\xafL\xaa\xf8\xa0\xa8\x0b\ +J\x8a\xb8\xfanLu\xa1\x82\x12@\xed\x90\xe8\x095\ +&@\xednx[\xd1\xdd?J U\xf3\xa1\xf5\x08\ +L\x0a\xae\xde\xd0\xce\xd9\x84\xf8\x89\xb2\x1e\xb3\x9dwb\ +\x96sa\x84\xd4>q\xbe\xc9$\x9b\x8765\xee\xb8\ +\xce\xab\xb7\xf6\x08\x99qZ \xc5\xae^\x95I\xe3Q\ +\xc8\xa9\xed\xc3\xc7a&CMy\xe4\xe5sO\xf2D\ +h\x99`\xcdT\xa7(\x84vh[m\xce\x18jC\ +kZ\x15l\x9c\x84\x118\x01\xd6\x0c\xa3Fx{\x8a\ +\xa6\xbaF\xe9T\x19\x05T\xf6E\xea;\xfdV\x84W\ +\x06[\xf3\x0b\xc3\x22\xf5\x813v\xa1\xde\xdb\xfb\xde<\ +6L\xcdcl\x99\xe1:>\xbd\xa7\x07J\xa4I\x8c\ +\x98\x82\x9a2\x05-l>\x0c>-~_\xef<\x13\ +\xc3\xf5[P!\xa8\x85\xe9s:%\xa4\xd3\xf8{\x17\ +\xe5\x81\xb0N\xef\xbdy2}O0\xa2\x19\x93\x15\xbc\ +w\xa7\x9adZ\xf9\x04\xf3\x91\xd7a\x90\x16.`&\ +\xde'\xe9\xea\xca7\xc6\x8eR\xef\xa0\xc0\xc5\xe0\x04Y\ +1\xe3\xbaLKWD\xf7no\x87\xed\x08@Z\xdb\ +\x04\xc5\x9f\xd7\x01\xe1\x07\xe1\xe4\x98\xc4\xb0\xbf@\xa0\xd7\ +\x86\x09\xe1\xa4\xc5\x9fm\xe8\xc3\xd3\xebj\xa0v\x07%\ +\xa0he\xa5T9\x8f\xc0\x99a\x02i\x89\xc0\xd91\ +^\xd9^\x93}BX\x0a\xa2\xca\xe2r%@\xab|\ +ok}k\x08J\x9c\xc0p\x91\x93\x22-`\x9c|\ +\xea\xb1L@R\x83\x12\x91\x13b\xd1D \xfaZ\x18\ +\xa0\xba\xb6L\x06\xca\x10\xado*y\x16f\x17*\xae\ +\x09>T\xa5\x14\xd9\x92v\x80\x079\xb5\x81\xb3\x8f\x97\ +;=\x13\xcc=\xbfR\xdd\x88\xba\x5cI\x81\x93\x0d\xc6\ +\xd5\x1bQ\x85WrJO\xe0\xd0\xa7\xd1\xd2\xa6\xb9@\ ++\xbb[\x96\xed'\x0c~n\xad(\x07%\x90S\xd4\ +\x99\x12^\x98\xe3<\xbb\xe3\xe6Y\xc1\xa1\xa5\xf8^4\ +}~\x94\x16/\xa7\x80i\xad\xe8\xbc\x13-\x00\x8b0\ +\xaf4\xd1\x93*\x13`z]r\xe2I\xb3W\x0d,\ +\xccT\x812=i12\x8a\x04\xa9\x1b|\x88\x8d\xb0\ +9\x9c\xf0\xf3\xb6X\xef\x8f\xaf\xces\xa1y\x05!\x85\ +\xb7\x87\xbd\xf7\x813\xa6\x09\x9fj\x9a \xab\x97S\x8d\ +\xef\xb1[\x02]\x11\xe1\xe1\xa0\xb5\x09\x9c\x09\xa7\x0fG\ +\x89\x90X\xad)\xb5\xb9\xd1\xd4\xeeC\x15b9gc\ +\x87\xd0I\x00\xfbZ\x837S(\xda\x02\xa7\xe1\x7ff\ +7\xa2\x88C\xc37\x12y\xc0\x89]\xa8\xb8zSl\ +\xe8\x13\xf3\x01\x18:oc\x92\xee>\xfc\xca\xf0=\x15\ +\x8c\x10S\x9f#s\x1b{y\xd5\xb0\xf8\x9a\xd2I\xb0\ +\xf6\x85\xf9\xb6^o0\x9a\xca\x9d\xa7\xa8iv\x84*\ +\xe9#\x0bR\xb9\xcd\x9f\x190\xa0Q\xa9\xcc\xe6\x1e\x15\ +1_\xafO:\x14\xaa3\xf74\xb0(\xf1\x9b\x01\x06\ +T\xd5\xfc\x19J\x9f~\x12_\xefl\xa8`\xb5\xf5z\ +\x07S\xa0\x82\x9c\xd0z+\xa2x)57\x86\xfa\xf8\ +\xaa\x5c\x83{s0\xd4*\xbd\xf8x\xe3\x9cJ\x13;\ +q\xab\x86\xad\xd7\xeb\xb2\xd2\xe2\x0cow\xd2\x16\xa3\x83\ +\xf7\xe9\xc6/\xd3\xc1\x13\xb0\x9fQ\xf2,\xe0\x99\x8c\x88\ +\xaai\xd2\xa9X5\xed\x88\x82\x18\xc2g\xa8\x92w\xf9\ +b\x9e*0\x1f\x8c\x17\xb4[7s9|\xdc\x14R\ +A)\xd3F\xa4\xc6=A\xe5\xe7\xd5\xeb\xbd\xd6\xbb\x1a\ +#|=\xf4\x09\x04U\xaa\x1e\xe5\x12\xeec\xa3f6\ +\x0f\xfe\x93&\x06\xec\xa8,\xf4\xc0\xd8\xbbz\xbd~C\ +\x8f\x90\x18\xf7\xad\xc3\xde\x85\xc2\xd1\xaf\xa2\x8e\xe1\xe5\x09\ +\xf6\xa2NJM\x1c\x0a;*O\x93\xf5}_\xaf\xc7\ +\x00T\xb0\xde6h\xf94\x09\x9ch\x1a;K\xaeZ\ +\x1e)L\x94\xeb\x95\xb0\x96\x9a\xb0\xa3\x8a\xd6\x0c_\xaf\ +\x87J\x81\xef\xfa\xb6Z/E\x11\xbb\x15\x81\xce\xc7^\ +\x83\x83\x13wcAQ\xc0\xe2[\xb43;\xaazT\ +\xfa\xf3\xf5\x88\x9f\x00\xd2\x15\x1a|\xd1\xd6\x88\xa7.\x02\ +u+\xf5\xee<\x96+D(\x94M\x8fZ\x01\x80l\ +\xaa6\x01k\xbb^\xef\x93\x8e\x0c\xd5\xdaR_\x15\x01\ +\xeb\x19\xe9\xef\x92q\xaa,\xebQ_.\x9c\x8c\xf2[\ +\x9f\xba\xfb|=\xcc\x93\x13R\xa0\xf5\x9e\xc9\xe0l{\ +z:=1F\xf3\x8b\xb4\x8eBF}\xcc\xac?}\ +\xe90\x81\xb3\xa2\xf5^I\x81\x9a\xcc8\xf6Lm\xa4\ +\x025\x7fwl\xa3\x9f6\x1bux\xf8D\x1e\x10\x9b\ +\x94\x8e+6\xb5\xc2\xe6\xc4\xd9\xd0\xeeN2[\xb2\x85\ +i\xd2h\xf4\x14\x11R\x82\x08\x9c\x85\xfa(\x0b\x18\xa7\ +\xab\xe3\x8b\xbf\x91&\xd1\x0f\xd4\xeb\x15\xa7\x05\xeb\xec\xa8\ +\xdf3\xf9\xf8\xf9(\x9f\xf3K\xcd)V\xdf\x9e\x93\xb2\ +\xb3GK\x11t\xde\xd7CP\xafW\xbd\x07\xeb\xe7\x1f\ +\xb7\xf4\xca\x84k?\xf2\xadiF]\xad\xe3\x8cqB\ +L9\x90*:z\x9e\x12lFk\x7f\xf3\x0b\xaa\xe0\ +\x1aE\x81\x98M)\xed\xcc8+\xf3S\x03\x97\x99\x9f\ +\xfd_l\xb6\x9f\x10\xc2\xd4\xb0^\xea\xf5^R\xa5\xa3\ +@E\xc0*\xfe\x90\xa6\xb6d:\xd6\x03\x9f\x0fJ\x8c\ +\xb1\x87\x19\x15\xda\xd2\xc9\x8b\x07\xa7P\xa5\xd4h\xbd\xf3\ +\xf5LJ~\x9b\xcev\xc8i\xbf\xa1\xee\x5c\x1d\x01J\ +\xb4j\x06\xeb\x8d\x07\xa5\xed2P\xfa\xfb\x89\ +\x8e\xcaY\x0cu\xf6Px({j#g\x95P\x18\ +Q\xb7\xb7w\xbe\xde'r}\xffh\xd5\xd0\xfa\xd4\x15\ +\x1c\xbe\xaa=\xe2\x834\x85\xc6#_B M\xe0\x0c\ +\x88\xde\xdd\x0fU\x93l\xae\x84\x96\x95NL\xb1 \x1e\ +\xad,\xebaGS9\xcf\xff\xaa\x09\xb4\xbeH)z\ +r\x22\x0a\xadG\xd5\x0e.\x14\x045\xe6\xb3\xef\xe2{\ + \xf5\xc5\x06\xe7BS(\xd3/\xdc\xbc\x97\x0e2\x0d\ +D\xeb\xc94\xa5\x85\xb4\x91Z\xde\x9b\xbd(@\x22$\ +!\xa4\x90P\xef\xebQ\x17i\x83\x85\x8c\x0e\x5c\x86\x8c\ +f\x96m\x14w\xcf\x8c\xe7\x08\xaf\x19\xe5\xa5\xa6\xb1\x00\ +\xed\x83\xbc\xd24F\x94\xe5\x13\xf5z\x97&\x01F\x13\ +8\x07\xde\xd3\xec\xa8.\x0b\xde7PS6\xeb\x92 \ +U\x8d\xc2@\xecl\xfc\xbc\xa3(*L\x88\xa0\xbdB\ +y\xc5\xefY\x80\x88\x98\x91\xc7\xcb\xfe\x84\x8f\xb5\x89\xd6\ +KiY\xf5\x08hk\xa3Q\xdd\xf7=Y_j\x82\ +{s\x08\x83^ns\xd7ASd\xf32q\xf7G\ +\xaaT\x98\xcf\xda\xd4\x11\xdc\xd7\xa8\x812L\x9f\xcb\xe3\ +`\xc4\x86y\xbel\xdb}e\xa2+\x88e\xd4\xa7\xa1\ +\x89\xfc\x0c1)\xc1\x94ZS\xe7&4a\x8a\x92\xeb\ +\x94\xc9\x87\x06\x90\x17#\xa0\x8aT\x13&\x18\xf3O\x8b\ +\xf4\xda}d\xa9\x1c\x0a\xd6\xd6\xac8\x1f\x8d1)\x1b\ +(4\xe7\xf1\xbb\xb0J\xaf1\x09\xa7t\xf4\xe4\x8d\xbd\ +L\x098\x09\xa9\x93N\xabO\xbe\xba\xec\xbbJ\x22U\ +\x09\xea)\x10RQwZ\x0dE}\x17!/5=\ +.\xca\xc7\xdd\x9e?7\x1e\x85\x1d\x95'E-\x14\x11\ +>\x01%!]\xff\xa6C$\x9e\xa6t\x8btn\x22\ +\x13E1\xbf\xc1#lf%\xc6\x03\xa1\x8bG=E\ +\xad\x12\xc1\x962R=M\xf9!\xa9\xdc5\xda\x88\x5c\ +\xed\xce\x10\x14\x22j\xb7LH\x96\x00(\xaf.\x1eE\ +\x83Vw\x87\x0eOi~y\xa3\x00\xbdm\x14\x94\xc9\ +\xd2\xb3\x9cS\xb0\xef\xa2(\x94\xcaD$\xa6\x82\x03|\ +\x00i\x1b\xb4\xa0\xf60\xf6\xaaQz\xb0r\xf5\x04\xc5\ +0o\x9e\x92\x048\xf9\xa3-\xa1\x0c\x0a\xde\xc9'\xf0\ +]<:\xaf^\xcfL\xf7\x1d\x10\xff\x16\xcf<\xec\xdb\ +3.\xb4\xd8\x10\xde\x04\xd5S\x15\x22\x0a\x9d\xf7\xea\xa4\ +g\xeb\xbdq\xf2\xf1(n\xd0\xf2\xd9\xbc\xf8\x12\xdd\x17\ +\xb0\xffz\xe2\xbe\xc98+\x1a\x09|\xa3L-]B\ +\xfc\xe4\xa2|\x98\xa7.\xcd\xf7\xf1((\xda\x1d9\xbb\ +\xb6'q\xf5\xf3e\x14\x05F]ivu\x11\xce-\ +\x88\xcd\x8fGs\x9b$Ky\xb5Z\x8fA\x04\x85\x81\ +\xf2\xaad<=o\xef\xc0\xfd!\xd2cP{\x9f'\ +\xf1\xe4\x5c!\x11\xbe\xdf\xd0\xe3.\x1dS\x06g\x8a\xa2\ +^\xef{\x89\xd0U\x227\x0e\x03%\x16\x93\xc9\xe3\xcf\ +\x9f\x1f\x8fV\xad\xb3\x22\xec\xde\x19\xaf\xf8\xfa\xcc\x92\x14\ +bZ\xd2?\xac\xaf\xa7\xc9B\x0a\x82\xf2\x00\xcb\x91#\ +\xa3\xb0\xcf_\xf7\xe4\xc2Q\xc9\x94T\xd6<\x19\xbe\x9b\ +~\x5c\x8a\xf2\x05\xa9\xab\x82\xab\x07\xc5\xa1\x16\x1c\x08\xae\ +Q\xaf\xf7\xbe\xde\xb0\x7f~<\xea{J\xe0\xefm\x0b\ +!j\xf5\xb6^o\xbb \xa0N\xa5?f\xad\x12\x0a\ +\xe6\xfb\x02#\xaeK\xf5\x09\x08\xb7\xfd$\xe9\x0c\xd3u\ +\xe2\xf3R\xb8\xbe<\xc8\xa7FO\xa2\xf5\xf3\xce\xd7\x1b\ +_\xef\xfb\xf0\x01\xd2\x1a|\x0c\xa8\xbcp\xbfh_\x97\ +\x09\x19\xa5\xd5\x94\xc1!\x9d\xb8\xdf\xd1\x07N\xfax\xee\ +\x83\xf7\x18\xae\xc7\x19\x038\xa1\xf5,\x9f\xa6^_\xf2\ +\xe2\x8f6\x98\x0c\xa9s\xf5J\xd5F\x82\x5cA\x02c\ ++\x93\xcb\x05\xb1\xbcMPl\xee\xe4J\x9d\x223\xf7\ +z\x02a\xd1*\xd7\x1bo\xef`\x12\xb3\x91#\x0d\x08\ +i\xb1f\xc9\xd7\x99|u\x19\x9a\xc4\x0bC\xe4)\x8f\ +\xb2^*w\xaeW\xc3\xd5\xeb%\xd2\xc3\xd0>l6\ +N\xf1\xed8\xff\xc1\xd3\xaf\xb0\x06\x0a\xf5z\x0c%$\ +}\xc4/\x08)\x8b\xa8\xd6\x99\x8c\xd6\xab\x12\xb9z}\ +\xc0m\xf8\x8e2\xb87PB\xceO\xd3e'e\xd7\ +5\xf3\xe1\xb1\x15\xb1,k\xb5\x12!\x8d\xabu&_\ +\x0f\xa3\xc5\xd5\xeb\xadt\x9a\xd48(\xab\xb4\xa47]\ +\xb7\xf8\x83\xdc\xd0\xd4\xd6\xeb\x81\x15\xddYz\x9c\xa9\xc8\ +T\xe9qb\xc4\xf6\x95\xf0\x9dTs\xeb\xf5\xc0\x8b\xd4\ +\xb8\xc2\xb4)\xb2+\x22\xd0o\xde\xa5\xfa\xb4\xc2\x9b'\ +\x98Re=\x88\x9a\x05\x94q\xe2F\xf4\xce\xb6\xcc\xba\ +\x95\x22\x87\x84\x22&Q\x8a\x12ho\xf0\xf9:\xbd\x0b\ +\xc6\x1d\xbe\xde:&F\x8a\x03\x8c\xe4\xef55\xaeQ\ +\xb3\xf6\xe1\x03f\x82\xb7\xf8\xfb\xday&\x01\xaaw\xcc\ +\xf3\xe3b\xbd\x15\xbdc\xc7\xf7\x8f\xefr}O\x83\xf9\ +\xfd\x8e\xb8~\x14\xca\xc4$E\x1f\xbe\xad\x82\xf2\xca\xb9\ +q\xa7\xef\xa8\x86\x09\xd2\x8bw}\xbey-\xba\xd6\xc1\ +\x93*\xed\xab1\x85\xd6\x0f\x9a\xea\x9421\xf5\x95\xb5\ +\xc2\xe6\xd4\xeeB\x11\x94\x80\x9ajKk\xb9\xac\x027\ +\x95\x08\xb3Y>w\x07\x90\xf1b\xc5c\xa3\xbeo\xc3\ +\x1fv' \xaa\xbc\xebp\x83\xdc\x9a\x07\x92\x82\xa2\x08\ +\x9e;+\x22\x04Qo\xd6\xf0\x09\x88~\x5c\xae\xdd\xac\ +\xa7\xce\xc7\x96\xf1\xba\x0d\xb9\xf8\xf6\xe7\xafHlO\x89\ +\x17\xd0\x94O\x04\xd3\x84:\xb1\x8c\x0a\xc0\x02j\xef\xa0\ +\xea \x88\xae\xbf\x9d\xd8\xdf\xb8\x87/\xb8\x1b\x1b\x17\x8a,.\x86\x22\x05H\x90\ +TnV\x80\xde\xe3\xa0\x90\x9ei\x00\xd2\x12\xc4D\x16\ +?\x08\xe5\xab\x01\xf4x\xde\xb7a\xf3?\xf6t<\x96\ +\xb43%\x95\xcb7f4Z\x91s\x01\x8a:\x98j\ +\xec\x81\x12\xc2Y\x8b\x95G\x7f\xc1\xc5\x04\xe4\x9e\x1e\x09\ +\xa9\xb9vx\xe5\xb9 \xf6u\xb9\xeb\x1aw\x22\xca\x12\ +\x8a\xab\xb1\x0bZ\x94\xa2\xa6\x0f\xdfy{`%mR\ +\xa8\xa0h\x18\xd7~\xe0\xc0\x8e\xa7'\x94\xca^4\xac\ +_\xb9\x04\xa0\x0f\x8e\xda\x145&\x1f\xe7\x99\xb0\x1b\xa1\ +\xa0\xb4h\xe6\xc6\xad\x80\xa6\xba\xa9\xaf\xe5\xd6a\x04\xce\ +\xfe\xa2\x92>=\xf1&\xc2/\xd1\xed\x86\x14\x97 p\ +^\x17\xad\xfd\xea\x0b(\xd3\x89\xebG\xdd\xbe\x1e\x09\x1d\ +\xc6\xcc\x8c'\xa7\x94\x15\x85m\x1b\x86s\xc2\x10\xb8\x12\ +\x94\xbc\xf8\x22EzH\x8e\x0aN\x89\xee\xdeKB\x9a\ +Z\x9d\xff\xad\xb3\xef}|\xb1\xba\x90\x85ta\x06\x15\ +\xcd/f\xe0\xcce&8\xc5\x7fJI\xa4,p\xaa\ +\x0d\x5c\x97l3S\xf4\x9d\xab\x82\x9d\xfc\xfe\xd8\x18\xfd\ +\xbePT\x0d>\xdd\xbc5j\x02\xd5\xe7\xe3T}O\ +\xe7\xc9\xa8\xed~\xd0\x02\x8ep>C\xdc,\xb5&7\ +\x12^\x03\xce\xeb\xf5\x02`D\xf9Re\x8a\x00\x13\xf1\ +\xa0\xebp\xd1<3\x1e\xc9Q\x08\xa9\x95Q\x8b5U\ +\x17\x0a\x19\x15\xa5\xb7\x94\x94\xd480\xd6\xba\x0dyT\ +\x80\xbe/g\x98\x8a\x93@\x92RE\xdf\xf9\xefjI\ +\xa1\xf9\xfc[XxO\x00\xfa\xcc\xd4P\xd4\x85\xf8\x80\ ++\xa9\xf1\x82cgh?\xf6\xf5\xce\xda\xcbf\xf9\x1b\ +\x02t\xf5h\x16\x94\xf41\xd5\xdb\x7f\x1cBj\xfb\x9b\ +\x17\x16N\x87%\xc5vy\x00\x90\xe8(A\x12B)\ +JS\x8c\x13\x81\xe57F\x8d*\xe3K_\x96\xebc\ +&3ez\x89\xb0i\x88G\xbc7B\xaaP\x99\xa2\ +\x1f\x84\x90\xce\xef)\x81\x94B\xeb\xd5\x90\xc6Q2\xe0\ +\x8e\xa3l8$\xb2\xa6\x1a\x7f\x80\xacO\x14\xd2\x7f\xfa\ +\xc63?\x0b\xdfoX\xda\xdd\xd7\xab X\x9b>E\ +\xb7\x1bZeb\x8a\x92\x90>12[\x91\xaaj\xb3\ +\xdd\x1cj\xa1\xa7`\x88\x92y@%\xd4\xed\x96%\x1e\ +\x89\x9ft}\xf2\x8e,\xf9\xab\xc6\x85\x8a\xbf\xa3\xd1(\ +\x9f\x0c\xfc\x12\x0b\xa9o\xd6XX\xf9i\xb6\xa4o\xf9\ +D\x88_6\x0f)p\xf6\xaa\x84\xba\xc8\xcc>!=\ +jN\x89\xb5F\xd3\xd5'}\xaa\xf4\xef\xb4\xf7\x15\x1e\ +\x13\xef\xc4=\xd9lI3\x90\x13\x8d\xae$\xa4_W\ +Q\xaf\x11\xe1\x9b\xaeq47gz\xc5\xbc\xf0\x9e!\ +\x16\x90M\xc0\xd5\xear\xad^42\xf6\x82c=;\ +^^\x0aI\xfbC\x15\xd2\x9dM\xe9\x8cl\x0f`\xdf\ +\x12vN\x18\xd7\x8c{\xa8\x82;k/f\x94pf\ +\xda\xa3\xa3w\xe9\xe8\xde\xbe\x9d\xd2a\xaf\xc4@w\x01\ +\xde\x86\xb5[\x0e\xdfv\x06}\x1e)\x84\xf5\x11\xf0\xa7\ +\xc8\x92\xc2\xd9\xd3\xa5\xae\x1f\xfcR\xeb\xb2\xf2S\xf7\x8c\ +\x18\xa8\xab4\xb5\x94\x09\x96\x09Y5\xe1\xbd\xe8\xfc\xde\xbc\x14@\xfd^D;\xc9p\ +\xc1_Q^\xfb\xdb\xc1P\xbe\x90\x07\xa0/*\xd0\xf5\ +\x13\xa2(\xfd\xfb\x8ei\x8a\xd8\xe9\x1c\x8aT\x88\xf7q\ +\x0e\x87F\xb9\xb7\xe4$\x01\x1b\xc7\xe3\x9d\x01\xa4\xbf\x93\ +\x0c\x01T\x96\x81\xf9\x0c\xd5n\xec\x0bE\x89\x1b\xfe\x96\ +^\xc5\xd0\xc6\x01h\x11\x0a\xe67\xed#!\xe5\xdd\x1d\ +y\xd1)\xc2<\xde\xd6=\x95\xf6i\xbcwWK\xbb\ +OVlC\x17\x16\x16:\xb6\xcb\xce:)5\xe9\x87\ +\xe4x!P-\xd2\x8b\xf4\x0a\xdfe.\xe0\x8fG?\ +\xa5{73J\x91\xac\xa3\xbe\x99\x1a\xcd/D\xc0I\ +\x04\xfaK\x86\x96\x91\xf2k\x9f\x9e$\xac\xf9a\xf8#\ +\xc1\xb8\xa0\x86gj\xf4\xa9\xb5\x05e\x98\x87\xce{\xf8\ +\x8d\x17\xdeY\x16\xf1W(5~1\xe3\x10\x8fu}\ +KU\xce\x84\xf4^\xec\x98w\x13\xf1\x97Kq\xf3\x00\ +y\xe6+\xa3L\xaa\xd1\x0f\xc3\xa5\xc6]\x1f\xbe\xad.\ ++\xef\x81v\xeb#\xeb\xe4~\xe1\xed\x11kzk\xa0\ +&\xddz\xfeE\x89Jj*\x98\x8f\xebD-\xe9\x86\ +\x91n\x98x\x9f||\x1cM\x93\x019\x1e\x15b\xf4\ +\xc97\x85\xa5A\xcdm\xb8U\xc3g\xf0\x815\xb3:\ +\x7f\xb4y9\xf7\x1f\x93\x00|rr0\xc2Y\xd4\x90\ +t\xbbXR\x15\xd2\xde\xdeR\x02=\xe6\xf6\xf2 \x9a\ +\xfb%\x92\xdf\xb3^\xf9\xf4\xe2(M\x9a\x95\xf0\x05\xa2\ +(\x80v\xfe\xa5\x16E\x87VW\x18\xa8C\xcfn?\ +\xf5\xe8\xf9V\xaen\xe1\x0d\xc9v\x12\xd2\x22)\xf17\ +0\xeeMi\xaf,w/>\xbb;y\xe9\xf5\xbbX\ +\xed\x0eLk2\xa1\xef\xbd\xee}\x8f\x8f\x03\xc8~\x03\ +%\xc2\xb1g:*$\x05\x81?\x19K ]\xd9\ +vAJb\xe6\x08F;\xc2G\xb1\xde\xdc\x04PU\ +/\xe3\x90-U\xafT\x5cD\x94\x1b\x15\x22\xa4\x1bv\ +\x96e\x91,5\xd2q\x8f\x12\x1dW\xefXN\x93\xb2\ +\xa8\x93\xa1\xfa'\xa1(\x85z@\xea\xae\xcb\xc402\ +\xea\xcf\xdf\xcc\xcc\xd3Vz\x13\x7fw\x8c\xe0AK\x02\ +\x1a\xedgA\xc2\xb8\xfe\xd9kO\xf9\xfd\x1e\xc6Cw\ +-m\xd9\xf1\xd4\xe2(\xabMR\x87\x86\xb4\xe9\xe8\x03\ +\x90\xdd-Z\xdb\xa8U\xa3\xb3\xd4\x94:\x83\xbf\xc4@\ +\xc9\x8f\x12E\xdfL\x7f\xa5a\x1c\x85\xf4\x0fzM\xb3\ +\xb0\x85`\x7ff9]\x134\xad\x91\xcb\xa3\x85\x07q\ +\xde\xd7\x96->kG\xfd1[\x98(\x13>\x1d\x22\ +-\x07E\x0b\xf2\xa5\x8f\x8d\xc8\xe6\x93b\xa9\xdb?\xb9\ +.\xb0{q'\xe7\x1c\xeb\xda$\xf3\x84\xaa\x8d{\x7f\ +\xfa\x8e\xf3\xb0M\xa0h\x17\xe7\x81\xd3\x8c\x92\xd3^z\ +\xdftJ\x0e\xf1\xe5\x93\xbc\x8c\xe3\xf2\x7f\x11\x94t\x8d\ +~R\xe5\xd2\x9d\x87\xb6\xb7\xa1\xb9\xd1\x95\x81&]\x7f\ +k\x1d4\xf5\xf5zOT\xa8\x15\x00\xf3~\xe8O\xf9\ +O\x06\xde\xc94<1.e|\x98<\xc0\x1d\x87'\ +\x93L\xfe,\xbc\x1f\x80\xe9\xee}AF\xcf\x1d\x0c]\ +\xe12\xce.\x22\xb1d}V\xac\xe2\xae\xa5\x03\xba\x13\ +~b\x5ca\xcf4\xf8\xe8\xc9\xc5\xc9(\xd3\xb4\xb8i\ +r\x16\xe6\xa3g\x1cP\x9d\xc1\x9f\xd3\x91[\xe5\x08\x9e\ +S\xdb\xada9OBj\xc7m\x93\x11\xce\xac\x9b\x14\ +\xbe\xf0]\xd8\x0e\xa8\xee&\xc2\xc4\xdd\xe0\x0d\xdf\xe4\xef\ +\xd2\xf1\xe6\x1e\x09]\xa8}\xde\xc6y\xcdt\x94\xba\x0c\ +Dx\x11Ps\xe50\x14_\xcf1\xa1)\xd7\x88\xa8\ +\xa7'\xfaGm\xbd^\xa7\xd7\xa54\xdfn\xe3\x8b\xfb\ +\xa6#\x86\x98\xa2\xffA)\xaa\xcdD\xad\x1a\x93\xb0\x1e\ +\xa7\x83\x1c\xebe\xb5H\xfd\x91`\xa7D&r\xe6H\ +\xf3\xe6c\xbd{\xee\xd9\xb0v\xffrU\x94\x85\xbb\xe1\ +\x8dP\xb2\x8cr\xe9\xd6\xdaQ\xd3D\x98\x00\xad?\x19\ +J\x0bN6\x18j\xba\x14\x04\x04\x15\x96\xf4\x92Q:\ +\xa0?\xfcGv\xdf\xe4\xc8x6e\xb4\xf6w\x95\xa0\ +\xe3M\x86~\x18b\xfa\xb3\x22\xf0\xf4\x96\xf7\xc0\x88Q\ +\x90K\x1f\x93\x15\xc5]\xe3\xb6\xb6\xac\x09R\x1c\xb8\x83\ +o\xb2v4\xce>Pj\xe2\x11T\xb5\x8d\xae\x1d\xda\ +\x94BL-\xda\x22Z\xd2\x1b&\x05\x0dE\x9aZ\xa8\ +\x8d\x12ci\x19O\xab\xc2D\xe8d\xd8\xefI\xe9o\ +\x22\xb4\xe7,\x9dk*\xe3\xf20\x05\xf5\xb9\xa0,\xdd\ +\x1d\xde\x5c\xb8S\xb0\xd0z{\x86Q-=\x90z\x17\ +\xea\xa2'\xd0\xd3\xc7O^H\x7f\x8fB\xe7\x91\xa6!\ +\xd0X\x80\xa1vT~\xfe\xcc\x1d\x9ar\xfd1F\x14\ +p\xa0O^\xebS,\xc2~\x7fA\x0d\x0b\xe9\x9d\xa7\ +\xacz\xb3\xb0\x9eP\xda\xcb\x89\x94\xf5e\xe7\xa1\x16m\ +~\xe9\xf2\xf5\xf0\x9d\x9e\xa2\xb6qXW\xa5\xa3\xbc\xd1\ +\xab\x83$\xf2\xd5\x8c\xd4\x8fZ\x86\xf3\xf7M;\xdaw\ +go\x0c^P\xd3\xdc\xde\xee\xf2\xcd\xfc\xe99\x8f\xbc\ +b\xdc\xcb\x05\xa0N\xed\x13u\xa2\xa0d\xd7M\x84\x08\ +C\xbd%u\xd7\xd1\xa1#\x97\xa73\xfa\xce\xd9\xaf1\ +)\xc2IK\xeb\x13\xd03\xac\xe8\x1d\xef\xf0\xa0\xb2\xb2\ +u\x82*\xf9K_\x86\xad0\xafrY\x5c\xd5|\x93\ +xj\xd0s\xdf\xe1\xe5\x9d\x0c\xd4\xf6\xe8\xf8kR\x95\ +\xfdC{\xe4\x92\x1eGQ\x1f5\xc3\xd7WN\xe5\x9b\ +\x09\x08\xf3\xb7\xac\xff\x830R\xc2(Ds^Fq\ +T\xdd]J\xe5n\xee\xa7\xe1]\xa8\xe2\xf4\xd7z\xce\ +/5\xd8\x9bg)\xd3\xfc\xec\x1b\xd6\x9f\xb5cy:\ +\x1e\xa4\xb3D\xee\xff7v6\xad\xb6\x1dE\x18\xbe\xd1\ +\xabk\x7f\xac\xbd\xd6Y\xd7\xbb\xb9\xde\x13P\x07^A\ +I@t 8\x88\xa0\x01\x11'\x89\xa0D\xf1k\x92\ + \x19)\x82\x1fq`\x06\x8e\x1c8\xf0'8S4\ +\x198\x0a\xfe\x80\x8c\xfc\x05\x01A2P\xfc\x15\xe6t\ +\xd7^OW\xbfUk\xdf>{\x9fs\x86EwW\ +u}\xbdo\x09\xa4mp\x16\xa0\x13\xd41\x16\xe8-\ +\x85\x1eY\x89\x00 \xd0B\x9f\x14\xdd\xb0J\xfb\xe0A\ +\x15\x92\xd9\x12\x09Y\x85N\x17\x98a,\xe0\xf4\xe5\xe4\ +[\x1b\xdaM\xb2\xa6\xbd\xddgslG\x91\x92\x9d\xad\ ++\x18\x81Q\x8f\x5c\xb0\xcb\xa3]Q+\xd5\x83\x15\xd1\ +\x14\x99B\xee4\x91\xabE[(\xfe\xa0\xa1;\xb2*\ +\x99\x8eHk\xa2)\xf5,\xc4?\xf6\x90\xf6r*U\ +\x85\xe2\xebc\x92\x1ae\xc9\xeds\xf8^\xcc*\x9a\x9a\ +\xa6^\xe3WL\xd3,*\x05\xdaN\xba\x1d\xb9\xa3D\ +\xf5H\xca\x00\xb9u\xba!b\x0a\x17\x04\xf6\x89{\xca\ +f\xfa\x99\x0dLB\xe8\xb7\x14n\x0d\x01\xb0\xb2\x9c\xa0\ +\xc2\x969V\x08\x86i\x927\xa3\x0eY_>\x8a[\ +\x07\xd1\x14\xb2\xfe\x84,\x00fG\xb1O\xf2\xd6w\xef\ +'\x0d\xe3\x91>y\x81\xb9\xa1J\xe6L\x02B\x19\x13\ +\xf9F\xdc\x8e\x8a\x05\x0f\xcd\x13rr\xf8\xc4v\x81\xcd\ +G\xab\xc8<9\xfe\xeea\x96\xfc\x83(\xbc\x8c=\x92\ +\xc2\x88\xea\x13\xd2\x16}/\xa2\x0a\xda\xb2\x01\x09\xc6~\ +\x09\x18!! \x05\xd5\xa0;\x0a[A\xafM}\x8e\ +\xcc\xda\x85\xa1#\xcb\xfc<0w\xfcv\xfeh\xc3\x94\ +\x99\xf2\x8f\xaa\xd6sI\xdd5E\x5c\xb7VI\x19$\ +\xd5\x8e\xe6\x02\xc2\xca\x93\xaf\x0e)\x89\x07\xf5\xf3\xb2\x85\ +\xa0'T\x1e\x07_\xa9\x9cM\x99\xd8\xd1\x9e\x97\x8a\xa3\ +Wb*\xc0\xe0\x8c9t\xea\xbeI\x94\xaa>\x89\xaf\ +\x84\xea\xcc\x86\x0a\x1c0]*\x92\x0e\x1eg\x8b!\x95\ +g)\x99\x81\x91o\xe9u|\xfd\x8e\xc9\x0d2O\x06\ +\xe4\xb2\xea\xfc\x80\xb8B\x8c\xcd>\x22\xaaR\x92\x09>\ +,\xc7\xd7\x17a/\x9by\x10\xdea\xb0\xa1)\xdf\x93\ +\xba\xa4K\x8b\x15\x22`BJ\xa1D\xbf\x8e\xaf\xb7\xec\ +\xbd\x94l\xab\x944\xe4\x061\x13\xa0\xf0\xee\x8a\x22/\ +\x964\xe1\x1f\xe5\xae.\x80\xacC|=hK\xc9\xe9\ +\x15M2\xc3\x1f<\xf5\xe0\xea\x95\xe8\xcbe\x9c\xc5:\ +!*\x1f\xccS\x8c\xaf'\x00eKWd5X\x11\ +\xe9\x1b\x1f\x1a\xc5O\xa3\x915\x5c\xe2\x9b\xf2\x8fz\xc6\ +\x02\xc4T0cg\x9fz\xac\xc8\x18\xa2\x97\xb1\xa3\x91\ +*\xa1H\xa2\xf7\x19\xffh\x82\xaf\xa7\x810\xec\x800\ +]2\xc8\xe51G\xad#5\x0bm\xf2\xa0p0\x22\ +\xc2?\xba\x85\xaf\xe7\x97\xb3\xa3~\xbe\x80\xe8\x12\xd8E\ +\xec\xa8\xc8\x88}\x8a\x9d<\x9f\xd8\xe9vt\x0b_/\ +l\xd3\x15\xc6\xc6\xfdTmRC\xaaS\xa4p\xf2R\ +\xfeQ\xdd\xd1\xd8<\x91v:\xe8k\x0f\x7f\xbfZ'\ +\xaf\xee\xd0\xbf,(?1\xd36\xff\xa82h\xddd\ +\xf8z5MQ]\ +>e\xf8\xfa\xb0\xcf\xf5h\xc2\xa2L\x89&\x11\xd6\xcb\ +\x02_\x1f\xb3b\x13\xdbk\xda1\xc7\xd7kR\x07Z\ +\x85\xf5+\x03\x8dE\xe7\xf5aj\xe4e\x09m?\x8b\ +Dn\x88\xaf\x07n\x8b\x88\xf6?l\x99naAu\ +\xe4\x15\x0a\xa5\x15{\xf6\x14\x9ay\xc9=m\xe1\xeb\x19\ +\x84P\x17G\x0f[&yq\x0d\xf0\x9a%I\x12\xf4\ +\x091\x91\xb6\x1d\xc2\xb9\x8d\xafO\xde\xfa1e(\xaa\ +\x82!j\x08\x05\xef\x08\x9f\x9e\x8e\x7f\xf4\xf6*\xbe>\ +\x19\x10\x0d\xe7\xb4.\x94I=|\x1d\xc1\xfb\x94\xfc\xa3\ +\xd7\xf1\xf5\x889\xd6\x0f\x14\xc9\x86\x1b\x91\xe5gre\ +D\xbeZoP\xfeQ\x84N\xf1\xf5\x07\x18\xb4\x5c\x80\ +g\xd2\x9a\x88\xfeq\xa2\x1a\xe2B\xd1`cy\x9b\xae\ +\xf1\x8f\xe6P6*\xe0F\xa8\x81\xa4\xe8\xfeQ\xe8\x0a\ +\xe4}\x92\xf8\x0ec\xefr\xce\xd7\xf8G)1&\xf8\ +z&3\xf9\xa8\xde\xe6\xdc1MJ\xa7\xd7c\xa2\xc2\ +\xe5\xa7\xb4\xd8\x7f9\xff(\xc1\x1d\x06\x9f\x00\x84\x1dE\ +\xd4Q \xeb^H\xd8\x1c\xc5\x8brB\xfaQ\xd6)\ +\xffh\xee\xe6\xb1\xe0$\xdb\xa3\xf5XSb&-\x85\ +\xeap\xcbQ\xc3z\xe4\xcc8r#\xfe\xd1\x80\x00\xa2\ +\xdaQ\xdbS\x84\x84{\xd2\xb8J\xdc\x08V-\x88\xe6\ +G\x8fB\xd9R\xbe\xa7\x04\x82q\xea\xb6s\xbf\x87\xfb\ +\xe3\xd0\xe7ur\x98P\xfd\x10\x86(S\x89g\xcf\x0a\ +\x1f\xfb\x96Hi\x03_\x7f\x01\xd8\x83\x13A\xcc\xe6\xd8\ +\xa34\xd9\x80\xb4\x81\x09\xf5\xe2\xf2\x1b\x09\x95\x7fT\xf1\ +\xf5j\xf2\xed\xe8\xfb\xb3\xf7\x13\x9a\xb4pGX/\xe6\ +\xc9\xf4(\xa8\xdf\x0cyc&Q\xa8\x89\x99\xe2\xeb\xf7\ +\xba\x9d\x8c\xba\xd3\x01\xd1\xael\x0b\xc0\x1at=\xd1\x9d\ +\xbb\x00\xd2I\x18\xbcL71\xbe\x1e\xa7D\xf6\x15j\ +Oe+\xc0w\xa2=\xcbg\x9c9\xf8\x84\xe1-\xb9\ +\xa3\xf8yb\xf3\xd9R?n;\x87\xaf2~S\xed\ +\xe8\xdc\xcc\x10\xa3k<\x0dEXO\x8d\xaf\x97\xe7\xc9\ +\xc4\xcc \xc1\xe5\xebX\xbe&G\xde\xbf\xb8\xaeq\xcd\ +8s\xec\xdb\x06\x1f,\xf8z\xf2\x92%s#\x8d\x8f\ +\x9d\xa4EF\xb6\xd2u\xb6\xb7\xf9\xfb\xb9O<\xf1A\ +\x9f2\xa7d\xa7\xf8\xfaN\x9bP\xa6\xf0\x8a2\xb1\x85\ +\xc1|\xed\x1duS\x06\xe2a-\xf6\xc1\xc7\x07x%\ +\x9eS\xd4\xf3\xc4\x8e:\xe6\xbc`\x98\xb1\x9aQt\xa9\ +.,h\xc7DH\x10\x9a\xb0\xb7\xe7\xf8zt\x1e\xfb\ +$\x05\x1c\xa4\x15\xdf\xc4\x98\x08i|r\xbc\xd8\x02\x12\ +B\xcae\x91(\xf4\x14Fvr\xf4\x08\x8b\x98\xa2\xf6\ +\xd8Q\x98TXE\xe3}\x0e\x7fP\xeaQ\xfb/\xc3\ +\x8a\xb0\xc0\xd7\xfbX\x04\xd3\xc4\x0f\x02s\xf8u+\xe1\ +y4\xbdr|\x15NFyE\xa91\x0b\x83\xd6M\ +\x8c\xaf\xc7:\x89\xa7\xc7\xd1\x87s\xee\xca\x9ad\x06\x06\ +~\xbe\xcc\xb5U\xe0U\x0e\xb7D\xa3(\xd6\xb3\xadD\ +v\xeb\x8f\xef\x19w\xf3\x99\xb8\xa0\xee\x09u\x1e\xbe\xef\ +s%\x99\x9b\xf3\xe1g\xf8\xfah+\x19\x1a)\xec\xed\ +-o\x9e\xce5uC\x0e\xab\xcc\x01\xf1l\x92\xc3\xdf\ +\xc6\xd7{\x07\x1f\x0b\xda\x19'd\x857\xcf\xcf<\xe3\ +\xf0\xcdi\xae`;\xa5\xc3\xc7\xde\xb36\xf0\xf5\xf6\xe5\ +\xec\xddJ\x95\x1ee\x12\x97d\xb6\xdf\x0b?\xb3(\x93\ +}\xc8\xe2g|\xf8\x8a\xafW\x7ftd_Q\xfb\x89\ +i\xeb\x8d_\xca \x0c.)\xf1\xb2\x9a'\x0dB\xf3\ +\xf9\xf5\xdb\xf8\xfa\x91\xbe\xa7\xc2\x8f\xab\xed\xa3\x13u\x11\ +\xb6\xd5]RW\xb3KN^\xfa\xc9n%\xae\x8f\xf1\ +\xf5\xda\xaa\x01\xf1l\xbf\x9e\xb0\x8e\xc8IV?l\x9d:8O(\ +\xda\xef\x82\x11\x92\xb83\x9d%\x12\x87jm9\x9f_\ +\xcf\xe9\x87\x992$\x0d\x0aw\xae\xedi\xf21\xe8R\ +#'\xd0\xe0\x9a\xd0c?}[\x89\xcc\xaf7\x01\xa3\ +\x1d\x1d\x11\xf0xdG\xb5\x7f\x94\x87\x14\x8b\x8f\xb0\xbe\ +UCy\x1d\xa9\x8cd|\xf8\xfa\xd8\xdbWc\xbc\xe3\ +1\xf6H\x10Q\x03;\x90WF\xfc\x81\x83/\xea\xf4\ +\xb4\xf5z\x8fa\xf5{j\xed:\x91\x8cHj/\xbe\ +?z\x86\xb2\xb1\xa7\xf3\x90\x95\xc1\x89\x9c\xf2z\xbd\x05\ +w\xa2\xf3H{\xf4\xbd:Zg\xb2+\xca\xd1\x0bX\ +\x04\x84\xd8\x80\x94\x00X\xd1'f\x83\x07\xd3%\x08\x98\ +\xa5\x99\xc8>\xcc\xb9\x0b\xdb\xc9\xc6\x15f-4\xf3\x94\ +\xc3\xb2\xc7\xe9\xea\xd1kML\x22P\x7f\x09\xdcc\x0f\ +\xe6\xc6\x8e\xbd\xc8\xaa;\xca\xe3\x04~\x99R\x18\xe9\x87\ +d\xd8\x19\xf5z\xbc<\x1a\xc7\x15\xdb s\xeeH\x90\ +\x18$\xbc'\xab0\xd3\x04\x9dJlE\xf1\xa1\x94\xfe\ +C\xd1\xb6\x80X=N\x88\xa4S>\x97\xedR\x0b\x99\ +x\x9a\xc0X\xf7uP\x11\x96;*\xe5\x1b\x89\x97p\ +K\xe4\xec\xedWkE\x11\xd5\xde\xf9\x89pi\x05\x85\ +\x03\x0ed\x8e\xd0\x1c\xbe\xf5\x18|\x85\xad7{\x8a\xd2\ +gu&\x9d\x1b\xa8o=\xe6t\xc2>aF\xcb\xd7\ +\xfcf\x9dr\xc7\x9e\xea\xfcz\xa4$X\x0a\x10w\xa3\ +&u\x1a\xcc\xdd\xc0\xae\xe2\xe8M\xbd\x943\xe91\x9d\ +l\xa9\xe0\x0b\xc1\xd7\xfb\x85\xb9/)\x09\xd6\x882\xa5\ +\x13\xee|\xbc<\xf1B1\xdb2\xe6\x80x6h*\ +\xda\xe2\xc3\x17\x0aJ\xcd\xe1s\xf4\xbd\x8f7\xc1:\x8c\ +\xb1\x0f\xa1l\xb6\xb9q\x04\xba(\xbe>\x8c\xeb1\xf7\ +\x87\xd0q\x8e\xb5~j\xae\xa8\x09\x8a:\xa1\xf5\xeb\x0f\ +\x88`\xcd\x8d\xcb\x12\x12J!\xa7A\xf3G7\x05A\ +\x94\xde\xc4,\xa22\x5c\xa2\x88\xeaAw\xe4G\xa3m\ +\x155\xca\xd17\x88\x9b]\x00$\xf5\xe5\xfa\xfa\xb1\x93\ +\x9f,\x1c\xd1\xa2\xedB\xe1N\xd3\xa32\xe02\xe7\xc8\ +E\xf1\x99\xcb&\xba\xe4\x8dS+.\xbb9Q\xb05\ +9\xa9\xd7\x03\xb2WeR1\xf1\x9e\xc2\xa2\x18\xcbg\ +\x1d\xe3z=\x83\x10lC\xcdq\x9e\x92'\x94\x08T\ +#&V\xc6\x87o\x1f\xea\xa1~\x80\x1c\xb2*\xe1\xb4\ +\xb2\xa9\x90|B\xe5\xbdS\xa2K\x04%S\xa2\xe6\x89\ +\x8am\x14\x8c`\xf1\x11\x16@\xc3\x1b\x9f}\xf2\xe4\x1b\ +\xf7\xab\x9c\xb0hE=:\x14\xc5\x00^\xc57\x14\xc0\ +\xc0\xa9\x8fB\x9c\xa8r\xfeH(\xe3\xce\xee\xdf+\xeb\ +/\xc5\x1d-\x1fw\xf4\xdf|\xe9\xcd\x97\x8b&\xcd\x92\ +\x1c\x97\xa8\xbe\xc3\xd7K6\x0fq#\x98\x90?\xf8\xde\ +\xd5\x1b\xc6\xdf\xdf\xab\xeb#\xa3yyET\x9b\x81\xf1\ +|a\x04\xfcw\xa1ML0\xd6\xd8\xd2~\xc5|\xf8\ +v\xe4\xf6M\xeb\xf5\x9a\xd1\xfb\xc5\x85\xdd\xf1QQ%\ +\xbf\xa3\xcfT\x92\xe1\x93\xd9NS\xa8nW\xd3\x82\xd8\ +!c\x9c\x0eq-\xbe^\xbf\x8a\xca%\xfd\xda\xf7\xdf\ +\xfat\x1d\xb03\xc8\xcc\xab\x1f\xdd3f\xf76f\x1a\ +\xe2\xa2\xedv\x92L\x93\x0f\xb6\x0eT\xee\xc883<\ +\xd0\xf9\xf8\x87\x8f\xc2\xe3l\x9ad\x9d/\xff\xaa\xdc\x85\ +g\xd7\xfb\xa0oh$\xe8\xf5\xf9\xf5\xfa\xdc\xfb\x1c>\ +'\x8f\xc1\xff\xdb\x85l|\xe8\x02\xbc\x8f\x17R\xa3B\ +?]X2\x87^F\x9f+a]\x9f_\xdf\xc7\xf5\ +Z\x10CLk)\x18+\xa7\xeb\xeb\xc7\xa2K\xbeW\ +\xe3\xfe\x97\xff\xfcp7\xd3\x03\xa1\xfe}\x9e\x1f\xdd\x9e\ +_\xaf:/\xf5z\xddQ#K\x9elO{\xa3?\ +\xcf\x02i\xd1\x0c\xc4\xd6[\x0fl\xfd\xee\xcblK\x87\ +g\xb2#g(\xe3\xc8\xc6\xae\xa8\xb0\xdf\x14\x82\xad\x22\ +\xa4\xd8\xd2\xc5fI-\xf6\x9aF1\x13\x9fVPj\ +\x8c\xfb\xf2)\x7f\xee\xe4\xdd\xfb>2\xa4\xb5\xe4\xbd\x10\ +\xaa\xac\xec\x1fw\x97\xf4\x1f\xe7n\x86\x18\x84D\x8c\xeb\ +\xd0\xb6\x12\xe2z\x96\x8bB)1\xc2FF\x0d\x5c;\ +\x08\x99n\xa9G?}\xa8\xb0\xeb\xedd\xac)rV\ +\x92\x5cb\x11\xc5\xdf\x5c-\xda\xf24a\xa3\x92D.\ +\x1b\xcb*\xde\xd3{eD\xcb\xa9\xa4\xca\xb1\xa4\xf3\xfa\ +\xb7\xca\xc9\x0c\xce\x84\xa4FG!\xa8a\x0a\xbb\x9e\xf4\ +\xfdd\x1d\x1b\x96\xb7i\xfa_\x99b\xf1\xe4}\x0bF\ +\xeaZ,\x14\x99~\xf7\xb32\x5c\xc2\xec=;J\xa0\ +\x1c+\x13[\xeaa\x8c\xccB\xd0\xc8>\xecr\xc6\xd1\ +{\xc6^\xd2?\xedp\x9d\xcb\x9a?\xfc\xe2\x07\xd4\xba\ +_\xda\x17:J\xf6\xd3a\xc3B`\x0bP\xb6\xc8\xe0\ +\x87x&\xd7]\xd2cX\x87\xea6\x7f\xe2S\xc6\xa0\ +\xfb\xa83\xa4\x7f\xac\xcc\xfd\xfb\x9a\xc5\xcd\xd1\x0dQ\x89\ +1\xe9q\xb6\xedT<\x13G\xaf\x1c\x10\x83Ew\xd3\ +\x1b\x95\xa3\xff\xbb\x8f\x07?\x16\xbe\xcc\xef\xf8\xeby\xb4\ +K\xea]\x12\x0fc\xd3;\x1aa\xeb\x09\xeb8zi\ +\xd4\x22r\x12$\xdb\x1f\x0a\xa7\xfc\xe7\xce7\x93w\xf2\ +_.\x9c\xfe\x0f\xe7\xcb\xd2p$b,@\xeb\x91T\ +\x19]\xb3\x0e|\x5c=\xdfNP\xc2\xd1\xc2Q\xfb\xda\ +\xc3]Q%\xdc\x92\xca\xe3\xff\xea\x83\x8b\x90rI\x1b\ +\xcaD\x0dEX2\x9aIk\xa1\xf4\xe1\xfbl3\xe2\ +\x16\x8b\xf4v\x11\xf4\xd0E\xa1su\x03\xce\x87\x99-\ +\x1d\xb6\xc8_4\xb8\xf3;j\xd4/\x1c\xbd\x80\xaf\x8e\ +a\x9f\xc6\xb0\xde\xd3\xf7\xeaso.>\xeb\xbfwc\ +u\xcf\xf64\x95/B:\x9cH\x8c\xb9\xe3\xe8\xf7\x9e\ +\x9d\xe8py\x9a\xc8\x8b\x96\xdf\x9aqF\xd4:\x81\xb1\ +>\xf7\xc0\x05\xa6\x9a\xd0\xf9J\x19\xa5\xd0\xdc\xd09v\ +Kx\x9b\xf0\x9e\xa2T\x89\xdbN\x09\xf0\xa9\xd7\xdb\xff\ +\xca\xe8;\xbdy\xa7Lg\xfcQcx{\xf1\x8e\x9d\ +\xbc\xb9\xa2\xb3\xc4K\xe8|^b\x84\x9e\xc8T\x89\x1e\ +g(J\xbc\xc6{\xa7\x84\x01r\xd3?\xabO\xda\xb7\ +=\xbdo\xf3O\xea\xc1\x9b\xa0,_m\xd0\xe0NZ\ +_\xaa\xab'Xp\x8c\xfeQ\xf3\xa3S[i\x9a\xbe\ +^/iu\x9dy\xeb\x9f\xfb\x80\x10\xf4<\xb6G\xef\ +\x02;\xef\xe0\xe7]:\x18'%\xa6RLS\x92\xc7\ +\xb5\xee,\x0b\x9c::\xd7\xe7\xb8\xa2(SgJ\x13\ +V\x8d8\xe1\x0c\xa8mo\xb2\x82\x07\xf6 \xeb\x84\xf0\ +\xa9\xf8\xa4\xff9\xfb\xdcx\x09D_{\xb0\x8e\xe1d\ +C\x111\x88En]c\x01bbI\xc3w\xc9\x1e\ +#\xcb\xe1S_\x1e\xec\xf0\xad$\xfa\xf7b1w\x1d\ +y\xda\xed/\xdf9\xefm\x0c's%p\xee\xedw\ +\xc6?\x9a\x00\xafv\xa0m%\xe5\xcc~v\x8f\x93\xd9\ +\xa7\xe1\xa5\x8b\xa0\x1dd\xe0tS\xe0B\xb6\xe2\x17\x94\ +\xd3\xef\x94\x09\xf1r|=\xe6\x9e\xc9\x81\x81\xcd\xb7\xce\ +\xac\x17\x8aO\xf2\xd6\xe3c\xc7\xe7Ye4\xad\xc7<\ +!c\x18,\xd3D\x88\xa8\xbcL\xda\xe3<\x12\xd7\xdb\ +\xa0}\xafI@\xee\xc6{\xd5yz\xe8O\x9e\xd9\xbb\ +h}\xca\xe6\xab]\xe3\x91\x12\x01\x10\x91\xfbY\xe4\xc5\ +\xbf\xeb\x14\xca\x10\x0d\x95\xe9\xf9\xf1\x091\xdd\x00\x14\xc6\ +\xad\x0b\x9e\x09\xac\x88\x94oB\x1c#\x95[\xcd\xe4\xea\ +\x9c;\x22&\xb3\xa6\xef\xde\xc9\xf9\xf3\x8f\xb5\xa0\x01;\ +\xfa\x22\xe7\xe2\xcdS\xd8\x98)\xa3\x10\x0e]xG\x8f\ +\x8eC\x83\x8f\x1a\x8bP\x11\xdd\xad\x95\x06\xab.?\xff\ +\xabw^\x7ft\x1aFo\x9c\x96\x15ze\x82r\xf2\ +.T\x0e\xe3z8(\x95\x08\xc06\xd3\x07#\x00\xd9\ +4R\xa6\xddq\xa8&\x8b\xe5\xc0\x0d\xee\x8e\xca\x0a\xac\ +\x93\xd9QL)\x09|\x84\xedr\xf7\xc0Y\xec\x8f\x0a\ +\x0a\xee\x86-\xf5\x09\x1d\xf6\x940Tw\xd5\x1b|\x1d\ +\x17J\x0c\x9a\x06\x22\xf6\xc3;\xca\xd1+n}l\xd1\ +\x22\xeb-]\xea\xd9;\xfaQ\xa9\xd6/\xb1y\x02v\ +\xb7\x07\x0d\x8e\xa4\x0e\xd3@\xcb\x9b\x13uj\xfat\x82\ ++\xca\x80\x1e=\xfag\xb5\x01f\x1bik\xf0zS\ +'\x0f_\x1d1S1&\x18\xb6\xa7\xa0{\x14\xad/\ +;Z\xbe\xea8\xa3\xf2\x89S\xa2\xe9\x92\xbd<\xa1\xf8\ +\xf9us\xa5h;\xd5s\xa6 \xde\xc2\xae0\xf9\xb6\ +\xa7\xbc\xf5\xe26+\xab\x06\xe3\x8c}Xo\x1a\x9f\xb4\ +\xbe\xf8=\xa5\x1d\x9b6-\xf4I\x86\x98\xdb\x9e\xb2\xa5\ +Q~T\xe3\xfa(\xf5D5L\xc0\xb6\x88\xaa\x0cZ\ +\x0e\x22\x16\x15\xeb\xd9\xd0\xbc^\xaf\x95p\x85\xadcH\ +=\xf0\xea\xa0\x05F\xc5[N\xbc\xa0@\x9aZz\xaa\ +u4\xd7V\xbd\x9eN\xa2%\x05\x0c($X\x8b7\ +\x98R\x9c\xbcv\x01\xbd\x91FB\xd4\x09|\xbdlk\ +\x95\x8f\x0b\xa0Cz4K\xe2\xc9\x15Px\xb5O\x8d\ +\xe5t\xddy2F\x0a\xdfi\xc8\xea\xf5KR\x0e\xb5\ +\xb7>\xc5\xd7\xb3\xa91\xbe^\x82&\x85\x8a\xe0\x93\x98\ +\xa86M&dU\x91,.;\xaa\x16\x9f\x17Jc\ +z\xad\xd7\xab\xac\xd0\xd5\xe8So\xea\x04.T\x18J\ +6\xfd\xd1|~\xbd\xc2W;\x88uD\xf9\xd3\x1e\xbc\ +\x1c>\xa8\x9b\xd9\x89\xa9Yg\xbd\xa3X(\xc5\xd7+\ +\xa3J\x06\xbbc+Q%~\xd1\xaa\xe1\xe1\xd5\x82g\ +\xca\xb0\x22\x87x\x11\xd9\x13/k+\xb6\x89\xaa-\xce\ +\xd0=\x89)u\x973\xc63Qc\xee\xb2y's\ +\xa0v\xd1\xfcz\xd4\x9e\x0d\x150\xb8\x13\x11([\xf0\ +2\x0d4\x8dg\xe6\x9e\xb7~\xdb)!IJ\x17a\ +Z\xaf\xf7\x0b)\x95\xe7KG\xca\x00i\xda\x86\x0c\x10\ +.\xc7S\xd9\x0e\x1a\x86j\xbd^z\xdb1P\xad\x94\ +\xd0\xcc\xb7\xf73\xae\xd7\x9b\x90Z\x15\xf1\xf5Z\xc13\ +\xe9V\x86P[\xb8\x1f\xc8\x93\xcb\x0d\xcd@\x18\xca\xec\ +\xa9\x99\x12\x13\xf3\xe6:\xbe\x9e\xcef\x14_-i\xf6\ +~\xfa6|\xeb\xc3\x8f\xf0L\xf4@,\x92\xcdS\xcc\ +:\xa0\x16\x89B\x15\xcd\xc2\xffz\xf4Un|\xbc\x22\ +\x9d\xd6\xeb\xf3\xfc\xa8\x92P\x9e\xbc\xac\xf6\x89\xbc\x12W\ +\xaf\xd7Wi\x90\x93w\x03&\x1c\x07a\xf9r\xeci\ +\x10*\x13\xaf\xd0\x22\xf1\x9e\xd0&\x93P\x8f\x7f2\x0f\ +\xdf>\xf6W\xa7\x9de\xe4\xed\xa8R\xde\x9b\x97\x95\x18\ +\x0fW\xfa\xdd\xd4\x1feO\xd9N?R\xc6\xab\x92\xd0\ +\x7f\xc4\xaddn\xb0)\x87\xce\x0c\x94\x80$\x17\xcb\xe4\ +\xed\x13\xb8P;\xf7\xf6\xfc\x17\x99q\x88\x1d\x8d\xb8\x15\ +\xb2\xc6\x02\xe5\x7f\x00\xc6\xe8)H\xf1\x9eBZ\x8d\x96\ +\xcf\x95=EXH\xd1{;\x0aT@o(d\xbe\ +\x1c\xb9\xbcN8%\xa3\x00\xc4\xec/Bv\xfe\xd3\x06\ +':$\x94\xc2\x9d\x16\xad~\x9c1\x22\xea\xd1c\xee\ +\x13\xb2/\xc7\x8d\x8cN\xc5\xbc\xe8\xc3,\x08\xb1\xedY\ +\x8c\x88\xa9\x96t\xe7aB\xa0\x18\xd9J\x99\xc0\xaa<\ +\xe3\xa3\x03[z\x9e\x12b\x11\xecS8\xa9\xe5\xffG\ +\x8a\xa8\x96\xa8Z\x04\xd8\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00\x06S\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ +\x00\x00\x02\xebPLTE\x00\x00\x00\xff\x00\x00\xff\xff\ +\xff\xff\xff\xff\xbf\x00\x00\xff\xff\xff\x99\x00\x00\xff\xff\xff\ +\x9f\x00\x00\xaa\x00\x00\xb2\x00\x00\xff\xff\xff\xb9\x00\x00\xff\ +\xff\xff\xaa\x00\x00\xff\xff\xff\xb0\x00\x00\xb6\x12\x12\xff\xff\ +\xff\xaa\x00\x00\xae\x00\x00\xff\xff\xff\xff\xff\xff\xaa\x00\x00\ +\xff\xff\xff\xad\x00\x00\xb3\x00\x00\xff\xff\xff\xad\x00\x00\xff\ +\xff\xff\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +\xff\xac\x00\x00\xb0\x00\x00\xc4GG\xff\xff\xff\xff\xff\xff\ +\xad\x00\x00\xaf\x00\x00\xb1\x00\x00\xff\xff\xff\xff\xff\xff\xae\ +\x00\x00\xff\xff\xff\xae\x00\x00\xff\xff\xff\xae\x00\x00\xf2\xd5\ +\xd5\xff\xff\xff\xff\xff\xff\xbf88\xad\x00\x00\xff\xff\xff\ +\xff\xff\xff\xff\xff\xff\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xaf\ +\x00\x00\xb0\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xae\x00\ +\x00\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +\xae\x00\x00\xaf\x00\x00\xff\xff\xff\xae\x00\x00\xd1pp\xae\ +\x00\x00\xae\x02\x02\xaf\x00\x00\xff\xff\xff\xb0\x00\x00\xff\xff\ +\xff\xda\x8c\x8c\xae\x00\x00\xff\xff\xff\xaf\x00\x00\xff\xff\xff\ +\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xae\x00\x00\xff\ +\xff\xff\xd3uu\xaf\x00\x00\xc9QQ\xae\x00\x00\xf4\xdc\ +\xdc\xff\xff\xff\xaf\x00\x00\xae\x00\x00\xff\xff\xff\xae\x00\x00\ +\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe6\xb2\xb2\xff\ +\xff\xff\xae\x00\x00\xff\xff\xff\xaf\x00\x00\xaf\x00\x00\xae\x00\ +\x00\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd2qq\ +\xaf\x00\x00\xff\xff\xff\xba''\xae\x00\x00\xaf\x00\x00\xfa\ +\xf4\xf4\xd9\x87\x87\xff\xff\xff\xff\xff\xff\xba$$\xff\xff\ +\xff\xb8\x1f\x1f\xff\xff\xff\xf3\xd9\xd9\xff\xff\xff\xb7\x1a\x1a\ +\xae\x00\x00\xae\x00\x00\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xae\ +\x00\x00\xaf\x00\x00\xcc\x5c\x5c\xff\xff\xff\xb7\x1b\x1b\xb2\x0a\ +\x0a\xaf\x03\x03\xae\x00\x00\xff\xff\xff\xff\xff\xff\xaf\x02\x02\ +\xff\xff\xff\xb0\x02\x02\xff\xff\xff\xff\xff\xff\xcdcc\xaf\ +\x00\x00\xaf\x01\x01\xff\xff\xff\xaf\x00\x00\xb1\x08\x08\xae\x00\ +\x00\xff\xff\xff\xd1mm\xaf\x00\x00\xb4\x10\x10\xe6\xae\xae\ +\xae\x00\x00\xaf\x00\x00\xff\xff\xff\xff\xff\xff\xea\xbd\xbd\xfb\ +\xf4\xf4\xae\x00\x00\xaf\x00\x00\xba\x22\x22\xeb\xc1\xc1\xff\xff\ +\xff\xcbZZ\xda\x8b\x8b\xff\xff\xff\xaf\x00\x00\xff\xff\xff\ +\xba\x22\x22\xaf\x01\x01\xbf22\xc6HH\xe8\xb7\xb7\xf8\ +\xea\xea\xfa\xf0\xf0\xfb\xf2\xf2\xff\xfe\xfe\xb0\x02\x02\xc7L\ +L\xb7\x1a\x1a\xb0\x04\x04\xbb&&\xbb''\xb1\x05\x05\ +\xbf33\xc055\xc2;;\xc2>>\xc4DD\xb1\ +\x06\x06\xb7\x19\x19\xc8OO\xc9RR\xcaWW\xcbX\ +X\xcbYY\xcdaa\xcebb\xcfff\xd0jj\ +\xd3tt\xd4uu\xd6{{\xd7~~\xd7\x81\x81\xdc\ +\x8f\x8f\xe1\x9e\x9e\xe1\x9f\x9f\xe2\xa2\xa2\xe4\xaa\xaa\xe5\xab\ +\xab\xe6\xb0\xb0\xe7\xb1\xb1\xe7\xb4\xb4\xb2\x09\x09\xeb\xbe\xbe\ +\xec\xc4\xc4\xf0\xd0\xd0\xf2\xd4\xd4\xf2\xd5\xd5\xf4\xdb\xdb\xf5\ +\xde\xde\xf5\xe0\xe0\xf7\xe4\xe4\xb2\x0b\x0b\xf9\xec\xec\xb3\x0e\ +\x0e\xb6\x15\x15\xfc\xf7\xf7\xfe\xfb\xfb\xfe\xfc\xfc\xb6\x16\x16\ +\xb6\x17\x17\xdc\x97<\x09\x00\x00\x00\xb6tRNS\x00\ +\x01\x01\x03\x04\x04\x05\x08\x08\x09\x0a\x0a\x0b\x0b\x0c\x0d\x0d\ +\x0e\x0f\x0f\x13\x13\x14\x15\x15\x16\x1b\x1b\x1c\x1c\x1d\x1e\x1f\ +!$%''*+,-./2669;\ +<=@ADEHKLMNOPTTU\ +Z\x5c]]`acegghkllmp\ +qsx|~\x80\x81\x83\x84\x8a\x8b\x8c\x8c\x8d\x91\x93\ +\x95\x95\x95\x96\x98\x99\x9c\x9d\x9e\xa4\xa6\xa7\xa7\xa8\xa8\xa9\ +\xaa\xac\xad\xad\xb0\xb3\xb3\xb4\xb7\xbb\xbc\xbd\xbd\xc0\xc1\xc4\ +\xc6\xca\xcb\xcc\xcd\xcd\xd0\xd2\xd4\xd7\xd8\xd9\xdb\xdc\xdc\xdd\ +\xde\xe0\xe1\xe4\xe5\xe6\xe7\xe8\xe9\xe9\xea\xef\xf0\xf0\xf1\xf3\ +\xf3\xf5\xf6\xf6\xf7\xf7\xf7\xf8\xfa\xfa\xfb\xfb\xfb\xfb\xfc\xfc\ +\xfd\xfd\xfe\xfe\xfe\xa0\xb1\xff\x8a\x00\x00\x02aIDA\ +Tx^\xdd\xd7Up\x13Q\x14\xc7\xe1\xd3R(\xda\ +B\xf1\xe2^\xdc[(\x10\xdc\xdd\xdd\xdd\x0aE\x8a\xb4\ +\xb8{p)^$P\xa0\xe8\xd9\xa4*\xb8\xbb\xbb\xbb\ +\xeb#\x93=w\xee\xcb\xe6f\x98\x93\x17\xa6\xbf\xd7\xff\ +\xe6\x9b}\xc8\x9c\x99\x85\x14R\xfaR9]\xfa\xf9\x80\ +(\xc4\x95A&60\x10\xa9\x19\xd9x\x80\xc7N\x14\ +\xed\xaa\xca\x02r\xa3\xec`%\x96\xb0\x1ee\x1b3p\ +\x80\xfa6\x09\xd8F\x00\xa7^\x17\xbe\xa0\xe8h\x19\x96\ +P}\xca\xeeh\x02\xae\xb6\x03^\x9e}\x08\xb0\x8e\x02\ +fE\x098a\xe6\x02y\x05\x10\xf9?\x03n.\x01\ +%G/9\xb0*4\x90\x0d4\x8f\xa2}2\x13\xf0\ +\xb3\xa0h*\x0f\xe8\x84\x22\xbc\x5c\x97\x05\x8c\x95\x80u\ +<\x0b\xe8-\x81sf\x16`\x92\xc0\xdd\xe9\x0a\xc0\xd7\ +)\xe06\x0b)k|7\x05\x90\x8e\x80\xa4\xfd\x8e\xe7\ +,\xcb.\xda\xe7+\x1f\xcd>\xa0h3\x09\x87\x147\ +\xc9\xbb\xdf\xbeG\xb1\x9f\xb4q\x85@\xd5B\x02bZ\ +\xa8\xfe\xb19*7\x0a(\x08\xea\xc2P\xb4\xa2\x95\x17\ +p\xaa\x85\xb2m\xc5X\xc2<\x94\xed\xc8\xc7\x01\xca\xa2\ +,\xb9'\x07\xe8\x81\xb2\x9b!\x0c\xc0o\x8f\x04l\xaf\ +\x870\x80`\x14\xe1\x9f'\xc7\xaa0\x80\xf9\x04\x1c\xbf\ +\xf7.q]\x03`\xb4\x89\x80\x17\xab\xbb\x96p\x07F\ +Y\x91\x8a\xab\xe1\xe2U\xd6r9\x9c\xfd\xbb\x88\x9a2\ +\x8fj(\x8a&4c\x01^\x16\xa4N\xfdl\xcc\x02\ +\x02Q\xf4tQj\x16\xd0\x17\xa9\xe8\xc4:\xc0\x02\x96\ +\x22\x15;\xd7\x9d\x05\x14A\xea\xbc\x16\x00,\xa05R\ +o\xa6\x01\x0f\x98Hc\xb2V\x81\x07\xa4\xddN\x17\xfb\ +m\x08\xf0\x00\x7f\xda\xae\x1f.\x0d\xea\xca\x13\xf0*R\ +yjN\x7f\x18\x0eN\xea@\xc0\xd9\x080\xb6@\x9f\ +n\xed-\xac\x04|\xeb\x05o%\xe0\xf6L\xe3\x9a\x9f\ +\xde\xed\xf3 P\x949\x08e\x8f\xfb\x1b\xf7&\xfar\ +'\x22\x8f\x0a\x18\x8c\xb2\xefq\x0d\x8d\xfb\x18\xfb\xf2\xed\ +kwP\x94\xc6\x82\xb2g\xe1\xc6s\xe0\xa1\xdf\xaa\x07\ +[\xb2\xff\xc3\xf7\xc25\xad\xb6q\xaf\xa8\xbfZBG\ +P\xb6\x16E7\x12F\x82\xb1\xb6\xf6\xe9a\xb8\xb7\x1a\ +0%\xe9\xc0\xef\xe7\xdaPGO\xb5D\xc4\x93?\xda\ +\x80\x93\xda\x1f9\x13s\xffe\xfc\x86\x9a\x0e\xd7\x8c\xcb\ +\xf1\xd2\xfb\xc5\x9e\xe0\xacr\xc3fO\xea\x5c\xcdG\xb1\ +f\x9a\xf3kMqp\xa9\x02\xa9 %\xf7\x17\x09\xba\ +99\xea\xb1au\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00\x0fk\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01\xf4\x00\x00\x00K\x08\x03\x00\x00\x00\xb1\xe3\x85\xac\ +\x00\x00\x00BPLTE\xd5\xd5\xff\xf6\xf7\xff\xda\xdb\ +\xff\xef\xef\xff\xdf\xe0\xff\xe7\xe7\xff\xea\xea\xff\xea\xeb\xff\ +\xeb\xeb\xff\xdf\xdf\xff\xf7\xf7\xff\xfa\xfb\xff\xf3\xf3\xff\xd7\ +\xd7\xff\xff\xff\xff\xe6\xe7\xff\xdb\xdb\xff\xe3\xe3\xff\xd5\xd6\ +\xff\xf2\xf3\xff\xee\xef\xff\xe5\xe6\xff\x96\xf6\xba\x85\x00\x00\ +\x0e\xe4IDATx^\xed]\xd9\x92$7\x08\x1c\ +\xa4:\x8f\xbefv\xff\xffW\x0d$\x14R\xd7N\xd8\ +\x0f#Gl\x84R\x05\xd5\xf6\x9b\x9d\x83\x0e U\x1f\ +\xf7\x1fE\xc7~\xdfwv\xf7\xedN\xf7m\xdf\xb7;\ +\x0f\xc1.\x8e\xb6c;\x88\x87\x812-\x94\xf9\xf9\xca\ +\x05\x96\xf0\ +0~\x94\x80\x8e\x1d\x9e\x84\xf5\x8d\xf9\xdf\x95m\xf1\x02\ +\x12S\xde\xc1\xbcr\x9e)3\xc0\xfb\xaf\x99\xc9\x16\xd6\ +\xf3\x22\x98\x95r\xc6\xfc\x98\x9d\xf4QY\x07\xedA\xbd\ +\x93\x9e\xd6\xf5)\x8e\xc9\x06\xe97\x19\xcf\xf4q\xbb\x81\ +\xf0\x06\xa4\xf70\x87\x17\xe3X\xdf\xc5\xf1k3\x10\xf3\ +m\xd1.\xc8\x94\xd9\xd3B\xcb\x97\xc5\xfa\xfcK\x1c\xa2\ +\xfc\x8f\x91\xfe\x1aeT\x94\xaf\xaf\xd7`\xd1\x9eV\x01\ +\x07yZ\x11\xe97\xe6;\xdd\xf0\xdc>8\xda\xd9\xb5\ +!\xbd\xc7\xfa.A.\xb1\xce\xcf\xae\xe3\xee\x91~\x90\ +qN\x94e\x1cY\xc3=0\xcf\x12\xe72\x9c\xf4I\ +I\x9f\x10\xe9\xc6\xbb\xd1\xbe\xca30\xe9\x80Dzz\ +\x1a\xe1n\xe9y\xbb\xd9\x14\xaf\x9c7 \xbd\x83\x84m\ +!\x9f\xd8\x8c\xf3=\xd6t\xe7\x1c\x91\x9e\x17:\x98\xf8\ +\xaf\xe0\x9c\x1f\xb0\xee\xd3;\xc6\xc8\xcc\x0b\xe9U\xa4\xaf\ +l\x03H\x1f\xd8V]\xd3\x95x~@\xba2\xfe\x94\ +\x18g(\xeb\xb7\x9f&\xbdc\x87\xdb\x09;8Y\xd5\ +\x85y\x00k:\x06\xf6ql\xf9\xf05=8\x9fu\ +v\x8fH\x9fFy\xc6\xc7\x0b\xacW\x91\xce\x9c\x8b\x07\ +\xf1\xe0\x5c\xe7wL\xef)\xdd\x94\xf7`\x9d\x9f\x1f&\ +\xa0S\xbe\xcb \x9d\xde9\xdei3\xec\x14kz\xec\ +\xde%\xdacM7\xcc\xc5\xee\x1d\xd0\xa9]M\xf6q\ +:\x04`\xdd\xa6\xf7\x97\xd0\xad\x900\x07\x12fw\x9b\ +\xdf\x99\xef&kz\xe7\x1c&^(g\xf3u\xdd\xd7\ +t\x1e\x94m\x8e\x97 \xc7\x16\x1e\x98\x84p~b\xf7\ +\xcex\xf03\x8a\x8d\x16\xe9\xfc\xc4\xee]#}x\xad\ +\x80\xed\xde\x13;\x90\xce\xb4K\x98\xa7\x9b \xf9\x9a>\ +\x01\xf3\xbc\x00Y\xc7\x9c'\xfb\xb5\xe4\x1a\xf8glA\ +\xf8\xb1]\xe8\xc2\xe3Plx\x9d\xabW>\xb6\x12\x98\ +\xf3\xf8\xa1\x8d\xa3\x00\xefM\xd7@q\x9b\x9cq\xe5\x8d\ +\xb5\xb1\x0d:\x0a\xd2\x033?\xe0\x5c\x80?\x82\x80\x10\ +,>\xfb_*\xce\x1e\x01a\x1b\x9e\x0e\xda\xc1\xfev\ +\xc1]l\x07\xe5L6i:\x83\xdf\x08\x16b\x93\x7f\ +\xe3Sf\x03t\xd2\xa7\xe0;\xcb[\xa9\xce\xf3\xac\xaf\ +\x12\x87\xbdA\xb8\xc47X?\x00\xda\xd8\xf0\xd6A\x1b\ +Ple\xee\xf8g\xb8\xfb\x1d&\xf1M\xf8MN\xb9\ +\x1fy\xf1j\x86N\xfa$\x9c\xcfY\xdf\xba\xb60\xa6\ +\xe0]~!u(\xac\xf3\x0f~\x1f\xfa\xeb\x08\xe4c\ +\xf3A\xf8M\x94\x83te\x9b0\x9bk\xc4\x13)\xf5\ +2$\xb4\xf5\x07\xf1`\xd7\x82\xec\x8e\x9f\xdd\xc8u\xec\ +\x18\xd8\x98`\xc7\xe2;\xb9\xcc\xbfb\xa7\xa3 ,\x95\ +\xb4,l\x88/\xc6\x82\xcd\xdcT\xec\xde\x1f#6r\ +\x91\x9by\xd8\xde]s\xefvF_\x93=)y\xee\ +\xfd\xa6\xc7\xb6'\xdb\xc7\xf3#5M\xc3v\xea\xc9l\ +C6.V8\x9c\xd3\xe9\xf0\xdd;a\x8fT\x16[\ +,3c\xa43\xcf\xecAz\x9c\xd3\x1d\xab\xda\xc0v\ +\xee\xde\x93\xbat\xe6\xde\x8dy\x1c\xd9Zd\xe4:4\ +-c\xb9w\xecO\xad\xe6B\x1b\xc3\xcf\xe9\x9e{\x17\ +OL\xbdc\x0e\xe2\x05s\x04\xfaX\xe5\xde\x03^e\ +Ss\xe2S\xe4\xde\xc5\xf00\x9a\xe4\xde;\x88\x0d\xe7\ +\x0eu\x98\xd9\xebsz\x99{\xb7\xf3O\xce\x14\xbck\ +\x8dm.H\x7fHr\xa6\xce\xbd?\xcaD,X/\ +\xcf\xe9L8\x22]\x89\xe7\xa3:\xd0\x22\xf7\xde\xb1\xbb\ +'\xf1\x1b\xdb\xbf\xd4\xd3\x17\x1e_\x19\x83\xf1\xeb-\x0f\ +;\xcfsD\xfa\x03iX\xb1\xd7\xeb\xf7oK\xcc\xac\ +/\xa7|\x18\x12\xc2\xbcZ\xd3Q]\xfdcv\xcff^c\x8b\x19~\xc1\xbc\x8e_\xf2\ +\xdbjl\x19\xb3<;\xab\xad\x09\xeb\xa8\xb1\xedy\xdb\ +H<\x83H\x1c\xaalb\xcc\xb5\xfe\xc2\xec\xce\xcf.\ +oy)\xf9\xf4W1\xde\xabl\xbd\xfb\x1d\x7f\xcd\xf6\ +7\xee\xbb\x9a\x834\x122\x91\xac\x89\x1a%\xb4,\xe7\ +>n\x16o;9\x17;\xa8cXrFS\xb0\xfc\ +\x00\xb1uO+\x80\x8c\x1c\x12\xb1\xc8\xbd'm\x8c\xc4\ +\xd6\x1d\xfe\xa7\x09\xe8\xe75\x14]L\xd1\x84\x07Y\xb9\ +\xb2\xe2\xa2\xf8\xbe\xef}^\xea\x1e9~\x81t\x10.\ +\xa3\xca\xbd\xaf\xea\xa2\xd8\xa2\xa7\xf4\x905\x99\xb4)\xb5\ +\xca\xbdw\xf8\x1e\x14\xbb\xd2m\x8f\xce\xc8\xa8\xa7\x1b\xbe\ +\xeb{\xaf\xb5l(\xaf\x22\xc8\xd5\xd5\x0a\x17\x88[\xd8\ +\xa2\x9e\x1eZ6a?\xa1\xbe&hXe\xeb}\xef\ +B<\x1ed\xe3.}\xef`\xfe\xda\xf7\xbe\xe4\xfc\xa7\ +n\xd8\xc7\xe4-\xd0L\xf7Xt\xc3\xae\xa7\x94m\xb8\ +\xd4\xd3C\xdd\xf2,\xfb\xde?\x7f\x9a\xf4\x9e\x9cq\x1d\ +\x9b\x982NE=\x9d\xa2\x9e\x0e\xfc\xb1\xef\xdd\xa2\xbc\ +\x100\x22#\xe7\xd9\x19p\xee\xb8\x94\xd3\x8b\x1e\xe8\xf4\ +4-[\xd9\xf7\xde\x86\xf4\x1e\xeaZe\xd3s\xc9\xf7\ +\xf5t\xf0\x1e}\xefE\xe7\xf1\x82\x11yXa\x1c\x91\ +\xfe\xe2\x17[\x10\x0e\xc7\xf6M=\xfd\xc6?\xa2\x87\xa2\ +Y\xa4w\xd2#\xd7\xe4\xeb\xb9\x81\xe8@\xfe\xdd8\xcf\ +Y\x1d1\xc3\x91{w\xc1C1\xbd\x83t\x8btM\ +\xc5~\xafOO\xb5>\x1d\xcdR\x1f\x09\xe2\xf4Vk\ +z_\xd1IM\x13\xcc\xf7M](\x18}=\x07\xe7\ +\xe2\xa1#\x10\x03B\x9d^\xd6\xd3\x99yDzt\xce\ +\x5c\xf5\xe9kz\xaf\xa7\x0bp`\x0b\xce\x9b\x91\xde\xbb\ +gx\xa0\x96\xee\x1d\xfex\xd9\xba\xee\x9bw!\x9b4\ +\xb3\xe9\x98\x8b\x1e\xb9\xd9T\xab\xde#\x87\xc3\xfak\xbc\ +\xe8\xd3\x11\xed\x86\xd7YO\xf7\x9eH\xb86\xfa\xf4\x0e\ +Wf\x10\x8a\x07\xbb\x86zqN\xcf\x16\xe5\xfa\xc61\ +]\x94\x03\xba\x94\x13\xb4l\xfa{B9}:1Z\ +\xe3\xcc\xf8\xba4\xc3\x96|\x87j\x15\xe2E\xc6\x13\xe9\ +\x19}<7S\x15\x5c&\xcb\xbd\x87\x96m\xae\x94\x0e\ +S\xf6.\xbe\x85,\x0bK\x8b\xe9\x1b\xe4\x8d_P6\ +e6}\x18Y=@\xa1p!\x8aS\xec\xeeU6\ +y!L\x5c\xec\xb0\xc3\xfd\x18:.\xa43r\xa1e\ +\x9b\xc5\x09\xf9\x05\x0e\xa9\xc0\xa1\xd6Bxe\xdf\x8c\xea\ +\x1bu5+\xb8\xf0oOC\xd6@Q\x8d\x1dfA\ +qb\xca/\x89\xc3\xef\xff\x05\xbd\xca\x16Z6\xb6w\ +|\xd9\xfaCG\xc6\xc8\x11\xdf\xa8\xa3\x97*F\xd4\xd0\ +\x0f\x04u\x09!\xd9\xb5l\xc4\x86\xcbY\xc4\xe07\x17\ +/\xb6\x976u\xd2\x01h\xd90\xecU\x01Z6\x0c\ +S*\x1f\x00e\xe5\x9b\x0eDx\xde\xf3\x81\xdc\xa3\x91\ +N\xae\xf3a\xb8\x96Ml'\xaf\xa7\x8b\xe9\x10ll\ +\x7f\x89n\xb5W\xd9\xfa\xfe\x9d\xde{\xe4\xbcm\x08\x19\ +\xb9L\xe79=\x17\x19\xb9_\x93\x9f\xd3\x97\x8b\xc2\xc5\ +\x1b\xe4\x90zg\xe7\xb0\xbc;\xbfyX\xdf\xbbo\xe6\ +\x90\x8e\x93\xf4\xbb\x0b\x9b\xc4Z\x90\xde\x13r\xea\xd0\x08\ +v\x07\xeb@\xd9\xf3^\x9f\xd3\x81_\x9e{\xcf\xf5\xe5\ +\x81\xd1\xf7~\xd9\xbd\x0f\xc3K\x86\xe6\xe2\xe2\x1e9\x88\ +[@\xba\xeb[\x8c\xf5V\xa4\xf7\xbew\xbb]j\xdb\ +\x91\x9c\x8b\xdc\xbb\xf1\xfevN\xbf\xf4\xbd\xcf\xcb\x9ck\ +Y\x93\x0b\x18\x85w\xa8V\x1d\xab\x8f\xb8s\x86\xf3q\ +H\xc3*n\xb8h\xa8u\x95\xad\xe7\xde7?\xa7\xa3\ +\xfb\xd9s\xef\xbe\xc3)\xce\xe998\x8f\xbew\xf6\x0a\ +P\xcef}\xef<\xca\xc2\xea\xea\xc9w\xc7y\x8f\x5c\ +:\xef\x9c\xb9\xdd\xd8\xb7\xd3\xb2u\xec0r\x95\x0bi\ +\x8cW\x0a\x97J\xcf&[b\xfaS\xdf\xfb\x8c\x84\x5c\ +\x5c4\xe4U6I\xc1V\xb4\xf3\x03}:\xac\xae\xa7\ +C\xbc(\x9c\xabB]\xa2\xbd\xcb\x9a\x9a\xb0\x8e{S\ +8\xca\xd9aM\xc7\xa8\x14.^V\xfd\x22\xebz\x0f\ +\xe6\x17\x10\xef\xa4?f\xb6\xa8\xb2]r\xefC\xe8\xd3\ +\x87\xa1\xca\xbd;\xe9\x89M\xa8\x17\xba?\x1b\x92\xde\xa7\ +w5\xe5\x1a>\x04\x8c\x88r1\x88\x17+\xc6\xab\xdd\ +\xbbGz\x90.\x0e\x1b96`\x88\x82\xfa\x90\xde\xeb\ +\xe9\xb0\xe4\x8a\xd5g+\x01c\xa7\x9c\xe4\xb5\xfb\x9a\x8e\ +\x19\x1e\xe63;\x19\xe7\xf4\xc5\x00\xe7b\xe0<\xd6\xf4\ +\xe9\x84W\xd9\x94pq\x8e\xe1\x1b}\xba\x13\x0e\xf9\x22\ +\xc7\xfbSXo\xd4\x18\xd9IG\x05\xc1\xef{g\xaa\ +\xb5\xcd\xfb\x04\xf2V'LA\xe0\x88\xce\x99z#\xe7\ +\xdd\xb0\xa5\xa4\xc9\xf5\xe9u\xebLJ\xa5>\xfd]\xa9\ +\xdcj#\xd7\xa7\xf6\xb8\xef\x9dL\xcb\xb6m\xea\xf7|\ +\x88\xa1\x0f\x9a\xb4\xf9\x99\xc4\x84h\x8d\xf4I\x09W5\ +\xdb<\x95\xc9\x196$g\xae\x0au\xe1=y\x0ft\ +\xac\xe9\x02\xbb\x94\x80\x17s\xa3\xdd\x0a\xeaU\x1aV\x9c\ +k\x1eP\xe1Ce\xad\xf4K\x16g56\xbbK\x8e\ +2eT\xd9\x16h\xd8\x8e\x83\xd8#\xf7\xb4ol\xc8\ +\xc2\x8b\xdd\xed\xbf\xff\xd4\xb2m\xa4\xe9+\xcf\xbb\xb3\xdb\ +\xed\xb4\xcb\x1e\xef\x86\xe8\xb9\xf7\xa9\xa8\xb9T\xb9\xf79\ +\x97 \x1e\xd9UM\xae\xb1\xa6#@\xa1d\xb3\x93)\ +\xbd_\x22\xe8\x1a6~\xe3\x89*\x1b?tv\xa0\xec\ +\x1eB-\xd0K\xab\xc0\x1c|\x9b<>\xc3;H-\ +\xda\xf4\x85t3R\x03\xe2\xc6Hc}\xab\x81<\x15\ +\xf8\xd6A\xe2,\xd6\xd1KJ\xec\x83\xfb\x06\xe8\xa4#\ +\xd61\xc3\xcf\xa8\xb3\x99\xcaF\xcd\xfd\x22\xb6\xe0\xd7q\ +,\xaab[\xec\xc6H\xb1\x83\xb2\xdf\x03Lj\x1b\xd4\ +l\x0a\xbc\xa1c\x9373\x0e-[\xa8\x95w6\xd0\ +.\xa0\xbf\x81\xed^e\xeb\xd81\xb0{g\xc3.\x86\ +G\xde7\xca;\x99\x92\x0dZ6\xb1B\xcb\x06[\xf2\ +l\x11\x08 %\xf7P\x03^'\x92\x9f\xd8\x8a\xdc;\ +v\xef\xb0\xdb\x99}o\xaap\xe9\xa4\x17\x97\x0dm\xdb\ +{\x95m\x0b\xad\x03\xf2\xee\x97\xbe\xf7E]4F\x8a\ +\xb1\x03\xe9/<\xd7z\x8b!\xc9\x03\x97\xe2\xc8&\x8f\ +\xa2\xe9\x8d\x91\xbd\xef\x1d7\x99\xdb^\xf5\x92{7D\ +\xffQ\xd5\xf7~\xd5\xb2\x8d\xd6\x19\xf9:/\x0fT\x0c\ +\xe6\xd0\x04\xeba^\xdd.e\xcaU\xb4E\xb6\x8e\xf4\ +\xde\xf7\xce\x5c\xbbm\x97\xdc;\xa2]\xb7E\xc2\xf9\xa5\ +\xef=\xbf\xabVGA|\x96\x8d=\x08\x1f\xcaH\x8f\ +z:\x90T\xe2\x82\xc1\x87\xf5v\xc9\x99\x9e\x9c\x11\xd0\ +\xeeyX\xda\xdfr\xef1\xbfS\x16\xa3j~\x9f\xdf\ +\xb5l\xe3$\x0ex\x08\xe3\x9a\x88\xf5P\xff\x8dF\x0a\ +\xe3}\x88z:H\x7fZ\xd3\xccg\xfaLm\xd7\xf4\ +\xfe\xe5\x1e\xbbG\xaeT\xb7\xa8\x95QN\xc67F^\ +\xa8\xe0\xfc\xa2e\x1b-\xd2yD\xa0\x87\x98\x0dd\xa7\ +a\x88z\xba\x91\x8e\xa2*\x87\xfc\xfa\xe9q\xde\x88\xf4\ +\xbew\x8f\xc6\xee\xcd9\xb7H\x0f\xce\x11\xe9\xc6yf\ +\xbb\xce\xef\xbe\xa6\x8f\xe7\x8d\x91\xf2D\xa0_\xd4\x0e\xd7\ +z:\xae\x92\xfb\xe4P\x17\xdf>\xd2{y\x15\x92e\ +\x0c\xdf\xbdWZ\xb6|x\xb4W\xf7\xbd\x97\xdfec\ +\xaa\xc5\xf3\x1b\xbb\xf7\xd0\xa7\x03\xab\x8d\xaa\xcafMr\ +\xc8\xbeK\xa43\xeb\xb7\xf4\xd92\xd2\xfb}\xef\xe8\x93\ +\xb3\x1b\xd3\xaa\xdd;\x86!\xfbp\xcc\xd5w\xd9\xae\xf7\ +\xbd\xbf4\xd2\xe5\x16\xe8\xd7\xb5\x9e\x9e\xd6\xe1\xaaO\xc7\ +N\x8e)W|\xf2\xf8y\xd2\xfb\x17\x1d\x00f\x1b\xba\ +\x0d!\x9e\xde;ba\xc0\xe5\xbe\xf7\xea&\x0a\xc1X\ +\xde\xf7>b\xfb\x0e\x0cU==\xbe\xaa\x0c\xc2\x15\xd0\ +\xa7\xcb\xec\x0e\xd6/Z\xb6\xf2\xbbl\xfa\xf6\x17\x0f\x87\ +\x7f\x82B\xdfK>\xb5l\x8e\x0d/\xa2\xd0\xb2\x1d<\ +\x02\xa5\xce\x01\xfa>\xfc\xf0\x0a\x1b\xf2\xb0<\x14\xbb=\ +\xcd\xd0\x0b.\xf5w\xd9\xa0\x8e\xbf\x02\xb57\x5c\x14\xe9\ +Z\xb6\x12\xae\xba\x87\x96\x8d0\xaf\x01\xd1/\x86\x14e\ +|\x97\xedN _\xa3\x034o\xffW\xee\xbd\xcb\x9a\ +.Z\xb6w\xdeC\xcbF\xf2\xdb\xdb\xf6\x05T}\x97\ +\x0dZ\xb6\xe3\xd4\xb2\xed\x88q\xc0\xd6\xba\x1de\xd5\xb8\ +1\x92Gh\xd9L\xb9\xda\x94\xf9N\xfa\x5c}\x97\x8d\ +mb\xe7\xd56\xab\xadUZ\xb6\xc5\xbf\xbai\xdc\xe7\ +\xf8.\x1b\xb4l[h\xd9r\x11\xed\xe4\xbf\xfc\xbbl\ +\x88p\x92\xf8\x0f\x9a\xb7\xbf%\xd2{\x95\xad\x0b\xd9\xd8\ +a\xdeRI[,o\x94\x91{\x8f\xef\xb2\xe9}\xef\ +\x84buh\xd9\xe2\xbblQq\x81\x96\x0d\x1fw\xb8\ +\x1e\xd9\xce\xf6gl\xe4\xd2\x93=\xa4\x0e\xa8\xb4}@\ +\xdd\xf4\xd1D\xd6\xd4\xb1cG\xaa\xe9\x19\x14\x5c\xc2h\ +\xb7\x9d;\x1d\xe57\x5c\x16\xca\xecK-\x9b\x7f\x97-\ +\xee\x0e\xf4Oty\xcd\xa5\xbe~\xc4S\xb0\xcey\x9c\ +\xd3q\xdd\xfb\x07?\xad\xabl\x9dx\xcf\xbd\x13\xfbo\ +s\xef8\x05\xb9\xd2AI\xff\xd3w\xd9Fe\x1dU\ +6\x8b\xf4\xf1\x22kz\xc5\x05\xff\xea\x93g\xe4 X\ +\x85k\x15\xe9=\xf5\x1e}\xef\xdb\xbf\xe6\xde\xe3kM\ +j\x904\xa9\x03\xe9\xd5\x97\x1d\xe2\x9c~\xf9Z\x13[\ +\x80Y\x8f*[\xd9\x03\xfd\xf1L\xcd2r]\xcb&\ +^\x0bl\xca9\xbe$\x1d\xb9\xf7\xc8\xc9\xa1\xb4Z\xde\ +\x0d;cx\xeb\xfb\xc99;\xdc\x22g\xa3\x84~\xc6\ +\xe3%nMj\x18\xa8\xacj\xc9\xa5\x90\xa77\x8b\xf4\ +\x1e\xedh\xf0\xd4\x04\x84g\xa2\xea\xdc\xfb!\x86\xd4;\ +?\x8c\x9a\xf7\xc5?\xd1e`\xc2\xdd\x5c\xe5\x02\xac\x1e\ +\xe9\xf8\x16\x9fs\xfeL\xd61%yw\x95\xb7\xa4\x96\ +\xaa\xd5N\xb8\x184.\xec\x91y\x02\xeb\x00sM\xca\ +\xb8\x07\xfbB\x84c\xb1`\xae\xd7\xf4\xd0\xb2\xd9\xb7\xd9\ +L\xbe\xe8\xac\xafp.p\x19\x10\xe9O\x1e\xab\x92\xee\ +\x84\xd7\xddR\xff\x00\x0e^\x0cN\xab\x94\x1d2\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x06S\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00@\x00\x00\x00@\x08\x03\x00\x00\x00\x9d\xb7\x81\xec\ +\x00\x00\x02\xebPLTE\x00\x00\x00\x00\x00\x00\xff\xff\ +\xff\xff\xff\xff\x7f\x00\x00\xff\xff\xfff\x00\x00\xff\xff\xff\ +\x7f\x00\x00q\x00\x00\x7f\x00\x00\xff\xff\xffs\x00\x00\xff\ +\xff\xff\x7f\x00\x00\xff\xff\xffu\x00\x00\x7f\x12\x12\xff\xff\ +\xffw\x00\x00x\x00\x00\xff\xff\xff\xff\xff\xffy\x00\x00\ +\xff\xff\xff\x7f\x00\x00z\x00\x00\xff\xff\xff\x7f\x00\x00\xff\ +\xff\xff{\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +\xff|\x00\x00|\x00\x00\xa3GG\xff\xff\xff\xff\xff\xff\ +\x7f\x00\x00|\x00\x00\x7f\x00\x00\xff\xff\xff\xff\xff\xff\x7f\ +\x00\x00\xff\xff\xff}\x00\x00\xff\xff\xff\x7f\x00\x00\xea\xd5\ +\xd5\xff\xff\xff\xff\xff\xff\x9988}\x00\x00\xff\xff\xff\ +\xff\xff\xff\xff\xff\xff}\x00\x00\xff\xff\xff\xff\xff\xff\x7f\ +\x00\x00\x7f\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\ +\x00~\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\ +~\x00\x00~\x00\x00\xff\xff\xff\x7f\x00\x00\xb7pp\x7f\ +\x00\x00\x7f\x02\x02~\x00\x00\xff\xff\xff~\x00\x00\xff\xff\ +\xff\xc5\x8c\x8c\x7f\x00\x00\xff\xff\xff\x7f\x00\x00\xff\xff\xff\ +~\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f\x00\x00\xff\ +\xff\xff\xbauu~\x00\x00\xa8QQ~\x00\x00\xed\xdc\ +\xdc\xff\xff\xff\x7f\x00\x00\x7f\x00\x00\xff\xff\xff\x7f\x00\x00\ +\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd8\xb2\xb2\xff\ +\xff\xff\x7f\x00\x00\xff\xff\xff~\x00\x00\x7f\x00\x00\x7f\x00\ +\x00~\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xb7qq\ +\x7f\x00\x00\xff\xff\xff\x93''\x7f\x00\x00~\x00\x00\xf9\ +\xf4\xf4\xc3\x87\x87\xff\xff\xff\xff\xff\xff\x91$$\xff\xff\ +\xff\x8f\x1f\x1f\xff\xff\xff\xec\xd9\xd9\xff\xff\xff\x8c\x1a\x1a\ +\x7f\x00\x00\x7f\x00\x00~\x00\x00\xff\xff\xff\xff\xff\xff~\ +\x00\x00\x7f\x00\x00\xad\x5c\x5c\xff\xff\xff\x8d\x1b\x1b\x84\x0a\ +\x0a\x81\x03\x03\x7f\x00\x00\xff\xff\xff\xff\xff\xff\x80\x02\x02\ +\xff\xff\xff\x80\x02\x02\xff\xff\xff\xff\xff\xff\xb1cc\x7f\ +\x00\x00\x7f\x01\x01\xff\xff\xff~\x00\x00\x83\x08\x08~\x00\ +\x00\xff\xff\xff\xb6mm~\x00\x00\x87\x10\x10\xd6\xae\xae\ +\x7f\x00\x00\x7f\x00\x00\xff\xff\xff\xff\xff\xff\xde\xbd\xbd\xf9\ +\xf4\xf4~\x00\x00\x7f\x00\x00\x90\x22\x22\xdf\xc1\xc1\xff\xff\ +\xff\xacZZ\xc4\x8b\x8b\xff\xff\xff\x7f\x00\x00\xff\xff\xff\ +\x90\x22\x22\x80\x01\x01\x9822\xa3HH\xdb\xb7\xb7\xf4\ +\xea\xea\xf7\xf0\xf0\xf8\xf2\xf2\xfe\xfe\xfe\x80\x02\x02\xa5L\ +L\x8c\x1a\x1a\x81\x04\x04\x92&&\x93''\x82\x05\x05\ +\x9933\x9a55\x9d;;\x9e>>\xa1DD\x82\ +\x06\x06\x8c\x19\x19\xa7OO\xa8RR\xabWW\xabX\ +X\xacYY\xb0aa\xb0bb\xb2ff\xb4jj\ +\xb9tt\xbauu\xbd{{\xbe~~\xc0\x81\x81\xc7\ +\x8f\x8f\xce\x9e\x9e\xcf\x9f\x9f\xd0\xa2\xa2\xd4\xaa\xaa\xd5\xab\ +\xab\xd7\xb0\xb0\xd8\xb1\xb1\xd9\xb4\xb4\x84\x09\x09\xde\xbe\xbe\ +\xe1\xc4\xc4\xe7\xd0\xd0\xe9\xd4\xd4\xea\xd5\xd5\xed\xdb\xdb\xee\ +\xde\xde\xef\xe0\xe0\xf1\xe4\xe4\x85\x0b\x0b\xf5\xec\xec\x86\x0e\ +\x0e\x8a\x15\x15\xfb\xf7\xf7\xfd\xfb\xfb\xfd\xfc\xfc\x8a\x16\x16\ +\x8b\x17\x17\xd2g\xa5\xb8\x00\x00\x00\xb6tRNS\x00\ +\x01\x01\x03\x04\x04\x05\x08\x08\x09\x0a\x0a\x0b\x0b\x0c\x0d\x0d\ +\x0e\x0f\x0f\x13\x13\x14\x15\x15\x16\x1b\x1b\x1c\x1c\x1d\x1e\x1f\ +!$%''*+,-./2669;\ +<=@ADEHKLMNOPTTU\ +Z\x5c]]`acegghkllmp\ +qsx|~\x80\x81\x83\x84\x8a\x8b\x8c\x8c\x8d\x91\x93\ +\x95\x95\x95\x96\x98\x99\x9c\x9d\x9e\xa4\xa6\xa7\xa7\xa8\xa8\xa9\ +\xaa\xac\xad\xad\xb0\xb3\xb3\xb4\xb7\xbb\xbc\xbd\xbd\xc0\xc1\xc4\ +\xc6\xca\xcb\xcc\xcd\xcd\xd0\xd2\xd4\xd7\xd8\xd9\xdb\xdc\xdc\xdd\ +\xde\xe0\xe1\xe4\xe5\xe6\xe7\xe8\xe9\xe9\xea\xef\xf0\xf0\xf1\xf3\ +\xf3\xf5\xf6\xf6\xf7\xf7\xf7\xf8\xfa\xfa\xfb\xfb\xfb\xfb\xfc\xfc\ +\xfd\xfd\xfe\xfe\xfe\xa0\xb1\xff\x8a\x00\x00\x02aIDA\ +Tx^\xdd\xd7Up\x13Q\x14\xc7\xe1\xd3R(\xda\ +B\xf1\xe2^\xdc[(\x10\xdc\xdd\xdd\xdd\x0aE\x8a\xb4\ +\xb8{p)^$P\xa0\xe8\xd9\xa4*\xb8\xbb\xbb\xbb\ +\xeb#\x93=w\xee\xcb\xe6f\x98\x93\x17\xa6\xbf\xd7\xff\ +\xe6\x9b}\xc8\x9c\x99\x85\x14R\xfaR9]\xfa\xf9\x80\ +(\xc4\x95A&60\x10\xa9\x19\xd9x\x80\xc7N\x14\ +\xed\xaa\xca\x02r\xa3\xec`%\x96\xb0\x1ee\x1b3p\ +\x80\xfa6\x09\xd8F\x00\xa7^\x17\xbe\xa0\xe8h\x19\x96\ +P}\xca\xeeh\x02\xae\xb6\x03^\x9e}\x08\xb0\x8e\x02\ +fE\x098a\xe6\x02y\x05\x10\xf9?\x03n.\x01\ +%G/9\xb0*4\x90\x0d4\x8f\xa2}2\x13\xf0\ +\xb3\xa0h*\x0f\xe8\x84\x22\xbc\x5c\x97\x05\x8c\x95\x80u\ +<\x0b\xe8-\x81sf\x16`\x92\xc0\xdd\xe9\x0a\xc0\xd7\ +)\xe06\x0b)k|7\x05\x90\x8e\x80\xa4\xfd\x8e\xe7\ +,\xcb.\xda\xe7+\x1f\xcd>\xa0h3\x09\x87\x147\ +\xc9\xbb\xdf\xbeG\xb1\x9f\xb4q\x85@\xd5B\x02bZ\ +\xa8\xfe\xb19*7\x0a(\x08\xea\xc2P\xb4\xa2\x95\x17\ +p\xaa\x85\xb2m\xc5X\xc2<\x94\xed\xc8\xc7\x01\xca\xa2\ +,\xb9'\x07\xe8\x81\xb2\x9b!\x0c\xc0o\x8f\x04l\xaf\ +\x870\x80`\x14\xe1\x9f'\xc7\xaa0\x80\xf9\x04\x1c\xbf\ +\xf7.q]\x03`\xb4\x89\x80\x17\xab\xbb\x96p\x07F\ +Y\x91\x8a\xab\xe1\xe2U\xd6r9\x9c\xfd\xbb\x88\x9a2\ +\x8fj(\x8a&4c\x01^\x16\xa4N\xfdl\xcc\x02\ +\x02Q\xf4tQj\x16\xd0\x17\xa9\xe8\xc4:\xc0\x02\x96\ +\x22\x15;\xd7\x9d\x05\x14A\xea\xbc\x16\x00,\xa05R\ +o\xa6\x01\x0f\x98Hc\xb2V\x81\x07\xa4\xddN\x17\xfb\ +m\x08\xf0\x00\x7f\xda\xae\x1f.\x0d\xea\xca\x13\xf0*R\ +yjN\x7f\x18\x0eN\xea@\xc0\xd9\x080\xb6@\x9f\ +n\xed-\xac\x04|\xeb\x05o%\xe0\xf6L\xe3\x9a\x9f\ +\xde\xed\xf3 P\x949\x08e\x8f\xfb\x1b\xf7&\xfar\ +'\x22\x8f\x0a\x18\x8c\xb2\xefq\x0d\x8d\xfb\x18\xfb\xf2\xed\ +kwP\x94\xc6\x82\xb2g\xe1\xc6s\xe0\xa1\xdf\xaa\x07\ +[\xb2\xff\xc3\xf7\xc25\xad\xb6q\xaf\xa8\xbfZBG\ +P\xb6\x16E7\x12F\x82\xb1\xb6\xf6\xe9a\xb8\xb7\x1a\ +0%\xe9\xc0\xef\xe7\xdaPGO\xb5D\xc4\x93?\xda\ +\x80\x93\xda\x1f9\x13s\xffe\xfc\x86\x9a\x0e\xd7\x8c\xcb\ +\xf1\xd2\xfb\xc5\x9e\xe0\xacr\xc3fO\xea\x5c\xcdG\xb1\ +f\x9a\xf3kMqp\xa9\x02\xa9 %\xf7\x17\x09\xba\ +99\xea\xb1au\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x0e\ +\x09\xbco'\ +\x00w\ +\x00a\x00t\x00e\x00r\x00m\x00a\x00r\x00k\x002\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0e&\xb1\xe7\ +\x00l\ +\x00o\x00g\x00o\x003\x00.\x00p\x00n\x00g\ +\x00\x0e\ +\x07\x04\x9f\x87\ +\x00b\ +\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x00.\x00p\x00n\x00g\ +\x00\x0e\ +\x09\xbdo'\ +\x00w\ +\x00a\x00t\x00e\x00r\x00m\x00a\x00r\x00k\x001\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0e%\xb1\xe7\ +\x00l\ +\x00o\x00g\x00o\x002\x00.\x00p\x00n\x00g\ +\x00\x0a\ +\x04\xc8G\xe7\ +\x00b\ +\x00a\x00n\x00n\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0e$\xb1\xe7\ +\x00l\ +\x00o\x00g\x00o\x001\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x07\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\xa8\x00\x00\x00\x00\x00\x01\x00\x00\xd7\xe0\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00L\x00\x00\x00\x00\x00\x01\x00\x00@\x9b\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00n\x00\x00\x00\x00\x00\x01\x00\x00\x98\xd1\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\xc2\x00\x00\x00\x00\x00\x01\x00\x00\xe7O\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\xd1\x89\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x004\x00\x00\x00\x00\x00\x01\x00\x00:D\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/dialogs/classwizard/images/background.png b/examples/widgets/dialogs/classwizard/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..44c7badb8568ff756804d2a5a651f8fff9961a1f GIT binary patch literal 22578 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 FV1kZVGdKVM literal 0 HcmV?d00001 diff --git a/examples/widgets/dialogs/classwizard/images/logo1.png b/examples/widgets/dialogs/classwizard/images/logo1.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b594aafcd6f944f6d950aeaab01017ddaef68a GIT binary patch literal 1619 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/dialogs/classwizard/images/logo3.png b/examples/widgets/dialogs/classwizard/images/logo3.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd3ea23589d5cd1e36995fb7930fbb65537e2c9 GIT binary patch literal 1619 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

~pmFwck7jhkKr6uo?q0+;sEMYfP3VosyR1 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" \ + "

Click a button to close the message box. Pressing the Esc " \ + "button will activate the detected escape button (if any).

" + + def __init__(self, parent=None): + super(Dialog, self).__init__(parent) + + self.openFilesPath = '' + + self.errorMessageDialog = QtWidgets.QErrorMessage(self) + + frameStyle = QtWidgets.QFrame.Sunken | QtWidgets.QFrame.Panel + + self.integerLabel = QtWidgets.QLabel() + self.integerLabel.setFrameStyle(frameStyle) + self.integerButton = QtWidgets.QPushButton("QInputDialog.get&Integer()") + + self.doubleLabel = QtWidgets.QLabel() + self.doubleLabel.setFrameStyle(frameStyle) + self.doubleButton = QtWidgets.QPushButton("QInputDialog.get&Double()") + + self.itemLabel = QtWidgets.QLabel() + self.itemLabel.setFrameStyle(frameStyle) + self.itemButton = QtWidgets.QPushButton("QInputDialog.getIte&m()") + + self.textLabel = QtWidgets.QLabel() + self.textLabel.setFrameStyle(frameStyle) + self.textButton = QtWidgets.QPushButton("QInputDialog.get&Text()") + + self.colorLabel = QtWidgets.QLabel() + self.colorLabel.setFrameStyle(frameStyle) + self.colorButton = QtWidgets.QPushButton("QColorDialog.get&Color()") + + self.fontLabel = QtWidgets.QLabel() + self.fontLabel.setFrameStyle(frameStyle) + self.fontButton = QtWidgets.QPushButton("QFontDialog.get&Font()") + + self.directoryLabel = QtWidgets.QLabel() + self.directoryLabel.setFrameStyle(frameStyle) + self.directoryButton = QtWidgets.QPushButton("QFileDialog.getE&xistingDirectory()") + + self.openFileNameLabel = QtWidgets.QLabel() + self.openFileNameLabel.setFrameStyle(frameStyle) + self.openFileNameButton = QtWidgets.QPushButton("QFileDialog.get&OpenFileName()") + + self.openFileNamesLabel = QtWidgets.QLabel() + self.openFileNamesLabel.setFrameStyle(frameStyle) + self.openFileNamesButton = QtWidgets.QPushButton("QFileDialog.&getOpenFileNames()") + + self.saveFileNameLabel = QtWidgets.QLabel() + self.saveFileNameLabel.setFrameStyle(frameStyle) + self.saveFileNameButton = QtWidgets.QPushButton("QFileDialog.get&SaveFileName()") + + self.criticalLabel = QtWidgets.QLabel() + self.criticalLabel.setFrameStyle(frameStyle) + self.criticalButton = QtWidgets.QPushButton("QMessageBox.critica&l()") + + self.informationLabel = QtWidgets.QLabel() + self.informationLabel.setFrameStyle(frameStyle) + self.informationButton = QtWidgets.QPushButton("QMessageBox.i&nformation()") + + self.questionLabel = QtWidgets.QLabel() + self.questionLabel.setFrameStyle(frameStyle) + self.questionButton = QtWidgets.QPushButton("QMessageBox.&question()") + + self.warningLabel = QtWidgets.QLabel() + self.warningLabel.setFrameStyle(frameStyle) + self.warningButton = QtWidgets.QPushButton("QMessageBox.&warning()") + + self.errorLabel = QtWidgets.QLabel() + self.errorLabel.setFrameStyle(frameStyle) + self.errorButton = QtWidgets.QPushButton("QErrorMessage.show&M&essage()") + + self.integerButton.clicked.connect(self.setInteger) + self.doubleButton.clicked.connect(self.setDouble) + self.itemButton.clicked.connect(self.setItem) + self.textButton.clicked.connect(self.setText) + self.colorButton.clicked.connect(self.setColor) + self.fontButton.clicked.connect(self.setFont) + self.directoryButton.clicked.connect(self.setExistingDirectory) + self.openFileNameButton.clicked.connect(self.setOpenFileName) + self.openFileNamesButton.clicked.connect(self.setOpenFileNames) + self.saveFileNameButton.clicked.connect(self.setSaveFileName) + self.criticalButton.clicked.connect(self.criticalMessage) + self.informationButton.clicked.connect(self.informationMessage) + self.questionButton.clicked.connect(self.questionMessage) + self.warningButton.clicked.connect(self.warningMessage) + self.errorButton.clicked.connect(self.errorMessage) + + self.native = QtWidgets.QCheckBox() + self.native.setText("Use native file dialog.") + self.native.setChecked(True) + if sys.platform not in ("win32", "darwin"): + self.native.hide() + + layout = QtWidgets.QGridLayout() + layout.setColumnStretch(1, 1) + layout.setColumnMinimumWidth(1, 250) + layout.addWidget(self.integerButton, 0, 0) + layout.addWidget(self.integerLabel, 0, 1) + layout.addWidget(self.doubleButton, 1, 0) + layout.addWidget(self.doubleLabel, 1, 1) + layout.addWidget(self.itemButton, 2, 0) + layout.addWidget(self.itemLabel, 2, 1) + layout.addWidget(self.textButton, 3, 0) + layout.addWidget(self.textLabel, 3, 1) + layout.addWidget(self.colorButton, 4, 0) + layout.addWidget(self.colorLabel, 4, 1) + layout.addWidget(self.fontButton, 5, 0) + layout.addWidget(self.fontLabel, 5, 1) + layout.addWidget(self.directoryButton, 6, 0) + layout.addWidget(self.directoryLabel, 6, 1) + layout.addWidget(self.openFileNameButton, 7, 0) + layout.addWidget(self.openFileNameLabel, 7, 1) + layout.addWidget(self.openFileNamesButton, 8, 0) + layout.addWidget(self.openFileNamesLabel, 8, 1) + layout.addWidget(self.saveFileNameButton, 9, 0) + layout.addWidget(self.saveFileNameLabel, 9, 1) + layout.addWidget(self.criticalButton, 10, 0) + layout.addWidget(self.criticalLabel, 10, 1) + layout.addWidget(self.informationButton, 11, 0) + layout.addWidget(self.informationLabel, 11, 1) + layout.addWidget(self.questionButton, 12, 0) + layout.addWidget(self.questionLabel, 12, 1) + layout.addWidget(self.warningButton, 13, 0) + layout.addWidget(self.warningLabel, 13, 1) + layout.addWidget(self.errorButton, 14, 0) + layout.addWidget(self.errorLabel, 14, 1) + layout.addWidget(self.native, 15, 0) + self.setLayout(layout) + + self.setWindowTitle("Standard Dialogs") + + def setInteger(self): + i, ok = QtWidgets.QInputDialog.getInt(self, + "QInputDialog.getInteger()", "Percentage:", 25, 0, 100, 1) + if ok: + self.integerLabel.setText("%d%%" % i) + + def setDouble(self): + d, ok = QtWidgets.QInputDialog.getDouble(self, "QInputDialog.getDouble()", + "Amount:", 37.56, -10000, 10000, 2) + if ok: + self.doubleLabel.setText("$%g" % d) + + def setItem(self): + items = ("Spring", "Summer", "Fall", "Winter") + + item, ok = QtWidgets.QInputDialog.getItem(self, "QInputDialog.getItem()", + "Season:", items, 0, False) + if ok and item: + self.itemLabel.setText(item) + + def setText(self): + text, ok = QtWidgets.QInputDialog.getText(self, "QInputDialog.getText()", + "User name:", QtWidgets.QLineEdit.Normal, + QtCore.QDir.home().dirName()) + if ok and text != '': + self.textLabel.setText(text) + + def setColor(self): + color = QtWidgets.QColorDialog.getColor(QtCore.Qt.green, self) + if color.isValid(): + self.colorLabel.setText(color.name()) + self.colorLabel.setPalette(QtGui.QPalette(color)) + self.colorLabel.setAutoFillBackground(True) + + def setFont(self): + ok, font = QtWidgets.QFontDialog.getFont(QtGui.QFont(self.fontLabel.text()), self) + if ok: + self.fontLabel.setText(font.key()) + self.fontLabel.setFont(font) + + def setExistingDirectory(self): + options = QtWidgets.QFileDialog.DontResolveSymlinks | QtWidgets.QFileDialog.ShowDirsOnly + directory = QtWidgets.QFileDialog.getExistingDirectory(self, + "QFileDialog.getExistingDirectory()", + self.directoryLabel.text(), options) + if directory: + self.directoryLabel.setText(directory) + + def setOpenFileName(self): + options = QtWidgets.QFileDialog.Options() + if not self.native.isChecked(): + options |= QtWidgets.QFileDialog.DontUseNativeDialog + fileName, filtr = QtWidgets.QFileDialog.getOpenFileName(self, + "QFileDialog.getOpenFileName()", + self.openFileNameLabel.text(), + "All Files (*);;Text Files (*.txt)", "", options) + if fileName: + self.openFileNameLabel.setText(fileName) + + def setOpenFileNames(self): + options = QtWidgets.QFileDialog.Options() + if not self.native.isChecked(): + options |= QtWidgets.QFileDialog.DontUseNativeDialog + files, filtr = QtWidgets.QFileDialog.getOpenFileNames(self, + "QFileDialog.getOpenFileNames()", self.openFilesPath, + "All Files (*);;Text Files (*.txt)", "", options) + if files: + self.openFilesPath = files[0] + self.openFileNamesLabel.setText("[%s]" % ', '.join(files)) + + def setSaveFileName(self): + options = QtWidgets.QFileDialog.Options() + if not self.native.isChecked(): + options |= QtWidgets.QFileDialog.DontUseNativeDialog + fileName, filtr = QtWidgets.QFileDialog.getSaveFileName(self, + "QFileDialog.getSaveFileName()", + self.saveFileNameLabel.text(), + "All Files (*);;Text Files (*.txt)", "", options) + if fileName: + self.saveFileNameLabel.setText(fileName) + + def criticalMessage(self): + reply = QtWidgets.QMessageBox.critical(self, "QMessageBox.critical()", + Dialog.MESSAGE, + QtWidgets.QMessageBox.Abort | QtWidgets.QMessageBox.Retry | QtWidgets.QMessageBox.Ignore) + if reply == QtWidgets.QMessageBox.Abort: + self.criticalLabel.setText("Abort") + elif reply == QtWidgets.QMessageBox.Retry: + self.criticalLabel.setText("Retry") + else: + self.criticalLabel.setText("Ignore") + + def informationMessage(self): + reply = QtWidgets.QMessageBox.information(self, + "QMessageBox.information()", Dialog.MESSAGE) + if reply == QtWidgets.QMessageBox.Ok: + self.informationLabel.setText("OK") + else: + self.informationLabel.setText("Escape") + + def questionMessage(self): + reply = QtWidgets.QMessageBox.question(self, "QMessageBox.question()", + Dialog.MESSAGE, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Cancel) + if reply == QtWidgets.QMessageBox.Yes: + self.questionLabel.setText("Yes") + elif reply == QtWidgets.QMessageBox.No: + self.questionLabel.setText("No") + else: + self.questionLabel.setText("Cancel") + + def warningMessage(self): + msgBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Warning, + "QMessageBox.warning()", Dialog.MESSAGE, + QtWidgets.QMessageBox.NoButton, self) + msgBox.addButton("Save &Again", QtWidgets.QMessageBox.AcceptRole) + msgBox.addButton("&Continue", QtWidgets.QMessageBox.RejectRole) + if msgBox.exec_() == QtWidgets.QMessageBox.AcceptRole: + self.warningLabel.setText("Save Again") + else: + self.warningLabel.setText("Continue") + + def errorMessage(self): + self.errorMessageDialog.showMessage("This dialog shows and remembers " + "error messages. If the checkbox is checked (as it is by " + "default), the shown message will be shown again, but if the " + "user unchecks the box the message will not appear again if " + "QErrorMessage.showMessage() is called with the same message.") + self.errorLabel.setText("If the box is unchecked, the message won't " + "appear again.") + + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + dialog = Dialog() + sys.exit(dialog.exec_()) diff --git a/examples/widgets/dialogs/trivialwizard.py b/examples/widgets/dialogs/trivialwizard.py new file mode 100644 index 0000000..80a3981 --- /dev/null +++ b/examples/widgets/dialogs/trivialwizard.py @@ -0,0 +1,112 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/dialogs/trivialwizard example from Qt v5.x""" + +from PySide2 import QtWidgets + + +def createIntroPage(): + page = QtWidgets.QWizardPage() + page.setTitle("Introduction") + + label = QtWidgets.QLabel("This wizard will help you register your copy of " + "Super Product Two.") + label.setWordWrap(True) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(label) + page.setLayout(layout) + + return page + + +def createRegistrationPage(): + page = QtWidgets.QWizardPage() + page.setTitle("Registration") + page.setSubTitle("Please fill both fields.") + + nameLabel = QtWidgets.QLabel("Name:") + nameLineEdit = QtWidgets.QLineEdit() + + emailLabel = QtWidgets.QLabel("Email address:") + emailLineEdit = QtWidgets.QLineEdit() + + layout = QtWidgets.QGridLayout() + layout.addWidget(nameLabel, 0, 0) + layout.addWidget(nameLineEdit, 0, 1) + layout.addWidget(emailLabel, 1, 0) + layout.addWidget(emailLineEdit, 1, 1) + page.setLayout(layout) + + return page + + +def createConclusionPage(): + page = QtWidgets.QWizardPage() + page.setTitle("Conclusion") + + label = QtWidgets.QLabel("You are now successfully registered. Have a nice day!") + label.setWordWrap(True) + + layout = QtWidgets.QVBoxLayout() + layout.addWidget(label) + page.setLayout(layout) + + return page + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + wizard = QtWidgets.QWizard() + wizard.addPage(createIntroPage()) + wizard.addPage(createRegistrationPage()) + wizard.addPage(createConclusionPage()) + + wizard.setWindowTitle("Trivial Wizard") + wizard.show() + + sys.exit(wizard.exec_()) diff --git a/examples/widgets/draganddrop/draggabletext/draggabletext.py b/examples/widgets/draganddrop/draggabletext/draggabletext.py new file mode 100644 index 0000000..77a40b1 --- /dev/null +++ b/examples/widgets/draganddrop/draggabletext/draggabletext.py @@ -0,0 +1,155 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/draganddrop/draggabletext example from Qt v5.x, originating from PyQt""" + +from PySide2.QtCore import QFile, QIODevice, QMimeData, QPoint, Qt, QTextStream +from PySide2.QtGui import QDrag, QPalette, QPixmap +from PySide2.QtWidgets import QApplication, QFrame, QLabel, QWidget + +import draggabletext_rc + + +class DragLabel(QLabel): + def __init__(self, text, parent): + super(DragLabel, self).__init__(text, parent) + + self.setAutoFillBackground(True) + self.setFrameShape(QFrame.Panel) + self.setFrameShadow(QFrame.Raised) + + def mousePressEvent(self, event): + hotSpot = event.pos() + + mimeData = QMimeData() + mimeData.setText(self.text()) + mimeData.setData('application/x-hotspot', + b'%d %d' % (hotSpot.x(), hotSpot.y())) + + pixmap = QPixmap(self.size()) + self.render(pixmap) + + drag = QDrag(self) + drag.setMimeData(mimeData) + drag.setPixmap(pixmap) + drag.setHotSpot(hotSpot) + + dropAction = drag.exec_(Qt.CopyAction | Qt.MoveAction, Qt.CopyAction) + + if dropAction == Qt.MoveAction: + self.close() + self.update() + + +class DragWidget(QWidget): + def __init__(self, parent=None): + super(DragWidget, self).__init__(parent) + + dictionaryFile = QFile(':/dictionary/words.txt') + dictionaryFile.open(QIODevice.ReadOnly) + + x = 5 + y = 5 + + for word in QTextStream(dictionaryFile).readAll().split(): + wordLabel = DragLabel(word, self) + wordLabel.move(x, y) + wordLabel.show() + x += wordLabel.width() + 2 + if x >= 195: + x = 5 + y += wordLabel.height() + 2 + + newPalette = self.palette() + newPalette.setColor(QPalette.Window, Qt.white) + self.setPalette(newPalette) + + self.setAcceptDrops(True) + self.setMinimumSize(400, max(200, y)) + self.setWindowTitle("Draggable Text") + + def dragEnterEvent(self, event): + if event.mimeData().hasText(): + if event.source() in self.children(): + event.setDropAction(Qt.MoveAction) + event.accept() + else: + event.acceptProposedAction() + else: + event.ignore() + + def dropEvent(self, event): + if event.mimeData().hasText(): + mime = event.mimeData() + pieces = mime.text().split() + position = event.pos() + hotSpot = QPoint() + + hotSpotPos = mime.data('application/x-hotspot').split(' ') + if len(hotSpotPos) == 2: + hotSpot.setX(hotSpotPos[0].toInt()[0]) + hotSpot.setY(hotSpotPos[1].toInt()[0]) + + for piece in pieces: + newLabel = DragLabel(piece, self) + newLabel.move(position - hotSpot) + newLabel.show() + + position += QPoint(newLabel.width(), 0) + + if event.source() in self.children(): + event.setDropAction(Qt.MoveAction) + event.accept() + else: + event.acceptProposedAction() + else: + event.ignore() + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + window = DragWidget() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/draganddrop/draggabletext/draggabletext.pyproject b/examples/widgets/draganddrop/draggabletext/draggabletext.pyproject new file mode 100644 index 0000000..0d42207 --- /dev/null +++ b/examples/widgets/draganddrop/draggabletext/draggabletext.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["draggabletext_rc.py", "words.txt", "draggabletext.qrc", + "draggabletext.py"] +} diff --git a/examples/widgets/draganddrop/draggabletext/draggabletext.qrc b/examples/widgets/draganddrop/draggabletext/draggabletext.qrc new file mode 100644 index 0000000..b72217d --- /dev/null +++ b/examples/widgets/draganddrop/draggabletext/draggabletext.qrc @@ -0,0 +1,5 @@ + + + words.txt + + diff --git a/examples/widgets/draganddrop/draggabletext/draggabletext_rc.py b/examples/widgets/draganddrop/draggabletext/draggabletext_rc.py new file mode 100644 index 0000000..c05e317 --- /dev/null +++ b/examples/widgets/draganddrop/draggabletext/draggabletext_rc.py @@ -0,0 +1,55 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x00\xf7\ +Q\ +t\x0aQuarterly\x0ais\x0aa\ +\x0apaper\x0abased\x0anew\ +sletter\x0aexclusiv\ +ely\x0aavailable\x0ato\ +\x0aQt\x0acustomers\x0aEv\ +ery\x0aquarter\x0awe\x0am\ +ail\x0aout\x0aan\x0aissue\ +\x0athat\x0awe\x0ahope\x0awi\ +ll\x0abring\x0aadded\x0ai\ +nsight\x0aand\x0apleas\ +ure\x0ato\x0ayour\x0aQt\x0ap\ +rogramming\x0awith\x0a\ +high\x0aquality\x0atec\ +hnical\x0aarticles\x0a\ +written\x0aby\x0aQt\x0aex\ +perts\x0a\ +" + +qt_resource_name = b"\ +\x00\x0a\ +\x0b\x0b\x17\xd9\ +\x00d\ +\x00i\x00c\x00t\x00i\x00o\x00n\x00a\x00r\x00y\ +\x00\x09\ +\x08\xb6\xa74\ +\x00w\ +\x00o\x00r\x00d\x00s\x00.\x00t\x00x\x00t\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/draganddrop/draggabletext/words.txt b/examples/widgets/draganddrop/draggabletext/words.txt new file mode 100644 index 0000000..19b8b03 --- /dev/null +++ b/examples/widgets/draganddrop/draggabletext/words.txt @@ -0,0 +1,41 @@ +Qt +Quarterly +is +a +paper +based +newsletter +exclusively +available +to +Qt +customers +Every +quarter +we +mail +out +an +issue +that +we +hope +will +bring +added +insight +and +pleasure +to +your +Qt +programming +with +high +quality +technical +articles +written +by +Qt +experts diff --git a/examples/widgets/effects/effects.pyproject b/examples/widgets/effects/effects.pyproject new file mode 100644 index 0000000..c64fe46 --- /dev/null +++ b/examples/widgets/effects/effects.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["lighting.py"] +} diff --git a/examples/widgets/effects/lighting.py b/examples/widgets/effects/lighting.py new file mode 100644 index 0000000..596db4e --- /dev/null +++ b/examples/widgets/effects/lighting.py @@ -0,0 +1,144 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import math + +from PySide2 import QtCore, QtGui, QtWidgets + + +class Lighting(QtWidgets.QGraphicsView): + def __init__(self, parent=None): + super(Lighting, self).__init__(parent) + + self.angle = 0.0 + self.m_scene = QtWidgets.QGraphicsScene() + self.m_lightSource = None + self.m_items = [] + + self.setScene(self.m_scene) + + self.setupScene() + + timer = QtCore.QTimer(self) + timer.timeout.connect(self.animate) + timer.setInterval(30) + timer.start() + + self.setRenderHint(QtGui.QPainter.Antialiasing) + self.setFrameStyle(QtWidgets.QFrame.NoFrame) + + def setupScene(self): + self.m_scene.setSceneRect(-300, -200, 600, 460) + + linearGrad = QtGui.QLinearGradient(QtCore.QPointF(-100, -100), + QtCore.QPointF(100, 100)) + linearGrad.setColorAt(0, QtGui.QColor(255, 255, 255)) + linearGrad.setColorAt(1, QtGui.QColor(192, 192, 255)) + self.setBackgroundBrush(linearGrad) + + radialGrad = QtGui.QRadialGradient(30, 30, 30) + radialGrad.setColorAt(0, QtCore.Qt.yellow) + radialGrad.setColorAt(0.2, QtCore.Qt.yellow) + radialGrad.setColorAt(1, QtCore.Qt.transparent) + + pixmap = QtGui.QPixmap(60, 60) + pixmap.fill(QtCore.Qt.transparent) + + painter = QtGui.QPainter(pixmap) + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(radialGrad) + painter.drawEllipse(0, 0, 60, 60) + painter.end() + + self.m_lightSource = self.m_scene.addPixmap(pixmap) + self.m_lightSource.setZValue(2) + + for i in range(-2, 3): + for j in range(-2, 3): + if (i + j) & 1: + item = QtWidgets.QGraphicsEllipseItem(0, 0, 50, 50) + else: + item = QtWidgets.QGraphicsRectItem(0, 0, 50, 50) + + item.setPen(QtGui.QPen(QtCore.Qt.black, 1)) + item.setBrush(QtGui.QBrush(QtCore.Qt.white)) + + effect = QtWidgets.QGraphicsDropShadowEffect(self) + effect.setBlurRadius(8) + item.setGraphicsEffect(effect) + item.setZValue(1) + item.setPos(i * 80, j * 80) + self.m_scene.addItem(item) + self.m_items.append(item) + + def animate(self): + self.angle += (math.pi / 30) + xs = 200 * math.sin(self.angle) - 40 + 25 + ys = 200 * math.cos(self.angle) - 40 + 25 + self.m_lightSource.setPos(xs, ys) + + for item in self.m_items: + effect = item.graphicsEffect() + + delta = QtCore.QPointF(item.x() - xs, item.y() - ys) + effect.setOffset(QtCore.QPointF(delta.toPoint() / 30)) + + dd = math.hypot(delta.x(), delta.y()) + color = effect.color() + color.setAlphaF(max(0.4, min(1 - dd / 200.0, 0.7))) + effect.setColor(color) + + self.m_scene.update() + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + lighting = Lighting() + lighting.setWindowTitle("Lighting and Shadows") + lighting.resize(640, 480) + lighting.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/gallery/gallery.pyproject b/examples/widgets/gallery/gallery.pyproject new file mode 100644 index 0000000..635e123 --- /dev/null +++ b/examples/widgets/gallery/gallery.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "widgetgallery.py"] +} diff --git a/examples/widgets/gallery/main.py b/examples/widgets/gallery/main.py new file mode 100644 index 0000000..11f1920 --- /dev/null +++ b/examples/widgets/gallery/main.py @@ -0,0 +1,56 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/gallery example from Qt v5.15""" + +import sys + +from PySide2.QtCore import QCoreApplication, Qt +from PySide2.QtWidgets import QApplication +from widgetgallery import WidgetGallery + + +if __name__ == '__main__': + QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) + app = QApplication() + gallery = WidgetGallery() + gallery.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/gallery/widgetgallery.py b/examples/widgets/gallery/widgetgallery.py new file mode 100644 index 0000000..a06ac2e --- /dev/null +++ b/examples/widgets/gallery/widgetgallery.py @@ -0,0 +1,429 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +from PySide2.QtWidgets import * +from PySide2.QtGui import (QCursor, QDesktopServices, QGuiApplication, QIcon, + QKeySequence, QStandardItem, QStandardItemModel, + QScreen, QWindow) +from PySide2.QtCore import (QDateTime, QDir, QLibraryInfo, QMetaObject, + QSysInfo, QTextStream, QTimer, Qt, qVersion) + + +POEM = """Twinkle, twinkle, little star, +How I wonder what you are. +Up above the world so high, +Like a diamond in the sky. +Twinkle, twinkle, little star, +How I wonder what you arenot""" + +DIR_OPEN_ICON = ":/qt-project.org/styles/commonstyle/images/diropen-128.png" + +COMPUTER_ICON = ":/qt-project.org/styles/commonstyle/images/computer-32.png" + +SYSTEMINFO = """ +

Python

{}

+

Qt Build

{}

+

Operating System

{}

+

Screens

+{} +""" + + +def class_name(o): + return o.metaObject().className() + + +def help_url(page): + """Build a Qt help URL from the page name""" + major_version = qVersion().split('.')[0] + return "https://doc.qt.io/qt-{}/{}.html".format(major_version, page) + + +def launch_help(widget): + """Launch a widget's help page""" + url = help_url(class_name(widget).lower()) + QDesktopServices.openUrl(url) + + +def launch_module_help(): + QDesktopServices.openUrl(help_url("qtwidgets-index")) + + +def init_widget(w, name): + """Init a widget for the gallery, give it a tooltip showing the + class name""" + w.setObjectName(name) + w.setToolTip(class_name(w)) + + +def style_names(): + """Return a list of styles, default platform style first""" + default_style_name = QApplication.style().objectName().lower() + result = [] + for style in QStyleFactory.keys(): + if style.lower() == default_style_name: + result.insert(0, style) + else: + result.append(style) + return result + + +def embed_into_hbox_layout(w, margin=5): + """Embed a widget into a layout to give it a frame""" + result = QWidget() + layout = QHBoxLayout(result) + layout.setContentsMargins(margin, margin, margin, margin) + layout.addWidget(w) + return result + + +def format_geometry(rect): + """Format a geometry as a X11 geometry specification""" + return "{}x{}{:+d}{:+d}".format(rect.width(), rect.height(), + rect.x(), rect.y()) + + +def screen_info(widget): + """Format information on the screens""" + policy = QGuiApplication.highDpiScaleFactorRoundingPolicy() + policy_string = str(policy).split('.')[-1] + result = "

High DPI scale factor rounding policy: {}

    ".format(policy_string) + for screen in QGuiApplication.screens(): + current = screen == widget.screen() + result += "
  1. " + if current: + result += "" + result += '"{}" {} {}DPI, DPR={}'.format(screen.name(), + format_geometry(screen.geometry()), + int(screen.logicalDotsPerInchX()), + screen.devicePixelRatio()) + if current: + result += "" + result += "
  2. " + result += "
" + return result + + +class WidgetGallery(QDialog): + """Dialog displaying a gallery of Qt Widgets""" + + def __init__(self): + super(WidgetGallery, self).__init__() + + self._progress_bar = self.create_progress_bar() + + self._style_combobox = QComboBox() + init_widget(self._style_combobox, "styleComboBox") + self._style_combobox.addItems(style_names()) + + style_label = QLabel("Style:") + init_widget(style_label, "style_label") + style_label.setBuddy(self._style_combobox) + + help_label = QLabel("Press F1 over a widget to see Documentation") + init_widget(help_label, "help_label") + + disable_widgets_checkbox = QCheckBox("Disable widgets") + init_widget(disable_widgets_checkbox, "disable_widgets_checkbox") + + buttons_groupbox = self.create_buttons_groupbox() + itemview_tabwidget = self.create_itemview_tabwidget() + simple_input_widgets_groupbox = self.create_simple_inputwidgets_groupbox() + text_toolbox = self.create_text_toolbox() + + self._style_combobox.textActivated.connect(self.change_style) + disable_widgets_checkbox.toggled.connect(buttons_groupbox.setDisabled) + disable_widgets_checkbox.toggled.connect(text_toolbox.setDisabled) + disable_widgets_checkbox.toggled.connect(itemview_tabwidget.setDisabled) + disable_widgets_checkbox.toggled.connect(simple_input_widgets_groupbox.setDisabled) + + help_shortcut = QShortcut(self) + help_shortcut.setKey(QKeySequence.HelpContents) + help_shortcut.activated.connect(self.help_on_current_widget) + + top_layout = QHBoxLayout() + top_layout.addWidget(style_label) + top_layout.addWidget(self._style_combobox) + top_layout.addStretch(1) + top_layout.addWidget(help_label) + top_layout.addStretch(1) + top_layout.addWidget(disable_widgets_checkbox) + + dialog_buttonbox = QDialogButtonBox(QDialogButtonBox.Help | + QDialogButtonBox.Close) + init_widget(dialog_buttonbox, "dialogButtonBox") + dialog_buttonbox.helpRequested.connect(launch_module_help) + dialog_buttonbox.rejected.connect(self.reject) + + main_layout = QGridLayout(self) + main_layout.addLayout(top_layout, 0, 0, 1, 2) + main_layout.addWidget(buttons_groupbox, 1, 0) + main_layout.addWidget(simple_input_widgets_groupbox, 1, 1) + main_layout.addWidget(itemview_tabwidget, 2, 0) + main_layout.addWidget(text_toolbox, 2, 1) + main_layout.addWidget(self._progress_bar, 3, 0, 1, 2) + main_layout.addWidget(dialog_buttonbox, 4, 0, 1, 2) + + self.setWindowTitle("Widget Gallery Qt {}".format(qVersion())) + + def setVisible(self, visible): + super(WidgetGallery, self).setVisible(visible) + if visible: + self.windowHandle().screenChanged.connect(self.update_systeminfo) + self.update_systeminfo() + + def change_style(self, style_name): + QApplication.setStyle(QStyleFactory.create(style_name)) + + def advance_progressbar(self): + cur_val = self._progress_bar.value() + max_val = self._progress_bar.maximum() + self._progress_bar.setValue(cur_val + (max_val - cur_val) / 100) + + def create_buttons_groupbox(self): + result = QGroupBox("Buttons") + init_widget(result, "buttons_groupbox") + + default_pushbutton = QPushButton("Default Push Button") + init_widget(default_pushbutton, "default_pushbutton") + default_pushbutton.setDefault(True) + + toggle_pushbutton = QPushButton("Toggle Push Button") + init_widget(toggle_pushbutton, "toggle_pushbutton") + toggle_pushbutton.setCheckable(True) + toggle_pushbutton.setChecked(True) + + flat_pushbutton = QPushButton("Flat Push Button") + init_widget(flat_pushbutton, "flat_pushbutton") + flat_pushbutton.setFlat(True) + + toolbutton = QToolButton() + init_widget(toolbutton, "toolButton") + toolbutton.setText("Tool Button") + + menu_toolbutton = QToolButton() + init_widget(menu_toolbutton, "menuButton") + menu_toolbutton.setText("Menu Button") + tool_menu = QMenu(menu_toolbutton) + menu_toolbutton.setPopupMode(QToolButton.InstantPopup) + tool_menu.addAction("Option") + tool_menu.addSeparator() + action = tool_menu.addAction("Checkable Option") + action.setCheckable(True) + menu_toolbutton.setMenu(tool_menu) + tool_layout = QHBoxLayout() + tool_layout.addWidget(toolbutton) + tool_layout.addWidget(menu_toolbutton) + + commandlinkbutton = QCommandLinkButton("Command Link Button") + init_widget(commandlinkbutton, "commandLinkButton") + commandlinkbutton.setDescription("Description") + + button_layout = QVBoxLayout() + button_layout.addWidget(default_pushbutton) + button_layout.addWidget(toggle_pushbutton) + button_layout.addWidget(flat_pushbutton) + button_layout.addLayout(tool_layout) + button_layout.addWidget(commandlinkbutton) + button_layout.addStretch(1) + + radiobutton_1 = QRadioButton("Radio button 1") + init_widget(radiobutton_1, "radioButton1") + radiobutton_2 = QRadioButton("Radio button 2") + init_widget(radiobutton_2, "radioButton2") + radiobutton_3 = QRadioButton("Radio button 3") + init_widget(radiobutton_3, "radioButton3") + radiobutton_1.setChecked(True) + + checkbox = QCheckBox("Tri-state check box") + init_widget(checkbox, "checkBox") + checkbox.setTristate(True) + checkbox.setCheckState(Qt.PartiallyChecked) + + checkableLayout = QVBoxLayout() + checkableLayout.addWidget(radiobutton_1) + checkableLayout.addWidget(radiobutton_2) + checkableLayout.addWidget(radiobutton_3) + checkableLayout.addWidget(checkbox) + checkableLayout.addStretch(1) + + main_layout = QHBoxLayout(result) + main_layout.addLayout(button_layout) + main_layout.addLayout(checkableLayout) + main_layout.addStretch() + return result + + def create_text_toolbox(self): + result = QToolBox() + init_widget(result, "toolBox") + + # Create centered/italic HTML rich text + rich_text = "" + for line in POEM.split('\n'): + rich_text += "
" + line + "
" + rich_text += "
" + + text_edit = QTextEdit(rich_text) + init_widget(text_edit, "textEdit") + plain_textedit = QPlainTextEdit(POEM) + init_widget(plain_textedit, "plainTextEdit") + + self._systeminfo_textbrowser = QTextBrowser() + init_widget(self._systeminfo_textbrowser, "systemInfoTextBrowser") + + result.addItem(embed_into_hbox_layout(text_edit), "Text Edit") + result.addItem(embed_into_hbox_layout(plain_textedit), + "Plain Text Edit") + result.addItem(embed_into_hbox_layout(self._systeminfo_textbrowser), + "Text Browser") + return result + + def create_itemview_tabwidget(self): + result = QTabWidget() + init_widget(result, "bottomLeftTabWidget") + result.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.Ignored) + + tree_view = QTreeView() + init_widget(tree_view, "treeView") + filesystem_model = QFileSystemModel(tree_view) + filesystem_model.setRootPath(QDir.rootPath()) + tree_view.setModel(filesystem_model) + + table_widget = QTableWidget() + init_widget(table_widget, "tableWidget") + table_widget.setRowCount(10) + table_widget.setColumnCount(10) + + list_model = QStandardItemModel(0, 1, result) + + list_model.appendRow(QStandardItem(QIcon(DIR_OPEN_ICON), "Directory")) + list_model.appendRow(QStandardItem(QIcon(COMPUTER_ICON), "Computer")) + + list_view = QListView() + init_widget(list_view, "listView") + list_view.setModel(list_model) + + icon_mode_listview = QListView() + init_widget(icon_mode_listview, "iconModeListView") + + icon_mode_listview.setViewMode(QListView.IconMode) + icon_mode_listview.setModel(list_model) + + result.addTab(embed_into_hbox_layout(tree_view), "Tree View") + result.addTab(embed_into_hbox_layout(table_widget), "Table") + result.addTab(embed_into_hbox_layout(list_view), "List") + result.addTab(embed_into_hbox_layout(icon_mode_listview), + "Icon Mode List") + return result + + def create_simple_inputwidgets_groupbox(self): + result = QGroupBox("Simple Input Widgets") + init_widget(result, "bottomRightGroupBox") + result.setCheckable(True) + result.setChecked(True) + + lineedit = QLineEdit("s3cRe7") + init_widget(lineedit, "lineEdit") + lineedit.setClearButtonEnabled(True) + lineedit.setEchoMode(QLineEdit.Password) + + spin_box = QSpinBox() + init_widget(spin_box, "spinBox") + spin_box.setValue(50) + + date_timeedit = QDateTimeEdit() + init_widget(date_timeedit, "dateTimeEdit") + date_timeedit.setDateTime(QDateTime.currentDateTime()) + + slider = QSlider() + init_widget(slider, "slider") + slider.setOrientation(Qt.Horizontal) + slider.setValue(40) + + scrollbar = QScrollBar() + init_widget(scrollbar, "scrollBar") + scrollbar.setOrientation(Qt.Horizontal) + scrollbar.setValue(60) + + dial = QDial() + init_widget(dial, "dial") + dial.setValue(30) + dial.setNotchesVisible(True) + + layout = QGridLayout(result) + layout.addWidget(lineedit, 0, 0, 1, 2) + layout.addWidget(spin_box, 1, 0, 1, 2) + layout.addWidget(date_timeedit, 2, 0, 1, 2) + layout.addWidget(slider, 3, 0) + layout.addWidget(scrollbar, 4, 0) + layout.addWidget(dial, 3, 1, 2, 1) + layout.setRowStretch(5, 1) + return result + + def create_progress_bar(self): + result = QProgressBar() + init_widget(result, "progressBar") + result.setRange(0, 10000) + result.setValue(0) + + timer = QTimer(self) + timer.timeout.connect(self.advance_progressbar) + timer.start(1000) + return result + + def update_systeminfo(self): + """Display system information""" + system_info = SYSTEMINFO.format(sys.version, + QLibraryInfo.build(), + QSysInfo.prettyProductName(), + screen_info(self)) + self._systeminfo_textbrowser.setHtml(system_info) + + def help_on_current_widget(self): + """Display help on widget under mouse""" + w = QApplication.widgetAt(QCursor.pos(self.screen())) + while w: # Skip over internal widgets + name = w.objectName() + if name and not name.startswith("qt_"): + launch_help(w) + break + w = w.parentWidget() diff --git a/examples/widgets/graphicsview/anchorlayout.py b/examples/widgets/graphicsview/anchorlayout.py new file mode 100644 index 0000000..f7f4edc --- /dev/null +++ b/examples/widgets/graphicsview/anchorlayout.py @@ -0,0 +1,125 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +def createItem(minimum, preferred, maximum, name): + w = QtWidgets.QGraphicsProxyWidget() + + w.setWidget(QtWidgets.QPushButton(name)) + w.setMinimumSize(minimum) + w.setPreferredSize(preferred) + w.setMaximumSize(maximum) + w.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) + + return w + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + scene = QtWidgets.QGraphicsScene() + scene.setSceneRect(0, 0, 800, 480) + + minSize = QtCore.QSizeF(30, 100) + prefSize = QtCore.QSizeF(210, 100) + maxSize = QtCore.QSizeF(300, 100) + + a = createItem(minSize, prefSize, maxSize, "A") + b = createItem(minSize, prefSize, maxSize, "B") + c = createItem(minSize, prefSize, maxSize, "C") + d = createItem(minSize, prefSize, maxSize, "D") + e = createItem(minSize, prefSize, maxSize, "E") + f = createItem(QtCore.QSizeF(30, 50), QtCore.QSizeF(150, 50), maxSize, "F") + g = createItem(QtCore.QSizeF(30, 50), QtCore.QSizeF(30, 100), maxSize, "G") + + l = QtWidgets.QGraphicsAnchorLayout() + l.setSpacing(0) + + w = QtWidgets.QGraphicsWidget(None, QtCore.Qt.Window) + w.setPos(20, 20) + w.setLayout(l) + + # Vertical. + l.addAnchor(a, QtCore.Qt.AnchorTop, l, QtCore.Qt.AnchorTop) + l.addAnchor(b, QtCore.Qt.AnchorTop, l, QtCore.Qt.AnchorTop) + + l.addAnchor(c, QtCore.Qt.AnchorTop, a, QtCore.Qt.AnchorBottom) + l.addAnchor(c, QtCore.Qt.AnchorTop, b, QtCore.Qt.AnchorBottom) + l.addAnchor(c, QtCore.Qt.AnchorBottom, d, QtCore.Qt.AnchorTop) + l.addAnchor(c, QtCore.Qt.AnchorBottom, e, QtCore.Qt.AnchorTop) + + l.addAnchor(d, QtCore.Qt.AnchorBottom, l, QtCore.Qt.AnchorBottom) + l.addAnchor(e, QtCore.Qt.AnchorBottom, l, QtCore.Qt.AnchorBottom) + + l.addAnchor(c, QtCore.Qt.AnchorTop, f, QtCore.Qt.AnchorTop) + l.addAnchor(c, QtCore.Qt.AnchorVerticalCenter, f, QtCore.Qt.AnchorBottom) + l.addAnchor(f, QtCore.Qt.AnchorBottom, g, QtCore.Qt.AnchorTop) + l.addAnchor(c, QtCore.Qt.AnchorBottom, g, QtCore.Qt.AnchorBottom) + + # Horizontal. + l.addAnchor(l, QtCore.Qt.AnchorLeft, a, QtCore.Qt.AnchorLeft) + l.addAnchor(l, QtCore.Qt.AnchorLeft, d, QtCore.Qt.AnchorLeft) + l.addAnchor(a, QtCore.Qt.AnchorRight, b, QtCore.Qt.AnchorLeft) + + l.addAnchor(a, QtCore.Qt.AnchorRight, c, QtCore.Qt.AnchorLeft) + l.addAnchor(c, QtCore.Qt.AnchorRight, e, QtCore.Qt.AnchorLeft) + + l.addAnchor(b, QtCore.Qt.AnchorRight, l, QtCore.Qt.AnchorRight) + l.addAnchor(e, QtCore.Qt.AnchorRight, l, QtCore.Qt.AnchorRight) + l.addAnchor(d, QtCore.Qt.AnchorRight, e, QtCore.Qt.AnchorLeft) + + l.addAnchor(l, QtCore.Qt.AnchorLeft, f, QtCore.Qt.AnchorLeft) + l.addAnchor(l, QtCore.Qt.AnchorLeft, g, QtCore.Qt.AnchorLeft) + l.addAnchor(f, QtCore.Qt.AnchorRight, g, QtCore.Qt.AnchorRight) + + scene.addItem(w) + scene.setBackgroundBrush(QtCore.Qt.darkGreen) + + view = QtWidgets.QGraphicsView(scene) + view.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/graphicsview/collidingmice/collidingmice.py b/examples/widgets/graphicsview/collidingmice/collidingmice.py new file mode 100644 index 0000000..2203cb3 --- /dev/null +++ b/examples/widgets/graphicsview/collidingmice/collidingmice.py @@ -0,0 +1,218 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import math + +from PySide2 import QtCore, QtGui, QtWidgets + +import mice_rc + + +def random(boundary): + return QtCore.QRandomGenerator.global_().bounded(boundary) + + +class Mouse(QtWidgets.QGraphicsItem): + Pi = math.pi + TwoPi = 2.0 * Pi + + # Create the bounding rectangle once. + adjust = 0.5 + BoundingRect = QtCore.QRectF(-20 - adjust, -22 - adjust, 40 + adjust, + 83 + adjust) + + def __init__(self): + super(Mouse, self).__init__() + + self.angle = 0.0 + self.speed = 0.0 + self.mouseEyeDirection = 0.0 + self.color = QtGui.QColor(random(256), random(256), random(256)) + + self.setTransform(QtGui.QTransform().rotate(random(360 * 16))) + + # In the C++ version of this example, this class is also derived from + # QObject in order to receive timer events. PySide2 does not support + # deriving from more than one wrapped class so we just create an + # explicit timer instead. + self.timer = QtCore.QTimer() + self.timer.timeout.connect(self.timerEvent) + self.timer.start(1000 / 33) + + @staticmethod + def normalizeAngle(angle): + while angle < 0: + angle += Mouse.TwoPi + while angle > Mouse.TwoPi: + angle -= Mouse.TwoPi + return angle + + def boundingRect(self): + return Mouse.BoundingRect + + def shape(self): + path = QtGui.QPainterPath() + path.addRect(-10, -20, 20, 40) + return path + + def paint(self, painter, option, widget): + # Body. + painter.setBrush(self.color) + painter.drawEllipse(-10, -20, 20, 40) + + # Eyes. + painter.setBrush(QtCore.Qt.white) + painter.drawEllipse(-10, -17, 8, 8) + painter.drawEllipse(2, -17, 8, 8) + + # Nose. + painter.setBrush(QtCore.Qt.black) + painter.drawEllipse(QtCore.QRectF(-2, -22, 4, 4)) + + # Pupils. + painter.drawEllipse(QtCore.QRectF(-8.0 + self.mouseEyeDirection, -17, 4, 4)) + painter.drawEllipse(QtCore.QRectF(4.0 + self.mouseEyeDirection, -17, 4, 4)) + + # Ears. + if self.scene().collidingItems(self): + painter.setBrush(QtCore.Qt.red) + else: + painter.setBrush(QtCore.Qt.darkYellow) + + painter.drawEllipse(-17, -12, 16, 16) + painter.drawEllipse(1, -12, 16, 16) + + # Tail. + path = QtGui.QPainterPath(QtCore.QPointF(0, 20)) + path.cubicTo(-5, 22, -5, 22, 0, 25) + path.cubicTo(5, 27, 5, 32, 0, 30) + path.cubicTo(-5, 32, -5, 42, 0, 35) + painter.setBrush(QtCore.Qt.NoBrush) + painter.drawPath(path) + + def timerEvent(self): + # Don't move too far away. + lineToCenter = QtCore.QLineF(QtCore.QPointF(0, 0), self.mapFromScene(0, 0)) + if lineToCenter.length() > 150: + angleToCenter = math.acos(lineToCenter.dx() / lineToCenter.length()) + if lineToCenter.dy() < 0: + angleToCenter = Mouse.TwoPi - angleToCenter + angleToCenter = Mouse.normalizeAngle((Mouse.Pi - angleToCenter) + Mouse.Pi / 2) + + if angleToCenter < Mouse.Pi and angleToCenter > Mouse.Pi / 4: + # Rotate left. + self.angle += [-0.25, 0.25][self.angle < -Mouse.Pi / 2] + elif angleToCenter >= Mouse.Pi and angleToCenter < (Mouse.Pi + Mouse.Pi / 2 + Mouse.Pi / 4): + # Rotate right. + self.angle += [-0.25, 0.25][self.angle < Mouse.Pi / 2] + elif math.sin(self.angle) < 0: + self.angle += 0.25 + elif math.sin(self.angle) > 0: + self.angle -= 0.25 + + # Try not to crash with any other mice. + dangerMice = self.scene().items(QtGui.QPolygonF([self.mapToScene(0, 0), + self.mapToScene(-30, -50), + self.mapToScene(30, -50)])) + + for item in dangerMice: + if item is self: + continue + + lineToMouse = QtCore.QLineF(QtCore.QPointF(0, 0), self.mapFromItem(item, 0, 0)) + angleToMouse = math.acos(lineToMouse.dx() / lineToMouse.length()) + if lineToMouse.dy() < 0: + angleToMouse = Mouse.TwoPi - angleToMouse + angleToMouse = Mouse.normalizeAngle((Mouse.Pi - angleToMouse) + Mouse.Pi / 2) + + if angleToMouse >= 0 and angleToMouse < Mouse.Pi / 2: + # Rotate right. + self.angle += 0.5 + elif angleToMouse <= Mouse.TwoPi and angleToMouse > (Mouse.TwoPi - Mouse.Pi / 2): + # Rotate left. + self.angle -= 0.5 + + # Add some random movement. + if len(dangerMice) > 1 and (QtCore.qrand() % 10) == 0: + if QtCore.qrand() % 1: + self.angle += random(100) / 500.0 + else: + self.angle -= random(100) / 500.0 + + self.speed += (-50 + random(100)) / 100.0 + + dx = math.sin(self.angle) * 10 + self.mouseEyeDirection = [dx / 5, 0.0][QtCore.qAbs(dx / 5) < 1] + + self.setTransform(QtGui.QTransform().rotate(dx)) + self.setPos(self.mapToParent(0, -(3 + math.sin(self.speed) * 3))) + + +if __name__ == '__main__': + + import sys + + MouseCount = 7 + + app = QtWidgets.QApplication(sys.argv) + + scene = QtWidgets.QGraphicsScene() + scene.setSceneRect(-300, -300, 600, 600) + scene.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex) + + for i in range(MouseCount): + mouse = Mouse() + mouse.setPos(math.sin((i * 6.28) / MouseCount) * 200, + math.cos((i * 6.28) / MouseCount) * 200) + scene.addItem(mouse) + + view = QtWidgets.QGraphicsView(scene) + view.setRenderHint(QtGui.QPainter.Antialiasing) + view.setBackgroundBrush(QtGui.QBrush(QtGui.QPixmap(':/images/cheese.jpg'))) + view.setCacheMode(QtWidgets.QGraphicsView.CacheBackground) + view.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate) + view.setDragMode(QtWidgets.QGraphicsView.ScrollHandDrag) + view.setWindowTitle("Colliding Mice") + view.resize(400, 300) + view.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/graphicsview/collidingmice/collidingmice.pyproject b/examples/widgets/graphicsview/collidingmice/collidingmice.pyproject new file mode 100644 index 0000000..ea58218 --- /dev/null +++ b/examples/widgets/graphicsview/collidingmice/collidingmice.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["collidingmice.py", "mice_rc.py"] +} diff --git a/examples/widgets/graphicsview/collidingmice/mice_rc.py b/examples/widgets/graphicsview/collidingmice/mice_rc.py new file mode 100644 index 0000000..e9042a0 --- /dev/null +++ b/examples/widgets/graphicsview/collidingmice/mice_rc.py @@ -0,0 +1,271 @@ +# -*- coding: utf-8 -*- + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# Resource object code +# +# Created: Fri Jul 30 17:52:15 2010 +# by: The Resource Compiler for PySide (Qt v4.6.2) +# +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x0b\xd5\ +\xff\ +\xd8\xff\xe0\x00\x10\x4a\x46\x49\x46\x00\x01\x02\x01\x00\x48\x00\ +\x48\x00\x00\xff\xee\x00\x0e\x41\x64\x6f\x62\x65\x00\x64\x40\x00\ +\x00\x00\x01\xff\xdb\x00\x84\x00\x02\x02\x02\x02\x02\x02\x02\x02\ +\x02\x02\x03\x02\x02\x02\x03\x04\x03\x02\x02\x03\x04\x05\x04\x04\ +\x04\x04\x04\x05\x06\x05\x05\x05\x05\x05\x05\x06\x06\x07\x07\x08\ +\x07\x07\x06\x09\x09\x0a\x0a\x09\x09\x0c\x0c\x0c\x0c\x0c\x0c\x0c\ +\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x01\x03\x03\x03\x05\x04\x05\x09\ +\x06\x06\x09\x0d\x0a\x09\x0a\x0d\x0f\x0e\x0e\x0e\x0e\x0f\x0f\x0c\ +\x0c\x0c\x0c\x0c\x0f\x0f\x0c\x0c\x0c\x0c\x0c\x0c\x0f\x0c\x0c\x0c\ +\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\ +\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\xff\xc0\x00\x11\x08\x00\x5e\ +\x00\x5e\x03\x01\x11\x00\x02\x11\x01\x03\x11\x01\xff\xdd\x00\x04\ +\x00\x0c\xff\xc4\x01\xa2\x00\x00\x00\x07\x01\x01\x01\x01\x01\x00\ +\x00\x00\x00\x00\x00\x00\x00\x04\x05\x03\x02\x06\x01\x00\x07\x08\ +\x09\x0a\x0b\x01\x00\x02\x02\x03\x01\x01\x01\x01\x01\x00\x00\x00\ +\x00\x00\x00\x00\x01\x00\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\ +\x10\x00\x02\x01\x03\x03\x02\x04\x02\x06\x07\x03\x04\x02\x06\x02\ +\x73\x01\x02\x03\x11\x04\x00\x05\x21\x12\x31\x41\x51\x06\x13\x61\ +\x22\x71\x81\x14\x32\x91\xa1\x07\x15\xb1\x42\x23\xc1\x52\xd1\xe1\ +\x33\x16\x62\xf0\x24\x72\x82\xf1\x25\x43\x34\x53\x92\xa2\xb2\x63\ +\x73\xc2\x35\x44\x27\x93\xa3\xb3\x36\x17\x54\x64\x74\xc3\xd2\xe2\ +\x08\x26\x83\x09\x0a\x18\x19\x84\x94\x45\x46\xa4\xb4\x56\xd3\x55\ +\x28\x1a\xf2\xe3\xf3\xc4\xd4\xe4\xf4\x65\x75\x85\x95\xa5\xb5\xc5\ +\xd5\xe5\xf5\x66\x76\x86\x96\xa6\xb6\xc6\xd6\xe6\xf6\x37\x47\x57\ +\x67\x77\x87\x97\xa7\xb7\xc7\xd7\xe7\xf7\x38\x48\x58\x68\x78\x88\ +\x98\xa8\xb8\xc8\xd8\xe8\xf8\x29\x39\x49\x59\x69\x79\x89\x99\xa9\ +\xb9\xc9\xd9\xe9\xf9\x2a\x3a\x4a\x5a\x6a\x7a\x8a\x9a\xaa\xba\xca\ +\xda\xea\xfa\x11\x00\x02\x02\x01\x02\x03\x05\x05\x04\x05\x06\x04\ +\x08\x03\x03\x6d\x01\x00\x02\x11\x03\x04\x21\x12\x31\x41\x05\x51\ +\x13\x61\x22\x06\x71\x81\x91\x32\xa1\xb1\xf0\x14\xc1\xd1\xe1\x23\ +\x42\x15\x52\x62\x72\xf1\x33\x24\x34\x43\x82\x16\x92\x53\x25\xa2\ +\x63\xb2\xc2\x07\x73\xd2\x35\xe2\x44\x83\x17\x54\x93\x08\x09\x0a\ +\x18\x19\x26\x36\x45\x1a\x27\x64\x74\x55\x37\xf2\xa3\xb3\xc3\x28\ +\x29\xd3\xe3\xf3\x84\x94\xa4\xb4\xc4\xd4\xe4\xf4\x65\x75\x85\x95\ +\xa5\xb5\xc5\xd5\xe5\xf5\x46\x56\x66\x76\x86\x96\xa6\xb6\xc6\xd6\ +\xe6\xf6\x47\x57\x67\x77\x87\x97\xa7\xb7\xc7\xd7\xe7\xf7\x38\x48\ +\x58\x68\x78\x88\x98\xa8\xb8\xc8\xd8\xe8\xf8\x39\x49\x59\x69\x79\ +\x89\x99\xa9\xb9\xc9\xd9\xe9\xf9\x2a\x3a\x4a\x5a\x6a\x7a\x8a\x9a\ +\xaa\xba\xca\xda\xea\xfa\xff\xda\x00\x0c\x03\x01\x00\x02\x11\x03\ +\x11\x00\x3f\x00\xfb\x41\xd3\x6f\xa2\x87\xc7\x3c\x37\x89\xe9\xd4\ +\xe9\xe2\x6b\x90\x29\x6e\xa3\x72\x4d\x0d\x0f\x8f\xf0\xc8\x82\xa5\ +\xb2\x41\x5a\x86\xfa\x46\xf9\x22\x37\x50\xa6\x63\xe5\xe2\x76\xf9\ +\x60\xe4\x95\xc1\x48\xd8\x74\x3d\x46\x0b\x56\xa4\x9a\x18\x14\x31\ +\x60\xa4\xec\x6b\xe3\x92\x1b\xa0\xac\x49\x92\x51\x1b\x02\xad\xc8\ +\x91\xb7\xea\xc2\x84\x34\xaf\xc5\x8e\xfb\x77\xc9\x81\x6c\x49\x62\ +\x3a\xaf\x9e\x3c\xbf\xa3\xcc\x6d\xee\xef\x2b\x38\x34\x68\x61\x1e\ +\xa3\x03\xfe\x55\x36\x1f\x7e\x3c\x51\x09\x11\x94\x91\xfa\x47\x9a\ +\xb4\x9d\x6e\xa9\x61\x75\xce\x50\x2a\x60\x70\x51\xe9\xec\x0f\x5f\ +\xa3\x11\x38\xc8\xd2\x0c\x65\x16\x48\x25\x3c\x5b\x7f\x0c\x4c\x37\ +\x5e\x2d\x9f\xff\xd0\xfb\x3a\xfb\x0a\xee\x4d\x6b\x4c\xf0\xb0\x1e\ +\xa1\x6f\x2d\xfa\x6e\x71\x21\x34\xb8\x11\x5e\x9b\xe4\x50\xd3\x53\ +\xa7\x8e\xe7\x25\x6a\xda\xd0\xee\x48\x03\xc7\x04\x95\x4e\x59\x12\ +\x15\x2e\xce\x02\x81\x52\x7e\x59\x00\x2d\x2f\x9c\xbf\x36\xbc\xc7\ +\xa8\x98\xa5\x5d\x1f\xce\x9a\x7e\x8f\x67\x14\x6c\xb7\x36\xf1\xd5\ +\xef\x5d\xc8\x20\x08\xe8\x0f\x1a\xd7\xae\xc4\x65\xb8\xf2\x00\x6a\ +\x89\xfb\x99\xc6\x16\x37\x67\x9f\x93\xcf\xa8\xdc\xf9\x2a\xda\xe2\ +\xfe\x49\xa6\x9d\xee\x65\x58\xee\x2e\x09\x77\x68\xd4\x2d\x0d\x4e\ +\xf5\xa9\x3d\x72\x73\x02\xb8\xbb\xda\xe5\xb4\xa9\x96\xf9\xa2\x6b\ +\x8b\x2d\x12\xfa\xea\xdc\x11\x3d\x38\x44\x47\x50\x5b\x6a\xfd\x19\ +\x5c\xe5\x51\xd9\x61\x1e\x29\x51\x7c\xdf\x17\x97\xda\xf2\x43\x35\ +\xc2\x16\x66\x35\x24\xd4\xd0\x93\x95\x44\x97\x22\x42\x99\x5e\x9b\ +\xa3\x5c\xe9\x77\x56\xd7\x56\xfc\x97\x83\x06\x53\x4e\x84\x65\x73\ +\xca\x8e\x0b\x7b\xbf\xac\x46\x9e\x2f\x3d\x3d\xcc\x3e\xa7\xa7\xef\ +\x4e\x9f\x7e\x65\xf8\x9e\x9e\x2f\x27\x13\x87\x7a\x7f\xff\xd1\xfb\ +\x3f\x4a\xed\xd4\xf6\xcf\x0b\xa7\xa8\x51\x79\x15\x3f\xd6\x3d\xb0\ +\x88\x71\x2d\xd2\x81\x9a\x84\x16\x6a\x7b\x64\xbc\x26\x06\x61\xc6\ +\x70\x4a\x91\x4a\x74\x22\x98\xf8\x74\x8e\x30\x55\xd4\x87\x07\x6e\ +\xdb\x8c\x8f\x0b\x3b\x40\xde\xda\x0b\x88\x9a\x16\x62\x12\x4a\x83\ +\xc4\xd1\xa8\x7c\x0e\xf9\x20\x05\xee\xac\x15\xbf\x2b\x7c\xb5\x3d\ +\xe0\xbb\x9e\x59\x1b\xe2\xe4\xc8\x62\x42\xff\x00\x21\x25\x4f\xdf\ +\xc7\x2c\x88\xc5\xd6\xfd\xcc\xbc\x49\x8e\x54\xf4\x6b\x2b\x5b\x2d\ +\x3a\xd6\x1b\x2b\x0b\x65\xb6\xb4\x80\x11\x1c\x29\xfe\x51\xab\x13\ +\xee\x4e\xe7\x21\x96\x7c\x67\x95\x00\xc0\x0e\xa7\x9a\xdd\x4e\xca\ +\x3d\x4e\xc2\xe6\xcd\xb6\x12\x80\x50\x9e\xcc\x37\x15\xca\xc4\x44\ +\xbd\x27\xab\x21\x23\x13\x61\x85\x69\xbe\x5c\x92\xdd\xbd\x3b\x8b\ +\x76\x4a\x1d\xd5\xc6\xff\x00\xdb\x98\xd9\x23\x2c\x47\x84\xb9\x3c\ +\x42\x7b\xb2\xdf\xd0\x29\x38\x58\x91\x15\x55\x57\x76\x3f\x65\x47\ +\x72\x4f\xb6\x47\x06\x9a\x59\x32\xd0\x3b\x75\x3d\xc1\xae\x79\xc4\ +\x42\x61\xe9\xdb\x95\x16\xf4\xff\x00\x47\x54\xf4\xf9\x53\xf6\x69\ +\xc7\x95\x3f\x1c\xd8\xdc\x38\xab\xf8\x7f\x43\x8b\x52\xab\xea\xff\ +\x00\xff\xd2\xfb\x3e\x0f\x2d\x80\xa9\xcf\x0a\xb7\xa8\x4a\x2f\xe7\ +\x8e\xda\x39\xee\x66\x71\x1c\x50\x21\x79\x1c\xf4\x01\x45\x49\x39\ +\x7c\x48\x02\xcb\x59\xb2\x68\x3e\x52\xf3\x27\xe6\x7f\x9a\xf5\x4b\ +\xe9\x62\xd0\x49\xd3\x6c\x51\x88\x8d\xd2\x9e\xab\x81\xdd\x9c\x83\ +\xd7\xc0\x65\x3e\x29\x9f\x5a\x72\x23\x86\x31\xe7\xba\x71\xe5\x5f\ +\x3e\x79\xa2\xd6\xee\x08\xf5\x8b\x87\xbe\xb5\x94\x81\x22\x4c\x01\ +\x60\x0f\x52\xac\x05\x76\xf7\xc8\x1c\x86\x06\xed\x12\xc4\x25\xc8\ +\x53\xe9\x9b\x49\x96\x45\x8a\x68\xdb\x9c\x52\x85\x64\x61\xd0\xa9\ +\x1b\x66\x41\x20\x8b\x0e\x3c\x6c\x1a\x4c\x4d\x08\x3b\x74\x39\x53\ +\x6a\xd0\xb4\xad\x0d\x3d\xb0\x5a\xb7\xb8\x20\x56\x83\x1b\x55\xe2\ +\x4e\x3d\x45\x6a\x30\x91\x6a\xa1\x15\xed\xd4\x44\x8a\x2c\xb1\x8f\ +\xb0\x8e\xa1\xa9\xf2\xae\xf9\x31\x9a\x63\x6d\x8f\xbc\x02\xd6\x60\ +\x3d\xcb\xa4\xbc\xbc\xb9\xf8\x5d\xb8\x45\xfc\x8a\x02\x83\xf3\x00\ +\x63\x3c\xb2\x90\xa3\xb0\xee\x00\x01\xf6\x2c\x71\x81\xc9\xc6\x36\ +\xe2\x14\x1d\x89\xf8\xbe\xef\xeb\x95\x58\x6c\xa7\xff\xd3\xfb\x3c\ +\xa4\x0e\x9b\x30\xf0\xcf\x07\xb7\xa9\x48\xfc\xc9\x66\xf7\xbe\x5f\ +\xd6\xe0\x88\x16\x96\x58\x1b\x8a\x8e\xa4\x0a\x13\xf8\x64\xc8\x33\ +\x89\x01\x61\xb4\xc1\x2f\x9e\x34\x6f\x29\x2b\x86\x01\x0a\x90\x76\ +\x04\x6f\x53\x98\xd0\x90\xe4\x79\xb9\x99\x3c\x99\xef\xf8\x20\x08\ +\x22\x67\x00\x48\xa7\x96\xc3\x31\x67\x9a\xe7\xc3\xd1\x63\x10\x05\ +\xbd\x3f\x46\xb2\x7b\x4d\x26\xc6\x19\x3e\xd8\x5a\xa8\x3d\x81\x35\ +\x19\xb5\x84\x0c\x31\x80\x7b\x9d\x7c\x88\x33\x34\x9b\x00\x6a\x7a\ +\xef\x4e\x4d\xef\xed\x90\x3c\x99\x86\xb8\x35\x09\x00\x91\x5a\x57\ +\xb7\xcb\x10\x0f\x35\xb5\x8c\xac\x0d\x6b\x81\x2d\xa9\xad\x01\xf0\ +\x39\x24\x2e\xe3\x4e\x84\x0f\x0e\xf8\x15\x7d\x48\x1e\x07\x25\x41\ +\x5d\xc8\xd4\xf8\xf8\xd7\x23\x4a\xff\x00\xff\xd4\xfb\x43\xc9\x29\ +\xd8\x1c\xf0\x7a\x7a\x85\x1e\x7f\x1f\x7a\x74\x20\xf4\xc9\xc4\xf0\ +\x9b\x1c\xd4\x8b\x4b\xad\xb4\x7d\x14\x4e\xed\x0c\xbf\x55\x94\xb1\ +\x66\x8e\x5a\x94\xff\x00\x60\xc0\x7e\x07\x27\x9b\x06\x3c\xfb\xc6\ +\x5c\x27\xb8\xdd\x7c\x08\xfd\x2b\x1c\xd2\x86\xc4\x5a\x7f\x27\xe8\ +\xab\x60\xbe\xa4\xab\x78\xca\x28\x21\x8c\x1a\x13\xdb\x93\x35\x36\ +\xc4\x69\xf1\x42\x62\x52\x90\xc9\x5d\x22\x0e\xfe\xf2\x40\x6a\xf1\ +\x72\x4f\x90\xaf\x34\x2a\xb3\xdc\xb9\x9d\xf8\xaa\xb1\x3c\x40\xd8\ +\x7c\x80\xf0\x18\x72\xe4\x96\x42\x65\x2e\x65\x94\x00\x88\xa0\xaa\ +\x40\x3f\x3e\x94\xca\x3a\x33\x73\x31\x20\x06\xdc\x2e\xca\xb5\xfd\ +\x58\x6c\xf5\x45\x21\xdc\x6f\xb0\x26\xa7\x14\xac\x0a\x7a\xd7\xe5\ +\x8a\x55\x14\x13\xd0\xf6\xeb\x8d\xa1\x7d\x09\x34\x1d\xf0\xda\xb8\ +\xc4\x79\xaa\x72\x52\x4f\x5d\xf6\x1f\x4f\x4c\x3c\x3b\xd5\xa3\x89\ +\xff\xd5\xfb\x38\xc0\xd6\xa3\xae\x78\x5d\xbd\x42\x93\x47\x5e\x84\ +\xd7\xb9\xc4\x2a\x80\xb7\x5d\xd9\xb6\x35\xdb\xc4\xe2\x00\x28\x56\ +\x48\xa0\x5f\x89\xba\xf8\x9d\xf2\x44\x1e\x8c\x78\x82\x36\xaa\x63\ +\xa2\x80\x05\x36\x23\x23\xcd\x92\x9f\xa8\x54\x7c\x40\x9d\xfa\xe2\ +\x60\x96\xea\x5c\xf1\x14\x1f\x3d\xce\x42\x92\xba\xaa\x2a\xa4\xd7\ +\xdf\x0f\x0a\x16\x54\x03\x4a\x54\x7b\x63\x4a\xbb\x9d\x77\x51\xb7\ +\x6c\x95\x2a\xe0\x6b\xfe\x4b\x78\x64\x24\x15\xdb\xd4\x6f\xf4\x60\ +\x57\xff\xd6\xfb\x3d\x51\xd7\x7f\x96\x78\x53\xd4\x2f\x24\x71\x24\ +\x6c\x69\xd3\x01\xd9\x52\x8d\x6e\x4b\x8b\x7d\x1b\x51\xbb\xb3\xa1\ +\xba\x86\x12\x6d\xc1\x1b\x06\x62\x00\x34\xf6\xad\x72\x32\x91\x11\ +\x24\x26\x31\x12\x90\x05\xe2\xba\x66\x87\xe6\x68\xee\x06\xaa\x35\ +\x3b\xc9\xae\x39\x09\x24\x32\x48\xc5\x18\x1e\xa2\x84\xd2\x9e\xd8\ +\x80\x40\x07\xab\x74\xa2\x39\x3d\xe2\xd4\xb9\x86\x27\x91\x78\x34\ +\x88\xae\xc9\xe0\x58\x54\x8c\xc8\xc9\xb5\x17\x16\x2a\xc6\x87\xae\ +\xf4\x34\xca\xec\xb3\x52\x63\xc7\x7a\x6e\x7b\xe2\x16\xd4\x4c\xbd\ +\x87\x5c\xb0\x06\x04\xb4\x26\x00\xd0\xb6\xfe\x03\x1e\x04\x71\xaf\ +\xf5\x96\x94\xaf\xd1\x80\xc1\x22\x6a\xab\x29\x24\x50\x8e\xbb\xe4\ +\x08\xa6\x56\xa6\x25\x23\x9a\x92\x79\x12\x29\x91\xa5\x7f\xff\xd7\ +\xfb\x3b\xd0\x50\x1a\x0f\xc7\x3c\x2a\xde\xa1\x50\x50\xfb\xf5\xc4\ +\xab\xa4\x55\x28\x41\x5e\x4a\xc0\x86\x53\xd0\x82\x28\x41\xc6\x04\ +\x83\x61\x05\x0f\x6e\xf6\xd1\x47\xe9\xc3\x61\x46\xaf\xd9\x67\xe4\ +\x83\xe8\xa5\x4f\xdf\x99\x7e\x2e\x21\xbf\x0e\xfe\xfd\xbf\x1f\x16\ +\x24\x4c\xf5\x54\x53\x23\x33\x99\x00\x24\xb6\xd4\x1e\xd9\x8b\x93\ +\x27\x19\xbe\xac\x80\xa6\x85\x6a\x46\xd5\x34\x60\xbd\xc7\xcf\x01\ +\xe4\x94\x35\xc1\x22\x83\xb9\xe9\x92\xc7\xbb\x19\x30\x2f\x38\xf9\ +\xc2\xc7\xca\x76\x42\x7b\xa0\xd3\x5c\x4b\x51\x6d\x6a\x86\x8d\x21\ +\x1d\x6a\x7f\x65\x45\x7a\xe5\xb2\x98\x80\xf3\x63\x08\x19\x97\xcf\ +\xf2\xfe\x73\xf9\xa6\xe6\xea\x96\x91\x43\x6b\x6b\x5f\x86\x31\x0f\ +\x30\x07\xbb\x31\xa9\xca\x8c\xe6\x7a\xb7\x8c\x31\x0f\x52\xf2\x6f\ +\xe6\x3c\xfa\xc4\xf1\x58\xea\xf0\xa4\x72\xcc\x42\xc5\x73\x10\x2a\ +\x39\x1e\x81\x94\x93\x4a\xf8\x8c\x11\xcc\x41\xa9\x35\xcf\x10\xab\ +\x0f\x64\x8d\x8a\xb0\x27\xa5\x77\x19\x74\xe3\xb3\x54\x64\x8d\xf4\ +\x96\xb5\xed\x4e\x99\x8e\xdc\xff\x00\xff\xd0\xfb\x34\xca\xdb\x1e\ +\xfd\xc6\x78\x43\xd4\xb6\x8c\x41\x5a\x91\xd6\xa7\x24\x82\xa8\x4f\ +\x26\x00\x12\x40\xaf\xb0\xdb\x02\xaf\xf8\x54\x6f\x40\x72\x2a\xb4\ +\x02\xcd\x55\x0d\x41\xd4\xf8\x7b\xe2\x02\x57\x15\xa7\x41\xd7\xae\ +\x1e\x88\x43\xbc\x6d\x2b\x2d\x0d\x46\xe3\x6c\xb3\x19\x63\x37\xcb\ +\xbf\x99\xb6\x37\x3a\x8f\x9a\x65\x88\x82\xd6\xd6\xa1\x62\x44\xeb\ +\x40\x00\x3f\x89\x39\x8b\x92\x77\x37\x37\x0c\x00\xc6\x12\x4b\x1f\ +\x2c\x8a\x46\x1a\x1d\x9b\x75\xf0\xcb\x2c\xc4\x30\x20\x5b\x21\x87\ +\xcb\x32\x59\xdc\x45\x3c\x51\xb2\x0d\x89\xa7\x6a\x66\x2c\xf3\x71\ +\x36\x08\x3e\x85\xd2\x7d\x5b\x8d\x2e\xd2\x69\x7f\xbd\x31\x81\x21\ +\xf1\x23\xbe\x6c\x71\x4a\xf1\x82\x5d\x7c\xc5\x4a\x93\x7e\x27\xd3\ +\xfa\x32\xbe\xad\x8f\xff\xd1\xfb\x39\x2d\x06\xfc\x4e\x78\x43\xd4\ +\x30\x2f\x32\x6b\x5e\x65\xb0\xd4\xf4\xfb\x2d\x0b\x46\x8b\x51\x8a\ +\x78\xda\x7b\xb9\xa6\x76\x50\x15\x5b\x8f\x08\xf8\xfe\xd6\xd5\xa9\ +\xf6\xc6\x79\x04\x06\xec\xa3\x8c\xcb\xab\x3f\xb5\x76\x78\x91\x9d\ +\x0a\x3d\x01\x74\x3d\x41\x22\xb4\x3e\xe3\x24\x46\xec\x02\xb9\x41\ +\xb9\x1d\x70\x14\xb6\xa0\x70\x55\x0c\x76\xdf\x7f\xd7\x86\x90\xef\ +\x87\xa7\x8f\x51\x80\xec\x97\x72\xe2\x00\x34\xc3\x19\x20\x87\x99\ +\x79\xc3\xcb\x6b\x75\xa8\x26\xab\x14\x6c\xde\xb5\x04\xe5\x77\x2a\ +\xe0\x01\x53\xec\x72\x59\xf4\xfc\x51\xe3\x8f\xc7\xcb\xf6\x16\xec\ +\x19\xab\xd2\x51\x5a\x46\x86\x84\xa7\xab\x0e\xe2\x82\x94\xa8\xda\ +\x9e\x1f\x2c\xc0\xe3\x32\x3c\x37\xbb\x71\xa1\xbb\x27\x6d\x01\xae\ +\x5c\x45\x14\x7c\x98\xec\x06\xd4\x1f\x4f\x86\x43\x49\xa3\x9e\x4c\ +\xfc\x11\xde\xcf\xf6\xb0\xc9\xa9\x88\x8d\x94\xcf\xd2\x8a\x08\xe2\ +\xb4\x82\x8f\x1d\xba\x88\xc3\xff\x00\x37\x11\xc4\x9f\xa6\x99\xb8\ +\xcd\xc1\x13\xc3\x0e\x43\x6f\x96\xdf\x6f\x37\x06\x16\x77\x3d\x55\ +\x39\x1a\xd3\x8f\x4d\xa9\x98\xf6\xdd\x4f\xff\xd2\xfb\x3c\x69\xc8\ +\xf5\x23\xbe\x78\x4e\xcf\x50\xd0\xe4\x5c\x7a\x5e\xa2\xb5\x0e\xc9\ +\xe1\xf4\x54\xe4\xa3\x7d\x11\x2a\xea\xbd\x00\xe3\x50\x41\xf6\xc8\ +\xa5\x78\xe7\xe1\x51\xf4\x62\x50\xb8\xd6\x83\xae\x05\x51\x25\xb9\ +\x8a\x83\xf3\xed\x85\x2b\x8f\x2a\x0c\x21\x0e\x53\x74\x18\x9b\x55\ +\xe4\xc3\xed\x03\x4e\x05\x7b\xf2\xe5\xb5\x3e\x79\x93\xa7\x39\x2f\ +\xd1\xf1\xee\xf8\xf4\x61\x3e\x1a\xdd\x5e\xda\xea\xdc\x90\x65\xd3\ +\x14\x4c\x2b\xc8\x24\xd4\x42\x7c\x77\xe4\x47\xdf\x95\x9c\xda\x7e\ +\x2b\x9e\x3b\x3b\xdd\x48\x81\xfa\x7e\xc2\x89\x47\x2d\x7d\x5b\x7b\ +\x95\x27\x9f\x50\x96\x29\xbe\xa9\x64\x96\xd6\xe1\x7f\x7d\xe9\xba\ +\xbb\xf1\xef\x53\xca\xb4\xf1\xa0\xc9\xe3\x99\x9c\x25\xe1\x44\x46\ +\x35\xbd\x6f\x2a\xeb\x77\xbf\xbe\x80\x0d\x62\x20\x11\xc4\x49\x3e\ +\x69\x64\x03\xe2\x1c\x8f\xc5\xe1\x94\x1a\xa7\x21\x19\xf0\xd4\x65\ +\x69\x7f\xff\xd9\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03\x7d\xc3\ +\x00\x69\ +\x00\x6d\x00\x61\x00\x67\x00\x65\x00\x73\ +\x00\x0a\ +\x0c\x9d\x6c\x07\ +\x00\x63\ +\x00\x68\x00\x65\x00\x65\x00\x73\x00\x65\x00\x2e\x00\x6a\x00\x70\x00\x67\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.py b/examples/widgets/graphicsview/diagramscene/diagramscene.py new file mode 100644 index 0000000..3890782 --- /dev/null +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.py @@ -0,0 +1,824 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import math + +from PySide2 import QtCore, QtGui, QtWidgets + +import diagramscene_rc + + +class Arrow(QtWidgets.QGraphicsLineItem): + def __init__(self, startItem, endItem, parent=None, scene=None): + super(Arrow, self).__init__(parent, scene) + + self.arrowHead = QtGui.QPolygonF() + + self.myStartItem = startItem + self.myEndItem = endItem + self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True) + self.myColor = QtCore.Qt.black + self.setPen(QtGui.QPen(self.myColor, 2, QtCore.Qt.SolidLine, + QtCore.Qt.RoundCap, QtCore.Qt.RoundJoin)) + + def setColor(self, color): + self.myColor = color + + def startItem(self): + return self.myStartItem + + def endItem(self): + return self.myEndItem + + def boundingRect(self): + extra = (self.pen().width() + 20) / 2.0 + p1 = self.line().p1() + p2 = self.line().p2() + return QtCore.QRectF(p1, QtCore.QSizeF(p2.x() - p1.x(), p2.y() - p1.y())).normalized().adjusted(-extra, -extra, extra, extra) + + def shape(self): + path = super(Arrow, self).shape() + path.addPolygon(self.arrowHead) + return path + + def updatePosition(self): + line = QtCore.QLineF(self.mapFromItem(self.myStartItem, 0, 0), self.mapFromItem(self.myEndItem, 0, 0)) + self.setLine(line) + + def paint(self, painter, option, widget=None): + if (self.myStartItem.collidesWithItem(self.myEndItem)): + return + + myStartItem = self.myStartItem + myEndItem = self.myEndItem + myColor = self.myColor + myPen = self.pen() + myPen.setColor(self.myColor) + arrowSize = 20.0 + painter.setPen(myPen) + painter.setBrush(self.myColor) + + centerLine = QtCore.QLineF(myStartItem.pos(), myEndItem.pos()) + endPolygon = myEndItem.polygon() + p1 = endPolygon.at(0) + myEndItem.pos() + + intersectPoint = QtCore.QPointF() + for i in endPolygon: + p2 = i + myEndItem.pos() + polyLine = QtCore.QLineF(p1, p2) + intersectType, intersectPoint = polyLine.intersect(centerLine) + if intersectType == QtCore.QLineF.BoundedIntersection: + break + p1 = p2 + + self.setLine(QtCore.QLineF(intersectPoint, myStartItem.pos())) + line = self.line() + + angle = math.acos(line.dx() / line.length()) + if line.dy() >= 0: + angle = (math.pi * 2.0) - angle + + arrowP1 = line.p1() + QtCore.QPointF(math.sin(angle + math.pi / 3.0) * arrowSize, + math.cos(angle + math.pi / 3) * arrowSize) + arrowP2 = line.p1() + QtCore.QPointF(math.sin(angle + math.pi - math.pi / 3.0) * arrowSize, + math.cos(angle + math.pi - math.pi / 3.0) * arrowSize) + + self.arrowHead.clear() + for point in [line.p1(), arrowP1, arrowP2]: + self.arrowHead.append(point) + + painter.drawLine(line) + painter.drawPolygon(self.arrowHead) + if self.isSelected(): + painter.setPen(QtGui.QPen(myColor, 1, QtCore.Qt.DashLine)) + myLine = QtCore.QLineF(line) + myLine.translate(0, 4.0) + painter.drawLine(myLine) + myLine.translate(0,-8.0) + painter.drawLine(myLine) + + +class DiagramTextItem(QtWidgets.QGraphicsTextItem): + lostFocus = QtCore.Signal(QtWidgets.QGraphicsTextItem) + + selectedChange = QtCore.Signal(QtWidgets.QGraphicsItem) + + def __init__(self, parent=None, scene=None): + super(DiagramTextItem, self).__init__(parent, scene) + + self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable) + self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable) + + def itemChange(self, change, value): + if change == QtWidgets.QGraphicsItem.ItemSelectedChange: + self.selectedChange.emit(self) + return value + + def focusOutEvent(self, event): + self.setTextInteractionFlags(QtCore.Qt.NoTextInteraction) + self.lostFocus.emit(self) + super(DiagramTextItem, self).focusOutEvent(event) + + def mouseDoubleClickEvent(self, event): + if self.textInteractionFlags() == QtCore.Qt.NoTextInteraction: + self.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) + super(DiagramTextItem, self).mouseDoubleClickEvent(event) + + +class DiagramItem(QtWidgets.QGraphicsPolygonItem): + Step, Conditional, StartEnd, Io = range(4) + + def __init__(self, diagramType, contextMenu, parent=None, scene=None): + super(DiagramItem, self).__init__(parent, scene) + + self.arrows = [] + + self.diagramType = diagramType + self.myContextMenu = contextMenu + + path = QtGui.QPainterPath() + if self.diagramType == self.StartEnd: + path.moveTo(200, 50) + path.arcTo(150, 0, 50, 50, 0, 90) + path.arcTo(50, 0, 50, 50, 90, 90) + path.arcTo(50, 50, 50, 50, 180, 90) + path.arcTo(150, 50, 50, 50, 270, 90) + path.lineTo(200, 25) + self.myPolygon = path.toFillPolygon() + elif self.diagramType == self.Conditional: + self.myPolygon = QtGui.QPolygonF([ + QtCore.QPointF(-100, 0), QtCore.QPointF(0, 100), + QtCore.QPointF(100, 0), QtCore.QPointF(0, -100), + QtCore.QPointF(-100, 0)]) + elif self.diagramType == self.Step: + self.myPolygon = QtGui.QPolygonF([ + QtCore.QPointF(-100, -100), QtCore.QPointF(100, -100), + QtCore.QPointF(100, 100), QtCore.QPointF(-100, 100), + QtCore.QPointF(-100, -100)]) + else: + self.myPolygon = QtGui.QPolygonF([ + QtCore.QPointF(-120, -80), QtCore.QPointF(-70, 80), + QtCore.QPointF(120, 80), QtCore.QPointF(70, -80), + QtCore.QPointF(-120, -80)]) + + self.setPolygon(self.myPolygon) + self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable, True) + self.setFlag(QtWidgets.QGraphicsItem.ItemIsSelectable, True) + + def removeArrow(self, arrow): + try: + self.arrows.remove(arrow) + except ValueError: + pass + + def removeArrows(self): + for arrow in self.arrows[:]: + arrow.startItem().removeArrow(arrow) + arrow.endItem().removeArrow(arrow) + self.scene().removeItem(arrow) + + def addArrow(self, arrow): + self.arrows.append(arrow) + + def image(self): + pixmap = QtGui.QPixmap(250, 250) + pixmap.fill(QtCore.Qt.transparent) + painter = QtGui.QPainter(pixmap) + painter.setPen(QtGui.QPen(QtCore.Qt.black, 8)) + painter.translate(125, 125) + painter.drawPolyline(self.myPolygon) + return pixmap + + def contextMenuEvent(self, event): + self.scene().clearSelection() + self.setSelected(True) + self.myContextMenu.exec_(event.screenPos()) + + def itemChange(self, change, value): + if change == QtWidgets.QGraphicsItem.ItemPositionChange: + for arrow in self.arrows: + arrow.updatePosition() + + return value + + +class DiagramScene(QtWidgets.QGraphicsScene): + InsertItem, InsertLine, InsertText, MoveItem = range(4) + + itemInserted = QtCore.Signal(DiagramItem) + + textInserted = QtCore.Signal(QtWidgets.QGraphicsTextItem) + + itemSelected = QtCore.Signal(QtWidgets.QGraphicsItem) + + def __init__(self, itemMenu, parent=None): + super(DiagramScene, self).__init__(parent) + + self.myItemMenu = itemMenu + self.myMode = self.MoveItem + self.myItemType = DiagramItem.Step + self.line = None + self.textItem = None + self.myItemColor = QtCore.Qt.white + self.myTextColor = QtCore.Qt.black + self.myLineColor = QtCore.Qt.black + self.myFont = QtGui.QFont() + + def setLineColor(self, color): + self.myLineColor = color + if self.isItemChange(Arrow): + item = self.selectedItems()[0] + item.setColor(self.myLineColor) + self.update() + + def setTextColor(self, color): + self.myTextColor = color + if self.isItemChange(DiagramTextItem): + item = self.selectedItems()[0] + item.setDefaultTextColor(self.myTextColor) + + def setItemColor(self, color): + self.myItemColor = color + if self.isItemChange(DiagramItem): + item = self.selectedItems()[0] + item.setBrush(self.myItemColor) + + def setFont(self, font): + self.myFont = font + if self.isItemChange(DiagramTextItem): + item = self.selectedItems()[0] + item.setFont(self.myFont) + + def setMode(self, mode): + self.myMode = mode + + def setItemType(self, type): + self.myItemType = type + + def editorLostFocus(self, item): + cursor = item.textCursor() + cursor.clearSelection() + item.setTextCursor(cursor) + + if not item.toPlainText(): + self.removeItem(item) + item.deleteLater() + + def mousePressEvent(self, mouseEvent): + if (mouseEvent.button() != QtCore.Qt.LeftButton): + return + + if self.myMode == self.InsertItem: + item = DiagramItem(self.myItemType, self.myItemMenu) + item.setBrush(self.myItemColor) + self.addItem(item) + item.setPos(mouseEvent.scenePos()) + self.itemInserted.emit(item) + elif self.myMode == self.InsertLine: + self.line = QtWidgets.QGraphicsLineItem(QtCore.QLineF(mouseEvent.scenePos(), + mouseEvent.scenePos())) + self.line.setPen(QtGui.QPen(self.myLineColor, 2)) + self.addItem(self.line) + elif self.myMode == self.InsertText: + textItem = DiagramTextItem() + textItem.setFont(self.myFont) + textItem.setTextInteractionFlags(QtCore.Qt.TextEditorInteraction) + textItem.setZValue(1000.0) + textItem.lostFocus.connect(self.editorLostFocus) + textItem.selectedChange.connect(self.itemSelected) + self.addItem(textItem) + textItem.setDefaultTextColor(self.myTextColor) + textItem.setPos(mouseEvent.scenePos()) + self.textInserted.emit(textItem) + + super(DiagramScene, self).mousePressEvent(mouseEvent) + + def mouseMoveEvent(self, mouseEvent): + if self.myMode == self.InsertLine and self.line: + newLine = QtCore.QLineF(self.line.line().p1(), mouseEvent.scenePos()) + self.line.setLine(newLine) + elif self.myMode == self.MoveItem: + super(DiagramScene, self).mouseMoveEvent(mouseEvent) + + def mouseReleaseEvent(self, mouseEvent): + if self.line and self.myMode == self.InsertLine: + startItems = self.items(self.line.line().p1()) + if len(startItems) and startItems[0] == self.line: + startItems.pop(0) + endItems = self.items(self.line.line().p2()) + if len(endItems) and endItems[0] == self.line: + endItems.pop(0) + + self.removeItem(self.line) + self.line = None + + if len(startItems) and len(endItems) and \ + isinstance(startItems[0], DiagramItem) and \ + isinstance(endItems[0], DiagramItem) and \ + startItems[0] != endItems[0]: + startItem = startItems[0] + endItem = endItems[0] + arrow = Arrow(startItem, endItem) + arrow.setColor(self.myLineColor) + startItem.addArrow(arrow) + endItem.addArrow(arrow) + arrow.setZValue(-1000.0) + self.addItem(arrow) + arrow.updatePosition() + + self.line = None + super(DiagramScene, self).mouseReleaseEvent(mouseEvent) + + def isItemChange(self, type): + for item in self.selectedItems(): + if isinstance(item, type): + return True + return False + + +class MainWindow(QtWidgets.QMainWindow): + InsertTextButton = 10 + + def __init__(self): + super(MainWindow, self).__init__() + + self.createActions() + self.createMenus() + self.createToolBox() + + self.scene = DiagramScene(self.itemMenu) + self.scene.setSceneRect(QtCore.QRectF(0, 0, 5000, 5000)) + self.scene.itemInserted.connect(self.itemInserted) + self.scene.textInserted.connect(self.textInserted) + self.scene.itemSelected.connect(self.itemSelected) + + self.createToolbars() + + layout = QtWidgets.QHBoxLayout() + layout.addWidget(self.toolBox) + self.view = QtWidgets.QGraphicsView(self.scene) + layout.addWidget(self.view) + + self.widget = QtWidgets.QWidget() + self.widget.setLayout(layout) + + self.setCentralWidget(self.widget) + self.setWindowTitle("Diagramscene") + + def backgroundButtonGroupClicked(self, button): + buttons = self.backgroundButtonGroup.buttons() + for myButton in buttons: + if myButton != button: + button.setChecked(False) + + text = button.text() + if text == "Blue Grid": + self.scene.setBackgroundBrush(QtGui.QBrush(QtGui.QPixmap(':/images/background1.png'))) + elif text == "White Grid": + self.scene.setBackgroundBrush(QtGui.QBrush(QtGui.QPixmap(':/images/background2.png'))) + elif text == "Gray Grid": + self.scene.setBackgroundBrush(QtGui.QBrush(QtGui.QPixmap(':/images/background3.png'))) + else: + self.scene.setBackgroundBrush(QtGui.QBrush(QtGui.QPixmap(':/images/background4.png'))) + + self.scene.update() + self.view.update() + + def buttonGroupClicked(self, id): + buttons = self.buttonGroup.buttons() + for button in buttons: + if self.buttonGroup.button(id) != button: + button.setChecked(False) + + if id == self.InsertTextButton: + self.scene.setMode(DiagramScene.InsertText) + else: + self.scene.setItemType(id) + self.scene.setMode(DiagramScene.InsertItem) + + def deleteItem(self): + for item in self.scene.selectedItems(): + if isinstance(item, DiagramItem): + item.removeArrows() + self.scene.removeItem(item) + + def pointerGroupClicked(self, i): + self.scene.setMode(self.pointerTypeGroup.checkedId()) + + def bringToFront(self): + if not self.scene.selectedItems(): + return + + selectedItem = self.scene.selectedItems()[0] + overlapItems = selectedItem.collidingItems() + + zValue = 0 + for item in overlapItems: + if (item.zValue() >= zValue and isinstance(item, DiagramItem)): + zValue = item.zValue() + 0.1 + selectedItem.setZValue(zValue) + + def sendToBack(self): + if not self.scene.selectedItems(): + return + + selectedItem = self.scene.selectedItems()[0] + overlapItems = selectedItem.collidingItems() + + zValue = 0 + for item in overlapItems: + if (item.zValue() <= zValue and isinstance(item, DiagramItem)): + zValue = item.zValue() - 0.1 + selectedItem.setZValue(zValue) + + def itemInserted(self, item): + self.pointerTypeGroup.button(DiagramScene.MoveItem).setChecked(True) + self.scene.setMode(self.pointerTypeGroup.checkedId()) + self.buttonGroup.button(item.diagramType).setChecked(False) + + def textInserted(self, item): + self.buttonGroup.button(self.InsertTextButton).setChecked(False) + self.scene.setMode(self.pointerTypeGroup.checkedId()) + + def currentFontChanged(self, font): + self.handleFontChange() + + def fontSizeChanged(self, font): + self.handleFontChange() + + def sceneScaleChanged(self, scale): + newScale = int(scale[:-1]) / 100.0 + oldMatrix = self.view.matrix() + self.view.resetMatrix() + self.view.translate(oldMatrix.dx(), oldMatrix.dy()) + self.view.scale(newScale, newScale) + + def textColorChanged(self): + self.textAction = self.sender() + self.fontColorToolButton.setIcon(self.createColorToolButtonIcon( + ':/images/textpointer.png', + QtGui.QColor(self.textAction.data()))) + self.textButtonTriggered() + + def itemColorChanged(self): + self.fillAction = self.sender() + self.fillColorToolButton.setIcon(self.createColorToolButtonIcon( + ':/images/floodfill.png', + QtGui.QColor(self.fillAction.data()))) + self.fillButtonTriggered() + + def lineColorChanged(self): + self.lineAction = self.sender() + self.lineColorToolButton.setIcon(self.createColorToolButtonIcon( + ':/images/linecolor.png', + QtGui.QColor(self.lineAction.data()))) + self.lineButtonTriggered() + + def textButtonTriggered(self): + self.scene.setTextColor(QtGui.QColor(self.textAction.data())) + + def fillButtonTriggered(self): + self.scene.setItemColor(QtGui.QColor(self.fillAction.data())) + + def lineButtonTriggered(self): + self.scene.setLineColor(QtGui.QColor(self.lineAction.data())) + + def handleFontChange(self): + font = self.fontCombo.currentFont() + font.setPointSize(int(self.fontSizeCombo.currentText())) + if self.boldAction.isChecked(): + font.setWeight(QtGui.QFont.Bold) + else: + font.setWeight(QtGui.QFont.Normal) + font.setItalic(self.italicAction.isChecked()) + font.setUnderline(self.underlineAction.isChecked()) + + self.scene.setFont(font) + + def itemSelected(self, item): + font = item.font() + color = item.defaultTextColor() + self.fontCombo.setCurrentFont(font) + self.fontSizeCombo.setEditText(str(font.pointSize())) + self.boldAction.setChecked(font.weight() == QtGui.QFont.Bold) + self.italicAction.setChecked(font.italic()) + self.underlineAction.setChecked(font.underline()) + + def about(self): + QtWidgets.QMessageBox.about(self, "About Diagram Scene", + "The Diagram Scene example shows use of the graphics framework.") + + def createToolBox(self): + self.buttonGroup = QtWidgets.QButtonGroup() + self.buttonGroup.setExclusive(False) + self.buttonGroup.buttonClicked[int].connect(self.buttonGroupClicked) + + layout = QtWidgets.QGridLayout() + layout.addWidget(self.createCellWidget("Conditional", DiagramItem.Conditional), + 0, 0) + layout.addWidget(self.createCellWidget("Process", DiagramItem.Step), 0, + 1) + layout.addWidget(self.createCellWidget("Input/Output", DiagramItem.Io), + 1, 0) + + textButton = QtWidgets.QToolButton() + textButton.setCheckable(True) + self.buttonGroup.addButton(textButton, self.InsertTextButton) + textButton.setIcon(QtGui.QIcon(QtGui.QPixmap(':/images/textpointer.png') + .scaled(30, 30))) + textButton.setIconSize(QtCore.QSize(50, 50)) + + textLayout = QtWidgets.QGridLayout() + textLayout.addWidget(textButton, 0, 0, QtCore.Qt.AlignHCenter) + textLayout.addWidget(QtWidgets.QLabel("Text"), 1, 0, + QtCore.Qt.AlignCenter) + textWidget = QtWidgets.QWidget() + textWidget.setLayout(textLayout) + layout.addWidget(textWidget, 1, 1) + + layout.setRowStretch(3, 10) + layout.setColumnStretch(2, 10) + + itemWidget = QtWidgets.QWidget() + itemWidget.setLayout(layout) + + self.backgroundButtonGroup = QtWidgets.QButtonGroup() + self.backgroundButtonGroup.buttonClicked.connect(self.backgroundButtonGroupClicked) + + backgroundLayout = QtWidgets.QGridLayout() + backgroundLayout.addWidget(self.createBackgroundCellWidget("Blue Grid", + ':/images/background1.png'), 0, 0) + backgroundLayout.addWidget(self.createBackgroundCellWidget("White Grid", + ':/images/background2.png'), 0, 1) + backgroundLayout.addWidget(self.createBackgroundCellWidget("Gray Grid", + ':/images/background3.png'), 1, 0) + backgroundLayout.addWidget(self.createBackgroundCellWidget("No Grid", + ':/images/background4.png'), 1, 1) + + backgroundLayout.setRowStretch(2, 10) + backgroundLayout.setColumnStretch(2, 10) + + backgroundWidget = QtWidgets.QWidget() + backgroundWidget.setLayout(backgroundLayout) + + self.toolBox = QtWidgets.QToolBox() + self.toolBox.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Ignored)) + self.toolBox.setMinimumWidth(itemWidget.sizeHint().width()) + self.toolBox.addItem(itemWidget, "Basic Flowchart Shapes") + self.toolBox.addItem(backgroundWidget, "Backgrounds") + + def createActions(self): + self.toFrontAction = QtWidgets.QAction( + QtGui.QIcon(':/images/bringtofront.png'), "Bring to &Front", + self, shortcut="Ctrl+F", statusTip="Bring item to front", + triggered=self.bringToFront) + + self.sendBackAction = QtWidgets.QAction( + QtGui.QIcon(':/images/sendtoback.png'), "Send to &Back", self, + shortcut="Ctrl+B", statusTip="Send item to back", + triggered=self.sendToBack) + + self.deleteAction = QtWidgets.QAction(QtGui.QIcon(':/images/delete.png'), + "&Delete", self, shortcut="Delete", + statusTip="Delete item from diagram", + triggered=self.deleteItem) + + self.exitAction = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+X", + statusTip="Quit Scenediagram example", triggered=self.close) + + self.boldAction = QtWidgets.QAction(QtGui.QIcon(':/images/bold.png'), + "Bold", self, checkable=True, shortcut="Ctrl+B", + triggered=self.handleFontChange) + + self.italicAction = QtWidgets.QAction(QtGui.QIcon(':/images/italic.png'), + "Italic", self, checkable=True, shortcut="Ctrl+I", + triggered=self.handleFontChange) + + self.underlineAction = QtWidgets.QAction( + QtGui.QIcon(':/images/underline.png'), "Underline", self, + checkable=True, shortcut="Ctrl+U", + triggered=self.handleFontChange) + + self.aboutAction = QtWidgets.QAction("A&bout", self, shortcut="Ctrl+B", + triggered=self.about) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.exitAction) + + self.itemMenu = self.menuBar().addMenu("&Item") + self.itemMenu.addAction(self.deleteAction) + self.itemMenu.addSeparator() + self.itemMenu.addAction(self.toFrontAction) + self.itemMenu.addAction(self.sendBackAction) + + self.aboutMenu = self.menuBar().addMenu("&Help") + self.aboutMenu.addAction(self.aboutAction) + + def createToolbars(self): + self.editToolBar = self.addToolBar("Edit") + self.editToolBar.addAction(self.deleteAction) + self.editToolBar.addAction(self.toFrontAction) + self.editToolBar.addAction(self.sendBackAction) + + self.fontCombo = QtWidgets.QFontComboBox() + self.fontCombo.currentFontChanged.connect(self.currentFontChanged) + + self.fontSizeCombo = QtWidgets.QComboBox() + self.fontSizeCombo.setEditable(True) + for i in range(8, 30, 2): + self.fontSizeCombo.addItem(str(i)) + validator = QtGui.QIntValidator(2, 64, self) + self.fontSizeCombo.setValidator(validator) + self.fontSizeCombo.currentIndexChanged.connect(self.fontSizeChanged) + + self.fontColorToolButton = QtWidgets.QToolButton() + self.fontColorToolButton.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) + self.fontColorToolButton.setMenu( + self.createColorMenu(self.textColorChanged, QtCore.Qt.black)) + self.textAction = self.fontColorToolButton.menu().defaultAction() + self.fontColorToolButton.setIcon( + self.createColorToolButtonIcon(':/images/textpointer.png', + QtCore.Qt.black)) + self.fontColorToolButton.setAutoFillBackground(True) + self.fontColorToolButton.clicked.connect(self.textButtonTriggered) + + self.fillColorToolButton = QtWidgets.QToolButton() + self.fillColorToolButton.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) + self.fillColorToolButton.setMenu( + self.createColorMenu(self.itemColorChanged, QtCore.Qt.white)) + self.fillAction = self.fillColorToolButton.menu().defaultAction() + self.fillColorToolButton.setIcon( + self.createColorToolButtonIcon(':/images/floodfill.png', + QtCore.Qt.white)) + self.fillColorToolButton.clicked.connect(self.fillButtonTriggered) + + self.lineColorToolButton = QtWidgets.QToolButton() + self.lineColorToolButton.setPopupMode(QtWidgets.QToolButton.MenuButtonPopup) + self.lineColorToolButton.setMenu( + self.createColorMenu(self.lineColorChanged, QtCore.Qt.black)) + self.lineAction = self.lineColorToolButton.menu().defaultAction() + self.lineColorToolButton.setIcon( + self.createColorToolButtonIcon(':/images/linecolor.png', + QtCore.Qt.black)) + self.lineColorToolButton.clicked.connect(self.lineButtonTriggered) + + self.textToolBar = self.addToolBar("Font") + self.textToolBar.addWidget(self.fontCombo) + self.textToolBar.addWidget(self.fontSizeCombo) + self.textToolBar.addAction(self.boldAction) + self.textToolBar.addAction(self.italicAction) + self.textToolBar.addAction(self.underlineAction) + + self.colorToolBar = self.addToolBar("Color") + self.colorToolBar.addWidget(self.fontColorToolButton) + self.colorToolBar.addWidget(self.fillColorToolButton) + self.colorToolBar.addWidget(self.lineColorToolButton) + + pointerButton = QtWidgets.QToolButton() + pointerButton.setCheckable(True) + pointerButton.setChecked(True) + pointerButton.setIcon(QtGui.QIcon(':/images/pointer.png')) + linePointerButton = QtWidgets.QToolButton() + linePointerButton.setCheckable(True) + linePointerButton.setIcon(QtGui.QIcon(':/images/linepointer.png')) + + self.pointerTypeGroup = QtWidgets.QButtonGroup() + self.pointerTypeGroup.addButton(pointerButton, DiagramScene.MoveItem) + self.pointerTypeGroup.addButton(linePointerButton, + DiagramScene.InsertLine) + self.pointerTypeGroup.buttonClicked[int].connect(self.pointerGroupClicked) + + self.sceneScaleCombo = QtWidgets.QComboBox() + self.sceneScaleCombo.addItems(["50%", "75%", "100%", "125%", "150%"]) + self.sceneScaleCombo.setCurrentIndex(2) + self.sceneScaleCombo.currentIndexChanged[str].connect(self.sceneScaleChanged) + + self.pointerToolbar = self.addToolBar("Pointer type") + self.pointerToolbar.addWidget(pointerButton) + self.pointerToolbar.addWidget(linePointerButton) + self.pointerToolbar.addWidget(self.sceneScaleCombo) + + def createBackgroundCellWidget(self, text, image): + button = QtWidgets.QToolButton() + button.setText(text) + button.setIcon(QtGui.QIcon(image)) + button.setIconSize(QtCore.QSize(50, 50)) + button.setCheckable(True) + self.backgroundButtonGroup.addButton(button) + + layout = QtWidgets.QGridLayout() + layout.addWidget(button, 0, 0, QtCore.Qt.AlignHCenter) + layout.addWidget(QtWidgets.QLabel(text), 1, 0, QtCore.Qt.AlignCenter) + + widget = QtWidgets.QWidget() + widget.setLayout(layout) + + return widget + + def createCellWidget(self, text, diagramType): + item = DiagramItem(diagramType, self.itemMenu) + icon = QtGui.QIcon(item.image()) + + button = QtWidgets.QToolButton() + button.setIcon(icon) + button.setIconSize(QtCore.QSize(50, 50)) + button.setCheckable(True) + self.buttonGroup.addButton(button, diagramType) + + layout = QtWidgets.QGridLayout() + layout.addWidget(button, 0, 0, QtCore.Qt.AlignHCenter) + layout.addWidget(QtWidgets.QLabel(text), 1, 0, QtCore.Qt.AlignCenter) + + widget = QtWidgets.QWidget() + widget.setLayout(layout) + + return widget + + def createColorMenu(self, slot, defaultColor): + colors = [QtCore.Qt.black, QtCore.Qt.white, QtCore.Qt.red, QtCore.Qt.blue, QtCore.Qt.yellow] + names = ["black", "white", "red", "blue", "yellow"] + + colorMenu = QtWidgets.QMenu(self) + for color, name in zip(colors, names): + action = QtWidgets.QAction(self.createColorIcon(color), name, self, + triggered=slot) + action.setData(QtGui.QColor(color)) + colorMenu.addAction(action) + if color == defaultColor: + colorMenu.setDefaultAction(action) + return colorMenu + + def createColorToolButtonIcon(self, imageFile, color): + pixmap = QtGui.QPixmap(50, 80) + pixmap.fill(QtCore.Qt.transparent) + painter = QtGui.QPainter(pixmap) + image = QtGui.QPixmap(imageFile) + target = QtCore.QRect(0, 0, 50, 60) + source = QtCore.QRect(0, 0, 42, 42) + painter.fillRect(QtCore.QRect(0, 60, 50, 80), color) + painter.drawPixmap(target, image, source) + painter.end() + + return QtGui.QIcon(pixmap) + + def createColorIcon(self, color): + pixmap = QtGui.QPixmap(20, 20) + painter = QtGui.QPainter(pixmap) + painter.setPen(QtCore.Qt.NoPen) + painter.fillRect(QtCore.QRect(0, 0, 20, 20), color) + painter.end() + + return QtGui.QIcon(pixmap) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + mainWindow = MainWindow() + mainWindow.setGeometry(100, 100, 800, 500) + mainWindow.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.pyproject b/examples/widgets/graphicsview/diagramscene/diagramscene.pyproject new file mode 100644 index 0000000..0acabdd --- /dev/null +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["diagramscene.qrc", "diagramscene.py", "diagramscene_rc.py"] +} diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene.qrc b/examples/widgets/graphicsview/diagramscene/diagramscene.qrc new file mode 100644 index 0000000..c4d845e --- /dev/null +++ b/examples/widgets/graphicsview/diagramscene/diagramscene.qrc @@ -0,0 +1,19 @@ + + + images/pointer.png + images/linepointer.png + images/textpointer.png + images/bold.png + images/italic.png + images/underline.png + images/floodfill.png + images/bringtofront.png + images/delete.png + images/sendtoback.png + images/linecolor.png + images/background1.png + images/background2.png + images/background3.png + images/background4.png + + diff --git a/examples/widgets/graphicsview/diagramscene/diagramscene_rc.py b/examples/widgets/graphicsview/diagramscene/diagramscene_rc.py new file mode 100644 index 0000000..8fee5a0 --- /dev/null +++ b/examples/widgets/graphicsview/diagramscene/diagramscene_rc.py @@ -0,0 +1,417 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x00\xf7\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0b\x00\x00\x00\x0c\x08\x06\x00\x00\x00\xb4\xa9G\x9e\ +\x00\x00\x00\xbeIDAT(S\x85\x911\x0e@@\ +\x10EWM$J7\xa1\xa4\x918\x85^t\xaa=\ +\x8aNT{\x80\xadun\xa0\xd1l\xe7\x12\xc4\x97\x19\ +\xb1!YQ\xfcb\xfe\xbc\xfc\x99\xcc\x08\x00\x82t\x1c\ +\x07\xa6i\x82\x10\xc2)\xcf\xf3.\xf0\xd68\x8e\xa8\xaa\ +\x8aU\x14\x05\x03I\x92X\xef\x05?\xd5u\x1d\xc3Z\ +k\xd0T\xf2\x9c 5\xeb\xbafx]W\xdc\xfeg\ +r\x9a\xa6\x88\xe3\x18O\xcf\x09n\xdb\x06\xdf\xf7Q\x96\ +\xa5]\xc1\x09Ss\x9eg^AJ\xf9\x9f<\x0c\x03\ +\xc3J\xa9\xff\xe4\xb6m\x19^\x96\xe5?9\xcfs\x84\ +a\x88}\xdf\xdf\xc9T\x18c\xec\xe1IA\x10 \x8a\ +\x22[7M\x03\x9b\xdc\xf7\xfd\xf5\xce\x8fWgY\xc6\ +\x13N\xfaWVX\xe8@\xda\xc6\x00\x00\x00\x00IE\ +ND\xaeB`\x82\ +\x00\x00\x01\x1a\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00*\x00\x00\x00+\x02\x03\x00\x00\x00s\xf1\xf2m\ +\x00\x00\x00\x0cPLTE\xff\xff\xff\x80\x80\x80\x00\x00\ +\x00\xff\xff\xffEJK8\x00\x00\x00\x01tRNS\ +\x00@\xe6\xd8f\x00\x00\x00\xbcIDATx^M\ +\xcb\xbd\x89\x041\x0c\x86a\xa1\xd0U8\x1c\xdc\x8f&\ +\xd8\x12\xa6\x0a\xb3\xe1\xe6N.2\x07\x02\xdb\x07[\xc0\ +\x96\xb4U\x9cG?3V\xf4!\xde\x07B\xcd\xe0\x17\ +F\xbd\xf6\xb6\xec\x1a\xef\xa6A\x024\xb2A\x80`$\ +\xcf\x9d\x9a\xee8\x8b~x\x83O~d\xb30hW\ +\x102t\x22\x05\x98\x91\x89\x0c\xe4P\x88\x0c\xd4D\xe4\ + \xce\xdc\xc1\x98\x89\x833q \x89\x02\xe4\x9d\x1d`\ +\xa1.@\xff\xe9\x02\xfd\xf1*\x0e\xd2\xfe{\x81P\xda\ +\x02\x8e\xef\x02>\x0bx\xb3l\x01\x7f]\x1a\x03f\x1d\ +4\x00\x03B\x15\xb0\xe4\x0a$7P$W\xc0\x92+\ +\xe8\x92\x1b\x90\xdc\x80\xe4\x0a$7\xf0so\x1cp_\ +[v<\xc7?\xd6Qh R\x85\xdb_\x00\x00\x00\ +\x00IEND\xaeB`\x82\ +\x00\x00\x00\xfa\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0b\x00\x00\x00\x0c\x08\x06\x00\x00\x00\xb4\xa9G\x9e\ +\x00\x00\x00\xc1IDAT(S\xcd\x901\x0a\x840\ +\x10E\xc7\xceV\xb0\xd3F\x10o`\xe5\x01\xbcB@\ +\x0b\x9bt\x22\x11\xbc\x94\x9d'\xd2\x03x\x03\x03\x19\xf7\ +\x0f\xb8\xd9,l\xbf\x81Of\xde\xfc|\xc8P\x1c\xc7\ +LD\xa2(\x8a8\xcfs~\x1d\xc2\xfd\xc9\xd34e\ +\xd2ZsQ\x14\x02\x86a\xe0y\x9e\xc5\x8c\x1b=8\ +\xe6\xe382a\xa0\x94\x12\x88\xfa[\xe0\x98;\xe7B\ +3\xc0/3\xea\x7fJ\xee\xbaN\xcc\xd7u\x05\x0f\xd0\ +\x83\xf7}\xef\x93\xb1&\xc0}\xdf\x03\xf3q\x1c\xc2\x97\ +e\xf1\xc9\xeb\xba\x0a\x9c\xa6)0?!\xdb\xb6\xf9d\ +\xa8\xaek\x19\x94e\xc9m\xdbrUU\xd27M\xc3\ +\xd6Z\x9f\xfc\xc8\x18\xc3Y\x96\x89)I\x12\xc6_\xce\ +\xf3|o\xe9\x063 8\xcd\x08\x1exv\x00\x00\x00\ +\x00IEND\xaeB`\x82\ +\x00\x00\x00r\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x7f\x00\x00\x00\x7f\x01\x03\x00\x00\x00\xfcs\x8fP\ +\x00\x00\x00\x06PLTE\xff\xff\xff\x00\x00\x00U\xc2\ +\xd3~\x00\x00\x00'IDATH\xc7c`\x80\x82\ +\x06\x0640*0*0*0*\x80*\xf0\x1f\x15\ +\xfc\x1b\x0d\xa0Q\x81Q\x81Q\x01\x22\x05\x00\xd5;N\ +\xf0s\xe3o\xe9\x00\x00\x00\x00IEND\xaeB`\ +\x82\ +\x00\x00\x02\xf1\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00*\x00\x00\x00,\x08\x03\x00\x00\x00$D\xdat\ +\x00\x00\x012PLTE\xff\xff\xff\xfe\xfe\xfe\x01\x01\ +\x01\xbe\xbe\xbe\xfd\xfd\xfd\x00\x00\x00ddd\xd2\xd2\xd2\ +|||\xfb\xfb\xfb\xe7\xe7\xe7\x84\x84\x84\xd7\xd7\xd7\xe0\ +\xe0\xe0\xe1\xe1\xe1\x0c\x0c\x0c(((\xf5\xf5\xf5\xb3\xb3\ +\xb3\x02\x02\x02\x95\x95\x95...\x11\x11\x11kkk\ +\x03\x03\x03rrrIII\xfc\xfc\xfc\x13\x13\x13\x04\ +\x04\x04\x9f\x9f\x9f\xc4\xc4\xc4\xa9\xa9\xa9\x05\x05\x05WW\ +W\x17\x17\x17\xf6\xf6\xf6\x16\x16\x16\xa6\xa6\xa6\xa0\xa0\xa0\ +```$$$>>>###\xb7\xb7\xb7M\ +MM\xf8\xf8\xf8\xc0\xc0\xc0000\x09\x09\x09\xec\xec\ +\xec \x8a\x8a\x8a\xda\xda\xda\xf1\xf1\xf1\x0d\x0d\x0d\ +\x99\x99\x99\x19\x19\x19\xf9\xf9\xf9\xcd\xcd\xcd\xf4\xf4\xf49\ +99---;;;\x12\x12\x12CCC\xc2\xc2\ +\xc2\xa4\xa4\xa4\xdc\xdc\xdcUUUhhhZZZ\ +PPP\xf0\xf0\xf0\x06\x06\x06\x1f\x1f\x1fttt\xb1\ +\xb1\xb1]]]!!!666\x08\x08\x08\xea\xea\ +\xea\xdb\xdb\xdb\x81\x81\x81\x9c\x9c\x9c\x8b\x8b\x8buuu\ +\xf2\xf2\xf2%%%\xce\xce\xceHHHccc\xba\ +\xba\xbaSSS888\xf7\xf7\xf7\xe4\xe4\xe4\xa2\xa2\ +\xa2JJJ\xf3\xf3\xf3___\xf1i\x00\xec\x00\x00\ +\x00\x01tRNS\x00@\xe6\xd8f\x00\x00\x01mI\ +DATx^\xd5\x92\xc5v\xc30\x10E=\x92\x1d\ +f\xe6\x94\x99\x99\x99\x99\x99\xe1\xff\x7f\xa1\x9e\x89\x93S\ +\xa9\xb2Nvm\xdf\xf2\xea\xfa\xbdY\xd8\xf8+\xf10\ +\xeb[X\xcc\x047\x13<\x96\x10\xc6\xb5\xadB\xda\x9a\ +om\x0d@\xb3\xad,\xe8\xda\x1a\xe2\xb5\xf4\xd4\xddq\ +\xbf\xa1\x0d\x14{\x1b\xed\x09\xd0\xbb\x03\x0d\x93\x0d\xeaM\ +\xd8A+3\x82n.\xac5\xc39\xbb\x95\xe5\xbb\xa9\ +\xdb\xa7\xbd\xc0G\xcedG'~1;\xa7q\x87\xda\ +\xd1,\x00\xf8\xe8\xda\x16\xcd~\x17\x19\x09\xc3\x88\x94\xd1\ +]\xd5\xb4\xf6\xe1n\xbf\xdf66\xe9\x92\x90\xab\xeb\xa5\ +\xf7\x09\xdb\x84a\xea\xcf\xbb\xeeg\xd1\x1c\x1dC`\xa6\ +\xd1]\x89\xbb\x98S\xd3\xb8\xef\xa9\x81\x19Z\xa8\x80\xda\ +M\xd1\xeb<\xbd\xc2B\x06\xbf[T\x9b\xe6\x12\x9a\xcb\ +N\x0f\x1c\xd0\xb5w\xca\xfd5z[\xaf\x83\x8d$\xba\ +[\xca\x0b\xb6q_\x0a\x8b\xee*\xdc\xc0\x9e\xa5\x08K\ +)\xf6\x83\x962i\xf3\x87\xe9\xdfgj\xb7\x0a\xb2{\ +\xe8b\xb2#\xd9\x84\x02\xf2c.\xe4\x04\xd9\xe9\x99d\ +\x9eS\xc3\x85H/i\xe9\x0aDzmS\x96\x8c\x08\ +\x14n\xa2Ho\x8b\x02\x8d\x97\xb0\xf5\x1e\xa4\xad\x07\xda\ +z\x14XE\xfd\xd7W\xe9\x82'\xa1\xe1\x19\x97J/\ +r\xab\x19C^~\xads\xce\xf9\x1b}\xfd\xce1\x1f\ +\xe0`\xcc'\xademL\xcc\x12\xc2\xbcN#\x139\ +A\x89y\xc1P5\xfc~\xeb\xff\xca\x17Uq \xbb\ +\xd7\xbb.\xca\x00\x00\x00\x00IEND\xaeB`\x82\ +\ +\x00\x00\x01>\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4l;\ +\x00\x00\x00\x06bKGD\x00\xff\x00\xff\x00\xff\xa0\xbd\ +\xa7\x93\x00\x00\x00\xf3IDAT8\xcb\xed\x94An\ +\x830\x10E\x9f%\xe0\x0c\xbdC/\xd0\x13\xe5\xfaU\ +b\x9b\xd83\x01w\x81\x0d$\x85\xaa1\xca\xaa\x1d\x89\ +\x8d\x0dO\xef{\x067m\xdb&\x0e\x94\xaa\x9a\xad\xf5\ +\x06@D\xaa\xa0]\xd7\xed\xee5\xbc\xa8\xfe\xc1\x7f\x01\ +l\x8c\xd9\xdbJ\x87\x8dS\xda`\x8c\x03\x0c\x01\xf4\x0a\ +\xd2Ct\x98\xb7\xf7\x83G1*h\x81z\x10\x07\xd1\ +\x1d<\xe3A&\xa0\xf6\x0b48\x88\x97Jp\x1aa\ +\x88Kt\xf5\x93e\xb4\xd3#5\xc6i\x80[\x00)\ +\xd1=\xa8\x83`W`_\x01\x96\x1c}\xb6|0\x95\ +jp\xfep\x06\xba\x15\xd4\xe5\x14v\x01\xfft\xfd\xdd\ +U\xb8\xe4\xce\xdb\x05\x5c&A\xfd\xb2\x064{\x17\xf5\ +\xe6\x8f\x10\xce\xdf\xa1\xc54\xe6\x89\xa8j^\xf8\x9cF\ +j\xb6t\x10\xb3\xa9\xac\x1a\xf84\xf8z\xce\xa6\x16b\ +\x0fj\xef\x1bXRT\x81\xa5\x98nLE\xf4p\xeb\ +\x9f\x07\x9b\x8f\xd3\xaf\xdf\xfd\x02\xd6\xbd\xde\xdfp\xdb\x04\ +\x83\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\xad\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0f\x00\x00\x00\x18\x02\x03\x00\x00\x00XkO\xfa\ +\x00\x00\x00\x09PLTE\xff\xff\xff\xff\xff\xff\x00\x00\ +\x00\x8e\xf4\xc3\xec\x00\x00\x00\x01tRNS\x00@\xe6\ +\xd8f\x00\x00\x00RIDAT\x08\x1d\x05\xc1\xb1\x0d\ +\xc20\x14\x05\xc0\x8b\x04\x1b\xd0g\x5c\xc7\x8cC\x93\xe2H\x19\ +O-\xeaW\x95\xed\x8e\x87!KI\x96\xbe\x8e\xa6\x92\ +\x1a1\xeb\xf1\xfc)V\xaa\xefk\xb0 \xc9TG\x0f\ +\xf85\xb8M\xd7V\x03\xe2 \x98\xc7\xaa\xf5\xb7\x98\x05\ +\xd6\xde\xd4>\xf7W\x1a\xb8:\x00\x8a\xa5\xcbfj\xee\ +\x91a\xa9f\xc0\x0f\xb5]\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +\x00\x00\x00`\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x7f\x00\x00\x00\x7f\x01\x03\x00\x00\x00\xfcs\x8fP\ +\x00\x00\x00\x03PLTE\xff\xff\xff\xa7\xc4\x1b\xc8\x00\ +\x00\x00\x18IDATx^\xed\xc01\x01\x00\x00\x00\ +\xc2 \xfb\xa76\xc5>X\x0b\x00\xe0\x08o\x00\x01\x01\ +>\xc31\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x03?\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4l;\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x02\xd1IDAT8\xcb}\ +\x95KhSA\x14\x86\x93\xe6\xd1\x08I(\x04[\x17\ +\x055\xeeZ\xbbP\xb2\xb1\xda\x85\x8f]\xb5\xbe\x16v\ +)-BIW\xed\xce\x8d\x0a\xa2\xe0\xba\xab\x14\x84\x8a\ ++QDE\x17\x0a\x8aU\xf1\x01\x1a\xb0V#\xad\xa2\ +\xc5\xb6\x92j\x95\xbe4\xcd\xc3\xe3\x7fn\xced\xe6N\ +\xd2\x16>\xe6\xde\xce?\x7ff\xcec\xae\x87\x88<&\ +\xf8\xf3\x01~\xa8\x07\x01Pgk\x0cm\x9d\xa1\x0d\xf2\ +\xda\xca\x9c!\xf2\x8a\x11Q\x7f\x7f^\x16l\x04a\xe0\ +\xafa\xeaw\xb4\x03\x03J\xdb\x08\x22\xe2\xe15\x85\x8e\ +\xe9\xbf\xa1!*uwS\xa1,f6\x83(\xcfW\ +iS)*\xf5\xf4P)\x18T\xda8hp\xe6\xcd\ +\xe3\x97`Z\xec\xed\xa5BK\x0b\xe5\xf0\xfe]\x9bo\ +U\xe6\xca\xb44R\xbex\xe8\xa0\xd6\ +\x1e\x05\x09\xf3\x12\xf2I\xd0\xb7\xb1\xe0\xa4>R\x97\xb4\ +\xa9}mV:\xf4\x94\xd6\xb2\xe9\x1e\xf1\x88\xda\xa5\xd6\ +\xa0\xcc\xe5H;\xc1\x965.\xfa\xa8\xcc)mB\xd6\ +\xea\x8b\xde\xfa4\xf1\x82MN\x9c\xca\xe1\x89\xac\xf3i\ +\x8a\x88\xa6Y\xd6\xa8Syku\x9eO>\x8e\x1b\xec\ +\x0f\xe4\x1a\xda\xa0h\xebM\xed\x7f=\xa9\x97\x96\x02\xf1\ ++\x1c\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x00\x8d\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x1b\x00\x00\x00\x1b\x01\x03\x00\x00\x00\xb7\x1af\x16\ +\x00\x00\x00\x06PLTE\xff\xff\xff\x00\x00\x00U\xc2\ +\xd3~\x00\x00\x00\x01tRNS\x00@\xe6\xd8f\x00\ +\x00\x005IDAT\x08\x99c`\xc0\x02\xd8\x1b\x80\ +\x04\xff\x01L\x82\xfd\x01H\xba\x00DX\x80\x08\x19\x10\ +\xc1\x07\xd6\x02\x22\x98A\xfa\x18A\x0a\x19\xc0\x0a\xeb@\ +\x84=\x16B\x0e\xddF\x00\xb5\x00\x09@\xa31\xbf^\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00\x01\x12\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x0b\x00\x00\x00\x0d\x08\x06\x00\x00\x00\x7f\xf5\x94;\ +\x00\x00\x00\xd9IDAT(S}\x901\x0eE@\ +\x10\x86G$$\x1a\x0d\x0d\xd1\x22Qp\x80m\x5c@\ +\xe7<\x0e!\x0aGq\x19\xb5N\xa9\xc1x3\xb2\x8b\ +\xf7\xec\xdb\xe4\xcbfv\xfe\xf9gv\xc00\x0c\x04\x80\ +\x07\xf4fY\x16&I\x82\x9f\x03\xc4\xbe\xef\x94;\x05\ +i\x9a2$\x08\xc3\xf0QX\xd75\x17\x01\x05\x04U\ +\xde]\xe8v\x1c\x87s\xb6m\xe3\xc3Y\x0a\xefDQ\ +\xc4\xe2 \x08\xf4\xce\xeb\xbab\xdb\xb6j\x94\xbe\xefO\ +\xb1|(\x8a\x82\xc9\xf3\x1c}\xdfg\x03!\x04\x0e\xc3\ +\xa0L@\xb7\x0d\xd34Y\xdcu\xdd%\xfe\x9ey\xdb\ +6\x9c\xa6\x89c\xd9!\x8ec\x1c\xc7\x11\xd5\xcco\x1f\ +$d\xbe\xaa\xaa\xff\xdbX\x96E\x8dF]^\xb7A\ +\xcc\xf3\x8cM\xd3\xa0\xccgYv9{\x9e\xa7p]\ +\xf7\xe7\xd3\xdamH\xa8\xa8,K\xd5\xf1\x00\xd0\xc0\x13\ +\xc8\x06\xaf\x16(\x00\x00\x00\x00IEND\xaeB`\ +\x82\ +\x00\x00\x00t\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x7f\x00\x00\x00\x7f\x01\x03\x00\x00\x00\xfcs\x8fP\ +\x00\x00\x00\x06PLTE\xc0\xc0\xc0\xff\xff\xff+i\ +\x87\xb4\x00\x00\x00)IDATHKc\xf8\x0f\x05\ +\x0d\x0cP0*0*0*0*@\xa4\x00\x0c\xd8\ +C\xc4\xff\x8d\x0a\x8c\x0a\x8c\x0a\x8c\x0a`\x17\x00\x00?\ +x\xe4\xb7\xe3\x900_\x00\x00\x00\x00IEND\xae\ +B`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x0a\ +\x02\xfcBG\ +\x00i\ +\x00t\x00a\x00l\x00i\x00c\x00.\x00p\x00n\x00g\ +\x00\x0d\ +\x06C\xe3g\ +\x00f\ +\x00l\x00o\x00o\x00d\x00f\x00i\x00l\x00l\x00.\x00p\x00n\x00g\ +\x00\x0d\ +\x08\xd5\xc4\xe7\ +\x00u\ +\x00n\x00d\x00e\x00r\x00l\x00i\x00n\x00e\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x00I\xdb\xa7\ +\x00b\ +\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x002\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x05\xaa\x0c\xc7\ +\x00t\ +\x00e\x00x\x00t\x00p\x00o\x00i\x00n\x00t\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x0e\ +\x0f\x0d\x22'\ +\x00s\ +\x00e\x00n\x00d\x00t\x00o\x00b\x00a\x00c\x00k\x00.\x00p\x00n\x00g\ +\x00\x0b\ +\x0a+\x97\xe7\ +\x00p\ +\x00o\x00i\x00n\x00t\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x00P\xdb\xa7\ +\x00b\ +\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x001\x00.\x00p\x00n\x00g\ +\x00\x0d\ +\x05l\x22\xc7\ +\x00l\ +\x00i\x00n\x00e\x00c\x00o\x00l\x00o\x00r\x00.\x00p\x00n\x00g\ +\x00\x10\ +\x0f\x9b\x88g\ +\x00b\ +\x00r\x00i\x00n\x00g\x00t\x00o\x00f\x00r\x00o\x00n\x00t\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x00K\xdb\xa7\ +\x00b\ +\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x004\x00.\x00p\x00n\x00g\ +\x00\x0a\ +\x0c\xad\x0f\x07\ +\x00d\ +\x00e\x00l\x00e\x00t\x00e\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x03J#\xe7\ +\x00l\ +\x00i\x00n\x00e\x00p\x00o\x00i\x00n\x00t\x00e\x00r\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x06'Zg\ +\x00b\ +\x00o\x00l\x00d\x00.\x00p\x00n\x00g\ +\x00\x0f\ +\x00J\xdb\xa7\ +\x00b\ +\x00a\x00c\x00k\x00g\x00r\x00o\x00u\x00n\x00d\x003\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x0f\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00l\x00\x00\x00\x00\x00\x01\x00\x00\x03\x17\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\xd4\x00\x00\x00\x00\x00\x01\x00\x00\x0f\xf5\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\x5c\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xa7\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\xf2\x00\x00\x00\x00\x00\x01\x00\x00\x08u\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\x9a\x00\x00\x00\x00\x00\x01\x00\x00\x0eN\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\x16\x00\x00\x00\x00\x00\x01\x00\x00\x08\xe9\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x03\x8d\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\xbe\x00\x00\x00\x00\x00\x01\x00\x00\x0e\xdf\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00,\x00\x00\x00\x00\x00\x01\x00\x00\x00\xfb\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00L\x00\x00\x00\x00\x00\x01\x00\x00\x02\x19\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\xd6\x00\x00\x00\x00\x00\x01\x00\x00\x07\xc4\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x01\x80\x00\x00\x00\x00\x00\x01\x00\x00\x0b\x0b\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x06\x82\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x016\x00\x00\x00\x00\x00\x01\x00\x00\x09~\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/graphicsview/diagramscene/images/background1.png b/examples/widgets/graphicsview/diagramscene/images/background1.png new file mode 100644 index 0000000000000000000000000000000000000000..0f93c6bf420da2d6488601c5fa165c57206b322d GIT binary patch literal 112 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_HSBC!}uyIG+0-%Vhr;B4q zMcmsnib4zwEDVnS>rI*jQ%d#ocHGE1#m&I*VJ;(s1M`#_uMbFCENlU4VDNPHb6Mw< G&;$V2W+Jly literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/background2.png b/examples/widgets/graphicsview/diagramscene/images/background2.png new file mode 100644 index 0000000000000000000000000000000000000000..1e293db67a5dfedacaee2b7448148dcf6bc53b92 GIT binary patch literal 114 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwewg8_H*Z=?j1DTL*{Qv)7JF|TYP(;(y z#WBRgJNXAcD=$xgfffWhEMefe;e6zOFINv3CWtdI*jGH+{&<2xJWvyZr>mdKI;Vst E0PAKUcK`qY literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/background4.png b/examples/widgets/graphicsview/diagramscene/images/background4.png new file mode 100644 index 0000000000000000000000000000000000000000..9c1f3bfd77764732b9a0138ffbd134e696e9c6d1 GIT binary patch literal 96 zcmeAS@N?(olHy`uVBq!ia0vp^^&rg13?%;)_Xhwe<^Z1%*Z=?jFFzuE0?3u{ba4!+ qhYP)(Fbo8M z2lQrH7A8r8p993c@02?QX__)52*dDESl2Zd0R;qA-d*T+9EWqZZR5jP3hzWw#Nr?b z^v>(LV%xTAl)mpzv3w|sg30q7ecxvTAp{P?piDrw4bwDP+;!b0{+@Z;Hk_u3W7#2& zV;sj3)y!`nBxJs-s{h+qmPL(5U0%0A%=3&*)1b^}S#~*lo~LkK_vh2vZAhr7EKAk# Y0MNh_$Of+#C;$Ke07*qoM6N<$f{V6t!Tdm4?Fu&!p#^mymSVTh zU>sb6HlP;7W{N`X0QDB+k_jxAXelOsn#*51@U_g5OYIsl5L%VuiskzuK3zz?-u00000NkvXXu0mjfg_VD% literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/delete.png b/examples/widgets/graphicsview/diagramscene/images/delete.png new file mode 100644 index 0000000000000000000000000000000000000000..df2a147d246ef62d628d73db36b0b24af98a2ab9 GIT binary patch literal 831 zcmV-F1Hk-=P)R5;6h zl}l(-K@^6Q=FtdACA#^NDs^{Lp)6)L zgDB5eX;UdG_4H6F7*yIgXmIAu0!5NyOCtSU7G=!;6%|3j{gliox-!pOK?G(o&X({YLK$5)lC7F{VZbo703UCXA=&? zO>Nu>w#%A8Rp;5oKacEBBT*BGX+{#I_yE%2i8f!~SeeejbP6SvLH5VQ-~o6A-hwe1 z-+)oOG3-#N-p|7H3rxph%DcJ`E`ihFDtIo2X&L#)9#wa!-__Ey=>18UreVqnx(m*O z14e_~1JA$~|`2HhU^Ra!WRl)GgiU zYU$BXh#q3R4$gpm?mF#|Br$YH!gK>%1c$VCx82fBJaI+hxwpFb)g=^Dbv{zQc<7+k z9t8>W67osVx3S=)K2n#oseNr$I`ov*vgsc2h}xyrpv>h+JHeJUF8ZjWkj` zH1UE>PMpf&iLCQ!iioCJ)~Hi?YjvJaK8_pg59Au!plIt&?SDO~mzDzYD;xj-002ov JPDHLkV1h`%ho%4k literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/floodfill.png b/examples/widgets/graphicsview/diagramscene/images/floodfill.png new file mode 100644 index 0000000000000000000000000000000000000000..54c0dae237849b1ac4c8f74edd2a9f868df636e0 GIT binary patch literal 282 zcmeAS@N?(olHy`uVBq!ia0vp^T0pGL#0(^hKYq#uQak}ZA+G=b|8Hn$0P=tgS1)f1 zAd9gi$S;_|;n|HeAZL%Ki(^PdobTzqoh*htZHWsngj&el=~ufUw2W)>!)JbaM(j+t z*`p6k+Y&m*-QGCti{d?Yr?U^l-S&Rl_D1UcGDjwpO^yu-D(C0UdS}sHSJCWWm$KO) zBV53!M2U6A#7>?k0UbP7T%IVLyK`_xXR~pkLMPLcxv~ih^&I}cWcvG2i|^9E>c)Uu zOnvW}?6@m7=P=gCN-?L&nlLasiEenprD7hS5`JKk_KQi<6YeyC_#cY%WeVb>%WRI@ YUkl7o2x`3@5A+9vr>mdKI;Vst01-}XF8}}l literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/italic.png b/examples/widgets/graphicsview/diagramscene/images/italic.png new file mode 100644 index 0000000000000000000000000000000000000000..9a438b57ad4369dfd110d2f2bdc126890e1aec8e GIT binary patch literal 247 zcmV(sy*Prg8NDWuEbzopr0L)V>;{X5v literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/linepointer.png b/examples/widgets/graphicsview/diagramscene/images/linepointer.png new file mode 100644 index 0000000000000000000000000000000000000000..66933d43b30e4352c763cadb4f0ca3bd80325037 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^(jd&p3?#QprHKJ4wg8_H*Z=?j1DTH@0 zC%qJfboH$su}j!iZuY)9>DRxMGyQkOZ#I9EdvfFM;~TQYiF#Z5)IYFal@OGE>#O_) PXgY(ZtDnm{r-UW|*?2%h literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/sendtoback.png b/examples/widgets/graphicsview/diagramscene/images/sendtoback.png new file mode 100644 index 0000000000000000000000000000000000000000..5aa3b0a24382610f1dc25d6708a02a90e3d6c340 GIT binary patch literal 318 zcmV-E0m1%>P)1A0e687B!#Lm%BmfS zjSWxldj>ac+a?Z_s+z6!20%orpk3GP?lruq{=t6%Y>e64N{5Y8+F*&ZZV(4{GllSW;AhrI>C^Mf7m%p9hk07*qoM6N<$f)Wjg@&Et; literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/textpointer.png b/examples/widgets/graphicsview/diagramscene/images/textpointer.png new file mode 100644 index 0000000000000000000000000000000000000000..b25832cada22845efb19650500edf1ceb522a8b4 GIT binary patch literal 753 zcmVE}0|Ntca&k#YN&Ni$6B82z1O%U-pTxw(si~<21qD}ER~Hu- z_V)G`78a(arl6ppU|?V*BqTmQJ|iO|x3{-VO-=at_`txxFfcF)2?^}%>>wZ@ii(Qb z+S>8)@eK_PnVFdx85#Nc`OVGE^z`&OIXNvYEjv3q5)u+aLqo#C!lb06+}zw%RaIzc zXj)oYP*70t@bCr(1|J_EbaZsFv9VoUT_GVMHa0d02ng!x>f77ffq{XXoSch`i*swgN1UC~rmJr6ZtwP$GZ*2`gv#l)X+8W}u^wiyPzo88jdmHTu(7OW- zlMU)k*g-2Zf^IIXHN!c(mF2ss+o!$2N6utNCw?(Ir*Vhc(JTP?=-L*|eis=D!-$m8 zUDdSq;cma*Ha6*!kgMyZ_X*pCVd~Gj?q|^)9YbKI(OrqVm{ZfZ@2PHF{gGgN-D*TgnTzabF6H?ke2Co}~y&DfWYwGHLUN z>ECB+w+ga*=wh-X*@Ob}V=m+b+3A^No>RkxNH1yW3PgHsQ;K9ZRdFD@*Sjvt00000NkvXXu0mjfuiIx( literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/diagramscene/images/underline.png b/examples/widgets/graphicsview/diagramscene/images/underline.png new file mode 100644 index 0000000000000000000000000000000000000000..9b8209f5252f74c3af386430d17b60f7eeda7ce3 GIT binary patch literal 250 zcmVVHb^x=zg3bp;R5gZF*!ld&eiecuD~aU8;zW%0@Dx(b}8DKI}F+qU^+sIF@nlx4|n z+j3P^(l<@R)>@zZ$QZ*}mWe4z62@Q7^L%gV1~VWy%?KWNb^rhX07*qoM6N<$f?^zL A8~^|S literal 0 HcmV?d00001 diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py new file mode 100644 index 0000000..73ca02d --- /dev/null +++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.py @@ -0,0 +1,287 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtGui, QtWidgets + +import dragdroprobot_rc + + +def random(boundary): + return QtCore.QRandomGenerator.global_().bounded(boundary) + + +class ColorItem(QtWidgets.QGraphicsItem): + n = 0 + + def __init__(self): + super(ColorItem, self).__init__() + + self.color = QtGui.QColor(random(256), random(256), random(256)) + + self.setToolTip( + "QColor(%d, %d, %d)\nClick and drag this color onto the robot!" % + (self.color.red(), self.color.green(), self.color.blue()) + ) + self.setCursor(QtCore.Qt.OpenHandCursor) + + def boundingRect(self): + return QtCore.QRectF(-15.5, -15.5, 34, 34) + + def paint(self, painter, option, widget): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.darkGray) + painter.drawEllipse(-12, -12, 30, 30) + painter.setPen(QtGui.QPen(QtCore.Qt.black, 1)) + painter.setBrush(QtGui.QBrush(self.color)) + painter.drawEllipse(-15, -15, 30, 30) + + def mousePressEvent(self, event): + if event.button() != QtCore.Qt.LeftButton: + event.ignore() + return + + self.setCursor(QtCore.Qt.ClosedHandCursor) + + def mouseMoveEvent(self, event): + if QtCore.QLineF(QtCore.QPointF(event.screenPos()), QtCore.QPointF(event.buttonDownScreenPos(QtCore.Qt.LeftButton))).length() < QtWidgets.QApplication.startDragDistance(): + return + + drag = QtGui.QDrag(event.widget()) + mime = QtCore.QMimeData() + drag.setMimeData(mime) + + ColorItem.n += 1 + if ColorItem.n > 2 and random(3) == 0: + image = QtGui.QImage(':/images/head.png') + mime.setImageData(image) + drag.setPixmap(QtGui.QPixmap.fromImage(image).scaled(30,40)) + drag.setHotSpot(QtCore.QPoint(15, 30)) + else: + mime.setColorData(self.color) + mime.setText("#%02x%02x%02x" % (self.color.red(), self.color.green(), self.color.blue())) + + pixmap = QtGui.QPixmap(34, 34) + pixmap.fill(QtCore.Qt.white) + + painter = QtGui.QPainter(pixmap) + painter.translate(15, 15) + painter.setRenderHint(QtGui.QPainter.Antialiasing) + self.paint(painter, None, None) + painter.end() + + pixmap.setMask(pixmap.createHeuristicMask()) + + drag.setPixmap(pixmap) + drag.setHotSpot(QtCore.QPoint(15, 20)) + + drag.exec_() + self.setCursor(QtCore.Qt.OpenHandCursor) + + def mouseReleaseEvent(self, event): + self.setCursor(QtCore.Qt.OpenHandCursor) + + +class RobotPart(QtWidgets.QGraphicsItem): + def __init__(self, parent=None): + super(RobotPart, self).__init__(parent) + + self.color = QtGui.QColor(QtCore.Qt.lightGray) + self.pixmap = None + self.dragOver = False + + self.setAcceptDrops(True) + + def dragEnterEvent(self, event): + if event.mimeData().hasColor() or \ + (isinstance(self, RobotHead) and event.mimeData().hasImage()): + event.setAccepted(True) + self.dragOver = True + self.update() + else: + event.setAccepted(False) + + def dragLeaveEvent(self, event): + self.dragOver = False + self.update() + + def dropEvent(self, event): + self.dragOver = False + if event.mimeData().hasColor(): + self.color = QtGui.QColor(event.mimeData().colorData()) + elif event.mimeData().hasImage(): + self.pixmap = QtGui.QPixmap(event.mimeData().imageData()) + + self.update() + + +class RobotHead(RobotPart): + def boundingRect(self): + return QtCore.QRectF(-15, -50, 30, 50) + + def paint(self, painter, option, widget=None): + if not self.pixmap: + painter.setBrush(self.dragOver and self.color.lighter(130) + or self.color) + painter.drawRoundedRect(-10, -30, 20, 30, 25, 25, + QtCore.Qt.RelativeSize) + painter.setBrush(QtCore.Qt.white) + painter.drawEllipse(-7, -3 - 20, 7, 7) + painter.drawEllipse(0, -3 - 20, 7, 7) + painter.setBrush(QtCore.Qt.black) + painter.drawEllipse(-5, -1 - 20, 2, 2) + painter.drawEllipse(2, -1 - 20, 2, 2) + painter.setPen(QtGui.QPen(QtCore.Qt.black, 2)) + painter.setBrush(QtCore.Qt.NoBrush) + painter.drawArc(-6, -2 - 20, 12, 15, 190 * 16, 160 * 16) + else: + painter.scale(.2272, .2824) + painter.drawPixmap(QtCore.QPointF(-15*4.4, -50*3.54), self.pixmap) + + +class RobotTorso(RobotPart): + def boundingRect(self): + return QtCore.QRectF(-30, -20, 60, 60) + + def paint(self, painter, option, widget=None): + painter.setBrush(self.dragOver and self.color.lighter(130) + or self.color) + painter.drawRoundedRect(-20, -20, 40, 60, 25, 25, + QtCore.Qt.RelativeSize) + painter.drawEllipse(-25, -20, 20, 20) + painter.drawEllipse(5, -20, 20, 20) + painter.drawEllipse(-20, 22, 20, 20) + painter.drawEllipse(0, 22, 20, 20) + + +class RobotLimb(RobotPart): + def boundingRect(self): + return QtCore.QRectF(-5, -5, 40, 10) + + def paint(self, painter, option, widget=None): + painter.setBrush(self.dragOver and self.color.lighter(130) or self.color) + painter.drawRoundedRect(self.boundingRect(), 50, 50, + QtCore.Qt.RelativeSize) + painter.drawEllipse(-5, -5, 10, 10) + + +class Robot(RobotPart): + def __init__(self): + super(Robot, self).__init__() + + self.torsoItem = RobotTorso(self) + self.headItem = RobotHead(self.torsoItem) + self.upperLeftArmItem = RobotLimb(self.torsoItem) + self.lowerLeftArmItem = RobotLimb(self.upperLeftArmItem) + self.upperRightArmItem = RobotLimb(self.torsoItem) + self.lowerRightArmItem = RobotLimb(self.upperRightArmItem) + self.upperRightLegItem = RobotLimb(self.torsoItem) + self.lowerRightLegItem = RobotLimb(self.upperRightLegItem) + self.upperLeftLegItem = RobotLimb(self.torsoItem) + self.lowerLeftLegItem = RobotLimb(self.upperLeftLegItem) + + self.timeline = QtCore.QTimeLine() + settings = [ + # item position rotation at + # x y time 0 / 1 + ( self.headItem, 0, -18, 20, -20 ), + ( self.upperLeftArmItem, -15, -10, 190, 180 ), + ( self.lowerLeftArmItem, 30, 0, 50, 10 ), + ( self.upperRightArmItem, 15, -10, 300, 310 ), + ( self.lowerRightArmItem, 30, 0, 0, -70 ), + ( self.upperRightLegItem, 10, 32, 40, 120 ), + ( self.lowerRightLegItem, 30, 0, 10, 50 ), + ( self.upperLeftLegItem, -10, 32, 150, 80 ), + ( self.lowerLeftLegItem, 30, 0, 70, 10 ), + ( self.torsoItem, 0, 0, 5, -20 ) + ] + self.animations = [] + for item, pos_x, pos_y, rotation1, rotation2 in settings: + item.setPos(pos_x,pos_y) + animation = QtWidgets.QGraphicsItemAnimation() + animation.setItem(item) + animation.setTimeLine(self.timeline) + animation.setRotationAt(0, rotation1) + animation.setRotationAt(1, rotation2) + self.animations.append(animation) + self.animations[0].setScaleAt(1, 1.1, 1.1) + + self.timeline.setUpdateInterval(1000 / 25) + self.timeline.setCurveShape(QtCore.QTimeLine.SineCurve) + self.timeline.setLoopCount(0) + self.timeline.setDuration(2000) + self.timeline.start() + + def boundingRect(self): + return QtCore.QRectF() + + def paint(self, painter, option, widget=None): + pass + + +if __name__== '__main__': + + import sys + import math + + app = QtWidgets.QApplication(sys.argv) + + scene = QtWidgets.QGraphicsScene(-200, -200, 400, 400) + + for i in range(10): + item = ColorItem() + angle = i*6.28 / 10.0 + item.setPos(math.sin(angle)*150, math.cos(angle)*150) + scene.addItem(item) + + robot = Robot() + robot.setTransform(QtGui.QTransform().scale(1.2, 1.2)) + robot.setPos(0, -20) + scene.addItem(robot) + + view = QtWidgets.QGraphicsView(scene) + view.setRenderHint(QtGui.QPainter.Antialiasing) + view.setViewportUpdateMode(QtWidgets.QGraphicsView.BoundingRectViewportUpdate) + view.setBackgroundBrush(QtGui.QColor(230, 200, 167)) + view.setWindowTitle("Drag and Drop Robot") + view.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.pyproject b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.pyproject new file mode 100644 index 0000000..587484a --- /dev/null +++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["dragdroprobot.qrc", "dragdroprobot_rc.py", "dragdroprobot.py"] +} diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.qrc b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.qrc new file mode 100644 index 0000000..b0969d2 --- /dev/null +++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot.qrc @@ -0,0 +1,5 @@ + + + images/head.png + + diff --git a/examples/widgets/graphicsview/dragdroprobot/dragdroprobot_rc.py b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot_rc.py new file mode 100644 index 0000000..23d3463 --- /dev/null +++ b/examples/widgets/graphicsview/dragdroprobot/dragdroprobot_rc.py @@ -0,0 +1,975 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00:|\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x84\x00\x00\x00\xb1\x08\x04\x00\x00\x00\xaf\xfa\xdd2\ +\x00\x00\x00\x09pHYs\x00\x00\x0b\x13\x00\x00\x0b\x13\ +\x01\x00\x9a\x9c\x18\x00\x00\x00\x07tIME\x07\xd6\x03\ +\x10\x0a1\x18\xc7\xacb\xef\x00\x00\x00\x1dtEXt\ +Comment\x00Created \ +with The GIMP\xefd%\ +n\x00\x00\x00\x02bKGD\x00\xff\x87\x8f\xcc\xbf\x00\ +\x009\xe4IDATx\xda\xd5\xbd\xd9\xb2]\xc7\xb5\ +\x9e\xf9e\xe6lW\xbb\xf7\x066\x00\xf6$\xa8\xc6u\ +\x8e\x1daY\xf2E\xd5E]T\xd1\xe1\x8b\xba&\x1f\ +\x81z\x04\xea\x11\xc8G\x10\x1fAz\x041\xea\xae\xae\ +|\x8e\xe3\xd4)GX\x16M\x1cQ\x02\x89nw\xab\ +\x9d}\xa6/r\xcc\x5cs-l\x10\x0dI\x85\x0b\x0c\ +\x92\x00v\xb7\xd6\x98\x99\xa3\xf9\xc7?\xfe\xa1V\xfc\xb8\ +\xbf\xdc\xe0\xf7*\xfc\x9d\x02,J~?\xfcSK\x07\ +\xc4\x18*\xda\x8f\xdb\xdfr\x19\xfd&\xfe\x9b\xfc\xa6\xa1\ +\xc3\xde\x8d\xee\xc5h\xc0\xe1\x00\x15\xbe\x9b\xda3\xf9\xff\ +\xd4\x86\xf0/\xdb\xc9[wh\x1c\x96N\x8c\xd2|z\ +\xf1IAM\xca\x98\x88\x925[\x1c\x09\x19\x0aKB\ +N\x8d\x05R&\xe4*\x12\xf3)\xf9\x09\xea\xe0'\xbd\ +\xbc!\x22\xfef\xbf\xfa\x0b\x01\x1a\xb0h:\xca\x8f\xb7\ +\xbf\xad\xb1T\x94lQ\xa4(\x1a6\x5c\xb2$&\xa7\ +\xe2\x8a\x0a\x03\xb4\x14hbr\xe6\x1c\xbb9\xb9\xca\xe4\ +\xad*9\x1d\xdf\xef\xd7\xdf\xd0\x10jp\x84-\x0d\xd5\ +\xdd\xf2\xabK.\xa8\xe8h\xd8r\xcc1s\x1c\x0b\xce\ +\xd8b\xd1\x94\x14\xc2{\x85\x9a\x0e(\xdd\x8a\xfbl8\xa3`\xc2)\ +34\x11[V\xac(\xa9)i8c\x83\xe1\x981\ +-\x96\x0c\x87\x01j\x1a\x14\x19)w\x98s\xca\x09\xe3\ +\xf7\xd3{\xe6{;\xcb\xe8\xd5\xdf\x9cz\xea\x8d\xf6\xb7\ +\xbfC\xc9S\xe2\xc0U\xb64\x1f\x17\xbf\xdd\xb2\xa1\xe4\ +>\x1d\x96\x11c\x124\x86+6\x5c\xb1f\xcb\x96%\ +%WL\x99\xd3\xf0\x98\x16ML\xd3\xc7\x16\x22fL\ +\x80\x05k\xd6\xcc\xbf\x9a1W\x99D!\xff\x1a\xa0\xc5\ +\x1c8\xd3\x1f\xe1D\xb8gX\xdcI6\xe0\x7f\xf5A\ +N\x0dND\xcd\x85[Rr\xceC.\xb0\x8c\xb8\xc1\ +\x18G\x83C\xb3\xe1\x82\x15\x1bJ\xb6T(\x12b4\ +\x1d-\x00\xe7\x00\xc4\xa4\xa4\xc4\x18nb\xd1Dd\x9c\ +\xf0&\xb7xS\xc5\x98\xf0\xca\xdc\xde\xef\x86\xa1[\xfd\ +\x18>b\xdf$>\x18j\x1c\x0d\xb5\xb3\xe8\xcb\xf4\xa4\ +\xf7\xed\x0d\x06G\xf5\xe99\xe7\x94<\xe0K\x22r\xc6\ +(\xd6,hHI\xb9\xe2!\x17\x944X,s:\ +:\xac\x18\xb8\xa3\xa6E\xa1\x18\x13c\xd9\xb2\x92\x8fk\ +\xe6\x9c\xf1\x0e\xb8\x19\xe3_\xeb\xcf\x15\x86\x18\xb5\xf7P\ +\x86g\xf7zc|\xcf\x131\xbc\x97\xed .\x94w\ +\xb7_\xadQ\xc4\x8c/''\x11\x8e\x0eC\xc9c\xf7\ +5\x8f\xd9\xf0\x98\x87$\xdc\xe6\x84\x96K\x1a&\xcc\xf8\ +\x86%\x17\xac\xb0D$\xc4\xa4(\x8c\x98\x01\xa0\xa2\xa2\ +!fLLK\xcd\x82\x88\x84\x08H\xb9\xcd\x1d\xde\xe1\ +\x84\x13r\x12r\x95`\xb0rU\x86y\x86\x1b\xc4\xaf\ +\x1f%j\xa8p\x19,\x0eMzO\xab\x09kw\xc1\ +\xf9\xf1\xc8\x1d3U1\x9b\x0f\x1e\xfd\xe1k\xce\xb9\xe2\ +\x9c\x0d\x13@\xb1\xe015\xc78\x9e\xf0\xdfh\xb1@\ +B\x8cO\xa93r\xa0\xa2A\x11ai\xa9\xd9\xb0\xc1\ +\x88\x07\xf2\x97\xa7\xa5\xe6\x9c\x86)-\x1d\xc7\x1c\x01\x8e\ +n\xcf\x87\xb9\xe7\x86\xd8\xe8\x87\x88\x07Jn\xaf\xa5\xb8\ +\xbb\xf8\xaa\xc6\xa0h\xb9\xf1Y\xc5\x9a\x05\x09%\x85\xcb\ +x\xcc=\xee\xd3\xb2\xe1\x09\x969\x8e+\xb6l\x99\x10\ +q\xce_)1$h\x1c%\x0bZ&\x8c\xa8\xb1l\ +(\x81\x08GMEA\x87&#F\xd1\xe1Hq@\ +\x89\xe1K&\x9c\xf2:\x11c\x0cJ.\xd5\xbe\xb3\xfe\ +Q\x9c\xa5\x93<\xb1/\x86b*\xce\xdd7\xacpT\ +,\xb9C\xc1\x8a\x12HH1\xacy\xc2\x0aE\xc1\x05\ +59\x19\x1d\x90\x12Qp\xc9\x92\x11\x96\x96\x8a\x92\x9a\ +\x0e\xcb\x1c\x83\xa6\xa5\xa4\x06\x14)\x96\x8e\x0e\x87&\xc2\ +\xe0\x80\x84\x8c\x94\x88\x8c\x9c-\x19G\xbc\xc5\xff\xc2O\ +9Q\xd1\xc0G\xb8\xa7j\x11\xf5C\x9e\x08\x9f\xda\xb6\ +t\x1f\xb7\x9f\xdac\xc7DU\xff\xe0\x1d]\xc7\x15\xdf\ +r\xc1\x96\x05+j\x1411\x13\x1c\xd0Qa\xa9\xd8\ +p\x8c\xe2\x84#\x9e\xf0gj\x8eh\xd8\xb2dCC\ +L\xce\x88\x86\x8a\x8e\x16\x8b\x95$\xcc\x07h\x034T\ +\xf2\xd2c:\x1c-%\x13\xa0\xe4\x9c\xc7\xdc \xfd\x87\ +\xd1\xaf\x8cD,\xf7}\xf3\x88\xa7\x13\x94\x0e'_\xe0\ +\xd0@Mq\xd1\x1c\xb7\x94\x94t\x94n\xc9#\x1eq\ +\xc6\x86\x0a\xcb)\x96\x92\x92\x05\x1bj\x1c7\x982\xa1\ +e\xc9\x96\x88\x11\x0d\xff\x9a\x9c\xff\x8f\x7f!bB\xc9\ +_h\xa8Qd\x8c\xa4\xe6\xachhH\xc8\xb0Tt\ +\xe4D8\x222\xa0d\x89\xc2\xe2\xe8\x980\x22aL\ +DF\xc4\x92\xc7\x8c~\x19\xdd\xcd\xef\xa9g\x84J\xf5\ +\xaa>B\x85\xcc\xc0\xed\xfdM{ws\x5cR\xb3a\ +A\xc1\x92K\x1e\xb3\xa2\x15\xff\xfc\x98\x96\x825\x05\x9a\ +1cFh6\xacY\xd11\x22\xe5\x94oYr\x81\ +\xa6fIA\x81\xc3a)\xe9\xa8I\xd8b\xe9\xd0\x18\ +q\x93q@,*\x14\x8e\x1b\xf2\xd1\x0cCK\x87\x22\ +''!\xf1\xce\xf4\x9e\x1b\xbca\xf5}N\x84\xba\xa6\ +zT\xc1\x03\xb7Tw/\xbfz\xcc\x9a\x8a+\xceX\ +\xe0\xb8bAK\x8c\xa2\xa4\xa0\xc0\xd2\xd0\x00)3f\ +,\xe9\xc4\x03$\xa4\xe48\xfe\xcac\x14\x8a\x15k\xc9\ +\x0b\x15\x96\x9a\x96\x96\x94\x0c|\x00&\xa1@\x01\x11)\ +\xd0b\xe9\xb0\x92\xbe\xa5\x80\xc6\xd2\xb1e*\xaf;%\ +\xa5qwTD\xf4\xc2\xb9e\xf42.R\x85\xff\xd6\ +\xac\xddC.9gK\xc1%gl\x18Q\xca]\xae\ +Y\xb1!E3\x22!&B\xb1a%?\xd0G\xff\ +\x8eoY\xd2\xe1(Y\xe2\xc8\x05\xab\xf0~@\x039\ +\xa0\x88\xc8\x18\x91\x92\xb0\xc0\x90\x12S\xb1\xa1\xc5R\xd3\ +\xa1p$\xc4@K\xcd\x16E\xc1\x15W\x5cr\x83\xad\ +\x9b2#W&\xa4\xdd\xdf\xdb\x10\xee\xe0O\x1dK\xf7\ +\x90\xaf\xd8RR\xb3\xe6\x92\x15\x0d\x1bj\x1a\x1a\xc9\x03\ +\x0d\xa7(bF\xc4\x94\x5c\xb0\x22\xc6\x04\xef]\xd3\xb0\ +%f\xcc\x86Fp\x06EC\x85!&\xc6\xa0Y\x89\ +\xd9\xb7\x8c\x88\xe9\xe8\xd8\xd2\x90\xd1R\xe1\xe4\xcd\xbbA\ +M3%\x92\xef\xdc\xd0p\xc9\x827x\x8f\xd3\xdf\xe5\ +\x1f\x99k\x11\xac\x974\x84\x1b\xfc\xd7\x07\xca\x8e\xb5{\ +\xc8}.\xe4G\xaeYQ`\xb9\xa0\x91\x808bD\ +\xca-*\x1a\xf1\xf0\x15%\x11\x84\x97\xad1\x01l\xcb\ +\xc8P8R\xa0\xc3\x11\xcb\x19\x8aPr\x99Z\xc9\x1a\ +|D\x89\x80\x8c)[y(-V\xaa\x92\xfe\x12X\ +6\xb4\x8ci1\xc4\x1fE\xa8\x83*\xe8\x15\x0c\xe1\x06\ +\xa6\xd0\x929l.\x1e\xf1\x0d\x17t\x14l(\xd9\xb0\ +\xa1\xa0\xa5\xc4a\x18q\xcc\x9c\x1cC\x22a\xb2\xa4\xa6\ +%\xa1#&#\x0e`\x9d\xa6\xc0\x91`\x80\x8eN\xae\ +\x81\xcf\x12\x224\xb7H\x81\x15+Z4\x8a\x86\x9a\x82\ +\x98\x04\x85\xa6\xa6\xa1\x93\xbc\xc21&a+>%\xc3\ +Q\xb2\xe5&\xed\xc0\xaf}\xef\xf0\xe9\xc2\xbfJ\xfe_\ +\x1c\x9fqA\x85\xa5\xe0R`\x12\xff\xec\x0d#nq\ +\x9b\x9c\x92\x15\x1d\x0d-%k\x1a\x22R\x14cNH\ +\xa8YS\xd2bh\x80\x8c\x9a\x12\xc5\x98\x92\x98D\x0a\ +70lI\x18\x01\x8e\x06\x85\xa1\xc6`\x88\x89\xe8\xa8\ +X3\xa1\xa1\xa2eCGMJ\x07\x82Xu4T\ +|I\xc4)S\xa7\xd5\xee\xb4\xbcr\xd4\xd8A\xe5\xfe\ +\xd0m\xef^~\xf5\x84\x82H\xea\x8a\x8a\x85\xd4\x80-\ +\x0d\xb7x\x93c4K\xceXp\x8b\x86\x92\x12\xc8\x99\ +0f\xc6\x881\xb0A\x13\xd3\xb1\x06\x1a\x1a49\xe0\ +\x88P\x18\x22\xa9^[\x14[JZ**\x09\xdd\xb7\ +\xd8\xe0\xc8X\xb1%e\x83\x96\x1cSq\xc5\x869\x9a\ +D\xa2\x86\x22Bs\xc1=2\x227W\xec]\x8d\xeb\ +`\x84\xe8\xc5\xa2\x857H\xc3\xfa\xabs\x9ep\xc9\x9a\ +\x86BR\xe1\x1a\x87!\xe7\x16\xb7\xb8\x85b-)\x8e\ +\xcf\x04cb\xc6\x9cp\xc4)\x19\x09\x0dK\xb4\x9c\x06\ +\x0dT8I\xd5T\x00cA\xa1q(24\x19\x05\ +\x15-s\x22\x0c\x15\x1111\xd0a\xe9h\xd1\x82P\ +t8j\x898\xb1\xc0\xbdK.9\x11,\xfc{E\ +\x0d5\xb8\x1a\x96\xea\xd35+\x96\x5c\xb1\xa6\xa1\xa3\x0e\ +\xb9\x7fJ\xc2\x0d\xa6\xf2,\xbdc\xad%\xce'\xdc\xe0\ +5\x8e\x99\x13\x11QKG\xa3\x22\x95:\xa3\xa3\xa5\x93\ +\xd4\xbb\xa3\x13\x5c\xa3\xa3 e\xca\x98\x94D\x12\xa6\x8c\ +\x84\x05\x8e\x91\x9cO%\x91C\x912f\x85\xa5\xa5\xc0\ +\xd2\x92\x12I\x0ds\xc6\x9c\xd4E*\xf9\xbeQC\x0d\ +\xf0\x06\xdf~\x89\x80\x92\x92\x88\x9a\x1aH\xc9\xc8\x89I\ +\xa9\xa9\xe4+6\x5c\x91cHI\x98r\x93\x1b\x1ca\ +0\x18\x14S \xa3aCJLAECM\x87\x91\ +S\xd6\xd2a\xb1h\x1aZ\xa9B3\x14\x1b4\x19\x15\ +\x0d\x19\x8e\x82X\xaa\xd5\x92N\xea\x93\x86Zj\x9d\x96\ +\x18\x83\xe3\x82\x87\x8cH\x88\xdcL\x99W/\xba\xdcA\ +\x87\xaa\xa1\xa4\x09]\x84\x86\x82\x0a\x183%\xc21\x01\ +\x1a6T\x94l\xa8\xc9I\x98s\xc4\x11'\x1c3\xa6\ +\x22\x12\x18%\xa7\xa6\xe31cr\xc1(\x155\x11%\ +m\xf8\xfe\x8a1\x8a\x08G\x85\x0d~C\x03\x1d\x86T\ +J9\x0f\xf0W\xb4\x94\x8cp\xe1\xba\xb4\x186T(\ +rRbR\xa2\xdfM?z\xc5Z\xc3\xed\xfd\xde\xd1\ +|\xbc\xe6\x9cK\x96\x14\xb4h)\xa5R&Lq\xd2\ +~qlyLM\xca\x11\x13f\xdc\xe1\x94\x19SF\ +$\x18\x01T\x1c\x09\xad<\xf1\x92\x15\x0b\x96\xac\xa9(\ +qt@\x14 :\x1f#\x1c%\x96\x96\x88\x0d1\x8e\ +\x92\x08C\x22\xd7(\x17\x8f\xe3B\x81\xee0h\xe9\xa3\ +\xb5l\xb8`\xc4\x09\xb3\x0f'\xdf\x99hG\xcf\xf3\x0f\ +H)dY\xfc\xf6\x8c3\x96\x14l\xd8\xd2Qc\x18\ +3f\xce\x98\x06\xcbC`\xcb%\x15\x19GL8\xe5\ +\x88\x9b\x1c\xf9\xa3\x89&\x0b\xd8v,\x00}GK\xc1\ +\x8a%k\x1a\xbe\xa5\xa5\xa1\xa6\xa6\xa0\xa0\xa2BI8\ +\xf4\x10m\xcb\x8a\x12\xcd\x86\x98)\x09\x0d-[R\x0c\ +\xbe\x01\xe8\xaf\xad\xc1JD\xf3\x0es\xcb%\x19\x0bN\ +\xbf\x8f\xb3\xec\x9bi\xdey]r\xc9\x06+\xdf\xbe\x22\ +%!f\xca\x84\x14\x03\xfc\x99\x0dk4\xa7\xbc\xc1\x14\ +\xcb\xebb\xa4Hz\xdc\xb9T\x11J\x92p\x1f\x8d&\ +L\x98\x0b\x1c\xe7k\xcb\x82+.\xd9\xd2\xa01tX\ +\x0c\x13F\x5c\xd0\xd1\xa1\xa9p8\x12\x14[j:\x12\ +\xc0\xa0\xb1h)\xbf\xac\xb8P_\x9a\xd5\x18.X\x7f\ +\xbf\xa8\xe1\xb0\x18\x0cW\xee\x1b\x16X\x12\xd6<\xe2\x9c\ +\x0a\x85b\xc61)\x1b\x1ep\xce\x9aK \xe1\x98\xdb\ +\xdc\xe6\x98\x84#f\xcc\x88h\xb1D\xc4\x12\xe3\xfb\x80\ +\xec\xdf\xa2\xc2\x90K\x1a\x95SQ\xd0`\xa9)(\xb9\ +\x92\xe4\xbc\x93@\x1b\xf1:5%\x9a\x92Kr\x14\x11\ +1\x06CB\x84a-\x10NC#\xc5yBGM\ +N\xc9}r^ws\xa5\xf6J\xc7\x97\x0a\x9f\x1aG\ +\xc5\x15\x0f\xd8\xd2P\xb2\xe6\x9c+\x22f\xdc\xa6\xe4[\ +*J*J\x1a\x0c\x09\x13nr\x9bS\x8eH\xc9H\ +B\xd3WK^\xe0\x06\x08\xb2\x1ep\x1a\x14\x9a\x13j\ +*\x81ZJ\xc1\xacJ\x0aJZ:\x1c\x09[\xb6$\ +\x18\x22 &\x11\x88\xd6\x10\x91b\xa4[\xdeIn\xea\ +A\xc4\x1e\xff~B\xca;p1;Q\x07\xdd\x96\x17\ +0\x84\x95c\xdc\xb2vO\xf86@d5\x96\x9c\x9b\ +d\xac\xb9`%WH\x913\xe56o\xf2\x1a7\x98\ +\x08\x9a\xe0?\xa21!7\xdd\xfd\xab\xa5\x14Rh,\ +\x0eED\x22e]C\xc3\x11\x96\x9a-[\xd6\x14\x12\ +\xa8c\x0a\x22\x12:\x14\xa9d1\x8aX\x8a\xfb\xde\x9b\ +\xb5t\xb4lqt\x8c\x04\x1b\x1dq\xc1\xcd\xe3\xe93\ +\x0b\xf2\xe7\xe6\x11\x96\xfa\xe3\xad`\xc7\x0d[Z\x12f\ +L\xc9\xb9`\x8bf$!\xad%\xe7&os\x87c\ +\xc6\xe4$\xb4by\x1f-vgL\x1d\x9c\xb8\xde`\ +\xde\xe7\xf7m\x01E\x8e\xa3c\xcc\x96\x945U\xc0 \ +\x0c\xb1t@\x8dT%\xbe\xfb\x11\x0bn\xddR\xd1\xd2\ +RH\xd7]3\xe6\x84\xdb\x9c2\xfe\xcc\xbc\x8a\x8f\xd0\ +\xf2\x8d\xca\xdf\x96\xc0\x845W,h\x18\xe1\xd0,y\ +\x82\x22\x11\x1f`\x88x\x9b\x9b\xbc\xce1\xa9'~\xd0\ +\x02\x9a\x98H^\xa8\x0a\xff\xf4&\xde\xb1]\xf4\xa0\xa8\ +sRv94Z\xcc\x18S\xb1\xa4\x91\xaa$\x93\x0b\ +\xa9\x89\x04\xcc\xdd\x99\xcfI\xf5\xd1\xe7\x14\x8a5\x09'\ +\xfc\x8c7?\x9b\xfe\x86\xd0\xf6yig\xd9}\x5cR\ +H\x82\xe2\xf1\x80\x11\x0d\x1bV\x820T\x94hf\xcc\ +\xb8\xcb\x8c99\x0aGM#/Ic\xa4\x80\xd7\x03\ +<\xa2\x0f\xcb\xc3\xeeS\xffF\xfa|\xa0\x09\x9eE\x11\ +\xd3\x08\x16\xb5\xa1\x95\xccvA$\xa7\xa1O\xcd;\x81\ +\xed\x1aq\xf2-\x8d<\x14MF\xf2\x1b\x7f^\xa2k\ +M\xf1|`\xe6n\xc3\x92s\x16\x9c\xe3\x181\xc2R\ +R\xb0\x05j*J,\xc7\xbc\xc9\xdb\xbcIB\x86\x91\ +\x00\xe6\xdf\x9a\xde3\x02\x03Z\x87;\x00\x82\xa1\x93\x0b\ +\xd4\x17]\xf1\x80\x1e\xa4\xa5\xab1bI#x\x83\x0e\ +\xde\xa5\x95\xb3\xd3I u\x18,\x8e\x8a\x12\xe5[\x8d\ +<\xe0=w\xa4\xcc n\xbdd\xd4P\xf7Z|F\ +y\xce\x9499+6\xac\xa9I\xa8\xa9h\xc8\xb9\xc5\ +Oy\x8fL\xb2\x84\xfe\xc6\xabp{\xad\xfc\xee\x90P\ +\xb6\x9f\xf2\xba\x80-\x1ay\xb2\xfd\xdf\xfa\x0e\xc5H\xfa\ +]\x05V\x80|\x8fO5\xf2=\xbc\xe1|F\xd1_\ +N\x7f\xb1\x1a\x1es\x8f\xbf#\xffx\xfc\xf9\xb3\xe0\xdc\ +\xef\xe8t\xf9O\xae\xb9\xef\xfe\x89/)x\xc4\x09\xc7\ +8\xcex\xc2\x96\x8eR\x90\xe5\xd7\xf97\xbc\xcf\x8c4\ +\xf8\x00\x7f\xe8\xe3\x90\xf31\xb8\x14J|\x82\x12\x1c\xba\ +o\xdf\x80\x198\xe8\xbe\xf0\xeaBBg\xa5\xe4/\xd8\ +J\xc5\xb3\x11\xc4\xbb\xa1\xa4\x12\xa6\x95\x93\xf0\xdb\x08~\ +\xf5\x10\xcb\xeb\xb4t\xbc\xcb\x7f\xe4\xdfs\xaa\x90\xcc\xf3\ +%3\xcb!`\xabhX\xd3\xb2\xa5Ea\x98`\x88\ +\x19\xf3\x0ew\x98\x92\x0d\x0erO\xd8\xd0r\xf3\x19\xb8\ +\xc9\xde\x0cC\x0e\xc3!\x1dl\x98_\xf4W\xcc\xcaS\ +\xb7Xi\x09\xfb\xfb^\x0b$\xac\xa9q\x12\xf2}-\ +\xe2H)9\xa7$\xa6\xe5\x09\xf7\xf8\x197\x9f\x09\xef\ +\xbf@_\xa3\x7f\xca1\x1d[Z)q=\xe9o<\ +\x88\x14Qx;z\xf0vw}rs`\x90>p\ +\xdap\x86v\x89\x8e\x0ao]\x853\xe4\xb3\x0e\x8d&\ +\x16(\xbf\xa3!\x11@\xb7\xe6R~r\x84!\x07\x1a\ +\x8eXq%\xc8G\xc5W\x9c\xf16\xf1\xab`\x96}\ +\xc1\x93\x90H\x09\xdd\x81\xa0\xce\x8a\x15\x09#N8\x22\ +\x0d\xb4\x8c\x9d)\xf4\x81\xd5\xd5\x9e\x11\xd8\x0byVn\ +\xf5\xfeg\x0f\x197}b\xe6\x82\x89}O4\xa2\x95\ +\xd8\x14\xb1\x91\xd8\xa1\x89\x84V`\x980\xc1b\xc9\x18\ +\xd1\xd2\xd2=\xf3\x0dG\xcfo\xe9\x18a,\xf4\x81\xac\ +'\xf5\xf9\xca\xe2\x881i\xe8\x88\x0e\x9f\xe9\xae\x05\xa0\ +\x0f(\x86\x87\x94\x82>\x03u\x83|CK\xb7\xb5\xaf\ +xl\xc8<41V\x12\xa8\xfe\xc4Y \x97\xaeJ\ +o\xaa\x9c\x8e\x11\xb79c\xc1\x8c\x9b\x1c\x93\x85\xcb\xf3\ +t\xdcx\x01\x84J\xcb\x97v\x18\x22\xb1\xbf\xffA\x19\ +S\xa6\xa4 \x8c\xb7\xdd\xdb\xfanf\xb4\x1b\x98\xf9Y\ +mZ\xff\xfc\x87\x0cl-\xdc\x19\x9f\xb2\xfb\x9a\xb6\xbf\ +b\x16\x18\xd3P\xd2\x06\xbf4\xa7dNJ\xc9\x19\x96\ +9o\x09A\xf1\x15\xf1\x08'\x00G-f\xf0\x07\xd9\ +`\x88\xc8\x980\x22\x96\x00\xe9_\xaa\x93\xecah\x8e\ +\xa1\x83\xd4\x07<&5h.\xab=j\x8f\x0b'\x03\ +\x81\x8f\x11\xc2\xb2\x22\x96\xb3\xd1\xc9u\x00%<\xba:\ +\x5c\xcc\x88\x889\x9a\x05O\xe8$+\x1eF\xaf\x97\x8e\ +\x1a\xde\x0c\x95\xf8\x09'\x04\x1fCL\xce\x84\x09)N\ +:W\xfd[\xe8\xa9=z`\x06-OO\xedqY\ +\xf4\xe0Y_G\xe5\xd8w\xad\x8e\x88.T\x16}U\ +\xdb\x9f\x94J\xc0\x98\xfe\xf07(F\xe4\xdc\xe2\x8c\x15\ +-\xe7\x14\xc1\xb0\xaf\xe4#4\x0999\x8dT\x0d\x11\ +\x9a\x84\x98\x9c7\xb8\x81\xc1\x92\xa2\xa9I\x06\x1d\xf3\x9d\ +\xb3S!T\xea\x01\xbd`\xc7k\xda\xfd3\xf4&\xfe\ +\xabZ\xc9#\x08\xd9\x86\x96\xef\xea\xe1\xb9\xfemE\x02\ +\xdfDt\x81z\xe6\xb0\x82l\xbe\x86\xe2\x1e\x8fQ\x94\ +\xb4\x1f\xa4_t\xa1\x5c{\xc9\xbe\x86\xa5\x11\x04)f\ +\x84\xa2\xc5\x11\x11\x0b\xd0\x1e\x85\xb2\xc8=\x15\x1f\x86f\ +\xe1\xa9\xa2\xeb\xbaK\xe0\xf6:l\x87\x83\x0dn\xef\xcf\ +&P\x09\xd8\xfbs\xef3\x1a4-c2,\x05\x8a\ +\x98\x96\xf6\x0fN\xbd\xa2\xb3tXjjJ\x22\xc6\xe4\ +\xd2\x7f\x82\x88\x91t\xad\xd5 \xee\xef\x07?u`\x98\ +}3\xec\xa2\x8b\xba\xa6\x02=t\xb1\xea \xf5\xea\x83\ +(!\xec\x1a\xb9\xba]0eM+L\xefJ\x1a\xcc\ +\x0d6D8\xf5r>\xc2\x09@n1dL\xb0\x94\ +\xf2\xe3#q\x8e\x96v/\xe2\xab\x80L\xeeg\x92O\ +g\x11\xbb\xe6\xf2\xf0I\x0e\xa3\xca\xae\xed\xf84\xb3\xd3\ +`1\x82Y{\xaa\xa1#\x11\x9e\x96\xa6#\x92\x14\xdc\ +\xa2\x89\x89I%\x0e\xbd2?\xa2G\x8f\x8e8fF\ +\xcbF\xf2\xb7h\x8fq\xab\x0f\x12\xec\xc3t\xfa\xe9\xf4\ +\xf9\xba\xc2K\x85\xb9\x9c\xde\x99v\xe1\x9a\xa8k\xd2p\ +'\xa0\xad\xa1E\x13\x85A\x986`\xd9=.\x12\xc9\ +\xe9\xed\xd3>\xfd\xf2\x86\xf0\x00kGN\x82\xa1\xa2\x96\ +\xaa.\x92&\xec\x0e\xdb<\xac\x13\xfah\xc1A\x03\xf6\ +\xbah\xee\x0eH\xc2\x87y\x86\x1ad\xaf\x87Y\x8e\x7f\ +\x1d\xadd\x98\x0c.\x97\x12\xd2J\xcc\x88\x9a\x86\xfa\x99\ +\xd4\xd3\x172D\xcc\x18C\x1c0K'\x00\xaa\x0b\xd4\ +s\x06\xfc\xaa\xdd\x91\x1f\xbaJ7\xf8\xa8;\xe0F\xbb\ +\xa78\x9b\xbb\xb3\xa1\xf6\xd0\xad]r\xd5\x0dLa\x88\ +$\xae\xf4\xf1\xc0\x05<\x149\x119%\x1b\xd64\xa4\ +\xd7\x9aB\xbf\x88!\x22\x12r\xb2\x10\xa5=\x0f\xd2\x06\ +\xb0\xcd\xc9\x8bP{o\xfa\xb0\xbe\xd8\xb5\x93\xdd5\xc3\ +Gn\x10\xf8^\x84\xda\xa6\x0e\x9c\xa8\x1e\x94{\xc3\xbc\ +\xc5\xd2\xd1\x08\xbe\xbdfC\xf3\x01/\x8bPY\xf9f\ +\x11c&l\x89\x85\x1a\x94a\xc8\xc9\xc9HB\xc6\xa7\ +\xc2\xad\x1b\xbe\xf1\xc3\xcc\x80\x01[F\xc9\xedwRN\ +ij1\x96\x1e\x9c\x10\x04\x01\xdfuC\xfa\xf6\x90\x95\ +\x9c\xa1\xa5\x95\xd75$\xb0;i4;\xc9\x83#b\ +\xe68\xd6T\x7f\x98\xa8W\xa2\x17z2NBA#\ +\x00\x98\x96\xbe\xb6\x13\x94H\xbd\xf0\xac\x8c;\xf0\x08.\ +\x14R\xee\x9a\xabr\xf8\xa7\x1e\xacw!\xc7\xf0\x81\xbd\ +\x0e\xfd\x8b\xdd\xd5\xdae\x90V\x00\x1e+\xae\xb3\x09\x90\ +\xe0K\x1aB\x13_f\xc7\x09J\x9c\xa4\x15B\xb1\x11\ +\x0c\xc9\xed\x11;\xaeK\x8f\x87oi??\x19^\x14\ +\xb7g\x9eCC8q\x966T\x16\x86\x8e\x8eZZ\ +\xd1Z \xba\x9d\xd7pr\xeaZ\xaa`\x8aV\x98W\ +\xd7=:\xfd\xddO\xd0\x01\xd1G\x89\xdc\xb5\x96F\x0a\ +.5x6\xfb\x07\xdf\x1d R\xd7\x99\xc1\xed\x99\xc0\ +\x0e\x00;+\x7f\xe3\xa4\x1e\xd97\x95\x0b\xe0\x1d\x82\x88\ +:ZZ\xc1&\x5c8+*\xb4\x8f\x9d4\x96[\xb9\ +L\xdd3\xc9\xa7/\xc0\x8f\xd0_h,\x15H\xac\xde\ +\xa59\x1c`X\xea\xa9\x13\xa5\x9e\x82g\x0e\xcd\xe2\x0e\ +\x80\xfd\xe1\xef\xd53\xdaB\x04:\xba\x11lB\x07\xcf\ +B\xc0\xcc;\xb4\xf4H\x9c4\xa1\xf4^\xd7\xed\x15\x08\ +\xa7\x96\x86\x92H\xea\xffXR)\xbd\x973\xee\xa7\xad\ +\xea\x19f\xd8\x9f\xad\xeaa:up\x1d\xd8\xab6\x86\ +\x95\xcb\xae\x9d\xe3$\x9b\xcc\xa5\xdf\x89\x10\x0d\xf5\xe0\xea\ +\xf5\xb5\xb3\x91\xb7\xaf\xbf\x83\x97\xfdB\xe0m'\xd8O\ +\x0b\xc2\x80\x8f\x9eB\x1d\x9e\x9e\xa1R\xd7\xfcY\xed\xa5\ +\xd6}l\xb2RJ\xbbA\x0e\xa1\xf6\xfa`\x9e\xff\xa0\ +\x03|g\xe5m\xfb\x8eg\x89\xa5\x19D\xb0]3\xc0\ +\x8a\x89zD\xbd'%\xbd\xa2!z'\xd5\x84\xe7\x12\ +\x89\x85\xf5S\x9e\xe0\xe9\xa2\x8a\xa7N\x89\xdb\xcb\x00\x86\ +9\x81\xdb#\xa8\xec\x17m6T\xa8}\x8f\xb3\xef|\ +j,\xed\x00\x96U\x03\xe7\xb7\xc3P#9\x1f\xf6e\ +3K\x1b\x92\x14K\xc3Hj\xceX|q,cG\ +]\xc87\xfc\x8b\xeahe\xd6\x8a\x81/Q2\xdf\xed\ +\xf9\x8fV.\x96\x0d\x1fi\xa8\xa9B\xfe!NZz\ +\x97J\xee\x7fG#\x90\xa0\x05\x19\x93\xf6\xf0@BK\ +#\x8e<\x06i\x15#|=#\x8c\xfe)-\x15k\ +!\xa8\xbc4\x9c\xef\xe8\xee\xfa\x16J'-]=\x80\ +\xdc\x875j\x86\x13\x9a\xb8\x91\x82W\x87\xca\xd0\xec\xc1\ +v\xfe,\xb5\xa1\xe5\xdb3j\x86\x10\xcd.g\xd0\xf2\ +\xffH`9#(Y)\x83\xb6\xbe\xac\x8a\x83ct\ +\x12#\x08\xdf\xadgb\x9b\x80\xbf\xaa\x97\xcd#\x1c\x96\ +\xf6w\x95\xb4\xe1=!\xa3\x0b\x17d\x97R\xfb\xe3\xd6\ +\xca3\x89\xe8\x84\x14\xe0\x065C,/\xc7\x0e\xfc\x87\ +\x09\xc77\x92\xd6\x9d\x0d\x9f_\x87\xf8\xa1\xa4s\xa6\x06\ +n\xd6\x9b<\x09\x0dg-o\xbd\x1b\xc4\x1d\x1b\xfc\x89\ +\x11\xfc:z\xf52\xdc\xe1~\xe9ogJL$\xbd\ +\x81\xec\xe0\x9b:,k\x10\xdf\xd1HsX\x87RY\ +cHP\xd2\x1a\xea\xf1\x84\xde#4\x92Xw\x83H\ +\xafB\xbe\xb8\xff{'\xcc(- \x0c\xf4:$Z\ +Jp'\xa7\xb5\x16#(1BC>\x98\xfe{\x89\ +\xab\xe1\x06\x18c\xc2X\x80\x8d\x8aV\xa6\xfbM\xf8\x11\ +J\xe0\x90\x84\x14-\x94A?\xd4\xac\x85\x11\x97\x91P\ +\x910b,\x06\x88\x04i\xd6t\x94\x01\x05\xb7\x83\xe8\ +a\x07\xa9\xb4\x15\xb2\x80\x91\xb3\x86\xd0\xd4}\xc7+\x0e\ +Mg\xa4'\xee\x06s>\x04\x94\xdb\x8f>\xb8\x97G\ +\xa8v\x9f\x94\xc9E\xf0\xe0WJN&\x13\x176p\ +\xe23\xe1\xc1\x9e\xf1\x90+\xc1\xb1z\xb7\x97\x92\xf2\x90\ +\x11sfD\x92\xa6\xcf\x88\x992\x16'\xaa\x07Y\x9f\ +\xdb\x8b\x19\xfb%{+\x97\xae\x939\xd0F\x1e\x94\xa1\ +\x0c\xaf\xb7\xa3\x91\xecb\xe7\xaa}\xf8M\xbe\x0fB\x85\ +\xf45[q]\x09S\xa6\x8c0\x02\xec#.q\x8d\ +\xa3\xe4\x82oyB%-|?\x01\xe8i^k\x12\ +\xc6\x8c\x85\xd5\x92s\x87\x9c\xdb\xdc\xc4P\xa1\x19\xc9t\ +\xe7!\xb6\xb9\x03d\x94p}\x15\x9a\xad\x0c\xcb\xf8A\ +\x05?\xf5\xd3\x08\xc8\xbf3\x87\x0d\xd7\xc4\xb3&\x22a\ +|^\x97\xa9>\xc7Y\x0eYo\x9d\x1c\xe6\x8c1\xb9\ +\xb8.\x1b\xfa\x97\x8a{\x14\x5c\xf0\x80sj\x91\xc5\xf0\ +\xdc\x99\xad0\xac3\x1aa69\x12\xc6(F\xe2\xea\ +\xae\xe8\x980\x93.k*\xa0\xb0\x1d\xe4\x95\x08;n\ +)\xfd\x95%\x0fx\x80\xc2\xb2e\x0b\x8c\x19q\x84!\ +\x13\x98\x06\x14\xd5 \x87\xf0EZ\x14b\xdewF\x0d\ +{\x00\x91:\xc9\xd9{\xbeA$\x938S2\x0c\x11\ +\x0d-9\x9a\x9a\x98\x96?s\x9f\x0b.\xa8\x889\xe6\ +\x84\x09\xb0\xa5\xa1\xe1\xb1\xd0JR eJ\xc1\x9a\x88\ +\x91P\xda\xad(DLyD\xc6\x9c\x13\xe1\xca8\x1c\ +5)F\x98\x96%\x9a\x15\x8fY\x12c8\xe3\x01\x8f\ +he\x84\xa5\x22a\xca\x9c\x88)\xb78\x0a\x19\x8a\x1b\ +\xcc\x00+\xa6\xd4$\xcc\x07\x19\xed3\x0c\xa1\x0f\xda}\ +Z2\xb1\x86:8\x9d($R\x9e#\xe1\x7f\xe0\x92\ +K\x1e\x00\x093\x12N\xb8\xc9\x94\x94\x8a\x9a-\x0do\ +\xf03\x1e\xf2\x84+,\x8a\x8c\x09)\x96%\xaf\xb1\xe2\ +B2\xbe\x9a\x05\x05s\x8ct\xaf\xad\xa4\xf0\xc3\xb3\xb9\ +\xe2\x8co\xb9@\xa1Yq\x8e\x9f*\xae\xa8(\xd8\xb0\ +bI\xc4\x98%\x13Rr\xc6\x02\xf472\xc6\xc0\xc1\ +\x95x\xc1\xab\xe1d0\xa1gO\x1b\x0c\x85p\x99\x12\ +\xe9\x80\x1a\x8c\xf4\x1b\xcf\xf9\x92\x0b\x12\x22nr\x83[\ +\xcc\x89\xe8\x18\x13QS\x11\xa1y\xc4=\xbe\xe2\x9cs\ +\x96\xdc\xe0\x98\x88\x965%1%\x11%\x15\x0dk2\ +\x89#;j\x88\x0d\xdd\xae\x96\x15W<\xe1\x02E\xc4\ +\x96\x0d-uh6UTl\x88\x18\xb3%#c\xc2\ +\x94\x19c\x22\x0a\xac\xc8\xf4\xc8I\xbf\xd4\xcf3\x84=\ +\xf8\xb0\xc5\x12\xe3X\xf3-\x8fPL%\x06\x18\xa9?\ +\x95\xcc\xdfD\xacy\x02\x8c\x18s\xc2\x9c)\x09--\ +9\x193\xe9,\xdcb\xc41\x0f\xf9\x9a+ fD\ +\xc7\xa58\xcf\x86\x0eKLJN\x8e\xc1I\xc1\xdc\xe7\ +\x14%\x86\x8e\x82\x0b\xae(\xe80\xc2t\xd8\xd2\xe2H\ +\x980bC\xc9E\x80\xf2K\x0aV\xb4\x18&Dt\ +2\xf3#\xc8\xea\xbdW\xe0Yj\x14\x9b\x0f\xbe\xe4?\ +\xb3!\xe5\xef$\x19v\x18\x91<\xb1BQ\xb7\x8c\x19\ +\xf1.S\xc6\x92<\xf9c\xbd\x95\xb4gK\xcb\x94\xb7\ +\xb9\xc3\xbb<\xa1 &\xc7\x90\x01\x19))\x96\x12\xc8\ +\x18\x13aiB\xeam\x05\x95t\xb4ly\xc0\x05%\ +\x0eG\xc5\x8a\xb58\xc3X\x94\x03\x1c\x09\x0d\x05-9\ +)\x85$\xe4\xa7\x81u\xe9\x06\x88\x85\xbb\x06=\x89\x9e\ +\xcd`\xf0\xb5D\xf9\x87\x07\x14\xcc\x98\x852\xa6\xc7\x05\ +\x1d\x13*\ +\x0c9\x9a\x86\x94\x9c-OX\xf3:\x7f\xcf\xfbL\xa8\ +)iI1\xccI\xa8\xe8P\xd4t\x94\x94\xf2\xaaV\ +\xac\xf9\x0b\x97\xacd\x22P\x93p,\x95\x8bg\xeag\ +R^\x95\xacY\xb0\x16\xbd\x02\xc3\x1b\xfc\x8c\xb7\xb9\xcd\ +\x9c\x12\xcb{\xfcD\xe6\xfd\xbe\xf3D(\x1c\xd5\x87\x97\ +\xac\x99\x93H\x17#bJC\xc1\x96\x0c\x87\x0aHv\ +\xce\x7f\xe6\x92\x9c\xbb\xccXpNK\xce\x96\x9a\x8a%\ +\x0bR\x12\x0a\x19Yy\x8d\x11\x8a\x07\x94l\x04r\xdb\ +\xa29\x22\xa6\xe2Oly\x9b9\xd01\x95!\xc7\xad\ +\xa8\x0c,)Y\xd3\x01\x15W,\xd8PP\x86\xa6p\ +\xcb\x8a-\x17\xa1$\x1c1\xc1\x900\xe7\x06W<\x94\ +\xc1\x5c\x9f\xd9Z\x22\x22\xe2P\xca?\x07\xc5\xf6\xb7~\ +\xcb\x05[\x92\xe0\x05\x22&X\x19#2\xe4\x8c\x88%\ +e\xfdg\xbe\xe6\x94\xd7\x98s\x9f\x7f\xa2\xa6!\x16\x81\ +\x9c\x9a\x04#\x91{\xca\x84\x88\x88\x1c\xcb%[Z\xb6\ +\x14Lx\x8d\x9cK\x1e\xb3\xc5\xf2\x1e9\xd0J\x92\xa6\ +E\x84\xab\x95r\xbee\xc39\x0b9\xf4.\x10\x83Z\ +\x09\xe4\x86\x96\x8dP\xd6\xa7\xdc`\xc6\x84c\x0cJ&\ +\x00\x17\x94\x81\xec\x94\xbeH\xd1\xe5\xa4n\xeb$\xdbk\ +\xc4!A\x82\xa1eE\xce1\xb79\x92*\xf4&\x17\ +\xc4\xb4\xacx\xc8\xd7\x14\xb6\xc4!\x0f\xeb\ +\xe1\x8e\x941\x13*r2\x01ObR2Fl\xa9\ +i\xb8C\xc6\x8a\x88\x09\xc7\xe4\xd4\x5cp\xc6\x9a%7\ +\xb8b\xcb\x98w\xd8p\x9f\x0d\x11gL8\xe5\x94\x9c\ +\x88\x96\x11)\x965\x97T\x9c\xf3W\x14\x0f\xd8\xf0s\ +\x12\xfe\x85{<\x14\x91\xcf\x15\x8d\x88\xae%\x8cIP\ +t\xd4\xd4\xa4D\xe4L\xc8PT\xd4B]i\xa4K\ +\x1b\x09\xf0;\x22\x97\xaa\xb9D\x13\xfd^\x89T\x97}\ +vB\xe5p\xd8_v\xa2\xfb\x93\xc9\x13\x81\x9c\x88\x88\ +N\x9e\x87\xcf\xcf\x0c)\x1br4\x1b\x19|N\xb9\xc9\ +\x94\x89\xa4;\x055Sn\xb0\x22g\xc6\x98%%w\ +\xa8\xe4\xc7\x97hRZZ\x22n\x93\xb0a\xc3},\ +\x8a\x96\x8a\x02\xc3\x88\x13\xd6\xacXp\xc5Vr\xd9X\ +\x0e\xb7\x17\xee\xebd\xc27%\xa2\x1d\x00\xc6\x95\x8c\xee\ +[\x16\x182\xc6L\xa4\xf3\xd1\xa1\x89>z\x01g\xd9\ +\xc9)P\xc2\x7f\xa8h\xa9e\xc2\xb2\x11\x18\xafsD\x8aa\xc4[\x18jN\x19\ +\xd31gE\xc4\x11Y\x98\xddT\xe4\xcc\x19IO-\ +b\x84b\xcb\x05\x17l\xb02y:\x95WQ\xb3\xa0\ +\xa2\xa1\x0aY\xe5Z\x06\x16<\xbcW\xb2\xe6\xbfsI\ +\xf7\xa9\x83\x01\x0d\xe5\x19\xd5\xa7\xc7\x12\xdb\xc0\xb7N\xc8\ +\xa4\xe4\xed0d\x8cd\xb6\xd2\x05\xaaq\xff\xdf\x11\xad\ +\x8c\xcb\xfb\x03\xb8\xa6\x22e\xc4\x9c9\xef\xb1\x024[\ +\x8ex\x8f\x9c\x0a\xc5\x11)\xf0:W4\xccY\xa0x\ +\x0b\xc3M^\x93\xe2\xc8\x8a\xa0\xeb\x11\x89\x88\xbce\xa4\ +\x94\xd4d\x1cs\xcc9\x05G\xcc\xb9\xa4\x12D+!\ +\xa6\xa3\x10\x0d#M!\xe7\xe1\x8a\x11\x11sR,\x0d\ +\xabO.>\xd9r\xc4\x0d\x15\x7f\x97\x8f\xb0\xe8\x7fL\ +\x7fi$\xe0x\xe0}+>\xbac\xca(\x08f\xea\ +@\xf3\xf1\x0d9?\xc2>F\x93\xcaA+\xb8\x8d\x22\ +\xe1\x06\xef\xb1fE)\x99\xdd\x92\x15%#\x8e)%\ +\xc9ih8&g\xc2\xcfy\x8d4P\xd5bf\xdc\ +&\xa7\xa6%bJ\xcd\x9a\x96\x1b\xfc=o\xf0G.\ +iX\xb1\xc5\x91\x92a\x98s\x835O\xd8\x023\x14\ +\x1d%\x8e\x9a%\x86\x8a\x8a)\x1b.y\xc4\x13\x9e\xf0\ +6\xa9;Q\xee\xd9\xe1S\x13\xff*v6\xa4\xd1\xbe\ +\xd5\x87\x94-\x99\x88'2P\xb4U\x01\xaa\xc9Y\x09\ +\x0c\x97\xd1\xe1\x18\x91\x0a\xc2\xe5\xb9\xbb\x8d\xa8:$R\ +S\xae\x98\xb1`\xcc\x11O(\xf9\x09\x0b~\xca\xfbL\ +\x84\x13\xe9\x95(F\xbc\xcb\x1b<\xa0\x22%\x13$\xc4\ +\xa00\x9c\xf06_\xb2\x02f\x9c\x10\xe3\xc8\xb8IJ\ +%\x91\xc9I;\xd03;\x1e\xb0%\xa6\xe2\x18E\xc1\ +\x8a\x95\x0cp>\x13\xb3\xecY(^\x83pM\xc5\x16\ +\xcb\x14-\xe5\xae\x09\x83\x08CB\xb0\x95\xce\xe3)\x8e\ +%#\xd2\xa0`;\x22\xc7\xb0\xa6&eBMA\x1b\ +\x84|k\xa0\xe0\x989gt\xbc\xcf\x92\x9f3\x17\x08\ +0\xc2\x91p\x8ef\xc6[\xfc\x15\x87\xa2\x91\xeb\xa4\xf8\ +\x9a\x86#~A\xce}\xb9\xb4\x8e)'\xc4\x8c\xb8E\ +J\x11\xf8\x94)\x13rj\x12F\xc4\x14l\xf8&\xf4\ +F\xddw#T>\xcd\xf6\xddD\x0f\x7f\xa4LD\x04\ +\xab\x0b\xf4\x9e\xbe\x17\xa9\x03/\xd7\x90\xf0\x0b\xfe\xcc\x9a\ +\x96\xa9\xa0\xdd\x0d\x19\x19\x8e\x9cDx\xd3\x1b\xd6\xb4X\ +\x81\xe4\x96$LPT\x18\x8e8\xe1\x88H\x5cqM\ +IMLI\xc3\x88\xdbh\x0a\x0a\xa9\x14\x12JV\xdc\ +\xe0\x94\x8c\x8c\x19k\x16d\xbc\xcd\x11\x8d8\xdb%W\ +bN\xcd\x88cb&\xdc\xe6\x04\xc5\x96%5\xb3\xbd\ +\xf9\xe1k\x13\xaa.p'U\xa0g)\x99\x90\xea\x02\ +S\xc9\x86\xa4j\x9fZ\xfaSV,i\xc3\x90\xe3\x09\ +\x9a\x96\x8e\x94\x88\x8a%\x05\x8e\x94Q8\xb8\xdf\xf2\x06\ +\x89t(\x157\xe4\xda\xf9\xe2k\xc3\x86c\x1eS\x01\ +sb\x96<\xa1@\x91J\x16aY\xd10\xe3\x16\x15\ +_\x93qG\x94\xf0\x0c9%\x8aD\x86/-\x8a\x84\ +9o\xf361_r\x0e\xcc\x99_3\xe2\xb6g\x88\ +\x9e][\xcb\xb7\x84\x96\x84\x1cE-\x9d\x22\x85\x15\xe2\ +\xd0\x8e\xb2\xd3\xf7\x13\x97\xbcK\xc2\x9f\xb8\xcf\xbb\x9c\xd2\ +\xb0$\x92\xf9\xbb--\x1a\xc7\x98LZ:\x1d[^\ +GS\x921c\xccH\x8c\xa7\x02\xfb!\x91V\x8eb\ +B\x22\xd5\xa6\xa3eMBFL\x8d\x16\xbd\x02G\xc5\ +#\x22.\xa4\x8d\xec\xd5n\xc01!'#\xa7\xe2\x09\ +'\xe4\xc4\xdcb\x8ba\xc6\xe4\xfd\xf6\xc0\x18{>\xa2\ +\x07\xcf\xbd?h\xc88\x22\x13\xe1\x94r\x8fK{]\ +?\xb9\xc61\xe3]\xcex\xc4\x82\x113\xc1\x0a\x12i\ +\xca{\xca\xea\x15\x17\x94 \xc2L#F\xa2-`\xf6\ +\xc0\x80\xbe\xfb\x19\x8bZ\x89!c\x83\x96t\xde\x1b\xad\ +$!\xe7\x84\x82\x96\x9a\xf5\x80\x9e\x10K~3\x165\ +\xe5\x98\x11c\xc1\xb1\xbc\x19\xf5=\xf3\xdd>\xa2\xfbx\ +7\xa8\xd4\x0a\xfa\x90\xd2\xd2\xb0\x0d3v\xea\x19\xed\xc1\ +\x84\x9a\x093\xe6\xdcc\x89\xe3\x98\x8a\x86B\xe6\xc5k\ +\x0c-\x05\x8f9Gs\xc4L\x847Fdr\xa6\xa2\ +\x019\xd4\xc90\xdd\x8811\x05\x86T\x84?\x9d\xa0\ +\x14\xbd d\xca\x84\x92\x15\xad\xe4\xb8\xad\xcc%\x1af\ +\x8c0h\x12\x22\xc6\x8c\x04\x97\xcf\x18\x93]\xc3\x938\ +H\xa8\xb8\xa7\x05\x91\x8cI\x18\xcb\x19\xe8\x84\x98\xe3\x06\ +\xbd\xa2\xa7\xf9\xd4\x095\x96\x8c[\xb4<\xa6\xe3\x01\x05\ +[\xea0\xc8\xf0\xae\x08~F\xcc\xb8\xc5LD[{\ +\xd1>'\x1d\x8d^\x86OI\xcd3\x16q\x8d\x98\x89\ +\x08\x80Ul\x88%\xd3l\xa5\xfb\x922b-\xf5\x8f\ +\xef\xa0\xc6r1\xf5\x80\xbf\xefU2'd\xd7P\x0c\ +\xa3\xfd\xb9\x0c\xf3E\x8c\x96\x14fB\x8e\x15\x03\xf4s\ +\xbe\xee\xda\x86\x99\x12l\x19\x81\xe1f\xa2B\xd9I\xfe\ +\xd03\xa7|\xf9\x1e1a\x12\xc6\x1ct\x98\xf3\xeb\x82\ +FY\xaf\x03\xe1\x03\xe0\x98\x05\xe0\xb8\xc5ZN\x85W\ +\xa4\xf2=\x95&D\xbbJF_SrR\x226\x22\ +\xd8\xd53{\xfc\xe4W\xca\x8c\xe4yM`\x87\x22\xba\ +L\x8e\xb5\xa8\xce&\x82){\xee\xd4n\xc0L=5\ +\xee\xea\xbb\xcf9\xb0\xa5$\xe2\x88\x19[\x22\x22!&\ +\xf6}h\x07\xa4\x22\xb5\x91\x1cL\x89n\xe5'\xec\x8f\ +\xa5\x8c9\x92~EB\x22m\xc0\x9a\x0d\xb14\x00l\ +`a\xdd\x1e\xcc\x18:,9cQ\xca\xb4\xf2\xf3-\ +\x8e\x11\x13\x92\xff\xc0w\xe5\x11\x86\x9a\xee\xae\xfe\x22\xfd\ +p$\xc2\xbb.\x8c\x86 \x8aa\xc3Y\xbb\xc3\x19\xd1\ +X\xe4\xf2\xb4\xccV\xa5r\xdfw\xf4\xe0X\x14\x0a=\ +\xcf-:\x18g\xd9]\x89>s\xf5\xc5\xde\x09K\x96\ +\x14\x22\xeb\x92\xd1\xb2e\x8b#\x97\x11%\x83b\x22=\ +\xf9JH\xea\x8e\x96[L\x85\xea\xd4Ia\x8e`-\ +\xc95M\x9e\x83\x06O\xf3\x0f^t\xbb\x91y(\x82\ +\x97(\x06\xa3\xc9\xd7\x83\x1bI\xd0\xb6\xd744\xd2G\ +\xf0\xd5l+ET$\xe9:a\xb0\xdaI/\xc5\x86\ +\xb1\x84\xa1\xac\x82#f\xcc\x8c\x0cC\x8db\xcc\x5cb\ +X\xcd\xa5\x0c\xec\xa7L\x98\xa0\xd9\x08\xa1TI\xdd9\ +e\x22\x17\x89\x81\xb4W2\x88P\xcf\xbc\x1a\x11\xe6\xf3\ +\xe5'\x96\x09\x19\x1b:\x1e\x10q,z\xb3\x06E\x8d\ +\x22\x0d,}\x0e&lj\x8c\xa0\xc4}\x08NCH\ +\xd3\xe4\xe2\x15bY\x13\xa1\xa4\xcd\xdb\x89o\xb0\xc2\xaa\ +&\xf8\x8d\x9e\x91\x9f0\xe7\x98\x05+\xd1\xc7\x9eq\x07\ +K\xc9#\x1e\xf3\x95l\xdb8f\xc49\x15\x0d\x11'\ +\xbc\xc9\x1b\xccY\x90\xb3\xa0\x90\x86\x94\xe7\x5clQ\x8c\ +\xdf7\xd7\x080\x1d\x14]\xfas\xfd\x89\x95\x09O\x0f\ +\xb8\xd5\x1c\xcb\x88\xa0g,\xf9\xb7\x13]\xe3,M\xf0\ +3\xbd\x12\x90f(\x0d\xea\xbb\x1c\x1a%\xc0H+\x14\ +\x94N\xbeJ\x0fX\xffJ\x1a7~\x9et\xcc\x8cc\ +\xd1\xcb6T\xc4d\xcc\xb8\xc1\x86%+*\x1ck6\ +\xe4\x8c\xc8\x99q\xc4\x18\xc5\x86\x0aD\x92\xa7W\xd8\xed\ +\x06\x93\x1d\xea\xbb\xae\x86\xc2\xdc\x8bdX)\xa1\x10\xd7\ +g\x84-w\xc6\x88\xa9\xbc\xdcN\xc6\x8f\x87Tc\x13\ +F\x9aL\x18\x91v\xe1\xb0\x9b\xa0\x13\xd5\xb3!\x1bZ\ +\x1aZ\xf9\x0a\x13\x92\xfafo\x14\xbe#\x22a\xcc\x94\ +\x0b\xd6T(2\x1arf\xcc\x83\xc2\x88Wc\xd6\xe4\ +\xcc\x99\x93cYS\xa2\xa8\xe4\xf5g\xd2\xb2n|\xc2\ +x\x97{\xcf\xa5\x05D\xa4\xbf\xe7CC\xf4\x99\xfe|\ +\xf6\x95'\x0b*\xb9\xe7\x0b\xe9]I\xa0}&\xe7J\ +\x07\xa5\x97\xdd\xfc\x84\x11ZI+\xd5\x8a\x17\xdc#\x8c\ +7\xf7\x1c]+$4+\xd4\xe1\x9d\x86DD\xca\x15\ +[\x22\xc6\x924y1\xe1#Zi\x19n\x03\xe5\xd0\ +;M/:\xef\x0d\x14\x0b\xaabQ\xa8{\xd7\xcd\x19\ +F\xfb\xdckC\xfa\x11\xbfsw\xd5=}o\xfa\xeb\ +)\xa3\xdf\xae$\x11\xf1\x14\xcf^R\xd5\x8b\x9b\xb0\x97\ +l\xbb@\xcf\xd1\x81\x1d\xb9S\x18\xf1,\x89:\xa0\x05\ +\x9dh\x8cE\x81j\xeeg\xc6b\xd9\xd5U\xc2\x80o\ +\xd9\x9f\xa8Z4\x95\xbdf\x9d\x92\x04\xca\xb3\xabgA\ +\x18\xb4\x15\xd2P\x1df\xba\xb4(mj\x12\xf4=\x9e\ +?\xaf\xa1\x88\xb0\x1f\xb5\x9f\xda\x0f@}\x11\xdf\xe3\x1e\ +\x7f\xf0\x92\xae:0\x18]\x80s\x87S\xdf\xc3I`\ +B[\xc5\x89\x1cF\x07\xf2\x06\x1a\xc9\x1d-\x91\xac\x84\ +\xb0\x81P\xda\xd1\x89z\x89\x8fSCSF\x02\xc1\x95\ +,1$$$\xb42\xf9\xab\xf1\xa3V\x08\x9e\xe2\xc7\ +\x96|\xa9\x88\xc4\xbe-\x0bYH`\x9e\xef#\xc2D\ +\xe6]\xfb\x81\xfd\x80\xe3\xee\xf7\xed\x87\xfe\x09\x1a&\xd4\ +\x02\x89\xc6R\x0dF\x83Etj\x8f\x89\xbf?\xc7\xdd\ +\xcf\xe29\x19\x80\xe9\xf5\x08\xc7B\xf4\xe8\xbf\xce\x8b\xf8\ +\xb80\xe7\xdd\x086\xe6k\x8b\x02\xcb\x98\x8a5\xe7\xc0\ +$\x08A\xea0\xaa\xf0h0\xaf\xe1\x85@[\x09\xdd\ +\x1d\x1d\x1b\x964\x02\x15\xf1<\xa2H\x98\xa2\xba\xeb\x8e\ +\xa1\xc1~\xd8J\xd9\x1d3\xa3\x94\x9e\xe7\x88Lx\xb2\ +n\xf0f\x87\x03k:p\xe2\x94\x98\xa1\x92\xc3n\xe5\ +\xd8&\xc4\x92n\xa9\x103\x96@\x22\xacY\x1b\xe4\xc8\ +[*\xb6,\xb8\x92U4K\xb6\xa44\x83\x8c\xd4\x8a\ +\xf6\xd8F|\x91\xbfFH\x03I\x89\x8c\x9f7e\x1c\ +\x14\xd5\x9fC\x14\x11H\xffW\xcd?\xd8_\xee\x18\xab\ +\x1d9oPI\xc9\xachEzG\x0d8\xfcJn\ +\xb3\x158\xc4Jk\xad\x13U\xca\xde9\xf6\xfau\x11\ +\x0d\x95\xe8\x9e\xf6\x18DC!\xaa\xd9~\xed\x80\x1fH\ +X\xf2\x0d\xf79\xa7%\x13~\xe6\x8a3&(4\xb9\ +\xcc\xff\xa80\xc6\xe0I\xa8\xad@<\x15\x19\x19#`\ +C\x8d\xe5\x16\xf30\xde\xaf\xbe\xdbG\xf8\xab\xe1~\xd9\ +J>\x80Hx\xb6ldl\xc5\x1d\x0c\xb23\x18y\ +\xb4a\xc8D\x85<\xd4I\xba\xdc\x05\xef\x1f\xe1h\x18\ +\x03\x9a\x8a\x0dW\x94(Q\xaf\x8d\x84\x9e\xa6e\x98\xf1\ +\x09\xdf\xf2\x80+\x11\x1a\xf6\xb3\xc8%\x0b\x9e0\x96\x82\ +\xae\x7fCGA\xa7\xdb\x0a\xa3\xc7\xbb\xe5\x94\x18GA\ +G\x16<\xc4s\xc2\xe7!\xf3\xb6\xa7\x9c\x1bR&\x81\ +\xffx8\xdbMP\x88\xda]/\x7f[\x1b\xc1\xb1{\ +\xce\xb4\xe7D\xe6D\xa2\xa1\xdeQp\xc6\x9f\xf8\x8a+\ +:\xc6\xdc\xe1\xe7\xbc\xcb\x11Hs\xb9\xe6\x82\xfb|\xcd\ +\x19\x05\x8eZ\xd6\x0b@\xcd\x8a\x0bN\xc9(\x84\x18k\ +\x80)\x95D\x8dZ\x94f<\xf9\xcd\xf7\xef7(\x8e\ +9!\xf9\xb5\xbevh7\xbaNe\xc8\xdc3\xbfw\ +\x1fva\x8e\xd6\xffm\xb2G\xf8\xe6\xa9\x89\xbd\xc3\xa1\ +\xd5\xdd<\xa7\x0fz\x06M*P\xae\xc6p\xc1\x86G\ +|\xc9\x7f\xe5>%\x86\x9c\x85<\xf3\x84B\xf4\xf0\xae\ +8\xe3\x9c\xc7Th\x0c\x95h\xe9\xf7\x8b\xaaRr\xf9\ +\x0a\x17vz\xb5\xb2Xb7\xa5\x9e\xc8\xfe\xd0\x13\xee\ +p\x93\xe4s\xf5\x22>\xa2\x97\xe0R\x1fE\x94\xceO\ +\xe0\xd9\xa0\xda\xb1\x1b#\xd8e\x96\xfd\x84\x94\x1aL\xe6\ +\xb8`,M\xcdV\x18+~\xcf\x8a\xef\x9f&\xb2'\ +\xa3d\x03\xdc`\xce)\xb7iP\x9c\xd1\x92c\xa9x\ +\xc2\x9a\x0b\x1e\xf1\x0d\xe74\x02\xbc\x19\xaa\x90\x94\x17\x94\ +\xb2\xf7\xb1\xd7\x0fh\x04\xd9\xf4\xf9E%r\x1a\x19\x0d\ +k\x11\x17\x9c\xffc4\x08\xf5\xcf!\x9c*\xf1\xbc\xf5\ +\x9e>\x90\x12N\x15\x073\xbf;Q\x83\xee\x80\xd3\xdf\ +\x0a\x93\xa1\xa0\x09z\x03Y\x88\x121\xc7T\xe4\x8c\xb8\ +\xc9\x88\x9f\xf0\x1e7Ys\xc5\x96\x8as.XRr\ +\xc1\x19\xe7\x5c\xb0\xc5I\x85c\xa5\x83\xb5+\xed;\xc9\ +D}p\xeeB\xb2o(\x04\xe3\x8cXq\x85\xc20\ +%\xff\x95z\xbe\x8f\x18\x1e\x19\x8d#~\x1f\xcc\xa7\xd1\ +\x87N\x9ef!#\xe6\xfb\xcf}\x98W\xee\x8fD\xd7\ +\xa2\xad\xee\x88\x85a\xbbC\xaa;Q\x9a\xbc\xc1]n\ +\x91p\x9b)\x1dcF\x94<\xe6\x09\xf79\xa3c!\ +S\x19\xfd\xd5\xf3\x1d8\x15\x0a\xbfH\xc2%\xe2\x8e\xdb\ +\xb0\xd9\xa1o\xe1h2\x0c\xe7,\xb8I\x17\x84\xdb^\ +h\x12x\x07\xc6\x8d\xee\x81\xfbh7O{\xee\xf4\xc0\ +c\xa8\xa7t@\xf4@\x92Q\x05\xde\x84W\x17\xedq\ +\xea^\xbb\xba\x11\xec\xeb\x16\xa7\x82U\xc4\x94\x02\xd3\x97\ +,\xd9PsEAK\x02h\x09\xd8=\xb5\xd9\x08\xd6\ +\x19I\xab\xc6\x84\xb8\xe4'\xc5k\x01\xf0z\x95\xcb-\ +\x85\xcc1\xf7\xa3W/0\xe5w\xa8$gB\x9d\x91\ +\x0d\x86\x81\x5c\xc0\x13v\x9a\x0evO\xa8\xc0\xdfaO\ +F\xcdH\xc3\xbcV\x9fox\x86\x85O\x81\x0d\x95(\ +\xa6:\x147x\x0f\xc3\x05g\x5c\xb1\x09\x13z\xa9L\ +\x89\xf8\x81\x83)sN\xc9\x85\x9a\xd6\x05\xf9\xd7\xbe\xd2\ +\xb0\xe23\xeep\x0bG\xc21\x11\xb1h\xa9\xbf\xf4\xb8\ +\xe3\xd3\x9f\xda\xf7\xbe\xdc0\x0b=\xc8,\xfb\xa3\xd9\x0a\ +\x8c\x13I\xd3h(\xed\xe8\x02\x03\xa6\xc7=\xbd\xea\x99\ +\x0f\xb3\x8e\x19wy\x9d\x87<\xe1L\x96\x18ZRi\ +\xf8e\x18\x8cH\x8f\x0f\x05\x7fz\xd1\xdf\xdd\x03\xf1\xe0\ +\xaf\x91Nl|\xc0'\xfd\x1e\xdb\x1d\xa3\xcf\xcc'&\ +LY\xed\x9c\xe5\xae\x05\xd8\x0a\x94\xdaJ\x17=\x91\x9e\ +\x05\xb2\x10D\x0d\xc6g\x9d\xb8\xbeNh\x00Z\x06\x9d\ +*:\x09\x8bcr\x0cWB\x15\xf5\x13@\x91x\x9b\ +\x89pg\xfa\xael'\x86p\x83\xa1\xe7R\xe4`\xda\ +\xd0\xb1\xbf^\xef\xe8\x855f\x82!~\x13\x07\x85\x80\ +\xa1\xf4\x81;\x80\xd8\x90&\x8c\xa7\x96\x8c\x06\x94>\xf5\ +\x94<\x06\x82ED\xa2g\xd4\xc85\xd4\x228>c\ +\xce\x0979\xe5&\x13\xc6\xe4dL\x983\x11\x9a\x92\ +\x09\xc5]'\x8f\xa0\x96\x1e\x8c\x15\x10'\x91\x93h\x18\ +\x87\xa7\xee^U6\xa1\xffT=P\x12\x1anrw\ +\xe1\x87\xb9\x90\xdc\x18Y3\xa6\x02S!\x0aC\xd4\xfb\ +J\x97f/\x18k\xa9c\xc01\xe6\x88HZ\x8e\xc8\ +8c$0\xbe\xde\xd3\xa2\xe8\xa4\xf4\xaaCd\xd3\xe4\ +B<\xdc\xd00b\xc4\x0d\xd2W[+q\xdd \xcb\ +~\xa6\xd0_\x92\x9d\xcam$\x82\x15\xb1\xec\xe4$\xcc\ +wG\x03!`\xbb\xa7\xfd\xd1\xbf\x0d#\xfa@~9\ +\x88\xa6c\xc4\x14EFMM#\xacY'\x88\x85o\ +\x08t\x81\x9a\xe0D\x14\xb8\x0dM\x81)\xb9\xa0\x990\ +a\xceMr\xf5\xb4\xb0\xe8+\x18b\xe7 \xf7\xc7\xdd\ +\xbb\x10)\x8b\x06]\x15-\xc5\xf7\x84\x09\xe6\xf3\ +\x97I\x17_\xea\x97\x1e\x5c\x0dwM\xb6n\x07\x93\xa3\ +Q\xd8\xd7\xebOJ\xca\x9c\x98\x93\xa0/\xe8\x04\xafX\ +\xb3\xa1\x92E\xca\x95\xc0p\xbd>m\x8f>\x18\xf9\x0a\ +#s\xe0\x89\xb4\xf4\xac\xd4/\x914\x95{\xc3L8\ +a\x8e\xf9|\xa8\xb8\xfc\x03_\x8dg\x7fC\x13B\xa1\ +\x8f\xf3>\x90%\x12I\x12\x19_P\xb2o\xcfk\x90\ +\xcc\x89\xb1\x94\xb25g\xc5\x13\xceYJS\xf7\xb10\ +a*i\x0c\xf7\xd4\xa3\x96\x9a\x0c\xcb\x8d\x80O\xf89\ +\xafB\xb2M\x88\xc8\x85Jv\x9d>\xd6+\x19b_\ +oP\x13\xbf\xaf\xbfR\xe1\x12\xa8\x00\xc6\xd8 |\xb1\ +\x13f\xb2\x82*\xf5\xbb\x9d:\xd9\x84\xd0\x85\x5c\xb4\xa2\ +\x22e\xcc\x94\x115[@s*\xcb/K\x16X\x96\ +\x9c\xb3\x92E\xec\x17T\x92+(&h\x96\x1c\x91\xcb\ +8S\xc7Z\xf2\x0c\xef\x80s\x8e8Qj\xa0\xa5\xf5\ +E.d\x02\xdc\ +k\x0f\xd8\xb0\xdcr#'\xa6\x14\xbe^*Sf^\ +\x0c\xccW(\x06G\xc5\x96-\x85\xd0\x0a'\xdc\xe6\x0e\ +\x93_\xeb\x17H\xab_\xd9\x10\xa0\xd0_\xe8\x0f\x87m\ +_\x06p\x8d\x0a\xb3=n\x0f(u\x83\xc9R\x17\xe6\ +~\xa64\xa2IP\xe1hX\xb1bI-\x0c\xbcZ\ +\xd2m+J21#\x19u\x8e$\xaa \x1f\xf3\xaa\ +C\x05#\xc00\xe6\x989\xe9\xe7j\x0fH|\x81k\ +\xbfz)X\xc6R\xb1rW,D\xb9#\x0aD\x9c\ +~!\x95\x19d\x8d*8W\x7f\xf8\xfbU\xb8\x8dl\ +}\xeed\xf2\xb7\xa4\xa4e\xcd\x8as\x16\xa2Z\xecD\ +\xe6\xb9\xef\xc7\xfb\xb9\xb1\xa9\xc8\x05&a\xbd\x89\x1fr\ +)iH\x898\xe2_\xf1\x0b\xde}\x7ft\xefE\xa3\ +\xc5+F\x0dpw{\xe7\xd8Jq\xa5\x06\xad x\ +z\x99\x04\xa1&\x1c\xeeOqTr\xae\x22i\xff\xb4\ +4\x8c\xa4\x87\xea\xcb)B\x87\xd3\xc9(\xa6\x9f2\xac\ +\xe9h\xc8$\x1d/E\xba/A\x91s\xcc\x8c\xe4\xde\ +\xcb]\x8bW2\xc4\xae\xd6\xace=\x91\x1e\x90\xc9z\ +\xfd\x07\x0d\x07{\xba\x86\x86\xf0\x90Y#\xe6t\x03\xfc\ +3\x91S\xd6\x0d\xb8\x15\x9d,.H\x05\xa1\xb4\xd2\x0f\ +\x89\x84\x13\xb3\x116DB\xe47\x94\xff:~\x85\xf7\ +\xf3\xca\x86 L\xd8\xc5\xc2\xabi\x05L\xd1\xb2\x1fg\ +\xa8\x83\xbc\xaf\xda\xe0\xeb\xc5~YT+yE$\x9a\ +\xc6\x99\xd0\x8az0\xcfg\x13\x0d\x0c\xba\xf3\x0a\x84\x5c\ +\x5c\xc9\xd0\x82\x01&\xbc\xc6-\xf2\xcfy\xe6\xce\x84\x1f\ +\xd0\x10\xea\x9e\x0ac\x91v\x80Q\xf6\xfb\x90\x5c\x80\xd2\ +\xf6+T\xb5W\x07j`6h\xc9\xb4t\xc4\x8c\x85\ +\xdejdgC\xbf\x97/aD+\xe3k;1\xd8\ +*\x84\xc8\x9e\xf1\x7f\x837\x99\x7f\xa6\x9fA\x88\xfdA\ +\xa3\x06\x83\x89p_!\xf4\xe9\xb2G\x9a\xfb\xb3a\x07\ +{\x9a\x14\xfb\x8b\xca\x5c(\xd9\xd5\x8e\xdbIG\x1a\xea\ +R\x9f8\xf5\xcc\xcb:@2=\x89\xb8'&9\xd9\ +\xe9\xe7\xab\xdb\x9c;\xdc\x22\xfd\x8d\xbbF\xda\xf7\x07?\ +\x11*\xd8?\x96\xa1\x14\xff\xc4\xa2A\xa6a\xd9WB\ +\x1cn\xe3s\x831\x07\xcbP\xf8K\x09\xf3\xba\x11\xfe\ +m,\x86h\xc2\xf9JC\xfb\xc6\x89C\xed\x04\xe2Q\ +Dd\x9cH\x22E\xd82\xfa\xe3^\x8d\xa0bl\xc4\ +Y52^\x9c\x0d\xea\x8f\xe1\xdaJ\xbd\xa7\x8d\xbb\xe3\ +\xe0E\xec\xd6\xa1)\x81\xd9l``\xf7*\xc9\xdd\x01\ +\x19\xd9\xc9\x89\xb2b\x8eZ\x96\x1a\xa6\xcc\x99\x91\xa8\x97\ +l\xe8\xbej\xad\xb1\x93\xe8\x8fI\xc8D\x12)bJ\ +N!\xf9^?<\xdd+\x9f\xfa^D$)\xd8\xae\ +\x8b\xd1'eV\xc0|'\xe4\x0fG%\xd8c\xaft\ +\xec\xf9\xd4\x1b\x09\xd8\x08\xb8W\x07f\xb7#\xe1\x94\x9f\ +\xf2\x9a\x0cM\x1f.\xb0P?^\xd4\xe8g2b\xd2\ +@/\xadE\x97\xb8\x17\xedK\x84\xd5\xdfK\xf1\x9ap\ +6\x5c\xd0\xadf\xb0CA\x05\xb2\xea\x90Lbe\xdd\ +M3\x18si\x82x[?\xf48b\xc2\x9c\xec3\ +3\xd8\xdc\xe3~\xec\xf0\xd9\x17\xd811\x19\x994\xde\ +J*\x12)\x85\xfd\xbf\xb9d\x85;>n\xb4\xb7\x9a\ +F\x0fL\xd1_\xa96\x0c\xadt\xe2\x10+\xa97\x1a\ +i\x05\xb7\xf2\x7f#T\xf9\x88\x88\x11G\x9cpL\xfa\ +\x9bg\x13A~PC\xb8=\xb4\xb8Ou;Jy\ +ym\xd0\xd47\x18\xe9\xf1I\x05\xa1V\x02\xed+a44\ +r\xe3\x9dt*k\xd9\x93P\x00\xa5\xb0\xf2=\xacW\ +\x0b`\xe7EG\x8d\xf8\xa2\xa7\x89\xf2\xee`\x01\xef\x0f\ +`\x88\xa1{\xdc)\x9b\xfaC\x5c\xa2ei\xba\x95\xb2\ +\xa7\xa6F\xcb\x0cv#\x8a\xb7\x1eH\xa9eT5\x15\ +x5!a\x11\xbe\xd6\xca\x89h\xd1\x82Hy\xde\xe4\ +\x15Kj\x99\xfc\xed\xb3X\x9f\x95\xf4\xdb\x04sQ\xcc\ +\xcd\xb8-C\x94Jh\xa6\xee\x87\x86\xeaT\xc0y\xf4\ +`%%\x03\x8e\xad!\x16\xf5(\x1dj\x91.PG\ +T\x98\xea\xf3\x12I}\x83\xb6\x1f;\xb0\x92\x84iY\ +km%Dv\xa2k\xeb\x85\x9e\x0b:\xe9\x86\xd90\ +.\xe1/R'.;\xe6\xfb\xfd\x8a\x9e\xe7\x16\x9f>\ +!\x84\xbdk=\x01<\x95&\x8dw\x8d\xad\x88&\xfa\ +\x99,\x8fGUat\xc0aD\xbf\xce\x0f\x92 j\ +D\x91\x9c&\xa4\xcd\xd7p\xc9\x8a\x95\xccsUX\xaa\ +\x81\xe9\xbdw\xf0\x17\xc9\xf3q\xd3\xff\xf0\xa3\x19\xe2\x90\ +\x8c,\x9c\xa8O{\x9c@\xef}\x9e\x16\xf9\x95\xbe*\ +0R#tAr~+%\x92\xe7M\x8c8\x0a\xfb\ +\xc2\xbd!\x12\xa0\xa4a\xc5\x15+ja\xdd\xd6\x92R\ +9i\xfb\x1bQ+\x8d\xa5WR\x13{\x1d\x8a/~\ +4C\xec\x17\xdf\x04\xd2F\xdf\xb9\xe8\x8f\xb5\x92\xcc1\ +\x91P\xd8Osi1\xc2\x8eQ\xe9'4:\xb6l\ +\x89)\x88Ej\xd3W%3Z\xb6,\xb9d\xc1F\ +\xb6\xceV\x92\xa5\xd8\xa03a\x84Kg\xa4mh\x84\ +M\xa1\xf9\x91\x0d\xc1`\x8f\x96\x0e=\x8d\xbe\xba\xec\xd9\ +)\xb1\xf44\xfb\x1bo\x05J\xab\x83\x06\x80\x966~\ ++\xca\xd6J\x9a\xbe\xb1x\x0e\xc7\x94\x8a%KVl\ +\xc4]6ar\x18\xd1>\xd2\x03\x95\x81&\x94v\xd9\ +\x8fk\x08\xb7G\x1e\xb3\xd4\x1fd_@\xf7I#G\ +\xd4\x0d\x1at~\x9b\xa2~Jp\xa5\x0e\x07\x1aa\xcb\ +\x1a\x99\xd6\xeaX\x8b\x98x\x22\x18e*\x02{\xb5\xb0\ +_\x90<\x03!\x94\xf5\x1a\xecJ\xce\x99\xef\x8d\xf8z\ +'\x82\x1f\xd3\x10}\x82\xe2k\xbe\xd5\x1f\xdcg\xe67\ +=\x10\x12S\x85\xd0\xba[E\xd9\xc9t\xae?\x07\xad\ +\x9c\x1f#\x88U_\xbeW(\xa9\x1a*Y\x8eW\x0d\ +V\x0f\xda\xbd\x15D\xbb,\xf6\xb0\xb3\xe6\x13\xb0^n\ +\xf4G3\x84\x93\x14\xd8\xa0\xa9\xf9\x8b\xfb\x9a-\xff\xee\ +\x93c\xa9\xf9Z\xd9\xba\xaa\x84A\xe7$zk\x12*\ +\xb6(Q\x83K$\x1cZ:\xe2\xa0 \x13\xcbFV\ +\xbf\x18\xc2\xcaI\xe8\x85v\x86\xab\xb6u\xc0\xc34=\ +O\xbb\x0f\xd2\x9dD'\xaf\xaa\xa8\x9f\x8ak\xdf\xcd\xf6\ +x\xce\x98\x82{j\x99m\xcd\xa5\xfb3\x7f\xe2[~\ +JE\xf5\x89\x0d\x9e\x82\x01\x04\xa7C6iD\xf0\xa6\ +\x8f4\xdd\x80\x07\xd9ObyDa&\xe2\xbd\x9d\x90\ +\xc8uX&\xc1\x80N`\x0et\xafv%{&\x84\ +\xb3^\xdcuX\xb6\xbd\xc2\x89\xd8\x0f\x90;\xce\x91\xc3\ +\xb2p\x0b.\xf8g\xfe\x09\xc5\xbb\xfc\x9c\xe3\x01\xbcF\ +\xc8\xe4z\xb3\xf4\xb1!\x11\xd8-\x92\x1a@\xc9\x8a\xed\ +\xed \xb86\x02\xb3\x19r\xb9.]\xd8\xe5\xea\x06h\ +\xa6\x19\x0c\x1e\xa9\xbd\xde;B'\x88H\x19\xc9\xc6\xa8\ +\xe1\x93\xfe\x1e\x99\xe5.?\xef(>\xa8\xfep\xc9\x1f\ +\xf9\x923\xfe\xcc%\xbf\xe0\x7f\xe5]R\xb6\x942\x82\ +\x14\x0dXl\x04i\x1c_\x1a\xa7\x02\xca'\xc2\xa0\xf4\ +\xdc\x88\x9d\x80\x8fO\xd5\x1fa\x84y]\xcb\xa2\x80\xbe\ +\xfepb\xd8\xe1\xe2\xc4C\x05,G%\x9ae\x89\x08\ +\xba\xb8\x01\x14|\x1d\xf3\xef\xa5\xa8C\x16G\xc5\xa5{\ +\xc89_\xf2W\xbe\xe6\x9c\x98\x9f\xf3\xbf\xf1&\x0d-\ +\x0bY\xe6\xa0\x83~\x84\x0a\xab\xb2u\xc84z\x8az\ +\x22\x99BD\xc4V\x8a\xea*\xc8\xff\xf5\x88\xb4\xa7y\ +X\xe9|1p\xc1\xc3\x85sz\xeft \x9a\xa7\x8a\ +\x8aR\xe8\xa6\xfa\x80\xc0\xf2\xca'Bc\xd9~\xb0\xfe\ +\xc3\x05\xdf\xf0\x15\x0f\xb8\xa4\xe2\x92K~\xc2\xff\xc9\xbf\ +%f\x032\x97\xa3e4i\x08\xe92\xe8}\xba\xc0\ +\x911Rv\xc5\x14\xc2\x89i\xc2\x10Z<\x10W\xf1\ +\x9a\xa8*L\x10\xab\xc1\xe2k\xb5\x17:w\xff\xa4\xd2\ +\xf4k\xf6\xb6R?\x8b)\xfe\x12\x86\xa8Y\xb8o\xf8\ +\x0b\x8f8\xe3\x9c\x0d5O\xd8\xf0&\xff;?\x93\x8d\ +\xcb\x88\xcc\x8a\xf7\xd6\xf1\xc1\x8f\x8c\xf7\xdc\xd9\xee)j\ +\xf9hGA*\x93\xfa\x8d4\xfd\xeb\x80^\xec\xc8$\ +\xf6)\xb2\xda\xee<\x0cw\x91\x97r6[\x16<\xa4\ +p7\xdfO\xee\xc5\x83\xc7\xfa\xca\x08\xd5c\xf7\x0d\xff\ +\xcc\x1fE\x16Ss\xc1\x97\x8c\xf8?\xf8\xbfH\xb8\x12\ +<\xb0\x92/1\xd2\x89:\xfcV6`\x01;I\x0c\ ++\xd2\x1b7\xa9\x990f\xcc9\x89,\x1c\xd1\xa28\ +\xd5\x84\xb0i\xaf\xd9\xd8\xd6\xb7\x15\xf7O\xc4VF\xe7\ +\xd6\xdc\xe3\x02\xf8\x8f_M\x98\xaah\xaf\x0ez\x09C\ +\xf86ks\xd7~\xfc\xff\xf0G\xfe,\xd4\xe0F\xda\ +\xefo\xf3\xafp\xac\x83\xb0\xa7\xefSDhj\xb1\xe1\ +n?g;\x98\xc1\xe8\x84\x89\xb9;\x11\x09\x15#f\ +\x1c\xb3\xe4\x88\x05[\x1e\xb3d\x1b\xe4\xc5\xd5\xdeNz\ +\xb5\xa7M\xa0D!d_F2\xa6\xa6`N\xc6\x82\ +\xff\xca7\xac\xf97\xfc\x9d\xbb\xa1z\xe5U-*\xb9\ +*\xd0\xd2w[g\xaf\xc9#*V\xcek\xdd?f\ +AI\x1b\x10$\x98s*\xea>&\x88\xa3 \xd9\xc2\ +~W\x0bI\x88m \x07\x0cW\xd2\xfa)\x8d,4\ +\xf0\xfc\xc0Z\xce\x82\x95\x88g\x94\xc1Y\xda\xf0=v\ +m\xc2af\xa9B\xaeY\x0b\xeb\xaa\xa5\xe1\x82\xc7\xfc\ +\xdf\x9ccy\xdf\xcd\x19\xa9\xdd\xf03\xd2^\xec\x88\x04\ +@\xba\xbe\x17\xf6?\x00\xe1\x00\x14\x01\xde&\x16\xb2\x00\ +\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x08\ +\x0bwZ\x87\ +\x00h\ +\x00e\x00a\x00d\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/graphicsview/dragdroprobot/images/head.png b/examples/widgets/graphicsview/dragdroprobot/images/head.png new file mode 100644 index 0000000000000000000000000000000000000000..1e520e09b8d0bde4af5947c1430a83feae03a822 GIT binary patch literal 14972 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 0: + angle = Edge.TwoPi - angle + + sourceArrowP1 = self.sourcePoint + QtCore.QPointF(math.sin(angle + Edge.Pi / 3) * self.arrowSize, + math.cos(angle + Edge.Pi / 3) * self.arrowSize) + sourceArrowP2 = self.sourcePoint + QtCore.QPointF(math.sin(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize, + math.cos(angle + Edge.Pi - Edge.Pi / 3) * self.arrowSize) + destArrowP1 = self.destPoint + QtCore.QPointF(math.sin(angle - Edge.Pi / 3) * self.arrowSize, + math.cos(angle - Edge.Pi / 3) * self.arrowSize) + destArrowP2 = self.destPoint + QtCore.QPointF(math.sin(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize, + math.cos(angle - Edge.Pi + Edge.Pi / 3) * self.arrowSize) + + painter.setBrush(QtCore.Qt.black) + painter.drawPolygon(QtGui.QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2])) + painter.drawPolygon(QtGui.QPolygonF([line.p2(), destArrowP1, destArrowP2])) + + +class Node(QtWidgets.QGraphicsItem): + Type = QtWidgets.QGraphicsItem.UserType + 1 + + def __init__(self, graphWidget): + QtWidgets.QGraphicsItem.__init__(self) + + self.graph = weakref.ref(graphWidget) + self.edgeList = [] + self.newPos = QtCore.QPointF() + self.setFlag(QtWidgets.QGraphicsItem.ItemIsMovable) + self.setFlag(QtWidgets.QGraphicsItem.ItemSendsGeometryChanges) + self.setCacheMode(self.DeviceCoordinateCache) + self.setZValue(-1) + + def type(self): + return Node.Type + + def addEdge(self, edge): + self.edgeList.append(weakref.ref(edge)) + edge.adjust() + + def edges(self): + return self.edgeList + + def calculateForces(self): + if not self.scene() or self.scene().mouseGrabberItem() is self: + self.newPos = self.pos() + return + + # Sum up all forces pushing this item away. + xvel = 0.0 + yvel = 0.0 + for item in self.scene().items(): + if not isinstance(item, Node): + continue + + line = QtCore.QLineF(self.mapFromItem(item, 0, 0), QtCore.QPointF(0, 0)) + dx = line.dx() + dy = line.dy() + l = 2.0 * (dx * dx + dy * dy) + if l > 0: + xvel += (dx * 150.0) / l + yvel += (dy * 150.0) / l + + # Now subtract all forces pulling items together. + weight = (len(self.edgeList) + 1) * 10.0 + for edge in self.edgeList: + if edge().sourceNode() is self: + pos = self.mapFromItem(edge().destNode(), 0, 0) + else: + pos = self.mapFromItem(edge().sourceNode(), 0, 0) + xvel += pos.x() / weight + yvel += pos.y() / weight + + if QtCore.qAbs(xvel) < 0.1 and QtCore.qAbs(yvel) < 0.1: + xvel = yvel = 0.0 + + sceneRect = self.scene().sceneRect() + self.newPos = self.pos() + QtCore.QPointF(xvel, yvel) + self.newPos.setX(min(max(self.newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)) + self.newPos.setY(min(max(self.newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)) + + def advance(self): + if self.newPos == self.pos(): + return False + + self.setPos(self.newPos) + return True + + def boundingRect(self): + adjust = 2.0 + return QtCore.QRectF(-10 - adjust, -10 - adjust, + 23 + adjust, 23 + adjust) + + def shape(self): + path = QtGui.QPainterPath() + path.addEllipse(-10, -10, 20, 20) + return path + + def paint(self, painter, option, widget): + painter.setPen(QtCore.Qt.NoPen) + painter.setBrush(QtCore.Qt.darkGray) + painter.drawEllipse(-7, -7, 20, 20) + + gradient = QtGui.QRadialGradient(-3, -3, 10) + if option.state & QtWidgets.QStyle.State_Sunken: + gradient.setCenter(3, 3) + gradient.setFocalPoint(3, 3) + gradient.setColorAt(1, QtGui.QColor(QtCore.Qt.yellow).lighter(120)) + gradient.setColorAt(0, QtGui.QColor(QtCore.Qt.darkYellow).lighter(120)) + else: + gradient.setColorAt(0, QtCore.Qt.yellow) + gradient.setColorAt(1, QtCore.Qt.darkYellow) + + painter.setBrush(QtGui.QBrush(gradient)) + painter.setPen(QtGui.QPen(QtCore.Qt.black, 0)) + painter.drawEllipse(-10, -10, 20, 20) + + def itemChange(self, change, value): + if change == QtWidgets.QGraphicsItem.ItemPositionChange: + for edge in self.edgeList: + edge().adjust() + self.graph().itemMoved() + + return QtWidgets.QGraphicsItem.itemChange(self, change, value) + + def mousePressEvent(self, event): + self.update() + QtWidgets.QGraphicsItem.mousePressEvent(self, event) + + def mouseReleaseEvent(self, event): + self.update() + QtWidgets.QGraphicsItem.mouseReleaseEvent(self, event) + + +class GraphWidget(QtWidgets.QGraphicsView): + def __init__(self): + QtWidgets.QGraphicsView.__init__(self) + + self.timerId = 0 + + scene = QtWidgets.QGraphicsScene(self) + scene.setItemIndexMethod(QtWidgets.QGraphicsScene.NoIndex) + scene.setSceneRect(-200, -200, 400, 400) + self.setScene(scene) + self.setCacheMode(QtWidgets.QGraphicsView.CacheBackground) + self.setRenderHint(QtGui.QPainter.Antialiasing) + self.setTransformationAnchor(QtWidgets.QGraphicsView.AnchorUnderMouse) + self.setResizeAnchor(QtWidgets.QGraphicsView.AnchorViewCenter) + + node1 = Node(self) + node2 = Node(self) + node3 = Node(self) + node4 = Node(self) + self.centerNode = Node(self) + node6 = Node(self) + node7 = Node(self) + node8 = Node(self) + node9 = Node(self) + scene.addItem(node1) + scene.addItem(node2) + scene.addItem(node3) + scene.addItem(node4) + scene.addItem(self.centerNode) + scene.addItem(node6) + scene.addItem(node7) + scene.addItem(node8) + scene.addItem(node9) + scene.addItem(Edge(node1, node2)) + scene.addItem(Edge(node2, node3)) + scene.addItem(Edge(node2, self.centerNode)) + scene.addItem(Edge(node3, node6)) + scene.addItem(Edge(node4, node1)) + scene.addItem(Edge(node4, self.centerNode)) + scene.addItem(Edge(self.centerNode, node6)) + scene.addItem(Edge(self.centerNode, node8)) + scene.addItem(Edge(node6, node9)) + scene.addItem(Edge(node7, node4)) + scene.addItem(Edge(node8, node7)) + scene.addItem(Edge(node9, node8)) + + node1.setPos(-50, -50) + node2.setPos(0, -50) + node3.setPos(50, -50) + node4.setPos(-50, 0) + self.centerNode.setPos(0, 0) + node6.setPos(50, 0) + node7.setPos(-50, 50) + node8.setPos(0, 50) + node9.setPos(50, 50) + + self.scale(0.8, 0.8) + self.setMinimumSize(400, 400) + self.setWindowTitle(self.tr("Elastic Nodes")) + + def itemMoved(self): + if not self.timerId: + self.timerId = self.startTimer(1000 / 25) + + def keyPressEvent(self, event): + key = event.key() + + if key == QtCore.Qt.Key_Up: + self.centerNode.moveBy(0, -20) + elif key == QtCore.Qt.Key_Down: + self.centerNode.moveBy(0, 20) + elif key == QtCore.Qt.Key_Left: + self.centerNode.moveBy(-20, 0) + elif key == QtCore.Qt.Key_Right: + self.centerNode.moveBy(20, 0) + elif key == QtCore.Qt.Key_Plus: + self.scaleView(1.2) + elif key == QtCore.Qt.Key_Minus: + self.scaleView(1 / 1.2) + elif key == QtCore.Qt.Key_Space or key == QtCore.Qt.Key_Enter: + for item in self.scene().items(): + if isinstance(item, Node): + item.setPos(-150 + random(300), -150 + random(300)) + else: + QtWidgets.QGraphicsView.keyPressEvent(self, event) + + + def timerEvent(self, event): + nodes = [item for item in self.scene().items() if isinstance(item, Node)] + + for node in nodes: + node.calculateForces() + + itemsMoved = False + for node in nodes: + if node.advance(): + itemsMoved = True + + if not itemsMoved: + self.killTimer(self.timerId) + self.timerId = 0 + + def wheelEvent(self, event): + self.scaleView(math.pow(2.0, -event.delta() / 240.0)) + + def drawBackground(self, painter, rect): + # Shadow. + sceneRect = self.sceneRect() + rightShadow = QtCore.QRectF(sceneRect.right(), sceneRect.top() + 5, 5, sceneRect.height()) + bottomShadow = QtCore.QRectF(sceneRect.left() + 5, sceneRect.bottom(), sceneRect.width(), 5) + if rightShadow.intersects(rect) or rightShadow.contains(rect): + painter.fillRect(rightShadow, QtCore.Qt.darkGray) + if bottomShadow.intersects(rect) or bottomShadow.contains(rect): + painter.fillRect(bottomShadow, QtCore.Qt.darkGray) + + # Fill. + gradient = QtGui.QLinearGradient(sceneRect.topLeft(), sceneRect.bottomRight()) + gradient.setColorAt(0, QtCore.Qt.white) + gradient.setColorAt(1, QtCore.Qt.lightGray) + painter.fillRect(rect.intersected(sceneRect), QtGui.QBrush(gradient)) + painter.setBrush(QtCore.Qt.NoBrush) + painter.drawRect(sceneRect) + + # Text. + textRect = QtCore.QRectF(sceneRect.left() + 4, sceneRect.top() + 4, + sceneRect.width() - 4, sceneRect.height() - 4) + message = self.tr("Click and drag the nodes around, and zoom with the " + "mouse wheel or the '+' and '-' keys") + + font = painter.font() + font.setBold(True) + font.setPointSize(14) + painter.setFont(font) + painter.setPen(QtCore.Qt.lightGray) + painter.drawText(textRect.translated(2, 2), message) + painter.setPen(QtCore.Qt.black) + painter.drawText(textRect, message) + + def scaleView(self, scaleFactor): + factor = self.matrix().scale(scaleFactor, scaleFactor).mapRect(QtCore.QRectF(0, 0, 1, 1)).width() + + if factor < 0.07 or factor > 100: + return + + self.scale(scaleFactor, scaleFactor) + + +if __name__ == "__main__": + app = QtWidgets.QApplication(sys.argv) + + widget = GraphWidget() + widget.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/graphicsview/graphicsview.pyproject b/examples/widgets/graphicsview/graphicsview.pyproject new file mode 100644 index 0000000..007d36b --- /dev/null +++ b/examples/widgets/graphicsview/graphicsview.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["elasticnodes.py", "anchorlayout.py"] +} diff --git a/examples/widgets/itemviews/addressbook/adddialogwidget.py b/examples/widgets/itemviews/addressbook/adddialogwidget.py new file mode 100644 index 0000000..7991039 --- /dev/null +++ b/examples/widgets/itemviews/addressbook/adddialogwidget.py @@ -0,0 +1,102 @@ + +############################################################################# +## +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt +from PySide2.QtWidgets import (QDialog, QLabel, QTextEdit, QLineEdit, + QDialogButtonBox, QGridLayout, QVBoxLayout) + +class AddDialogWidget(QDialog): + """ A dialog to add a new address to the addressbook. """ + + def __init__(self, parent=None): + super(AddDialogWidget, self).__init__(parent) + + nameLabel = QLabel("Name") + addressLabel = QLabel("Address") + buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | + QDialogButtonBox.Cancel) + + self.nameText = QLineEdit() + self.addressText = QTextEdit() + + grid = QGridLayout() + grid.setColumnStretch(1, 2) + grid.addWidget(nameLabel, 0, 0) + grid.addWidget(self.nameText, 0, 1) + grid.addWidget(addressLabel, 1, 0, Qt.AlignLeft | Qt.AlignTop) + grid.addWidget(self.addressText, 1, 1, Qt.AlignLeft) + + layout = QVBoxLayout() + layout.addLayout(grid) + layout.addWidget(buttonBox) + + self.setLayout(layout) + + self.setWindowTitle("Add a Contact") + + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + + # These properties make using this dialog a little cleaner. It's much + # nicer to type "addDialog.address" to retrieve the address as compared + # to "addDialog.addressText.toPlainText()" + @property + def name(self): + return self.nameText.text() + + @property + def address(self): + return self.addressText.toPlainText() + + +if __name__ == "__main__": + import sys + from PySide2.QtWidgets import QApplication + + app = QApplication(sys.argv) + + dialog = AddDialogWidget() + if (dialog.exec_()): + name = dialog.name + address = dialog.address + print("Name:" + name) + print("Address:" + address) diff --git a/examples/widgets/itemviews/addressbook/addressbook.py b/examples/widgets/itemviews/addressbook/addressbook.py new file mode 100644 index 0000000..262027a --- /dev/null +++ b/examples/widgets/itemviews/addressbook/addressbook.py @@ -0,0 +1,130 @@ + +############################################################################# +## +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import (QMainWindow, QAction, QFileDialog, QApplication) + +from addresswidget import AddressWidget + + +class MainWindow(QMainWindow): + + def __init__(self, parent=None): + super(MainWindow, self).__init__(parent) + + self.addressWidget = AddressWidget() + self.setCentralWidget(self.addressWidget) + self.createMenus() + self.setWindowTitle("Address Book") + + def createMenus(self): + # Create the main menuBar menu items + fileMenu = self.menuBar().addMenu("&File") + toolMenu = self.menuBar().addMenu("&Tools") + + # Populate the File menu + openAction = self.createAction("&Open...", fileMenu, self.openFile) + saveAction = self.createAction("&Save As...", fileMenu, self.saveFile) + fileMenu.addSeparator() + exitAction = self.createAction("E&xit", fileMenu, self.close) + + # Populate the Tools menu + addAction = self.createAction("&Add Entry...", toolMenu, self.addressWidget.addEntry) + self.editAction = self.createAction("&Edit Entry...", toolMenu, self.addressWidget.editEntry) + toolMenu.addSeparator() + self.removeAction = self.createAction("&Remove Entry", toolMenu, self.addressWidget.removeEntry) + + # Disable the edit and remove menu items initially, as there are + # no items yet. + self.editAction.setEnabled(False) + self.removeAction.setEnabled(False) + + # Wire up the updateActions slot + self.addressWidget.selectionChanged.connect(self.updateActions) + + def createAction(self, text, menu, slot): + """ Helper function to save typing when populating menus + with action. + """ + action = QAction(text, self) + menu.addAction(action) + action.triggered.connect(slot) + return action + + # Quick gotcha: + # + # QFiledialog.getOpenFilename and QFileDialog.get.SaveFileName don't + # behave in PySide2 as they do in Qt, where they return a QString + # containing the filename. + # + # In PySide2, these functions return a tuple: (filename, filter) + + def openFile(self): + filename, _ = QFileDialog.getOpenFileName(self) + if filename: + self.addressWidget.readFromFile(filename) + + def saveFile(self): + filename, _ = QFileDialog.getSaveFileName(self) + if filename: + self.addressWidget.writeToFile(filename) + + def updateActions(self, selection): + """ Only allow the user to remove or edit an item if an item + is actually selected. + """ + indexes = selection.indexes() + + if len(indexes) > 0: + self.removeAction.setEnabled(True) + self.editAction.setEnabled(True) + else: + self.removeAction.setEnabled(False) + self.editAction.setEnabled(False) + + +if __name__ == "__main__": + """ Run the application. """ + import sys + app = QApplication(sys.argv) + mw = MainWindow() + mw.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/addressbook/addressbook.pyproject b/examples/widgets/itemviews/addressbook/addressbook.pyproject new file mode 100644 index 0000000..2aa7637 --- /dev/null +++ b/examples/widgets/itemviews/addressbook/addressbook.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["tablemodel.py", "addressbook.py", "adddialogwidget.py", + "addresswidget.py", "newaddresstab.py"] +} diff --git a/examples/widgets/itemviews/addressbook/addresswidget.py b/examples/widgets/itemviews/addressbook/addresswidget.py new file mode 100644 index 0000000..d0c1747 --- /dev/null +++ b/examples/widgets/itemviews/addressbook/addresswidget.py @@ -0,0 +1,248 @@ + +############################################################################# +## +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +try: + import cpickle as pickle +except ImportError: + import pickle + +from PySide2.QtCore import (Qt, Signal, QRegularExpression, QModelIndex, + QItemSelection, QSortFilterProxyModel) +from PySide2.QtWidgets import QTabWidget, QMessageBox, QTableView, QAbstractItemView + +from tablemodel import TableModel +from newaddresstab import NewAddressTab +from adddialogwidget import AddDialogWidget + + +class AddressWidget(QTabWidget): + """ The central widget of the application. Most of the addressbook's + functionality is contained in this class. + """ + + selectionChanged = Signal(QItemSelection) + + def __init__(self, parent=None): + """ Initialize the AddressWidget. """ + super(AddressWidget, self).__init__(parent) + + self.tableModel = TableModel() + self.newAddressTab = NewAddressTab() + self.newAddressTab.sendDetails.connect(self.addEntry) + + self.addTab(self.newAddressTab, "Address Book") + + self.setupTabs() + + def addEntry(self, name=None, address=None): + """ Add an entry to the addressbook. """ + if name is None and address is None: + addDialog = AddDialogWidget() + + if addDialog.exec_(): + name = addDialog.name + address = addDialog.address + + address = {"name": name, "address": address} + addresses = self.tableModel.addresses[:] + + # The QT docs for this example state that what we're doing here + # is checking if the entered name already exists. What they + # (and we here) are actually doing is checking if the whole + # name/address pair exists already - ok for the purposes of this + # example, but obviously not how a real addressbook application + # should behave. + try: + addresses.remove(address) + QMessageBox.information(self, "Duplicate Name", + "The name \"%s\" already exists." % name) + except ValueError: + # The address didn't already exist, so let's add it to the model. + + # Step 1: create the row + self.tableModel.insertRows(0) + + # Step 2: get the index of the newly created row and use it. + # to set the name + ix = self.tableModel.index(0, 0, QModelIndex()) + self.tableModel.setData(ix, address["name"], Qt.EditRole) + + # Step 3: lather, rinse, repeat for the address. + ix = self.tableModel.index(0, 1, QModelIndex()) + self.tableModel.setData(ix, address["address"], Qt.EditRole) + + # Remove the newAddressTab, as we now have at least one + # address in the model. + self.removeTab(self.indexOf(self.newAddressTab)) + + # The screenshot for the QT example shows nicely formatted + # multiline cells, but the actual application doesn't behave + # quite so nicely, at least on Ubuntu. Here we resize the newly + # created row so that multiline addresses look reasonable. + tableView = self.currentWidget() + tableView.resizeRowToContents(ix.row()) + + def editEntry(self): + """ Edit an entry in the addressbook. """ + tableView = self.currentWidget() + proxyModel = tableView.model() + selectionModel = tableView.selectionModel() + + # Get the name and address of the currently selected row. + indexes = selectionModel.selectedRows() + + for index in indexes: + row = proxyModel.mapToSource(index).row() + ix = self.tableModel.index(row, 0, QModelIndex()) + name = self.tableModel.data(ix, Qt.DisplayRole) + ix = self.tableModel.index(row, 1, QModelIndex()) + address = self.tableModel.data(ix, Qt.DisplayRole) + + # Open an addDialogWidget, and only allow the user to edit the address. + addDialog = AddDialogWidget() + addDialog.setWindowTitle("Edit a Contact") + + addDialog.nameText.setReadOnly(True) + addDialog.nameText.setText(name) + addDialog.addressText.setText(address) + + # If the address is different, add it to the model. + if addDialog.exec_(): + newAddress = addDialog.address + if newAddress != address: + ix = self.tableModel.index(row, 1, QModelIndex()) + self.tableModel.setData(ix, newAddress, Qt.EditRole) + + def removeEntry(self): + """ Remove an entry from the addressbook. """ + tableView = self.currentWidget() + proxyModel = tableView.model() + selectionModel = tableView.selectionModel() + + # Just like editEntry, but this time remove the selected row. + indexes = selectionModel.selectedRows() + + for index in indexes: + row = proxyModel.mapToSource(index).row() + self.tableModel.removeRows(row) + + # If we've removed the last address in the model, display the + # newAddressTab + if self.tableModel.rowCount() == 0: + self.insertTab(0, self.newAddressTab, "Address Book") + + def setupTabs(self): + """ Setup the various tabs in the AddressWidget. """ + groups = ["ABC", "DEF", "GHI", "JKL", "MNO", "PQR", "STU", "VW", "XYZ"] + + for group in groups: + proxyModel = QSortFilterProxyModel(self) + proxyModel.setSourceModel(self.tableModel) + proxyModel.setDynamicSortFilter(True) + + tableView = QTableView() + tableView.setModel(proxyModel) + tableView.setSortingEnabled(True) + tableView.setSelectionBehavior(QAbstractItemView.SelectRows) + tableView.horizontalHeader().setStretchLastSection(True) + tableView.verticalHeader().hide() + tableView.setEditTriggers(QAbstractItemView.NoEditTriggers) + tableView.setSelectionMode(QAbstractItemView.SingleSelection) + + # This here be the magic: we use the group name (e.g. "ABC") to + # build the regex for the QSortFilterProxyModel for the group's + # tab. The regex will end up looking like "^[ABC].*", only + # allowing this tab to display items where the name starts with + # "A", "B", or "C". Notice that we set it to be case-insensitive. + re = QRegularExpression("^[{}].*".format(group)) + assert re.isValid() + re.setPatternOptions(QRegularExpression.CaseInsensitiveOption) + proxyModel.setFilterRegularExpression(re) + proxyModel.setFilterKeyColumn(0) # Filter on the "name" column + proxyModel.sort(0, Qt.AscendingOrder) + + # This prevents an application crash (see: http://www.qtcentre.org/threads/58874-QListView-SelectionModel-selectionChanged-Crash) + viewselectionmodel = tableView.selectionModel() + tableView.selectionModel().selectionChanged.connect(self.selectionChanged) + + self.addTab(tableView, group) + + # Note: the QT example uses a QDataStream for the saving and loading. + # Here we're using a python dictionary to store the addresses, which + # can't be streamed using QDataStream, so we just use cpickle for this + # example. + def readFromFile(self, filename): + """ Read contacts in from a file. """ + try: + f = open(filename, "rb") + addresses = pickle.load(f) + except IOError: + QMessageBox.information(self, "Unable to open file: %s" % filename) + finally: + f.close() + + if len(addresses) == 0: + QMessageBox.information(self, "No contacts in file: %s" % filename) + else: + for address in addresses: + self.addEntry(address["name"], address["address"]) + + def writeToFile(self, filename): + """ Save all contacts in the model to a file. """ + try: + f = open(filename, "wb") + pickle.dump(self.tableModel.addresses, f) + + except IOError: + QMessageBox.information(self, "Unable to open file: %s" % filename) + finally: + f.close() + + +if __name__ == "__main__": + import sys + from PySide2.QtWidgets import QApplication + + app = QApplication(sys.argv) + addressWidget = AddressWidget() + addressWidget.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/addressbook/newaddresstab.py b/examples/widgets/itemviews/addressbook/newaddresstab.py new file mode 100644 index 0000000..ab54fb8 --- /dev/null +++ b/examples/widgets/itemviews/addressbook/newaddresstab.py @@ -0,0 +1,93 @@ + +############################################################################# +## +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import (Qt, Signal) +from PySide2.QtWidgets import (QWidget, QLabel, QPushButton, QVBoxLayout) + +from adddialogwidget import AddDialogWidget + +class NewAddressTab(QWidget): + """ An extra tab that prompts the user to add new contacts. + To be displayed only when there are no contacts in the model. + """ + + sendDetails = Signal(str, str) + + def __init__(self, parent=None): + super(NewAddressTab, self).__init__(parent) + + descriptionLabel = QLabel("There are no contacts in your address book." + "\nClick Add to add new contacts.") + + addButton = QPushButton("Add") + + layout = QVBoxLayout() + layout.addWidget(descriptionLabel) + layout.addWidget(addButton, 0, Qt.AlignCenter) + + self.setLayout(layout) + + addButton.clicked.connect(self.addEntry) + + def addEntry(self): + addDialog = AddDialogWidget() + + if addDialog.exec_(): + name = addDialog.name + address = addDialog.address + self.sendDetails.emit(name, address) + + +if __name__ == "__main__": + + def printAddress(name, address): + print("Name:" + name) + print("Address:" + address) + + import sys + from PySide2.QtWidgets import QApplication + + app = QApplication(sys.argv) + newAddressTab = NewAddressTab() + newAddressTab.sendDetails.connect(printAddress) + newAddressTab.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/addressbook/tablemodel.py b/examples/widgets/itemviews/addressbook/tablemodel.py new file mode 100644 index 0000000..155f091 --- /dev/null +++ b/examples/widgets/itemviews/addressbook/tablemodel.py @@ -0,0 +1,146 @@ + +############################################################################# +## +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import (Qt, QAbstractTableModel, QModelIndex) + +class TableModel(QAbstractTableModel): + + def __init__(self, addresses=None, parent=None): + super(TableModel, self).__init__(parent) + + if addresses is None: + self.addresses = [] + else: + self.addresses = addresses + + def rowCount(self, index=QModelIndex()): + """ Returns the number of rows the model holds. """ + return len(self.addresses) + + def columnCount(self, index=QModelIndex()): + """ Returns the number of columns the model holds. """ + return 2 + + def data(self, index, role=Qt.DisplayRole): + """ Depending on the index and role given, return data. If not + returning data, return None (PySide equivalent of QT's + "invalid QVariant"). + """ + if not index.isValid(): + return None + + if not 0 <= index.row() < len(self.addresses): + return None + + if role == Qt.DisplayRole: + name = self.addresses[index.row()]["name"] + address = self.addresses[index.row()]["address"] + + if index.column() == 0: + return name + elif index.column() == 1: + return address + + return None + + def headerData(self, section, orientation, role=Qt.DisplayRole): + """ Set the headers to be displayed. """ + if role != Qt.DisplayRole: + return None + + if orientation == Qt.Horizontal: + if section == 0: + return "Name" + elif section == 1: + return "Address" + + return None + + def insertRows(self, position, rows=1, index=QModelIndex()): + """ Insert a row into the model. """ + self.beginInsertRows(QModelIndex(), position, position + rows - 1) + + for row in range(rows): + self.addresses.insert(position + row, {"name":"", "address":""}) + + self.endInsertRows() + return True + + def removeRows(self, position, rows=1, index=QModelIndex()): + """ Remove a row from the model. """ + self.beginRemoveRows(QModelIndex(), position, position + rows - 1) + + del self.addresses[position:position+rows] + + self.endRemoveRows() + return True + + def setData(self, index, value, role=Qt.EditRole): + """ Adjust the data (set it to ) depending on the given + index and role. + """ + if role != Qt.EditRole: + return False + + if index.isValid() and 0 <= index.row() < len(self.addresses): + address = self.addresses[index.row()] + if index.column() == 0: + address["name"] = value + elif index.column() == 1: + address["address"] = value + else: + return False + + self.dataChanged.emit(index, index, 0) + return True + + return False + + def flags(self, index): + """ Set the item flags at the given index. Seems like we're + implementing this function just to see how it's done, as we + manually adjust each tableView to have NoEditTriggers. + """ + if not index.isValid(): + return Qt.ItemIsEnabled + return Qt.ItemFlags(QAbstractTableModel.flags(self, index) | + Qt.ItemIsEditable) diff --git a/examples/widgets/itemviews/basicsortfiltermodel.py b/examples/widgets/itemviews/basicsortfiltermodel.py new file mode 100644 index 0000000..00441ff --- /dev/null +++ b/examples/widgets/itemviews/basicsortfiltermodel.py @@ -0,0 +1,213 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import (QDate, QDateTime, QRegularExpression, + QSortFilterProxyModel, QTime, Qt) +from PySide2.QtGui import QStandardItemModel +from PySide2.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, + QGroupBox, QHBoxLayout, QLabel, QLineEdit, + QTreeView, QVBoxLayout, QWidget) + + +REGULAR_EXPRESSION = 0 +WILDCARD = 1 +FIXED_STRING = 2 + + +class Window(QWidget): + def __init__(self): + super(Window, self).__init__() + + self.proxyModel = QSortFilterProxyModel() + self.proxyModel.setDynamicSortFilter(True) + + self.sourceGroupBox = QGroupBox("Original Model") + self.proxyGroupBox = QGroupBox("Sorted/Filtered Model") + + self.sourceView = QTreeView() + self.sourceView.setRootIsDecorated(False) + self.sourceView.setAlternatingRowColors(True) + + self.proxyView = QTreeView() + self.proxyView.setRootIsDecorated(False) + self.proxyView.setAlternatingRowColors(True) + self.proxyView.setModel(self.proxyModel) + self.proxyView.setSortingEnabled(True) + + self.sortCaseSensitivityCheckBox = QCheckBox("Case sensitive sorting") + self.filterCaseSensitivityCheckBox = QCheckBox("Case sensitive filter") + + self.filterPatternLineEdit = QLineEdit() + self.filterPatternLineEdit.setClearButtonEnabled(True) + self.filterPatternLabel = QLabel("&Filter pattern:") + self.filterPatternLabel.setBuddy(self.filterPatternLineEdit) + + self.filterSyntaxComboBox = QComboBox() + self.filterSyntaxComboBox.addItem("Regular expression", + REGULAR_EXPRESSION) + self.filterSyntaxComboBox.addItem("Wildcard", + WILDCARD) + self.filterSyntaxComboBox.addItem("Fixed string", + FIXED_STRING) + self.filterSyntaxLabel = QLabel("Filter &syntax:") + self.filterSyntaxLabel.setBuddy(self.filterSyntaxComboBox) + + self.filterColumnComboBox = QComboBox() + self.filterColumnComboBox.addItem("Subject") + self.filterColumnComboBox.addItem("Sender") + self.filterColumnComboBox.addItem("Date") + self.filterColumnLabel = QLabel("Filter &column:") + self.filterColumnLabel.setBuddy(self.filterColumnComboBox) + + self.filterPatternLineEdit.textChanged.connect(self.filterRegExpChanged) + self.filterSyntaxComboBox.currentIndexChanged.connect(self.filterRegExpChanged) + self.filterColumnComboBox.currentIndexChanged.connect(self.filterColumnChanged) + self.filterCaseSensitivityCheckBox.toggled.connect(self.filterRegExpChanged) + self.sortCaseSensitivityCheckBox.toggled.connect(self.sortChanged) + + sourceLayout = QHBoxLayout() + sourceLayout.addWidget(self.sourceView) + self.sourceGroupBox.setLayout(sourceLayout) + + proxyLayout = QGridLayout() + proxyLayout.addWidget(self.proxyView, 0, 0, 1, 3) + proxyLayout.addWidget(self.filterPatternLabel, 1, 0) + proxyLayout.addWidget(self.filterPatternLineEdit, 1, 1, 1, 2) + proxyLayout.addWidget(self.filterSyntaxLabel, 2, 0) + proxyLayout.addWidget(self.filterSyntaxComboBox, 2, 1, 1, 2) + proxyLayout.addWidget(self.filterColumnLabel, 3, 0) + proxyLayout.addWidget(self.filterColumnComboBox, 3, 1, 1, 2) + proxyLayout.addWidget(self.filterCaseSensitivityCheckBox, 4, 0, 1, 2) + proxyLayout.addWidget(self.sortCaseSensitivityCheckBox, 4, 2) + self.proxyGroupBox.setLayout(proxyLayout) + + mainLayout = QVBoxLayout() + mainLayout.addWidget(self.sourceGroupBox) + mainLayout.addWidget(self.proxyGroupBox) + self.setLayout(mainLayout) + + self.setWindowTitle("Basic Sort/Filter Model") + self.resize(500, 450) + + self.proxyView.sortByColumn(1, Qt.AscendingOrder) + self.filterColumnComboBox.setCurrentIndex(1) + + self.filterPatternLineEdit.setText("Andy|Grace") + self.filterCaseSensitivityCheckBox.setChecked(True) + self.sortCaseSensitivityCheckBox.setChecked(True) + + def setSourceModel(self, model): + self.proxyModel.setSourceModel(model) + self.sourceView.setModel(model) + + def filterRegExpChanged(self): + syntax_nr = self.filterSyntaxComboBox.currentData() + pattern = self.filterPatternLineEdit.text() + if syntax_nr == WILDCARD: + pattern = QRegularExpression.wildcardToRegularExpression(pattern) + elif syntax_nr == FIXED_STRING: + pattern = QRegularExpression.escape(pattern) + + regExp = QRegularExpression(pattern) + if not self.filterCaseSensitivityCheckBox.isChecked(): + options = regExp.patternOptions() + options |= QRegularExpression.CaseInsensitiveOption + regExp.setPatternOptions(options) + self.proxyModel.setFilterRegularExpression(regExp) + + def filterColumnChanged(self): + self.proxyModel.setFilterKeyColumn(self.filterColumnComboBox.currentIndex()) + + def sortChanged(self): + if self.sortCaseSensitivityCheckBox.isChecked(): + caseSensitivity = Qt.CaseSensitive + else: + caseSensitivity = Qt.CaseInsensitive + + self.proxyModel.setSortCaseSensitivity(caseSensitivity) + + +def addMail(model, subject, sender, date): + model.insertRow(0) + model.setData(model.index(0, 0), subject) + model.setData(model.index(0, 1), sender) + model.setData(model.index(0, 2), date) + + +def createMailModel(parent): + model = QStandardItemModel(0, 3, parent) + + model.setHeaderData(0, Qt.Horizontal, "Subject") + model.setHeaderData(1, Qt.Horizontal, "Sender") + model.setHeaderData(2, Qt.Horizontal, "Date") + + addMail(model, "Happy New Year!", "Grace K. ", + QDateTime(QDate(2006, 12, 31), QTime(17, 3))) + addMail(model, "Radically new concept", "Grace K. ", + QDateTime(QDate(2006, 12, 22), QTime(9, 44))) + addMail(model, "Accounts", "pascale@nospam.com", + QDateTime(QDate(2006, 12, 31), QTime(12, 50))) + addMail(model, "Expenses", "Joe Bloggs ", + QDateTime(QDate(2006, 12, 25), QTime(11, 39))) + addMail(model, "Re: Expenses", "Andy ", + QDateTime(QDate(2007, 1, 2), QTime(16, 5))) + addMail(model, "Re: Accounts", "Joe Bloggs ", + QDateTime(QDate(2007, 1, 3), QTime(14, 18))) + addMail(model, "Re: Accounts", "Andy ", + QDateTime(QDate(2007, 1, 3), QTime(14, 26))) + addMail(model, "Sports", "Linda Smith ", + QDateTime(QDate(2007, 1, 5), QTime(11, 33))) + addMail(model, "AW: Sports", "Rolf Newschweinstein ", + QDateTime(QDate(2007, 1, 5), QTime(12, 0))) + addMail(model, "RE: Sports", "Petra Schmidt ", + QDateTime(QDate(2007, 1, 5), QTime(12, 1))) + + return model + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = Window() + window.setSourceModel(createMailModel(window)) + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/fetchmore.py b/examples/widgets/itemviews/fetchmore.py new file mode 100644 index 0000000..2b0d8c1 --- /dev/null +++ b/examples/widgets/itemviews/fetchmore.py @@ -0,0 +1,147 @@ + +############################################################################# +## +## Copyright (C) 2009 Darryl Wallace, 2009 +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class FileListModel(QtCore.QAbstractListModel): + numberPopulated = QtCore.Signal(int) + + def __init__(self, parent=None): + super(FileListModel, self).__init__(parent) + + self.fileCount = 0 + self.fileList = [] + + def rowCount(self, parent=QtCore.QModelIndex()): + return self.fileCount + + def data(self, index, role=QtCore.Qt.DisplayRole): + if not index.isValid(): + return None + + if index.row() >= len(self.fileList) or index.row() < 0: + return None + + if role == QtCore.Qt.DisplayRole: + return self.fileList[index.row()] + + if role == QtCore.Qt.BackgroundRole: + batch = (index.row() // 100) % 2 +# FIXME: QGuiApplication::palette() required + if batch == 0: + return qApp.palette().base() + + return qApp.palette().alternateBase() + + return None + + def canFetchMore(self, index): + return self.fileCount < len(self.fileList) + + def fetchMore(self, index): + remainder = len(self.fileList) - self.fileCount + itemsToFetch = min(100, remainder) + + self.beginInsertRows(QtCore.QModelIndex(), self.fileCount, + self.fileCount + itemsToFetch) + + self.fileCount += itemsToFetch + + self.endInsertRows() + + self.numberPopulated.emit(itemsToFetch) + + def setDirPath(self, path): + dir = QtCore.QDir(path) + + self.beginResetModel() + self.fileList = list(dir.entryList()) + self.fileCount = 0 + self.endResetModel() + + +class Window(QtWidgets.QWidget): + def __init__(self, parent=None): + super(Window, self).__init__(parent) + + model = FileListModel(self) + model.setDirPath(QtCore.QLibraryInfo.location(QtCore.QLibraryInfo.PrefixPath)) + + label = QtWidgets.QLabel("Directory") + lineEdit = QtWidgets.QLineEdit() + label.setBuddy(lineEdit) + + view = QtWidgets.QListView() + view.setModel(model) + + self.logViewer = QtWidgets.QTextBrowser() + self.logViewer.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)) + + lineEdit.textChanged.connect(model.setDirPath) + lineEdit.textChanged.connect(self.logViewer.clear) + model.numberPopulated.connect(self.updateLog) + + layout = QtWidgets.QGridLayout() + layout.addWidget(label, 0, 0) + layout.addWidget(lineEdit, 0, 1) + layout.addWidget(view, 1, 0, 1, 2) + layout.addWidget(self.logViewer, 2, 0, 1, 2) + + self.setLayout(layout) + self.setWindowTitle("Fetch More Example") + + def updateLog(self, number): + self.logViewer.append("%d items added." % number) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + + window = Window() + window.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/itemviews.pyproject b/examples/widgets/itemviews/itemviews.pyproject new file mode 100644 index 0000000..a582259 --- /dev/null +++ b/examples/widgets/itemviews/itemviews.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["basicsortfiltermodel.py", "fetchmore.py"] +} diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.py b/examples/widgets/itemviews/stardelegate/stardelegate.py new file mode 100644 index 0000000..86fd99c --- /dev/null +++ b/examples/widgets/itemviews/stardelegate/stardelegate.py @@ -0,0 +1,173 @@ + +############################################################################# +## +## Copyright (C) 2010 Hans-Peter Jansen +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import QStyledItemDelegate, QStyle + +from starrating import StarRating +from stareditor import StarEditor + +class StarDelegate(QStyledItemDelegate): + """ A subclass of QStyledItemDelegate that allows us to render our + pretty star ratings. + """ + + def __init__(self, parent=None): + super(StarDelegate, self).__init__(parent) + + def paint(self, painter, option, index): + """ Paint the items in the table. + + If the item referred to by is a StarRating, we handle the + painting ourselves. For the other items, we let the base class + handle the painting as usual. + + In a polished application, we'd use a better check than the + column number to find out if we needed to paint the stars, but + it works for the purposes of this example. + """ + if index.column() == 3: + starRating = StarRating(index.data()) + + # If the row is currently selected, we need to make sure we + # paint the background accordingly. + if option.state & QStyle.State_Selected: + # The original C++ example used option.palette.foreground() to + # get the brush for painting, but there are a couple of + # problems with that: + # - foreground() is obsolete now, use windowText() instead + # - more importantly, windowText() just returns a brush + # containing a flat color, where sometimes the style + # would have a nice subtle gradient or something. + # Here we just use the brush of the painter object that's + # passed in to us, which keeps the row highlighting nice + # and consistent. + painter.fillRect(option.rect, painter.brush()) + + # Now that we've painted the background, call starRating.paint() + # to paint the stars. + starRating.paint(painter, option.rect, option.palette) + else: + QStyledItemDelegate.paint(self, painter, option, index) + + def sizeHint(self, option, index): + """ Returns the size needed to display the item in a QSize object. """ + if index.column() == 3: + starRating = StarRating(index.data()) + return starRating.sizeHint() + else: + return QStyledItemDelegate.sizeHint(self, option, index) + + # The next 4 methods handle the custom editing that we need to do. + # If this were just a display delegate, paint() and sizeHint() would + # be all we needed. + + def createEditor(self, parent, option, index): + """ Creates and returns the custom StarEditor object we'll use to edit + the StarRating. + """ + if index.column() == 3: + editor = StarEditor(parent) + editor.editingFinished.connect(self.commitAndCloseEditor) + return editor + else: + return QStyledItemDelegate.createEditor(self, parent, option, index) + + def setEditorData(self, editor, index): + """ Sets the data to be displayed and edited by our custom editor. """ + if index.column() == 3: + editor.starRating = StarRating(index.data()) + else: + QStyledItemDelegate.setEditorData(self, editor, index) + + def setModelData(self, editor, model, index): + """ Get the data from our custom editor and stuffs it into the model. + """ + if index.column() == 3: + model.setData(index, editor.starRating.starCount) + else: + QStyledItemDelegate.setModelData(self, editor, model, index) + + def commitAndCloseEditor(self): + """ Erm... commits the data and closes the editor. :) """ + editor = self.sender() + + # The commitData signal must be emitted when we've finished editing + # and need to write our changed back to the model. + self.commitData.emit(editor) + self.closeEditor.emit(editor, QStyledItemDelegate.NoHint) + + +if __name__ == "__main__": + """ Run the application. """ + from PySide2.QtWidgets import (QApplication, QTableWidget, QTableWidgetItem, + QAbstractItemView) + import sys + + app = QApplication(sys.argv) + + # Create and populate the tableWidget + tableWidget = QTableWidget(4, 4) + tableWidget.setItemDelegate(StarDelegate()) + tableWidget.setEditTriggers(QAbstractItemView.DoubleClicked | + QAbstractItemView.SelectedClicked) + tableWidget.setSelectionBehavior(QAbstractItemView.SelectRows) + tableWidget.setHorizontalHeaderLabels(["Title", "Genre", "Artist", "Rating"]) + + data = [ ["Mass in B-Minor", "Baroque", "J.S. Bach", 5], + ["Three More Foxes", "Jazz", "Maynard Ferguson", 4], + ["Sex Bomb", "Pop", "Tom Jones", 3], + ["Barbie Girl", "Pop", "Aqua", 5] ] + + for r in range(len(data)): + tableWidget.setItem(r, 0, QTableWidgetItem(data[r][0])) + tableWidget.setItem(r, 1, QTableWidgetItem(data[r][1])) + tableWidget.setItem(r, 2, QTableWidgetItem(data[r][2])) + item = QTableWidgetItem() + item.setData(0, StarRating(data[r][3]).starCount) + tableWidget.setItem(r, 3, item) + + tableWidget.resizeColumnsToContents() + tableWidget.resize(500, 300) + tableWidget.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/itemviews/stardelegate/stardelegate.pyproject b/examples/widgets/itemviews/stardelegate/stardelegate.pyproject new file mode 100644 index 0000000..13fdf9d --- /dev/null +++ b/examples/widgets/itemviews/stardelegate/stardelegate.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["stardelegate.py", "stareditor.py", "starrating.py"] +} diff --git a/examples/widgets/itemviews/stardelegate/stareditor.py b/examples/widgets/itemviews/stardelegate/stareditor.py new file mode 100644 index 0000000..820aba8 --- /dev/null +++ b/examples/widgets/itemviews/stardelegate/stareditor.py @@ -0,0 +1,100 @@ + +############################################################################# +## +## Copyright (C) 2010 Hans-Peter Jansen +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import (QWidget) +from PySide2.QtGui import (QPainter) +from PySide2.QtCore import Signal + +from starrating import StarRating + +class StarEditor(QWidget): + """ The custom editor for editing StarRatings. """ + + # A signal to tell the delegate when we've finished editing. + editingFinished = Signal() + + def __init__(self, parent=None): + """ Initialize the editor object, making sure we can watch mouse + events. + """ + super(StarEditor, self).__init__(parent) + + self.setMouseTracking(True) + self.setAutoFillBackground(True) + self.starRating = StarRating() + + def sizeHint(self): + """ Tell the caller how big we are. """ + return self.starRating.sizeHint() + + def paintEvent(self, event): + """ Paint the editor, offloading the work to the StarRating class. """ + painter = QPainter(self) + self.starRating.paint(painter, self.rect(), self.palette(), isEditable=True) + + def mouseMoveEvent(self, event): + """ As the mouse moves inside the editor, track the position and + update the editor to display as many stars as necessary. + """ + star = self.starAtPosition(event.x()) + + if (star != self.starRating.starCount) and (star != -1): + self.starRating.starCount = star + self.update() + + def mouseReleaseEvent(self, event): + """ Once the user has clicked his/her chosen star rating, tell the + delegate we're done editing. + """ + self.editingFinished.emit() + + def starAtPosition(self, x): + """ Calculate which star the user's mouse cursor is currently + hovering over. + """ + star = (x / (self.starRating.sizeHint().width() / + self.starRating.maxStarCount)) + 1 + if (star <= 0) or (star > self.starRating.maxStarCount): + return -1 + + return star diff --git a/examples/widgets/itemviews/stardelegate/starrating.py b/examples/widgets/itemviews/stardelegate/starrating.py new file mode 100644 index 0000000..d40b382 --- /dev/null +++ b/examples/widgets/itemviews/stardelegate/starrating.py @@ -0,0 +1,100 @@ + +############################################################################# +## +## Copyright (C) 2010 Hans-Peter Jansen +## Copyright (C) 2011 Arun Srinivasan +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from math import (cos, sin, pi) + +from PySide2.QtGui import (QPainter, QPolygonF) +from PySide2.QtCore import (QPointF, QSize, Qt) + +PAINTING_SCALE_FACTOR = 20 + + +class StarRating(object): + """ Handle the actual painting of the stars themselves. """ + + def __init__(self, starCount=1, maxStarCount=5): + self.starCount = starCount + self.maxStarCount = maxStarCount + + # Create the star shape we'll be drawing. + self.starPolygon = QPolygonF() + self.starPolygon.append(QPointF(1.0, 0.5)) + for i in range(1, 5): + self.starPolygon.append(QPointF(0.5 + 0.5 * cos(0.8 * i * pi), + 0.5 + 0.5 * sin(0.8 * i * pi))) + + # Create the diamond shape we'll show in the editor + self.diamondPolygon = QPolygonF() + diamondPoints = [QPointF(0.4, 0.5), QPointF(0.5, 0.4), + QPointF(0.6, 0.5), QPointF(0.5, 0.6), + QPointF(0.4, 0.5)] + self.diamondPolygon.append(diamondPoints) + + def sizeHint(self): + """ Tell the caller how big we are. """ + return PAINTING_SCALE_FACTOR * QSize(self.maxStarCount, 1) + + def paint(self, painter, rect, palette, isEditable=False): + """ Paint the stars (and/or diamonds if we're in editing mode). """ + painter.save() + + painter.setRenderHint(QPainter.Antialiasing, True) + painter.setPen(Qt.NoPen) + + if isEditable: + painter.setBrush(palette.highlight()) + else: + painter.setBrush(palette.windowText()) + + yOffset = (rect.height() - PAINTING_SCALE_FACTOR) / 2 + painter.translate(rect.x(), rect.y() + yOffset) + painter.scale(PAINTING_SCALE_FACTOR, PAINTING_SCALE_FACTOR) + + for i in range(self.maxStarCount): + if i < self.starCount: + painter.drawPolygon(self.starPolygon, Qt.WindingFill) + elif isEditable: + painter.drawPolygon(self.diamondPolygon, Qt.WindingFill) + painter.translate(1.0, 0.0) + + painter.restore() diff --git a/examples/widgets/layouts/basiclayouts.py b/examples/widgets/layouts/basiclayouts.py new file mode 100644 index 0000000..565ce72 --- /dev/null +++ b/examples/widgets/layouts/basiclayouts.py @@ -0,0 +1,134 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/layouts/basiclayout example from Qt v5.x""" + +from PySide2 import QtWidgets + + +class Dialog(QtWidgets.QDialog): + NumGridRows = 3 + NumButtons = 4 + + def __init__(self): + super(Dialog, self).__init__() + + self.createMenu() + self.createHorizontalGroupBox() + self.createGridGroupBox() + self.createFormGroupBox() + + bigEditor = QtWidgets.QTextEdit() + bigEditor.setPlainText("This widget takes up all the remaining space " + "in the top-level layout.") + + buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) + + buttonBox.accepted.connect(self.accept) + buttonBox.rejected.connect(self.reject) + + mainLayout = QtWidgets.QVBoxLayout() + mainLayout.setMenuBar(self.menuBar) + mainLayout.addWidget(self.horizontalGroupBox) + mainLayout.addWidget(self.gridGroupBox) + mainLayout.addWidget(self.formGroupBox) + mainLayout.addWidget(bigEditor) + mainLayout.addWidget(buttonBox) + self.setLayout(mainLayout) + + self.setWindowTitle("Basic Layouts") + + def createMenu(self): + self.menuBar = QtWidgets.QMenuBar() + + self.fileMenu = QtWidgets.QMenu("&File", self) + self.exitAction = self.fileMenu.addAction("E&xit") + self.menuBar.addMenu(self.fileMenu) + + self.exitAction.triggered.connect(self.accept) + + def createHorizontalGroupBox(self): + self.horizontalGroupBox = QtWidgets.QGroupBox("Horizontal layout") + layout = QtWidgets.QHBoxLayout() + + for i in range(Dialog.NumButtons): + button = QtWidgets.QPushButton("Button %d" % (i + 1)) + layout.addWidget(button) + + self.horizontalGroupBox.setLayout(layout) + + def createGridGroupBox(self): + self.gridGroupBox = QtWidgets.QGroupBox("Grid layout") + layout = QtWidgets.QGridLayout() + + for i in range(Dialog.NumGridRows): + label = QtWidgets.QLabel("Line %d:" % (i + 1)) + lineEdit = QtWidgets.QLineEdit() + layout.addWidget(label, i + 1, 0) + layout.addWidget(lineEdit, i + 1, 1) + + self.smallEditor = QtWidgets.QTextEdit() + self.smallEditor.setPlainText("This widget takes up about two thirds " + "of the grid layout.") + + layout.addWidget(self.smallEditor, 0, 2, 4, 1) + + layout.setColumnStretch(1, 10) + layout.setColumnStretch(2, 20) + self.gridGroupBox.setLayout(layout) + + def createFormGroupBox(self): + self.formGroupBox = QtWidgets.QGroupBox("Form layout") + layout = QtWidgets.QFormLayout() + layout.addRow(QtWidgets.QLabel("Line 1:"), QtWidgets.QLineEdit()) + layout.addRow(QtWidgets.QLabel("Line 2, long text:"), QtWidgets.QComboBox()) + layout.addRow(QtWidgets.QLabel("Line 3:"), QtWidgets.QSpinBox()) + self.formGroupBox.setLayout(layout) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + dialog = Dialog() + sys.exit(dialog.exec_()) diff --git a/examples/widgets/layouts/dynamiclayouts.py b/examples/widgets/layouts/dynamiclayouts.py new file mode 100644 index 0000000..5ae7113 --- /dev/null +++ b/examples/widgets/layouts/dynamiclayouts.py @@ -0,0 +1,170 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/layouts/dynamiclayouts example from Qt v5.x""" + +from PySide2.QtCore import Qt, QSize +from PySide2.QtWidgets import (QApplication, QDialog, QLayout, QGridLayout, + QMessageBox, QGroupBox, QSpinBox, QSlider, + QProgressBar, QDial, QDialogButtonBox, + QComboBox, QLabel) + +class Dialog(QDialog): + def __init__(self): + super(Dialog, self).__init__() + + self.rotableWidgets = [] + + self.createRotableGroupBox() + self.createOptionsGroupBox() + self.createButtonBox() + + mainLayout = QGridLayout() + mainLayout.addWidget(self.rotableGroupBox, 0, 0) + mainLayout.addWidget(self.optionsGroupBox, 1, 0) + mainLayout.addWidget(self.buttonBox, 2, 0) + mainLayout.setSizeConstraint(QLayout.SetMinimumSize) + + self.mainLayout = mainLayout + self.setLayout(self.mainLayout) + + self.setWindowTitle("Dynamic Layouts") + + def rotateWidgets(self): + count = len(self.rotableWidgets) + if count % 2 == 1: + raise AssertionError("Number of widgets must be even") + + for widget in self.rotableWidgets: + self.rotableLayout.removeWidget(widget) + + self.rotableWidgets.append(self.rotableWidgets.pop(0)) + + for i in range(count//2): + self.rotableLayout.addWidget(self.rotableWidgets[count - i - 1], 0, i) + self.rotableLayout.addWidget(self.rotableWidgets[i], 1, i) + + + def buttonsOrientationChanged(self, index): + self.mainLayout.setSizeConstraint(QLayout.SetNoConstraint) + self.setMinimumSize(0, 0) + + orientation = Qt.Orientation(int(self.buttonsOrientationComboBox.itemData(index))) + + if orientation == self.buttonBox.orientation(): + return + + self.mainLayout.removeWidget(self.buttonBox) + + spacing = self.mainLayout.spacing() + + oldSizeHint = self.buttonBox.sizeHint() + QSize(spacing, spacing) + self.buttonBox.setOrientation(orientation) + newSizeHint = self.buttonBox.sizeHint() + QSize(spacing, spacing) + + if orientation == Qt.Horizontal: + self.mainLayout.addWidget(self.buttonBox, 2, 0) + self.resize(self.size() + QSize(-oldSizeHint.width(), newSizeHint.height())) + else: + self.mainLayout.addWidget(self.buttonBox, 0, 3, 2, 1) + self.resize(self.size() + QSize(newSizeHint.width(), -oldSizeHint.height())) + + self.mainLayout.setSizeConstraint(QLayout.SetDefaultConstraint) + + def show_help(self): + QMessageBox.information(self, "Dynamic Layouts Help", + "This example shows how to change layouts " + "dynamically.") + + def createRotableGroupBox(self): + self.rotableGroupBox = QGroupBox("Rotable Widgets") + + self.rotableWidgets.append(QSpinBox()) + self.rotableWidgets.append(QSlider()) + self.rotableWidgets.append(QDial()) + self.rotableWidgets.append(QProgressBar()) + count = len(self.rotableWidgets) + for i in range(count): + self.rotableWidgets[i].valueChanged[int].\ + connect(self.rotableWidgets[(i+1) % count].setValue) + + self.rotableLayout = QGridLayout() + self.rotableGroupBox.setLayout(self.rotableLayout) + + self.rotateWidgets() + + def createOptionsGroupBox(self): + self.optionsGroupBox = QGroupBox("Options") + + buttonsOrientationLabel = QLabel("Orientation of buttons:") + + buttonsOrientationComboBox = QComboBox() + buttonsOrientationComboBox.addItem("Horizontal", Qt.Horizontal) + buttonsOrientationComboBox.addItem("Vertical", Qt.Vertical) + buttonsOrientationComboBox.currentIndexChanged[int].connect(self.buttonsOrientationChanged) + + self.buttonsOrientationComboBox = buttonsOrientationComboBox + + optionsLayout = QGridLayout() + optionsLayout.addWidget(buttonsOrientationLabel, 0, 0) + optionsLayout.addWidget(self.buttonsOrientationComboBox, 0, 1) + optionsLayout.setColumnStretch(2, 1) + self.optionsGroupBox.setLayout(optionsLayout) + + def createButtonBox(self): + self.buttonBox = QDialogButtonBox() + + closeButton = self.buttonBox.addButton(QDialogButtonBox.Close) + helpButton = self.buttonBox.addButton(QDialogButtonBox.Help) + rotateWidgetsButton = self.buttonBox.addButton("Rotate &Widgets", QDialogButtonBox.ActionRole) + + rotateWidgetsButton.clicked.connect(self.rotateWidgets) + closeButton.clicked.connect(self.close) + helpButton.clicked.connect(self.show_help) + + +if __name__ == '__main__': + import sys + + app = QApplication(sys.argv) + dialog = Dialog() + dialog.exec_() diff --git a/examples/widgets/layouts/flowlayout.py b/examples/widgets/layouts/flowlayout.py new file mode 100644 index 0000000..970d5ac --- /dev/null +++ b/examples/widgets/layouts/flowlayout.py @@ -0,0 +1,160 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/layouts/flowlayout example from Qt v5.x""" + +import sys +from PySide2.QtCore import Qt, QMargins, QPoint, QRect, QSize +from PySide2.QtWidgets import (QApplication, QLayout, QPushButton, + QSizePolicy, QWidget) + + +class Window(QWidget): + def __init__(self): + super(Window, self).__init__() + + flowLayout = FlowLayout(self) + flowLayout.addWidget(QPushButton("Short")) + flowLayout.addWidget(QPushButton("Longer")) + flowLayout.addWidget(QPushButton("Different text")) + flowLayout.addWidget(QPushButton("More text")) + flowLayout.addWidget(QPushButton("Even longer button text")) + + self.setWindowTitle("Flow Layout") + + +class FlowLayout(QLayout): + def __init__(self, parent=None): + super(FlowLayout, self).__init__(parent) + + if parent is not None: + self.setContentsMargins(QMargins(0, 0, 0, 0)) + + self._item_list = [] + + def __del__(self): + item = self.takeAt(0) + while item: + item = self.takeAt(0) + + def addItem(self, item): + self._item_list.append(item) + + def count(self): + return len(self._item_list) + + def itemAt(self, index): + if index >= 0 and index < len(self._item_list): + return self._item_list[index] + + return None + + def takeAt(self, index): + if index >= 0 and index < len(self._item_list): + return self._item_list.pop(index) + + return None + + def expandingDirections(self): + return Qt.Orientations(Qt.Orientation(0)) + + def hasHeightForWidth(self): + return True + + def heightForWidth(self, width): + height = self._do_layout(QRect(0, 0, width, 0), True) + return height + + def setGeometry(self, rect): + super(FlowLayout, self).setGeometry(rect) + self._do_layout(rect, False) + + def sizeHint(self): + return self.minimumSize() + + def minimumSize(self): + size = QSize() + + for item in self._item_list: + size = size.expandedTo(item.minimumSize()) + + size += QSize(2 * self.contentsMargins().top(), + 2 * self.contentsMargins().top()) + return size + + def _do_layout(self, rect, test_only): + x = rect.x() + y = rect.y() + line_height = 0 + spacing = self.spacing() + + for item in self._item_list: + style = item.widget().style() + layout_spacing_x = style.layoutSpacing(QSizePolicy.PushButton, + QSizePolicy.PushButton, + Qt.Horizontal) + layout_spacing_y = style.layoutSpacing(QSizePolicy.PushButton, + QSizePolicy.PushButton, + Qt.Vertical) + space_x = spacing + layout_spacing_x + space_y = spacing + layout_spacing_y + next_x = x + item.sizeHint().width() + space_x + if next_x - space_x > rect.right() and line_height > 0: + x = rect.x() + y = y + line_height + space_y + next_x = x + item.sizeHint().width() + space_x + line_height = 0 + + if not test_only: + item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) + + x = next_x + line_height = max(line_height, item.sizeHint().height()) + + return y + line_height - rect.y() + + +if __name__ == '__main__': + app = QApplication(sys.argv) + mainWin = Window() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/layouts/layouts.pyproject b/examples/widgets/layouts/layouts.pyproject new file mode 100644 index 0000000..85eb227 --- /dev/null +++ b/examples/widgets/layouts/layouts.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["basiclayouts.py", "dynamiclayouts.py", "flowlayout.py"] +} diff --git a/examples/widgets/mainwindows/application/application.py b/examples/widgets/mainwindows/application/application.py new file mode 100644 index 0000000..8c4626f --- /dev/null +++ b/examples/widgets/mainwindows/application/application.py @@ -0,0 +1,275 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtGui, QtWidgets + +import application_rc + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + self.curFile = '' + + self.textEdit = QtWidgets.QTextEdit() + self.setCentralWidget(self.textEdit) + + self.createActions() + self.createMenus() + self.createToolBars() + self.createStatusBar() + + self.readSettings() + + self.textEdit.document().contentsChanged.connect(self.documentWasModified) + + self.setCurrentFile('') + self.setUnifiedTitleAndToolBarOnMac(True) + + def closeEvent(self, event): + if self.maybeSave(): + self.writeSettings() + event.accept() + else: + event.ignore() + + def newFile(self): + if self.maybeSave(): + self.textEdit.clear() + self.setCurrentFile('') + + def open(self): + if self.maybeSave(): + fileName, filtr = QtWidgets.QFileDialog.getOpenFileName(self) + if fileName: + self.loadFile(fileName) + + def save(self): + if self.curFile: + return self.saveFile(self.curFile) + + return self.saveAs() + + def saveAs(self): + fileName, filtr = QtWidgets.QFileDialog.getSaveFileName(self) + if fileName: + return self.saveFile(fileName) + + return False + + def about(self): + QtWidgets.QMessageBox.about(self, "About Application", + "The Application example demonstrates how to write " + "modern GUI applications using Qt, with a menu bar, " + "toolbars, and a status bar.") + + def documentWasModified(self): + self.setWindowModified(self.textEdit.document().isModified()) + + def createActions(self): + self.newAct = QtWidgets.QAction(QtGui.QIcon(':/images/new.png'), "&New", + self, shortcut=QtGui.QKeySequence.New, + statusTip="Create a new file", triggered=self.newFile) + + self.openAct = QtWidgets.QAction(QtGui.QIcon(':/images/open.png'), + "&Open...", self, shortcut=QtGui.QKeySequence.Open, + statusTip="Open an existing file", triggered=self.open) + + self.saveAct = QtWidgets.QAction(QtGui.QIcon(':/images/save.png'), + "&Save", self, shortcut=QtGui.QKeySequence.Save, + statusTip="Save the document to disk", triggered=self.save) + + self.saveAsAct = QtWidgets.QAction("Save &As...", self, + shortcut=QtGui.QKeySequence.SaveAs, + statusTip="Save the document under a new name", + triggered=self.saveAs) + + self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q", + statusTip="Exit the application", triggered=self.close) + + self.cutAct = QtWidgets.QAction(QtGui.QIcon(':/images/cut.png'), "Cu&t", + self, shortcut=QtGui.QKeySequence.Cut, + statusTip="Cut the current selection's contents to the clipboard", + triggered=self.textEdit.cut) + + self.copyAct = QtWidgets.QAction(QtGui.QIcon(':/images/copy.png'), + "&Copy", self, shortcut=QtGui.QKeySequence.Copy, + statusTip="Copy the current selection's contents to the clipboard", + triggered=self.textEdit.copy) + + self.pasteAct = QtWidgets.QAction(QtGui.QIcon(':/images/paste.png'), + "&Paste", self, shortcut=QtGui.QKeySequence.Paste, + statusTip="Paste the clipboard's contents into the current selection", + triggered=self.textEdit.paste) + + self.aboutAct = QtWidgets.QAction("&About", self, + statusTip="Show the application's About box", + triggered=self.about) + + self.aboutQtAct = QtWidgets.QAction("About &Qt", self, + statusTip="Show the Qt library's About box", + triggered=qApp.aboutQt) + + self.cutAct.setEnabled(False) + self.copyAct.setEnabled(False) + self.textEdit.copyAvailable.connect(self.cutAct.setEnabled) + self.textEdit.copyAvailable.connect(self.copyAct.setEnabled) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.newAct) + self.fileMenu.addAction(self.openAct) + self.fileMenu.addAction(self.saveAct) + self.fileMenu.addAction(self.saveAsAct) + self.fileMenu.addSeparator() + self.fileMenu.addAction(self.exitAct) + + self.editMenu = self.menuBar().addMenu("&Edit") + self.editMenu.addAction(self.cutAct) + self.editMenu.addAction(self.copyAct) + self.editMenu.addAction(self.pasteAct) + + self.menuBar().addSeparator() + + self.helpMenu = self.menuBar().addMenu("&Help") + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + def createToolBars(self): + self.fileToolBar = self.addToolBar("File") + self.fileToolBar.addAction(self.newAct) + self.fileToolBar.addAction(self.openAct) + self.fileToolBar.addAction(self.saveAct) + + self.editToolBar = self.addToolBar("Edit") + self.editToolBar.addAction(self.cutAct) + self.editToolBar.addAction(self.copyAct) + self.editToolBar.addAction(self.pasteAct) + + def createStatusBar(self): + self.statusBar().showMessage("Ready") + + def readSettings(self): + settings = QtCore.QSettings("Trolltech", "Application Example") + pos = settings.value("pos", QtCore.QPoint(200, 200)) + size = settings.value("size", QtCore.QSize(400, 400)) + self.resize(size) + self.move(pos) + + def writeSettings(self): + settings = QtCore.QSettings("Trolltech", "Application Example") + settings.setValue("pos", self.pos()) + settings.setValue("size", self.size()) + + def maybeSave(self): + if self.textEdit.document().isModified(): + ret = QtWidgets.QMessageBox.warning(self, "Application", + "The document has been modified.\nDo you want to save " + "your changes?", + QtWidgets.QMessageBox.Save | QtWidgets.QMessageBox.Discard | + QtWidgets.QMessageBox.Cancel) + if ret == QtWidgets.QMessageBox.Save: + return self.save() + elif ret == QtWidgets.QMessageBox.Cancel: + return False + return True + + def loadFile(self, fileName): + file = QtCore.QFile(fileName) + if not file.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(self, "Application", + "Cannot read file %s:\n%s." % (fileName, file.errorString())) + return + + inf = QtCore.QTextStream(file) + QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) + self.textEdit.setPlainText(inf.readAll()) + QtWidgets.QApplication.restoreOverrideCursor() + + self.setCurrentFile(fileName) + self.statusBar().showMessage("File loaded", 2000) + + def saveFile(self, fileName): + error = None + QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) + file = QtCore.QSaveFile(fileName) + if file.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): + outf = QtCore.QTextStream(file) + outf << self.textEdit.toPlainText() + if not file.commit(): + error = "Cannot write file %s:\n%s." % (fileName, file.errorString()) + else: + error = "Cannot open file %s:\n%s." % (fileName, file.errorString()) + QtWidgets.QApplication.restoreOverrideCursor() + + if error: + QtWidgets.QMessageBox.warning(self, "Application", error) + return False + + self.setCurrentFile(fileName) + self.statusBar().showMessage("File saved", 2000) + return True + + def setCurrentFile(self, fileName): + self.curFile = fileName + self.textEdit.document().setModified(False) + self.setWindowModified(False) + + if self.curFile: + shownName = self.strippedName(self.curFile) + else: + shownName = 'untitled.txt' + + self.setWindowTitle("%s[*] - Application" % shownName) + + def strippedName(self, fullFileName): + return QtCore.QFileInfo(fullFileName).fileName() + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/mainwindows/application/application.pyproject b/examples/widgets/mainwindows/application/application.pyproject new file mode 100644 index 0000000..0e04139 --- /dev/null +++ b/examples/widgets/mainwindows/application/application.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["application.qrc", "application.py", "application_rc.py"] +} diff --git a/examples/widgets/mainwindows/application/application.qrc b/examples/widgets/mainwindows/application/application.qrc new file mode 100644 index 0000000..0a776fa --- /dev/null +++ b/examples/widgets/mainwindows/application/application.qrc @@ -0,0 +1,10 @@ + + + images/copy.png + images/cut.png + images/new.png + images/open.png + images/paste.png + images/save.png + + diff --git a/examples/widgets/mainwindows/application/application_rc.py b/examples/widgets/mainwindows/application/application_rc.py new file mode 100644 index 0000000..2a392be --- /dev/null +++ b/examples/widgets/mainwindows/application/application_rc.py @@ -0,0 +1,608 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x04\xa3\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x045IDATX\xc3\xe5\ +\x97\xcd\x8fTE\x14\xc5\x7f\xb7\xea\xd6{\xaf\xdbn\xc7\ +\xf9@\x9d\x89FM4\x99D\x8d\x1aH\x98\xc4\x8c\x1f\ +\x1b\xfe\x02L\x5c\xf1\x07\x18\x16.M\x5ckX\xc3\x8e\ +\xc4\x8d\x1b\x17\xce\x82htA\x5c\x18\x0d\xe2\xc4\xc6\x00\ +=`PQ\x19`\x02\xa2\x0e\x0c\x83\xd3\xfd^\xf7\x94\ +\x8b\xaa\xee\xf9`\xe6\x0d\x84Q\x16VR\xa9\xce{\xb7\ +\xeb\x9e:\xf7\xd4\xa9z\xea\xbd\xe7~6\xe5>\xb7>\ +\x80]\xbbv\xbd\x03\xec\xfd\x8f\xf2N5\x1a\x8d\x03\xeb\ +\x19\xd8\xbb\xef\xbd\xa3;\x1f\x1fv\x00\x9c<:\xcf\xcc\ +\x977X\x9c\xef\xdcS\xa6\xda\xa0\xf2\xdck\x03\xbc\xb8\ +g\x10\x80\x8b\x7f\x16|\xf8\xee\x1e\x80\xdb\x00p\xfc\xec\ +\x1c\xdf?0\x04x.\xfd\xb8\xc0\xfe\xb7\xceo\xcbr\ +\x0f\x1dy\x9a\x0b#\x96\xd3\x9f\x1fd\xfc\xd5}\x9bk\ +@E\xb0\x16@xp,#\xcb\xb2m\x0100\x96\ +a\x8dP\x1b|\x14#%\x22\x14+\xd8\x18\x91\xd5\x95\ +s\xe7\xce\x83*\xb8\x04\xd2\x14\xb2\x0c\xd2,\x8cI\x0a\ +I\x12\xdew:\x90\xe7\x90\xb7\xa1\xd5\x82v+\x8em\ +(r\xb2\xfa8\xd6\x0a\xe3\xaf\xbcIk\xf1\xfa\xe6\x00\ +\xac\x15\xac\x15\x04\xb0F\xd8\xbd{\xe7\x16k\xeb\x86\xae\ +\x80Z\xa8V\x81\xeamQ\x8d\xaf\x04\xb5\x82\xf7\xa0\xa6\ +\x84\x01g\x055\x82\x08\xa8\x0a\x95,\xc3# \x1e\x08\ +\xc0\xf0\x1e/\x02\xde#\x12&\x15|\x88#\xc4!\x1e\ +\xd0\xaf\x16\xaa\x1b\x8b\xf6\xd8'a\ +a\xbd\x1c%% \x00\xf0\x81\x8d4M\xa3:\xc3\xb3\ +\x98\x11\x89l\x07\xdac\x09V\x98_)F\xfca\xcd\ +r\x7fa\x1d-\xd1\x80:\x09TI\x18O4/\xe0\ +\x9d\x85\xc4!\x89\xc3g\x09\x92i\xd8\x11\x89\xe2\x13\x87\ +X\x8b\xefv\x91\xbc\x80\xbc\x03\xed\x02\xdfj#\xed\x02\ +\xf2\x02\x9fwP\x1dE\xd5 x:\xebTx\x9b\x06\ +\x9c3x\x0f\x03\x8f$\xbc\xfe\xf2\xf3wh\xe86h\ +\xa4\xbe\xf1\xeb\xc6\xfc\xdf\xb1\x04R^\x82DM_\x84\ +\x8f\x0d\xa58\xe7\xb6\xc5\x88\x9e\x18K\xb9v\xb3\x03\x08\ +\x9dR\x11\xaa\x90\xb8P\xefZ\xc50}\xb1\xcb@\xc5\ +\xb0\x0e\xf4&\xadW\xf9U.\xe1\xe1\xc6\xd22\xf5\xcc\ +p}\xc9\x84-\xe9J\x19\x10\x9c\x1a\xc0s\xe5f\x97\ ++7\xbb\xacQW?\xd7\xaad~\xc5'\xa2)\xac\ +\x05\x15\xc3\x9c\x0b\xb5w\xa6l\x17\xa8\xc1\xa9 \xc8\x1a\ +5\xaf\x9b5\x1a\x8fY1\x9e\xfe{\xe9\xef\x14\x00\xf1\ +\x82\xef\x9bX0+WV\x02U!\xd1\x90\xfc\xe7S\ +\xdf\xf2\xeb\x99\x13,-\xde\xb8\xa7\xfaWj\x03<\xf5\ +\xecN\x9eya\x02\x0f\xa83[1\x10\x03|\x87\xf7\ +\xf7\xbf\xc1\xc2\xc2\x02\xb7n\xdd\xa2(\x0aD\x04k-\ +\xd6ZT\x15U\xc59\x87\xaab\xad\xc5\x98\xf0\xdf\xe5\ +\xe5e\xf2<\xef\xf7#\xcd\xf9\xb8\xf2-\x18pVP\ +\x17\x18\xdc1:\xb6rO8~\x9c\xe9\xe9i\x8c1\ +x\xef\x99\x98\x98`rr\xf2\x8eY\xd81:\xd6\xdf\ +\x86\xae\xd4\x09Up6\xac\xa2V\xaf\xf7k933\ +\xc3\xd0\xd0\x10\xd6Z\xbc\xf74\x9b\xcd\xbb\x02P\xab\xd7\ +p\xd1\x88\xb4\xd4\x88\x14\x9c\x0b'\x5c\xa0*\x00\xa8V\ +\xabdY\xd6\xa7\xb87\xdeis\x1a\xa9\x17AK\xad\ +8\x1e\xc7\xbd#\xb4\xd7\x8c1\x88D\xdf\x8f:\xb8\xab\ +\x9b\xaf5\xa8\x0d\xf3\xf6\x18.=\x8e\x83)m\xe3\xd5\ +\xdb\x12\xa9\xf7\xe5Vl\xad\xf4\x91\x0e\x8e\x0c\xc3\xf2\xef\ +\xdb\x02\xe0\xa1\x91a\xd4\xc2\xb5+\x97Y\x9c\xbf\xbe\x05\ +\x036\xf8\xc0`\xad\x02\x0b\xdb\xc3\xc0P\xad\xc2\xec\xc5\ +K\x9c\xfd\xee\x1b\xce\x9f\x9c\x9e\x03\xa66\x04`$^\ +J\x05\x12\x0b\xed\x91'\xa9=\x0co\x1f8\xc8f\xc7\ +\x81':\xf1*\xe75\x1e2\x81\x14(\xbap\xf9\xea\ +U\xce4\x8e\xd1\xfc\xfa\x8b\xb9\xd9\x1fN\x1d\x02\x0eo\ +\x08\xe0\xb3\x8f>\xe0\xa7\xd3'W\x99\xe9\xda\xa3\x86U\ +\xe6\xbb\x1e\x04\x1b<_\x1do|w\xee\x8f\xd9_\x0e\ +\x01\x87\x1b\x8d\xc6_\x1b\x01\x98\x9a\xfe\xf4\xe3\x7f\xf5s\ +l}\xf25\x00\xe2\xb7\xda\x81\xff\xdd\xd7\xf1?M\xf0\ +K\xb9\xe8F\x89\xaf\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00\x08\x19\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x07\xabIDATX\xc3\xad\ +W[P\x93g\x1a\xf6\xca\xce\xec\xcc\xf6b/\xbc\xd9\ +\xe9\xce\xecn\xbd\xda\xd9\x9b\xb5\xce\xba;{\xb0\xad\xcc\ +z\xb1\xce\xce:\xb3vTpu\xdb\xe2\x81\xd6\xb6T\ +\x04\xbb\xa5 m\xc1\x82\x06\x08\x07QB\x80\x80\x80\x02\ +!\x81\x10\x92@H\x10s$!gr\x80\x04B \ +\x9c\x09G\xb5Tx\xf6\xfb~\x13\x160X\x8b}g\ +\x9e\xf9/\x92\xfc\xcf\xfb>\xcf\xfb\xbe\xdf\x97]\x00v\ +\xfd\x98 \xf1\x0b\x82\x14\x02\x03\xc1u\x82\x03\xcf\xfd\xfe\ +\x8fH\xbc\x9b \xe1W\xaf\xef\xb5*\x8c\xd6e\xdb\x02\ +`\x19\x1e[\x09'\xf13\xfa\x19\x81\x22\xfc\xdc>v\ +H~\x8a\xa0\xb9\xb6Y\x1c2\xcf\xadB9\xfe\x1dD\ +\xf6Q\xd8\xc7\xe6\xe8\x87\x86={\xf6XSR\xae,\ +\xca::\x10N\xe2\xe5I\xc3\xc41\x04\xb7>I\xf9\ +,`\x9b]YSM\x03M\xb6\x114\xeb\xfb 1\ +y`\x19\x9d\xc5\xbb\xef\xbe?\xc5\xab\xbe\x83\xf1\x89)\ +LO\xcf\xae\x92\xef\xd7\xbct\x02\x11\x9f\x0f\xbe\x1d\xe3\ +\xb2\x04CO\xb43@\x8b{\x06\xcd=.4\xeb\xec\ +\xa8W\xf6 \x87S\x852^5C\xbc\xb0\xf4\x90\x81\ +\xc1`\x5c&\xbfK|\xe1\x04H\x1c$8A\xfd\xdd\ +\xeas'\xf1\xb9'\x04H\x87\x97\xc1\xd7\xbb \x22U\ +7\xdc7\xa2\xb8N\x88,V>\xccV\xdb:q\x04\ +,\x16k,\xfc\xce\xe7'\x10\x916\x93\x95?F}\ +\xa5\xfe\x12\xc4o\xf4Y1\xb6\x02~\xef Z{\x9c\ +\xe0?0\xa1L(CF\x0e\x1b\xb2\x0e\xf9&\xd2\xf9\ +\xc5e\xcc-,!4\xbf\x88\xbd{\xf7Z\xc9;~\ +\xbam\x02$~C\x90F=5\x13iu\xb3\x80\xd2\ +?\x0f\xcb\xc4\xe2\x9aP\xa1Z\xb4l\xf1Y\xa0\xb6\xa0\ +\xa6]\x8d/\xb2sq\xb7\x9e\xff\x0c1%\x9d\x09\xcd\ +cbj\x06\x83C\x81'\xe4\xdd\xbc-\xd3\xb0;\x92\ +\x033&\xd4S\xb5\xd3\xfbXO\x88\xc5\x03!\x88,\ +CP\xbaF\xd0\xed\x09B\xe5\x9bB\x9bs\xfc\xa9\xcf\ +Z\x1b\xee*t\xc8\xbc\xc9E\x09\xa7l\x93\xcf\x9b\x88\ +'\xa7\x11\x18\x1d\xc3\x80o\x08\xa2\xd6\xd6%\xc2Q\xdb\ +(\x12\x87\xc6\x1f\xaf\x82/b\x94M\x89$\x90\x22\xea\ +R-\x9aB\xab\xe8\x18y\x04\xa1\xc5\xcf\x10St\xf6\ +\x0d\xa3\xd3\xe1\x87\xd4<\x80\x16\xbd\x03\x0d]\x06\x14\xd5\ +\x0a\x90\x91\x95\x0d/y\xf1\xc6\xaa\xa9\xd4\xb3s\x0bL\ +\xc5\x94\xd8\xdd\xef\x85\xc9b\x05\xb7\xbc\x12\xa5\xe5\x95K\ +\x13\xf3\xcb\xab#\x0f\x017\xd9\x11\xe6\xd9\x15\x84\x97\x15\ +\x13\x06\xcb<\xd0h\xf2\xa3\xdd\xee_'\x96;\x86 \ +\xb3x\xd7}\xe6\x08\xa4\xf8<3\x1b*\x8d6\xaa\xdc\ +S3!\x8c\x8e\x8d3\x15\xd3&\xe47\x09\xf1\xc1\xc5\ +\x8fQs\xaf\x01\xbee`\xfc\x11\xa0#\x13#\xf2\xce\ +\xa1\xbe]\xb9\xb8Q\x01\x83\x81ttM\xa7\x1e\x0ag\ +\x80\xa9\xb8\xdd\xea\x83\xd8\xe8B\x93\xca\xcc\xf8|\xe5\xcb\ +,\x88\xda$Q\x89\xa7g\xe7\x18\x1b\x86\x86G`w\ +8I\x82:$|\xf8!\xae\xb3\x0b\xe1\x99\x5c\x80o\ +\x09\xd0\x90\xde\xe1\x0f,\x81\xab\x1f\xc4}\xef\x04\xdd\x07\ +\x1da\xeb\xff\x9f\xc0\x1d\xb9\x16\x1d\xf6!H\xcc\xfdO\ +}\xee\xd4\x22\x9dU\x84\xaa\x9a\xbaM>G\xe4\x8e\xf8\ +<<\x12\x84\xd3\xdd\x0f\xbd\xc1\x88\xc2\xe2b\x9c~/\ +\x1e=\x03\x01\xf4/\x02\x83\x84\xbc\xc5\xff-\xee:C\ +(Q\x91\xf7\xf6\x05\xf1N\xdc\xbf}\x843i\xe3 \ +\x18\xf43\xab\xe0\xc9Th58\xd1\xd8\xdd\x0b\x9eX\ +\x89\xac\x5c\xf63>G\xaa\x9e\x9c\x9ee\xe4\xee\xf7\x0e\ +\xa2\xd7lAC\x03\x1f'b\xe3 \xe9\xd6\xc0E\xcf\ +\x01R\x90$\xb8\x86\xb2\x9e\x00n\xb4\xdbP\xd1\x1bD\ +\x85\xce\x8bJ~\x0bm\xbe\x9b['\xd1\xa0\x99\xf8\x16\ +e\x22\x05\xee)\xf4(\x13\xc8\x90x5\x0b\x1a\xad>\ +\xaa\xdcc\x13\x93\xf0\x0d\x0d\xc3f\xef\x83\xb4]\x8e\xc4\ +K\x97\x90\xc3\xca\xc3\xd4c\xc0NzI1N\xfa\x89\ +\x94\x7f[;\x84|\x85\x13%j\x1fJ\xd5\x03\xe8\xf2\ +0\xa3(\x22\xf8\xf93\x09t\x8f.\xa1\xa8\xbe\x15\xa5\ +|\x09\xb2J*\xf0\xcf\xe3qQ\xe5\xf6\x07F\xd1\xe7\ +\xf2@\xab7 \xfdj\x06\x92\xbfH\x83\xcd7\x02'\ +\xa9\xda@\x1aL\xe0{\x88R\x9d\x1fE\xdd\xfd\x0cq\ +A\x97\x1b\xc5\xdd\x1e\x88\x9cA\xfc\xf9\xcd\xb7]\x84\xeb\ +l\xb4C\xd0(\xf7N#\xa7\xfc\x1e\xb2K\xab\xf1Q\ +\xeaWH\xfeo\xea\xfaXQ\xb9G\x82\xe3\xf0\x0c\xf8\ +`4\x99Q\xc9\xab\xc2\xfbg\xcfA\xfe@\x03?\xe9\ +n\xb2\x8d\x19\xb9oi\x06\x19\xd2\x9b*/r\xe5\x0e\ +\xe4u\xf6\xa1\xf0\xbe\x1b\x1c\x95\x1b\xf9\x9c\xca)\xc2S\ +\xb8\xdd)\xdc+v\x04\x90Q\xc8\xc5\x95ky8\x11\ +\x9f\x80\x9b\xb7n3c\x15\x91\xdbjs@\x22m\xc7\ +\x85\x84\x0fPt\xbb\x0c\xf3+\x80\x9f4X\xf7$ \ +\x1c|\x84J\xd3\x188\xfaa\x86\x9cV\xfdU\xb3\x1e\ +\xac\x0e;\xb8:\x1f\xd9!\x1ez/\xe0\x13\xbc\xba]\ +\x02&\xbe\xc1\x83\x94o\xd88\x9f\x9c\x8a\x03\x7f=\x04\ +c\xaf\x99\xe9n*\xb7F\xd7\x83\xa4\xcb\xc9H\xff:\ +\x8b\x8c\xd5\xc7\xd1\xd83\xf881\x09\x86^\x13\x1a\x9b\ +\x04\xf8\xdd\x1b\xfbQO\xd4\xf1\x90\x99\xee\x9a\x00\xaa\xad\ +\x93`+]\x0c9\xf5\xbc\xf0\xbeg\xbd\xea\xcc\x16=\ +JU\x1e\x08m\x01\x94\xd4\xf1C\xe1eS@\xf0\xca\ +\xf7%`+nj\xc7\xa9\x84D\xc4\x1c9\x8a\xdc|\ +6ZZ\xc58\x14\x13\x83/95\xc8\x14j\x98\xe6\ +\xa2\xd5\xd2'\xf5\x9azL\x13\xa1Id\xb7\x99\x90\xdb\ +nF\xb9\xda\x8d\x06\xa5v9,9=\xf9N\x13\xec\ +\xd9r\xd4G\x0d;\xabF\x88c\xff9\x8f\xdf\xee\xfb\ +=\x1a\xf9\x02\x9c\xbf\x90\x80\x93\xf1\x17p\xa3\xad\x07\x19\ +\xc4OJ\x14\xe9n\xbaX\xa8\xef,\xfa\x94\x98P(\ +\xb7@\xe9\x0e<\xf9W\xec)*w-\xc1g\x04\xfb\ +\xb6\xb9\xe4D\x8d\xbe\xcc\xb2Z\xfc\xe3\xe4\x19\x1c<\xf4\ +7\xb0r\xf3\xb0\xef\xc0\x1fP \xd1!\x89'e*\ +\xa6K\x85>\xbf!\xd5F\xe4.\x90[!\xb0\x0c\xae\ +\xe5\xdc\xe2\xd2\x11\x13\x13\xe4\x87o<\xaf<\xe7\x96\x15\ +5\x9ciE\xe5\xf8\xfb\xb1X\x1c?\x19\x877\xf6\xef\ +\xc7\x8d:\x11\x92\xab\xa4\x0c!\xedp\xea5U!\x8b\ +4[\xc9\x037*4n\xd4I:\x17\xc3rs\x08\ +\x8em\x95\xfb\x87$\xe0Jesp\xe4\xf8)\x1c>\ +|\x98\x8cc.2\x05*\x5c\x22\xd5\xd3]~M\xdc\ +\x0b6\xe9tv\xa7\x1dw\x8c\xe4\x88\xb6\xf9\x9e\x84\xb7\ +\x1a\x95\xfb\x22\xbdI\xfd\x80\x0bm\xf4\x042JxL\ +\x0f\x9cKI\xc3\xb5\xa6.|\xc2me6Y\xf1\x83\ +\x01\x5c\x97\x9a\xc1Q{ \xf3\x04\xd7\xce%&\x056\ +\xc8\xfd\xc7\x9d\xc8\x1d\xd5\x82\xdc\x1a\x01\xce^NE\x81\ +X\x85x\xf6]\x5c\xa9U\x90\xaa\xfb\xc0\x96\xdbP\xad\ +u\xe3\xaeTA/\x10\xca\x0dr\xbf\xba\xd3j\xa3\x05\ +\xb7\xa2Q\xf8\x1d\xafC\x8dO\xb9-\x88\xcb\xe6\xe1\x9a\ +H\x8f\xaa\x1e/\x9a5\xe6\xc7\x7fz\xf3-Wx\xac\ +\xa8\xdc\xaf\xbd\xac\xdc\xd1\xe2\x08\xdd\x05\x5cu\x1f\xde\xcb\ +\xafE\xb9v\x002g`\xf5\xc2\xa7\x97\xa9\xdc\xf7\x08\ +\xd2\xa9\xdc;\xf8\x03\xf3\xc2\xf1\x13\x82\xca\x1c\xee\x9dP\ +\x0b9\x94\xb8\x0d\xc2\xc8\x16\xa3\x17\x87\xc3/\x22\xf7\x0e\ +\xff\xdam\x8a\xdda\x99\xd5\x1b\xb6\xd8k\xbb^2\xbe\ +/\x89\xff\x01f\xb9_\xfc\x11\x80=\xcf\x00\x00\x00\x00\ +IEND\xaeB`\x82\ +\x00\x00\x05+\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x04\xbdIDATX\xc3\xed\ +WkL\x93W\x18>#q\xc92\xe9\x16\x97\xa8T\ +e8\x9d\x02\x15\xf6\x03\x872\x93\x01f,[p\xc4\ +0\xff`\xa2.\x1a:\x1dN\x03\xba1\x89[\xb3\x80\ +\xd9\x0c\x84\x02\x19X\x1c\x14\x8b\x85\xb2\x82\x95^\xe4f\ +\x0b\x8e1\xf8\xc3F\xcb-\x81\x15\xdc\xa8\xc2\x1c\x1b\xb7\ +ji\x91\xf2\xee\xbc\x87\xaf\x0c\xdc\xb8\x0da\xd9\xb2\x93\ +<\xed\x97\xf3}\xfd\xde\xe7\xbc\xef\xf3^J\x00\x80\xfc\ +\x93 \xff\x0a\x02t\x09(D\x14\xd9\x14q\x14\x01+\ +F\x80\xae\xddd\xdd\xc6f\x22L\xf8\x95\xc4\x8bG\xc8\ +\xa1\xd3\xf7\xc8\x8e\x97;82a+A \x85\x9c\xbe\ +0H.\xdd\x80\x19@2\xabyM\xf4\xbe\xfbr\x13\ +hd\x06\x91\x04^\xa3Q\xf4\x06\xee\x85G\xf5\xd0\xbd\ +\x83\xcbM \x9b\x9d\xf6@t/\xbd\x162= \x89\ +?H\xa5,\x1b\x01\x8c1y\xc1\xbb\x9d\x88K\xc6\xd7\ +\xc6&\x0e\xa0\x10\xb9\xfdB\xfe\xc5+6F\x8c\x12\x5c\ +N\x02\x93\xa7\xa7\xa7\x0d\xcc\xd39\xb9\x98c6\x14\x0a\ +\xd2\xe4\xa3+A \x8c)\x9e*\xdf7G\xeb\xdc{\ +\xb5\xcc\x89\x9e@D\x96T\x83+,\x0b6FH\x08\ +\x13\xf5d*{.T\x03\x01\xf8\x037\xbf\xc0\x0e4\ +*T\xdfb\x88R\xd5,X\x03t\x1d\x16\x08\x04z\ +EU\xf5\xc8\xa0mt\xc2\xd4s\xf7!\xbesQ\x95\ +\x90\xae\x8f\xd0\x13\xcf\xe5\x94\x83\x87\xb4\x02\x9e\xcc.\x03\ +\xd4\x06\xdd\xaf\x99\xcb\xb0\xaf\xaf\xaf>\xbf\xd2`\xb5\xdb\ +\xed\x80\xf8y\xe4>\xc4^\xab\xb4\xb9\x88/\x86\x80'\ +\xd3\xc0g\xf9\x8e\x19\xf5`\xd7^3\xbav\xdas\xee\ +h\xd8\xc7\xc7G\x9f\xab\xab\xb0\x0e\x0f\x0d\xc1\x10\x87\xb2\ +\xf6.\xe7\x967\xf7wsa\xd8\xbd\xe8^\x80/f\ +\x9a\xa0\x86\xdf\xa96B\xf7\xf0\x03\xd8\x19\x9f\xd4\xcf\xa5\ +\xe7\x1a\x8a\x98-~\xfem\x97T\x1ak__\x1f\xb8\ +\xd0\xd1s\x07br\x15VN\xc4\x87\x97\xd4\x8c0\x14\ +\xe9\x15\xb7\x1e8\x1c\x0e@\xa4\xd6\x191\x9e\x85\x9b\x05\ +~m\xa9%\x1a[\x97\xd9\x0c\xe6.\x0a\xf3$\x14\xdf\ +6\x8e{\xbd\x1e\xd1\xcdB\xc8\x09o\xa9\x04<\xd1\xbd\ +V\xab\x15\x10w\x7f\x1b\x84\xf3\x92\x5c\xbbR\xa9\x84\xfa\ +\xfaz0\x99L\x0cu\xdf5\xc1Q\xb1d\x18\xc9Q\ +D>\xb6v\xcc\xb4@O\x93_~\xd3\xd6\xdf\xdf\x0f\ +2\x99\x0cD\x22\x11\xa8T*\x90J\xa5\xa0\xd1h \ +K[9\xbe\xe9\x95\xe0\x1f\xb8S\xafy,\xf3\x00\x97\ +\x8e\x22\x9e\xc7\x86\xe6S)\x19\xf6\x82\x82\x02\xe6\xe2\xa0\ +\xa0 \xe0\xf1x`\xb1X@[^\x01\xfb\xcf&\x0c\ +-\xa6S\xceg\x94\xcf\x09L\x83\xe2[{\xe6\xc2`\ +\x9a\xb2\x14\x14\x0a\x05\x88\xc5b\xc8\xcc\xcc\x84\xa2\xa2\x22\ +P\xab\xd5\xd0\xd9\xd9\xc9`\xec\xfe\xc9\xb9\xc9\xdb\xa7u\ +.\xb7\xcfK\x80\xae\xb7\xd8)p\x0e\xc0j\x97\xacx\ +\x88\xca\x7f\x82\xe2)\x89\x0e>\x97+![\x96\x0f\x07\ +c\xe3G\x84\x1f&\xd8\x92rd\x8eo\x1a\xbf\x07\xa3\ +\xd1\x08-\xad-\xf0\xcb\xc0 \x1c8\xf1\xbe\x05\xb3b\ +\xc1\x04\x5ci\x84\x85\x85\x84F\xdc&\xe72\xac,\xcf\ +3\xb5\x13\xec;\xe3\xba\xd33\xaf\x82\xe5\xfez\x89\x06\ +\x9e\xde\xfcb\x1b\xf7<\x92\x8d{f\xabO[\xca5\ +\xedXCC=444\x80\xa5\xb7\x172\x14\xc5\xc3\ +\xf3\xe9\xc0e<\x92\xe5(\x9e6]\xe5\x9c*2x\ +}\xf4\x83.Zl\x121\x0c\x1b%\xeaq\xf7/\xcb\ +'\xef\x05\x87_\xfe\xd3\xe4D\x0bLh\xf4\xc9>u\ +\x95\x1e\x0c\x06\x03\xb4\xb7\xb7\xc3\xd7\xc6\x961\xae\x81\x09\ +f\xf16m8h\xed\xf7\x08\x1e*>\ +]\xe5X\xaa\xf1GZ\xf5\xb6Y\x0b\x11\x1d\xb3C\xc9\ +\x918\x099\xf9\xa9\x96!\xfa\x5c\x1a\x0d\xcf\xb3\xff\xff\ +7\xfcO\x13\xf8\x1d\xe7\x87\x19\xb9D\xc3\x01\xcf\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x05:\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x04\xccIDATX\xc3\xb5\ +\x97]L[e\x1c\xc6wo\xbc\xd9\xe5\x12I q\ +\xd7&\xe3N\x13\xb8p\xd1\x85D\xbdP\xe3\x10\x18\xe5\ ++.&J\x04'\x86\xaa\x8b\x99\xe0\xd0\xa2l\x19\x86\ +9\x17\xdc\x1a\x16\x98\x80@l\xa6C\xca +\x83\x1e\ +(\xcc\xda\xd1\x96\xd2\xd2J{\xfa\x01\xa5\xd0\xef\x16\x1e\ +\xdf\xff\xdb\x1d\xc7\xcc\x04*\x87\x93<9o!\x9c\xe7\ +\xf7<\xefG\x0f\x87\x00\x1c\xcaF\xcf\xbd\xfa\xe9\xbbL\ +Z&a\x0fj`\xca\xd9\xe9y\xd9\x9a?]P\xf2\ +\xa5\xc1\xe9\x8f\xa7W\xc3@0\x02\x84\xa2\x19\xad\xc72\ +\x8a'\x81X\x22s\xbfyk\xdaK\x10r\x02\x1c{\ +\xe7\xac\xda\x1c\xd8\xc8\x98\x12@\x84\x99\x85\xe3\x19\x911\ +)\x1aKa%\x94D8\x9aBs\x87\xc6\xbe\x13\xc4\ +\xff\x02\x90\x12\x93y$\xf1\xc8X\x92\xcf\x1f\x84]\x8c\ +\xc2\xe5\x09\x22\x12K\xa3\xf4\xc3\xefM4uY\x01\xb0\ +\xeb\xd86\xd5\x90\x9e:\xfc\xcc\xb9\xe7_.\x11?V\ +\x9eEEU\x0d*\x99\xde\xaf\xad\xc3\x9d\xb1\x89\xc7\x00\ +\xac\xb6%\xfc\xb9\xe8\x87k\x15X\xf6\x04\x10\x08\xc6\xd2\ +\xaf\x9c\xbep\x9fA\x1c\xd9\x15\x80]\x87\x99\x1a\x8a\x8a\ +\x8a\xcc\x92Z[[\xdd\xa4\xafU\xad\xfe\xafT\xdf\xa6\ +\x06\x06\x06195\x85\xd9\xb99\xe8&&PPP\ +\x80!\xcdo|\xdeI\xa6\xf9\x05\xcc\x98\x5c\x1c\xc0\xe1\ +OA\xf4\x85\xf0C\xaf\xce\xcd\x00j\xf6\x02PCf\ +\xd8\xe5\x8a\xc7\xe3\xf0z\xbdH\xa7\xd3\x98\x9c\x9cDe\ +e5fg\x8d\xbc\x81\x07f\x1bt\xd3\x16\x0e@2\ +-x\xf0\xdd\x8dQ\x8f\xac\x00\xe1p\x18F\xa3\x91\x8f\ +S\xa9\x14~\xea\xedE\xe3'\x9fa\x86A8\x96\xdc\ +Pwu\xe3LC#\xce5\x9d\xc7\xed\x91q\x5c\xbc\ +>,/\xc0\xc6\xc6\x06\xf4z\xfdc@}}\xfdP\ +2\x88\xd0F\x1cf\x9b\x0b\x82\xc1\x88\xa9\x19\x13\xac\x0e\ +\x11\x97\xbadn\x80\x00\xa6\xd8:\xd8~E\x22\x11\x94\ ++*0\xae\x13@\xe7\x04mW\xda\xaa4\xbe|S\ +\xe65@f:\x9d\x0e\xc3\xc3\xc3\xe8e\xf5\xf7\xf7\xf7\ +C\xab\xd5\xa2\xaa\xba\x06cw\xf5\x90\x0e*w\x90\xed\ +\x04\xb6\x0e\xda\xbbe\x06\xa0y\xb7\xdb\xed\x18\x1a\x1aB\ +gg'zzz8PIi\x19ni\xf5\x10\xd7\ +\x00o\x08\xb0\xf9\x00g\x00\xb8\xd0%3\xc0\xd6\xd6\x16\ +\xdf\x09\x81@\x00\xa2(\xc2\xef\xf7cmm\x0d\xa7\x14\ +\x95\xd0\xfc\xae\xe7\xa9\xc9|\xc1\x0b\x98=@\x9b\xdc\x00\ +\xdbA677\xf9v\xa4V\x14\x15\xd5\xe8\xfbU\xe0\ +\xa9\x1d\x81G\x00\xe7;\x0f\x00\x80\xcc%\x80$3O\ +$\x12(+\xaf\xe2\x00\x7f\xb8\x00\x8b\x98\x01\xa06Z\ +\xd5\x070\x05\xff\x98'\x93<=MI\xc9\xa9J\x0e\ +\xa0\xb7\xb3\x03\x89=\xc5\xf8\x170\xb1\x00|q\xf5\x00\ +\x00\xa4\xea\xc9\x98\x14\x8b\xc5P\xa6\xa8\x82zH\xc0\x98\ +\x19\xb8k\x05\xe6\x9c\x99\xfb\xe7Wd\x04\x90\xd2Sj\ +\x02\x88F\xa3\xdc<\x14\x0a\xa1\xb8\xb4\x02\xd7\x06\x05\xdc\ +f\x87\xe4\xa0\x01\x1cd\xc4\x04(;d\x06H=\x9c\ +s\x12\x99\xd3\xb9@ \xc5eU\xb8\xd8-\xa0\x7f:\ +c\xae}\x90i\xe0\xa3v\x99\x00\xfe]=\xa5&\xad\ +\xae\xaer\x88\xb7J*p\xb9W\xc0=\x1b\xb8~\x9e\ +\x01\xee\xcc\x03g.\xed\x13@\xaa\x9dD\x8b\x8e\x92\xd3\ +qL\xdf\x01+++X__\xe7\x10'Y\x03\xdf\ +t\x09PO\x00\xbf\xcce\x1a\xb82\x064\xec\xa7\x01\ +\xc9X\xda\xebdNi)9\x1dD\x04@\xf5\xd3\xcf\ +\xde|[\x81\x96\xeb\x02O~u\x1c\xb8q\x0f\xf8q\ +,\x9e~\xbdNm\xa67\xaa\xac\x00\x9ed,m7\ +2%\x00\xd1#\xf2\xe4\x12\xcc\x1b'\x15h\xef\x11\xa0\ +\xbcf[\x7fO5\xe2\xc9xG\x00\x95\ +J\xc5\x01\xa4\x15.\xcd7\x19RR:\xf7)\xb5\xc3\ +\xe1\xe0\x22\xe3\xc5\xc5E\x0e\xf5\xe2\xf1\x97\x5c\xf4\x1e\xb9\ +\x93\xe9\xae\x00---n\xe9`\xa1\xd4\xd2\x97\x0d\x8d\ +\x97\x97\x97\xe1\xf3\xf9`\xb3\xd9\xf8}ii\x89C\x10\ +\x00\x8d\x0b\x0b\x0b\xcd\xb2\x00\xd0\xa2\x92R\x93\x11\x8d\xe9\ +N\xdfxT;5`\xb5Zy\xf5\xd4\x0a\xfd\xce`\ +0$\xf2\xf2\xf2\xee\xb3g\x1c\xd9\x17@SS\x93[\ +\x9agJO\x22\x13\xaa\x9a\xc6\x16\x8b\x997@\x9fG\ +GG#mmm\xde\xfc\xfc|\x13\xfb\xdbA\xa6\xb2\ +\xbd\x9a\xff'@ss3\x9f\x02JG\x10T?U\ +???\xcf\xeb\xd6h4\x91\xba\xba:\xe7\xc3\xb4]\ +L\x1f0\x1d\xcd\xc6xG\x00\xa5R\xe9v:\x9d\xbc\ +bJJo>\x94\xb4\xbe\xbe\xde\x99\x93\x93#\x99\x16\ +gSuV\x00\x8d\x8d\x8dn\x8b\xc5\x82\x81\x81\x81H\ +mm\xad377WV\xd3\xdd\x00\xf8\x7fFL\xc2\ +A\x99n\xd7\xdfC9V\x18\x85p\xc8\x04\x00\x00\x00\ +\x00IEND\xaeB`\x82\ +\x00\x00\x03T\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x02\xe6IDATX\xc3\xd5\ +\x97\xcdN\x13a\x14\x86\xeb5\x94\x95{q\xe1\xd2\xc4\ +\xe0\x05\xb8\xe2\x0e\x5c\xb8\xf4\x02\x5c\xb10\xea\x05\x18\x96\ +&bX\xb8\xb0\x91X \xd1\x9d\xbf\x89\xa4\x14\xb1R\ +\xa4HE\x94\xfe\xd0\x02C\xff\xa6\x9d\x19\xa6e\x80\xe3\ +y{\xfa\x85QJ\x82\xc9!\x86I\xde\x9c3\xa7\xf3\ +\xcd\xfb\x9c\xf3M\x9bN\x84\x88\x22\xffS\x91s\x01\xc0\ +\xc7\xd5\x90n\xff\xa5\xfb\xac\xc7==d\x0d\xa9\x02\xf0\ +12<<\xbcj4::\xba\x19V<\x1e\xaf&\ +\x93\xc9V:\x9dv\x13\x89Dk`` \xcdkn\ +h\x02\xa48\xd2\xe1\xe1q\x99\xba\xef\xb7\xc9\xb2,\xda\ +\xdf\xdf'\x86\xf1x\xcd\x18\xeb\x8a\x1a@?\xf3\xb0\x1c\ +\xc7\xa5Lf\xb9\x0b\x14\x04\x01\xc5b\xb1:\xaf{p\ +\x1a\x88S\x01\x1c\x1c\x10ww\xb2l\xdb\xa1\xf9\xf9\xcf\ +d\x0e\xd7u\xe9\xf9\xc4D\x17B\x05\x00&{\xc1\xc9\ +\xaa7\x1cJ\xce\xcdS\xf8p]\x0f\x8b\x17T\x00\x82\ +\x10@gO\x14\xce\xed\xa6G\x1fgf\xe9\xf5\x9b\xb7\ +\x14\x9f\x9c\xa4\xa9\xa9iz\xf7\xfe\x03E\xa3\xd1e^\ +\x7fA\x05\xc0\xef\x10\xed\xb6%\x86\x85\x9a\xe3\x05\x94]\ +\xcd\xd1\xe4\xf4+z2\xfe\x94\x9e\xc5^\xd0Lb\x0e\ +\x8b\x17U\x00\xda\x81\x18\xf5\x13 <\xff\x90j\xcd6\ +\x157\xab\x94/nS\x89c\x8d\xb7\x85\xd7~Q\x01\ +\xf0y\xcc\xcd]\x1e\xb5\xc7{\xdb\xee\x9f;\xbe\xe4\x88\ +]\xb8\xbd\xee\xe2\x94\xca3\xe0u\xe4\xc6uWb\xd8\ +\x109\xea\xe63D\xd4\x01\xa7\x06\xe0\xf4:\xad9\x22\ +\x98\x98hr\x80\x98kPS\x9d\x00\x00*-\xb91\ +\xe2NS\x8c\x10\x0d\x04\xf2m\xfb(\xb6|E\x00\x9b\ +;\xdbj\xfci\x8e\xfb\ +\xc5S(\xf0C\xb8fI\xf7k\xf9R\x87\xd7\xbeT\ +\x01\xc8U\x8f\xbaN\xadK\x0e\x90\xaf\x85\xde\xb7\xc2\x92\ +=O\xa6\xb3\xde\xa3\xb1q\xeb\xda\xd0\xf5\x15\x98\xb3n\ +\xa9\x00l4\xa4k\x18\xff\xe0\x11\x7fZ\x17S\xd4\x13\ +\x0bYo\xe4\xee\xbd\xe2\xa5\xc1\xcbK|m\x8cu\x87\ +5\xa8\xfa\xb7\x1c\xdde\xd9<\x8f\x1f\x19\xfe\x9e\xcf\x1e\ +7\xbd\xc9\xbax&oF\x00h\xf2\xff\x81\x99\x94\x9e\ +\xe9?\xbf\x19\x01B\xd3\xf4\xfc\xbd\x9c\x9e\xa5~\x03Q\ +l%\xa1\x92\x95\x0aw\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00\x06m\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x064IDATx^\xad\x97[lT\xc7\ +\x1d\xc6\x7fs\xce\xd9\x8b\xbd\xf6\xfa\x16\xa0\xbe\x00\x0e\xb2\ +ic$BJ!\x22\xa1-\x95b\xa5/\xeeKh\ ++\x95\xa6U\xa5\xc6`U\xaa\xda\xb4\xaa\xfaV\x09U\ +\xca\x03\x94'\xda\x07\x84\x14)\xad\xc4\x8b\xa5R\x83y\ +\x08\xc5\x189\x0ei\xd3\x84\x9a\x9bcj\xec\xb2\x04\x1b\ +;\xbb\xf6z\x8f\xbd\xbb\xde\xb3g\xa6\xc3h\x85\xe5r\ +l\x88\xc9'}\xfa\x9f\x9d\x87\xfd~\xf3\x9f\x99s\x11\ +J)\x82$\x84x\x05x\x9e\xc7kH)\xf5w\xd6\ +(' \xb8C\xbb\x01h\x97R\xbe\xc6cdY\xd6\ +\x07\x1a\xf6\xbb@\xb7\x069\xff\x14\x00&\xfc\xb7\xed\xf5\ +\xe2`]DDn\xce\x89\x8a+W\xaeP]S\x8d\ +@\x00\xa0P\x08e(A)f\xd3i^\xa9\x17/\ +\xbc\xb4Nl;\xf1\x1f\xb9G\x83|[CL;\x8f\x85D\x952\xe2\xb6\xc4\ +\xb6\x04!!p>Sl\x8c;\x80D*\x04\xf0\x9c\ +\x10\x02\xe0\xcb@\x05P\x0f4`\xc4Hi\x9f$\x02\ +\x01N\x9c8!\x00\x81\x05\xd2\x87\x96\x96g\x09em\ +\x14\xe5(\xa5\xb4A\x08XW\x19%\xe2\xd8DB\x16\ +\xc3\x13s\x5c\xbc=A\xf7X\x8e\x5c$\xbe\xa9\xbd}\ +\xf7\xef-\xcbZ\xdc\xb1cGYUU\x95\xd3\xd8\xd8\ +\x18~\xe0\x86\x86\x86\xd0\xa5K\x97\xdc\xae\xae\xae\x08\xf0\ +\xd6\xaa\x1d\x00\x13DU,\xc2s\xd51\xf2\x9eO\xa1\ +(\x91Ja\x09A\xd8\xb1\x88\x86l\xe6r\x05\x12\xa2\ +\x8e?\x9f\xff+\x0dM\x1b\x01\x22\xc0f\x96\x84\xef\xfb\ +x\x9eGuu\xb5\x9ePK\xf4\xea\xd5\xab\x87\x84\x10\ +(\xa5\xdeZ\x11\xc0\xb2A\x00\xb6-\x90\xda\xb6\x148\ +\x08\xa4\x12X\xc2\x8c\x1b\x8fL\xb9\xec{\xf5;\xd47\ +6\x11|/\xc1\x84g2\x19\xca\xcb\xcb\xcdf>v\ +\xec\xd8&\xbd\x7f\x0e.A,\x01\xd0\xd9\xd9\xa9\x0e\x1d\ +:\xa4l!\x08Y\x10\xb6-\x1c\xc7\xc6BP\xb4\xcd\ +\x1a\x1b\x00\xc7\xb2\x888\x96\xae\x02`Yx\x10\xc0\xdc\ +\xdc\x1c555\x06 \x1a\x8dr\xe4\xc8\x91\xcd\xc0\x03\ +\x88\x1b\x1a\xa2\xc7b\xb9\xb0mt0f\x8d\xcb#6\ +\xb1\xa8\xa3\xc7,2\x8b\x1e\x93\x99\x1cc\xa9y\xee\xcc\ +.\xe8\xdfEr\xf9<\xab\xc8,A6\x9b5\xa7f\ +\xe9\xffm\x0e\x1c8\xb0\x1e\xe8\x00X\x06\xa0\xb4t\x16\ +\x8e\x0d\xe1\x90\xc0S\x8a\xb1\xa4\xcb\x8d\x8c\x83\xd3\xb2\x97\ +\xa6}\xaf\xb3\xb5\xe3\x17\xac\xdb\xfb:\x0d/\xb4s\xfb\ +\xce$\xfd\xfd\xfd$\x93I\x94R\xe6\xfa\xf8\xf1\xe3\xe8\ +\xba\xac3\xe7\xce\x9d\xe3\xe8\xd1\xa3\x1c>|\x98\xde\xde\ +^\x12\x89\x84\x04,\xa1\x15\xdc\x01\xed\xff\xce\xe6\xf8\xe7\ +\x94Ok\xc7\xcf\xf8\xe6/\xdf&\xf6\xf57\x99|\xa6\ +\x83k\xfe.\xae\xf1-dk\x17\xad{\x7fN^V\ +s\xfaog\xd1wM\xee\xdc\x9d\xe2\x1b\xafvr\xfd\ +\xfau\x03\xa0gk\xd6?\x16\x8b\x99\xebx<\x8e\xe3\ +8%8\x04\xc0#\x00\x96%\x98\xcaA:\xde\xca\xfe\ +\xdf\xbdM\xd5\xae\xd7(\x84b\x08\xdbBY\x82lA\ +r\x7ff\x91O\xeef\x18\xb8\xear\xfa\x1fad\xd5\ +^\xae\x8f\xdcg2\xd7\xc6\x85\x0f\xee\x9b\x00\xed\x87\xa1\ +\xcd\xcd\xcd\xb4\xb5\xb5\x19755\xa1\xa1\x14 \x83\x1f\ +F\x16\xdcq\x15\xdf\xff\xe9o\xa8l\xd8H\xe2\xec;\ +L\x8f^\xc3\x89\x94\xb1\xb5y\x07\x9b[\xb6\xf3Iy\ +%c\x09\x97\xcff\xf2\xdc\x9d\xce2\xa1\xed\x88\x0dL\ +'\xe7\xd8\xb7+\xca\xfa%\x003{=k\xea\xea\xea\ +\x00\xccu*\x952\x00J+\x10\xa0\xb9Zp\xe1\x9d\ +c(,\xca\xe6\xc6\xd9\x10\x8fR\x94\x92{\xc3}$\ +e\x05\xdb\xda\x7fLM\xdb\xcb|<\x9cf\xd2_\xc0\ +\xcdx,\xcck/x \x00\xb5t:B\xa1\x90\x09\ +-\xdd\xea\x1f\x8e\x01*\xf8>`\xc1\xc6\xb8\xa0P\x1c\ +#\x1c\x8bS\xb7\xa5\x96\x92xv}\x05\xe9\xac\xc7h\ +\xff\x9f\x98\xae\xbcL\xcb\xf6\x83\xb8\x0ba\xbc\x82\xa4X\ +\x94x\xda!\xc7B-\xaa\x80\xe3i\xa0\x96\xd5\x15\x01\ +\x00\xd6\xc7C\x84\xca#\xfc\xbfjc!\x9e\xa9\x0cs\ +\xe1\xdf\x83\xec\xd9\xf9\x13\xca\xa3\x0e\xb92G\x03(\x03\ +ak\x00\x16K!\xa5\x1c%0*\x15\xa4\x5c\x05@\ +X\xa5*\xcc\xf5#\xfapl\x86\xf1Y\x8f\xef\xfd\xfa\ +\x8f\xdc\xca\xd4\xe0D\x5c\xa2\x11\x1b\xcf\x93\x14=\x07\xd3\ +\x01\xa5\x90R\xf2PjY\x01V\x05\x10\x08L\x0d\x04\ +\x18\x9dv\xf9\xd5_\x86\x18\xbd\xb7\x80=\x93g\xd3\xba\ +2\xf2y_\xbbh\xea\xce\xaf\xd4p\xf9\xdd\xe0%\x00\ +\x9ex\x09L\xb8\x10<\xa2\xd6/U\xf2\x87\x1f>\xcf\ +\xf5O3D\x1b\xb7\xb1\xf3\xc5\x97Y\x12\x5cN`\x8e\ +\xdbS\x01(\xc0\x12%\x00m\xd4R}\xb1\xb5\x96\xdd\ +[\xe2t\xbf\x97\xa5j\xf7W\xf9\xd1\x1bo\x10\xa0\xb5\ +\x03\x98\xb57\xd5\xd8\x08\x01\xd2\xcbSpSx\xf33\ +\x14\xb3i\x0a\x19\x1f%\xfd\xd5\x82\xd6\x08\xf0\xf0)\xe7\ +\xe3\xe73\x14\xe6u\xa8\x0e\xd6\x00\xcb\xf7\x89\x10\xc13\ +}\xfa\xd7r\x8c\xb2\x137\x03\xc7\x01\xb2\x1e\xfe\xad\x94\ +\xcco\xf7DT\x03\xd8_p\x07\x08\x92\x09\xfd\xd7=\ +?\xfd~B\xa6\xcf\xdf\xf6\xef\x02\xeev;\xfc\x92\x06\ +\xa8\xe3s\xcau]\x1fpW\xed\x00@2\xab\x0a\x1f\ +~*\xd3\xbd\xb7\xfc\xd4\xcdi9\x05\xf4\x03\x97th\ +\xbf\x10\xa2\xd3\xb6\xed\xaf}\x9e%XXX\xf0\x07\x06\ +\x06\xd2'O\x9e\x9c\x06\xba\x83\x00>\x1aI\xca\xad\xe3\ +\xb3*\xd7;\xe2\xa7nL\xcb\xd1R\xe8Y\x1dt\x8b\ +\x00=\x09\xc0\xd0\xd0\x90\xdb\xd3\xd3\x93\xd2N\xcf\xce\xce\ +\x9e.\xbd\x1d\xdf\x08\x02\xe8\xee\xea)\x00\x8c\x04\x84\x06\ +\x85\xaf\x08055U\xd0/\x22\xa9S\xa7N%\xc7\ +\xc7\xc7/\x03g\x81~\x1d\xec\xae\xb8\x09K\xdfv\xda\ +O&\x85\x01@\x08@aZ\xfc\xde\xe0`\xba\xbb\xbb\ +;\xa5\xdf\x8a\xcc$\xd0^\xeds\xcda\xed\x9aw3\ +n\x11`p\xf0\xfdt___\xfa\xcc\x993\xa6\xc5\ +\xa5\xd0\x8fx\x02\x89\xb5\x9ec!D\x18x\x13\xd8O\ +is\x06\xb4\xf8\xb1\xfa\x1f\xbd\xfa*_\xf2\xd8\x15\x9d\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x08\ +\x08\xc8Xg\ +\x00s\ +\x00a\x00v\x00e\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x06\xc1Y\x87\ +\x00o\ +\x00p\x00e\x00n\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x0a\xc7W\x87\ +\x00c\ +\x00u\x00t\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x06|Z\x07\ +\x00c\ +\x00o\x00p\x00y\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x04\xcaW\xa7\ +\x00n\ +\x00e\x00w\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\xa8\xbaG\ +\x00p\ +\x00a\x00s\x00t\x00e\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00h\x00\x00\x00\x00\x00\x01\x00\x00\x171\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00R\x00\x00\x00\x00\x00\x01\x00\x00\x11\xf3\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa7\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00|\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x89\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00>\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xc4\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/mainwindows/application/images/copy.png b/examples/widgets/mainwindows/application/images/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..2aeb28288f58ddffdd1d75115f170c5bf2773814 GIT binary patch literal 1338 zcmV-A1;zS_P)3P|jKV4ArrNQZsr&q&3Fam_48Lh`MiYI|sB6GiaYuZZ? zasnKC=d9Ws*vOa?K!llv;~9}LDH=;*C6q)snnH7j#=aB8{{oN_lX)cZ$XJrkAB0_u z!sQ7f5=*1>!|zQrby)$h>)1Bcke)jH%(>@ZE)hRgo<&7f4Jw)5udTzKv5Ch3thOcm zx#)*$6jZ zxjE=2CQwjNfFaFqeBMc>`320FTpYmRPeJsB@I$Z8%>Zil0#HL{*yW1HLMx&9BQ>hew>g`42C!b-4K{%G& zPNKpdi`TSeSQ5jt zz}D6l-wA<00HP?u@AqSEZ4IXsmC*dI=c&nj!3&r@K%3kE+d(!rH~Ds?RumQ0==)XR zsU3kw0Ovao0D#OTfFv_dBoZhqui^lIxB!co0iZTo)dw&I|ClF}JUvZG$*D>XptrLF zi9N;m7cj8^d~x*v0Ho^4m=ue}P^PGYdPu;S8Mtc&=A4=P=T~F|kkV6X0*FSV+&mNt zp}4dH*9HaLW{2dU0UTt+1SmUX21q@ea}t@;xj-PrWmUM?EueooW3GLWY2c%FnE?J> zJ*6hCuC8*3w@NB-xmUnF8@PU+0q)ELXD;m%K&qWYi;j}haZKLWGrnrG9>`fBl6@D%o`^aXzvlAyk=W}Pc`B^ahku5Y4`j}CIOJCBx$u% zLNX5qgK)WA+>l;M=(ES;f!poI@e{8lpM9a6Ogos0nT|fmct-%0O2q-B6)w#;8B$U@ z_bIi*;ou_U#l=Mq_2TiDT=X8flj*JiEiEl>>0qJM(w7a5mzS5}^Z8)2+4y~FX^BG+ z0F4U^3(c|s(4vx3lM#*SPTzP`J2hanT6y)<3jNMtFeLKw^6s-|9N8B@Q&W>$nrBK+ zA`_~b#ukg2H$b09M@J)VZEfEC{CpGp+d-zXy_)|gKy!05p8`rp5L7=^KR-Xu>(*#A zk-EA%=fkvJOdl{E&Bk~~0Hsptb~>HBVoFMHK9sb+zTTOWlOvfHXH#`n0F8}}Zi~f& wfq{WYZEdYHH#b*S)7=30e@0BgL78sX-$OZ87=>`i1ONa407*qoM6N<$g6NH5LI3~& literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/application/images/cut.png b/examples/widgets/mainwindows/application/images/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..54638e9386dc8af40dcc9a3ee2f57c62e248e406 GIT binary patch literal 1323 zcmV+`1=RY9P)J0(1!|L=@Q+aTEb7Mu4u}WZlMQB24&|#EVDBq0{%sj+Z+)GGQx0 zAcdU1Fi0-lfEhqCt9ecIzWZ_$Xk-SF1YV<2^ak#QNA=LXgUd}Io1OMRbT7RYGCd%P zKS-r48v%?ldBMA#h)c%T#wHG+5V`$A{>3XcMvM|%P6Cssr>70f(>b}AV>T2D(&VEn zK_HANo+{rrN9){swakg0Ktz^QgDWfxHbzJY6ZK>&doEN10r&$qzrYSODpcQMh*H%o zSOat&76=4-MOF34plx)*)N}VCzH?EPkgku=6VK(8gNL*Np3E)-)CS$Jnai-RudhD8 z(qOgQ?SS}sjv4h}*IqNacG`39XxPWcN1v;!unrFm!4QYC z_Acj^H}`jQVc5OsUVtxVnxKZ?sWw9Q@B`QxpVZH#=NgKbEq?xOmsA>SUtb@%(9v@T zVsaH$PQ-_o)Qm6`=@qvgI2;Z@q}CZRo`stQer>5G8e5my4CXEh^CT4CHjaC}9?{K0 z$O&($1U%8bR;v{dcYhm%^O9V6PFgxKporEb{=Djv}7NhUQZ#8TNvL0_NhN zpdjG!cwn(uKwDk``_Co}Ev8e>XOzzgOoQTEd*;Gmnz9rW3I&M8V#v(QgrcG%P^;C@ z+1bfp?EcBQ$=j!OF1OE1fUdXLDR2(JYL~2dh{}J0;wgy^K9?&YTb2(8W8+7JA12t6 za%7Hg8ovjl(FiTAE%3|0ARIXHz6G;l!311sgoTBKM%*UnGOR4mGqn@!JL9_3Gp~Z> z{(6Z9p5FXo8}~etjeBORPg}}0?N~!YJv1~lfTgz=G8Dzb^Xb54Jd))oo;F?OoGLPS zee{DaT5J+A3>zitarZCFC+`J^U;fkNL<>x4^vOPTl^zTR1GKld!`H@^F|L6LX7M&{ zIA}acIyz>{0a00^F4~fx%15b|k+|p_1^WSy+Zxk*z z((l+8X-U2;oygOcJEspZj3vh3pSpKnaW$YpY_$lC`IPbC@H0!Ad}tF|z0RZAYfnh` z3=gmm{_}^(`7iFdNp1l4dp_;=2p%dvUFBG+@kd(qwpj}i9kWBpkvIuC`Kgv6`dk_f h&$IvkH~dc%_#Nkm8M#Em0nY#c002ovPDHLkV1hsWYZL$g literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/application/images/new.png b/examples/widgets/mainwindows/application/images/new.png new file mode 100644 index 0000000000000000000000000000000000000000..12131b01008a3ec29ec69f8b3f65c4b3c15b60d6 GIT binary patch literal 852 zcmV-a1FQUrP)IE2xvpcKl890$E8eWxeF8o0mWjmIG{M&7eWO9CVRojsy7@;&dpQ!a9t0J7gPX(5I|>76wd9YM;~Wq>Ghkp6rY@= zsi|pt_x=M#qtRtve?bMn?-1>_C5DBX;{}vm&C%raD|#~il%B<2&`e?uix*V@+JPAL z6CgbQkZR2~6*sGtFK$zbV~w|k*M3m}@OjM5T^_Z^d)w}xJHF(IUAVpO;*`oW;C1B2 zbys585IO4RGepz@rv~8kI;}Y(n3!mCfS7AgQ=I?+DlNG&;!abH5Df(KZTl#;d_@48 zJKJjfX^uQ>h#Iar6M#C8w^So4*Tn<|1^_iEoENLSCA-QKz)fKe6)JLW%zjz|XlmW9 z@suY3Q`{VJZCgNKnyVajp6h`@6-N=kYKbun)^`LT3}hx^wrO>XsHzE2w#B^A1Ngov zV}~hV3>btQ09#E(0CWRWn5~q>9Op*n90161U8$i6fc^Yd5_2;F2sIc&=-PaaDX2~W zTL1&dm}fQw05ax<-uM>_{4Cgt02pUFPqb7NBbWjJ0t`O;#ZxHoL%3#1_iOo5hu6MT z0mxO4x=yW24v?>f-nYV%Jx`{y-lMT`>)O!u6_~SbsQ_#=q-z-e;1PdX7gN*|3t4aE z?!Drr!OKg0ZH#q?HK_Wx9NlHvJdYn4{+`bsH@(TacqVT~0BG|6fti$^=|8_20YcOC e{Jor>rG5iZY$c(Rl?rzN0000RP)CWtKz1rEEwa&Ubd$6s{da=&VIP1;2`BM0`Wb;D z{M-!)vd0-ix#k=pmKgFxQgYk(eOi$0QlJD2NbOI5d5567avIIj< zv@<}9dj`!tE;Q@xs8{wNhf{?zUNu9!u=J3D!C+h_ze{}K1V|htI6?j0>T@UYxhDij zhnKMl|M#(rT!AcZ}eF)wgP_d zAX10jekLr}U#(CrCA<(opAbNs2#S{v>vbjZBPMG2>Dlh2!oC#Mk@9m9Zc z2%^^3CBjkLC=!RpAFqNhVw6pZB#Q!^oqj*T-F(Vw$mLX*nO_ zNX-3DeeTpEomGUYnz~IsN92z9JUkMF)7=lf!HB}*Vw`?29z6pA^e+N~guKQ7E$%u) zC{dC3_66}y+`oN81yr%;K@{IH8|1O-3y*riL6}qGd@SEo}8X#Q_kq zZ|eG3QMpHgF(8Pc07FLLD$kpMaaUZZl&Qk=tr>Kq76&g@g}Kbh`}mD}bLg zSob6#9DIaI(-=7VVTPPm{Z+FbtPVT4Iv?2~9(pg}6TG@z0w%t}gOqRBIG>z~1AjdP zW3QR%ZYsA%*Mp?X$w>b?i;UGgQ?+sSsoXX8X`%zES@sOGBngFV;lVB@d3_10@@V;lg>dY2BN>v^RZ2^?j@k8NdQ$X;_ z_a$H}ZfeJ=gha#~If~qTHdcoJ4Lhqwh-3dbkKgY5JsSA}oWGEOlkpdDqpb%S#7{~T>2A7M zsP8QLl$cN`w?OF*Jo#7bDJpj@!Dj^fwz=d)jlRsXTKwbW85}(HH?VT^u<$rb~rBzaiB|lB=W)A?(%51dO$!?mU^ ze8O#IHd*n50bG}w!BKl4^90wps7K`#)>4RXJ_(`usyx1v$_9j`-;Pq{6K%jV&lNRO%>FPb&x$A5bBEmwG~ zsNAo;tlZJ!2;Bu-bsyf#uSL0b05WG_^}?r@soeJn(y81#_yhC8@e_i|9PXV^3ptdy z4Z_G4qZfz6FCzC2|JrSe-C>#48@AYMyIwNBFNyyFX1QPd5r93<00000NkvXXu0mjf DP*&js literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/application/images/paste.png b/examples/widgets/mainwindows/application/images/paste.png new file mode 100644 index 0000000000000000000000000000000000000000..c14425cad1ff1b2c5628be5769c9e9e52b78635f GIT binary patch literal 1645 zcmV-z29o)SP)3Gx zefpoBhy8x@pP6$JN-2UQgm?vbp2urQDfM^OC?_DeL%RWJmr}mQV`N#@2O9RfK(_`t z{}ccw{I~7(;$U4wL~hQBiYr&HP+e1vKmedn2xTZiDQ44YUa1!^ytGbiJMka6M}vG@ zLrgqP2loG9i`^_G_)0Q7JWOR}B`e8wT^_)0sjwm&qAGGfr|N;V0|+ezNTCh%UA#yx zm%}d>QA&}|=UH4_q);eO)MK@^wUhx^fcS#;fB^tDLmDAYR7=GY}hKA6kOPAcP zuC561)~X!<6GT-k!gJLz@}5tjD3MBG2|?Jgh=y$Das?8ijz6FOD-BH>0V2R=mW1#7 zc%Dafb+w*QOZ4j1tA~UTD5c(75x}xR0JbfV+O`xp2&58N!i*b_Ou6iP^*huzHW7R; z!Gvcr8OqDc&1OD!?ARu~e-17|ECJBj*{Kd4I;3nN2w4!eEgZ+jLQu5L8XEw|vWPgA zt^#0Lco4wc+#EGEH3lFWjdJA3kD9q>HlpG95}EZ=m1y-ptN)rjt$|Ez*CB`q|1$rgVVB? zrhTuowc{78+xt2VFSK*}&LsW){Unn~lv3vU`0?ZDx~wzj&Yk1v(W4wbe3;(eUJ{9f z1T3Ky+yU+X&gS^%luv8N&-msq-zN6;H<^5HH8r836d;2i zMi$(072p5qZ>Vh8NaE}}Opji}iIlOmc?X+Yw)07OC1VMf&t~%6oz60$?T8IbC+FC= zE6VyM05f|%YwGIi0L*nNl`;TID-fW$T5#c=V<;@j=Em6&k5ZJ9d&7MsWd+;Xe@so= z%X~bXX3}54&3G)#YcF^p0JU^FLZOfeE#2xLjsYt8K48JdxS&uRBOHrUx22Yncy@gS z>8!_S|DTwyyiCjXgSZP}yn>`ylz7@9$3iWtfa7VPmemyj0M^GtgvulQziMM4o~aCT z;opPo+4&R7qYk+;M*}DWVQT;uOChBkB`_)#q+A6+Sfwh=^&|RlY=-e!kMI5ZkKD@C z;6z-a5gX5w6g>yi0i}>q@=$770agVN2uuwG7@cUt@bD?; zK3j0A)Rg|7%OH8oYxFCwW^r%olu$Hy-NXMuhl?5?;8OW$_d zPbP%{KnOr#TKwMNV7j}zJEh->%p}lW?Q_jx?V5KpZV_N`@cndOUtjvnnKP!vrO=Of r0*SSrV$g&__6vQz4|I&^4Jxf00000NkvXXu0mjfT=)$w literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/application/images/save.png b/examples/widgets/mainwindows/application/images/save.png new file mode 100644 index 0000000000000000000000000000000000000000..daba865fafd22fa18e7c0488eb699b79d3554170 GIT binary patch literal 1187 zcmV;U1YG-xP)5-PJz!8#8DIjU4h)0S{a*K!i>mJVVCD^kQ5IHGsm^=1>z+FI)Tw&v zz2|;5 zYXiKvXAppke-?cB?jC^K0C4>59N#}M1b8m}xWN9m&Tq?d4;^`$3nP}(pC4rW)qR_5 zKt-??KzML0Bg?XF0WdI@VU185d=w)kA`~mw7?IVLbLY;3D!2sF6tWD`ER0DCNfO?7 zI*{j(x1rU7b}No;C~~s;IMxc|ue?cX@%rWftQD*k1h7Wfy?f^tYwL!tfLf?lf$D8h zjjsf?g7=`NgaKy-HG&AJ3Y9FwBOo3K!0;X~0^TDMCKY^$Bg7#dJRx2{O;{K}*Gh>7 ztf1Os0Gczu1&UJ#X#$l5vNZMt5(iG9=s;dTE04VeOF6W2$O}}5aXkPkPoHKY21CJ!U{_^v8Xy`U*q`vX%#{A#01X5mtL``3Wj}4_b=eEU&o)}BH zcC!Nrol+61khoCqTE#GZvCBZkunzPltylR~F5%(E(lYhTaDB;yE$K=b5S$vobLD22 zD>u8WQCC0Ls$_n}C!#5=1r@`b3$=HqY!|4(sUXN2HLsgB8jo2qp8k93?-T&>g72GH zFe_J90#zZ=ko@OU-}3936D%#>xTpG8Y6Cp=>`tC}VFC}RGg~nb1AK?~_rJly!UDH$ z-J&Q8L>2*RmC}ns$#9hnDF1_1m8Hc<-5*m|${p@{U>9F*?@YhOX2JRd6<}qE@f>YdJGB!_d$W)>^#xG@H%40#K{h zaM6gg)QA+E3nyHlDgdZft7KW$r?@xXX>%H>7ePy{I3CBnBed6yF^ELpk2<)ko3Ayf z4fFOGEDock Widgets example demonstrates how to use " + "Qt's dock widgets. You can enter your own text, click a " + "customer to add a customer name and address, and click " + "standard paragraphs to add them.") + + def createActions(self): + self.newLetterAct = QAction(QIcon.fromTheme('document-new', QIcon(':/images/new.png')), "&New Letter", + self, shortcut=QKeySequence.New, + statusTip="Create a new form letter", triggered=self.newLetter) + + self.saveAct = QAction(QIcon.fromTheme('document-save', QIcon(':/images/save.png')), "&Save...", self, + shortcut=QKeySequence.Save, + statusTip="Save the current form letter", triggered=self.save) + + self.printAct = QAction(QIcon.fromTheme('document-print', QIcon(':/images/print.png')), "&Print...", self, + shortcut=QKeySequence.Print, + statusTip="Print the current form letter", + triggered=self.print_) + + self.undoAct = QAction(QIcon.fromTheme('edit-undo', QIcon(':/images/undo.png')), "&Undo", self, + shortcut=QKeySequence.Undo, + statusTip="Undo the last editing action", triggered=self.undo) + + self.quitAct = QAction("&Quit", self, shortcut="Ctrl+Q", + statusTip="Quit the application", triggered=self.close) + + self.aboutAct = QAction("&About", self, + statusTip="Show the application's About box", + triggered=self.about) + + self.aboutQtAct = QAction("About &Qt", self, + statusTip="Show the Qt library's About box", + triggered=QApplication.instance().aboutQt) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.newLetterAct) + self.fileMenu.addAction(self.saveAct) + self.fileMenu.addAction(self.printAct) + self.fileMenu.addSeparator() + self.fileMenu.addAction(self.quitAct) + + self.editMenu = self.menuBar().addMenu("&Edit") + self.editMenu.addAction(self.undoAct) + + self.viewMenu = self.menuBar().addMenu("&View") + + self.menuBar().addSeparator() + + self.helpMenu = self.menuBar().addMenu("&Help") + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + def createToolBars(self): + self.fileToolBar = self.addToolBar("File") + self.fileToolBar.addAction(self.newLetterAct) + self.fileToolBar.addAction(self.saveAct) + self.fileToolBar.addAction(self.printAct) + + self.editToolBar = self.addToolBar("Edit") + self.editToolBar.addAction(self.undoAct) + + def createStatusBar(self): + self.statusBar().showMessage("Ready") + + def createDockWindows(self): + dock = QDockWidget("Customers", self) + dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) + self.customerList = QListWidget(dock) + self.customerList.addItems(( + "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton", + "Jane Doe, Memorabilia, 23 Watersedge, Beaton", + "Tammy Shea, Tiblanka, 38 Sea Views, Carlton", + "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal", + "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston", + "Sally Hobart, Tiroli Tea, 67 Long River, Fedula")) + dock.setWidget(self.customerList) + self.addDockWidget(Qt.RightDockWidgetArea, dock) + self.viewMenu.addAction(dock.toggleViewAction()) + + dock = QDockWidget("Paragraphs", self) + self.paragraphsList = QListWidget(dock) + self.paragraphsList.addItems(( + "Thank you for your payment which we have received today.", + "Your order has been dispatched and should be with you within " + "28 days.", + "We have dispatched those items that were in stock. The rest of " + "your order will be dispatched once all the remaining items " + "have arrived at our warehouse. No additional shipping " + "charges will be made.", + "You made a small overpayment (less than $5) which we will keep " + "on account for you, or return at your request.", + "You made a small underpayment (less than $1), but we have sent " + "your order anyway. We'll add this underpayment to your next " + "bill.", + "Unfortunately you did not send enough money. Please remit an " + "additional $. Your order will be dispatched as soon as the " + "complete amount has been received.", + "You made an overpayment (more than $5). Do you wish to buy more " + "items, or should we return the excess to you?")) + dock.setWidget(self.paragraphsList) + self.addDockWidget(Qt.RightDockWidgetArea, dock) + self.viewMenu.addAction(dock.toggleViewAction()) + + self.customerList.currentTextChanged.connect(self.insertCustomer) + self.paragraphsList.currentTextChanged.connect(self.addParagraph) + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/mainwindows/dockwidgets/dockwidgets.pyproject b/examples/widgets/mainwindows/dockwidgets/dockwidgets.pyproject new file mode 100644 index 0000000..2df1146 --- /dev/null +++ b/examples/widgets/mainwindows/dockwidgets/dockwidgets.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["dockwidgets.qrc", "dockwidgets.py", "dockwidgets_rc.py"] +} diff --git a/examples/widgets/mainwindows/dockwidgets/dockwidgets.qrc b/examples/widgets/mainwindows/dockwidgets/dockwidgets.qrc new file mode 100644 index 0000000..968feac --- /dev/null +++ b/examples/widgets/mainwindows/dockwidgets/dockwidgets.qrc @@ -0,0 +1,8 @@ + + + images/new.png + images/print.png + images/save.png + images/undo.png + + diff --git a/examples/widgets/mainwindows/dockwidgets/dockwidgets_rc.py b/examples/widgets/mainwindows/dockwidgets/dockwidgets_rc.py new file mode 100644 index 0000000..35b13db --- /dev/null +++ b/examples/widgets/mainwindows/dockwidgets/dockwidgets_rc.py @@ -0,0 +1,464 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x06\xc4\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd9\x04\xdc\xb2\xda\x02\ +\x00\x00\x06{IDATX\xc3\xadWiLTW\ +\x14v!b\x95\x04\x97\xa8%\x18R\x1b\x0d\x11E\x04\ +\xaa\xa4I\xb5VMli\xb0h\xa3\xb6\xc5\xb2F\xfd\ +\xa3,aQH$\x08d\xc2\x12\xd0\x22B\x11YD\ +@@\xf6\x91}S6\x09\xb2\xa9\x08\x0e$\x0cb\x01\ +\x83\x02\x82\x0b\x08\xa9_\xcf\xb9\x991\xa3\x80\x9d\xb4\xf3\ +\x92/\xf3\xde\xbc{\xce\xf7\xdds\xce=\xf7\xbey\xf3\ +T.;\xbb\xe8/\x1c\x1d#\x1d\x1d\x1d#\x02\x1d\x1c\ +.H\xd2\xd3\xab%\x97.\x15VGF\xde\xacML\ +\xac\xa8\xad\xaaj\xbf/\x956A\x89+WJ\xdb\x8d\ +\x8d\xf7|I\xa6\xf3\xe7i\xe8Zho\xffG\xa1\xfc\ +\xf1sL\xff\x0d\xb5\x10\x10\x98\xd3\x88\x82\xed\ +\xdb\x0f\xac=\xeb\x97\x89\xde\x17P\x0b\xf9\xe52\x18\x18\ +\x18\xc7\x91\xe9\xe7\x1a\x8b\x82\xadmXyc\xf78d\ +\xcf\xf1\xaf\xe0q\x16\x16\x07[\xc8\xee+\x82\x96F\x14\ +\xd8\xd8\x04\xfb\xa4\x15\xc9\xd0:\x08\xb5`\xe7\x18\xf4\x9c\ +\xcc~!,\xd1\x88\x00KK\xaf\x8d\xa1\x97\xaa\xd0\xf0\ +\x17\xd4B\x08\x8d%3\x7f\xc2\x0a\x8d-I\x17\xf7\xa4\ +\xfeJ9\xa0\x0e\x22\x92\x9a\xa0\xa7g(\xd5\xe4j\x98\ +G\xcd\xa8(\xbf\xfd-\x8a\xba1'\x0a\xba\x80\xdcN\ + \xb6t\x00\x86\x86;\xea\xc9\xccTcu`g\x17\ +\x1e\xc4\x8e\xb3:\x80\x8c6 \xad\x09Hi\x00\x92\xea\ +\x80\x84j \xa6\x1c\xc8l\x04J\x1e\x00\xf5\xed\xe3h\ +j\xea\x80\xaf\xaf\xef+25\xf8\xdf\xe4\x12\x89D.\ +\x95\x96 \xabp\x00\xa9R\x08\x94\x101qP\xf3\x01\ +z\x9e\x8cahh\x08\xbd\xbd\xbdx\xf8\xf0!\x1e<\ +x ~\x13\x13\x13\xb1{\xf7\xee\xdaC\x87\x0e\x05X\ +ZZn\xe4T\xfe'\x01\xa1\xa1\xa1}\x13\x13\x13\x98\ +\x9c\x9c\xc4\xd4\xd4\x14\xba\xba\xbap\xe7\xce\x1d\xdc\xbe}\ +\x1b\xf9\xf9\xf9())AUU\x15\xea\xeb\xeb\xd1\xdc\ +\xdc,\x040\x92\x92\x92p\xe3\xc6\x0d\xe4\xe5\xe5\x89\xfb\ +\x13'N\xdc\xdd\xb1c\x87\x99\xdaB\xec\xec\xec\x96\xd9\ +\xda\xda~\x17\x12\x12\xd2\xce3T\xa2\xb0\xb0P8V\ +%\xcf\xca\xcaBBB\x02\xc2\xc3\xc3\x11\x17\x17\x87\xab\ +W\xaf\x0a\x81}}}\xe8\xe9\xe9\x116uuu8\ +}\xfa\xf4\x84\xb9\xb9\xf9o\xe4^\xfb\x93\xe4G\x8f\x1e\ +\xb5\xa7\xc1/\xa2\xa2\xa2\x10\x1d\x1d\x8d\x8c\x8c\x0c\xc4\xc6\ +\xc6\x2277\x17999\x88\x8c\x8c\x04\x09\x03\xbf\xbf\ +v\xed\x1a***D\xd8GFF0<<\x8cg\ +\xcf\x9e\x09\xb1O\x9f>\xc5\xe0\xe0 \x06\x06\x06PP\ +P\x80\x86\x86\x06xxxLn\xda\xb4\xc9i\xcev\ +mcc\xb3+,,L\x84\xba\xa3\xa3\x03\xf7\xee\xdd\ +\x13\xbfr\xb9\x5c\x08\xb8|\xf9\xb2\xf8\xef\xd5\xabW\x18\ +\x1f\x1f\xc7\xd8\xd8\x18FGG?I\xde\xdd\xdd\x8d\xca\ +\xcaJ\x11\xb9\xb6\xb66\x1c8p`\x88\xa8\xbe\x99u\ +\x95\x1c9r$O&\x93\x89\xd0\xa9\x8a`C&\xe2\ +\xfc\x96\x95\x95}\x92\x9c\xc5666\x8a\xd0s\x0d0\ +ykk\xab(T\xf6\x1b\x14\x14\x04\x13\x13\x93\xbcY\ +{\x05Um\x0d\xabV\xe6OU\x04;aB\xbe\xe7\ +\x9c*\xc9y\xb6\xf7\xef\xdf\x17\xa9\xe0\xda`\x81--\ +-\x82\xf0\xc9\x93'x\xfc\xf81\x1e=z$\x8a\xb4\ +\xa6\xa6\x06\xc1\xc1\xc1\xa0Z\xe8 \xba\xefg\xa4\x82\xc2\ +S\xdb\xd9\xd9\x89\xb9D\xb4\xb7\xb7\x8b\x99s\xf1q\x11\ +J\xa5R\x14\x17\x17\x8bwL\xa6\x0c;\x93\xb2`&\ +\xe4H0n\xde\xbc)\x0a\xd4\xdd\xdd\x1d[\xb7n\x95\ +\x11\xdd\xef\x04\x9d\x0f\x04\xec\xdf\xbf\xbf\x96\x0aP8\x9d\ +K\x04?\xf3\xcc\xf9\x9dj\xce\x95K\x94\x0b\x8eW\x06\ +\xd7Lvv\xb6(d???899\xe1\xd8\xb1\ +c\xf0\xf6\xf6\xe6\x14\xb0\x00\xfb\x19\x02\xa8i\x14\x14\x15\ +\x15!&&\x06\xce\xce\xceHII\x11\x8eUEp\ +\x1d01\xcf\x92C\xcdb\xd3\xd2\xd2p\xfd\xfau\xb1\ +b\x92\x93\x93q\xfe\xfcy\xaex\xb8\xba\xba\x82z\x09\ +233\xe1\x1b\xef\x0c\xef\xaa\xc3B\x84\xb1\xb1\xf1\xec\ +\x02\xf6\xed\xdb\x17t\xf7\xee]Qd\xfd\xfd\xfdHO\ +O\x87\x97\x97\x97XzL\xa6\x14\xc1\xa1\x8f\x8f\x8f\x17\ +M\x86\x09yu\x04\x04\x04\x88\xf021\x17\x1a\x0b\xe2\ +4\x95\x97\x97\x8b\x94\xf9%\xba\xc2+\xe7W\xee\x07\xd8\ +\xbcy\xf3\xec\x02\xf6\xee\xdd+a\xa27o\xde\x08\x11\ +\x1cj\x9e);c!\x11\x11\x11\x22\xaf\x1cb\x9e\xe5\ +\xb9s\xe7D\xa4\x98\x98\x9fy\x1c\x8b\xe3\x9c\xab\x92\xb3\ +\x0d\xe7\x9f{\x01\x17\xa1\x91\x91\xd1\xec\x02\xa8\x7fKx\ +\xc9MOO\x7f \x82\xf3\xcc5\xc1\x85\xe4\xe9\xe9\x89\ +\xe3\xc7\x8f\xc3\xc7\xc7G\x84\x97\xa3\xa0\xcc\xb9*9\xa7\ +\x92\xdf]\xb8p\x01T[\x5c\xf9\xe2\xff3g\xce\xd0\ +\x8ei8\xbb\x80\x9d;wJX\xe9\xbbw\xef\xe6\x14\ +\xc1\xc5\xc7ME\x99\xf3\x8f\xc9\xb9~\x02\x03\x03\x85P\ +\xda\x15\xdf\xb7h\x1e\xcfM\xce\xcd\xcd\x0d\xa6\xa6\xa6}\ +D\xe74C\xc0\x86\x0d\x1b\xf4i\x89dP?x\xcb\ +a\x9bK\x04\x13\xa9\x92s$N\x9d:\x05jd\xa0\ +}\x04...\x1f\x90s\x0b\xe7\x0d\x8bmyS\xa3\ +1\xc3D\xe7F\xd0\x9dq\x10\xe5}\x5cWW\xd7c\ +\xcb\x96-rv\xcaE\xf7\xb1\x88\xd2\xd2\xd2\xf7\xe4\x1c\ +\x0d\xda\xe9`mm=+97-\xb6\xe1\xab\xa9\xa9\ +\x09'O\x9e\x1c%\xff|h\xf1\x98\xeb\xe86_\xa1\ +\xcc|\xcd\x9a5\xd1fff#\xfe\xfe\xfe\xc2\x89R\ +\x04w=e\xd8\xb3\xb3\xcb \x91dQ\x04|\xde\x93\ +\xf3\xe6\xc5\xdd\xf1\xe5\xcb\x97\xc2&55\x15\x94\xde\xc1\ +\xa5K\x97\xd6\x92\xdfT\xc2Y\xc5~\xb0\xe8\x93\xe7A\ +\xc2j\xc2\x9eu\xeb\xd6\x95\xec\xda\xb5k\x8aw@v\ +x\xeb\xd6-\xb1\x13\xf2\x0a\xb0\xb2\xb2\xa6\xa2\xf4\xc3\xc5\ +\x8b\xd5\xb4J\x8a\xa9[v\x89\xd9r\xb8I\xcc4E\ +\xb2o\xf1\xe2\xc5\x95\xe4\xe7*\xc1\x95\xf0\xb5\xc2\xef\x22\ +u\xcf%<\xd0@[[\xdbq\xfd\xfa\xf5mVV\ +V\xa0-\x1b\xdb\xb6m\x03=\x0f\xaeZ\xb5\xaaYG\ +G\xa7\xd2\xc4\xc4|\x88\x85\xa4\xa6\xe6\xc2\xc1\xc1aB\ +OOO\xa6\xa5\xa5U@\xb6\x7f\x12N(\xce\x89+\ +\xfe\xcfY\x91+\xd6h\xf9\xf2\xe5\x81\xfa\xfa\xfa\x8d\x0b\ +\x16,(\xa2\xe7D\x82;\xe1\x07\x8e\xd4\xca\x95+\xe3\ +V\xaf^\xdd@\xf7Y\x84p\xc57\x82\xa1\x22\xa5\x0b\ +5\xf2\xb5\xa4\x98\x05\x87\xf1 \x0b\x22,S\x9cr\xb4\ +\x14\x9fe\xdf\x12~T\x1cJ\x97\xa8\xf3\xc5\xfc\x0f\xd1\ +\xc2G\xb4c\xf2\xc9\xfc\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00\x07f\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x07-IDATx^\xb5V]o\x1cW\ +\x19~\xce\xc7|\xec\x97\xd7n\x9c8\xc6\x89\x03I\x9a\ +&M!\xaa\x08\x95\xb8@\xca%\x08\x89\xfb\x8a+\xee\ +\xb8AHH !!\x047\x5c\xf1\x03\xb8\x00\xa9p\ +\x83\xa2\x0aQ\x22\x017 \x15\xd1\xa0\xe6\xb3\xadS+\ +I\x9b\xa4\xb1\xe3\x8f\xb5\xbd;\x9bY\xef\xcc\xce\xce\xcc\ +9\x87\xf3\x1e-+\xd3:\xf5\x02\xe2X\x8f\xde9\xc7\ +\x1a?\xcf\xfb\xbc\xefy\xc7\xcc\x18\x83\xffu]\xbc\xf8\ +m\x0e T\xaa\xa8h]\xd6\x19\xe3\x14\xa7t\xa9\xea\ +Z\x95\x15\xad\xf4\x941hz\x15\xb9\xba\xbc|\xf9M\ +\x00\x99\xe5\xd5\x00 \xf7\x12\x5c\xf8\xc2\xb7\xbe\x94\xa5\x83\ +S@Yc\xe0u?\x0ckBzU\x18V\x07P\ +c\x8c\xd5\x00\xd4\xc1\x10Z\xd0Y\x08\x98\x0a\x98\x0e\xb5\ +1\x81\x86\xf64+=K*\x99'\xc5\xdc\xe9\xe7\xd9\ +\xd9\x17\xcf\xf2\xc6\xcc\x0c\x13\xcd\x19\xf1\x97_\xbd\xf6\x00\ +\xc0\xab\x16\x14\xe3O\x088<\x7f\xf8\x97_\xfc\xca\xcb\ +/e\xdaSyQ\xb0;7\xdfb\x1f\xdc}\x17^\ +\xe0\x81\x0b0\xce\x01!\xb8\x83\xe7\x09\x16\x04\x92\x85\xa1\ +\x8f\x8aE\xb5\x1a\xda\x18\xa2^\xab\xa2V\xab`\xee\xe8\ +\x02N_\xf82\xael\x7f\x16\xed\xf6\x03\xf0\xd62\x94\ +*\xe7\x01\xbcb\xd1\xd9W\xc0\xc9s\xa7\xce\x7f\xe3{\ +\xaf\xf2\xdf\xfdc\xc8?\xba\xf9\x16\xe6\x16$~\xf8\xdd\ +\x1f\xa1T@\x18\x04\xf0=\x89j\xa5\x820\x0c\x10\xf8\ +\x9e\xdd\xfb\x90R@\x08\x01\xce\x18\x98\x05\x18 \xa5\xe7\ +\xce\xb3\x5c\xe1'W;xx{\x09\xcf\x9bw\xe1\xab\ +\x5c\x00 \x11\xa1\x05>!`7\xc9\xb37o\x0fk\ +\xbf\xf9\xeb\x0a:\xd7\x96\xf0\xcdS\x06_\xff\xea\xd7\xb0\ +\xb1\xbe\x8e~\xd2G\x96\x0d\xa1\x94BY\x14\xc8\x87C\ +h\xada\x8cq\xb1,\xcb1\xe8\xcc\x89\x11>N\x1e\ +:\x89\xf5\x13\xaf\xa0\x9a\xe7(W\xaf\x01\x00#\xec+\ +\x80^T\xf4\xc7\x94q/GOc\xdcx\xfb*\xd6\ +6\xb7Q\x14\x85#\xe3\x9c\xec\xa7\x0c%\xc1eO\x8b\ +D\xd0\xa2\xdf\xfb\xbeo\xcbPC\xb5\xd1\x84\xfc@!\ +\xacV!\x94@\xb9\x87k_\x01$Z\x0a\x8e\xc0\x13\ +\x80d\x08\xc3\x0a\x16\x17\x17\xc1\xbd\x902'\x01DH\ +\xd9\x8dA\xcb\xed9\x07\xed8\xf5\x87\xf4\x5c?\x88\xa0\ +\x0a\xc9\x13\x04\x82\xc1\xe3@~\x90\x00\x80Ap\x06_\ +p\x80\x19\xd4m\x16s\x9f9\x8a$+\x9c\xfdE1\ +\x1cYn\xe0~\x94\x866\xe4\x9cv\x0e9\x94\x05T\ +\xa9\xe0\x16\xb7B*/\xc2\xf72'\x1c\x07:`A\ +\xdc\xbe\xc7 }\x89\xa8\x1b\xe1\xf6\xf5\x9b\xd8\xdc\x89\xc8\ +\xe2\xb1\xbdA\x10P\x19\xe8\x99\x1a\x93\x1c\xb0D\x15\xb2\ +\x9f\x88\xdcy\xd5\xda\xeeY\x07~\xfdF\x8c@\x0a\x97\ +\x18\xd8\x81\x0e\x18H\xce\xe0Ia#P\xaf\xd7\xf1\xc2\ +\xf9\xcfc\xb6\x13\x8d\xad\xfe\xb7\x12\xb87\x00\xce\xc8\xb1\ +q\x1c\x97\x85\x1a2\x94\x02\xa1\xa7!\x05;\xd8\x01\x22\ +\x90\x92#\xb0\x90\x8cQ#Y\xd4Q\x14\xa5C\xa9J\ +\xa8Q\x97\x13@\x11\xb0gd}\x89\xe10GY\x94\ +P\xda\xf5\x0b\x0c\x97\xa8\x86\xc7\x10\xf8\x8a\x12\x9b\xac\x04\ +\x94y\xe8\xb9FD\xa7\xbd\x83{\xcbKhw{.\ +s\xcf\xf7\xdd<\xa8\x84\x15\x04\x81\x0f?\x08!=9\ +\xb6\x9e@7\xc3se\xe1\xa0\xf5\xfb\xf5mW\x02\x8f\ +\xcc9H\x00)\xf0\x84s\xc0\x92y\x98=d\xa7\xd9\ +\x99s89\xba~\xd25\xe7~\x99\x18\x17\xb42\xc8\ +J N4\xb2B!\xb7\xfbj@%0\x936!\ +\x83\xeb\x01\x01Tg\xe60\x7f\xa6\x09\xe9yn6d\ +\x85Aw\xa0\x90\xe4\x06i\xae\xd1\xb7\xb1?\xd4\xd8\xcd\ +4zC\xe3blAgin\xa0\x0c\x5c\x89:\x03\ +\x8df5\x04\x04\x0e\x16\xc0\x19)\x05|\xa1\xec\xf5;\ +\x81;\x9a\xe1\xfbWv0[\x15\x18\x94\x06\x89%\x1c\ +\x14\x06y9\x82\x02JcP\x8e\x9e\x15\x18\xc08\x04\ +\x97`\xe4\x96.\x1dosJ\xa0\xa0\xfd$s\x80j\ +\x15p\x86\xe9\xa9\x06J\x0e\xdco\x15\xb8\x8b\x02\xca\xd0\ +\xb0\x11`BB\xba\x9asp\xc9\xc0\x8d\x86`9\xbc\ +\xb2\x0f=\xe8#\xdd\x8d0\xe8E(\x8b\x1cSGO\ +b\xfe\xd8\x09T|\x01#0\xc95\x84\xb3?\xf4\x05\ +\x187\x90\x9e\xef\xb2(\xb3\x14&\xddE\x96\xc6\xc8z\ +\x16I\x17\xc3$\x86\xca\xfa\x10j\x80\x9a\xd4\x98\xaeI\ +\x1cnVq\xee\xb9\x06\xe6N7p\xe4\xd04\x9a3\ +\x1aot|\xd7W\x1eM\xca\xc9F1\x09\x90\x964\ +\xc6\xfa;\x7fB\xda\xfa\x10S\x15\x89C\x8d\x10\x0b\xd3\ +5\xcc\x1fmbv\xba\x8e\x99\xc6\x09\x1c\x9d\x9d\xc6\x9c\ +\xc5sSuT+\x81k\xd4R)\xa4\x83\x0c\xbb\xfd\ +\x04\xbd\xfe\x10\x8b&\xc0@\x0b\xe4\x93\xcc\x01\x0e'\xc0\ +Z\xe6c;j\xe1\xe2\x91\x1c?\xfd\xf1w\xb0\xb1\xb9\ +\x85\xcd\x8du\xb4Z-D\xdd6\x9a\xd08s\xfc8\ +\x820t\x9f\xe1$\xcb\xa9\xeb\xdd\x1c1\xc6\x8cF\xb2\ +\x86a@=\x14\xd0\x05G:\x89\x00\x8c\x1c\xf0\x03\x09\ +fJW\x0e\xc6\x04\xee}\xf8\x08\x97/_\xc6`0\ +p#vjj\x0a\xc7N|\xce\xcd\x81O[D\x19\ +\xd0\xb5\x06\x0d\xb6\xfd\x9b\xf0c\xa7\xcc\x91\x06\xa3A\xc4\ +\x19w\x83e}}\x9d\xc8\xdd\x97\xf1\xb8\xcd\x9c\xbe\x03\ +\x93.\x9f&\xab\xcf\xe0\xfb\xf2`\x01\x9c\x8d&\xa1\xe4\ +\xeeE\xce\x01\x03C\x84\xf4\xb1q\x1f\x19!\x04\xed\xc9\ +\xee\xc9\x04\xf8\x1c\x013(\xd2\x0e\x98\x19\xdb\xc0\x9e\xe1\ +\x80\x13\xe0\xc8}\xc1]}a\xc6\xdf\x89q\x8d\xff\x93\ +\x15H\xa0\xfb\xf0\x06V\x97\xdeG\xb7\xbb\xb2\x0e`h\ +Q>S\x80\x10\x80'\xb9\x05\x95\xc0i\xfd\xaf\x17\xe9\ +g\xfd\x16\xee\xfe\xed\x0f\xb8\x7f\xeb\xc1\xf6\xda\xda\x8d\xeb\ +\x00V,z\xfb\xdf\x02>jB\xc9 \xe5\xbf2\x06\ +\x14]\xad4\xa5> \xfbi\xff\xa9%\x10\x82\xbb\x9a\ +kSb\xe5\xfa\x9fq\xef\xdarou\xe5\xd6\xad\xa2\ +HH\xc0{\x16\xdd}\x05\xc00g\x89 !\x16\x9c\ +3h\xad1;;\x8bK\x97.aaa\x01\xd3\xd3\ +\xd3h4\x1a\xee?c)\x85\x8d\x9e{\xe6\x5c \xcf\ +K<}\x9a\x98v\xbb\xc7\xda\xed\x18\xbd\xdd\x0cw\xaf\ +=\x1a>y|\xe7N\x92l\xbd\x0d\xe0\x9a\xc5G\x16\ +\xf93\x07Q\xa3\x0a\xcc\x1f\x06\xe2\xc3M\x84\xba\x81\xbc\ +\xc8q\xe1\xc2K8\x7f\xfe\x05K\x90C)\xedf\x7f\ +\xb7\x9b\x22Ib\xc4q\x86(J\xcc\xf6vWmm\ +\xed\x0c\xdb\xed\xad~\xaf\x17\xc5i\xda\xe9\xc6\xf1V{\ +u\xf5\xe1\xd6`\xb0\xfb\x00\x00e\x7f\xdf\xa2o\xec\xda\ +W\x80\xe7K\x7f\xd0Oq\xf5\xb7\xafac\xed\x09\xce\ +\xce\x1f1\x0f\x1fm\xe3\xf1J\x8bEQ\xdf\x92&&\ +\x8av\xcbN'\xca\xba\xdd\x9d~\x1c\xb7\xe38\xde\x89\ +\xba\xdd\xcdv\xbb\xbd\xd1N\xd3^D\x04\x16\xb1Eo\ +\x14\x9fZ\xb4,6i?&\xdfO\xc0\xe3Gk\x1b\ +?\xff\xc1/\x16\xef\xbe\xf7~\x91&Y\xb1\x94\xdf\xcb\ +\xae\xbc\xfe\xf7~\xad\x86\xdd~?\xeaF\xd1F{g\ +gm{8\x1c\x10\xc1\xee\x98d\x0c\xb7O,2\x8b\ +\xe1\x9e\x98[\xde\xf2\xc0Ixo\xe9\xf6\xcfz\xbd'\ +/\xa7\x83V}0\x88\x22\xadKR\xdf'\xec!|\ +:zN\x1d\xc1\x98dL\xa4p\xf0\xda_\xc0\xc3G\ +\x7f|\x1d\xc0;\x16\xcdQ&\xbd\xbdY|\x8cHO\ +\xc81\xb9\x80\x11\xe1\xf2h>\x14#\x22\x83\xff\xe3\xfa\ +'\x0a\xd7w\xe2\xf8Nm\x80\x00\x00\x00\x00IEN\ +D\xaeB`\x82\ +\x00\x00\x06\xe8\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x06zIDATX\xc3\xed\ +W\x09LTW\x14\x1dj\xed\xa6Mii\xb5.\x15\ +\xf7\x1d\xb1 \x8a\x0a(*\xb2\xa9\x88\xc0 (\x22\xae\ +\xe00\x08nl#B\x01\xc5qAvq\xa1\x0a(\ +\xe2Z\xc0\x0aZ\x91`\xc0\x15\xad\x88h\xcd\x18\xd4\xaa\ +\xd4Z\xb1.\xe8\x8c\x0a\x9e\x9e\x0f?\x8dR)\x9a\x9a\ +6i\x9c\xe4d23\xff\xdds\xef9\xf7\xde\xffG\ +\x02@\xf2_B\xf26\x81\xffe\x02fR\x85\x91\x99\ +4Xf\xea\x14\x14o\xea\x18\x98f\xea\x18\x90>\xd4\ +~\xc1\xaa\x81\xb6\xde\x93%\x12\xc9\xc7D3\xc9\x9b~\ +\x0d\x9b\x18\xd2\x97\xc4\x11\xc3\x9c\x17\x17{,\xdc|9\ +`\xf9\xe1\xdb\xa1\xd1\x17\xab\x15+\xae\xa8\x15\xcb\xaf\xa8\ +\x03\xa3\xce<\x90)v\xdf\x1al\xe7\x97o`1]\ +\xc6#\x9f\x10\xef\xbe\x01\xe2\xc5\x96$M\x9947Y\ +\x15\x91Pv7\x0c\x8c\x06\xdc\x02I$\x03L\xa6\ +\x01\x86\x93\x01=)\xd0\xdb\x1e\xe8fK\x8c\x06\xfa\xd9\ +\x00\xd29\xc0\x82\xf0\x22u\xaf\xc1\x13r\x18\xc6\xe0\xf5\ +\x89\x9d\x17\xeb\x12\x8aI\xbe\xc9\xaa\x95\x1bI\xbc\x06p\ +\x0d\x02,\xe4\xc0PVlL\x0cd\x12\x83\xbc\x09\x92\ +\xe9{\x00=]\x80Nc\x00]\x0b`\x88\x13\x10\x10\ +\xa5~6\xd0VV\xc9pN\xafE>|b\x88\xdc\ +\xc6#\xaa,<\xbe\xa4*<\x19\x98\xba\x84\x15\xfb\x01\ +fs\x89\xf9\x94[\x01\xd8G\x01\x93\xa9\xc6\xd48&\ +\xc6\xf7q\xdfP\x11_\xa0\xef\x14\xa0\xab\x1d`\xe4\x0c\ +\xcc\xa5E\xe6N\x01w\x19\xd2\xf7\xb5\xaa\x96-\xd9q\ +5&]S\xebM\x92\xf1\x01\xf4\x96\xa4#\xfc\x01\x9b\ +\x08\x92\x92p~:\xb0|/\xb0\xbe\x10\xd8T\x04$\ +\xfc\x00\xf8o\xa5\xec+\xa8\x0e\x13\xed\xc3^\x18\xcc^\ +\xf0]\xc6\xe4\xbc\xe3\xab\x19Z\xf1\x0a\xe4\x0a'\xa1\xea\ +\xc8\xc4\x92\xaa\x88u$\x0ac\xd5$\x1dE\xbfm\x22\ +\xd9l\x09\xf4t\x1b\x10{\x08\xc8*\x03\xb6\x1eT\xd5\ +\x84\xc4\xeeQ{,\x88{\x18\xb9.O\xb3\xbd\x84\x92\ +gP\x09^kLkF\xd1*E,\xed\x19#\xbf\ +\xc7\xf0K\xfe\x1c\x1f\x8e\x861\xbf\xf8\x88\xd0z^r\ +\x07\xcf\x98\x0b\xb1i75\xf3\xe9\xb5S\x08`I\x99\ +\xadY\xb14\x06\x90\xb1b\xe5\x01`W)\xb0\xad@\ +U3\xc6#\xf4A_\xd3\x89W;\xf4\x1aZ\xac\xd3\ +\xae\xfbN6\xda\xb1\xb5\xbbJ4\x89\xf9\xb4$\x91}\ +\x12T\x1fcU\x9a\xfa\x99\x91\xb5\xe7\xed:\x05\x04\xf2\ +\xc4\xd4\xb2\xdf\x0d-gm\xea\xd2\xdfb\xbc\xb8(\xb4\ +\x98X\xf0\x0c\xff\xd4\x8a\xd8-\x9aZ/%\xbd\xe5A\ ++\xfai\xbf\x0a\xf0Ha\x159@\xca1 \xfb\xf4\ +\x9dZY\xe8\x86G\x02\xf1\x97\x9d\xf4\xf3yv9\xe1\ +E\x8cc<\x7f\xdf\xc8\xf4\xdf2O\x02>\xa9L\x9a\ +q|\xe3\x81\xc8\xa4\x13O\xba\x1b\x8d9\xcfk\xfc\x04\ +\x05J\x0b\x8f0\xabu\xa7\x1f\xe9\x9b\xbbe\xe9\x99\xb9\ +\xc8\xb9\xc1\xb6\xf9E\xe4\x5cWn\x06\xa6\xd1o;\xca\ +n\xcbw\x97$@\x9e\x09\xac,\x00\xf6\x94\x03i\xfb\ +\xcb\x9e\x8ep\xf6\xbf\xdf\xa1\xb7I\x09\x83\xad!<\x09\ +s\xa23\xf1Y\xff\x11\xee\x16^!)\xd7w\xfdH\ +\x1b\xb6S1Z\x18\x9fE\x05\xddB\x1fh\xb7\xea\xb8\ +\x9b\xd7\xb8\x08\x0dV\x96\xcb\x80+\xf9\xa3\x97\xe2\x94\xda\ +x\x9c\xef\x85\xf0\xa4\xeb\x1a\x7fz\xeb\xb6\x94\xcb\x84r\ +\xdb\x0b]\xfd-\x83\xb0\xc1\xd6\x1e\x07\xf2\xca\xd5\xcf\x16\ +)\xb7p\x96\xed+>o\xdfc_\x9d\x97\x12\x89\x1d\ +\xd1\xf5\xf9Uk\xe2\xb0h\xda\xb2\x0d\xfb\x7f\xcdd\x1f\ +\x84\x91X\xf9\x1d\x10\x9et\xf8qW\x03+\xa1\xfa0\ +\xc2X\xb0\xe0\xdc\xae\x5c`N(;\xdb\x07p\x5cT\ +]\xebBR\x07b\x1c\xbbUJ\xc9fm\x01B\xe9\ +u*+\xc9-\xbbS;Q\xae\xac\xee\xd4oD)\ +\x03\xc4\x103\x89!D\xeb\x86\xabU\xb8\x17d\x1c\xbc\ +X\x9d\xce\xa4\xe38\x11i\x07\xef\xd4\x9a;\xf9\xdfo\ +\xa1\xdd:\x93?\xbb\x12m\xeb\x12\xd8\xb9\x9f\xber\xa6\ +M\xbc\x00S\x8e\x8bUX}\xd5\x93\xd6\x03\x9e\x94n\ +);<\x93\x92\xe7\x9c\xbaQ#J~\x92\x87\x95\x84\ +\x83Xu\x0b\xe2\x9d\x86\xf7\x06\xa9<\xe6B\xf1e6\ +({`\xe7Q\xf53G/e\xb5x6\x980$\ +>\xa8K`\x0f\x09f+\xebgz$\x95\xb0g\x87\ +O\xa1\xff>\x94,\x923\x9dA\xf2\xb5Y'\x9e\x8c\ +$y\xbbn\x03\x8f\xf0`$1\x96h\xdf\xd8\x0dE\ +h\xee\xf4\xbc\xb2\xbb\x85* \xff\x020/r\x8bZ\ +TMH\xdc\x96\xf8\xa2n\xe2\x84\x04r\x8a\xd9\x9d\xdc\ +lvL\xc2\x81\x92O\xe5xy\xd3\xb3\x10\xf6F\xf2\ +\x19Vp\xecF\x0d\x1b\xb4R\xbb\x95n\x8e\xb8<\xac\ +\x886\x8d\x91\x0b\xbb\xc3\xc3?YU\xfe\x0bp\xfa*\ +\xf7\xc4\xd2\xad\x8fD\xdfW\x13\x13^H\x5cH \xef\ +\x14\xc7\x8a\xdd\xed\xbe\x11\x98\xc1\xa51\x97\xcd\x16LU\ +\xa28fk\x0a\xea\xc9\xdbw\x1fT\xc8\xcb\x17\x0a\xd6\ +\x8a\xd9\xbf\xbcr\xa7 \x1d&\xb0\xf3P\xe9MMy\ +%\xc9\xa3\xb6>\x14\xc9\x85~\x11\xee\x80\xba/\x9c\x15\ +\x12(\xa2Dq\x5c\x16A\x9c\xed\xc5l\xb6e\x5c\xa3\ +\xd1\xec\xdc\xb5\xdcl\x99\x97\xb8R\xb3N>\xee=d\ +\xc2Q\x9d\xb6\xdd<\xc5\xec\x1b}\xa0`\xbc9q\x19\ +E\xb7J*4\xb5\xce\xb2\x15\xf7\xba\x19Z\x97\x8b#\ +\xeaLt$\x9a7k\x13_\x0b\xf71\xd1*\xedWy\xeek\ +&&\xd1Fl\xb0\xbfC\x9b&\x9ej\xb5\xea\x96\x8b\ +D\xd2\x92x\xef%I\xfe\xfb\xaf\xb7\xff\x8c\xde&\xd0\ +\x14\xfe\x00\xc6\x8fm_Q\xaa\x96$\x00\x00\x00\x00I\ +END\xaeB`\x82\ +\x00\x00\x03\xd1\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x03cIDATX\xc3\xc5\ +\x97\xcdo\x1bU\x14\xc5\x7fwf\x92\x89\xd3|\xd4\xad\ +\x17\x09 \xd2MUQ\x10\x08Q\x84\xca\x0a\x09\xd8 \ +\xc4\xa2R\x17,*$(k6,\x90\xfa\x1f\xc0\x82\ +\x0d\xa8;\x04,\xd8\x82\x10\xaa\xdaE\x05d\x07\x08\x04\ +\xa14@\x85\x11n!\xb5\x13\x9c\xe6\xc3\xb5\xd3y\xef\ +]\x16\xf3\xec\x8c\x9d\xc4\xa6\xf5T\x1d\xe9J\x1ei<\ +\xe7\xdcs\xce\xbb\xef\x8d\xa8*\xf7\xf2\x0a\xb8\xc7W\xf4\ +\x7f\x1ez\xff5y\xf2\xe6\x16\x91U\xa40\xca\x13\xc6\ +\x12\xaa\x22\x00Q\xc0L\x180\xeb\x94\xc0:\x1a\xd55\ +>{\xfbs\xe6\x81\xa6\xaa\xbaA\xef\x96A\x16\x9c}\ +]\xce<\xf8\xc8\x0b\xaf:\xa7\xa1\xaa\x06\x0f\x1c}v\ +\xdc9\x15T\x05`\xaa4\x17\x8d\x17\xef\x1f\x09\xc2\x82\ +\x98\xad\x86~\xf1\xde\x89\xeaw\x8b\xff\xbe\xfb\xe1W|\ +\x02\xd4U\xd5\xf6\x05P\xd5\xbeu\xf64?\xaa\xaa\xaa\ +:_\xb6\xab\x9cZm\xb5nj\xb5\xba\xa4\xc6\x18\xbd\ +\xb2\xf0u\xf2\xe6\x8b|\xfb\xfc\xa3\xbc\x02\x14\xdbM\xee\ +U\x033\xe0\x94\x10,`|9\xd2\xfb\xb4\x04\x8b1\ +\xb7X^\xae\x11\x86!\x87\x1ez::\xf9\xc6\x07\x8f\ +\x1d\x9e\xe1\xe5\x97\x8e\xf1\x1c0!\x22r\xc7!L\xbd\ +\xd6.\xd0\xb4\x1c\xe0P,\xaa\x09\xcdf#\x0dU\x14\ +\xf1\xf0\xf1\x93\xa3\xa7\xdf\xfa\xf8\x99\xb9\x12\xa7\x80C@\ +a\xc8U\x90\x02\x81E1\x9e@\x02\x18\xc4\x93\xc9\xe6\ +m\xdf\xbe\x09\x8e\x96\xd2\x09\xa7\xcd\xdf\x82\xde^\ +\xa5\x13\xc6\x14z\xfby\xbd\x1b\x0a$;\xe4\xee\xf6\x5c\ +\xbb\x16g\xce\x0a\xec\x9c\x84\xba\xebs\xd9\xddC\xf3\x1f\ +D\x83b\xd7\xfd\xfb.\x0c\xa2\xac\xf3\xfd\x94h\x0f\xec\ +\x5c\x97a\xba\x15\x0f:\xe1\xc7\xc08Pdm%p\ +\x1bMZ\xb9mF;-\x80\xf4H9\x860\x8dR\ +\xa4VY\xb1\x95\xc5\xcb\xf6\xa7/?J\xae,\xfe\xd0\ +\xb8t\x95?\x80U`kH\x05\xd4\x1f@\x15%\x04\ +\x0a\x08S(\x07\xa8UV\xed\xc2\xfc\xb9\xe4\xd7o>\ +5\xe5ry\xfd\xef:\xcb\xdf\xff\xc9o\xe5*e\xe0\ +\x1ap\x19X\x1f2\x03\xa0\x8c\xa1L\x03\x07=\xe8\x85\ +\x0e\xe8/\xd7\xa8\x5c\xaa\xf0\xfb\xd2\x0d\xfe\x02j\xc0\x12\ +\xf0\x8f?\x86\xd5\x81\xcd!\x158B\xad\xb2l\x17\xe6\ +\xcf\xef\x05z\x1d\xb8\xeaA\xeb\xc0\x86\x07\xdd\xd2\x01_\ +>\x03\x09\xac79\xf7\xce\xa9\xc2\xf4\xf5\x1b\xd8\x9f+\ +,\xed\x01\xba\xe2en\x00\x89\xde\xc6\x17\xef\xc0O3\ +\x11)\x01\xc7\x80\xc3\xc0-\x0f8\x14\xe8\xed\x12\x18\x01\ +\xa6\xfd\xd1\xdazi\x87\x02\xcd^\xff\x01\xf9h\x10\x8e\ +\x11Wv$\x00\x00\x00\x00IEND\xaeB`\x82\ +\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x09\ +\x00W\xb8g\ +\x00p\ +\x00r\x00i\x00n\x00t\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x08\xc8Xg\ +\x00s\ +\x00a\x00v\x00e\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x04\xb2X\xc7\ +\x00u\ +\x00n\x00d\x00o\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x04\xcaW\xa7\ +\x00n\ +\x00e\x00w\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00@\x00\x00\x00\x00\x00\x01\x00\x00\x0e2\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00V\x00\x00\x00\x00\x00\x01\x00\x00\x15\x1e\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00*\x00\x00\x00\x00\x00\x01\x00\x00\x06\xc8\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/mainwindows/dockwidgets/images/new.png b/examples/widgets/mainwindows/dockwidgets/images/new.png new file mode 100644 index 0000000000000000000000000000000000000000..dd795cfffc5c1ce273b3afedb5ed01da3fc5668c GIT binary patch literal 977 zcmV;?11|iDP)bWCsWYp)^2+5pE&16P)J5wbOa;T^94~jGe@$^;8|{N*-xE=iGD7yYG#t zD);gVxW`xYe;#`OHF@&p7Liq?Fv=6g5~?BqQNT@!pB*cZ>hN`{7r7 z0@PL2_61PYzIFCAKdP##I$yS{oLX(QZfdoPWw^&}T5r!d$9(p=D`Njv29iHLkmyYoqFd-sx$01C;)-KSr9NW?hA@p%q*ht6 zmBq{Ur!PNBt}Oo0xOA02fK^~?NCng%Kounf3J6mu2dGt6?ZW)I`_c{m0&2h#@Q*)+)q%|+6*xkz zvTPUT&+i3#9k}X2>%fKw-O>SHJ_8A?H#zstslxR28`z&KEbRfh;$?0CiQdK+@4!zp z5h(%3fWyEo4>%O)?GhLPrv1^{dTECO&0hZj`DhT15m$C300000NkvXXu0mjfIXk#o literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/dockwidgets/images/print.png b/examples/widgets/mainwindows/dockwidgets/images/print.png new file mode 100644 index 0000000000000000000000000000000000000000..2afb769ee23189efd927255c5f01da54588f17a0 GIT binary patch literal 1732 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/dockwidgets/images/undo.png b/examples/widgets/mainwindows/dockwidgets/images/undo.png new file mode 100644 index 0000000000000000000000000000000000000000..eee23d24a3128303b6096d80582ffa3fef7af7fb GIT binary patch literal 1768 zcmVP)v;?WRp>X|*mD_Z_hyiV7$yvZ;u`ASfcP;4lboY$HMe#c@G)aiIz*;#$B8 zT9IJD6|IP9%^1|G)LOAF=!^=Uo)15bQYo66HffyXWHK}V-E;3b_ul_U0zmR#Lh?3& z|78MZQiYM3G+1Wp6clgj7?@`27?3{He!;4Nw%(H^63NFzGs&BN4VxI!m&6gnoEH~+ zEZlrKVEN(Oq0tws6)Uc&70a)v1EbD7kSTWG8f@p6Z(uQ9#v`8)@4f-z#g-&ZnKU<9 z6_HSOH#|X8D-Q=IEda)P0;8t_Bi#UNcffrf5Efne#KLvSwbr_NQXbd&$HdbYrB*1D zuRaWn2HXNkBm+#Q0fv(SJt@%J9_VIEj0XDI0Ma?Yg76}BufY>?7{=iBiJceg5{gN_ z$*PqbNxTMd4FW9Wz))6fOblcagS-in>3aY@U4Tww09^}Uh!YSHrG7ThR#wSyPOn8i zd}4^)#v`gMJieqVJQrImJ0rZxnBm4oI2$GU;embyxFR;E4*i-~0`~diG zrR*!H4ioLeUKq??@Lk5_yyL4GTJZ|x3MZlJ$i$MWh;<|iW7Q-bMZaw#*=z~)bQ=(R z2*@e}wjNZ~gv9Pqdn|~17`ZM_v%Q3pXHW@VYfNiK(JDnO?HMD#$M8%393PH`F~9hT z(0X2S2hW%bv1vCo^Xauy2w+K>ty!@&29U90y{!Rhs&lk+tXTIt2vs#MH9i4J~JF>eAn0ytpW|m{{-( z|I~`uEt*;{CB5ZAEBa}_3h+o_6*)l4F(CW&omyGwhDQSNm!0(Ud3HJBMT}!Sf8WUT z-!e}EKB-KaaeU)}$fOfbx*Lr-&ujby1xgE#FspT^AL*OBW$Br@$hpC``921>Hg)Xt(OPo7cDq4OW)RfGhc~*bt)^#ExS`YQLe1+ z)Ne#71H=$Bi6KPmhO1S$7i1i~Se?$K<2Vs%2k+FHJNe&lq1`%@Kf4lb>k`t}i-m9S@rPoe)llq`}nok8-oStp*1Bze1T1CQ`v zBr%p~-`EXBXzuj9vb%*UApZg|FLH}oR82_SmiVG>;)DcpirJmqY<5h-fs#+_r%hzk3`>B6BAxYTu31A z6vv9)?Ym%@#~mqBv%23hK$*cOO*9%NGjPirK%sa;G32Cb08R=}k>}CCQ_< zJ`~A?ei80~x-Xm+5-6fXaaJ-8{wY z8-1W)yg6|hMYl>SG_}sM75BOsT9=C>>P&Pbnm0Uf?(EON!JkN0THkDY=v#ILu#fT; z+yKs20qb@bsr#5nckoCb;{8S*O6)=t_g>3CeN!`bdc^I{`lE#Xuu{D1{gqst)r{<- z%bM)sOHZ?kR5jU0RW&)p-ebgZRn7NA?g;^xp1S(3u4<*L=Og;B)!_M{heyEri>uQL zs|+n?p8Klj-~;?Rg0L55Z~jur3`Wmz8DKTLpx^Mx=k?57FExr`uBtX&406P|@A48G znsqm_HSaytapQ+AKaJvNIWdxG*VLnzu(<|^i(z&Xa1%rmAEmS!#1TGg6JHDWG0`gR zS9$JhCMMBFY_PvWn(hEjNT^D6#f9lk8NL3s+J@G0000< KMNUMnLSTY!`bcR2 literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/mdi/images/copy.png b/examples/widgets/mainwindows/mdi/images/copy.png new file mode 100644 index 0000000000000000000000000000000000000000..2aeb28288f58ddffdd1d75115f170c5bf2773814 GIT binary patch literal 1338 zcmV-A1;zS_P)3P|jKV4ArrNQZsr&q&3Fam_48Lh`MiYI|sB6GiaYuZZ? zasnKC=d9Ws*vOa?K!llv;~9}LDH=;*C6q)snnH7j#=aB8{{oN_lX)cZ$XJrkAB0_u z!sQ7f5=*1>!|zQrby)$h>)1Bcke)jH%(>@ZE)hRgo<&7f4Jw)5udTzKv5Ch3thOcm zx#)*$6jZ zxjE=2CQwjNfFaFqeBMc>`320FTpYmRPeJsB@I$Z8%>Zil0#HL{*yW1HLMx&9BQ>hew>g`42C!b-4K{%G& zPNKpdi`TSeSQ5jt zz}D6l-wA<00HP?u@AqSEZ4IXsmC*dI=c&nj!3&r@K%3kE+d(!rH~Ds?RumQ0==)XR zsU3kw0Ovao0D#OTfFv_dBoZhqui^lIxB!co0iZTo)dw&I|ClF}JUvZG$*D>XptrLF zi9N;m7cj8^d~x*v0Ho^4m=ue}P^PGYdPu;S8Mtc&=A4=P=T~F|kkV6X0*FSV+&mNt zp}4dH*9HaLW{2dU0UTt+1SmUX21q@ea}t@;xj-PrWmUM?EueooW3GLWY2c%FnE?J> zJ*6hCuC8*3w@NB-xmUnF8@PU+0q)ELXD;m%K&qWYi;j}haZKLWGrnrG9>`fBl6@D%o`^aXzvlAyk=W}Pc`B^ahku5Y4`j}CIOJCBx$u% zLNX5qgK)WA+>l;M=(ES;f!poI@e{8lpM9a6Ogos0nT|fmct-%0O2q-B6)w#;8B$U@ z_bIi*;ou_U#l=Mq_2TiDT=X8flj*JiEiEl>>0qJM(w7a5mzS5}^Z8)2+4y~FX^BG+ z0F4U^3(c|s(4vx3lM#*SPTzP`J2hanT6y)<3jNMtFeLKw^6s-|9N8B@Q&W>$nrBK+ zA`_~b#ukg2H$b09M@J)VZEfEC{CpGp+d-zXy_)|gKy!05p8`rp5L7=^KR-Xu>(*#A zk-EA%=fkvJOdl{E&Bk~~0Hsptb~>HBVoFMHK9sb+zTTOWlOvfHXH#`n0F8}}Zi~f& wfq{WYZEdYHH#b*S)7=30e@0BgL78sX-$OZ87=>`i1ONa407*qoM6N<$g6NH5LI3~& literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/mdi/images/cut.png b/examples/widgets/mainwindows/mdi/images/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..54638e9386dc8af40dcc9a3ee2f57c62e248e406 GIT binary patch literal 1323 zcmV+`1=RY9P)J0(1!|L=@Q+aTEb7Mu4u}WZlMQB24&|#EVDBq0{%sj+Z+)GGQx0 zAcdU1Fi0-lfEhqCt9ecIzWZ_$Xk-SF1YV<2^ak#QNA=LXgUd}Io1OMRbT7RYGCd%P zKS-r48v%?ldBMA#h)c%T#wHG+5V`$A{>3XcMvM|%P6Cssr>70f(>b}AV>T2D(&VEn zK_HANo+{rrN9){swakg0Ktz^QgDWfxHbzJY6ZK>&doEN10r&$qzrYSODpcQMh*H%o zSOat&76=4-MOF34plx)*)N}VCzH?EPkgku=6VK(8gNL*Np3E)-)CS$Jnai-RudhD8 z(qOgQ?SS}sjv4h}*IqNacG`39XxPWcN1v;!unrFm!4QYC z_Acj^H}`jQVc5OsUVtxVnxKZ?sWw9Q@B`QxpVZH#=NgKbEq?xOmsA>SUtb@%(9v@T zVsaH$PQ-_o)Qm6`=@qvgI2;Z@q}CZRo`stQer>5G8e5my4CXEh^CT4CHjaC}9?{K0 z$O&($1U%8bR;v{dcYhm%^O9V6PFgxKporEb{=Djv}7NhUQZ#8TNvL0_NhN zpdjG!cwn(uKwDk``_Co}Ev8e>XOzzgOoQTEd*;Gmnz9rW3I&M8V#v(QgrcG%P^;C@ z+1bfp?EcBQ$=j!OF1OE1fUdXLDR2(JYL~2dh{}J0;wgy^K9?&YTb2(8W8+7JA12t6 za%7Hg8ovjl(FiTAE%3|0ARIXHz6G;l!311sgoTBKM%*UnGOR4mGqn@!JL9_3Gp~Z> z{(6Z9p5FXo8}~etjeBORPg}}0?N~!YJv1~lfTgz=G8Dzb^Xb54Jd))oo;F?OoGLPS zee{DaT5J+A3>zitarZCFC+`J^U;fkNL<>x4^vOPTl^zTR1GKld!`H@^F|L6LX7M&{ zIA}acIyz>{0a00^F4~fx%15b|k+|p_1^WSy+Zxk*z z((l+8X-U2;oygOcJEspZj3vh3pSpKnaW$YpY_$lC`IPbC@H0!Ad}tF|z0RZAYfnh` z3=gmm{_}^(`7iFdNp1l4dp_;=2p%dvUFBG+@kd(qwpj}i9kWBpkvIuC`Kgv6`dk_f h&$IvkH~dc%_#Nkm8M#Em0nY#c002ovPDHLkV1hsWYZL$g literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/mdi/images/new.png b/examples/widgets/mainwindows/mdi/images/new.png new file mode 100644 index 0000000000000000000000000000000000000000..12131b01008a3ec29ec69f8b3f65c4b3c15b60d6 GIT binary patch literal 852 zcmV-a1FQUrP)IE2xvpcKl890$E8eWxeF8o0mWjmIG{M&7eWO9CVRojsy7@;&dpQ!a9t0J7gPX(5I|>76wd9YM;~Wq>Ghkp6rY@= zsi|pt_x=M#qtRtve?bMn?-1>_C5DBX;{}vm&C%raD|#~il%B<2&`e?uix*V@+JPAL z6CgbQkZR2~6*sGtFK$zbV~w|k*M3m}@OjM5T^_Z^d)w}xJHF(IUAVpO;*`oW;C1B2 zbys585IO4RGepz@rv~8kI;}Y(n3!mCfS7AgQ=I?+DlNG&;!abH5Df(KZTl#;d_@48 zJKJjfX^uQ>h#Iar6M#C8w^So4*Tn<|1^_iEoENLSCA-QKz)fKe6)JLW%zjz|XlmW9 z@suY3Q`{VJZCgNKnyVajp6h`@6-N=kYKbun)^`LT3}hx^wrO>XsHzE2w#B^A1Ngov zV}~hV3>btQ09#E(0CWRWn5~q>9Op*n90161U8$i6fc^Yd5_2;F2sIc&=-PaaDX2~W zTL1&dm}fQw05ax<-uM>_{4Cgt02pUFPqb7NBbWjJ0t`O;#ZxHoL%3#1_iOo5hu6MT z0mxO4x=yW24v?>f-nYV%Jx`{y-lMT`>)O!u6_~SbsQ_#=q-z-e;1PdX7gN*|3t4aE z?!Drr!OKg0ZH#q?HK_Wx9NlHvJdYn4{+`bsH@(TacqVT~0BG|6fti$^=|8_20YcOC e{Jor>rG5iZY$c(Rl?rzN0000RP)CWtKz1rEEwa&Ubd$6s{da=&VIP1;2`BM0`Wb;D z{M-!)vd0-ix#k=pmKgFxQgYk(eOi$0QlJD2NbOI5d5567avIIj< zv@<}9dj`!tE;Q@xs8{wNhf{?zUNu9!u=J3D!C+h_ze{}K1V|htI6?j0>T@UYxhDij zhnKMl|M#(rT!AcZ}eF)wgP_d zAX10jekLr}U#(CrCA<(opAbNs2#S{v>vbjZBPMG2>Dlh2!oC#Mk@9m9Zc z2%^^3CBjkLC=!RpAFqNhVw6pZB#Q!^oqj*T-F(Vw$mLX*nO_ zNX-3DeeTpEomGUYnz~IsN92z9JUkMF)7=lf!HB}*Vw`?29z6pA^e+N~guKQ7E$%u) zC{dC3_66}y+`oN81yr%;K@{IH8|1O-3y*riL6}qGd@SEo}8X#Q_kq zZ|eG3QMpHgF(8Pc07FLLD$kpMaaUZZl&Qk=tr>Kq76&g@g}Kbh`}mD}bLg zSob6#9DIaI(-=7VVTPPm{Z+FbtPVT4Iv?2~9(pg}6TG@z0w%t}gOqRBIG>z~1AjdP zW3QR%ZYsA%*Mp?X$w>b?i;UGgQ?+sSsoXX8X`%zES@sOGBngFV;lVB@d3_10@@V;lg>dY2BN>v^RZ2^?j@k8NdQ$X;_ z_a$H}ZfeJ=gha#~If~qTHdcoJ4Lhqwh-3dbkKgY5JsSA}oWGEOlkpdDqpb%S#7{~T>2A7M zsP8QLl$cN`w?OF*Jo#7bDJpj@!Dj^fwz=d)jlRsXTKwbW85}(HH?VT^u<$rb~rBzaiB|lB=W)A?(%51dO$!?mU^ ze8O#IHd*n50bG}w!BKl4^90wps7K`#)>4RXJ_(`usyx1v$_9j`-;Pq{6K%jV&lNRO%>FPb&x$A5bBEmwG~ zsNAo;tlZJ!2;Bu-bsyf#uSL0b05WG_^}?r@soeJn(y81#_yhC8@e_i|9PXV^3ptdy z4Z_G4qZfz6FCzC2|JrSe-C>#48@AYMyIwNBFNyyFX1QPd5r93<00000NkvXXu0mjf DP*&js literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/mdi/images/paste.png b/examples/widgets/mainwindows/mdi/images/paste.png new file mode 100644 index 0000000000000000000000000000000000000000..c14425cad1ff1b2c5628be5769c9e9e52b78635f GIT binary patch literal 1645 zcmV-z29o)SP)3Gx zefpoBhy8x@pP6$JN-2UQgm?vbp2urQDfM^OC?_DeL%RWJmr}mQV`N#@2O9RfK(_`t z{}ccw{I~7(;$U4wL~hQBiYr&HP+e1vKmedn2xTZiDQ44YUa1!^ytGbiJMka6M}vG@ zLrgqP2loG9i`^_G_)0Q7JWOR}B`e8wT^_)0sjwm&qAGGfr|N;V0|+ezNTCh%UA#yx zm%}d>QA&}|=UH4_q);eO)MK@^wUhx^fcS#;fB^tDLmDAYR7=GY}hKA6kOPAcP zuC561)~X!<6GT-k!gJLz@}5tjD3MBG2|?Jgh=y$Das?8ijz6FOD-BH>0V2R=mW1#7 zc%Dafb+w*QOZ4j1tA~UTD5c(75x}xR0JbfV+O`xp2&58N!i*b_Ou6iP^*huzHW7R; z!Gvcr8OqDc&1OD!?ARu~e-17|ECJBj*{Kd4I;3nN2w4!eEgZ+jLQu5L8XEw|vWPgA zt^#0Lco4wc+#EGEH3lFWjdJA3kD9q>HlpG95}EZ=m1y-ptN)rjt$|Ez*CB`q|1$rgVVB? zrhTuowc{78+xt2VFSK*}&LsW){Unn~lv3vU`0?ZDx~wzj&Yk1v(W4wbe3;(eUJ{9f z1T3Ky+yU+X&gS^%luv8N&-msq-zN6;H<^5HH8r836d;2i zMi$(072p5qZ>Vh8NaE}}Opji}iIlOmc?X+Yw)07OC1VMf&t~%6oz60$?T8IbC+FC= zE6VyM05f|%YwGIi0L*nNl`;TID-fW$T5#c=V<;@j=Em6&k5ZJ9d&7MsWd+;Xe@so= z%X~bXX3}54&3G)#YcF^p0JU^FLZOfeE#2xLjsYt8K48JdxS&uRBOHrUx22Yncy@gS z>8!_S|DTwyyiCjXgSZP}yn>`ylz7@9$3iWtfa7VPmemyj0M^GtgvulQziMM4o~aCT z;opPo+4&R7qYk+;M*}DWVQT;uOChBkB`_)#q+A6+Sfwh=^&|RlY=-e!kMI5ZkKD@C z;6z-a5gX5w6g>yi0i}>q@=$770agVN2uuwG7@cUt@bD?; zK3j0A)Rg|7%OH8oYxFCwW^r%olu$Hy-NXMuhl?5?;8OW$_d zPbP%{KnOr#TKwMNV7j}zJEh->%p}lW?Q_jx?V5KpZV_N`@cndOUtjvnnKP!vrO=Of r0*SSrV$g&__6vQz4|I&^4Jxf00000NkvXXu0mjfT=)$w literal 0 HcmV?d00001 diff --git a/examples/widgets/mainwindows/mdi/images/save.png b/examples/widgets/mainwindows/mdi/images/save.png new file mode 100644 index 0000000000000000000000000000000000000000..daba865fafd22fa18e7c0488eb699b79d3554170 GIT binary patch literal 1187 zcmV;U1YG-xP)5-PJz!8#8DIjU4h)0S{a*K!i>mJVVCD^kQ5IHGsm^=1>z+FI)Tw&v zz2|;5 zYXiKvXAppke-?cB?jC^K0C4>59N#}M1b8m}xWN9m&Tq?d4;^`$3nP}(pC4rW)qR_5 zKt-??KzML0Bg?XF0WdI@VU185d=w)kA`~mw7?IVLbLY;3D!2sF6tWD`ER0DCNfO?7 zI*{j(x1rU7b}No;C~~s;IMxc|ue?cX@%rWftQD*k1h7Wfy?f^tYwL!tfLf?lf$D8h zjjsf?g7=`NgaKy-HG&AJ3Y9FwBOo3K!0;X~0^TDMCKY^$Bg7#dJRx2{O;{K}*Gh>7 ztf1Os0Gczu1&UJ#X#$l5vNZMt5(iG9=s;dTE04VeOF6W2$O}}5aXkPkPoHKY21CJ!U{_^v8Xy`U*q`vX%#{A#01X5mtL``3Wj}4_b=eEU&o)}BH zcC!Nrol+61khoCqTE#GZvCBZkunzPltylR~F5%(E(lYhTaDB;yE$K=b5S$vobLD22 zD>u8WQCC0Ls$_n}C!#5=1r@`b3$=HqY!|4(sUXN2HLsgB8jo2qp8k93?-T&>g72GH zFe_J90#zZ=ko@OU-}3936D%#>xTpG8Y6Cp=>`tC}VFC}RGg~nb1AK?~_rJly!UDH$ z-J&Q8L>2*RmC}ns$#9hnDF1_1m8Hc<-5*m|${p@{U>9F*?@YhOX2JRd6<}qE@f>YdJGB!_d$W)>^#xG@H%40#K{h zaM6gg)QA+E3nyHlDgdZft7KW$r?@xXX>%H>7ePy{I3CBnBed6yF^ELpk2<)ko3Ayf z4fFOGEMDI example demonstrates how to write multiple " + "document interface applications using Qt.") + + def updateMenus(self): + hasMdiChild = (self.activeMdiChild() is not None) + self.saveAct.setEnabled(hasMdiChild) + self.saveAsAct.setEnabled(hasMdiChild) + self.pasteAct.setEnabled(hasMdiChild) + self.closeAct.setEnabled(hasMdiChild) + self.closeAllAct.setEnabled(hasMdiChild) + self.tileAct.setEnabled(hasMdiChild) + self.cascadeAct.setEnabled(hasMdiChild) + self.nextAct.setEnabled(hasMdiChild) + self.previousAct.setEnabled(hasMdiChild) + self.separatorAct.setVisible(hasMdiChild) + + hasSelection = (self.activeMdiChild() is not None and + self.activeMdiChild().textCursor().hasSelection()) + self.cutAct.setEnabled(hasSelection) + self.copyAct.setEnabled(hasSelection) + + def updateWindowMenu(self): + self.windowMenu.clear() + self.windowMenu.addAction(self.closeAct) + self.windowMenu.addAction(self.closeAllAct) + self.windowMenu.addSeparator() + self.windowMenu.addAction(self.tileAct) + self.windowMenu.addAction(self.cascadeAct) + self.windowMenu.addSeparator() + self.windowMenu.addAction(self.nextAct) + self.windowMenu.addAction(self.previousAct) + self.windowMenu.addAction(self.separatorAct) + + windows = self.mdiArea.subWindowList() + self.separatorAct.setVisible(len(windows) != 0) + + for i, window in enumerate(windows): + child = window.widget() + + text = "%d %s" % (i + 1, child.userFriendlyCurrentFile()) + if i < 9: + text = '&' + text + + action = self.windowMenu.addAction(text) + action.setCheckable(True) + action.setChecked(child is self.activeMdiChild()) + action.triggered.connect(self.windowMapper.map) + self.windowMapper.setMapping(action, window) + + def createMdiChild(self): + child = MdiChild() + self.mdiArea.addSubWindow(child) + + child.copyAvailable.connect(self.cutAct.setEnabled) + child.copyAvailable.connect(self.copyAct.setEnabled) + + return child + + def createActions(self): + + self.newAct = QAction(QIcon.fromTheme("document-new", QIcon(':/images/new.png')), "&New", self, + shortcut=QKeySequence.New, statusTip="Create a new file", + triggered=self.newFile) + + self.openAct = QAction(QIcon.fromTheme("document-open", QIcon(':/images/open.png')), "&Open...", self, + shortcut=QKeySequence.Open, statusTip="Open an existing file", + triggered=self.open) + + self.saveAct = QAction(QIcon.fromTheme("document-save", QIcon(':/images/save.png')), "&Save", self, + shortcut=QKeySequence.Save, + statusTip="Save the document to disk", triggered=self.save) + + self.saveAsAct = QAction("Save &As...", self, + shortcut=QKeySequence.SaveAs, + statusTip="Save the document under a new name", + triggered=self.saveAs) + + self.exitAct = QAction("E&xit", self, shortcut=QKeySequence.Quit, + statusTip="Exit the application", + triggered=QApplication.instance().closeAllWindows) + + self.cutAct = QAction(QIcon.fromTheme("edit-cut", QIcon(':/images/cut.png')), "Cu&t", self, + shortcut=QKeySequence.Cut, + statusTip="Cut the current selection's contents to the clipboard", + triggered=self.cut) + + self.copyAct = QAction(QIcon.fromTheme("edit-copy", QIcon(':/images/copy.png')), "&Copy", self, + shortcut=QKeySequence.Copy, + statusTip="Copy the current selection's contents to the clipboard", + triggered=self.copy) + + self.pasteAct = QAction(QIcon.fromTheme("edit-paste", QIcon(':/images/paste.png')), "&Paste", self, + shortcut=QKeySequence.Paste, + statusTip="Paste the clipboard's contents into the current selection", + triggered=self.paste) + + self.closeAct = QAction("Cl&ose", self, + statusTip="Close the active window", + triggered=self.mdiArea.closeActiveSubWindow) + + self.closeAllAct = QAction("Close &All", self, + statusTip="Close all the windows", + triggered=self.mdiArea.closeAllSubWindows) + + self.tileAct = QAction("&Tile", self, statusTip="Tile the windows", + triggered=self.mdiArea.tileSubWindows) + + self.cascadeAct = QAction("&Cascade", self, + statusTip="Cascade the windows", + triggered=self.mdiArea.cascadeSubWindows) + + self.nextAct = QAction("Ne&xt", self, shortcut=QKeySequence.NextChild, + statusTip="Move the focus to the next window", + triggered=self.mdiArea.activateNextSubWindow) + + self.previousAct = QAction("Pre&vious", self, + shortcut=QKeySequence.PreviousChild, + statusTip="Move the focus to the previous window", + triggered=self.mdiArea.activatePreviousSubWindow) + + self.separatorAct = QAction(self) + self.separatorAct.setSeparator(True) + + self.aboutAct = QAction("&About", self, + statusTip="Show the application's About box", + triggered=self.about) + + self.aboutQtAct = QAction("About &Qt", self, + statusTip="Show the Qt library's About box", + triggered=QApplication.instance().aboutQt) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.newAct) + self.fileMenu.addAction(self.openAct) + self.fileMenu.addAction(self.saveAct) + self.fileMenu.addAction(self.saveAsAct) + self.fileMenu.addSeparator() + action = self.fileMenu.addAction("Switch layout direction") + action.triggered.connect(self.switchLayoutDirection) + self.fileMenu.addAction(self.exitAct) + + self.editMenu = self.menuBar().addMenu("&Edit") + self.editMenu.addAction(self.cutAct) + self.editMenu.addAction(self.copyAct) + self.editMenu.addAction(self.pasteAct) + + self.windowMenu = self.menuBar().addMenu("&Window") + self.updateWindowMenu() + self.windowMenu.aboutToShow.connect(self.updateWindowMenu) + + self.menuBar().addSeparator() + + self.helpMenu = self.menuBar().addMenu("&Help") + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + def createToolBars(self): + self.fileToolBar = self.addToolBar("File") + self.fileToolBar.addAction(self.newAct) + self.fileToolBar.addAction(self.openAct) + self.fileToolBar.addAction(self.saveAct) + + self.editToolBar = self.addToolBar("Edit") + self.editToolBar.addAction(self.cutAct) + self.editToolBar.addAction(self.copyAct) + self.editToolBar.addAction(self.pasteAct) + + def createStatusBar(self): + self.statusBar().showMessage("Ready") + + def readSettings(self): + settings = QSettings('Trolltech', 'MDI Example') + pos = settings.value('pos', QPoint(200, 200)) + size = settings.value('size', QSize(400, 400)) + self.move(pos) + self.resize(size) + + def writeSettings(self): + settings = QSettings('Trolltech', 'MDI Example') + settings.setValue('pos', self.pos()) + settings.setValue('size', self.size()) + + def activeMdiChild(self): + activeSubWindow = self.mdiArea.activeSubWindow() + if activeSubWindow: + return activeSubWindow.widget() + return None + + def findMdiChild(self, fileName): + canonicalFilePath = QFileInfo(fileName).canonicalFilePath() + + for window in self.mdiArea.subWindowList(): + if window.widget().currentFile() == canonicalFilePath: + return window + return None + + def switchLayoutDirection(self): + if self.layoutDirection() == Qt.LeftToRight: + QApplication.setLayoutDirection(Qt.RightToLeft) + else: + QApplication.setLayoutDirection(Qt.LeftToRight) + + def setActiveSubWindow(self, window): + if window: + self.mdiArea.setActiveSubWindow(window) + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/mainwindows/mdi/mdi.pyproject b/examples/widgets/mainwindows/mdi/mdi.pyproject new file mode 100644 index 0000000..7df26fd --- /dev/null +++ b/examples/widgets/mainwindows/mdi/mdi.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["mdi_rc.py", "mdi.py", "mdi.qrc"] +} diff --git a/examples/widgets/mainwindows/mdi/mdi.qrc b/examples/widgets/mainwindows/mdi/mdi.qrc new file mode 100644 index 0000000..0a776fa --- /dev/null +++ b/examples/widgets/mainwindows/mdi/mdi.qrc @@ -0,0 +1,10 @@ + + + images/copy.png + images/cut.png + images/new.png + images/open.png + images/paste.png + images/save.png + + diff --git a/examples/widgets/mainwindows/mdi/mdi_rc.py b/examples/widgets/mainwindows/mdi/mdi_rc.py new file mode 100644 index 0000000..2a392be --- /dev/null +++ b/examples/widgets/mainwindows/mdi/mdi_rc.py @@ -0,0 +1,608 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x04\xa3\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x045IDATX\xc3\xe5\ +\x97\xcd\x8fTE\x14\xc5\x7f\xb7\xea\xd6{\xaf\xdbn\xc7\ +\xf9@\x9d\x89FM4\x99D\x8d\x1aH\x98\xc4\x8c\x1f\ +\x1b\xfe\x02L\x5c\xf1\x07\x18\x16.M\x5ckX\xc3\x8e\ +\xc4\x8d\x1b\x17\xce\x82htA\x5c\x18\x0d\xe2\xc4\xc6\x00\ +=`PQ\x19`\x02\xa2\x0e\x0c\x83\xd3\xfd^\xf7\x94\ +\x8b\xaa\xee\xf9`\xe6\x0d\x84Q\x16VR\xa9\xce{\xb7\ +\xeb\x9e:\xf7\xd4\xa9z\xea\xbd\xe7~6\xe5>\xb7>\ +\x80]\xbbv\xbd\x03\xec\xfd\x8f\xf2N5\x1a\x8d\x03\xeb\ +\x19\xd8\xbb\xef\xbd\xa3;\x1f\x1fv\x00\x9c<:\xcf\xcc\ +\x977X\x9c\xef\xdcS\xa6\xda\xa0\xf2\xdck\x03\xbc\xb8\ +g\x10\x80\x8b\x7f\x16|\xf8\xee\x1e\x80\xdb\x00p\xfc\xec\ +\x1c\xdf?0\x04x.\xfd\xb8\xc0\xfe\xb7\xceo\xcbr\ +\x0f\x1dy\x9a\x0b#\x96\xd3\x9f\x1fd\xfc\xd5}\x9bk\ +@E\xb0\x16@xp,#\xcb\xb2m\x0100\x96\ +a\x8dP\x1b|\x14#%\x22\x14+\xd8\x18\x91\xd5\x95\ +s\xe7\xce\x83*\xb8\x04\xd2\x14\xb2\x0c\xd2,\x8cI\x0a\ +I\x12\xdew:\x90\xe7\x90\xb7\xa1\xd5\x82v+\x8em\ +(r\xb2\xfa8\xd6\x0a\xe3\xaf\xbcIk\xf1\xfa\xe6\x00\ +\xac\x15\xac\x15\x04\xb0F\xd8\xbd{\xe7\x16k\xeb\x86\xae\ +\x80Z\xa8V\x81\xeamQ\x8d\xaf\x04\xb5\x82\xf7\xa0\xa6\ +\x84\x01g\x055\x82\x08\xa8\x0a\x95,\xc3# \x1e\x08\ +\xc0\xf0\x1e/\x02\xde#\x12&\x15|\x88#\xc4!\x1e\ +\xd0\xaf\x16\xaa\x1b\x8b\xf6\xd8'a\ +a\xbd\x1c%% \x00\xf0\x81\x8d4M\xa3:\xc3\xb3\ +\x98\x11\x89l\x07\xdac\x09V\x98_)F\xfca\xcd\ +r\x7fa\x1d-\xd1\x80:\x09TI\x18O4/\xe0\ +\x9d\x85\xc4!\x89\xc3g\x09\x92i\xd8\x11\x89\xe2\x13\x87\ +X\x8b\xefv\x91\xbc\x80\xbc\x03\xed\x02\xdfj#\xed\x02\ +\xf2\x02\x9fwP\x1dE\xd5 x:\xebTx\x9b\x06\ +\x9c3x\x0f\x03\x8f$\xbc\xfe\xf2\xf3wh\xe86h\ +\xa4\xbe\xf1\xeb\xc6\xfc\xdf\xb1\x04R^\x82DM_\x84\ +\x8f\x0d\xa58\xe7\xb6\xc5\x88\x9e\x18K\xb9v\xb3\x03\x08\ +\x9dR\x11\xaa\x90\xb8P\xefZ\xc50}\xb1\xcb@\xc5\ +\xb0\x0e\xf4&\xadW\xf9U.\xe1\xe1\xc6\xd22\xf5\xcc\ +p}\xc9\x84-\xe9J\x19\x10\x9c\x1a\xc0s\xe5f\x97\ ++7\xbb\xacQW?\xd7\xaad~\xc5'\xa2)\xac\ +\x05\x15\xc3\x9c\x0b\xb5w\xa6l\x17\xa8\xc1\xa9 \xc8\x1a\ +5\xaf\x9b5\x1a\x8fY1\x9e\xfe{\xe9\xef\x14\x00\xf1\ +\x82\xef\x9bX0+WV\x02U!\xd1\x90\xfc\xe7S\ +\xdf\xf2\xeb\x99\x13,-\xde\xb8\xa7\xfaWj\x03<\xf5\ +\xecN\x9eya\x02\x0f\xa83[1\x10\x03|\x87\xf7\ +\xf7\xbf\xc1\xc2\xc2\x02\xb7n\xdd\xa2(\x0aD\x04k-\ +\xd6ZT\x15U\xc59\x87\xaab\xad\xc5\x98\xf0\xdf\xe5\ +\xe5e\xf2<\xef\xf7#\xcd\xf9\xb8\xf2-\x18pVP\ +\x17\x18\xdc1:\xb6rO8~\x9c\xe9\xe9i\x8c1\ +x\xef\x99\x98\x98`rr\xf2\x8eY\xd81:\xd6\xdf\ +\x86\xae\xd4\x09Up6\xac\xa2V\xaf\xf7k933\ +\xc3\xd0\xd0\x10\xd6Z\xbc\xf74\x9b\xcd\xbb\x02P\xab\xd7\ +p\xd1\x88\xb4\xd4\x88\x14\x9c\x0b'\x5c\xa0*\x00\xa8V\ +\xabdY\xd6\xa7\xb87\xdeis\x1a\xa9\x17AK\xad\ +8\x1e\xc7\xbd#\xb4\xd7\x8c1\x88D\xdf\x8f:\xb8\xab\ +\x9b\xaf5\xa8\x0d\xf3\xf6\x18.=\x8e\x83)m\xe3\xd5\ +\xdb\x12\xa9\xf7\xe5Vl\xad\xf4\x91\x0e\x8e\x0c\xc3\xf2\xef\ +\xdb\x02\xe0\xa1\x91a\xd4\xc2\xb5+\x97Y\x9c\xbf\xbe\x05\ +\x036\xf8\xc0`\xad\x02\x0b\xdb\xc3\xc0P\xad\xc2\xec\xc5\ +K\x9c\xfd\xee\x1b\xce\x9f\x9c\x9e\x03\xa66\x04`$^\ +J\x05\x12\x0b\xed\x91'\xa9=\x0co\x1f8\xc8f\xc7\ +\x81':\xf1*\xe75\x1e2\x81\x14(\xbap\xf9\xea\ +U\xce4\x8e\xd1\xfc\xfa\x8b\xb9\xd9\x1fN\x1d\x02\x0eo\ +\x08\xe0\xb3\x8f>\xe0\xa7\xd3'W\x99\xe9\xda\xa3\x86U\ +\xe6\xbb\x1e\x04\x1b<_\x1do|w\xee\x8f\xd9_\x0e\ +\x01\x87\x1b\x8d\xc6_\x1b\x01\x98\x9a\xfe\xf4\xe3\x7f\xf5s\ +l}\xf25\x00\xe2\xb7\xda\x81\xff\xdd\xd7\xf1?M\xf0\ +K\xb9\xe8F\x89\xaf\x00\x00\x00\x00IEND\xaeB\ +`\x82\ +\x00\x00\x08\x19\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x07\xabIDATX\xc3\xad\ +W[P\x93g\x1a\xf6\xca\xce\xec\xcc\xf6b/\xbc\xd9\ +\xe9\xce\xecn\xbd\xda\xd9\x9b\xb5\xce\xba;{\xb0\xad\xcc\ +z\xb1\xce\xce:\xb3vTpu\xdb\xe2\x81\xd6\xb6T\ +\x04\xbb\xa5 m\xc1\x82\x06\x08\x07QB\x80\x80\x80\x02\ +!\x81\x10\x92@H\x10s$!gr\x80\x04B \ +\x9c\x09G\xb5Tx\xf6\xfb~\x13\x160X\x8b}g\ +\x9e\xf9/\x92\xfc\xcf\xfb>\xcf\xfb\xbe\xdf\x97]\x00v\ +\xfd\x98 \xf1\x0b\x82\x14\x02\x03\xc1u\x82\x03\xcf\xfd\xfe\ +\x8fH\xbc\x9b \xe1W\xaf\xef\xb5*\x8c\xd6e\xdb\x02\ +`\x19\x1e[\x09'\xf13\xfa\x19\x81\x22\xfc\xdc>v\ +H~\x8a\xa0\xb9\xb6Y\x1c2\xcf\xadB9\xfe\x1dD\ +\xf6Q\xd8\xc7\xe6\xe8\x87\x86={\xf6XSR\xae,\ +\xca::\x10N\xe2\xe5I\xc3\xc41\x04\xb7>I\xf9\ +,`\x9b]YSM\x03M\xb6\x114\xeb\xfb 1\ +y`\x19\x9d\xc5\xbb\xef\xbe?\xc5\xab\xbe\x83\xf1\x89)\ +LO\xcf\xae\x92\xef\xd7\xbct\x02\x11\x9f\x0f\xbe\x1d\xe3\ +\xb2\x04CO\xb43@\x8b{\x06\xcd=.4\xeb\xec\ +\xa8W\xf6 \x87S\x852^5C\xbc\xb0\xf4\x90\x81\ +\xc1`\x5c&\xbfK|\xe1\x04H\x1c$8A\xfd\xdd\ +\xeas'\xf1\xb9'\x04H\x87\x97\xc1\xd7\xbb \x22U\ +7\xdc7\xa2\xb8N\x88,V>\xccV\xdb:q\x04\ +,\x16k,\xfc\xce\xe7'\x10\x916\x93\x95?F}\ +\xa5\xfe\x12\xc4o\xf4Y1\xb6\x02~\xef Z{\x9c\ +\xe0?0\xa1L(CF\x0e\x1b\xb2\x0e\xf9&\xd2\xf9\ +\xc5e\xcc-,!4\xbf\x88\xbd{\xf7Z\xc9;~\ +\xbam\x02$~C\x90F=5\x13iu\xb3\x80\xd2\ +?\x0f\xcb\xc4\xe2\x9aP\xa1Z\xb4l\xf1Y\xa0\xb6\xa0\ +\xa6]\x8d/\xb2sq\xb7\x9e\xff\x0c1%\x9d\x09\xcd\ +cbj\x06\x83C\x81'\xe4\xdd\xbc-\xd3\xb0;\x92\ +\x033&\xd4S\xb5\xd3\xfbXO\x88\xc5\x03!\x88,\ +CP\xbaF\xd0\xed\x09B\xe5\x9bB\x9bs\xfc\xa9\xcf\ +Z\x1b\xee*t\xc8\xbc\xc9E\x09\xa7l\x93\xcf\x9b\x88\ +'\xa7\x11\x18\x1d\xc3\x80o\x08\xa2\xd6\xd6%\xc2Q\xdb\ +(\x12\x87\xc6\x1f\xaf\x82/b\x94M\x89$\x90\x22\xea\ +R-\x9aB\xab\xe8\x18y\x04\xa1\xc5\xcf\x10St\xf6\ +\x0d\xa3\xd3\xe1\x87\xd4<\x80\x16\xbd\x03\x0d]\x06\x14\xd5\ +\x0a\x90\x91\x95\x0d/y\xf1\xc6\xaa\xa9\xd4\xb3s\x0bL\ +\xc5\x94\xd8\xdd\xef\x85\xc9b\x05\xb7\xbc\x12\xa5\xe5\x95K\ +\x13\xf3\xcb\xab#\x0f\x017\xd9\x11\xe6\xd9\x15\x84\x97\x15\ +\x13\x06\xcb<\xd0h\xf2\xa3\xdd\xee_'\x96;\x86 \ +\xb3x\xd7}\xe6\x08\xa4\xf8<3\x1b*\x8d6\xaa\xdc\ +S3!\x8c\x8e\x8d3\x15\xd3&\xe47\x09\xf1\xc1\xc5\ +\x8fQs\xaf\x01\xbee`\xfc\x11\xa0#\x13#\xf2\xce\ +\xa1\xbe]\xb9\xb8Q\x01\x83\x81ttM\xa7\x1e\x0ag\ +\x80\xa9\xb8\xdd\xea\x83\xd8\xe8B\x93\xca\xcc\xf8|\xe5\xcb\ +,\x88\xda$Q\x89\xa7g\xe7\x18\x1b\x86\x86G`w\ +8I\x82:$|\xf8!\xae\xb3\x0b\xe1\x99\x5c\x80o\ +\x09\xd0\x90\xde\xe1\x0f,\x81\xab\x1f\xc4}\xef\x04\xdd\x07\ +\x1da\xeb\xff\x9f\xc0\x1d\xb9\x16\x1d\xf6!H\xcc\xfdO\ +}\xee\xd4\x22\x9dU\x84\xaa\x9a\xbaM>G\xe4\x8e\xf8\ +<<\x12\x84\xd3\xdd\x0f\xbd\xc1\x88\xc2\xe2b\x9c~/\ +\x1e=\x03\x01\xf4/\x02\x83\x84\xbc\xc5\xff-\xee:C\ +(Q\x91\xf7\xf6\x05\xf1N\xdc\xbf}\x843i\xe3 \ +\x18\xf43\xab\xe0\xc9Th58\xd1\xd8\xdd\x0b\x9eX\ +\x89\xac\x5c\xf63>G\xaa\x9e\x9c\x9ee\xe4\xee\xf7\x0e\ +\xa2\xd7lAC\x03\x1f'b\xe3 \xe9\xd6\xc0E\xcf\ +\x01R\x90$\xb8\x86\xb2\x9e\x00n\xb4\xdbP\xd1\x1bD\ +\x85\xce\x8bJ~\x0bm\xbe\x9b['\xd1\xa0\x99\xf8\x16\ +e\x22\x05\xee)\xf4(\x13\xc8\x90x5\x0b\x1a\xad>\ +\xaa\xdcc\x13\x93\xf0\x0d\x0d\xc3f\xef\x83\xb4]\x8e\xc4\ +K\x97\x90\xc3\xca\xc3\xd4c\xc0NzI1N\xfa\x89\ +\x94\x7f[;\x84|\x85\x13%j\x1fJ\xd5\x03\xe8\xf2\ +0\xa3(\x22\xf8\xf93\x09t\x8f.\xa1\xa8\xbe\x15\xa5\ +|\x09\xb2J*\xf0\xcf\xe3qQ\xe5\xf6\x07F\xd1\xe7\ +\xf2@\xab7 \xfdj\x06\x92\xbfH\x83\xcd7\x02'\ +\xa9\xda@\x1aL\xe0{\x88R\x9d\x1fE\xdd\xfd\x0cq\ +A\x97\x1b\xc5\xdd\x1e\x88\x9cA\xfc\xf9\xcd\xb7]\x84\xeb\ +l\xb4C\xd0(\xf7N#\xa7\xfc\x1e\xb2K\xab\xf1Q\ +\xeaWH\xfeo\xea\xfaXQ\xb9G\x82\xe3\xf0\x0c\xf8\ +`4\x99Q\xc9\xab\xc2\xfbg\xcfA\xfe@\x03?\xe9\ +n\xb2\x8d\x19\xb9oi\x06\x19\xd2\x9b*/r\xe5\x0e\ +\xe4u\xf6\xa1\xf0\xbe\x1b\x1c\x95\x1b\xf9\x9c\xca)\xc2S\ +\xb8\xdd)\xdc+v\x04\x90Q\xc8\xc5\x95ky8\x11\ +\x9f\x80\x9b\xb7n3c\x15\x91\xdbjs@\x22m\xc7\ +\x85\x84\x0fPt\xbb\x0c\xf3+\x80\x9f4X\xf7$ \ +\x1c|\x84J\xd3\x188\xfaa\x86\x9cV\xfdU\xb3\x1e\ +\xac\x0e;\xb8:\x1f\xd9!\x1ez/\xe0\x13\xbc\xba]\ +\x02&\xbe\xc1\x83\x94o\xd88\x9f\x9c\x8a\x03\x7f=\x04\ +c\xaf\x99\xe9n*\xb7F\xd7\x83\xa4\xcb\xc9H\xff:\ +\x8b\x8c\xd5\xc7\xd1\xd83\xf881\x09\x86^\x13\x1a\x9b\ +\x04\xf8\xdd\x1b\xfbQO\xd4\xf1\x90\x99\xee\x9a\x00\xaa\xad\ +\x93`+]\x0c9\xf5\xbc\xf0\xbeg\xbd\xea\xcc\x16=\ +JU\x1e\x08m\x01\x94\xd4\xf1C\xe1eS@\xf0\xca\ +\xf7%`+nj\xc7\xa9\x84D\xc4\x1c9\x8a\xdc|\ +6ZZ\xc58\x14\x13\x83/95\xc8\x14j\x98\xe6\ +\xa2\xd5\xd2'\xf5\x9azL\x13\xa1Id\xb7\x99\x90\xdb\ +nF\xb9\xda\x8d\x06\xa5v9,9=\xf9N\x13\xec\ +\xd9r\xd4G\x0d;\xabF\x88c\xff9\x8f\xdf\xee\xfb\ +=\x1a\xf9\x02\x9c\xbf\x90\x80\x93\xf1\x17p\xa3\xad\x07\x19\ +\xc4OJ\x14\xe9n\xbaX\xa8\xef,\xfa\x94\x98P(\ +\xb7@\xe9\x0e<\xf9W\xec)*w-\xc1g\x04\xfb\ +\xb6\xb9\xe4D\x8d\xbe\xcc\xb2Z\xfc\xe3\xe4\x19\x1c<\xf4\ +7\xb0r\xf3\xb0\xef\xc0\x1fP \xd1!\x89'e*\ +\xa6K\x85>\xbf!\xd5F\xe4.\x90[!\xb0\x0c\xae\ +\xe5\xdc\xe2\xd2\x11\x13\x13\xe4\x87o<\xaf<\xe7\x96\x15\ +5\x9ciE\xe5\xf8\xfb\xb1X\x1c?\x19\x877\xf6\xef\ +\xc7\x8d:\x11\x92\xab\xa4\x0c!\xedp\xea5U!\x8b\ +4[\xc9\x037*4n\xd4I:\x17\xc3rs\x08\ +\x8em\x95\xfb\x87$\xe0Jesp\xe4\xf8)\x1c>\ +|\x98\x8cc.2\x05*\x5c\x22\xd5\xd3]~M\xdc\ +\x0b6\xe9tv\xa7\x1dw\x8c\xe4\x88\xb6\xf9\x9e\x84\xb7\ +\x1a\x95\xfb\x22\xbdI\xfd\x80\x0bm\xf4\x042JxL\ +\x0f\x9cKI\xc3\xb5\xa6.|\xc2me6Y\xf1\x83\ +\x01\x5c\x97\x9a\xc1Q{ \xf3\x04\xd7\xce%&\x056\ +\xc8\xfd\xc7\x9d\xc8\x1d\xd5\x82\xdc\x1a\x01\xce^NE\x81\ +X\x85x\xf6]\x5c\xa9U\x90\xaa\xfb\xc0\x96\xdbP\xad\ +u\xe3\xaeTA/\x10\xca\x0dr\xbf\xba\xd3j\xa3\x05\ +\xb7\xa2Q\xf8\x1d\xafC\x8dO\xb9-\x88\xcb\xe6\xe1\x9a\ +H\x8f\xaa\x1e/\x9a5\xe6\xc7\x7fz\xf3-Wx\xac\ +\xa8\xdc\xaf\xbd\xac\xdc\xd1\xe2\x08\xdd\x05\x5cu\x1f\xde\xcb\ +\xafE\xb9v\x002g`\xf5\xc2\xa7\x97\xa9\xdc\xf7\x08\ +\xd2\xa9\xdc;\xf8\x03\xf3\xc2\xf1\x13\x82\xca\x1c\xee\x9dP\ +\x0b9\x94\xb8\x0d\xc2\xc8\x16\xa3\x17\x87\xc3/\x22\xf7\x0e\ +\xff\xdam\x8a\xdda\x99\xd5\x1b\xb6\xd8k\xbb^2\xbe\ +/\x89\xff\x01f\xb9_\xfc\x11\x80=\xcf\x00\x00\x00\x00\ +IEND\xaeB`\x82\ +\x00\x00\x05+\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x04\xbdIDATX\xc3\xed\ +WkL\x93W\x18>#q\xc92\xe9\x16\x97\xa8T\ +e8\x9d\x02\x15\xf6\x03\x872\x93\x01f,[p\xc4\ +0\xff`\xa2.\x1a:\x1dN\x03\xba1\x89[\xb3\x80\ +\xd9\x0c\x84\x02\x19X\x1c\x14\x8b\x85\xb2\x82\x95^\xe4f\ +\x0b\x8e1\xf8\xc3F\xcb-\x81\x15\xdc\xa8\xc2\x1c\x1b\xb7\ +ji\x91\xf2\xee\xbc\x87\xaf\x0c\xdc\xb8\x0da\xd9\xb2\x93\ +<\xed\x97\xf3}\xfd\xde\xe7\xbc\xef\xf3^J\x00\x80\xfc\ +\x93 \xff\x0a\x02t\x09(D\x14\xd9\x14q\x14\x01+\ +F\x80\xae\xddd\xdd\xc6f\x22L\xf8\x95\xc4\x8bG\xc8\ +\xa1\xd3\xf7\xc8\x8e\x97;82a+A \x85\x9c\xbe\ +0H.\xdd\x80\x19@2\xabyM\xf4\xbe\xfbr\x13\ +hd\x06\x91\x04^\xa3Q\xf4\x06\xee\x85G\xf5\xd0\xbd\ +\x83\xcbM \x9b\x9d\xf6@t/\xbd\x162= \x89\ +?H\xa5,\x1b\x01\x8c1y\xc1\xbb\x9d\x88K\xc6\xd7\ +\xc6&\x0e\xa0\x10\xb9\xfdB\xfe\xc5+6F\x8c\x12\x5c\ +N\x02\x93\xa7\xa7\xa7\x0d\xcc\xd39\xb9\x98c6\x14\x0a\ +\xd2\xe4\xa3+A \x8c)\x9e*\xdf7G\xeb\xdc{\ +\xb5\xcc\x89\x9e@D\x96T\x83+,\x0b6FH\x08\ +\x13\xf5d*{.T\x03\x01\xf8\x037\xbf\xc0\x0e4\ +*T\xdfb\x88R\xd5,X\x03t\x1d\x16\x08\x04z\ +EU\xf5\xc8\xa0mt\xc2\xd4s\xf7!\xbesQ\x95\ +\x90\xae\x8f\xd0\x13\xcf\xe5\x94\x83\x87\xb4\x02\x9e\xcc.\x03\ +\xd4\x06\xdd\xaf\x99\xcb\xb0\xaf\xaf\xaf>\xbf\xd2`\xb5\xdb\ +\xed\x80\xf8y\xe4>\xc4^\xab\xb4\xb9\x88/\x86\x80'\ +\xd3\xc0g\xf9\x8e\x19\xf5`\xd7^3\xbav\xdas\xee\ +h\xd8\xc7\xc7G\x9f\xab\xab\xb0\x0e\x0f\x0d\xc1\x10\x87\xb2\ +\xf6.\xe7\x967\xf7wsa\xd8\xbd\xe8^\x80/f\ +\x9a\xa0\x86\xdf\xa96B\xf7\xf0\x03\xd8\x19\x9f\xd4\xcf\xa5\ +\xe7\x1a\x8a\x98-~\xfem\x97T\x1ak__\x1f\xb8\ +\xd0\xd1s\x07br\x15VN\xc4\x87\x97\xd4\x8c0\x14\ +\xe9\x15\xb7\x1e8\x1c\x0e@\xa4\xd6\x191\x9e\x85\x9b\x05\ +~m\xa9%\x1a[\x97\xd9\x0c\xe6.\x0a\xf3$\x14\xdf\ +6\x8e{\xbd\x1e\xd1\xcdB\xc8\x09o\xa9\x04<\xd1\xbd\ +V\xab\x15\x10w\x7f\x1b\x84\xf3\x92\x5c\xbbR\xa9\x84\xfa\ +\xfaz0\x99L\x0cu\xdf5\xc1Q\xb1d\x18\xc9Q\ +D>\xb6v\xcc\xb4@O\x93_~\xd3\xd6\xdf\xdf\x0f\ +2\x99\x0cD\x22\x11\xa8T*\x90J\xa5\xa0\xd1h \ +K[9\xbe\xe9\x95\xe0\x1f\xb8S\xafy,\xf3\x00\x97\ +\x8e\x22\x9e\xc7\x86\xe6S)\x19\xf6\x82\x82\x02\xe6\xe2\xa0\ +\xa0 \xe0\xf1x`\xb1X@[^\x01\xfb\xcf&\x0c\ +-\xa6S\xceg\x94\xcf\x09L\x83\xe2[{\xe6\xc2`\ +\x9a\xb2\x14\x14\x0a\x05\x88\xc5b\xc8\xcc\xcc\x84\xa2\xa2\x22\ +P\xab\xd5\xd0\xd9\xd9\xc9`\xec\xfe\xc9\xb9\xc9\xdb\xa7u\ +.\xb7\xcfK\x80\xae\xb7\xd8)p\x0e\xc0j\x97\xacx\ +\x88\xca\x7f\x82\xe2)\x89\x0e>\x97+![\x96\x0f\x07\ +c\xe3G\x84\x1f&\xd8\x92rd\x8eo\x1a\xbf\x07\xa3\ +\xd1\x08-\xad-\xf0\xcb\xc0 \x1c8\xf1\xbe\x05\xb3b\ +\xc1\x04\x5ci\x84\x85\x85\x84F\xdc&\xe72\xac,\xcf\ +3\xb5\x13\xec;\xe3\xba\xd33\xaf\x82\xe5\xfez\x89\x06\ +\x9e\xde\xfcb\x1b\xf7<\x92\x8d{f\xabO[\xca5\ +\xedXCC=444\x80\xa5\xb7\x172\x14\xc5\xc3\ +\xf3\xe9\xc0e<\x92\xe5(\x9e6]\xe5\x9c*2x\ +}\xf4\x83.Zl\x121\x0c\x1b%\xeaq\xf7/\xcb\ +'\xef\x05\x87_\xfe\xd3\xe4D\x0bLh\xf4\xc9>u\ +\x95\x1e\x0c\x06\x03\xb4\xb7\xb7\xc3\xd7\xc6\x961\xae\x81\x09\ +f\xf16m8h\xed\xf7\x08\x1e*>\ +]\xe5X\xaa\xf1GZ\xf5\xb6Y\x0b\x11\x1d\xb3C\xc9\ +\x918\x099\xf9\xa9\x96!\xfa\x5c\x1a\x0d\xcf\xb3\xff\xff\ +7\xfcO\x13\xf8\x1d\xe7\x87\x19\xb9D\xc3\x01\xcf\x00\x00\ +\x00\x00IEND\xaeB`\x82\ +\x00\x00\x05:\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x04\xccIDATX\xc3\xb5\ +\x97]L[e\x1c\xc6wo\xbc\xd9\xe5\x12I q\ +\xd7&\xe3N\x13\xb8p\xd1\x85D\xbdP\xe3\x10\x18\xe5\ ++.&J\x04'\x86\xaa\x8b\x99\xe0\xd0\xa2l\x19\x86\ +9\x17\xdc\x1a\x16\x98\x80@l\xa6C\xca +\x83\x1e\ +(\xcc\xda\xd1\x96\xd2\xd2J{\xfa\x01\xa5\xd0\xef\x16\x1e\ +\xdf\xff\xdb\x1d\xc7\xcc\x04*\x87\x93<9o!\x9c\xe7\ +\xf7<\xefG\x0f\x87\x00\x1c\xcaF\xcf\xbd\xfa\xe9\xbbL\ +Z&a\x0fj`\xca\xd9\xe9y\xd9\x9a?]P\xf2\ +\xa5\xc1\xe9\x8f\xa7W\xc3@0\x02\x84\xa2\x19\xad\xc72\ +\x8a'\x81X\x22s\xbfyk\xdaK\x10r\x02\x1c{\ +\xe7\xac\xda\x1c\xd8\xc8\x98\x12@\x84\x99\x85\xe3\x19\x911\ +)\x1aKa%\x94D8\x9aBs\x87\xc6\xbe\x13\xc4\ +\xff\x02\x90\x12\x93y$\xf1\xc8X\x92\xcf\x1f\x84]\x8c\ +\xc2\xe5\x09\x22\x12K\xa3\xf4\xc3\xefM4uY\x01\xb0\ +\xeb\xd86\xd5\x90\x9e:\xfc\xcc\xb9\xe7_.\x11?V\ +\x9eEEU\x0d*\x99\xde\xaf\xad\xc3\x9d\xb1\x89\xc7\x00\ +\xac\xb6%\xfc\xb9\xe8\x87k\x15X\xf6\x04\x10\x08\xc6\xd2\ +\xaf\x9c\xbep\x9fA\x1c\xd9\x15\x80]\x87\x99\x1a\x8a\x8a\ +\x8a\xcc\x92Z[[\xdd\xa4\xafU\xad\xfe\xafT\xdf\xa6\ +\x06\x06\x06195\x85\xd9\xb99\xe8&&PPP\ +\x80!\xcdo|\xdeI\xa6\xf9\x05\xcc\x98\x5c\x1c\xc0\xe1\ +OA\xf4\x85\xf0C\xaf\xce\xcd\x00j\xf6\x02PCf\ +\xd8\xe5\x8a\xc7\xe3\xf0z\xbdH\xa7\xd3\x98\x9c\x9cDe\ +e5fg\x8d\xbc\x81\x07f\x1bt\xd3\x16\x0e@2\ +-x\xf0\xdd\x8dQ\x8f\xac\x00\xe1p\x18F\xa3\x91\x8f\ +S\xa9\x14~\xea\xedE\xe3'\x9fa\x86A8\x96\xdc\ +Pwu\xe3LC#\xce5\x9d\xc7\xed\x91q\x5c\xbc\ +>,/\xc0\xc6\xc6\x06\xf4z\xfdc@}}\xfdP\ +2\x88\xd0F\x1cf\x9b\x0b\x82\xc1\x88\xa9\x19\x13\xac\x0e\ +\x11\x97\xbadn\x80\x00\xa6\xd8:\xd8~E\x22\x11\x94\ ++*0\xae\x13@\xe7\x04mW\xda\xaa4\xbe|S\ +\xe65@f:\x9d\x0e\xc3\xc3\xc3\xe8e\xf5\xf7\xf7\xf7\ +C\xab\xd5\xa2\xaa\xba\x06cw\xf5\x90\x0e*w\x90\xed\ +\x04\xb6\x0e\xda\xbbe\x06\xa0y\xb7\xdb\xed\x18\x1a\x1aB\ +gg'zzz8PIi\x19ni\xf5\x10\xd7\ +\x00o\x08\xb0\xf9\x00g\x00\xb8\xd0%3\xc0\xd6\xd6\x16\ +\xdf\x09\x81@\x00\xa2(\xc2\xef\xf7cmm\x0d\xa7\x14\ +\x95\xd0\xfc\xae\xe7\xa9\xc9|\xc1\x0b\x98=@\x9b\xdc\x00\ +\xdbA677\xf9v\xa4V\x14\x15\xd5\xe8\xfbU\xe0\ +\xa9\x1d\x81G\x00\xe7;\x0f\x00\x80\xcc%\x80$3O\ +$\x12(+\xaf\xe2\x00\x7f\xb8\x00\x8b\x98\x01\xa06Z\ +\xd5\x070\x05\xff\x98'\x93<=MI\xc9\xa9J\x0e\ +\xa0\xb7\xb3\x03\x89=\xc5\xf8\x170\xb1\x00|q\xf5\x00\ +\x00\xa4\xea\xc9\x98\x14\x8b\xc5P\xa6\xa8\x82zH\xc0\x98\ +\x19\xb8k\x05\xe6\x9c\x99\xfb\xe7Wd\x04\x90\xd2Sj\ +\x02\x88F\xa3\xdc<\x14\x0a\xa1\xb8\xb4\x02\xd7\x06\x05\xdc\ +f\x87\xe4\xa0\x01\x1cd\xc4\x04(;d\x06H=\x9c\ +s\x12\x99\xd3\xb9@ \xc5eU\xb8\xd8-\xa0\x7f:\ +c\xae}\x90i\xe0\xa3v\x99\x00\xfe]=\xa5&\xad\ +\xae\xaer\x88\xb7J*p\xb9W\xc0=\x1b\xb8~\x9e\ +\x01\xee\xcc\x03g.\xed\x13@\xaa\x9dD\x8b\x8e\x92\xd3\ +qL\xdf\x01+++X__\xe7\x10'Y\x03\xdf\ +t\x09PO\x00\xbf\xcce\x1a\xb82\x064\xec\xa7\x01\ +\xc9X\xda\xebdNi)9\x1dD\x04@\xf5\xd3\xcf\ +\xde|[\x81\x96\xeb\x02O~u\x1c\xb8q\x0f\xf8q\ +,\x9e~\xbdNm\xa67\xaa\xac\x00\x9ed,m7\ +2%\x00\xd1#\xf2\xe4\x12\xcc\x1b'\x15h\xef\x11\xa0\ +\xbcf[\x7fO5\xe2\xc9xG\x00\x95\ +J\xc5\x01\xa4\x15.\xcd7\x19RR:\xf7)\xb5\xc3\ +\xe1\xe0\x22\xe3\xc5\xc5E\x0e\xf5\xe2\xf1\x97\x5c\xf4\x1e\xb9\ +\x93\xe9\xae\x00---n\xe9`\xa1\xd4\xd2\x97\x0d\x8d\ +\x97\x97\x97\xe1\xf3\xf9`\xb3\xd9\xf8}ii\x89C\x10\ +\x00\x8d\x0b\x0b\x0b\xcd\xb2\x00\xd0\xa2\x92R\x93\x11\x8d\xe9\ +N\xdfxT;5`\xb5Zy\xf5\xd4\x0a\xfd\xce`\ +0$\xf2\xf2\xf2\xee\xb3g\x1c\xd9\x17@SS\x93[\ +\x9agJO\x22\x13\xaa\x9a\xc6\x16\x8b\x997@\x9fG\ +GG#mmm\xde\xfc\xfc|\x13\xfb\xdbA\xa6\xb2\ +\xbd\x9a\xff'@ss3\x9f\x02JG\x10T?U\ +???\xcf\xeb\xd6h4\x91\xba\xba:\xe7\xc3\xb4]\ +L\x1f0\x1d\xcd\xc6xG\x00\xa5R\xe9v:\x9d\xbc\ +bJJo>\x94\xb4\xbe\xbe\xde\x99\x93\x93#\x99\x16\ +gSuV\x00\x8d\x8d\x8dn\x8b\xc5\x82\x81\x81\x81H\ +mm\xad377WV\xd3\xdd\x00\xf8\x7fFL\xc2\ +A\x99n\xd7\xdfC9V\x18\x85p\xc8\x04\x00\x00\x00\ +\x00IEND\xaeB`\x82\ +\x00\x00\x03T\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x00\x04gAMA\x00\x00\xd6\xd8\xd4OX2\ +\x00\x00\x00\x19tEXtSoftware\ +\x00Adobe ImageRead\ +yq\xc9e<\x00\x00\x02\xe6IDATX\xc3\xd5\ +\x97\xcdN\x13a\x14\x86\xeb5\x94\x95{q\xe1\xd2\xc4\ +\xe0\x05\xb8\xe2\x0e\x5c\xb8\xf4\x02\x5c\xb10\xea\x05\x18\x96\ +&bX\xb8\xb0\x91X \xd1\x9d\xbf\x89\xa4\x14\xb1R\ +\xa4HE\x94\xfe\xd0\x02C\xff\xa6\x9d\x19\xa6e\x80\xe3\ +y{\xfa\x85QJ\x82\xc9!\x86I\xde\x9c3\xa7\xf3\ +\xcd\xfb\x9c\xf3M\x9bN\x84\x88\x22\xffS\x91s\x01\xc0\ +\xc7\xd5\x90n\xff\xa5\xfb\xac\xc7==d\x0d\xa9\x02\xf0\ +12<<\xbcj4::\xba\x19V<\x1e\xaf&\ +\x93\xc9V:\x9dv\x13\x89Dk`` \xcdkn\ +h\x02\xa48\xd2\xe1\xe1q\x99\xba\xef\xb7\xc9\xb2,\xda\ +\xdf\xdf'\x86\xf1x\xcd\x18\xeb\x8a\x1a@?\xf3\xb0\x1c\ +\xc7\xa5Lf\xb9\x0b\x14\x04\x01\xc5b\xb1:\xaf{p\ +\x1a\x88S\x01\x1c\x1c\x10ww\xb2l\xdb\xa1\xf9\xf9\xcf\ +d\x0e\xd7u\xe9\xf9\xc4D\x17B\x05\x00&{\xc1\xc9\ +\xaa7\x1cJ\xce\xcdS\xf8p]\x0f\x8b\x17T\x00\x82\ +\x10@gO\x14\xce\xed\xa6G\x1fgf\xe9\xf5\x9b\xb7\ +\x14\x9f\x9c\xa4\xa9\xa9iz\xf7\xfe\x03E\xa3\xd1e^\ +\x7fA\x05\xc0\xef\x10\xed\xb6%\x86\x85\x9a\xe3\x05\x94]\ +\xcd\xd1\xe4\xf4+z2\xfe\x94\x9e\xc5^\xd0Lb\x0e\ +\x8b\x17U\x00\xda\x81\x18\xf5\x13 <\xff\x90j\xcd6\ +\x157\xab\x94/nS\x89c\x8d\xb7\x85\xd7~Q\x01\ +\xf0y\xcc\xcd]\x1e\xb5\xc7{\xdb\xee\x9f;\xbe\xe4\x88\ +]\xb8\xbd\xee\xe2\x94\xca3\xe0u\xe4\xc6uWb\xd8\ +\x109\xea\xe63D\xd4\x01\xa7\x06\xe0\xf4:\xad9\x22\ +\x98\x98hr\x80\x98kPS\x9d\x00\x00*-\xb91\ +\xe2NS\x8c\x10\x0d\x04\xf2m\xfb(\xb6|E\x00\x9b\ +;\xdbj\xfci\x8e\xfb\ +\xc5S(\xf0C\xb8fI\xf7k\xf9R\x87\xd7\xbeT\ +\x01\xc8U\x8f\xbaN\xadK\x0e\x90\xaf\x85\xde\xb7\xc2\x92\ +=O\xa6\xb3\xde\xa3\xb1q\xeb\xda\xd0\xf5\x15\x98\xb3n\ +\xa9\x00l4\xa4k\x18\xff\xe0\x11\x7fZ\x17S\xd4\x13\ +\x0bYo\xe4\xee\xbd\xe2\xa5\xc1\xcbK|m\x8cu\x87\ +5\xa8\xfa\xb7\x1c\xdde\xd9<\x8f\x1f\x19\xfe\x9e\xcf\x1e\ +7\xbd\xc9\xbax&oF\x00h\xf2\xff\x81\x99\x94\x9e\ +\xe9?\xbf\x19\x01B\xd3\xf4\xfc\xbd\x9c\x9e\xa5~\x03Q\ +l%\xa1\x92\x95\x0aw\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00\x06m\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00 \x08\x06\x00\x00\x00szz\xf4\ +\x00\x00\x064IDATx^\xad\x97[lT\xc7\ +\x1d\xc6\x7fs\xce\xd9\x8b\xbd\xf6\xfa\x16\xa0\xbe\x00\x0e\xb2\ +ic$BJ!\x22\xa1-\x95b\xa5/\xeeKh\ ++\x95\xa6U\xa5\xc6`U\xaa\xda\xb4\xaa\xfaV\x09U\ +\xca\x03\x94'\xda\x07\x84\x14)\xad\xc4\x8b\xa5R\x83y\ +\x08\xc5\x189\x0ei\xd3\x84\x9a\x9bcj\xec\xb2\x04\x1b\ +;\xbb\xf6z\x8f\xbd\xbb\xde\xb3g\xa6\xc3h\x85\xe5r\ +l\x88\xc9'}\xfa\x9f\x9d\x87\xfd~\xf3\x9f\x99s\x11\ +J)\x82$\x84x\x05x\x9e\xc7kH)\xf5w\xd6\ +(' \xb8C\xbb\x01h\x97R\xbe\xc6cdY\xd6\ +\x07\x1a\xf6\xbb@\xb7\x069\xff\x14\x00&\xfc\xb7\xed\xf5\ +\xe2`]DDn\xce\x89\x8a+W\xaeP]S\x8d\ +@\x00\xa0P\x08e(A)f\xd3i^\xa9\x17/\ +\xbc\xb4Nl;\xf1\x1f\xb9G\x83|[CL;\x8f\x85D\x952\xe2\xb6\xc4\ +\xb6\x04!!p>Sl\x8c;\x80D*\x04\xf0\x9c\ +\x10\x02\xe0\xcb@\x05P\x0f4`\xc4Hi\x9f$\x02\ +\x01N\x9c8!\x00\x81\x05\xd2\x87\x96\x96g\x09em\ +\x14\xe5(\xa5\xb4A\x08XW\x19%\xe2\xd8DB\x16\ +\xc3\x13s\x5c\xbc=A\xf7X\x8e\x5c$\xbe\xa9\xbd}\ +\xf7\xef-\xcbZ\xdc\xb1cGYUU\x95\xd3\xd8\xd8\ +\x18~\xe0\x86\x86\x86\xd0\xa5K\x97\xdc\xae\xae\xae\x08\xf0\ +\xd6\xaa\x1d\x00\x13DU,\xc2s\xd51\xf2\x9eO\xa1\ +(\x91Ja\x09A\xd8\xb1\x88\x86l\xe6r\x05\x12\xa2\ +\x8e?\x9f\xff+\x0dM\x1b\x01\x22\xc0f\x96\x84\xef\xfb\ +x\x9eGuu\xb5\x9ePK\xf4\xea\xd5\xab\x87\x84\x10\ +(\xa5\xdeZ\x11\xc0\xb2A\x00\xb6-\x90\xda\xb6\x148\ +\x08\xa4\x12X\xc2\x8c\x1b\x8fL\xb9\xec{\xf5;\xd47\ +6\x11|/\xc1\x84g2\x19\xca\xcb\xcb\xcdf>v\ +\xec\xd8&\xbd\x7f\x0e.A,\x01\xd0\xd9\xd9\xa9\x0e\x1d\ +:\xa4l!\x08Y\x10\xb6-\x1c\xc7\xc6BP\xb4\xcd\ +\x1a\x1b\x00\xc7\xb2\x888\x96\xae\x02`Yx\x10\xc0\xdc\ +\xdc\x1c555\x06 \x1a\x8dr\xe4\xc8\x91\xcd\xc0\x03\ +\x88\x1b\x1a\xa2\xc7b\xb9\xb0mt0f\x8d\xcb#6\ +\xb1\xa8\xa3\xc7,2\x8b\x1e\x93\x99\x1cc\xa9y\xee\xcc\ +.\xe8\xdfEr\xf9<\xab\xc8,A6\x9b5\xa7f\ +\xe9\xffm\x0e\x1c8\xb0\x1e\xe8\x00X\x06\xa0\xb4t\x16\ +\x8e\x0d\xe1\x90\xc0S\x8a\xb1\xa4\xcb\x8d\x8c\x83\xd3\xb2\x97\ +\xa6}\xaf\xb3\xb5\xe3\x17\xac\xdb\xfb:\x0d/\xb4s\xfb\ +\xce$\xfd\xfd\xfd$\x93I\x94R\xe6\xfa\xf8\xf1\xe3\xe8\ +\xba\xac3\xe7\xce\x9d\xe3\xe8\xd1\xa3\x1c>|\x98\xde\xde\ +^\x12\x89\x84\x04,\xa1\x15\xdc\x01\xed\xff\xce\xe6\xf8\xe7\ +\x94Ok\xc7\xcf\xf8\xe6/\xdf&\xf6\xf57\x99|\xa6\ +\x83k\xfe.\xae\xf1-dk\x17\xad{\x7fN^V\ +s\xfaog\xd1wM\xee\xdc\x9d\xe2\x1b\xafvr\xfd\ +\xfau\x03\xa0gk\xd6?\x16\x8b\x99\xebx<\x8e\xe3\ +8%8\x04\xc0#\x00\x96%\x98\xcaA:\xde\xca\xfe\ +\xdf\xbdM\xd5\xae\xd7(\x84b\x08\xdbBY\x82lA\ +r\x7ff\x91O\xeef\x18\xb8\xear\xfa\x1fad\xd5\ +^\xae\x8f\xdcg2\xd7\xc6\x85\x0f\xee\x9b\x00\xed\x87\xa1\ +\xcd\xcd\xcd\xb4\xb5\xb5\x19755\xa1\xa1\x14 \x83\x1f\ +F\x16\xdcq\x15\xdf\xff\xe9o\xa8l\xd8H\xe2\xec;\ +L\x8f^\xc3\x89\x94\xb1\xb5y\x07\x9b[\xb6\xf3Iy\ +%c\x09\x97\xcff\xf2\xdc\x9d\xce2\xa1\xed\x88\x0dL\ +'\xe7\xd8\xb7+\xca\xfa%\x003{=k\xea\xea\xea\ +\x00\xccu*\x952\x00J+\x10\xa0\xb9Zp\xe1\x9d\ +c(,\xca\xe6\xc6\xd9\x10\x8fR\x94\x92{\xc3}$\ +e\x05\xdb\xda\x7fLM\xdb\xcb|<\x9cf\xd2_\xc0\ +\xcdx,\xcck/x \x00\xb5t:B\xa1\x90\x09\ +-\xdd\xea\x1f\x8e\x01*\xf8>`\xc1\xc6\xb8\xa0P\x1c\ +#\x1c\x8bS\xb7\xa5\x96\x92xv}\x05\xe9\xac\xc7h\ +\xff\x9f\x98\xae\xbcL\xcb\xf6\x83\xb8\x0ba\xbc\x82\xa4X\ +\x94x\xda!\xc7B-\xaa\x80\xe3i\xa0\x96\xd5\x15\x01\ +\x00\xd6\xc7C\x84\xca#\xfc\xbfjc!\x9e\xa9\x0cs\ +\xe1\xdf\x83\xec\xd9\xf9\x13\xca\xa3\x0e\xb92G\x03(\x03\ +ak\x00\x16K!\xa5\x1c%0*\x15\xa4\x5c\x05@\ +X\xa5*\xcc\xf5#\xfapl\x86\xf1Y\x8f\xef\xfd\xfa\ +\x8f\xdc\xca\xd4\xe0D\x5c\xa2\x11\x1b\xcf\x93\x14=\x07\xd3\ +\x01\xa5\x90R\xf2PjY\x01V\x05\x10\x08L\x0d\x04\ +\x18\x9dv\xf9\xd5_\x86\x18\xbd\xb7\x80=\x93g\xd3\xba\ +2\xf2y_\xbbh\xea\xce\xaf\xd4p\xf9\xdd\xe0%\x00\ +\x9ex\x09L\xb8\x10<\xa2\xd6/U\xf2\x87\x1f>\xcf\ +\xf5O3D\x1b\xb7\xb1\xf3\xc5\x97Y\x12\x5cN`\x8e\ +\xdbS\x01(\xc0\x12%\x00m\xd4R}\xb1\xb5\x96\xdd\ +[\xe2t\xbf\x97\xa5j\xf7W\xf9\xd1\x1bo\x10\xa0\xb5\ +\x03\x98\xb57\xd5\xd8\x08\x01\xd2\xcbSpSx\xf33\ +\x14\xb3i\x0a\x19\x1f%\xfd\xd5\x82\xd6\x08\xf0\xf0)\xe7\ +\xe3\xe73\x14\xe6u\xa8\x0e\xd6\x00\xcb\xf7\x89\x10\xc13\ +}\xfa\xd7r\x8c\xb2\x137\x03\xc7\x01\xb2\x1e\xfe\xad\x94\ +\xcco\xf7DT\x03\xd8_p\x07\x08\x92\x09\xfd\xd7=\ +?\xfd~B\xa6\xcf\xdf\xf6\xef\x02\xeev;\xfc\x92\x06\ +\xa8\xe3s\xcau]\x1fpW\xed\x00@2\xab\x0a\x1f\ +~*\xd3\xbd\xb7\xfc\xd4\xcdi9\x05\xf4\x03\x97th\ +\xbf\x10\xa2\xd3\xb6\xed\xaf}\x9e%XXX\xf0\x07\x06\ +\x06\xd2'O\x9e\x9c\x06\xba\x83\x00>\x1aI\xca\xad\xe3\ +\xb3*\xd7;\xe2\xa7nL\xcb\xd1R\xe8Y\x1dt\x8b\ +\x00=\x09\xc0\xd0\xd0\x90\xdb\xd3\xd3\x93\xd2N\xcf\xce\xce\ +\x9e.\xbd\x1d\xdf\x08\x02\xe8\xee\xea)\x00\x8c\x04\x84\x06\ +\x85\xaf\x08055U\xd0/\x22\xa9S\xa7N%\xc7\ +\xc7\xc7/\x03g\x81~\x1d\xec\xae\xb8\x09K\xdfv\xda\ +O&\x85\x01@\x08@aZ\xfc\xde\xe0`\xba\xbb\xbb\ +;\xa5\xdf\x8a\xcc$\xd0^\xeds\xcda\xed\x9aw3\ +n\x11`p\xf0\xfdt___\xfa\xcc\x993\xa6\xc5\ +\xa5\xd0\x8fx\x02\x89\xb5\x9ec!D\x18x\x13\xd8O\ +is\x06\xb4\xf8\xb1\xfa\x1f\xbd\xfa*_\xf2\xd8\x15\x9d\ +\x00\x00\x00\x00IEND\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x08\ +\x08\xc8Xg\ +\x00s\ +\x00a\x00v\x00e\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x06\xc1Y\x87\ +\x00o\ +\x00p\x00e\x00n\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x0a\xc7W\x87\ +\x00c\ +\x00u\x00t\x00.\x00p\x00n\x00g\ +\x00\x08\ +\x06|Z\x07\ +\x00c\ +\x00o\x00p\x00y\x00.\x00p\x00n\x00g\ +\x00\x07\ +\x04\xcaW\xa7\ +\x00n\ +\x00e\x00w\x00.\x00p\x00n\x00g\ +\x00\x09\ +\x0a\xa8\xbaG\ +\x00p\ +\x00a\x00s\x00t\x00e\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x06\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00h\x00\x00\x00\x00\x00\x01\x00\x00\x171\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00R\x00\x00\x00\x00\x00\x01\x00\x00\x11\xf3\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00(\x00\x00\x00\x00\x00\x01\x00\x00\x04\xa7\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00|\x00\x00\x00\x00\x00\x01\x00\x00\x1a\x89\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +\x00\x00\x00>\x00\x00\x00\x00\x00\x01\x00\x00\x0c\xc4\ +\x00\x00\x01e\xaf\x16\xd2\x9d\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.py b/examples/widgets/painting/basicdrawing/basicdrawing.py new file mode 100644 index 0000000..f92da1b --- /dev/null +++ b/examples/widgets/painting/basicdrawing/basicdrawing.py @@ -0,0 +1,349 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/painting/basicdrawing example from Qt v5.x, originating from PyQt""" + +from PySide2.QtCore import QPoint, QRect, QSize, Qt, qVersion +from PySide2.QtGui import (QBrush, QConicalGradient, QLinearGradient, QPainter, + QPainterPath, QPalette, QPen, QPixmap, QPolygon, QRadialGradient) +from PySide2.QtWidgets import (QApplication, QCheckBox, QComboBox, QGridLayout, + QLabel, QSpinBox, QWidget) + +import basicdrawing_rc + + +class RenderArea(QWidget): + points = QPolygon([ + QPoint(10, 80), + QPoint(20, 10), + QPoint(80, 30), + QPoint(90, 70) + ]) + + Line, Points, Polyline, Polygon, Rect, RoundedRect, Ellipse, Arc, Chord, \ + Pie, Path, Text, Pixmap = range(13) + + def __init__(self, parent=None): + super(RenderArea, self).__init__(parent) + + self.pen = QPen() + self.brush = QBrush() + self.pixmap = QPixmap() + + self.shape = RenderArea.Polygon + self.antialiased = False + self.transformed = False + self.pixmap.load(':/images/qt-logo.png') + + self.setBackgroundRole(QPalette.Base) + self.setAutoFillBackground(True) + + def minimumSizeHint(self): + return QSize(100, 100) + + def sizeHint(self): + return QSize(400, 200) + + def setShape(self, shape): + self.shape = shape + self.update() + + def setPen(self, pen): + self.pen = pen + self.update() + + def setBrush(self, brush): + self.brush = brush + self.update() + + def setAntialiased(self, antialiased): + self.antialiased = antialiased + self.update() + + def setTransformed(self, transformed): + self.transformed = transformed + self.update() + + def paintEvent(self, event): + rect = QRect(10, 20, 80, 60) + + path = QPainterPath() + path.moveTo(20, 80) + path.lineTo(20, 30) + path.cubicTo(80, 0, 50, 50, 80, 80) + + startAngle = 30 * 16 + arcLength = 120 * 16 + + painter = QPainter(self) + painter.setPen(self.pen) + painter.setBrush(self.brush) + if self.antialiased: + painter.setRenderHint(QPainter.Antialiasing) + + for x in range(0, self.width(), 100): + for y in range(0, self.height(), 100): + painter.save() + painter.translate(x, y) + if self.transformed: + painter.translate(50, 50) + painter.rotate(60.0) + painter.scale(0.6, 0.9) + painter.translate(-50, -50) + + if self.shape == RenderArea.Line: + painter.drawLine(rect.bottomLeft(), rect.topRight()) + elif self.shape == RenderArea.Points: + painter.drawPoints(RenderArea.points) + elif self.shape == RenderArea.Polyline: + painter.drawPolyline(RenderArea.points) + elif self.shape == RenderArea.Polygon: + painter.drawPolygon(RenderArea.points) + elif self.shape == RenderArea.Rect: + painter.drawRect(rect) + elif self.shape == RenderArea.RoundedRect: + painter.drawRoundedRect(rect, 25, 25, Qt.RelativeSize) + elif self.shape == RenderArea.Ellipse: + painter.drawEllipse(rect) + elif self.shape == RenderArea.Arc: + painter.drawArc(rect, startAngle, arcLength) + elif self.shape == RenderArea.Chord: + painter.drawChord(rect, startAngle, arcLength) + elif self.shape == RenderArea.Pie: + painter.drawPie(rect, startAngle, arcLength) + elif self.shape == RenderArea.Path: + painter.drawPath(path) + elif self.shape == RenderArea.Text: + painter.drawText(rect, Qt.AlignCenter, + "PySide 2\nQt %s" % qVersion()) + elif self.shape == RenderArea.Pixmap: + painter.drawPixmap(10, 10, self.pixmap) + + painter.restore() + + painter.setPen(self.palette().dark().color()) + painter.setBrush(Qt.NoBrush) + painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1)) + + +IdRole = Qt.UserRole + +class Window(QWidget): + def __init__(self): + super(Window, self).__init__() + + self.renderArea = RenderArea() + + self.shapeComboBox = QComboBox() + self.shapeComboBox.addItem("Polygon", RenderArea.Polygon) + self.shapeComboBox.addItem("Rectangle", RenderArea.Rect) + self.shapeComboBox.addItem("Rounded Rectangle", RenderArea.RoundedRect) + self.shapeComboBox.addItem("Ellipse", RenderArea.Ellipse) + self.shapeComboBox.addItem("Pie", RenderArea.Pie) + self.shapeComboBox.addItem("Chord", RenderArea.Chord) + self.shapeComboBox.addItem("Path", RenderArea.Path) + self.shapeComboBox.addItem("Line", RenderArea.Line) + self.shapeComboBox.addItem("Polyline", RenderArea.Polyline) + self.shapeComboBox.addItem("Arc", RenderArea.Arc) + self.shapeComboBox.addItem("Points", RenderArea.Points) + self.shapeComboBox.addItem("Text", RenderArea.Text) + self.shapeComboBox.addItem("Pixmap", RenderArea.Pixmap) + + shapeLabel = QLabel("&Shape:") + shapeLabel.setBuddy(self.shapeComboBox) + + self.penWidthSpinBox = QSpinBox() + self.penWidthSpinBox.setRange(0, 20) + self.penWidthSpinBox.setSpecialValueText("0 (cosmetic pen)") + + penWidthLabel = QLabel("Pen &Width:") + penWidthLabel.setBuddy(self.penWidthSpinBox) + + self.penStyleComboBox = QComboBox() + self.penStyleComboBox.addItem("Solid", Qt.SolidLine) + self.penStyleComboBox.addItem("Dash", Qt.DashLine) + self.penStyleComboBox.addItem("Dot", Qt.DotLine) + self.penStyleComboBox.addItem("Dash Dot", Qt.DashDotLine) + self.penStyleComboBox.addItem("Dash Dot Dot", Qt.DashDotDotLine) + self.penStyleComboBox.addItem("None", Qt.NoPen) + + penStyleLabel = QLabel("&Pen Style:") + penStyleLabel.setBuddy(self.penStyleComboBox) + + self.penCapComboBox = QComboBox() + self.penCapComboBox.addItem("Flat", Qt.FlatCap) + self.penCapComboBox.addItem("Square", Qt.SquareCap) + self.penCapComboBox.addItem("Round", Qt.RoundCap) + + penCapLabel = QLabel("Pen &Cap:") + penCapLabel.setBuddy(self.penCapComboBox) + + self.penJoinComboBox = QComboBox() + self.penJoinComboBox.addItem("Miter", Qt.MiterJoin) + self.penJoinComboBox.addItem("Bevel", Qt.BevelJoin) + self.penJoinComboBox.addItem("Round", Qt.RoundJoin) + + penJoinLabel = QLabel("Pen &Join:") + penJoinLabel.setBuddy(self.penJoinComboBox) + + self.brushStyleComboBox = QComboBox() + self.brushStyleComboBox.addItem("Linear Gradient", + Qt.LinearGradientPattern) + self.brushStyleComboBox.addItem("Radial Gradient", + Qt.RadialGradientPattern) + self.brushStyleComboBox.addItem("Conical Gradient", + Qt.ConicalGradientPattern) + self.brushStyleComboBox.addItem("Texture", Qt.TexturePattern) + self.brushStyleComboBox.addItem("Solid", Qt.SolidPattern) + self.brushStyleComboBox.addItem("Horizontal", Qt.HorPattern) + self.brushStyleComboBox.addItem("Vertical", Qt.VerPattern) + self.brushStyleComboBox.addItem("Cross", Qt.CrossPattern) + self.brushStyleComboBox.addItem("Backward Diagonal", Qt.BDiagPattern) + self.brushStyleComboBox.addItem("Forward Diagonal", Qt.FDiagPattern) + self.brushStyleComboBox.addItem("Diagonal Cross", Qt.DiagCrossPattern) + self.brushStyleComboBox.addItem("Dense 1", Qt.Dense1Pattern) + self.brushStyleComboBox.addItem("Dense 2", Qt.Dense2Pattern) + self.brushStyleComboBox.addItem("Dense 3", Qt.Dense3Pattern) + self.brushStyleComboBox.addItem("Dense 4", Qt.Dense4Pattern) + self.brushStyleComboBox.addItem("Dense 5", Qt.Dense5Pattern) + self.brushStyleComboBox.addItem("Dense 6", Qt.Dense6Pattern) + self.brushStyleComboBox.addItem("Dense 7", Qt.Dense7Pattern) + self.brushStyleComboBox.addItem("None", Qt.NoBrush) + + brushStyleLabel = QLabel("&Brush Style:") + brushStyleLabel.setBuddy(self.brushStyleComboBox) + + otherOptionsLabel = QLabel("Other Options:") + self.antialiasingCheckBox = QCheckBox("&Antialiasing") + self.transformationsCheckBox = QCheckBox("&Transformations") + + self.shapeComboBox.activated.connect(self.shapeChanged) + self.penWidthSpinBox.valueChanged.connect(self.penChanged) + self.penStyleComboBox.activated.connect(self.penChanged) + self.penCapComboBox.activated.connect(self.penChanged) + self.penJoinComboBox.activated.connect(self.penChanged) + self.brushStyleComboBox.activated.connect(self.brushChanged) + self.antialiasingCheckBox.toggled.connect(self.renderArea.setAntialiased) + self.transformationsCheckBox.toggled.connect(self.renderArea.setTransformed) + + mainLayout = QGridLayout() + mainLayout.setColumnStretch(0, 1) + mainLayout.setColumnStretch(3, 1) + mainLayout.addWidget(self.renderArea, 0, 0, 1, 4) + mainLayout.setRowMinimumHeight(1, 6) + mainLayout.addWidget(shapeLabel, 2, 1, Qt.AlignRight) + mainLayout.addWidget(self.shapeComboBox, 2, 2) + mainLayout.addWidget(penWidthLabel, 3, 1, Qt.AlignRight) + mainLayout.addWidget(self.penWidthSpinBox, 3, 2) + mainLayout.addWidget(penStyleLabel, 4, 1, Qt.AlignRight) + mainLayout.addWidget(self.penStyleComboBox, 4, 2) + mainLayout.addWidget(penCapLabel, 5, 1, Qt.AlignRight) + mainLayout.addWidget(self.penCapComboBox, 5, 2) + mainLayout.addWidget(penJoinLabel, 6, 1, Qt.AlignRight) + mainLayout.addWidget(self.penJoinComboBox, 6, 2) + mainLayout.addWidget(brushStyleLabel, 7, 1, Qt.AlignRight) + mainLayout.addWidget(self.brushStyleComboBox, 7, 2) + mainLayout.setRowMinimumHeight(8, 6) + mainLayout.addWidget(otherOptionsLabel, 9, 1, Qt.AlignRight) + mainLayout.addWidget(self.antialiasingCheckBox, 9, 2) + mainLayout.addWidget(self.transformationsCheckBox, 10, 2) + self.setLayout(mainLayout) + + self.shapeChanged() + self.penChanged() + self.brushChanged() + self.antialiasingCheckBox.setChecked(True) + + self.setWindowTitle("Basic Drawing") + + def shapeChanged(self): + shape = self.shapeComboBox.itemData(self.shapeComboBox.currentIndex(), + IdRole) + self.renderArea.setShape(shape) + + def penChanged(self): + width = self.penWidthSpinBox.value() + style = Qt.PenStyle(self.penStyleComboBox.itemData( + self.penStyleComboBox.currentIndex(), IdRole)) + cap = Qt.PenCapStyle(self.penCapComboBox.itemData( + self.penCapComboBox.currentIndex(), IdRole)) + join = Qt.PenJoinStyle(self.penJoinComboBox.itemData( + self.penJoinComboBox.currentIndex(), IdRole)) + + self.renderArea.setPen(QPen(Qt.blue, width, style, cap, join)) + + def brushChanged(self): + style = Qt.BrushStyle(self.brushStyleComboBox.itemData( + self.brushStyleComboBox.currentIndex(), IdRole)) + + if style == Qt.LinearGradientPattern: + linearGradient = QLinearGradient(0, 0, 100, 100) + linearGradient.setColorAt(0.0, Qt.white) + linearGradient.setColorAt(0.2, Qt.green) + linearGradient.setColorAt(1.0, Qt.black) + self.renderArea.setBrush(QBrush(linearGradient)) + elif style == Qt.RadialGradientPattern: + radialGradient = QRadialGradient(50, 50, 50, 70, 70) + radialGradient.setColorAt(0.0, Qt.white) + radialGradient.setColorAt(0.2, Qt.green) + radialGradient.setColorAt(1.0, Qt.black) + self.renderArea.setBrush(QBrush(radialGradient)) + elif style == Qt.ConicalGradientPattern: + conicalGradient = QConicalGradient(50, 50, 150) + conicalGradient.setColorAt(0.0, Qt.white) + conicalGradient.setColorAt(0.2, Qt.green) + conicalGradient.setColorAt(1.0, Qt.black) + self.renderArea.setBrush(QBrush(conicalGradient)) + elif style == Qt.TexturePattern: + self.renderArea.setBrush(QBrush(QPixmap(':/images/brick.png'))) + else: + self.renderArea.setBrush(QBrush(Qt.green, style)) + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.pyproject b/examples/widgets/painting/basicdrawing/basicdrawing.pyproject new file mode 100644 index 0000000..9ecbfad --- /dev/null +++ b/examples/widgets/painting/basicdrawing/basicdrawing.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["basicdrawing_rc.py", "basicdrawing.qrc", "basicdrawing.py"] +} diff --git a/examples/widgets/painting/basicdrawing/basicdrawing.qrc b/examples/widgets/painting/basicdrawing/basicdrawing.qrc new file mode 100644 index 0000000..9d8a23a --- /dev/null +++ b/examples/widgets/painting/basicdrawing/basicdrawing.qrc @@ -0,0 +1,6 @@ + + + images/brick.png + images/qt-logo.png + + diff --git a/examples/widgets/painting/basicdrawing/basicdrawing_rc.py b/examples/widgets/painting/basicdrawing/basicdrawing_rc.py new file mode 100644 index 0000000..3a54805 --- /dev/null +++ b/examples/widgets/painting/basicdrawing/basicdrawing_rc.py @@ -0,0 +1,135 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x03X\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00 \x00\x00\x00\x10\x08\x02\x00\x00\x00\xf8b\xea\x0e\ +\x00\x00\x00\x04gAMA\x00\x00\xb1\x8e|\xfbQ\x93\ +\x00\x00\x00 cHRM\x00\x00z%\x00\x00\x80\x83\ +\x00\x00\xf9\xff\x00\x00\x80\xe8\x00\x00u0\x00\x00\xea`\ +\x00\x00:\x97\x00\x00\x17o\x97\xa9\x99\xd4\x00\x00\x02\xe3\ +IDAT8\xcbE\x94\xcb\x8d\x1eE\x10\xc7\x7fU\ +\xd53\xb3\xf6j\x9d\x09I\x90\x04\x0e\x05\x09\x99x\xe0\ +\xc4\xc1\x12\x07B \x04\x08\xc1\x96\xd7\xcb\xb7\xf3\xcd\xf4\ +\xa3\xaa8L[\xees\xbd\xfa\xff\x92\xcf\xff\xfc\xa6\x86\ +\x1a(* dB\x92A\x048\x1e\xa4\x93A89\ +@\x11A\x94\x8cY\x93WABb+e\xc3\x16\xac\ + \x85\xf7?\xbd/\x08\xf5\xf6o\xd9P%\x0c5\xc4\ +H\xc7;1\x18\x8d\x18\xa4\x13Nt| \x82\x16\x80\ +t\xdc\xf1F\x0c\xc2\x11\x00\xa4\xb0\xbc\xe1\xe1\x09\xdb\xf8\ +\xf5\xc3\x87\x0c\x8a\x1a\xaa\xd4\x97\xbf\xcb\x82.\xf3\x04\x9c\ +\xa8\xd4\x9d~\xa7\x9f\xf3\xd8\xd1\xf0\x93p\xb4 \x82w\ +\xfa\xc1h\x10D\x02\xa8b\x0b\xeb#\xfd\x1d\x7f\xfe\xf5\ +1\x02Q\x8a\x16\xd4\x10\xa5\xdd>ja{\x22 \x06\ +}\xe7\xfc\xc2\xf9\x1f\xc73\xf5u\x82\xd0vFE\x94\ +\x18x\xa7\xef\x8c\x8e*\xde\xc9\xc4\x0a\xdb;\x1e\x9eX\ +\x1e\xf1\x0e\x01PD\x10\xc3\x0aa\x94\x07\xca\x86.\x84\ +\x93\x01L2\xc6\x81\x0f\xd2i\x07^\x01\xc4\x88\x81\x18\ +\x0c\xbc3\x1a\xd1\xf1B\xd9h\x85Lb\x90I\x06\xe5\ +\xc2T\x0cQlE\x0b\x19d\xe2\x83v\xe7\xf8J\xdb\ +Ihw\xc6\x9d\xd1\x89A\x06\xb6 J?!\x18\x8d\ +\xbe\x93I\x11\xbca\x1b\xfd\xa0\xef\x8c\x13\xef\x17\x07\x05\ +QD\x11!\x9cQ\xa97\xce\x17\x8e\xaf\xd4\xdb\xe4`\ +\x9c\xdc\xbf\x90\x17\xb7\x83\xf5\x11Q\xfa}v\x89\x92\x8e\ +\x08\x11x\x87\xa4\x9f\xf4\x93Q/\x88\x14\xb9x\x1b\x8c\ +\xca\xf9\xc2\xf1\xc2\xf1<\xfb\xc9\x89\xd5hx\xbb\xb4B\ +\x0c\x80QQ\xa3l,o!'n^Q\x9d\xda\x8d\ +\xa0D\x00\x98\x12+\x80W\xfaI\xbbQo\xb4W2\ +\x09g\x1cd\xa0\x85~\xc7;Z\xe8\x8a\x15\xc89\xb7\ +\xac\x08\x88R\x1e\xa6\x823A )\x17\x99b\xa8\x11\ +\x8ew\xbc\x11A8u\xa7\x1fS\x91\xa3~\xf7\x97w\ +2\x88\x95p`\xee6\xc3\x16\x96G2\xbeA\xa7 \ +\x14Q\x08b\xd0\x0eT\x19\x95\xe8Lb\x8cLFe\ +\x1c\xd4\x1d?I\x07!\x83\x14\xa2\x91I\xef\xa0\xaco\ +\x91\x85d\xb2}\xad\xbc\x0e*\x99x\xa7\xed\xec\x9f\xb0\ +\x85\x18\x93\x0f5\xcaJ7\x86S_i\xfb4\xd4%\ +A5\x10F#\x1d5\xfa\x1d5\xb2\x93\x81(j\x13\ +\x15[(1\xe8\x07\xf7g\xf6O\xacO\xa8\xe1\x8dQ\ +!\xb0\x82\x95\xefn\xb8\xac$B\x0f`\xc6Cy\x83\ +m\x84\xd3O\x00\xdb\xe6\xee\xebD+\x94p|\xf0\xc7\ +\xef\x1f#\xd8\x9e\xa6K\x11\xa2\xd1v\xda\x9d\xfaJ\xbb\ +1*\x97\xf5/Ef\x80 \x8a\x1eX\xc5\xf6\xc9\xa2\ +\x1a\xba\x00\x94o\x9bJ8\xbf\xfc\xfc\xe12\x9e\xad\x88\ +\xccT\xf1A\xdd\x89+\xf2\xeaL\xba\xab\x87+h\xa1\ +\xac\xe8\x82tTA\xd0\x05U\x00QtA\x8dL\xe4\ +\xc7\x1f@g\x16^\xc0]\xef\x92S\xe6\x84>\x06\x04\ +W]\x06\xe4\xfcAY\xbf\xb5\x08Wn\x8a\xce9\x97\ +\xe4\xfe\x07\xb6\x84\x15$\x5c\xbcO\xce\x00\x00\x00\x00I\ +END\xaeB`\x82\ +\x00\x00\x02\x15\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00P\x00\x00\x00P\x04\x03\x00\x00\x00|?\xef\x9e\ +\x00\x00\x00\x15PLTE\xa3\xc2\x00\xf4\xf8\xe1\x8a\xa1\ +\x09\x14\x14\x18?G\x16\xd3\xe2\x86p\x82\x0e\xfd\x17\x22\ +9\x00\x00\x00\x09pHYs\x00\x00\x00H\x00\x00\x00\ +H\x00F\xc9k>\x00\x00\x01\xa6IDATH\xc7\ +\xedVKn\x840\x0cEf\xc49\xa2I\xd55\x22\ +\x11k\xd4Hs\x0eT\x10\xf7?B\x0b\xc4L\xfc\x83\ +\xd9u\xd1\xf1\x0a\xa2\x97\x17\xdb\xb1\x9fSUo\xfbk\ +\xbb/\xcb\xfd\x1a\x05s\x0a\xbf\x16\x1f\xee\x1c\xd7l\xb0\ +\x0d:\x9e\xe2Ba\xe3\x8b\xb8\x13$$\x0a\x8c\x96\x9f\ +S`\xd6\xeb\xb8[\x106\xa8\xc0$\x81\xf1EB\x9d\ +\x12\x09\xe3cY\xe6dSbj\xf6+\x81\xd9\xa4\xf4\ +\x19\x87\xff\x1fV\xe0\x89\xaf\xe7d9=\x14'\xd2?\ +\xa8'\x7f\xc9\xbd\x9dz\xf2\x93n\xc45\x167\xb0\xdd\ +~u\xb6VJ\xe3F\xd7`\xfb\x06\xc5\xc9\x9a\x9e\xe2\ +\xf7\xf8\x93tr\x22K\x90\xe9k\x99\xc9D\x0e\xf1\x19\ +\xd0\xc8hR\x99D\xc0\x02\x07\x91r [\xf3m\xb6\ +l\xffQ\x11=%\x5c\x9d\x9cx~\x080\x13v\xf8\ +9\xf04v\x94\xd0a\xd6\x04\xb0\x15\x84\xfb\xba\x01\x84\ +\xb2\xa9u\xe0P\x12\xf6\xd5\x05#\x84k\xc6\xb6 \xcc\ +\x9473j\xa0\xca#\xa2>\xf2\xe8\xa9\x9ex\x15\x18\ +\x09\xa1~3x\xd75\x93(q\xd7\xb8\x02T\x1f\x81\ +6RY\x8f\x9bS\x1d\xe6R\xa9G\xacp(\x98B\ +\x98d\x85\x1f=\xb3wK\x11<\xeb\x99\xa3\x0bas\ +\x1eL\xe5{\xf6\xb5\xef*\x9aO\xa7)\x85\xcb\x1aQ\ +PFU{:\xae\x82R{\x1av\x0e\x98\xe2\xcc\xf5\ +\x11)-\xc5=\x90\xb35\xbeP\xc3{\xaa\xe1\xa66\ +\xb3\xa9\xa0Q\xaas\xe6\x94\x92\xdbx1\x84O\xa6\xd7\ +\xa4\xe2\xe2\x0b\xf3z\xb2\xc6a\x93d\x85\xc7\x8b\xb7\xc7\ +\x1e\x84\xb7F6\x7f\xa5\x80A\xb8\xda\x92\xdf=\xf9b\ +\x87\xb3\x97\xd4\xe7\xf7\xf1\x92\x02\xf7~Y\xfe?\xfb\x01\ +\xbd\xf6\xdd\x91\xa2\xf3\xda\xd4\x00\x00\x00\x00IEND\ +\xaeB`\x82\ +" + +qt_resource_name = b"\ +\x00\x06\ +\x07\x03}\xc3\ +\x00i\ +\x00m\x00a\x00g\x00e\x00s\ +\x00\x09\ +\x0f\x9e\x84G\ +\x00b\ +\x00r\x00i\x00c\x00k\x00.\x00p\x00n\x00g\ +\x00\x0b\ +\x05R\xbf'\ +\x00q\ +\x00t\x00-\x00l\x00o\x00g\x00o\x00.\x00p\x00n\x00g\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00*\x00\x00\x00\x00\x00\x01\x00\x00\x03\x5c\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/painting/basicdrawing/images/brick.png b/examples/widgets/painting/basicdrawing/images/brick.png new file mode 100644 index 0000000000000000000000000000000000000000..ab5e383dce423441b3278ae83bbd1a5ce01bdf40 GIT binary patch literal 856 zcmV-e1E>6nP)004R=004l4008;_004mK004C`008P>0026d000+nm#LZ50008x zNklPqpCPe zTkdnc`u~#8|NN$g8Yn6tWI~cb1UMd~lR-E+KoLQdj9HUcK|*3HWy2P%Acgloy)Ov$ z_HWrxB@8vhNXI)d7>yXD6Hat|Ac7WvblmYq48jorq_Di<;R)OL^}~k@iW;iam%qz` zF7pJOsMMW)r=RoK(eRUSv><|a`oU-rL;|Q{3+p5O9e@7yF#=JF7Ss@>-9Bnzdmu>Kc1A^%7J3SpE7%7!k4lL1UJ z#(@vgX$M{b#E5|y47@WM(eXmrXoXB-kVyvR!c+`VY()zhWa5K%=lDw7NoaS*ozaOw z2DTtdKOq>6zLQB2ykQ&tpzn+m?-vIJQA80ToKdMa&KHia)Z64>oZP>V7q^4;5mEYm zc8QXX2oZRPq@VPYQ7?!Txp*6l%K5_a!tp%&$%)lyc)PSh41iHlqiig1At!ELQJvb2 zphN(e5-WgL`boP{Z?so331=K+poMDw%kv?d+ehg&30$HOfjihErc@`!v)gK{XIYBONvR9W}C( zfhcMd6qIM*aD4E` z?;j)Bo~BC?qS1ERo%%|P)(;hbw5ItmuMtR6)=MRRB?RL5)o0#~(mv7GA(z?~+sIggyoYS6v3={6Sg2 iwFp;kiq1Kg)a}HDx_dh}l#7z8y*>%zJ3Zj=6+p(WhRd4%iyD!WA z8U=F-zZM_v9M^2H4LY9ULSf^JxDzBK3XGPYQ()HXxLXi5sK6wF@kK(N5((pDS>|L@ zVrup)f!U<=8HfKLR^W-R=VUoO6erR@s3(8Py`6gUlWxQ{7B{fnes#81O5;Y?VEYEe z$(o+x_xO`^aw1ER>1&zEL=N#8(8y>~nMA+>2a$3hTk~zUZ2wUaJtbV7oOpf+FcWt8 zIq)=gl+a<;1h5r^`?>*yvZ;08P!jgl1tWxO#Hh-mnLActI-#z(ahqIT|=lAiF0{4Dd{y+Nx Xz4qOaqVw9+00000NkvXXu0mjfxVr9- literal 0 HcmV?d00001 diff --git a/examples/widgets/painting/concentriccircles.py b/examples/widgets/painting/concentriccircles.py new file mode 100644 index 0000000..ff13292 --- /dev/null +++ b/examples/widgets/painting/concentriccircles.py @@ -0,0 +1,146 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/painting/concentriccircles example from Qt v5.x, originating from PyQt""" + +from PySide2.QtCore import QRect, QRectF, QSize, Qt, QTimer +from PySide2.QtGui import QColor, QPainter, QPalette, QPen +from PySide2.QtWidgets import (QApplication, QFrame, QGridLayout, QLabel, + QSizePolicy, QWidget) + + +class CircleWidget(QWidget): + def __init__(self, parent=None): + super(CircleWidget, self).__init__(parent) + + self.floatBased = False + self.antialiased = False + self.frameNo = 0 + + self.setBackgroundRole(QPalette.Base) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + def setFloatBased(self, floatBased): + self.floatBased = floatBased + self.update() + + def setAntialiased(self, antialiased): + self.antialiased = antialiased + self.update() + + def minimumSizeHint(self): + return QSize(50, 50) + + def sizeHint(self): + return QSize(180, 180) + + def nextAnimationFrame(self): + self.frameNo += 1 + self.update() + + def paintEvent(self, event): + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing, self.antialiased) + painter.translate(self.width() / 2, self.height() / 2) + + for diameter in range(0, 256, 9): + delta = abs((self.frameNo % 128) - diameter / 2) + alpha = 255 - (delta * delta) / 4 - diameter + if alpha > 0: + painter.setPen(QPen(QColor(0, diameter / 2, 127, alpha), 3)) + + if self.floatBased: + painter.drawEllipse(QRectF(-diameter / 2.0, + -diameter / 2.0, diameter, diameter)) + else: + painter.drawEllipse(QRect(-diameter / 2, + -diameter / 2, diameter, diameter)) + + +class Window(QWidget): + def __init__(self): + super(Window, self).__init__() + + aliasedLabel = self.createLabel("Aliased") + antialiasedLabel = self.createLabel("Antialiased") + intLabel = self.createLabel("Int") + floatLabel = self.createLabel("Float") + + layout = QGridLayout() + layout.addWidget(aliasedLabel, 0, 1) + layout.addWidget(antialiasedLabel, 0, 2) + layout.addWidget(intLabel, 1, 0) + layout.addWidget(floatLabel, 2, 0) + + timer = QTimer(self) + + for i in range(2): + for j in range(2): + w = CircleWidget() + w.setAntialiased(j != 0) + w.setFloatBased(i != 0) + + timer.timeout.connect(w.nextAnimationFrame) + + layout.addWidget(w, i + 1, j + 1) + + timer.start(100) + self.setLayout(layout) + + self.setWindowTitle("Concentric Circles") + + def createLabel(self, text): + label = QLabel(text) + label.setAlignment(Qt.AlignCenter) + label.setMargin(2) + label.setFrameStyle(QFrame.Box | QFrame.Sunken) + return label + + +if __name__ == '__main__': + + import sys + + app = QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/painting/painting.pyproject b/examples/widgets/painting/painting.pyproject new file mode 100644 index 0000000..ed24e12 --- /dev/null +++ b/examples/widgets/painting/painting.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["concentriccircles.py"] +} diff --git a/examples/widgets/richtext/orderform.py b/examples/widgets/richtext/orderform.py new file mode 100644 index 0000000..7c0d273 --- /dev/null +++ b/examples/widgets/richtext/orderform.py @@ -0,0 +1,296 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/richtext/orderform example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets, QtPrintSupport + + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + + fileMenu = QtWidgets.QMenu("&File", self) + newAction = fileMenu.addAction("&New...") + newAction.setShortcut("Ctrl+N") + self.printAction = fileMenu.addAction("&Print...", self.printFile) + self.printAction.setShortcut("Ctrl+P") + self.printAction.setEnabled(False) + quitAction = fileMenu.addAction("E&xit") + quitAction.setShortcut("Ctrl+Q") + self.menuBar().addMenu(fileMenu) + + self.letters = QtWidgets.QTabWidget() + + newAction.triggered.connect(self.openDialog) + quitAction.triggered.connect(self.close) + + self.setCentralWidget(self.letters) + self.setWindowTitle("Order Form") + + def createLetter(self, name, address, orderItems, sendOffers): + editor = QtWidgets.QTextEdit() + tabIndex = self.letters.addTab(editor, name) + self.letters.setCurrentIndex(tabIndex) + + cursor = editor.textCursor() + cursor.movePosition(QtGui.QTextCursor.Start) + topFrame = cursor.currentFrame() + topFrameFormat = topFrame.frameFormat() + topFrameFormat.setPadding(16) + topFrame.setFrameFormat(topFrameFormat) + + textFormat = QtGui.QTextCharFormat() + boldFormat = QtGui.QTextCharFormat() + boldFormat.setFontWeight(QtGui.QFont.Bold) + + referenceFrameFormat = QtGui.QTextFrameFormat() + referenceFrameFormat.setBorder(1) + referenceFrameFormat.setPadding(8) + referenceFrameFormat.setPosition(QtGui.QTextFrameFormat.FloatRight) + referenceFrameFormat.setWidth(QtGui.QTextLength(QtGui.QTextLength.PercentageLength, 40)) + cursor.insertFrame(referenceFrameFormat) + + cursor.insertText("A company", boldFormat) + cursor.insertBlock() + cursor.insertText("321 City Street") + cursor.insertBlock() + cursor.insertText("Industry Park") + cursor.insertBlock() + cursor.insertText("Another country") + + cursor.setPosition(topFrame.lastPosition()) + + cursor.insertText(name, textFormat) + for line in address.split("\n"): + cursor.insertBlock() + cursor.insertText(line) + + cursor.insertBlock() + cursor.insertBlock() + + date = QtCore.QDate.currentDate() + cursor.insertText("Date: %s" % date.toString('d MMMM yyyy'), + textFormat) + cursor.insertBlock() + + bodyFrameFormat = QtGui.QTextFrameFormat() + bodyFrameFormat.setWidth(QtGui.QTextLength(QtGui.QTextLength.PercentageLength, 100)) + cursor.insertFrame(bodyFrameFormat) + + cursor.insertText("I would like to place an order for the following " + "items:", textFormat) + cursor.insertBlock() + cursor.insertBlock() + + orderTableFormat = QtGui.QTextTableFormat() + orderTableFormat.setAlignment(QtCore.Qt.AlignHCenter) + orderTable = cursor.insertTable(1, 2, orderTableFormat) + + orderFrameFormat = cursor.currentFrame().frameFormat() + orderFrameFormat.setBorder(1) + cursor.currentFrame().setFrameFormat(orderFrameFormat) + + cursor = orderTable.cellAt(0, 0).firstCursorPosition() + cursor.insertText("Product", boldFormat) + cursor = orderTable.cellAt(0, 1).firstCursorPosition() + cursor.insertText("Quantity", boldFormat) + + for text, quantity in orderItems: + row = orderTable.rows() + + orderTable.insertRows(row, 1) + cursor = orderTable.cellAt(row, 0).firstCursorPosition() + cursor.insertText(text, textFormat) + cursor = orderTable.cellAt(row, 1).firstCursorPosition() + cursor.insertText(str(quantity), textFormat) + + cursor.setPosition(topFrame.lastPosition()) + + cursor.insertBlock() + + cursor.insertText("Please update my records to take account of the " + "following privacy information:") + cursor.insertBlock() + + offersTable = cursor.insertTable(2, 2) + + cursor = offersTable.cellAt(0, 1).firstCursorPosition() + cursor.insertText("I want to receive more information about your " + "company's products and special offers.", textFormat) + cursor = offersTable.cellAt(1, 1).firstCursorPosition() + cursor.insertText("I do not want to receive any promotional " + "information from your company.", textFormat) + + if sendOffers: + cursor = offersTable.cellAt(0, 0).firstCursorPosition() + else: + cursor = offersTable.cellAt(1, 0).firstCursorPosition() + + cursor.insertText('X', boldFormat) + + cursor.setPosition(topFrame.lastPosition()) + cursor.insertBlock() + cursor.insertText("Sincerely,", textFormat) + cursor.insertBlock() + cursor.insertBlock() + cursor.insertBlock() + cursor.insertText(name) + + self.printAction.setEnabled(True) + + def createSample(self): + dialog = DetailsDialog('Dialog with default values', self) + self.createLetter('Mr Smith', + '12 High Street\nSmall Town\nThis country', + dialog.orderItems(), True) + + def openDialog(self): + dialog = DetailsDialog("Enter Customer Details", self) + + if dialog.exec_() == QtWidgets.QDialog.Accepted: + self.createLetter(dialog.senderName(), dialog.senderAddress(), + dialog.orderItems(), dialog.sendOffers()) + + def printFile(self): + editor = self.letters.currentWidget() + printer = QtPrintSupport.QPrinter() + + dialog = QtPrintSupport.QPrintDialog(printer, self) + dialog.setWindowTitle("Print Document") + + if editor.textCursor().hasSelection(): + dialog.addEnabledOption(QtPrintSupport.QAbstractPrintDialog.PrintSelection) + + if dialog.exec_() != QtWidgets.QDialog.Accepted: + return + + editor.print_(printer) + + +class DetailsDialog(QtWidgets.QDialog): + def __init__(self, title, parent): + super(DetailsDialog, self).__init__(parent) + + self.items = ("T-shirt", "Badge", "Reference book", "Coffee cup") + + nameLabel = QtWidgets.QLabel("Name:") + addressLabel = QtWidgets.QLabel("Address:") + addressLabel.setAlignment(QtCore.Qt.AlignLeft | QtCore.Qt.AlignTop) + + self.nameEdit = QtWidgets.QLineEdit() + self.addressEdit = QtWidgets.QTextEdit() + self.offersCheckBox = QtWidgets.QCheckBox("Send information about " + "products and special offers:") + + self.setupItemsTable() + + buttonBox = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) + + buttonBox.accepted.connect(self.verify) + buttonBox.rejected.connect(self.reject) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameEdit, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0) + mainLayout.addWidget(self.addressEdit, 1, 1) + mainLayout.addWidget(self.itemsTable, 0, 2, 2, 1) + mainLayout.addWidget(self.offersCheckBox, 2, 1, 1, 2) + mainLayout.addWidget(buttonBox, 3, 0, 1, 3) + self.setLayout(mainLayout) + + self.setWindowTitle(title) + + def setupItemsTable(self): + self.itemsTable = QtWidgets.QTableWidget(len(self.items), 2) + + for row, item in enumerate(self.items): + name = QtWidgets.QTableWidgetItem(item) + name.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) + self.itemsTable.setItem(row, 0, name) + quantity = QtWidgets.QTableWidgetItem('1') + self.itemsTable.setItem(row, 1, quantity) + + def orderItems(self): + orderList = [] + + for row in range(len(self.items)): + text = self.itemsTable.item(row, 0).text() + quantity = int(self.itemsTable.item(row, 1).data(QtCore.Qt.DisplayRole)) + orderList.append((text, max(0, quantity))) + + return orderList + + def senderName(self): + return self.nameEdit.text() + + def senderAddress(self): + return self.addressEdit.toPlainText() + + def sendOffers(self): + return self.offersCheckBox.isChecked() + + def verify(self): + if self.nameEdit.text() and self.addressEdit.toPlainText(): + self.accept() + return + + answer = QtWidgets.QMessageBox.warning(self, "Incomplete Form", + "The form does not contain all the necessary information.\n" + "Do you want to discard it?", + QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No) + + if answer == QtWidgets.QMessageBox.Yes: + self.reject() + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + window = MainWindow() + window.resize(640, 480) + window.show() + window.createSample() + sys.exit(app.exec_()) diff --git a/examples/widgets/richtext/richtext.pyproject b/examples/widgets/richtext/richtext.pyproject new file mode 100644 index 0000000..e91a989 --- /dev/null +++ b/examples/widgets/richtext/richtext.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["syntaxhighlighter.py", "orderform.py"] +} diff --git a/examples/widgets/richtext/syntaxhighlighter.py b/examples/widgets/richtext/syntaxhighlighter.py new file mode 100644 index 0000000..9be2994 --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter.py @@ -0,0 +1,210 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/richtext/syntaxhighlighter example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets + + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super(MainWindow, self).__init__(parent) + + self.setupFileMenu() + self.setupHelpMenu() + self.setupEditor() + + self.setCentralWidget(self.editor) + self.setWindowTitle("Syntax Highlighter") + + def about(self): + QtWidgets.QMessageBox.about(self, "About Syntax Highlighter", + "

The Syntax Highlighter example shows how to " \ + "perform simple syntax highlighting by subclassing the " \ + "QSyntaxHighlighter class and describing highlighting " \ + "rules using regular expressions.

") + + def newFile(self): + self.editor.clear() + + def openFile(self, path=None): + if not path: + path = QtWidgets.QFileDialog.getOpenFileName(self, "Open File", + '', "C++ Files (*.cpp *.h)") + + if path: + inFile = QtCore.QFile(path[0]) + if inFile.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): + text = inFile.readAll() + + try: + # Python v3. + text = str(text, encoding='ascii') + except TypeError: + # Python v2. + text = str(text) + + self.editor.setPlainText(text) + + def setupEditor(self): + font = QtGui.QFont() + font.setFamily('Courier') + font.setFixedPitch(True) + font.setPointSize(10) + + self.editor = QtWidgets.QTextEdit() + self.editor.setFont(font) + + self.highlighter = Highlighter(self.editor.document()) + + def setupFileMenu(self): + fileMenu = QtWidgets.QMenu("&File", self) + self.menuBar().addMenu(fileMenu) + + fileMenu.addAction("&New...", self.newFile, "Ctrl+N") + fileMenu.addAction("&Open...", self.openFile, "Ctrl+O") + fileMenu.addAction("E&xit", qApp.quit, "Ctrl+Q") + + def setupHelpMenu(self): + helpMenu = QtWidgets.QMenu("&Help", self) + self.menuBar().addMenu(helpMenu) + + helpMenu.addAction("&About", self.about) + helpMenu.addAction("About &Qt", qApp.aboutQt) + + +class Highlighter(QtGui.QSyntaxHighlighter): + def __init__(self, parent=None): + super(Highlighter, self).__init__(parent) + + keywordFormat = QtGui.QTextCharFormat() + keywordFormat.setForeground(QtCore.Qt.darkBlue) + keywordFormat.setFontWeight(QtGui.QFont.Bold) + + keywordPatterns = ["\\bchar\\b", "\\bclass\\b", "\\bconst\\b", + "\\bdouble\\b", "\\benum\\b", "\\bexplicit\\b", "\\bfriend\\b", + "\\binline\\b", "\\bint\\b", "\\blong\\b", "\\bnamespace\\b", + "\\boperator\\b", "\\bprivate\\b", "\\bprotected\\b", + "\\bpublic\\b", "\\bshort\\b", "\\bsignals\\b", "\\bsigned\\b", + "\\bslots\\b", "\\bstatic\\b", "\\bstruct\\b", + "\\btemplate\\b", "\\btypedef\\b", "\\btypename\\b", + "\\bunion\\b", "\\bunsigned\\b", "\\bvirtual\\b", "\\bvoid\\b", + "\\bvolatile\\b"] + + self.highlightingRules = [(QtCore.QRegularExpression(pattern), keywordFormat) + for pattern in keywordPatterns] + + classFormat = QtGui.QTextCharFormat() + classFormat.setFontWeight(QtGui.QFont.Bold) + classFormat.setForeground(QtCore.Qt.darkMagenta) + pattern = QtCore.QRegularExpression(r'\bQ[A-Za-z]+\b') + assert pattern.isValid() + self.highlightingRules.append((pattern, classFormat)) + + singleLineCommentFormat = QtGui.QTextCharFormat() + singleLineCommentFormat.setForeground(QtCore.Qt.red) + pattern = QtCore.QRegularExpression('//[^\n]*') + assert pattern.isValid() + self.highlightingRules.append((pattern, singleLineCommentFormat)) + + self.multiLineCommentFormat = QtGui.QTextCharFormat() + self.multiLineCommentFormat.setForeground(QtCore.Qt.red) + + quotationFormat = QtGui.QTextCharFormat() + quotationFormat.setForeground(QtCore.Qt.darkGreen) + pattern = QtCore.QRegularExpression('".*"') + assert pattern.isValid() + self.highlightingRules.append((pattern, quotationFormat)) + + functionFormat = QtGui.QTextCharFormat() + functionFormat.setFontItalic(True) + functionFormat.setForeground(QtCore.Qt.blue) + pattern = QtCore.QRegularExpression(r'\b[A-Za-z0-9_]+(?=\()') + assert pattern.isValid() + self.highlightingRules.append((pattern, functionFormat)) + + self.commentStartExpression = QtCore.QRegularExpression(r'/\*') + assert self.commentStartExpression.isValid() + self.commentEndExpression = QtCore.QRegularExpression(r'\*/') + assert self.commentEndExpression.isValid() + + def highlightBlock(self, text): + for pattern, format in self.highlightingRules: + match = pattern.match(text) + while match.hasMatch(): + index = match.capturedStart(0) + length = match.capturedLength(0) + self.setFormat(index, length, format) + match = pattern.match(text, index + length) + + self.setCurrentBlockState(0) + + startIndex = 0 + if self.previousBlockState() != 1: + match = self.commentStartExpression.match(text) + startIndex = match.capturedStart(0) if match.hasMatch() else -1 + + while startIndex >= 0: + match = self.commentEndExpression.match(text, startIndex) + if match.hasMatch(): + endIndex = match.capturedStart(0) + length = match.capturedLength(0) + commentLength = endIndex - startIndex + length + else: + self.setCurrentBlockState(1) + commentLength = len(text) - startIndex + + self.setFormat(startIndex, commentLength, + self.multiLineCommentFormat) + match = self.commentStartExpression.match(text, startIndex + commentLength) + startIndex = match.capturedStart(0) if match.hasMatch() else -1 + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + window = MainWindow() + window.resize(640, 512) + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/richtext/syntaxhighlighter/examples/example b/examples/widgets/richtext/syntaxhighlighter/examples/example new file mode 100644 index 0000000..db8e7b1 --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter/examples/example @@ -0,0 +1,79 @@ +TEMPLATE = app +LANGUAGE = C++ +TARGET = assistant + +CONFIG += qt warn_on +QT += xml network + +PROJECTNAME = Assistant +DESTDIR = ../../bin + +FORMS += finddialog.ui \ + helpdialog.ui \ + mainwindow.ui \ + settingsdialog.ui \ + tabbedbrowser.ui \ + topicchooser.ui + +SOURCES += main.cpp \ + helpwindow.cpp \ + topicchooser.cpp \ + docuparser.cpp \ + settingsdialog.cpp \ + index.cpp \ + profile.cpp \ + config.cpp \ + finddialog.cpp \ + helpdialog.cpp \ + mainwindow.cpp \ + tabbedbrowser.cpp + +HEADERS += helpwindow.h \ + topicchooser.h \ + docuparser.h \ + settingsdialog.h \ + index.h \ + profile.h \ + finddialog.h \ + helpdialog.h \ + mainwindow.h \ + tabbedbrowser.h \ + config.h + +RESOURCES += assistant.qrc + +DEFINES += QT_KEYWORDS +#DEFINES += QT_PALMTOPCENTER_DOCS +!network:DEFINES += QT_INTERNAL_NETWORK +else:QT += network +!xml: DEFINES += QT_INTERNAL_XML +else:QT += xml +include( ../../src/qt_professional.pri ) + +win32 { + LIBS += -lshell32 + RC_FILE = assistant.rc +} + +macos { + ICON = assistant.icns + TARGET = assistant +# QMAKE_INFO_PLIST = Info_mac.plist +} + +#target.path = $$[QT_INSTALL_BINS] +#INSTALLS += target + +#assistanttranslations.files = *.qm +#assistanttranslations.path = $$[QT_INSTALL_TRANSLATIONS] +#INSTALLS += assistanttranslations + +TRANSLATIONS = assistant_de.ts \ + assistant_fr.ts + + +unix:!contains(QT_CONFIG, zlib):LIBS += -lz + + +target.path=$$[QT_INSTALL_BINS] +INSTALLS += target diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.py b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.py new file mode 100644 index 0000000..089c434 --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.py @@ -0,0 +1,154 @@ + +############################################################################ +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/richtext/syntaxhighlighter example from Qt v5.x""" + +import sys +import re +from PySide2.QtCore import (QFile, Qt, QTextStream) +from PySide2.QtGui import (QColor, QFont, QKeySequence, QSyntaxHighlighter, + QTextCharFormat) +from PySide2.QtWidgets import (QApplication, QFileDialog, QMainWindow, + QPlainTextEdit) + +import syntaxhighlighter_rc + + +class MainWindow(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + + self._highlighter = Highlighter() + + self.setup_file_menu() + self.setup_editor() + + self.setCentralWidget(self._editor) + self.setWindowTitle(self.tr("Syntax Highlighter")) + + def new_file(self): + self._editor.clear() + + def open_file(self, path=""): + file_name = path + + if not file_name: + file_name, _ = QFileDialog.getOpenFileName(self, self.tr("Open File"), "", + "qmake Files (*.pro *.prf *.pri)") + + if file_name: + inFile = QFile(file_name) + if inFile.open(QFile.ReadOnly | QFile.Text): + stream = QTextStream(inFile) + self._editor.setPlainText(stream.readAll()) + + def setup_editor(self): + variable_format = QTextCharFormat() + variable_format.setFontWeight(QFont.Bold) + variable_format.setForeground(Qt.blue) + self._highlighter.add_mapping("\\b[A-Z_]+\\b", variable_format) + + single_line_comment_format = QTextCharFormat() + single_line_comment_format.setBackground(QColor("#77ff77")) + self._highlighter.add_mapping("#[^\n]*", single_line_comment_format) + + quotation_format = QTextCharFormat() + quotation_format.setBackground(Qt.cyan) + quotation_format.setForeground(Qt.blue) + self._highlighter.add_mapping("\".*\"", quotation_format) + + function_format = QTextCharFormat() + function_format.setFontItalic(True) + function_format.setForeground(Qt.blue) + self._highlighter.add_mapping("\\b[a-z0-9_]+\\(.*\\)", function_format) + + font = QFont() + font.setFamily("Courier") + font.setFixedPitch(True) + font.setPointSize(10) + + self._editor = QPlainTextEdit() + self._editor.setFont(font) + self._highlighter.setDocument(self._editor.document()) + + def setup_file_menu(self): + file_menu = self.menuBar().addMenu(self.tr("&File")) + + new_file_act = file_menu.addAction(self.tr("&New...")) + new_file_act.setShortcut(QKeySequence(QKeySequence.New)) + new_file_act.triggered.connect(self.new_file) + + open_file_act = file_menu.addAction(self.tr("&Open...")) + open_file_act.setShortcut(QKeySequence(QKeySequence.Open)) + open_file_act.triggered.connect(self.open_file) + + quit_act = file_menu.addAction(self.tr("E&xit")) + quit_act.setShortcut(QKeySequence(QKeySequence.Quit)) + quit_act.triggered.connect(self.close) + + help_menu = self.menuBar().addMenu("&Help") + help_menu.addAction("About &Qt", qApp.aboutQt) + + +class Highlighter(QSyntaxHighlighter): + def __init__(self, parent=None): + QSyntaxHighlighter.__init__(self, parent) + + self._mappings = {} + + def add_mapping(self, pattern, format): + self._mappings[pattern] = format + + def highlightBlock(self, text): + for pattern, format in self._mappings.items(): + for match in re.finditer(pattern, text): + start, end = match.span() + self.setFormat(start, end - start, format) + + +if __name__ == '__main__': + app = QApplication(sys.argv) + window = MainWindow() + window.resize(640, 512) + window.show() + window.open_file(":/examples/example") + sys.exit(app.exec_()) diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pyproject b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pyproject new file mode 100644 index 0000000..e42b221 --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["syntaxhighlighter_rc.py", "syntaxhighlighter.py", + "syntaxhighlighter.qrc"] +} diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.qrc b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.qrc new file mode 100644 index 0000000..e5f9abf --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter.qrc @@ -0,0 +1,5 @@ + + + examples/example + + diff --git a/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter_rc.py b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter_rc.py new file mode 100644 index 0000000..34fa7d4 --- /dev/null +++ b/examples/widgets/richtext/syntaxhighlighter/syntaxhighlighter_rc.py @@ -0,0 +1,143 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x06{\ +T\ +EMPLATE = app\x0aLA\ +NGUAGE = C++\x0aTAR\ +GET = as\ +sistant\x0a\x0aCONFIG \ + += qt war\ +n_on\x0aQT \ + += xml networ\ +k\x0a\x0aPROJECTNAME \ + = Assistan\ +t\x0aDESTDIR \ + = ../../bin\ +\x0a\x0aFORMS += findd\ +ialog.ui \x5c\x0a \ + helpdialog.ui\ + \x5c\x0a mainw\ +indow.ui \x5c\x0a \ + settingsdialo\ +g.ui \x5c\x0a t\ +abbedbrowser.ui \ +\x5c\x0a topicc\ +hooser.ui\x0a\x0aSOURC\ +ES += main.cpp \x5c\ +\x0a helpwin\ +dow.cpp \x5c\x0a \ + topicchooser.c\ +pp \x5c\x0a doc\ +uparser.cpp \x5c\x0a \ + settingsdi\ +alog.cpp \x5c\x0a \ + index.cpp \x5c\x0a \ + profile.c\ +pp \x5c\x0a con\ +fig.cpp \x5c\x0a \ + finddialog.cpp\ + \x5c\x0a helpd\ +ialog.cpp \x5c\x0a \ + mainwindow.c\ +pp \x5c\x0a tab\ +bedbrowser.cpp\x0a\x0a\ +HEADERS +\ += helpwindow.h \x5c\ +\x0a topicch\ +ooser.h \x5c\x0a \ + docuparser.h \x5c\ +\x0a setting\ +sdialog.h \x5c\x0a \ + index.h \x5c\x0a \ + profile.h \ +\x5c\x0a finddi\ +alog.h \x5c\x0a \ + helpdialog.h \x5c\x0a\ + mainwind\ +ow.h \x5c\x0a t\ +abbedbrowser.h \x5c\ +\x0a config.\ +h\x0a\x0aRESOURCES += \ +assistant.qrc\x0a\x0aD\ +EFINES += QT_KEY\ +WORDS\x0a#DEFINES +\ += QT_PALMTOPCEN\ +TER_DOCS\x0a!networ\ +k:DEFINES \ + += QT_INTERNAL_\ +NETWORK\x0aelse:QT \ ++= network\x0a!xml:\ + DEFINES \ + += QT_IN\ +TERNAL_XML\x0aelse:\ +QT += xml\x0ainclud\ +e( ../../src/qt_\ +professional.pri\ + )\x0a\x0awin32 {\x0a \ +LIBS += -lshell3\ +2\x0a RC_FILE = \ +assistant.rc\x0a}\x0a\x0a\ +macos {\x0a ICON\ + = assistant.icn\ +s\x0a TARGET = a\ +ssistant\x0a# QM\ +AKE_INFO_PLIST =\ + Info_mac.plist\x0a\ +}\x0a\x0a#target.path \ += $$[QT_INSTALL_\ +BINS]\x0a#INSTALLS \ ++= target\x0a\x0a#assi\ +stanttranslation\ +s.files = *.qm\x0a#\ +assistanttransla\ +tions.path = $$[\ +QT_INSTALL_TRANS\ +LATIONS]\x0a#INSTAL\ +LS += assistantt\ +ranslations\x0a\x0aTRA\ +NSLATIONS \ + = assistant_de.\ +ts \x5c\x0a \ + assistant\ +_fr.ts\x0a\x0a\x0aunix:!c\ +ontains(QT_CONFI\ +G, zlib):LIBS +=\ + -lz\x0a\x0a\x0atarget.pa\ +th=$$[QT_INSTALL\ +_BINS]\x0aINSTALLS \ ++= target\x0a\ +" + +qt_resource_name = b"\ +\x00\x08\ +\x0e\x84\x7fC\ +\x00e\ +\x00x\x00a\x00m\x00p\x00l\x00e\x00s\ +\x00\x07\ +\x0c\xe8G\xe5\ +\x00e\ +\x00x\x00a\x00m\x00p\x00l\x00e\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x16\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/richtext/textobject/files/heart.svg b/examples/widgets/richtext/textobject/files/heart.svg new file mode 100644 index 0000000..ba5f050 --- /dev/null +++ b/examples/widgets/richtext/textobject/files/heart.svg @@ -0,0 +1,55 @@ + + + + + +Heart Left-Highlight +This is a normal valentines day heart. + + +holiday +valentines + +valentine +hash(0x8a091c0) +hash(0x8a0916c) +signs_and_symbols +hash(0x8a091f0) +day + + + + +Jon Phillips + + + + +Jon Phillips + + + + +Jon Phillips + + + +image/svg+xml + + +en + + + + + + + + + + + + + + + diff --git a/examples/widgets/richtext/textobject/textobject.py b/examples/widgets/richtext/textobject/textobject.py new file mode 100644 index 0000000..b828ea3 --- /dev/null +++ b/examples/widgets/richtext/textobject/textobject.py @@ -0,0 +1,129 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/richtext/textobject example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets, QtSvg + + +class SvgTextObject(QtCore.QObject, QtGui.QTextObjectInterface): + + def intrinsicSize(self, doc, posInDocument, format): + renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData).toByteArray()) + size = renderer.defaultSize() + + if size.height() > 25: + size *= 25.0 / size.height() + + return QtCore.QSizeF(size) + + def drawObject(self, painter, rect, doc, posInDocument, format): + renderer = QtSvg.QSvgRenderer(format.property(Window.SvgData).toByteArray()) + renderer.render(painter, rect) + + +class Window(QtWidgets.QWidget): + + SvgTextFormat = QtGui.QTextFormat.UserObject + 1 + + SvgData = 1 + + def __init__(self): + super(Window, self).__init__() + + self.setupGui() + self.setupTextObject() + + self.setWindowTitle(self.tr("Text Object Example")) + + def insertTextObject(self): + fileName = self.fileNameLineEdit.text() + file = QtCore.QFile(fileName) + + if not file.open(QtCore.QIODevice.ReadOnly): + QtWidgets.QMessageBox.warning(self, self.tr("Error Opening File"), + self.tr("Could not open '%1'").arg(fileName)) + + svgData = file.readAll() + + svgCharFormat = QtGui.QTextCharFormat() + svgCharFormat.setObjectType(Window.SvgTextFormat) + svgCharFormat.setProperty(Window.SvgData, svgData) + + cursor = self.textEdit.textCursor() + cursor.insertText(u"\uFFFD", svgCharFormat) + self.textEdit.setTextCursor(cursor) + + def setupTextObject(self): + svgInterface = SvgTextObject(self) + self.textEdit.document().documentLayout().registerHandler(Window.SvgTextFormat, svgInterface) + + def setupGui(self): + fileNameLabel = QtWidgets.QLabel(self.tr("Svg File Name:")) + self.fileNameLineEdit = QtWidgets.QLineEdit() + insertTextObjectButton = QtWidgets.QPushButton(self.tr("Insert Image")) + + self.fileNameLineEdit.setText('./files/heart.svg') + QtCore.QObject.connect(insertTextObjectButton, QtCore.SIGNAL('clicked()'), self.insertTextObject) + + bottomLayout = QtWidgets.QHBoxLayout() + bottomLayout.addWidget(fileNameLabel) + bottomLayout.addWidget(self.fileNameLineEdit) + bottomLayout.addWidget(insertTextObjectButton) + + self.textEdit = QtWidgets.QTextEdit() + + mainLayout = QtWidgets.QVBoxLayout() + mainLayout.addWidget(self.textEdit) + mainLayout.addLayout(bottomLayout) + + self.setLayout(mainLayout) + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/richtext/textobject/textobject.pyproject b/examples/widgets/richtext/textobject/textobject.pyproject new file mode 100644 index 0000000..ed41358 --- /dev/null +++ b/examples/widgets/richtext/textobject/textobject.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["textobject.py"] +} diff --git a/examples/widgets/state-machine/eventtrans.py b/examples/widgets/state-machine/eventtrans.py new file mode 100644 index 0000000..183f117 --- /dev/null +++ b/examples/widgets/state-machine/eventtrans.py @@ -0,0 +1,92 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtCore import * + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + button = QPushButton(self) + button.setGeometry(QRect(100, 100, 100, 100)) + + machine = QStateMachine(self) + s1 = QState() + s1.assignProperty(button, 'text', 'Outside') + s2 = QState() + s2.assignProperty(button, 'text', 'Inside') + + enterTransition = QEventTransition(button, QEvent.Enter) + enterTransition.setTargetState(s2) + s1.addTransition(enterTransition) + + leaveTransition = QEventTransition(button, QEvent.Leave) + leaveTransition.setTargetState(s1) + s2.addTransition(leaveTransition) + + s3 = QState() + s3.assignProperty(button, 'text', 'Pressing...') + + pressTransition = QEventTransition(button, QEvent.MouseButtonPress) + pressTransition.setTargetState(s3) + s2.addTransition(pressTransition) + + releaseTransition = QEventTransition(button, QEvent.MouseButtonRelease) + releaseTransition.setTargetState(s2) + s3.addTransition(releaseTransition) + + machine.addState(s1) + machine.addState(s2) + machine.addState(s3) + + machine.setInitialState(s1) + machine.start() + + self.setCentralWidget(button) + self.show() + +if __name__ == '__main__': + import sys + + app = QApplication(sys.argv) + mainWin = MainWindow() + sys.exit(app.exec_()) diff --git a/examples/widgets/state-machine/factstates.py b/examples/widgets/state-machine/factstates.py new file mode 100644 index 0000000..bd71b20 --- /dev/null +++ b/examples/widgets/state-machine/factstates.py @@ -0,0 +1,111 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtCore import * + +class Factorial(QObject): + xChanged = Signal(int) + def __init__(self): + super(Factorial, self).__init__() + self.xval = -1 + self.facval = 1 + def getX(self): + return self.xval + def setX(self, x): + if self.xval == x: + return + self.xval = x + self.xChanged.emit(x) + x = Property(int, getX, setX) + def getFact(self): + return self.facval + def setFact(self, fac): + self.facval = fac + fac = Property(int, getFact, setFact) + +class FactorialLoopTransition(QSignalTransition): + def __init__(self, fact): + super(FactorialLoopTransition, self).__init__(fact, SIGNAL('xChanged(int)')) + self.fact = fact + def eventTest(self, e): + if not super(FactorialLoopTransition, self).eventTest(e): + return False + return e.arguments()[0] > 1 + def onTransition(self, e): + x = e.arguments()[0] + fac = self.fact.fac + self.fact.fac = x * fac + self.fact.x = x - 1 + +class FactorialDoneTransition(QSignalTransition): + def __init__(self, fact): + super(FactorialDoneTransition, self).__init__(fact, SIGNAL('xChanged(int)')) + self.fact = fact + def eventTest(self, e): + if not super(FactorialDoneTransition, self).eventTest(e): + return False + return e.arguments()[0] <= 1 + def onTransition(self, e): + print(self.fact.fac) + +if __name__ == '__main__': + import sys + app = QCoreApplication(sys.argv) + factorial = Factorial() + machine = QStateMachine() + + compute = QState(machine) + compute.assignProperty(factorial, 'fac', 1) + compute.assignProperty(factorial, 'x', 6) + compute.addTransition(FactorialLoopTransition(factorial)) + + done = QFinalState(machine) + doneTransition = FactorialDoneTransition(factorial) + doneTransition.setTargetState(done) + compute.addTransition(doneTransition) + + machine.setInitialState(compute) + machine.finished.connect(app.quit) + machine.start() + + sys.exit(app.exec_()) diff --git a/examples/widgets/state-machine/pingpong.py b/examples/widgets/state-machine/pingpong.py new file mode 100644 index 0000000..84c5cab --- /dev/null +++ b/examples/widgets/state-machine/pingpong.py @@ -0,0 +1,96 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtCore import * + +class PingEvent(QEvent): + def __init__(self): + super(PingEvent, self).__init__(QEvent.Type(QEvent.User+2)) +class PongEvent(QEvent): + def __init__(self): + super(PongEvent, self).__init__(QEvent.Type(QEvent.User+3)) + +class Pinger(QState): + def __init__(self, parent): + super(Pinger, self).__init__(parent) + def onEntry(self, e): + self.p = PingEvent() + self.machine().postEvent(self.p) + print('ping?') + +class PongTransition(QAbstractTransition): + def eventTest(self, e): + return e.type() == QEvent.User+3 + def onTransition(self, e): + self.p = PingEvent() + machine.postDelayedEvent(self.p, 500) + print('ping?') +class PingTransition(QAbstractTransition): + def eventTest(self, e): + return e.type() == QEvent.User+2 + def onTransition(self, e): + self.p = PongEvent() + machine.postDelayedEvent(self.p, 500) + print('pong!') + +if __name__ == '__main__': + import sys + app = QCoreApplication(sys.argv) + + machine = QStateMachine() + group = QState(QState.ParallelStates) + group.setObjectName('group') + + pinger = Pinger(group) + pinger.setObjectName('pinger') + pinger.addTransition(PongTransition()) + + ponger = QState(group) + ponger.setObjectName('ponger') + ponger.addTransition(PingTransition()) + + machine.addState(group) + machine.setInitialState(group) + machine.start() + + sys.exit(app.exec_()) diff --git a/examples/widgets/state-machine/rogue.py b/examples/widgets/state-machine/rogue.py new file mode 100644 index 0000000..755b847 --- /dev/null +++ b/examples/widgets/state-machine/rogue.py @@ -0,0 +1,202 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtGui import * +from PySide2.QtCore import * + +class MovementTransition(QEventTransition): + def __init__(self, window): + super(MovementTransition, self).__init__(window, QEvent.KeyPress) + self.window = window + def eventTest(self, event): + if event.type() == QEvent.StateMachineWrapped and \ + event.event().type() == QEvent.KeyPress: + key = event.event().key() + return key == Qt.Key_2 or key == Qt.Key_8 or \ + key == Qt.Key_6 or key == Qt.Key_4 + return False + def onTransition(self, event): + key = event.event().key() + if key == Qt.Key_4: + self.window.movePlayer(self.window.Left) + if key == Qt.Key_8: + self.window.movePlayer(self.window.Up) + if key == Qt.Key_6: + self.window.movePlayer(self.window.Right) + if key == Qt.Key_2: + self.window.movePlayer(self.window.Down) + +class Custom(QState): + def __init__(self, parent, mw): + super(Custom, self).__init__(parent) + self.mw = mw + + def onEntry(self, e): + print(self.mw.status) + +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + self.pX = 5 + self.pY = 5 + self.width = 35 + self.height = 20 + self.statusStr = '' + + database = QFontDatabase() + font = QFont() + if 'Monospace' in database.families(): + font = QFont('Monospace', 12) + else: + for family in database.families(): + if database.isFixedPitch(family): + font = QFont(family, 12) + self.setFont(font) + + self.setupMap() + self.buildMachine() + self.show() + def setupMap(self): + self.map = [] + qsrand(QTime(0, 0, 0).secsTo(QTime.currentTime())) + for x in range(self.width): + column = [] + for y in range(self.height): + if x == 0 or x == self.width - 1 or y == 0 or \ + y == self.height - 1 or qrand() % 40 == 0: + column.append('#') + else: + column.append('.') + self.map.append(column) + + def buildMachine(self): + machine = QStateMachine(self) + + inputState = Custom(machine, self) + # this line sets the status + self.status = 'hello!' + # however this line does not + inputState.assignProperty(self, 'status', 'Move the rogue with 2, 4, 6, and 8') + + machine.setInitialState(inputState) + machine.start() + + transition = MovementTransition(self) + inputState.addTransition(transition) + + quitState = QState(machine) + quitState.assignProperty(self, 'status', 'Really quit(y/n)?') + + yesTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Y) + self.finalState = QFinalState(machine) + yesTransition.setTargetState(self.finalState) + quitState.addTransition(yesTransition) + + noTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_N) + noTransition.setTargetState(inputState) + quitState.addTransition(noTransition) + + quitTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Q) + quitTransition.setTargetState(quitState) + inputState.addTransition(quitTransition) + + machine.setInitialState(inputState) + machine.finished.connect(qApp.quit) + machine.start() + + def sizeHint(self): + metrics = QFontMetrics(self.font()) + return QSize(metrics.width('X') * self.width, metrics.height() * (self.height + 1)) + def paintEvent(self, event): + metrics = QFontMetrics(self.font()) + painter = QPainter(self) + fontHeight = metrics.height() + fontWidth = metrics.width('X') + + painter.fillRect(self.rect(), Qt.black) + painter.setPen(Qt.white) + + yPos = fontHeight + painter.drawText(QPoint(0, yPos), self.status) + for y in range(self.height): + yPos += fontHeight + xPos = 0 + for x in range(self.width): + if y == self.pY and x == self.pX: + xPos += fontWidth + continue + painter.drawText(QPoint(xPos, yPos), self.map[x][y]) + xPos += fontWidth + painter.drawText(QPoint(self.pX * fontWidth, (self.pY + 2) * fontHeight), '@') + def movePlayer(self, direction): + if direction == self.Left: + if self.map[self.pX - 1][self.pY] != '#': + self.pX -= 1 + elif direction == self.Right: + if self.map[self.pX + 1][self.pY] != '#': + self.pX += 1 + elif direction == self.Up: + if self.map[self.pX][self.pY - 1] != '#': + self.pY -= 1 + elif direction == self.Down: + if self.map[self.pX][self.pY + 1] != '#': + self.pY += 1 + self.repaint() + def getStatus(self): + return self.statusStr + def setStatus(self, status): + self.statusStr = status + self.repaint() + status = Property(str, getStatus, setStatus) + Up = 0 + Down = 1 + Left = 2 + Right = 3 + Width = 35 + Height = 20 + +if __name__ == '__main__': + import sys + app = QApplication(sys.argv) + mainWin = MainWindow() + sys.exit(app.exec_()) diff --git a/examples/widgets/state-machine/state-machine.pyproject b/examples/widgets/state-machine/state-machine.pyproject new file mode 100644 index 0000000..dafb204 --- /dev/null +++ b/examples/widgets/state-machine/state-machine.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["pingpong.py", "trafficlight.py", "twowaybutton.py", + "eventtrans.py", "rogue.py", "factstates.py"] +} diff --git a/examples/widgets/state-machine/trafficlight.py b/examples/widgets/state-machine/trafficlight.py new file mode 100644 index 0000000..3be9b45 --- /dev/null +++ b/examples/widgets/state-machine/trafficlight.py @@ -0,0 +1,139 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtGui import * +from PySide2.QtCore import * + +class LightWidget(QWidget): + def __init__(self, color): + super(LightWidget, self).__init__() + self.color = color + self.onVal = False + def isOn(self): + return self.onVal + def setOn(self, on): + if self.onVal == on: + return + self.onVal = on + self.update() + @Slot() + def turnOff(self): + self.setOn(False) + @Slot() + def turnOn(self): + self.setOn(True) + def paintEvent(self, e): + if not self.onVal: + return + painter = QPainter(self) + painter.setRenderHint(QPainter.Antialiasing) + painter.setBrush(self.color) + painter.drawEllipse(0, 0, self.width(), self.height()) + + on = Property(bool, isOn, setOn) + +class TrafficLightWidget(QWidget): + def __init__(self): + super(TrafficLightWidget, self).__init__() + vbox = QVBoxLayout(self) + self.redLight = LightWidget(Qt.red) + vbox.addWidget(self.redLight) + self.yellowLight = LightWidget(Qt.yellow) + vbox.addWidget(self.yellowLight) + self.greenLight = LightWidget(Qt.green) + vbox.addWidget(self.greenLight) + pal = QPalette() + pal.setColor(QPalette.Background, Qt.black) + self.setPalette(pal) + self.setAutoFillBackground(True) + +def createLightState(light, duration, parent=None): + lightState = QState(parent) + timer = QTimer(lightState) + timer.setInterval(duration) + timer.setSingleShot(True) + timing = QState(lightState) + timing.entered.connect(light.turnOn) + timing.entered.connect(timer.start) + timing.exited.connect(light.turnOff) + done = QFinalState(lightState) + timing.addTransition(timer, SIGNAL('timeout()'), done) + lightState.setInitialState(timing) + return lightState + +class TrafficLight(QWidget): + def __init__(self): + super(TrafficLight, self).__init__() + vbox = QVBoxLayout(self) + widget = TrafficLightWidget() + vbox.addWidget(widget) + vbox.setContentsMargins(0, 0, 0, 0) + + machine = QStateMachine(self) + redGoingYellow = createLightState(widget.redLight, 1000) + redGoingYellow.setObjectName('redGoingYellow') + yellowGoingGreen = createLightState(widget.redLight, 1000) + yellowGoingGreen.setObjectName('redGoingYellow') + redGoingYellow.addTransition(redGoingYellow, SIGNAL('finished()'), yellowGoingGreen) + greenGoingYellow = createLightState(widget.yellowLight, 3000) + greenGoingYellow.setObjectName('redGoingYellow') + yellowGoingGreen.addTransition(yellowGoingGreen, SIGNAL('finished()'), greenGoingYellow) + yellowGoingRed = createLightState(widget.greenLight, 1000) + yellowGoingRed.setObjectName('redGoingYellow') + greenGoingYellow.addTransition(greenGoingYellow, SIGNAL('finished()'), yellowGoingRed) + yellowGoingRed.addTransition(yellowGoingRed, SIGNAL('finished()'), redGoingYellow) + + machine.addState(redGoingYellow) + machine.addState(yellowGoingGreen) + machine.addState(greenGoingYellow) + machine.addState(yellowGoingRed) + machine.setInitialState(redGoingYellow) + machine.start() + +if __name__ == '__main__': + import sys + app = QApplication(sys.argv) + widget = TrafficLight() + widget.resize(110, 300) + widget.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/state-machine/twowaybutton.py b/examples/widgets/state-machine/twowaybutton.py new file mode 100644 index 0000000..27ed58e --- /dev/null +++ b/examples/widgets/state-machine/twowaybutton.py @@ -0,0 +1,70 @@ + +############################################################################# +## +## Copyright (C) 2010 velociraptor Genjix +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import * +from PySide2.QtCore import * + +if __name__ == '__main__': + import sys + app = QApplication(sys.argv) + button = QPushButton() + machine = QStateMachine() + + off = QState() + off.assignProperty(button, 'text', 'Off') + off.setObjectName('off') + + on = QState() + on.setObjectName('on') + on.assignProperty(button, 'text', 'On') + + off.addTransition(button, SIGNAL('clicked()'), on) + # Let's use the new style signals just for the kicks. + on.addTransition(button.clicked, off) + + machine.addState(off) + machine.addState(on) + machine.setInitialState(off) + machine.start() + button.resize(100, 50) + button.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/systray/images/bad.png b/examples/widgets/systray/images/bad.png new file mode 100644 index 0000000000000000000000000000000000000000..c8701a241a458d257e2e71c3d1af06007927fb86 GIT binary patch literal 2496 zcmZ`*cQ_S_8-A@EBxGb|ud^)M5P!1g#**la`B%_oOp(0tiX^3klA>AVs zHx<>vEpci1xqscie(&>s@B4h?&+mJl@2riL87I3iI{;4d0g~OO7jH%bfoW3{+MRSa zjUmL&%ouggMCUgXHtGS_kj>#g{|yFXg)0%8Mb=QVr3vdK6B}VCktAnz17IArv2ZZi zZ2dnlFo2N(OpIV=1Pc?kY?2wQ%pkCUjRovmz`=^Gtl%VI8v$Hw;ARI8JGOIxmjirT z!OsZ+PVCqQ!EF%Yf-pBkxFO1eojefR4sl*c@IsOgQhbo+hl~JZ1t7Nr@;jg)h+RV1 zEd)hjC<#MZ1S+CX6$No8)OO-GF{q0}LmZkC(2{_*By^;pD+N7i?2*P^8R*NxKoM8c^E5TzXC|RV6qFQyJ4mXvJws|!CV;@DzH?6l`5=NVMBzi8tl|y{~H|D;j94{ zO}J{pO$&##;jWFtIyj;O4_$cb!AlR`dvHu2eg^P2!0~-JVTb@jP>c|0gdk&_+z;x0 z1d|YAf>2Y0nIhZ_r_B&aMid#*2NAPLbHth>&I0ikNU%hrC6cU=Y>gCaq}m|O7U_04 zXO9efWIN)#6LOq!(FJ*~xa5j_HxwR1kvocy;OY@v^FWCQNo-kKZ=T@sPx7S zA5{6^rY~;$q1GRFj-&nr?w&wH02%|(L_u>PS_07;g!@#qQSl%c4}L9V=)|ykvNRT<3&8i67Vtse|gGVB035pznTaAxwH;v&L}L+>ErO*}CWeY_TJgj2t3f(TmqS@*MfPYj67s20GZZ zGyieMgyjimpUrTuyBmLVmrTFLfX2YV!TymKcAKivuzj%K;;zI60?FQR#d3wgw8-oI z)p*I5h3^h8oLV53JQx}(UX3e?e6xD(YjH@G$3B(+;5@eTbX)p*M*CFFDW0jWnV?;* zKHeoa4Fy!XMyhtdrHW>EK6z4fSg?*bYxY-VSmsQ>vBN9-6pHJkJ%t^PDJ>g=7t~3V z9jUh*t_XEFo(T(zTX@V~HKQDN?L>&wX%vBk3*xKU5_33%5mVax$U|ZgEMb096 zaa!P9V_-d1TRixH%fk_#@n=!AGz0IHlz>B`XD~c8e|L)(gcr~$o zo-0@iMeH z!D>EXS4);vv7}g{mPekl?R8PTnqtNv`P|=msFo>o5zd4DE<$RPDx^=c_3erD^exI7 ztqI%<-ag(6_0O~E0h}lNZ47uO<23IF@;mr+hPxz-318T}Pwr&PO7`YQk&i+<*}e@u zN!@d<*>KNc-C?uWYf?kqDdsP#iJEuI_bjVx230SobJzS`RtYS+&^9WNI-+qnHFV>gAX*=9Cmea&M0{XLsw9m-z?88 zYs@>lT{CH7FPZqpveb*}&#uWbhm-d6F}2W~B&4fm;;1c^TZkODeT9h=rdC#Dsn6GhfyzA7aY~i)p9$F&T-L2;O8l@-ZF41c#g)y>f&Nlv@^=!XdJ6 zYsQ_f6g6vP^w>7k@(OAtXC&9qj_?<@41evmsSo59rN}l?u3Ej~L1qlm##U_Pw7n>AA_r%SmXesH8o|t4Y z^;!Axy~H!k*XwmiN7MtBnBSsLe&QmYOtbi0-q96WZJI7@*OHj+=$Ri`9=aq)?BOT#_4cb?XLvIzpySaynx&erVUQ9=yQCR@ zJc5!i*=?`n?ay|nw;`6r)*)U#wobBw^s<`oWq+$~n&;1_8R_)cGN~Q?`|4u#cl)-P(H*>5nTy~<}eaLe1o8P+2;WsCI4!L$8t9~mo zYneOnkRI|WCy-g__Ibi>{=%k$y5+5=PrJPvb)~pZ`o1Vs{4Csicjvh2^-n?_=hf8$ zjthikx(yDyE{&~|ds!Ra=r6}KZJ`~hBKVC+8q|!Qrb+&zAq_$mLcS!S@aW@iO$WLsmeVj2D{ww*m`+wNj|C6Jr(ml>B*wgsm Omx^p+MXEFQO!^xC;V-$kf%K1|ZNK^z9!J0r1Jg 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 H-GBUl5R*?B literal 0 HcmV?d00001 diff --git a/examples/widgets/systray/images/trash.png b/examples/widgets/systray/images/trash.png new file mode 100644 index 0000000000000000000000000000000000000000..4c24db926d6fedc7cfe2b92a9b62c8aecd25f8be GIT binary patch literal 12128 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 literal 0 HcmV?d00001 diff --git a/examples/widgets/systray/main.py b/examples/widgets/systray/main.py new file mode 100644 index 0000000..4fad002 --- /dev/null +++ b/examples/widgets/systray/main.py @@ -0,0 +1,58 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +from PySide2.QtWidgets import QApplication, QMessageBox, QSystemTrayIcon + +from window import Window + +if __name__ == "__main__": + app = QApplication() + + if not QSystemTrayIcon.isSystemTrayAvailable(): + QMessageBox.critical(None, "Systray", "I couldn't detect any system tray on this system.") + sys.exit(1) + + QApplication.setQuitOnLastWindowClosed(False) + + window = Window() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/systray/rc_systray.py b/examples/widgets/systray/rc_systray.py new file mode 100644 index 0000000..2d59adc --- /dev/null +++ b/examples/widgets/systray/rc_systray.py @@ -0,0 +1,2581 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.15.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00d\xb4\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x02\xe8\x00\x00\x02\xe8\x08\x06\x00\x00\x00*Z\x00\x90\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\ +\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1e\ +4hf\xd9|\x00\x00\x00\x06bKGD\x00\xff\x00\ +\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00d4IDATx\ +\xda\xec\x9d\x07\xb8U\xc5\xb9\xbf\xf7i\x1c\x0e\xe7\xd0\xcb\ +\x01Tz\x95\xa6 \xbd\x8b\x14E@\x10Q\x14\xa4\x05\ +\x14\x14\x14AAD\xaaT\xe9\xe7h\xd4\xab&\xc6$\ +\xb6\xc4DM\xa2&\x1a{\x895\xb1w\x05\xd9k\xa7\ +\xdc\x14M\x8c\xc66\xf7\x1b\xf6J\x82W\x84\xb5\xf6\xd9\ +k\xd6\xac\xb5\xdf\xf7y\xde\xe7\xb9\xf7\x7f\xff\xf7F\xcf\ +\x9e\xf9\xe6\xb7g\xcf|\x93H\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00@.Q(\xd6um\x22\xb6\x12;\x8a=\xc4\ +>\xe2q\xe2(\xf1x\xf7\xbf\xd6\xf6u\xff\xe7\xda\xa3\ +\xdc\xff\x9dz\xee\xff-\x00\x80\xaaRM\xac\xef\xd6\x96\ +\xee\xfb\xd5\x9b~\xfb\xd5\xa1\xd1\xe2\x08\xf7\xbf\xee\xed\xfe\ +\xcf\xdb\xbb\xff;\x8d\xf7\xabk\xf9\xfc9\x01\x00\xc0\x06\ +j\x8a\xdd\xc4\x93\xc4\x05\xe2*\xb1B\xfc\x81x\x8f\xf8\ +\x94\xf8\x8e\xf8\x81\xa8\xb2\xec?\xc5\xdf\x8bo\x8a\x0f\x8a\ +7\x89;\xc5\xe5\xe2,q\x8c\xbb\x90\xd6\xe3c\x02\xc8\ +)\x1a\x89\xbd\xc4\xb1\xe2\x1cq\x85[\x97n\x13\x1f\x16\ +\xdf\x12\xff(~\x1c@]\xfa\x8b[\x93~#\xfeB\ +\xfc\xbe[\x97V\x8a\xe7\xbau\xa9\x93X\x83\x8f\x09\x00\ +\x00\xaaB\xb3Dz\xf7h\xb6\xb8^\xbc\xd9]|\xfe\ +\x14\xc0\xe2\x16\x94\x1f\x8a/\x88w\x8a\xbb\xc4\x0b\xc4\x13\ +\xc4\xe6|\xbc\x00\x91C\xefT\xb7\x16\xc7\x89\x17\x8aW\ +\x88?\x17_\x16?\x8aP]J\x89\x8f\xbb\x1b\x1ak\ +\xc5\x99\xe2\xb1\x89\xf4/\x8c\x00\x00\x00\xfb\xa8\x9eH\xef\ +8\xebEB\xef\xf8<\x90H\xef\x06\xa9\x98\xfb\x81\xbb\ +H^\x93H\xff\x0a\xa0\x7f\xc6\xae\xc3p\x00\xb0\x82\x86\ +\x89\xf4\xd1\xb7E\xe2\xf5\x89\xf4\xafr\xff\xc8\x81\xba\xa4\ +w\xf8\x7f%^.N\x15\xbb\x8aE\x0c\x07\x00\x80x\ +\x93\x97H\xff\xcc\xaaw\xc5\xbf#\xbe$~\x96\x03\x8b\ +\x9eW\xbf\x14_\x17otC\xbb>\x0b_\xca\xb0\x01\ +\x08\x94Z\xe2 q\xb1x\x8b\xf8.\xb5\xe8+\xfeK\ +|\xde\xddL\x98&\xb6e\xc8\x00\x00D\x1b}\x09J\ +\x9f}\xdc(>\x9a#;PA\xf8\xb6x\xb5x\xa6\ +x\x04\xc3\x0a\xa0J\xb4H\xa4\xcf\x88\x7f\xcf\x9d[\xd4\ +\x18\xff\xfe\xdd\xad\xe9\x1b\xdd\x1a\xcf\xaf\x7f\x00\x00\x16\xa3\ +;\x13\xe8\xb3\x8c\x9b\xc5\xa7\x13\xec\x8e\x07\xe1\xe7\xe2\xb3\ +\x89\xf4O\xd0\xfaXLu\x86\x1d\xc0A)sC\xa4\ +\xbe\xb0\xa9\x7f\xb5\xfb\x92:\x92u?\x11\x1fK\xa4\xcf\ +\xb4\xeb_\xfe\x0a\x18v\x00\x00\xe1\xa2\xcf\x8f/I\xa4\ +\xcf-\x06\xd1\x9d\x00\x0f\x1d\xd8\x9fqw\xb2t`\xa7\ +\x15$\xb0Q\x90\x9e\x0b\x1b\xdd\xb9\xf1\x05u\xc2\xb8\x1f\ +\xb9k\xc2y\x09.\xc5\x03\x00\x18A\x9f#\xd7\xad\xc4\ +6\x89/\xb2\x10Y\xe7\x1eq\x878 A\x7fd\xc8\ +\x1d\x0a\xddP~U\x22\xdd\x06\x95Z`\x8f_\xb8_\ +\x94V\x8b]\x18\xaa\x00\x00\xd9\xe5\x98D\xfa\xe8\x0a\x17\ +\xa8\xa2\xa3#V\x8aC\x13\xfc\xe4\x0c\xf1C\xef\x94\xeb\ +\x07\xc6\xae\x15\xff\x97\xf9\x1e\x19_u\xc3z'\x860\ +\x00@f\xe8\x17\xee\xf4\xcf\xc4\x5c\xa4\x8aG\xfb4\x1d\ +\xd6\xf5\xf9\xd0<\x866D\x14\xfd\xab\xd0\xb0D\xba\xf5\ +\xe1\xdf\x98\xd7\x91W\xf7\x90\xd7\x8f)udh\x03\x00\ +\x1c\x9c\x96\x89\xf4E\x9f7Y\ +\x7f\xde\xa9\ +\xef\xce\x943\x1d\x01\xc0$\xba\xe8\x5c\xe1\xee\x16P\x8c\ +\xd1\x06?I\xa4/\xfe5dz\xe6,\xfaK\xda\xf5\ +\xee\x976\xe6\x04\xda\xe0?\xc4\x8d\x89t\xc7 \x00\x80\ +\xc0\xa8\x96H\xb7%\xe3\x11\x0f\xb4\xf9\xd2\xd6j\xb1\x8c\ +\xe9\x9a3\xd4w\xbf\x9c}\xc2\xf8GK\xfd\xbd8[\ +,`\xba\x02@\xb6\x19\x9fH\xf7\xa6\xa6\xd8b\x14\xdc\ ++NI\xa4\x1f\xc7\x82x\xa2\x1f\x18:G\xfc3\xe3\ +\x1d#\xe2\xef\xc4c\x99\xba\x00\x90\x0dtk\xb2_S\ +X1\xa2>&\x1e\xc34\x8e\x1dC\xc5\x17\x18\xdf\x18\ +Q\xf5\xcb\xa4m\x99\xc6\x00\x90\x09\xfa\x9c\xb9\xeeeN\ +g\x16\x8cC\xc7\x17}\x99\xb91\xd3:\xf2\xe8~\xd3\ +\xb71\xa61\x06\xea;\x5c[\x13\xb82\xb8U\x03\xb1\xbd8@\x9c \xce\x16\x97\ +\x89\xdb\xc5k\xdd\x9ar\xb7\xf8\xa8[k\x0eV\x8b\x9e\ +\xd9\xafn\xdd\xbb_=\xbbI\xbcB\x5c+.\x14\xcf\ +\x14O\x10\xfb\x88\xad\xc5b>\x0b\xaf:\xe2D\xa68\ +\x00\x1c\x0c\xa9\xe9\x89\x87(\x98_\xb5\x898D\x9c!\ +\xaep\xc3\xf2/\xc4\x17D\xc7\x12\xdf\x16\xef\x17\xaf\x17\ +W\xba_\x14\x06\x89\x87\xf1\xf9\x1d\xc8\x07\x12\xfc\xbc\x1c\ +%\xba\x8b\xcf1n\xffk\xbe\xd8L:~\x8b\xa1\x9e3\xe3(\x1f\x811^\xfcs\ +\x9c~\xc1\xeb\xeb^p|\x95\xba\x10\xba\xbf\x16\xcf\x13\ +[\xc4\xaf.\xbd\x9fH\xbf\xa4\x0b\x00\x11\xa6\x9axe\ +\x5c\x0aSC\xf7<\xf4\x83,>\xd6\xfa\x98\xb8(^\ +gC\xbf\x14+\x13\x5c\xd4\xca&\xa5q\xaaK-\xdd\ +3\xe5O3\xff\xad\xf5\x1e\xb7_|\xedx\xbd\x8e\xbc\ +:A;F\x80H\xa2\x7f\x9e\x7f\x22\x0e\xbbR\x83\xdc\ +\xc7\x81v\xb3\xd0D\xeal\xa8\xbe\xc8u\x5c|\xda7\ +\xea\xc7\x8d\xca)+U\xa6\x83\xf8j\xd4\xc7\x83n\x87\ +8\xd6\xed\xe3\xcd]\x97h]|\xd7\xefA\xf4\x8aO\ +P\xff\x99X\x97\xb2\x02\x10\x1d\x86\x88\x7f\x88r\xe1)\ +w{\x01?\xc1\xa2\x12y\xf5\xce\xe2\x05\xf1\xd8U\xdf\ ++\xf6\xa3\xbcd\x8c>\xd2\xf2a\xd4w\xcb\x97\xd3\xa6\ +5\x16>\xe8\xb6\xdd\xad\x1b\xfd\xba\xf4\x96\xd8\x8d\xf2\x02\ +`7\xfa\xe7\xae\x8d\x89\xf4\xcf\xf2\x91,6\xc7\xb8;\ +\xaf{\xa3\xfc\xd8Fa\xa1J\xd5\xae\xadRM\x9b*\ +\xa7m[\xe5t\xeb\xa6\x92\xfd\xfa)g\xc4\x08\xe5\x8c\ +\x1b\x97v\xd2$\xe5L\x9e\xac\x9c)S\x943k\xd6\ +\xd7L\x9dqF\xfa\x7f\xae=\xe9$\xe5\x8c\x1c\xa9\x9c\ +\xc1\x83\x95\xd3\xab\x97r\xbavM\xff\xdfm\xdcX9\ +\xc5\xc5\x91\xf9\xbb\xecu?\xdb\x81\xd1^\x0c?O\xa4\ +{\x13\xf3\xd3\xb2w\xf4\xf1\xa0\xab\xa3\xfa\x99\xe7\xb9\x17\ +>\x7fJ\xa8\x8d\xa5\xbb\xdd]\xf5\x88_,\xd5\x9d\xd9\ +\xce\xa3\xd4\x00\xd8IM\xf1\xd6\xa8\x16\x18}\x8c\xe5\xe6\ +\x08\x05p\xa7\xbc\x5c9G\x1e\xa9\x9cA\x83\x943~\ +\xbcrf\xcfV\xce\xd2\xa5\xca\xd9\xb2E9W\x5ca\ +\xd4\xe4\xd6\xad\xcaY\xbe\x5c9\xf3\xe7+g\xeaT\xe5\ +\x8c\x1a\xa5\x9c\x1e=\x94\xd3\xac\x99rJJ\xac\xfc\x1b\ +\xea\xb0s\xbc{\x84)\xa2c\xf6\x87b\x0d\xca\xce!\ +\xd1\x1d'\xee\x8e\xe2g\xac\x8f\xb1\x9c,\xfe\x92\x10\x9b\ +\x13\xea\x0d\x84\xeb\xdcM\xa2\x08\x07\xf5+\x12\xe9\xbbg\ +\x00`\x09m\xc4W\xa2VLt{>\xfd\x9c\xf3}\ +6\x17\xee:u\x94\xd3\xa9\xd3\xbe\xdd\xef\xd4\xcc\x99\xfb\ +\x82p\xaa\xa2\xc2x\x08\xaf\x92\x1b7*\xe7\xfc\xf3\xd3\ +\xbb\xf6\xfd\xfb+\xa7E\x0b\x95\xaaV\xcd\x8a\xbf\xef\xc3\ +n\x08\x8a\xe89\xf5g\x13\xb4b<\x18\xfa\xbc\xf9\x9b\ +Q\xfb\x5c\xab\xb9\xafVr\xe93w\xd5\xbd\xd5GE\ +\xf7\xbd\x87\xc7\xc5\xc6\x94\x1f\x80\xf0\xd1\xaf\x82\xfe)J\ +\x05D\xef\x9a\x8e\x17\x1f\xb5\xad0\x97\x95)\xa7sg\ +\xe5\x8c\x19\xa3\x9c\x05\x0b\x94\xb3ys\xb4\x82\xb8\x1f+\ ++\x95\xb3b\xc5\xbe\x1d\xf7}\xc7o\xf4q\x99\xbc\xbc\ +P\xbb\xbfL\x8afOu\xf9\xc7O\xf4\xa2\x0c}\x8d\ +\x91\xe2_\xa3\xf4Y\x16\xbb\x9d>xL\x08\xff\xed/\ +\xdd\xe3M\x11\x0c\xe9\xef\x89\x9d)C\x00\xe1qZ\x22\ +\xfd\xf2ad\xcer\x9e\xe0\xf6\xa7\xb5\xa1\xf8\xa6\x9a4\ +Q\xa9\x81\x03URBjj\xe5\xca\xf8\x86q\xaf\xea\ +/$g\x9f\xad\x9ca\xc3\x94s\xc4\x11\xa1\x04v\xdd\ +\xd7\xfe\xa4\xe8\x1d}\xd1s\xf0t\xca\xd1\x7f\xd0ga\ +?\x8f\xd2Q\x96\xa9\xe2\xf3\x04R\xfc\x06\x7f\xe6\x1e\xc3\ +\x8cXH\xff\x9b8\x9cr\x04`\x1e\xfd\x1cyd.\ +\x83\xeav{\xf7\x86]h\xf5\xb1\x8e\xae]UJ_\ +\xbc\x5c\xbb\x96@\xee%\xb0\x7f\xeb[\xca\x91/1N\ +\xc3\x86F?+}\xeciX\xf4\xfa\xa5_\x9a\xe35\ +I_\x9c\xad\x88\xd2\x86\xc18\xf7\xd7\x1bB(z\xf1\ +v\xb1w\xb4\xea\xd2\xa7\xe2l\xe2\x12\x80\x19tG\x84\ +\xeb\xa3R \x8et{\x05\x87VT\x1b4H\xef\x08\ +\xcf\x9f\xafR;w\x12\xba\xab\xa2\xbe\x88:f\x8cJ\ +\xea\xcb\xa7\x86v\xd7\x7f\x12\xbd\x17J\xf5\xa3F\x059\ +X\x97\x8a\xc5\x9b\xa3\xf29\x0d\xe0\xf2'V\xc1\xeb\xa2\ +\xf7B\xa9\xee\xee\x96G|\x02\x08\x8e:\xe2\xfdQ(\ +\x08\xfa\xd5\xcf\xcb\xdd\x07kB\xb9\xd8y\xec\xb1\xca\xb9\ +\xf0BBuP^v\x99rN9E9-[\x06\ +\x1e\xd6\xf5C0\x15\xd1\xea\xa3~\xbbX\x92cu\xe9\ +\x81(|6\xba\x8f\xf9w\x09\x98\x98\xa5\xf6\x8c\x97\x8a\ +\xb5\xa2S\x97n\xcd\xb1\xba\x04`\x8c\xfa\x89t\xd7\x08\ +\xeb; \x9c#\xben\xba\xf5\xa1\xbe\xe0\xa9[\x1e.\ +\x5c\x98\xbe\x00I\x886fj\xf5j\xe5\x8c\x1e\xad\x9c\ +F\x8d\x02\xfd\x8c\xdf\x16\x17\x89%\xd1X\x0c\x1fM\xa4\ +[\x0c\xc6\x1d\xdd\xc5\xe6\x05\xdb?\x0f\x1d\xa2V\xf1\x1a\ +1\x06\xe0\x8b\xe2\x99\xd1\xe9D\xa5\xebRm\xe2\x14@\ +\xf6h\x22\xbeh\xfb\xe4\x1f->i\xb28\xe6\xe7\xa7\ +[ \xce\x99\xa3\x9c]\xbb\x08\xcb6\x84\xf5\x0b/\xdc\ +w\xf16\xc8\xfe\xebOG\xa7\xb3\xc2+\xee\xdc\x8d+\ +\xed\xc5\xf7m\xff\x1c\xc6\xf3\xf2'\x1a\xf0~\xf7\xe8T\ +\x04\xea\xd23b\x03b\x15@\xd5i+\xee\xb6\xfdg\ +\xe3\x1f\x9b\xec\xbe\xa2_\xe8<\xe5\x14\x95\xd2\xfd\xbd\x09\ +\xc5v\xaa\xcf\xfb\xebWQ\xbbtI\x7f\x91\x0a`\x1c\ +\xdc&\xb6\x8aF\xbb\xb3\xd61\xacK=\xc5\xbf\xd8\xfc\ +\xb7o\xcf\xeb\x9f\x18\x82\xfa\xb5\xe4\xc6\xf6\xd7\xa5\xd7\xc4\ +#\x88W\x00U\xdb\xa1\xdac\xeb$\xd7]\x10\xce\x10\ +_3Q\xf8\xf49\xe7\xce\x9dU\xea\x9cs8\xc2\x12\ +\xb5]\xf5K/U\xa9\xc1\x83\xd3]t\xb2<.\xde\ +\x10g\xd9\xdf\x96\xf1\x1d\xb1e\x8c\xea\xd2Q\xe2\x1fm\ +\xfd{\xeb\xb6\x89\xe7\x89\xef\x10\x161$\x7f'\x8e\xb5\ +?\xa4\xbfAH\x07\xc8\x8cn\xe2\x1fl\x9d\xdc-\xdc\ +\x1dL#\xad\x11\x87\x0eU\xce\x9a5\x84\xdd\x88\x9b\xdc\ +\xba5\xfd\xcbG\xbdzY\x1f'\xfa\x17\x9c\xe6v/\ +\x86\xfa\x8bv;v\xce\x83\xef\x1aEw\x16\xb4\xc5\xef\ +\x88\xe5\xfc\xc2\x07\x10+\xfa\xd8\xba\x08\xea\x9d\xca\xb3\xdc\ +\x0b{\x81\x16\xb7\x1a5Tj\xe4H\x95\xda\xb0\x81p\ +\x1b\xb7\x1d\xf5\x9d;U\xea\x8c3T2\xcb\x97J\xdf\ +\x12g\xd8\xfd<\xb7~u4\xca\xaf\xfb\x0d\x10?\xb0\ +u\xd7\xfc\x02.\x81\xa2\x85\xea_\x98O\xb5;\xa4'\ +\xc5\x0e\xc4.\x80C\xd3[\xfc\xd0\xc6\x89\xdc\xd8DO\ +\xf3\x9a5\x953a\x82r\xb6m#\xcc\xc6\xdd\x8a\x0a\ +\x95\x9c>]9M\x9adu\x0c\xfd\xc8\xee\xdd\xf4?\ +\x89]\x22X\x97\x06\x89\x1f\xb1k\x8e\x98\x99\xd7\x88u\ +\xec\xadK\xef\xc7\xec\x18\x1e@ \xc7Z\xac\xdc9\xd7\ +\x1dZ^\x09\xb2\x80\xd5\xae\xad\x1c\xfd\xc2'\x8f\x09\xe5\ +\xa6\xfa!)\xddS=K\xe3\xe9M\xbbw\xad~\x9f\ +H\xdf/a\xd3\xa0\x8aw`\xcef\xd7\x1c#\xe4\xb3\ +b\x7f\xbb\xef\xca\x1cN\x0c\x03\xf8:G\x8b\x7f\xb5m\ +\xd2\xd6\x16\xaf\x0e\xb2h\xe9v|'\x9e\x98>\x9fL\ +P\xcdm++UJw~i\xd80\xabg@\xeb\ +\xda\xb9\x18\xea\xfb%GF\xe4X\xcb?l\xfc5\xef\ +G\x04>\x8c\xa0\xfa\xe1\xb5\xcd\xf6\xbe\xe7\xa0;\xc65\ +'\x8e\x01\xfc\x97\x16\x09\x0b\xfb\x09\xeb'\xd6\x1f\x0b\xaa\ +P\x15\x15)g\xe4H\xe5l\xd9B0\xc5\xaf\xaa{\ +\xdaO\x9a\x94>\xee\x94\x85\xb1\xa6{\xf3w\xb7\xf7\x82\ +V3\x8b\xebRg\xf7H\x8eU\x7f\xb7\xc1\xe2o\x09\ +z\x18q\xef\x16[\xdbY\x97\xf4\xc3c\xf5\x89e\x00\ +\x89DS\xf1-\xdb&\xe9\xb7\x82\xfa\xe9X\xb7K\xec\ +\xd1C9k\xd7\x12D\xf1\xd0]_\x8e?>\xfde\ +.\x0b\xcfr\xcf\xb0\xb7\x1f\xb1\x8d\x8f\x86\xb4J\xa4/\ +\xb5ZuA}\xb1\xbb\x03I\xc0\xc38\xa8\x9b-L\ +\xb0\xb3.=\x9d\xe0\xc5Q\xc8q\xf4\xc2\xfc\xb2M\x13\ +\xb3\x86xeP\x05\xa9M\x1b\xe5,]J\xf8D\x7f\ +]_\xd6\xafWN\xef\xde\xe9/wU\x1c\x83;\xc5\ +b\xfb\x16\xc3\xdf\x88\xa5\x16\xd5\xa5\x86\x89t\x8fdk\ +\xfeF\xb5\xc4\xef\x11\xe80\xa6^\xe6v\x22\xb2\xac.\ +=jY]\x020F\x89\xf8\x84M\x13\xb2\xa5\xfb\x5c\ +q\x10\x17@\x93S\xa7\xf2\xc0\x10V\xcdy\xf3\xb2r\ +>\xfd^\xf1p\xfb\x16\xc3_\x88E\x16\xd4\xa52\xf1\ +)\x9b\xfe6\x1d\xc4\xc7\x09q\x18s\xef\xb0\xb3g\xfa\ +\x9db\x01q\x0dr\x89|\xf1v\x9b&\xe2\x88 ^\ +\x04\xd5;\x9e\x83\x06)\x87\x0b\xa0\x98\xc5\x1e\xea\xce\xe8\ +\xd1*YXX\xa5\xb1\xf9\x92x\xac}\x8b\xe1\x0db\ +^\x88uI\x7fA\xb8\xc7\xa6\xbf\xc9x\xb7#\x0f\x01\ +\x0esA}\xb7\xa2\x8f}u\xa9\x92\xc8\x06\xb9\xc4v\ +\x9b&\xe0\x1cqo\xb6\x8bM\xf3\xe6\xcaY\xb6\x8cP\ +\x89\xc1\xb8f\x8dJv\xe8P\xa51\xfa\xbe8\xcb\xbe\ +\xc5pc\x88u\xe9\x06[\xfe\x0e\xba\x85\xe2E\x9c7\ +\xc7\x1c\xf4=\xf1d\xfb\xea\xd2\x22b\x1b\xe4\x02\x17\xda\ +2\xe9\xf4\x99\xb7\xed\xd9.0\xc5\xc5\xe9\xe7\xdc+*\ +\x08\x91\x18\xbc\xba-cYY\x95\xc6\xecv\xfb\xce\x7f\ +\x9e\x13B]Ze\xcb\xbf\x7fM\xf1\xfb\x045\xccq\ +\xd7\xb8\x17\xa3-\x99\x97_\x8aS\x89o\x10g\xc6\x89\ +\x9f\xdb0\xe1\xca\xc4\x1b\xb3\x5cP\xf4C3\xa9K/\ +%4\xa2Y/\xbb\xac\xca\xbb\xe9?\x10K\xedY\x0c\ +\xff%\x0e1X\x97&\x88_\xd8\xf0\xef^_\xbc\x8b\ +p\x86\xb8\xcf]vm\x1e\xfcS\xecG\x8c\x838\xd2\ +_\xfc\xd8\x86\x89v\x84\xf8`6\x0b\x89>\x0f|\xca\ +)\x5c\x02\xc5p\x9d6-\xfd\x0bN\x86\xe3\xf8\x01\xb1\ +\xa9=\x8b\xe1\x07\x89t\x1f\xf2\xa0\xe9kK]\xd2=\ +\xa1\x7fC(C\xfc\x8a?\x13\x1b\xdaS\x97\xfe&v\ +!\xceA\x9c\xd0\xcf\xe7\xa6l\x98`\x9d\xc4\xe7\xb2Y\ +@\x1a5R\xceE\x17\x11\x0e\xd1\x9a\xb3\xe9N\xabV\ +\x19\x8f\xe7'\xdcnF\x96,\x86\xaf\x8au\x02\xacK\ +\xfa\x0d\x86\xbd6\xfc\xbbv\x14\x9f'\x8c!\x1e\xd0G\ +\xc4\x16\xf6\xd4\xa5\xd7\x03\xaeK\x00\xc6(NX\xd2N\ +\xf1\x98lwj\xe9\xde]9\x97_N(\xc4\xc0^\ +\x14Mm\xd8\xa0\x9c\xe5\xcbUr\xe1B\xe5\xcc\x99\xa3\ +\x9c3\xceP\xa9\xf1\xe3\x953n\xdc\xben.\xa9\x11\ +#\x943|\xb8r\x06\x0c\xf8\xaf\x03\x07\xaaT\xf5\xea\ +\x19\x8f\xeb\x17\xedzy\xf4\xdeD0m\xcet\x9b\xd7\ +gl\xf8w\xec\x1bD\x07)\xc4\x98\xa9\xbf\xc0\xb6\xb3\ +\xa7.\xdd\x95Hw\xa3\x03\x884\xdf\xb6aB\xf5\xcf\ +f\xbb2\xfd\xb2\xe3\x94)\x04H\xac\x9a[\xb6\xec{\ +\xb8*5{\xb6rt\xe8\x96`\xed\x1cy\xa4J6\ +jT\xa5\x80\x9d\x0d\xdf\xb0\xab\xdd\xd9\xfa\x00\xea\x92\x15\ +\x1d[F\x89\xef\x12\xbe\x10=\xb7\x87\xedlO]Z\ +A\xbc\x83(s\xb6\x0d\x13\xe9\x04\xf7\xa9\xf3\xac\x14\x89\ +\x06\x0d\x94s\xf1\xc5\x84K\xf4\xd7\xbb\x5c\xbf \xab\x1f\ +\xab\x1a6L9\xed\xdbW\xb9\xf3\x8a\xa9vg#\xed\ +Y\x0c'e\xb1.\x9do\xc3\xbf\xd3\xa9n\xabK\x82\ +\x17\xa2w\xdf\x12\x07\xd8\xd3\xd9\xe5db\x1eD\x11\x99\ +C\x89O\xc3\x9eD\xa7ds\x11\xec\xd4\x89#-x\ +\xf00\xae\xdbk\xea0~\xea\xa9\xca\xe9\xd5K9M\ +\x9a\xa8d~~d\x17\xc3\xdd\xee\x17\x5c\x0b\x16\xc3\xbf\ +\x8b\x9d\xb2P\x97\x06\x89\x9f\x85\xfd\xef3\x83\x1e\xe7\x88\ +\x19\xfb\xb68\xc4\x8e\xba\xf4\xa1\xd8\x91\xb8\x07Q\xa2\xbe\ +\xf8^\xd8\x93G\xbf\xc2\xb7'[/\x82\x8e\x1eM\x97\ +\x16\xfc\xba\xfa\x0b\xdb\xd9g+g\xe4H\xe5\xb4m[\ +\xa5.*6\x87\xf4\xe3\xedX\x0c_\x14K\xabP\x97\ +\x1a\x89\xef\x87\xfd\xef1%\x88\x87\xd1\x10s\xccw\xec\ +y\x0d\xf9y\xb1\x06\xb1\x0f\xa2\x80\xbe\xd0uo\xd8\x93\ +fL\xb6v\xcek\xd4P\xce\xbcy\x04QL\xab\xbf\ +\xa4\xe9\x1d\xf2\xb1c\x95\xd3\xba\xb5r\x22\xbc;\xee7\ +\xa4\x8f\xb2c1\xfca\x86uI_\xe8\xba/\xec\x7f\ +\xfe\xa9\xec\x9c#f\xb5.\x1dgG]\xfa\x1e\xd1\x0f\ +\xa2\xc0\xea\xb0'\xcb\xf0l\x9d9\xaf_\x9f\x87\x87P\ +9\xdb\xb6)\xe7[\xdfRN\xdf\xbe*U\xbbvN\ +/\x86\x96\xecX\xcd\xcc\xa0.-\x0f\xfb\x9f{\x12;\ +\xe7\x88\x81\xec\xa4\xf7\xb7\xa3.\xcd&\xfe\x81\xcd\xf4\x0b\ +\xfb|\xe7`\xf7r[\x95'~\x9b6\xca\xd9\xbc\x99\ +p\x9a\xa3&\xb7nM?\xfc\xa3_\xe8\xcc\x91]r\ +\xaf\x8b\xa1\x05\x17\xb4\xfe!\xb6\xf7Q\x97\x06\x86]\x97\ +\xc6r!\x141\xd0\xaeS\xdd\xed\xa8K\xed\x88\x81`\ +#\xb5\xc4\xb7\xc3\x9c }\xdc\xcb#U\x9e\xf0={\ +\xa6;o\x10Ts\xcb\xed\xdb\xd3\xa1\xbcK\x97t+\ +M\x16\xbeo\xec\xa2\xd0+\xfc\xc5\xf0\xb9D\xfa\x8d\x05\ +/\xf7a\xf6\x84\xf9\xcf:\x22\x9b]\xa4\x10\xf1\x80\xbe\ +*\x1e\x19~]zZ,\x22\x0e\x82m|7\xcc\x89\ +\xd1\xc3\xfd\x16]\xe5\x89>t(\x97As\xad\xf3\xca\ +\x8a\x15\xfb\xda\x1f&#\xd0\xfa\xd0\xa6\xc5\xb0C\xf8\x8b\ +\xe1\xb6C\xd4\xa4<\xf1\xce0\xff\x19{\xb9\xbf:0\ +f\x10\x83\xf7\x05\xb1u\xf8ui\x1dq\x10l\xe2\x94\ +0'D[70T\xb9S\xcb\x84\x09\x04\xd6\x5c\x09\ +\xe5;v(\xe7\xcc3UJ\x1feba\xcb\xc8\xe7\ +\xc4\xc3\xc2\xefC<\xea uiv\x98u\xa9}6\ +\xea\x12\x22\xfa\xf2\x19\xb1<\xdc\xba\xf4\xb9{\xac\x0e \ +tZ\x88\x7f\x0bk24I\xa4\x9f\x00\xaej8O\ +\x9dv\x1a\xc15\x17\x82\xb9\xbe\xf4;h\x90rJJ\ +X\xcc\xb2\xe0\xe3b\xa3p\x17\xc3?\x8a\xe5\x07\xa8K\ +m\xc4\x8f\xc2\xfa\xe7j)\xbe\xc8\xf8@\x0c\xc5\x07\xc5\ +Z\xe1\xd6\xa5\xbd\xee\xf1:\x80\xd0\xd0\xad\xcb\xee\x0fk\ +\x12T\x17\xef\xaa\xead.(P\xce\xcc\x99\x84\xd78\ +\xab\x1f\x0f\x9a5+\xdd\x16\x91\xc5+\xeb\xea9Xl\ +W\xebE}\xb4%\xb4\x96\x8ae\xe2\xfd\x8c\x0b\xc4P\ +\xbdA,\x08\xb7.\xddHD\x840Y\x10\xd6\xe0\x97\ +o\x06\xea\xea\xaaNb}\x11p\xee\x5c\x02l\x9c/\ +}\x9er\x8aJ6h\xc0\x82\x15\xb0W\x8ay\xe1.\ +\x86\xa7\xecW\x97\xe6\x86\xf5\xcf\xa1\x03\xc1\xf7\x18\x0f\x88\ +V\xb8.\xfc\xf3\xe8'\x12\x13!\x0c\x9a%\xd2\xcfo\ +\x872\xf0/\xa9\xe2\xc4M\x16\x16*\xe7\xac\xb3\x08\xb1\ +q\x0d\xe6'\x9d\xa4\x9cZ\xb5X\xa4\x0c\xba0\xdc\x85\ +\xf0Obc\xb1e\x98u\xe92\xc6\x01\xa2U~+\ +\xdc\xba\xa4;H\xd5\x22.\x82i~\x1e\xd6\xa0\x9f\x9c\ +\x8d\x9d\xf3\xf9\xf3\x09\xb2q\xbc\xf89n\x9crJK\ +Y\x98BP\xbf\x909&\xdc\xc5\xf0\x16\xf1\xd7a\xfd\ +\xe7\xcf`\x0c Z\xa7~\x7f`x\xb8u\xe9\x0a\xe2\ +\x22\x98\xe4\xf4\xb0\x06{\xf7\xaa>D\xa4\xcf\x9c\xb3s\ +\x1e\xaf`\xae{\xd6\xeb`^\xb3&\x0b\x92\x05\x0f\x19\ +u\x0e\xffge\xe3\x0e\xe4!\x22Dk}Ml\x11\ +^}\xf8\x22AW\x170\x84\xbe\x99\xfc\x870\x06z\ +\x03\xb7\x85R\x95Z)N\x99B\xa8\x8d\x93s\xe6(\ +\xa7qc\x16!\x8b|R\xac\x93C\xe1\x5c\xb7\x9a|\ +\x89\xcf\x1d\xd1j\xf5\xc5\xed\x1a\xe1\xd5\x09\xf9\x8e\x90\xa8\ +N|\x84\xa0\xf9a\x18\x03\xbc\xa8\xaa\x1d[t8\x9f\ +:\x95@\x1b\x17\x17-R\xc9f\xcdXx,\xf56\ +\xb10\x07\xc2y\x09\x1d[\x10#\xe3w\xc2\xbd\xcc~\ +9\xf1\x11\x82dxX\x0b\xe1\xa5U\x9d\x9c\xfa\x08\x04\ +\xc16\xfa\xc7Y6nTN\xff\xfe\xca\xc9\xcfg\xc1\ +\xb1\xdc\xc59\x10\xd07\xf39#ri\xd4\x9b\x9f\x8a\ +\xdd\x88\x91\x10\x04\xd5\xc4\xd7\xc3\x18\xd8c\xdc\x0bh\x19\ +O\xca\xa1C\x09\xb7q8g\xae;\xb3T\xaf\xce\x22\ +\x13\x11\xf7\x8aCb\x1c\xce'\xf1\x19#F\xce\xddb\ +\xef\xf0\xea\xc6#\x89\xf4;\x0d\x00YeQ\x18\x03\xba\ +\x8d\xf8fU&d\xaf^\xca\xa9\xac$\xe4F9\x9c\ +\x9f{\xaer\xea\xd7gq\x89\xa0\xbfK\x84\xfe\xd2h\ +`u\xe9->_\xc4H\xfa[\xb1<\xbc\xfaq\x1a\ +q\x12\xb2\x89\xac\xb1\x89\xbf\x85q\xee\xfc\xde\xaaL\xc4\ +v\xed\x94\xa3w^\x09\xb9\xd1\x0c\xe6\x9b6)\xa7{\ +w\x16\x94\x88{K\x22\xfd\xb0X\x5c\xc2y1\xe7\xce\ +\x11#\xef\x0f\xc3;\x8f\xbe[,!VB\xb6\xb8>\ +\x8c\x85peU&`y\xb9r6o&\xe8FQ\ +\xfd\x8b\xc7\xe4\xc9\xca\xa9Q\x83\x85$&.\x8aQ@\ +\xdf\xca\xe7\x89\x18\x0b\xe7\x86WG\xd6\x12+!\x1b\xe8\ +K\x0d\x9f\x9b\x1e\xc0}\xdd3\xac\x19M<\xfdP\xcd\ +\x8a\x15\x04\xdd(\xba~\xbdr\xbave\xf1\x88\x99{\ +\xc4\x1e1\x08\xe7#\xf8,\x11c\xe3\xbbb\x87pj\ +\xc9G\xe2\xe1\xc4K\xa8*\x0f\x98\x1e\xbc\xb5\xc4\xa73\ +\x9dt\xba\xbb\xc7\x82\x05\x04\xdd(:w\xaeJ\x96\x95\ +\xb1p\xc4\xd4G\xdd\xb6\x84Q\x0d\xe7\xf5\xdc\xb3\xab|\ +\x96\x88\xf1\xea\x8f^-\x9c\x9a\xf2\x03\xe2%T\x85\x93\ +\xc3X\x08\xaf\xac\xca\x84\x9b8\x91\xa0\x1b5\xb7mS\ +N\xef\xde,\x169\xe0\xba\x08\x07\xf4\xab\xf8\xfc\x10c\ +\xe9\xaapj\xca\x97b?b&dB\x91\xf8\x96\xe9\ +A{RU&Z\x9f>\x84\xdd\xa8]\x04]\xbc\x98\ +\x0e-9\xa4n\x97: \x82\xe1|\x1c\x9f\x1db\xac\ +\xebR\xffpj\xcb\x13DM\xc8\x849a\xfc\x84\xfc\ +b\xa6\x93\xacI\x93\xf4N,\xa17:N\x9a\xa4\x9c\ +\xa2\x22\x16\x88\x1cS\x1f_\xab\x19\xa1p\xae\xdb\xb1\xbd\ +\xcc\xe7\x86\x18k\x1f\x13\xab\x87Sc\xc6\x107\xc1\x0f\ +\xc5\xe2\x1e\xd3\x03uW\xa6\x93K\x9f[^\xbb\x96\xc0\ +\x1b\x15\xb7lQN\x97.,\x0a\x1cu\x89\x84\xd7\xf0\ +y!\xe6\x84\xcb\xc2\xa91\xcf%x\xbc\x08|0\xdf\ +\xf4 \x1dR\x95\x895g\x0e\xa17*\xae\x5c\xa9\x9c\ +\xa6MY\x0cr\x5c\xdd\xa1\xa9{\x04\xc2\xf9p>+\ +\xc4\x9c\xea6\xd5)\x9cZs2\xb1\x13\xbc\xa0\x1b\xe8\ +;&\x07g\x0d\xf17\x99N\xaa\xc1\x83\x09\xbdQq\ +\xe6L\xe5\x14\x17\xb3\x10\xe0\x7f\xba'\x14Y\x1c\xceK\ +\xab\xd2M\x0a\x11#\xe9\xddb\x81\xf9z\xf3\xa2\x98O\ +\xfc\x84C\xb1\xc8\xf4B\xb8*\xd3\xc9\xa4\x1f#\xda\xbe\ +\x9d\xe0\x1b\x85\x87\x87F\x8dRN^\x1e\x0b\x00~\xc5\ +s,\x0e\xe8\xab\xf9|\x10s\xd2\xb3\xc2\xa99\x93\x89\ +\x9fp0\xca\xc4?\x9a\x1c\x94G\x8a\xefg2\x89\x8a\ +\x8aT\xf2\x92K\x08\xbf\xb6\xbbu\xabr:v\xa4\xe8\ +\xe3\x01}Glna8\xef\x9ai]B\xc4\xc8\xfb\ +\x96\xd8\xc4|\xddyM, \x86\xc27\xb1\xd4\xf4B\ +\xf8\xa3L'\xd1\xf8\xf1\x84_\xdb\xbd\xec2\xce\x9b\xe3\ +!\xbd\xde\xb2p\x9e'\xde\xc5\xe7\x82\x98\xd3V\x86S\ +\x7f\xa6\x11C\xe1\x9b:\xb7\x18={>:\xc3\x89\x93\ +j\xd3F9\x15\x15\x04`\x9b\xfb\x9b\xafX\xa1\x9c\x06\ +\x0d(\xf4\xe8\xc9\x81\x16\x05\xf4\x09|\x1e\x88\xf4F\x17\ +{\x84\xb3\x8b\xceYt\xf8\x1a\xb3L\x0eD\xf96\xa0\ +\x9e\xcc$\x9cW\xaf\xae\x92\xb4T\xb4\xdb\xb9s\xb9\x0c\ +\x8a\xbe|@,\xb4 \x9c\xeb\x0b\xeb\xcf\xf1y \xa2\ +\xf8s1\xdf|\x1d\x1aK\x1c\x85\xfd\xd1=8_6\ +9\x08\xe7g:i&L \x00\xdb\xec\xacY*Y\ +XHqG\xdf\xce\xb0 \xa0/\xe1s@\xc4\xfd\x9c\ +d\xbe\x0e=L$\x85\xfd9\xd1\xe4\x00\xd4/\xf3\xbd\ +\x91\xc9di\xdd:\xdd\x11\x84 l\xef\xcb\xa0tj\ +\xc1\x0c\xd5\xafu\xd6\x0a1\x9c\xebKa\xef\xf29 \ +\xe2~>\xef\xb6\x5c5\x5c\x8fz\x11K\xe1\xdfJ\x94\xe4\ +\xef\x8e\x88\x89\x83?^d\xf8\xd7\xbd\xbf\x8b\xb5\x89\xa9\ +\xb9\xcbZ\x93\xdf\x08\xaf\xcd\xa4\xadb\xd7\xae\x04a\x1b\ +\xfb\x9c\x8f\x1bG\xd1\xc6\xc0\xdcn\xb0.}\x8f\xbf7\ +\x22\xda\xf9\xeb\xde\xb9\xc4\xd4\xdc\xa4HL\x99\x1ahG\ +e\xb0K\xa5\xdb\xf5\xa5V\xaf&\x10\xdb\xa6nuI\ +\xb1\xc6\x00\xd5\xbf\xb4\xb54P\x97\xba\xf1\xb7FDK\ +\x7f\xdd\x13_ \xaa\xe6&F[+^\x97\xc9\x848\ +\xf6X\xc2\xb0m\x9e~:\xddZ\xd0\x88\x1b\x0d\xd4\xa5\ +\xab\xf9;#\xa2\x0f\xd7\x9b\xdfE?\x86\xb8\x9a{\xdc\ +a\xb2C\xc2^\xbf\x13\xa1F\x0d\xe5l\xdeL \xb6\ +\xc99sT2?\x9f\x22\x8dF|\xcf\xedM\x1eT\ +]j\x97I]B\xc4\x9c\xf6\x1d\xb1\xbe\xd9\x80~5\ +q5\xb78L\xfc\xcc\xd4\x00\xdb\x94\xc9D\x988\x91\ +@l\x91\xc9\x85\x0b\xd3\xbd\xe8)\xd0h\xd0\xcb\x02\xac\ +KW\xf0\xf7E\xc4\x0c\x5cd6\xa0\x7f(\x96\x11[\ +s\x87U\xa6\x06W\xb9\xbb\x13\xe6k\x024h\xa0\x9c\ +]\xbb\x08\xc6\xb6\xb8l\x99r\xaaW\xa70c(\xbb\ +\xe8\xe5\x01\xd4\xa5V\xec\x9e#b\x86\xbe\x920\xfe\xba\ +\xe8\xd9\xc4\xd6\xdc\xa0@|\xdf\xd4\xc0\xba(\x93\x090\ +e\x0a\xa1\xd8\x16\xd7\xadS\xa9:u(\xca\x18\x9a\x17\ +'x5\x14\x11\xedr\x86\xd9\x80\xfe,\xd157\x18\ +ajPU\x17_\xf4;\xf0\xcb\xcb\x95SQA0\ +\xb6\xc1m\xdb\x94s\xc4\x11\x14c\x0c}\xb7\xaa,\x8b\ +u\xa9\x91\xf8.\x7fWD\xac\x82\x8f\x8a\xf9fCz\ +g\xe2k\xfc\xb9\xd1\xd4\x80\x9a\x91\xc9\xc0\x9f6\x8d`\ +lC\x9fs\xf9\x92\x94\xea\xd4\x89B\x8cVxN\x16\ +\xeb\xd2\xa5\xfc=\x111\x0b\x9eh6\xa0o$\xbe\xc6\ +\x9bb\xf1\xaf&\x06S\x9e\xf8\x88\xcf\xc1\x9el\xd4h\ +_0$ [\x10\xd0G\x8e\xa4\x00\xa35>'\x16\ +e\xa1.\xd5\x12_\xe3\xef\x89\x88Y\xf0'f\x03\xfa\ +\x9bD\xd8xs\x92\xa9\xc14$\x83\xc1\x9e\x9c>\x9d\ +plI;Ez\x9d\xa3mN\xcdB]:\x9f\xbf\ +#\x22f\xd1NfCzObl|\xf9\xbe\xa9\x81\ +tU&g\xcf++\x09\xc7a\xbbt)\xed\x14\xd1\ +J\x1f\xa9\xe2\x99\xcfb\xf1\xb7\xfc\x1d\x111\x8b\xae6\ +\x1b\xd07\x11c\xe3I\xa9\xf8\x91\x89A\xd4 \x91~\ +\x12\xd7\xcf O\x9dv\x1a\xe18l\xf5\xc3P\xf5\xeb\ +St\xd1Z\xc7\x9a\xbe\x13\x83\x88x\x10\xf5\x91\xb9\x12\ +s\x01}\x8f\x98G\x9c\x8d\x1f\x13M}\xcb\x9b\xe7\xf7\ +hKY\x99J\xed\xd8A@\x0e\xd3\x8a\x0a\x95\xec\xd0\ +\x81\x82\x8bV{\x9f{\xbf\xc5oM\xd2\xe7\xd7\x9f\xe1\ +\xef\x87\x88\x018\xc1\xec.z?\xe2l\xfc\xb8\xcd\xd4\ +\xe5\xd0G\xfd\x0ep}!\x91\x90\x1c\xae\xe3\xc6Qh\ +1\x12\x0e\xcd\xa0.M\xe4\xef\x86\x88\x01\xf9#\xb3\x01\ +}'q6^\x94\x88\xff01xz\xf9\x1d\xdcE\ +E*\xb5i\x13\x019\xcc\x8e-\x8b\x17\xabd~>\ +\x85\x16#\xe1-\x19l\x1a\xdc\xc7\xdf\x0d\x11\x032)\ +6\xe7\x98\x0bd\xc8\xf1\xa6\xbe\xddm\xf5;\xb8\x07\x0c\ + $\x87\xe9\xd6\xad\xcai\xd0\x80\x22\x8b\x91\xb2\x9b\x8f\ +\x9at,\x7f/D\x0c\xd8\x0b\xcd\xee\xa2\x1fE\xac\x8d\ +\x0f\x15&\x06M\xb5Lz\x0c/[FH\x0eS\xfd\ +\x05\x89\xe2\x8a\x11\xf3z\x1fu\xe9g\xfc\xbd\x101`\ +\x9f\xc8\xf0~L\x86^B\xac\x8d\x0f\xef\x98\x184\xc3\ +\xfd\x0e\xea\x96-\x09\xc8a:s&\x85\x15#\xfb\x93\ +r{\x0f5\xa97\x7f+D\xb4\xf0\x97\xbd*\xfa\x08\ +\xb16\x1e\xb46\xf5\xb3\xcb\x0e\xbf\x03z\xca\x14Br\ +H&\xd7\xaeUNI\x09E\x15#\xeb\x16\x0f5\xe9\ +;\xfc\x9d\x10\xd1\x90\x97\x98\x0b\xe8\x9f\x8a\xb5\x88\xb7\xd1\ +g\x81\x89\x01S]|\xc3\xcf`..VI}\xfe\ +\x99\xb0\x1c\x8e]\xbbRP1\xd2\xea\xb7\x16\x0e?H\ +M\xea\xcc\xdf\x08\x11\x0d\xfa\x8c\xd9c.\x13\x89\xb7\xd1\ +\xe7\x17&\x06\xcb\xf1>\x07rj\xe0@BrXN\ +\x9fN1\xc5X\xb8\xe6 5\xe9\x0a\xfe>\x88h\xd8\ +\x1e\xe6\x02\xfa\xb5\xc4\xdbhSl\xaa\xbdb\xa5\xdf\x81\ +\xac\x9f\x94',\x9bw\xe3F\xe5\x94\x96RH1\x16\ +\xea_\xed\xea\x1c\xa0\x1e\x1d\x9e\xf0\xff\x9a1\x22bU\ +]a.\xa0\xef&\xe2F\x9b\xe1&\x06\x8a~\xa5\xef\ +u?\x83\xb8iS\x82rX\xf6\xe9C\x11\xc5X\xb9\ +\xf0\x005i-\x7f\x17D\x0c\xc1'\xcd\xb6[\xecD\ +\xcc\x8d.\x1bL\x0c\x92~~\x07\xf1I'\x11\x94\xc3\ +\xb8\x18z\xd6Y\x14P\x8c\x9d/\x8a%\xfb\xd5\xa3z\ +\xe2\xdb\xfc]\x101$[\x9b\x0b\xe8\xf3\x89\xb9\xd1\xe5\ +1\x13\x83\xe4R\xbf\xe7\xcfW\xaf&0\x9bv\xfbv\ +\xe5\xd4\xafO\xf1\xc4X:g\xbfz\xb4\x94\xbf\x07\x22\ +\x86\xe8Y\xe6\x02\xfa\xad\xc4\xdchR]\xfc\xc4\xc4 \ +\xf9\xb5\x9f\xc1\xdb\xa2\x05a9\x0cG\x8e\xa4pbl\ +}\xd6=jW\xcb\xefq;D\xc4,{\xb3\xb9\x80\ +\x9e$\xeaF\x93\xbe&\x06H\xe3D\xfa\xd1\x10\xcf\x83\ +w\xc2\x04\xc2\xb2i\xd7\xacQNQ\x11\x85\x13c\xed\ +Dw\xe7\x8a\xbf\x05\x22\x86\xe9;\x89t\xebiC!\ +\xbd9q7z,218N\xf33p\xf3\xf2\x94\ +\xb3n\x1d\x81\xd9\xf4\xd9\xf3\xee\xdd)\x9a\x18{\x1fp\ +w\xd2\xf9[ b\xd8\x1ek.\xa0O&\xeeF\x8f\ +\xdbM\x0c\x8ek\xfc\x0c\xdaV\xad\x08\xcc\xa6]\xb8\x90\ +b\x89\x88\x88h\xd0\xb5\xe6\x02z%q7z\xfc>\ +\xe8\x81Q \xbeF\xf7\x16{\xad\xacT\xa9\x96-)\ +\x96\x88\x88\x88\x06}\xc4\x5c@\x7f\x9e\xb8\x1b-\xda\x99\ +\x18\x18\x9d\xfc\x0e\xdaK.!4\x9b<\xda\xc2\x8b\xa1\ +\x88\x88\x88\xa1Xn&\xa0\x7f!\xd6!\xf6F\x87\xa9\ +&\x02\xfa4?\x83\xb5^=B\xb3AS;w\xaa\ +\x94\xfe\x9bS$\x11\x11\x11\x8d{\xbc\xb9]\xf4\xe1\xc4\ +\xde\xe8\xb0\xcd\xc4\xa0\xb8\xd2\xcf`\x1d0\x80\xe0lr\ +\xf7|\xd2$\x0a$\x22\x22bH\xae2\x17\xd0/\x22\ +\xf6F\x87_\x99\x18\x14O\xfb\x19\xacs\xe6\x10\x9c\x0d\ +>J\x94\xaa]\x9b\x02\x89\x88\x88\x18\x92?7\x17\xd0\ +o$\xf6rA\xf4?\x96\xfb\x19\xa8\x85\x85*\xb9u\ ++\xc1\xd9\x94\xe3\xc7S\x1c\x11\x11\x11Ctw\xc2X\ +?t.\x8aF\x84\xc6&\xbe\xb1\x8d\xf53P\xdb\xb6\ +%4\x1b\xdc=O\xd6\xacIqDDD\x0c\xd9\xbe\ +f\x02\xfa\xa7b5\xe2\xaf\xfd\x1cg\x22\xa0\xaf\xf23\ +HO8\x81\xe0l\xca\xb1c)\x8a\x88\x88\x88\x168\ +\xcf\xdc1\x97N\xc4_\xfb1\xf2\x82\xe8m~\x06\xe9\ +\x82\x05\x04gC\xbb\xe7Ni)E\x11\x11\x11\xd1\x02\ +\xaf4\x17\xd0O'\xfe\xda\xcfwM\x0c\x86W<\x0e\ +\xced~~:8\x12\xa0\x83\xf7\xb4\xd3(\x88\x88\x88\ +\x88\x96\xf8\x80\xb9\x80\xbe\x81\xf8k?\xcfXuA\xf4\ +\x88#\x08\xce\x86^\x0du\x1a5\xa2 \x22\x22\x22Z\ +tQ\xb4\xc8L@\xbf\x8b\xf8k?\x7f\x0fz \x0c\ +\xf63@\x87\x0c!<\x9b\xe8{~\xd6Y\x14CD\ +DD\xcb\xech&\xa0\xbfE\xfc\xb5\x9b\x86&~J\ +\x99\xebgp\xce\x9cI\x806\xa1\xee\x94C!DD\ +D\xb4\xca\x93\xcdur) \x06\xdbKo\x13\x01\xbd\ +\xc2\xc7\xc0L\xae]Kx\x0e\xda\x8b/\xa6\x08\x22\x22\ +\x22Z\xe8rs\xe7\xd0\x9b\x13\x83\xed\xe5T\x13\x83\xe0\ +W^\x07\xa6\xee(B\x80\x0e\xde\xbe})\x82\x88\x88\ +\x88\x16\xfa}s\x01}\x101\xd8^\x96\x04=\x00\xf2\ +\xc4\xb7\xbd\x0e\xcc\xf6\xed\x09\xcfA{\xf9\xe5\xca)*\ +\xa2\x08\x22\x22\x22Z\xe8\x93\xe6\x02\xfa4b\xb0\xbd\x5c\ +\x1d\xf4\x00h\xe4g`\x0e\x1dJ\x80\x0e\xfar\xe8\xa4\ +I\x14@DDDK\xddc\xae\x93\xcb*b\xb0\xbd\ +\xdc\x1b\xf4\x00\xe8\xe1g`N\x99B\x88\x0e\xda\xc3\x0e\ +\xa3\x00\x22\x22\x22Zl33\x01\xfd\x06b\xb0\xbd\xbc\ +\x11\xf4\x008\xc9\xc7\x80L-YB\x80\x0e\xd2\x8b.\ +\xa2\xf0!\x22\x22Zn\x7f3\x01\xfd!b\xb0\x9d\xe4\ +\x89\x1f\x07=\x00\xce\xf5: \xf3\xf3Uj\xc7\x0eB\ +t\x90\xf6\xefO\xe1CDD\xb4\xdcS\xcd\x04\xf4\xf7\ +\x88\xc2vR\xd7\xc4%\x84M^\x07\xa4~\xd5\x92\x10\ +\x1d\x9c\xdb\xb7+\xa7\xa4\x84\xc2\x87\x88\x88h\xb9\x8b\xcd\ +\x04\xf4O\x88\xc2v\xd2\xc6D@\xbf\xc9\xeb\x80\xec\xd4\ +\x89\x10\x1d\xa4\xfa\x01(\x8a\x1e\x22\x22\xa2\xf5\xee2\xd7\ +\xc9\xa5\x8c8l\x1f}L|\xf8\x0f{=\x7f>x\ +0!:H\x8f:\x8a\xa2\x87\x88\x88\x18\x01\x7fd.\ +\xa0\xb7 \x0e\xdb\xc7\x89&>\xfc\x97\xbd\x0e\xc8\xf1\xe3\ +\x09\xd1A\xb9u+\xbd\xcf\x11\x11\x11#\xe2\x03\xe6\x02\ +\xfa1\xc4a\xfb\x98\x16\xf4\x07_ \xee\xf5\xba\x83>\ +{6A:(\xa7O\xa7\xe0!\x22\x22F\xc4\xdf\x9a\ +\x0b\xe8#\x89\xc3\xf6\xb1(\xe8\x0f\xbe\x9e\x9f\x01\xb9t\ +)A: S]\xbbR\xf0\x10\x11\x11#\xe2\xeeD\ +\xfa%v\x03\x01\xfd\x0c\xe2\xb0}\xac\x0f\xfa\x83o\xed\ +g@n\xdeL\x98\x0e\xc2-[T\xb2\xb0\x90\x82\x87\ +\x88\x88\x18!k\x99\x09\xe8\x0b\x88\xc3\xf6qu\xd0\x1f\ +|O\xaf\xc7[\xaaW'H\x07\xb5{N\xf7\x16D\ +D\xc4\xc8\xd9\xc2L@_M\x1c\xb6\x8f\xdb\x82\xfe\xe0\ +Gx\x1c\x84Iz\xa0\x07g\xcf\x9e\x14:DD\xc4\ +\x88y\xb4\x99\x80^A\x1c\xb6\x8f_\x04\xfd\xc1\x9f\xea\ +u \xb6lI\x90\x0e\xc2\xcaJ\xe5\x94\x95Q\xe8\x10\ +\x11\x11#\xe603\x01\xfdz\xe2\xb0}\xdc\x17\xf4\x07\ +?\xcb\xeb@\xec\xd2\x850\x1d\x84\x17^H\x91CD\ +D\x8c\xa0c\xcd\x04\xf4\x1f\x10\x87\xed\xe3\xe1\xa0?\xf8\ +y^\x07b\x9f>\x84\xe9 \x1c=\x9a\x22\x87\x88\x88\ +\x18A'\x9a\x09\xe8\xb7\x11\x87\xed\xe37A\x7f\xf0\xe7\ +y\x1d\x88\xc3\x86\x11\xa6\x83\xb8 \xaa\x8f\x0eQ\xe4\x10\ +\x11\x11#\xe7\xe9f\x02\xfa\x9d\xc4a\xfbx>\xe8\x0f\ +~\xb1\xd7\x818v,\x81:\xdb\xea\xb6\x95\xf9\xf9\x14\ +9DD\xc4\x08:\xc3L@\xbf\x978l\x1f/\x07\ +\xfd\xc1/\xf3:\x10O?\x9d@\x9dm\xe7\xcc\xa1\xc0\ +!\x22\x22F\xd49f\x02\xfa\x03\xc4a\xfbx+\xe8\ +\x0f~\x95\xc7A\xb8\xafW7\xa1:\xab&\x8f;\x8e\ +\x02\x87\x88\x88\x18Q\xcf5\x13\xd0\x1f'\x0e\xdb\xc7\x9e\ +\xa0?\xf8u^\x07\xa2\xde\xed%Ts\xfe\x1c\x11\x11\ +\x11\xf7y\x81\x99\x80\xfe\x0cq\xd8>RA\x7f\xf0\x97\ +{\x1d\x88s\xe7\x12\xaa\xb3\xe9\xf6\xed\xca)(\xa0\xc0\ +!\x22\x22F\xd4%f\x02\xfa\x0b\xc4a\xfbp\x82\xfe\ +\xe07{=\xe22\x7f>\xa1:\x9b\xc7[\x16.\xa4\ +\xb8!\x22\x22F\xd8\x0b\xcd\x04\xf4\xdf\x12\x87s\xf0\x88\ +\xcbz\xaf\x03Q\x07J\x82u\xf6\x8e\xb7\x8c\x1bGq\ +CDD\xe4\x88\x0bG\x5c\x22\xc8;A\x7f\xf0k\xbd\ +\x0e\xc4\xc5\x8b\x09\xd6\xd9\x0c\xe8]\xbbR\xdc\x10\x11\x11\ +#\xec\x023\x01\xfd\x09\xe2\xb0}\xbc\x11\xf4\x07\xbf\xd2\ +\xeb@\x5c\xba\x94`\x9dMk\xd7\xa6\xb8!\x22\x22F\ +\xd8yf\x02\xfa#\xc4a\xfbx%\xe8\x0f~\xb9\xd7\ +\x81\xb8l\x19\xa1:\x9b\x0f\x14Q\xd8\x10\x11\x11\xe9\x83\ +\x9e\xa0\x0fz\x14y1\xe8\x0f~);\xe8\xe6=\xef\ +<\x0a\x1b\x22\x22b\xc4\x9di&\xa0\xff\x928l\x1f\ +\xcf\x07\xfd\xc1/\xf6:\x10/\xba\x88`\x9d-O9\ +\x85\xc2\x86\x88\x88\x18q\xcf4\x13\xd0\x7fA\x1c\xb6\x8f\ +\xa7\x83\xfe\xe0/\xf0\xdaf\x91K\xa2\xd9k\xb1\xd8\xaf\ +\x1f\x85\x0d\x11\x111\xe2N6\x13\xd0\xef \x0e\xdb\xc7\ +\xe3A\x7f\xf0s=\x0e\xc2$m\x16\xb3g\x8b\x16\x14\ +6DD\xc4\x88;\xd6L@\xbf\x8d8l\x1f\xbf\x0a\ +\xfa\x83\x9f\xeau \x9e\x7f>\xc1:\x1bVV*\xa7\ +\xb8\x98\xc2\x86\x88\x88\x18q\x8f5\x13\xd0\xaf'\x0e\xdb\ +\xc7O\x82\xfe\xe0'x=\xe2\xc2K\xa2\xd9q\xdd:\ +\x8a\x1a\x22\x22b\x0c\xeci&\xa0\xef$\x0e\xdb\xc7\x8d\ +A\x7f\xf0#\xbc\x06\xf4s\xce!\x5cg\xc3\x0b.\xa0\ +\xa8!\x22\x22\xc6\xc0\x8ef\x02\xfae\xc4a\xfb\xb82\ +\xe8\x0f~\x80\xd7\x80>{6\xe1:\x1bN\x9bFQ\ +CDD\x8c\x81\xcd\xcc\x04\xf4%\xc4a\xfb\xd8\x1c\xf4\ +\x07\x7f\xb4\xd7K\xa2S\xa7\x12\xae\xb3\xe1\xe8\xd1\x145\ +DD\xc4\x18X\xcfL@\x9fK\x1c\xb6\x8f\x15A\x7f\ +\xf0\xed\xbc\x0e\xc4I\x93\x08\xd7\xd9\xb0o_\x8a\x1a\x22\ +\x22b\x0c\xacf&\xa0O%\x0e\xdb\xc7\x05A\x7f\xf0\ +M\xbd\x1eq\x197\x8ep\x9d\x0d\xdb\xb6\xa5\xa8!\x22\ +\x22F\xdcw\xcc\x84s\xed8\xe2\xb0}\xcc\x09\xfa\x83\ +/\xf1:\x18G\x8d\x22\x5cg\xc3\xfa\xf5)l\x88\x88\ +\x88\x11\xf77\xe6\x02\xfa\xb1\xc4a\xfb\x98d\xe2\xc3\x7f\ +\xdb\xcb`\x1c:\x94p\x9d\x8dWD\x0b\x0b)l\x88\ +\x88\x88\x11\xf7\xe7\xe6\x02z7\xe2\xb0}\x0c5\xf1\xe1\ +?\xe5e0\xea\xe7\xe9\x09\xd8Us\xdb6\x8a\x1a\x22\ +\x22b\x0c\xbc\xc1\x5c@oL\x1c\xb6\x8f.&>\xfc\ +\xbb\xbd\x0c\xc6n\xdd\x08\xd8Uu\xcd\x1a\x8a\x1a\x22\x22\ +b\x0c\xdcb&\x9c\x7f!\x16\x10\x87\xed\xa3\xb1\x89\x80\ +\xfe}/\x97D\xdb\xb4!`W\xd5%K(j\x88\ +\x88\x881p\xa9\x99\x80\xfeG\xa2\xb0\x9d\x14\x89_\x06\ +=\x00vy\x19\x8c\xe5\xe5\x04\xec*\x9a:\xf7\x5c\x8a\ +\x1a\x22\x22b\x0c\xfc\x96\x99\x80\xfe\x12Q\xd8^\xfe\x1a\ +\xf4\x00X\xe5e0\x96\x96\x12\xb2\xab\xea\xf4\xe9\x145\ +DD\xc4\x188\xceL@\xff51\xd8^\xde\x08z\ +\x00\xcc\xf32\x18\xf3\xf2\x94SQA\xc8\xae\x8a\xa7\x9c\ +BQCDD\x8c\x81=\xcd\x04\xf4\x9b\x89\xc1\xf6\xf2\ +X\xd0\x03\xe0$\x8f\x831\xb5i\x13!\xbb*\x8e\x19\ +CQCDD\x8c\x81\x8d\xcd\x04\xf4\x9d\xc4`{\xf9\ +i\xd0\x03\xa0\x97\xd7\x01\xb9|9!\xbb*\x1e\x7f<\ +E\x0d\x11\x111\xe2\xee\x16\xf3\xcd\x04\xf4\xa5\xc4`{\ +\xb9\x22\xe8\x01\xd0\xd4\xeb\xa0\x5c\xb0\x80\x90]\x95K\xa2\ +#FP\xd8\x10\x11\x11#\xee\xe3\x09c=\xd0O#\ +\x06\xdb\xcb\xd2\xa0\x07@\x81\xb8\xc7\xcb\xa0\x9c:\x95\xa0\ +]\x15\x8f=\x96\xc2\x86\x88\x88\x18qo5\x17\xd0\xfb\ +\x10\x83\xed\xe5t\x13\x83\xe0\x19/\x83r\xf4hBv\ +Uv\xd0\x07\x0f\xa6\xb0!\x22\x22F\xdcm\xe6\x02z\ +\x13b\xb0\xbd\x0c21\x08\xee\xf20 \x93\xfd\xfa\x11\ +\xb4\xab\xe0\xbe\xbf\x1f\x85\x0d\x11\x111\xd2^`&\x9c\ +\x7f\x22\xe6\x13\x83\xed\xa5\x85\x89\x80~\x95\x97A\xd9\xb1\ +#A\xbb*\xf6\xeeMaCDD\x8c\xb8c\xcd\x04\ +\xf47\x89\xc0v\xa3_\x13\xfd\x22\xe8\x81p\x91\x97A\ +\xd9\xa4\x09!\xbb*G\x5cz\xf6\xa4\xb0!\x22\x22F\ +\xdc\x8ef\x02\xfa}D`\xfb\xd9\x1b\xf4@\x98\xe8a\ +@\xa6\xaaW'h\xb3\x83\x8e\x88\x88\x98\xb3\xbe/\x16\ +\x9b\x09\xe8\xd7\x11\x7f\xed\xe7\xf1\xa0\x07Bw\xaf\x83s\ +\xe3F\x826g\xd0\x11\x11\x11i\xb1\x18\xac\x97\x10\x7f\ +\xed\xe7\x07A\x0f\x84\xda^\x07\xe7\x05\x17\x10\xb63u\ +\xd0 \x8a\x1b\x22\x22b\x84\xbd\xc1\x5c@?\x99\xf8k\ +?+L\x0c\x86\x17\xbc\x0c\xce3\xce hg\xea\xd0\ +\xa1\x147DD\xc4\x08\xbb\xdc\x5c@\xefH\xfc\xb5\x9f\ +\xc9&\x06\xc3\x1d^\xce\xa1\xeb\xd70\x09\xdb\x99\x1dq\ +9\xee8\x8a\x1b\x22\x22b\x84=\xcdL8\xffL\xac\ +F\xfc\xb5\x9f\x1e&\x02\xfav/\x83\xb3[7\xc2v\ +\xa6\x8e\x1cIqCDD\x8c\xb0\x9d\xcd\x04\xf4\xd7\x88\ +\xbe\xd1\xa0\xa6\xf8e\xd0\x03\xe2,/;\xe8\xb4Z\xcc\ +\xdcq\xe3(n\x88\x88\x88\x11u\xb7Xd&\xa0\xff\ +\x84\xe8K\xab\xc5\xff8\xc0\xcb\x00-*RNE\x05\ +a;\x93>\xe8\x93'S\xe0\x10\x11\x11#\xea\xdd\xe6\ +\xce\x9f\xaf#\xf6F\x87\x07\x83\x1e\x10\xf5\xbc\x0e\xd2\xe5\ +\xcb\x09\xdc\x998k\x16\x05\x0e\x11\x111\xa2n1\x17\ +\xd0\xcf$\xf6F\x87kL\x0c\x8a\xe7\xbc\x0c\xd2\x193\ +\x08\xdb\x998\x7f>\x05\x0e\x11\x111\xa2N3\x17\xd0\ +\x8f&\xf6F\x87\x85&\x06\xc5\x8dtr\x09\xce%K\ +(p\x88\x88\x88\x11\xb5\xbb\x99p\xfe\x09\x1d\x5c\xa2\xc5\ +\xb1&\x02\xfa\xc5^\x06i\xc7\x8e\x84\xedL\x5c\xbd\x9a\ +\x02\x87\x88\x88\x18\xd1\x0b\xa2\xd5\xcd\x04\xf4g\x88\xbc\xd1\ +\xa2\xbe\x89\x80>\xd6\xcb@\xad]\x9b\xb0\x9d\x89[\xb6\ +P\xe4\x10\x11\x11#\xe8\xcf\xcd\x1do\xb9\x86\xc8\x1b=\ +\xf6\x04=0Zy\x1c\xa8\xa9\x8d\x1b\x09\xdc\x99tr\ +\xa9^\x9dB\x87\x88\x88\x181W\x99\x0b\xe8s\x89\xbb\ +\xd1\xe3\xae\xa0\x07F\x9e\xf8\xb2\x97\x80~\xee\xb9\x04\xee\ +L,/\xa7\xd0!\x22\x22F\xcc\xd1\xe6\x02zo\xe2\ +n\xf4\xb8\xcc\xc4\xe0\xf8\x9e\x97\xc1z\xc2\x09\x84\xedL\ +l\xdf\x9eB\x87\x88\x88\x181\x1b\x99\x09\xe7\x9f\x89%\ +\xc4\xdd\xe81\xd1D@?\x8f\x8b\xa2\xc1\xd9\xbb7\x85\ +\x0e\x11\x111B>nn\xf7\xfc\x05\xa2n4ik\ +b\x80xzQ\xb4\xa4D9\x95\x95\x04n\xbfg\xd0\ +G\x8e\xa4\xd8!\x22\x22F\xc8\x1d\xe6\x02\xfauD\xdd\ +h\x92'\xfe%\xe8\x01R&\xbe\xefe\xd0\xaeXA\ +\xe8\xf6\xeb\xa4I\x14;DD\xc4\x08y\x9a\xb9\x80>\ +\x93\xa8\x1b]\xee11H\xee\xf32h\xa7L!p\ +\xfb\xddA?\xe7\x1c\x8a\x1d\x22\x22b\x84<\xcc\x5c@\ +oG\xcc\x8d.\xabL\x0c\x92\xf5^\x06\xed\xc0\x81\x84\ +n\xbf\xaeZE\xb1CDD\x8c\x88\x8f\x98\x0b\xe7\x7f\ +pOJ@D\x19eb\xa0\x9c\xe8e\xe0\xea\x96\x81\ +\x84n\x7fVT\xa8da!E\x0f\x11\x111\x02\xae\ +3\x17\xd0\x7fL\xc4\x8d6u\xc5/\x83\x1e(\xf2\x1f\ +\xa2\xf6z\x19\xbc\xeb\xd6\x11\xba\xe9\x85\x8e\x88\x88\x18K\ +G\x9a\x0b\xe8\x17\x10q\xa3\xcf\xcb&\x06\xcb=^\x06\ +\xef\xb4i\x04n\xbf\xe7\xd0\xbbv\xa5\xe8!\x22\x22Z\ +\xeen\xb7q\x86\xa1\x80~\x0c\xf16\xfa\x5cob\xb0\ +\xac\xf02\x80\xfb\xf6%t\xfbu\xd80\x0a\x1f\x22\x22\ +\xa2\xe5\xdea.\x9c\xffC,\x22\xdeF\x9f9&\x06\ +\xcc0/\x03\xb8A\x03\x02\xb7_O?\x9d\xc2\x87\x88\ +\x88h\xb9\xe7\x99\x0b\xe8w\x13m\xe3\xc1\x91&\x06L\ +\xa9\xfb\xf3\xce\xa1\x06pj\xf5jB\xb7\x1f/\xba\x88\ +\xc2\x87\x88\x88h\xb9\x1d8\x7f\x0e>\xd1mxR&\ +\x06\xcd\x8f\xbd\x0c\xe2\xc9\x93\x09\xdd~\xdc\xbe]9y\ +y\x14?DDDK}\xdc\x5c8\xd7v&\xda\xc6\ +\x87\x1f\x98\x184\xf3\xbc\x0c\xe4\xce\x9d\x09\xddtrA\ +DD\x8c\x8d\xab\xcc\x85\xf3$\xfd\xcf\xe3\xc5\x0c\x13\x03\ +\xa7\x8d\x97\x81\x5cT\x94\xde\x15&x{6\xd9\xbd;\ +\x05\x10\x11\x11\xd1R{\x99\x0b\xe8\xd7\x13i\xe3EK\ +S?\xbd\xfc\xc6\xcb`\x9e7\x8f\xe0\xed\xc7\xb1c)\ +\x80\x88\x88\x88\x16\xfa\xb2X`.\xa0\x9fA\xa4\x8d\x1f\ +o\x9b\x18<\xeb\xbc\x0c\xe8!C\x08\xdd~<\xfbl\ +\x8a \x22\x22\xa2\x85n7\x17\xce\xf5\xc3\x93\xe5\xc4\xd9\ +\xf8\xf1?\xb6\xb4[L\xd5\xabG\xe8\xf6\xe3\xc6\x8d\x14\ +ADDD\x0b\x1dd.\xa0?G\x94\x8d'\x93M\ +\x0c\xa0\xea\xe2\x9b^\x06\xf5\xf2\xe5\x04o?\xd6\xafO\ +!DDD\xb4\xc8\xdf\x89\x85\xe6\x02\xfaJ\xa2l<\ +\xa9'~nb\x10Uz\x19\xd8\xc7\x1fO\xe8\xf6a\ +\xaagO\x8a!\x22\x22\xa2E\xae5\xdb^\xb1\x0bQ\ +6\xbee\xd5e\xd1\xf1\xe3\x09\xdf^\x1c2\x84\xa2\x89\ +\x88\x88h\xc0af\x03\xfa\xcd\xc4S\xd0l15\xe8\ +N\xf72\x11\xf4\xcepe%\x01\xfcP\xce\x9bG\xd1\ +DDD\x0c\xd8\xfb\xcd\xb6V\xd4\x0e'\x9a\x82\xa6\xab\ +\xa9AWC|\xcd\xcb\x84\x98=\x9b\x00~\xa8v\x8b\ +;w*\xa7zu\x8a'\x22\x22b\x80\x9el6\x9c\ +\xbf\x97\xa0\xf79\xec\xc7s\xa6\x06\xdfj/\x13\xa2U\ ++B\xb8\x07\x93\xfa\x05V\x8a'\x22\x22b \xfeF\ +,4\x1b\xd0W\x12Ia\x7f\xce75\xf8\x8e\x10\xf7\ +x\x99\x18\x8b\x17\x13\xc2\x0f\xe5\x8c\x19\x14PDD\xc4\ +\x80\x9ci6\x9c\xffKlL$\x85\xfdi$~f\ +j\x10^\xe5\xa5\xa3\x8b\xde\x1d&\x84\x1f\xdc-[\x94\ +SXH\x11EDD\xcc\xb2/\x8a%f\x03\xfa\xf7\ +\x89\xa3p ~jj\x10v\xf729\x0a\x0a\x94s\ +\xd9e\x84\xf0C\x1ds\xe9\xd0\x81B\x8a\x88\x88\x98e\ +\x17\x9a\x0d\xe7\xda>DQ8\x10\xa3L\x0e\xc4;\xbc\ +L\x90\xc1\x83\x09\xe1\x87r\xf2d\x0a)\x22\x22b\x16\ +\xd5\x0d-j\x99\x0d\xe7O\x11C\xe1\x9b\xd0\xb7\x86\xdf\ +25\x18\x8f\xf70AR\xd5\xaa\xf1p\xd1\xa1\xba\xb9\ +\xac_\xaf\x9c\xbc<\x0a*\x22\x22btw\xcf\xa7\x12\ +C\xe1`\x5cdj0\x16\x88\x8fy9\x8b~\xdcq\ +\x04\xf1C\xd9\xae\x1d\x05\x15\x11\x111\x0b\xbe,\xd64\ +\x1b\xce\xff \x16\x13A\xe1`4H\xa4\x9f\x9852\ +(O\xf52Y\xd8E?\xf4.:\xc7\x5c\x10\x11\x11\ +\xb3\xe2|\xf3\xbb\xe7k\x89\x9f\xe0\x85\x1bM\x0d\xca\x22\ +\xf1I/\x13\xe6\xf8\xe3\x09\xe2\x07S\x7f\x81\xd1\x97j\ +)\xac\x88\x88\x88U\xea\xdcRj6\x9c\xebM\xd1&\ +DO\xf0B?\x93\xdf\x1c\xa7z\x994\xa5\xa5*\xb9\ +u+A\xfc`v\xecHqEDD\xac\x82s\xcd\ +\xef\x9e_M\xec\x04?\xbd\xdf\xed.g8\xa0\xf7 nB\ +&\x9cor\xa0N\xf62\x89\xf4\xb3\xf6k\xd6\x10\xc4\ +\xbf\xc9\xb3\xce\xa2\xd0\x22\x22\x22\xfa\xb4\xbf\xf9p\xfe\x0b\ +b&dJm\xf1C\x93g\xd1\x1f\xf72\x91\xfa\xf6\ +%\x88\x7fS\xbb\xc5\x8a\x0a\x95\xacY\x93b\x8b\x88\x88\ +\xe8\xd1[\xcd\x87s\xedq\xc4L\xa8\x0a;L\x0e\xd8\ +\x09^&\x93n'\xb8b\x05\x81\xfc\x9b\x1c<\x98\x82\ +\x8b\x88\x88\xe8\xc1\xa4\xd8\xd5|8\x7f\x8ax\x09U\xa5\ +\x95{\xcb\xd8\xc8\xa0\xcdw\xcf\x81\x1djB\xa5:u\ +\x22\x88\x7f\x93\x17_L\xd1EDD\xf4\xe0\x15\xe1\xec\ +\x9e\x9f@\xbc\x84lp\x83\xc9\x81;\xd2\xe3\xa4J\x9d\ +{.a\xfc\x9b<\xec0\x0a/\x22\x22\xe2A|K\ +lb>\x9c?I\xac\x84l\xd1A\xfc\xc2\xe4\x00\xbe\ +\xc3\xcb\xe4j\xdcx\xdf\x99k\x02\xf9\x01<\xf9d\x8a\ +/\x22\x22\xe2A\x05\x18\x11\x11\xf1k>\x9a0\xfe\ +(\x91\xf6A\xe2$d\x9b\x8e\xa6w\xd1\xb7{9\xe6\ +R\xbb\xb6r\xb6m#\x94\x1f\xe8e\xd1\xa3\x8e\xa2\x08\ +#\x22\x22\x1e\xc0\x11\xe1\xec\x9e\x0f%NB\x10\xdca\ +r \xebsao{\x99hC\x87\x12\xc8\x0f\xe4\x82\ +\x05\x14aDDD;\xda*>L\x8c\x84\xa08J\ +\xfc\xd2\xe4\x80>\xdf\xcbd\xcb\xcfOw.!\x94\x7f\ +\xd5\xcaJ\x95l\xd4\x88b\x8c\x88\x88\xb8\xdf\xc5\xd0\xc3\ +\xcd\x87\xf3/\xdc\x0c\x05\x10\x18w\x9b\x1c\xd45\xc4\xe7\ +\xbcL\xbaV\xad\xf6\x05R\x82\xf9\xff;\x8b>~<\ +\x05\x19\x11\x11\xd1\xf5\x82pv\xcfo#>B\xd0\xf4\ +0\xbd\x8b>\xc9\xeb\xc4\x9b:\x95P\xfe\xff\xdd\xb4I\ +%\x0b\x0b)\xca\x88\x88\x98\xf3>,V3\x1f\xce?\ +\x15\xdb\x12\x1f\xc1\x047\x99\xfe\xf6y\x9b\x97\xc9W\xab\ +\x96r\xb6l!\x94\xff\x7f\xbbw\xa70#\x22bN\ +\xab;\xc3u\x0fg\xf7|;\xb1\x11L\xd1\xd6\xfdF\ +hl\x80\xb7\x13w{\x99\x84\x83\x06\x11\xc8\xff\xbf\xe7\ +\x9dGqFD\xc4\x9cvc8\xe1\xfc\xcfb]b\ +#\x98\xe4;\xa6\x07\xfae^&a^\x9er\xe6\xcf\ +'\x94\xf3\xb2(\x22\x22\xe2>_\x10\xeb\x86\x13\xd0\x97\ +\x13\x17\xc14-\xc4\x7f\x99\x1c\xe8\xb5\xc4\xdfy\x99\x8c\ +\x8d\x1a\xa9\xd4\x8e\x1d\x84\xf2\xfd=\xe3\x0c\x8a4\x22\x22\ +\xe6\xa4'\x86\x13\xce\xf7\x8a\xa5\xc4E\x08\x83]\xa6\x07\ +\xfc)^'\xe4\x88\x11\x84\xf2\xfd\xbb\xb9\xe8/,\xa5\ +\xa5\x14jDD\xcc)\xaf\x0e'\x9ckO'&B\ +X4\x12?0=\xe8o\xf60!\x93\xba7\xfa\x92\ +%\x84\xf3\xfdC\xba\xfe\xd2B\xb1FD\xc4\x1c\xf1%\ +\xb1A8\xe1\xfc\x111\x8f\x98\x08a\xb2\xd8\xf4\xc0?\ +L|\xc3\xcb\xe4l\xde\x5c\xa5**\x08\xe7\xffv\xf5\ +\xea\xf4\x19}\x8a6\x22\x22\xe6\x80#\xc2\x09\xe7\xba\x89\ +\xc6\x91\xc4C\x08\x9b\xea\xe2{\xa6'\xc0\x5c\xaf\x13t\ +\xcc\x18\x82\xf9\xfe\xbb\xe8]\xbbR\xb4\x11\x111\xf6^\ +\x1f\xde\xd1\x96+\x89\x86`\x0b\x93MO\x80B\xf1^\ +\xafG].\xba\x88p\xee\x9a\x5c\xb8\x90\xc2\x8d\x88\x88\ +\xb1\xf6E\xb1Qxm\x15\xeb\x13\x0b\xc1\x16\xf49\xab\ +'MO\x84.\xe2\x1e/\x93\xb5qc\xe5\xd0\xd5\xe5\ +\xbf\xb6hA\x01GD\xc4\xd8:*\xbc\xdd\xf3yD\ +B\xb0\x8d\xfe\xe2\x97\xa6'\xc3R\xaf\x13v\xf8p\x82\ +\xf9\xbf\x8f\xb9\xcc\x9cI\x01GD\xc4X\xba-\xbcp\ +\xfe\x94X@\x1c\x04\x1b\xb9\xd9\xf4\x84(\x12\x7f\xe5\xf1\ +\xa8K\xea\xc2\x0b\x09\xe8\xda]\xbb\x94S\xa7\x0e\x85\x1c\ +\x11\x11c\xe5\x13bY8\xe1\xfcs\xb1;1\x10l\ +\xa5\x5c\xfc\xab\xe9\x89\xd1F|\xc7\xcb\xe4\xad[W9\ +\x9b7\x13\xd0\xb5\x13&P\xcc\x11\x1116\xee\x16\xbb\ +\x86\xb7{\xbe\x99\x08\x08\xb6\xb38\x8c\xc91\xdf\xeb$\ +>\xfah\xc2\xb9\xbe,\xbau\xabrJJ(\xea\x88\ +\x88\x18\x0b/\x0e/\x9c\xeb\x17Ck\x12\xff\xc0v\xf4\ +\xf9\xab\xdf\x9a\x9e \xf9\xe2\x8f=N\xe2}g\xb0\x09\ +\xe9\xca\x19:\x94\xa2\x8e\x88\x88\x91\xf7.\xb7\xbb[H\ +\x01\xfdx\xa2\x1fD\x85\xa1aL\x92\xd6\xe2\xdb^&\ +sq\xb1J\xad\x5c\xc9e\xd1\x0d\x1b\x94STDq\ +GD\xc4\xc8\xaa\x1f.l\x19^8\xff\x19\x91\x0f\xa2\ +\xc6\x0f\xc3\x98,g{\x9d\xd4\xadZ\xf1\xca\xa8>\xea\ +\xd2\xaf\x1f\x05\x1e\x11\x11#\xeb\xc4\xf0\xc2\xf9\x07b3\ +\xe2\x1eD\x8d\xa6\xe2\x87a\x1cu\xb9\xcd\xeb\xc4\x1e2\ +\x84\x80\xbev\xadr\x0a\x0b)\xf2\x88\x88\x189w\x86\ +\x17\xce\xb5g\x11\xf5 \xaa,\x0ac\xd24\x11_\xf1\ +:\xc1\xa7M\xe3,z\xdf\xbe\x14zDD\x8c\x94\x8f\ +\x8a\xa5\xe1\x85\xf3\xfb\x12\xe9G\x1a\x01\x22I\xa1\xf8L\ +\x18\x93g\xb4\xd7I^\x5c\xac\x9c\xe5\xcbs\xfb,\xfa\ +\xea\xd5\xfb\xfa\xc4S\xf0\x11\x111\x0a\xea\xfbfG\x86\ +\x17\xce\xff.\xb6$\xe2A\xd4\xe9 ~\x12\xc6$Z\ +\xefu\xb2\x97\x97+G\xb7\x1d\xcc\xe5]\xf4c\x8e\xa1\ +\xe8#\x22b$\x1c\x1b\xee\xd1\x96\xd9D;\x88\x0b\xeb\ +\xc2\x98D5\xc4\x87\xbdN\xf8\x1e=r;\xa0\xeb_\ +\x11\xf2\xf2(\xfc\x88\x88h\xb5\x97\x87\x1b\xce\x1f\x14\xf3\ +\x89u\x10\x17\xaa\x8b\xaf\x851\x99:xm\xbd\xa8\x9d\ +4)\xb7Cz\xb7n\x14\x7fDD\xb4\xd6{\xc5\xe2\ +p\x8f\xb6\xb4&\xd2A\xdc\x18(~\x11\xc6\xa4:\xd5\ +\xeb\xe4/(P\xce\xa2E\xb9\x1b\xd0\x97.e\x17\x1d\ +\x11\x11\xad\xf4U\xb1Y\xb8\xbb\xe7\xb3\x88r\x10W\xae\ +\x08kb\xed\xf4Z\x04\xea\xd6U\xa9M\x9br\xf7\xc2\ +h\xa7N,\x04\x88\x88h\x95Iqx\xb8\xe1\xfc\xa7\ +D8\x883e\xe2\xdba\x9dG\x7f\xd0k1h\xdf\ +^9\xb9\xfa\x88\xd1\xe2\xc5,\x06\x88\x88h\x95\x8b\xc3\ +\x0d\xe7\xbf\x17\x1b\x12\xe1 \xee\x0c\x0e\xeb\xa8K{?\ +\xe7\xd1\xc7\x8c\xc9\xdd]\xf46mX\x10\x10\x11\xd1\x0a\ +\xbf\x9bH?B\x18b@?\x91\xe8\x06\xb9\xc2\xce\xb0\ +&\xda\x04\xafE!/O%\xa7O\xcf\xcd\x90\xbe`\ +\x01\x8b\x02\x22\x22\x86\xeeCb\xcdp\xc3\xf9\xd5D6\ +\xc8%j\x88o\x845\xe1\xd6x-\x0e\xd5\xaa)\xe7\ +\xe2\x8bss\x17\xbdeK\x16\x07DD\x0c\xcd\xd7\xc4\ +\xd6\xe1\x86\xf3\xb7\xc4R\x22\x1b\xe4\x1a\xfd\xc3:\xeaR\ +$\xfe\xc4k\x91\xa8UK9\x97]\x96{!\xfd\x82\ +\x0bX \x10\x111\x14\xf7\x8a\xc7\x85\x1b\xce\xff%\xf6\ +$\xaaA\xae\xb2)\xac\xc9\xd7H|\xdek\xb18\xfc\ +p\xe5l\xdfNG\x17DDD\x03.\x087\x9ck\ +\x17\x13\xd1 \x97\xd1\xafq=\x10\xd6\x04\xec$\xbe\xe3\ +\xb5`\xe8G|*+s+\xa4/[F_tD\ +D4\xea\xc6\xf0\xc3\xf9O\xc4<\x22\x1a\xe4:\xfaU\ +\xae\x0f\xc3\x9a\x883|\x14\x8d\xd4\xc8\x91\xb9w\xd4\xa5\ +G\x0f\x16\x0cDD4\xa2>~Z-\xdcp.\xff\ +\x18\x89FD3\x804g\x86\xf9my\x87\x9f\x90~\ +\xc6\x19\xb9\x15\xd0W\xaeL\xbf\xb0\xca\xc2\x81\x88\x88\x01\ +\xfa\xb8X/\xdcp\xae\xef\xc5\x0d#\x92\x01|\x95\x9b\ +\xc2\x9a\x94\xfa\xdb\xfaO\xbd\x16\x11\x1dV\xcf??\xb7\ +B\xfa\x80\x01,\x1e\x88\x88\x18\x98\xaf\x84\xdf\xb1E\xbb\ +\x9e(\x06\xf0u\xea\x88\xef\x8551\xeb\x8bOz-\ +&\xa5\xa5*\xb5zu\xee\x5c\x16]\xbf^\xa5t\xcb\ +I\x16\x11DD\xcc\xb2\xbb\xc5\xfe\xe1\x87\xf3\x87\xc4B\ +\xa2\x18\xc0\x81\x19 ~\x1e\xd6\x04\xd5/\x8d\xbe\xee\xa3\ +\xb3Kr\xeb\xd6\xdc\xd9E\x1f:\x94\x85\x04\x11\x11\xb3\ +\xee\xa9\xe1\x87\xf3\x94\xd8\x84\x08\x06pp\x96\x879Q\ +\xfb\xb8\xdf\xe6=\x15\x966m\x94\xb3cGn\x04\xf4\ +\xcb/WN\x8d\x1a,&\x88\x88\x985\x17\x85\x1f\xce\ +u\xbf\xf3\xdeD/\x80CS \xfe:\xcc\x09;\xcb\ +\xcf\xa5\xd1\xae]U\xaa\xa2\x227B\xfa\x981,(\ +\x88\x88\x98\x15\xaf\x11\xf3\xc3\x0f\xe8\x17\x11\xbb\x00\xbc\xd3\ +P\xdc\x1b\xe6\xa4]\xe3\xa7\xd0\xe8K\x94\xb9\x10\xd0\xb7\ +oW\xc9\x9a5YX\x10\x11\xb1J\xde\x96H\xbf\xea\ +\x1dr8\xbf\x91\xb8\x05\xe0\x9f\xe3\x12\xe9\x96G\xa1L\ +\x5c]8n\xf1SpN8!7B\xfa)\xa7\xb0\ +\xb8 \x22b\xc6>\x95H\xbf\xe6\x1dr8\x7fS\xac\ +M\xd4\x02\xc8\x8c\xd5aN`\x99\xb9\xea\x11?\x85G\ +\x87\xd7\xb8\x07\xf4\x9d;\x95\xd3\xa0\x01\x8b\x0c\x22\x22\xfa\ +\xf65\xb1C\xf8\xe1\x5c?\x8e\xd8\x89\x88\x05P\xb5\xf3\ +\xe8\xf7\x879\x91[\xba\xfdY\xbd\x14\x9ed~\xber\ +\xe6\xce\x8d\x7fH\x9f:\x95\x85\x06\x11\x11}\xf9\x8e\xd8\ +;\xfcp\xfe\xa58\x9ex\x05Pu\x1a$B\xec\x8f\ +\xae\xed'\xbe\xeb\xb5\x08\x15\x16*g\xfe\xfcx\x07\xf4\ +\xcaJ\xe5\xb4j\xc5\x82\x83\x88\x88\x9e\xdc#\x0e\x0f?\ +\x9c+\xf7\x97y\x00\xc8\x12=\xc4\x8f\xc3\x9c\xd4'\x88\ +\xef{-F\xd5\xab+\xe7\xe2\x8b\xe3\x1d\xd2\x17/V\ +N^\x1e\x0b\x0f\x22\x22\x1e\xfc\xd7eq\x92\x1d\xe1\xfc\ +\x0e1\x9fH\x05\x90]&\x87=\xb9Ov\x0b\x8d\xa7\ +\xa2T\xbb\xb6r\xd6\xac\x89uHOv\xef\xce\xe2\x83\ +\x88\x88\x07u\x9a\x1d\xe1\xfc\x05\xb1\x8c(\x05\x10\x0cW\ +\x85=\xc9\x17\xf9\xe9\x91\xde\xa4\x89Jm\xda\x14\xdf\x90\ +\xbejU\xfaH\x0f\x0b\x10\x22\x22\x1e\xc0\xe5v\x84\xf3\ +\xbf\x88\xed\x89P\x00\xc1Q(>\x14\xf6d_\xe5\xa7\ +@\x95\x97\xab\xd4\xc6\x8d\xf1\x0d\xe9#F\xb0\x08!\x22\ +\xe2\xd7\x5ccG8\xd7\xc7c\xfb\x13\x9f\x00\x82\xe7p\ +\xf1\x0faN\xf8\x02\xf1:?\x85\xea\xb0\xc3\x94\xb3y\ +s<\x8f\xb9l\xdd\xaa\x9cZ\xb5X\x8c\x10\x11\xf1?\ +^/\x16\xda\x11\xd0g\x10\x9b\x00\xcc1D\xfcW\x98\ +\x93\xbeX\xfc\x89\x9f\x82u\xc4\x11\xca\xb9\xfc\xf2x\xee\ +\xa2O\x9e\xcc\x82\x84\x88\x88\xfb\xfc\xb1\xbbFZ\x10\xce\ +7\x10\x97\x00\xcc3)\x91\xeeg\x1a\xda\xe4/\x13\xef\ +\xf5S\xb8Z\xb6T\xce\xb6m\xf1\x0b\xe8\x15\x15\xcai\ +\xda\x94\x85\x09\x111\xc7\xbdS,\xb1#\x9c\x7fO\xcc\ +#*\x01\x84\xc3\xba\xb0\x8b@}\xf1Q?\x05\xac}\ +{\x95\xda\xb1#~!}\xc1\x02\x16'D\xc4\x1c\xf6\ +!\xb1\xae\x1d\xe1\xfc\xd7b5\x22\x12@x\xe8\x97F\ +\xef\x0c\xbb\x18\xb4\x11_\xf6S\xc8:vT\xa9\x9d;\ +\xe3\x17\xd2;wf\x91BD\xccA\x9f\x15\x9b\xd9\x11\ +\xce\xdf\x13\x1b\x13\x8f\x00\xc2\xa7D\xfcM\xd8E\xa1\xab\ +\xf8\x86\x9f\x82\xd6\xad\x9brv\xed\x8aU@O\xadX\ +\xa1\x9c\x82\x02\x16+D\xc4\x1cR\x16`u\x18\xed\x14\ +\x01\xe0\x004\x17\x7f\x1fvq8.\x91~\xce\xd8s\ +a;\xfah\x95\xd2\xe7\xb7\xe3\xb4\x8b>x0\x0b\x16\ +\x22b\x8e\xf8\x82\xd8\xd6\x8ep\xfe\x998\x8a8\x04`\ +\x1fG\x8b\xff\x08\xbbH\x8c\xf2\x19\xd2S\x03\x07*\xa7\ +\xb22>\x01]\xf7|/)a\xe1BD\x8c\xb9\xcf\ +\x8b\xad\xec\x08\xe7\xb4S\x04\xb0\x9c\x09\xe2\x17a\x17\x8a\ +\x13\xc5\xf7\xfd\x14\xbac\x8eIwB\x89\xcbQ\x97\xd3\ +Nc\xf1BD\x8c\xb1/\x89\x1d\xed\x09\xe7\xb4S\x04\ +\x88\x00\xcbm(\x18\xa7\x8a{\xfd\x14\xbc\x1e=\xe2s\ +\xdcE\xff\x22\xd0\xa2\x05\x8b\x18\x22b\x0c}E<\xd2\ +\x9ep\xfe\xc3\x04\xed\x14\x01\x22\x81\x9e\xa8\xb7\xdaP8\ +\xe6\xf9-|q\x0a\xe9K\x96('/\x8f\xc5\x0c\x11\ +1F\xbe)\xf6\xb4'\x9c?%\x96\x11{\x00\xa2C\ +u\xf1q\x1b\x0a\xc8\x1c\x9f\xc5/\xd9\xbd{|B\xfa\ +\x80\x01,h\x88\x881Qw*\xebaO8\x7f^\ +\xacM\xdc\x01\x88\x1eM\xc5wm($\xcb\xfd\x16\xc2\ +\xa3\x8f\x8eG\x0b\xc6\xcd\x9bU\xb2\xac\x8c\x85\x0d\x111\ +\xe2\xcab\xaa\x06\xd9\x13\xce\xdf\x17\x9b\x11s\x00\xa2K\ ++1eCA\xb9\xc4\xefN\xfaQG\xc5#\xa4\x9f\ +q\x06\x8b\x1b\x22b\x84}G\x1chO8\xd7kz\ +k\xe2\x0d@\xf4\xe9\x22\xfe5\xec\xa2\x92'\xae\xf7[\ +\x18;w\x8e\xfe\x8b\xa3\xfa\xc2h\xcb\x96,r\x88\x88\ +\x11\xdd9\x1flO8\xd7kyWb\x0d@|8\ +^\xfc4\xec\xe2R ^\xe1\xb7@v\xea\xa4\x9c\x1d\ +;\xa2\x1d\xd2\x97.UN~>\x8b\x1d\x22b\x84\xd4\ +oz\x8c\xb5'\x9c\xffK\x1cA\x9c\x01\x88\x1f\xa7&\ +,\xe8\x91\x9e\x9fAHO\xc5!\xa4\xf3\xc2(\x22b\ +\xa4v\xce\x8f\xb5'\x9c\xebWB\xc7\x12c\x00\xe2\xcb\ +E6\x14\x9b\x22\xf1\x1a\xbf!\xbdk\xd7h\x1fw\xd9\ +\xbcY9\x5c\x18ED\xb4\xde\xdd\x89\xf4\xab\xd8\x09{\ +<\x87\xf8\x02\x10\x7f6\xd8Pp\xf4q\x97\xed~C\ +z\x9b6\xca\xd9\xb2%\xba!\xfd\xcc3Y\xfc\x10\x11\ +-\xefs\xde\xd7\xaep\xbe\x94\xd8\x02\x90\x1b\xe8\x87\x8c\ +\xae\xb5\xa1\xf0\xe8\x8b\xa3\x1b\xfc\x16\xd0#\x8eP\xa9M\ +\x9b\xa2{a\xb4m[\x16ADDK\xc3y\x1f\xbb\ +\xc2\xf9\x16\x22\x0b@nQ \xdenKH\xf7\xdd\xdd\ +\xa5qc\xe5\xac[\x17\xcd\x90\xbe|\xb9r\x0a\x0aX\ +\x0c\x11\x11-{\x84\xa8\x97]\xe1\xfc:wC\x0d\x00\ +r\x8c\x9a\xe236\x14\xa2\xfc\x0c\x8e\xbb8\xe5\xe5\xd1\ +\x0d\xe9C\x87\xb2 \x22\x22Z\xe2[b\x7f\xbb\xc2\xf9\ +\xbdb5b\x0a@\xeeR_|\xc5\x96\x9d\xf4\xb5~\ +\xcf\xa4\xd7\xae\xad\x92\x97\x5c\x12\xb9\x80\x9e\xd2\x1di\x1a\ +6daDD\x0cYY\x00UW\xbb\xc2\xf9\xcf\x09\ +\xe7\x00\xa0\xd1\xaf\x8d:\xb6\x84\xf4M~\x0bli\xa9\ +r.\xbc0z\xbb\xe8\xe7\x9f\xaf\x9c\xbc<\x16HD\ +\xc4\x90|]\xeciW8\x7fL,#\x96\x00\xc0\xbf\ +i#&m)RK\xfd\x16\xda\x92\x12\xe5,Z\x14\ +\xbd\x9d\xf4>}X$\x11\x11C\xf0%\xb1\x93]\xe1\ +\xfc!\xb1\x06q\x04\x00\xfe?G\x89\x7f\x89\xecq\x97\ +j\xd5\x94s\xee\xb9\xd1\xeb\x8d^\xb3&\x8b%\x22\xa2\ +A_\x15\xbb\xd9\x15\xce\x9f\x17\xeb\x12C\x00\xe0\x9b\xe8\ +%~`KH_\x95IH\x9f7/R!=9\ +u*\x0b&\x22\xa2\xc1\x9ds\xcb\xce\x9c\xbf(6 \ +~\x00\xc0\xa1\x18(~dK\xf1Z\xee\xb7\x00\xe7\xe7\ ++\xe7\xf4\xd3\xa3\xb5\x93\xde\xa5\x0b\x0b'\x22b\xc0>\ +/\xb6\xb3+\x9c\xbf*\x96\x13;\x00\xc0+\xfd\xc4\xbf\ +\xdbR\xc4f\x88I?\x85X_\xbe\x1c=::\xbb\ +\xe8k\xd7*\xa7\xb8\x98\x05\x14\x111 \x1f\x11\x0f\xb3\ ++\x9c\xbf$6$n\x00\x80_\x8e\x13?\xb6\xa5\x98\ +M\x11\xf7\xfa-\xcaC\x86\xa4_\xef\x8cBP?\xf9\ +d\x16QD\xc4\x00\xfc\x95\xd8\xc0\xaep\xfe\x0a;\xe7\ +\x00P\x15F\x89\x9f\xd8R\xd4N\x12w\xfb-\xce\xbd\ +z)g\xd7.\xfb\x03\xba\xfe\x22\xd1\xb2%\x8b)\x22\ +b\x16\xbdS\xaceW8\x7f[<\x9cx\x01\x00U\ +e\x82\xf8\x99-\xc5m\xb8\xf8\xae\xdf\x22\xdd\xb9\xb3r\ +\xb6o\xb7?\xa4\xebG\x97\x0a\x0aXT\x11\x11\xb3\xe0\ +Mb\x0d\xbb\xc2\xb9,_\x89f\xc4\x0a\x00\xc8\x16s\ +\xc4/m)r#\xc4\xf7\xfc\x16\xeb\x16-\xd2m\x0d\ +m\x0f\xe9#F\xb0\xb0\x22\x22V\xd1\x1f\x88%v\x85\ +\xf3?\x88\x1d\x89\x13\x00\x90m\xce\xb3\xa8\xd0\xa9\x81\xe2\ +[~\x8bv\x93&\xcaY\xb7\xce\xee\xc7\x8bv\xeeT\ +Ny9\x0b,\x22b\x86^#\x16\xd9\x15\xce\xffW\ +\xecN\x8c\x00\x80\xa0\xb8\xd8\xa6\x90\xae\x9fh~\xcdg\ +\xe1N6j\xa4\x9c5k\xec\xdeE\xd7\x0f.\xe9N\ +4,\xb4\x88\x88\xbe\xdc.\x16\xd8\x15\xce\xff(v#\ +>\x00@\xd0\x5chSH\xef\xe2><\xe1\xebA\xa3\ +:uTR\x9f\xf7\xb6\xb9\xf5b\xbf~,\xb6\x88\x88\ +>\xd4/P\xe7\xd9\x15\xce\x7f/v&6\x00\x80)\ +\x16&,:\x93\xde\xce}\x80\xc2W1/.V\xa9\ +s\xce\xb17\xa4o\xdf\xae\x92\x0d\x1a\xb0\xe8\x22\x22z\ +\xf0B\xbb\x82\xb9V\xfe\xb18s\x0e\x00\xe6\x99%~\ +aK1\xd4\x0fP<\xe6\xb7\xa8\x17\x16\xaa\xe4\xf4\xe9\ +\xf6\x86\xf4\xf3\xce\xe3\xa8\x0b\x22\xe2A\xdc#\x9ej_\ +8\xd7\xad\x14\x9b\x13\x13\x00 ,\xe6\xd9\xb4\x93\xdeD\ +|\xd8o\x81\xd7\x01\xf8\xa4\x93\xec\xbd4:p \x8b\ +0\x22\xe2\x01\xd4\xefb\x9cl_8\x97\xef\x0c\x896\ +\xc4\x03\x00\x08\x9b\xc9\x09\x8b\xfa\xa4\xeb\x07)~\x92I\ +\xb1\x1f:\xd4\xceWGu\xffv\x8e\xba \x22~\xc5\ +\xd7\xc5\xfe\xf6\x85\xf37\xc5#\x88\x05\x00`\x0b\xa7\xda\ +\x14\xd2\xab\x89\xd7fR\xf4{\xf6T\x8ensh[\ +H_\xb0\x80\xa3.\x88\x88\xae/\x8a\xdd\xec\x0b\xe7/\ +\x8b\x8d\x89\x03\x00`\x1b\x93l\x0a\xe9\xba\xcd\xd6\xd6L\ +\x8a\x7f\xfb\xf6\xca\xd9\xba\xd5\xbe\x90\xde\xbf?\x0b3\x22\ +\xe6\xbcO\x8bm\xec\x0b\xe7\xf2\x9d!QN\x0c\x00\x00\ +[\x99(~jK\xd1\xd4\xed\xb6\x96g\xb2\x084m\ +j\xdf\x83F\xf2\xa5!U\xaf\x1e\x0b4\x22\xe6\xac\xf7\ +\x8b\xe5\xf6\x85\xf3\x17\xc4F,\xff\x00`;'\xdb\x14\ +\xd2\xb5\xb3\xf4\x03E~\x17\x83\xfa\xf5\x95\xb3b\x05G\ +]\x10\x11-\xf0.\xb1\x8e}\xe1\xfc\xb7bC\x96}\ +\x00\x88\x0aV\x9dI\xd7N\x17\xf7\xfa]\x14JK\x95\ +\xb3h\x91]!\x9d\x07\x8c\x101\xc7\xbc\xddm\x00`\ +Y8\x7fZl\xc0r\x0f\x00\x1cw\xa9\xa2c\xdd\xb6\ +\x5c\xbe\x16\x87\x92\x92\xf4\xce\xb5-\x01}\xf3f\x95\xaa\ +]\x9bE\x1b\x11s\xc2\x1b\xc4\xea\xf6\x85\xf3\x87\xc5Z\ +,\xf3\x00\x10UN\x12?\xb1\xa9\xb0\x0e\x12\xdf\xf4\xbb\ +H\xe4\xe7\xab\xd4i\xa7\xd9\x13\xd2\xe7\xcf\xe7\xa8\x0b\x22\ +\xc6\xde\x1db\xa1}\xe1\xfc\x1e\xb1\x06\xcb;\x00D\x9d\ +\xe1\xe2?l*\xb0G\x89/e\xf2\xa0\xd1\x981\xf6\ +\x84\xf4^\xbdX\xc0\x111\xb6\xaer/\xfa[\x16\xce\ +o\x17\x8bY\xd6\x01 .\xf4\x17\xffjS\xa1m\xe3\ +\xb6\xeb\xf2\xbdp\xe8`lC\xaft\xfd\x80Q\xc3\x86\ +,\xe4\x88\x18+\xf5\x85\xfey\xf6\x05s\xed\x8db!\ +\xcb9\x00\xc4\x8d\xa3\xc5?\xdaTp\x1b\x8a\xf7f\xda\ ++}\xcb\x96\xf0C\xba\xbe\xc0\x9a\x9f\xcf\xa2\x8e\x88\xb1\ +P\xdf\x11\x9ahg8\xff\xb6\x98\xcf2\x0e\x00q\xa5\ +\xa5\xf8\x96M\x85\xb7\xc4\xbd\x84\xe4{1i\xd2D%\ +\xd7\xae\x0d?\xa4\x8f\x18\xc1\xc2\x8e\x88\x91\xf75\xb1\x9f\ +\x9d\xe1|\x09K7\x00\xe4\x02M\x12\xe9W\xd7\xac)\ +\xc0\xfa\xd5\xd1M\x19,(\xfb\xba\xa9,]\x1an@\ +\xdf\xb5K9\xcd\x9b\xb3\xc0#bd}Flo_\ +0\xffR<\x97%\x1b\x00r\x09\xfd\xea\xda\xf3\xb6\xed\ +\x94\x9c\x93\xc9\xe2R\x5c\xac\x9cy\xf3B\x0d\xe9\xa9K\ +/UNQ\x11\x0b=\x22F\xce\x87\xc5\xc3\xed\x0b\xe7\ +_\x88sX\xaa\x01 \x17\xa9#>j[H?U\ +\xdc\xe3\xf7R\x93>\x07>yr\xb8;\xe9\x13'\xb2\ +\xd8#b\xa4\xfc\xa9X\xdb\xbep\xae\xdf\xef\x98\xcc\x12\ +\x0d\x00\xb9\x8c\xee%{\xafm!}\x84\xf8v&m\ +\x18G\x8fVNee8\x01]\xff\xe7\x1ey$\x8b\ +>\x22F\xc2k\xc4j\xf6\x85\xf3\x8f\xc5\x13Y\x9a\x01\ +\x00\xd2!\xfdn\xdbBz\x7f\xf7\xd2\x92\xef\x85\xa7O\ +\x9f\xf4\xb9\xf00B\xfa\xbau\xca)-e\xf1GD\ +\xab\xdd%\x16\xd9\x17\xce?\x12G\xb3$\x03\x00\xfc\x97\ +j\xe2\x8fl\x0b\xe9\x1d\xc5\xe73Y\x80:tP\xce\ +\xd6\xad\xe1\x84\xf4\x193\x08\x00\x88h\xad\xcb\xed|\x80\ +\xe8/b?\x96b\x00\x80\x03\x87\xf4\x9bm\x0b\xe9\xfa\ +\xf2\xd2C\x99,DM\x9b\xa6w\xb4\xc3\x08\xe9\xc7\x1c\ +C\x10@D\xab\xdc+~\xcb\xce6\x8a\xf2\x8f\x96\xe8\ +\xcc\x12\x0c\x00\xf0\xcd\xe8\x87 \xae\xb0\xad\x80\xd7\x15\xef\ +\xcc\xa4\x0dc\x9d:\xcaY\xb6\xcc|@\xdf\xb2E\xa5\ +\xea\xd5#\x14 \xa2\x15\xbe+\x8e\xb13\x9c\xbf&6\ +g\xe9\x05\x00\xf0\xc6J\xdb\x0ayu\xf1\xbb\x99,N\ +%%\xca9\xff|\xf3!}\xc1\x82\xf4\xc5U\xc2\x01\ +\x22\x86\xe8\xabbo;\xc3\xf9\xd3bC\x96[\x00\x00\ +\x7fL\x15?\xb3\xa9\xa0\xebs\x93\x8b2Y\xa4t\x8f\ +\xf2\xd9\xb3\xcd\xf7G\x1f<\x98\x80\x80\x88\xa1\xf9\xa8\xd8\ +\xdc\xcep\xfe\xb3D\xbaA\x01\x00\x00d\xc0\x18\xf1\x9f\ +\xb6\x15\xf7Y\xeey\xca\x8c\xda0\x9a\x0c\xe8;w*\ +\xe7\x88#\x08\x0a\x88h\xdc;\xdd\xe3\x81\x16\x86\xf3k\ +\xc5\x02\x96W\x00\x80\xaa1H\xfc\x9bmE~T&\ +\xbd\xd2\xb5}\xfb\xaaTE\x85\xd1WFS\xd5\xaa\x11\ +\x18\x10\xd1\x987\x885\xec\x0c\xe7\x9b\xc4<\x96U\x00\ +\x80\xec\xd0)\x91\xbeioU\xb1\xef.\xbe\x90\xc9\x02\ +\xd6\xb1\xa3J\x1al\xc3\x98\xd2\xaf\x9c\x12\x1a\x10\xd1\x80\ +\x92\x80U\x81}\xc1\xfcK\xf1<\x96R\x00\x80\xec\xd3\ +R|\xc3\xb6\x90\xde\xdc=g\xe9{!k\xd5J9\ +\x9b7\x9b{e\xb4S'\xc2\x03\x22\x06\xea9v\xee\ +\x9a\xeb\xbbLg\xb2\x84\x02\x00\x04G\xb9\xf8\x9cm\x0b\ +\x80>gyG&\x0bZ\xfd\xfa\xcaY\xb1\xc2LH\ +\xbf\xfcrZ/\x22b \xee\x16O\xb53\x9c\xeb;\ +LcX:\x01\x00\x82\xa7\x9e\xf8\x84m\x0bA\x99\xf8\ +\x83L\x16\xb7\xd2R\xe5\x5cp\x81\x99\x90\xae\xdb=\xe6\ +\xe7\x13(\x101\xab=\xceO\xb07\x9c\x9f\xc8\x92\x09\ +\x00`\x8e\xd2D\xbaM\x96U\x0bB\xa1\xb85\x83\x05\ +.YX\xa8\x9cY\xb3\xcc\x84\xf4\xe1\xc3\x09\x15\x88\x98\ +\x15_\x11{\xd9\x19\xce\xff,\xf6c\xa9\x04\x000\x8f\ +n\x93u\xb5\x85\x0b\x83Z\xa8C\xb7\xdf\xc5.?_\ +%'M\x0a>\xa0\xef\xda\xa5\x9c\x16-\x08\x17\x88X\ +%\x9f\x12\xdb\xda\x19\xcew\x8b\x1dY\x22\x01\x00\xc2\xc5\ +\xbaWG\xb5\x93\xdcs\x99\xbe\x17\xbe\xa1C\xd3\x97:\ +\x83\xec\xea\xb2z\xb5JU\xafN\xc8@\xc4\x8c\xfc\x95\ +Xng8\x7fA<\x8ce\x11\x00\xc0\x0e\xa6\x88\x9f\ +\xda\xb6X\xf4\x10_\xcad\x01<\xfah\xe5\xec\xd8\x11\ +\xecN\xfa\x94)\x04\x0dD\x8cS\x8f\xf3_$\xd2\xc7\ +\x1f\x01\x00\xc0\x22\x86\x89\x1f\xd8\xb6h\xb4\x10\x1f\xcfd\ +!l\xdf^9[\xb6\x04\x1b\xd2{\xf4 p \xa2\ +g7\xda\xd9\xe3\xfc\xdf\xaf\x83\x16\xb2\x0c\x02\x00\xd8I\ +\x97\x84\x85\x0f\x1a5\x12\xef\xc9\xe4\xf2h\xb3f*\xb5\ +qcp\x01}\xd3&\xe5\xd4\xaeM\xf0@\xc4\x83\xd7\ +\x22{{\x9ckW%x\x1d\x14\x00\xc0z\xf4\x83F\ +\xaf\xd9\xb6\x88\xd4p\x7f\x1a\xf6\xbd8\xea\x00\xbdlY\ +p\xe7\xd1/\xbcP9\x05\x05\x84\x10D\x8cZ\x8f\xf3\ +/\xc4\x05,y\x00\x00\xd1A\xf7J\x7f\xcc\xb6\x05E\ +\xff4\xbc!\x93E\xb2\xa4$\xdd\xc3<\xa8\x9d\xf4\xb1\ +c\x09\x22\x88\xf85\xdf\x10\x07\xd9\x19\xce?\x16'\xb0\ +\xd4\x01\x00D\x0f+{\xa5kg\x89{\xfd.\x96\x85\ +\x85*9}z0\x01]w\x8d\xe9\xd8\x91@\x82\x88\ +\xff\xf1wb7;\xc3\xf9\xdf\xc4\xa1,q\x00\x00\xd1\ +E\xf7J\xbf\xc6\xc6\x90>\xc6}\x81\xcf\xd7\xa2\x99\x97\ +\xa7\x9c\xd1\xa3\x83\x09\xe9\xfa\xac;\xe7\xd1\x11Q|D\ +lfg8\x7f_\xec\xcc\xd2\x06\x00\x10}\xf2\xc5m\ +6\x86\xf4c\xc573Y@\x87\x0c\x09\xa6W\xba>\ +F\x93\x9fO@A\xcca\x7fio\x8f\xf3w\xc4\xf6\ +,i\x00\x00\xf1bQ\x22}\xa9\xc8\xaaE\xa7\x8b\xf8\ +|&\x0bi\xb7n*\x15D\xaf\xf4\xe3\x8f'\xa4 \ +\xe6\xa87\x8bev\x86\xf3g\xc5\xc6,c\x00\x00\xf1\ +d\xac\xf8\x91m\x8bO\xb9\xbbk\xe5w1M\xb5l\ +\x99n\x95\x98\xed\xf3\xe8\xba\x07;a\x05\x91\x1e\xe7v\ +x\xa7X\x83\xe5\x0b\x00 \xde\x0c\x14\xffl\xdb\x22T\ +[\xbc=\x93\x85\xb5aC\xe5\xacZ\x95\xdd\x90\xben\ +\x9dr\xca\xca\x08-\x889\xe2r1\xcf\xcep\xfe]\ +\xb1\x88e\x0b\x00 7\xe8\x90H\x9fg\xb4j1\xaa\ +&^\x9b\xc9\x02[\xab\x96r\x96.\xcdnH\x9f7\ +/})\x95\xf0\x82\x18\xeb\x07\x88\xe6\xda\xfb\x00\xd1\xba\ +\x04\x0f\x10\x01\x00\xe4\x1c\xbaW\xfa\xc3\xb6-Jz\x17\ +\xeb\x92L\x16\xdb\xe2\xe2t\xa8\xcefH\x1f6\x8c\x10\ +\x83\x18S\xdf\x11G\xd9\x19\xcc?\x15\xcfd\x89\x02\x00\ +\xc8]\x8a\xc5\x9bl\xdc=\xca\xa4WzRw`9\ +\xfd\xf4\xec\x05\xf4]\xbb\x94\xa3\xcf\xb9\x13f\x10c\xe5\ +Kb\x0f;\xc3\xf9\x07\xe2q,M\x00\x00\xa0\x7fB\ +\xddhcH?\xde\xdd\xe5\xf2\xdd+}\xc2\x84\xec\x85\ +\xf4\x95+U\xaazuB\x0dbL|Zlgg\ +8\xdf+veI\x02\x00\x80\xfd9/aa\x1bF\ +\xbd\xcb\xf5b&\x0b\xf1q\xc7e\xafW\xfa\xcc\x99\x04\ +\x1b\xc4\x18x\x9f\xbd=\xce_\x15[\xb2\x0c\x01\x00\xc0\ +\x81\x18/\xfe\xd3\xb6\xc5\xab\x85\xf8X\x86\xbd\xd2\x9dl\ +\xf5J\xe7<:b\xa4\xd5]\xa2j\xd9\x19\xce\x1fI\ +\xa4\xef\x04\x01\x00\x00|#}\xc4?\xda\xb6\x885\x14\ +\xef\xcedan\xdbV9[\xb6T9\xa0\xa7**\ +\x94\xd3\xba5A\x071\x82^\xe5v\x89\xb20\x9c\xdf\ +\x9aH\xdf\x05\x02\x00\x008$\xad\xc5\xd7m[\xccj\ +\x887d\xf2\xa0Q\xd3\xa6\xe9\xde\xe6Y\xe8\x8f\x9e\xa4\ +?:b\xa4\x5cg\xef\x03DW\x88\x05,7\x00\x00\ +\xe0\x87\xfa\xe2\xa3\xb6-jz\xa1\xdd\x90\xc9B]\xbf\ +\xberV\xac\xa8zH_\xb0@9\xba[\x0c\xc1\x07\ +\xd1\xfa\x1e\xe7\xb3\xec\x0c\xe6_&\xd2w~\x00\x00\x00\ +2\xa2\xa6x\xafm\x0b\x9c\xee\x95\xbe$\x93E\xbb\xb4\ +T9\x8b\x16U=\xa4\x9fp\x02\x01\x08\xd1b\xdf\x17\ +\xcf\xb43\x9c\x7f.\x9e\xc5\xd2\x02\x00\x00UE?3\ +}\xbd\x85\x0b\x9d\x9a\x22\xee\xf1\xbbxW\xabV\xf5\x07\ +\x8dtw\x98\x8e\x1d\x09B\x88<@\xe4\xc7\x8f\xc4\xb1\ +,)\x00\x00\x90M\xacl\xc38@|-\x93\x07\x8d\ +\xce8\xa3j\x97F7mRN\x9d:\x04\x22D\x8b\ +|A\xecfo\x8f\xf3.,#\x00\x00\x10\x04'\x8b\ +\x1f\xdb\xb6\xf8u\x10\x9f\xc9\xe4A\xa3\xd1\xa3\xab\xb6\x93\ +\xbex\xb1r\x0a\x0b\x09F\x88\x16\xa8[\xb16\xb7\xb7\ +\xc7y\x0b\x96\x0f\x00\x00\x08\x92~\xe2\x9fl[\x04\xf5\ +\xe3#\xbf\xcada\x1f5\xaaj\x0f\x1a\x8d\x1dK8\ +B\x0c\xd9{\xdcV\xac\x16\x86sz\x9c\x03\x00\x801\ +\x8e\x14\xdf\xb3m1,\x13\x7f\x98\xc9\x02\xdf\xb3\xa7r\ +v\xed\xca\xfc<\xfaQG\x11\x92\x10C\xf2\xfbn\x0b\ +V\x0b\xc39=\xce\x01\x00\xc08\x8d\xc5gl[\x14\ +\x8b\xc4\x8aL\x16\xfa\xa3\x8fV\xa9\x9d;3\x0b\xe9\x9b\ +7+\xa7^=\xc2\x12\xa2a\xb7\x8a\x85v\x86\xf3\xca\ +\x04=\xce\x01\x00 $J\xc5\x9f\xd9\xb68\xea6\x8c\ +\x8b2y\xd0\xa8M\x9b\xcc_\x1d]\xb6L\xa5t\x87\ +\x18B\x13\xa2\x11\x17\xb9s\xdd\xb2\xfa\xa3/\xd2\xd3\xe3\ +\x1c\x00\x00BG\xef\x12}\xdb\xc2\x1d,59\x836\ +\x8c\xfa\xd5\xd1\xd4\xfa\xf5\x99\x85\xf4\xe9\xd3\x09N\x88\x01\ +\xbbW\x9ci\xe7\xae\xf9\xa7\xe2T\x96\x04\x00\x00\xb0\x85\ +e\xdb\xe2\xaa\xfb&_\xe17,\ +\xe4\xe5)g\xc2\x04\xff\x8f\x18u\xeaD\xd0B\xcc\xc0\ +\x1f\x8b\xb5\xec\x0c\xe7\xdf\x13\x8b(\xef\x00\x00\x10e\xf4\ +Kz7\xd9\xb6\xc8f\xd4+]\x87\xf4\xf1\xe3\xfd]\ +\x1a\xdd\xb4I9u\xeb\x12\xb8\x10}\xf8m\xf7\xd11\ +\x0b\xc3\xf9\x12J:\x00\x00\xc4\x05\xdd\x86q\x93\x85\x8b\ +\xad\x9a\xe1\xf6U\xf6\x15 \x86\x0f\xe7\x11#\xc4\x80\x5c\ +i\xe7\x03D\x9f\x893(\xe5\x00\x00\x10G\xf4\x0b{\ +_\xd8\x16\xd2\x8f\xcf\xa0Wzj\xe0\xc0\xf4\x11\x16\xaf\ +!}\xda4\xc2\x17\xe2!<\xc7\xce]\xf3\x7f\x8ac\ +)\xdf\x00\x00\x10g&\xb8\x0b\x9eU\x8bp?\xf15\ +\xbf\x81b\xd0 \x7f!\xbdwoB\x18\xe27\xbc\x0e\ +:\xcd\xcep\xfe'\xb17e\x1b\x00\x00r\x81\xbe\xee\ +\xc2g\xd5b\xdcA|\xceo\xb8\xe8\xd1C9\xbbv\ +y\x0b\xe8\xf2\xff/\xd5\xa6\x0d\x81\x0cq?\xf5\xafW\ +\xa3\xec\x0c\xe7\xbb\xc5\x8e\x94k\x00\x00\xc8%\x8e\x14\xdf\ +\xb3mQ>B|\xd4o\xc8\xe8\xdcY9;vx\ +\xbb4\xbaa\x83J\xd5\xa9C0C\x14_\x17\xfb\xdb\ +\x19\xce\x9f\x17\x9bP\xa6\x01\x00 \x17\xd1\x0b\xe0\xb3\xb6\ +-\xceu\xc5\xbb\xfc\x86\x8dv\xed\x94\xb3m\x9b\xb7\x9d\ +\xf4\xc5\x8bU\xb2\xb0\x90\x80\x869\xed\x8bb7;\xc3\ +\xf9Cb\x1d\xca3\x00\x00\xe42\xfa\xb1\x8f_\xd8\xb6\ +H\xd7\xc8\xe0A\xa3}\xc7W\xb6n\xf5\x16\xd2'O\ +&\xa4a\xce\xfa\xb4\xd8\xc6\xcep~K\x22\xdd\x1a\x16\ +\x00\x00 \xe7\xd1\x0b\xe2\xcd\xb6-\xd6\xd5\xc4\xff\xf1\x1b\ +>\x9a5S\xce\xe6\xcd\xdeB\xfa\x80\x01\x845\xcc9\ +\x1f\x13\x9b\xd9\x19\xce\xaf\x13\x0b)\xc7\x00\x00\x00\xffE\ +\xf7J_e\xdb\xa2\xad\xfb1_\xe27\x844i\xa2\ +\x9c\xf5\xeb=]\x1au\xb84\x8a9\xe4\x1dbm\xfb\ +\x82\xf9\x97\x09\x1e \x02\x00\x008(V\xf6J_(\ +&\xfd\x84\x91\xf2r\xe5\xac[w\xe8K\xa3\x1b7*\ +\x87K\xa3\x98\x03\xfeX\xaci_8\xff\x5c\x9cG\xd9\ +\x05\x00\x0084'\x8b\x1f\xdb\x16\xd2'\x89{|\x86\ +\xf4\x94\x87\x9d\xf4\xe4\xc2\x85\xca)( \xc4al\xd5\ +\xf79J\xec\x0b\xe7\x1f\xbb\xb5\x06\x00\x00\x00<\xd2S\ +\xfc\xbdm!}\x80\xf8\x86\x9fpR\xaf\x9erV\xaf\ +>\xf4q\x973\xcf$\xc8a,\xdd.\x16\xd8\x17\xce\ +\xff\xe8\xd6\x18\x00\x00\x00\xf0IK\xf15\xdbB\xfaQ\ +\xe2K~\xba\xbbHHOy\x09\xe9\x03\x07\x12\xe80\ +V\xaev\xefqX6\x87\xdf\x14[S^\x01\x00\x00\ +2\xa7\x9e\xf8\x88m!\xbd\xad\xf8\xac\x9f\xb0R\xb7\xae\ +rV\xad:\xf4\xa5\xd1\xb6m\x09v\x18\x0b\xcf\xb1\xb3\ +S\xcbsbc\xca*\x00\x00@\xd5\xd1m\x18o\xb1\ +m\xb1?\xdc\xef\xab\xa3\xfa2\xe8!B:\x97F1\ +\xea&\xed\x0d\xe7\xf7&\xd2\xef.\x00\x00\x00@\x96(\ +\x10+m[\xf4\x1b\x8a\xbf\xf4\x13`j\xd5R\xce\xf2\ +\xe5\x07\xdfI_\xbaT9EE\x84=\x8c\x9c{\xc5\ +3\xed\x0c\xe77\x89\xd5(\xa3\x00\x00\x00\xc1\xb0\xca\xb6\ +\xc5\xbf\x8e\xf83?;\x8c5k\x1e:\xa4O\x9bF\ +\xe0\xc3H\xf9\xbe8\xd9\xcep~\xa5\xfb\x05\x1f\x00\x00\ +\x00\x02d\xaa\xf8/\x9bB@\xa9x\x93\x9f@#!\ +=y\xc9%\x07?\xee2x0\xc1\x0f#\xe1nq\ +\xac\x9d\xe1|%\xe5\x12\x00\x00\xc0\x1c#\xc4\xbf\xdb\x14\ +\x06\x8a\xc4\xab|\x86t\xe7`!\x9dK\xa3\x18\x01\xdf\ +\x11\x87\xd9\x17\xcc\xf5cg\xe7P&\x01\x00\x00\xccs\ +\x8c\xf8\x07\x9b\x82\x81\xee\xf7\xbc\xc9\xcfq\x97\xb22\xe5\ +,[v\xf0K\xa3\xba\x03\x0cA\x10-\xf4u\xb1\xaf\ +}\xe1\x5c\xff\xba6\x99\xf2\x08\x00\x00\x10\x1e\xcd\xc5W\ +-\x0b\x08\xfb\xbaXx\x0e:5j\xa8\xd4\x92%\x07\ +\xbd4\x9a\xaaV\x8d@\x88V\xf9\xbc\xd8\xce\xbep\xfe\ +\x818\x98\xb2\x08\x00\x00\x10>\xba\xaf\xf1s\xb6\x85\xf4\ +9n\xcb9\xcf\xc7]\x0evqt\xf2dB!Z\ +\x15\xce\xdb\xdb\x17\xce\xff,\xf6\xa5\x1c\x02\x00\x00\xd8C\ +-\xf1>\xdbB\xfa\xa9nw\x0bO\xc1\xa7\xac\xec\xe0\ +\x17G\x87\x0c!\x1cb\xe8>-\xb6\xb0/\x9c\xcbw\ +\xe1Dg\xca \x00\x00\x80}\xe8Vj\xffc[H\ +\x1f.\xbe\x9b\x85\x9d\xf4TE\x85r\xda\xb5#$b\ +h>(6\xb2/\x9c\xffNlB\xf9\x03\x00\x00\xb0\ +\x97\xbc\x84\x85\xbd\xd2\xfb\x89oz\x0dB\xf5\xea)g\ +\xed\xda\x03\xef\xa2\xaf_\xcfK\xa3\x18\x8a\xbfv\x1f\xe6\ +\xb2ln=&\xd6\xa5\xec\x01\x00\x00D\x83\xf9\x89t\ +\xab5k\xc2D/\xb7\xeb\x85\xa7@\xa4;\xb7\xacY\ +s\xe0\x90\xae\xbb\xbepi\x14\x0dz\xbf\xd8\xc0\xbep\ +~\xb7XJ\xa9\x03\x00\x00\x88\x16\x13\xc4\x8fm\x0a\x15\ +]\xc5\x97<\x86\xa2\xd4\xc1v\xd2\xe7\xccQN^\x1e\ +\xe1\x11\x03\xf7\xe7bm\xfb\xc2\xf9\xcdb5J\x1c\x00\ +\x00@4\x19\x9aH\xb7^\xb3&\x5c\xb4s\xbb`x\ +\x0aH\x8d\x1a\xa9\x94>\xd6r\xa0\x90>z4\x01\x12\ +\x03\xf5.\xb1\x96}\xe1\xfc\xdb\x89\xf4}\x13\x00\x00\x00\ +\x880}\xc4\xbf\xd8\x142:\x88\xbf\xf5\x1a\x94\xca\xcb\ +Uj\xc3\x86\xaf\x07\xf4\xcaJ\xe5\xf4\xe8A\x90\xc4@\ +\xbc\xdb\xce\x9d\xf3\xcb\x13\xe9{&\x00\x00\x00\x10\x03:\ +\x8a{l\x0a\x1b\x87\x8b\x8f{\x0dLM\x9b*g\xf3\ +\xe6\xafwv\xd9\xb1C9\xcd\x9a\x11(1\xab\xde*\ +\xd6\xb0+\x98\x7f)\x9eK\x19\x03\x00\x00\x88\x1f\xcd\xc4\ +\xd7l\x0a\xe9\x8d\xdc\xee\x18\x9e\x82\xd3\xe1\x87\x1f0\xa4\ +\xef;\xa7\xae\xdb3\x12,1\x0b\xde,\x96\xd8\x15\xce\ +?\x13\xa7R\xbe\x00\x00\x00\xe2KS\xf1\x05\x9bBz\ +\xb9\xdb_\xdaS\x80j\xd1B9[\xb7~=\xa4/\ +Z\xa4\x92\x85\x85\x04L\x8c\xdb\xce\xb9\x0e\xe7gR\xb6\ +\x00\x00\x00\xe2O\x99\xf8K\x9bBz-\xf7B\x9e\xa7\ + \xd5\xaa\x95r\xb6m\xfbzH\x9f:\x95\x90\x89\x19\ +{\x9dXdW8\xff\xa7x\x02\xe5\x0a\x00\x00 w\ +(\x16\x7fdSH\xd7;\x97\xb7x\x0dT\x9d;+\ +g\xd7\xae\xaf\x87\xf4\xfe\xfd\x09\x9b\xe8\xdb\xff\xb1/\x9c\ +\xeb\xceK\x83(S\x00\x00\x00\xb9\x87\xee\xa3|\x93M\ +!\xbd\xd4=f\xe0)Xu\xeb\xa6R\x15\x15_\xbd\ +4\xaa\xff\xfb\xf6\xed\x09\x9d\xe8\xd9\xeb\xed\x0b\xe7\x7f\x15\ +\xfbS\x9e\x00\x00\x00r\x17\xdd\xb2m\xb3M!]\x87\ +\xa5k\xbd\x06\xac\x01\x03\xbe\xbe\x8b\xae/\x926lH\ +\xf8\xc4C\xfam\xb1\xc0\xaep\xbe7\x91\xee\xb8\x04\x00\ +\x00\x00\x90X\x92H\xb7r\xb3\x22\xa8\xe8\xd0t\xa5\xd7\ +\xa05j\xd4\xd7\xdb/\xaeX\xa1\x9c\x92\x12B(F\ +i\xe7\xfc-\xb1\x05\xa5\x08\x00\x00\x00\xf6gZ\x22\xdd\ +5\xc2\x9a\x90~\x85\xd7\xc05a\xc2\xd7w\xd2\xcf:\ +K9yy\x84Q\xfc\x9a\xdf\xb1/\x9c\xeb\xceJM\ +(A\x00\x00\x00p N\x12?\xb6)\xa4Wz\x09\ +]:\x88O\x99\xf2\xf5\x90>f\x0c\x81\x14\xbf\xe2w\ +\xed\x0b\xe7O\x8a\xf5(=\x00\x00\x00p0\x86\x8a\x1f\ +\xda\x14\xd2+\xbc\x84\xaf\xfc|\xe5\xcc\x9e\xfd\xd5\x80^\ +Y\xa9\x9cc\x8e!\x98\xe2>o\xb0/\x9c?\x22\xd6\ +\xa6\xe4\x00\x00\x00\x80\x17\x06\x8a\x7f\xb3%\xc8\x14\xb9\xad\ +\xf0\x0e\x19\xc2\x8a\x8a\x94\xb3p\xe1WC\xfa\x8e\x1d\xca\ +i\xde\x9c\x80\x9a\xe3\xfe\xc8\xbe\x17B\x1f\x12kRj\ +\x00\x00\x00\xc0\x0f\xba\x9bD2a\xd1N\xfaN/a\ +\xaczu\xe5,]\xfa\xd5K\xa3\xeb\xd7\xabT\x9d:\ +\x04\xd5\x1c\xf5F\xb1\x9a]\xe1\xfc\x8eD\xfa-\x02\x00\ +\x00\x00\x00\xdf\xb4\x13\xf7\xd8\x14\xd2wx\x08d\xc9\xb2\ +2\xe5\xe8N.\xfb\x87\xf4\xc5\x8bU\xb2\xb0\x90\xc0\x9a\ +c\xea\xbe\xfa\xd5\xed\x0a\xe7\xb7'\xd2o\x10\x00\x00\x00\ +\x00dL[q\xb7-\x01\xa7\xd0\xed_}\xc8pV\ +\xb7\xaer.\xbb\xec\xab\xc7]\xce<\x93\xd0\x9aC\xde\ +)\x96\xd9\x15\xce\xe5\x1f\x89\x9ds\x00\x00\x00\xc8\x0e\xcd\ +\xc47\x12\x89\x88\xb5`l\xd2$\xfdp\xd1\xfe!\xfd\ +\xd8c\x09\xaf9\xe0]bM\xbb\xc2\xf9\x8f\x13\xec\x9c\ +\x03\x00\x00@\x96\xd1\xad\xe0~cK\xe0\xc9\x13\xd7{\ +\x09k\xed\xda\xa9\xd4\xce\x9d\xff\x0d\xe8\xbbv\xed\xfb\x7f\ +#\xc4r!\xd4\xa0\xd7\x8b\x05\x94\x10\x00\x00\x00\x08\x82\ +:\xe2c\x91\x0b\xe9]\xba(\xa7\xa2\xe2\xbf!\xfd\xf2\ +\xcbU\xb2Q#\xc2l\x0c\xbd]\xacaW8\xaf\x14\ +\xf3(\x1d\x00\x00\x00\x10$\xb5m\x0a\xe9\xf9\x1e/\x8e\ +:\xc3\x86}\xf5\xa8\x8b\xbeDZRB\xa8\x8d\x91\xf7\ +\x8a\xb5\xed\x0a\xe7\xd7\x8a\xf9\x94\x0c\x00\x00\x000A\xa9\ +x\x9fM!\xdd\xd3\x8b\xa3\x13'~5\xa4\x9f{n\ +\xfa\x81#\xc2m\xe4}@\xackW8\xbf2\xc1\xce\ +9\x00\x00\x00\x18F_x\xbb\xcd\xa6\x90\xbe\xebPA\ +./\xef\xeb\xaf\x8d\x9et\x12\x017\xe2>(\xd6\xb7\ ++\x9c\xaf\xa1<\x00\x00\x00@X\xe8\x8bo\xdf\xb1%\ +\x18\xe9\xee.Wzymt\xd1\xa2\xaf\x86\xf4\xbe}\ +\x09\xba\x11\xf5I\xb1\xb1]\xe1|\x09e\x01\x00\x00\x00\ +\xc2F\xff\x8c\xbf\xcb\xa6\x90~\xd5\xa1\x82]i\xa9J\ +\xad\x5c\xf9\xdf\x80\xbec\x87rZ\xb4 \xf0F\xcc\xe7\ +\xc5\x16\x84s\x00\x00\x00\x80\x03\xa2/\xc2]aKP\ +*\x16o9T\xc0k\xd0@9\x1b7\xfe\xf7\xa5\xd1\ +\x0d\x1b\x94S\xa7\x0e\xc17\x22\xbe&v\xb6+\x9c\xaf\ +\xa6\x0c\x00\x00\x00\x80m\xe8\x9d\xf4u\xb6\x04&\xdd\x07\ +\xfb\xc7\x87\x0az\xcd\x9b\xab\xffk\xef\xfec\xed\xae\xeb\ +;\x8e\x7fo\x7f\xd1\xd6\xda\x9f\x16\x1a\x1bhK\xaf\xa6\ +\x19\xb8D\xaa-m\x88s\xcd\xbaF\x94\x15\x9dT\xc6\ +\xa6\x80\xa3\xb9\x13\x7f\xc4\x94\x8b\xd8\xc9\xc0\x16*k\xb5\ ++\xed\xed6\xdc2\xe6\xb6f,\xe0d\xd9\x961A\ +\x13\xc1X\x7f!n\xc8HQA\x84\xdes\x8d\x1a\xa3\ +\x9bf*\xb4_\xdf\xdf\x9d\xe3N[\xee\xbd\xed\xed\xfd\ +\xf1\xf9\x9cs\x1e\x8f\xe4\xf5o\xd3\x9c\xf3=\xc9\xb3\xa7\ +\xdf\xf3\xf9\xd6\xf6\xeci~\x93\xfe\xfe\xf7\x97\x03\xd3\xa6\ +\x09\xe0\xcc\xf7\xcd\xd8\xab\xf3\x8a\xf3\x9d>\xfe\x00@\xce\ +\xae\xcf%\x9c\xa6\xc7\xee\x19\xe9\x19\xe9W^)\x823\ +\x8f\xf3W\xf9A(\x00\xc0\x88\xf5\x16\xad\xf4M\xfa\xba\ +u\xc7\xffht\xfdz1\x9c\xe1\x9e\x8e\xbd&\xaf8\ +\xbf\xd5G\x1d\x00h%7\xe5\x12R\xd5\xc3k\xee\x1f\ +\xc9\x19\xe9\xfb\xf7\x97\xb5\xf3\xcf\x17\xc5\x19\xedp\xec\xcd\ +y\xc5y\xf5\xc3h\xe7\x9c\x03\x00-gK.A5\ +;v\xdf0\x01\xd8_=\xb0\xe8\x1d\xefhF\xfa\xae\ +]em\xe1Bq\x9cI\x9co\xca+\xceo\xf3\xd1\ +\x06\x00Z\xd9{cGs\x89\xf4O\x9e\xec\x8c\xf4\xf7\ +\xbd\xaf\x19\xe9\xdb\xb7\x97\xb5Y\xb3Dr\xe2]\x9dW\ +\x9c\xff\xb1\x8f4\x00\xd0\x0e\xfe \x97H_\xd0x,\ +\xfc\x90A8gNY\xdb\xb1\xa3\x19\xe9\xef~w\xfd\ +\xdbu\xa1\x9cd[\xdc\xd6\x02\x000nzr\x89\xf4\ +\x85\xb1\x07\x87\x89\xc2\x81\xee\xee\xb2\xb6wo3\xd27\ +n\x14\xcb\x09vc^q\xde'\xce\x01\x80vt]\ +.\xc1uN\xec\xcb\xc3\x05\xe2\xaaU\xc7\x9f\xec\xb2f\ +\x8dh\x9e\xc0\xed\x8fM\xca'\xce?V\xd4\x1f\xc6\x05\ +\x00\xd0\x966\xc7\x8e\xe4\x10^K\x1a\x8f\x8b\x1f2\x14\ +/\xbd\xb4\x19\xe8\xb7\xdf^\xd6\x96.\x15\xcf\x13\xb0;\ +c\x93\xf3\x89\xf3?+|s\x0e\x00t\x80kr\x89\ +\xf4\x15\xb1\xc7\x87\x8a\xc5\xae\xae\xb2\xbf\xa7\xa7\x19\xe9\x1f\ +\xfaP\xfd\x1eu\x11=n\xfb\xe7\xc6\x03\xa62\x89\xf3\ +;\xc49\x00\xd0I~?\x97H_\xd9xB\xe5\xa0\ +\xf7\xa3O\x9f^\xd6>\xf0\x81f\xa4_w]Y\x9b\ +2EL\x8f\xc3\x1e\x8a\xcds[\x0b\x00@R\xef,\ +2\xf9\xe1\xe8\xebb\xcf\x0e\x15\x8f\x0b\x16\x94\x03;w\ +6#}\xd3&A=\xc6{4\xb64\x9f8\xbf'\ +6\xc5\xc7\x13\x00\xe8To/2\xf9&\xfd\x8d\x8d\x87\ +\xe2\x0c\x1a\x91\xcb\x97\x1fw\xb2K\xff\xda\xb5\xc2z\x8c\ +v\xa8q\xabQ&q~wl\xb2\x8f%\x00\xd0\xe9\ +\xdeUd\xf2M\xfaU\xc3\xc5du\x92K#\xd0\x07\ +\xaaX\xf7\xa3\xd1Q\xef\xe9\xd8\xda|\xe2\xfc\xbe\xd84\ +\x1fG\x00\x80\xba\xf7f\x12ie\xef0A\xd9_\xdd\ +\xde\xe2G\xa3c\xb2\xea\x7f+~+\x9f8\x7f(6\ +\xd3\xc7\x10\x00\xe0x\xd9\x9c\x93\xbem\xa8@\xaf\x9e*\ +\xfa\x9e\xf74\xbfI\xef\xed\xf5\xa3\xd1\xd3\xdc\x95\xf9\xc4\ +\xf9\xc3\xb19>~\x00\x00\x83\xdb\x99C\xb4U\xe7p\ +\xff\xd5Pq9sfY\xbb\xf9\xe6f\xa4_~\xb9\ +\xe0\x1e\xe1\xb6\xe7\x13\xe7\xdf\x8c\xbd\xd4\xc7\x0e\x00`x\ +;r\x88\xb7\xa9\xb1\x03CE\xe6\xe2\xc5\xe5@\xf5\xf0\ +\xa2_\xde\xeeR=yTx\x9f\xd2\xf6\xc4\xba\xf2\x88\ +\xf3\xa7b\x8b}\xdc\x00\x00NM\x16\xdf\xa4\xcf\x88\xfd\ +\xd3P\xb1\xb9re3\xd0\xf7\xed+\x07\xba\xbb\x05\xf8\ +Iv\xa0\xf1\x0f\x9f\x0c\xde\xdb\xf8\xeb\x14\xcb}\xcc\x00\ +\x00N]\xf5\x04\xc7?\xcd!\xd2g\xc7\x1e\x18*:\ +/\xbb\xacy\xab\xcbm\xb7\x95\x03s\xe7\x0a\xf1!\xf6\ +/\x8d\x7f\xf0d\xf0\x9e~?v\xbe\x8f\x18\x00\xc0\xe9\ +E\xfa\x1d9D\xfaY\xb1/\x0c\x16\x9e\x93'\x97\xb5\ +-[\x9a\xdf\xa4\xf7\xf6\x96\xfd~4\xfa\x82}66\ +?\x8f8\xff\xef\xd8\xab}\xb4\x00\x00N_\xf5\xd0\x98\ +\xbbs\x88\xf4\x97\xc5\x1e\x1f,@\xe7\xcf/k\xbbv\ +5#\xbd\xfaV]\x94\xff\xff\x1e\x8b-\xcf#\xce\x7f\ +\x1a\xfbM\x1f)\x00\x80\xd1\x9b\x1a\xbb7\x87H_\x1d\ +\xfb\xd6`!\xfa\xf2\x97\x97\xb5\xbe\xbef\xa4_x\xa1\ +8o<\x88hU\x1eq\xfe\x5c\xec\x8d>J\x00\x00\ +c\xa7\xfa&\xfd\x1fr\x88\xf4\xf5\xb1g\x07\x0b\xd2\x0d\ +\x1b\x9a\x81^\x9d\xf0r\xf6\xd9\x1d\xff \xa27\xe4\x13\ +\xe7o\xf2\x11\x02\x00\x18{\xd3c\x0f\xe4\x10\xe9\xd7\x0e\ +\x16\xa5]]em\xf3\xe6f\xa4Wg\xa5\xcf\x98\xd1\ +\xb1\x81~C\x1eq~4v\xad\x8f\x0e\x00\xc0\xf8\x99\ +Q\xd4\x1f\xcb\x9e<\xfen\x1e,L#\xc8\x07\xb6m\ +kFzOO=\xdc;,\xce\xf7\xe5s\xd6\xf9u\ +>2\x00\x00\xe3\xafz,\xfb#\xa9\xe3oR\xec/\ +\x86x\x88Qm\xcf\x9ef\xa4\xaf[\xd7Qq\xfe\xf1\ +|\xce:\xdf\xed\xa3\x02\x000q\xce\x8c=\x91:\x02\ +\xcf\x18\xeaAF\x17]\xd4<\x1f}\xef\xde\xb2\xb6d\ +IG\xc4\xf9\xc1\xd8\xbc<\xe2\xfco\x8b\xfa1\x9d\x00\ +\x00L\xa0s\x8b\xfa\x13!\x93\xc6\xe0\xbc\xc69\xdf/\ +\x08\xd6+\xaeh~\x8b~\xeb\xade\xedE/j\xeb\ +8?\x14\xeb\xce#\xce\xef/\xea'\xff\x00\x00\x90\xc0\ ++b?H\x1d\x85\xe7\xc4\xfe\xf3\x84`\xad\x1eX4\ +p\xc3\x0d\xcdo\xd2\xab\x1f\x90\xb6i\x9c?\x13{M\ +\x1eq\xfe\xd5\xd8l\x1f\x0b\x00\x80\xb4\xd6\x15\xf5\x87\xd0\ +$\x8d\xc3U\x83\x9d\x91\xbepaY\xfb\xc8G\x9a\xdf\ +\xa4\xaf^\xdd\x96\x81\xbe9\x8f8?\x1c;\xc7\xc7\x01\ +\x00 \x0f\xaf\x8f\xfd}l\x08\xafYS\x0f\xf4\xb7\xbd\ +-\xbb@\xef\xcd\xe3G\xa1\xefr\xd9\x02\x00\xb4\xb7\xde\ +\xd4\xd1\xb9,\xf6\xf8\xb11|\xcd5e\xff-\xb7d\ +\x15\xe7\x07b\x93\xd3\xc7\xf9G]\xae\x00\x00\x9d\xa1/\ +u\xa4_\x14{\xe6\x97A#}j\xe3!\ +@9\x04\xfa\x1f\xa6\x8f\xf3\xea\x94\x9d\x95.K\x00\x80\ +\xce\x96\xfc\x8c\xf4\x85\xb1\x87\x13\xc7\xf9]\x8dc \x13\ +\xbe\x0eGb\xbf\xedr\x04\x00\xa0\x92\xfc\x8c\xf4\xf3b\ +O&\x8a\xf3\xaf\xc4^\x92\xfe\xdb\xf3\xad.C\x00\x00\ +\x8eU\x9d\x91\xfe\x5c\xcaH}S\x828\x7f:v\x81\ +\xe3\x14\x01\x00\xc8\xd4\x96\xc4\xa1Z\xde2\xc1\x81\xde\x93\ +>\xce?W\xd4\x7f\xb0\x0b\x00\x00\x83\xda\x972X\xa7\ +\xc4>>Aq~G\xac+m\x9c\x7f+\xb6\xd0%\ +\x07\x00\xc0p&\xc5\xeeM\x19\xe9sc_\x18\xe78\ +\xffLlf\xda8\xffQl\x85\xcb\x0d\x00\x80S1\ +#\xf6\xa5\x22\xf1\x8fF\x9f\x1a\xa78\xffzly\xfa\ +\x13[6\xba\xcc\x00\x00\x18\x89\x97\x16\xf5\x87\xe6$\x0b\ +\xd9\xdf\x1d\xa7@\xbf4\xfd}\xe7\xdb\x5c^\x00\x00\x9c\ +\x8e\xea\xa19?I\x19\xb3\xbb\xc78\xce\xff$}\x9c\ +\xdf\x13\xebri\x01\x00p\xba\xde\x1c;\x9a*h\xcf\ +\x88\xdd7Fq~\x7f\xe3\xcfK\x18\xe7_\x8b\xcdr\ +I\x01\x000Z\x1fL\x18\xb5\xe5\xe2\xd8c\xa3\x8c\xf3\ +'b\xcb\xd2\xc6\xf9\xf7\x8a\xfaS[\x01\x00`\xd4\xaa\ +\x93]>\x912\xd2\xd7\xc7\x0e\x8f\x22\xd07\xa5\xffQ\ +\xe8%.#\x00\x00\xc6Ruk\xc6\xa3)#\xbd\xf7\ +4\xe3\xbc/\xfd}\xe7;\x5c>\x00\x00\x8c\x87\xead\ +\x97\xfeT\xa1;)v`\x84q\xfe`\xfa\xf3\xce\xff\ +\xb5\xa8\xff\x0f\x04\x00\x00\x8c\x8b\xb5\xb1\x9f\x16\x09\x1fb\ +\xf4\xc5S\x8c\xf3\xea\x1c\xf5\x15i\xe3\xfc\x1b\xb1\xb9.\ +\x19\x00\x00\xc6\xdb\x95\x09\xa3\xb7|e\xec\xdb\xa7\x10\xe8\ +W\xa7\x8d\xf3\x1f\xc7^\xe1R\x01\x00`\xa2\xf4\xa5\x8c\ +\xf4\x9e\x93\xc4\xf9\x9d\xe9\xef;\xff\x1d\x97\x08\x00\x00\x13\ +iJ\xec\xd3\xa9\x02\xb8+\xf6\x97C\xc4\xf9\x97bs\ +\xd2\xc6\xf9>\x97\x07\x00\x00)\xcc/\xea\xf7Y'\x09\ +\xe1\xd9\xb1\x83'\xc4\xf9\xb3\xb1\xd5i\xe3\xfc\xc1\xd8T\ +\x97\x06\x00\x00\xa9\x5c\x10\xfb\xdfTA|\xc1\x09\xf7\xa3\ +oM\x1b\xe7\xdf\x8f\x9d\xed\x92\x00\x00 \xb5\xab\x13F\ +\xf1\xff\xfd\x18\xb4\x8a\xf3\x7f\x8fMI\xf7\xf78\x1a\xbb\ +\xd8\xa5\x00\x00@.nO\x19\xe9\xbbbK\xd2~{\ +\xbe\xcd%\x00\x00@N\xa6\xc5>_$\xfc\xd1h\xc2\ +8\x7f\xa8\xa8\xffh\x16\x00\x00\xb2rV\xecp\x91\xfe\ +\x88\xc3\x89\x5c\xf5d\xd53\xbd\xf5\x00\x00\xe4\xea\xc2\xd8\ +\xcf:$\xce\x9f\x8f\xfd\x9a\xb7\x1c\x00\x80\xdc\xbd\xb3C\ +\x02\xfdFo5\x00\x00\xad\xe2\xce6\x8f\xf3\xfbb\x93\ +\xbc\xcd\x00\x00\xb4\x8aY\xb1Cm\x1a\xe7\xdf\x89-\xf2\ +\x16\x03\x00\xd0j\xce\x8f\xfd\xa4\xcd\xe2\xbc:\xef|\x83\ +\xb7\x16\x00\x80V\xb5\xa9\xcd\x02}\x87\xb7\x14\x00\x80V\ +\xd7\xd7&q~\xb0p\xde9\x00\x00m`j\xecs\ +-\x1e\xe7?\x8c-\xf3V\x02\x00\xd0.\xce\x8e}\xaf\ +\x85\x03\xfd2o!\x00\x00\xed\xe6u\xb1#-\x18\xe7\ +\x7f\xed\xad\x03\x00\xa0]\xedj\xb18\x7f26\xc7\xdb\ +\x06\x00@\xbb\xaa\xeeG\xffb\x8b\xc4\xf9s\xb1U\xde\ +2\x00\x00\xda\xdd\xb9E\xfdG\x97\xb9\x07\xfaM\xde*\ +\x00\x00:E\xee\xe7\xa3;R\x11\x00\x80\x8e\xf3\xd1L\ +\xe3\xfc\x7fb\xcb\xbd=\x00\x00t\x9a3b_\xc90\ +\xd0\xdf\xea\xad\x01\x00\xa0Su\xc7~\x94Q\x9c\xdf\xe5\ +-\x01\x00\xa0\xd3\xbd%\x938\xffvl\xae\xb7\x03\x00\ +\x00\x8a\xe2\xef\x13\xc7\xf9\xd1\xa2\xfe %\x00\x00 \xcc\ +\x8b=\x930\xd0\xef\xf0\x16\x00\x00\xc0\xf1^\x1b;\x92\ + \xce\x9f\x8a\xbd\xd8\xcb\x0f\x00\x00/\xb4m\x82\xe3\xfc\ +\xf9\xd8\x1a/;\x00\x00\x0c\xaez8\xd0\xc1\x09\x0c\xf4\ +]^r\x00\x00\x18\xde\xb9\xc5\xc4\x1c\xbd\xf8\xb5\xa2~\ +\x16;\x00\x00p\x12W\x8ds\x9c\xff<\xf6J/3\ +\x00\x00\x9c\xba\xbb\xc61\xd0\xb7{y\x01\x00`d^\ +\x12\xeb\x1f\x878\x7f\xacpk\x0b\x00\x00\x9c\x96\xea\xe1\ +AG\x8b\xb1=\xb5e\x95\x97\x15\x00\x00N\xdf\xde1\ +\x0c\xf4[\xbc\x9c\x00\x000:\xd5\xed(\x8f\x8eA\x9c\ +W\x7f\xc64/'\x00\x00\x8c^u\xe2\xca\xcf\x0a\xa7\ +\xb6\x00\x00@6\xb6\x8e\x22\xd0o\xf3\xf2\x01\x00\xc0\xd8\ +\x9a\x14\xfbL\xe1\xd4\x16\x00\x00\xc8\xc6\xb2bdO\x19\ +\xadNmY\xede\x03\x00\x80\xf1\xf3\xf6\x11\x04\xfa.\ +/\x17\x00\x00\x8c\xbf\xbbO!\xce\xff\xabpk\x0b\x00\ +\x00L\x88\xea)\xa3\x03\xc5\xf0\xb7\xb6\x5c\xe8e\x02\x00\ +\x80\x89\xb3\xa1\x18\xfa)\xa3\xbb\xbd<\x00\x000\xf1\xfe\ +|\x908\xffzl\x86\x97\x06\x00\x00&\xde\xcc\xd8\xa1\ +\xe2\xf8[[\xd6xY\x00\x00 \x9d\x95E\xfdI\xa1\ +U\xa0\xef\xf5r\x00\x00@z\x1f\x8c}\xa3\xa8\x7f\xa3\ +\x0e\x00\x00$6-v\x81\x97\x01\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80\x0e\xf2\x0b@\ +;\x84\xc7\x9dY\x0c\xd3\x00\x00\x00\x00IEND\xae\ +B`\x82\ +\x00\x00\x09\xc0\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x00\x9c\x00\x00\x00\xb2\x08\x03\x00\x00\x00\x80\xc0V9\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\ +\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1d\ +0D&N\xa6\x00\x00\x02\xd3PLTE\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x01\x01\x00\x02\x01\x00\x03\x02\ +\x00\x04\x02\x00\x05\x03\x00\x06\x03\x00\x06\x04\x00\x07\x04\x00\ +\x08\x05\x00\x09\x05\x00\x0a\x06\x00\x0b\x07\x00\x0c\x07\x00\x0d\ +\x08\x00\x0e\x08\x00\x0f\x09\x00\x10\x0a\x00\x11\x0a\x00\x12\x0b\ +\x00\x13\x0b\x00\x14\x0c\x00\x15\x0d\x00\x16\x0d\x00\x17\x0e\x00\ +\x18\x0e\x00\x19\x0f\x00\x1a\x10\x00\x1b\x10\x00\x1c\x11\x00\x1d\ +\x11\x00\x1e\x12\x00\x1f\x13\x00 \x13\x00!\x14\x00\x22\x14\ +\x00#\x15\x00$\x16\x00%\x16\x00&\x17\x00'\x17\x00\ +(\x18\x00)\x19\x00*\x19\x00+\x1a\x00,\x1a\x00-\ +\x1b\x00.\x1c\x00/\x1c\x000\x1d\x001\x1d\x002\x1e\ +\x003\x1f\x004\x1f\x005 \x006 \x007!\x00\ +8\x22\x009\x22\x00:#\x00;#\x00<$\x00=\ +%\x00>%\x00?&\x00@&\x00A'\x00B(\ +\x00C(\x00D)\x00E)\x00F*\x00G+\x00\ +I,\x00J,\x00K-\x00L.\x00M.\x00N\ +/\x00O/\x00P0\x00Q1\x00R1\x00S2\ +\x00U3\x00W4\x00X5\x00Y5\x00Z6\x00\ +[7\x00\x5c7\x00]8\x00^8\x00_9\x00`\ +:\x00a:\x00c;\x00e=\x00g>\x00h>\ +\x00i?\x00j@\x00k@\x00lA\x00mA\x00\ +nB\x00oC\x00pC\x00qD\x00sE\x00t\ +F\x00uF\x00vG\x00wG\x00yI\x00zI\ +\x00{J\x00|J\x00|K\x00}K\x00~L\x00\ +\x7fL\x00\x80M\x00\x81M\x00\x82N\x00\x83O\x00\x84\ +O\x00\x86P\x00\x87Q\x00\x88R\x00\x8aS\x00\x8bS\ +\x00\x8eU\x00\x8fV\x00\x91W\x00\x93X\x00\x94Y\x00\ +\x95Y\x00\x96Z\x00\x98[\x00\x99\x5c\x00\x9c^\x00\x9d\ +^\x00\x9e_\x00\x9f_\x00\xa0`\x00\xa1a\x00\xa2a\ +\x00\xa3b\x00\xa4b\x00\xa5c\x00\xa6d\x00\xa7d\x00\ +\xaaf\x00\xacg\x00\xadh\x00\xafi\x00\xb0j\x00\xb1\ +j\x00\xb2k\x00\xb3k\x00\xb4l\x00\xb5m\x00\xb6m\ +\x00\xb8n\x00\xbap\x00\xbbp\x00\xbcq\x00\xbdq\x00\ +\xber\x00\xbfs\x00\xc0s\x00\xc1t\x00\xc2t\x00\xc3\ +u\x00\xc5v\x00\xc7w\x00\xc8x\x00\xc9y\x00\xcay\ +\x00\xcbz\x00\xccz\x00\xce|\x00\xcf|\x00\xd0}\x00\ +\xd1}\x00\xd2~\x00\xd3\x7f\x00\xd4\x7f\x00\xd5\x80\x00\xd6\ +\x80\x00\xd7\x81\x00\xd8\x82\x00\xd9\x82\x00\xda\x83\x00\xdb\x83\ +\x00\xdc\x84\x00\xdd\x85\x00\xde\x85\x00\xdf\x86\x00\xe0\x86\x00\ +\xe1\x87\x00\xe2\x88\x00\xe3\x88\x00\xe4\x89\x00\xe5\x89\x00\xe6\ +\x8a\x00\xe7\x8b\x00\xe8\x8b\x00\xe9\x8c\x00\xea\x8c\x00\xeb\x8d\ +\x00\xec\x8e\x00\xed\x8e\x00\xee\x8f\x00\xef\x8f\x00\xf0\x90\x00\ +\xf1\x91\x00\xf2\x91\x00\xf3\x92\x00\xf4\x92\x00\xf5\x93\x00\xf6\ +\x94\x00\xf7\x94\x00\xf8\x95\x00\xf9\x95\x00\xfa\x96\x00\xfb\x97\ +\x00\xfc\x97\x00\xfd\x98\x00\xfe\x98\x00\xff\x99\x00\xff\xff\xff\ +s\xb6\xc7\xfa\x00\x00\x00\x08tRNS\x00\x09\x0e\x1b\ +(=\x5cr\xeeu#\xcb\x00\x00\x00\x01bKGD\ +\xf05\xb8\xefT\x00\x00\x06RIDATx\xda\xed\ +\x9c\xf9_\x94U\x14\xc6\xad\xacf\x18mTP\xc0\x04\ +\xc4\x85E\x05\xc1\x0d\xc9P\xd1\xc8\x5cZ\x15\xb5\xc5$\ +\xca4\xcb4\xcbJ\xcd\xca\xd2\xd4RJ\xcd\xca4\xb2\ +\x12\xcd\xcaL\xb1 \x90\x08DS@\xf6M\xf6\x01F\ +\x99a\xe6\x9d\x7f!\xd6\x98\xe5]\xeer\xee0\x9f\xbc\ +\xcf\xcf\x9c\xf7~\x99y\xdf\xf7\x9e\xf3\x9cs\xa7_?\ +...........W\xd5\x1dw\xbb\ +\x88\xfa\x8b\xc0\xdd\xa9r\x11\xdd\xc5\xe1n)\xb8dc\ +\x9f\xaa@\x16.\xc5\xd2\xa7*\xe3p\x1c\x8e\xc3\xc1\xc1\ +\x99]\x18\xae0\xe4G\xe2\xa5u\x8c\xe1\xcaBT\xda\ +S\x84lY\xbe;\x98\xc2U\x84\xb6\xff\xcd\x903D\ +l\x17\x86\xabT\x9b\x19\xc2U\x85un~\xee\xbf\x11\ +\xb0\xa5{w\x84\xbe\xcd\x0c\xae6\xa2{kv?\x8b\ +\xcd\x96\xe6\xdd\x15\xbaI`\x03W\x17\xf9_\xe2\xe0~\ +\x0e\x93\xedO\xaf\x9e\xd0\x97\x05\x16pM\xd1Vi\x8d\ +\xc7y,\xb6T\xaf\xde\xd0\x97\xcc\xf0p\xcdsm\x92\ +.\xcfT\x0c\xb6d\x0f\xeb\xd0\xb86h\xb8\x96\x18\xbb\ +\x94\xd0+\x0d\x99\xed\x9c\x87m\xe8\xb3m\xb0p7\x1f\ +qHX\xbd\xd2\x11\xd9\xcez\xd8\x87>c\x84\x84k\ +}L$\x9d\xf6\xbe\x80\xc4v\xc6\xdd1tI+\x1c\ +\x9cq\xb9h\xb2\xef\x9d\x81\xc0\xf6\xab\xbbX\xe8\xe37\ +\xa1\xe0\xda\x9e\x96(E|\xb2\x15\xd9N\x0f\x11\x0f}\ +\xf4\x06\x0c\x9c\xf9y\xc9B\xc9\xf7\xa2\x02\xdb\xc9AR\ +\xa1\xf3\x9a \xe0\xcc/\xca\x94q~9\xb2l'\xb4\ +\xd2\xa11:z8a\x8dl\x91\xe9wI\x86-I\ ++\x17\x1aUG\x0d\xf7\x9aB\x09<\xf2\xb2$\xdbq\ +\xad|\xe8\x8cZJ\xb87\x14\x0bt\xff\x7f$\xd8~\ +\x18\xa8\x14\x1aYM\x05\xf7\x1e\x82}06_\x94-\ +Q\xa3\x1c:\xa9\x9c\x02n'\x92\xb9\x11pM\x84\xed\ +\x1b\x0dJhX\x191\xdc.D\xeb%\xb0\xc0\x81\xed\ +\x88\x06-4\xb8\x80\x10\xeecdc(\xb0\xd0\x8e\xed\ +k\x0djhP>\x11\xdc~5\xbam\x15Td\xc3\ +vX\x83\x1e\x1a\x90G\x00w\x10\x83M\xa5\x0a\xb5\xbe\ +y\xbet\xc3\x09\xf5\xcf\xc1\x86;\x8a\xb5@;]9\ +\xd1G\xde\xf9\x22\xcf\xc6\x84K\xd4\xa805\xb1\xa2;\ +\xf435n\xa8\xef\xdfxp\xcb\xf0\xed\xd2\xc8:\x82\ +\xef\xb4{\x9f\xc5\x833.\xc5_\x22\xbc\xb2=0A\ +\x8d\x1f\x18Q\x8dy\xcf\x19b\x09\x16\xa9\xb1\xec#`\ +\x8b\xaa\xc7~Z\x0dK\xf0\x97\x99\xfe.\x81{>\xb3\ +\x9e\xe0=gX\xec\x14g\x7fV\x03\xd1\x0eqc\x91\ +\x13\xd8f7\x12\xee\xad\xfa\x85\xcc\xd9\xa2\x1b\x89\xb3\x12\ +\xfd\x02\xc6l\x0f\xb5P\xe4s\xfa\xf9L\xd9\xe6\xb7P\ +e\xc2-\xf3\x18\xb2-l\xa1\xac!t\xd1\xcc\xd8\x16\ +\xe9\xa9K\xc3\xc6Y\x8c\xd8\x1e\xd6\x03\x14\xd5\x8d3\x99\ +\xb0\x89\xf9%\x04vDC\x14\x03\xb6\xd8V #\xa7\ +\xe1~p\xb6\xa5\x060\x0b\xacf\x1a0\xdbr\x03\xa0\ +yX=\x15\x94\xedI\x03\xa8\xedz}\x0a \xdbS\ +\xa0\xcef\x07\xddd0\xb6\xe7L\xe0V\x7f\xd5$ \ +\xb6x\x13\x83&Ie8\x08\xdb\x0b&&\xed\xa5\xd2\ +\x09\x00l\xabL\x8c\x1as%\xe3\xa9\xd9V\x9b\x99\xb5\ +4\x8b\xc7Q\xb2\xad\x13\x186\x83\x8b\x83\xa9\xd8^\x15\ +\x98\xb6\xd1\xf3\xc6P\xb0m\x10\x18\x0f \xe4\x92\xd3m\ +Tb\xa3\x1f\xdd\xc8\x1dM\xc8\xf6\xba\x22\x1b\xc0\x5c\xc9\ +\xd5QDl[\x9d3\xf4\xf2\xd7=\x04l\xdb\x9c3\ +\x91\xd3\xfc \xc9\x07\xb7\xc9)pM1d\xb7\xdc\x9b\ +N\x80kz\x80\xf4a\xdd\xce\x1cN7\x97\xfc5\xf7\ +!c\xb8z\xaaZg'S\xb8:\xcaJ\xe7#\x86\ +p\xb53h\x93\x92]\xec\xc6\x85\xee\xa3O\xe7\xf60\ +\x82\xab\x89\x04\xc85\xd5\x09L\xe0\xaa\xa7\x83d\xe9\xea\ +O\x19\xc0U@\xd57\xea\xfd\xe0p\x15\xe1*(\xa9\ +\x0f\x00\xc3\x95\x87\x01\xd6\xd4\xea\x83\xa0pe\x13A\xdd\ +\x08\xb7\xc3\x80p\xa5\xa1\xc0>\x8e\xdb\x110\xb8\xc2`\ +\x15\xb44G\x81\xe0\x0a\x82\x18x\x87\x9aD\x10\xb8k\ +\x81L\x5cW\xcd\xb7\x00p\xf9l\xd8\xda\xe9\x8eQ\xc3\ +\xe5\x050s\xfa\x07&Q\xc2\xe5\x8ee\xd8#\xd1\x9e\ +\xa0\x82\xbb\xe4\xcf\xb4\xbb\xa4=I\x01\x973\x92q_\ +\xce~\x08\x1f\x03\xee\xa2\x1f\xf3\x8e\xe6\xa0\x9f\x08\xe1\xb2\ +\xd9\xb3\xd9\x1f\x11@\x86\xcb\xf2\xc5_j0\xfe\xf8\x81\ +\xcd\x10>*\x5c\xc7\xf1\x05\x5cy\xa6\x10\x0cnX\x0f\ +\xe1#\xc2\xa5{\xe3\xb3\x0d\xcf\xb0X\xf6\xe1\x87y$\ +c\xc2\xa5\x11\xb0\xdd\xdb9\xd3\xbc\x97\x80\xee<\x1e\xdc\ +\x1a\x92\xef\xb4+t;~\xe8\x846,8\xd3j\xdc\ +\x05Fd\xf6\xfc\xfb\x9f`\x87fa\xdes\xc2z\xbc\ +\x05|2{o\xeb\x0f0o\x87L\xec\xa7U\xd8\x88\ +\xb3\x80\xbf\xcd\xb4\xf0\xfb8\xa1\xc3RI^\xc2\xef\xa0\ +/0\xcanVx\x1bz\xe8\xd0\x14\xb2\xed\x0b\xf9\xd6\ +\x1e}\xc5>\xbd\xd8\x8a\xfc\xa4\xfeA\xba\xf1\xef!e\ +\xb3X\xb6 n)\xa7\xc9S&\xa4a\xdc1W\xc5\ +\xca\x81\xcdH\xfb\xfe/4\xc9\xe6\x01\xe5\xed(\xb8P\ +\xb4\x90\x126 \xe4\xc2\xc7\xe9\xd2\xf4\xcf\x95&0\xc7\ +\x15I\x14\xc8\xca/\xa3\x01\xdf\xd3\x168_\xc8\xd3\x8d\ +/\x964>\x84u\xd8\x955vixl\x80\xdc\xc6\ +S,ch\x09\xaf\xc8\xb2}\x05QT\x7f'}\xae\ +!\xa4D\xd6\xa8\x14\xd6\xca\xb89\x87`\xec\x88S\x83\ +%\x16\x08-U0\xa0\xcd\xab$\xe1\x12\xa0\x8c\x9c\x9f\ +\xc5\xcfGM\xaeTl,H\x9e|\xda\x0bg\x81%\ +\x0f\x15\xb9\xfe\x94*\x84\x86\x91)^\x94m\x07\xa4y\ +\xf8\xfb0\x87\xebO\xbd\x8et\x9a\xcf\x14\x87\xd1B$\ +\xb4]S<\xed\xae?\x0d\x8d\xad\x9dn\xa5\x03\xdb\x16\ +h\xc3:c\x84\xcd\xf5#\xaa\x91O\x90\x9aV\xd8\xb1\ +\xbd\x05o\xf5g\xfaX]\xdfjd[Y\xc6e\xa8\ +\xe3\x1b\xe4M\x92\xcb\xbd\xeds\xeb\x91m\x04\x19\xac\x8f\ +\x08\xac\x15\x98\xb4\x97\xae\xf4\x0cF\xcc\xc6c\xb39\x22\ +\x10of\xd4\x98+\xec\x1a\xc8\xb1\x1d\xd9F\xa3\xeb\x19\ +\xc2\x8f31ki\x16u\x8cZ\xcd\xd1Y\xf0\xd5\xfa\ +D'\xdb\x0a\x13\xc3fpI\xa8\xc3\xc86\xa2:\x8f\ +\x08\xc4\x1a\x99\xb6\xd1\x8bW6Z\xc8\xa4_\xa0Zl\ +`?WB(\xdd\xfaf\x8b\xcb\xc29g\x22\x87\xc3\ +q8\x0e\xe7\x02p\xbb\x93\xfaT\x87d\xe1\x5cA\x1c\ +\xee\x96\x81\xbb\xad\xbf\x8b\xe8v\xfe\x83\xac\x5c\x5c\x5c\x5c\ +\x5c\x5c\x5c\x5c\x5c\x5c\x5c\xffC\xfd\x0b\x99\xa5\x5c~G\ +q`B\x00\x00\x00\x00IEND\xaeB`\x82\ +\x00\x00/`\ +\x89\ +PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\ +\x00\x01[\x00\x00\x01\x5c\x08\x06\x00\x00\x00f\xca\x1dU\ +\x00\x00\x00\x01sRGB\x00\xae\xce\x1c\xe9\x00\x00\x00\ +\x09pHYs\x00\x00\x0d\xd7\x00\x00\x0d\xd7\x01B(\ +\x9bx\x00\x00\x00\x07tIME\x07\xdc\x03\x09\x08\x1f\ +%\x1b\xcd\xc8\xcf\x00\x00\x00\x06bKGD\x00\xff\x00\ +\xff\x00\xff\xa0\xbd\xa7\x93\x00\x00.\xe0IDATx\ +\xda\xed\x9d\x09t\x15U\xb6\xfe\xaf\xb6C\xdb-\xdc\x9b\ +\x00b\xdb\xb4\xa2\xb6\xf6\xa0\xdd\xb6\xa2>q\xa0\xaa\x92\ +0*\x8a \xa2\x88\x8a8\xb7-\x88\xa08a\xa7E\ +Q[[\x14'\x22!u+\x84\x00\x81\x10H \x10\ +\xa6@\x98\xc7\x80!\xcc\x90\x90\x89\x84\x04\x12\x12\x12\x12\ +\x02\xa9W\xbb\x82\x1aHn\x86\x9b[u\xeb\xd4\xf9~\ +\xff\xf5\xad\xf7_\xbd^?\xaa\xce>\xe7\xcb\xb9\xa7\xf6\ +\xd9\xdb\xe1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x18@\x07Y\xbc2P\x11\xba\x06\xc8B_\x97,\ +\x0eu\xb9\xc5QNE\xfcX\xfb\x9f\xe1\x9a\xe24\xa5\ +\xb8\xdcB\xba\xa6\x03\xb5\x12\x0b5\x1d\xd3\xfe\xff\xc7\xb5\ +\xff\xa9\xd6\x97\xfe\x9f\x1f\xab\xfd\xdf\xfb\xe9\xbf\xa3\xff\xf7\ +Wj\xff\xd9\x1cM\x93\x9dni<\xfd;\xf4\xef\xd1\ +\xbf\x1b(\x8bw\xd1s \x1a\x00\x00v\x09\xebrq\ +\x80\x12\xfcw\xcd\xe0\x06\xe8\x06\xe7\x16\xbfq*\xc2\x82\ +Z\x03\x14+\x1a6L\xbf\xa9\xe2\xecs\xcd\xd7\xf4\xb5\ +K\x91^w\xc9R\xff\x00\xb9\xdb\xdf\xe8=\x10L\x00\ +\x80\xffQ\x1d\x17\x04\xba\xa5\x9b\x9c\xb20P\xdb1\x86\ +jf\x95\xa0)\xcfbf\xdaZ\xe5\xe9\xef\xa5\xbd\x1f\ +\xbd'\xbd/\xbd7\x82\x0f\x000\x8e\x89\xbd/\x0d\x8c\ +\x08\xba\xdb\xe9\x16Gk\xe63W\xdb\x11\xe6\xda\xccX\ +\x9b)\xfd\xbd\xe9\xb8c\x14\x1d\x878b\x06^\x82\xc9\ +\x01\x00\xf0\x9a6Jp;\x97[z0\xc0-|\xaa\ +\x19\xcb*\xcddO\xf2i\xae\x8d\xeb\xec\xb8\xa4\xd0\xb9\ +3\x9d\x07\xb7\x0d\xef\x19\x88\xd9\x03\x00ht\xe7Jf\ +\xa1\x99k\xd8\xd9\x0fS0S\xefw\xbf\xf4\x91\xee+\ +\xcd\x80Ch\x5c1\xb9\x00\xe0\x9c\xc0(\xb1\x93\xb63\ +{V3\x88Yg\xbf\xe8\xc3(}o\xbcG\xb5?\ +`3]\xb24\xac\x9d\x12\xf4{\xcc:\x00\xf89\x1e\ +\xb8\xb1\xf6\x83\x96\xfe\x15\x1efh\xbe\xf9\xa6\xd3\xf8\xb7\ +\x95\xbb\xdd\x80\xd9\x08\x80\xcdp\xba\x83\xae\x87\xc1Z\xd7\ +x\x9d\x11!\xd7a\x96\x02\xc0(\x9db\xba^\xe6r\ +KOi\x8bz\xa9\xa6\xd306K\x8b\xe2\xb38@\ +\x11\x87t\x96\xc5_c\xf6\x02\xc0\xc2.V\x11C\x02\ +\x14)\x06\xd9\x03\xcc\xaa\xd4\xa5H\x91\xfa\xc75\x00\x80\ +\xe5\xcea\xdbi\x8bs\x8cf\xb0;aV\xf6:f\ +\xa0\xb8\x22\x9d\x0c\x00?\xe3\x92\xc5\xce\x94b\xe4\xb9n\ +\x00d\x13\x95h\x9a\xe0\x0a\x0f\xba\x06\xb3\x1e\x00\x93\x8f\ +\x0aj\xaf\xc7\x0ag`D\x5c\xedt)\xde\x09\x01\x91\ +\xe2\xbdX\x05\x00\x18E\xb2xQ\xed\x07/a\x0bL\ +\x07\xd2\xb4\x99\xe6\x83#f\xe0\xaf\xb08\x00\xf0\x05\xa1\ +\xa1\x17\x06\xc8\xd2`\xa4mA\x1e\x94\xa6\xfd\xd2\x19D\ +\xf3\x04\x8b\x05\x00o\xd0v,N\xb7\xf4\x82\xb6\x982\ +`(P3j4\xec\xc2N\x17\x80\x96\xa0:.\xd0\ +\xcb\x16b'\x0by\xa7\x1d4\x7fP\x0a\x12\x80Fp\ +EJ\x82\xb6XV\xc30 \x1f|L[\x89\x0fi\ +\x00\x9c\x07u\x068{\xd3\x0b&\x01\xf9ZK4\xd3\ +\xbd\x19\xab\x0cp\xcd\xe5\x11\xf7u\xa8-i(V\xc3\ +\x14 \x03u\x8a\xe6Y\x9bh\xb1=V\x1d\xe0\xed\xe3\ +\xd7%t3\x08e\x0d!\xb3\xcb=\xba\x14q\x04\xa5\ +\x11b\x11\x02\xfb\x1f\x19\xb8\xa5{\xb4\x89\x9f\x8a\x85\x0f\ +\xf93G\x97:\x0cc5\x02[B\xf5\x0b\xa8@\x0c\ +\x16:d\x11\xd5P\xc1\x1b\xd4]\x00\xb6\xe2l\xa9\xc3\ +|,p\xc8\x82\xf9\xb9\x87\x9d\x8a\xf8\x08V)`\x1a\ +j;s\xb6\xc57\x166\xc3\xfaG\xec\xe3\xeaK\xab\ +\xc6\xab\x13\xd2\xa2\xd5y\x99+\xd5-\x85\xbb\xd4\xbd%\ +\x87\xd4\x8c\xd2\xad\x06\xb8\ +%\xd6\xde3\x01m{\x00\xa3g\xb3\xc2\xe3\xda\x04.\ +\x84Y\xb1\xa9\xee\x0b^Q\xbf\xdf9[\xcd9Q\xa0\ +zCQe\x89\xaa\xec\x9d\xaf>\xbcx\xb4\x1a\xa8\xb0\ +b\xbcB\x81\xd3-=\x8a\xd5\x0b\x989\x9b\xd5&\xee\ +\x1c\x18\x16{\x22S|v\xe58}\xa7\xeaKh\xf7\ +;r\xdd\x17\xea\x15\x91!l\x8c\x85\x22\xc4\xd2<\xc6\ +j\x06\xd6\xdd\xcd\xcaR\x1f\x9c\xcd\xb2\xa9\x9e\x89\xff\xf2\ +\xb9\xc9\x9e\xcf~\xcdt\x07-}\x9b\x99\xb3\xdc@Y\ +\xec\x85U\x0d\xac\xc5\xc4\xde\x97\xd6\x16\xf1\x16k`\x5c\ +l\xa9\xe3\xd4\xee\xea\xa4\x9d\xb1j\x8d\xf6\xff\xcc\x82\xce\ +};G\xf7e#cA\x9b\xd7\x94\x17\x8eE\x0e\xfc\ +\x0e\xb5\xa4\xd6&\xe4\x06\x18\x17{\xbaqf\x7fuC\ +\xc1\x0e\xd5\x1f\xd0\x07\xb6\xdb\xe7\x0cae\x97\xbb\x16\x1d\ +\x80\x81_q)\xe2\xd3h\xac\xc8\xa6\xba\xce}F\xcd\ +\xf6\xf2\xe3\x97\xaf(\xae*U\xfb.\x1a\xc9\xca\x98\x95\ +\xe9\xd5\xc4\x000\x95\xb0.\x17\x9f\xadi\x00\xe3bP\ +\xdd\xe2\x9fWK\xaa\xcaT+Pu\xa6Z\x1d\xb0\xe4\ +Mv.B\xd0\xb1\x02\xae\xfb\x023\xf8\xed\xe4\xe0\x8e\ +T\xbe\x0e\xa6\xc5\xea\xd1\xc1\xc3^\xa7s\x19E\xe9\xa9\ +r\xf5\xce\xb8\xa7Y\x1a\xc7\xe4\xcb#{\x5c\x017\x00\ +\xc6\x9d\xcf*Awj\x13-\x1b\xa6\xc5\xa6\xda+\xc1\ +\xea\xea\xfcm\xaa\x15\xa13\xdc?L\xeb\xc3\xd2xf\ +\xb5\x95\x85;\xe0\x0a\xc0\xe7P\xb2\xb76\xc1N\xc0\xb4\ +\xd8\xd5'\xdb\xdc\xaa\x95\x99\xb6o!kcZ\xe6\x92\ +\xa5\xfep\x07\xe0\x1bBC/<\x9b\xd6\x05\xc3bX\ +\xf4\xe5\xbf\xf2t\x95\xa5\xcd\x96\xd2\xcf\xee_8\x82\xbd\ +\x826\xb2\x18\x8a6<\xa0Ut\x8a\xe9z\x19*u\ +\xd9C\x0b\xb2V\xab,\x90~\xec\x00C\xd7{\xebH\ +\x16\xdd\xc8\xc7\x05^A]\x14(\xbf\x10F\xc5\xbe\xee\ +\x8b\x7f\xce\xd4K\x0b\xade\xc8\xf2\xb1\xac\x8e\xf5jt\ +\x83\x00-\xa2\xcd\x14\xe9O\xda\xc4\xd9\x0f\xa3\xb2\x87\xe8\ +,\x94%\xd6\xe4ogy\xbc\xf7\xd1E\x1f\xb8\x08h\ +\x12\x97\xd2\xedV\xba\x17\x0e\x93\xb2\x87~\x1f\xd5[-\ +;U\xce\x94\xd9\xd2.\xfc\x96\xd9\x8f\xb3\xdc~'7\ +@\x09\xfe;\xdc\x04x\xce8\x88\x08\x0aB\xc6\x81\xbd\ +D?\xc9Y\xe4\xbdM\xdf\xb1>\xf6%\x81\x11Aw\ +\xc3U@}\xa3\x95\x85\xee\xda_\xe4r\x18\x94\xbd4\ +yW\x1c\x93f\xbb$g\xbd\x1d\xc6\xff\x84S\x11C\ +\xe0.\xa0\xce\xd1\x81\xf4\x9061*aN\xf6\x93\xd1\ +e\x13\x8d\x82\xae\x13\xdb$\x06\xda\xba\x92\x1e\x84\xcb\x00\ +\xba\xac0@\xdb\xd1V\xc1\x98\xec'jMS^}\ +Re\x15\xbaZl\x93\x16\xeaU\xb8\xfc\xc0\xfd\x8eV\ +x\x18Fk_\xfdqF?\x95eB\xe6\xbfl\xa3\ +xh\xebL\xfb\x05\x09\xd7\xe1sGK\xd7oO\xc3\ +\x94\xec\xab[c\x073m\xb6\x03\x16\xbfa\xb7\x98\x9c\ +F\x99F\xce\xd0~^\xde\x8f\x1d\xad\xfdu\xf7\xbca\ +L\x9b-\xc3\x97\x1b\x1a\xdd\xe1R\xfb(\xb8\x10\x0fG\ +\x07\xb2(jA\xaf\x80\x19\xf1\xd1\x82\x9ce\xfa/\x1e\ +m\xd7\xd8T\xb8\x22%\x01nd\xe7\x1dm\xa4x/\ +\xf2hqf\x8b3[K\xecp\x8f\xa3D\xa3}\xcf\ +h\xbbP\xa25L\x88\xafl\x84R\xc6n\x8f\xd5\x85\ +\xfeX\xd8\x88\x895\x98\x9cPS\ +\xa2\x82\xdc9'\x0a,e\xb4t\xa5\xf8\xce\xb8\xa7\x11\ +\x1f\x0f\x1f\xcc\xa8J\x1f\x5c\xce\x0aF\x1b\xd9\xedZ-\ +(\xc70)\xa1\x96\xd4\xb9=\x5c^d\x09\xa3\xa5\x1c\ +\xe0\xe0\xf9/!.\x8d\xab0 2\xe4j\xb8\x9d?\ +\x09\xebr\xb1\x16\x88\xcd\x98\x8cPK\xd5u\xee3j\ +\xb6\x9fw\xb8\xc5U\xa5j\xdfE#\x11\x8f\xe6]x\ +X\xe3H\x16/\x82\xe9\xe1\x9c\x16b\xf2H\xa1\xbf\xba\ +\xa1`\x87\xdf\xceh)C\x02qh\x89\xa4\xf7\xe1z\ +\xfe0\xdaHI\xc0\xc5\x05\xa8\xb5j\xa7\x04\xa9\xa1\x9b\ +\xc3\xd4Sg\xaaMK\xef\x9a\xb43V\xed8\xb5\x07\ +\xc6\xbf\xe5\xaa\x0eT\x84\xaep?\x13\x09\x8c\xea\xddV\ +\x1b\xf8\x83\x98|\x90\xaf\xd43\xf1_\x86\xb7=\xdf\x7f\ +<[\x1d\xb4\xf4m\x8cw\xeb>\x98\x1d\xa0\xf5\x0f\x17\ +4kW\xabH\x91\x98t\x90\xaf\x15\xa8H\xea\xb3+\ +\xc7\xf9\xdct\xf7i&;r\xdd\x17\xea\x15\x91!\x18\ +g\xdf\x1c'D\xc0\x05\xcd0ZY\xec\x87\xc9\x06\x19\ +\xad\xee\x0b^Q\xbf\xdf9\xdb\xeb41*\xfe\xad\xec\ +\x9d\xaf>\xbcx\xb4n\xe2\x18S_\x17\xac\x11\xfa\xc2\ +\x0d\x0d\xe4\xf2\xc8\x1eWh\x03]\x84\xc9\x06\x99)j\ +\x1c\xf9\xd2\xaa\xf1\xea7\xe91\xea\xb2\xdcM\xea\x81\xd2\ +\x1c5\xa34\xef\x1c\xa5\x1c\xde\xaa\x17*\x1f\xb1\xf6s\ +\xf5\xff\xe6>\xad\xb7\xe4\xc1\xd8\x19\xaa\xfc\xb6\xe1=\x03\ +\xe1\x8a8>\x80 \x08\xf5o\xd9\xa4m\xa4\xd4\x13\x13\ +\x0c\x82\xa0:\xaaq*b\x08\xdc\xd1\x87t\x88\x11/\ +G5/\xa8\xb5\xea\x1c\xdd\xb7IQ\xee-\x1d\x1b4\ +%\xaa\x91+&\xbc\xd0\xa8\xa8\x15y\xbf\xa4QMj\ +\xf0\xb2w\xd5\xa1+B\x1b\xd5\x93\xc9c\x11\xc3\x86\xb5\ +\xafSL\xd7\xcb\xe0\x92>\xfb(&\xfc\x0f\x93\xea\x5c\ +\xfd%\xe6\x11u\xd4\xba\x09\xea\x84\xb4h\x8f\xfa*m\ +\xba*\xefIhR3\xf6'\xa9q\x19\xc9M\x8a:\ +\x08$\xe7mnTk\xf2\xb7\xeb_\xf3\x9b\x12}\xa1\ +?\xff\xdc\xf3|e\x95\xe5\xeb\xb7\xac\x9aR\xe5\xe9S\ +*\x0f\xfcm\xf6 \xcc\xfd\x06\xa4\xedn?\x86K\xfa\ +\x22\xa7V\x11\xba\xe2\xf2B\xe3\x1fo\xde\xda\xf0\xb5\xba\ +\xbe \x8d\xa9n\x04\xa0\xe5|\xf1c\x14\xe6\xbc\x87\xcb\ +\x0e(6\xdeZT\xc7\x05N\xb7\xb8\x0e\x93\xa9y\xa2\ +\xcaQ\x1fl\x99lxr>\xf0\x0f\x85'\x8b\xd5\xdf\ +E\xf5\xc4\x5co\xf8\xb2\xc3J\x18f\xebrj\x87b\ +\x12y\xa7\xeb\xa6?\xa8\xa7+-\xca^\xabV\x99t\ +\x15\x15\x18O\xe8\x96\x1f0\xbf=\xe6\xdeJ\x83\xe1\x9a\ +\xde_\xc9\xcd\xc7$j\xbd\xae\x8a\xea\xa5>\xb6\xec\x1d\ +\xfdl\x96\xb5\xb6\xde\xe0\x5cJ\xaa\xca\xd4k\xa2\x1f\xc0\ +\xbcnX9\x1d#{\xfc\x16\xee\xd9B\x9c\xb2\xf0\x11\ +&\x8f\xefE\x05P\xc8x\xe9\xc3\xd8\x11\xedg)`\ +\x8fO\xb6\xb91\x97=I\x16C\xe1\x9e-1\xda\xc8\ +n\xd7\xa2C\xae9\x15\xafz%\xbe\xaaW\xa1\xca+\ +/\x84\x8b1\x02uv\xb8vz_\xcc\xe1\x86U\xe1\ +\x0a\x0f\xba\x06.\xda\xdc\xb3Z\xb78\x0b\x93\xc6|\xdd\ +5w\xa8\xbek\xa2Z\xab\x00\x99\x09\xec\xa6\x82\x09\xd3\ +\xe0\xa2\xcdN\xf5B?1+\x18/\xd5yEJ\x99\ +5)\xaf>\xa9\xf7S\xc3\x5cm\xb8o\x993R\xbc\ +\x1dn\xda\xf4\xaev5&\x8b\xf5\x8c\xf7\xc3\xadS\xd4\ +mE{\xe1r\x16\xe2\xeb\x1d31?=k)\xdc\ +\xb4\xb1\xb3ZE\x0c\xc1$\xb1\xb6\xae\x9f\xfe\x10R\xca\ +,\x02\x8d?5\xaf\xc4\xbc\xf4\xf8\xb1L\x84\xabz\xb8\ +\xc0\xa0\x0d\xd0FL\x12\xb6j\x0d\xd0\xbd}\xa4\x94\xf9\ +\x8f\x99\x07\x16c.z\xd6j\x18k\x03\x04\xc8R\x1f\ +L\x0evu\xe5\xd4\x9eH)\xf3\x03gjj\xd4n\ +\xf1\xcfc\x0ez\xae\x9b\x80\xaa`\xf5w\xb5\xc2\x16L\ +\x0e\xfb\xa5\x94\x1d./\x82#\x1a\xcc\xe2\xec\xf5\x98w\ +\x9e\xcc\xd6-\xae\x85\xc1\xd6\xfd(\xa6H\x0fab\xd8\ +\xb7\xaf\x17\x95\x1b\xacM)\xcb\x823\x1a\xc4\x83I#\ +1\xdf<]\xe3U\x84\xdep\xd9_2\x10pV\xcb\ +aJ\x19\xf0\x1d\x9b\x0bw\xa1\x15\x0f\xcen\x9b\xc8@\ +\x88\x08\x0a\xc2d\xe0S\x7f\x9f\xfd\xd8\xcf\xe5!\xe9\xec\ +\x11\xb4\x8e!\xcbQ`\xbc\x91\x06\x91\xf7\xc1l\x15a\ +\x01&\x03\xf4\xc7\x19\xfd\x90R\xd6J\xe8\x98\xa6\xbd\x12\ +\x8c\xf9\xd4p\x1a\xd8\x5c\xbeo\x8bE\x04\xff\x15\xb7\xc5\ +\xa0\xc6R\xcaNTW\xc0E[\xc0\xf05\x9fa\x0e\ +y\xe8W\xd6N\x16\xff\xcco\xba\x97\x22\xfd\x80I\x00\ +5'\xa5\x8c\x8c\x97\xca\x0b\x82\xc6\xa1\xec\x0f\x14\x18\xf7\ +\x94\x99 }\xc7\xa5\xd1v\x90\xc5+\xb5\x01\xa8\xc4$\ +\x80\xbcI)\xcb\xaf@J\x99'\xe8\x03$\xe6K\x83\ +5\x13\xca\xdbD\x8b\xed\xf9\xcb@\x90\xc5P\x04\x1f\xf2\ +EJ\x195\x8f\x04\xbf@\xbf\x00P\x82\xd1\xd3\xd9\xad\ +0\x96/\xa7\x0d\xebr\xb1\xf6\xe2y\x08>\xe4\xeb\xf2\ +\x90\xe8\xbfV\xcb\x97i\xd31/\ +\xa4\xd1\x99\xb5\x94\xf0\x22\xe2^_\xd9\x8e\x98\x81\xbf\xb2\ +\xf1Y\xad\xf4 \x82\xec\x1b\xdd0\xa3_\xa3\xd7Z3\ +\xcb\xf2\xd4\xaf\xd2\xa6\xab\xc1\x9a\xf1\xa2@I}\xf5^\ +8\x9c\x9b\xdd\xed\xb2\xdcM\x889o\xd5\xc0\xb4\x17\x9c\ +\x8d \xfbF\xe3\xb6\x867{\xb1e\x9f(P\xbfM\ +\x8f\xd1/\x04\xe0\xee\xfc/J\xca^\xc7\x8d\xe1\xd2\x1f\ +\x17\xc4\xbc\xde\x87\xb2\xe9\xf6\xbc\x9a\x1b\x16\xe2\xc4\x8d1\ +\xdf\xe8\x8a\xc8\x10\xafoPU\xd7\x9c\xd6\x7fBOH\ +\x8bV\xfb%\x8d\xd2\xffo\xf1:\x8eB\xc2\xf3\xdc\xa4\ +\x86-\xc9A\x81\xf1\x86n\x94u\x88\x11/\xb7\xe1\x8d\ +1\xe1I\x04\xd77\x1a\xb6\xe2?>[\x84\x85'\x8b\ +\xf5\xb3\xdf77L\xd4w\xbe\x9d\xa6\xf5\xe1j,\xe3\ +3S\xb8\xd9\xdd\xf6\xc1\xee\xb6\x81\xd2\x8b\xe2cv<\ +B\x88Gp}\xf3qgk\xd1nC?\xa8\x1c(\ +\xcdQ\xe32\x92\xd5\xffl\x99\xac>\xb2d\x8cz\xf3\ +\xacG\xf5\xba\x04f\x5c\xc1\xbd-\xf6\x09S\xc7\xf3\xde\ +\xf8g\xb9\xd9\xdd\xae\xc8\xdb\x825T_sle\xb4\ +m\xc3{\x06j[\xf6*\x04\xb6\xf5\xa2\x0aX\xfe\x80\ +>\xc6\x91\x09/\xcf\xdd\xa47u\x0c\xdd\xf2\x83\xbe\xc3\ +\x0eY\xf0O\xf5\xf69C\x9a\x9dvvu\xf4\xfd\xfa\ +\xcd\xa6\xbb\xe7\x0d\xd3\x8b]\x8f\xdd\xf4\xbd\x1a\xb1'^\ +\xddP\xb0\xe3\xe7\x0e\xbdf\xa7\xb0-\xc8Z\xcd\xcd\xee\ +\xf6\xfe\x85#\xb0\x8e\xce=\xb7=\x19\x18\xd5\xbb\xad\x9d\ +\x8a\xce\x0cE`\xed\x9f\xb2D\xdd\x16\x8a\xabJ=\xaa\ +\xb9\x98}Q\x83\xba\xd3\xf2\xb2\xbb]\x99\xb7\x15k\xa9\ +\xde\xba\x12\x9f@7\x06\xe8\x1c\x0d^\xf6.\x17\x86\xd0\ +}\xc1+\xa6\x8f\xed\xd2\xdc\x8d\xdc\xecn{&\xfe\x0b\ +\xeb\xe9\xdc\x0fe\xf3\x90\x85\x00\x9d\x93\x81\xb0\xbb8\x93\ +\x0b3\xb8g\xde0\xd3\xc7\xb7\xef\xa2\x91\xdc\x98\xed\xaa\ +\xc3\xa9XS\xe7\x1d%\xd8\x22+\xc1\xe9\x96\x1eE@\ +[\xaf\x0f\xb6L\xe6\xe6\xc6\xd35\xd1\x0f\xf8\xe5\x88&\ +\xfd\xd8\x01n\x0c\x972O\xb0\xaelV\x09\xcc\xe5\x96\ +\x22\x10\xcc\xd6\xe9\x1f\xb1\x8f\xab'OWra\x02{\ +K\x0e\xf9m\x9c\xa9:\x18n\x95\xf1zn+\x84\xb1\ +\xed\xb4\xaa\xe3\x02\xd4Bh\xfd\x8eku\xfe6nL\ +\x80\xb2\x1c\xfc5\xd6\x1d\x22C\xd4\xdc\xf2#\xdc\x8c5\ +u\xba\xc0\x1a\xabS+\x81\xe9]\xed\x14\xe9\x16\x04\xb1\ +uz\x91\xa3\xdd\x16\xddn\xfbK\xcc#\xcc\x5c\x83f\ +\x9d9\x19\xc9Xcu\xf3\xbc\xdd\xd2M\xec~\x1c\x93\ +\xc5\xb7\x10D\xefug\xdc\xd3jy\xf5In\x16\xbf\ +\x15Z\xb9P\xb1q\xear\xc0\xcb\x1f7\xeaj\x81\xb5\ +\xf6\xb3F\xb1\x9c_\xbb\x02\x01\xf4N\xd4\x8ez[\xd1\ +^n\x8c\xf6`i\xaeeZp\xcf:\xb0\x94\x9bq\ +\xffa\xd7\x1c\xac\xb7_\xb4\x84\xe5\x94\xafj\x04\xd0\xbb\ +sZ\xfa\x89\xc7\x0b\xd4\x0d\x96.\x16Xe\xfc\x1fX\ +\xf4\x1a7c_Q]\x89N\xbc\xbf\xe4\xdbV1\x99\ +\x02F\xb5\x22\x11<\xefD\x15\xb9x\x81\x8eIz$\ +\xbeb\xb9?vt5\x99\x17\xde\xd9\xf8-\xd6\xddO\ +9\xb7\x8a\x18\xc2^~\xad,|\x84\xe0\xb5\x5cTw\ +\x96\x17\xe8\xcb\xff\xdd~\xb8\xc0\x80\x0fe\xf5\x8fp\xa8\ +\x08\x10\xd6\x9f\xbe\xbb\xfd\x0f\xcek98:\xe0iG\ +K;G+7#\xa4\xac\x88\xd35g\xb8\x89\xc7\xc0\ +\xa5c\xb0\x0ek\xb5\x94-\xa7\x8d\x19x\x89\xf6\xd0\x15\ +\x08\x5c\xf3\xf3;\xa7\xefO\xe2faG\xef_\xc4D\ +\xdd\x5c\x9e\xea%\xcc\xcb\x5c\x89\xb5X\xab\x13\x8ed\xf1\ +\x22vJ**Aw\x22h\xcd\xbf\x1d\xc6K\xd6A\ +A\xc5Q\xbd#0+\xb1y!\xe5#n\xcc\x96\xd2\ +\xdd\xfcqM\xda\x9a\xb5\x12\xa4.\x0c]\xd1\x15F\x22\ +hM\xeb\xd1\xa5o\xe9\x9d\x12x\x80n\xc1Q\x1d[\ +\x96\xe2C\xb5w\x1bk\xaai7^[\xfb9\xd6\xa5\ +.i8\x1a;\xdaD\x94H\xceK\xb3AJ-\xa2\ +E\xccj\x87\xdf\xe4\xbc\xcd\xdc\x98\xed\x9a\xfc\xedX\x9f\ +\xb5u\x12f\xb2d\xb69\x08Z\xc3\xb7\x93\xe8#\xd8\ +\x89\xea\x0a.\x16\xef\x9e\x92LK\xe5\xcfz#J\x8b\ +\xe2\x05*\xfe~\x836G\xb1V\x85CL\x18\xed\xe5\ +\x91=\xae@\xb0\xce\x15u\x1e\xa0\x9b:\xbc\x5c\xbd\xa5\ +2\x89\x93w\xc5\xa9WN\xed\xc9|\xec(5\x8d'\ +\xa8\x16\x07\xd6\xac\xa8\xb6Q\x82\xdb\xb1P\xbf6\x18\xc1\ +\xfa%\xcb`S\xe1N\xae\x16+\x1d\x1b<\x95\xfc\xbe\ +\xadR\xf2\x8a*K\xb8\x89\xdf\x8c\xfdIX\xbb$Y\ +\x14\xf1q\x8c1Q3C^\xa0l\x03)\xe1E\xdb\ +\xc5\x90\xa7\x86\x90y\xe5\x85X\xb7\xba\xd9\x0a\xaf\xa2X\ +8c\xa26\xe0\xb4\xdb\xb3;\xb4\xfb\xbbk\xeeP[\ +\xc6\xf0\xb3\xed\x91\x5c\xfd:\xa1,\x0c\xee?\x92)\xd2\ +\x0f,|\x1c\xdb\x0c\x93=W\xd4\xae\xdb\xde9\x9a\xa7\ +l]\x88\xfa\xb9\x94q\x5c\x99\xadU\xafP\x9bj\xb6\ +\xb2\xb8\xde\xdaN\x9b,^D\xcd\xd3`\xb0\xe7\xaa\xbd\ +\x12\xac\xae\xcd\xdfn\xdb\xc59>5\xc2\xd6\xf1\x0b\x99\ +\xff2Wf\xdb\x7f\xf1h\xac[\xbaI\x16\x1az\xa1\ +e\xbd\xb6\x9d,\xfe\x19A\xf2\x9c\xf6\x95Y\x96g\xbb\ +\x85I5\x0e\xa8\xf3\xaf\x9dcwG\xdcS\x5c\x99\xad\ +?Z\xc9[\xf3&Y\xd0\xf5V.>\xd3\x0fAj\ +\xfc2CF\xa9\xbd\x0c\xf7\xed\x8d\xdf\xd8>nt\xf3\ +\xcd\xee\x19$9'\x0a\xd4\x1f\x8f\xee\xd3\xebAt\x9c\ +\xda\x1d\xebU?\xb7\x15\x1f\xb0\xae\xd9*\xd2\xeb\x08R\ +\xe3\xfas\xcc\x00u\xd3\x91t\xdb,\xd4[c\x07\xdb\ +>f\xb7\xc5>\xc1L<(\x97;[3N\xaa\xb7\ +A\xc6I]'\xc2v\xc6\xaa\x1f\xa7\xca\xea\xe8\xf5_\ +\xaa\xc3V~\xa0\xf6K\x1a\xa5\xe7~\xd3\x1f\x11;\xe4\ +BsymW3\xdb\x89\x08P\xf3\xf2o\xbfJ\x9b\ +\xce|\x09?\xba\x09\xc7\xea5\xdc\x96\x88\x8a\xe7\x98\xcd\ +\xa93\xd5j~E\x91\x9aZ\xb4G]\x94\xbdV\xcf\ +\x7f\x9d\xa4\x99\xe6'\xdb\xdc\xea[\x1b\xbe\xd6\xdb\xae\x93\ +iR\x06\x08\xfd\x01\x87i\x1ab\xb6_X9\x13!\ +\x1e\x01j\xbe\x84\x84\xe7\xd5U\x87S\x995[\xdaA\ +\xf1\x10\xa7w[ye\xf7\xe4\xe9J=\x7f5\xfd\xd8\ +\x01=\xde\xf1\x99)\xaa\xb2w\xbe~u\xfb\xfd\xcd\x93\ +\xd4W\xd7\xfcW}b\xf9{j\x9f\x85\xc3\xd5\xaes\ +\x9f\xd1\xcd\xd3\xee\xe7\xe0\x8ch\x8e\x95\xcd6\x0d\x01\xf2\ +\xcet#\xf7.P\xcbN\x95\xfb\xd5\x95\xbb\xb1\xfd\x83\x81E\x8b\x18V\xa9\x15\xcd\xb6\ +\x1a\x95\x9f\x80\xd1|\xbfs\xb6)1O8\x94\xc2\xd9\ +yx\x15\x8c\xb5\xe1c\x84*k9mh\xe8\x85v\ +\x1ep\xaaI\xca\xdb\xc7\x12\xabB\xb5t\xcd\x88\xf9\xbe\ +\xe3\xd9\x5c\x8dkn\xf9\x11\x18k\xc3\xaaq\xa8\x8e\x0b\ +,\xe3\xb5\x9de\xf1\xd7v\x1f\xf4%9\xeb\xe1t~\ +\x86\x8a\xc2\x98\xd1.\x86\xea\x08\xb3\xde\x1f\xae\xa5l?\ +\x8a\xba\x08\x9e\xe4\x88\x19x\x89e\xcc60\xaaw[\ +\xbb\x0f\xf8\x1dqO\xa9%Uep\ +\x90\x9dM\xfd:\xc5K\x00\xa8\xf1\x220\x07\xea\x8fe\ +v|\xf7\x94dr7\xce\xc3\xd7|\x06ce\x22\xf5\ +\xcb\xe6\x97\x1a\xce\xd73+B\xe1\x82&A\x1f&\xcd\ +\x8c-e;\xf8\xaa\x85\x01ce\xa7\x10\x8d}K,6\xa4\ +\xac\xb2|\xb8\xa1\xc1\xec8v\xc0\xf4\xb8~\x9c*s\ +9\xd6WG\xdf\x0fcmX\x07Q<\xdc\xcf\xa2|\ +[`,\x8b\xb3\xd7\x9b\x1e\xd7\xd8\x8c\xe5\xdc\x8d3\xd5\ +\x09\x86\xa9\xb2U<|%OA\xa06-\xc0X\x22\ +\xf6\xc4\x9b\x1e\xd7\x9d\xc5\x07\xb9\x1b\xe7\xbc\xf2B\x98\xaa\ +g-\xb7\x9e\xd9*B,OA\x18\xbd\xfeK\xb8\xa1\ +\xc1|\xb8u\x8a\xb97\x85\x94`\xb5\x8a\xc3L\x84\x1f\ +\x8f\xee\x83\xa9z\xea\xae\xabH1\x963[\xed\xa1~\ +\xe0)\x08\xfd\x92F\xc1\x0d\x0d\xe6\xe5U\x1f\x9b^\xff\ +\x82G\xe8H\x0c\xc6\xda\xb0\x9cn\xf1{\x0bf#H\ +\xe3y\x0a\xc2M\xb3\x1e\x85\x1b\x1a\xcc\x83I#M\x8d\ +\xe9\x93\xc9c\xb9\x1cg\xba\x11\x09c\xf5\xa8qV\xcc\ +\xb3\x1d\xc5\xd5\xcf\x0b\xb7\xa4\x9e\xa8\xae\x80#\x1a\x085\ +\xda43\xa6tl\xc1#\xdf\xa5\xcf\x82\xa9z\x92,\ +\xbef=\xb3\x95\xc5\xa1\xbc\x05\x82j\x80\x02\xe3\xa0|\ +f3\xe39\xeb\xc0R.\xc7\xf9\x03\xd4Eh\xc4l\ +\x85'\xadwf+\x0b}y\x0bD\xec\xc1epD\ +\x838Zy\xdc\xf4x\xa6\x1d\xdd\xcf\xe5X\x8fX\xfb\ +9L\xd5\xd3/XY\xeac\xbd3\xdb\x88\xa0\xdbx\ +\x0b\xc4'\xdb\xdcpE\x9b|!o\xa7\x04\xe9}\xb8\ +xd\xf0\xb2wa\xac\x9e4E\xba\xc5rf\xdb6\ +\xbcg o\x81xv\xe58\xb8\xa2A,\xccZc\ +j,\xe9|\x98Wz$\xa2.\x82'Qc\x04\x87\ +\x15\xd1\x1e\xae\x84\xa7@\x08\x09\xcf\xc3\x15\x0db\xca\xee\ +\xb9\xa6\xc6\x92vw\xf8\x10\x09\x9dW\x17\xe1\xa8\xc3\xaa\ +\xb8\x14q\x1bO\xc1\xa0\x8aT5*\x0a\xd2\x18\x81\xd9\ +\xc5\xac\xe9\xdf\xe3\x95k\xa2\x1f\x80\xb16l\xb6[\xac\ +k\xb6\xb28\x97\xb7\x80P\x0bh\xe0{^\x5c5\xde\ +\xd48\xce\xd8\x9f\xc4\xe58\xd3\x8d9\x98\xaaG\xcd\xb6\ +\xb2\xd9~\xc9[@V\xe4m\x813\x1a\xc0\x03\x8b^\ +35\x8e\xa9E{\xb8\x1c\xe7\xc3\xe5E0U\xcf\xfa\ +\xdc\xcaf\xfb\x1ao\x01\x09\xdf=\x17\xceh\x00\xb7\xc6\ +\x0e6\xef#\x88\x22\xe9\xad\xd2y\x84\xd2\xdd`\xaa\x9e\ +..\x89\xafX\xd9l\xfb\xf1\x16\x901\x1b&\xc2\x19\ +}\x0c\x9d\x83w\x9c\xda\xdd\xb4\x18\xfe#\xf6qn\xc7\ +z9\xea\x224R\x84F|\xc0\xb2f\xdbV\xeev\ +\x03o\x01\x19\xb0\xf8\x0d\xb8\xa3\x8f9r\xb2\xd8\xd4\x18\ +\x0eZ\xfa6\xb7cM\xb7\xe6`\xac\x1e\xaf\xeav\xb6\ +\xac\xd9\x9emi~\x82\xa7\x80\xfcm\xf6 \xb8\xa3\x8f\ +\xd9V\xb4\xd7\xd4\x18\xfe{\xf3$n\xc7\xfa\xfb\x9d\xb3\ +a\xaa\x0dg\x22\x1c\xb7\x5c\x0b\xf3\x06\x8a\x88o\xe0*\ +\xe9\x99\xe3\xf3>\xa3X\x90\xb5\xda\xd4\x18N\xdb\xb7\x90\ +\xdb\xb1\x1e\xb75\x1c\xc6\xda\x90\x14a\x8d\xc3\xeah\x0f\ +:\x99\xb7\xc0P\xaf,\xe0;~\xd85\xc7\xd4\xf8m\ +.\xdc\xc5\xedX\xbf\x86\xba\x08\xec\xd4\xb1\xado\xb6\xd2\ +p\xde\x02\x13\x97\x91\x0c\x87\xf4!\xa1\x9b\xc3P*\xd3\ +$\x9eX\xfe\x1e\xcc\xb5\xe1\x0e\x0d\xff\xb4\xbe\xd9\xca\xa2\ +\xc8[`>\xdb\x1e\x09\x87\xf4!\xcf\xa5\x8c\xc3\x99\xbb\ +I\xf4L\xfc\x17\xcc\xb5\xc1j_\xc2}\x967[\x1e\ +\x0b\xd2\xbc\x90\xf2\x11\x1c\xd2\x87\xf4^8\xdc\xb4\xd8=\ +\xb2d\x0c\xd7c};\xea\x224\xa4\x9a\x80\xb0\x10\xa7\ +\x83\x05\xb4\x87\xcd\xe1)8A\xf3_\x82C\xfa\x90[\ +f?nZ\xec\xde\xdb\xf4\x1d\xd7c\xdd9\xba/\xcc\ +\xb5~&\xc2!\x07+\x04\xc8\xe2\x0c\x9e\x82\xd3iZ\ +\x1f\x14\xa4\xf1\x11gjj\xd4+\x22CL\x8b]\xe4\ +\xde\x05\xdc\x8e\xf5\xa93\xd5\xfa\x995\xcc\xf5\xbc\x8fc\ +\x8a0\x8d\x19\xb3u\xc9\xc2\xab\xbc\x05(\xbf\xa2\x08N\ +\xe9\x03\x0a*\x8e\x9a\x1a\xb7\x8dGvp;\xd64g\ +a\xae\x8c~\x1c\xe3\xb9k\xc3\xaa\xc3\xa9pJ\x1f\xb0\ +\xa5p\x97\xa9\x99\x08\xa5\xa7\xca\xb9\x1dkJY\x84\xb9\ +2\xd2\x9d\xc1#1\x03\x7f\xa5=t)O\x01\x8a\xd8\ +\x13\x0f\xa7\xf4\x01\x09\x87RL\x8b\xd9_c\x06r=\ +\xd6T\xb1\x0e\xe6ZO%t\x13\xd6\xc1\x12\xdaC/\ +\xe5)H\xefl\xfc\x16N\xe9\x03&\xed\x8c5-f\ +\xfd\x17\x8f\xe6z\xacg\x1fD]\x84\xfa)_\xe2\x22\ +\x07k\xb8\xdc\xc2\x7fx\x0a\xd2\xc0\xa5c\xe0\x94>\xe0\ +\xfd\xcd\x93L\x8b\xd9\xdb\x1b\xbf\xc1\x1f6\x18\xec\xf9\xad\ +\xcb\xc72g\xb6\x01\x8a\xd0\x9b\xa7 \xf1\x5c\xa6\xcf\x97\ +\x0c[\xf9\x01\xb7G?\x85'\x8bM\xfd\xf7>J\x8d\ +\x80\xb9\xd6\xcbD\x10C\x983\xdb\x8e\x91=~\xab=\ +|%O\x05ixm\x85\xedK\xcc\xbc\xd1\xb4\xae\xe0\ +G\xcb\xbcw\xe5\xe9S\xea}\xf1\xcf\xe9mj\xccb\ +\xe4\xda\xff\xc1`\xcf\xcd\xaf-\xef,\x8b\xbfv\xb0\x88\ +\xf6\x02Kx\x0a\xd6\xae\xe2\x0c\xb8e+\xb9y\xd6\xa3\ +\xa6\xc5\xab\xb8\xaa\xd42\xef\xfd\xbf\x1f\xa3LOE{\ +2y,\x0c\xf6\xdc\xe23\x89\x0eV\xd1^`\x14O\ +\xc1\x8a\xcfL\x81[\xb6\x82\xd35g\xd4\xf6J\xb0)\ +\xb1\xfa\xd3\xcc\x01\x96y\xef\x83\xa5\xb9\xea\x95S{\xea\ +\xcf5\xe1\xc7i\xa6\xfd\xbb\xbd\x12_\x85\xc9\x9e#i\ +8\xb3f\x1b\x18\x11\xfcW\x9e\x82\xf5\x85\xb6;\x01\xde\ +cf\xf3\xc1\x87\x92^\xb7\xcc{SV\x84?>\xb4\ +\xde\x11\xf7$\x0c\xb6\x8e\xda(\xc17:X\xc6\xa5\x88\ +\x99\xbc\x04\xeb\xe5U\x1f\xc31[\xc1\xa6\xc2\x9d\xa6\xc5\ +\xeaM\x8b\xf4\x8e\x8b\xcdX~\xces\xfdaZ\x1f}\ +\x87o\x06\xd7NG]\x84:\xda\xef`\x9d\x00\xb7\x10\ +\xc6K\xc0B\xe6\xbf\x0c\xc7l\x05s3W\x98\x16\xab\ +)\x16\xe8\x8a\x5cRU\xa6\xde8\xb3\xbf_\xda\xaa\xa3\ +.\xc2y\xe7\xb5\xb2\xf0-\xf3f\xebR\x84\x87y\x09\ +\xd85\xd1\x0f\xc01[\xc1w\xe9\xb3\xb8\xba^My\ +\xbe\x0d=\x1b\xf5\x053\x1a\xb3kP0P\xbf\xb6/\ +\xfb;\xdb\xb0\x10'O)`GL\xce\x95\xb4\x13\xef\ +n\xfc\xd6\xb48\x1d\xad<\xee\xd7w\xa5\xac\x03J\x17\ +l\xe8\xd9\xa8{\x82\xd1\xa4\xa3.B\xdd,\x84\x93\x1d\ +b\xc4\xcb\x1dv@{\xa18^\x02\xb76\x7f;\x5c\ +\xd3K\x86\xae\x085%F\x7f\x9c\xd1\xcf\xefY\x17T\ +\x03\xb9\xb1\xe73\xbad\xe7\xca\xbc\xad0\xda_4\xcb\ +a\x17\x02di0/\x81S\xf6\xce\x87kzI\xf7\ +\x05\xaf\x98\x12\xa3\xbe\x8bF\xfa\xf5=\xbfM\x8fi\xf2\ +\x19\xd3\x0dn\x22\x1a{p\x19L\xf6\x97\xf3\xda\x81\xb6\ +1[\xda\xa2k/U\xc1C\xe0\xc6n\xfa\x1e\xae\xe9\ +%T\x85\xcb\x8c\x18\x8d^\xff\xa5\xdf\xde\xf1P\xd9a\ +\xf5wQ=\x9b|\xc6\xc9\xbb\xe2\x0c}\x0e\xd4E\xf8\ +YeW\x85\xf5\xfd\x8d\xc3N\xb8\x14!\x96\x87\xe0\x0d\ +Z\xfa6\x5c\xd3\x0b\xaakN\xab\xed\x94 Sb\x14\ +\xee\xc7L\x84\xe6v\xb3}fE\xa8\xa1\xcf\xf1\xe1\xd6\ +)0\xda\xda*_3\x1cv\xc3\xa9\x88\x83x\x08^\ +\x979C\xe0\x9c^\x90s\xa2\xc0\xb4\x18\xad\xce\xdf\xe6\ +\x97w\x5c\x90\xb5\xba\xd9\xcfH)aF\xf2\xda\xda\xcf\ +a\xb6\xfa\xc71i\x80\xed\xcc\x96\xb6\xea\xda\xcb\x9d\xb0\ +{\xf0\xe8\xba\xa9\x99\xc5D\xec\x02}\x9d7+FE\ +\x95%\xa6\xbf\xdf\x89\xea\x0a\xf5\xa6\x16\xd6}\xd8w<\ +\xdb\xb0\xe7\x19\xb2\x1cu\x11\x5cn\xe18\xb3\x85g\x9a\ +\x91\x950\x9b\x87 \xee-9\x04\xf7l!s2\x92\ +M\x89\xcd\x0d~\xcaD\xa0.\xbe-}V\xf7\x9e\x04\ +\xc3\x9e\xc7\xcc\xeaj\x16N\xf9\x9a\xee\xb0+m#\xa5\ +\x9e<\x04\x91~.\x82\x96\xf1\xf5\x8e\x99\xa6\xc4\xe6\x81\ +E\xaf\x99\xfen\xdb\x8f\xee\xf5\xaa\xc0\xce\x0b)\x1f\x19\ +\xf6Lt\xdc\xc5\xbd\xd9F\x04\x05\xd9\xd6l\xa9\xb7\x8f\ +\xf6\x92\x19v\x0f\xe2\x97i\xd3\xe1\x9e-\xc4\xd3m*\ +\xd63\x11\x9a\xca\xa9\xf5W\x8f\xb4\xab\xa3\xef\xe7\xddl\ +\xf79T\xc7\x05\x0e;Cm'\xec\x1e\xc8\x7f\xad\xf9\ +\x14\xee\xd9B\x9eJ~\xdf\x96\x99\x08T\x83\xa15\xcf\ +K\xa9b\xbe\x86\x0a\x95s\x9f\x85\xe0\x16\xdev\xd8\x9d\ +vJ\xd0\xef\xb5\x97=m\xe7@\xf6H|\x05\xee\xd9\ +B\x82\xbd\xdc\xfdY9\x13\x81JFR\x15\xaf\xd6<\ +\xef\xf4\xfdI>\x7f\xae\xdc\xf2#\xbc\x9b\xed\xa9\x0e\xb2\ +x\xa5\x83\x07\xb4\x97M\xb0s0\xfd}\x1d\x94E\xfe\ +\x12\xf3\x88)\xb11\xb3\xcf\x97/\xfa\xa9\xbd\xba\xe6\xbf\ +\x86\x9c!sn\xb6q\x0e^p\xb9\xa5\x07\xed\x1eP\ +\x7f\x17:a\x09*\xf7\xe7\xa9(\x0b\xab\x7f\x04\x93\xb2\ +\xd7\xf9\xe4\x99o\x8b}\xc2\xe7\xcf\xb64w#\xe7G\ +\x08\xd2\xfd\xdc\x98\xad#\xac\xcb\xc5\xdaK\xe7\xd99\xa0\ +\x1b\x0av\xc0E\x9b\x09\x9dK\xda)\x13\xe1\xe4\xe9J\ +\xf5\xd6\xd8\xc1>{n:\x8e\xf0%3\xf6'\xf1l\ +\xb69\x8ed\xf1\x22\x07O\x04\xc8\xe2[v\x0ej\xd4\ +\xbeD\xb8h3Y\x93\xbf\xdd\x94\x98\x8cZ7\xc1\x94\ +\xf7\x19\xb75\xdc\xa7\xcfMEcXL\xb3\xb3h\xd1\ +\x997\x1c\xbc\xe1\x9cvo\x00\x15\x81\xb0kPC7\ +\x87\xc1E\x9bI\xcc\x81%\xb6\xc9D\xd8]\x9c\xa9^\ +\x11\x19\xe2\xd3\xe7~\xdd\xc7\x7f$hnrj\xb6%\ +\x81Q\xbd\xdb:xD{\xf9\xaf\xed\x1a\xd8\xc1\xcb\xde\ +\x85\x8b6\x13\xea(k\x87\xee\x0cT\x83\xb6\xf7\xc2\xe1\ +>\x7f\xee\xbb\xe6\x0e\xf5\xe9sRj\x22\xa7\xdds\xbf\ +p\xf0\x8a3\xb2\xdb\xb5vM\x03\xbb#\xee)\xb8h\ +3\xa1\x9f\xf7v\xc8D\xa0\xa3#\x83>\xe8\xf8\xb4\x03\ +\x08U\xa6\xe3\xd0l\xab]\xe1A\xd78x\xc6\xae\xa5\ +\x17\xe9\xa7$\x95\x0d\x04\xd6X\xfcFg\x22\x90\x91\x1b\ +\xd9\xad6>3\x85\xb9\x9cf\x94R\xb4\x18\x81\x11A\ +w\xdb5\xc0\xfb\x0d\xac\xdad'\xee\x8d\x7f\xd6\xf0X\ +\xdc\xbfp\x84\xa1\xef\xf0\xcf\xd5\x9f\x18\xfa\xfcom\xf8\ +\xdag\xcfz\xcb\xec\xc7\xf9\xfb0\x16)\xde\xee\x00\xfa\ +\xd9\xedF;\x06xQ\xf6Z8i30rGh\ +F&\x02\xf5\xf32\xba-x\xb7\xf8\xe7}\xf6\xbcW\ +E\xf5\xe2\xcdlW\xc3em^\x0dl\xe2\x8e\x19p\ +\xd2&\xa0:\xaff\xc4\xc2\xa863Tg\xe0v\x13\ +*h\xd1\xa5\x8f\x92\xaa\xb2V?oy\xf5I\xfe\xce\ +k\x15A\x82\xcb\x9e\xb3\xbb\x15V\xda-\xc8\xc3\xd7|\ +\x067m\x02\xaa\xfd\xcbr&\xc2g\xdb#\x99\xfa\xa5\ +d\xd6\x05\x12\x0bi9\xdc\xb5\xfe\x872\xc9n\x81\xa6\ +4 \xd08\xcbr7\x99\x12\x8b#\x06d\x22\xec-\ +\xc9R;N\xedn\xda|z\x7f\xf3\xa4V?\xf3\xe6\ +\xc2]\x5c\x99-}\x13\x82\xbb6|v\xbb\xdcN\x81\ +\xbe\x01\x05i\x9a$r\xef\x02f3\x11\x1e^<\xda\ +\xd4\xf9\x142\xff\xe5V?3\xed\x8e9*\xa3\x98\x04\ +W\xe5(3\xa1\xb8\xaa\x14\x8e\xda\x08\x1f\xa7\xcaLf\ +\x22\xcc>\xb8\xd4/\xfd\xed\xcaN\x95[2\x17\xd8\x82\ +\xaaA\x06BS5\x13\xb4\xbfFv\x0a\xfa\xa6\xc2\x9d\ +p\xd4Fxe\xb5\xf1\xb7\x99|}\xdd\x95\xfe\x80\xde\ +8\xf3a\xbf\xcc\xa7\xe5\xb9\x9bZ\xf5\xec\x13\xd2\xa2y\ +1\xdb\xf9p\xd3\xa6v\xb7\x8a\xd0\x95\xfe*\xd9%\xe8\ +F\x14\x7f\xb6\x13\xfd\x92F\x19\x1e\x83\xb0\x9d\xb1>}\ +\xe677L\xf4\xdb|\x1a\x9f\x1a\xd1\xaag\xf7\xa6\xf1\ +$\x83]s\xcf`W\xdb\xfc\xcc\x04\xc5.\x81\xff`\ +\xcbd8j#\xdc\x11\xf7\xa4\xe11H9\xbc\xd5g\ +\xcfK\xa53\xcd\xa8\xbdk\xd4G\xd7\x17W\x8d\xe7a\ +W\x1b\x0e\x17m&\xbf\x9d\x1c\xdc\x91z\xba\xdb!\xf0\ +O&\x8f\x85\xa36\xc2\xef\xa2z2\x93\x89@E\xce\ +\xef\x9e7\xcc\xaf\xf3\x89\xb2\x1f*OWy\xfd\x0e\x03\ +\x16\xbfa\xfb\xca^\x97G\xf6\xb8\x02.\xda\xb2\xcc\x84\ +\xf7\xec\x10|_Wl\xb2\x13\xd4\xcd\xc2\xe8\xf1\xbf~\ +\xfaC>{\xde\xaf\xd2\xa6[bN\xb5\xa6\x8f\x9a\x90\ +\xf0\xbc\xbd\xaf\xe5\xba\xa57\xe1\x9e-\xa4\xb3,\xfe\xda\ +\x0em\xcfi'B\xed\xacA}\xcc\xe8\x85\xd5\xc7G\ +\xb9\xce\x19\xa5y\xa6\xec\xc2\x9b\xa3O\xb7)^\xbf\x07\ +\xb5G\xb7\xb1\xd9\xeeu\xc4\x0c\xbc\x04\xee\xe9\x05NE\ +\x1cd\x87I@\x0b\x15\xd4'1k\x0d3\x99\x08\x03\ +\x96\xbci\x99\xf9D\x1f\x15\xbd\xc5\xccK\x18\xa6K\x16\ +\xfb\xc15\xbdEu\x5c\xe0t\x8b\xebX\x9f\x04Kr\ +\xd6\xc3Y\x1b\x80\xea\x15\x18=\xf6?\xec\x9a\xd3\xea\xe7\ +\x9c\x97\xb9\xd2R\xf3\x89v\xd8Ug\xaa[\xfc\x1e\xc7\ +\xabN\xd89\x03a%\x0c\xb3\xb5y\xb7\x91\xe2\xcd\xda\ +@V\xb1<\x11\xbeM\x8f\x81\xb36\x80\x19\xedYZ\ +\x9b\x89@\xc5_\xfe4s\x80\xe5\xe6\xd4\xc6#-o\ +(J%?\xedyN+\x9el\xa3\x04\xdf\x08\xb7\xf4\ +I\xdd\x04\xe9\x03\x96'\xc3\xc8\xb5\xff\x83\xb36\xc0\xb3\ ++\xc7\x19>\xf6\x05\x15\xc7\x98\xcd\xa9mLt9\xc1\ +\x9b\xb45\x9b\xeel\xdf\x83K\xfa\x8a\x89\xbd/\xd5v\ +\xb7\xe9\xacN\x06\xb3Zh\xb3F\xaf\xc4W-\x9d\x89\ +\xb0\xe9H\xba_sj\x1b\xd3\xc0\xa5cZ\xfc>\xf3\ +\x0f\xad\xb2\xa3\xd1\xa6r\xd7\x9a\xdc\xf0\x9be\xb2x\x17\ +\xdd\x0caqB\xd0\xcfPP\x9f\x9bg=j\xd9L\ +\x04jit\x8f\x9fsj\x1b\xd3\x1f\xa6\xf5iq\x96\ +\x8b\xbc'\xc1nF{\xba\xad\x12t'\xdc\xd1\x88\xec\ +\x04\xb7\xf8=\xab\x13\xa3\xb4\x95\x05D\xec\x06\x19\x05\x15\ +V\xb1j&\xc2w\xe9\xb3,?\xa7R\x8b\xf6\xb4\xe8\ +\x9d\xcc\xac\xbdkNQpi\x22\x5c\xd1\xa8\xddmT\ +\xef\xb6\xda g\xb381\xb6\x16\xed\x86\xc3\xd6!\xb7\ +\xfc\x88e3\x11rN\x14\xa8\x9d\xb4\x9d\xa3\xdd>\xbc\ +\x8e\xb1\xe8\xf9\xb3\x97:\xd81\xb2\xc7o\xe1\x8aF~\ +,\x93\xc5~,N\x8e\x99\x07\x16\xc3a\xeb@_\xd3\ +\x8d\x1es\xea\x0d\xe6\x0dO,\x7f\x8f\x899E\xcfi\ +\xb5\x0f\x92\xe6u\xcb\x15\xfa\xc2\x0dM9N\x90\xbec\ +mr|\xb8u\x0a\x1c\xb6\x0es2\x92-\x99\x89\xb0\ + k53s\x8a\x1ae\x9e\xa9\xa9i\xf6\xbb=\x94\ +\xf4\xba]rj\xbf\x82\x0b\x9a{\x957\x8d\xa5\x092\ +tE(\x1c\xb6\x0e\xd4\x0c\xd3j\x99\x08\xd4|\xf2&\ +\x83?\xda\xf9Z;\x8b\x0f6\xfb\xfd\xee\xb6\xf0\x07\xbf\ +\x16\x18\xedv\xcaN\x82\x0b\x9a\x9a{\xdb\xedV\x96.\ +;\xd0\x97m`\xde\xf9\xa17\xa5\x08\xdf\xdd\xf8-s\ +\xe6\xd3\x92\xae\xc17\xce\xec\xcf\xfc\xe5\x85@\xb7t\x13\ +\xdc\xcf?\xb5\x13\xc6\xb02Q\xae\x9c\xda\xb3E?\xf9\ +\xec\xce\x90\xe5c\x8d\xbdH\xb2\xee\x8b\x16=\xcf\xb6\xa2\ +\xbdj;%\x889\x03z\xa6\x99\xbf\x98h\xee\xb1\xf8\ +~\xe7e\x1f\xbc\x0e\xd7\xf3\x17\xa1\xa1\x17\xba\x14a\x19\ ++\x93%\xab,\x1f.{\x161\xe1\x05\xcbtg\xa0\ +44)\xe1E&\x0d\x88v\xab\xcd\xa1\xa8\xb2\x84\xf5\ +]m\x22\xd5J\x81\xe9\xf9sw\x1b\xd9\xedZ-\x18\ +\xc7X\x980\xcbZ\xd9?\xcaNP\xe7a\xabd\x22\ +P\x8a\x18\xcbF\xb4\xefxv\x93\xef\xb8\xa7$\x93\xe5\ +w,\x0c\x88\x0c\xb9\x1ang\x05\xc3\x8d\x08\x0a\xd2\x02\ +Rm\xf5I3\xc9\xc7\xbd\xb0X\x85:\x0d\x04\xb8%\ +\x833\x11\x8e6\xebY\xf2\xca\x0b\xf5\xdbX,\x9b\xad\ +{OB\x93\xefI\x05\xc7\x19}\xbfS\xd4u\x1b.\ +g\xadt\xb07\xad>qF\xf9\xb8\xcb+\xab\x1c(\ +\xcd1t\x9c\xaf\x9b\xfe`\xb3\x9f\x85\xb2DX\xffB\ +O}\xc5\x9a\x22\xce\x84T;\x9c\xd3\xf2\x82\xea\xb8 \ +\xc0-\xcc\xb4\xf2\xc4\xa1\xc5m\xa7\x8a\x7f\x84\ +\x9b\xb1q~;\xc0\xaa\xe5\x18\xa9\xc9!\xef\xbc\xb6\xf6\ +sC\xc7xE\xde\x96F\xff\xfd\x1f\x8f\xee3\xbc\xe2\ +\x98\xd9zu\xcd\x7f\x1b}\xe7\xa7\x93\xff\xcd\xca\xd1\xc1\ +\x19\x97\x22=\x04\x17c\xcbp_\xb0\xe2d\x9a}p\ +)\xf7f\xfb\xc8\x921~\xcbD\xa0\xe4\xfe\xe0\xf9/\ +\xd9\xae\x88\xf6m\xb1O4:\xe6T\xdb\x97\x89|Z\ +E|\x0e\xee\xc5 .Y\xfc\xd2j\x93\xe9\xe3T\x99\ +{\xb3\xbdk\xeeP\xbfe\x22D\xec\x89\xb7m\xd3\xc3\ +\xc3\xe5E\x1e\xdf\xfb\xce\xb8\xa7Yx\x87\xcf\xe1Z\xac\ +B7\xcc\xdcb\x9c\x95&\xd4\xb0\x95\x1fpo\xb6F\ +\xd6\x8am,\x13\x81\xcc\xe8\xea\xe8\xfbmk\xb6\xb1\x07\ +\x97y|w\xfa#d\xed\x14/!\x96\xd6+L\x8b\ +a:\xc5t\xbd,@\x16\xd7[eRu\x8b\x7f\x9e\ +k\xa35\xba\x9dvc\xcd5\x9fK\x19g[\xa3m\ +\xac3\x05\xb5\xf81\xfa\x12I+\xaf\xe2\xae\xa5u\x0a\ +\xb7\xb2\x01\x81Qb'-\xa89V\x98XWE\xf5\ +RkT~\x0b\xd2PI@\x7f\xdc\xd2[\x9c\xbd\xde\ +\xd6FK\xa2\xe3\x99\x86\xa03l\x0b?wV\xfb)\ +\xdd\xaf\x82K\xd9\x08J%\xd1\x02\x9bg\x85\x09F-\ +ax\xc5h\xd3k(\x13\xe1\xe4\xe9J\xfd\x03\x92\xdd\ +\xcd\x96v\xafGN\x16\xd7{\xff\x1d\xc7\x0eX5\xf3\ + \xd7\xe9\x0e\xba\x1e\xeedC\x02\x22\xc5\x9b\xb5 \x17\ +\xf9{\x92%\xe7m\xe6\xd6l\x8d\xfe@\x95_Q\xff\ +#\x11u\xc9\xb0\xbb\xd1\xfe\xa4\xf8\xcc\x94z\xefO\xf3\ +\xcd\x82\xcf\x9aO9\xf1p%{g(\xfc\xc3\xdfU\ +\xc2ZR\xf0\xd9n\x8c\xdb\x1anh\x9b\x98\xf3\xd9]\ +\x9c\xa9^\x11\x19\xc2\x8d\xd9\xbe\xb5\xe1\xebzc@\xe9\ +\x86\x16\xdb\xd1\x1euM\x91n\x81\x1b\xf1p\x86\xab\x08\ +]\xb5\xa0\x97\xf9k\xb2\xbd\xb9a\x22\xb7f\xfb\xd2\xaa\ +\xf1\x86\x8dk\xaf\xc4W\xcf\xf9\xb7\xe8l\xbc7#\xf9\ +\xa5F~\x80\xfd~\xe7l+=ci\xa0,\xde\x05\ +\x17\xe2\x08\xa7[\x0a\xa66\x1b\xfe\x98p\xfd\x17\x8f\xe6\ +\xd6l\x1fX\xf4\x9ai\x99\x08S\xf7&re\xb4\xa4\ +@ERK\xaa\xcaL\xfb5\xd1\xd2\xb66T\x0e\x15\ +\xee\xc3\xe3\x91\x82\x22<\xec\x8f>f\x7f\x9b=\x88[\ +\xb3\xbd5v\xb0)\x99\x08\xf4\xa1\x88\x8e\x15x3[\ +RR\xf6\xbas\xc6|\x84\xc1\xd7\xa3\x9bytP\x85\ +k\xb8\xbc\x1bn\xa4$\x98}\xa4@\xbb\x8f\x8a\xeaJ\ +\xee\x8c\x96~\xd6w\x9c\xda\xdd\xb0qM8\xf4\xcb\xc7\ +\xa1\xe1k>\xe3\xd2hITd\xa7.O,\x7f\xcf\ +\xefG\x07.wP7\xb8\x0d\xa0,\x85{\xb5\xbf\xbc\ +\xc7\xcd\x9c\x80iG\xf7sg\xb6\x05\x15\xc7\x0c\x1d\xd3\ +\xbe\x8bF\xea\xad\x87\xc6\xa7FX:\x89\xdf\x8cR\x9e\ +Ks6\xe8\xedr\x16d\xad\xd6\xdb\xba\xfb\xf1yJ\ +\xb4X\xdc\x03\x97\x01u\xcfp\xbb\x98\x99\x166'#\ +\x99;\xb3\xddR\xb8\x8b[\x03\xe4T\x85\xce\x88\xa0\xdb\ +\xe0.\xc0SZ\xd8\x11\xb3\xaa\xebS\x87Y\x9e\xd4e\ +\xce\x10\x18\x10?\xca\x0b\x8c\x08\xfe+\x5c\x054\xf2\xd1\ +\xac\xdb\xadN\xb7x\x18\x8b\x05\x82\xbc\xbf\x19\x16\xa0\x04\ +\xff\x1dn\x02\x9a\xa4\xfd\xd4\xfb~\xa7M\x9a\xcdX4\ +\x10\xd4bm\xec \x8bW\xc2E@\xb3\xa1\xfeG\xda\ +\xc4\x89\xc7\xe2\x81\xa0fJ\x16\xe7\xa2o\x18\xf0\x8e\x98\ +\x81\xbfr)\xd2D,$\x08j\xd2hC\xa9\xc35\ +L\x03\xb4\xf2\x1cW\x1c\xa1M\xa8\xd3XT\x10TO\ +\xd5NYx\x1e.\x01|\x99\x1a\xf6\xa86\xb1N`\ +qA\xd0\xcf*s\xc9R\x7f\xb8\x03\xf09m\xe5n\ +7h\x13l\x07\x16\x19\x04\x89ih7\x0e\x0c\xa5C\ +\x8cx\xb96\xd1fc\xb1A\xbc*@\x91bh\x1d\ +\xc0\x0d\x80\xf1\xa8\x8e\x0b\x9c\x8a8\x06\xe7\xb8\x10o\xe7\ +\xb3\xf4\xfd\x02\x1f\xc2\x80\xe9\x04\xcab/\x7f\x17\x22\x87\ + \x93.*\x14P\xd1&\xacz\xe0\xe7s\x5ca\x03\ +\x16#dWQ\xf7[gD\xc8uX\xed\xc0\xff\x84\ +\x86^X\x9b\x1ef~m\x5c\x082\xb6\x06-\x8e\x0d\ +\x80%w\xb9\xc2\x1d\xda\x04\xdd\x83E\x0a\xb1\xff\x11L\ +\xdcM\x95\xf0\xb0\xaa\x81e\xe9\x14\xd3\xf52\xcdp\xbf\ +\xc2\x82\x85\x18\xde\xd1~E\xf3\x18\xab\x190A\x80[\ +x\x9c\xeayb\xe1B,}\x04\xa3\xcb;X\xbd\x80\ +=\xc3\x0d\x0bqj\xa6\x1b\xa6M\xe4\x1a,d\xc8\xc2\ +&{\x86v\xb34_\xb1j\x01\xdb\xa6+\x0b\xf7\xd1\ +\x19\x18\x165d\xc1L\x83]\xd4\x16\x0a\xab\x14\xd8\xea\ +,7@\x16?\xc1E\x08\xc82\x99\x06\xb2\x18\xdaY\ +\x16\x7f\x8d\xd5\x09lz\x96+\xdd\xa3M\xf6T,v\ +\xc8\x8f\xda\x1c(\x8bwa5\x02\xfbC\xd7}ea\ +\xa0K\x113\xb1\xf0!\x13\x95\x11 \x0b}\xb1\x00\x01\ +w\x5c\x15\xd6\xf77gk,\x94\xc1\x08 \x03UJ\ +\xf3\x0c\xe9\x5c\x80{\xda)A\xbfw)R$\xb2\x16\ + _g\x19P6L\xfb)\xdd\xaf\xc2*\x03\xa0\x0e\ +T\xe8C[$\xaba\x12\x90\x0f\x8cv%\xb2\x0c\x00\ +h\xdeG\xb4\xe50\x0c\xa8\xc5R\x84e\x81\x8a\xd0\x15\ +\xab\x08\x80\x16\xe0T\xc4\x10j\x0d\x0d\x13\x81\xb0\x93\x05\ +\xc0hBC/\x0c\x90\xa5\xc1\xdabJ\x87\xa1@\x0d\ +\xb5\xa7\xd1\xfe(\x0f\xa2y\x82\xc5\x02\x80\xaf\x8e\x17\xb4\ +\x9d\x8b\xb6\xb8\x12\xf0!\x8d{Q\xfc\x13\xb0\x93\x05\xc0\ +`\xce\x16,\xff\xca\xe9\x16O\xc2x\xb8R\x05\xc5\x1d\ +\x8d\x16\x010\x19\x97,v\xae-\xe7(\x1c\x87\x11\xd9\ +Z%\x9a&\xb8\xc2\x83\xae\xc1\xac\x07\xc0\x9fL\xec}\ +\xa9~#\xcd-.\xc1\x11\x83\xad\x8e\x0a\x96P\x5c\x1d\ +1\x03/\xc1$\x07\xc0\x82G\x0c\xb5\x05o\x84\x02\x18\ +\x16\x93\xca\xa2\x0218*\x00\x80\x11j;FHO\ +\x9d\xdd\xedV\xc3\xc4\xac\xdd\x22<\xc0-$\x05(\xe2\ +\x10T\xe1\x02\x80a\xa8\x06\x03\x15 9{%\xf8\x04\ +\xcc\xcd\x12:A\xf1\xa0\xb8P|0K\x01\xb0\x19m\ +\x94\xe0vNE|\x8evR\xd8\xf1\x9a\xaeSN\xb7\ +\xb8\xd0%K\xc3\xda\x86\xf7\x0c\xc4l\x04\x80\xa3\xa3\x86\ +\xda[j\xc2W(\xf7h`'\x04Y\xfc\x84\xc6\x19\ +U\xb7\x00\x00:\xce\x88\x90\xeb4\xd3\x1dQ{\xce+\ +T\xc1,\xbdR%]8p\xba\xa5\x17h<1\xab\ +\x00\x00M\x1e7\xb8\xdc\xd2\x83\x01n\xe1S\xcd\x00\x00\x00\x00\x00\x01\x00\x00n|\ +\x00\x00\x01r\x0e\xc2\x8cW\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/widgets/systray/systray.pyproject b/examples/widgets/systray/systray.pyproject new file mode 100644 index 0000000..eadfb0d --- /dev/null +++ b/examples/widgets/systray/systray.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["main.py", "window.py", "systray.qrc"] +} diff --git a/examples/widgets/systray/systray.qrc b/examples/widgets/systray/systray.qrc new file mode 100644 index 0000000..a8b6535 --- /dev/null +++ b/examples/widgets/systray/systray.qrc @@ -0,0 +1,7 @@ + + + images/bad.png + images/heart.png + images/trash.png + + diff --git a/examples/widgets/systray/window.py b/examples/widgets/systray/window.py new file mode 100644 index 0000000..ca65f04 --- /dev/null +++ b/examples/widgets/systray/window.py @@ -0,0 +1,273 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot +from PySide2.QtGui import QIcon +from PySide2.QtWidgets import (QAction, QCheckBox, QComboBox, QDialog, + QGridLayout, QGroupBox, QHBoxLayout, QLabel, + QLineEdit, QMenu, QMessageBox, QPushButton, + QSpinBox, QStyle, QSystemTrayIcon, QTextEdit, + QVBoxLayout) + +import rc_systray + + +class Window(QDialog): + def __init__(self, parent=None): + super(Window, self).__init__(parent) + + self.iconGroupBox = QGroupBox() + self.iconLabel = QLabel() + self.iconComboBox = QComboBox() + self.showIconCheckBox = QCheckBox() + + self.messageGroupBox = QGroupBox() + self.typeLabel = QLabel() + self.durationLabel = QLabel() + self.durationWarningLabel = QLabel() + self.titleLabel = QLabel() + self.bodyLabel = QLabel() + + self.typeComboBox = QComboBox() + self.durationSpinBox = QSpinBox() + self.titleEdit = QLineEdit() + self.bodyEdit = QTextEdit() + self.showMessageButton = QPushButton() + + self.minimizeAction = QAction() + self.maximizeAction = QAction() + self.restoreAction = QAction() + self.quitAction = QAction() + + self.trayIcon = QSystemTrayIcon() + self.trayIconMenu = QMenu() + + self.createIconGroupBox() + self.createMessageGroupBox() + + self.iconLabel.setMinimumWidth(self.durationLabel.sizeHint().width()) + + self.createActions() + self.createTrayIcon() + + self.showMessageButton.clicked.connect(self.showMessage) + self.showIconCheckBox.toggled.connect(self.trayIcon.setVisible) + self.iconComboBox.currentIndexChanged.connect(self.setIcon) + self.trayIcon.messageClicked.connect(self.messageClicked) + self.trayIcon.activated.connect(self.iconActivated) + + self.mainLayout = QVBoxLayout() + self.mainLayout.addWidget(self.iconGroupBox) + self.mainLayout.addWidget(self.messageGroupBox) + self.setLayout(self.mainLayout) + + self.iconComboBox.setCurrentIndex(1) + self.trayIcon.show() + + self.setWindowTitle("Systray") + self.resize(400, 300) + + def setVisible(self, visible): + self.minimizeAction.setEnabled(visible) + self.maximizeAction.setEnabled(not self.isMaximized()) + self.restoreAction.setEnabled(self.isMaximized() or not visible) + super().setVisible(visible) + + def closeEvent(self, event): + if not event.spontaneous() or not self.isVisible(): + return + if self.trayIcon.isVisible(): + QMessageBox.information(self, "Systray", + "The program will keep running in the system tray. " + "To terminate the program, choose Quit in the context " + "menu of the system tray entry.") + self.hide() + event.ignore() + + @Slot(int) + def setIcon(self, index): + icon = self.iconComboBox.itemIcon(index) + self.trayIcon.setIcon(icon) + self.setWindowIcon(icon) + self.trayIcon.setToolTip(self.iconComboBox.itemText(index)) + + @Slot(str) + def iconActivated(self, reason): + if reason == QSystemTrayIcon.Trigger: + pass + if reason == QSystemTrayIcon.DoubleClick: + self.iconComboBox.setCurrentIndex( + (self.iconComboBox.currentIndex() + 1) % self.iconComboBox.count() + ) + if reason == QSystemTrayIcon.MiddleClick: + self.showMessage() + + @Slot() + def showMessage(self): + self.showIconCheckBox.setChecked(True) + selectedIcon = self.typeComboBox.itemData(self.typeComboBox.currentIndex()) + msgIcon = QSystemTrayIcon.MessageIcon(selectedIcon) + + if selectedIcon == -1: # custom icon + icon = QIcon(self.iconComboBox.itemIcon(self.iconComboBox.currentIndex())) + self.trayIcon.showMessage( + self.titleEdit.text(), + self.bodyEdit.toPlainText(), + icon, + self.durationSpinBox.value() * 1000, + ) + else: + self.trayIcon.showMessage( + self.titleEdit.text(), + self.bodyEdit.toPlainText(), + msgIcon, + self.durationSpinBox.value() * 1000, + ) + + @Slot() + def messageClicked(self): + QMessageBox.information(None, "Systray", + "Sorry, I already gave what help I could.\n" + "Maybe you should try asking a human?") + + def createIconGroupBox(self): + self.iconGroupBox = QGroupBox("Tray Icon") + + self.iconLabel = QLabel("Icon:") + + self.iconComboBox = QComboBox() + self.iconComboBox.addItem(QIcon(":/images/bad.png"), "Bad") + self.iconComboBox.addItem(QIcon(":/images/heart.png"), "Heart") + self.iconComboBox.addItem(QIcon(":/images/trash.png"), "Trash") + + self.showIconCheckBox = QCheckBox("Show icon") + self.showIconCheckBox.setChecked(True) + + iconLayout = QHBoxLayout() + iconLayout.addWidget(self.iconLabel) + iconLayout.addWidget(self.iconComboBox) + iconLayout.addStretch() + iconLayout.addWidget(self.showIconCheckBox) + self.iconGroupBox.setLayout(iconLayout) + + def createMessageGroupBox(self): + self.messageGroupBox = QGroupBox("Balloon Message") + + self.typeLabel = QLabel("Type:") + + self.typeComboBox = QComboBox() + self.typeComboBox.addItem("None", QSystemTrayIcon.NoIcon) + self.typeComboBox.addItem( + self.style().standardIcon(QStyle.SP_MessageBoxInformation), + "Information", + QSystemTrayIcon.Information, + ) + self.typeComboBox.addItem( + self.style().standardIcon(QStyle.SP_MessageBoxWarning), + "Warning", + QSystemTrayIcon.Warning, + ) + self.typeComboBox.addItem( + self.style().standardIcon(QStyle.SP_MessageBoxCritical), + "Critical", + QSystemTrayIcon.Critical, + ) + self.typeComboBox.addItem(QIcon(), "Custom icon", -1) + self.typeComboBox.setCurrentIndex(1) + + self.durationLabel = QLabel("Duration:") + + self.durationSpinBox = QSpinBox() + self.durationSpinBox.setRange(5, 60) + self.durationSpinBox.setSuffix(" s") + self.durationSpinBox.setValue(15) + + self.durationWarningLabel = QLabel("(some systems might ignore this hint)") + self.durationWarningLabel.setIndent(10) + + self.titleLabel = QLabel("Title:") + self.titleEdit = QLineEdit("Cannot connect to network") + self.bodyLabel = QLabel("Body:") + + self.bodyEdit = QTextEdit() + self.bodyEdit.setPlainText("Don't believe me. Honestly, I don't have a clue." + "\nClick this balloon for details.") + + self.showMessageButton = QPushButton("Show Message") + self.showMessageButton.setDefault(True) + + messageLayout = QGridLayout() + messageLayout.addWidget(self.typeLabel, 0, 0) + messageLayout.addWidget(self.typeComboBox, 0, 1, 1, 2) + messageLayout.addWidget(self.durationLabel, 1, 0) + messageLayout.addWidget(self.durationSpinBox, 1, 1) + messageLayout.addWidget(self.durationWarningLabel, 1, 2, 1, 3) + messageLayout.addWidget(self.titleLabel, 2, 0) + messageLayout.addWidget(self.titleEdit, 2, 1, 1, 4) + messageLayout.addWidget(self.bodyLabel, 3, 0) + messageLayout.addWidget(self.bodyEdit, 3, 1, 2, 4) + messageLayout.addWidget(self.showMessageButton, 5, 4) + messageLayout.setColumnStretch(3, 1) + messageLayout.setRowStretch(4, 1) + self.messageGroupBox.setLayout(messageLayout) + + def createActions(self): + self.minimizeAction = QAction("Minimize", self) + self.minimizeAction.triggered.connect(self.hide) + + self.maximizeAction = QAction("Maximize", self) + self.maximizeAction.triggered.connect(self.showMaximized) + + self.restoreAction = QAction("Restore", self) + self.restoreAction.triggered.connect(self.showNormal) + + self.quitAction = QAction("Quit", self) + self.quitAction.triggered.connect(qApp.quit) + + def createTrayIcon(self): + self.trayIconMenu = QMenu(self) + self.trayIconMenu.addAction(self.minimizeAction) + self.trayIconMenu.addAction(self.maximizeAction) + self.trayIconMenu.addAction(self.restoreAction) + self.trayIconMenu.addSeparator() + self.trayIconMenu.addAction(self.quitAction) + + self.trayIcon = QSystemTrayIcon(self) + self.trayIcon.setContextMenu(self.trayIconMenu) diff --git a/examples/widgets/threads/thread_signals.py b/examples/widgets/threads/thread_signals.py new file mode 100644 index 0000000..d630404 --- /dev/null +++ b/examples/widgets/threads/thread_signals.py @@ -0,0 +1,100 @@ + +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from PySide2.QtCore import QObject, QThread, Signal, Slot +from PySide2.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget + + +# Create a basic window with a layout and a button +class MainForm(QWidget): + def __init__(self): + QWidget.__init__(self) + self.setWindowTitle("My Form") + self.layout = QVBoxLayout() + self.button = QPushButton("Click me!") + self.button.clicked.connect(self.start_thread) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + # Instantiate and start a new thread + def start_thread(self): + instanced_thread = WorkerThread(self) + instanced_thread.start() + + # Create the Slots that will receive signals + @Slot(str) + def update_str_field(self, message): + print(message) + + @Slot(int) + def update_int_field(self, value): + print(value) + + +# Signals must inherit QObject +class MySignals(QObject): + signal_str = Signal(str) + signal_int = Signal(int) + + +# Create the Worker Thread +class WorkerThread(QThread): + def __init__(self, parent=None): + QThread.__init__(self, parent) + # Instantiate signals and connect signals to the slots + self.signals = MySignals() + self.signals.signal_str.connect(parent.update_str_field) + self.signals.signal_int.connect(parent.update_int_field) + + def run(self): + # Do something on the worker thread + a = 1 + 1 + # Emit signals whenever you want + self.signals.signal_int.emit(a) + self.signals.signal_str.emit("This text comes to Main thread from our Worker thread.") + + +if __name__ == "__main__": + app = QApplication(sys.argv) + window = MainForm() + window.show() + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/addressbook.pyproject b/examples/widgets/tutorials/addressbook/addressbook.pyproject new file mode 100644 index 0000000..13d739e --- /dev/null +++ b/examples/widgets/tutorials/addressbook/addressbook.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["part3.py", "part1.py", "part5.py", "part2.py", + "part7.py", "part6.py", "part4.py"] +} diff --git a/examples/widgets/tutorials/addressbook/part1.py b/examples/widgets/tutorials/addressbook/part1.py new file mode 100644 index 0000000..8958730 --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part1.py @@ -0,0 +1,74 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class AddressBook(QtWidgets.QWidget): + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part2.py b/examples/widgets/tutorials/addressbook/part2.py new file mode 100644 index 0000000..6eac33b --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part2.py @@ -0,0 +1,180 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.cancelButton.clicked.connect(self.cancel) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton, QtCore.Qt.AlignTop) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addStretch() + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.submitButton.show() + self.cancelButton.show() + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + self.submitButton.hide() + self.cancelButton.hide() + + def cancel(self): + self.nameLine.setText(self.oldName) + self.nameLine.setReadOnly(True) + + self.addressText.setText(self.oldAddress) + self.addressText.setReadOnly(True) + + self.addButton.setEnabled(True) + self.submitButton.hide() + self.cancelButton.hide() + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part3.py b/examples/widgets/tutorials/addressbook/part3.py new file mode 100644 index 0000000..d425c11 --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part3.py @@ -0,0 +1,245 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + self.nextButton = QtWidgets.QPushButton("&Next") + self.nextButton.setEnabled(False) + self.previousButton = QtWidgets.QPushButton("&Previous") + self.previousButton.setEnabled(False) + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.cancelButton.clicked.connect(self.cancel) + self.nextButton.clicked.connect(self.next) + self.previousButton.clicked.connect(self.previous) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton, QtCore.Qt.AlignTop) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addStretch() + + buttonLayout2 = QtWidgets.QHBoxLayout() + buttonLayout2.addWidget(self.previousButton) + buttonLayout2.addWidget(self.nextButton) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + mainLayout.addLayout(buttonLayout2, 3, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.nextButton.setEnabled(False) + self.previousButton.setEnabled(False) + self.submitButton.show() + self.cancelButton.show() + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number > 1) + + self.submitButton.hide() + self.cancelButton.hide() + + def cancel(self): + self.nameLine.setText(self.oldName) + self.addressText.setText(self.oldAddress) + + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number > 1) + + self.submitButton.hide() + self.cancelButton.hide() + + def next(self): + name = self.nameLine.text() + it = iter(self.contacts) + + try: + while True: + this_name, _ = it.next() + + if this_name == name: + next_name, next_address = it.next() + break + except StopIteration: + next_name, next_address = iter(self.contacts).next() + + self.nameLine.setText(next_name) + self.addressText.setText(next_address) + + def previous(self): + name = self.nameLine.text() + + prev_name = prev_address = None + for this_name, this_address in self.contacts: + if this_name == name: + break + + prev_name = this_name + prev_address = this_address + else: + self.nameLine.clear() + self.addressText.clear() + return + + if prev_name is None: + for prev_name, prev_address in self.contacts: + pass + + self.nameLine.setText(prev_name) + self.addressText.setText(prev_address) + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part4.py b/examples/widgets/tutorials/addressbook/part4.py new file mode 100644 index 0000000..e4b1d16 --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part4.py @@ -0,0 +1,299 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + NavigationMode, AddingMode, EditingMode = range(3) + + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + self.currentMode = self.NavigationMode + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.editButton = QtWidgets.QPushButton("&Edit") + self.editButton.setEnabled(False) + self.removeButton = QtWidgets.QPushButton("&Remove") + self.removeButton.setEnabled(False) + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + + self.nextButton = QtWidgets.QPushButton("&Next") + self.nextButton.setEnabled(False) + self.previousButton = QtWidgets.QPushButton("&Previous") + self.previousButton.setEnabled(False) + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.editButton.clicked.connect(self.editContact) + self.removeButton.clicked.connect(self.removeContact) + self.cancelButton.clicked.connect(self.cancel) + self.nextButton.clicked.connect(self.next) + self.previousButton.clicked.connect(self.previous) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton) + buttonLayout1.addWidget(self.editButton) + buttonLayout1.addWidget(self.removeButton) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addStretch() + + buttonLayout2 = QtWidgets.QHBoxLayout() + buttonLayout2.addWidget(self.previousButton) + buttonLayout2.addWidget(self.nextButton) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + mainLayout.addLayout(buttonLayout2, 3, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.updateInterface(self.AddingMode) + + def editContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.updateInterface(self.EditingMode) + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if self.currentMode == self.AddingMode: + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + elif self.currentMode == self.EditingMode: + if self.oldName != name: + if name not in self.contacts: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % self.oldName) + del self.contacts[self.oldName] + self.contacts[name] = address + else: + QtWidgets.QMessageBox.information(self, "Edit Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + elif self.oldAddress != address: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % name) + self.contacts[name] = address + + self.updateInterface(self.NavigationMode) + + def cancel(self): + self.nameLine.setText(self.oldName) + self.addressText.setText(self.oldAddress) + self.updateInterface(self.NavigationMode) + + def removeContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name in self.contacts: + button = QtWidgets.QMessageBox.question(self, "Confirm Remove", + "Are you sure you want to remove \"%s\"?" % name, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) + + if button == QtWidgets.QMessageBox.Yes: + self.previous() + del self.contacts[name] + + QtWidgets.QMessageBox.information(self, "Remove Successful", + "\"%s\" has been removed from your address book." % name) + + self.updateInterface(self.NavigationMode) + + def next(self): + name = self.nameLine.text() + it = iter(self.contacts) + + try: + while True: + this_name, _ = it.next() + + if this_name == name: + next_name, next_address = it.next() + break + except StopIteration: + next_name, next_address = iter(self.contacts).next() + + self.nameLine.setText(next_name) + self.addressText.setText(next_address) + + def previous(self): + name = self.nameLine.text() + + prev_name = prev_address = None + for this_name, this_address in self.contacts: + if this_name == name: + break + + prev_name = this_name + prev_address = this_address + else: + self.nameLine.clear() + self.addressText.clear() + return + + if prev_name is None: + for prev_name, prev_address in self.contacts: + pass + + self.nameLine.setText(prev_name) + self.addressText.setText(prev_address) + + def updateInterface(self, mode): + self.currentMode = mode + + if self.currentMode in (self.AddingMode, self.EditingMode): + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.editButton.setEnabled(False) + self.removeButton.setEnabled(False) + + self.nextButton.setEnabled(False) + self.previousButton.setEnabled(False) + + self.submitButton.show() + self.cancelButton.show() + + elif self.currentMode == self.NavigationMode: + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.editButton.setEnabled(number >= 1) + self.removeButton.setEnabled(number >= 1) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number >1 ) + + self.submitButton.hide() + self.cancelButton.hide() + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part5.py b/examples/widgets/tutorials/addressbook/part5.py new file mode 100644 index 0000000..cb666ff --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part5.py @@ -0,0 +1,359 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + NavigationMode, AddingMode, EditingMode = range(3) + + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + self.currentMode = self.NavigationMode + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.editButton = QtWidgets.QPushButton("&Edit") + self.editButton.setEnabled(False) + self.removeButton = QtWidgets.QPushButton("&Remove") + self.removeButton.setEnabled(False) + self.findButton = QtWidgets.QPushButton("&Find") + self.findButton.setEnabled(False) + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + + self.nextButton = QtWidgets.QPushButton("&Next") + self.nextButton.setEnabled(False) + self.previousButton = QtWidgets.QPushButton("&Previous") + self.previousButton.setEnabled(False) + + self.dialog = FindDialog() + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.editButton.clicked.connect(self.editContact) + self.removeButton.clicked.connect(self.removeContact) + self.findButton.clicked.connect(self.findContact) + self.cancelButton.clicked.connect(self.cancel) + self.nextButton.clicked.connect(self.next) + self.previousButton.clicked.connect(self.previous) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton) + buttonLayout1.addWidget(self.editButton) + buttonLayout1.addWidget(self.removeButton) + buttonLayout1.addWidget(self.findButton) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addStretch() + + buttonLayout2 = QtWidgets.QHBoxLayout() + buttonLayout2.addWidget(self.previousButton) + buttonLayout2.addWidget(self.nextButton) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + mainLayout.addLayout(buttonLayout2, 2, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.updateInterface(self.AddingMode) + + def editContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.updateInterface(self.EditingMode) + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if self.currentMode == self.AddingMode: + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + elif self.currentMode == self.EditingMode: + if self.oldName != name: + if name not in self.contacts: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % self.oldName) + del self.contacts[self.oldName] + self.contacts[name] = address + else: + QtWidgets.QMessageBox.information(self, "Edit Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + elif self.oldAddress != address: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % name) + self.contacts[name] = address + + self.updateInterface(self.NavigationMode) + + def cancel(self): + self.nameLine.setText(self.oldName) + self.addressText.setText(self.oldAddress) + self.updateInterface(self.NavigationMode) + + def removeContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name in self.contacts: + button = QtWidgets.QMessageBox.question(self, "Confirm Remove", + "Are you sure you want to remove \"%s\"?" % name, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) + + if button == QtWidgets.QMessageBox.Yes: + self.previous() + del self.contacts[name] + + QtWidgets.QMessageBox.information(self, "Remove Successful", + "\"%s\" has been removed from your address book." % name) + + self.updateInterface(self.NavigationMode) + + def next(self): + name = self.nameLine.text() + it = iter(self.contacts) + + try: + while True: + this_name, _ = it.next() + + if this_name == name: + next_name, next_address = it.next() + break + except StopIteration: + next_name, next_address = iter(self.contacts).next() + + self.nameLine.setText(next_name) + self.addressText.setText(next_address) + + def previous(self): + name = self.nameLine.text() + + prev_name = prev_address = None + for this_name, this_address in self.contacts: + if this_name == name: + break + + prev_name = this_name + prev_address = this_address + else: + self.nameLine.clear() + self.addressText.clear() + return + + if prev_name is None: + for prev_name, prev_address in self.contacts: + pass + + self.nameLine.setText(prev_name) + self.addressText.setText(prev_address) + + def findContact(self): + self.dialog.show() + + if self.dialog.exec_() == QtWidgets.QDialog.Accepted: + contactName = self.dialog.getFindText() + + if contactName in self.contacts: + self.nameLine.setText(contactName) + self.addressText.setText(self.contacts[contactName]) + else: + QtWidgets.QMessageBox.information(self, "Contact Not Found", + "Sorry, \"%s\" is not in your address book." % contactName) + return + + self.updateInterface(self.NavigationMode) + + def updateInterface(self, mode): + self.currentMode = mode + + if self.currentMode in (self.AddingMode, self.EditingMode): + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.editButton.setEnabled(False) + self.removeButton.setEnabled(False) + + self.nextButton.setEnabled(False) + self.previousButton.setEnabled(False) + + self.submitButton.show() + self.cancelButton.show() + + elif self.currentMode == self.NavigationMode: + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.editButton.setEnabled(number >= 1) + self.removeButton.setEnabled(number >= 1) + self.findButton.setEnabled(number > 2) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number >1 ) + + self.submitButton.hide() + self.cancelButton.hide() + + +class FindDialog(QtWidgets.QDialog): + def __init__(self, parent=None): + super(FindDialog, self).__init__(parent) + + findLabel = QtWidgets.QLabel("Enter the name of a contact:") + self.lineEdit = QtWidgets.QLineEdit() + + self.findButton = QtWidgets.QPushButton("&Find") + self.findText = '' + + layout = QtWidgets.QHBoxLayout() + layout.addWidget(findLabel) + layout.addWidget(self.lineEdit) + layout.addWidget(self.findButton) + + self.setLayout(layout) + self.setWindowTitle("Find a Contact") + + self.findButton.clicked.connect(self.findClicked) + self.findButton.clicked.connect(self.accept) + + def findClicked(self): + text = self.lineEdit.text() + + if not text: + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name.") + return + else: + self.findText = text + self.lineEdit.clear() + self.hide() + + def getFindText(self): + return self.findText + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part6.py b/examples/widgets/tutorials/addressbook/part6.py new file mode 100644 index 0000000..559cc35 --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part6.py @@ -0,0 +1,424 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import pickle + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + NavigationMode, AddingMode, EditingMode = range(3) + + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + self.currentMode = self.NavigationMode + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.editButton = QtWidgets.QPushButton("&Edit") + self.editButton.setEnabled(False) + self.removeButton = QtWidgets.QPushButton("&Remove") + self.removeButton.setEnabled(False) + self.findButton = QtWidgets.QPushButton("&Find") + self.findButton.setEnabled(False) + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + + self.nextButton = QtWidgets.QPushButton("&Next") + self.nextButton.setEnabled(False) + self.previousButton = QtWidgets.QPushButton("&Previous") + self.previousButton.setEnabled(False) + + self.loadButton = QtWidgets.QPushButton("&Load...") + self.loadButton.setToolTip("Load contacts from a file") + self.saveButton = QtWidgets.QPushButton("Sa&ve...") + self.saveButton.setToolTip("Save contacts to a file") + self.saveButton.setEnabled(False) + + self.dialog = FindDialog() + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.editButton.clicked.connect(self.editContact) + self.removeButton.clicked.connect(self.removeContact) + self.findButton.clicked.connect(self.findContact) + self.cancelButton.clicked.connect(self.cancel) + self.nextButton.clicked.connect(self.next) + self.previousButton.clicked.connect(self.previous) + self.loadButton.clicked.connect(self.loadFromFile) + self.saveButton.clicked.connect(self.saveToFile) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton) + buttonLayout1.addWidget(self.editButton) + buttonLayout1.addWidget(self.removeButton) + buttonLayout1.addWidget(self.findButton) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addWidget(self.loadButton) + buttonLayout1.addWidget(self.saveButton) + buttonLayout1.addStretch() + + buttonLayout2 = QtWidgets.QHBoxLayout() + buttonLayout2.addWidget(self.previousButton) + buttonLayout2.addWidget(self.nextButton) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + mainLayout.addLayout(buttonLayout2, 2, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.updateInterface(self.AddingMode) + + def editContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.updateInterface(self.EditingMode) + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if self.currentMode == self.AddingMode: + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + elif self.currentMode == self.EditingMode: + if self.oldName != name: + if name not in self.contacts: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % self.oldName) + del self.contacts[self.oldName] + self.contacts[name] = address + else: + QtWidgets.QMessageBox.information(self, "Edit Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + elif self.oldAddress != address: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % name) + self.contacts[name] = address + + self.updateInterface(self.NavigationMode) + + def cancel(self): + self.nameLine.setText(self.oldName) + self.addressText.setText(self.oldAddress) + self.updateInterface(self.NavigationMode) + + def removeContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name in self.contacts: + button = QtWidgets.QMessageBox.question(self, "Confirm Remove", + "Are you sure you want to remove \"%s\"?" % name, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) + + if button == QtWidgets.QMessageBox.Yes: + self.previous() + del self.contacts[name] + + QtWidgets.QMessageBox.information(self, "Remove Successful", + "\"%s\" has been removed from your address book." % name) + + self.updateInterface(self.NavigationMode) + + def next(self): + name = self.nameLine.text() + it = iter(self.contacts) + + try: + while True: + this_name, _ = it.next() + + if this_name == name: + next_name, next_address = it.next() + break + except StopIteration: + next_name, next_address = iter(self.contacts).next() + + self.nameLine.setText(next_name) + self.addressText.setText(next_address) + + def previous(self): + name = self.nameLine.text() + + prev_name = prev_address = None + for this_name, this_address in self.contacts: + if this_name == name: + break + + prev_name = this_name + prev_address = this_address + else: + self.nameLine.clear() + self.addressText.clear() + return + + if prev_name is None: + for prev_name, prev_address in self.contacts: + pass + + self.nameLine.setText(prev_name) + self.addressText.setText(prev_address) + + def findContact(self): + self.dialog.show() + + if self.dialog.exec_() == QtWidgets.QDialog.Accepted: + contactName = self.dialog.getFindText() + + if contactName in self.contacts: + self.nameLine.setText(contactName) + self.addressText.setText(self.contacts[contactName]) + else: + QtWidgets.QMessageBox.information(self, "Contact Not Found", + "Sorry, \"%s\" is not in your address book." % contactName) + return + + self.updateInterface(self.NavigationMode) + + def updateInterface(self, mode): + self.currentMode = mode + + if self.currentMode in (self.AddingMode, self.EditingMode): + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.editButton.setEnabled(False) + self.removeButton.setEnabled(False) + + self.nextButton.setEnabled(False) + self.previousButton.setEnabled(False) + + self.submitButton.show() + self.cancelButton.show() + + self.loadButton.setEnabled(False) + self.saveButton.setEnabled(False) + + elif self.currentMode == self.NavigationMode: + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.editButton.setEnabled(number >= 1) + self.removeButton.setEnabled(number >= 1) + self.findButton.setEnabled(number > 2) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number >1 ) + + self.submitButton.hide() + self.cancelButton.hide() + + self.loadButton.setEnabled(True) + self.saveButton.setEnabled(number >= 1) + + def saveToFile(self): + fileName,_ = QtWidgets.QFileDialog.getSaveFileName(self, + "Save Address Book", '', + "Address Book (*.abk);;All Files (*)") + + if not fileName: + return + + try: + out_file = open(str(fileName), 'wb') + except IOError: + QtWidgets.QMessageBox.information(self, "Unable to open file", + "There was an error opening \"%s\"" % fileName) + return + + pickle.dump(self.contacts, out_file) + out_file.close() + + def loadFromFile(self): + fileName,_ = QtWidgets.QFileDialog.getOpenFileName(self, + "Open Address Book", '', + "Address Book (*.abk);;All Files (*)") + + if not fileName: + return + + try: + in_file = open(str(fileName), 'rb') + except IOError: + QtWidgets.QMessageBox.information(self, "Unable to open file", + "There was an error opening \"%s\"" % fileName) + return + + self.contacts = pickle.load(in_file) + in_file.close() + + if len(self.contacts) == 0: + QtWidgets.QMessageBox.information(self, "No contacts in file", + "The file you are attempting to open contains no " + "contacts.") + else: + for name, address in self.contacts: + self.nameLine.setText(name) + self.addressText.setText(address) + + self.updateInterface(self.NavigationMode) + + +class FindDialog(QtWidgets.QDialog): + def __init__(self, parent=None): + super(FindDialog, self).__init__(parent) + + findLabel = QtWidgets.QLabel("Enter the name of a contact:") + self.lineEdit = QtWidgets.QLineEdit() + + self.findButton = QtWidgets.QPushButton("&Find") + self.findText = '' + + layout = QtWidgets.QHBoxLayout() + layout.addWidget(findLabel) + layout.addWidget(self.lineEdit) + layout.addWidget(self.findButton) + + self.setLayout(layout) + self.setWindowTitle("Find a Contact") + + self.findButton.clicked.connect(self.findClicked) + self.findButton.clicked.connect(self.accept) + + def findClicked(self): + text = self.lineEdit.text() + + if not text: + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name.") + return + + self.findText = text + self.lineEdit.clear() + self.hide() + + def getFindText(self): + return self.findText + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/tutorials/addressbook/part7.py b/examples/widgets/tutorials/addressbook/part7.py new file mode 100644 index 0000000..f32a2a6 --- /dev/null +++ b/examples/widgets/tutorials/addressbook/part7.py @@ -0,0 +1,476 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import pickle + +from PySide2 import QtCore, QtWidgets + + +class SortedDict(dict): + class Iterator(object): + def __init__(self, sorted_dict): + self._dict = sorted_dict + self._keys = sorted(self._dict.keys()) + self._nr_items = len(self._keys) + self._idx = 0 + + def __iter__(self): + return self + + def next(self): + if self._idx >= self._nr_items: + raise StopIteration + + key = self._keys[self._idx] + value = self._dict[key] + self._idx += 1 + + return key, value + + __next__ = next + + def __iter__(self): + return SortedDict.Iterator(self) + + iterkeys = __iter__ + + +class AddressBook(QtWidgets.QWidget): + NavigationMode, AddingMode, EditingMode = range(3) + + def __init__(self, parent=None): + super(AddressBook, self).__init__(parent) + + self.contacts = SortedDict() + self.oldName = '' + self.oldAddress = '' + self.currentMode = self.NavigationMode + + nameLabel = QtWidgets.QLabel("Name:") + self.nameLine = QtWidgets.QLineEdit() + self.nameLine.setReadOnly(True) + + addressLabel = QtWidgets.QLabel("Address:") + self.addressText = QtWidgets.QTextEdit() + self.addressText.setReadOnly(True) + + self.addButton = QtWidgets.QPushButton("&Add") + self.editButton = QtWidgets.QPushButton("&Edit") + self.editButton.setEnabled(False) + self.removeButton = QtWidgets.QPushButton("&Remove") + self.removeButton.setEnabled(False) + self.findButton = QtWidgets.QPushButton("&Find") + self.findButton.setEnabled(False) + self.submitButton = QtWidgets.QPushButton("&Submit") + self.submitButton.hide() + self.cancelButton = QtWidgets.QPushButton("&Cancel") + self.cancelButton.hide() + + self.nextButton = QtWidgets.QPushButton("&Next") + self.nextButton.setEnabled(False) + self.previousButton = QtWidgets.QPushButton("&Previous") + self.previousButton.setEnabled(False) + + self.loadButton = QtWidgets.QPushButton("&Load...") + self.loadButton.setToolTip("Load contacts from a file") + self.saveButton = QtWidgets.QPushButton("Sa&ve...") + self.saveButton.setToolTip("Save contacts to a file") + self.saveButton.setEnabled(False) + + self.exportButton = QtWidgets.QPushButton("Ex&port") + self.exportButton.setToolTip("Export as vCard") + self.exportButton.setEnabled(False) + + self.dialog = FindDialog() + + self.addButton.clicked.connect(self.addContact) + self.submitButton.clicked.connect(self.submitContact) + self.editButton.clicked.connect(self.editContact) + self.removeButton.clicked.connect(self.removeContact) + self.findButton.clicked.connect(self.findContact) + self.cancelButton.clicked.connect(self.cancel) + self.nextButton.clicked.connect(self.next) + self.previousButton.clicked.connect(self.previous) + self.loadButton.clicked.connect(self.loadFromFile) + self.saveButton.clicked.connect(self.saveToFile) + self.exportButton.clicked.connect(self.exportAsVCard) + + buttonLayout1 = QtWidgets.QVBoxLayout() + buttonLayout1.addWidget(self.addButton) + buttonLayout1.addWidget(self.editButton) + buttonLayout1.addWidget(self.removeButton) + buttonLayout1.addWidget(self.findButton) + buttonLayout1.addWidget(self.submitButton) + buttonLayout1.addWidget(self.cancelButton) + buttonLayout1.addWidget(self.loadButton) + buttonLayout1.addWidget(self.saveButton) + buttonLayout1.addWidget(self.exportButton) + buttonLayout1.addStretch() + + buttonLayout2 = QtWidgets.QHBoxLayout() + buttonLayout2.addWidget(self.previousButton) + buttonLayout2.addWidget(self.nextButton) + + mainLayout = QtWidgets.QGridLayout() + mainLayout.addWidget(nameLabel, 0, 0) + mainLayout.addWidget(self.nameLine, 0, 1) + mainLayout.addWidget(addressLabel, 1, 0, QtCore.Qt.AlignTop) + mainLayout.addWidget(self.addressText, 1, 1) + mainLayout.addLayout(buttonLayout1, 1, 2) + mainLayout.addLayout(buttonLayout2, 2, 1) + + self.setLayout(mainLayout) + self.setWindowTitle("Simple Address Book") + + def addContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.nameLine.clear() + self.addressText.clear() + + self.updateInterface(self.AddingMode) + + def editContact(self): + self.oldName = self.nameLine.text() + self.oldAddress = self.addressText.toPlainText() + + self.updateInterface(self.EditingMode) + + def submitContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name == "" or address == "": + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name and address.") + return + + if self.currentMode == self.AddingMode: + if name not in self.contacts: + self.contacts[name] = address + QtWidgets.QMessageBox.information(self, "Add Successful", + "\"%s\" has been added to your address book." % name) + else: + QtWidgets.QMessageBox.information(self, "Add Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + + elif self.currentMode == self.EditingMode: + if self.oldName != name: + if name not in self.contacts: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % self.oldName) + del self.contacts[self.oldName] + self.contacts[name] = address + else: + QtWidgets.QMessageBox.information(self, "Edit Unsuccessful", + "Sorry, \"%s\" is already in your address book." % name) + return + elif self.oldAddress != address: + QtWidgets.QMessageBox.information(self, "Edit Successful", + "\"%s\" has been edited in your address book." % name) + self.contacts[name] = address + + self.updateInterface(self.NavigationMode) + + def cancel(self): + self.nameLine.setText(self.oldName) + self.addressText.setText(self.oldAddress) + self.updateInterface(self.NavigationMode) + + def removeContact(self): + name = self.nameLine.text() + address = self.addressText.toPlainText() + + if name in self.contacts: + button = QtWidgets.QMessageBox.question(self, "Confirm Remove", + "Are you sure you want to remove \"%s\"?" % name, + QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No) + + if button == QtWidgets.QMessageBox.Yes: + self.previous() + del self.contacts[name] + + QtWidgets.QMessageBox.information(self, "Remove Successful", + "\"%s\" has been removed from your address book." % name) + + self.updateInterface(self.NavigationMode) + + def next(self): + name = self.nameLine.text() + it = iter(self.contacts) + + try: + while True: + this_name, _ = it.next() + + if this_name == name: + next_name, next_address = it.next() + break + except StopIteration: + next_name, next_address = iter(self.contacts).next() + + self.nameLine.setText(next_name) + self.addressText.setText(next_address) + + def previous(self): + name = self.nameLine.text() + + prev_name = prev_address = None + for this_name, this_address in self.contacts: + if this_name == name: + break + + prev_name = this_name + prev_address = this_address + else: + self.nameLine.clear() + self.addressText.clear() + return + + if prev_name is None: + for prev_name, prev_address in self.contacts: + pass + + self.nameLine.setText(prev_name) + self.addressText.setText(prev_address) + + def findContact(self): + self.dialog.show() + + if self.dialog.exec_() == QtWidgets.QDialog.Accepted: + contactName = self.dialog.getFindText() + + if contactName in self.contacts: + self.nameLine.setText(contactName) + self.addressText.setText(self.contacts[contactName]) + else: + QtWidgets.QMessageBox.information(self, "Contact Not Found", + "Sorry, \"%s\" is not in your address book." % contactName) + return + + self.updateInterface(self.NavigationMode) + + def updateInterface(self, mode): + self.currentMode = mode + + if self.currentMode in (self.AddingMode, self.EditingMode): + self.nameLine.setReadOnly(False) + self.nameLine.setFocus(QtCore.Qt.OtherFocusReason) + self.addressText.setReadOnly(False) + + self.addButton.setEnabled(False) + self.editButton.setEnabled(False) + self.removeButton.setEnabled(False) + + self.nextButton.setEnabled(False) + self.previousButton.setEnabled(False) + + self.submitButton.show() + self.cancelButton.show() + + self.loadButton.setEnabled(False) + self.saveButton.setEnabled(False) + self.exportButton.setEnabled(False) + + elif self.currentMode == self.NavigationMode: + if not self.contacts: + self.nameLine.clear() + self.addressText.clear() + + self.nameLine.setReadOnly(True) + self.addressText.setReadOnly(True) + self.addButton.setEnabled(True) + + number = len(self.contacts) + self.editButton.setEnabled(number >= 1) + self.removeButton.setEnabled(number >= 1) + self.findButton.setEnabled(number > 2) + self.nextButton.setEnabled(number > 1) + self.previousButton.setEnabled(number >1 ) + + self.submitButton.hide() + self.cancelButton.hide() + + self.exportButton.setEnabled(number >= 1) + + self.loadButton.setEnabled(True) + self.saveButton.setEnabled(number >= 1) + + def saveToFile(self): + fileName,_ = QtWidgets.QFileDialog.getSaveFileName(self, + "Save Address Book", '', + "Address Book (*.abk);;All Files (*)") + + if not fileName: + return + + try: + out_file = open(str(fileName), 'wb') + except IOError: + QtWidgets.QMessageBox.information(self, "Unable to open file", + "There was an error opening \"%s\"" % fileName) + return + + pickle.dump(self.contacts, out_file) + out_file.close() + + def loadFromFile(self): + fileName,_ = QtWidgets.QFileDialog.getOpenFileName(self, + "Open Address Book", '', + "Address Book (*.abk);;All Files (*)") + + if not fileName: + return + + try: + in_file = open(str(fileName), 'rb') + except IOError: + QtWidgets.QMessageBox.information(self, "Unable to open file", + "There was an error opening \"%s\"" % fileName) + return + + self.contacts = pickle.load(in_file) + in_file.close() + + if len(self.contacts) == 0: + QtWidgets.QMessageBox.information(self, "No contacts in file", + "The file you are attempting to open contains no " + "contacts.") + else: + for name, address in self.contacts: + self.nameLine.setText(name) + self.addressText.setText(address) + + self.updateInterface(self.NavigationMode) + + def exportAsVCard(self): + name = str(self.nameLine.text()) + address = self.addressText.toPlainText() + + nameList = name.split() + + if len(nameList) > 1: + firstName = nameList[0] + lastName = nameList[-1] + else: + firstName = name + lastName = '' + + fileName = QtWidgets.QFileDialog.getSaveFileName(self, "Export Contact", + '', "vCard Files (*.vcf);;All Files (*)")[0] + + if not fileName: + return + + out_file = QtCore.QFile(fileName) + + if not out_file.open(QtCore.QIODevice.WriteOnly): + QtWidgets.QMessageBox.information(self, "Unable to open file", + out_file.errorString()) + return + + out_s = QtCore.QTextStream(out_file) + + out_s << 'BEGIN:VCARD' << '\n' + out_s << 'VERSION:2.1' << '\n' + out_s << 'N:' << lastName << ';' << firstName << '\n' + out_s << 'FN:' << ' '.join(nameList) << '\n' + + address.replace(';', '\\;') + address.replace('\n', ';') + address.replace(',', ' ') + + out_s << 'ADR;HOME:;' << address << '\n' + out_s << 'END:VCARD' << '\n' + + QtWidgets.QMessageBox.information(self, "Export Successful", + "\"%s\" has been exported as a vCard." % name) + + +class FindDialog(QtWidgets.QDialog): + def __init__(self, parent=None): + super(FindDialog, self).__init__(parent) + + findLabel = QtWidgets.QLabel("Enter the name of a contact:") + self.lineEdit = QtWidgets.QLineEdit() + + self.findButton = QtWidgets.QPushButton("&Find") + self.findText = '' + + layout = QtWidgets.QHBoxLayout() + layout.addWidget(findLabel) + layout.addWidget(self.lineEdit) + layout.addWidget(self.findButton) + + self.setLayout(layout) + self.setWindowTitle("Find a Contact") + + self.findButton.clicked.connect(self.findClicked) + self.findButton.clicked.connect(self.accept) + + def findClicked(self): + text = self.lineEdit.text() + + if not text: + QtWidgets.QMessageBox.information(self, "Empty Field", + "Please enter a name.") + return + + self.findText = text + self.lineEdit.clear() + self.hide() + + def getFindText(self): + return self.findText + + +if __name__ == '__main__': + import sys + + app = QtWidgets.QApplication(sys.argv) + + addressBook = AddressBook() + addressBook.show() + + sys.exit(app.exec_()) diff --git a/examples/widgets/widgets/hellogl_openglwidget_legacy.py b/examples/widgets/widgets/hellogl_openglwidget_legacy.py new file mode 100644 index 0000000..8745b4e --- /dev/null +++ b/examples/widgets/widgets/hellogl_openglwidget_legacy.py @@ -0,0 +1,288 @@ + +############################################################################ +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +"""PySide2 port of the opengl/legacy/hellogl example from Qt v5.x modified to use a QOpenGLWidget to demonstrate porting from QGLWidget to QOpenGLWidget""" + +import sys +import math +from PySide2 import QtCore, QtGui, QtWidgets + +try: + from OpenGL import GL +except ImportError: + app = QtWidgets.QApplication(sys.argv) + messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL hellogl", + "PyOpenGL must be installed to run this example.", + QtWidgets.QMessageBox.Close) + messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") + messageBox.exec_() + sys.exit(1) + + +class Window(QtWidgets.QWidget): + def __init__(self, parent=None): + QtWidgets.QWidget.__init__(self, parent) + + self.glWidget = GLWidget() + + self.xSlider = self.createSlider(QtCore.SIGNAL("xRotationChanged(int)"), + self.glWidget.setXRotation) + self.ySlider = self.createSlider(QtCore.SIGNAL("yRotationChanged(int)"), + self.glWidget.setYRotation) + self.zSlider = self.createSlider(QtCore.SIGNAL("zRotationChanged(int)"), + self.glWidget.setZRotation) + + mainLayout = QtWidgets.QHBoxLayout() + mainLayout.addWidget(self.glWidget) + mainLayout.addWidget(self.xSlider) + mainLayout.addWidget(self.ySlider) + mainLayout.addWidget(self.zSlider) + self.setLayout(mainLayout) + + self.xSlider.setValue(170 * 16) + self.ySlider.setValue(160 * 16) + self.zSlider.setValue(90 * 16) + + self.setWindowTitle(self.tr("QOpenGLWidget")) + + def createSlider(self, changedSignal, setterSlot): + slider = QtWidgets.QSlider(QtCore.Qt.Vertical) + + slider.setRange(0, 360 * 16) + slider.setSingleStep(16) + slider.setPageStep(15 * 16) + slider.setTickInterval(15 * 16) + slider.setTickPosition(QtWidgets.QSlider.TicksRight) + + self.glWidget.connect(slider, QtCore.SIGNAL("valueChanged(int)"), setterSlot) + self.connect(self.glWidget, changedSignal, slider, QtCore.SLOT("setValue(int)")) + + return slider + + +class GLWidget(QtWidgets.QOpenGLWidget): + xRotationChanged = QtCore.Signal(int) + yRotationChanged = QtCore.Signal(int) + zRotationChanged = QtCore.Signal(int) + + def __init__(self, parent=None): + QtWidgets.QOpenGLWidget.__init__(self, parent) + + self.object = 0 + self.xRot = 0 + self.yRot = 0 + self.zRot = 0 + + self.lastPos = QtCore.QPoint() + + self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) + self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0) + + def xRotation(self): + return self.xRot + + def yRotation(self): + return self.yRot + + def zRotation(self): + return self.zRot + + def minimumSizeHint(self): + return QtCore.QSize(50, 50) + + def sizeHint(self): + return QtCore.QSize(400, 400) + + def setXRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.xRot: + self.xRot = angle + self.emit(QtCore.SIGNAL("xRotationChanged(int)"), angle) + self.update() + + def setYRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.yRot: + self.yRot = angle + self.emit(QtCore.SIGNAL("yRotationChanged(int)"), angle) + self.update() + + def setZRotation(self, angle): + angle = self.normalizeAngle(angle) + if angle != self.zRot: + self.zRot = angle + self.emit(QtCore.SIGNAL("zRotationChanged(int)"), angle) + self.update() + + def initializeGL(self): + darkTrolltechPurple = self.trolltechPurple.darker() + GL.glClearColor(darkTrolltechPurple.redF(), darkTrolltechPurple.greenF(), darkTrolltechPurple.blueF(), darkTrolltechPurple.alphaF()) + self.object = self.makeObject() + GL.glShadeModel(GL.GL_FLAT) + GL.glEnable(GL.GL_DEPTH_TEST) + GL.glEnable(GL.GL_CULL_FACE) + + def paintGL(self): + GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT) + GL.glLoadIdentity() + GL.glTranslated(0.0, 0.0, -10.0) + GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) + GL.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) + GL.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) + GL.glCallList(self.object) + + def resizeGL(self, width, height): + side = min(width, height) + GL.glViewport(int((width - side) / 2),int((height - side) / 2), side, side) + + GL.glMatrixMode(GL.GL_PROJECTION) + GL.glLoadIdentity() + GL.glOrtho(-0.5, +0.5, -0.5, +0.5, 4.0, 15.0) + GL.glMatrixMode(GL.GL_MODELVIEW) + + def mousePressEvent(self, event): + self.lastPos = QtCore.QPoint(event.pos()) + + def mouseMoveEvent(self, event): + dx = event.x() - self.lastPos.x() + dy = event.y() - self.lastPos.y() + + if event.buttons() & QtCore.Qt.LeftButton: + self.setXRotation(self.xRot + 8 * dy) + self.setYRotation(self.yRot + 8 * dx) + elif event.buttons() & QtCore.Qt.RightButton: + self.setXRotation(self.xRot + 8 * dy) + self.setZRotation(self.zRot + 8 * dx) + + self.lastPos = QtCore.QPoint(event.pos()) + + def makeObject(self): + genList = GL.glGenLists(1) + GL.glNewList(genList, GL.GL_COMPILE) + + GL.glBegin(GL.GL_QUADS) + + x1 = +0.06 + y1 = -0.14 + x2 = +0.14 + y2 = -0.06 + x3 = +0.08 + y3 = +0.00 + x4 = +0.30 + y4 = +0.22 + + self.quad(x1, y1, x2, y2, y2, x2, y1, x1) + self.quad(x3, y3, x4, y4, y4, x4, y3, x3) + + self.extrude(x1, y1, x2, y2) + self.extrude(x2, y2, y2, x2) + self.extrude(y2, x2, y1, x1) + self.extrude(y1, x1, x1, y1) + self.extrude(x3, y3, x4, y4) + self.extrude(x4, y4, y4, x4) + self.extrude(y4, x4, y3, x3) + + Pi = 3.14159265358979323846 + NumSectors = 200 + + for i in range(NumSectors): + angle1 = (i * 2 * Pi) / NumSectors + x5 = 0.30 * math.sin(angle1) + y5 = 0.30 * math.cos(angle1) + x6 = 0.20 * math.sin(angle1) + y6 = 0.20 * math.cos(angle1) + + angle2 = ((i + 1) * 2 * Pi) / NumSectors + x7 = 0.20 * math.sin(angle2) + y7 = 0.20 * math.cos(angle2) + x8 = 0.30 * math.sin(angle2) + y8 = 0.30 * math.cos(angle2) + + self.quad(x5, y5, x6, y6, x7, y7, x8, y8) + + self.extrude(x6, y6, x7, y7) + self.extrude(x8, y8, x5, y5) + + GL.glEnd() + GL.glEndList() + + return genList + + def quad(self, x1, y1, x2, y2, x3, y3, x4, y4): + GL.glColor(self.trolltechGreen.redF(), self.trolltechGreen.greenF(), self.trolltechGreen.blueF(), self.trolltechGreen.alphaF()) + + GL.glVertex3d(x1, y1, +0.05) + GL.glVertex3d(x2, y2, +0.05) + GL.glVertex3d(x3, y3, +0.05) + GL.glVertex3d(x4, y4, +0.05) + + GL.glVertex3d(x4, y4, -0.05) + GL.glVertex3d(x3, y3, -0.05) + GL.glVertex3d(x2, y2, -0.05) + GL.glVertex3d(x1, y1, -0.05) + + def extrude(self, x1, y1, x2, y2): + darkTrolltechGreen = self.trolltechGreen.darker(250 + int(100 * x1)) + GL.glColor(darkTrolltechGreen.redF(), darkTrolltechGreen.greenF(), darkTrolltechGreen.blueF(), darkTrolltechGreen.alphaF()) + + GL.glVertex3d(x1, y1, -0.05) + GL.glVertex3d(x2, y2, -0.05) + GL.glVertex3d(x2, y2, +0.05) + GL.glVertex3d(x1, y1, +0.05) + + def normalizeAngle(self, angle): + while angle < 0: + angle += 360 * 16 + while angle > 360 * 16: + angle -= 360 * 16 + return angle + + def freeResources(self): + self.makeCurrent() + GL.glDeleteLists(self.object, 1) + +if __name__ == '__main__': + app = QtWidgets.QApplication(sys.argv) + window = Window() + window.show() + res = app.exec_() + window.glWidget.freeResources() + sys.exit(res) diff --git a/examples/widgets/widgets/tetrix.py b/examples/widgets/widgets/tetrix.py new file mode 100644 index 0000000..134eec4 --- /dev/null +++ b/examples/widgets/widgets/tetrix.py @@ -0,0 +1,498 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the widgets/widgets/tetrix example from Qt v5.x""" + +import random + +from PySide2 import QtCore, QtGui, QtWidgets + + +NoShape, ZShape, SShape, LineShape, TShape, SquareShape, LShape, MirroredLShape = range(8) + + +class TetrixWindow(QtWidgets.QWidget): + def __init__(self): + super(TetrixWindow, self).__init__() + + self.board = TetrixBoard() + + nextPieceLabel = QtWidgets.QLabel() + nextPieceLabel.setFrameStyle(QtWidgets.QFrame.Box | QtWidgets.QFrame.Raised) + nextPieceLabel.setAlignment(QtCore.Qt.AlignCenter) + self.board.setNextPieceLabel(nextPieceLabel) + + scoreLcd = QtWidgets.QLCDNumber(5) + scoreLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) + levelLcd = QtWidgets.QLCDNumber(2) + levelLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) + linesLcd = QtWidgets.QLCDNumber(5) + linesLcd.setSegmentStyle(QtWidgets.QLCDNumber.Filled) + + startButton = QtWidgets.QPushButton("&Start") + startButton.setFocusPolicy(QtCore.Qt.NoFocus) + quitButton = QtWidgets.QPushButton("&Quit") + quitButton.setFocusPolicy(QtCore.Qt.NoFocus) + pauseButton = QtWidgets.QPushButton("&Pause") + pauseButton.setFocusPolicy(QtCore.Qt.NoFocus) + + startButton.clicked.connect(self.board.start) + pauseButton.clicked.connect(self.board.pause) + quitButton.clicked.connect(qApp.quit) + self.board.scoreChanged.connect(scoreLcd.display) + self.board.levelChanged.connect(levelLcd.display) + self.board.linesRemovedChanged.connect(linesLcd.display) + + layout = QtWidgets.QGridLayout() + layout.addWidget(self.createLabel("NEXT"), 0, 0) + layout.addWidget(nextPieceLabel, 1, 0) + layout.addWidget(self.createLabel("LEVEL"), 2, 0) + layout.addWidget(levelLcd, 3, 0) + layout.addWidget(startButton, 4, 0) + layout.addWidget(self.board, 0, 1, 6, 1) + layout.addWidget(self.createLabel("SCORE"), 0, 2) + layout.addWidget(scoreLcd, 1, 2) + layout.addWidget(self.createLabel("LINES REMOVED"), 2, 2) + layout.addWidget(linesLcd, 3, 2) + layout.addWidget(quitButton, 4, 2) + layout.addWidget(pauseButton, 5, 2) + self.setLayout(layout) + + self.setWindowTitle("Tetrix") + self.resize(550, 370) + + def createLabel(self, text): + lbl = QtWidgets.QLabel(text) + lbl.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom) + return lbl + + +class TetrixBoard(QtWidgets.QFrame): + BoardWidth = 10 + BoardHeight = 22 + + scoreChanged = QtCore.Signal(int) + + levelChanged = QtCore.Signal(int) + + linesRemovedChanged = QtCore.Signal(int) + + def __init__(self, parent=None): + super(TetrixBoard, self).__init__(parent) + + self.timer = QtCore.QBasicTimer() + self.nextPieceLabel = None + self.isWaitingAfterLine = False + self.curPiece = TetrixPiece() + self.nextPiece = TetrixPiece() + self.curX = 0 + self.curY = 0 + self.numLinesRemoved = 0 + self.numPiecesDropped = 0 + self.score = 0 + self.level = 0 + self.board = None + + self.setFrameStyle(QtWidgets.QFrame.Panel | QtWidgets.QFrame.Sunken) + self.setFocusPolicy(QtCore.Qt.StrongFocus) + self.isStarted = False + self.isPaused = False + self.clearBoard() + + self.nextPiece.setRandomShape() + + def shapeAt(self, x, y): + return self.board[(y * TetrixBoard.BoardWidth) + x] + + def setShapeAt(self, x, y, shape): + self.board[(y * TetrixBoard.BoardWidth) + x] = shape + + def timeoutTime(self): + return 1000 / (1 + self.level) + + def squareWidth(self): + return self.contentsRect().width() / TetrixBoard.BoardWidth + + def squareHeight(self): + return self.contentsRect().height() / TetrixBoard.BoardHeight + + def setNextPieceLabel(self, label): + self.nextPieceLabel = label + + def sizeHint(self): + return QtCore.QSize(TetrixBoard.BoardWidth * 15 + self.frameWidth() * 2, + TetrixBoard.BoardHeight * 15 + self.frameWidth() * 2) + + def minimumSizeHint(self): + return QtCore.QSize(TetrixBoard.BoardWidth * 5 + self.frameWidth() * 2, + TetrixBoard.BoardHeight * 5 + self.frameWidth() * 2) + + def start(self): + if self.isPaused: + return + + self.isStarted = True + self.isWaitingAfterLine = False + self.numLinesRemoved = 0 + self.numPiecesDropped = 0 + self.score = 0 + self.level = 1 + self.clearBoard() + + self.linesRemovedChanged.emit(self.numLinesRemoved) + self.scoreChanged.emit(self.score) + self.levelChanged.emit(self.level) + + self.newPiece() + self.timer.start(self.timeoutTime(), self) + + def pause(self): + if not self.isStarted: + return + + self.isPaused = not self.isPaused + if self.isPaused: + self.timer.stop() + else: + self.timer.start(self.timeoutTime(), self) + + self.update() + + def paintEvent(self, event): + super(TetrixBoard, self).paintEvent(event) + + painter = QtGui.QPainter(self) + rect = self.contentsRect() + + if self.isPaused: + painter.drawText(rect, QtCore.Qt.AlignCenter, "Pause") + return + + boardTop = rect.bottom() - TetrixBoard.BoardHeight * self.squareHeight() + + for i in range(TetrixBoard.BoardHeight): + for j in range(TetrixBoard.BoardWidth): + shape = self.shapeAt(j, TetrixBoard.BoardHeight - i - 1) + if shape != NoShape: + self.drawSquare(painter, + rect.left() + j * self.squareWidth(), + boardTop + i * self.squareHeight(), shape) + + if self.curPiece.shape() != NoShape: + for i in range(4): + x = self.curX + self.curPiece.x(i) + y = self.curY - self.curPiece.y(i) + self.drawSquare(painter, rect.left() + x * self.squareWidth(), + boardTop + (TetrixBoard.BoardHeight - y - 1) * self.squareHeight(), + self.curPiece.shape()) + + def keyPressEvent(self, event): + if not self.isStarted or self.isPaused or self.curPiece.shape() == NoShape: + super(TetrixBoard, self).keyPressEvent(event) + return + + key = event.key() + if key == QtCore.Qt.Key_Left: + self.tryMove(self.curPiece, self.curX - 1, self.curY) + elif key == QtCore.Qt.Key_Right: + self.tryMove(self.curPiece, self.curX + 1, self.curY) + elif key == QtCore.Qt.Key_Down: + self.tryMove(self.curPiece.rotatedRight(), self.curX, self.curY) + elif key == QtCore.Qt.Key_Up: + self.tryMove(self.curPiece.rotatedLeft(), self.curX, self.curY) + elif key == QtCore.Qt.Key_Space: + self.dropDown() + elif key == QtCore.Qt.Key_D: + self.oneLineDown() + else: + super(TetrixBoard, self).keyPressEvent(event) + + def timerEvent(self, event): + if event.timerId() == self.timer.timerId(): + if self.isWaitingAfterLine: + self.isWaitingAfterLine = False + self.newPiece() + self.timer.start(self.timeoutTime(), self) + else: + self.oneLineDown() + else: + super(TetrixBoard, self).timerEvent(event) + + def clearBoard(self): + self.board = [NoShape for i in range(TetrixBoard.BoardHeight * TetrixBoard.BoardWidth)] + + def dropDown(self): + dropHeight = 0 + newY = self.curY + while newY > 0: + if not self.tryMove(self.curPiece, self.curX, newY - 1): + break + newY -= 1 + dropHeight += 1 + + self.pieceDropped(dropHeight) + + def oneLineDown(self): + if not self.tryMove(self.curPiece, self.curX, self.curY - 1): + self.pieceDropped(0) + + def pieceDropped(self, dropHeight): + for i in range(4): + x = self.curX + self.curPiece.x(i) + y = self.curY - self.curPiece.y(i) + self.setShapeAt(x, y, self.curPiece.shape()) + + self.numPiecesDropped += 1 + if self.numPiecesDropped % 25 == 0: + self.level += 1 + self.timer.start(self.timeoutTime(), self) + self.levelChanged.emit(self.level) + + self.score += dropHeight + 7 + self.scoreChanged.emit(self.score) + self.removeFullLines() + + if not self.isWaitingAfterLine: + self.newPiece() + + def removeFullLines(self): + numFullLines = 0 + + for i in range(TetrixBoard.BoardHeight - 1, -1, -1): + lineIsFull = True + + for j in range(TetrixBoard.BoardWidth): + if self.shapeAt(j, i) == NoShape: + lineIsFull = False + break + + if lineIsFull: + numFullLines += 1 + for k in range(TetrixBoard.BoardHeight - 1): + for j in range(TetrixBoard.BoardWidth): + self.setShapeAt(j, k, self.shapeAt(j, k + 1)) + + for j in range(TetrixBoard.BoardWidth): + self.setShapeAt(j, TetrixBoard.BoardHeight - 1, NoShape) + + if numFullLines > 0: + self.numLinesRemoved += numFullLines + self.score += 10 * numFullLines + self.linesRemovedChanged.emit(self.numLinesRemoved) + self.scoreChanged.emit(self.score) + + self.timer.start(500, self) + self.isWaitingAfterLine = True + self.curPiece.setShape(NoShape) + self.update() + + def newPiece(self): + self.curPiece = self.nextPiece + self.nextPiece.setRandomShape() + self.showNextPiece() + self.curX = TetrixBoard.BoardWidth // 2 + 1 + self.curY = TetrixBoard.BoardHeight - 1 + self.curPiece.minY() + + if not self.tryMove(self.curPiece, self.curX, self.curY): + self.curPiece.setShape(NoShape) + self.timer.stop() + self.isStarted = False + + def showNextPiece(self): + if self.nextPieceLabel is not None: + return + + dx = self.nextPiece.maxX() - self.nextPiece.minX() + 1 + dy = self.nextPiece.maxY() - self.nextPiece.minY() + 1 + + pixmap = QtGui.QPixmap(dx * self.squareWidth(), dy * self.squareHeight()) + painter = QtGui.QPainter(pixmap) + painter.fillRect(pixmap.rect(), self.nextPieceLabel.palette().background()) + + for int in range(4): + x = self.nextPiece.x(i) - self.nextPiece.minX() + y = self.nextPiece.y(i) - self.nextPiece.minY() + self.drawSquare(painter, x * self.squareWidth(), + y * self.squareHeight(), self.nextPiece.shape()) + + self.nextPieceLabel.setPixmap(pixmap) + + def tryMove(self, newPiece, newX, newY): + for i in range(4): + x = newX + newPiece.x(i) + y = newY - newPiece.y(i) + if x < 0 or x >= TetrixBoard.BoardWidth or y < 0 or y >= TetrixBoard.BoardHeight: + return False + if self.shapeAt(x, y) != NoShape: + return False + + self.curPiece = newPiece + self.curX = newX + self.curY = newY + self.update() + return True + + def drawSquare(self, painter, x, y, shape): + colorTable = [0x000000, 0xCC6666, 0x66CC66, 0x6666CC, + 0xCCCC66, 0xCC66CC, 0x66CCCC, 0xDAAA00] + + color = QtGui.QColor(colorTable[shape]) + painter.fillRect(x + 1, y + 1, self.squareWidth() - 2, + self.squareHeight() - 2, color) + + painter.setPen(color.lighter()) + painter.drawLine(x, y + self.squareHeight() - 1, x, y) + painter.drawLine(x, y, x + self.squareWidth() - 1, y) + + painter.setPen(color.darker()) + painter.drawLine(x + 1, y + self.squareHeight() - 1, + x + self.squareWidth() - 1, y + self.squareHeight() - 1) + painter.drawLine(x + self.squareWidth() - 1, + y + self.squareHeight() - 1, x + self.squareWidth() - 1, y + 1) + + +class TetrixPiece(object): + coordsTable = ( + ((0, 0), (0, 0), (0, 0), (0, 0)), + ((0, -1), (0, 0), (-1, 0), (-1, 1)), + ((0, -1), (0, 0), (1, 0), (1, 1)), + ((0, -1), (0, 0), (0, 1), (0, 2)), + ((-1, 0), (0, 0), (1, 0), (0, 1)), + ((0, 0), (1, 0), (0, 1), (1, 1)), + ((-1, -1), (0, -1), (0, 0), (0, 1)), + ((1, -1), (0, -1), (0, 0), (0, 1)) + ) + + def __init__(self): + self.coords = [[0,0] for _ in range(4)] + self.pieceShape = NoShape + + self.setShape(NoShape) + + def shape(self): + return self.pieceShape + + def setShape(self, shape): + table = TetrixPiece.coordsTable[shape] + for i in range(4): + for j in range(2): + self.coords[i][j] = table[i][j] + + self.pieceShape = shape + + def setRandomShape(self): + self.setShape(random.randint(1, 7)) + + def x(self, index): + return self.coords[index][0] + + def y(self, index): + return self.coords[index][1] + + def setX(self, index, x): + self.coords[index][0] = x + + def setY(self, index, y): + self.coords[index][1] = y + + def minX(self): + m = self.coords[0][0] + for i in range(4): + m = min(m, self.coords[i][0]) + + return m + + def maxX(self): + m = self.coords[0][0] + for i in range(4): + m = max(m, self.coords[i][0]) + + return m + + def minY(self): + m = self.coords[0][1] + for i in range(4): + m = min(m, self.coords[i][1]) + + return m + + def maxY(self): + m = self.coords[0][1] + for i in range(4): + m = max(m, self.coords[i][1]) + + return m + + def rotatedLeft(self): + if self.pieceShape == SquareShape: + return self + + result = TetrixPiece() + result.pieceShape = self.pieceShape + for i in range(4): + result.setX(i, self.y(i)) + result.setY(i, -self.x(i)) + + return result + + def rotatedRight(self): + if self.pieceShape == SquareShape: + return self + + result = TetrixPiece() + result.pieceShape = self.pieceShape + for i in range(4): + result.setX(i, -self.y(i)) + result.setY(i, self.x(i)) + + return result + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + window = TetrixWindow() + window.show() + random.seed(None) + sys.exit(app.exec_()) diff --git a/examples/widgets/widgets/widgets.pyproject b/examples/widgets/widgets/widgets.pyproject new file mode 100644 index 0000000..b4e3ef6 --- /dev/null +++ b/examples/widgets/widgets/widgets.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["tetrix.py", "hellogl_openglwidget_legacy.py"] +} diff --git a/examples/xml/dombookmarks/dombookmarks.py b/examples/xml/dombookmarks/dombookmarks.py new file mode 100644 index 0000000..20ec09e --- /dev/null +++ b/examples/xml/dombookmarks/dombookmarks.py @@ -0,0 +1,262 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +"""PySide2 port of the xml/dombookmarks example from Qt v5.x""" + +from PySide2 import QtCore, QtGui, QtWidgets, QtXml + + +class MainWindow(QtWidgets.QMainWindow): + def __init__(self, parent=None): + super(MainWindow, self).__init__(parent) + + self.xbelTree = XbelTree() + self.setCentralWidget(self.xbelTree) + + self.createActions() + self.createMenus() + + self.statusBar().showMessage("Ready") + + self.setWindowTitle("DOM Bookmarks") + self.resize(480, 320) + + def open(self): + fileName = QtWidgets.QFileDialog.getOpenFileName(self, + "Open Bookmark File", QtCore.QDir.currentPath(), + "XBEL Files (*.xbel *.xml)")[0] + + if not fileName: + return + + inFile = QtCore.QFile(fileName) + if not inFile.open(QtCore.QFile.ReadOnly | QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(self, "DOM Bookmarks", + "Cannot read file %s:\n%s." % (fileName, inFile.errorString())) + return + + if self.xbelTree.read(inFile): + self.statusBar().showMessage("File loaded", 2000) + + def saveAs(self): + fileName = QtWidgets.QFileDialog.getSaveFileName(self, + "Save Bookmark File", QtCore.QDir.currentPath(), + "XBEL Files (*.xbel *.xml)")[0] + + if not fileName: + return + + outFile = QtCore.QFile(fileName) + if not outFile.open(QtCore.QFile.WriteOnly | QtCore.QFile.Text): + QtWidgets.QMessageBox.warning(self, "DOM Bookmarks", + "Cannot write file %s:\n%s." % (fileName, outFile.errorString())) + return + + if self.xbelTree.write(outFile): + self.statusBar().showMessage("File saved", 2000) + + def about(self): + QtWidgets.QMessageBox.about(self, "About DOM Bookmarks", + "The DOM Bookmarks example demonstrates how to use Qt's " + "DOM classes to read and write XML documents.") + + def createActions(self): + self.openAct = QtWidgets.QAction("&Open...", self, shortcut="Ctrl+O", + triggered=self.open) + + self.saveAsAct = QtWidgets.QAction("&Save As...", self, shortcut="Ctrl+S", + triggered=self.saveAs) + + self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q", + triggered=self.close) + + self.aboutAct = QtWidgets.QAction("&About", self, triggered=self.about) + + self.aboutQtAct = QtWidgets.QAction("About &Qt", self, + triggered=qApp.aboutQt) + + def createMenus(self): + self.fileMenu = self.menuBar().addMenu("&File") + self.fileMenu.addAction(self.openAct) + self.fileMenu.addAction(self.saveAsAct) + self.fileMenu.addAction(self.exitAct) + + self.menuBar().addSeparator() + + self.helpMenu = self.menuBar().addMenu("&Help") + self.helpMenu.addAction(self.aboutAct) + self.helpMenu.addAction(self.aboutQtAct) + + +class XbelTree(QtWidgets.QTreeWidget): + def __init__(self, parent=None): + super(XbelTree, self).__init__(parent) + + self.header().setSectionResizeMode(QtWidgets.QHeaderView.Stretch) + self.setHeaderLabels(("Title", "Location")) + + self.domDocument = QtXml.QDomDocument() + + self.domElementForItem = {} + + self.folderIcon = QtGui.QIcon() + self.bookmarkIcon = QtGui.QIcon() + + self.folderIcon.addPixmap(self.style().standardPixmap(QtWidgets.QStyle.SP_DirClosedIcon), + QtGui.QIcon.Normal, QtGui.QIcon.Off) + self.folderIcon.addPixmap(self.style().standardPixmap(QtWidgets.QStyle.SP_DirOpenIcon), + QtGui.QIcon.Normal, QtGui.QIcon.On) + self.bookmarkIcon.addPixmap(self.style().standardPixmap(QtWidgets.QStyle.SP_FileIcon)) + + def read(self, device): + ok, errorStr, errorLine, errorColumn = self.domDocument.setContent(device, True) + if not ok: + QtWidgets.QMessageBox.information(self.window(), "DOM Bookmarks", + "Parse error at line %d, column %d:\n%s" % (errorLine, errorColumn, errorStr)) + return False + + root = self.domDocument.documentElement() + if root.tagName() != 'xbel': + QtWidgets.QMessageBox.information(self.window(), "DOM Bookmarks", + "The file is not an XBEL file.") + return False + elif root.hasAttribute('version') and root.attribute('version') != '1.0': + QtWidgets.QMessageBox.information(self.window(), "DOM Bookmarks", + "The file is not an XBEL version 1.0 file.") + return False + + self.clear() + + # It might not be connected. + try: + self.itemChanged.disconnect(self.updateDomElement) + except: + pass + + child = root.firstChildElement('folder') + while not child.isNull(): + self.parseFolderElement(child) + child = child.nextSiblingElement('folder') + + self.itemChanged.connect(self.updateDomElement) + + return True + + def write(self, device): + indentSize = 4 + + out = QtCore.QTextStream(device) + self.domDocument.save(out, indentSize) + return True + + def updateDomElement(self, item, column): + element = self.domElementForItem.get(id(item)) + if not element.isNull(): + if column == 0: + oldTitleElement = element.firstChildElement('title') + newTitleElement = self.domDocument.createElement('title') + + newTitleText = self.domDocument.createTextNode(item.text(0)) + newTitleElement.appendChild(newTitleText) + + element.replaceChild(newTitleElement, oldTitleElement) + else: + if element.tagName() == 'bookmark': + element.setAttribute('href', item.text(1)) + + def parseFolderElement(self, element, parentItem=None): + item = self.createItem(element, parentItem) + + title = element.firstChildElement('title').text() + if not title: + title = "Folder" + + item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) + item.setIcon(0, self.folderIcon) + item.setText(0, title) + + folded = (element.attribute('folded') != 'no') + self.setItemExpanded(item, not folded) + + child = element.firstChildElement() + while not child.isNull(): + if child.tagName() == 'folder': + self.parseFolderElement(child, item) + elif child.tagName() == 'bookmark': + childItem = self.createItem(child, item) + + title = child.firstChildElement('title').text() + if not title: + title = "Folder" + + childItem.setFlags(item.flags() | QtCore.Qt.ItemIsEditable) + childItem.setIcon(0, self.bookmarkIcon) + childItem.setText(0, title) + childItem.setText(1, child.attribute('href')) + elif child.tagName() == 'separator': + childItem = self.createItem(child, item) + childItem.setFlags(item.flags() & ~(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable)) + childItem.setText(0, 30 * "\xb7") + + child = child.nextSiblingElement() + + def createItem(self, element, parentItem=None): + item = QtWidgets.QTreeWidgetItem() + + if parentItem is not None: + item = QtWidgets.QTreeWidgetItem(parentItem) + else: + item = QtWidgets.QTreeWidgetItem(self) + + self.domElementForItem[id(item)] = element + return item + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + mainWin = MainWindow() + mainWin.show() + mainWin.open() + sys.exit(app.exec_()) diff --git a/examples/xml/dombookmarks/dombookmarks.pyproject b/examples/xml/dombookmarks/dombookmarks.pyproject new file mode 100644 index 0000000..9a68855 --- /dev/null +++ b/examples/xml/dombookmarks/dombookmarks.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["jennifer.xbel", "frank.xbel", "dombookmarks.py"] +} diff --git a/examples/xml/dombookmarks/frank.xbel b/examples/xml/dombookmarks/frank.xbel new file mode 100644 index 0000000..f498a5e --- /dev/null +++ b/examples/xml/dombookmarks/frank.xbel @@ -0,0 +1,230 @@ + + + + + Literate Programming + + Synopsis of Literate Programming + + + Literate Programming: Propaganda and Tools + + + Literate Programming by Henrik Turbell + + + Literate Programming Library + + + Literate Programming Basics + + + Literate Programming Overview + + + POD is not Literate Programming + + + Computers That We Can Count On + + + Literate Programming - Issues and Problems + + + Literate Programming - Wiki Pages + + + What is well-commented code? + + + Bibliography on literate programming - A searchable bibliography + + + Program comprehension and code reading bibliography + + + Elucidative Programming + + + AVL Trees (TexiWeb) + + + Literate Programming on Wikiverse + + + Physically Based Rendering: From Theory to Implementation + + + + Useful C++ Links + + STL + + STL Reference Documentation + + + STL Tutorial + + + STL Reference + + + + Qt + + Qt 2.3 Reference + + + Qt 3.3 Reference + + + Qt 4.0 Reference + + + Trolltech Home Page + + + + IOStreams + + IO Stream Library + + + Binary I/O + + + I/O Stream FAQ + + + + gdb + + GDB Tutorial + + + Debugging with GDB + + + GDB Quick Reference Page (PDF) (Handy) + + + + Classes and Constructors + + Constructor FAQ + + + Organizing Classes + + + + + Software Documentation or System Documentation + + The Almighty Thud + + + Microsoft Coding Techniques and Programming Practices + + + Software and Documentation + + + The Source Code is the Design + + + What is Software Design? + + + How To Write Unmaintainable Code + + + Self Documenting Program Code Remains a Distant Goal + + + Place Tab A in Slot B + + + UML Reference Card + + + + TeX Resources + + The TeX User's Group + + + MikTeX website + + + MetaPost website + + + HEVEA is a quite complete and fast LATEX to HTML translator + + + + Portable Document Format (PDF) + + Adobe - The postscript and PDF standards + + + Reference Manual Portable Document Format + + + Adobe Acrobat Software Development Kit + + + + Literature Sites + + Guide to Special Collections (Columbia University) + + + Literary Criticism on the Web from the Internet Public Library + + + Victorian Web. + + + Voice of the Shuttle. + + + Modernist Journals Project + + + Museum of American Poetics + + + Modern American Poetry + + + FindArticles.com + + + Literary History + + + Literary Encyclopedia + + + + The University of California Press + + + Wright American Fiction, 1851-1875 + + + Documenting the American South: Beginnings to 1920 + + + Electronic Text Center at the University of Virginia + + + The Schomburg Center for Research in Black Culture + + + Alex Catalog of Electronic Texts. + + + diff --git a/examples/xml/dombookmarks/jennifer.xbel b/examples/xml/dombookmarks/jennifer.xbel new file mode 100644 index 0000000..1f7810b --- /dev/null +++ b/examples/xml/dombookmarks/jennifer.xbel @@ -0,0 +1,93 @@ + + + + + Qt Resources + + Trolltech Partners + + Training Partners + + + Consultants and System Integrators + + + Technology Partners + + + Value Added Resellers (VARs) + + + + Community Resources + + QtForum.org + + + The Independent Qt Tutorial + + + French PROG.Qt + + + German Qt Forum + + + Korean Qt Community Site + + + Russian Qt Forum + + + Digitalfanatics: The QT 4 Resource Center + + + QtQuestions + + + + Qt Quarterly + + + Trolltech's home page + + + Qt 4.0 documentation + + + Frequently Asked Questions + + + + Online Dictionaries + + Dictionary.com + + + Merriam-Webster Online + + + Cambridge Dictionaries Online + + + OneLook Dictionary Search + + + + The New English-German Dictionary + + + TU Chemnitz German-English Dictionary + + + + Trésor de la Langue Française informatisé + + + Dictionnaire de l'Académie Française + + + Dictionnaire des synonymes + + + diff --git a/examples/xmlpatterns/schema/files/contact.xsd b/examples/xmlpatterns/schema/files/contact.xsd new file mode 100644 index 0000000..3e1b570 --- /dev/null +++ b/examples/xmlpatterns/schema/files/contact.xsd @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/invalid_contact.xml b/examples/xmlpatterns/schema/files/invalid_contact.xml new file mode 100644 index 0000000..42f1edd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + Prof. + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/invalid_order.xml b/examples/xmlpatterns/schema/files/invalid_order.xml new file mode 100644 index 0000000..8ffc5fd --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_order.xml @@ -0,0 +1,13 @@ + + 234219 +
+ 21692 + 3 +
+
+ 24749 + 9 +
+ 2009-01-23 + yes +
diff --git a/examples/xmlpatterns/schema/files/invalid_recipe.xml b/examples/xmlpatterns/schema/files/invalid_recipe.xml new file mode 100644 index 0000000..4d75af6 --- /dev/null +++ b/examples/xmlpatterns/schema/files/invalid_recipe.xml @@ -0,0 +1,14 @@ + + Cheese on Toast + + + diff --git a/examples/xmlpatterns/schema/files/order.xsd b/examples/xmlpatterns/schema/files/order.xsd new file mode 100644 index 0000000..405cafe --- /dev/null +++ b/examples/xmlpatterns/schema/files/order.xsd @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/recipe.xsd b/examples/xmlpatterns/schema/files/recipe.xsd new file mode 100644 index 0000000..bbbafd9 --- /dev/null +++ b/examples/xmlpatterns/schema/files/recipe.xsd @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/files/valid_contact.xml b/examples/xmlpatterns/schema/files/valid_contact.xml new file mode 100644 index 0000000..53c04d4 --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_contact.xml @@ -0,0 +1,11 @@ + + John + Doe + 1977-12-25 + + Sandakerveien 116 + N-0550 + Oslo + Norway + + diff --git a/examples/xmlpatterns/schema/files/valid_order.xml b/examples/xmlpatterns/schema/files/valid_order.xml new file mode 100644 index 0000000..f83c36c --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_order.xml @@ -0,0 +1,18 @@ + + 194223 +
+ 22242 + 5 +
+
+ 32372 + 12 + without stripes +
+
+ 23649 + 2 +
+ 2009-01-23 + true +
diff --git a/examples/xmlpatterns/schema/files/valid_recipe.xml b/examples/xmlpatterns/schema/files/valid_recipe.xml new file mode 100644 index 0000000..f6499ba --- /dev/null +++ b/examples/xmlpatterns/schema/files/valid_recipe.xml @@ -0,0 +1,13 @@ + + Cheese on Toast + + + diff --git a/examples/xmlpatterns/schema/schema.py b/examples/xmlpatterns/schema/schema.py new file mode 100644 index 0000000..d3c22c1 --- /dev/null +++ b/examples/xmlpatterns/schema/schema.py @@ -0,0 +1,286 @@ + +############################################################################# +## +## Copyright (C) 2013 Riverbank Computing Limited. +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2 import QtCore, QtGui, QtWidgets, QtXmlPatterns + +import schema_rc +from ui_schema import Ui_SchemaMainWindow + + +try: + # Python v2. + unicode + + def encode_utf8(ba): + return unicode(ba, encoding='utf8') + + def decode_utf8(qs): + return QtCore.QByteArray(str(qs)) + +except NameError: + # Python v3. + + def encode_utf8(ba): + return str(ba.data(), encoding='utf8') + + def decode_utf8(qs): + return QtCore.QByteArray(bytes(qs, encoding='utf8')) + + +class XmlSyntaxHighlighter(QtGui.QSyntaxHighlighter): + + def __init__(self, parent=None): + super(XmlSyntaxHighlighter, self).__init__(parent) + + self.highlightingRules = [] + + # Tag format. + format = QtGui.QTextCharFormat() + format.setForeground(QtCore.Qt.darkBlue) + format.setFontWeight(QtGui.QFont.Bold) + pattern = QtCore.QRegularExpression(r'(<[a-zA-Z:]+\b|<\?[a-zA-Z:]+\b|\?>|>|/>|)') + assert pattern.isValid() + self.highlightingRules.append((pattern, format)) + + # Attribute format. + format = QtGui.QTextCharFormat() + format.setForeground(QtCore.Qt.darkGreen) + pattern = QtCore.QRegularExpression('[a-zA-Z:]+=') + assert pattern.isValid() + self.highlightingRules.append((pattern, format)) + + # Attribute content format. + format = QtGui.QTextCharFormat() + format.setForeground(QtCore.Qt.red) + pattern = QtCore.QRegularExpression("(\"[^\"]*\"|'[^']*')") + assert pattern.isValid() + self.highlightingRules.append((pattern, format)) + + # Comment format. + self.commentFormat = QtGui.QTextCharFormat() + self.commentFormat.setForeground(QtCore.Qt.lightGray) + self.commentFormat.setFontItalic(True) + + self.commentStartExpression = QtCore.QRegularExpression("") + assert self.commentEndExpression.isValid() + + def highlightBlock(self, text): + for pattern, format in self.highlightingRules: + match = pattern.match(text) + while match.hasMatch(): + index = match.capturedStart() + length = match.capturedLength(0) + self.setFormat(index, length, format) + match = pattern.match(text, index + length) + + self.setCurrentBlockState(0) + + startIndex = 0 + if self.previousBlockState() != 1: + match = self.commentStartExpression.match(text) + startIndex = match.capturedStart(0) if match.hasMatch() else -1 + + while startIndex >= 0: + match = self.commentEndExpression.match(text, startIndex) + endIndex = match.capturedStart(0) if match.hasMatch() else -1 + if match.hasMatch(): + endIndex = match.capturedStart(0) + length = match.capturedLength(0) + commentLength = endIndex - startIndex + length + else: + self.setCurrentBlockState(1) + commentLength = text.length() - startIndex + + self.setFormat(startIndex, commentLength, self.commentFormat) + match = self.commentStartExpression.match(text, startIndex + commentLength) + startIndex = match.capturedStart(0) if match.hasMatch() else -1 + + +class MessageHandler(QtXmlPatterns.QAbstractMessageHandler): + + def __init__(self): + super(MessageHandler, self).__init__() + + self.m_description = "" + self.m_sourceLocation = QtXmlPatterns.QSourceLocation() + + def statusMessage(self): + return self.m_description + + def line(self): + return self.m_sourceLocation.line() + + def column(self): + return self.m_sourceLocation.column() + + def handleMessage(self, type, description, identifier, sourceLocation): + self.m_description = description + self.m_sourceLocation = sourceLocation + + +class MainWindow(QtWidgets.QMainWindow, Ui_SchemaMainWindow): + + def __init__(self): + QtWidgets.QMainWindow.__init__(self) + + self.setupUi(self) + + XmlSyntaxHighlighter(self.schemaView.document()) + XmlSyntaxHighlighter(self.instanceEdit.document()) + + self.schemaSelection.addItem("Contact Schema") + self.schemaSelection.addItem("Recipe Schema") + self.schemaSelection.addItem("Order Schema") + + self.instanceSelection.addItem("Valid Contact Instance") + self.instanceSelection.addItem("Invalid Contact Instance") + + self.schemaSelection.currentIndexChanged[int].connect(self.schemaSelected) + self.instanceSelection.currentIndexChanged[int].connect(self.instanceSelected) + self.validateButton.clicked.connect(self.validate) + self.instanceEdit.textChanged.connect(self.textChanged) + + self.validationStatus.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter) + + self.schemaSelected(0) + self.instanceSelected(0) + + def schemaSelected(self, index): + self.instanceSelection.clear() + + if index == 0: + self.instanceSelection.addItem("Valid Contact Instance") + self.instanceSelection.addItem("Invalid Contact Instance") + elif index == 1: + self.instanceSelection.addItem("Valid Recipe Instance") + self.instanceSelection.addItem("Invalid Recipe Instance") + elif index == 2: + self.instanceSelection.addItem("Valid Order Instance") + self.instanceSelection.addItem("Invalid Order Instance") + + self.textChanged() + + schemaFile = QtCore.QFile(':/schema_%d.xsd' % index) + schemaFile.open(QtCore.QIODevice.ReadOnly) + schemaData = schemaFile.readAll() + self.schemaView.setPlainText(encode_utf8(schemaData)) + + self.validate() + + def instanceSelected(self, index): + if index == -1: + return + + index += 2 * self.schemaSelection.currentIndex() + instanceFile = QtCore.QFile(':/instance_%d.xml' % index) + instanceFile.open(QtCore.QIODevice.ReadOnly) + instanceData = instanceFile.readAll() + self.instanceEdit.setPlainText(encode_utf8(instanceData)) + + self.validate() + + def validate(self): + schemaData = decode_utf8(self.schemaView.toPlainText()) + instanceData = decode_utf8(self.instanceEdit.toPlainText()) + + messageHandler = MessageHandler() + + schema = QtXmlPatterns.QXmlSchema() + schema.setMessageHandler(messageHandler) + schema.load(schemaData, QtCore.QUrl()) + + errorOccurred = False + if not schema.isValid(): + errorOccurred = True + else: + validator = QtXmlPatterns.QXmlSchemaValidator(schema) + if not validator.validate(instanceData): + errorOccurred = True + + if errorOccurred: + self.validationStatus.setText(messageHandler.statusMessage()) + self.moveCursor(messageHandler.line(), messageHandler.column()) + background = QtCore.Qt.red + else: + self.validationStatus.setText("validation successful") + background = QtCore.Qt.green + + styleSheet = 'QLabel {background: %s; padding: 3px}' % QtGui.QColor(background).lighter(160).name() + self.validationStatus.setStyleSheet(styleSheet) + + def textChanged(self): + self.instanceEdit.setExtraSelections([]) + + def moveCursor(self, line, column): + self.instanceEdit.moveCursor(QtGui.QTextCursor.Start) + + for i in range(1, line): + self.instanceEdit.moveCursor(QtGui.QTextCursor.Down) + + for i in range(1, column): + self.instanceEdit.moveCursor(QtGui.QTextCursor.Right) + + extraSelections = [] + selection = QtWidgets.QTextEdit.ExtraSelection() + + lineColor = QtGui.QColor(QtCore.Qt.red).lighter(160) + selection.format.setBackground(lineColor) + selection.format.setProperty(QtGui.QTextFormat.FullWidthSelection, True) + selection.cursor = self.instanceEdit.textCursor() + selection.cursor.clearSelection() + extraSelections.append(selection) + + self.instanceEdit.setExtraSelections(extraSelections) + + self.instanceEdit.setFocus() + + +if __name__ == '__main__': + + import sys + + app = QtWidgets.QApplication(sys.argv) + window = MainWindow() + window.show() + sys.exit(app.exec_()) diff --git a/examples/xmlpatterns/schema/schema.pyproject b/examples/xmlpatterns/schema/schema.pyproject new file mode 100644 index 0000000..697e58d --- /dev/null +++ b/examples/xmlpatterns/schema/schema.pyproject @@ -0,0 +1,4 @@ +{ + "files": ["schema.qrc", "schema.py", "schema.ui", "ui_schema.py", + "schema_rc.py"] +} diff --git a/examples/xmlpatterns/schema/schema.qrc b/examples/xmlpatterns/schema/schema.qrc new file mode 100644 index 0000000..eb7ddfd --- /dev/null +++ b/examples/xmlpatterns/schema/schema.qrc @@ -0,0 +1,13 @@ + + + files/contact.xsd + files/recipe.xsd + files/order.xsd + files/valid_contact.xml + files/invalid_contact.xml + files/valid_recipe.xml + files/invalid_recipe.xml + files/valid_order.xml + files/invalid_order.xml + + diff --git a/examples/xmlpatterns/schema/schema.ui b/examples/xmlpatterns/schema/schema.ui new file mode 100644 index 0000000..b67f444 --- /dev/null +++ b/examples/xmlpatterns/schema/schema.ui @@ -0,0 +1,71 @@ + + + SchemaMainWindow + + + + 0 + 0 + 417 + 594 + + + + XML Schema Validation + + + + + + + XML Schema Document: + + + + + + + + + + + + + XML Instance Document: + + + + + + + + + + + + + Status: + + + + + + + not validated + + + + + + + Validate + + + + + + + + + + diff --git a/examples/xmlpatterns/schema/schema_rc.py b/examples/xmlpatterns/schema/schema_rc.py new file mode 100644 index 0000000..0c607af --- /dev/null +++ b/examples/xmlpatterns/schema/schema_rc.py @@ -0,0 +1,394 @@ +# Resource object code (Python 3) +# Created by: object code +# Created by: The Resource Compiler for Qt version 5.14.0 +# WARNING! All changes made in this file will be lost! + +from PySide2 import QtCore + +qt_resource_data = b"\ +\x00\x00\x01\x81\ +\x00\ +\x00\x06\x05x\x9c\xbdT\xc1r\xc2 \x10\xbd\xfb\x15\x0c\ +\x1f`\xb4\xbd9F\xcf\x9di\xa7\x87\xf6\xd0+\x92\x1d\ +\xc3L\x80\x08\x8b\x89\x7f_\x82\x1am\x0cI\xbc\x94C\ +&\xc3\xbe\xf7\xd8]\x1e\xbb\xde\xd6\xb2 G0Vh\ +\x95\xd2\xe5|A\xb7\x9b\xd9\xba\xb6\xd9\xca\xf2\x1c$#\ +>\xae\xec\xcao\xa44G,WIRU\xd5\xbcz\ +\x9dk\xb3O^\x16\x8be\xf2\xf3\xf1\xfe\x15\xb0t3\ +\x9b\x11\xbf\x02\x1d\x0a\x90\xa0\x90(&!\xa5\x06\xb8(\ +\xc1\x03\xc8e\x05\x0c\xd7\xb2,\xa0\xfe>\x95p\x8b\xb4\ +Q\x0b\x07\x07\x8awB\x91\x03P`\x01\x94\xa0\x97J\ +i`\xa3\x11jO\x93Il\x8f4\x90\x09\xbfq\x95\ +\xb8\xed4\xd9Q\x22Y\xfd\xc9\xb936\xa5N\xed\xb4\ +S\x19d\x13\xc5Q\xc86\xb3\xe6?\x08N\xa3J\xc0\ +\x5cg\xf4\x11;\xde\xc2'\xda9\x92\x84E({:\ +;\xb9%\xadt2\x9e\xc6\x193X\xd4\x19rI\xb1\ +c\x9b\xc8\x09\x11\xd5\x8e\xd2\xcd\xbbw\xc8\x07\x83\x84\xdb\ +\xeb\xf8\x98\xa1o\xc9\xce\xe1\x15\xdd|\x87\xbd\xd8K;\ +8\xa6\xbc\x8fO\xf7\xd4R[\x81\xe2\x08o\x0aa\x0f\ +fT\xc3)\x81\xf1\xa3{\x1a1Tu\xeb\xd6\xffJ\ +\xbco\x0a\x88&\xab\x88\x15\x1a\x80\x81\xa6F\x8e~\x80\ +\x91\x1d\xb3\x7f\xeb\x1ex9\xa0\x9c\x04\xc3\x02\xef\xc8\x0a\ +\xd78\x1d\xb8V\x99\x8d\x998F\x93B\xf9:\x9e\xa6\ +\xe5\xda\xbf\x9d\xdeA\x90t\xea\xeauyO_\xce\x91\ +\xb6\xb3\xf1;\xbfH\x84\xa9\xbd\x99\xfd\x02,\xd8\xc0\x1d\ +\ +\x00\x00\x02U\ +<\ +recipe>\x0a Cheese on Toa\ +st\x0a <\ +ingredient name=\ +\x22Bread\x22 quantity\ +=\x222\x22 unit=\x22slice\ +s\x22/>\x0a \x0a\ +
\x0a Tell your fr\ +iends about it!<\ +/comment>\x0a\x0a\ +\x00\x00\x03\xbb\ +<\ +?xml version=\x221.\ +0\x22?>\x0a\x0a\x0a\ + \ +\x0a \x0a \ + \x0a \ + \x0a \ + \x0a \ + \x0a \ + \x0a \ + \x0a \ + \x0a
\x0a\ + \x0a\x0a \x0a \ + \x0a\ + \x0a \ + \x0a \ + \x0a\ + \x0a \ + \x0a \x0a\x0a\x0a\ +\x00\x00\x02%\ +<\ +recipe>\x0a Cheese on Toa\ +st\x0a <\ +ingredient name=\ +\x22Bread\x22 quantity\ +=\x222\x22 unit=\x22slice\ +s\x22/>\x0a \x0a\ + \x0a\ + \x0a\x0a\x0a\ +\x00\x00\x01\xb6\ +<\ +order>\x0a 194223\x0a <\ +article>\x0a \ + 2224\ +2\x0a \ + 5\x0a \x0a \x0a 32372\x0a \ + 12\x0a without stri\ +pes\x0a \ + \x0a \ +
\x0a \ + 23\ +649\x0a\ + 2\ +\x0a \x0a 2009-0\ +1-23\x0a t\ +rue\x0a\x0a\ +" + +qt_resource_name = b"\ +\x00\x0c\ +\x08\x13\x87\xf4\ +\x00s\ +\x00c\x00h\x00e\x00m\x00a\x00_\x001\x00.\x00x\x00s\x00d\ +\x00\x0e\ +\x00sJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x003\x00.\x00x\x00m\x00l\ +\x00\x0c\ +\x08\x10\x87\xf4\ +\x00s\ +\x00c\x00h\x00e\x00m\x00a\x00_\x000\x00.\x00x\x00s\x00d\ +\x00\x0e\ +\x00pJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x002\x00.\x00x\x00m\x00l\ +\x00\x0e\ +\x00yJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x001\x00.\x00x\x00m\x00l\ +\x00\x0e\ +\x00uJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x005\x00.\x00x\x00m\x00l\ +\x00\x0e\ +\x00vJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x000\x00.\x00x\x00m\x00l\ +\x00\x0c\ +\x08\x16\x87\xf4\ +\x00s\ +\x00c\x00h\x00e\x00m\x00a\x00_\x002\x00.\x00x\x00s\x00d\ +\x00\x0e\ +\x00rJ\x1c\ +\x00i\ +\x00n\x00s\x00t\x00a\x00n\x00c\x00e\x00_\x004\x00.\x00x\x00m\x00l\ +" + +qt_resource_struct = b"\ +\x00\x00\x00\x00\x00\x02\x00\x00\x00\x09\x00\x00\x00\x01\ +\x00\x00\x00\x00\x00\x00\x00\x00\ +\x00\x00\x00^\x00\x00\x00\x00\x00\x01\x00\x00\x07\x9d\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x01\x04\x00\x00\x00\x00\x00\x01\x00\x00\x10\xb2\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x01\x85\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\xa2\x00\x00\x00\x00\x00\x01\x00\x00\x0a\xe7\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x19\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\x80\x00\x00\x00\x00\x00\x01\x00\x00\x09\xc6\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00@\x00\x00\x00\x00\x00\x01\x00\x00\x03\xde\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +\x00\x00\x00\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x0dG\ +\x00\x00\x01e\xaf\x16\xd2\xa1\ +" + +def qInitResources(): + QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +def qCleanupResources(): + QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data) + +qInitResources() diff --git a/examples/xmlpatterns/schema/ui_schema.py b/examples/xmlpatterns/schema/ui_schema.py new file mode 100644 index 0000000..f9cc751 --- /dev/null +++ b/examples/xmlpatterns/schema/ui_schema.py @@ -0,0 +1,88 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'schema.ui' +## +## Created by: Qt User Interface Compiler version 5.14.0 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint, + QRect, QSize, QUrl, Qt) +from PySide2.QtGui import (QColor, QFont, QIcon, QPixmap) +from PySide2.QtWidgets import * + +class Ui_SchemaMainWindow(object): + def setupUi(self, SchemaMainWindow): + if SchemaMainWindow.objectName(): + SchemaMainWindow.setObjectName(u"SchemaMainWindow") + SchemaMainWindow.resize(417, 594) + self.centralwidget = QWidget(SchemaMainWindow) + self.centralwidget.setObjectName(u"centralwidget") + self.gridLayout = QGridLayout(self.centralwidget) + self.gridLayout.setObjectName(u"gridLayout") + self.schemaLabel = QLabel(self.centralwidget) + self.schemaLabel.setObjectName(u"schemaLabel") + + self.gridLayout.addWidget(self.schemaLabel, 0, 0, 1, 2) + + self.schemaSelection = QComboBox(self.centralwidget) + self.schemaSelection.setObjectName(u"schemaSelection") + + self.gridLayout.addWidget(self.schemaSelection, 0, 2, 1, 2) + + self.schemaView = QTextBrowser(self.centralwidget) + self.schemaView.setObjectName(u"schemaView") + + self.gridLayout.addWidget(self.schemaView, 1, 0, 1, 4) + + self.instanceLabel = QLabel(self.centralwidget) + self.instanceLabel.setObjectName(u"instanceLabel") + + self.gridLayout.addWidget(self.instanceLabel, 2, 0, 1, 2) + + self.instanceSelection = QComboBox(self.centralwidget) + self.instanceSelection.setObjectName(u"instanceSelection") + + self.gridLayout.addWidget(self.instanceSelection, 2, 2, 1, 2) + + self.instanceEdit = QTextEdit(self.centralwidget) + self.instanceEdit.setObjectName(u"instanceEdit") + + self.gridLayout.addWidget(self.instanceEdit, 3, 0, 1, 4) + + self.label = QLabel(self.centralwidget) + self.label.setObjectName(u"label") + + self.gridLayout.addWidget(self.label, 4, 0, 1, 1) + + self.validationStatus = QLabel(self.centralwidget) + self.validationStatus.setObjectName(u"validationStatus") + + self.gridLayout.addWidget(self.validationStatus, 4, 1, 1, 2) + + self.validateButton = QPushButton(self.centralwidget) + self.validateButton.setObjectName(u"validateButton") + + self.gridLayout.addWidget(self.validateButton, 4, 3, 1, 1) + + SchemaMainWindow.setCentralWidget(self.centralwidget) + self.statusbar = QStatusBar(SchemaMainWindow) + self.statusbar.setObjectName(u"statusbar") + SchemaMainWindow.setStatusBar(self.statusbar) + + self.retranslateUi(SchemaMainWindow) + + QMetaObject.connectSlotsByName(SchemaMainWindow) + # setupUi + + def retranslateUi(self, SchemaMainWindow): + SchemaMainWindow.setWindowTitle(QCoreApplication.translate("SchemaMainWindow", u"XML Schema Validation", None)) + self.schemaLabel.setText(QCoreApplication.translate("SchemaMainWindow", u"XML Schema Document:", None)) + self.instanceLabel.setText(QCoreApplication.translate("SchemaMainWindow", u"XML Instance Document:", None)) + self.label.setText(QCoreApplication.translate("SchemaMainWindow", u"Status:", None)) + self.validationStatus.setText(QCoreApplication.translate("SchemaMainWindow", u"not validated", None)) + self.validateButton.setText(QCoreApplication.translate("SchemaMainWindow", u"Validate", None)) + # retranslateUi + diff --git a/ez_setup.py b/ez_setup.py new file mode 100644 index 0000000..eb37479 --- /dev/null +++ b/ez_setup.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +""" +Bootstrap setuptools installation + +To use setuptools in your package's setup.py, include this +file in the same directory and add this to the top of your setup.py:: + + from ez_setup import use_setuptools + use_setuptools() + +To require a specific version of setuptools, set a download +mirror, or use an alternate download directory, simply supply +the appropriate options to ``use_setuptools()``. + +This file can also be run as a script to install or upgrade setuptools. +""" +import os +import shutil +import sys +import tempfile +import zipfile +import optparse +import subprocess +import platform +import textwrap +import contextlib + +from distutils import log + +try: + from urllib.request import urlopen +except ImportError: + from urllib2 import urlopen + +try: + from site import USER_SITE +except ImportError: + USER_SITE = None + +DEFAULT_VERSION = "7.0" +DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" + +def _python_cmd(*args): + """ + Return True if the command succeeded. + """ + args = (sys.executable,) + args + return subprocess.call(args) == 0 + + +def _install(archive_filename, install_args=()): + with archive_context(archive_filename): + # installing + log.warn('Installing Setuptools') + if not _python_cmd('setup.py', 'install', *install_args): + log.warn('Something went wrong during the installation.') + log.warn('See the error message above.') + # exitcode will be 2 + return 2 + + +def _build_egg(egg, archive_filename, to_dir): + with archive_context(archive_filename): + # building an egg + log.warn('Building a Setuptools egg in {}'.format(to_dir)) + _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) + # returning the result + log.warn(egg) + if not os.path.exists(egg): + raise IOError('Could not build the egg.') + + +class ContextualZipFile(zipfile.ZipFile): + """ + Supplement ZipFile class to support context manager for Python 2.6 + """ + + def __enter__(self): + return self + + def __exit__(self, type, value, traceback): + self.close() + + def __new__(cls, *args, **kwargs): + """ + Construct a ZipFile or ContextualZipFile as appropriate + """ + if hasattr(zipfile.ZipFile, '__exit__'): + return zipfile.ZipFile(*args, **kwargs) + return super(ContextualZipFile, cls).__new__(cls) + + +@contextlib.contextmanager +def archive_context(filename): + # extracting the archive + tmpdir = tempfile.mkdtemp() + log.warn('Extracting in {}'.format(tmpdir)) + old_wd = os.getcwd() + try: + os.chdir(tmpdir) + with ContextualZipFile(filename) as archive: + archive.extractall() + + # going in the directory + subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) + os.chdir(subdir) + log.warn('Now working in {}'.format(subdir)) + yield + + finally: + os.chdir(old_wd) + shutil.rmtree(tmpdir) + + +def _do_download(version, download_base, to_dir, download_delay): + egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' + % (version, sys.version_info[0], sys.version_info[1])) + if not os.path.exists(egg): + archive = download_setuptools(version, download_base, + to_dir, download_delay) + _build_egg(egg, archive, to_dir) + sys.path.insert(0, egg) + + # Remove previously-imported pkg_resources if present (see + # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). + if 'pkg_resources' in sys.modules: + del sys.modules['pkg_resources'] + + import setuptools + setuptools.bootstrap_install_from = egg + + +def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, + to_dir=os.curdir, download_delay=15): + to_dir = os.path.abspath(to_dir) + rep_modules = 'pkg_resources', 'setuptools' + imported = set(sys.modules).intersection(rep_modules) + try: + import pkg_resources + except ImportError: + return _do_download(version, download_base, to_dir, download_delay) + try: + pkg_resources.require("setuptools>=" + version) + return + except pkg_resources.DistributionNotFound: + return _do_download(version, download_base, to_dir, download_delay) + except pkg_resources.VersionConflict as VC_err: + if imported: + msg = textwrap.dedent(""" + The required version of setuptools (>={version}) is not + available, and can't be installed while this script is running. + Please install a more recent version first, using + 'easy_install -U setuptools'. + + (Currently using {VC_err.args[0]!r}) + """).format(VC_err=VC_err, version=version) + sys.stderr.write(msg) + sys.exit(2) + + # otherwise, reload ok + del pkg_resources, sys.modules['pkg_resources'] + return _do_download(version, download_base, to_dir, download_delay) + +def _clean_check(cmd, target): + """ + Run the command to download target. + If the command fails, clean up before re-raising the error. + """ + try: + subprocess.check_call(cmd) + except subprocess.CalledProcessError: + if os.access(target, os.F_OK): + os.unlink(target) + raise + +def download_file_powershell(url, target): + """ + Download the file at url to target using Powershell + (which will validate trust). + Raise an exception if the command cannot complete. + """ + target = os.path.abspath(target) + ps_cmd = ( + "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " + "[System.Net.CredentialCache]::DefaultCredentials; " + "(new-object System.Net.WebClient).DownloadFile({}, {})".format( + url, target)) +# ) + cmd = [ + 'powershell', + '-Command', + ps_cmd, + ] + _clean_check(cmd, target) + +def has_powershell(): + if platform.system() != 'Windows': + return False + cmd = ['powershell', '-Command', 'echo test'] + with open(os.path.devnull, 'wb') as devnull: + try: + subprocess.check_call(cmd, stdout=devnull, stderr=devnull) + except Exception: + return False + return True + +download_file_powershell.viable = has_powershell + +def download_file_curl(url, target): + cmd = ['curl', url, '--silent', '--output', target] + _clean_check(cmd, target) + +def has_curl(): + cmd = ['curl', '--version'] + with open(os.path.devnull, 'wb') as devnull: + try: + subprocess.check_call(cmd, stdout=devnull, stderr=devnull) + except Exception: + return False + return True + +download_file_curl.viable = has_curl + +def download_file_wget(url, target): + cmd = ['wget', url, '--quiet', '--output-document', target] + _clean_check(cmd, target) + +def has_wget(): + cmd = ['wget', '--version'] + with open(os.path.devnull, 'wb') as devnull: + try: + subprocess.check_call(cmd, stdout=devnull, stderr=devnull) + except Exception: + return False + return True + +download_file_wget.viable = has_wget + +def download_file_insecure(url, target): + """ + Use Python to download the file, even though it cannot authenticate + the connection. + """ + src = urlopen(url) + try: + # Read all the data in one block. + data = src.read() + finally: + src.close() + + # Write all the data in one block to avoid creating a partial file. + with open(target, "wb") as dst: + dst.write(data) + +download_file_insecure.viable = lambda: True + +def get_best_downloader(): + downloaders = ( + download_file_powershell, + download_file_curl, + download_file_wget, + download_file_insecure, + ) + viable_downloaders = (dl for dl in downloaders if dl.viable()) + return next(viable_downloaders, None) + +def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, + to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): + """ + Download setuptools from a specified location and return its + filename + + `version` should be a valid setuptools version number that is + available as an sdist for download under the `download_base` URL + (which should end with a '/'). + `to_dir` is the directory where the egg will be downloaded. + `delay` is the number of seconds to pause before an actual download + attempt. + + ``downloader_factory`` should be a function taking no arguments and + returning a function for downloading a URL to a target. + """ + # making sure we use the absolute path + to_dir = os.path.abspath(to_dir) + zip_name = "setuptools-{}.zip".format(version) + url = download_base + zip_name + saveto = os.path.join(to_dir, zip_name) + if not os.path.exists(saveto): # Avoid repeated downloads + log.warn("Downloading {}".format(url)) + downloader = downloader_factory() + downloader(url, saveto) + return os.path.realpath(saveto) + +def _build_install_args(options): + """ + Build the arguments to 'python setup.py install' on the + setuptools package + """ + return ['--user'] if options.user_install else [] + +def _parse_args(): + """ + Parse the command line for options + """ + parser = optparse.OptionParser() + parser.add_option( + '--user', dest='user_install', action='store_true', default=False, + help='install in user site package (requires Python 2.6 or later)') + parser.add_option( + '--download-base', dest='download_base', metavar="URL", + default=DEFAULT_URL, + help='alternative URL from where to download the setuptools package') + parser.add_option( + '--insecure', dest='downloader_factory', action='store_const', + const=lambda: download_file_insecure, default=get_best_downloader, + help='Use internal, non-validating downloader' + ) + parser.add_option( + '--version', help="Specify which version to download", + default=DEFAULT_VERSION, + ) + options, args = parser.parse_args() + # positional arguments are ignored + return options + +def main(): + """Install or upgrade setuptools and EasyInstall""" + options = _parse_args() + archive = download_setuptools( + version=options.version, + download_base=options.download_base, + downloader_factory=options.downloader_factory, + ) + return _install(archive, _build_install_args(options)) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/header.BSD-OLD b/header.BSD-OLD new file mode 100644 index 0000000..687705f --- /dev/null +++ b/header.BSD-OLD @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the FOO module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD-OLD$ +** You may use this file under the terms of the BSD license as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ diff --git a/keyword-errors.lst b/keyword-errors.lst new file mode 100644 index 0000000..af8c581 --- /dev/null +++ b/keyword-errors.lst @@ -0,0 +1,43 @@ +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QAbstractItemModel.changePersistentIndex', 'arglist': 'from:PySide2.QtCore.QModelIndex,to:PySide2.QtCore.QModelIndex', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QAbstractItemModel.changePersistentIndexList', 'arglist': 'from:QModelIndexList,to:QModelIndexList', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QByteArray.indexOf', 'arglist': 'a:PySide2.QtCore.QByteArray,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QByteArray.lastIndexOf', 'arglist': 'a:PySide2.QtCore.QByteArray,from:int=-1', 'returntype': 'int'} +KEYWORD {'multi': '1', 'funcname': 'PySide2.QtCore.QByteArrayMatcher.indexIn', 'arglist': 'ba:PySide2.QtCore.QByteArray,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': '0', 'funcname': 'PySide2.QtCore.QByteArrayMatcher.indexIn', 'arglist': 'str:str,len:int,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.indexOf', 'arglist': 't:PySide2.QtCore.QItemSelectionRange,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.lastIndexOf', 'arglist': 't:PySide2.QtCore.QItemSelectionRange,from:int=-1', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QItemSelection.move', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QTextCodec.convertToUnicode', 'arglist': 'in:str,length:int,state:PySide2.QtCore.QTextCodec.ConverterState', 'returntype': 'QString'} +KEYWORD {'multi': '0', 'funcname': 'PySide2.QtCore.QTextCodec.toUnicode', 'arglist': 'in:str,length:int,state:PySide2.QtCore.QTextCodec.ConverterState=nullptr', 'returntype': 'QString'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QVariantAnimation.interpolated', 'arglist': 'from:QVariant,to:QVariant,progress:double', 'returntype': 'QVariant'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.indexOf', 'arglist': 't:PySide2.QtCore.QXmlStreamAttribute,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.lastIndexOf', 'arglist': 't:PySide2.QtCore.QXmlStreamAttribute,from:int=-1', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtCore.QXmlStreamAttributes.move', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QAbstractTextDocumentLayout.documentChanged', 'arglist': 'from:int,charsRemoved:int,charsAdded:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QIconEngine.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'bool'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QKeySequence.__lshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.indexOf', 'arglist': 't:PySide2.QtCore.QPoint,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.lastIndexOf', 'arglist': 't:PySide2.QtCore.QPoint,from:int=-1', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygon.move', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.indexOf', 'arglist': 't:PySide2.QtCore.QPointF,from:int=0', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.lastIndexOf', 'arglist': 't:PySide2.QtCore.QPointF,from:int=-1', 'returntype': 'int'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QPolygonF.move', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QQuaternion.rotationTo', 'arglist': 'from:PySide2.QtGui.QVector3D,to:PySide2.QtGui.QVector3D', 'returntype': 'PySide2.QtGui.QQuaternion'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QStandardItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QStandardItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'} +KEYWORD {'multi': '4', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'expr:PySide2.QtCore.QRegExp,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'} +KEYWORD {'multi': '2', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'expr:PySide2.QtCore.QRegularExpression,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'} +KEYWORD {'multi': '0', 'funcname': 'PySide2.QtGui.QTextDocument.find', 'arglist': 'subString:QString,from:int=0,options:PySide2.QtGui.QTextDocument.FindFlags=QTextDocument.FindFlags()', 'returntype': 'PySide2.QtGui.QTextCursor'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtGui.QTextDocument.markContentsDirty', 'arglist': 'from:int,length:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QHeaderView.moveSection', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QLayout.replaceWidget', 'arglist': 'from:PySide2.QtWidgets.QWidget,to:PySide2.QtWidgets.QWidget,options:PySide2.QtCore.Qt.FindChildOptions=Qt.FindChildrenRecursively', 'returntype': 'PySide2.QtWidgets.QLayoutItem'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QListWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QListWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QPlainTextDocumentLayout.documentChanged', 'arglist': 'from:int,arg__2:int,charsAdded:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTabBar.moveTab', 'arglist': 'from:int,to:int', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTableWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTableWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTreeWidgetItem.read', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': None} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtWidgets.QTreeWidgetItem.__rshift__', 'arglist': 'in:PySide2.QtCore.QDataStream', 'returntype': 'PySide2.QtCore.QDataStream'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtMultimedia.QAudio.convertVolume', 'arglist': 'volume:double,from:PySide2.QtMultimedia.QAudio.VolumeScale,to:PySide2.QtMultimedia.QAudio.VolumeScale', 'returntype': 'double'} +KEYWORD {'multi': None, 'funcname': 'PySide2.QtMultimedia.QMediaPlaylist.moveMedia', 'arglist': 'from:int,to:int', 'returntype': 'bool'} diff --git a/product_dependencies.yaml b/product_dependencies.yaml new file mode 100644 index 0000000..29c4fb5 --- /dev/null +++ b/product_dependencies.yaml @@ -0,0 +1,3 @@ +dependencies: + ../../qt/qt5.git: + ref: "5.15.2" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..9c25886 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,11 @@ +numpy==1.16.6; python_version < '3' +# numpy; python_version >= '3', installed in coin_*_instructions.py atm +# see https://tinyurl.com/y3dm3h86 for details +# setuptools from v45+ removed the support for Python 2, so we pin an old release +setuptools==44.0.0; python_version < '3' +setuptools; python_version >= '3' +sphinx +six +wheel>=0.35 +PyOpenGL +pyinstaller==3.6 diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..8eb2027 --- /dev/null +++ b/setup.py @@ -0,0 +1,296 @@ +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the Qt for Python project. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function + +""" +This is a distutils setup-script for the Qt for Python project + +To build both shiboken2 and PySide2 simply execute: + + python setup.py build + +or + + python setup.py install + +to build and install into your current Python installation. + +The same setup.py script is used to build all the components of the +project: + - shiboken2 (the supporting Python module) + - shiboken2-generator (the bindings generation executable) + - PySide2 + - pyside2-tools + +Preferably, a Qt (build) environment should be used to automatically +pick up the associated `qmake`, but optionally one can specify the +location of `qmake` and `cmake` if it is not in the current PATH with: + + --qmake=/path/to/qt/bin/qmake + +and + + --cmake=/path/to/bin/cmake + +respectively. + +By default, all of the above is built when no special options are +passed to the script. You can use the --build-type parameter to specify +which things should be built: + + --build-type=shiboken2 - build / package only the python module + --build-type=shiboken2-generator - build / package the generator + executable + --build-type=pyside2 - build / package the PySide2 bindings and + and pyside2-tools + --build-type=all - the implicit default to build all of the above + + +When building PySide2, optionally, one can specify the location of the +shiboken2 cmake config path if it is not on the current PATH with: + + --shiboken-config-dir=/path/to/shiboken/cmake/config/dir + +This is useful if you did a cmake installation of shiboken2 into +a custom location. + +For Windows, if OpenSSL support is required, it's necessary to specify +the directory path that contains the OpenSSL shared libraries +"libeay32.dll" and "ssleay32.dll", for example: + + --openssl=C:\\OpenSSL-Win64\\bin + +This will make sure that the libraries are copied into the PySide2 +package and are found by the QtNetwork module. + +ADDITIONAL OPTIONS: + +On Linux and macOS you can use the option `--standalone` to embed Qt +libraries into the PySide2 package. +The option does not affect Windows, because it is used implicitly, +i.e. all relevant DLLs have to be copied into the PySide2 package +anyway, because there is no proper rpath support on the platform. + +You can use the option `--rpath=/path/to/lib/path` to specify which +rpath values should be embedded into the PySide2 modules and shared +libraries. +This overrides the automatically generated values when the option is +not specified. + +You can use the option `--only-package` if you want to create more +binary packages (bdist_wheel, bdist_egg, ...) without rebuilding the +entire project every time: + +e.g.: + +* First, we create a bdist_wheel from a full PySide2 build: + + python setup.py bdist_wheel --qmake=c:\\Qt\\5.12\\bin\\qmake.exe + --cmake=c:\\tools\\cmake\\bin\\cmake.exe + --openssl=c:\\libs\\OpenSSL32bit\\bin + +* Then, we create a bdist_egg reusing the PySide2 build with option + `--only-package`: + + python setup.py bdist_egg --only-package + --qmake=c:\\Qt\\5.12\\bin\\qmake.exe + --cmake=c:\\tools\\cmake\\bin\\cmake.exe + --openssl=c:\\libs\\OpenSSL32bit\\bin + +You can use the option `--qt-conf-prefix` to pass a path relative to +the PySide2 installed package, which will be embedded into an +auto-generated `qt.conf` registered in the Qt resource system. +This path will serve as the PrefixPath for QLibraryInfo, thus allowing +to choose where Qt plugins should be loaded from. +This option overrides the usual prefix chosen by `--standalone` option, +or when building on Windows. + +To temporarily disable registration of the internal `qt.conf` file, a +new environment variable called PYSIDE_DISABLE_INTERNAL_QT_CONF is +introduced. + +You should assign the integer "1" to disable the internal `qt.conf`, +or "0" (or leave empty) to keep using the internal `qt.conf` file. + +DEVELOPMENT OPTIONS: + +For development purposes the following options might be of use, when +using `setup.py build`: + + --ignore-git will skip the fetching and checkout steps for + supermodule and all submodules. + --limited-api=yes|no default yes if applicable + Set or clear the limited API flag. Ignored for Python 2. + --module-subset allows for specifying the Qt modules to be built. + A minimal set is: --module-subset=Core,Gui,Test,Widgets + --package-timestamp allows specifying the timestamp that will be + used as part of the version number for a snapshot package. + For example given --package-timestamp=1529646276 + the package version will be 5.x.y.dev1529646276. + --reuse-build option allows recompiling only the modified sources and + not the whole world, shortening development iteration time. + --sanitize-address will build the project with address sanitizer. + --skip-cmake will reuse the already generated Makefiles (or + equivalents), instead of invoking, CMake to update the + Makefiles (note, CMake should be ran at least once to generate + the files). + --skip-docs skip the documentation generation. + --skip-make-install will not run make install (or equivalent) for + each module built. + --skip-modules allows for specifying the Qt modules that will be + skipped during the build process. + For example: --skip-modules=WebEngineCore,WebEngineWidgets + --skip-packaging will skip creation of the python package, + enabled (Linux or macOS only). + --verbose-build will output the compiler invocation with command line + arguments, etc. + +REQUIREMENTS: + +* Python: 2.7 and 3.5+ are supported +* CMake: Specify the path to cmake with `--cmake` option or add cmake + to the system path. +* Qt: 5.11+ is supported. Specify the path to qmake with + `--qmake` option or add qmake to the system path. + +OPTIONAL: + +* OpenSSL: + Specifying the --openssl option only affects Windows. + It is a no-op for other platforms. + + Please note that official Windows packages do not ship the + OpenSSL libraries due to import / export restrictions as + described in + http://doc.qt.io/qt-5/ssl.html#import-and-export-restrictions + + You can specify the location of the OpenSSL DLLs with the + following option: + + --openssl=. + + You can download OpenSSL for Windows here: + + http://slproweb.com/products/Win32OpenSSL.html (*) + + Official Qt packages do not link to the SSL library directly, but + rather try to find the library at runtime. + + On Windows, official Qt builds will try to pick up OpenSSL + libraries at application path, system registry, or in the PATH + environment variable. + + On macOS, official Qt builds use SecureTransport (provided by OS) + instead of OpenSSL. + + On Linux, official Qt builds will try to pick up the system OpenSSL + library. + + Note: this means that Qt packages that directly link to the OpenSSL + shared libraries, are not currently compatible with + standalone PySide2 packages. + + (*) Revised on 2018.10.24 + +* macOS SDK: + You can specify which macOS SDK should be used for compilation with + the option: + + --macos-sysroot=. + + e.g.: "--macos-sysroot=/Applications/Xcode.app/.../Developer/SDKs/MacOSX10.12.sdk/" + +* macOS minimum deployment target: + You can specify a custom macOS minimum deployment target with the + option: + + --macos-deployment-target= + + e.g.: "--macos-deployment-target=10.10" + + If the option is not set, the minimum deployment target of the used + Qt library will be used instead. Thus it is not necessary to use + the option without a good reason. + + If a new value is specified, it has to be higher or equal to both + Python's and Qt's minimum deployment targets. + + Description: macOS allows specifying a minimum OS version on which + a binary will be able to run. This implies that an + application can be built on a machine with the latest + macOS version installed, with latest Xcode version and + SDK version and the built application can still run on + an older OS version. +""" + +import os +import sys + +# Change the current directory to setup.py's dir. +try: + this_file = __file__ +except NameError: + this_file = sys.argv[0] +this_file_original = this_file +this_file = os.path.abspath(this_file) +if os.path.dirname(this_file): + os.chdir(os.path.dirname(this_file)) + +# Save the original command line arguments to pass them on to the setup +# mechanism. +original_argv = list(sys.argv) + +# If setup.py was invoked via -c "some code" or -m some_command, make sure +# to replace the first argv to be the script name, so that sub-invocations +# continue to work. +if original_argv and original_argv[0] in ['-c', '-m']: + original_argv[0] = this_file_original + +from build_scripts.main import get_package_version, check_allowed_python_version +from build_scripts.setup_runner import SetupRunner + +# The __version__ variable is just for PEP compliance, and shouldn't be +# used as a value source. Use get_package_version() instead. +__version__ = get_package_version() + +check_allowed_python_version() + +setup_runner = SetupRunner(original_argv) +setup_runner.run_setup() diff --git a/sources/cmake_helpers/helpers.cmake b/sources/cmake_helpers/helpers.cmake new file mode 100644 index 0000000..fed96b5 --- /dev/null +++ b/sources/cmake_helpers/helpers.cmake @@ -0,0 +1,274 @@ +macro(collect_essential_modules) +# Collect all essential modules. +# note: the order of this list is relevant for dependencies. +# For instance: Qt5Printsupport must come before Qt5WebKitWidgets. +set(ALL_ESSENTIAL_MODULES + Core + Gui + Widgets + PrintSupport + Sql + Network + Test + Concurrent) +if(UNIX AND NOT APPLE) + list(APPEND ALL_ESSENTIAL_MODULES X11Extras) +endif() +if(WIN32) + list(APPEND ALL_ESSENTIAL_MODULES WinExtras) +endif() +if(APPLE) + list(APPEND ALL_ESSENTIAL_MODULES MacExtras) +endif() +endmacro() + +macro(collect_optional_modules) +# Collect all optional modules. +set(ALL_OPTIONAL_MODULES + Xml + XmlPatterns + Help Multimedia + MultimediaWidgets + OpenGL + OpenGLFunctions + Positioning + Location + Qml + Quick + QuickControls2 + QuickWidgets + RemoteObjects + Scxml + Script + ScriptTools + Sensors + SerialPort + TextToSpeech + Charts + Svg + DataVisualization) +find_package(Qt${QT_MAJOR_VERSION}UiTools) +if(Qt${QT_MAJOR_VERSION}UiTools_FOUND) + list(APPEND ALL_OPTIONAL_MODULES UiTools) +else() + set(DISABLE_QtUiTools 1) +endif() +if(WIN32) + list(APPEND ALL_OPTIONAL_MODULES AxContainer) +endif() +# Disabling WebKit by default +# If WebKit support is needed add the following elements +# to the list: WebKit WebKitWidgets +list(APPEND ALL_OPTIONAL_MODULES WebChannel WebEngineCore WebEngine WebEngineWidgets WebSockets) +if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.9.3) # Depending on fixes in Qt3D + list(APPEND ALL_OPTIONAL_MODULES 3DCore 3DRender 3DInput 3DLogic 3DAnimation 3DExtras) +endif() +endmacro() + +macro(check_os) +set(ENABLE_X11 "0") +set(ENABLE_MAC "0") +set(ENABLE_WIN "0") +set(ENABLE_SIMULATOR "0") + +if(CMAKE_HOST_APPLE) + set(ENABLE_MAC "1") + set(AUTO_OS "mac") +elseif(CMAKE_HOST_WIN32) + set(ENABLE_WIN "1") + set(AUTO_OS "win") +elseif(CMAKE_HOST_UNIX) + set(ENABLE_X11 "1") + set(AUTO_OS "x11") +else() + message(FATAL_ERROR "OS not supported") +endif() +endmacro() + +macro(use_protected_as_public_hack) +# 2017-04-24 The protected hack can unfortunately not be disabled, because +# Clang does produce linker errors when we disable the hack. +# But the ugly workaround in Python is replaced by a shiboken change. +if(WIN32 OR DEFINED AVOID_PROTECTED_HACK) + message(STATUS "PySide2 will be generated avoiding the protected hack!") + set(GENERATOR_EXTRA_FLAGS ${GENERATOR_EXTRA_FLAGS} --avoid-protected-hack) + add_definitions(-DAVOID_PROTECTED_HACK) +else() + message(STATUS "PySide will be generated using the protected hack!") +endif() +endmacro() + +macro(remove_skipped_modules) +# Removing from the MODULES list the items that were defined with +# -DSKIP_MODULES on command line +if (SKIP_MODULES) + foreach(s ${SKIP_MODULES}) + list(REMOVE_ITEM MODULES ${s}) + endforeach() +endif() + +foreach(m ${MODULES}) + COLLECT_MODULE_IF_FOUND(${m}) + list(FIND all_module_shortnames ${m} is_module_collected) + # If the module was collected, remove it from disabled modules list. + if (NOT is_module_collected EQUAL -1) + list(REMOVE_ITEM DISABLED_MODULES ${m}) + endif() +endforeach() +endmacro() + +macro(COLLECT_MODULE_IF_FOUND shortname) + set(name "Qt${QT_MAJOR_VERSION}${shortname}") + set(_qt_module_name "${name}") + if ("${shortname}" STREQUAL "OpenGLFunctions") + set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui") + endif() + # Determine essential/optional/missing + set(module_state "missing") + list(FIND ALL_ESSENTIAL_MODULES "${shortname}" essentialIndex) + if(${essentialIndex} EQUAL -1) + list(FIND ALL_OPTIONAL_MODULES "${shortname}" optionalIndex) + if(NOT ${optionalIndex} EQUAL -1) + set(module_state "optional") + endif() + else() + set(module_state "essential") + endif() + + # Silence warnings when optional packages are not found when doing a quiet build. + set(quiet_argument "") + if (QUIET_BUILD AND "${module_state}" STREQUAL "optional") + set(quiet_argument "QUIET") + endif() + + find_package(${_qt_module_name} ${quiet_argument}) + # If package is found, _name_found will be equal to 1 + set(_name_found "${_qt_module_name}_FOUND") + # _name_dir will keep the path to the directory where the CMake rules were found + # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Core or /usr/lib64/cmake/Qt5Core + set(_name_dir "${_qt_module_name}_DIR") + # Qt5Core will set the base path to check if all the modules are on the same + # directory, to avoid CMake looking in another path. + # This will be saved in a global variable at the beginning of the modules + # collection process. + string(FIND "${name}" "Qt${QT_MAJOR_VERSION}Core" qtcore_found) + if(("${qtcore_found}" GREATER "0") OR ("${qtcore_found}" EQUAL "0")) + get_filename_component(_core_abs_dir "${${_name_dir}}/../" ABSOLUTE) + # Setting the absolute path where the Qt5Core was found + # e.g: ~/qt5.9-install/qtbase/lib/cmake or /usr/lib64/cmake + message(STATUS "CORE_ABS_DIR:" ${_core_abs_dir}) + endif() + + # Getting the absolute path for each module where the CMake was found, to + # compare it with CORE_ABS_DIR and check if they are in the same source directory + # e.g: ~/qt5.9-install/qtbase/lib/cmake/Qt5Script or /usr/lib64/cmake/Qt5Script + get_filename_component(_module_dir "${${_name_dir}}" ABSOLUTE) + string(FIND "${_module_dir}" "${_core_abs_dir}" found_basepath) + + # If the module was found, and also the module path is the same as the + # Qt5Core base path, we will generate the list with the modules to be installed + set(looked_in_message ". Looked in: ${${_name_dir}}") + if("${${_name_found}}" AND (("${found_basepath}" GREATER "0") OR ("${found_basepath}" EQUAL "0"))) + message(STATUS "${module_state} module ${name} found (${ARGN})${looked_in_message}") + # record the shortnames for the tests + list(APPEND all_module_shortnames ${shortname}) + # Build Qt 5 compatibility variables + if(${QT_MAJOR_VERSION} GREATER_EQUAL 6) + get_target_property(Qt6${shortname}_INCLUDE_DIRS Qt6::${shortname} + INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(Qt6${shortname}_PRIVATE_INCLUDE_DIRS + Qt6::${shortname}Private + INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(Qt6${shortname}_LIBRARIES Qt6::${shortname} + INTERFACE_LINK_LIBRARIES) + endif() + else() + if("${module_state}" STREQUAL "optional") + message(STATUS "optional module ${name} skipped${looked_in_message}") + elseif("${module_state}" STREQUAL "essential") + message(STATUS "skipped module ${name} is essential!\n" + " We do not guarantee that all tests are working.${looked_in_message}") + else() + message(FATAL_ERROR "module ${name} MISSING${looked_in_message}") + endif() + endif() +endmacro() + +macro(compute_config_py_values + full_version_var_name + ) + string(TIMESTAMP PACKAGE_BUILD_DATE "%Y-%m-%dT%H:%M:%S+00:00" UTC) + if (PACKAGE_BUILD_DATE) + set(PACKAGE_BUILD_DATE "__build_date__ = '${PACKAGE_BUILD_DATE}'") + endif() + + if (PACKAGE_SETUP_PY_PACKAGE_VERSION) + set(PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT "__setup_py_package_version__ = '${PACKAGE_SETUP_PY_PACKAGE_VERSION}'") + set(FINAL_PACKAGE_VERSION ${PACKAGE_SETUP_PY_PACKAGE_VERSION}) + else() + set(FINAL_PACKAGE_VERSION ${${full_version_var_name}}) + endif() + + if (PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP) + set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "__setup_py_package_timestamp__ = '${PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP}'") + else() + set(PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT "") + endif() + + find_package(Git) + if(GIT_FOUND) + # Check if current source folder is inside a git repo, so that commit information can be + # queried. + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir + OUTPUT_VARIABLE PACKAGE_SOURCE_IS_INSIDE_REPO + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + if(PACKAGE_SOURCE_IS_INSIDE_REPO) + # Force git dates to be UTC-based. + set(ENV{TZ} UTC) + execute_process( + COMMAND ${GIT_EXECUTABLE} --no-pager show --date=format-local:%Y-%m-%dT%H:%M:%S+00:00 -s --format=%cd HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_DATE + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_DATE) + set(PACKAGE_BUILD_COMMIT_DATE "__build_commit_date__ = '${PACKAGE_BUILD_COMMIT_DATE}'") + endif() + unset(ENV{TZ}) + + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_HASH) + set(PACKAGE_BUILD_COMMIT_HASH "__build_commit_hash__ = '${PACKAGE_BUILD_COMMIT_HASH}'") + endif() + + execute_process( + COMMAND ${GIT_EXECUTABLE} describe HEAD + OUTPUT_VARIABLE PACKAGE_BUILD_COMMIT_HASH_DESCRIBED + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED) + set(PACKAGE_BUILD_COMMIT_HASH_DESCRIBED "__build_commit_hash_described__ = '${PACKAGE_BUILD_COMMIT_HASH_DESCRIBED}'") + endif() + + endif() + endif() + +endmacro() + +# Creates a new target called "${library_name}_generator" which +# depends on the mjb_rejected_classes.log file generated by shiboken. +# This target is added as a dependency to ${library_name} target. +# This file's timestamp informs cmake when the last generation was +# done, without force-updating the timestamps of the generated class +# cpp files. +# In practical terms this means that changing some injection code in +# an xml file that modifies only one specific class cpp file, will +# not force rebuilding all the cpp files, and thus allow for better +# incremental builds. +macro(create_generator_target library_name) + add_custom_target(${library_name}_generator DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log") + add_dependencies(${library_name} ${library_name}_generator) +endmacro() diff --git a/sources/patchelf/COPYING b/sources/patchelf/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/sources/patchelf/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/sources/patchelf/README b/sources/patchelf/README new file mode 100644 index 0000000..1db25bc --- /dev/null +++ b/sources/patchelf/README @@ -0,0 +1,107 @@ +PatchELF is a simple utility for modifing existing ELF executables and +libraries. In particular, it can do the following: + +* Change the dynamic loader ("ELF interpreter") of executables: + + $ patchelf --set-interpreter /lib/my-ld-linux.so.2 my-program + +* Change the RPATH of executables and libraries: + + $ patchelf --set-rpath /opt/my-libs/lib:/other-libs my-program + +* Shrink the RPATH of executables and libraries: + + $ patchelf --shrink-rpath my-program + + This removes from the RPATH all directories that do not contain a + library referenced by DT_NEEDED fields of the executable or library. + For instance, if an executable references one library libfoo.so, has + an RPATH "/lib:/usr/lib:/foo/lib", and libfoo.so can only be found + in /foo/lib, then the new RPATH will be "/foo/lib". + + +AUTHOR + +Copyright 2004-2009 Eelco Dolstra . + + +LICENSE + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or (at +your option) any later version. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + + +HOMEPAGE + +http://nixos.org/patchelf.html + + +BUGS + +The `strip' command from binutils generated broken executables when +applied to the output of patchelf (if `--set-rpath' or +`--set-interpreter' with a larger path than the original is used). +This appears to be a bug in binutils +(http://bugs.strategoxt.org/browse/NIXPKGS-85). + + +RELEASE HISTORY + +0.6 (November 7, 2011): + +* Hacky support for executables created by the Gold linker. + +* Support segments with an alignment of 0 (contributed by Zack + Weinberg). + +* Added a manual page (contributed by Jeremy Sanders + ). + +0.5 (November 4, 2009): + +* Various bugfixes. + +* `--force-rpath' now deletes the DT_RUNPATH if it is present. + +0.4 (June 4, 2008): + +* Support for growing the RPATH on dynamic libraries. + +* IA-64 support (not tested) and related 64-bit fixes. + +* FreeBSD support. + +* `--set-rpath', `--shrink-rpath' and `--print-rpath' now prefer + DT_RUNPATH over DT_RPATH, which is obsolete. When updating, if both + are present, both are updated. If only DT_RPATH is present, it is + converted to DT_RUNPATH unless `--force-rpath' is specified. If + neither is present, a DT_RUNPATH is added unless `--force-rpath' is + specified, in which case a DT_RPATH is added. + +0.3 (May 24, 2007): + +* Support for 64-bit ELF binaries (such as on x86_64-linux). + +* Support for big-endian ELF binaries (such as on powerpc-linux). + +* Various bugfixes. + +0.2 (January 15, 2007): + +* Provides a hack to get certain programs (such as the + Belastingaangifte 2005) to work. + +0.1 (October 11, 2005): + +* Initial release. + diff --git a/sources/patchelf/elf.h b/sources/patchelf/elf.h new file mode 100644 index 0000000..b897f5b --- /dev/null +++ b/sources/patchelf/elf.h @@ -0,0 +1,2674 @@ +/* This file defines standard ELF types, structures, and macros. + Copyright (C) 1995-2003,2004,2005,2006,2007,2008 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _ELF_H +#define _ELF_H 1 + +/* Standard ELF types. */ + +#include + +/* Type for a 16-bit quantity. */ +typedef uint16_t Elf32_Half; +typedef uint16_t Elf64_Half; + +/* Types for signed and unsigned 32-bit quantities. */ +typedef uint32_t Elf32_Word; +typedef int32_t Elf32_Sword; +typedef uint32_t Elf64_Word; +typedef int32_t Elf64_Sword; + +/* Types for signed and unsigned 64-bit quantities. */ +typedef uint64_t Elf32_Xword; +typedef int64_t Elf32_Sxword; +typedef uint64_t Elf64_Xword; +typedef int64_t Elf64_Sxword; + +/* Type of addresses. */ +typedef uint32_t Elf32_Addr; +typedef uint64_t Elf64_Addr; + +/* Type of file offsets. */ +typedef uint32_t Elf32_Off; +typedef uint64_t Elf64_Off; + +/* Type for section indices, which are 16-bit quantities. */ +typedef uint16_t Elf32_Section; +typedef uint16_t Elf64_Section; + +/* Type for version symbol information. */ +typedef Elf32_Half Elf32_Versym; +typedef Elf64_Half Elf64_Versym; + + +/* The ELF file header. This appears at the start of every ELF file. */ + +#define EI_NIDENT (16) + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf32_Half e_type; /* Object file type */ + Elf32_Half e_machine; /* Architecture */ + Elf32_Word e_version; /* Object file version */ + Elf32_Addr e_entry; /* Entry point virtual address */ + Elf32_Off e_phoff; /* Program header table file offset */ + Elf32_Off e_shoff; /* Section header table file offset */ + Elf32_Word e_flags; /* Processor-specific flags */ + Elf32_Half e_ehsize; /* ELF header size in bytes */ + Elf32_Half e_phentsize; /* Program header table entry size */ + Elf32_Half e_phnum; /* Program header table entry count */ + Elf32_Half e_shentsize; /* Section header table entry size */ + Elf32_Half e_shnum; /* Section header table entry count */ + Elf32_Half e_shstrndx; /* Section header string table index */ +} Elf32_Ehdr; + +typedef struct +{ + unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */ + Elf64_Half e_type; /* Object file type */ + Elf64_Half e_machine; /* Architecture */ + Elf64_Word e_version; /* Object file version */ + Elf64_Addr e_entry; /* Entry point virtual address */ + Elf64_Off e_phoff; /* Program header table file offset */ + Elf64_Off e_shoff; /* Section header table file offset */ + Elf64_Word e_flags; /* Processor-specific flags */ + Elf64_Half e_ehsize; /* ELF header size in bytes */ + Elf64_Half e_phentsize; /* Program header table entry size */ + Elf64_Half e_phnum; /* Program header table entry count */ + Elf64_Half e_shentsize; /* Section header table entry size */ + Elf64_Half e_shnum; /* Section header table entry count */ + Elf64_Half e_shstrndx; /* Section header string table index */ +} Elf64_Ehdr; + +/* Fields in the e_ident array. The EI_* macros are indices into the + array. The macros under each EI_* macro are the values the byte + may have. */ + +#define EI_MAG0 0 /* File identification byte 0 index */ +#define ELFMAG0 0x7f /* Magic number byte 0 */ + +#define EI_MAG1 1 /* File identification byte 1 index */ +#define ELFMAG1 'E' /* Magic number byte 1 */ + +#define EI_MAG2 2 /* File identification byte 2 index */ +#define ELFMAG2 'L' /* Magic number byte 2 */ + +#define EI_MAG3 3 /* File identification byte 3 index */ +#define ELFMAG3 'F' /* Magic number byte 3 */ + +/* Conglomeration of the identification bytes, for easy testing as a word. */ +#define ELFMAG "\177ELF" +#define SELFMAG 4 + +#define EI_CLASS 4 /* File class byte index */ +#define ELFCLASSNONE 0 /* Invalid class */ +#define ELFCLASS32 1 /* 32-bit objects */ +#define ELFCLASS64 2 /* 64-bit objects */ +#define ELFCLASSNUM 3 + +#define EI_DATA 5 /* Data encoding byte index */ +#define ELFDATANONE 0 /* Invalid data encoding */ +#define ELFDATA2LSB 1 /* 2's complement, little endian */ +#define ELFDATA2MSB 2 /* 2's complement, big endian */ +#define ELFDATANUM 3 + +#define EI_VERSION 6 /* File version byte index */ + /* Value must be EV_CURRENT */ + +#define EI_OSABI 7 /* OS ABI identification */ +#define ELFOSABI_NONE 0 /* UNIX System V ABI */ +#define ELFOSABI_SYSV 0 /* Alias. */ +#define ELFOSABI_HPUX 1 /* HP-UX */ +#define ELFOSABI_NETBSD 2 /* NetBSD. */ +#define ELFOSABI_LINUX 3 /* Linux. */ +#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */ +#define ELFOSABI_AIX 7 /* IBM AIX. */ +#define ELFOSABI_IRIX 8 /* SGI Irix. */ +#define ELFOSABI_FREEBSD 9 /* FreeBSD. */ +#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */ +#define ELFOSABI_MODESTO 11 /* Novell Modesto. */ +#define ELFOSABI_OPENBSD 12 /* OpenBSD. */ +#define ELFOSABI_ARM 97 /* ARM */ +#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */ + +#define EI_ABIVERSION 8 /* ABI version */ + +#define EI_PAD 9 /* Byte index of padding bytes */ + +/* Legal values for e_type (object file type). */ + +#define ET_NONE 0 /* No file type */ +#define ET_REL 1 /* Relocatable file */ +#define ET_EXEC 2 /* Executable file */ +#define ET_DYN 3 /* Shared object file */ +#define ET_CORE 4 /* Core file */ +#define ET_NUM 5 /* Number of defined types */ +#define ET_LOOS 0xfe00 /* OS-specific range start */ +#define ET_HIOS 0xfeff /* OS-specific range end */ +#define ET_LOPROC 0xff00 /* Processor-specific range start */ +#define ET_HIPROC 0xffff /* Processor-specific range end */ + +/* Legal values for e_machine (architecture). */ + +#define EM_NONE 0 /* No machine */ +#define EM_M32 1 /* AT&T WE 32100 */ +#define EM_SPARC 2 /* SUN SPARC */ +#define EM_386 3 /* Intel 80386 */ +#define EM_68K 4 /* Motorola m68k family */ +#define EM_88K 5 /* Motorola m88k family */ +#define EM_860 7 /* Intel 80860 */ +#define EM_MIPS 8 /* MIPS R3000 big-endian */ +#define EM_S370 9 /* IBM System/370 */ +#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */ + +#define EM_PARISC 15 /* HPPA */ +#define EM_VPP500 17 /* Fujitsu VPP500 */ +#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */ +#define EM_960 19 /* Intel 80960 */ +#define EM_PPC 20 /* PowerPC */ +#define EM_PPC64 21 /* PowerPC 64-bit */ +#define EM_S390 22 /* IBM S390 */ + +#define EM_V800 36 /* NEC V800 series */ +#define EM_FR20 37 /* Fujitsu FR20 */ +#define EM_RH32 38 /* TRW RH-32 */ +#define EM_RCE 39 /* Motorola RCE */ +#define EM_ARM 40 /* ARM */ +#define EM_FAKE_ALPHA 41 /* Digital Alpha */ +#define EM_SH 42 /* Hitachi SH */ +#define EM_SPARCV9 43 /* SPARC v9 64-bit */ +#define EM_TRICORE 44 /* Siemens Tricore */ +#define EM_ARC 45 /* Argonaut RISC Core */ +#define EM_H8_300 46 /* Hitachi H8/300 */ +#define EM_H8_300H 47 /* Hitachi H8/300H */ +#define EM_H8S 48 /* Hitachi H8S */ +#define EM_H8_500 49 /* Hitachi H8/500 */ +#define EM_IA_64 50 /* Intel Merced */ +#define EM_MIPS_X 51 /* Stanford MIPS-X */ +#define EM_COLDFIRE 52 /* Motorola Coldfire */ +#define EM_68HC12 53 /* Motorola M68HC12 */ +#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/ +#define EM_PCP 55 /* Siemens PCP */ +#define EM_NCPU 56 /* Sony nCPU embeeded RISC */ +#define EM_NDR1 57 /* Denso NDR1 microprocessor */ +#define EM_STARCORE 58 /* Motorola Start*Core processor */ +#define EM_ME16 59 /* Toyota ME16 processor */ +#define EM_ST100 60 /* STMicroelectronic ST100 processor */ +#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/ +#define EM_X86_64 62 /* AMD x86-64 architecture */ +#define EM_PDSP 63 /* Sony DSP Processor */ + +#define EM_FX66 66 /* Siemens FX66 microcontroller */ +#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */ +#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */ +#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */ +#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */ +#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */ +#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */ +#define EM_SVX 73 /* Silicon Graphics SVx */ +#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */ +#define EM_VAX 75 /* Digital VAX */ +#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */ +#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */ +#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */ +#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */ +#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */ +#define EM_HUANY 81 /* Harvard University machine-independent object files */ +#define EM_PRISM 82 /* SiTera Prism */ +#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */ +#define EM_FR30 84 /* Fujitsu FR30 */ +#define EM_D10V 85 /* Mitsubishi D10V */ +#define EM_D30V 86 /* Mitsubishi D30V */ +#define EM_V850 87 /* NEC v850 */ +#define EM_M32R 88 /* Mitsubishi M32R */ +#define EM_MN10300 89 /* Matsushita MN10300 */ +#define EM_MN10200 90 /* Matsushita MN10200 */ +#define EM_PJ 91 /* picoJava */ +#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ +#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ +#define EM_NUM 95 + +/* If it is necessary to assign new unofficial EM_* values, please + pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the + chances of collision with official or non-GNU unofficial values. */ + +#define EM_ALPHA 0x9026 + +/* Legal values for e_version (version). */ + +#define EV_NONE 0 /* Invalid ELF version */ +#define EV_CURRENT 1 /* Current version */ +#define EV_NUM 2 + +/* Section header. */ + +typedef struct +{ + Elf32_Word sh_name; /* Section name (string tbl index) */ + Elf32_Word sh_type; /* Section type */ + Elf32_Word sh_flags; /* Section flags */ + Elf32_Addr sh_addr; /* Section virtual addr at execution */ + Elf32_Off sh_offset; /* Section file offset */ + Elf32_Word sh_size; /* Section size in bytes */ + Elf32_Word sh_link; /* Link to another section */ + Elf32_Word sh_info; /* Additional section information */ + Elf32_Word sh_addralign; /* Section alignment */ + Elf32_Word sh_entsize; /* Entry size if section holds table */ +} Elf32_Shdr; + +typedef struct +{ + Elf64_Word sh_name; /* Section name (string tbl index) */ + Elf64_Word sh_type; /* Section type */ + Elf64_Xword sh_flags; /* Section flags */ + Elf64_Addr sh_addr; /* Section virtual addr at execution */ + Elf64_Off sh_offset; /* Section file offset */ + Elf64_Xword sh_size; /* Section size in bytes */ + Elf64_Word sh_link; /* Link to another section */ + Elf64_Word sh_info; /* Additional section information */ + Elf64_Xword sh_addralign; /* Section alignment */ + Elf64_Xword sh_entsize; /* Entry size if section holds table */ +} Elf64_Shdr; + +/* Special section indices. */ + +#define SHN_UNDEF 0 /* Undefined section */ +#define SHN_LORESERVE 0xff00 /* Start of reserved indices */ +#define SHN_LOPROC 0xff00 /* Start of processor-specific */ +#define SHN_BEFORE 0xff00 /* Order section before all others + (Solaris). */ +#define SHN_AFTER 0xff01 /* Order section after all others + (Solaris). */ +#define SHN_HIPROC 0xff1f /* End of processor-specific */ +#define SHN_LOOS 0xff20 /* Start of OS-specific */ +#define SHN_HIOS 0xff3f /* End of OS-specific */ +#define SHN_ABS 0xfff1 /* Associated symbol is absolute */ +#define SHN_COMMON 0xfff2 /* Associated symbol is common */ +#define SHN_XINDEX 0xffff /* Index is in extra table. */ +#define SHN_HIRESERVE 0xffff /* End of reserved indices */ + +/* Legal values for sh_type (section type). */ + +#define SHT_NULL 0 /* Section header table entry unused */ +#define SHT_PROGBITS 1 /* Program data */ +#define SHT_SYMTAB 2 /* Symbol table */ +#define SHT_STRTAB 3 /* String table */ +#define SHT_RELA 4 /* Relocation entries with addends */ +#define SHT_HASH 5 /* Symbol hash table */ +#define SHT_DYNAMIC 6 /* Dynamic linking information */ +#define SHT_NOTE 7 /* Notes */ +#define SHT_NOBITS 8 /* Program space with no data (bss) */ +#define SHT_REL 9 /* Relocation entries, no addends */ +#define SHT_SHLIB 10 /* Reserved */ +#define SHT_DYNSYM 11 /* Dynamic linker symbol table */ +#define SHT_INIT_ARRAY 14 /* Array of constructors */ +#define SHT_FINI_ARRAY 15 /* Array of destructors */ +#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */ +#define SHT_GROUP 17 /* Section group */ +#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */ +#define SHT_NUM 19 /* Number of defined types. */ +#define SHT_LOOS 0x60000000 /* Start OS-specific. */ +#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */ +#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */ +#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */ +#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */ +#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */ +#define SHT_SUNW_move 0x6ffffffa +#define SHT_SUNW_COMDAT 0x6ffffffb +#define SHT_SUNW_syminfo 0x6ffffffc +#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */ +#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */ +#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */ +#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */ +#define SHT_HIOS 0x6fffffff /* End OS-specific type */ +#define SHT_LOPROC 0x70000000 /* Start of processor-specific */ +#define SHT_HIPROC 0x7fffffff /* End of processor-specific */ +#define SHT_LOUSER 0x80000000 /* Start of application-specific */ +#define SHT_HIUSER 0x8fffffff /* End of application-specific */ + +/* Legal values for sh_flags (section flags). */ + +#define SHF_WRITE (1 << 0) /* Writable */ +#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */ +#define SHF_EXECINSTR (1 << 2) /* Executable */ +#define SHF_MERGE (1 << 4) /* Might be merged */ +#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */ +#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */ +#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */ +#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling + required */ +#define SHF_GROUP (1 << 9) /* Section is member of a group. */ +#define SHF_TLS (1 << 10) /* Section hold thread-local data. */ +#define SHF_MASKOS 0x0ff00000 /* OS-specific. */ +#define SHF_MASKPROC 0xf0000000 /* Processor-specific */ +#define SHF_ORDERED (1 << 30) /* Special ordering requirement + (Solaris). */ +#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless + referenced or allocated (Solaris).*/ + +/* Section group handling. */ +#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */ + +/* Symbol table entry. */ + +typedef struct +{ + Elf32_Word st_name; /* Symbol name (string tbl index) */ + Elf32_Addr st_value; /* Symbol value */ + Elf32_Word st_size; /* Symbol size */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf32_Section st_shndx; /* Section index */ +} Elf32_Sym; + +typedef struct +{ + Elf64_Word st_name; /* Symbol name (string tbl index) */ + unsigned char st_info; /* Symbol type and binding */ + unsigned char st_other; /* Symbol visibility */ + Elf64_Section st_shndx; /* Section index */ + Elf64_Addr st_value; /* Symbol value */ + Elf64_Xword st_size; /* Symbol size */ +} Elf64_Sym; + +/* The syminfo section if available contains additional information about + every dynamic symbol. */ + +typedef struct +{ + Elf32_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf32_Half si_flags; /* Per symbol flags */ +} Elf32_Syminfo; + +typedef struct +{ + Elf64_Half si_boundto; /* Direct bindings, symbol bound to */ + Elf64_Half si_flags; /* Per symbol flags */ +} Elf64_Syminfo; + +/* Possible values for si_boundto. */ +#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */ +#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */ +#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */ + +/* Possible bitmasks for si_flags. */ +#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */ +#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */ +#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */ +#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy + loaded */ +/* Syminfo version values. */ +#define SYMINFO_NONE 0 +#define SYMINFO_CURRENT 1 +#define SYMINFO_NUM 2 + + +/* How to extract and insert information held in the st_info field. */ + +#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4) +#define ELF32_ST_TYPE(val) ((val) & 0xf) +#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) + +/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */ +#define ELF64_ST_BIND(val) ELF32_ST_BIND (val) +#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val) +#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type)) + +/* Legal values for ST_BIND subfield of st_info (symbol binding). */ + +#define STB_LOCAL 0 /* Local symbol */ +#define STB_GLOBAL 1 /* Global symbol */ +#define STB_WEAK 2 /* Weak symbol */ +#define STB_NUM 3 /* Number of defined types. */ +#define STB_LOOS 10 /* Start of OS-specific */ +#define STB_HIOS 12 /* End of OS-specific */ +#define STB_LOPROC 13 /* Start of processor-specific */ +#define STB_HIPROC 15 /* End of processor-specific */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_NOTYPE 0 /* Symbol type is unspecified */ +#define STT_OBJECT 1 /* Symbol is a data object */ +#define STT_FUNC 2 /* Symbol is a code object */ +#define STT_SECTION 3 /* Symbol associated with a section */ +#define STT_FILE 4 /* Symbol's name is file name */ +#define STT_COMMON 5 /* Symbol is a common data object */ +#define STT_TLS 6 /* Symbol is thread-local data object*/ +#define STT_NUM 7 /* Number of defined types. */ +#define STT_LOOS 10 /* Start of OS-specific */ +#define STT_HIOS 12 /* End of OS-specific */ +#define STT_LOPROC 13 /* Start of processor-specific */ +#define STT_HIPROC 15 /* End of processor-specific */ + + +/* Symbol table indices are found in the hash buckets and chain table + of a symbol hash table section. This special index value indicates + the end of a chain, meaning no further symbols are found in that bucket. */ + +#define STN_UNDEF 0 /* End of a chain. */ + + +/* How to extract and insert information held in the st_other field. */ + +#define ELF32_ST_VISIBILITY(o) ((o) & 0x03) + +/* For ELF64 the definitions are the same. */ +#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o) + +/* Symbol visibility specification encoded in the st_other field. */ +#define STV_DEFAULT 0 /* Default symbol visibility rules */ +#define STV_INTERNAL 1 /* Processor specific hidden class */ +#define STV_HIDDEN 2 /* Sym unavailable in other modules */ +#define STV_PROTECTED 3 /* Not preemptible, not exported */ + + +/* Relocation table entry without addend (in section of type SHT_REL). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ +} Elf32_Rel; + +/* I have seen two different definitions of the Elf64_Rel and + Elf64_Rela structures, so we'll leave them out until Novell (or + whoever) gets their act together. */ +/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */ + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ +} Elf64_Rel; + +/* Relocation table entry with addend (in section of type SHT_RELA). */ + +typedef struct +{ + Elf32_Addr r_offset; /* Address */ + Elf32_Word r_info; /* Relocation type and symbol index */ + Elf32_Sword r_addend; /* Addend */ +} Elf32_Rela; + +typedef struct +{ + Elf64_Addr r_offset; /* Address */ + Elf64_Xword r_info; /* Relocation type and symbol index */ + Elf64_Sxword r_addend; /* Addend */ +} Elf64_Rela; + +/* How to extract and insert information held in the r_info field. */ + +#define ELF32_R_SYM(val) ((val) >> 8) +#define ELF32_R_TYPE(val) ((val) & 0xff) +#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff)) + +#define ELF64_R_SYM(i) ((i) >> 32) +#define ELF64_R_TYPE(i) ((i) & 0xffffffff) +#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type)) + +/* Program segment header. */ + +typedef struct +{ + Elf32_Word p_type; /* Segment type */ + Elf32_Off p_offset; /* Segment file offset */ + Elf32_Addr p_vaddr; /* Segment virtual address */ + Elf32_Addr p_paddr; /* Segment physical address */ + Elf32_Word p_filesz; /* Segment size in file */ + Elf32_Word p_memsz; /* Segment size in memory */ + Elf32_Word p_flags; /* Segment flags */ + Elf32_Word p_align; /* Segment alignment */ +} Elf32_Phdr; + +typedef struct +{ + Elf64_Word p_type; /* Segment type */ + Elf64_Word p_flags; /* Segment flags */ + Elf64_Off p_offset; /* Segment file offset */ + Elf64_Addr p_vaddr; /* Segment virtual address */ + Elf64_Addr p_paddr; /* Segment physical address */ + Elf64_Xword p_filesz; /* Segment size in file */ + Elf64_Xword p_memsz; /* Segment size in memory */ + Elf64_Xword p_align; /* Segment alignment */ +} Elf64_Phdr; + +/* Legal values for p_type (segment type). */ + +#define PT_NULL 0 /* Program header table entry unused */ +#define PT_LOAD 1 /* Loadable program segment */ +#define PT_DYNAMIC 2 /* Dynamic linking information */ +#define PT_INTERP 3 /* Program interpreter */ +#define PT_NOTE 4 /* Auxiliary information */ +#define PT_SHLIB 5 /* Reserved */ +#define PT_PHDR 6 /* Entry for header table itself */ +#define PT_TLS 7 /* Thread-local storage segment */ +#define PT_NUM 8 /* Number of defined types */ +#define PT_LOOS 0x60000000 /* Start of OS-specific */ +#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */ +#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */ +#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */ +#define PT_LOSUNW 0x6ffffffa +#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */ +#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */ +#define PT_HISUNW 0x6fffffff +#define PT_HIOS 0x6fffffff /* End of OS-specific */ +#define PT_LOPROC 0x70000000 /* Start of processor-specific */ +#define PT_HIPROC 0x7fffffff /* End of processor-specific */ + +/* Legal values for p_flags (segment flags). */ + +#define PF_X (1 << 0) /* Segment is executable */ +#define PF_W (1 << 1) /* Segment is writable */ +#define PF_R (1 << 2) /* Segment is readable */ +#define PF_MASKOS 0x0ff00000 /* OS-specific */ +#define PF_MASKPROC 0xf0000000 /* Processor-specific */ + +/* Legal values for note segment descriptor types for core files. */ + +#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */ +#define NT_FPREGSET 2 /* Contains copy of fpregset struct */ +#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */ +#define NT_PRXREG 4 /* Contains copy of prxregset struct */ +#define NT_TASKSTRUCT 4 /* Contains copy of task structure */ +#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */ +#define NT_AUXV 6 /* Contains copy of auxv array */ +#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */ +#define NT_ASRS 8 /* Contains copy of asrset struct */ +#define NT_PSTATUS 10 /* Contains copy of pstatus struct */ +#define NT_PSINFO 13 /* Contains copy of psinfo struct */ +#define NT_PRCRED 14 /* Contains copy of prcred struct */ +#define NT_UTSNAME 15 /* Contains copy of utsname struct */ +#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */ +#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */ +#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */ +#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */ +#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */ +#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */ +#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */ + +/* Legal values for the note segment descriptor types for object files. */ + +#define NT_VERSION 1 /* Contains a version string. */ + + +/* Dynamic section entry. */ + +typedef struct +{ + Elf32_Sword d_tag; /* Dynamic entry type */ + union + { + Elf32_Word d_val; /* Integer value */ + Elf32_Addr d_ptr; /* Address value */ + } d_un; +} Elf32_Dyn; + +typedef struct +{ + Elf64_Sxword d_tag; /* Dynamic entry type */ + union + { + Elf64_Xword d_val; /* Integer value */ + Elf64_Addr d_ptr; /* Address value */ + } d_un; +} Elf64_Dyn; + +/* Legal values for d_tag (dynamic entry type). */ + +#define DT_NULL 0 /* Marks end of dynamic section */ +#define DT_NEEDED 1 /* Name of needed library */ +#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */ +#define DT_PLTGOT 3 /* Processor defined value */ +#define DT_HASH 4 /* Address of symbol hash table */ +#define DT_STRTAB 5 /* Address of string table */ +#define DT_SYMTAB 6 /* Address of symbol table */ +#define DT_RELA 7 /* Address of Rela relocs */ +#define DT_RELASZ 8 /* Total size of Rela relocs */ +#define DT_RELAENT 9 /* Size of one Rela reloc */ +#define DT_STRSZ 10 /* Size of string table */ +#define DT_SYMENT 11 /* Size of one symbol table entry */ +#define DT_INIT 12 /* Address of init function */ +#define DT_FINI 13 /* Address of termination function */ +#define DT_SONAME 14 /* Name of shared object */ +#define DT_RPATH 15 /* Library search path (deprecated) */ +#define DT_SYMBOLIC 16 /* Start symbol search here */ +#define DT_REL 17 /* Address of Rel relocs */ +#define DT_RELSZ 18 /* Total size of Rel relocs */ +#define DT_RELENT 19 /* Size of one Rel reloc */ +#define DT_PLTREL 20 /* Type of reloc in PLT */ +#define DT_DEBUG 21 /* For debugging; unspecified */ +#define DT_TEXTREL 22 /* Reloc might modify .text */ +#define DT_JMPREL 23 /* Address of PLT relocs */ +#define DT_BIND_NOW 24 /* Process relocations of object */ +#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */ +#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */ +#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */ +#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */ +#define DT_RUNPATH 29 /* Library search path */ +#define DT_FLAGS 30 /* Flags for the object being loaded */ +#define DT_ENCODING 32 /* Start of encoded range */ +#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/ +#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */ +#define DT_NUM 34 /* Number used */ +#define DT_LOOS 0x6000000d /* Start of OS-specific */ +#define DT_HIOS 0x6ffff000 /* End of OS-specific */ +#define DT_LOPROC 0x70000000 /* Start of processor-specific */ +#define DT_HIPROC 0x7fffffff /* End of processor-specific */ +#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */ + +/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the + Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's + approach. */ +#define DT_VALRNGLO 0x6ffffd00 +#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */ +#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */ +#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */ +#define DT_CHECKSUM 0x6ffffdf8 +#define DT_PLTPADSZ 0x6ffffdf9 +#define DT_MOVEENT 0x6ffffdfa +#define DT_MOVESZ 0x6ffffdfb +#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */ +#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting + the following DT_* entry. */ +#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */ +#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */ +#define DT_VALRNGHI 0x6ffffdff +#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */ +#define DT_VALNUM 12 + +/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the + Dyn.d_un.d_ptr field of the Elf*_Dyn structure. + + If any adjustment is made to the ELF object after it has been + built these entries will need to be adjusted. */ +#define DT_ADDRRNGLO 0x6ffffe00 +#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */ +#define DT_TLSDESC_PLT 0x6ffffef6 +#define DT_TLSDESC_GOT 0x6ffffef7 +#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */ +#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */ +#define DT_CONFIG 0x6ffffefa /* Configuration information. */ +#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */ +#define DT_AUDIT 0x6ffffefc /* Object auditing. */ +#define DT_PLTPAD 0x6ffffefd /* PLT padding. */ +#define DT_MOVETAB 0x6ffffefe /* Move table. */ +#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */ +#define DT_ADDRRNGHI 0x6ffffeff +#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */ +#define DT_ADDRNUM 11 + +/* The versioning entry types. The next are defined as part of the + GNU extension. */ +#define DT_VERSYM 0x6ffffff0 + +#define DT_RELACOUNT 0x6ffffff9 +#define DT_RELCOUNT 0x6ffffffa + +/* These were chosen by Sun. */ +#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */ +#define DT_VERDEF 0x6ffffffc /* Address of version definition + table */ +#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */ +#define DT_VERNEED 0x6ffffffe /* Address of table with needed + versions */ +#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */ +#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */ +#define DT_VERSIONTAGNUM 16 + +/* Sun added these machine-independent extensions in the "processor-specific" + range. Be compatible. */ +#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */ +#define DT_FILTER 0x7fffffff /* Shared object to get values from */ +#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1) +#define DT_EXTRANUM 3 + +/* Values of `d_un.d_val' in the DT_FLAGS entry. */ +#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */ +#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */ +#define DF_TEXTREL 0x00000004 /* Object contains text relocations */ +#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */ +#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */ + +/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 + entry in the dynamic section. */ +#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */ +#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */ +#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */ +#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/ +#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/ +#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/ +#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */ +#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */ +#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */ +#define DF_1_TRANS 0x00000200 +#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */ +#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */ +#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */ +#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/ +#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */ +#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */ +#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ + +/* Flags for the feature selection in DT_FEATURE_1. */ +#define DTF_1_PARINIT 0x00000001 +#define DTF_1_CONFEXP 0x00000002 + +/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */ +#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */ +#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not + generally available. */ + +/* Version definition sections. */ + +typedef struct +{ + Elf32_Half vd_version; /* Version revision */ + Elf32_Half vd_flags; /* Version information */ + Elf32_Half vd_ndx; /* Version Index */ + Elf32_Half vd_cnt; /* Number of associated aux entries */ + Elf32_Word vd_hash; /* Version name hash value */ + Elf32_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf32_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf32_Verdef; + +typedef struct +{ + Elf64_Half vd_version; /* Version revision */ + Elf64_Half vd_flags; /* Version information */ + Elf64_Half vd_ndx; /* Version Index */ + Elf64_Half vd_cnt; /* Number of associated aux entries */ + Elf64_Word vd_hash; /* Version name hash value */ + Elf64_Word vd_aux; /* Offset in bytes to verdaux array */ + Elf64_Word vd_next; /* Offset in bytes to next verdef + entry */ +} Elf64_Verdef; + + +/* Legal values for vd_version (version revision). */ +#define VER_DEF_NONE 0 /* No version */ +#define VER_DEF_CURRENT 1 /* Current version */ +#define VER_DEF_NUM 2 /* Given version number */ + +/* Legal values for vd_flags (version information flags). */ +#define VER_FLG_BASE 0x1 /* Version definition of file itself */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + +/* Versym symbol index values. */ +#define VER_NDX_LOCAL 0 /* Symbol is local. */ +#define VER_NDX_GLOBAL 1 /* Symbol is global. */ +#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */ +#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */ + +/* Auxialiary version information. */ + +typedef struct +{ + Elf32_Word vda_name; /* Version or dependency names */ + Elf32_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf32_Verdaux; + +typedef struct +{ + Elf64_Word vda_name; /* Version or dependency names */ + Elf64_Word vda_next; /* Offset in bytes to next verdaux + entry */ +} Elf64_Verdaux; + + +/* Version dependency section. */ + +typedef struct +{ + Elf32_Half vn_version; /* Version of structure */ + Elf32_Half vn_cnt; /* Number of associated aux entries */ + Elf32_Word vn_file; /* Offset of filename for this + dependency */ + Elf32_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf32_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf32_Verneed; + +typedef struct +{ + Elf64_Half vn_version; /* Version of structure */ + Elf64_Half vn_cnt; /* Number of associated aux entries */ + Elf64_Word vn_file; /* Offset of filename for this + dependency */ + Elf64_Word vn_aux; /* Offset in bytes to vernaux array */ + Elf64_Word vn_next; /* Offset in bytes to next verneed + entry */ +} Elf64_Verneed; + + +/* Legal values for vn_version (version revision). */ +#define VER_NEED_NONE 0 /* No version */ +#define VER_NEED_CURRENT 1 /* Current version */ +#define VER_NEED_NUM 2 /* Given version number */ + +/* Auxiliary needed version information. */ + +typedef struct +{ + Elf32_Word vna_hash; /* Hash value of dependency name */ + Elf32_Half vna_flags; /* Dependency specific information */ + Elf32_Half vna_other; /* Unused */ + Elf32_Word vna_name; /* Dependency name string offset */ + Elf32_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf32_Vernaux; + +typedef struct +{ + Elf64_Word vna_hash; /* Hash value of dependency name */ + Elf64_Half vna_flags; /* Dependency specific information */ + Elf64_Half vna_other; /* Unused */ + Elf64_Word vna_name; /* Dependency name string offset */ + Elf64_Word vna_next; /* Offset in bytes to next vernaux + entry */ +} Elf64_Vernaux; + + +/* Legal values for vna_flags. */ +#define VER_FLG_WEAK 0x2 /* Weak version identifier */ + + +/* Auxiliary vector. */ + +/* This vector is normally only used by the program interpreter. The + usual definition in an ABI supplement uses the name auxv_t. The + vector is not usually defined in a standard file, but it + can't hurt. We rename it to avoid conflicts. The sizes of these + types are an arrangement between the exec server and the program + interpreter, so we don't fully specify them here. */ + +typedef struct +{ + uint32_t a_type; /* Entry type */ + union + { + uint32_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + uint64_t a_type; /* Entry type */ + union + { + uint64_t a_val; /* Integer value */ + /* We use to have pointer elements added here. We cannot do that, + though, since it does not work when using 32-bit definitions + on 64-bit platforms and vice versa. */ + } a_un; +} Elf64_auxv_t; + +/* Legal values for a_type (entry type). */ + +#define AT_NULL 0 /* End of vector */ +#define AT_IGNORE 1 /* Entry should be ignored */ +#define AT_EXECFD 2 /* File descriptor of program */ +#define AT_PHDR 3 /* Program headers for program */ +#define AT_PHENT 4 /* Size of program header entry */ +#define AT_PHNUM 5 /* Number of program headers */ +#define AT_PAGESZ 6 /* System page size */ +#define AT_BASE 7 /* Base address of interpreter */ +#define AT_FLAGS 8 /* Flags */ +#define AT_ENTRY 9 /* Entry point of program */ +#define AT_NOTELF 10 /* Program is not ELF */ +#define AT_UID 11 /* Real uid */ +#define AT_EUID 12 /* Effective uid */ +#define AT_GID 13 /* Real gid */ +#define AT_EGID 14 /* Effective gid */ +#define AT_CLKTCK 17 /* Frequency of times() */ + +/* Some more special a_type values describing the hardware. */ +#define AT_PLATFORM 15 /* String identifying platform. */ +#define AT_HWCAP 16 /* Machine dependent hints about + processor capabilities. */ + +/* This entry gives some information about the FPU initialization + performed by the kernel. */ +#define AT_FPUCW 18 /* Used FPU control word. */ + +/* Cache block sizes. */ +#define AT_DCACHEBSIZE 19 /* Data cache block size. */ +#define AT_ICACHEBSIZE 20 /* Instruction cache block size. */ +#define AT_UCACHEBSIZE 21 /* Unified cache block size. */ + +/* A special ignored value for PPC, used by the kernel to control the + interpretation of the AUXV. Must be > 16. */ +#define AT_IGNOREPPC 22 /* Entry should be ignored. */ + +#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ + +#define AT_EXECFN 31 /* Filename of executable. */ + +/* Pointer to the global system page used for system calls and other + nice things. */ +#define AT_SYSINFO 32 +#define AT_SYSINFO_EHDR 33 + +/* Shapes of the caches. Bits 0-3 contains associativity; bits 4-7 contains + log2 of line size; mask those to get cache size. */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 +#define AT_L3_CACHESHAPE 37 + +/* Note section contents. Each entry in the note section begins with + a header of a fixed form. */ + +typedef struct +{ + Elf32_Word n_namesz; /* Length of the note's name. */ + Elf32_Word n_descsz; /* Length of the note's descriptor. */ + Elf32_Word n_type; /* Type of the note. */ +} Elf32_Nhdr; + +typedef struct +{ + Elf64_Word n_namesz; /* Length of the note's name. */ + Elf64_Word n_descsz; /* Length of the note's descriptor. */ + Elf64_Word n_type; /* Type of the note. */ +} Elf64_Nhdr; + +/* Known names of notes. */ + +/* Solaris entries in the note section have this name. */ +#define ELF_NOTE_SOLARIS "SUNW Solaris" + +/* Note entries for GNU systems have this name. */ +#define ELF_NOTE_GNU "GNU" + + +/* Defined types of notes for Solaris. */ + +/* Value of descriptor (one word) is desired pagesize for the binary. */ +#define ELF_NOTE_PAGESIZE_HINT 1 + + +/* Defined note types for GNU systems. */ + +/* ABI information. The descriptor consists of words: + word 0: OS descriptor + word 1: major version of the ABI + word 2: minor version of the ABI + word 3: subminor version of the ABI +*/ +#define NT_GNU_ABI_TAG 1 +#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */ + +/* Known OSes. These values can appear in word 0 of an + NT_GNU_ABI_TAG note section entry. */ +#define ELF_NOTE_OS_LINUX 0 +#define ELF_NOTE_OS_GNU 1 +#define ELF_NOTE_OS_SOLARIS2 2 +#define ELF_NOTE_OS_FREEBSD 3 + +/* Synthetic hwcap information. The descriptor begins with two words: + word 0: number of entries + word 1: bitmask of enabled entries + Then follow variable-length entries, one byte followed by a + '\0'-terminated hwcap name string. The byte gives the bit + number to test if enabled, (1U << bit) & bitmask. */ +#define NT_GNU_HWCAP 2 + +/* Build ID bits as generated by ld --build-id. + The descriptor consists of any nonzero number of bytes. */ +#define NT_GNU_BUILD_ID 3 + + +/* Move records. */ +typedef struct +{ + Elf32_Xword m_value; /* Symbol value. */ + Elf32_Word m_info; /* Size and index. */ + Elf32_Word m_poffset; /* Symbol offset. */ + Elf32_Half m_repeat; /* Repeat count. */ + Elf32_Half m_stride; /* Stride info. */ +} Elf32_Move; + +typedef struct +{ + Elf64_Xword m_value; /* Symbol value. */ + Elf64_Xword m_info; /* Size and index. */ + Elf64_Xword m_poffset; /* Symbol offset. */ + Elf64_Half m_repeat; /* Repeat count. */ + Elf64_Half m_stride; /* Stride info. */ +} Elf64_Move; + +/* Macro to construct move records. */ +#define ELF32_M_SYM(info) ((info) >> 8) +#define ELF32_M_SIZE(info) ((unsigned char) (info)) +#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size)) + +#define ELF64_M_SYM(info) ELF32_M_SYM (info) +#define ELF64_M_SIZE(info) ELF32_M_SIZE (info) +#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size) + + +/* Motorola 68k specific definitions. */ + +/* Values for Elf32_Ehdr.e_flags. */ +#define EF_CPU32 0x00810000 + +/* m68k relocs. */ + +#define R_68K_NONE 0 /* No reloc */ +#define R_68K_32 1 /* Direct 32 bit */ +#define R_68K_16 2 /* Direct 16 bit */ +#define R_68K_8 3 /* Direct 8 bit */ +#define R_68K_PC32 4 /* PC relative 32 bit */ +#define R_68K_PC16 5 /* PC relative 16 bit */ +#define R_68K_PC8 6 /* PC relative 8 bit */ +#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */ +#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */ +#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */ +#define R_68K_GOT32O 10 /* 32 bit GOT offset */ +#define R_68K_GOT16O 11 /* 16 bit GOT offset */ +#define R_68K_GOT8O 12 /* 8 bit GOT offset */ +#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */ +#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */ +#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */ +#define R_68K_PLT32O 16 /* 32 bit PLT offset */ +#define R_68K_PLT16O 17 /* 16 bit PLT offset */ +#define R_68K_PLT8O 18 /* 8 bit PLT offset */ +#define R_68K_COPY 19 /* Copy symbol at runtime */ +#define R_68K_GLOB_DAT 20 /* Create GOT entry */ +#define R_68K_JMP_SLOT 21 /* Create PLT entry */ +#define R_68K_RELATIVE 22 /* Adjust by program base */ +/* Keep this the last entry. */ +#define R_68K_NUM 23 + +/* Intel 80386 specific definitions. */ + +/* i386 relocs. */ + +#define R_386_NONE 0 /* No reloc */ +#define R_386_32 1 /* Direct 32 bit */ +#define R_386_PC32 2 /* PC relative 32 bit */ +#define R_386_GOT32 3 /* 32 bit GOT entry */ +#define R_386_PLT32 4 /* 32 bit PLT address */ +#define R_386_COPY 5 /* Copy symbol at runtime */ +#define R_386_GLOB_DAT 6 /* Create GOT entry */ +#define R_386_JMP_SLOT 7 /* Create PLT entry */ +#define R_386_RELATIVE 8 /* Adjust by program base */ +#define R_386_GOTOFF 9 /* 32 bit offset to GOT */ +#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */ +#define R_386_32PLT 11 +#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */ +#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS + block offset */ +#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block + offset */ +#define R_386_TLS_LE 17 /* Offset relative to static TLS + block */ +#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of + general dynamic thread local data */ +#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of + local dynamic thread local data + in LE code */ +#define R_386_16 20 +#define R_386_PC16 21 +#define R_386_8 22 +#define R_386_PC8 23 +#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic + thread local data */ +#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */ +#define R_386_TLS_GD_CALL 26 /* Relocation for call to + __tls_get_addr() */ +#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */ +#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic + thread local data in LE code */ +#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */ +#define R_386_TLS_LDM_CALL 30 /* Relocation for call to + __tls_get_addr() in LDM code */ +#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */ +#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */ +#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS + block offset */ +#define R_386_TLS_LE_32 34 /* Negated offset relative to static + TLS block */ +#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */ +#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */ +#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */ +/* 38? */ +#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */ +#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS + descriptor for + relaxation. */ +#define R_386_TLS_DESC 41 /* TLS descriptor containing + pointer to code and to + argument, returning the TLS + offset for the symbol. */ +/* Keep this the last entry. */ +#define R_386_NUM 42 + +/* SUN SPARC specific definitions. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */ + +/* Values for Elf64_Ehdr.e_flags. */ + +#define EF_SPARCV9_MM 3 +#define EF_SPARCV9_TSO 0 +#define EF_SPARCV9_PSO 1 +#define EF_SPARCV9_RMO 2 +#define EF_SPARC_LEDATA 0x800000 /* little endian data */ +#define EF_SPARC_EXT_MASK 0xFFFF00 +#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */ +#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */ +#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */ +#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */ + +/* SPARC relocs. */ + +#define R_SPARC_NONE 0 /* No reloc */ +#define R_SPARC_8 1 /* Direct 8 bit */ +#define R_SPARC_16 2 /* Direct 16 bit */ +#define R_SPARC_32 3 /* Direct 32 bit */ +#define R_SPARC_DISP8 4 /* PC relative 8 bit */ +#define R_SPARC_DISP16 5 /* PC relative 16 bit */ +#define R_SPARC_DISP32 6 /* PC relative 32 bit */ +#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */ +#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */ +#define R_SPARC_HI22 9 /* High 22 bit */ +#define R_SPARC_22 10 /* Direct 22 bit */ +#define R_SPARC_13 11 /* Direct 13 bit */ +#define R_SPARC_LO10 12 /* Truncated 10 bit */ +#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */ +#define R_SPARC_GOT13 14 /* 13 bit GOT entry */ +#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */ +#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */ +#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */ +#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */ +#define R_SPARC_COPY 19 /* Copy symbol at runtime */ +#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */ +#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */ +#define R_SPARC_RELATIVE 22 /* Adjust by program base */ +#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */ + +/* Additional Sparc64 relocs. */ + +#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */ +#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */ +#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */ +#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */ +#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */ +#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */ +#define R_SPARC_10 30 /* Direct 10 bit */ +#define R_SPARC_11 31 /* Direct 11 bit */ +#define R_SPARC_64 32 /* Direct 64 bit */ +#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */ +#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */ +#define R_SPARC_HM10 35 /* High middle 10 bits of ... */ +#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */ +#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */ +#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */ +#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */ +#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */ +#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */ +#define R_SPARC_7 43 /* Direct 7 bit */ +#define R_SPARC_5 44 /* Direct 5 bit */ +#define R_SPARC_6 45 /* Direct 6 bit */ +#define R_SPARC_DISP64 46 /* PC relative 64 bit */ +#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */ +#define R_SPARC_HIX22 48 /* High 22 bit complemented */ +#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */ +#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */ +#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */ +#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */ +#define R_SPARC_REGISTER 53 /* Global register usage */ +#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */ +#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */ +#define R_SPARC_TLS_GD_HI22 56 +#define R_SPARC_TLS_GD_LO10 57 +#define R_SPARC_TLS_GD_ADD 58 +#define R_SPARC_TLS_GD_CALL 59 +#define R_SPARC_TLS_LDM_HI22 60 +#define R_SPARC_TLS_LDM_LO10 61 +#define R_SPARC_TLS_LDM_ADD 62 +#define R_SPARC_TLS_LDM_CALL 63 +#define R_SPARC_TLS_LDO_HIX22 64 +#define R_SPARC_TLS_LDO_LOX10 65 +#define R_SPARC_TLS_LDO_ADD 66 +#define R_SPARC_TLS_IE_HI22 67 +#define R_SPARC_TLS_IE_LO10 68 +#define R_SPARC_TLS_IE_LD 69 +#define R_SPARC_TLS_IE_LDX 70 +#define R_SPARC_TLS_IE_ADD 71 +#define R_SPARC_TLS_LE_HIX22 72 +#define R_SPARC_TLS_LE_LOX10 73 +#define R_SPARC_TLS_DTPMOD32 74 +#define R_SPARC_TLS_DTPMOD64 75 +#define R_SPARC_TLS_DTPOFF32 76 +#define R_SPARC_TLS_DTPOFF64 77 +#define R_SPARC_TLS_TPOFF32 78 +#define R_SPARC_TLS_TPOFF64 79 +/* Keep this the last entry. */ +#define R_SPARC_NUM 80 + +/* For Sparc64, legal values for d_tag of Elf64_Dyn. */ + +#define DT_SPARC_REGISTER 0x70000001 +#define DT_SPARC_NUM 2 + +/* Bits present in AT_HWCAP on SPARC. */ + +#define HWCAP_SPARC_FLUSH 1 /* The CPU supports flush insn. */ +#define HWCAP_SPARC_STBAR 2 +#define HWCAP_SPARC_SWAP 4 +#define HWCAP_SPARC_MULDIV 8 +#define HWCAP_SPARC_V9 16 /* The CPU is v9, so v8plus is ok. */ +#define HWCAP_SPARC_ULTRA3 32 +#define HWCAP_SPARC_BLKINIT 64 /* Sun4v with block-init/load-twin. */ +#define HWCAP_SPARC_N2 128 + +/* MIPS R3000 specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used */ +#define EF_MIPS_PIC 2 /* Contains PIC code */ +#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence */ +#define EF_MIPS_XGOT 8 +#define EF_MIPS_64BIT_WHIRL 16 +#define EF_MIPS_ABI2 32 +#define EF_MIPS_ABI_ON32 64 +#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level */ + +/* Legal values for MIPS architecture level. */ + +#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define EF_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define EF_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* The following are non-official names and should not be used. */ + +#define E_MIPS_ARCH_1 0x00000000 /* -mips1 code. */ +#define E_MIPS_ARCH_2 0x10000000 /* -mips2 code. */ +#define E_MIPS_ARCH_3 0x20000000 /* -mips3 code. */ +#define E_MIPS_ARCH_4 0x30000000 /* -mips4 code. */ +#define E_MIPS_ARCH_5 0x40000000 /* -mips5 code. */ +#define E_MIPS_ARCH_32 0x60000000 /* MIPS32 code. */ +#define E_MIPS_ARCH_64 0x70000000 /* MIPS64 code. */ + +/* Special section indices. */ + +#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols */ +#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */ +#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */ +#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols */ +#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link */ +#define SHT_MIPS_MSYM 0x70000001 +#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols */ +#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes */ +#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */ +#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging information*/ +#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information */ +#define SHT_MIPS_PACKAGE 0x70000007 +#define SHT_MIPS_PACKSYM 0x70000008 +#define SHT_MIPS_RELD 0x70000009 +#define SHT_MIPS_IFACE 0x7000000b +#define SHT_MIPS_CONTENT 0x7000000c +#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */ +#define SHT_MIPS_SHDR 0x70000010 +#define SHT_MIPS_FDESC 0x70000011 +#define SHT_MIPS_EXTSYM 0x70000012 +#define SHT_MIPS_DENSE 0x70000013 +#define SHT_MIPS_PDESC 0x70000014 +#define SHT_MIPS_LOCSYM 0x70000015 +#define SHT_MIPS_AUXSYM 0x70000016 +#define SHT_MIPS_OPTSYM 0x70000017 +#define SHT_MIPS_LOCSTR 0x70000018 +#define SHT_MIPS_LINE 0x70000019 +#define SHT_MIPS_RFDESC 0x7000001a +#define SHT_MIPS_DELTASYM 0x7000001b +#define SHT_MIPS_DELTAINST 0x7000001c +#define SHT_MIPS_DELTACLASS 0x7000001d +#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */ +#define SHT_MIPS_DELTADECL 0x7000001f +#define SHT_MIPS_SYMBOL_LIB 0x70000020 +#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */ +#define SHT_MIPS_TRANSLATE 0x70000022 +#define SHT_MIPS_PIXIE 0x70000023 +#define SHT_MIPS_XLATE 0x70000024 +#define SHT_MIPS_XLATE_DEBUG 0x70000025 +#define SHT_MIPS_WHIRL 0x70000026 +#define SHT_MIPS_EH_REGION 0x70000027 +#define SHT_MIPS_XLATE_OLD 0x70000028 +#define SHT_MIPS_PDR_EXCEPTION 0x70000029 + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_MIPS_GPREL 0x10000000 /* Must be part of global data area */ +#define SHF_MIPS_MERGE 0x20000000 +#define SHF_MIPS_ADDR 0x40000000 +#define SHF_MIPS_STRINGS 0x80000000 +#define SHF_MIPS_NOSTRIP 0x08000000 +#define SHF_MIPS_LOCAL 0x04000000 +#define SHF_MIPS_NAMES 0x02000000 +#define SHF_MIPS_NODUPE 0x01000000 + + +/* Symbol tables. */ + +/* MIPS specific values for `st_other'. */ +#define STO_MIPS_DEFAULT 0x0 +#define STO_MIPS_INTERNAL 0x1 +#define STO_MIPS_HIDDEN 0x2 +#define STO_MIPS_PROTECTED 0x3 +#define STO_MIPS_PLT 0x8 +#define STO_MIPS_SC_ALIGN_UNUSED 0xff + +/* MIPS specific values for `st_info'. */ +#define STB_MIPS_SPLIT_COMMON 13 + +/* Entries found in sections of type SHT_MIPS_GPTAB. */ + +typedef union +{ + struct + { + Elf32_Word gt_current_g_value; /* -G value used for compilation */ + Elf32_Word gt_unused; /* Not used */ + } gt_header; /* First entry in section */ + struct + { + Elf32_Word gt_g_value; /* If this value were used for -G */ + Elf32_Word gt_bytes; /* This many bytes would be used */ + } gt_entry; /* Subsequent entries in section */ +} Elf32_gptab; + +/* Entry found in sections of type SHT_MIPS_REGINFO. */ + +typedef struct +{ + Elf32_Word ri_gprmask; /* General registers used */ + Elf32_Word ri_cprmask[4]; /* Coprocessor registers used */ + Elf32_Sword ri_gp_value; /* $gp register value */ +} Elf32_RegInfo; + +/* Entries found in sections of type SHT_MIPS_OPTIONS. */ + +typedef struct +{ + unsigned char kind; /* Determines interpretation of the + variable part of descriptor. */ + unsigned char size; /* Size of descriptor, including header. */ + Elf32_Section section; /* Section header index of section affected, + 0 for global options. */ + Elf32_Word info; /* Kind-specific information. */ +} Elf_Options; + +/* Values for `kind' field in Elf_Options. */ + +#define ODK_NULL 0 /* Undefined. */ +#define ODK_REGINFO 1 /* Register usage information. */ +#define ODK_EXCEPTIONS 2 /* Exception processing options. */ +#define ODK_PAD 3 /* Section padding options. */ +#define ODK_HWPATCH 4 /* Hardware workarounds performed */ +#define ODK_FILL 5 /* record the fill value used by the linker. */ +#define ODK_TAGS 6 /* reserve space for desktop tools to write. */ +#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */ +#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */ + +/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */ + +#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */ +#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */ +#define OEX_PAGE0 0x10000 /* page zero must be mapped. */ +#define OEX_SMM 0x20000 /* Force sequential memory mode? */ +#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */ +#define OEX_PRECISEFP OEX_FPDBUG +#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */ + +#define OEX_FPU_INVAL 0x10 +#define OEX_FPU_DIV0 0x08 +#define OEX_FPU_OFLO 0x04 +#define OEX_FPU_UFLO 0x02 +#define OEX_FPU_INEX 0x01 + +/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */ + +#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */ +#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */ +#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */ +#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */ + +#define OPAD_PREFIX 0x1 +#define OPAD_POSTFIX 0x2 +#define OPAD_SYMBOL 0x4 + +/* Entry found in `.options' section. */ + +typedef struct +{ + Elf32_Word hwp_flags1; /* Extra flags. */ + Elf32_Word hwp_flags2; /* Extra flags. */ +} Elf_Options_Hw; + +/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */ + +#define OHWA0_R4KEOP_CHECKED 0x00000001 +#define OHWA1_R4KEOP_CLEAN 0x00000002 + +/* MIPS relocs. */ + +#define R_MIPS_NONE 0 /* No reloc */ +#define R_MIPS_16 1 /* Direct 16 bit */ +#define R_MIPS_32 2 /* Direct 32 bit */ +#define R_MIPS_REL32 3 /* PC relative 32 bit */ +#define R_MIPS_26 4 /* Direct 26 bit shifted */ +#define R_MIPS_HI16 5 /* High 16 bit */ +#define R_MIPS_LO16 6 /* Low 16 bit */ +#define R_MIPS_GPREL16 7 /* GP relative 16 bit */ +#define R_MIPS_LITERAL 8 /* 16 bit literal entry */ +#define R_MIPS_GOT16 9 /* 16 bit GOT entry */ +#define R_MIPS_PC16 10 /* PC relative 16 bit */ +#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */ +#define R_MIPS_GPREL32 12 /* GP relative 32 bit */ + +#define R_MIPS_SHIFT5 16 +#define R_MIPS_SHIFT6 17 +#define R_MIPS_64 18 +#define R_MIPS_GOT_DISP 19 +#define R_MIPS_GOT_PAGE 20 +#define R_MIPS_GOT_OFST 21 +#define R_MIPS_GOT_HI16 22 +#define R_MIPS_GOT_LO16 23 +#define R_MIPS_SUB 24 +#define R_MIPS_INSERT_A 25 +#define R_MIPS_INSERT_B 26 +#define R_MIPS_DELETE 27 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_CALL_HI16 30 +#define R_MIPS_CALL_LO16 31 +#define R_MIPS_SCN_DISP 32 +#define R_MIPS_REL16 33 +#define R_MIPS_ADD_IMMEDIATE 34 +#define R_MIPS_PJUMP 35 +#define R_MIPS_RELGOT 36 +#define R_MIPS_JALR 37 +#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */ +#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */ +#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */ +#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */ +#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */ +#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */ +#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */ +#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */ +#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */ +#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */ +#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */ +#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */ +#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */ +#define R_MIPS_GLOB_DAT 51 +#define R_MIPS_COPY 126 +#define R_MIPS_JUMP_SLOT 127 +/* Keep this the last entry. */ +#define R_MIPS_NUM 128 + +/* Legal values for p_type field of Elf32_Phdr. */ + +#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */ +#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ +#define PT_MIPS_OPTIONS 0x70000002 + +/* Special program header types. */ + +#define PF_MIPS_LOCAL 0x10000000 + +/* Legal values for d_tag field of Elf32_Dyn. */ + +#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */ +#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */ +#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */ +#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */ +#define DT_MIPS_FLAGS 0x70000005 /* Flags */ +#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */ +#define DT_MIPS_MSYM 0x70000007 +#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */ +#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */ +#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */ +#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */ +#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */ +#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */ +#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */ +#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */ +#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */ +#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */ +#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */ +#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in + DT_MIPS_DELTA_CLASS. */ +#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */ +#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in + DT_MIPS_DELTA_INSTANCE. */ +#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */ +#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in + DT_MIPS_DELTA_RELOC. */ +#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta + relocations refer to. */ +#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in + DT_MIPS_DELTA_SYM. */ +#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the + class declaration. */ +#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in + DT_MIPS_DELTA_CLASSSYM. */ +#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */ +#define DT_MIPS_PIXIE_INIT 0x70000023 +#define DT_MIPS_SYMBOL_LIB 0x70000024 +#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025 +#define DT_MIPS_LOCAL_GOTIDX 0x70000026 +#define DT_MIPS_HIDDEN_GOTIDX 0x70000027 +#define DT_MIPS_PROTECTED_GOTIDX 0x70000028 +#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */ +#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */ +#define DT_MIPS_DYNSTR_ALIGN 0x7000002b +#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */ +#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve + function stored in GOT. */ +#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added + by rld on dlopen() calls. */ +#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */ +#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */ +#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */ +/* The address of .got.plt in an executable using the new non-PIC ABI. */ +#define DT_MIPS_PLTGOT 0x70000032 +/* The base of the PLT in an executable using the new non-PIC ABI if that + PLT is writable. For a non-writable PLT, this is omitted or has a zero + value. */ +#define DT_MIPS_RWPLT 0x70000034 +#define DT_MIPS_NUM 0x35 + +/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */ + +#define RHF_NONE 0 /* No flags */ +#define RHF_QUICKSTART (1 << 0) /* Use quickstart */ +#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */ +#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */ +#define RHF_NO_MOVE (1 << 3) +#define RHF_SGI_ONLY (1 << 4) +#define RHF_GUARANTEE_INIT (1 << 5) +#define RHF_DELTA_C_PLUS_PLUS (1 << 6) +#define RHF_GUARANTEE_START_INIT (1 << 7) +#define RHF_PIXIE (1 << 8) +#define RHF_DEFAULT_DELAY_LOAD (1 << 9) +#define RHF_REQUICKSTART (1 << 10) +#define RHF_REQUICKSTARTED (1 << 11) +#define RHF_CORD (1 << 12) +#define RHF_NO_UNRES_UNDEF (1 << 13) +#define RHF_RLD_ORDER_SAFE (1 << 14) + +/* Entries found in sections of type SHT_MIPS_LIBLIST. */ + +typedef struct +{ + Elf32_Word l_name; /* Name (string table index) */ + Elf32_Word l_time_stamp; /* Timestamp */ + Elf32_Word l_checksum; /* Checksum */ + Elf32_Word l_version; /* Interface version */ + Elf32_Word l_flags; /* Flags */ +} Elf32_Lib; + +typedef struct +{ + Elf64_Word l_name; /* Name (string table index) */ + Elf64_Word l_time_stamp; /* Timestamp */ + Elf64_Word l_checksum; /* Checksum */ + Elf64_Word l_version; /* Interface version */ + Elf64_Word l_flags; /* Flags */ +} Elf64_Lib; + + +/* Legal values for l_flags. */ + +#define LL_NONE 0 +#define LL_EXACT_MATCH (1 << 0) /* Require exact match */ +#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */ +#define LL_REQUIRE_MINOR (1 << 2) +#define LL_EXPORTS (1 << 3) +#define LL_DELAY_LOAD (1 << 4) +#define LL_DELTA (1 << 5) + +/* Entries found in sections of type SHT_MIPS_CONFLICT. */ + +typedef Elf32_Addr Elf32_Conflict; + + +/* HPPA specific definitions. */ + +/* Legal values for e_flags field of Elf32_Ehdr. */ + +#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */ +#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */ +#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */ +#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */ +#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch + prediction. */ +#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */ +#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */ + +/* Defined values for `e_flags & EF_PARISC_ARCH' are: */ + +#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */ +#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */ +#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */ + +/* Additional section indeces. */ + +#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared + symbols in ANSI C. */ +#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */ + +/* Legal values for sh_type field of Elf32_Shdr. */ + +#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */ +#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */ +#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */ + +/* Legal values for sh_flags field of Elf32_Shdr. */ + +#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */ +#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */ +#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */ + +/* Legal values for ST_TYPE subfield of st_info (symbol type). */ + +#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */ + +#define STT_HP_OPAQUE (STT_LOOS + 0x1) +#define STT_HP_STUB (STT_LOOS + 0x2) + +/* HPPA relocs. */ + +#define R_PARISC_NONE 0 /* No reloc. */ +#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */ +#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */ +#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */ +#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */ +#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */ +#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */ +#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */ +#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */ +#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */ +#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */ +#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */ +#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */ +#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */ +#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */ +#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */ +#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */ +#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */ +#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */ +#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */ +#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */ +#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */ +#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */ +#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */ +#define R_PARISC_FPTR64 64 /* 64 bits function address. */ +#define R_PARISC_PLABEL32 65 /* 32 bits function address. */ +#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */ +#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */ +#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */ +#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */ +#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */ +#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */ +#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */ +#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */ +#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */ +#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */ +#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */ +#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */ +#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */ +#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */ +#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */ +#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */ +#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */ +#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */ +#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */ +#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */ +#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */ +#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */ +#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */ +#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */ +#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */ +#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */ +#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */ +#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */ +#define R_PARISC_LORESERVE 128 +#define R_PARISC_COPY 128 /* Copy relocation. */ +#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */ +#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */ +#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */ +#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */ +#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */ +#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */ +#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */ +#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */ +#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */ +#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */ +#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/ +#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */ +#define R_PARISC_GNU_VTENTRY 232 +#define R_PARISC_GNU_VTINHERIT 233 +#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */ +#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */ +#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */ +#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */ +#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */ +#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */ +#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */ +#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */ +#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */ +#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */ +#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */ +#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L +#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R +#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L +#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R +#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32 +#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64 +#define R_PARISC_HIRESERVE 255 + +/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */ + +#define PT_HP_TLS (PT_LOOS + 0x0) +#define PT_HP_CORE_NONE (PT_LOOS + 0x1) +#define PT_HP_CORE_VERSION (PT_LOOS + 0x2) +#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3) +#define PT_HP_CORE_COMM (PT_LOOS + 0x4) +#define PT_HP_CORE_PROC (PT_LOOS + 0x5) +#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6) +#define PT_HP_CORE_STACK (PT_LOOS + 0x7) +#define PT_HP_CORE_SHM (PT_LOOS + 0x8) +#define PT_HP_CORE_MMF (PT_LOOS + 0x9) +#define PT_HP_PARALLEL (PT_LOOS + 0x10) +#define PT_HP_FASTBIND (PT_LOOS + 0x11) +#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12) +#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13) +#define PT_HP_STACK (PT_LOOS + 0x14) + +#define PT_PARISC_ARCHEXT 0x70000000 +#define PT_PARISC_UNWIND 0x70000001 + +/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */ + +#define PF_PARISC_SBP 0x08000000 + +#define PF_HP_PAGE_SIZE 0x00100000 +#define PF_HP_FAR_SHARED 0x00200000 +#define PF_HP_NEAR_SHARED 0x00400000 +#define PF_HP_CODE 0x01000000 +#define PF_HP_MODIFY 0x02000000 +#define PF_HP_LAZYSWAP 0x04000000 +#define PF_HP_SBP 0x08000000 + + +/* Alpha specific definitions. */ + +/* Legal values for e_flags field of Elf64_Ehdr. */ + +#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */ +#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */ + +/* Legal values for sh_type field of Elf64_Shdr. */ + +/* These two are primerily concerned with ECOFF debugging info. */ +#define SHT_ALPHA_DEBUG 0x70000001 +#define SHT_ALPHA_REGINFO 0x70000002 + +/* Legal values for sh_flags field of Elf64_Shdr. */ + +#define SHF_ALPHA_GPREL 0x10000000 + +/* Legal values for st_other field of Elf64_Sym. */ +#define STO_ALPHA_NOPV 0x80 /* No PV required. */ +#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */ + +/* Alpha relocs. */ + +#define R_ALPHA_NONE 0 /* No reloc */ +#define R_ALPHA_REFLONG 1 /* Direct 32 bit */ +#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */ +#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */ +#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */ +#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */ +#define R_ALPHA_GPDISP 6 /* Add displacement to GP */ +#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */ +#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */ +#define R_ALPHA_SREL16 9 /* PC relative 16 bit */ +#define R_ALPHA_SREL32 10 /* PC relative 32 bit */ +#define R_ALPHA_SREL64 11 /* PC relative 64 bit */ +#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */ +#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */ +#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */ +#define R_ALPHA_COPY 24 /* Copy symbol at runtime */ +#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */ +#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */ +#define R_ALPHA_RELATIVE 27 /* Adjust by program base */ +#define R_ALPHA_TLS_GD_HI 28 +#define R_ALPHA_TLSGD 29 +#define R_ALPHA_TLS_LDM 30 +#define R_ALPHA_DTPMOD64 31 +#define R_ALPHA_GOTDTPREL 32 +#define R_ALPHA_DTPREL64 33 +#define R_ALPHA_DTPRELHI 34 +#define R_ALPHA_DTPRELLO 35 +#define R_ALPHA_DTPREL16 36 +#define R_ALPHA_GOTTPREL 37 +#define R_ALPHA_TPREL64 38 +#define R_ALPHA_TPRELHI 39 +#define R_ALPHA_TPRELLO 40 +#define R_ALPHA_TPREL16 41 +/* Keep this the last entry. */ +#define R_ALPHA_NUM 46 + +/* Magic values of the LITUSE relocation addend. */ +#define LITUSE_ALPHA_ADDR 0 +#define LITUSE_ALPHA_BASE 1 +#define LITUSE_ALPHA_BYTOFF 2 +#define LITUSE_ALPHA_JSR 3 +#define LITUSE_ALPHA_TLS_GD 4 +#define LITUSE_ALPHA_TLS_LDM 5 + +/* Legal values for d_tag of Elf64_Dyn. */ +#define DT_ALPHA_PLTRO (DT_LOPROC + 0) +#define DT_ALPHA_NUM 1 + +/* PowerPC specific declarations */ + +/* Values for Elf32/64_Ehdr.e_flags. */ +#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */ + +/* Cygnus local bits below */ +#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/ +#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib + flag */ + +/* PowerPC relocations defined by the ABIs */ +#define R_PPC_NONE 0 +#define R_PPC_ADDR32 1 /* 32bit absolute address */ +#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */ +#define R_PPC_ADDR16 3 /* 16bit absolute address */ +#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */ +#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */ +#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */ +#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */ +#define R_PPC_ADDR14_BRTAKEN 8 +#define R_PPC_ADDR14_BRNTAKEN 9 +#define R_PPC_REL24 10 /* PC relative 26 bit */ +#define R_PPC_REL14 11 /* PC relative 16 bit */ +#define R_PPC_REL14_BRTAKEN 12 +#define R_PPC_REL14_BRNTAKEN 13 +#define R_PPC_GOT16 14 +#define R_PPC_GOT16_LO 15 +#define R_PPC_GOT16_HI 16 +#define R_PPC_GOT16_HA 17 +#define R_PPC_PLTREL24 18 +#define R_PPC_COPY 19 +#define R_PPC_GLOB_DAT 20 +#define R_PPC_JMP_SLOT 21 +#define R_PPC_RELATIVE 22 +#define R_PPC_LOCAL24PC 23 +#define R_PPC_UADDR32 24 +#define R_PPC_UADDR16 25 +#define R_PPC_REL32 26 +#define R_PPC_PLT32 27 +#define R_PPC_PLTREL32 28 +#define R_PPC_PLT16_LO 29 +#define R_PPC_PLT16_HI 30 +#define R_PPC_PLT16_HA 31 +#define R_PPC_SDAREL16 32 +#define R_PPC_SECTOFF 33 +#define R_PPC_SECTOFF_LO 34 +#define R_PPC_SECTOFF_HI 35 +#define R_PPC_SECTOFF_HA 36 + +/* PowerPC relocations defined for the TLS access ABI. */ +#define R_PPC_TLS 67 /* none (sym+add)@tls */ +#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */ +#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */ +#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */ +#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */ +#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */ +#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */ +#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */ +#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */ +#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */ + +/* Keep this the last entry. */ +#define R_PPC_NUM 95 + +/* The remaining relocs are from the Embedded ELF ABI, and are not + in the SVR4 ELF ABI. */ +#define R_PPC_EMB_NADDR32 101 +#define R_PPC_EMB_NADDR16 102 +#define R_PPC_EMB_NADDR16_LO 103 +#define R_PPC_EMB_NADDR16_HI 104 +#define R_PPC_EMB_NADDR16_HA 105 +#define R_PPC_EMB_SDAI16 106 +#define R_PPC_EMB_SDA2I16 107 +#define R_PPC_EMB_SDA2REL 108 +#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */ +#define R_PPC_EMB_MRKREF 110 +#define R_PPC_EMB_RELSEC16 111 +#define R_PPC_EMB_RELST_LO 112 +#define R_PPC_EMB_RELST_HI 113 +#define R_PPC_EMB_RELST_HA 114 +#define R_PPC_EMB_BIT_FLD 115 +#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */ + +/* Diab tool relocations. */ +#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */ +#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */ +#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */ +#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */ +#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */ +#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */ + +/* GNU relocs used in PIC code sequences. */ +#define R_PPC_REL16 249 /* word32 (sym-.) */ +#define R_PPC_REL16_LO 250 /* half16 (sym-.)@l */ +#define R_PPC_REL16_HI 251 /* half16 (sym-.)@h */ +#define R_PPC_REL16_HA 252 /* half16 (sym-.)@ha */ + +/* This is a phony reloc to handle any old fashioned TOC16 references + that may still be in object files. */ +#define R_PPC_TOC16 255 + +/* PowerPC specific values for the Dyn d_tag field. */ +#define DT_PPC_GOT (DT_LOPROC + 0) +#define DT_PPC_NUM 1 + +/* PowerPC64 relocations defined by the ABIs */ +#define R_PPC64_NONE R_PPC_NONE +#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */ +#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */ +#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */ +#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */ +#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */ +#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */ +#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */ +#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN +#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN +#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */ +#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */ +#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN +#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN +#define R_PPC64_GOT16 R_PPC_GOT16 +#define R_PPC64_GOT16_LO R_PPC_GOT16_LO +#define R_PPC64_GOT16_HI R_PPC_GOT16_HI +#define R_PPC64_GOT16_HA R_PPC_GOT16_HA + +#define R_PPC64_COPY R_PPC_COPY +#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT +#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT +#define R_PPC64_RELATIVE R_PPC_RELATIVE + +#define R_PPC64_UADDR32 R_PPC_UADDR32 +#define R_PPC64_UADDR16 R_PPC_UADDR16 +#define R_PPC64_REL32 R_PPC_REL32 +#define R_PPC64_PLT32 R_PPC_PLT32 +#define R_PPC64_PLTREL32 R_PPC_PLTREL32 +#define R_PPC64_PLT16_LO R_PPC_PLT16_LO +#define R_PPC64_PLT16_HI R_PPC_PLT16_HI +#define R_PPC64_PLT16_HA R_PPC_PLT16_HA + +#define R_PPC64_SECTOFF R_PPC_SECTOFF +#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO +#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI +#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA +#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */ +#define R_PPC64_ADDR64 38 /* doubleword64 S + A */ +#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */ +#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */ +#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */ +#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */ +#define R_PPC64_UADDR64 43 /* doubleword64 S + A */ +#define R_PPC64_REL64 44 /* doubleword64 S + A - P */ +#define R_PPC64_PLT64 45 /* doubleword64 L + A */ +#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */ +#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */ +#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */ +#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */ +#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */ +#define R_PPC64_TOC 51 /* doubleword64 .TOC */ +#define R_PPC64_PLTGOT16 52 /* half16* M + A */ +#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */ +#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */ +#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */ + +#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */ +#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */ +#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */ +#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */ +#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */ +#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */ +#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */ +#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */ +#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */ +#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */ +#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */ + +/* PowerPC64 relocations defined for the TLS access ABI. */ +#define R_PPC64_TLS 67 /* none (sym+add)@tls */ +#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */ +#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */ +#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */ +#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */ +#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */ +#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */ +#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */ +#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */ +#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */ +#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */ +#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */ +#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */ +#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */ +#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */ +#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */ +#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */ +#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */ +#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */ +#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */ +#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */ +#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */ +#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */ +#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */ +#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */ +#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */ +#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */ +#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */ +#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */ +#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */ +#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */ +#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */ +#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */ +#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */ +#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */ +#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */ + +/* Keep this the last entry. */ +#define R_PPC64_NUM 107 + +/* PowerPC64 specific values for the Dyn d_tag field. */ +#define DT_PPC64_GLINK (DT_LOPROC + 0) +#define DT_PPC64_OPD (DT_LOPROC + 1) +#define DT_PPC64_OPDSZ (DT_LOPROC + 2) +#define DT_PPC64_NUM 3 + + +/* ARM specific declarations */ + +/* Processor specific flags for the ELF header e_flags field. */ +#define EF_ARM_RELEXEC 0x01 +#define EF_ARM_HASENTRY 0x02 +#define EF_ARM_INTERWORK 0x04 +#define EF_ARM_APCS_26 0x08 +#define EF_ARM_APCS_FLOAT 0x10 +#define EF_ARM_PIC 0x20 +#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */ +#define EF_ARM_NEW_ABI 0x80 +#define EF_ARM_OLD_ABI 0x100 + +/* Other constants defined in the ARM ELF spec. version B-01. */ +/* NB. These conflict with values defined above. */ +#define EF_ARM_SYMSARESORTED 0x04 +#define EF_ARM_DYNSYMSUSESEGIDX 0x08 +#define EF_ARM_MAPSYMSFIRST 0x10 +#define EF_ARM_EABIMASK 0XFF000000 + +#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK) +#define EF_ARM_EABI_UNKNOWN 0x00000000 +#define EF_ARM_EABI_VER1 0x01000000 +#define EF_ARM_EABI_VER2 0x02000000 + +/* Additional symbol types for Thumb */ +#define STT_ARM_TFUNC 0xd + +/* ARM-specific values for sh_flags */ +#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */ +#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined + in the input to a link step */ + +/* ARM-specific program header flags */ +#define PF_ARM_SB 0x10000000 /* Segment contains the location + addressed by the static base */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */ + +/* ARM relocs. */ + +#define R_ARM_NONE 0 /* No reloc */ +#define R_ARM_PC24 1 /* PC relative 26 bit branch */ +#define R_ARM_ABS32 2 /* Direct 32 bit */ +#define R_ARM_REL32 3 /* PC relative 32 bit */ +#define R_ARM_PC13 4 +#define R_ARM_ABS16 5 /* Direct 16 bit */ +#define R_ARM_ABS12 6 /* Direct 12 bit */ +#define R_ARM_THM_ABS5 7 +#define R_ARM_ABS8 8 /* Direct 8 bit */ +#define R_ARM_SBREL32 9 +#define R_ARM_THM_PC22 10 +#define R_ARM_THM_PC8 11 +#define R_ARM_AMP_VCALL9 12 +#define R_ARM_SWI24 13 +#define R_ARM_THM_SWI8 14 +#define R_ARM_XPC25 15 +#define R_ARM_THM_XPC22 16 +#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */ +#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */ +#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */ +#define R_ARM_COPY 20 /* Copy symbol at runtime */ +#define R_ARM_GLOB_DAT 21 /* Create GOT entry */ +#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */ +#define R_ARM_RELATIVE 23 /* Adjust by program base */ +#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */ +#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */ +#define R_ARM_GOT32 26 /* 32 bit GOT entry */ +#define R_ARM_PLT32 27 /* 32 bit PLT address */ +#define R_ARM_ALU_PCREL_7_0 32 +#define R_ARM_ALU_PCREL_15_8 33 +#define R_ARM_ALU_PCREL_23_15 34 +#define R_ARM_LDR_SBREL_11_0 35 +#define R_ARM_ALU_SBREL_19_12 36 +#define R_ARM_ALU_SBREL_27_20 37 +#define R_ARM_GNU_VTENTRY 100 +#define R_ARM_GNU_VTINHERIT 101 +#define R_ARM_THM_PC11 102 /* thumb unconditional branch */ +#define R_ARM_THM_PC9 103 /* thumb conditional branch */ +#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic + thread local data */ +#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic + thread local data */ +#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS + block */ +#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of + static TLS block offset */ +#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static + TLS block */ +#define R_ARM_RXPC25 249 +#define R_ARM_RSBREL32 250 +#define R_ARM_THM_RPC22 251 +#define R_ARM_RREL32 252 +#define R_ARM_RABS22 253 +#define R_ARM_RPC24 254 +#define R_ARM_RBASE 255 +/* Keep this the last entry. */ +#define R_ARM_NUM 256 + +/* IA-64 specific declarations. */ + +/* Processor specific flags for the Ehdr e_flags field. */ +#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */ +#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */ +#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */ + +/* Processor specific values for the Phdr p_type field. */ +#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */ +#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */ +#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12) +#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13) +#define PT_IA_64_HP_STACK (PT_LOOS + 0x14) + +/* Processor specific flags for the Phdr p_flags field. */ +#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Shdr sh_type field. */ +#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */ +#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */ + +/* Processor specific flags for the Shdr sh_flags field. */ +#define SHF_IA_64_SHORT 0x10000000 /* section near gp */ +#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */ + +/* Processor specific values for the Dyn d_tag field. */ +#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0) +#define DT_IA_64_NUM 1 + +/* IA-64 relocations. */ +#define R_IA64_NONE 0x00 /* none */ +#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */ +#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */ +#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */ +#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */ +#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */ +#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */ +#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */ +#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */ +#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */ +#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */ +#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */ +#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */ +#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */ +#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */ +#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */ +#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */ +#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */ +#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */ +#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */ +#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */ +#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */ +#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */ +#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */ +#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */ +#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */ +#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */ +#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */ +#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */ +#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */ +#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */ +#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */ +#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */ +#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */ +#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */ +#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */ +#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */ +#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */ +#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */ +#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */ +#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */ +#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */ +#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */ +#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */ +#define R_IA64_REL32MSB 0x6c /* data 4 + REL */ +#define R_IA64_REL32LSB 0x6d /* data 4 + REL */ +#define R_IA64_REL64MSB 0x6e /* data 8 + REL */ +#define R_IA64_REL64LSB 0x6f /* data 8 + REL */ +#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */ +#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */ +#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */ +#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */ +#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */ +#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */ +#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */ +#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */ +#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */ +#define R_IA64_COPY 0x84 /* copy relocation */ +#define R_IA64_SUB 0x85 /* Addend and symbol difference */ +#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */ +#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */ +#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */ +#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */ +#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */ +#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */ +#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */ +#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */ +#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */ +#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */ +#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */ +#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */ +#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */ +#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */ +#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */ +#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */ +#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */ + +/* SH specific declarations */ + +/* SH relocs. */ +#define R_SH_NONE 0 +#define R_SH_DIR32 1 +#define R_SH_REL32 2 +#define R_SH_DIR8WPN 3 +#define R_SH_IND12W 4 +#define R_SH_DIR8WPL 5 +#define R_SH_DIR8WPZ 6 +#define R_SH_DIR8BP 7 +#define R_SH_DIR8W 8 +#define R_SH_DIR8L 9 +#define R_SH_SWITCH16 25 +#define R_SH_SWITCH32 26 +#define R_SH_USES 27 +#define R_SH_COUNT 28 +#define R_SH_ALIGN 29 +#define R_SH_CODE 30 +#define R_SH_DATA 31 +#define R_SH_LABEL 32 +#define R_SH_SWITCH8 33 +#define R_SH_GNU_VTINHERIT 34 +#define R_SH_GNU_VTENTRY 35 +#define R_SH_TLS_GD_32 144 +#define R_SH_TLS_LD_32 145 +#define R_SH_TLS_LDO_32 146 +#define R_SH_TLS_IE_32 147 +#define R_SH_TLS_LE_32 148 +#define R_SH_TLS_DTPMOD32 149 +#define R_SH_TLS_DTPOFF32 150 +#define R_SH_TLS_TPOFF32 151 +#define R_SH_GOT32 160 +#define R_SH_PLT32 161 +#define R_SH_COPY 162 +#define R_SH_GLOB_DAT 163 +#define R_SH_JMP_SLOT 164 +#define R_SH_RELATIVE 165 +#define R_SH_GOTOFF 166 +#define R_SH_GOTPC 167 +/* Keep this the last entry. */ +#define R_SH_NUM 256 + +/* Additional s390 relocs */ + +#define R_390_NONE 0 /* No reloc. */ +#define R_390_8 1 /* Direct 8 bit. */ +#define R_390_12 2 /* Direct 12 bit. */ +#define R_390_16 3 /* Direct 16 bit. */ +#define R_390_32 4 /* Direct 32 bit. */ +#define R_390_PC32 5 /* PC relative 32 bit. */ +#define R_390_GOT12 6 /* 12 bit GOT offset. */ +#define R_390_GOT32 7 /* 32 bit GOT offset. */ +#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ +#define R_390_COPY 9 /* Copy symbol at runtime. */ +#define R_390_GLOB_DAT 10 /* Create GOT entry. */ +#define R_390_JMP_SLOT 11 /* Create PLT entry. */ +#define R_390_RELATIVE 12 /* Adjust by program base. */ +#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ +#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */ +#define R_390_GOT16 15 /* 16 bit GOT offset. */ +#define R_390_PC16 16 /* PC relative 16 bit. */ +#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ +#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ +#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ +#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ +#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ +#define R_390_64 22 /* Direct 64 bit. */ +#define R_390_PC64 23 /* PC relative 64 bit. */ +#define R_390_GOT64 24 /* 64 bit GOT offset. */ +#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ +#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ +#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ +#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ +#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ +#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ +#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ +#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ +#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ +#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ +#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ +#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ +#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ +#define R_390_TLS_GDCALL 38 /* Tag for function call in general + dynamic TLS code. */ +#define R_390_TLS_LDCALL 39 /* Tag for function call in local + dynamic TLS code. */ +#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic + thread local data. */ +#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic + thread local data. */ +#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS + block offset. */ +#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic + thread local data in LE code. */ +#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for + negated static TLS block offset. */ +#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to + static TLS block. */ +#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS + block. */ +#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS + block. */ +#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ +#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ +#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS + block. */ +#define R_390_20 57 /* Direct 20 bit. */ +#define R_390_GOT20 58 /* 20 bit GOT offset. */ +#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ +#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS + block offset. */ +/* Keep this the last entry. */ +#define R_390_NUM 61 + + +/* CRIS relocations. */ +#define R_CRIS_NONE 0 +#define R_CRIS_8 1 +#define R_CRIS_16 2 +#define R_CRIS_32 3 +#define R_CRIS_8_PCREL 4 +#define R_CRIS_16_PCREL 5 +#define R_CRIS_32_PCREL 6 +#define R_CRIS_GNU_VTINHERIT 7 +#define R_CRIS_GNU_VTENTRY 8 +#define R_CRIS_COPY 9 +#define R_CRIS_GLOB_DAT 10 +#define R_CRIS_JUMP_SLOT 11 +#define R_CRIS_RELATIVE 12 +#define R_CRIS_16_GOT 13 +#define R_CRIS_32_GOT 14 +#define R_CRIS_16_GOTPLT 15 +#define R_CRIS_32_GOTPLT 16 +#define R_CRIS_32_GOTREL 17 +#define R_CRIS_32_PLT_GOTREL 18 +#define R_CRIS_32_PLT_PCREL 19 + +#define R_CRIS_NUM 20 + + +/* AMD x86-64 relocations. */ +#define R_X86_64_NONE 0 /* No reloc */ +#define R_X86_64_64 1 /* Direct 64 bit */ +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */ +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */ +#define R_X86_64_PLT32 4 /* 32 bit PLT address */ +#define R_X86_64_COPY 5 /* Copy symbol at runtime */ +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ +#define R_X86_64_RELATIVE 8 /* Adjust by program base */ +#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative + offset to GOT */ +#define R_X86_64_32 10 /* Direct 32 bit zero extended */ +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */ +#define R_X86_64_16 12 /* Direct 16 bit zero extended */ +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ +#define R_X86_64_8 14 /* Direct 8 bit sign extended */ +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ +#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */ +#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */ +#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */ +#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset + to two GOT entries for GD symbol */ +#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset + to two GOT entries for LD symbol */ +#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */ +#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset + to GOT entry for IE symbol */ +#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */ +#define R_X86_64_PC64 24 /* PC relative 64 bit */ +#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */ +#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative + offset to GOT */ +/* 27 .. 33 */ +#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */ +#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS + descriptor. */ +#define R_X86_64_TLSDESC 36 /* TLS descriptor. */ + +#define R_X86_64_NUM 37 + + +/* AM33 relocations. */ +#define R_MN10300_NONE 0 /* No reloc. */ +#define R_MN10300_32 1 /* Direct 32 bit. */ +#define R_MN10300_16 2 /* Direct 16 bit. */ +#define R_MN10300_8 3 /* Direct 8 bit. */ +#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */ +#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */ +#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */ +#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */ +#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */ +#define R_MN10300_24 9 /* Direct 24 bit. */ +#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */ +#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */ +#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */ +#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */ +#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */ +#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */ +#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */ +#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */ +#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */ +#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */ +#define R_MN10300_COPY 20 /* Copy symbol at runtime. */ +#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */ +#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */ +#define R_MN10300_RELATIVE 23 /* Adjust by program base. */ + +#define R_MN10300_NUM 24 + + +/* M32R relocs. */ +#define R_M32R_NONE 0 /* No reloc. */ +#define R_M32R_16 1 /* Direct 16 bit. */ +#define R_M32R_32 2 /* Direct 32 bit. */ +#define R_M32R_24 3 /* Direct 24 bit. */ +#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */ +#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */ +#define R_M32R_LO16 9 /* Low 16 bit. */ +#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */ +#define R_M32R_GNU_VTINHERIT 11 +#define R_M32R_GNU_VTENTRY 12 +/* M32R relocs use SHT_RELA. */ +#define R_M32R_16_RELA 33 /* Direct 16 bit. */ +#define R_M32R_32_RELA 34 /* Direct 32 bit. */ +#define R_M32R_24_RELA 35 /* Direct 24 bit. */ +#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */ +#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */ +#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */ +#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */ +#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */ +#define R_M32R_LO16_RELA 41 /* Low 16 bit */ +#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */ +#define R_M32R_RELA_GNU_VTINHERIT 43 +#define R_M32R_RELA_GNU_VTENTRY 44 +#define R_M32R_REL32 45 /* PC relative 32 bit. */ + +#define R_M32R_GOT24 48 /* 24 bit GOT entry */ +#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */ +#define R_M32R_COPY 50 /* Copy symbol at runtime */ +#define R_M32R_GLOB_DAT 51 /* Create GOT entry */ +#define R_M32R_JMP_SLOT 52 /* Create PLT entry */ +#define R_M32R_RELATIVE 53 /* Adjust by program base */ +#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */ +#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */ +#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned + low */ +#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed + low */ +#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */ +#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to + GOT with unsigned low */ +#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to + GOT with signed low */ +#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to + GOT */ +#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT + with unsigned low */ +#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT + with signed low */ +#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */ +#define R_M32R_NUM 256 /* Keep this the last entry. */ + + +#endif /* elf.h */ diff --git a/sources/patchelf/patchelf.cc b/sources/patchelf/patchelf.cc new file mode 100644 index 0000000..c6f495e --- /dev/null +++ b/sources/patchelf/patchelf.cc @@ -0,0 +1,1239 @@ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "elf.h" + +using namespace std; + + +#ifdef MIPSEL +/* The lemote fuloong 2f kernel defconfig sets a page size of 16KB */ +const unsigned int pageSize = 4096*4; +#else +const unsigned int pageSize = 4096; +#endif + + +static bool debugMode = false; + +static bool forceRPath = false; + +static string fileName; + + +off_t fileSize, maxSize; +unsigned char * contents = 0; + + +#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym +#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym + + +template +class ElfFile +{ + Elf_Ehdr * hdr; + vector phdrs; + vector shdrs; + + bool littleEndian; + + bool changed; + + bool isExecutable; + + typedef string SectionName; + typedef map ReplacedSections; + + ReplacedSections replacedSections; + + string sectionNames; /* content of the .shstrtab section */ + + /* Align on 4 or 8 bytes boundaries on 32- or 64-bit platforms + respectively. */ + unsigned int sectionAlignment; + + vector sectionsByOldIndex; + +public: + + ElfFile() + { + changed = false; + sectionAlignment = sizeof(Elf_Off); + } + + bool isChanged() + { + return changed; + } + + void parse(); + +private: + + struct CompPhdr + { + ElfFile * elfFile; + bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y) + { + if (x.p_type == PT_PHDR) return true; + if (y.p_type == PT_PHDR) return false; + return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr); + } + }; + + friend struct CompPhdr; + + void sortPhdrs(); + + struct CompShdr + { + ElfFile * elfFile; + bool operator ()(const Elf_Shdr & x, const Elf_Shdr & y) + { + return elfFile->rdi(x.sh_offset) < elfFile->rdi(y.sh_offset); + } + }; + + friend struct CompShdr; + + void sortShdrs(); + + void shiftFile(unsigned int extraPages, Elf_Addr startPage); + + string getSectionName(const Elf_Shdr & shdr); + + Elf_Shdr & findSection(const SectionName & sectionName); + + Elf_Shdr * findSection2(const SectionName & sectionName); + + unsigned int findSection3(const SectionName & sectionName); + + string & replaceSection(const SectionName & sectionName, + unsigned int size); + + void writeReplacedSections(Elf_Off & curOff, + Elf_Addr startAddr, Elf_Off startOffset); + + void rewriteHeaders(Elf_Addr phdrAddress); + + void rewriteSectionsLibrary(); + + void rewriteSectionsExecutable(); + +public: + + void rewriteSections(); + + string getInterpreter(); + + void setInterpreter(const string & newInterpreter); + + typedef enum { rpPrint, rpShrink, rpSet } RPathOp; + + void modifyRPath(RPathOp op, string newRPath); + + void removeNeeded(set libs); + +private: + + /* Convert an integer in big or little endian representation (as + specified by the ELF header) to this platform's integer + representation. */ + template + I rdi(I i); + + /* Convert back to the ELF representation. */ + template + I wri(I & t, unsigned long long i) + { + t = rdi((I) i); + return i; + } +}; + + +/* !!! G++ creates broken code if this function is inlined, don't know + why... */ +template +template +I ElfFile::rdi(I i) +{ + I r = 0; + if (littleEndian) { + for (unsigned int n = 0; n < sizeof(I); ++n) { + r |= ((I) *(((unsigned char *) &i) + n)) << (n * 8); + } + } else { + for (unsigned int n = 0; n < sizeof(I); ++n) { + r |= ((I) *(((unsigned char *) &i) + n)) << ((sizeof(I) - n - 1) * 8); + } + } + return r; +} + + +/* Ugly: used to erase DT_RUNPATH when using --force-rpath. */ +#define DT_IGNORE 0x00726e67 + + +static void debug(const char * format, ...) +{ + if (debugMode) { + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + } +} + + +static void error(string msg) +{ + if (errno) perror(msg.c_str()); else fprintf(stderr, "%s\n", msg.c_str()); + exit(1); +} + + +static void growFile(off_t newSize) +{ + if (newSize > maxSize) error("maximum file size exceeded"); + if (newSize <= fileSize) return; + if (newSize > fileSize) + memset(contents + fileSize, 0, newSize - fileSize); + fileSize = newSize; +} + + +static void readFile(string fileName, mode_t * fileMode) +{ + struct stat st; + if (stat(fileName.c_str(), &st) != 0) error("stat"); + fileSize = st.st_size; + *fileMode = st.st_mode; + maxSize = fileSize + 8 * 1024 * 1024; + + contents = (unsigned char *) malloc(fileSize + maxSize); + if (!contents) abort(); + + int fd = open(fileName.c_str(), O_RDONLY); + if (fd == -1) error("open"); + + if (read(fd, contents, fileSize) != fileSize) error("read"); + + close(fd); +} + + +static void checkPointer(void * p, unsigned int size) +{ + unsigned char * q = (unsigned char *) p; + assert(q >= contents && q + size <= contents + fileSize); +} + + +template +void ElfFile::parse() +{ + isExecutable = false; + + /* Check the ELF header for basic validity. */ + if (fileSize < (off_t) sizeof(Elf_Ehdr)) error("missing ELF header"); + + hdr = (Elf_Ehdr *) contents; + + if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) + error("not an ELF executable"); + + littleEndian = contents[EI_DATA] == ELFDATA2LSB; + + if (rdi(hdr->e_type) != ET_EXEC && rdi(hdr->e_type) != ET_DYN) + error("wrong ELF type"); + + if ((off_t) (rdi(hdr->e_phoff) + rdi(hdr->e_phnum) * rdi(hdr->e_phentsize)) > fileSize) + error("missing program headers"); + + if ((off_t) (rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * rdi(hdr->e_shentsize)) > fileSize) + error("missing section headers"); + + if (rdi(hdr->e_phentsize) != sizeof(Elf_Phdr)) + error("program headers have wrong size"); + + /* Copy the program and section headers. */ + for (int i = 0; i < rdi(hdr->e_phnum); ++i) { + phdrs.push_back(* ((Elf_Phdr *) (contents + rdi(hdr->e_phoff)) + i)); + if (rdi(phdrs[i].p_type) == PT_INTERP) isExecutable = true; + } + + for (int i = 0; i < rdi(hdr->e_shnum); ++i) + shdrs.push_back(* ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i)); + + /* Get the section header string table section (".shstrtab"). Its + index in the section header table is given by e_shstrndx field + of the ELF header. */ + unsigned int shstrtabIndex = rdi(hdr->e_shstrndx); + assert(shstrtabIndex < shdrs.size()); + unsigned int shstrtabSize = rdi(shdrs[shstrtabIndex].sh_size); + char * shstrtab = (char * ) contents + rdi(shdrs[shstrtabIndex].sh_offset); + checkPointer(shstrtab, shstrtabSize); + + assert(shstrtabSize > 0); + assert(shstrtab[shstrtabSize - 1] == 0); + + sectionNames = string(shstrtab, shstrtabSize); + + sectionsByOldIndex.resize(hdr->e_shnum); + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + sectionsByOldIndex[i] = getSectionName(shdrs[i]); +} + + +template +void ElfFile::sortPhdrs() +{ + /* Sort the segments by offset. */ + CompPhdr comp; + comp.elfFile = this; + sort(phdrs.begin(), phdrs.end(), comp); +} + + +template +void ElfFile::sortShdrs() +{ + /* Translate sh_link mappings to section names, since sorting the + sections will invalidate the sh_link fields. */ + map linkage; + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + if (rdi(shdrs[i].sh_link) != 0) + linkage[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_link)]); + + /* Idem for sh_info on certain sections. */ + map info; + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + if (rdi(shdrs[i].sh_info) != 0 && + (rdi(shdrs[i].sh_type) == SHT_REL || rdi(shdrs[i].sh_type) == SHT_RELA)) + info[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_info)]); + + /* Idem for the index of the .shstrtab section in the ELF header. */ + SectionName shstrtabName = getSectionName(shdrs[rdi(hdr->e_shstrndx)]); + + /* Sort the sections by offset. */ + CompShdr comp; + comp.elfFile = this; + sort(shdrs.begin(), shdrs.end(), comp); + + /* Restore the sh_link mappings. */ + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + if (rdi(shdrs[i].sh_link) != 0) + wri(shdrs[i].sh_link, + findSection3(linkage[getSectionName(shdrs[i])])); + + /* And the st_info mappings. */ + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + if (rdi(shdrs[i].sh_info) != 0 && + (rdi(shdrs[i].sh_type) == SHT_REL || rdi(shdrs[i].sh_type) == SHT_RELA)) + wri(shdrs[i].sh_info, + findSection3(info[getSectionName(shdrs[i])])); + + /* And the .shstrtab index. */ + wri(hdr->e_shstrndx, findSection3(shstrtabName)); +} + + +static void writeFile(string fileName, mode_t fileMode) +{ + string fileName2 = fileName + "_patchelf_tmp"; + + int fd = open(fileName2.c_str(), + O_CREAT | O_TRUNC | O_WRONLY, 0700); + if (fd == -1) error("open"); + + if (write(fd, contents, fileSize) != fileSize) error("write"); + + if (close(fd) != 0) error("close"); + + if (chmod(fileName2.c_str(), fileMode) != 0) error("chmod"); + + if (rename(fileName2.c_str(), fileName.c_str()) != 0) error("rename"); +} + + +static unsigned int roundUp(unsigned int n, unsigned int m) +{ + return ((n - 1) / m + 1) * m; +} + + +template +void ElfFile::shiftFile(unsigned int extraPages, Elf_Addr startPage) +{ + /* Move the entire contents of the file `extraPages' pages + further. */ + unsigned int oldSize = fileSize; + unsigned int shift = extraPages * pageSize; + growFile(fileSize + extraPages * pageSize); + memmove(contents + extraPages * pageSize, contents, oldSize); + memset(contents + sizeof(Elf_Ehdr), 0, shift - sizeof(Elf_Ehdr)); + + /* Adjust the ELF header. */ + wri(hdr->e_phoff, sizeof(Elf_Ehdr)); + wri(hdr->e_shoff, rdi(hdr->e_shoff) + shift); + + /* Update the offsets in the section headers. */ + for (int i = 1; i < rdi(hdr->e_shnum); ++i) + wri(shdrs[i].sh_offset, rdi(shdrs[i].sh_offset) + shift); + + /* Update the offsets in the program headers. */ + for (int i = 0; i < rdi(hdr->e_phnum); ++i) { + wri(phdrs[i].p_offset, rdi(phdrs[i].p_offset) + shift); + if (rdi(phdrs[i].p_align) != 0 && + (rdi(phdrs[i].p_vaddr) - rdi(phdrs[i].p_offset)) % rdi(phdrs[i].p_align) != 0) { + debug("changing alignment of program header %d from %d to %d\n", i, + rdi(phdrs[i].p_align), pageSize); + wri(phdrs[i].p_align, pageSize); + } + } + + /* Add a segment that maps the new program/section headers and + PT_INTERP segment into memory. Otherwise glibc will choke. */ + phdrs.resize(rdi(hdr->e_phnum) + 1); + wri(hdr->e_phnum, rdi(hdr->e_phnum) + 1); + Elf_Phdr & phdr = phdrs[rdi(hdr->e_phnum) - 1]; + wri(phdr.p_type, PT_LOAD); + wri(phdr.p_offset, 0); + wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); + wri(phdr.p_filesz, wri(phdr.p_memsz, shift)); + wri(phdr.p_flags, PF_R | PF_W); + wri(phdr.p_align, pageSize); +} + + +template +string ElfFile::getSectionName(const Elf_Shdr & shdr) +{ + return string(sectionNames.c_str() + rdi(shdr.sh_name)); +} + + +template +Elf_Shdr & ElfFile::findSection(const SectionName & sectionName) +{ + Elf_Shdr * shdr = findSection2(sectionName); + if (!shdr) + error("cannot find section " + sectionName); + return *shdr; +} + + +template +Elf_Shdr * ElfFile::findSection2(const SectionName & sectionName) +{ + unsigned int i = findSection3(sectionName); + return i ? &shdrs[i] : 0; +} + + +template +unsigned int ElfFile::findSection3(const SectionName & sectionName) +{ + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + if (getSectionName(shdrs[i]) == sectionName) return i; + return 0; +} + + +template +string & ElfFile::replaceSection(const SectionName & sectionName, + unsigned int size) +{ + ReplacedSections::iterator i = replacedSections.find(sectionName); + string s; + + if (i != replacedSections.end()) { + s = string(i->second); + } else { + Elf_Shdr & shdr = findSection(sectionName); + s = string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size)); + } + + s.resize(size); + replacedSections[sectionName] = s; + + return replacedSections[sectionName]; +} + + +template +void ElfFile::writeReplacedSections(Elf_Off & curOff, + Elf_Addr startAddr, Elf_Off startOffset) +{ + /* Overwrite the old section contents with 'X's. Do this + *before* writing the new section contents (below) to prevent + clobbering previously written new section contents. */ + for (ReplacedSections::iterator i = replacedSections.begin(); + i != replacedSections.end(); ++i) + { + string sectionName = i->first; + Elf_Shdr & shdr = findSection(sectionName); + memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size)); + } + + for (ReplacedSections::iterator i = replacedSections.begin(); + i != replacedSections.end(); ++i) + { + string sectionName = i->first; + Elf_Shdr & shdr = findSection(sectionName); + debug("rewriting section `%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n", + sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i->second.size()); + + memcpy(contents + curOff, (unsigned char *) i->second.c_str(), + i->second.size()); + + /* Update the section header for this section. */ + wri(shdr.sh_offset, curOff); + wri(shdr.sh_addr, startAddr + (curOff - startOffset)); + wri(shdr.sh_size, i->second.size()); + wri(shdr.sh_addralign, sectionAlignment); + + /* If this is the .interp section, then the PT_INTERP segment + must be sync'ed with it. */ + if (sectionName == ".interp") { + for (unsigned int j = 0; j < phdrs.size(); ++j) + if (rdi(phdrs[j].p_type) == PT_INTERP) { + phdrs[j].p_offset = shdr.sh_offset; + phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr; + phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size; + } + } + + /* If this is the .dynamic section, then the PT_DYNAMIC segment + must be sync'ed with it. */ + if (sectionName == ".dynamic") { + for (unsigned int j = 0; j < phdrs.size(); ++j) + if (rdi(phdrs[j].p_type) == PT_DYNAMIC) { + phdrs[j].p_offset = shdr.sh_offset; + phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr; + phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size; + } + } + + curOff += roundUp(i->second.size(), sectionAlignment); + } + + replacedSections.clear(); +} + + +template +void ElfFile::rewriteSectionsLibrary() +{ + /* For dynamic libraries, we just place the replacement sections + at the end of the file. They're mapped into memory by a + PT_LOAD segment located directly after the last virtual address + page of other segments. */ + Elf_Addr startPage = 0; + for (unsigned int i = 0; i < phdrs.size(); ++i) { + Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), pageSize); + if (thisPage > startPage) startPage = thisPage; + } + + debug("last page is 0x%llx\n", (unsigned long long) startPage); + + + /* Compute the total space needed for the replaced sections and + the program headers. */ + off_t neededSpace = (phdrs.size() + 1) * sizeof(Elf_Phdr); + for (ReplacedSections::iterator i = replacedSections.begin(); + i != replacedSections.end(); ++i) + neededSpace += roundUp(i->second.size(), sectionAlignment); + debug("needed space is %d\n", neededSpace); + + + size_t startOffset = roundUp(fileSize, pageSize); + + growFile(startOffset + neededSpace); + + + /* Even though this file is of type ET_DYN, it could actually be + an executable. For instance, Gold produces executables marked + ET_DYN. In that case we can still hit the kernel bug that + necessitated rewriteSectionsExecutable(). However, such + executables also tend to start at virtual address 0, so + rewriteSectionsExecutable() won't work because it doesn't have + any virtual address space to grow downwards into. As a + workaround, make sure that the virtual address of our new + PT_LOAD segment relative to the first PT_LOAD segment is equal + to its offset; otherwise we hit the kernel bug. This may + require creating a hole in the executable. The bigger the size + of the uninitialised data segment, the bigger the hole. */ + if (isExecutable) { + if (startOffset >= startPage) { + debug("shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug\n", startOffset - startPage); + } else { + size_t hole = startPage - startOffset; + /* Print a warning, because the hole could be very big. */ + fprintf(stderr, "warning: working around a Linux kernel bug by creating a hole of %zu bytes in ‘%s’\n", hole, fileName.c_str()); + assert(hole % pageSize == 0); + /* !!! We could create an actual hole in the file here, + but it's probably not worth the effort. */ + growFile(fileSize + hole); + startOffset += hole; + } + startPage = startOffset; + } + + + /* Add a segment that maps the replaced sections and program + headers into memory. */ + phdrs.resize(rdi(hdr->e_phnum) + 1); + wri(hdr->e_phnum, rdi(hdr->e_phnum) + 1); + Elf_Phdr & phdr = phdrs[rdi(hdr->e_phnum) - 1]; + wri(phdr.p_type, PT_LOAD); + wri(phdr.p_offset, startOffset); + wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); + wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace)); + wri(phdr.p_flags, PF_R | PF_W); + wri(phdr.p_align, pageSize); + + + /* Write out the replaced sections. */ + Elf_Off curOff = startOffset + phdrs.size() * sizeof(Elf_Phdr); + writeReplacedSections(curOff, startPage, startOffset); + assert((off_t) curOff == startOffset + neededSpace); + + + /* Move the program header to the start of the new area. */ + wri(hdr->e_phoff, startOffset); + + rewriteHeaders(startPage); +} + + +template +void ElfFile::rewriteSectionsExecutable() +{ + /* Sort the sections by offset, otherwise we won't correctly find + all the sections before the last replaced section. */ + sortShdrs(); + + + /* What is the index of the last replaced section? */ + unsigned int lastReplaced = 0; + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) { + string sectionName = getSectionName(shdrs[i]); + if (replacedSections.find(sectionName) != replacedSections.end()) { + debug("using replaced section `%s'\n", sectionName.c_str()); + lastReplaced = i; + } + } + + assert(lastReplaced != 0); + + debug("last replaced is %d\n", lastReplaced); + + /* Try to replace all sections before that, as far as possible. + Stop when we reach an irreplacable section (such as one of type + SHT_PROGBITS). These cannot be moved in virtual address space + since that would invalidate absolute references to them. */ + assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */ + size_t startOffset = rdi(shdrs[lastReplaced + 1].sh_offset); + Elf_Addr startAddr = rdi(shdrs[lastReplaced + 1].sh_addr); + string prevSection; + for (unsigned int i = 1; i <= lastReplaced; ++i) { + Elf_Shdr & shdr(shdrs[i]); + string sectionName = getSectionName(shdr); + debug("looking at section `%s'\n", sectionName.c_str()); + /* !!! Why do we stop after a .dynstr section? I can't + remember! */ + if ((rdi(shdr.sh_type) == SHT_PROGBITS && sectionName != ".interp") + || prevSection == ".dynstr") + { + startOffset = rdi(shdr.sh_offset); + startAddr = rdi(shdr.sh_addr); + lastReplaced = i - 1; + break; + } else { + if (replacedSections.find(sectionName) == replacedSections.end()) { + debug("replacing section `%s' which is in the way\n", sectionName.c_str()); + replaceSection(sectionName, rdi(shdr.sh_size)); + } + } + prevSection = sectionName; + } + + debug("first reserved offset/addr is 0x%x/0x%llx\n", + startOffset, (unsigned long long) startAddr); + + assert(startAddr % pageSize == startOffset % pageSize); + Elf_Addr firstPage = startAddr - startOffset; + debug("first page is 0x%llx\n", (unsigned long long) firstPage); + + /* Right now we assume that the section headers are somewhere near + the end, which appears to be the case most of the time. + Therefore they're not accidentally overwritten by the replaced + sections. !!! Fix this. */ + assert((off_t) rdi(hdr->e_shoff) >= startOffset); + + + /* Compute the total space needed for the replaced sections, the + ELF header, and the program headers. */ + size_t neededSpace = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr); + for (ReplacedSections::iterator i = replacedSections.begin(); + i != replacedSections.end(); ++i) + neededSpace += roundUp(i->second.size(), sectionAlignment); + + debug("needed space is %d\n", neededSpace); + + /* If we need more space at the start of the file, then grow the + file by the minimum number of pages and adjust internal + offsets. */ + if (neededSpace > startOffset) { + + /* We also need an additional program header, so adjust for that. */ + neededSpace += sizeof(Elf_Phdr); + debug("needed space is %d\n", neededSpace); + + unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize; + debug("needed pages is %d\n", neededPages); + if (neededPages * pageSize > firstPage) + error("virtual address space underrun!"); + + firstPage -= neededPages * pageSize; + startOffset += neededPages * pageSize; + + shiftFile(neededPages, firstPage); + } + + + /* Clear out the free space. */ + Elf_Off curOff = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr); + debug("clearing first %d bytes\n", startOffset - curOff); + memset(contents + curOff, 0, startOffset - curOff); + + + /* Write out the replaced sections. */ + writeReplacedSections(curOff, firstPage, 0); + assert((off_t) curOff == neededSpace); + + + rewriteHeaders(firstPage + rdi(hdr->e_phoff)); +} + + +template +void ElfFile::rewriteSections() +{ + if (replacedSections.empty()) return; + + for (ReplacedSections::iterator i = replacedSections.begin(); + i != replacedSections.end(); ++i) + debug("replacing section `%s' with size %d\n", + i->first.c_str(), i->second.size()); + + if (rdi(hdr->e_type) == ET_DYN) { + debug("this is a dynamic library\n"); + rewriteSectionsLibrary(); + } else if (rdi(hdr->e_type) == ET_EXEC) { + debug("this is an executable\n"); + rewriteSectionsExecutable(); + } else error("unknown ELF type"); +} + + +template +void ElfFile::rewriteHeaders(Elf_Addr phdrAddress) +{ + /* Rewrite the program header table. */ + + /* If there is a segment for the program header table, update it. + (According to the ELF spec, it must be the first entry.) */ + if (rdi(phdrs[0].p_type) == PT_PHDR) { + phdrs[0].p_offset = hdr->e_phoff; + wri(phdrs[0].p_vaddr, wri(phdrs[0].p_paddr, phdrAddress)); + wri(phdrs[0].p_filesz, wri(phdrs[0].p_memsz, phdrs.size() * sizeof(Elf_Phdr))); + } + + sortPhdrs(); + + for (unsigned int i = 0; i < phdrs.size(); ++i) + * ((Elf_Phdr *) (contents + rdi(hdr->e_phoff)) + i) = phdrs[i]; + + + /* Rewrite the section header table. For neatness, keep the + sections sorted. */ + assert(rdi(hdr->e_shnum) == shdrs.size()); + sortShdrs(); + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) + * ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i) = shdrs[i]; + + + /* Update all those nasty virtual addresses in the .dynamic + section. Note that not all executables have .dynamic sections + (e.g., those produced by klibc's klcc). */ + Elf_Shdr * shdrDynamic = findSection2(".dynamic"); + if (shdrDynamic) { + Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic->sh_offset)); + unsigned int d_tag; + for ( ; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) + if (d_tag == DT_STRTAB) + dyn->d_un.d_ptr = findSection(".dynstr").sh_addr; + else if (d_tag == DT_STRSZ) + dyn->d_un.d_val = findSection(".dynstr").sh_size; + else if (d_tag == DT_SYMTAB) + dyn->d_un.d_ptr = findSection(".dynsym").sh_addr; + else if (d_tag == DT_HASH) + dyn->d_un.d_ptr = findSection(".hash").sh_addr; + else if (d_tag == DT_GNU_HASH) + dyn->d_un.d_ptr = findSection(".gnu.hash").sh_addr; + else if (d_tag == DT_JMPREL) { + Elf_Shdr * shdr = findSection2(".rel.plt"); + if (!shdr) shdr = findSection2(".rela.plt"); /* 64-bit Linux, x86-64 */ + if (!shdr) shdr = findSection2(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ + if (!shdr) error("cannot find section corresponding to DT_JMPREL"); + dyn->d_un.d_ptr = shdr->sh_addr; + } + else if (d_tag == DT_REL) { /* !!! hack! */ + Elf_Shdr * shdr = findSection2(".rel.dyn"); + /* no idea if this makes sense, but it was needed for some + program */ + if (!shdr) shdr = findSection2(".rel.got"); + if (!shdr) error("cannot find .rel.dyn or .rel.got"); + dyn->d_un.d_ptr = shdr->sh_addr; + } + else if (d_tag == DT_RELA) + dyn->d_un.d_ptr = findSection(".rela.dyn").sh_addr; /* PPC Linux */ + else if (d_tag == DT_VERNEED) + dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr; + else if (d_tag == DT_VERSYM) + dyn->d_un.d_ptr = findSection(".gnu.version").sh_addr; + } + + + /* Rewrite the .dynsym section. It contains the indices of the + sections in which symbols appear, so these need to be + remapped. */ + for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) { + if (rdi(shdrs[i].sh_type) != SHT_SYMTAB && rdi(shdrs[i].sh_type) != SHT_DYNSYM) continue; + debug("rewriting symbol table section %d\n", i); + for (size_t entry = 0; (entry + 1) * sizeof(Elf_Sym) <= rdi(shdrs[i].sh_size); entry++) { + Elf_Sym * sym = (Elf_Sym *) (contents + rdi(shdrs[i].sh_offset) + entry * sizeof(Elf_Sym)); + if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) { + string section = sectionsByOldIndex[rdi(sym->st_shndx)]; + assert(!section.empty()); + unsigned int newIndex = findSection3(section); // inefficient + //debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, rdi(sym->st_shndx), section.c_str(), newIndex); + wri(sym->st_shndx, newIndex); + } + } + } +} + + + +static void setSubstr(string & s, unsigned int pos, const string & t) +{ + assert(pos + t.size() <= s.size()); + copy(t.begin(), t.end(), s.begin() + pos); +} + + +template +string ElfFile::getInterpreter() +{ + Elf_Shdr & shdr = findSection(".interp"); + return string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size)); +} + + +template +void ElfFile::setInterpreter(const string & newInterpreter) +{ + string & section = replaceSection(".interp", newInterpreter.size() + 1); + setSubstr(section, 0, newInterpreter + '\0'); + changed = true; +} + + +static void concatToRPath(string & rpath, const string & path) +{ + if (!rpath.empty()) rpath += ":"; + rpath += path; +} + + +template +void ElfFile::modifyRPath(RPathOp op, string newRPath) +{ + Elf_Shdr & shdrDynamic = findSection(".dynamic"); + + /* !!! We assume that the virtual address in the DT_STRTAB entry + of the dynamic section corresponds to the .dynstr section. */ + Elf_Shdr & shdrDynStr = findSection(".dynstr"); + char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset); + + /* Find the DT_STRTAB entry in the dynamic section. */ + Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); + Elf_Addr strTabAddr = 0; + for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) + if (rdi(dyn->d_tag) == DT_STRTAB) strTabAddr = rdi(dyn->d_un.d_ptr); + if (!strTabAddr) error("strange: no string table"); + + assert(strTabAddr == rdi(shdrDynStr.sh_addr)); + + + /* Walk through the dynamic section, look for the RPATH/RUNPATH + entry. + + According to the ld.so docs, DT_RPATH is obsolete, we should + use DT_RUNPATH. DT_RUNPATH has two advantages: it can be + overriden by LD_LIBRARY_PATH, and it's scoped (the DT_RUNPATH + for an executable or library doesn't affect the search path for + libraries used by it). DT_RPATH is ignored if DT_RUNPATH is + present. The binutils `ld' still generates only DT_RPATH, + unless you use its `--enable-new-dtag' option, in which case it + generates a DT_RPATH and DT_RUNPATH pointing at the same + string. */ + static vector neededLibs; + dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); + Elf_Dyn * dynRPath = 0, * dynRunPath = 0; + char * rpath = 0; + for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) { + if (rdi(dyn->d_tag) == DT_RPATH) { + dynRPath = dyn; + /* Only use DT_RPATH if there is no DT_RUNPATH. */ + if (!dynRunPath) + rpath = strTab + rdi(dyn->d_un.d_val); + } + else if (rdi(dyn->d_tag) == DT_RUNPATH) { + dynRunPath = dyn; + rpath = strTab + rdi(dyn->d_un.d_val); + } + else if (rdi(dyn->d_tag) == DT_NEEDED) + neededLibs.push_back(string(strTab + rdi(dyn->d_un.d_val))); + } + + if (op == rpPrint) { + printf("%s\n", rpath ? rpath : ""); + return; + } + + if (op == rpShrink && !rpath) { + debug("no RPATH to shrink\n"); + return; + } + + + /* For each directory in the RPATH, check if it contains any + needed library. */ + if (op == rpShrink) { + static vector neededLibFound(neededLibs.size(), false); + + newRPath = ""; + + char * pos = rpath; + while (*pos) { + char * end = strchr(pos, ':'); + if (!end) end = strchr(pos, 0); + + /* Get the name of the directory. */ + string dirName(pos, end - pos); + if (*end == ':') ++end; + pos = end; + + /* Non-absolute entries are allowed (e.g., the special + "$ORIGIN" hack). */ + if (dirName[0] != '/') { + concatToRPath(newRPath, dirName); + continue; + } + + /* For each library that we haven't found yet, see if it + exists in this directory. */ + bool libFound = false; + for (unsigned int j = 0; j < neededLibs.size(); ++j) + if (!neededLibFound[j]) { + string libName = dirName + "/" + neededLibs[j]; + struct stat st; + if (stat(libName.c_str(), &st) == 0) { + neededLibFound[j] = true; + libFound = true; + } + } + + if (!libFound) + debug("removing directory `%s' from RPATH\n", dirName.c_str()); + else + concatToRPath(newRPath, dirName); + } + } + + + if (string(rpath ? rpath : "") == newRPath) return; + + changed = true; + + /* Zero out the previous rpath to prevent retained dependencies in + Nix. */ + unsigned int rpathSize = 0; + if (rpath) { + rpathSize = strlen(rpath); + memset(rpath, 'X', rpathSize); + } + + debug("new rpath is `%s'\n", newRPath.c_str()); + + if (!forceRPath && dynRPath && !dynRunPath) { /* convert DT_RPATH to DT_RUNPATH */ + dynRPath->d_tag = DT_RUNPATH; + dynRunPath = dynRPath; + dynRPath = 0; + } + + if (forceRPath && dynRPath && dynRunPath) { /* convert DT_RUNPATH to DT_RPATH */ + dynRunPath->d_tag = DT_IGNORE; + } + + if (newRPath.size() <= rpathSize) { + strcpy(rpath, newRPath.c_str()); + return; + } + + /* Grow the .dynstr section to make room for the new RPATH. */ + debug("rpath is too long, resizing...\n"); + + string & newDynStr = replaceSection(".dynstr", + rdi(shdrDynStr.sh_size) + newRPath.size() + 1); + setSubstr(newDynStr, rdi(shdrDynStr.sh_size), newRPath + '\0'); + + /* Update the DT_RUNPATH and DT_RPATH entries. */ + if (dynRunPath || dynRPath) { + if (dynRunPath) dynRunPath->d_un.d_val = shdrDynStr.sh_size; + if (dynRPath) dynRPath->d_un.d_val = shdrDynStr.sh_size; + } + + else { + /* There is no DT_RUNPATH entry in the .dynamic section, so we + have to grow the .dynamic section. */ + string & newDynamic = replaceSection(".dynamic", + rdi(shdrDynamic.sh_size) + sizeof(Elf_Dyn)); + + unsigned int idx = 0; + for ( ; rdi(((Elf_Dyn *) newDynamic.c_str())[idx].d_tag) != DT_NULL; idx++) ; + debug("DT_NULL index is %d\n", idx); + + /* Shift all entries down by one. */ + setSubstr(newDynamic, sizeof(Elf_Dyn), + string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1))); + + /* Add the DT_RUNPATH entry at the top. */ + Elf_Dyn newDyn; + wri(newDyn.d_tag, forceRPath ? DT_RPATH : DT_RUNPATH); + newDyn.d_un.d_val = shdrDynStr.sh_size; + setSubstr(newDynamic, 0, string((char *) &newDyn, sizeof(Elf_Dyn))); + } +} + + +template +void ElfFile::removeNeeded(set libs) +{ + if (libs.empty()) return; + + Elf_Shdr & shdrDynamic = findSection(".dynamic"); + Elf_Shdr & shdrDynStr = findSection(".dynstr"); + char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset); + + Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); + Elf_Dyn * last = dyn; + for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) { + if (rdi(dyn->d_tag) == DT_NEEDED) { + char * name = strTab + rdi(dyn->d_un.d_val); + if (libs.find(name) != libs.end()) { + debug("removing DT_NEEDED entry `%s'\n", name); + changed = true; + } else { + debug("keeping DT_NEEDED entry `%s'\n", name); + *last++ = *dyn; + } + } else + *last++ = *dyn; + } + + memset(last, 0, sizeof(Elf_Dyn) * (dyn - last)); +} + + +static bool printInterpreter = false; +static string newInterpreter; + +static bool shrinkRPath = false; +static bool setRPath = false; +static bool printRPath = false; +static string newRPath; +static set neededLibsToRemove; + + +template +static void patchElf2(ElfFile & elfFile, mode_t fileMode) +{ + elfFile.parse(); + + if (printInterpreter) + printf("%s\n", elfFile.getInterpreter().c_str()); + + if (newInterpreter != "") + elfFile.setInterpreter(newInterpreter); + + if (printRPath) + elfFile.modifyRPath(elfFile.rpPrint, ""); + + if (shrinkRPath) + elfFile.modifyRPath(elfFile.rpShrink, ""); + else if (setRPath) + elfFile.modifyRPath(elfFile.rpSet, newRPath); + + elfFile.removeNeeded(neededLibsToRemove); + + if (elfFile.isChanged()){ + elfFile.rewriteSections(); + writeFile(fileName, fileMode); + } +} + + +static void patchElf() +{ + if (!printInterpreter && !printRPath) + debug("patching ELF file `%s'\n", fileName.c_str()); + + mode_t fileMode; + + readFile(fileName, &fileMode); + + + /* Check the ELF header for basic validity. */ + if (fileSize < (off_t) sizeof(Elf32_Ehdr)) error("missing ELF header"); + + if (memcmp(contents, ELFMAG, SELFMAG) != 0) + error("not an ELF executable"); + + if (contents[EI_CLASS] == ELFCLASS32 && + contents[EI_VERSION] == EV_CURRENT) + { + ElfFile elfFile; + patchElf2(elfFile, fileMode); + } + else if (contents[EI_CLASS] == ELFCLASS64 && + contents[EI_VERSION] == EV_CURRENT) + { + ElfFile elfFile; + patchElf2(elfFile, fileMode); + } + else { + error("ELF executable is not 32/64-bit, little/big-endian, version 1"); + } +} + + +void showHelp(const string & progName) +{ + fprintf(stderr, "syntax: %s\n\ + [--set-interpreter FILENAME]\n\ + [--print-interpreter]\n\ + [--set-rpath RPATH]\n\ + [--shrink-rpath]\n\ + [--print-rpath]\n\ + [--force-rpath]\n\ + [--remove-needed LIBRARY]\n\ + [--debug]\n\ + [--version]\n\ + FILENAME\n", progName.c_str()); +} + + +int main(int argc, char * * argv) +{ + if (argc <= 1) { + showHelp(argv[0]); + return 1; + } + + if (getenv("PATCHELF_DEBUG") != 0) debugMode = true; + + int i; + for (i = 1; i < argc; ++i) { + string arg(argv[i]); + if (arg == "--set-interpreter" || arg == "--interpreter") { + if (++i == argc) error("missing argument"); + newInterpreter = argv[i]; + } + else if (arg == "--print-interpreter") { + printInterpreter = true; + } + else if (arg == "--shrink-rpath") { + shrinkRPath = true; + } + else if (arg == "--set-rpath") { + if (++i == argc) error("missing argument"); + setRPath = true; + newRPath = argv[i]; + } + else if (arg == "--print-rpath") { + printRPath = true; + } + else if (arg == "--force-rpath") { + /* Generally we prefer to emit DT_RUNPATH instead of + DT_RPATH, as the latter is obsolete. However, there is + a slight semantic difference: DT_RUNPATH is "scoped", + it only affects the executable or library in question, + not its recursive imports. So maybe you really want to + force the use of DT_RPATH. That's what this option + does. Without it, DT_RPATH (if encountered) is + converted to DT_RUNPATH, and if neither is present, a + DT_RUNPATH is added. With it, DT_RPATH isn't converted + to DT_RUNPATH, and if neither is present, a DT_RPATH is + added. */ + forceRPath = true; + } + else if (arg == "--remove-needed") { + if (++i == argc) error("missing argument"); + neededLibsToRemove.insert(argv[i]); + } + else if (arg == "--debug") { + debugMode = true; + } + else if (arg == "--help") { + showHelp(argv[0]); + return 0; + } + else if (arg == "--version") { + printf("1.0\n"); + return 0; + } + else break; + } + + if (i == argc) error("missing filename"); + fileName = argv[i]; + + patchElf(); + + return 0; +} diff --git a/sources/pyside2-tools/CMakeLists.txt b/sources/pyside2-tools/CMakeLists.txt new file mode 100644 index 0000000..ce65750 --- /dev/null +++ b/sources/pyside2-tools/CMakeLists.txt @@ -0,0 +1,127 @@ +cmake_minimum_required(VERSION 3.1) +project(pyside2-tools) + +# Don't display "up-to-date / install" messages when installing, to reduce visual clutter. +if (QUIET_BUILD) + set(CMAKE_INSTALL_MESSAGE NEVER) +endif() + +find_package(Shiboken2 2.0.0 REQUIRED) +find_package(Qt5 REQUIRED Core) +find_package(PySide2 2.0.0 REQUIRED) + +set(pyside2_tools_MAJOR_VERSION "2") +set(pyside2_tools_MINOR_VERSION "0") +set(pyside2_tools_MICRO_VERSION "0") +set(pyside2_tools_VERSION "${pyside2_tools_MAJOR_VERSION}.${pyside2_tools_MINOR_VERSION}.${pyside2_tools_MICRO_VERSION}") + +option(BUILD_TESTS "Build tests." TRUE) + +if(CMAKE_HOST_APPLE) + set(OSX_USE_LIBCPP "OFF" CACHE BOOL "Explicitly link the libc++ standard library (useful for osx deployment targets lower than 10.9.") + if(OSX_USE_LIBCPP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + endif() +endif() + +# UIC stuff +if (NOT PYTHON_SITE_PACKAGES) + execute_process( + COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} -c "if True: + from distutils import sysconfig + from os.path import sep + print(sysconfig.get_python_lib(1, 0, prefix='${CMAKE_INSTALL_PREFIX}').replace(sep, '/')) + " + OUTPUT_VARIABLE PYTHON_SITE_PACKAGES + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT PYTHON_SITE_PACKAGES) + message(FATAL_ERROR "Could not detect Python module installation directory.") + endif() +endif() + +# Handling .exe extension for Window and the uic/rcc executables +if (WIN32) + set(EXE_EXT ".exe") +else() + set(EXE_EXT "") +endif() + +set(TOOLS_PATH "${_qt5Core_install_prefix}/bin") +set(UIC_PATH "${TOOLS_PATH}/uic${EXE_EXT}") +set(RCC_PATH "${TOOLS_PATH}/rcc${EXE_EXT}") +if (APPLE) + set(DESIGNER_PATH "${TOOLS_PATH}/Designer.app") +else() + set(DESIGNER_PATH "${TOOLS_PATH}/designer${EXE_EXT}") +endif() + +install(FILES "${UIC_PATH}" + DESTINATION bin + PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +install(FILES "${RCC_PATH}" + DESTINATION bin + PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +if (EXISTS ${DESIGNER_PATH}) + if (APPLE) + install(DIRECTORY "${DESIGNER_PATH}" + DESTINATION bin + FILE_PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + else() + install(FILES "${DESIGNER_PATH}" + DESTINATION bin + PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + endif() +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +# When opening super project, prevent redefinition of uninstall target. +if (NOT TARGET uninstall) + add_custom_target(uninstall "${CMAKE_COMMAND}" + -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +endif() + + +# Does not work with ninja on Win32. +if (NOT (WIN32 AND CMAKE_GENERATOR STREQUAL "Ninja")) +set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${pyside2_tools_VERSION}) +add_custom_target(dist + COMMAND mkdir -p "${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}" && + git log > "${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}/ChangeLog" && + git archive --prefix=${ARCHIVE_NAME}/ HEAD --format=tar --output="${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar" && + tar -C "${CMAKE_BINARY_DIR}" --owner=root --group=root -r "${ARCHIVE_NAME}/ChangeLog" -f "${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar" && + bzip2 -f9 "${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar" && + echo "Source package created at ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2.\n" + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) +endif() + +add_subdirectory(pylupdate) + +# pyside2-rcc, pyside2-uic, pyside2-designer, shiboken and pyside2-lupdate entrypoints +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/pyside_tool.py + DESTINATION bin + PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_READ + WORLD_EXECUTE WORLD_READ) + +if (BUILD_TESTS) + enable_testing() + add_subdirectory(tests) +endif () diff --git a/sources/pyside2-tools/LICENSE-lupdate b/sources/pyside2-tools/LICENSE-lupdate new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/sources/pyside2-tools/LICENSE-lupdate @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/sources/pyside2-tools/LICENSE-rcc b/sources/pyside2-tools/LICENSE-rcc new file mode 100644 index 0000000..4ccd714 --- /dev/null +++ b/sources/pyside2-tools/LICENSE-rcc @@ -0,0 +1,342 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + +------------------------------------------------------------------------- diff --git a/sources/pyside2-tools/LICENSE-uic b/sources/pyside2-tools/LICENSE-uic new file mode 100644 index 0000000..984e154 --- /dev/null +++ b/sources/pyside2-tools/LICENSE-uic @@ -0,0 +1,372 @@ +Copyright (c) 2005,2006 Torsten Marek . +All rights reserved. + +The software module is double-licensed under the revised BSD and GPL +licenses. + + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/sources/pyside2-tools/README.md b/sources/pyside2-tools/README.md new file mode 100644 index 0000000..a0af623 --- /dev/null +++ b/sources/pyside2-tools/README.md @@ -0,0 +1,21 @@ +Tools +===== + +PySide development tools (pyrcc) + +This repository is the tools for PySide2. If you would like to install PySide2, please go to [pyside2-setup](https://github.com/PySide/pyside2-setup) for instructions. + +Resources: + +* [PySide2-setup](https://github.com/PySide/pyside2-setup) + The container-project with the setup.py script. It contains the following sub-projects: + * [PySide2 Wiki](https://github.com/PySide/pyside2/wiki) + Developer information + * [PySide2](https://github.com/PySide/pyside2) + The PySide2 project + * [Shiboken2](https://github.com/PySide/shiboken2) + The Shiboken2 project + * [PySide2-tools](https://github.com/PySide/pyside2-examples) + The PySide2-tools project + * [PySide2-examples](https://github.com/PySide/pyside2-examples) + The PySide2 example scripts diff --git a/sources/pyside2-tools/cmake_uninstall.cmake b/sources/pyside2-tools/cmake_uninstall.cmake new file mode 100644 index 0000000..df95fb9 --- /dev/null +++ b/sources/pyside2-tools/cmake_uninstall.cmake @@ -0,0 +1,21 @@ +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) diff --git a/sources/pyside2-tools/pylupdate/CMakeLists.txt b/sources/pyside2-tools/pylupdate/CMakeLists.txt new file mode 100644 index 0000000..a46608c --- /dev/null +++ b/sources/pyside2-tools/pylupdate/CMakeLists.txt @@ -0,0 +1,44 @@ + +set(lupdate_SRC +fetchtr.cpp +main.cpp +merge.cpp +metatranslator.cpp +numberh.cpp +proparser.cpp +sametexth.cpp +simtexth.cpp +translator.cpp +) + +find_package(Qt5Core) +find_package(Qt5Gui) +find_package(Qt5Xml) +find_package(Qt5Widgets) + +set(lupdate_MOC_HEADERS translator.h) +qt5_wrap_cpp(lupdate_MOC_OUTFILES ${lupdate_MOC_HEADERS}) + +add_executable(pyside2-lupdate ${lupdate_SRC} ${lupdate_MOC_OUTFILES}) +include_directories(pyside2-lupdate + ${CMAKE_CURRENT_SOURCE_DIR} + ${Qt5Xml_INCLUDE_DIRS} + ${Qt5Core_INCLUDE_DIRS} + ${Qt5Gui_INCLUDE_DIRS} + ${Qt5Widgets_INCLUDE_DIRS} + ) + +target_link_libraries(pyside2-lupdate + ${Qt5Core_LIBRARIES} + ${Qt5Xml_LIBRARIES} + ${Qt5Gui_LIBRARIES} + ${Qt5Widgets_LIBRARIES} + ) + +install(TARGETS pyside2-lupdate RUNTIME DESTINATION bin) + +# Man pages +if (NOT WIN32) + file(GLOB manpages "${CMAKE_CURRENT_SOURCE_DIR}/*.1") + install(FILES ${manpages} DESTINATION share/man/man1) +endif() diff --git a/sources/pyside2-tools/pylupdate/fetchtr.cpp b/sources/pyside2-tools/pylupdate/fetchtr.cpp new file mode 100644 index 0000000..7873236 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/fetchtr.cpp @@ -0,0 +1,889 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +static const char MagicComment[] = "TRANSLATOR "; + +static QMap needs_Q_OBJECT; +static QMap lacks_Q_OBJECT; + +/* + The first part of this source file is the Python tokenizer. We skip + most of Python; the only tokens that interest us are defined here. +*/ + +enum { Tok_Eof, Tok_class, Tok_return, Tok_tr, + Tok_trUtf8, Tok_translate, Tok_Ident, + Tok_Comment, Tok_Dot, Tok_String, + Tok_LeftParen, Tok_RightParen, + Tok_Comma, Tok_None, Tok_Integer}; + +/* + The tokenizer maintains the following global variables. The names + should be self-explanatory. +*/ +static QByteArray yyFileName; +static int yyCh; +static char yyIdent[128]; +static size_t yyIdentLen; +static char yyComment[65536]; +static size_t yyCommentLen; +static char yyString[65536]; +static size_t yyStringLen; +static qlonglong yyInteger; +static QStack yySavedParenDepth; +static int yyParenDepth; +static int yyLineNo; +static int yyCurLineNo; +static int yyParenLineNo; +static QTextCodec *yyCodecForTr = 0; +static QTextCodec *yyCodecForSource = 0; + +// the file to read from (if reading from a file) +static FILE *yyInFile; + +// the string to read from and current position in the string (otherwise) +static QString yyInStr; +static int yyInPos; +static int buf; + +static int (*getChar)(); +static int (*peekChar)(); + +static bool yyParsingUtf8; + +static int yyIndentationSize; +static int yyContinuousSpaceCount; +static bool yyCountingIndentation; + +// (Context, indentation level) pair. +typedef QPair ContextPair; +// Stack of (Context, indentation level) pairs. +typedef QStack ContextStack; +static ContextStack yyContextStack; + +static int yyContextPops; + +static int getCharFromFile() +{ + int c; + + if ( buf < 0 ) + c = getc( yyInFile ); + else { + c = buf; + buf = -1; + } + if ( c == '\n' ) { + yyCurLineNo++; + yyCountingIndentation = true; + yyContinuousSpaceCount = 0; + } else if ( yyCountingIndentation && ( c == 32 || c == 9 ) ) { + yyContinuousSpaceCount++; + } else { + if ( yyIndentationSize == 1 && yyContinuousSpaceCount > yyIndentationSize ) + yyIndentationSize = yyContinuousSpaceCount; + if ( yyCountingIndentation && yyContextStack.count() > 1 ) { + ContextPair& top = yyContextStack.top(); + if ( top.second == 0 && yyContinuousSpaceCount > 0 ) { + top.second = yyContinuousSpaceCount; + yyContinuousSpaceCount = 0; + } else if ( yyContinuousSpaceCount < top.second ) { + yyContextPops = (top.second - yyContinuousSpaceCount) / yyIndentationSize; + } + } + yyCountingIndentation = false; + } + return c; +} + +static int peekCharFromFile() +{ + int c = getc( yyInFile ); + buf = c; + return c; +} + +static void startTokenizer( const char *fileName, int (*getCharFunc)(), + int (*peekCharFunc)(), QTextCodec *codecForTr, QTextCodec *codecForSource ) +{ + yyInPos = 0; + buf = -1; + getChar = getCharFunc; + peekChar = peekCharFunc; + + yyFileName = fileName; + yyCh = getChar(); + yySavedParenDepth.clear(); + yyParenDepth = 0; + yyCurLineNo = 1; + yyParenLineNo = 1; + yyCodecForTr = codecForTr; + if (!yyCodecForTr) + yyCodecForTr = QTextCodec::codecForName("ISO-8859-1"); + Q_ASSERT(yyCodecForTr); + yyCodecForSource = codecForSource; + + yyParsingUtf8 = false; + yyIndentationSize = 1; + yyContinuousSpaceCount = 0; + yyCountingIndentation = false; + yyContextStack.clear(); + yyContextPops = 0; +} + +static int getToken() +{ + const char tab[] = "abfnrtv"; + const char backTab[] = "\a\b\f\n\r\t\v"; + uint n; + bool quiet; + + yyIdentLen = 0; + yyCommentLen = 0; + yyStringLen = 0; + while ( yyCh != EOF ) { + yyLineNo = yyCurLineNo; + + if ( isalpha(yyCh) || yyCh == '_' ) { + do { + if ( yyIdentLen < sizeof(yyIdent) - 1 ) + yyIdent[yyIdentLen++] = (char) yyCh; + yyCh = getChar(); + } while ( isalnum(yyCh) || yyCh == '_' ); + yyIdent[yyIdentLen] = '\0'; + + switch ( yyIdent[0] ) { + case 'N': + if ( strcmp(yyIdent + 1, "one") == 0 ) + return Tok_None; + break; + case 'Q': + if ( strcmp(yyIdent + 1, "T_TR_NOOP") == 0 ) { + yyParsingUtf8 = false; + return Tok_tr; + } else if ( strcmp(yyIdent + 1, "T_TRANSLATE_NOOP") == 0 ) { + yyParsingUtf8 = false; + return Tok_translate; + } + break; + case 'c': + if ( strcmp(yyIdent + 1, "lass") == 0 ) + return Tok_class; + break; + case 'f': + /* + QTranslator::findMessage() has the same parameters as + QApplication::translate(). + */ + if ( strcmp(yyIdent + 1, "indMessage") == 0 ) + return Tok_translate; + break; + case 'r': + if ( strcmp(yyIdent + 1, "eturn") == 0 ) + return Tok_return; + break; + case 't': + if ( strcmp(yyIdent + 1, "r") == 0 ) { + yyParsingUtf8 = false; + return Tok_tr; + } else if ( qstrcmp(yyIdent + 1, "rUtf8") == 0 ) { + yyParsingUtf8 = true; + return Tok_trUtf8; + } else if ( qstrcmp(yyIdent + 1, "ranslate") == 0 ) { + yyParsingUtf8 = false; + return Tok_translate; + } + break; + case '_': + if ( strcmp(yyIdent + 1, "_tr") == 0 ) { + yyParsingUtf8 = false; + return Tok_tr; + } else if ( strcmp(yyIdent + 1, "_trUtf8") == 0 ) { + yyParsingUtf8 = true; + return Tok_trUtf8; + } + break; + } + return Tok_Ident; + } else { + switch ( yyCh ) { + case '#': + yyCh = getChar(); + do { + yyCh = getChar(); + } while ( yyCh != EOF && yyCh != '\n' ); + break; + case '"': + case '\'': + int quoteChar; + int trippelQuote, singleQuote; + int in; + + quoteChar = yyCh; + trippelQuote = 0; + singleQuote = 1; + in = 0; + yyCh = getChar(); + quiet = false; + + while ( yyCh != EOF ) { + if ( singleQuote && (yyCh == '\n' || (in && yyCh == quoteChar)) ) + break; + + if ( yyCh == quoteChar ) { + if (peekChar() == quoteChar) { + yyCh = getChar(); + if (!trippelQuote) { + trippelQuote = 1; + singleQuote = 0; + in = 1; + yyCh = getChar(); + } else { + yyCh = getChar(); + if (yyCh == quoteChar) { + trippelQuote = 0; + break; + } + } + } else if (trippelQuote) { + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) yyCh; + yyCh = getChar(); + continue; + } else + break; + } else + in = 1; + + if ( yyCh == '\\' ) { + yyCh = getChar(); + + if ( yyCh == 'x' ) { + QByteArray hex = "0"; + + yyCh = getChar(); + while ( isxdigit(yyCh) ) { + hex += (char) yyCh; + yyCh = getChar(); + } +#if defined(_MSC_VER) && _MSC_VER >= 1400 + sscanf_s( hex, "%x", &n ); +#else + sscanf( hex, "%x", &n ); +#endif + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) n; + } else if ( yyCh >= '0' && yyCh < '8' ) { + QByteArray oct = ""; + int n = 0; + + do { + oct += (char) yyCh; + ++n; + yyCh = getChar(); + } while ( yyCh >= '0' && yyCh < '8' && n < 3 ); + #if defined(_MSC_VER) && _MSC_VER >= 1400 + sscanf_s( oct, "%o", &n ); + #else + sscanf( oct, "%o", &n ); + #endif + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) n; + } else { + const char *p = strchr( tab, yyCh ); + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = ( p == 0 ) ? + (char) yyCh : backTab[p - tab]; + yyCh = getChar(); + } + } else { + if (!yyCodecForSource) { + if ( yyParsingUtf8 && yyCh >= 0x80 && !quiet) { + qWarning( "%s:%d: Non-ASCII character detected in trUtf8 string", + (const char *) yyFileName, yyLineNo ); + quiet = true; + } + // common case: optimized + if ( yyStringLen < sizeof(yyString) - 1 ) + yyString[yyStringLen++] = (char) yyCh; + yyCh = getChar(); + } else { + QByteArray originalBytes; + while ( yyCh != EOF && (trippelQuote || yyCh != '\n') && yyCh != quoteChar && yyCh != '\\' ) { + if ( yyParsingUtf8 && yyCh >= 0x80 && !quiet) { + qWarning( "%s:%d: Non-ASCII character detected in trUtf8 string", + (const char *) yyFileName, yyLineNo ); + quiet = true; + } + originalBytes += (char)yyCh; + yyCh = getChar(); + } + + QString unicodeStr = yyCodecForSource->toUnicode(originalBytes); + QByteArray convertedBytes; + + if (!yyCodecForTr->canEncode(unicodeStr) && !quiet) { + qWarning( "%s:%d: Cannot convert Python string from %s to %s", + (const char *) yyFileName, yyLineNo, yyCodecForSource->name().constData(), + yyCodecForTr->name().constData() ); + quiet = true; + } + convertedBytes = yyCodecForTr->fromUnicode(unicodeStr); + + size_t len = qMin((size_t)convertedBytes.size(), sizeof(yyString) - yyStringLen - 1); + memcpy(yyString + yyStringLen, convertedBytes.constData(), len); + yyStringLen += len; + } + } + } + yyString[yyStringLen] = '\0'; + + if ( yyCh != quoteChar ) { + printf("%c\n", yyCh); + qWarning( "%s:%d: Unterminated string", + (const char *) yyFileName, yyLineNo ); + } + + if ( yyCh == EOF ) { + return Tok_Eof; + } else { + yyCh = getChar(); + return Tok_String; + } + break; + 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_Dot; + 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(); + } + } + } + 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 int yyTok; + +static bool match( int t ) +{ + bool matches = ( yyTok == t ); + if ( matches ) + yyTok = getToken(); + return matches; +} + +static bool matchString( QByteArray *s ) +{ + bool matches = ( yyTok == Tok_String ); + *s = ""; + while ( yyTok == Tok_String ) { + *s += yyString; + yyTok = getToken(); + } + return matches; +} + +static bool matchEncoding( bool *utf8 ) +{ + // Remove any leading module paths. + if (yyTok == Tok_Ident && strcmp(yyIdent, "PySide2") == 0) + { + yyTok = getToken(); + + if (yyTok != Tok_Dot) + return false; + + yyTok = getToken(); + } + + if (yyTok == Tok_Ident && (strcmp(yyIdent, "QtGui") == 0 || strcmp(yyIdent, "QtCore") == 0)) + { + yyTok = getToken(); + + if (yyTok != Tok_Dot) + return false; + + yyTok = getToken(); + } + + if ( yyTok == Tok_Ident ) { + if (strcmp(yyIdent, "QApplication") == 0 || strcmp(yyIdent, "QCoreApplication") == 0) { + yyTok = getToken(); + + if (yyTok == Tok_Dot) + yyTok = getToken(); + } + *utf8 = QString( yyIdent ).endsWith( QString("UTF8") ); + yyTok = getToken(); + return true; + } else { + return false; + } +} + +static bool matchStringOrNone(QByteArray *s) +{ + bool matches = matchString(s); + + if (!matches) + matches = match(Tok_None); + + return matches; +} + +/* + * 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()') + * + * 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 (parenlevel == 0) { + return false; + } + } + return true; +} + +static void parse( MetaTranslator *tor, const char *initialContext, + const char *defaultContext ) +{ + QByteArray context; + QByteArray text; + QByteArray com; + QByteArray prefix; + bool utf8 = false; + + yyContextStack.push(ContextPair(initialContext, 0)); + + yyTok = getToken(); + while ( yyTok != Tok_Eof ) { + + if (yyContextPops > 0) { + for ( int i = 0; i < yyContextPops; i++) + yyContextStack.pop(); + yyContextPops = 0; + } + + switch ( yyTok ) { + case Tok_class: + yyTok = getToken(); + yyContextStack.push(ContextPair(yyIdent, 0)); + yyContinuousSpaceCount = 0; + yyTok = getToken(); + break; + case Tok_tr: + case Tok_trUtf8: + utf8 = (yyTok == Tok_trUtf8 || (yyCodecForTr && strcmp(yyCodecForTr->name(), "UTF-8") == 0)); + yyTok = getToken(); + if (match(Tok_LeftParen) && matchString(&text)) + { + com = ""; + bool plural = false; + + if (match(Tok_RightParen)) + { + // There is no comment or plural arguments. + } + else if (match(Tok_Comma) && matchStringOrNone(&com)) + { + // There is a comment argument. + if (match(Tok_RightParen)) + { + // There is no plural argument. + } + else if (match(Tok_Comma)) + { + // There is a plural argument. + plural = true; + } + } + + if (prefix.isNull()) + context = defaultContext; + else if (qstrcmp(prefix, "self") == 0) + context = yyContextStack.top().first; + else + context = prefix; + + prefix = (const char *) 0; + + if (!text.isEmpty()) + { + tor->insert(MetaTranslatorMessage(context, text, com, + yyFileName, yyLineNo, + QStringList(), utf8, + MetaTranslatorMessage::Unfinished, plural)); + } + } + break; + case Tok_translate: + utf8 = false; + yyTok = getToken(); + if ( match(Tok_LeftParen) && + matchString(&context) && + match(Tok_Comma) && + matchString(&text) ) { + com = ""; + bool plural = false; + if (!match(Tok_RightParen)) { + // look for comment + if ( match(Tok_Comma) && matchStringOrNone(&com)) { + 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()) + { + tor->insert( MetaTranslatorMessage(context, text, com, + yyFileName, yyLineNo, + QStringList(), utf8, + MetaTranslatorMessage::Unfinished, + plural) ); + } + } + break; + case Tok_Ident: + if ( !prefix.isNull() ) + prefix += "."; + prefix += yyIdent; + yyTok = getToken(); + if ( yyTok != Tok_Dot ) + prefix = (const char *) 0; + break; + case Tok_Comment: + com = yyComment; + com = com.simplified(); + if ( com.left(sizeof(MagicComment) - 1) == MagicComment ) { + com.remove( 0, sizeof(MagicComment) - 1 ); + int k = com.indexOf( ' ' ); + if ( k == -1 ) { + context = com; + } else { + context = com.left( k ); + com.remove( 0, k + 1 ); + tor->insert( MetaTranslatorMessage(context, "", com, + yyFileName, yyLineNo, + QStringList(), false) ); + + } + } + yyTok = getToken(); + break; + default: + yyTok = getToken(); + } + } + + if ( yyParenDepth != 0 ) + qWarning( "%s: Unbalanced parentheses in Python code", + (const char *) yyFileName ); +} + +void fetchtr_py( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist, const QByteArray &codecForSource ) +{ +#if defined(_MSC_VER) && _MSC_VER >= 1400 + if (fopen_s(&yyInFile, fileName, "r")) { + if ( mustExist ) { + char buf[100]; + strerror_s(buf, sizeof(buf), errno); + fprintf( stderr, + "pyside2-lupdate error: Cannot open Python source file '%s': %s\n", + fileName, buf ); + } +#else + yyInFile = fopen( fileName, "r" ); + if ( yyInFile == 0 ) { + if ( mustExist ) + fprintf( stderr, + "pyside2-lupdate error: Cannot open Python source file '%s': %s\n", + fileName, strerror(errno) ); +#endif + return; + } + + startTokenizer( fileName, getCharFromFile, peekCharFromFile, tor->codecForTr(), QTextCodec::codecForName(codecForSource) ); + parse( tor, 0, defaultContext ); + fclose( yyInFile ); +} + +class UiHandler : public QXmlDefaultHandler +{ +public: + UiHandler( MetaTranslator *translator, const char *fileName ) + : tor( translator ), fname( fileName ), comment( "" ) { } + + virtual bool startElement( const QString& namespaceURI, + const QString& localName, const QString& qName, + const QXmlAttributes& atts ); + virtual bool endElement( const QString& namespaceURI, + const QString& localName, const QString& qName ); + virtual bool characters( const QString& ch ); + virtual bool fatalError( const QXmlParseException& exception ); + + virtual void setDocumentLocator(QXmlLocator *locator) + { + m_locator = locator; + } + QXmlLocator *m_locator; +private: + void flush(); + + MetaTranslator *tor; + QByteArray fname; + QString context; + QString source; + QString comment; + + QString accum; + int m_lineNumber; + bool trString; +}; + +bool UiHandler::startElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName, + const QXmlAttributes& atts ) +{ + if ( qName == QString("item") ) { + flush(); + if ( !atts.value(QString("text")).isEmpty() ) + source = atts.value( QString("text") ); + } else if ( qName == QString("string") ) { + flush(); + if (atts.value(QString("notr")).isEmpty() || + atts.value(QString("notr")) != QString("true")) { + trString = true; + comment = atts.value(QString("comment")); + } else { + trString = false; + } + } + if (trString) m_lineNumber = m_locator->lineNumber(); + accum.truncate( 0 ); + return true; +} + +bool UiHandler::endElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName ) +{ + accum.replace( QRegExp(QString("\r\n")), "\n" ); + + if ( qName == QString("class") ) { + if ( context.isEmpty() ) + context = accum; + } else if ( qName == QString("string") && trString ) { + source = accum; + } else if ( qName == QString("comment") ) { + comment = accum; + flush(); + } else { + flush(); + } + return true; +} + +bool UiHandler::characters( const QString& ch ) +{ + accum += ch; + return true; +} + +bool UiHandler::fatalError( const QXmlParseException& exception ) +{ + fprintf(stderr, "XML error: Parse error at line %d, column %d (%s).\n", + exception.lineNumber(), exception.columnNumber(), + qPrintable(exception.message())); + return false; +} + +void UiHandler::flush() +{ + if ( !context.isEmpty() && !source.isEmpty() ) + tor->insert( MetaTranslatorMessage(context.toUtf8(), source.toUtf8(), + comment.toUtf8(), QString(fname), m_lineNumber, + QStringList(), true) ); + source.truncate( 0 ); + comment.truncate( 0 ); +} + +void fetchtr_ui( const char *fileName, MetaTranslator *tor, + const char * /* defaultContext */, bool mustExist ) +{ + QFile f( fileName ); + if ( !f.open(QIODevice::ReadOnly) ) { + if ( mustExist ) { +#if defined(_MSC_VER) && _MSC_VER >= 1400 + char buf[100]; + strerror_s(buf, sizeof(buf), errno); + fprintf( stderr, "pyside2-lupdate error: cannot open UI file '%s': %s\n", + fileName, buf ); +#else + fprintf( stderr, "pyside2-lupdate error: cannot open UI file '%s': %s\n", + fileName, strerror(errno) ); +#endif + } + return; + } + + QXmlInputSource in( &f ); + QXmlSimpleReader reader; + reader.setFeature( "http://xml.org/sax/features/namespaces", false ); + reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", true ); + reader.setFeature( "http://trolltech.com/xml/features/report-whitespace" + "-only-CharData", false ); + QXmlDefaultHandler *hand = new UiHandler( tor, fileName ); + reader.setContentHandler( hand ); + reader.setErrorHandler( hand ); + + if ( !reader.parse(in) ) + fprintf( stderr, "%s: Parse error in UI file\n", fileName ); + reader.setContentHandler( 0 ); + reader.setErrorHandler( 0 ); + delete hand; + f.close(); +} diff --git a/sources/pyside2-tools/pylupdate/main.cpp b/sources/pyside2-tools/pylupdate/main.cpp new file mode 100644 index 0000000..f0e6d5b --- /dev/null +++ b/sources/pyside2-tools/pylupdate/main.cpp @@ -0,0 +1,256 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +// defined in fetchtr.cpp +extern void fetchtr_py( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist, const QByteArray &codecForSource ); +extern void fetchtr_ui( const char *fileName, MetaTranslator *tor, + const char *defaultContext, bool mustExist ); + + + +// defined in merge.cpp +extern void merge( const MetaTranslator *tor, const MetaTranslator *virginTor, MetaTranslator *out, + bool verbose, bool noObsolete ); + +typedef QList TML; + +static void printUsage() +{ + fprintf( stderr, "Usage:\n" + " pyside2-lupdate [options] project-file\n" + " pyside2-lupdate [options] source-files -ts ts-files\n" + "Options:\n" + " -help Display this information and exit\n" + " -noobsolete\n" + " Drop all obsolete strings\n" + " -verbose\n" + " Explain what is being done\n" + " -version\n" + " Display the version of pyside2-lupdate and exit\n" ); +} + +static void updateTsFiles( const MetaTranslator& fetchedTor, + const QStringList& tsFileNames, const QString& codecForTr, + bool noObsolete, bool verbose ) +{ + QStringList::ConstIterator t = tsFileNames.begin(); + QDir dir; + while ( t != tsFileNames.end() ) { + QString fn = dir.relativeFilePath(*t); + MetaTranslator tor; + MetaTranslator out; + tor.load( *t ); + if ( !codecForTr.isEmpty() ) + tor.setCodec( codecForTr.toLatin1() ); + if ( verbose ) + fprintf( stderr, "Updating '%s'...\n", fn.toLatin1().constData() ); + + merge( &tor, &fetchedTor, &out, verbose, noObsolete ); + if ( noObsolete ) + out.stripObsoleteMessages(); + out.stripEmptyContexts(); + if ( !out.save(*t) ) { +#if defined(_MSC_VER) && _MSC_VER >= 1400 + char buf[100]; + strerror_s(buf, sizeof(buf), errno); + fprintf( stderr, "pyside2-lupdate error: Cannot save '%s': %s\n", + fn.toLatin1().constData(), buf ); +#else + fprintf( stderr, "pyside2-lupdate error: Cannot save '%s': %s\n", + fn.toLatin1().constData(), strerror(errno) ); +#endif + } + ++t; + } +} + +int main( int argc, char **argv ) +{ + QString defaultContext = "@default"; + MetaTranslator fetchedTor; + QByteArray codecForTr; + QByteArray codecForSource; + QStringList tsFileNames; + QStringList uiFileNames; + + bool verbose = false; + bool noObsolete = false; + bool metSomething = false; + int numFiles = 0; + bool standardSyntax = true; + bool metTsFlag = false; + + int i; + + for ( i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-ts") == 0 ) + standardSyntax = false; + } + + for ( i = 1; i < argc; i++ ) { + if ( qstrcmp(argv[i], "-help") == 0 ) { + printUsage(); + return 0; + } else if ( qstrcmp(argv[i], "-noobsolete") == 0 ) { + noObsolete = true; + continue; + } else if ( qstrcmp(argv[i], "-verbose") == 0 ) { + verbose = true; + continue; + } else if ( qstrcmp(argv[i], "-version") == 0 ) { + fprintf( stderr, "pyside2-lupdate version %s\n", QT_VERSION_STR ); + return 0; + } else if ( qstrcmp(argv[i], "-ts") == 0 ) { + metTsFlag = true; + continue; + } + + numFiles++; + + QString fullText; + + if ( !metTsFlag ) { + QFile f( argv[i] ); + if ( !f.open(QIODevice::ReadOnly) ) { +#if defined(_MSC_VER) && _MSC_VER >= 1400 + char buf[100]; + strerror_s(buf, sizeof(buf), errno); + fprintf( stderr, "pyside2-lupdate error: Cannot open file '%s': %s\n", + argv[i], buf ); +#else + fprintf( stderr, "pyside2-lupdate error: Cannot open file '%s': %s\n", + argv[i], strerror(errno) ); +#endif + return 1; + } + + QTextStream t( &f ); + fullText = t.readAll(); + f.close(); + } + + QString oldDir = QDir::currentPath(); + QDir::setCurrent( QFileInfo(argv[i]).path() ); + + if ( standardSyntax ) { + fetchedTor = MetaTranslator(); + codecForTr.clear(); + codecForSource.clear(); + tsFileNames.clear(); + uiFileNames.clear(); + + QMap tagMap = proFileTagMap( fullText ); + QMap::Iterator it; + + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + QStringList toks = it.value().split(' '); + QStringList::Iterator t; + + for ( t = toks.begin(); t != toks.end(); ++t ) { + if ( it.key() == "SOURCES" ) { + fetchtr_py( (*t).toUtf8(), &fetchedTor, defaultContext.toUtf8(), true, codecForSource ); + metSomething = true; + } else if ( it.key() == "TRANSLATIONS" ) { + tsFileNames.append( *t ); + metSomething = true; + } else if ( it.key() == "CODEC" || + it.key() == "DEFAULTCODEC" || + it.key() == "CODECFORTR" ) { + codecForTr = (*t).toLatin1(); + fetchedTor.setCodecForTr(codecForTr); + } else if ( it.key() == "CODECFORSRC" ) { + codecForSource = (*t).toLatin1(); + } else if ( it.key() == "FORMS" ) { + fetchtr_ui( (*t).toUtf8(), &fetchedTor, defaultContext.toUtf8(), true); + } + } + } + + updateTsFiles( fetchedTor, tsFileNames, codecForTr, noObsolete, verbose ); + + if ( !metSomething ) { + fprintf( stderr, + "pyside2-lupdate warning: File '%s' does not look like a" + " project file\n", + argv[i] ); + } else if ( tsFileNames.isEmpty() ) { + fprintf( stderr, + "pyside2-lupdate warning: Met no 'TRANSLATIONS' entry in" + " project file '%s'\n", + argv[i] ); + } + } else { + if ( metTsFlag ) { + if ( QString(argv[i]).toLower().endsWith(".ts") ) { + QFileInfo fi( argv[i] ); + if ( !fi.exists() || fi.isWritable() ) { + tsFileNames.append( argv[i] ); + } else { + fprintf( stderr, + "pyside2-lupdate warning: For some reason, I cannot" + " save '%s'\n", + argv[i] ); + } + } else { + fprintf( stderr, + "pyside2-lupdate error: File '%s' lacks .ts extension\n", + argv[i] ); + } + } else { + QFileInfo fi(argv[i]); + if ( fi.suffix() == "py" || fi.suffix() == "pyw" ) { + fetchtr_py( fi.fileName().toUtf8(), &fetchedTor, defaultContext.toUtf8(), true, codecForSource ); + } else { + fetchtr_ui( fi.fileName().toUtf8(), &fetchedTor, defaultContext.toUtf8(), true); + } + } + } + QDir::setCurrent( oldDir ); + } + + if ( !standardSyntax ) + updateTsFiles( fetchedTor, tsFileNames, codecForTr, noObsolete, verbose ); + + if ( numFiles == 0 ) { + printUsage(); + return 1; + } + return 0; +} diff --git a/sources/pyside2-tools/pylupdate/merge.cpp b/sources/pyside2-tools/pylupdate/merge.cpp new file mode 100644 index 0000000..9d0b8ef --- /dev/null +++ b/sources/pyside2-tools/pylupdate/merge.cpp @@ -0,0 +1,199 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2006 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + + +#include "metatranslator.h" +#include "simtexth.h" +#include + +// defined in numberh.cpp +extern int applyNumberHeuristic( MetaTranslator *tor ); +// defined in sametexth.cpp +extern int applySameTextHeuristic( MetaTranslator *tor ); + +typedef QList TML; + +/* + Merges two MetaTranslator objects into the first one. The first one + is a set of source texts and translations for a previous version of + the internationalized program; the second one is a set of fresh + source texts newly extracted from the source code, without any + translation yet. +*/ + +void merge( const MetaTranslator *tor, const MetaTranslator *virginTor, MetaTranslator *outTor, bool verbose, bool noObsolete ) +{ + int known = 0; + int neww = 0; + int obsoleted = 0; + int UntranslatedObsoleted = 0; + int similarTextHeuristicCount = 0; + TML all = tor->messages(); + TML::Iterator it; + outTor->setLanguageCode(tor->languageCode()); + + /* + The types of all the messages from the vernacular translator + are updated according to the virgin translator. + */ + for ( it = all.begin(); it != all.end(); ++it ) { + MetaTranslatorMessage::Type newType = MetaTranslatorMessage::Finished; + MetaTranslatorMessage m = *it; + + // skip context comment + if ( !QByteArray(m.sourceText()).isEmpty() ) { + MetaTranslatorMessage mv = virginTor->find(m.context(), m.sourceText(), m.comment()); + if ( mv.isNull() ) { + mv = virginTor->find(m.context(), m.comment(), m.fileName(), m.lineNumber()); + if ( mv.isNull() ) { + // did not find it in the virgin, mark it as obsolete + newType = MetaTranslatorMessage::Obsolete; + if ( m.type() != MetaTranslatorMessage::Obsolete ) + obsoleted++; + } else { + // Do not just accept it if its on the same line number, but different source text. + // Also check if the texts are more or less similar before we consider them to represent the same message... + // ### The QString() cast is evil + if (getSimilarityScore(QString(m.sourceText()), mv.sourceText()) >= textSimilarityThreshold) { + // It is just slightly modified, assume that it is the same string + m = MetaTranslatorMessage(m.context(), mv.sourceText(), m.comment(), m.fileName(), m.lineNumber(), m.translations()); + m.setPlural(mv.isPlural()); + + // Mark it as unfinished. (Since the source text was changed it might require re-translating...) + newType = MetaTranslatorMessage::Unfinished; + ++similarTextHeuristicCount; + } else { + // The virgin and vernacular sourceTexts are so different that we could not find it. + newType = MetaTranslatorMessage::Obsolete; + if ( m.type() != MetaTranslatorMessage::Obsolete ) + obsoleted++; + } + neww++; + } + } else { + switch ( m.type() ) { + case MetaTranslatorMessage::Finished: + default: + if (m.isPlural() == mv.isPlural()) { + newType = MetaTranslatorMessage::Finished; + } else { + newType = MetaTranslatorMessage::Unfinished; + } + known++; + break; + case MetaTranslatorMessage::Unfinished: + newType = MetaTranslatorMessage::Unfinished; + known++; + break; + case MetaTranslatorMessage::Obsolete: + newType = MetaTranslatorMessage::Unfinished; + neww++; + } + + // Always get the filename and linenumber info from the virgin Translator, in case it has changed location. + // This should also enable us to read a file that does not have the element. + m.setFileName(mv.fileName()); + m.setLineNumber(mv.lineNumber()); + m.setPlural(mv.isPlural()); // ### why not use operator=? + } + + if (newType == MetaTranslatorMessage::Obsolete && !m.isTranslated()) { + ++UntranslatedObsoleted; + } + + m.setType(newType); + outTor->insert(m); + } + } + + /* + Messages found only in the virgin translator are added to the + vernacular translator. Among these are all the context comments. + */ + all = virginTor->messages(); + + for ( it = all.begin(); it != all.end(); ++it ) { + MetaTranslatorMessage mv = *it; + bool found = tor->contains(mv.context(), mv.sourceText(), mv.comment()); + if (!found) { + MetaTranslatorMessage m = tor->find(mv.context(), mv.comment(), mv.fileName(), mv.lineNumber()); + if (!m.isNull()) { + if (getSimilarityScore(QString(m.sourceText()), mv.sourceText()) >= textSimilarityThreshold) { + found = true; + } + } else { + found = false; + } + } + if ( !found ) { + outTor->insert( mv ); + if ( !QByteArray(mv.sourceText()).isEmpty() ) + neww++; + } + } + + /* + The same-text heuristic handles cases where a message has an + obsolete counterpart with a different context or comment. + */ + int sameTextHeuristicCount = applySameTextHeuristic( outTor ); + + /* + The number heuristic handles cases where a message has an + obsolete counterpart with mostly numbers differing in the + source text. + */ + int sameNumberHeuristicCount = applyNumberHeuristic( outTor ); + + if ( verbose ) { + int totalFound = neww + known; + fprintf( stderr, " Found %d source text%s (%d new and %d already existing)\n", + totalFound, totalFound == 1 ? "" : "s", neww, known); + + if (obsoleted) { + if (noObsolete) { + fprintf( stderr, " Removed %d obsolete entr%s\n", + obsoleted, obsoleted == 1 ? "y" : "ies" ); + } else { + int total = obsoleted - UntranslatedObsoleted; + fprintf( stderr, " Kept %d obsolete translation%s\n", + total, total == 1 ? "" : "s" ); + + fprintf( stderr, " Removed %d obsolete untranslated entr%s\n", + UntranslatedObsoleted, UntranslatedObsoleted == 1 ? "y" : "ies" ); + + } + } + + if (sameNumberHeuristicCount) + fprintf( stderr, " Number heuristic provided %d translation%s\n", + sameNumberHeuristicCount, sameNumberHeuristicCount == 1 ? "" : "s" ); + if (sameTextHeuristicCount) + fprintf( stderr, " Same-text heuristic provided %d translation%s\n", + sameTextHeuristicCount, sameTextHeuristicCount == 1 ? "" : "s" ); + if (similarTextHeuristicCount) + fprintf( stderr, " Similar-text heuristic provided %d translation%s\n", + similarTextHeuristicCount, similarTextHeuristicCount == 1 ? "" : "s" ); + } +} diff --git a/sources/pyside2-tools/pylupdate/metatranslator.cpp b/sources/pyside2-tools/pylupdate/metatranslator.cpp new file mode 100644 index 0000000..8a8ac8e --- /dev/null +++ b/sources/pyside2-tools/pylupdate/metatranslator.cpp @@ -0,0 +1,766 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "metatranslator.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool encodingIsUtf8( const QXmlAttributes& atts ) +{ + for ( int i = 0; i < atts.length(); i++ ) { + // utf8="true" is a pre-3.0 syntax + if ( atts.qName(i) == QString("utf8") ) { + return ( atts.value(i) == QString("true") ); + } else if ( atts.qName(i) == QString("encoding") ) { + return ( atts.value(i) == QString("UTF-8") ); + } + } + return false; +} + +class TsHandler : public QXmlDefaultHandler +{ +public: + TsHandler( MetaTranslator *translator ) + : tor( translator ), type( MetaTranslatorMessage::Finished ), + inMessage( false ), ferrorCount( 0 ), contextIsUtf8( false ), + messageIsUtf8( false ), m_isPlural(false) { } + + virtual bool startElement( const QString& namespaceURI, + const QString& localName, const QString& qName, + const QXmlAttributes& atts ); + virtual bool endElement( const QString& namespaceURI, + const QString& localName, const QString& qName ); + virtual bool characters( const QString& ch ); + virtual bool fatalError( const QXmlParseException& exception ); + QString language() const { return m_language; } + +private: + MetaTranslator *tor; + MetaTranslatorMessage::Type type; + bool inMessage; + QString m_language; + QString context; + QString source; + QString comment; + QStringList translations; + QString m_fileName; + int m_lineNumber; + + QString accum; + int ferrorCount; + bool contextIsUtf8; + bool messageIsUtf8; + bool m_isPlural; +}; + +bool TsHandler::startElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName, + const QXmlAttributes& atts ) +{ + if ( qName == QString("byte") ) { + for ( int i = 0; i < atts.length(); i++ ) { + if ( atts.qName(i) == QString("value") ) { + QString value = atts.value( i ); + int base = 10; + if ( value.startsWith("x") ) { + base = 16; + value = value.mid( 1 ); + } + int n = value.toUInt( 0, base ); + if ( n != 0 ) + accum += QChar( n ); + } + } + } else { + if ( qName == QString("TS") ) { + m_language = atts.value(QLatin1String("language")); + } else if ( qName == QString("context") ) { + context.truncate( 0 ); + source.truncate( 0 ); + comment.truncate( 0 ); + translations.clear(); + contextIsUtf8 = encodingIsUtf8( atts ); + } else if ( qName == QString("message") ) { + inMessage = true; + type = MetaTranslatorMessage::Finished; + source.truncate( 0 ); + comment.truncate( 0 ); + translations.clear(); + messageIsUtf8 = encodingIsUtf8( atts ); + m_isPlural = atts.value(QLatin1String("numerus")).compare(QLatin1String("yes")) == 0; + } else if (qName == QString("location") && inMessage) { + bool bOK; + int lineNo = atts.value(QString("line")).toInt(&bOK); + if (!bOK) lineNo = -1; + m_fileName = atts.value(QString("filename")); + m_lineNumber = lineNo; + } else if ( qName == QString("translation") ) { + for ( int i = 0; i < atts.length(); i++ ) { + if ( atts.qName(i) == QString("type") ) { + if ( atts.value(i) == QString("unfinished") ) + type = MetaTranslatorMessage::Unfinished; + else if ( atts.value(i) == QString("obsolete") ) + type = MetaTranslatorMessage::Obsolete; + else + type = MetaTranslatorMessage::Finished; + } + } + } + accum.truncate( 0 ); + } + return true; +} + +bool TsHandler::endElement( const QString& /* namespaceURI */, + const QString& /* localName */, + const QString& qName ) +{ + if ( qName == QString("codec") || qName == QString("defaultcodec") ) { + // "codec" is a pre-3.0 syntax + tor->setCodec( accum.toLatin1() ); + } else if ( qName == QString("name") ) { + context = accum; + } else if ( qName == QString("source") ) { + source = accum; + } else if ( qName == QString("comment") ) { + if ( inMessage ) { + comment = accum; + } else { + if ( contextIsUtf8 ) + tor->insert( MetaTranslatorMessage(context.toUtf8(), + ContextComment, + accum.toUtf8(), QString(), 0, + QStringList(), true, + MetaTranslatorMessage::Unfinished) ); + else + tor->insert( MetaTranslatorMessage(context.toUtf8(), + ContextComment, + accum.toUtf8(), QString(), 0, + QStringList(), false, + MetaTranslatorMessage::Unfinished) ); + } + } else if ( qName == QString("numerusform") ) { + translations.append(accum); + m_isPlural = true; + } else if ( qName == QString("translation") ) { + if (translations.isEmpty()) + translations.append(accum); + } else if ( qName == QString("message") ) { + if ( messageIsUtf8 ) + tor->insert( MetaTranslatorMessage(context.toUtf8(), source.toUtf8(), + comment.toUtf8(), m_fileName, m_lineNumber, + translations, true, type, m_isPlural) ); + else + tor->insert( MetaTranslatorMessage(context.toUtf8(), source.toUtf8(), + comment.toUtf8(), m_fileName, m_lineNumber, + translations, false, type, m_isPlural) ); + inMessage = false; + } + return true; +} + +bool TsHandler::characters( const QString& ch ) +{ + QString t = ch; + t.replace( "\r", "" ); + accum += t; + return true; +} + +bool TsHandler::fatalError( const QXmlParseException& exception ) +{ + if ( ferrorCount++ == 0 ) { + const QString msg = QString::asprintf( "Parse error at line %d, column %d (%s).", + exception.lineNumber(), exception.columnNumber(), + exception.message().toLatin1().data() ); + if ( qApp == 0 ) + fprintf( stderr, "XML error: %s\n", msg.toLatin1().data() ); + else + QMessageBox::information(0, + QObject::tr("Qt Linguist"), msg ); + } + return false; +} + +static QString numericEntity( int ch ) +{ + return QString( ch <= 0x20 ? "" : "&#x%1;" ) + .arg( ch, 0, 16 ); +} + +static QString protect( const QByteArray& str ) +{ + QString result; + int len = (int) str.length(); + for ( int k = 0; k < len; k++ ) { + switch( str[k] ) { + case '\"': + result += QString( """ ); + break; + case '&': + result += QString( "&" ); + break; + case '>': + result += QString( ">" ); + break; + case '<': + result += QString( "<" ); + break; + case '\'': + result += QString( "'" ); + break; + default: + if ( (uchar) str[k] < 0x20 && str[k] != '\n' ) + result += numericEntity( (uchar) str[k] ); + else + result += str[k]; + } + } + return result; +} + +static QString evilBytes( const QByteArray& str, bool utf8 ) +{ + if ( utf8 ) { + return protect( str ); + } else { + QString result; + QByteArray t = protect( str ).toLatin1(); + int len = (int) t.length(); + for ( int k = 0; k < len; k++ ) { + if ( (uchar) t[k] >= 0x7f ) + result += numericEntity( (uchar) t[k] ); + else + result += QChar( t[k] ); + } + return result; + } +} + +MetaTranslatorMessage::MetaTranslatorMessage() + : utfeight( false ), ty( Unfinished ), m_plural(false) +{ +} + +MetaTranslatorMessage::MetaTranslatorMessage( const char *context, + const char *sourceText, + const char *comment, + const QString &fileName, + int lineNumber, + const QStringList& translations, + bool utf8, Type type, bool plural ) + : TranslatorMessage( context, sourceText, comment, fileName, lineNumber, translations ), + utfeight( false ), ty( type ), m_plural(plural) +{ + /* + Don't use UTF-8 if it makes no difference. UTF-8 should be + reserved for the real problematic case: non-ASCII (possibly + non-Latin1) characters in .ui files. + */ + if ( utf8 ) { + if ( sourceText != 0 ) { + int i = 0; + while ( sourceText[i] != '\0' ) { + if ( (uchar) sourceText[i] >= 0x80 ) { + utfeight = true; + break; + } + i++; + } + } + if ( !utfeight && comment != 0 ) { + int i = 0; + while ( comment[i] != '\0' ) { + if ( (uchar) comment[i] >= 0x80 ) { + utfeight = true; + break; + } + i++; + } + } + } +} + +MetaTranslatorMessage::MetaTranslatorMessage( const MetaTranslatorMessage& m ) + : TranslatorMessage( m ), utfeight( m.utfeight ), ty( m.ty ), m_plural(m.m_plural) +{ +} + +MetaTranslatorMessage& MetaTranslatorMessage::operator=( + const MetaTranslatorMessage& m ) +{ + TranslatorMessage::operator=( m ); + utfeight = m.utfeight; + ty = m.ty; + m_plural = m.m_plural; + return *this; +} + +bool MetaTranslatorMessage::operator==( const MetaTranslatorMessage& m ) const +{ + return qstrcmp( context(), m.context() ) == 0 && + qstrcmp( sourceText(), m.sourceText() ) == 0 && + qstrcmp( comment(), m.comment() ) == 0; +} + +bool MetaTranslatorMessage::operator<( const MetaTranslatorMessage& m ) const +{ + int delta = qstrcmp( context(), m.context() ); + if ( delta == 0 ) { + delta = qstrcmp( sourceText(), m.sourceText() ); + if ( delta == 0 ) + delta = qstrcmp( comment(), m.comment() ); + } + return delta < 0; +} + +MetaTranslator::MetaTranslator() +{ + clear(); +} + +MetaTranslator::MetaTranslator( const MetaTranslator& tor ) + : mm( tor.mm ), codecName( tor.codecName ), codec( tor.codec ) +{ +} + +MetaTranslator& MetaTranslator::operator=( const MetaTranslator& tor ) +{ + mm = tor.mm; + codecName = tor.codecName; + codec = tor.codec; + return *this; +} + +void MetaTranslator::clear() +{ + mm.clear(); + codecName = "ISO-8859-1"; + codec = 0; +} + +bool MetaTranslator::load( const QString& filename ) +{ + QFile f( filename ); + if ( !f.open(QIODevice::ReadOnly) ) + return false; + + QXmlInputSource in( &f ); + QXmlSimpleReader reader; + reader.setFeature( "http://xml.org/sax/features/namespaces", false ); + reader.setFeature( "http://xml.org/sax/features/namespace-prefixes", true ); + TsHandler *hand = new TsHandler( this ); + reader.setContentHandler( static_cast(hand) ); + reader.setErrorHandler( static_cast(hand) ); + + bool ok = reader.parse( in ); + reader.setContentHandler( 0 ); + reader.setErrorHandler( 0 ); + + m_language = hand->language(); + makeFileNamesAbsolute(QFileInfo(filename).absoluteDir()); + + delete hand; + f.close(); + return ok; +} + +bool MetaTranslator::save( const QString& filename ) const +{ + QFile f( filename ); + if ( !f.open(QIODevice::WriteOnly) ) + return false; + + QTextStream t( &f ); + t.setCodec( QTextCodec::codecForName("ISO-8859-1") ); + + //### The xml prolog allows processors to easily detect the correct encoding + t << "\n\n"; + if ( codecName != "ISO-8859-1" ) + t << "" << codecName << "\n"; + TMM::ConstIterator m = mm.begin(); + while ( m != mm.end() ) { + TMMInv inv; + TMMInv::Iterator i; + bool contextIsUtf8 = m.key().utf8(); + QByteArray context = m.key().context(); + QByteArray comment = ""; + + do { + if (QByteArray(m.key().sourceText()) == ContextComment) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { + contextIsUtf8 = m.key().utf8(); + comment = QByteArray(m.key().comment()); + } + } else { + inv.insert( *m, m.key() ); + } + } while ( ++m != mm.end() && QByteArray(m.key().context()) == context ); + + if ( inv.isEmpty() ) + continue; + + t << "\n"; + t << " " << evilBytes( context, contextIsUtf8 ) + << "\n"; + if ( !comment.isEmpty() ) + t << " " << evilBytes( comment, contextIsUtf8 ) + << "\n"; + + for ( i = inv.begin(); i != inv.end(); ++i ) { + MetaTranslatorMessage msg = *i; + // no need for such noise + if ( msg.type() == MetaTranslatorMessage::Obsolete && + msg.translation().isEmpty() ) + continue; + + t << " \n"; + if (!msg.fileName().isEmpty() && msg.lineNumber() >= 0) { + QDir tsPath = QFileInfo(filename).absoluteDir(); + QString fn = tsPath.relativeFilePath(msg.fileName()).replace('\\','/'); + t << " \n"; + } + t << " " << evilBytes( msg.sourceText(), + msg.utf8() ) + << "\n"; + if ( !QByteArray(msg.comment()).isEmpty() ) + t << " " << evilBytes( msg.comment(), + msg.utf8() ) + << "\n"; + t << " "; + if (msg.isPlural()) { + t << "\n"; + QLocale::Language l; + QLocale::Country c; + languageAndCountry(m_language, &l, &c); + QStringList translns = normalizedTranslations(msg, l, c); + for (int j = 0; j < qMax(1, translns.count()); ++j) + t << " " << protect( translns.value(j).toUtf8() ) << "\n"; + t << " "; + } else { + t << protect( msg.translation().toUtf8() ); + } + t << "\n"; + t << " \n"; + } + t << "\n"; + } + t << "\n"; + f.close(); + return true; +} + +void MetaTranslator::languageAndCountry(const QString &languageCode, QLocale::Language *lang, QLocale::Country *country) +{ + QLocale locale(languageCode); + if (lang) + *lang = locale.language(); + + if (country) { + if (languageCode.indexOf(QLatin1Char('_')) != -1) { + *country = locale.country(); + } else { + *country = QLocale::AnyCountry; + } + } +} + +bool MetaTranslator::release( const QString& filename, bool verbose, + bool ignoreUnfinished, + Translator::SaveMode mode ) const +{ + Translator tor( 0 ); + int finished = 0; + int unfinished = 0; + int untranslated = 0; + TMM::ConstIterator m; + + for ( m = mm.begin(); m != mm.end(); ++m ) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) { + if ( m.key().translation().isEmpty() ) { + untranslated++; + } else { + if ( m.key().type() == MetaTranslatorMessage::Unfinished ) + unfinished++; + else + finished++; + + QByteArray context = m.key().context(); + QByteArray sourceText = m.key().sourceText(); + QByteArray comment = m.key().comment(); + QStringList translations = m.key().translations(); + + if ( !ignoreUnfinished + || m.key().type() != MetaTranslatorMessage::Unfinished ) { + /* + Drop the comment in (context, sourceText, comment), + unless the context is empty, + unless (context, sourceText, "") already exists or + unless we already dropped the comment of (context, + sourceText, comment0). + */ + if ( comment.isEmpty() + || context.isEmpty() + || contains(context, sourceText, "") + || !tor.findMessage(context, sourceText, "").translation() + .isNull() ) { + tor.insert( m.key() ); + } else { + tor.insert( TranslatorMessage(context, sourceText, "", + QString(), -1, translations) ); + //filename and lineNumbers will be ignored from now. + } + } + } + } + } + + bool saved = tor.save( filename, mode ); + if ( saved && verbose ) + fprintf( stderr, + " %d finished, %d unfinished and %d untranslated messages\n", + finished, unfinished, untranslated ); + + return saved; +} + +QString MetaTranslator::languageCode() const +{ + return m_language; +} + +void MetaTranslator::setLanguageCode(const QString &languageCode) +{ + m_language = languageCode; +} + +bool MetaTranslator::contains( const char *context, const char *sourceText, + const char *comment ) const +{ + return mm.contains(MetaTranslatorMessage(context, sourceText, comment, QString(), 0)); +} + +MetaTranslatorMessage MetaTranslator::find( const char *context, + const char *sourceText, const char *comment ) const +{ + QMap::const_iterator it = + mm.constFind(MetaTranslatorMessage(context, sourceText, comment, QString(), 0)); + return (it == mm.constEnd() ? MetaTranslatorMessage() : it.key()); +} + +MetaTranslatorMessage MetaTranslator::find(const char *context, const char *comment, + const QString &fileName, int lineNumber) const +{ + if (lineNumber >= 0 && !fileName.isEmpty()) { + MetaTranslatorMessage m; + + for (QMap::const_iterator it = mm.constBegin(); + it != mm.constEnd(); ++it) { + m = it.key(); + int delta = qstrcmp(m.context(), context); + if (delta == 0) { + delta = qstrcmp(m.comment(), comment); + if (delta == 0) { + delta = QString::compare(m.fileName(), fileName); + if (delta == 0) { + delta = m.lineNumber() - lineNumber; + if (delta == 0) + return m; + } + } + } + } + } + return MetaTranslatorMessage(); +} + +void MetaTranslator::insert( const MetaTranslatorMessage& m ) +{ + int pos = mm.count(); + if (mm.contains(m)) { + pos = mm.value(m); + mm.remove(m); + } + mm.insert(m, pos); +} + +void MetaTranslator::stripObsoleteMessages() +{ + TMM newmm; + TMM::Iterator m = mm.begin(); + while ( m != mm.end() ) { + if ( m.key().type() != MetaTranslatorMessage::Obsolete ) + newmm.insert( m.key(), *m ); + ++m; + } + mm = newmm; +} + +void MetaTranslator::stripEmptyContexts() +{ + TMM newmm; + + TMM::Iterator m = mm.begin(); + while ( m != mm.end() ) { + if ( QByteArray(m.key().sourceText()) == ContextComment ) { + TMM::Iterator n = m; + ++n; + // the context comment is followed by other messages + if ( n != newmm.end() && + qstrcmp(m.key().context(), n.key().context()) == 0 ) + newmm.insert( m.key(), *m ); + } else { + newmm.insert( m.key(), *m ); + } + ++m; + } + mm = newmm; +} + +void MetaTranslator::makeFileNamesAbsolute(const QDir &oldPath) +{ + TMM newmm; + for (TMM::iterator m = mm.begin(); m != mm.end(); ++m) { + MetaTranslatorMessage msg = m.key(); + QString fileName = m.key().fileName(); + QFileInfo fi (fileName); + if (fi.isRelative()) { + fileName = oldPath.absoluteFilePath(fileName); + } + + msg.setFileName(fileName); + newmm.insert(msg, m.value()); + } + mm = newmm; +} + +void MetaTranslator::setCodec( const char *name ) +{ + const int latin1 = 4; + + codecName = name; + codec = QTextCodec::codecForName( name ); + if ( codec == 0 || codec->mibEnum() == latin1 ) + codec = 0; +} + +QString MetaTranslator::toUnicode( const char *str, bool utf8 ) const +{ + if ( utf8 ) + return QString::fromUtf8( str ); + else if ( codec == 0 ) + return QString( str ); + else + return codec->toUnicode( str ); +} + +QList MetaTranslator::messages() const +{ + int n = mm.count(); + TMM::ConstIterator *t = new TMM::ConstIterator[n + 1]; + TMM::ConstIterator m; + for ( m = mm.begin(); m != mm.end(); ++m ) + t[*m] = m; + + QList val; + for ( int i = 0; i < n; i++ ) + val.append( t[i].key() ); + + delete[] t; + return val; +} + +QList MetaTranslator::translatedMessages() const +{ + QList val; + TMM::ConstIterator m; + for ( m = mm.begin(); m != mm.end(); ++m ) { + if ( m.key().type() == MetaTranslatorMessage::Finished ) + val.append( m.key() ); + } + return val; +} + +// the grammatical numerus is the number of plural forms + singular forms. +// i.e english has two forms: singular og plural. +// and polish has three forms: +// 1. singular (1), +// 2. plural form 1 (numbers that ends with 2,3,4 except 12,13,14) +// 3. plural form 2 (all others) +// Thus, english returns 2, polish returns 3 +int MetaTranslator::grammaticalNumerus(QLocale::Language language, QLocale::Country country) +{ + QStringList forms; + getNumerusInfo(language, country, &forms); + return forms.count(); +} + +QStringList MetaTranslator::normalizedTranslations(const MetaTranslatorMessage& m, + QLocale::Language language, + QLocale::Country country) +{ + QStringList translations = m.translations(); + int numTranslations = 1; + if (m.isPlural()) { + numTranslations = grammaticalNumerus(language, country); + } + + // make sure that the stringlist always have the size of the language's current numerus, or 1 if its not plural + if (translations.count() > numTranslations) { + for (int i = translations.count(); i > numTranslations; --i) + translations.removeLast(); + } else if (translations.count() < numTranslations) { + for (int i = translations.count(); i < numTranslations; ++i) + translations << QString(); + } + return translations; +} diff --git a/sources/pyside2-tools/pylupdate/metatranslator.h b/sources/pyside2-tools/pylupdate/metatranslator.h new file mode 100644 index 0000000..8575351 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/metatranslator.h @@ -0,0 +1,144 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef METATRANSLATOR_H +#define METATRANSLATOR_H + +#include +#include +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QTextCodec) + +class MetaTranslatorMessage : public TranslatorMessage +{ +public: + enum Type { Unfinished, Finished, Obsolete }; + + MetaTranslatorMessage(); + MetaTranslatorMessage( const char *context, const char *sourceText, + const char *comment, + const QString &fileName, int lineNumber, + const QStringList& translations = QStringList(), + bool utf8 = false, Type type = Unfinished, + bool plural = false ); + MetaTranslatorMessage( const MetaTranslatorMessage& m ); + + MetaTranslatorMessage& operator=( const MetaTranslatorMessage& m ); + + void setType( Type nt ) { ty = nt; } + Type type() const { return ty; } + bool utf8() const { return utfeight; } + bool isPlural() const { return m_plural; } + void setPlural(bool isplural) { m_plural = isplural; } + + bool operator==( const MetaTranslatorMessage& m ) const; + bool operator!=( const MetaTranslatorMessage& m ) const + { return !operator==( m ); } + bool operator<( const MetaTranslatorMessage& m ) const; + bool operator<=( const MetaTranslatorMessage& m ) + { return !operator>( m ); } + bool operator>( const MetaTranslatorMessage& m ) const + { return this->operator<( m ); } + bool operator>=( const MetaTranslatorMessage& m ) const + { return !operator<( m ); } + +private: + bool utfeight; + Type ty; + bool m_plural; +}; + +class MetaTranslator +{ +public: + MetaTranslator(); + MetaTranslator( const MetaTranslator& tor ); + + MetaTranslator& operator=( const MetaTranslator& tor ); + + void clear(); + bool load( const QString& filename ); + bool save( const QString& filename ) const; + bool release( const QString& filename, bool verbose = false, + bool ignoreUnfinished = false, + Translator::SaveMode mode = Translator::Stripped ) const; + + bool contains( const char *context, const char *sourceText, + const char *comment ) const; + + MetaTranslatorMessage find( const char *context, const char *sourceText, + const char *comment ) const; + MetaTranslatorMessage find(const char *context, const char *comment, + const QString &fileName, int lineNumber) const; + + void insert( const MetaTranslatorMessage& m ); + + void stripObsoleteMessages(); + void stripEmptyContexts(); + + void setCodec( const char *name ); // kill me + void setCodecForTr( const char *name ) { setCodec(name); } + QTextCodec *codecForTr() const { return codec; } + QString toUnicode( const char *str, bool utf8 ) const; + + QString languageCode() const; + static void languageAndCountry(const QString &languageCode, QLocale::Language *lang, QLocale::Country *country); + void setLanguageCode(const QString &languageCode); + QList messages() const; + QList translatedMessages() const; + static int grammaticalNumerus(QLocale::Language language, QLocale::Country country); + static QStringList normalizedTranslations(const MetaTranslatorMessage& m, + QLocale::Language lang, QLocale::Country country); + +private: + void makeFileNamesAbsolute(const QDir &oldPath); + + typedef QMap TMM; + typedef QMap TMMInv; + + TMM mm; + QByteArray codecName; + QTextCodec *codec; + QString m_language; // A string beginning with a 2 or 3 letter language code (ISO 639-1 or ISO-639-2), + // followed by the optional country variant to distinguist between country-specific variations + // of the language. The language code and country code are always separated by '_' + // Note that the language part can also be a 3-letter ISO 639-2 code. + // Legal examples: + // 'pt' portuguese, assumes portuguese from portugal + // 'pt_BR' Brazilian portuguese (ISO 639-1 language code) + // 'por_BR' Brazilian portuguese (ISO 639-2 language code) +}; + +/* + This is a quick hack. The proper way to handle this would be + to extend MetaTranslator's interface. +*/ +#define ContextComment "QT_LINGUIST_INTERNAL_CONTEXT_COMMENT" + +#endif diff --git a/sources/pyside2-tools/pylupdate/numberh.cpp b/sources/pyside2-tools/pylupdate/numberh.cpp new file mode 100644 index 0000000..04f2d41 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/numberh.cpp @@ -0,0 +1,240 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2006 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "metatranslator.h" + +#include +#include +#include +#include +#include + +typedef QMap TMM; +typedef QList TML; + +static bool isDigitFriendly( int c ) +{ + return ispunct((uchar)c) || isspace((uchar)c); +} + +static int numberLength( const char *s ) +{ + int i = 0; + + if ( isdigit((uchar)s[0]) ) { + do { + i++; + } while (isdigit((uchar)s[i]) || + (isDigitFriendly(s[i]) && + (isdigit((uchar)s[i + 1]) || + (isDigitFriendly(s[i + 1]) && isdigit((uchar)s[i + 2]))))); + } + return i; +} + +/* + Returns a version of 'key' where all numbers have been replaced by zeroes. If + there were none, returns "". +*/ +static QByteArray zeroKey( const char *key ) +{ + QByteArray zeroed; + zeroed.resize( int(strlen(key)) + 1 ); + char *z = zeroed.data(); + int i = 0, j = 0; + int len; + bool metSomething = false; + + while ( key[i] != '\0' ) { + len = numberLength( key + i ); + if ( len > 0 ) { + i += len; + z[j++] = '0'; + metSomething = true; + } else { + z[j++] = key[i++]; + } + } + z[j] = '\0'; + + if ( metSomething ) + return zeroed; + else + return ""; +} + +static QString translationAttempt( const QString& oldTranslation, + const char *oldSource, + const char *newSource ) +{ + int p = zeroKey( oldSource ).count( '0' ); + int oldSourceLen = qstrlen( oldSource ); + QString attempt; + QStringList oldNumbers; + QStringList newNumbers; + QVector met( p ); + QVector matchedYet( p ); + int i, j; + int k = 0, ell, best; + int m, n; + int pass; + + /* + This algorithm is hard to follow, so we'll consider an example + all along: oldTranslation is "XeT 3.0", oldSource is "TeX 3.0" + and newSource is "XeT 3.1". + + First, we set up two tables: oldNumbers and newNumbers. In our + example, oldNumber[0] is "3.0" and newNumber[0] is "3.1". + */ + for ( i = 0, j = 0; i < oldSourceLen; i++, j++ ) { + m = numberLength( oldSource + i ); + n = numberLength( newSource + j ); + if ( m > 0 ) { + oldNumbers.append( QByteArray(oldSource + i, m + 1) ); + newNumbers.append( QByteArray(newSource + j, n + 1) ); + i += m; + j += n; + met[k] = false; + matchedYet[k] = 0; + k++; + } + } + + /* + We now go over the old translation, "XeT 3.0", one letter at a + time, looking for numbers found in oldNumbers. Whenever such a + number is met, it is replaced with its newNumber equivalent. In + our example, the "3.0" of "XeT 3.0" becomes "3.1". + */ + for ( i = 0; i < (int) oldTranslation.length(); i++ ) { + attempt += oldTranslation[i]; + for ( k = 0; k < p; k++ ) { + if ( oldTranslation[i] == oldNumbers[k][matchedYet[k]] ) + matchedYet[k]++; + else + matchedYet[k] = 0; + } + + /* + Let's find out if the last character ended a match. We make + two passes over the data. In the first pass, we try to + match only numbers that weren't matched yet; if that fails, + the second pass does the trick. This is useful in some + suspicious cases, flagged below. + */ + for ( pass = 0; pass < 2; pass++ ) { + best = p; // an impossible value + for ( k = 0; k < p; k++ ) { + if ( (!met[k] || pass > 0) && + matchedYet[k] == (int) oldNumbers[k].length() && + numberLength(oldTranslation.toLatin1().constData() + (i + 1) - + matchedYet[k]) == matchedYet[k] ) { + // the longer the better + if ( best == p || matchedYet[k] > matchedYet[best] ) + best = k; + } + } + if ( best != p ) { + attempt.truncate( attempt.length() - matchedYet[best] ); + attempt += newNumbers[best]; + met[best] = true; + for ( k = 0; k < p; k++ ) + matchedYet[k] = 0; + break; + } + } + } + + /* + We flag two kinds of suspicious cases. They are identified as + such with comments such as "{2000?}" at the end. + + Example of the first kind: old source text "TeX 3.0" translated + as "XeT 2.0" is flagged "TeX 2.0 {3.0?}", no matter what the + new text is. + */ + for ( k = 0; k < p; k++ ) { + if ( !met[k] ) + attempt += QString( " {" ) + newNumbers[k] + QString( "?}" ); + } + + /* + Example of the second kind: "1 of 1" translated as "1 af 1", + with new source text "1 of 2", generates "1 af 2 {1 or 2?}" + because it's not clear which of "1 af 2" and "2 af 1" is right. + */ + for ( k = 0; k < p; k++ ) { + for ( ell = 0; ell < p; ell++ ) { + if ( k != ell && oldNumbers[k] == oldNumbers[ell] && + newNumbers[k] < newNumbers[ell] ) + attempt += QString( " {" ) + newNumbers[k] + QString( " or " ) + + newNumbers[ell] + QString( "?}" ); + } + } + return attempt; +} + +/* + Augments a MetaTranslator with translations easily derived from + similar existing (probably obsolete) translations. + + For example, if "TeX 3.0" is translated as "XeT 3.0" and "TeX 3.1" + has no translation, "XeT 3.1" is added to the translator and is + marked Unfinished. + + Returns the number of additional messages that this heuristic translated. +*/ +int applyNumberHeuristic( MetaTranslator *tor ) +{ + TMM translated, untranslated; + TMM::Iterator t, u; + TML all = tor->messages(); + TML::Iterator it; + int inserted = 0; + + for ( it = all.begin(); it != all.end(); ++it ) { + bool hasTranslation = (*it).isTranslated(); + if ( (*it).type() == MetaTranslatorMessage::Unfinished ) { + if ( !hasTranslation ) + untranslated.insert(QByteArray((*it).context()) + "\n" + (*it).sourceText() + "\n" + + (*it).comment(), *it); + } else if ( hasTranslation && (*it).translations().count() == 1 ) { + translated.insert( zeroKey((*it).sourceText()), *it ); + } + } + + for ( u = untranslated.begin(); u != untranslated.end(); ++u ) { + t = translated.find( zeroKey((*u).sourceText()) ); + if ( t != translated.end() && !t.key().isEmpty() && + qstrcmp((*t).sourceText(), (*u).sourceText()) != 0 ) { + MetaTranslatorMessage m( *u ); + m.setTranslation(translationAttempt((*t).translation(), (*t).sourceText(), + (*u).sourceText())); + tor->insert( m ); + inserted++; + } + } + return inserted; +} diff --git a/sources/pyside2-tools/pylupdate/proparser.cpp b/sources/pyside2-tools/pylupdate/proparser.cpp new file mode 100644 index 0000000..54ee43b --- /dev/null +++ b/sources/pyside2-tools/pylupdate/proparser.cpp @@ -0,0 +1,209 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "proparser.h" + +#include +#include +#include +#include +#include +#include + +#ifdef Q_OS_UNIX +#include +#endif + +#ifdef Q_OS_WIN32 +#define QT_POPEN _popen +#else +#define QT_POPEN popen +#endif + +QString loadFile( const QString &fileName ) +{ + QFile file( fileName ); + if ( !file.open(QIODevice::ReadOnly) ) { + fprintf( stderr, "error: Cannot load '%s': %s\n", + file.fileName().toLatin1().constData(), + file.errorString().toLatin1().constData() ); + return QString(); + } + + QTextStream in( &file ); + return in.readAll(); +} + +QMap proFileTagMap( const QString& text ) +{ + QString t = text; + + QMap tagMap; + bool stillProcess = true; // If include() has a $$tag then we need to reprocess + + while (stillProcess) { + /* + Strip any commments before we try to include. We + still need to do it after we include to make sure the + included file does not have comments + */ + t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") ); + + /* + Process include() commands. + $$PWD is a special case so we have to change it while + we know where the included file is. + */ + QRegExp callToInclude("include\\s*\\(\\s*([^()\\s]+)\\s*\\)"); + int i = 0; + while ( (i = callToInclude.indexIn(t, i)) != -1 ) { + bool doneWithVar = false; + QString fileName = callToInclude.cap(1); + QString after = fileName.replace("$$PWD", QDir::currentPath()); + if (!tagMap.isEmpty() && after.contains("$$")) { + QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" ); + int ii = 0; + while ((ii = after.indexOf(var, ii)) != -1) { + if (tagMap.contains(var.cap(1))) { + after.replace(ii, var.cap(0).length(), tagMap[var.cap(1)]); + } else { // Couldn't find it + doneWithVar = true; + break; + } + } + + } + if (doneWithVar || !after.contains("$$")) { + after = loadFile(after); + QFileInfo fi(callToInclude.cap(1)); + after.replace("$$PWD", fi.path()); + t.replace( i, callToInclude.matchedLength(), after ); + } + i += after.length(); + } + + /* + Strip comments, merge lines ending with backslash, add + spaces around '=' and '+=', replace '\n' with ';', and + simplify white spaces. + */ + t.replace( QRegExp(QString("#[^\n]*\n")), QString(" ") ); + t.replace( QRegExp(QString("\\\\[^\n\\S]*\n")), QString(" ") ); + t.replace( "=", QString(" = ") ); + t.replace( "+ =", QString(" += ") ); + t.replace( "\n", QString(";") ); + t.replace( "\r", QString("") ); // remove carriage return + t = t.simplified(); + + /* + Populate tagMap with 'key = value' entries. + */ + QStringList lines = t.split(';', QString::SkipEmptyParts); + QStringList::Iterator line; + for ( line = lines.begin(); line != lines.end(); ++line ) { + QStringList toks = (*line).split(' ', QString::SkipEmptyParts); + + if ( toks.count() >= 3 && + (toks[1] == QString("=") || toks[1] == QString("+=") || + toks[1] == QString("*=")) ) { + QString tag = toks.first(); + int k = tag.lastIndexOf( QChar(':') ); // as in 'unix:' + if ( k != -1 ) + tag = tag.mid( k + 1 ); + toks.erase( toks.begin() ); + + QString action = toks.first(); + toks.erase( toks.begin() ); + + if ( tagMap.contains(tag) ) { + if ( action == QString("=") ) + tagMap.insert( tag, toks.join(" ") ); + else + tagMap[tag] += QChar( ' ' ) + toks.join( " " ); + } else { + tagMap[tag] = toks.join( " " ); + } + } + } + /* + Expand $$variables within the 'value' part of a 'key = value' + pair. + */ + QRegExp var( "\\$\\$[({]?([a-zA-Z0-9_]+)[)}]?" ); + QMap::Iterator it; + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + int i = 0; + while ( (i = var.indexIn((*it), i)) != -1 ) { + int len = var.matchedLength(); + QString invocation = var.cap(1); + QString after; + + if ( invocation == "system" ) { + // skip system(); it will be handled in the next pass + ++i; + } else { + if ( tagMap.contains(invocation) ) + after = tagMap[invocation]; + else if (invocation.toLower() == "pwd") + after = QDir::currentPath(); + (*it).replace( i, len, after ); + i += after.length(); + } + } + } + + /* + Execute system() calls. + */ + QRegExp callToSystem( "\\$\\$system\\s*\\(([^()]*)\\)" ); + for ( it = tagMap.begin(); it != tagMap.end(); ++it ) { + int i = 0; + while ( (i = callToSystem.indexIn((*it), i)) != -1 ) { + /* + This code is stolen from qmake's project.cpp file. + Ideally we would use the same parser, so we wouldn't + have this code duplication. + */ + QString after; + char buff[256]; + FILE *proc = QT_POPEN( callToSystem.cap(1).toLatin1().constData(), "r" ); + while ( proc && !feof(proc) ) { + int read_in = int(fread( buff, 1, 255, proc )); + if ( !read_in ) + break; + for ( int i = 0; i < read_in; i++ ) { + if ( buff[i] == '\n' || buff[i] == '\t' ) + buff[i] = ' '; + } + buff[read_in] = '\0'; + after += buff; + } + (*it).replace( i, callToSystem.matchedLength(), after ); + i += after.length(); + } + } + stillProcess = callToInclude.indexIn(t) != -1; + } + return tagMap; +} diff --git a/sources/pyside2-tools/pylupdate/proparser.h b/sources/pyside2-tools/pylupdate/proparser.h new file mode 100644 index 0000000..742080d --- /dev/null +++ b/sources/pyside2-tools/pylupdate/proparser.h @@ -0,0 +1,34 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef PROPARSER_H +#define PROPARSER_H + +#include +#include + +QMap proFileTagMap( const QString& text ); + +#endif diff --git a/sources/pyside2-tools/pylupdate/pyside2-lupdate.1 b/sources/pyside2-tools/pylupdate/pyside2-lupdate.1 new file mode 100644 index 0000000..d5e95e0 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/pyside2-lupdate.1 @@ -0,0 +1,27 @@ +.TH PYSIDE-LUPDATE "1" "December 2010" "pyside2-lupdate" "User Commands" +.SH NAME +pyside2\-lupdate \- extracts translatable messages from Qt UI files and Python source code. +.SH DESCRIPTION +.SS "Usage:" +.IP +pyside2\-lupdate [options] project\-file +.IP +pyside2\-lupdate [options] source\-files \-ts ts\-files +.SS "Options:" +.TP +\fB\-noobsolete +Drop all obsolete strings +.TP +\fB\-verbose +Explain what is being done +.TP +\fB\-version +Display the version of pyside2-lupdate and exit +.TP +\fB\-help +Display this information and exit +.SH COPYRIGHT +Copyright \(co 2010 Nokia Corporation and/or its subsidiary(\fB\-ies\fR) +.SH AUTHOR +.PP +This manpage was written by Marcelo Lira , on the 29. December 2010. diff --git a/sources/pyside2-tools/pylupdate/sametexth.cpp b/sources/pyside2-tools/pylupdate/sametexth.cpp new file mode 100644 index 0000000..fa5cc5a --- /dev/null +++ b/sources/pyside2-tools/pylupdate/sametexth.cpp @@ -0,0 +1,87 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2006 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "metatranslator.h" + +#include +#include + +typedef QMap TMM; +typedef QList TML; + +/* + Augments a MetaTranslator with trivially derived translations. + + For example, if "Enabled:" is consistendly translated as "Eingeschaltet:" no + matter the context or the comment, "Eingeschaltet:" is added as the + translation of any untranslated "Enabled:" text and is marked Unfinished. + + Returns the number of additional messages that this heuristic translated. +*/ + +int applySameTextHeuristic( MetaTranslator *tor ) +{ + TMM translated; + TMM avoid; + TMM::Iterator t; + TML untranslated; + TML::Iterator u; + TML all = tor->messages(); + TML::Iterator it; + int inserted = 0; + + for ( it = all.begin(); it != all.end(); ++it ) { + if ( (*it).type() == MetaTranslatorMessage::Unfinished ) { + if ( !(*it).isTranslated() ) + untranslated.append( *it ); + } else { + QByteArray key = (*it).sourceText(); + t = translated.find( key ); + if ( t != translated.end() ) { + /* + The same source text is translated at least two + different ways. Do nothing then. + */ + if ( (*t).translations() != (*it).translations() ) { + translated.remove( key ); + avoid.insert( key, *it ); + } + } else if ( !avoid.contains(key) && (*it).isTranslated() ) { + translated.insert( key, *it ); + } + } + } + + for ( u = untranslated.begin(); u != untranslated.end(); ++u ) { + QByteArray key = (*u).sourceText(); + t = translated.find( key ); + if ( t != translated.end() ) { + MetaTranslatorMessage m( *u ); + m.setTranslations( (*t).translations() ); + tor->insert( m ); + inserted++; + } + } + return inserted; +} diff --git a/sources/pyside2-tools/pylupdate/simtexth.cpp b/sources/pyside2-tools/pylupdate/simtexth.cpp new file mode 100644 index 0000000..b8d8d44 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/simtexth.cpp @@ -0,0 +1,256 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2006 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "simtexth.h" +#include "metatranslator.h" + +#include +#include + +#include + +typedef QList TML; + +/* + How similar are two texts? The approach used here relies on co-occurrence + matrices and is very efficient. + + Let's see with an example: how similar are "here" and "hither"? The + co-occurrence matrix M for "here" is M[h,e] = 1, M[e,r] = 1, M[r,e] = 1, and 0 + elsewhere; the matrix N for "hither" is N[h,i] = 1, N[i,t] = 1, ..., + N[h,e] = 1, N[e,r] = 1, and 0 elsewhere. The union U of both matrices is the + matrix U[i,j] = max { M[i,j], N[i,j] }, and the intersection V is + V[i,j] = min { M[i,j], N[i,j] }. The score for a pair of texts is + + score = (sum of V[i,j] over all i, j) / (sum of U[i,j] over all i, j), + + a formula suggested by Arnt Gulbrandsen. Here we have + + score = 2 / 6, + + or one third. + + The implementation differs from this in a few details. Most importantly, + repetitions are ignored; for input "xxx", M[x,x] equals 1, not 2. +*/ + +/* + Every character is assigned to one of 20 buckets so that the co-occurrence + matrix requires only 20 * 20 = 400 bits, not 256 * 256 = 65536 bits or even + more if we want the whole Unicode. Which character falls in which bucket is + arbitrary. + + The second half of the table is a replica of the first half, because of + laziness. +*/ +static const int indexOf[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// ! " # $ % & ' ( ) * + , - . / + 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0, +// 0 1 2 3 4 5 6 7 8 9 : ; < = > ? + 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15, +// @ A B C D E F G H I J K L M N O + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, +// P Q R S T U V W X Y Z [ \ ] ^ _ + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, +// ` a b c d e f g h i j k l m n o + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, +// p q r s t u v w x y z { | } ~ + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 6, 7, 10, 12, 15, 19, 2, 6, 7, 10, 12, 15, 19, 0, + 1, 3, 4, 5, 8, 9, 11, 13, 14, 16, 2, 6, 7, 10, 12, 15, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 6, 10, 11, 12, 13, 14, + 15, 12, 16, 17, 18, 19, 2, 10, 15, 7, 19, 2, 6, 7, 10, 0 +}; + +/* + The entry bitCount[i] (for i between 0 and 255) is the number of bits used to + represent i in binary. +*/ +static const int bitCount[256] = { + 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, + 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8 +}; + +struct CoMatrix +{ + /* + The matrix has 20 * 20 = 400 entries. This requires 50 bytes, or 13 + words. Some operations are performed on words for more efficiency. + */ + union { + quint8 b[52]; + quint32 w[13]; + }; + + CoMatrix() { memset( b, 0, 52 ); } + CoMatrix( const char *text ) { + char c = '\0', d; + memset( b, 0, 52 ); + /* + The Knuth books are not in the office only for show; they help make + loops 30% faster and 20% as readable. + */ + while ( (d = *text) != '\0' ) { + setCoocc( c, d ); + if ( (c = *++text) != '\0' ) { + setCoocc( d, c ); + text++; + } + } + } + + void setCoocc( char c, char d ) { + int k = indexOf[(uchar) c] + 20 * indexOf[(uchar) d]; + b[k >> 3] |= k & 0x7; + } + + int worth() const { + int w = 0; + for ( int i = 0; i < 50; i++ ) + w += bitCount[b[i]]; + return w; + } +}; + +static inline CoMatrix reunion( const CoMatrix& m, const CoMatrix& n ) +{ + CoMatrix p; + for ( int i = 0; i < 13; i++ ) + p.w[i] = m.w[i] | n.w[i]; + return p; +} + +static inline CoMatrix intersection( const CoMatrix& m, const CoMatrix& n ) +{ + CoMatrix p; + for ( int i = 0; i < 13; i++ ) + p.w[i] = m.w[i] & n.w[i]; + return p; +} + +StringSimilarityMatcher::StringSimilarityMatcher(const QString &stringToMatch) +{ + m_cm = new CoMatrix( stringToMatch.toLatin1().constData() ); + m_length = stringToMatch.length(); +} + +int StringSimilarityMatcher::getSimilarityScore(const QString &strCandidate) +{ + CoMatrix cmTarget( strCandidate.toLatin1().constData() ); + int targetLen = strCandidate.length(); + int delta = qAbs( m_length - targetLen ); + + int score = ( (intersection(*m_cm, cmTarget).worth() + 1) << 10 ) / + ( reunion(*m_cm, cmTarget).worth() + (delta << 1) + 1 ); + + return score; +} + +StringSimilarityMatcher::~StringSimilarityMatcher() +{ + delete m_cm; +} + +/** + * Checks how similar two strings are. + * The return value is the score, and a higher score is more similar than one with a low score. + * Linguist considers a score over 190 to be a good match. + * \sa StringSimilarityMatcher + */ +int getSimilarityScore(const QString &str1, const char* str2) +{ + CoMatrix cmTarget( str2 ); + int targetLen = qstrlen( str2 ); + CoMatrix cm( str1.toLatin1().constData() ); + int delta = qAbs( (int) str1.length() - targetLen ); + + int score = ( (intersection(cm, cmTarget).worth() + 1) << 10 ) / + ( reunion(cm, cmTarget).worth() + (delta << 1) + 1 ); + + return score; +} + +CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor, + const char *text, + int maxCandidates ) +{ + QList scores; + CandidateList candidates; + + TML all = tor->translatedMessages(); + + foreach ( MetaTranslatorMessage mtm, all ) { + if ( mtm.type() == MetaTranslatorMessage::Unfinished || + mtm.translation().isEmpty() ) + continue; + + QString s = tor->toUnicode( mtm.sourceText(), mtm.utf8() ); + int score = getSimilarityScore(s, text); + + if ( (int) candidates.count() == maxCandidates && + score > scores[maxCandidates - 1] ) + candidates.removeAt( candidates.size()-1 ); + if ( (int) candidates.count() < maxCandidates && score >= textSimilarityThreshold ) { + Candidate cand( s, mtm.translation() ); + + int i; + for ( i = 0; i < (int) candidates.size(); i++ ) { + if ( score >= scores.at(i) ) { + if ( score == scores.at(i) ) { + if ( candidates.at(i) == cand ) + goto continue_outer_loop; + } else { + break; + } + } + } + scores.insert( i, score ); + candidates.insert( i, cand ); + } + continue_outer_loop: + ; + } + return candidates; +} diff --git a/sources/pyside2-tools/pylupdate/simtexth.h b/sources/pyside2-tools/pylupdate/simtexth.h new file mode 100644 index 0000000..5cdd12c --- /dev/null +++ b/sources/pyside2-tools/pylupdate/simtexth.h @@ -0,0 +1,77 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2006 Trolltech AS. All rights reserved. + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef SIMTEXTH_H +#define SIMTEXTH_H + +const int textSimilarityThreshold = 190; + +#include +#include + +class MetaTranslator; + +struct Candidate { + QString source; + QString target; + + Candidate() { } + Candidate( const QString& source0, const QString& target0 ) + : source( source0 ), target( target0 ) { } +}; + +inline bool operator==( const Candidate& c, const Candidate& d ) { + return c.target == d.target && c.source == d.source; +} +inline bool operator!=( const Candidate& c, const Candidate& d ) { + return !operator==( c, d ); +} + +typedef QList CandidateList; + +struct CoMatrix; +/** + * This class is more efficient for searching through a large array of candidate strings, since we only + * have to construct the CoMatrix for the \a stringToMatch once, + * after that we just call getSimilarityScore(strCandidate). + * \sa getSimilarityScore + */ +class StringSimilarityMatcher { +public: + StringSimilarityMatcher(const QString &stringToMatch); + ~StringSimilarityMatcher(); + int getSimilarityScore(const QString &strCandidate); + +private: + CoMatrix *m_cm; + int m_length; +}; + +int getSimilarityScore(const QString &str1, const char* str2); + +CandidateList similarTextHeuristicCandidates( const MetaTranslator *tor, + const char *text, + int maxCandidates ); + +#endif diff --git a/sources/pyside2-tools/pylupdate/translator.cpp b/sources/pyside2-tools/pylupdate/translator.cpp new file mode 100644 index 0000000..7a90770 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/translator.cpp @@ -0,0 +1,1184 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#include "translator.h" + +#ifndef QT_NO_TRANSLATION + +#include "qfileinfo.h" +#include "qstring.h" +#include "qcoreapplication.h" +#include "qdatastream.h" +#include "qfile.h" +#include "qmap.h" +#include "qalgorithms.h" +#include "qhash.h" +#include "qglobal.h" + +// most of the headers below are already included in qplatformdefs.h +// also this lacks Large File support but that's probably irrelevant +#if defined(QT_USE_MMAP) +// for mmap +#include +#include +#endif + +#include + +/* +$ mcookie +3cb86418caef9c95cd211cbf60a1bddd +$ +*/ + +// magic number for the file +static const int MagicLength = 16; +static const uchar magic[MagicLength] = { + 0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95, + 0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd +}; + +static uint elfHash(const char * name) +{ + const uchar *k; + uint h = 0; + uint g; + + if (name) { + k = (const uchar *) name; + while (*k) { + h = (h << 4) + *k++; + if ((g = (h & 0xf0000000)) != 0) + h ^= g >> 24; + h &= ~g; + } + } + if (!h) + h = 1; + return h; +} + +extern bool qt_detectRTLLanguage(); + +class TranslatorPrivate +{ +public: + struct Offset { + Offset() + : h(0), o(0) { } + Offset(const TranslatorMessage& m, int offset) + : h(m.hash()), o(offset) { } + + bool operator<(const Offset &other) const { + return (h != other.h) ? h < other.h : o < other.o; + } + bool operator==(const Offset &other) const { + return h == other.h && o == other.o; + } + uint h; + uint o; + }; + + enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69 }; + + TranslatorPrivate(Translator *qq) : q(qq), unmapPointer(0), unmapLength(0) {} + // Translator must finalize this before deallocating it + + Translator *q; + // for mmap'ed files, this is what needs to be unmapped. + char *unmapPointer; + unsigned int unmapLength; + + // for squeezed but non-file data, this is what needs to be deleted + QByteArray messageArray; + QByteArray offsetArray; + QByteArray contextArray; + +#ifndef QT_NO_TRANSLATION_BUILDER + QMap messages; +#endif + + bool do_load(const uchar *data, int len); + +}; + + +/*! + \class Translator + + \brief The Translator class provides internationalization support for text + output. + + \ingroup i18n + \ingroup environment + \mainclass + + An object of this class contains a set of TranslatorMessage + objects, each of which specifies a translation from a source + language to a target language. Translator provides functions to + look up translations, add new ones, remove them, load and save + them, etc. + + The most common use of Translator is to: load a translator file + created with \l{Qt Linguist Manual}, install it using + QApplication::installTranslator(), and use it via QObject::tr(). + For example: + + \code + int main(int argc, char ** argv) + { + QApplication app(argc, argv); + + Translator translator(0); + translator.load("french.qm", "."); + app.installTranslator(&translator); + + MyWidget m; + app.setMainWidget(&m); + m.show(); + + return app.exec(); + } + \endcode + Note that the translator must be created \e before the + application's main window. + + Most applications will never need to do anything else with this + class. The other functions provided by this class are useful for + applications that work on translator files. + + We call a translation a "messsage". For this reason, translation + files are sometimes referred to as "message files". + + It is possible to lookup a translation using findMessage() (as + tr() and QApplication::translate() do) and contains(), to insert a + new translation messsage using insert(), and to remove one using + remove(). + + Translation tools often need more information than the bare source + text and translation, for example, context information to help + the translator. But end-user programs that are using translations + usually only need lookup. To cater for these different needs, + Translator can use stripped translator files that use the minimum + of memory and which support little more functionality than + findMessage(). + + Thus, load() may not load enough information to make anything more + than findMessage() work. save() has an argument indicating + whether to save just this minimum of information or to save + everything. + + "Everything" means that for each translation item the following + information is kept: + + \list + \i The \e {translated text} - the return value from tr(). + \i The input key: + \list + \i The \e {source text} - usually the argument to tr(). + \i The \e context - usually the class name for the tr() caller. + \i The \e comment - a comment that helps disambiguate different uses + of the same text in the same context. + \endlist + \endlist + + The minimum for each item is just the information necessary for + findMessage() to return the right text. This may include the + source, context and comment, but usually it is just a hash value + and the translated text. + + For example, the "Cancel" in a dialog might have "Anuluj" when the + program runs in Polish (in this case the source text would be + "Cancel"). The context would (normally) be the dialog's class + name; there would normally be no comment, and the translated text + would be "Anuluj". + + But it's not always so simple. The Spanish version of a printer + dialog with settings for two-sided printing and binding would + probably require both "Activado" and "Activada" as translations + for "Enabled". In this case the source text would be "Enabled" in + both cases, and the context would be the dialog's class name, but + the two items would have disambiguating comments such as + "two-sided printing" for one and "binding" for the other. The + comment enables the translator to choose the appropriate gender + for the Spanish version, and enables Qt to distinguish between + translations. + + Note that when Translator loads a stripped file, most functions + do not work. The functions that do work with stripped files are + explicitly documented as such. + + \sa TranslatorMessage QApplication::installTranslator() + QApplication::removeTranslator() QObject::tr() QApplication::translate() +*/ + +/*! + \enum Translator::SaveMode + + This enum type defines how Translator writes translation + files. There are two modes: + + \value Everything files are saved with all available information + \value Stripped files are saved with just enough information for + end-user applications + + Note that when Translator loads a stripped file, most functions do + not work. The functions that do work with stripped files are + explicitly documented as such. +*/ + +/*! + Constructs an empty message file object with parent \a parent that + is not connected to any file. +*/ + +Translator::Translator(QObject * parent) + : QTranslator(parent) +{ + d = new TranslatorPrivate(this); +} + +/*! + Destroys the object and frees any allocated resources. +*/ + +Translator::~Translator() +{ + if (QCoreApplication::instance()) + QCoreApplication::instance()->removeTranslator(this); + clear(); + delete d; +} + +/*! + Loads \a filename + \a suffix (".qm" if the \a suffix is + not specified), which may be an absolute file name or relative + to \a directory. The previous contents of this translator object + is discarded. + + If the file name does not exist, other file names are tried + in the following order: + + \list 1 + \i File name without \a suffix appended. + \i File name with text after a character in \a search_delimiters + stripped ("_." is the default for \a search_delimiters if it is + an empty string) and \a suffix. + \i File name stripped without \a suffix appended. + \i File name stripped further, etc. + \endlist + + For example, an application running in the fr_CA locale + (French-speaking Canada) might call load("foo.fr_ca", + "/opt/foolib"). load() would then try to open the first existing + readable file from this list: + + \list 1 + \i /opt/foolib/foo.fr_ca.qm + \i /opt/foolib/foo.fr_ca + \i /opt/foolib/foo.fr.qm + \i /opt/foolib/foo.fr + \i /opt/foolib/foo.qm + \i /opt/foolib/foo + \endlist + + \sa save() +*/ + +bool Translator::load(const QString & filename, const QString & directory, + const QString & search_delimiters, + const QString & suffix) +{ + clear(); + + QString prefix; + + if (filename[0] == QLatin1Char('/') +#ifdef Q_WS_WIN + || (filename[0].isLetter() && filename[1] == QLatin1Char(':')) || filename[0] == QLatin1Char('\\') +#endif + ) + prefix = QLatin1String(""); + else + prefix = directory; + + if (prefix.length()) { + if (prefix[int(prefix.length()-1)] != QLatin1Char('/')) + prefix += QLatin1Char('/'); + } + + QString fname = filename; + QString realname; + QString delims; + delims = search_delimiters.isNull() ? QString::fromLatin1("_.") : search_delimiters; + + for (;;) { + QFileInfo fi; + + realname = prefix + fname + (suffix.isNull() ? QString::fromLatin1(".qm") : suffix); + fi.setFile(realname); + if (fi.isReadable()) + break; + + realname = prefix + fname; + fi.setFile(realname); + if (fi.isReadable()) + break; + + int rightmost = 0; + for (int i = 0; i < (int)delims.length(); i++) { + int k = fname.lastIndexOf(delims[i]); + if (k > rightmost) + rightmost = k; + } + + // no truncations? fail + if (rightmost == 0) + return false; + + fname.truncate(rightmost); + } + + // realname is now the fully qualified name of a readable file. + + bool ok = false; + +#ifdef QT_USE_MMAP + +#ifndef MAP_FILE +#define MAP_FILE 0 +#endif +#ifndef MAP_FAILED +#define MAP_FAILED -1 +#endif + + int fd = -1; + if (!realname.startsWith(QLatin1String(":"))) + fd = QT_OPEN(QFile::encodeName(realname), O_RDONLY, +#if defined(Q_OS_WIN) + _S_IREAD | _S_IWRITE +#else + 0666 +#endif + ); + if (fd >= 0) { + struct stat st; + if (!fstat(fd, &st)) { + char *ptr; + ptr = reinterpret_cast( + mmap(0, st.st_size, // any address, whole file + PROT_READ, // read-only memory + MAP_FILE | MAP_PRIVATE, // swap-backed map from file + fd, 0)); // from offset 0 of fd + if (ptr && ptr != reinterpret_cast(MAP_FAILED)) { + d->unmapPointer = ptr; + d->unmapLength = st.st_size; + ok = true; + } + } + ::close(fd); + } +#endif // QT_USE_MMAP + + if (!ok) { + QFile file(realname); + if (!file.exists()) + return false; + d->unmapLength = file.size(); + d->unmapPointer = new char[d->unmapLength]; + + if (file.open(QIODevice::ReadOnly)) + ok = (d->unmapLength == (uint)file.read(d->unmapPointer, d->unmapLength)); + + if (!ok) { + delete [] d->unmapPointer; + d->unmapPointer = 0; + d->unmapLength = 0; + return false; + } + } + + return d->do_load(reinterpret_cast(d->unmapPointer), d->unmapLength); +} + +/*! + \overload + \fn bool Translator::load(const uchar *data, int len) + + Loads the .qm file data \a data of length \a len into the + translator. + + The data is not copied. The caller must be able to guarantee that \a data + will not be deleted or modified. +*/ +bool Translator::load(const uchar *data, int len) +{ + clear(); + return d->do_load(data, len); +} + +bool TranslatorPrivate::do_load(const uchar *data, int len) +{ + if (len < MagicLength || memcmp(data, magic, MagicLength) != 0) { + q->clear(); + return false; + } + + QByteArray array = QByteArray::fromRawData((const char *) data, len); + QDataStream s(&array, QIODevice::ReadOnly); + bool ok = true; + + s.device()->seek(MagicLength); + + quint8 tag = 0; + quint32 blockLen = 0; + s >> tag >> blockLen; + while (tag && blockLen) { + if ((quint32) s.device()->pos() + blockLen > (quint32) len) { + ok = false; + break; + } + + if (tag == TranslatorPrivate::Contexts) { + contextArray = QByteArray(array.constData() + s.device()->pos(), blockLen); + } else if (tag == TranslatorPrivate::Hashes) { + offsetArray = QByteArray(array.constData() + s.device()->pos(), blockLen); + } else if (tag == TranslatorPrivate::Messages) { + messageArray = QByteArray(array.constData() + s.device()->pos(), blockLen); + } + + if (!s.device()->seek(s.device()->pos() + blockLen)) { + ok = false; + break; + } + tag = 0; + blockLen = 0; + if (!s.atEnd()) + s >> tag >> blockLen; + } + + return ok; +} + +#ifndef QT_NO_TRANSLATION_BUILDER + +/*! + Saves this message file to \a filename, overwriting the previous + contents of \a filename. If \a mode is \c Everything (the + default), all the information is preserved. If \a mode is \c + Stripped, any information that is not necessary for findMessage() + is stripped away. + + \sa load() +*/ + +bool Translator::save(const QString & filename, SaveMode mode) +{ + QFile file(filename); + if (file.open(QIODevice::WriteOnly)) { + squeeze(mode); + + QDataStream s(&file); + s.writeRawData((const char *)magic, MagicLength); + quint8 tag; + + if (!d->offsetArray.isEmpty()) { + tag = (quint8)TranslatorPrivate::Hashes; + quint32 oas = (quint32)d->offsetArray.size(); + s << tag << oas; + s.writeRawData(d->offsetArray, oas); + } + if (!d->messageArray.isEmpty()) { + tag = (quint8)TranslatorPrivate::Messages; + quint32 mas = (quint32)d->messageArray.size(); + s << tag << mas; + s.writeRawData(d->messageArray, mas); + } + if (!d->contextArray.isEmpty()) { + tag = (quint8)TranslatorPrivate::Contexts; + quint32 cas = (quint32)d->contextArray.size(); + s << tag << cas; + s.writeRawData(d->contextArray, cas); + } + return true; + } + return false; +} + +#endif + +/*! + Empties this translator of all contents. + + This function works with stripped translator files. +*/ + +void Translator::clear() +{ + if (d->unmapPointer && d->unmapLength) { +#if defined(QT_USE_MMAP) + munmap(d->unmapPointer, d->unmapLength); +#else + delete [] d->unmapPointer; +#endif + d->unmapPointer = 0; + d->unmapLength = 0; + } + + d->messageArray.clear(); + d->offsetArray.clear(); + d->contextArray.clear(); +#ifndef QT_NO_TRANSLATION_BUILDER + d->messages.clear(); +#endif + + QEvent ev(QEvent::LanguageChange); + QCoreApplication::sendEvent(QCoreApplication::instance(), &ev); +} + +#ifndef QT_NO_TRANSLATION_BUILDER + +/*! + Converts this message file to the compact format used to store + message files on disk. + + You should never need to call this directly; save() and other + functions call it as necessary. \a mode is for internal use. + + \sa save() unsqueeze() +*/ + +void Translator::squeeze(SaveMode mode) +{ + if (d->messages.isEmpty()) { + if (mode == Stripped) + unsqueeze(); + else + return; + } + + QMap messages = d->messages; + clear(); + + QMap offsets; + + QDataStream ms(&d->messageArray, QIODevice::WriteOnly); + QMap::const_iterator it, next; + int cpPrev = 0, cpNext = 0; + for (it = messages.constBegin(); it != messages.constEnd(); ++it) { + cpPrev = cpNext; + next = it; + ++next; + if (next == messages.constEnd()) + cpNext = 0; + else + cpNext = (int) it.key().commonPrefix(next.key()); + offsets.insert(TranslatorPrivate::Offset(it.key(), ms.device()->pos()), (void *)0); + it.key().write(ms, mode == Stripped, (TranslatorMessage::Prefix)qMax(cpPrev, cpNext + 1)); + } + + QMap::Iterator offset; + offset = offsets.begin(); + QDataStream ds(&d->offsetArray, QIODevice::WriteOnly); + while (offset != offsets.end()) { + TranslatorPrivate::Offset k = offset.key(); + ++offset; + ds << (quint32)k.h << (quint32)k.o; + } + + if (mode == Stripped) { + QMap contextSet; + for (it = messages.constBegin(); it != messages.constEnd(); ++it) + ++contextSet[it.key().context()]; + + quint16 hTableSize; + if (contextSet.size() < 200) + hTableSize = (contextSet.size() < 60) ? 151 : 503; + else if (contextSet.size() < 2500) + hTableSize = (contextSet.size() < 750) ? 1511 : 5003; + else + hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2; + + QMultiMap hashMap; + QMap::const_iterator c; + for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c) + hashMap.insert(elfHash(c.key()) % hTableSize, c.key()); + + /* + The contexts found in this translator are stored in a hash + table to provide fast lookup. The context array has the + following format: + + quint16 hTableSize; + quint16 hTable[hTableSize]; + quint8 contextPool[...]; + + The context pool stores the contexts as Pascal strings: + + quint8 len; + quint8 data[len]; + + Let's consider the look-up of context "FunnyDialog". A + hash value between 0 and hTableSize - 1 is computed, say h. + If hTable[h] is 0, "FunnyDialog" is not covered by this + translator. Else, we check in the contextPool at offset + 2 * hTable[h] to see if "FunnyDialog" is one of the + contexts stored there, until we find it or we meet the + empty string. + */ + d->contextArray.resize(2 + (hTableSize << 1)); + QDataStream t(&d->contextArray, QIODevice::WriteOnly); + + quint16 *hTable = new quint16[hTableSize]; + memset(hTable, 0, hTableSize * sizeof(quint16)); + + t << hTableSize; + t.device()->seek(2 + (hTableSize << 1)); + t << (quint16)0; // the entry at offset 0 cannot be used + uint upto = 2; + + QMap::const_iterator entry = hashMap.constBegin(); + while (entry != hashMap.constEnd()) { + int i = entry.key(); + hTable[i] = (quint16)(upto >> 1); + + do { + const char *con = entry.value(); + uint len = (uint)qstrlen(con); + len = qMin(len, 255u); + t << (quint8)len; + t.writeRawData(con, len); + upto += 1 + len; + ++entry; + } while (entry != hashMap.constEnd() && entry.key() == i); + do { + t << (quint8) 0; // empty string + ++upto; + } while ((upto & 0x1) != 0); // offsets have to be even + } + t.device()->seek(2); + for (int j = 0; j < hTableSize; j++) + t << hTable[j]; + delete [] hTable; + + if (upto > 131072) { + qWarning("Translator::squeeze: Too many contexts"); + d->contextArray.clear(); + } + } +} + + +/*! + Converts this message file into an easily modifiable data + structure, less compact than the format used in the files. + + You should never need to call this function; it is called by + insert() and friends as necessary. + + \sa squeeze() +*/ + +void Translator::unsqueeze() +{ + if (!d->messages.isEmpty() || d->messageArray.isEmpty()) + return; + + qFatal("Cannot unsqueeze (bug in Linguist?)"); +} + + +/*! + Returns true if this message file contains a message with the key + (\a context, \a sourceText, \a comment); otherwise returns false. + + This function works with stripped translator files. + + (This is is a one-liner that calls findMessage().) +*/ + +bool Translator::contains(const char* context, const char* sourceText, + const char* comment) const +{ + return !findMessage(context, sourceText, comment).translation().isNull(); +} + + +bool Translator::contains(const char *context, + const char *comment, const QString &fileName, int lineNumber) const +{ + return !findMessage(context, 0, comment, fileName, lineNumber).isNull(); +} + +/*! + Inserts \a message into this message file. + + This function does \e not work with stripped translator files. It + may appear to, but that is not dependable. + + \sa remove() +*/ + +void Translator::insert(const TranslatorMessage& message) +{ + unsqueeze(); + d->messages.remove(message); // safer + d->messages.insert(message, (void *) 0); +} + +/*! + \fn void Translator::insert(const char *context, const char + *sourceText, const QString &translation) + \overload + \obsolete + + Inserts the \a sourceText and \a translation into the translator + with the given \a context. +*/ + +/*! + Removes \a message from this translator. + + This function works with stripped translator files. + + \sa insert() +*/ + +void Translator::remove(const TranslatorMessage& message) +{ + unsqueeze(); + d->messages.remove(message); +} + + +/*! + \fn void Translator::remove(const char *, const char *) + \overload + \obsolete + + Removes the translation associated to the key (\a context, \a sourceText, + "") from this translator. +*/ +#endif + +/*! Returns the TranslatorMessage for the key + (\a context, \a sourceText, \a comment). If none is found, + also tries (\a context, \a sourceText, ""). +*/ + +TranslatorMessage Translator::findMessage(const char *context, const char *sourceText, + const char *comment, + const QString &fileName, int lineNumber) const +{ + if (context == 0) + context = ""; + if (sourceText == 0) + sourceText = ""; + if (comment == 0) + comment = ""; + + QString myFilename = fileName; + int myLineNumber = lineNumber; + + if (!d->messages.isEmpty()) { + QMap::const_iterator it; + + // Either we want to find an item that matches context, sourcetext (and optionally comment) + // Or we want to find an item that matches context, filename, linenumber (and optionally comment) + it = d->messages.find(TranslatorMessage(context, sourceText, comment, myFilename, myLineNumber)); + if (it != d->messages.constEnd()) + return it.key(); + + if (comment[0]) { + it = d->messages.find(TranslatorMessage(context, sourceText, "", myFilename, myLineNumber)); + if (it != d->messages.constEnd()) + return it.key(); + } + it = d->messages.find(TranslatorMessage(context, "", comment, myFilename, myLineNumber)); + if (it != d->messages.constEnd()) + return it.key(); + if (comment[0]) { + it = d->messages.find(TranslatorMessage(context, "", "", myFilename, myLineNumber)); + if (it != d->messages.constEnd()) + return it.key(); + } + return TranslatorMessage(); + } + + return TranslatorMessage(); +} + +/*! + Returns true if this translator is empty, otherwise returns false. + This function works with stripped and unstripped translation files. +*/ +bool Translator::isEmpty() const +{ + return !d->unmapPointer && !d->unmapLength && d->messageArray.isEmpty() && + d->offsetArray.isEmpty() && d->contextArray.isEmpty() && d->messages.isEmpty(); +} + + +#ifndef QT_NO_TRANSLATION_BUILDER + +/*! + Returns a list of the messages in the translator. This function is + rather slow. Because it is seldom called, it's optimized for + simplicity and small size, rather than speed. + + If you want to iterate over the list, you should iterate over a + copy, e.g. + \code + QList list = myTranslator.messages(); + QList::Iterator it = list.begin(); + while (it != list.end()) { + process_message(*it); + ++it; + } + \endcode +*/ + +QList Translator::messages() const +{ + ((Translator *) this)->unsqueeze(); + return d->messages.keys(); +} + +#endif + +/*! + \class TranslatorMessage + + \brief The TranslatorMessage class contains a translator message and its + properties. + + \ingroup i18n + \ingroup environment + + This class is of no interest to most applications. It is useful + for translation tools such as \l{Qt Linguist Manual}{Qt Linguist}. + It is provided simply to make the API complete and regular. + + For a Translator object, a lookup key is a triple (\e context, \e + {source text}, \e comment) that uniquely identifies a message. An + extended key is a quadruple (\e hash, \e context, \e {source + text}, \e comment), where \e hash is computed from the source text + and the comment. Unless you plan to read and write messages + yourself, you need not worry about the hash value. + + TranslatorMessage stores this triple or quadruple and the relevant + translation if there is any. + + \sa Translator +*/ + +/*! + Constructs a translator message with the extended key (0, 0, 0, 0) + and an empty string as translation. +*/ + +TranslatorMessage::TranslatorMessage() + : h(0), m_fileName(), m_lineNumber(-1) +{ +} + + +/*! + Constructs an translator message with the extended key (\e h, \a + context, \a sourceText, \a comment), where \e h is computed from + \a sourceText and \a comment, and possibly with a \a translation. +*/ + +TranslatorMessage::TranslatorMessage(const char * context, + const char * sourceText, + const char * comment, + const QString &fileName, + int lineNumber, + const QStringList& translations) + : cx(context), st(sourceText), cm(comment), m_translations(translations), + m_fileName(fileName), m_lineNumber(lineNumber) +{ + // 0 means we don't know, "" means empty + if (cx == (const char*)0) + cx = ""; + if (st == (const char*)0) + st = ""; + if (cm == (const char*)0) + cm = ""; + h = elfHash(st + cm); +} + + +/*! + Constructs a copy of translator message \a m. +*/ + +TranslatorMessage::TranslatorMessage(const TranslatorMessage & m) + : cx(m.cx), st(m.st), cm(m.cm), m_translations(m.m_translations), + m_fileName(m.m_fileName), m_lineNumber(m.m_lineNumber) +{ + h = m.h; +} + + +/*! + Assigns message \a m to this translator message and returns a + reference to this translator message. +*/ + +TranslatorMessage & TranslatorMessage::operator=( + const TranslatorMessage & m) +{ + h = m.h; + cx = m.cx; + st = m.st; + cm = m.cm; + m_translations = m.m_translations; + m_fileName = m.m_fileName; + m_lineNumber = m.m_lineNumber; + return *this; +} + + +/*! + \fn uint TranslatorMessage::hash() const + + Returns the hash value used internally to represent the lookup + key. This value is zero only if this translator message was + constructed from a stream containing invalid data. + + The hashing function is unspecified, but it will remain unchanged + in future versions of Qt. +*/ + +/*! + \fn const char *TranslatorMessage::context() const + + Returns the context for this message (e.g. "MyDialog"). +*/ + +/*! + \fn const char *TranslatorMessage::sourceText() const + + Returns the source text of this message (e.g. "&Save"). +*/ + +/*! + \fn const char *TranslatorMessage::comment() const + + Returns the comment for this message (e.g. "File|Save"). +*/ + +/*! + \fn void TranslatorMessage::setTranslation(const QString & translation) + + Sets the translation of the source text to \a translation. + + \sa translation() +*/ + +/*! + \fn QString TranslatorMessage::translation() const + + Returns the translation of the source text (e.g., "&Sauvegarder"). + + \sa setTranslation() +*/ + +/*! + \enum TranslatorMessage::Prefix + + Let (\e h, \e c, \e s, \e m) be the extended key. The possible + prefixes are + + \value NoPrefix no prefix + \value Hash only (\e h) + \value HashContext only (\e h, \e c) + \value HashContextSourceText only (\e h, \e c, \e s) + \value HashContextSourceTextComment the whole extended key, (\e + h, \e c, \e s, \e m) + + \sa write() commonPrefix() +*/ + +/*! + Writes this translator message to the \a stream. If \a strip is + false (the default), all the information in the message is + written. If \a strip is true, only the part of the extended key + specified by \a prefix is written with the translation (\c + HashContextSourceTextComment by default). + + \sa commonPrefix() +*/ + +void TranslatorMessage::write(QDataStream & stream, bool strip, Prefix prefix) const +{ + for (int i = 0; i < m_translations.count(); ++i) + stream << quint8(Tag_Translation) << m_translations.at(i); + + if (!strip) + prefix = HashContextSourceTextComment; + + switch (prefix) { + case HashContextSourceTextComment: + stream << quint8(Tag_Comment) << cm; + // fall through + case HashContextSourceText: + stream << quint8(Tag_SourceText) << st; + // fall through + case HashContext: + stream << quint8(Tag_Context) << cx; + default: + ; + } + + stream << quint8(Tag_End); +} + + +/*! + Returns the widest lookup prefix that is common to this translator + message and to message \a m. + + For example, if the extended key is for this message is (71, + "PrintDialog", "Yes", "Print?") and that for \a m is (71, + "PrintDialog", "No", "Print?"), this function returns \c + HashContext. + + \sa write() +*/ + +TranslatorMessage::Prefix TranslatorMessage::commonPrefix( + const TranslatorMessage& m) const +{ + if (h != m.h) + return NoPrefix; + if (cx != m.cx) + return Hash; + if (st != m.st) + return HashContext; + if (cm != m.cm) + return HashContextSourceText; + return HashContextSourceTextComment; +} + + +/*! + Returns true if the extended key of this object is equal to that of + \a m; otherwise returns false. +*/ + +bool TranslatorMessage::operator==(const TranslatorMessage& m) const +{ + bool isHashEq = (h == m.h ? true : false); + bool isContextEq = (cx == m.cx ? true : false); + bool isSourceEq = (st == m.st ? true : false); + bool isCommentEq = (cm == m.cm ? true : false); + bool isLocationEq = m_lineNumber == m.m_lineNumber && m_fileName == m.m_fileName; + + return (isHashEq && isContextEq && isSourceEq && isCommentEq) || // translation can be different, but treat the equal + (st.isEmpty() && isContextEq && isCommentEq && isLocationEq); +} + + +/*! + \fn bool TranslatorMessage::operator!=(const TranslatorMessage& m) const + + Returns true if the extended key of this object is different from + that of \a m; otherwise returns false. +*/ + + +/*! + Returns true if the extended key of this object is + lexicographically before than that of \a m; otherwise returns + false. +*/ + +bool TranslatorMessage::operator<(const TranslatorMessage& m) const +{ + return h != m.h ? h < m.h + : (cx != m.cx ? cx < m.cx + : (st != m.st ? st < m.st : cm < m.cm)); +} + + +/*! + \fn bool TranslatorMessage::operator<=(const TranslatorMessage& m) const + + Returns true if the extended key of this object is + lexicographically before that of \a m or if they are equal; + otherwise returns false. +*/ + +/*! + \fn bool TranslatorMessage::operator>(const TranslatorMessage& m) const + + Returns true if the extended key of this object is + lexicographically after that of \a m; otherwise returns false. +*/ + +/*! + \fn bool TranslatorMessage::operator>=(const TranslatorMessage& m) const + + Returns true if the extended key of this object is + lexicographically after that of \a m or if they are equal; + otherwise returns false. +*/ + +/*! + \fn QString Translator::find(const char *context, const char *sourceText, const char * comment) const + + Use findMessage() instead. +*/ + +bool getNumerusInfo(QLocale::Language language, QLocale::Country country, + QStringList *forms) +{ + forever { + for (int i = 0; i < NumerusTableSize; ++i) { + const NumerusTableEntry &entry = numerusTable[i]; + for (int j = 0; entry.languages[j] != EOL; ++j) { + if (entry.languages[j] == language + && ((!entry.countries && country == QLocale::AnyCountry) + || (entry.countries && entry.countries[j] == country))) { + if (forms) { + forms->clear(); + for (int k = 0; entry.forms[k]; ++k) + forms->append(QLatin1String(entry.forms[k])); + } + return true; + } + } + } + + if (country == QLocale::AnyCountry) + break; + country = QLocale::AnyCountry; + } + return false; +} + +#endif // QT_NO_TRANSLATION diff --git a/sources/pyside2-tools/pylupdate/translator.h b/sources/pyside2-tools/pylupdate/translator.h new file mode 100644 index 0000000..d0cd4e7 --- /dev/null +++ b/sources/pyside2-tools/pylupdate/translator.h @@ -0,0 +1,387 @@ +/* + * This file is part of the PySide Tools project. + * + * Copyright (C) 1992-2005 Trolltech AS. All rights reserved. + * Copyright (C) 2002-2007 Detlev Offenbach + * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + * + * Contact: PySide team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + * + */ + +#ifndef TRANSLATOR_H +#define TRANSLATOR_H + +#include "QtCore/qobject.h" +#include "QtCore/qbytearray.h" +#include "QtCore/qstringlist.h" +#include "QtCore/qlocale.h" +#include + +class TranslatorPrivate; + +class TranslatorMessage +{ +public: + TranslatorMessage(); + TranslatorMessage(const char * context, const char * sourceText, + const char * comment, + const QString &fileName, + int lineNumber, + const QStringList& translations = QStringList()); + TranslatorMessage(const TranslatorMessage & m); + + TranslatorMessage & operator=(const TranslatorMessage & m); + + uint hash() const { return h; } + const char *context() const { return cx.isNull() ? 0 : cx.constData(); } + const char *sourceText() const { return st.isNull() ? 0 : st.constData(); } + const char *comment() const { return cm.isNull() ? 0 : cm.constData(); } + + inline void setTranslations(const QStringList &translations); + QStringList translations() const { return m_translations; } + void setTranslation(const QString &translation) { m_translations = QStringList(translation); } + QString translation() const { return m_translations.value(0); } + bool isTranslated() const { return m_translations.count() > 1 || !m_translations.value(0).isEmpty(); } + + enum Prefix { NoPrefix, Hash, HashContext, HashContextSourceText, + HashContextSourceTextComment }; + void write(QDataStream & s, bool strip = false, + Prefix prefix = HashContextSourceTextComment) const; + Prefix commonPrefix(const TranslatorMessage&) const; + + bool operator==(const TranslatorMessage& m) const; + bool operator!=(const TranslatorMessage& m) const + { return !operator==(m); } + bool operator<(const TranslatorMessage& m) const; + bool operator<=(const TranslatorMessage& m) const + { return !m.operator<(*this); } + bool operator>(const TranslatorMessage& m) const + { return m.operator<(*this); } + bool operator>=(const TranslatorMessage& m) const + { return !operator<(m); } + + QString fileName(void) const { return m_fileName; } + void setFileName(const QString &fileName) { m_fileName = fileName; } + int lineNumber(void) const { return m_lineNumber; } + void setLineNumber(int lineNumber) { m_lineNumber = lineNumber; } + bool isNull() const { return st.isNull() && m_lineNumber == -1 && m_translations.isEmpty(); } + +private: + uint h; + QByteArray cx; + QByteArray st; + QByteArray cm; + QStringList m_translations; + QString m_fileName; + int m_lineNumber; + + enum Tag { Tag_End = 1, Tag_SourceText16, Tag_Translation, Tag_Context16, + Tag_Hash, Tag_SourceText, Tag_Context, Tag_Comment, + Tag_Obsolete1 }; +}; + +QT_BEGIN_NAMESPACE +Q_DECLARE_TYPEINFO(TranslatorMessage, Q_MOVABLE_TYPE); +QT_END_NAMESPACE + +inline void TranslatorMessage::setTranslations(const QStringList &translations) +{ m_translations = translations; } + +class Translator : public QTranslator +{ + Q_OBJECT +public: + explicit Translator(QObject *parent = 0); + ~Translator(); + + virtual TranslatorMessage findMessage(const char *context, const char *sourceText, + const char *comment = 0, + const QString &fileName = 0, int lineNumber = -1) const; + virtual QString translate(const char *context, const char *sourceText, + const char *comment = 0) const + { return findMessage(context, sourceText, comment).translation(); } + + bool load(const QString & filename, + const QString & directory = QString(), + const QString & search_delimiters = QString(), + const QString & suffix = QString()); + bool load(const uchar *data, int len); + + void clear(); + + enum SaveMode { Everything, Stripped }; + + bool save(const QString & filename, SaveMode mode = Everything); + + void insert(const TranslatorMessage&); + inline void insert(const char *context, const char *sourceText, const QString &fileName, int lineNo, const QStringList &translations) { + insert(TranslatorMessage(context, sourceText, "", fileName, lineNo, translations)); + } + void remove(const TranslatorMessage&); + inline void remove(const char *context, const char *sourceText) { + remove(TranslatorMessage(context, sourceText, "", QLatin1String(""), -1)); + } + bool contains(const char *context, const char *sourceText, const char * comment = 0) const; + bool contains(const char *context, const char *comment, const QString &fileName, int lineNumber) const; + + void squeeze(SaveMode = Everything); + void unsqueeze(); + + QList messages() const; + + bool isEmpty() const; + +private: + Q_DISABLE_COPY(Translator) + TranslatorPrivate *d; +}; + +static const char * const japaneseStyleForms[] = { "Unique Form", 0 }; +static const char * const englishStyleForms[] = { "Singular", "Plural", 0 }; +static const char * const frenchStyleForms[] = { "Singular", "Plural", 0 }; +static const char * const latvianForms[] = { "Singular", "Plural", "Nullar", 0 }; +static const char * const irishStyleForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const czechForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const slovakForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const macedonianForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const lithuanianForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const russianStyleForms[] = { "Singular", "Dual", "Plural", 0 }; +static const char * const polishForms[] = { "Singular", "Paucal", "Plural", 0 }; +static const char * const romanianForms[] = + { "Singular", "Plural Form for 2 to 19", "Plural", 0 }; +static const char * const slovenianForms[] = { "Singular", "Dual", "Trial", "Plural", 0 }; +static const char * const malteseForms[] = + { "Singular", "Plural Form for 2 to 10", "Plural Form for 11 to 19", "Plural", 0 }; +static const char * const welshForms[] = + { "Nullar", "Singular", "Dual", "Sexal", "Plural", 0 }; +static const char * const arabicForms[] = + { "Nullar", "Singular", "Dual", "Minority Plural", "Plural", "Plural Form for 100, 200, ...", 0 }; + +#define EOL QLocale::C + +static const QLocale::Language japaneseStyleLanguages[] = { + QLocale::Afan, + QLocale::Armenian, + QLocale::Bhutani, + QLocale::Bislama, + QLocale::Burmese, + QLocale::Chinese, + QLocale::Fijian, + QLocale::Guarani, + QLocale::Hungarian, + QLocale::Indonesian, + QLocale::Japanese, + QLocale::Javanese, + QLocale::Korean, + QLocale::Malay, + QLocale::NauruLanguage, + QLocale::Persian, + QLocale::Sundanese, + QLocale::Thai, + QLocale::Tibetan, + QLocale::Vietnamese, + QLocale::Yoruba, + QLocale::Zhuang, + EOL +}; + +static const QLocale::Language englishStyleLanguages[] = { + QLocale::Abkhazian, + QLocale::Afar, + QLocale::Afrikaans, + QLocale::Albanian, + QLocale::Amharic, + QLocale::Assamese, + QLocale::Aymara, + QLocale::Azerbaijani, + QLocale::Bashkir, + QLocale::Basque, + QLocale::Bengali, + QLocale::Bihari, + // Missing: Bokmal, + QLocale::Bulgarian, + QLocale::Cambodian, + QLocale::Catalan, + QLocale::Cornish, + QLocale::Corsican, + QLocale::Danish, + QLocale::Dutch, + QLocale::English, + QLocale::Esperanto, + QLocale::Estonian, + QLocale::Faroese, + QLocale::Finnish, + // Missing: Friulian, + QLocale::Frisian, + QLocale::Galician, + QLocale::Georgian, + QLocale::German, + QLocale::Greek, + QLocale::Greenlandic, + QLocale::Gujarati, + QLocale::Hausa, + QLocale::Hebrew, + QLocale::Hindi, + QLocale::Icelandic, + QLocale::Interlingua, + QLocale::Interlingue, + QLocale::Italian, + QLocale::Kannada, + QLocale::Kashmiri, + QLocale::Kazakh, + QLocale::Kinyarwanda, + QLocale::Kirghiz, + QLocale::Kurdish, + QLocale::Kurundi, + QLocale::Lao, + QLocale::Latin, + // Missing: Letzeburgesch, + QLocale::Lingala, + QLocale::Malagasy, + QLocale::Malayalam, + QLocale::Marathi, + QLocale::Mongolian, + // Missing: Nahuatl, + QLocale::Nepali, + QLocale::NorthernSotho, + QLocale::Norwegian, + QLocale::NorwegianNynorsk, + QLocale::Occitan, + QLocale::Oriya, + QLocale::Pashto, + QLocale::Portuguese, + QLocale::Punjabi, + QLocale::Quechua, + QLocale::RhaetoRomance, + QLocale::SouthernSotho, + QLocale::Tswana, + QLocale::Shona, + QLocale::Sindhi, + QLocale::Sinhala, + QLocale::Swati, + QLocale::Somali, + QLocale::Spanish, + QLocale::Swahili, + QLocale::Swedish, + QLocale::Tagalog, + QLocale::Tajik, + QLocale::Tamil, + QLocale::Tatar, + QLocale::Telugu, + QLocale::Tongan, + QLocale::Tsonga, + QLocale::Turkish, + QLocale::Turkmen, + QLocale::Twi, + QLocale::Uigur, + QLocale::Uzbek, + QLocale::Volapuk, + QLocale::Wolof, + QLocale::Xhosa, + QLocale::Yiddish, + QLocale::Zulu, + EOL +}; +static const QLocale::Language frenchStyleLanguages[] = { + // keep synchronized with frenchStyleCountries + QLocale::Breton, + QLocale::French, + QLocale::Portuguese, + // Missing: Filipino, + QLocale::Tigrinya, + // Missing: Walloon + EOL +}; +static const QLocale::Language latvianLanguage[] = { QLocale::Latvian, EOL }; +static const QLocale::Language irishStyleLanguages[] = { + QLocale::Divehi, + QLocale::Gaelic, + QLocale::Inuktitut, + QLocale::Inupiak, + QLocale::Irish, + QLocale::Manx, + QLocale::Maori, + // Missing: Sami, + QLocale::Samoan, + QLocale::Sanskrit, + EOL +}; +static const QLocale::Language czechLanguage[] = { QLocale::Czech, EOL }; +static const QLocale::Language slovakLanguage[] = { QLocale::Slovak, EOL }; +static const QLocale::Language macedonianLanguage[] = { QLocale::Macedonian, EOL }; +static const QLocale::Language lithuanianLanguage[] = { QLocale::Lithuanian, EOL }; +static const QLocale::Language russianStyleLanguages[] = { + QLocale::Bosnian, + QLocale::Byelorussian, + QLocale::Croatian, + QLocale::Russian, + QLocale::Serbian, + QLocale::SerboCroatian, + QLocale::Ukrainian, + EOL +}; +static const QLocale::Language polishLanguage[] = { QLocale::Polish, EOL }; +static const QLocale::Language romanianLanguages[] = { + QLocale::Moldavian, + QLocale::Romanian, + EOL +}; +static const QLocale::Language slovenianLanguage[] = { QLocale::Slovenian, EOL }; +static const QLocale::Language malteseLanguage[] = { QLocale::Maltese, EOL }; +static const QLocale::Language welshLanguage[] = { QLocale::Welsh, EOL }; +static const QLocale::Language arabicLanguage[] = { QLocale::Arabic, EOL }; + +static const QLocale::Country frenchStyleCountries[] = { + // keep synchronized with frenchStyleLanguages + QLocale::AnyCountry, + QLocale::AnyCountry, + QLocale::Brazil, + QLocale::AnyCountry +}; + +struct NumerusTableEntry { + const char * const *forms; + const QLocale::Language *languages; + const QLocale::Country *countries; +}; + +static const NumerusTableEntry numerusTable[] = { + { japaneseStyleForms, japaneseStyleLanguages, 0 }, + { englishStyleForms, englishStyleLanguages, 0 }, + { frenchStyleForms, frenchStyleLanguages, frenchStyleCountries }, + { latvianForms, latvianLanguage, 0 }, + { irishStyleForms, irishStyleLanguages, 0 }, + { czechForms, czechLanguage, 0 }, + { slovakForms, slovakLanguage, 0 }, + { macedonianForms, macedonianLanguage, 0 }, + { lithuanianForms, lithuanianLanguage, 0 }, + { russianStyleForms, russianStyleLanguages, 0 }, + { polishForms, polishLanguage, 0 }, + { romanianForms, romanianLanguages, 0 }, + { slovenianForms, slovenianLanguage, 0 }, + { malteseForms, malteseLanguage, 0 }, + { welshForms, welshLanguage, 0 }, + { arabicForms, arabicLanguage, 0 } +}; + +static const int NumerusTableSize = sizeof(numerusTable) / sizeof(numerusTable[0]); + +bool getNumerusInfo(QLocale::Language language, QLocale::Country country, + QStringList *forms); + +#endif // TRANSLATOR_H diff --git a/sources/pyside2-tools/pyside_tool.py b/sources/pyside2-tools/pyside_tool.py new file mode 100755 index 0000000..da2d741 --- /dev/null +++ b/sources/pyside2-tools/pyside_tool.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +############################################################################# +## +## Copyright (C) 2018 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# +import sys +import os +import subprocess + +from subprocess import Popen, PIPE +import PySide2 as ref_mod + + +def main(): + # This will take care of "pyside2-lupdate" listed as an entrypoint + # in setup.py are copied to 'scripts/..' + cmd = os.path.join("..", os.path.basename(sys.argv[0])) + command = [os.path.join(os.path.dirname(os.path.realpath(__file__)), cmd)] + command.extend(sys.argv[1:]) + sys.exit(subprocess.call(command)) + + +def qt_tool_wrapper(qt_tool, args): + # Taking care of pyside2-uic, pyside2-rcc, and pyside2-designer + # listed as an entrypoint in setup.py + pyside_dir = os.path.dirname(ref_mod.__file__) + exe = os.path.join(pyside_dir, qt_tool) + + cmd = [exe] + args + proc = Popen(cmd, stderr=PIPE) + out, err = proc.communicate() + if err: + msg = err.decode("utf-8") + print("Error: {}\nwhile executing '{}'".format(msg, ' '.join(cmd))) + sys.exit(proc.returncode) + + +def uic(): + qt_tool_wrapper("uic", ['-g', 'python'] + sys.argv[1:]) + + +def rcc(): + qt_tool_wrapper("rcc", ['-g', 'python'] + sys.argv[1:]) + + +def designer(): + if sys.platform == "darwin": + qt_tool_wrapper("Designer.app/Contents/MacOS/Designer", sys.argv[1:]) + else: + qt_tool_wrapper("designer", sys.argv[1:]) + + +if __name__ == "__main__": + main() diff --git a/sources/pyside2-tools/qt_attribution.json b/sources/pyside2-tools/qt_attribution.json new file mode 100644 index 0000000..2c7ffff --- /dev/null +++ b/sources/pyside2-tools/qt_attribution.json @@ -0,0 +1,16 @@ +[ +{ + "Id": "pylupdate", + "Name": "pylupdate", + "Path": "pylupdate", + "Description": "The pylupdate tool is used to create or update Qt Linguist translation files from Python sources", + "QtUsage": "Python version of the Qt lupdate tool", + "License": "GNU Library General Public License v2 only", + "LicenseId": "GPL-2.0", + "LicenseFile": "LICENSE-lupdate", + "Copyright": "Copyright (C) 1992-2006 Trolltech AS. +Copyright (C) 2002-2007 Detlev Offenbach . +Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +Copyright (C) 2010 Marcelo Lira ." +} +] diff --git a/sources/pyside2-tools/tests/CMakeLists.txt b/sources/pyside2-tools/tests/CMakeLists.txt new file mode 100644 index 0000000..25a9cb7 --- /dev/null +++ b/sources/pyside2-tools/tests/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(rcc) +add_test(QWizard ${SHIBOKEN_PYTHON_INTERPRETER} ${CMAKE_SOURCE_DIR}/pyside2-uic "${CMAKE_CURRENT_SOURCE_DIR}/qwizard_test.ui") +set_tests_properties(QWizard PROPERTIES + ENVIRONMENT "PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_SOURCE_DIR}:${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/sources/pyside2-tools/tests/qwizard_test.ui b/sources/pyside2-tools/tests/qwizard_test.ui new file mode 100644 index 0000000..6b725f8 --- /dev/null +++ b/sources/pyside2-tools/tests/qwizard_test.ui @@ -0,0 +1,67 @@ + + + Wizard + + + + 0 + 0 + 400 + 300 + + + + Wizard + + + + + + + + 0 + 0 + + + + + 72 + + + + Hello + + + Qt::PlainText + + + true + + + Qt::AlignCenter + + + + + + + + http://test.qml + + + + + + + + + + + QDeclarativeView + QGraphicsView +
QtDeclarative/QDeclarativeView
+
+
+ + +
diff --git a/sources/pyside2-tools/tests/rcc/CMakeLists.txt b/sources/pyside2-tools/tests/rcc/CMakeLists.txt new file mode 100644 index 0000000..70341ab --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/CMakeLists.txt @@ -0,0 +1,10 @@ +macro(ADD_RCC_TEST name pyfile qrcfile) + add_test(${name} ${CMAKE_CURRENT_SOURCE_DIR}/run_test.sh + ${PYSIDERCC_EXECUTABLE} + ${CMAKE_CURRENT_SOURCE_DIR}/${pyfile} + ${CMAKE_CURRENT_SOURCE_DIR}/${qrcfile} + ${CMAKE_CURRENT_SOURCE_DIR}) +endmacro() + +add_rcc_test(RccTest rcc_test.py example.qrc) +add_rcc_test(RccImageTest rcc_image_test.py image.qrc) diff --git a/sources/pyside2-tools/tests/rcc/document-print-preview.png b/sources/pyside2-tools/tests/rcc/document-print-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..772efe5a8a6f214a249d7c4cbf54b72bd153b91d GIT binary patch literal 1719 zcmV;o21xmdP)H>IQPh+aB~gKj zgitC%r2tiV^-CWhXw}k6i5eC701|wNA~k|Ugp^jsRIMnGmWJ{QH7RW%F$G(G#@>f_ z);lxz-hS}fv3a;Wl78utj&x_QX3p>Y@0oLU;Q!sU+ih&$zI}Htms#ic=LhrI@O(XewqWtr zMp`;Dyts53@1HtJ%heXz+uMiTvMemix_bp)dF2=LYra%7Hx{d5*|tCM(zDZ;^I!!9 zrj92hWr0E}f+b9skNCQe}b z#0WwPgp^1rQBoj;hoK~o)>ZQA{tuY?;6q&brP|$+jyR$q{!lWM-M)KA;R-+%G&e1y8{3%?RsumS)oBk zuT5335Wl5^uA>3A?O|FLq46bT9Yw$GB85vTnFJu4&7x_aHCWRe<4wOcfci_;9(duY zM?#$cS37>grNn3AGr>S$nHrvitgC40$PgLlBUI+2tE&s8prfN>FpWG!d3pJr1FTuI zW_EX1?}Fxw&8&F#8CJe}f^a}19`WNh6+S~zV1O$%`fS1B_uKf%@;a_wy-F&T;>wlF zghJub0rCp0UcFjbrrDWuoUiQNyZ6JP{oy{kZrwVc&*wY2=|`I)*RNlrq&UFyPt~#O z&_#L@HkR(8q)Trq%Y~K{e>~sK*5%WAcwz? zwzihS!a~B~aOtU2r^J~vXHLL~alCfz+P)n-c8nW3yG*8^!$%qcnA0$a^2h|Nf&zpm z=u7nS!G&`iJ$jVMwNr>z#qm6k&dyFO%i_w%m+|?1tY5nUzu!N)!jxkD`gNIIyLK0k zssYz^$0?;~Z*Rl0ELvOJsGIsQLU^1#cb1O!cI>Q;X_y280pjsEE55ao0|(#6&e}|x zIGIQ!LQhW*wUZ{()zirjH+`R#FMXTR;$l*%G_L0|eR@4Y$iOX&PzXUXnWU;R%D}(? zWu+wq0zrb~Lr5u+QXqvyr%*m2!takX zv3k`SIy$=;$l5r$+$cpxwPMfnXly);ZD)vt!)Tg@5FVcA;y5{Sxf}zz0kTx_O&MqWrMsjRHzr$5_9E|)_o zHQ4`^8g%(t_CpGcbcN)=!2>K=vVH+2xe852M-d-g15&6V@LnQ{{8!iR#mZV=~4nkf#F2lu>gb+ z!)r~`Fbo}Cw}vO%kP337B1#Qj=hx+tauzLIc+>Ag=D6 + + words.txt + shining.txt + manychars.txt + + diff --git a/sources/pyside2-tools/tests/rcc/image.qrc b/sources/pyside2-tools/tests/rcc/image.qrc new file mode 100644 index 0000000..c569508 --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/image.qrc @@ -0,0 +1,5 @@ + + + document-print-preview.png + + diff --git a/sources/pyside2-tools/tests/rcc/manychars.txt b/sources/pyside2-tools/tests/rcc/manychars.txt new file mode 100644 index 0000000..82e73d0 --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/manychars.txt @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa diff --git a/sources/pyside2-tools/tests/rcc/rcc_image_test.py b/sources/pyside2-tools/tests/rcc/rcc_image_test.py new file mode 100644 index 0000000..00015be --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/rcc_image_test.py @@ -0,0 +1,16 @@ + +import unittest + +from PySide2.QtWidgets import QApplication +from PySide2.QtGui import QPixmap + +import image_rc + +class TestRccImage(unittest.TestCase): + def testImage(self): + app = QApplication([]) + image = QPixmap(":image") + self.assertFalse(image.isNull()) + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2-tools/tests/rcc/rcc_test.py b/sources/pyside2-tools/tests/rcc/rcc_test.py new file mode 100644 index 0000000..91b5ca8 --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/rcc_test.py @@ -0,0 +1,31 @@ +import os +import unittest +from PySide2.QtCore import QFile +import example_rc + +class TestRccSimple(unittest.TestCase): + + def setUp(self): + self.testdir = os.path.dirname(__file__) + + def testSimple(self): + handle = QFile(":words.txt") + handle.open(QFile.ReadOnly) + original = open(os.path.join(self.testdir, "words.txt"), "r") + self.assertEqual(handle.readLine(), original.readline()) + + def testAlias(self): + handle = QFile(":jack") + handle.open(QFile.ReadOnly) + original = open(os.path.join(self.testdir, "shining.txt"), "r") + self.assertEqual(handle.readLine(), original.readline()) + + def testHuge(self): + handle = QFile(":manychars.txt") + handle.open(QFile.ReadOnly) + original = open(os.path.join(self.testdir, "manychars.txt"), "r") + self.assertEqual(handle.readLine(), original.readline()) + + +if __name__ == '__main__': + unittest.main() diff --git a/sources/pyside2-tools/tests/rcc/run_test.sh b/sources/pyside2-tools/tests/rcc/run_test.sh new file mode 100755 index 0000000..72c4906 --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/run_test.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# This is a nasty workaround of a CTest limitation +# of setting the environment variables for the test. + +# $1: pyside2-rcc +# $2: python test +# $3: qrc file + +export PYTHONPATH=$PYTHONPATH:`pwd` +$1 -o `basename $3 .qrc`_rc.py $3 +`pkg-config shiboken2 --variable=python_interpreter` $2 diff --git a/sources/pyside2-tools/tests/rcc/shining.txt b/sources/pyside2-tools/tests/rcc/shining.txt new file mode 100644 index 0000000..2528eb9 --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/shining.txt @@ -0,0 +1 @@ +All work and no play makes Jack a dull boy. diff --git a/sources/pyside2-tools/tests/rcc/words.txt b/sources/pyside2-tools/tests/rcc/words.txt new file mode 100644 index 0000000..53f03fc --- /dev/null +++ b/sources/pyside2-tools/tests/rcc/words.txt @@ -0,0 +1 @@ +The Quick Brown Fox Jumps Over The Lazy Dog. diff --git a/sources/pyside2/CMakeLists.txt b/sources/pyside2/CMakeLists.txt new file mode 100644 index 0000000..dc2bede --- /dev/null +++ b/sources/pyside2/CMakeLists.txt @@ -0,0 +1,284 @@ +include(cmake/Macros/icecc.cmake) # this must be the first line! + +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +# Don't ignore targets that do not exist, inside add_dependencies calls. +cmake_policy(SET CMP0046 NEW) + +set (QT_MAJOR_VERSION 5) + +project(pysidebindings) + +set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_helpers/ + ${CMAKE_CURRENT_SOURCE_DIR}/../shiboken2/data/ + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/Macros/ + ${CMAKE_MODULE_PATH}) +include(shiboken_helpers) +include(helpers) + +# Don't display "up-to-date / install" messages when installing, to reduce visual clutter. +if (QUIET_BUILD) + set(CMAKE_INSTALL_MESSAGE NEVER) +endif() + +# Override message not to display info messages when doing a quiet build. +if (QUIET_BUILD AND is_pyside2_superproject_build) + function(message) + list(GET ARGV 0 MessageType) + if (MessageType STREQUAL FATAL_ERROR OR + MessageType STREQUAL SEND_ERROR OR + MessageType STREQUAL WARNING OR + MessageType STREQUAL AUTHOR_WARNING) + list(REMOVE_AT ARGV 0) + _message(${MessageType} "${ARGV}") + endif() + endfunction() +endif() + +set(PYSIDE_VERSION_FILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/pyside_version.py") +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS + ${PYSIDE_VERSION_FILE_PATH} +) +execute_process( + COMMAND ${PYTHON_EXECUTABLE} "${PYSIDE_VERSION_FILE_PATH}" + OUTPUT_VARIABLE PYSIDE_VERSION_OUTPUT + ERROR_VARIABLE PYSIDE_VERSION_OUTPUT_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE) +if (NOT PYSIDE_VERSION_OUTPUT) + message(FATAL_ERROR "Could not identify PySide2 version. Error: ${PYSIDE_VERSION_OUTPUT_ERROR}") +endif() + +list(GET PYSIDE_VERSION_OUTPUT 0 BINDING_API_MAJOR_VERSION) +list(GET PYSIDE_VERSION_OUTPUT 1 BINDING_API_MINOR_VERSION) +list(GET PYSIDE_VERSION_OUTPUT 2 BINDING_API_MICRO_VERSION) +# a - alpha, b - beta, rc - rc +list(GET PYSIDE_VERSION_OUTPUT 3 BINDING_API_PRE_RELEASE_VERSION_TYPE) +# the number of the pre release (alpha1, beta3, rc7, etc.) +list(GET PYSIDE_VERSION_OUTPUT 4 BINDING_API_PRE_RELEASE_VERSION) + +if (WIN32) + set(PATH_SEP "\;") +else() + set(PATH_SEP ":") +endif() + +find_package(Shiboken2 2.0.0 REQUIRED) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "${SHIBOKEN_BUILD_TYPE}" CACHE STRING "Build Type") +endif() + +if (CMAKE_BUILD_TYPE STREQUAL "Release") + add_definitions("-DNDEBUG") +endif() + +if (SHIBOKEN_PYTHON_LIMITED_API) + message(STATUS "******************************************************") + message(STATUS "** PySide2 Limited API enabled.") + message(STATUS "******************************************************") +endif() + +find_package(Qt${QT_MAJOR_VERSION} 5.12 REQUIRED COMPONENTS Core) +add_definitions(${Qt${QT_MAJOR_VERSION}Core_DEFINITIONS}) + +find_file(GL_H "gl.h" PATH_SUFFIXES "GL") +message(STATUS "GL Headers path:" "${GL_H}") +include(FindQt5Extra) + +set(XVFB_EXEC "") +option(USE_XVFB "Uses xvfb-run with the unit tests to avoid QtGui tests popping windows on the screen." FALSE) +if(USE_XVFB) + find_program(XVFB_RUN NAMES xvfb-run) + if (NOT ${XVFB_RUN} MATCHES "XVFB_RUN-NOTFOUND") + set(XVFB_EXEC ${XVFB_RUN} -a) + message(STATUS "Using xvfb-run to perform QtGui tests.") + endif() +endif() + +option(BUILD_TESTS "Build tests." TRUE) +option(ENABLE_VERSION_SUFFIX "Used to use current version in suffix to generated files. This is used to allow multiples versions installed simultaneous." FALSE) +set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" ) +set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE) +if(CMAKE_HOST_APPLE) + set(ALTERNATIVE_QT_INCLUDE_DIR "" CACHE PATH "Deprecated. CMake now finds the proper include dir itself.") + set(OSX_USE_LIBCPP "OFF" CACHE BOOL "Explicitly link the libc++ standard library (useful for osx deployment targets lower than 10.9.") + if(OSX_USE_LIBCPP) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") + endif() +endif() + +# Force usage of the C++11 standard, without a silent fallback +# to C++98 if the compiler does not support C++11. +if(${QT_MAJOR_VERSION} GREATER_EQUAL 6) + set(CMAKE_CXX_STANDARD 17) +else() + set(CMAKE_CXX_STANDARD 11) +endif() +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# >= Qt5: QT_INCLUDE_DIR does no longer exist. Derive from QtCore +if(${QT_MAJOR_VERSION} GREATER_EQUAL 6) + get_target_property(QT_INCLUDE_DIR Qt6::Core INTERFACE_INCLUDE_DIRECTORIES) + get_filename_component(QT_INCLUDE_DIR "${QT_INCLUDE_DIR}" DIRECTORY) +else() + # On Windows, macOS, and Linux it can be computed from Qt5Core_INCLUDE_DIRS, which contains + # a list of include directories. We take the first one. + list(GET Qt5Core_INCLUDE_DIRS 0 QT_INCLUDE_DIR) +endif() +message(STATUS "*** Qt ${QT_MAJOR_VERSION}, QT_INCLUDE_DIR= ${QT_INCLUDE_DIR}") + +# On macOS, check if Qt is a framework build. This affects how include paths should be handled. +get_target_property(QtCore_is_framework Qt${QT_MAJOR_VERSION}::Core FRAMEWORK) + +if (QtCore_is_framework) + # Get the path to the framework dir. + get_filename_component(QT_FRAMEWORK_INCLUDE_DIR "${QT_INCLUDE_DIR}/../" ABSOLUTE) + message(STATUS "*** QT_FRAMEWORK_INCLUDE_DIR is ${QT_FRAMEWORK_INCLUDE_DIR}") + + # QT_INCLUDE_DIR points to the QtCore.framework directory, so we need to adjust this to point + # to the actual include directory, which has include files for non-framework parts of Qt. + get_filename_component(QT_INCLUDE_DIR "${QT_INCLUDE_DIR}/../../include" ABSOLUTE) +endif() + +set_cmake_cxx_flags() + +message(STATUS "*** computed QT_INCLUDE_DIR as ${QT_INCLUDE_DIR}") + +set(BINDING_NAME PySide2) + +set(BINDING_API_VERSION "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" CACHE STRING "PySide2 version" FORCE) +set(PYSIDE_SO_VERSION ${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}) +if (BINDING_API_PRE_RELEASE_VERSION_TYPE STREQUAL "") + set(BINDING_API_VERSION_FULL "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}" + CACHE STRING "PySide2 version [full]" FORCE) +else() + set(BINDING_API_VERSION_FULL "${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}.${BINDING_API_MICRO_VERSION}~${BINDING_API_PRE_RELEASE_VERSION_TYPE}${BINDING_API_PRE_RELEASE_VERSION}" + CACHE STRING "PySide2 version [full]" FORCE) +endif() + +compute_config_py_values(BINDING_API_VERSION) + +include(PySideModules) + +# Set default values for pyside2_global.h +set (Qt${QT_MAJOR_VERSION}X11Extras_FOUND "0") +set (Qt${QT_MAJOR_VERSION}Test_FOUND "0") +set (Qt${QT_MAJOR_VERSION}Widgets_FOUND "0") + +collect_essential_modules() +collect_optional_modules() + +# Modules to be built unless specified by -DMODULES on command line +if (NOT MODULES) + set(MODULES "${ALL_ESSENTIAL_MODULES};${ALL_OPTIONAL_MODULES}") +endif() + +# This will contain the set of modules for which bindings are not built. +set(DISABLED_MODULES "${ALL_ESSENTIAL_MODULES};${ALL_OPTIONAL_MODULES}") + +remove_skipped_modules() + +# Mark all non-collected modules as disabled. This is used for disabling tests +# that depend on the disabled modules. +foreach(m ${DISABLED_MODULES}) + set(DISABLE_Qt${m} 1) +endforeach() + + +string(REGEX MATCHALL "[0-9]+" qt_version_helper "${Qt${QT_MAJOR_VERSION}Core_VERSION}") + +list(GET qt_version_helper 0 QT_VERSION_MAJOR) +list(GET qt_version_helper 1 QT_VERSION_MINOR) +list(GET qt_version_helper 2 QT_VERSION_PATCH) +unset(qt_version_helper) + +set(PYSIDE_QT_VERSION "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" CACHE STRING "Qt version used to compile PySide" FORCE) +if(ENABLE_VERSION_SUFFIX) + set(pyside_SUFFIX "-${BINDING_API_MAJOR_VERSION}.${BINDING_API_MINOR_VERSION}") +endif() + +# no more supported: include(${QT_USE_FILE}) + +# Configure OS support +check_os() +message(STATUS "Detected OS: ${AUTO_OS}") + +# Define supported Qt Version +set(SUPPORTED_QT_VERSION "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}") + + +# uninstall target +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) + +# When opening super project, prevent redefinition of uninstall target. +if (NOT TARGET uninstall) + add_custom_target(uninstall "${CMAKE_COMMAND}" + -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +endif() + +if (NOT PYTHON_SITE_PACKAGES) + execute_process( + COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} -c "if True: + from distutils import sysconfig + from os.path import sep + print(sysconfig.get_python_lib(1, 0, prefix='${CMAKE_INSTALL_PREFIX}').replace(sep, '/')) + " + OUTPUT_VARIABLE PYTHON_SITE_PACKAGES + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (NOT PYTHON_SITE_PACKAGES) + message(FATAL_ERROR "Could not detect Python module installation directory.") + elseif (APPLE) + message(STATUS "!!! The generated bindings will be installed on ${PYTHON_SITE_PACKAGES}, is it right!?") + endif() +endif() + +set(GENERATOR_EXTRA_FLAGS --generator-set=shiboken + --enable-parent-ctor-heuristic + --enable-pyside-extensions + --enable-return-value-heuristic + --use-isnull-as-nb_nonzero) +use_protected_as_public_hack() + +# Build with Address sanitizer enabled if requested. This may break things, so use at your own risk. +if (SANITIZE_ADDRESS AND NOT MSVC) + setup_sanitize_address() +endif() + +##################################################################### +# Adding sub-directories to build +##################################################################### + +add_subdirectory(libpyside) +find_package(Qt${QT_MAJOR_VERSION}Designer) +if(${QT_MAJOR_VERSION} LESS 6 AND Qt${QT_MAJOR_VERSION}UiTools_FOUND + AND Qt${QT_MAJOR_VERSION}Designer_FOUND) + add_subdirectory(plugins) +endif() + +# project directories +add_subdirectory(PySide2) +if (BUILD_TESTS) + enable_testing() + add_subdirectory(tests) +endif () + +find_program(SPHINX_BUILD sphinx-build) +find_program(DOT_EXEC dot) + +if (QT_SRC_DIR AND SPHINX_BUILD AND DOT_EXEC) + add_subdirectory(doc) +else () + set(DOCS_TARGET_DISABLED_MESSAGE "apidoc generation targets disabled.") + if (NOT QT_SRC_DIR) + message(STATUS "QT_SRC_DIR variable not set, ${DOCS_TARGET_DISABLED_MESSAGE}") + elseif (NOT SPHINX_BUILD) + message(STATUS "sphinx-build command not found, ${DOCS_TARGET_DISABLED_MESSAGE}") + elseif (NOT DOT_EXEC) + message(STATUS "graphviz not found, ${DOCS_TARGET_DISABLED_MESSAGE}") + else() + message(STATUS "Unknown issue occurred, ${DOCS_TARGET_DISABLED_MESSAGE}") + endif() +endif() diff --git a/sources/pyside2/COPYING b/sources/pyside2/COPYING new file mode 100644 index 0000000..9315102 --- /dev/null +++ b/sources/pyside2/COPYING @@ -0,0 +1,501 @@ +GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + diff --git a/sources/pyside2/PySide2/CMakeLists.txt b/sources/pyside2/PySide2/CMakeLists.txt new file mode 100644 index 0000000..120bc8e --- /dev/null +++ b/sources/pyside2/PySide2/CMakeLists.txt @@ -0,0 +1,108 @@ +project(pyside2) + +# Configure include based on platform +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/global.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h" @ONLY) + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/__init__.py.in" + "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/_config.py.in" + "${CMAKE_CURRENT_BINARY_DIR}/_config.py" @ONLY) +# typing support for mypy +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/py.typed.in" + "${CMAKE_CURRENT_BINARY_DIR}/py.typed" @ONLY) + +# Use absolute path instead of relative path, to avoid ninja build errors due to +# duplicate file dependency inconsistency. +set(pyside_version_relative_path "${CMAKE_CURRENT_SOURCE_DIR}/../pyside_version.py") +get_filename_component(pyside_version_path ${pyside_version_relative_path} ABSOLUTE) +configure_file("${pyside_version_path}" + "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py" @ONLY) + +# qt.conf needs to be placed next to QtWebEngineProcess so that the executable uses the correct +# Prefix location leading to an existing icu data file. It is needed on Windows, Linux, and macOS +# non-framework build. In framework build, instead of using qt.conf, Bundle querying is used. +if (WIN32 OR (UNIX AND NOT APPLE) OR (APPLE AND NOT QtCore_is_framework)) + + if (WIN32) + # On Windows, the QtWebEngineProcess is directly located in the Prefix, due to not using + # a "Qt" subfolder like on the other platforms. + set(QT_CONF_PREFIX ".") + else() + # On Linux and non-framework macOS, the QtWebEngineProcess is in ./libexec, so prefix is one + # level higher. + set(QT_CONF_PREFIX "..") + endif() + + configure_file("${CMAKE_CURRENT_SOURCE_DIR}/qt.conf.in" + "${CMAKE_CURRENT_BINARY_DIR}/qt.conf" @ONLY) +endif() + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/__init__.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/__init__.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/generate_pyi.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/generate_pyi.py" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/support/deprecated.py" + "${CMAKE_CURRENT_BINARY_DIR}/support/deprecated.py" COPYONLY) + +# now compile all modules. +file(READ "${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h" pyside2_global_contents) + +foreach(shortname IN LISTS all_module_shortnames) + set(name "Qt${QT_MAJOR_VERSION}${shortname}") + set(_qt_module_name "${name}") + if ("${shortname}" STREQUAL "OpenGLFunctions") + set(_qt_module_name "Qt${QT_MAJOR_VERSION}Gui") + endif() + HAS_QT_MODULE(${_qt_module_name}_FOUND Qt${shortname}) + + # Create a module header consisting of pyside2_global.h and the module + # include. Note: The contents of pyside2_global.h must be copied instead of + # just #including it since shiboken will otherwise generate an + # #include for the the type entries originating from it + # (cf AbstractMetaBuilderPrivate::setInclude()). + set(module_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}_global.h") + set(module_header_content "") + set(pre_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}/Qt${shortname}_global.pre.h") + if(EXISTS "${pre_header}") + file(READ "${pre_header}" pre_header_content) + set(module_header_content "${pre_header_content}") + endif() + set(module_header_content "${module_header_content}\n${pyside2_global_contents}") + # AxContainer/AxServer from Active Qt do not have module headers + if(NOT "${shortname}" STREQUAL "AxContainer" AND NOT "${shortname}" STREQUAL "OpenGLFunctions") + set(module_header_content "${module_header_content}\n#include ") + endif() + set(post_header "${CMAKE_CURRENT_BINARY_DIR}/Qt${shortname}/Qt${shortname}_global.post.h") + if(EXISTS "${post_header}") + file(READ "${post_header}" post_header_content) + set(module_header_content "${module_header_content}\n${post_header_content}") + endif() + file(WRITE ${module_header} "${module_header_content}") +endforeach() + +# install +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/__init__.py" + DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside2_SUFFIX}") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_config.py" + DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside2_SUFFIX}") +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/_git_pyside_version.py" + DESTINATION "${PYTHON_SITE_PACKAGES}/${BINDING_NAME}${pyside2_SUFFIX}") +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/core_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/gui_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/widgets_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/datavisualization_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/opengl_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/openglfunctions_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/webkitwidgets_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/templates/xml_common.xml + DESTINATION share/PySide2${pyside_SUFFIX}/typesystems) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pyside2_global.h + DESTINATION include/${BINDING_NAME}${pyside2_SUFFIX}) diff --git a/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt new file mode 100644 index 0000000..970c910 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DAnimation/CMakeLists.txt @@ -0,0 +1,57 @@ +project(Qt3DAnimation) + +set(Qt3DAnimation_SRC +${Qt3DAnimation_GEN_DIR}/qt3danimation_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractanimation_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractanimationclip_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractchannelmapping_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractclipanimator_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qabstractclipblendnode_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qadditiveclipblend_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationaspect_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcallback_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationclip_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcliploader_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationcontroller_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qanimationgroup_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qblendedclipanimator_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qclipanimator_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qclock_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qkeyframe_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qkeyframeanimation_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qlerpclipblend_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qmorphinganimation_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qmorphtarget_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qskeletonmapping_wrapper.cpp +${Qt3DAnimation_GEN_DIR}/qt3danimation_qvertexblendanimation_wrapper.cpp +# module is always needed +${Qt3DAnimation_GEN_DIR}/qt3danimation_module_wrapper.cpp) + +set(Qt3DAnimation_include_dirs + ${Qt3DAnimation_SOURCE_DIR} + ${Qt3DAnimation_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIR} + ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DAnimation_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${Qt3DCore_GEN_DIR} + ${Qt3DRender_GEN_DIR} + ${Qt3DAnimation_GEN_DIR}) + +set(Qt3DAnimation_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DAnimation_LIBRARIES}) + +set(Qt3DAnimation_deps Qt3DRender) + +create_pyside_module(NAME Qt3DAnimation + INCLUDE_DIRS Qt3DAnimation_include_dirs + LIBRARIES Qt3DAnimation_libraries + DEPS Qt3DAnimation_deps + TYPESYSTEM_PATH Qt3DAnimation_SOURCE_DIR + SOURCES Qt3DAnimation_SRC + TYPESYSTEM_NAME ${Qt3DAnimation_BINARY_DIR}/typesystem_3danimation.xml) diff --git a/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml b/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml new file mode 100644 index 0000000..7f24234 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DAnimation/typesystem_3danimation.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt new file mode 100644 index 0000000..aa40c6e --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DCore/CMakeLists.txt @@ -0,0 +1,69 @@ +project(Qt3DCore) + +set(Qt3DCore_SRC +${Qt3DCore_GEN_DIR}/qt3dcore_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qabstractaspect_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qaspectengine_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qaspectjob_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qbackendnode_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qcomponent_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qcomponentaddedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qcomponentremovedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qdynamicpropertyupdatedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qentity_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qnode_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qnodecreatedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qnodedestroyedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qnodeid_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qnodeidtypepair_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertynodeaddedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertynoderemovedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyupdatedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyupdatedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyvalueaddedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyvalueaddedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyvalueremovedchange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qpropertyvalueremovedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qscenechange_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qstaticpropertyupdatedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qstaticpropertyvalueaddedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qstaticpropertyvalueremovedchangebase_wrapper.cpp +${Qt3DCore_GEN_DIR}/qt3dcore_qtransform_wrapper.cpp +# module is always needed +${Qt3DCore_GEN_DIR}/qt3dcore_module_wrapper.cpp) + +if (Qt${QT_MAJOR_VERSION}3DCore_VERSION VERSION_EQUAL 5.10.0 OR Qt${QT_MAJOR_VERSION}3DCore_VERSION VERSION_GREATER 5.10.0) + list(APPEND Qt3DCore_SRC + ${Qt3DCore_GEN_DIR}/qt3dcore_qarmature_wrapper.cpp + ${Qt3DCore_GEN_DIR}/qt3dcore_qjoint_wrapper.cpp + ${Qt3DCore_GEN_DIR}/qt3dcore_qabstractskeleton_wrapper.cpp + ${Qt3DCore_GEN_DIR}/qt3dcore_qnodecommand_wrapper.cpp + ${Qt3DCore_GEN_DIR}/qt3dcore_qskeleton_wrapper.cpp + ${Qt3DCore_GEN_DIR}/qt3dcore_qskeletonloader_wrapper.cpp) +endif() + +set(Qt3DCore_include_dirs + ${Qt3DCore_SOURCE_DIR} + ${Qt3DCore_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtNetwork_GEN_DIR}) + +set(Qt3DCore_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DCore_LIBRARIES}) + +set(Qt3DCore_deps QtGui QtNetwork) + +create_pyside_module(NAME Qt3DCore + INCLUDE_DIRS Qt3DCore_include_dirs + LIBRARIES Qt3DCore_libraries + DEPS Qt3DCore_deps + TYPESYSTEM_PATH Qt3DCore_SOURCE_DIR + SOURCES Qt3DCore_SRC + TYPESYSTEM_NAME ${Qt3DCore_BINARY_DIR}/typesystem_3dcore.xml) diff --git a/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml new file mode 100644 index 0000000..8696a12 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DCore/typesystem_3dcore.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt new file mode 100644 index 0000000..2e5c56d --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DExtras/CMakeLists.txt @@ -0,0 +1,78 @@ +project(Qt3DExtras) + +set(Qt3DExtras_SRC +${Qt3DExtras_GEN_DIR}/qt3dextras_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qconegeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qconemesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qcuboidgeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qcuboidmesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qcylindergeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qcylindermesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusemapmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusespecularmapmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qextrudedtextgeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qextrudedtextmesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qfirstpersoncameracontroller_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qforwardrenderer_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qgoochmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qmetalroughmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qmorphphongmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusemapmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusemapalphamaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qnormaldiffusespecularmapmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qorbitcameracontroller_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qpervertexcolormaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qphongmaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qphongalphamaterial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qplanegeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qplanemesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qskyboxentity_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qspheregeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qspheremesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qtext2dentity_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qtexturematerial_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qtorusgeometry_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qtorusmesh_wrapper.cpp +${Qt3DExtras_GEN_DIR}/qt3dextras_qt3dwindow_wrapper.cpp +# module is always needed +${Qt3DExtras_GEN_DIR}/qt3dextras_module_wrapper.cpp) + +if (Qt${QT_MAJOR_VERSION}3DExtras_VERSION VERSION_EQUAL 5.10.0 + OR Qt${QT_MAJOR_VERSION}3DExtras_VERSION VERSION_GREATER 5.10.0) + list(APPEND Qt3DExtras_SRC + ${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractcameracontroller_inputstate_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qabstractspritesheet_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qdiffusespecularmaterial_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qspritegrid_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qspritesheet_wrapper.cpp + ${Qt3DExtras_GEN_DIR}/qt3dextras_qspritesheetitem_wrapper.cpp) +endif() + +set(Qt3DExtras_include_dirs + ${Qt3DExtras_SOURCE_DIR} + ${Qt3DExtras_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DCore_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DRender_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}3DExtras_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${Qt3DCore_GEN_DIR} + ${Qt3DRender_GEN_DIR}) + +set(Qt3DExtras_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DExtras_LIBRARIES}) + +set(Qt3DExtras_deps Qt3DRender) + +create_pyside_module(NAME Qt3DExtras + INCLUDE_DIRS Qt3DExtras_include_dirs + LIBRARIES Qt3DExtras_libraries + DEPS Qt3DExtras_deps + TYPESYSTEM_PATH Qt3DExtras_SOURCE_DIR + SOURCES Qt3DExtras_SRC + TYPESYSTEM_NAME ${Qt3DExtras_BINARY_DIR}/typesystem_3dextras.xml) diff --git a/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml b/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml new file mode 100644 index 0000000..217aea0 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DExtras/typesystem_3dextras.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt new file mode 100644 index 0000000..8c87b43 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DInput/CMakeLists.txt @@ -0,0 +1,51 @@ +project(Qt3DInput) + +set(Qt3DInput_SRC +${Qt3DInput_GEN_DIR}/qt3dinput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qabstractactioninput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qabstractaxisinput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qabstractphysicaldevice_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qaction_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qactioninput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qanalogaxisinput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qaxis_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qaxisaccumulator_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qaxissetting_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qbuttonaxisinput_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qinputaspect_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qinputchord_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qinputsequence_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qinputsettings_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qkeyboardhandler_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qkeyevent_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qlogicaldevice_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qkeyboarddevice_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qmousedevice_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qmouseevent_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qwheelevent_wrapper.cpp +${Qt3DInput_GEN_DIR}/qt3dinput_qmousehandler_wrapper.cpp +# module is always needed +${Qt3DInput_GEN_DIR}/qt3dinput_module_wrapper.cpp) + +set(Qt3DInput_include_dirs + ${Qt3DInput_SOURCE_DIR} + ${Qt3DInput_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${Qt3DCore_GEN_DIR}) + +set(Qt3DInput_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DInput_LIBRARIES}) + +set(Qt3DInput_deps Qt3DCore) + +create_pyside_module(NAME Qt3DInput + INCLUDE_DIRS Qt3DInput_include_dirs + LIBRARIES Qt3DInput_libraries + DEPS Qt3DInput_deps + TYPESYSTEM_PATH Qt3DInput_SOURCE_DIR + SOURCES Qt3DInput_SRC + TYPESYSTEM_NAME ${Qt3DInput_BINARY_DIR}/typesystem_3dinput.xml) diff --git a/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml new file mode 100644 index 0000000..a74c3ab --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DInput/typesystem_3dinput.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt new file mode 100644 index 0000000..9197c35 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DLogic/CMakeLists.txt @@ -0,0 +1,32 @@ +project(Qt3DLogic) + +set(Qt3DLogic_SRC +${Qt3DLogic_GEN_DIR}/qt3dlogic_wrapper.cpp +${Qt3DLogic_GEN_DIR}/qt3dlogic_qframeaction_wrapper.cpp +${Qt3DLogic_GEN_DIR}/qt3dlogic_qlogicaspect_wrapper.cpp +# module is always needed +${Qt3DLogic_GEN_DIR}/qt3dlogic_module_wrapper.cpp) + +set(Qt3DLogic_include_dirs + ${Qt3DLogic_SOURCE_DIR} + ${Qt3DLogic_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${Qt3DCore_GEN_DIR}) + +set(Qt3DLogic_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DLogic_LIBRARIES}) + +set(Qt3DLogic_deps Qt3DCore) + +create_pyside_module(NAME Qt3DLogic + INCLUDE_DIRS Qt3DLogic_include_dirs + LIBRARIES Qt3DLogic_libraries + DEPS Qt3DLogic_deps + TYPESYSTEM_PATH Qt3DLogic_SOURCE_DIR + SOURCES Qt3DLogic_SRC + TYPESYSTEM_NAME ${Qt3DLogic_BINARY_DIR}/typesystem_3dlogic.xml) diff --git a/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml b/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml new file mode 100644 index 0000000..1583f9e --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DLogic/typesystem_3dlogic.xml @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt new file mode 100644 index 0000000..32f28e0 --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DRender/CMakeLists.txt @@ -0,0 +1,173 @@ +project(Qt3DRender) + +set(Qt3DRender_SRC +${Qt3DRender_GEN_DIR}/qt3drender_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_propertyreaderinterface_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qabstractfunctor_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qabstractlight_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qabstracttexture_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qabstracttextureimage_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qalphacoverage_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qalphatest_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qattribute_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qblendequation_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qblendequationarguments_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qbuffer_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qbuffercapture_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qbufferdatagenerator_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcamera_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcameralens_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcameraselector_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qclearbuffers_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qclipplane_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcolormask_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcomputecommand_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qcullface_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qdepthtest_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qdirectionallight_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qdispatchcompute_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qdithering_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qeffect_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qenvironmentlight_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qfilterkey_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qframegraphnode_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qframegraphnodecreatedchangebase_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qfrontface_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qfrustumculling_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qgeometry_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qgeometryfactory_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qgeometryrenderer_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qgraphicsapifilter_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qlayer_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qlayerfilter_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetail_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetailboundingsphere_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qlevelofdetailswitch_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qmaterial_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qmemorybarrier_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qmesh_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qmultisampleantialiasing_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qnodepthmask_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qnodraw_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qobjectpicker_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpaintedtextureimage_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qparameter_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpickevent_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpicktriangleevent_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpickingsettings_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpointlight_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpointsize_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qpolygonoffset_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrenderaspect_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendercapture_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendercapturereply_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrenderpass_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrenderpassfilter_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendersettings_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrenderstate_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrenderstateset_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendersurfaceselector_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendertarget_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendertargetoutput_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qrendertargetselector_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qsceneloader_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qscissortest_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qseamlesscubemap_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qshaderdata_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qshaderprogram_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qsortpolicy_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qspotlight_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qstencilmask_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qstenciloperation_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qstenciloperationarguments_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qstenciltest_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qstenciltestarguments_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtechnique_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtechniquefilter_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture1d_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture1darray_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture2d_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture2darray_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture2dmultisample_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture2dmultisamplearray_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexture3d_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturebuffer_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturecubemap_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturecubemaparray_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturedata_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturegenerator_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtextureimage_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtextureimagedata_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtextureimagedatagenerator_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtextureloader_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturerectangle_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qtexturewrapmode_wrapper.cpp +${Qt3DRender_GEN_DIR}/qt3drender_qviewport_wrapper.cpp +# module is always needed +${Qt3DRender_GEN_DIR}/qt3drender_module_wrapper.cpp) + +if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.10.0 + OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.10.0) + list(APPEND Qt3DRender_SRC + ${Qt3DRender_GEN_DIR}/qt3drender_qblitframebuffer_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qlinewidth_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qpicklineevent_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qpickpointevent_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qproximityfilter_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qshaderprogrambuilder_wrapper.cpp +) +endif() + +if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.11.0 + OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.11.0) + list(APPEND Qt3DRender_SRC + ${Qt3DRender_GEN_DIR}/qt3drender_qabstractraycaster_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qraycaster_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qraycasterhit_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qscreenraycaster_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.13.0 + OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.13.0) + list(APPEND Qt3DRender_SRC + ${Qt3DRender_GEN_DIR}/qt3drender_qsetfence_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qsharedgltexture_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qwaitfence_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.14.0 + OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.14.0) + list(APPEND Qt3DRender_SRC + ${Qt3DRender_GEN_DIR}/qt3drender_qnopicking_wrapper.cpp + ${Qt3DRender_GEN_DIR}/qt3drender_qshaderimage_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_EQUAL 5.15.0 + OR Qt${QT_MAJOR_VERSION}3DRender_VERSION VERSION_GREATER 5.15.0) + list(APPEND Qt3DRender_SRC + ${Qt3DRender_GEN_DIR}/qt3drender_qrendercapabilities_wrapper.cpp) +endif() + +set(Qt3DRender_include_dirs + ${Qt3DRender_SOURCE_DIR} + ${Qt3DRender_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${Qt3DCore_GEN_DIR}) + +set(Qt3DRender_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}3DRender_LIBRARIES}) + +set(Qt3DRender_deps Qt3DCore) + +create_pyside_module(NAME Qt3DRender + INCLUDE_DIRS Qt3DRender_include_dirs + LIBRARIES Qt3DRender_libraries + DEPS Qt3DRender_deps + TYPESYSTEM_PATH Qt3DRender_SOURCE_DIR + SOURCES Qt3DRender_SRC + TYPESYSTEM_NAME ${Qt3DRender_BINARY_DIR}/typesystem_3drender.xml) diff --git a/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml new file mode 100644 index 0000000..5176a4c --- /dev/null +++ b/sources/pyside2/PySide2/Qt3DRender/typesystem_3drender.xml @@ -0,0 +1,277 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt new file mode 100644 index 0000000..38e7644 --- /dev/null +++ b/sources/pyside2/PySide2/QtAxContainer/CMakeLists.txt @@ -0,0 +1,41 @@ +project(QtAxContainer) + +set(QtAxContainer_SRC +${QtAxContainer_GEN_DIR}/qaxbase_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxobject_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxscript_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxscriptengine_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxscriptmanager_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxselect_wrapper.cpp +${QtAxContainer_GEN_DIR}/qaxwidget_wrapper.cpp +# module is always needed +${QtAxContainer_GEN_DIR}/qtaxcontainer_module_wrapper.cpp) + +configure_file("${QtAxContainer_SOURCE_DIR}/QtAxContainer_global.post.h.in" + "${QtAxContainer_BINARY_DIR}/QtAxContainer_global.post.h" @ONLY) + +set(QtAxContainer_include_dirs + ${QtAxContainer_SOURCE_DIR} + ${QtAxContainer_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR}) + +set(QtAxContainer_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}AxContainer_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}AxBase_LIBRARIES}) + +set(QtAxContainer_deps QtWidgets) + +create_pyside_module(NAME QtAxContainer + INCLUDE_DIRS QtAxContainer_include_dirs + LIBRARIES QtAxContainer_libraries + DEPS QtAxContainer_deps + TYPESYSTEM_PATH QtAxContainer_SOURCE_DIR + SOURCES QtAxContainer_SRC + TYPESYSTEM_NAME ${QtAxContainer_BINARY_DIR}/typesystem_axcontainer.xml) diff --git a/sources/pyside2/PySide2/QtAxContainer/QtAxContainer_global.post.h.in b/sources/pyside2/PySide2/QtAxContainer/QtAxContainer_global.post.h.in new file mode 100644 index 0000000..22e1b01 --- /dev/null +++ b/sources/pyside2/PySide2/QtAxContainer/QtAxContainer_global.post.h.in @@ -0,0 +1,5 @@ +#include +#include +#include +#include +#include diff --git a/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml b/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml new file mode 100644 index 0000000..e6c8def --- /dev/null +++ b/sources/pyside2/PySide2/QtAxContainer/typesystem_axcontainer.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtCharts/CMakeLists.txt b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt new file mode 100644 index 0000000..f73a28b --- /dev/null +++ b/sources/pyside2/PySide2/QtCharts/CMakeLists.txt @@ -0,0 +1,85 @@ +project(QtCharts) + +set(QtCharts_SRC +${QtCharts_GEN_DIR}/qtcharts_qabstractaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qabstractbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qabstractseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qarealegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qareaseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qbarcategoryaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qbarlegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qbarmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qbarset_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qboxplotlegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qboxplotmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qboxplotseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qboxset_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qcandlesticklegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qcandlestickmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qcandlestickseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qcandlestickset_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qcategoryaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qchart_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qchartview_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qdatetimeaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhbarmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhboxplotmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhcandlestickmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhorizontalbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhorizontalpercentbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhorizontalstackedbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhpiemodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qhxymodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qlegend_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qlegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qlineseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qlogvalueaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpercentbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpielegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpiemodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpieseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpieslice_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qpolarchart_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qscatterseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qsplineseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qstackedbarseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvalueaxis_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvbarmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvboxplotmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvcandlestickmodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvpiemodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qvxymodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qxylegendmarker_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qxymodelmapper_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_qxyseries_wrapper.cpp +${QtCharts_GEN_DIR}/qtcharts_wrapper.cpp +# module is always needed +${QtCharts_GEN_DIR}/qtcharts_module_wrapper.cpp +) + +set(QtCharts_include_dirs ${QtCharts_SOURCE_DIR} + ${QtCharts_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Charts_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR}) + +set(QtCharts_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Charts_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}) + +set(QtCharts_deps QtCore QtGui QtWidgets) + +create_pyside_module(NAME QtCharts + INCLUDE_DIRS QtCharts_include_dirs + LIBRARIES QtCharts_libraries + DEPS QtCharts_deps + TYPESYSTEM_PATH QtCharts_SOURCE_DIR + SOURCES QtCharts_SRC) diff --git a/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml new file mode 100644 index 0000000..8ab7347 --- /dev/null +++ b/sources/pyside2/PySide2/QtCharts/typesystem_charts.xml @@ -0,0 +1,272 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt new file mode 100644 index 0000000..a6e8cd2 --- /dev/null +++ b/sources/pyside2/PySide2/QtConcurrent/CMakeLists.txt @@ -0,0 +1,31 @@ +project(QtConcurrent) + +set(QtConcurrent_SRC +${QtConcurrent_GEN_DIR}/qtconcurrent_wrapper.cpp +${QtConcurrent_GEN_DIR}/qfuturevoid_wrapper.cpp +${QtConcurrent_GEN_DIR}/qfutureqstring_wrapper.cpp +${QtConcurrent_GEN_DIR}/qfuturewatchervoid_wrapper.cpp +${QtConcurrent_GEN_DIR}/qfuturewatcherqstring_wrapper.cpp +# module is always needed +${QtConcurrent_GEN_DIR}/qtconcurrent_module_wrapper.cpp +) + +set(QtConcurrent_include_dirs ${QtConcurrent_SOURCE_DIR} + ${QtConcurrent_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Concurrent_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtConcurrent_libraries pyside2 + ${QtConcurrent_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtConcurrent_deps QtCore) + +create_pyside_module(NAME QtConcurrent + INCLUDE_DIRS QtConcurrent_include_dirs + LIBRARIES QtConcurrent_libraries + DEPS QtConcurrent_deps + TYPESYSTEM_PATH QtConcurrent_SOURCE_DIR + SOURCES QtConcurrent_SRC) diff --git a/sources/pyside2/PySide2/QtConcurrent/curr_errors.txt b/sources/pyside2/PySide2/QtConcurrent/curr_errors.txt new file mode 100644 index 0000000..d8405c7 --- /dev/null +++ b/sources/pyside2/PySide2/QtConcurrent/curr_errors.txt @@ -0,0 +1,21 @@ +Generating class model... [OK] +Generating enum model... [OK] +Generating namespace model... [WARNING] + enum 'QtConcurrent::ThreadFunctionResult' does not have a type entry or is not an enum + enum 'QtConcurrent::ReduceQueueThrottleLimit' does not have a type entry or is not an enum + + +Resolving typedefs... [OK] +Fixing class inheritance... [OK] +Detecting inconsistencies in class model... [OK] +[OK] + +Done, 2 warnings (506 known issues) +Scanning dependencies of target QtConcurrent +[ 21%] Building CXX object PySide/QtConcurrent/CMakeFiles/QtConcurrent.dir/PySide/QtConcurrent/qtconcurrent_module_wrapper.cpp.o +In file included from /Users/tismer/src/pyside-setup2/pyside_build/py3.4-qt5.4.2-64bit-debug/pyside/PySide/QtConcurrent/PySide/QtConcurrent/qtconcurrent_module_wrapper.cpp:30: +/Users/tismer/src/pyside-setup2/pyside_build/py3.4-qt5.4.2-64bit-debug/pyside/PySide/QtConcurrent/PySide/QtConcurrent/pyside_qtconcurrent_python.h:44:10: fatal error: + 'qtconcurrentexception.h' file not found +#include + ^ +1 error generated. diff --git a/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml new file mode 100644 index 0000000..ea34150 --- /dev/null +++ b/sources/pyside2/PySide2/QtConcurrent/typesystem_concurrent.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtCore/CMakeLists.txt b/sources/pyside2/PySide2/QtCore/CMakeLists.txt new file mode 100644 index 0000000..16a88d2 --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/CMakeLists.txt @@ -0,0 +1,233 @@ +project(QtCore) + +set(QtCore_gluecode "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp") + +if(ENABLE_WIN) + set(SPECIFIC_OS_FILES + ${QtCore_GEN_DIR}/qwineventnotifier_wrapper.cpp + ) +else() + set(SPECIFIC_OS_FILES "") +endif() + +set(QtCore_SRC +${QtCore_GEN_DIR}/qabstractanimation_wrapper.cpp +${QtCore_GEN_DIR}/qabstracteventdispatcher_timerinfo_wrapper.cpp +${QtCore_GEN_DIR}/qabstracteventdispatcher_wrapper.cpp +${QtCore_GEN_DIR}/qabstractitemmodel_wrapper.cpp +${QtCore_GEN_DIR}/qabstractlistmodel_wrapper.cpp +${QtCore_GEN_DIR}/qabstractnativeeventfilter_wrapper.cpp +${QtCore_GEN_DIR}/qabstractproxymodel_wrapper.cpp +${QtCore_GEN_DIR}/qabstractstate_wrapper.cpp +${QtCore_GEN_DIR}/qabstracttablemodel_wrapper.cpp +${QtCore_GEN_DIR}/qabstracttransition_wrapper.cpp +${QtCore_GEN_DIR}/qanimationgroup_wrapper.cpp +${QtCore_GEN_DIR}/qbasicmutex_wrapper.cpp +${QtCore_GEN_DIR}/qbasictimer_wrapper.cpp +${QtCore_GEN_DIR}/qbitarray_wrapper.cpp +${QtCore_GEN_DIR}/qbuffer_wrapper.cpp +${QtCore_GEN_DIR}/qbytearray_wrapper.cpp +${QtCore_GEN_DIR}/qbytearraymatcher_wrapper.cpp +${QtCore_GEN_DIR}/qchildevent_wrapper.cpp +${QtCore_GEN_DIR}/qcborarray_wrapper.cpp +${QtCore_GEN_DIR}/qcborerror_wrapper.cpp +${QtCore_GEN_DIR}/qcbormap_wrapper.cpp +${QtCore_GEN_DIR}/qcborparsererror_wrapper.cpp +${QtCore_GEN_DIR}/qcborstreamreader_wrapper.cpp +${QtCore_GEN_DIR}/qcborstringresultstring_wrapper.cpp +${QtCore_GEN_DIR}/qcborstringresultbytearray_wrapper.cpp +${QtCore_GEN_DIR}/qcborstreamwriter_wrapper.cpp +${QtCore_GEN_DIR}/qcborvalue_wrapper.cpp +${QtCore_GEN_DIR}/qcollator_wrapper.cpp +${QtCore_GEN_DIR}/qcollatorsortkey_wrapper.cpp +${QtCore_GEN_DIR}/qcommandlineoption_wrapper.cpp +${QtCore_GEN_DIR}/qcommandlineparser_wrapper.cpp +${QtCore_GEN_DIR}/qcoreapplication_wrapper.cpp +${QtCore_GEN_DIR}/qcryptographichash_wrapper.cpp +${QtCore_GEN_DIR}/qdatastream_wrapper.cpp +${QtCore_GEN_DIR}/qdate_wrapper.cpp +${QtCore_GEN_DIR}/qdatetime_wrapper.cpp +${QtCore_GEN_DIR}/qdeadlinetimer_wrapper.cpp +${QtCore_GEN_DIR}/qdir_wrapper.cpp +${QtCore_GEN_DIR}/qdiriterator_wrapper.cpp +${QtCore_GEN_DIR}/qdynamicpropertychangeevent_wrapper.cpp +${QtCore_GEN_DIR}/qeasingcurve_wrapper.cpp +${QtCore_GEN_DIR}/qelapsedtimer_wrapper.cpp +${QtCore_GEN_DIR}/qevent_wrapper.cpp +${QtCore_GEN_DIR}/qeventloop_wrapper.cpp +${QtCore_GEN_DIR}/qeventtransition_wrapper.cpp +${QtCore_GEN_DIR}/qfactoryinterface_wrapper.cpp +${QtCore_GEN_DIR}/qfile_wrapper.cpp +${QtCore_GEN_DIR}/qfileselector_wrapper.cpp +${QtCore_GEN_DIR}/qfiledevice_wrapper.cpp +${QtCore_GEN_DIR}/qfileinfo_wrapper.cpp +${QtCore_GEN_DIR}/qfilesystemwatcher_wrapper.cpp +${QtCore_GEN_DIR}/qfinalstate_wrapper.cpp +${QtCore_GEN_DIR}/qfutureinterfacebase_wrapper.cpp +${QtCore_GEN_DIR}/qgenericargument_wrapper.cpp +${QtCore_GEN_DIR}/qgenericreturnargument_wrapper.cpp +${QtCore_GEN_DIR}/qhistorystate_wrapper.cpp +${QtCore_GEN_DIR}/qidentityproxymodel_wrapper.cpp +${QtCore_GEN_DIR}/qiodevice_wrapper.cpp +${QtCore_GEN_DIR}/qjsonarray_wrapper.cpp +${QtCore_GEN_DIR}/qjsondocument_wrapper.cpp +${QtCore_GEN_DIR}/qjsonparseerror_wrapper.cpp +${QtCore_GEN_DIR}/qjsonvalue_wrapper.cpp +${QtCore_GEN_DIR}/qitemselection_wrapper.cpp +${QtCore_GEN_DIR}/qitemselectionmodel_wrapper.cpp +${QtCore_GEN_DIR}/qitemselectionrange_wrapper.cpp +${QtCore_GEN_DIR}/qlibraryinfo_wrapper.cpp +${QtCore_GEN_DIR}/qline_wrapper.cpp +${QtCore_GEN_DIR}/qlinef_wrapper.cpp +${QtCore_GEN_DIR}/qlocale_wrapper.cpp +${QtCore_GEN_DIR}/qlockfile_wrapper.cpp +${QtCore_GEN_DIR}/qmargins_wrapper.cpp +${QtCore_GEN_DIR}/qmarginsf_wrapper.cpp +${QtCore_GEN_DIR}/qmessageauthenticationcode_wrapper.cpp +${QtCore_GEN_DIR}/qmessagelogcontext_wrapper.cpp +${QtCore_GEN_DIR}/qmetaclassinfo_wrapper.cpp +${QtCore_GEN_DIR}/qmetaenum_wrapper.cpp +${QtCore_GEN_DIR}/qmetamethod_wrapper.cpp +${QtCore_GEN_DIR}/qmetaobject_connection_wrapper.cpp +${QtCore_GEN_DIR}/qmetaobject_wrapper.cpp +${QtCore_GEN_DIR}/qmetaproperty_wrapper.cpp +${QtCore_GEN_DIR}/qmimedata_wrapper.cpp +${QtCore_GEN_DIR}/qmimedatabase_wrapper.cpp +${QtCore_GEN_DIR}/qmimetype_wrapper.cpp +${QtCore_GEN_DIR}/qmodelindex_wrapper.cpp +${QtCore_GEN_DIR}/qmutex_wrapper.cpp +${QtCore_GEN_DIR}/qmutexlocker_wrapper.cpp +${QtCore_GEN_DIR}/qobject_wrapper.cpp +${QtCore_GEN_DIR}/qoperatingsystemversion_wrapper.cpp +${QtCore_GEN_DIR}/qparallelanimationgroup_wrapper.cpp +${QtCore_GEN_DIR}/qpauseanimation_wrapper.cpp +${QtCore_GEN_DIR}/qpersistentmodelindex_wrapper.cpp +${QtCore_GEN_DIR}/qpluginloader_wrapper.cpp +${QtCore_GEN_DIR}/qpoint_wrapper.cpp +${QtCore_GEN_DIR}/qpointf_wrapper.cpp +${QtCore_GEN_DIR}/qprocess_wrapper.cpp +${QtCore_GEN_DIR}/qprocessenvironment_wrapper.cpp +${QtCore_GEN_DIR}/qpropertyanimation_wrapper.cpp +${QtCore_GEN_DIR}/qrandomgenerator_wrapper.cpp +${QtCore_GEN_DIR}/qrandomgenerator64_wrapper.cpp +${QtCore_GEN_DIR}/qreadlocker_wrapper.cpp +${QtCore_GEN_DIR}/qreadwritelock_wrapper.cpp +${QtCore_GEN_DIR}/qrect_wrapper.cpp +${QtCore_GEN_DIR}/qrectf_wrapper.cpp +${QtCore_GEN_DIR}/qregexp_wrapper.cpp +${QtCore_GEN_DIR}/qregularexpression_wrapper.cpp +${QtCore_GEN_DIR}/qregularexpressionmatch_wrapper.cpp +${QtCore_GEN_DIR}/qregularexpressionmatchiterator_wrapper.cpp +${QtCore_GEN_DIR}/qresource_wrapper.cpp +${QtCore_GEN_DIR}/qrunnable_wrapper.cpp +${QtCore_GEN_DIR}/qsavefile_wrapper.cpp +${QtCore_GEN_DIR}/qsemaphore_wrapper.cpp +${QtCore_GEN_DIR}/qsemaphorereleaser_wrapper.cpp +${QtCore_GEN_DIR}/qsequentialanimationgroup_wrapper.cpp +${QtCore_GEN_DIR}/qsettings_wrapper.cpp +${QtCore_GEN_DIR}/qsignalblocker_wrapper.cpp +${QtCore_GEN_DIR}/qsignalmapper_wrapper.cpp +${QtCore_GEN_DIR}/qsignaltransition_wrapper.cpp +${QtCore_GEN_DIR}/qsize_wrapper.cpp +${QtCore_GEN_DIR}/qsizef_wrapper.cpp +${QtCore_GEN_DIR}/qsocketdescriptor_wrapper.cpp +${QtCore_GEN_DIR}/qsocketnotifier_wrapper.cpp +${QtCore_GEN_DIR}/qsortfilterproxymodel_wrapper.cpp +${QtCore_GEN_DIR}/qstate_wrapper.cpp +${QtCore_GEN_DIR}/qstandardpaths_wrapper.cpp +${QtCore_GEN_DIR}/qstatemachine_signalevent_wrapper.cpp +${QtCore_GEN_DIR}/qstatemachine_wrappedevent_wrapper.cpp +${QtCore_GEN_DIR}/qstatemachine_wrapper.cpp +${QtCore_GEN_DIR}/qstorageinfo_wrapper.cpp +${QtCore_GEN_DIR}/qstringlistmodel_wrapper.cpp +${QtCore_GEN_DIR}/qsysinfo_wrapper.cpp +${QtCore_GEN_DIR}/qsystemsemaphore_wrapper.cpp +${QtCore_GEN_DIR}/qt_wrapper.cpp +${QtCore_GEN_DIR}/qtemporarydir_wrapper.cpp +${QtCore_GEN_DIR}/qtemporaryfile_wrapper.cpp +${QtCore_GEN_DIR}/qtextboundaryfinder_wrapper.cpp +${QtCore_GEN_DIR}/qtextcodec_converterstate_wrapper.cpp +${QtCore_GEN_DIR}/qtextcodec_wrapper.cpp +${QtCore_GEN_DIR}/qtextdecoder_wrapper.cpp +${QtCore_GEN_DIR}/qtextencoder_wrapper.cpp +${QtCore_GEN_DIR}/qtextstream_wrapper.cpp +${QtCore_GEN_DIR}/qtextstreammanipulator_wrapper.cpp +${QtCore_GEN_DIR}/qthread_wrapper.cpp +${QtCore_GEN_DIR}/qthreadpool_wrapper.cpp +${QtCore_GEN_DIR}/qtime_wrapper.cpp +${QtCore_GEN_DIR}/qtimeline_wrapper.cpp +${QtCore_GEN_DIR}/qtimer_wrapper.cpp +${QtCore_GEN_DIR}/qtimerevent_wrapper.cpp +${QtCore_GEN_DIR}/qtimezone_wrapper.cpp +${QtCore_GEN_DIR}/qtimezone_offsetdata_wrapper.cpp +${QtCore_GEN_DIR}/qtranslator_wrapper.cpp +${QtCore_GEN_DIR}/qurl_wrapper.cpp +${QtCore_GEN_DIR}/qurlquery_wrapper.cpp +${QtCore_GEN_DIR}/quuid_wrapper.cpp +${QtCore_GEN_DIR}/qvariantanimation_wrapper.cpp +${QtCore_GEN_DIR}/qversionnumber_wrapper.cpp +${QtCore_GEN_DIR}/qwaitcondition_wrapper.cpp +${QtCore_GEN_DIR}/qwritelocker_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamattribute_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamattributes_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamentitydeclaration_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamentityresolver_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamnamespacedeclaration_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamnotationdeclaration_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamreader_wrapper.cpp +${QtCore_GEN_DIR}/qxmlstreamwriter_wrapper.cpp + + +${SPECIFIC_OS_FILES} +# module is always needed +${QtCore_GEN_DIR}/qtcore_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.13.0 + OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.13.0) + list(APPEND QtCore_SRC + ${QtCore_GEN_DIR}/qconcatenatetablesproxymodel_wrapper.cpp + ${QtCore_GEN_DIR}/qtransposeproxymodel_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.14.0 + OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.14.0) + list(APPEND QtCore_SRC + ${QtCore_GEN_DIR}/qcalendar_wrapper.cpp + ${QtCore_GEN_DIR}/qcalendar_yearmonthday_wrapper.cpp + ${QtCore_GEN_DIR}/qrecursivemutex_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_EQUAL 5.15.0 + OR Qt${QT_MAJOR_VERSION}Core_VERSION VERSION_GREATER 5.15.0) + list(APPEND QtCore_SRC + ${QtCore_GEN_DIR}/qbytearray_frombase64result_wrapper.cpp) +endif() + +set(QtCore_glue_sources + "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.cpp" + "${QtCore_SOURCE_DIR}/glue/qeasingcurve_glue.h" +) + +configure_file("${QtCore_SOURCE_DIR}/typesystem_core.xml.in" + "${QtCore_BINARY_DIR}/typesystem_core.xml" @ONLY) + +set(QtCore_include_dirs ${QtCore_SOURCE_DIR} + ${QtCore_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ) +set(QtCore_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) + +create_pyside_module(NAME QtCore + INCLUDE_DIRS QtCore_include_dirs + LIBRARIES QtCore_libraries + TYPESYSTEM_PATH QtCore_SOURCE_DIR + SOURCES QtCore_SRC + STATIC_SOURCES QtCore_gluecode + TYPESYSTEM_NAME ${QtCore_BINARY_DIR}/typesystem_core.xml + GLUE_SOURCES QtCore_glue_sources + ) + diff --git a/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp new file mode 100644 index 0000000..5521919 --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.cpp @@ -0,0 +1,158 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include + +#include "glue/qeasingcurve_glue.h" + +#define MAX_CUSTOM_FUNCTIONS 10 + +static void deleteData(void *data); + +struct CustomFunctionsData +{ + static CustomFunctionsData m_list[MAX_CUSTOM_FUNCTIONS]; + + PySideEasingCurveFunctor *m_obj; + QEasingCurve::EasingFunction m_func; +}; + +CustomFunctionsData CustomFunctionsData::m_list[MAX_CUSTOM_FUNCTIONS]; + +template +struct CustomFunctions +{ + static void init() + { + CustomFunctionsData data; + data.m_obj = 0; + data.m_func = &CustomFunctions::callback; + CustomFunctionsData::m_list[N] = data; + + CustomFunctions::init(); + } + + static qreal callback(qreal v) + { + return (*CustomFunctionsData::m_list[N].m_obj)(v); + } +}; + +template<> +struct CustomFunctions<0> +{ + static void init() + { + CustomFunctionsData data; + data.m_obj = 0; + data.m_func = &CustomFunctions<0>::callback; + CustomFunctionsData::m_list[0] = data; + } + + static qreal callback(qreal v) + { + return (*CustomFunctionsData::m_list[0].m_obj)(v); + } +}; + +void deleteData(void *data) +{ + delete (PySideEasingCurveFunctor *)(data); +} + +void PySideEasingCurveFunctor::init() +{ + CustomFunctions::init(); +} + +QEasingCurve::EasingFunction PySideEasingCurveFunctor::createCustomFuntion(PyObject *parent, PyObject *pyFunc) +{ + for(int i=0; i < MAX_CUSTOM_FUNCTIONS; i++) { + CustomFunctionsData &data = CustomFunctionsData::m_list[i]; + if (data.m_obj == 0) { + data.m_obj = new PySideEasingCurveFunctor(i, parent, pyFunc); + return data.m_func; + } + } + //PyErr_Format(PyExc_RuntimeError, "PySide only supports %d custom functions simultaneously.", MAX_CUSTOM_FUNCTIONS); + return 0; +} + +PySideEasingCurveFunctor::~PySideEasingCurveFunctor() +{ + + CustomFunctionsData::m_list[m_index].m_obj = 0; + PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), Py_None); +} + +qreal PySideEasingCurveFunctor::operator()(qreal progress) +{ + Shiboken::GilState state; + PyObject *args = Py_BuildValue("(f)", progress); + PyObject *result = PyObject_CallObject(m_func, args); + qreal cppResult = 0.0; + if (result) { + Shiboken::Conversions::pythonToCppCopy(Shiboken::Conversions::PrimitiveTypeConverter(), result, &cppResult); + Py_DECREF(result); + } + Py_DECREF(args); + return cppResult; +} + +PyObject *PySideEasingCurveFunctor::callable() +{ + Py_INCREF(m_func); + return m_func; +} + +PyObject *PySideEasingCurveFunctor::callable(PyObject *parent) +{ + return PyObject_GetAttr(parent, Shiboken::PyMagicName::ecf()); +} + +PySideEasingCurveFunctor::PySideEasingCurveFunctor(int index, PyObject *parent, PyObject *pyFunc) + : m_parent(parent), m_func(pyFunc), m_index(index) +{ + PyObject_SetAttr(m_parent, Shiboken::PyMagicName::ecf(), m_func); + PySide::WeakRef::create(m_parent, deleteData, this); +} + diff --git a/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.h b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.h new file mode 100644 index 0000000..f6c80fa --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/glue/qeasingcurve_glue.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __QEASINGCURVE_GLUE__ +#define __QEASINGCURVE_GLUE__ + +#include +#include + +class PySideEasingCurveFunctor +{ + public: + static void init(); + static QEasingCurve::EasingFunction createCustomFuntion(PyObject *parent, PyObject *pyFunc); + + qreal operator()(qreal progress); + + PyObject *callable(); //Return New reference + static PyObject *callable(PyObject *parent); //Return New reference + + ~PySideEasingCurveFunctor(); + private: + PyObject *m_parent; + PyObject *m_func; + int m_index; + + PySideEasingCurveFunctor(int index, PyObject *parent, PyObject *pyFunc); +}; + +#endif diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core.xml.in b/sources/pyside2/PySide2/QtCore/typesystem_core.xml.in new file mode 100644 index 0000000..8be5bba --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/typesystem_core.xml.in @@ -0,0 +1,45 @@ + + + + + + diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml new file mode 100644 index 0000000..205e4ef --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_common.xml @@ -0,0 +1,3394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Returns a read only buffer object pointing to the segment of data that this resource represents. If the resource is compressed the data returns is compressed and qUncompress() must be used to access the data. If the resource is a directory None is returned. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Creates a model index for the given row and column with the internal pointer ptr. + When using a QSortFilterProxyModel, its indexes have their own internal pointer. + It is not advisable to access this internal pointer outside of the model. + Use the data() function instead. + This function provides a consistent interface that model subclasses must use to create model indexes. + + .. warning:: Because of some Qt/Python itegration rules, the ptr argument do not get the reference + incremented during the QModelIndex life time. So it is necessary to keep the object used + on ptr argument alive during the whole process. + Do not destroy the object if you are not sure about that. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To find the child of a certain QObject, the first argument of this function should be the child's type, and the second the name of the child: + + :: + + ... + parent = QWidget() + ... + # The first argument must be the child type + child1 = parent.findChild(QPushButton, "child_button") + child2 = parent.findChild(QWidget, "child_widget") + + + + + + + + + + + + + Like the method *findChild*, the first parameter should be the child's type. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Replaces every occurrence of the regular expression in *sourceString* with *after*. + Returns a new Python string with the modified contents. For example: + + :: + + s = "Banana" + re = QRegExp("a[mn]") + s = re.replace(s, "ox") + # s == "Boxoxa" + + + For regular expressions containing capturing parentheses, occurrences of \1, \2, ..., in *after* + are replaced with rx.cap(1), cap(2), ... + + :: + + t = "A <i>bon mot</i>." + re = QRegExp("<i>([^<]*)</i>") + t = re.replace(t, "\\emph{\\1}") + # t == "A \\emph{bon mot}." + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +.. class:: QCoreApplication(args) + + Constructs a Qt kernel application. Kernel applications are applications + without a graphical user interface. These type of applications are used + at the console or as server processes. + + The *args* argument is processed by the application, and made available + in a more convenient form by the :meth:`~QCoreApplication.arguments()` + method. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <code>machine = QStateMachine() + +s1 = QState() +s11 = QState(s1) +s12 = QState(s1) + +s1h = QHistoryState(s1) +s1h.setDefaultState(s11) + +machine.addState(s1) + +s2 = QState() +machine.addState(s2) + +button = QPushButton() +# Clicking the button will cause the state machine to enter the child state +# that s1 was in the last time s1 was exited, or the history state's default +# state if s1 has never been entered. +s1.addTransition(button.clicked, s1h)</code> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml new file mode 100644 index 0000000..6e1a555 --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_mac.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml new file mode 100644 index 0000000..8e3fa6f --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_win.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + #ifdef IS_PY3K + return PyCapsule_New(%in, 0, 0); + #else + return PyCObject_FromVoidPtr(%in, 0); + #endif + + + + %out = 0; + + + #ifdef IS_PY3K + %out = (%OUTTYPE)PyCapsule_GetPointer(%in, 0); + #else + %out = (%OUTTYPE)PyCObject_AsVoidPtr(%in); + #endif + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml new file mode 100644 index 0000000..88cbf76 --- /dev/null +++ b/sources/pyside2/PySide2/QtCore/typesystem_core_x11.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt new file mode 100644 index 0000000..46868fe --- /dev/null +++ b/sources/pyside2/PySide2/QtDataVisualization/CMakeLists.txt @@ -0,0 +1,65 @@ +project(QtDataVisualization) + +set(QtDataVisualization_SRC +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qabstract3daxis_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qcategory3daxis_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qlogvalue3daxisformatter_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qvalue3daxis_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qvalue3daxisformatter_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qabstract3dseries_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qabstractdataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qbar3dseries_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qbardataitem_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qbardataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qcustom3ditem_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qcustom3dlabel_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qcustom3dvolume_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qheightmapsurfacedataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qitemmodelbardataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qitemmodelscatterdataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qitemmodelsurfacedataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qscatter3dseries_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qscatterdataitem_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qscatterdataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qsurface3dseries_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qsurfacedataitem_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qsurfacedataproxy_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dbars_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dcamera_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dlight_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dobject_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dscatter_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dscene_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dsurface_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qabstract3dgraph_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dinputhandler_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qabstract3dinputhandler_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_qtouch3dinputhandler_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_q3dtheme_wrapper.cpp +${QtDataVisualization_GEN_DIR}/qtdatavisualization_wrapper.cpp +# module is always needed +${QtDataVisualization_GEN_DIR}/qtdatavisualization_module_wrapper.cpp +) + +set(QtDataVisualization_include_dirs ${QtDataVisualization_SOURCE_DIR} + ${QtDataVisualization_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}DataVisualization_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR}) + +set(QtDataVisualization_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}DataVisualization_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}) + +set(QtDataVisualization_deps QtCore QtGui) + +create_pyside_module(NAME QtDataVisualization + INCLUDE_DIRS QtDataVisualization_include_dirs + LIBRARIES QtDataVisualization_libraries + DEPS QtDataVisualization_deps + TYPESYSTEM_PATH QtDataVisualization_SOURCE_DIR + SOURCES QtDataVisualization_SRC) diff --git a/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml new file mode 100644 index 0000000..f10aeea --- /dev/null +++ b/sources/pyside2/PySide2/QtDataVisualization/typesystem_datavisualization.xml @@ -0,0 +1,422 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtGui/CMakeLists.txt b/sources/pyside2/PySide2/QtGui/CMakeLists.txt new file mode 100644 index 0000000..c4a38a1 --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/CMakeLists.txt @@ -0,0 +1,268 @@ +project(QtGui) + +if (${QT_MAJOR_VERSION} GREATER_EQUAL 6) + qt6_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h") +else() + qt5_wrap_cpp(QPYTEXTOBJECT_MOC "${pyside2_SOURCE_DIR}/qpytextobject.h") +endif() + +set(QtGui_DROPPED_ENTRIES) + +get_property(QtGui_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui + PROPERTY QT_ENABLED_PUBLIC_FEATURES) + +set(QtGui_SRC +${QtGui_GEN_DIR}/qabstractopenglfunctions_wrapper.cpp +${QtGui_GEN_DIR}/qabstracttextdocumentlayout_paintcontext_wrapper.cpp +${QtGui_GEN_DIR}/qabstracttextdocumentlayout_selection_wrapper.cpp +${QtGui_GEN_DIR}/qabstracttextdocumentlayout_wrapper.cpp +${QtGui_GEN_DIR}/qaccessible_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleeditabletextinterface_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleobject_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblestatechangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletablecellinterface_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletablemodelchangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextcursorevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextinsertevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextinterface_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextremoveevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextselectionevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibletextupdateevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblevaluechangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qaccessiblevalueinterface_wrapper.cpp +${QtGui_GEN_DIR}/qactionevent_wrapper.cpp +${QtGui_GEN_DIR}/qbackingstore_wrapper.cpp +${QtGui_GEN_DIR}/qbitmap_wrapper.cpp +${QtGui_GEN_DIR}/qbrush_wrapper.cpp +${QtGui_GEN_DIR}/qclipboard_wrapper.cpp +${QtGui_GEN_DIR}/qcloseevent_wrapper.cpp +${QtGui_GEN_DIR}/qcolor_wrapper.cpp +${QtGui_GEN_DIR}/qconicalgradient_wrapper.cpp +${QtGui_GEN_DIR}/qcontextmenuevent_wrapper.cpp +${QtGui_GEN_DIR}/qcursor_wrapper.cpp +${QtGui_GEN_DIR}/qdesktopservices_wrapper.cpp +${QtGui_GEN_DIR}/qdoublevalidator_wrapper.cpp +${QtGui_GEN_DIR}/qdrag_wrapper.cpp +${QtGui_GEN_DIR}/qdragenterevent_wrapper.cpp +${QtGui_GEN_DIR}/qdragleaveevent_wrapper.cpp +${QtGui_GEN_DIR}/qdragmoveevent_wrapper.cpp +${QtGui_GEN_DIR}/qdropevent_wrapper.cpp +${QtGui_GEN_DIR}/qenterevent_wrapper.cpp +${QtGui_GEN_DIR}/qexposeevent_wrapper.cpp +${QtGui_GEN_DIR}/qfileopenevent_wrapper.cpp +${QtGui_GEN_DIR}/qfocusevent_wrapper.cpp +${QtGui_GEN_DIR}/qfont_wrapper.cpp +${QtGui_GEN_DIR}/qfontdatabase_wrapper.cpp +${QtGui_GEN_DIR}/qfontinfo_wrapper.cpp +${QtGui_GEN_DIR}/qfontmetrics_wrapper.cpp +${QtGui_GEN_DIR}/qfontmetricsf_wrapper.cpp +${QtGui_GEN_DIR}/qgradient_wrapper.cpp +${QtGui_GEN_DIR}/qguiapplication_wrapper.cpp +${QtGui_GEN_DIR}/qhelpevent_wrapper.cpp +${QtGui_GEN_DIR}/qhideevent_wrapper.cpp +${QtGui_GEN_DIR}/qhoverevent_wrapper.cpp +${QtGui_GEN_DIR}/qicon_wrapper.cpp +${QtGui_GEN_DIR}/qicondragevent_wrapper.cpp +${QtGui_GEN_DIR}/qiconengine_availablesizesargument_wrapper.cpp +${QtGui_GEN_DIR}/qiconengine_wrapper.cpp +${QtGui_GEN_DIR}/qimage_wrapper.cpp +${QtGui_GEN_DIR}/qimageiohandler_wrapper.cpp +${QtGui_GEN_DIR}/qimagereader_wrapper.cpp +${QtGui_GEN_DIR}/qimagewriter_wrapper.cpp +${QtGui_GEN_DIR}/qinputevent_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethod_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethodevent_attribute_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethodevent_wrapper.cpp +${QtGui_GEN_DIR}/qinputmethodqueryevent_wrapper.cpp +${QtGui_GEN_DIR}/qintvalidator_wrapper.cpp +${QtGui_GEN_DIR}/qkeyevent_wrapper.cpp +${QtGui_GEN_DIR}/qkeysequence_wrapper.cpp +${QtGui_GEN_DIR}/qlineargradient_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix2x2_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix2x3_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix2x4_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix3x2_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix3x3_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix3x4_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix4x2_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix4x3_wrapper.cpp +${QtGui_GEN_DIR}/qmatrix4x4_wrapper.cpp +${QtGui_GEN_DIR}/qmouseevent_wrapper.cpp +${QtGui_GEN_DIR}/qmoveevent_wrapper.cpp +${QtGui_GEN_DIR}/qmovie_wrapper.cpp +${QtGui_GEN_DIR}/qnativegestureevent_wrapper.cpp +${QtGui_GEN_DIR}/qoffscreensurface_wrapper.cpp +${QtGui_GEN_DIR}/qopenglcontextgroup_wrapper.cpp +${QtGui_GEN_DIR}/qopengldebuglogger_wrapper.cpp +${QtGui_GEN_DIR}/qopengldebugmessage_wrapper.cpp +${QtGui_GEN_DIR}/qopenglextrafunctions_wrapper.cpp +${QtGui_GEN_DIR}/qopenglframebufferobjectformat_wrapper.cpp +${QtGui_GEN_DIR}/qopenglfunctions_wrapper.cpp +# Compile error on Windows: ${QtGui_GEN_DIR}/qopenglpaintdevice_wrapper.cpp +${QtGui_GEN_DIR}/qopenglpixeltransferoptions_wrapper.cpp +${QtGui_GEN_DIR}/qopenglshaderprogram_wrapper.cpp +${QtGui_GEN_DIR}/qopengltexture_wrapper.cpp +${QtGui_GEN_DIR}/qopengltextureblitter_wrapper.cpp +${QtGui_GEN_DIR}/qopenglversionprofile_wrapper.cpp +${QtGui_GEN_DIR}/qopenglvertexarrayobject_wrapper.cpp +${QtGui_GEN_DIR}/qopenglvertexarrayobject_binder_wrapper.cpp +${QtGui_GEN_DIR}/qopenglwindow_wrapper.cpp +${QtGui_GEN_DIR}/qpagedpaintdevice_margins_wrapper.cpp +${QtGui_GEN_DIR}/qpagedpaintdevice_wrapper.cpp +${QtGui_GEN_DIR}/qpagelayout_wrapper.cpp +${QtGui_GEN_DIR}/qpagesize_wrapper.cpp +${QtGui_GEN_DIR}/qpaintdevice_wrapper.cpp +${QtGui_GEN_DIR}/qpaintdevicewindow_wrapper.cpp +${QtGui_GEN_DIR}/qpaintengine_wrapper.cpp +${QtGui_GEN_DIR}/qpaintenginestate_wrapper.cpp +${QtGui_GEN_DIR}/qpainter_pixmapfragment_wrapper.cpp +${QtGui_GEN_DIR}/qpainter_wrapper.cpp +${QtGui_GEN_DIR}/qpainterpath_element_wrapper.cpp +${QtGui_GEN_DIR}/qpainterpath_wrapper.cpp +${QtGui_GEN_DIR}/qpainterpathstroker_wrapper.cpp +${QtGui_GEN_DIR}/qpaintevent_wrapper.cpp +${QtGui_GEN_DIR}/qpalette_wrapper.cpp +${QtGui_GEN_DIR}/qpdfwriter_wrapper.cpp +${QtGui_GEN_DIR}/qpen_wrapper.cpp +${QtGui_GEN_DIR}/qpicture_wrapper.cpp +${QtGui_GEN_DIR}/qpictureio_wrapper.cpp +${QtGui_GEN_DIR}/qpixmap_wrapper.cpp +${QtGui_GEN_DIR}/qpixmapcache_key_wrapper.cpp +${QtGui_GEN_DIR}/qpixmapcache_wrapper.cpp +${QtGui_GEN_DIR}/qpixelformat_wrapper.cpp +${QtGui_GEN_DIR}/qpointingdeviceuniqueid_wrapper.cpp +${QtGui_GEN_DIR}/qpolygon_wrapper.cpp +${QtGui_GEN_DIR}/qpolygonf_wrapper.cpp +${QtGui_GEN_DIR}/qpytextobject_wrapper.cpp +${QtGui_GEN_DIR}/qquaternion_wrapper.cpp +${QtGui_GEN_DIR}/qradialgradient_wrapper.cpp +${QtGui_GEN_DIR}/qregexpvalidator_wrapper.cpp +${QtGui_GEN_DIR}/qregularexpressionvalidator_wrapper.cpp +${QtGui_GEN_DIR}/qregion_wrapper.cpp +${QtGui_GEN_DIR}/qresizeevent_wrapper.cpp +${QtGui_GEN_DIR}/qsessionmanager_wrapper.cpp +${QtGui_GEN_DIR}/qshortcutevent_wrapper.cpp +${QtGui_GEN_DIR}/qshowevent_wrapper.cpp +${QtGui_GEN_DIR}/qstandarditem_wrapper.cpp +${QtGui_GEN_DIR}/qstandarditemmodel_wrapper.cpp +${QtGui_GEN_DIR}/qstatustipevent_wrapper.cpp +${QtGui_GEN_DIR}/qopenglbuffer_wrapper.cpp +${QtGui_GEN_DIR}/qopenglcontext_wrapper.cpp +${QtGui_GEN_DIR}/qaccessible_state_wrapper.cpp +${QtGui_GEN_DIR}/qaccessibleinterface_wrapper.cpp +${QtGui_GEN_DIR}/qscreen_wrapper.cpp +${QtGui_GEN_DIR}/qopenglshader_wrapper.cpp +#${QtGui_GEN_DIR}/qopenglshaderprogram_wrapper.cpp +${QtGui_GEN_DIR}/qopenglframebufferobject_wrapper.cpp +${QtGui_GEN_DIR}/qrasterwindow_wrapper.cpp +${QtGui_GEN_DIR}/qrawfont_wrapper.cpp +${QtGui_GEN_DIR}/qscrollevent_wrapper.cpp +${QtGui_GEN_DIR}/qscrollprepareevent_wrapper.cpp +${QtGui_GEN_DIR}/qstatictext_wrapper.cpp +${QtGui_GEN_DIR}/qstylehints_wrapper.cpp +${QtGui_GEN_DIR}/qsurface_wrapper.cpp +${QtGui_GEN_DIR}/qsurfaceformat_wrapper.cpp +${QtGui_GEN_DIR}/qsyntaxhighlighter_wrapper.cpp +${QtGui_GEN_DIR}/qtabletevent_wrapper.cpp +${QtGui_GEN_DIR}/qtextblock_iterator_wrapper.cpp +${QtGui_GEN_DIR}/qtextblock_wrapper.cpp +${QtGui_GEN_DIR}/qtextblockformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextblockgroup_wrapper.cpp +${QtGui_GEN_DIR}/qtextblockuserdata_wrapper.cpp +${QtGui_GEN_DIR}/qtextcharformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextcursor_wrapper.cpp +${QtGui_GEN_DIR}/qtextdocument_wrapper.cpp +${QtGui_GEN_DIR}/qtextdocumentfragment_wrapper.cpp +${QtGui_GEN_DIR}/qtextdocumentwriter_wrapper.cpp +${QtGui_GEN_DIR}/qtextformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextfragment_wrapper.cpp +${QtGui_GEN_DIR}/qtextframe_iterator_wrapper.cpp +${QtGui_GEN_DIR}/qtextframe_wrapper.cpp +${QtGui_GEN_DIR}/qtextframeformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextimageformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextinlineobject_wrapper.cpp +${QtGui_GEN_DIR}/qtextitem_wrapper.cpp +${QtGui_GEN_DIR}/qtextlayout_formatrange_wrapper.cpp +${QtGui_GEN_DIR}/qtextlayout_wrapper.cpp +${QtGui_GEN_DIR}/qtextlength_wrapper.cpp +${QtGui_GEN_DIR}/qtextline_wrapper.cpp +${QtGui_GEN_DIR}/qtextlist_wrapper.cpp +${QtGui_GEN_DIR}/qtextlistformat_wrapper.cpp +${QtGui_GEN_DIR}/qtextobject_wrapper.cpp +${QtGui_GEN_DIR}/qtextobjectinterface_wrapper.cpp +${QtGui_GEN_DIR}/qtextoption_tab_wrapper.cpp +${QtGui_GEN_DIR}/qtextoption_wrapper.cpp +${QtGui_GEN_DIR}/qtexttable_wrapper.cpp +${QtGui_GEN_DIR}/qtexttablecell_wrapper.cpp +${QtGui_GEN_DIR}/qtexttablecellformat_wrapper.cpp +${QtGui_GEN_DIR}/qtexttableformat_wrapper.cpp +${QtGui_GEN_DIR}/qtoolbarchangeevent_wrapper.cpp +${QtGui_GEN_DIR}/qtouchdevice_wrapper.cpp +${QtGui_GEN_DIR}/qtouchevent_touchpoint_wrapper.cpp +${QtGui_GEN_DIR}/qtouchevent_wrapper.cpp +${QtGui_GEN_DIR}/qtransform_wrapper.cpp +${QtGui_GEN_DIR}/qt_wrapper.cpp +${QtGui_GEN_DIR}/qvalidator_wrapper.cpp +${QtGui_GEN_DIR}/qvector2d_wrapper.cpp +${QtGui_GEN_DIR}/qvector3d_wrapper.cpp +${QtGui_GEN_DIR}/qvector4d_wrapper.cpp +${QtGui_GEN_DIR}/qwhatsthisclickedevent_wrapper.cpp +${QtGui_GEN_DIR}/qwheelevent_wrapper.cpp +${QtGui_GEN_DIR}/qwindow_wrapper.cpp +${QtGui_GEN_DIR}/qwindowstatechangeevent_wrapper.cpp +# module is always needed +${QtGui_GEN_DIR}/qtgui_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Gui_VERSION VERSION_EQUAL 5.14.0 + OR Qt${QT_MAJOR_VERSION}Gui_VERSION VERSION_GREATER 5.14.0) + list(APPEND QtGui_SRC ${QtGui_GEN_DIR}/qcolorspace_wrapper.cpp) + list(APPEND QtGui_SRC ${QtGui_GEN_DIR}/qcolorconstants_wrapper.cpp) + list(APPEND QtGui_SRC ${QtGui_GEN_DIR}/qcolorconstants_svg_wrapper.cpp) +endif() + +# cf qtbase/src/gui/opengl/opengl.pri +list(FIND QtGui_enabled_features "opengles2" _opengles2Index) +# ### fixme: For cmake >= 3.3: if(opengles2 IN_LIST QtGui_enabled_features) +if(_opengles2Index GREATER -1) + list(APPEND QtGui_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery) + message(STATUS "Qt${QT_MAJOR_VERSION}Gui: Dropping Desktop OpenGL classes (GLES2)") +else() + list(APPEND QtGui_SRC + ${QtGui_GEN_DIR}/qopengltimemonitor_wrapper.cpp + ${QtGui_GEN_DIR}/qopengltimerquery_wrapper.cpp) + message(STATUS "Qt${QT_MAJOR_VERSION}Gui: Adding Desktop OpenGL classes") +endif() + +configure_file("${QtGui_SOURCE_DIR}/typesystem_gui.xml.in" + "${QtGui_BINARY_DIR}/typesystem_gui.xml" @ONLY) + +configure_file("${QtGui_SOURCE_DIR}/QtGui_global.post.h.in" + "${QtGui_BINARY_DIR}/QtGui_global.post.h" @ONLY) + +set(QtGui_include_dirs ${QtGui_SOURCE_DIR} + ${QtGui_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtGui_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}) +set(QtGui_deps QtCore) + +create_pyside_module(NAME QtGui + INCLUDE_DIRS QtGui_include_dirs + LIBRARIES QtGui_libraries + DEPS QtGui_deps + TYPESYSTEM_PATH QtGui_SOURCE_DIR + SOURCES QtGui_SRC + STATIC_SOURCES QPYTEXTOBJECT_MOC + TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml + DROPPED_ENTRIES QtGui_DROPPED_ENTRIES) + +install(FILES ${pyside2_SOURCE_DIR}/qpytextobject.h DESTINATION include/PySide2/QtGui/) + diff --git a/sources/pyside2/PySide2/QtGui/QtGui_global.post.h.in b/sources/pyside2/PySide2/QtGui/QtGui_global.post.h.in new file mode 100644 index 0000000..6d3a3ee --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/QtGui_global.post.h.in @@ -0,0 +1 @@ +#include "qpytextobject.h" // PySide class diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui.xml.in b/sources/pyside2/PySide2/QtGui/typesystem_gui.xml.in new file mode 100644 index 0000000..dfd5a9c --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui.xml.in @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml new file mode 100644 index 0000000..04abbae --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_common.xml @@ -0,0 +1,3069 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This method must be used with an QPixmap object, not the class: + + :: + + # Wrong + pixmap = QPixmap.loadFromData(...) + + # Right + pixmap = QPixmap().loadFromData(...) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + _______ end of matrix block _______ --> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml new file mode 100644 index 0000000..8b071a1 --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_mac.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml new file mode 100644 index 0000000..6386cbd --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_win.xml @@ -0,0 +1,42 @@ + + + diff --git a/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml b/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml new file mode 100644 index 0000000..6386cbd --- /dev/null +++ b/sources/pyside2/PySide2/QtGui/typesystem_gui_x11.xml @@ -0,0 +1,42 @@ + + + diff --git a/sources/pyside2/PySide2/QtHelp/CMakeLists.txt b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt new file mode 100644 index 0000000..267703f --- /dev/null +++ b/sources/pyside2/PySide2/QtHelp/CMakeLists.txt @@ -0,0 +1,60 @@ +project(QtHelp) + +set(QtHelp_SRC +${QtHelp_GEN_DIR}/qhelpcontentitem_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpcontentmodel_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpcontentwidget_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpenginecore_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpengine_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpindexmodel_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpindexwidget_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpsearchengine_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpsearchquerywidget_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpsearchquery_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpsearchresult_wrapper.cpp +${QtHelp_GEN_DIR}/qhelpsearchresultwidget_wrapper.cpp +# module is always needed +${QtHelp_GEN_DIR}/qthelp_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_EQUAL 5.13.0 + OR Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_GREATER 5.13.0) + list(APPEND QtHelp_SRC + ${QtHelp_GEN_DIR}/qcompressedhelpinfo_wrapper.cpp + ${QtHelp_GEN_DIR}/qhelpfilterdata_wrapper.cpp + ${QtHelp_GEN_DIR}/qhelpfilterengine_wrapper.cpp) +endif() + +if (Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_EQUAL 5.15.0 + OR Qt${QT_MAJOR_VERSION}Help_VERSION VERSION_GREATER 5.15.0) + list(APPEND QtHelp_SRC + ${QtHelp_GEN_DIR}/qhelpfiltersettingswidget_wrapper.cpp + ${QtHelp_GEN_DIR}/qhelplink_wrapper.cpp) +endif() + + +set(QtHelp_include_dirs ${QtHelp_SOURCE_DIR} + ${QtHelp_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Help_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtWidgets_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ) +set(QtHelp_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Help_LIBRARIES}) + +set(QtHelp_deps QtWidgets) + +create_pyside_module(NAME QtHelp + INCLUDE_DIRS QtHelp_include_dirs + LIBRARIES QtHelp_libraries + DEPS QtHelp_deps + TYPESYSTEM_PATH QtHelp_SOURCE_DIR + SOURCES QtHelp_SRC) diff --git a/sources/pyside2/PySide2/QtHelp/typesystem_help.xml b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml new file mode 100644 index 0000000..76013d1 --- /dev/null +++ b/sources/pyside2/PySide2/QtHelp/typesystem_help.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtLocation/CMakeLists.txt b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt new file mode 100644 index 0000000..fa21310 --- /dev/null +++ b/sources/pyside2/PySide2/QtLocation/CMakeLists.txt @@ -0,0 +1,75 @@ +project(QtLocation) + +set(QtLocation_OPTIONAL_SRC ) +set(QtLocation_DROPPED_ENTRIES ) + +set(QtLocation_SRC +${QtLocation_GEN_DIR}/qgeocodereply_wrapper.cpp +${QtLocation_GEN_DIR}/qgeomaneuver_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoroute_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoroutereply_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoroutesegment_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoserviceprovider_wrapper.cpp +${QtLocation_GEN_DIR}/qplace_wrapper.cpp +${QtLocation_GEN_DIR}/qplacecontentreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplacedetailsreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceicon_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceidreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplacemanager_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceuser_wrapper.cpp +${QtLocation_GEN_DIR}/qgeocodingmanager_wrapper.cpp +${QtLocation_GEN_DIR}/qgeocodingmanagerengine_wrapper.cpp +${QtLocation_GEN_DIR}/qgeorouterequest_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoroutingmanager_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoroutingmanagerengine_wrapper.cpp +${QtLocation_GEN_DIR}/qgeoserviceproviderfactory_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceattribute_wrapper.cpp +${QtLocation_GEN_DIR}/qplacecategory_wrapper.cpp +${QtLocation_GEN_DIR}/qplacecontactdetail_wrapper.cpp +${QtLocation_GEN_DIR}/qplacecontent_wrapper.cpp +${QtLocation_GEN_DIR}/qplacecontentrequest_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceeditorial_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceimage_wrapper.cpp +${QtLocation_GEN_DIR}/qplacemanagerengine_wrapper.cpp +${QtLocation_GEN_DIR}/qplacematchreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplacematchrequest_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceproposedsearchresult_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceratings_wrapper.cpp +${QtLocation_GEN_DIR}/qplacereply_wrapper.cpp +${QtLocation_GEN_DIR}/qplaceresult_wrapper.cpp +${QtLocation_GEN_DIR}/qplacereview_wrapper.cpp +${QtLocation_GEN_DIR}/qplacesearchreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplacesearchrequest_wrapper.cpp +${QtLocation_GEN_DIR}/qplacesearchresult_wrapper.cpp +${QtLocation_GEN_DIR}/qplacesearchsuggestionreply_wrapper.cpp +${QtLocation_GEN_DIR}/qplacesupplier_wrapper.cpp +# module is always needed +${QtLocation_GEN_DIR}/qtlocation_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Location_VERSION VERSION_EQUAL 5.11.0 + OR Qt${QT_MAJOR_VERSION}Location_VERSION VERSION_GREATER 5.11.0) + list(APPEND QtLocation_SRC + ${QtLocation_GEN_DIR}/qgeoserviceproviderfactoryv2_wrapper.cpp) +endif() + +set(QtLocation_include_dirs ${QtLocation_SOURCE_DIR} + ${QtLocation_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Location_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtPositioning_GEN_DIR}) + +set(QtLocation_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Location_LIBRARIES}) + +set(QtLocation_deps QtCore QtPositioning) + +create_pyside_module(NAME QtLocation + INCLUDE_DIRS QtLocation_include_dirs + LIBRARIES QtLocation_libraries + DEPS QtLocation_deps + TYPESYSTEM_PATH QtLocation_SOURCE_DIR + SOURCES QtLocation_SRC + DROPPED_ENTRIES QtLocation_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtLocation/typesystem_location.xml b/sources/pyside2/PySide2/QtLocation/typesystem_location.xml new file mode 100644 index 0000000..2d39e65 --- /dev/null +++ b/sources/pyside2/PySide2/QtLocation/typesystem_location.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt new file mode 100644 index 0000000..6e3d0f2 --- /dev/null +++ b/sources/pyside2/PySide2/QtMacExtras/CMakeLists.txt @@ -0,0 +1,33 @@ +project(QtMacExtras) + +set(QtMacExtras_SRC +${QtMacExtras_GEN_DIR}/qmacpasteboardmime_wrapper.cpp +${QtMacExtras_GEN_DIR}/qmactoolbar_wrapper.cpp +${QtMacExtras_GEN_DIR}/qmactoolbaritem_wrapper.cpp + +# module is always needed +${QtMacExtras_GEN_DIR}/qtmacextras_module_wrapper.cpp +) + +set(QtMacExtras_include_dirs ${QtMacExtras_SOURCE_DIR} + ${QtMacExtras_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}MacExtras_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${libpyside_SOURCE_DIR}) + +set(QtMacExtras_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}MacExtras_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}) + +set(QtMacExtras_deps QtCore QtGui) + +create_pyside_module(NAME QtMacExtras + INCLUDE_DIRS QtMacExtras_include_dirs + LIBRARIES QtMacExtras_libraries + DEPS QtMacExtras_deps + TYPESYSTEM_PATH QtMacExtras_SOURCE_DIR + SOURCES QtMacExtras_SRC) diff --git a/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml b/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml new file mode 100644 index 0000000..d62ce48 --- /dev/null +++ b/sources/pyside2/PySide2/QtMacExtras/typesystem_macextras.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt new file mode 100644 index 0000000..64e6a3a --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimedia/CMakeLists.txt @@ -0,0 +1,130 @@ +project(QtMultimedia) + +set(QtMultimedia_SRC +${QtMultimedia_GEN_DIR}/qabstractaudiodeviceinfo_wrapper.cpp +${QtMultimedia_GEN_DIR}/qabstractaudioinput_wrapper.cpp +${QtMultimedia_GEN_DIR}/qabstractaudiooutput_wrapper.cpp +${QtMultimedia_GEN_DIR}/qabstractvideobuffer_wrapper.cpp +${QtMultimedia_GEN_DIR}/qabstractvideofilter_wrapper.cpp +${QtMultimedia_GEN_DIR}/qabstractvideosurface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiobuffer_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiodecoder_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiodecodercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiodeviceinfo_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioencodersettingscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioencodersettings_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioformat_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioinputselectorcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioinput_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiooutputselectorcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiooutput_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudioprobe_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiorecorder_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudiorolecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qaudio_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameracapturebufferformatcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameracapturedestinationcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameracontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraexposurecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraexposure_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerafeedbackcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerafocus_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraflashcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerafocuscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerafocuszone_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamera_frameraterange_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraimagecapturecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraimagecapture_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraimageprocessing_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraimageprocessingcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerainfocontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerainfo_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameralockscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraviewfindersettingscontrol2_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraviewfindersettingscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcameraviewfindersettings_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamera_wrapper.cpp +${QtMultimedia_GEN_DIR}/qcamerazoomcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qimageencodercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qimageencodersettings_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaaudioprobecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaavailabilitycontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediabindableinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediacontainercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediacontent_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediacontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediagaplessplaybackcontrol_wrapper.cpp +# Causes compile errors: ${QtMultimedia_GEN_DIR}/qmediametadata_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmedianetworkaccesscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaobject_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaplayercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaplayer_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaplaylist_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediarecordercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediarecorder_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaresource_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservice_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicecamerainfointerface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicedefaultdeviceinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicefeaturesinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaserviceproviderhint_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicesupporteddevicesinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediaservicesupportedformatsinterface_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediastreamscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediatimeinterval_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediatimerange_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmediavideoprobecontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmetadatareadercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmetadatawritercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qmultimedia_wrapper.cpp +${QtMultimedia_GEN_DIR}/qradiodatacontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qradiodata_wrapper.cpp +${QtMultimedia_GEN_DIR}/qradiotunercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qradiotuner_wrapper.cpp +${QtMultimedia_GEN_DIR}/qsoundeffect_wrapper.cpp +${QtMultimedia_GEN_DIR}/qsound_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideodeviceselectorcontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideoencodersettingscontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideoencodersettings_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideofilterrunnable_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideoframe_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideoprobe_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideorenderercontrol_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideosurfaceformat_wrapper.cpp +${QtMultimedia_GEN_DIR}/qvideowindowcontrol_wrapper.cpp + +# module is always needed +${QtMultimedia_GEN_DIR}/qtmultimedia_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Multimedia_VERSION VERSION_EQUAL 5.11.0 + OR Qt${QT_MAJOR_VERSION}Multimedia_VERSION VERSION_GREATER 5.11.0) + list(APPEND QtMultimedia_SRC + ${QtMultimedia_GEN_DIR}/qcustomaudiorolecontrol_wrapper.cpp) +endif() + +set(QtMultimedia_include_dirs ${QtMultimedia_SOURCE_DIR} + ${QtMultimedia_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtNetwork_GEN_DIR}) + +set(QtMultimedia_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ) +set(QtMultimedia_deps QtCore QtGui QtNetwork) + +create_pyside_module(NAME QtMultimedia + INCLUDE_DIRS QtMultimedia_include_dirs + LIBRARIES QtMultimedia_libraries + DEPS QtMultimedia_deps + TYPESYSTEM_PATH QtMultimedia_SOURCE_DIR + SOURCES QtMultimedia_SRC) diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml new file mode 100644 index 0000000..323c50b --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia.xml @@ -0,0 +1,45 @@ + + + + + + diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml new file mode 100644 index 0000000..0c10121 --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_common.xml @@ -0,0 +1,372 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml new file mode 100644 index 0000000..733e9b2 --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimedia/typesystem_multimedia_forward_declarations.xml @@ -0,0 +1,45 @@ + + + + + + diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt new file mode 100644 index 0000000..052db6c --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimediaWidgets/CMakeLists.txt @@ -0,0 +1,42 @@ +project(QtMultimediaWidgets) + +set(QtMultimediaWidgets_SRC +${QtMultimediaWidgets_GEN_DIR}/qcameraviewfinder_wrapper.cpp +${QtMultimediaWidgets_GEN_DIR}/qgraphicsvideoitem_wrapper.cpp +${QtMultimediaWidgets_GEN_DIR}/qvideowidget_wrapper.cpp +${QtMultimediaWidgets_GEN_DIR}/qvideowidgetcontrol_wrapper.cpp +# module is always needed +${QtMultimediaWidgets_GEN_DIR}/qtmultimediawidgets_module_wrapper.cpp +) + +set(QtMultimediaWidgets_include_dirs ${QtMultimediaWidgets_SOURCE_DIR} + ${QtMultimediaWidgets_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Multimedia_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtMultimedia_GEN_DIR}) + +set(QtMultimediaWidgets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}MultimediaWidgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}) + +set(QtMultimediaWidgets_deps QtCore QtGui QtNetwork QtWidgets QtMultimedia) + +create_pyside_module(NAME QtMultimediaWidgets + INCLUDE_DIRS QtMultimediaWidgets_include_dirs + LIBRARIES QtMultimediaWidgets_libraries + DEPS QtMultimediaWidgets_deps + TYPESYSTEM_PATH QtMultimediaWidgets_SOURCE_DIR + SOURCES QtMultimediaWidgets_SRC) diff --git a/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml new file mode 100644 index 0000000..6902205 --- /dev/null +++ b/sources/pyside2/PySide2/QtMultimediaWidgets/typesystem_multimediawidgets.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt new file mode 100644 index 0000000..9557c4a --- /dev/null +++ b/sources/pyside2/PySide2/QtNetwork/CMakeLists.txt @@ -0,0 +1,121 @@ +project(QtNetwork) + +set(QtNetwork_DROPPED_ENTRIES ) + +set(QtNetwork_SRC +${QtNetwork_GEN_DIR}/qabstractnetworkcache_wrapper.cpp +${QtNetwork_GEN_DIR}/qabstractsocket_wrapper.cpp +${QtNetwork_GEN_DIR}/qauthenticator_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnsdomainnamerecord_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnshostaddressrecord_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnslookup_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnsmailexchangerecord_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnsservicerecord_wrapper.cpp +${QtNetwork_GEN_DIR}/qdnstextrecord_wrapper.cpp +${QtNetwork_GEN_DIR}/qhostaddress_wrapper.cpp +${QtNetwork_GEN_DIR}/qhostinfo_wrapper.cpp +${QtNetwork_GEN_DIR}/qhstspolicy_wrapper.cpp +${QtNetwork_GEN_DIR}/qhttpmultipart_wrapper.cpp +${QtNetwork_GEN_DIR}/qhttppart_wrapper.cpp +${QtNetwork_GEN_DIR}/qipv6address_wrapper.cpp +${QtNetwork_GEN_DIR}/qlocalserver_wrapper.cpp +${QtNetwork_GEN_DIR}/qlocalsocket_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkaccessmanager_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkaddressentry_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkcachemetadata_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkconfiguration_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkconfigurationmanager_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkcookie_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkcookiejar_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkdatagram_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkdiskcache_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkinterface_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkproxy_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkproxyfactory_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkproxyquery_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkreply_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworkrequest_wrapper.cpp +${QtNetwork_GEN_DIR}/qnetworksession_wrapper.cpp +${QtNetwork_GEN_DIR}/qpassworddigestor_wrapper.cpp +${QtNetwork_GEN_DIR}/qssl_wrapper.cpp +${QtNetwork_GEN_DIR}/qsslcertificate_wrapper.cpp +${QtNetwork_GEN_DIR}/qsslcertificateextension_wrapper.cpp +${QtNetwork_GEN_DIR}/qtcpserver_wrapper.cpp +${QtNetwork_GEN_DIR}/qtcpsocket_wrapper.cpp +${QtNetwork_GEN_DIR}/qudpsocket_wrapper.cpp +# module is always needed +${QtNetwork_GEN_DIR}/qtnetwork_module_wrapper.cpp +) + +get_property(QtNetwork_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Network + PROPERTY QT_ENABLED_PUBLIC_FEATURES) +get_property(QtNetwork_disabled_features TARGET Qt${QT_MAJOR_VERSION}::Network + PROPERTY QT_DISABLED_PUBLIC_FEATURES) + +# ### fixme: For cmake >= 3.3, use if( needle IN_LIST list) +list(FIND QtNetwork_enabled_features "ssl" _sslEnabledIndex) +list(FIND QtNetwork_disabled_features "dtls" _dtlsDisabledIndex) +list(FIND QtNetwork_disabled_features "sctp" _sctpDisabledIndex) + +if(_sslEnabledIndex EQUAL -1) + list(APPEND QtNetwork_DROPPED_ENTRIES QOcspResponse QSslCipher + QSslConfiguration QSslDiffieHellmanParameters QSslError + QSslKey QSslPreSharedKeyAuthenticator QSslSocket) + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SSL classes") +else() + # Problems with operator==(QSslEllipticCurve,QSslEllipticCurve) + # check_qt_class(QtNetwork QSslEllipticCurve QtNetwork_OPTIONAL_SRC QtNetwork_DROPPED_ENTRIES) + list(APPEND QtNetwork_SRC + ${QtNetwork_GEN_DIR}/qsslcipher_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsslconfiguration_wrapper.cpp + ${QtNetwork_GEN_DIR}/qssldiffiehellmanparameters_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsslerror_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsslkey_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsslpresharedkeyauthenticator_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsslsocket_wrapper.cpp) + if (Qt${QT_MAJOR_VERSION}Network_VERSION VERSION_EQUAL 5.13.0 + OR Qt${QT_MAJOR_VERSION}Network_VERSION VERSION_GREATER 5.13.0) + list(APPEND QtNetwork_SRC + ${QtNetwork_GEN_DIR}/qocspresponse_wrapper.cpp) + endif() + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SSL classes") +endif() + +if(_dtlsDisabledIndex GREATER -1) + list(APPEND QtNetwork_DROPPED_ENTRIES QDtls) + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping DTLS classes") +else() + list(APPEND QtNetwork_SRC + ${QtNetwork_GEN_DIR}/qdtls_wrapper.cpp) + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding DTLS classes") +endif() + +if(_sctpDisabledIndex GREATER -1) + list(APPEND QtNetwork_DROPPED_ENTRIES QSctpServer QSctpSocket) + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Dropping SCTP classes") +else() + list(APPEND QtNetwork_SRC + ${QtNetwork_GEN_DIR}/qsctpserver_wrapper.cpp + ${QtNetwork_GEN_DIR}/qsctpsocket_wrapper.cpp) + message(STATUS "Qt${QT_MAJOR_VERSION}Network: Adding SCTP classes") +endif() + +set(QtNetwork_include_dirs ${QtNetwork_SOURCE_DIR} + ${QtNetwork_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtNetwork_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES}) + +set(QtNetwork_deps QtCore) + +create_pyside_module(NAME QtNetwork + INCLUDE_DIRS QtNetwork_include_dirs + LIBRARIES QtNetwork_libraries + DEPS QtNetwork_deps + TYPESYSTEM_PATH QtNetwork_SOURCE_DIR + SOURCES QtNetwork_SRC + DROPPED_ENTRIES QtNetwork_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml new file mode 100644 index 0000000..dc60a50 --- /dev/null +++ b/sources/pyside2/PySide2/QtNetwork/typesystem_network.xml @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt new file mode 100644 index 0000000..1d2c406 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGL/CMakeLists.txt @@ -0,0 +1,42 @@ +project(QtOpenGL) + +set(QtOpenGL_SRC +${QtOpenGL_GEN_DIR}/qgl_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglbuffer_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglcolormap_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglcontext_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglformat_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglframebufferobject_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglframebufferobjectformat_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglpixelbuffer_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglshader_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglshaderprogram_wrapper.cpp +${QtOpenGL_GEN_DIR}/qglwidget_wrapper.cpp +# module is always needed +${QtOpenGL_GEN_DIR}/qtopengl_module_wrapper.cpp +) + +set(QtOpenGL_include_dirs ${QtOpenGL_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}OpenGL_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtWidgets_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ${QtOpenGL_GEN_DIR} + ) +set(QtOpenGL_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}OpenGL_LIBRARIES}) +set(QtOpenGL_deps QtWidgets) + +create_pyside_module(NAME QtOpenGL + INCLUDE_DIRS QtOpenGL_include_dirs + LIBRARIES QtOpenGL_libraries + DEPS QtOpenGL_deps + TYPESYSTEM_PATH QtOpenGL_SOURCE_DIR + SOURCES QtOpenGL_SRC) diff --git a/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml new file mode 100644 index 0000000..5e864ca --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGL/typesystem_opengl.xml @@ -0,0 +1,716 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt new file mode 100644 index 0000000..383afb6 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/CMakeLists.txt @@ -0,0 +1,73 @@ +project(QtOpenGLFunctions) + +set(QtOpenGLFunctions_DROPPED_ENTRIES) + +get_property(QtOpenGLFunctions_enabled_features TARGET Qt${QT_MAJOR_VERSION}::Gui + PROPERTY QT_ENABLED_PUBLIC_FEATURES) + +set(QtOpenGLFunctions_SRC ${QtOpenGLFunctions_GEN_DIR}/qtopenglfunctions_module_wrapper.cpp) + +# cf qtbase/src/gui/opengl/opengl.pri +list(FIND QtOpenGLFunctions_enabled_features "opengles2" _opengles2Index) +# ### fixme: For cmake >= 3.3: if(opengles2 IN_LIST QtOpenGLFunctions_enabled_features) +if(_opengles2Index GREATER -1) + list(APPEND QtOpenGLFunctions_DROPPED_ENTRIES QOpenGLTimeMonitor QOpenGLTimerQuery) + list(APPEND QtOpenGLFunctions_SRC + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_es2_wrapper.cpp) + message(STATUS "Qt${QT_MAJOR_VERSION}OpenGLFunctions: Dropping Desktop OpenGL classes (GLES2)") +else() + list(APPEND QtOpenGLFunctions_SRC + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_0_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_1_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_2_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_3_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_4_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_1_5_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_2_0_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_2_1_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_0_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_1_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_2_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_2_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_3_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_3_3_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_0_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_0_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_1_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_1_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_2_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_2_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_3_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_3_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_4_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_4_core_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_compatibility_wrapper.cpp + ${QtOpenGLFunctions_GEN_DIR}/qopenglfunctions_4_5_core_wrapper.cpp) + message(STATUS "Qt${QT_MAJOR_VERSION}OpenGLFunctions: Adding Desktop OpenGL classes") +endif() + +configure_file("${QtOpenGLFunctions_SOURCE_DIR}/QtOpenGLFunctions_global.post.h.in" + "${QtOpenGLFunctions_BINARY_DIR}/QtOpenGLFunctions_global.post.h" @ONLY) + +set(QtOpenGLFunctions_include_dirs ${QtGOpenGLFunctions_SOURCE_DIR} + ${QtOpenGLFunctions_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ) +set(QtOpenGLFunctions_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}) + +set(QtOpenGLFunctions_deps QtGui) + +create_pyside_module(NAME QtOpenGLFunctions + INCLUDE_DIRS QtOpenGLFunctions_include_dirs + LIBRARIES QtOpenGLFunctions_libraries + DEPS QtOpenGLFunctions_deps + TYPESYSTEM_PATH QtOpenGLFunctions_SOURCE_DIR + SOURCES QtOpenGLFunctions_SRC + TYPESYSTEM_NAME ${QtOpenGLFunctions_BINARY_DIR}/typesystem_openglfunctions.xml + DROPPED_ENTRIES QtOpenGLFunctions_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in b/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in new file mode 100644 index 0000000..6c8c770 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/QtOpenGLFunctions_global.post.h.in @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +// OpenGL functions are not in the QtGui module header +#if QT_CONFIG(opengl) +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif +#if QT_CONFIG(opengles2) +# include +#endif diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml new file mode 100644 index 0000000..1d5b08e --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions.xml @@ -0,0 +1,409 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_1; + &openglfunctions_modifications4_0; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications_va; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications_va; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications4_3; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_3; + &openglfunctions_modifications4_1; + &openglfunctions_modifications_va; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications4_3; + &openglfunctions_modifications4_4; + &openglfunctions_modifications4_4_core; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications_va; + &openglfunctions_modifications4_3; + &openglfunctions_modifications4_4; + &openglfunctions_modifications4_4_core; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_0_compat; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_1_compat; + &openglfunctions_modifications1_2_compat; + &openglfunctions_modifications1_3_compat; + &openglfunctions_modifications1_4; + &openglfunctions_modifications1_4_compat; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_0_compat; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications3_3a; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications4_3; + &openglfunctions_modifications4_4; + &openglfunctions_modifications4_4_core; + &openglfunctions_modifications4_5; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + &openglfunctions_modifications1_4; + &openglfunctions_modifications2_0; + &openglfunctions_modifications2_1; + &openglfunctions_modifications3_0; + &openglfunctions_modifications3_3; + &openglfunctions_modifications4_0; + &openglfunctions_modifications4_1; + &openglfunctions_modifications4_3; + &openglfunctions_modifications4_4; + &openglfunctions_modifications4_4_core; + &openglfunctions_modifications4_5; + &openglfunctions_modifications_va; + + + &openglfunctions_modifications1_0; + &openglfunctions_modifications1_1; + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0.xml new file mode 100644 index 0000000..5652ad6 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0_compat.xml new file mode 100644 index 0000000..5793048 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_0_compat.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1.xml new file mode 100644 index 0000000..9383fb8 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1.xml @@ -0,0 +1,44 @@ + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1_compat.xml new file mode 100644 index 0000000..3f8075b --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_1_compat.xml @@ -0,0 +1,44 @@ + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_2_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_2_compat.xml new file mode 100644 index 0000000..c13b09b --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_2_compat.xml @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_3_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_3_compat.xml new file mode 100644 index 0000000..e35f3b3 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_3_compat.xml @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4.xml new file mode 100644 index 0000000..1102dae --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4.xml @@ -0,0 +1,47 @@ + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4_compat.xml new file mode 100644 index 0000000..4cb75d4 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications1_4_compat.xml @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0.xml new file mode 100644 index 0000000..28a424e --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0.xml @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0_compat.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0_compat.xml new file mode 100644 index 0000000..49cbd5c --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_0_compat.xml @@ -0,0 +1 @@ +&typesystem_openglfunctions_modifications_va.xml; diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_1.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_1.xml new file mode 100644 index 0000000..af515ed --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications2_1.xml @@ -0,0 +1,43 @@ + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_0.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_0.xml new file mode 100644 index 0000000..8377e44 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_0.xml @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3.xml new file mode 100644 index 0000000..7f47171 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3.xml @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3a.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3a.xml new file mode 100644 index 0000000..4bf2bc8 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications3_3a.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_0.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_0.xml new file mode 100644 index 0000000..cf2e47a --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_0.xml @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_1.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_1.xml new file mode 100644 index 0000000..bc92ce8 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_1.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_3.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_3.xml new file mode 100644 index 0000000..b3c2b61 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_3.xml @@ -0,0 +1,43 @@ + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4.xml new file mode 100644 index 0000000..6b59f17 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4_core.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4_core.xml new file mode 100644 index 0000000..c747997 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_4_core.xml @@ -0,0 +1,43 @@ + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5.xml new file mode 100644 index 0000000..2ea0a45 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5_core.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5_core.xml new file mode 100644 index 0000000..5cd5161 --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications4_5_core.xml @@ -0,0 +1,41 @@ + diff --git a/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications_va.xml b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications_va.xml new file mode 100644 index 0000000..ae4d49a --- /dev/null +++ b/sources/pyside2/PySide2/QtOpenGLFunctions/typesystem_openglfunctions_modifications_va.xml @@ -0,0 +1,43 @@ + + + + diff --git a/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt new file mode 100644 index 0000000..321478c --- /dev/null +++ b/sources/pyside2/PySide2/QtPositioning/CMakeLists.txt @@ -0,0 +1,50 @@ +project(QtPositioning) + +set(QtPositioning_OPTIONAL_SRC ) +set(QtPositioning_DROPPED_ENTRIES ) + +set(QtPositioning_SRC +${QtPositioning_GEN_DIR}/qgeoaddress_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeoareamonitorinfo_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeoareamonitorsource_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeolocation_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeocircle_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeocoordinate_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeopath_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeopositioninfo_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeopositioninfosource_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeopositioninfosourcefactory_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeorectangle_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeosatelliteinfo_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeosatelliteinfosource_wrapper.cpp +${QtPositioning_GEN_DIR}/qgeoshape_wrapper.cpp +${QtPositioning_GEN_DIR}/qnmeapositioninfosource_wrapper.cpp +# module is always needed +${QtPositioning_GEN_DIR}/qtpositioning_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Positioning_VERSION VERSION_EQUAL 5.10.0 + OR Qt${QT_MAJOR_VERSION}Positioning_VERSION VERSION_GREATER 5.10.0) + list(APPEND QtPositioning_SRC + ${QtPositioning_GEN_DIR}/qgeopolygon_wrapper.cpp) +endif() + +set(QtPositioning_include_dirs ${QtPositioning_SOURCE_DIR} + ${QtPositioning_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Positioning_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtPositioning_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Positioning_LIBRARIES}) + +set(QtPositioning_deps QtCore) + +create_pyside_module(NAME QtPositioning + INCLUDE_DIRS QtPositioning_include_dirs + LIBRARIES QtPositioning_libraries + DEPS QtPositioning_deps + TYPESYSTEM_PATH QtPositioning_SOURCE_DIR + SOURCES QtPositioning_SRC + DROPPED_ENTRIES QtPositioning_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml b/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml new file mode 100644 index 0000000..5a72089 --- /dev/null +++ b/sources/pyside2/PySide2/QtPositioning/typesystem_positioning.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt new file mode 100644 index 0000000..fd39797 --- /dev/null +++ b/sources/pyside2/PySide2/QtPrintSupport/CMakeLists.txt @@ -0,0 +1,43 @@ +project(QtPrintSupport) + +set(QtPrintSupport_SRC +${QtPrintSupport_GEN_DIR}/qabstractprintdialog_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qpagesetupdialog_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprintdialog_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprintengine_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprinter_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprinterinfo_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprintpreviewdialog_wrapper.cpp +${QtPrintSupport_GEN_DIR}/qprintpreviewwidget_wrapper.cpp +# module is always needed +${QtPrintSupport_GEN_DIR}/qtprintsupport_module_wrapper.cpp +) + +configure_file("${QtPrintSupport_SOURCE_DIR}/typesystem_printsupport.xml.in" + "${QtPrintSupport_BINARY_DIR}/typesystem_printsupport.xml" @ONLY) + +set(QtPrintSupport_include_dirs ${QtPrintSupport_SOURCE_DIR} + ${QtPrintSupport_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ) +set(QtPrintSupport_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}PrintSupport_LIBRARIES} + ) +set(QtPrintSupport_deps QtWidgets) +create_pyside_module(NAME QtPrintSupport + INCLUDE_DIRS QtPrintSupport_include_dirs + LIBRARIES QtPrintSupport_libraries + DEPS QtPrintSupport_deps + TYPESYSTEM_PATH QtPrintSupport_SOURCE_DIR + SOURCES QtPrintSupport_SRC + TYPESYSTEM_NAME ${QtPrintSupport_BINARY_DIR}/typesystem_printsupport.xml) diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in new file mode 100644 index 0000000..ff078d1 --- /dev/null +++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport.xml.in @@ -0,0 +1,45 @@ + + + + + + diff --git a/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml new file mode 100644 index 0000000..4871038 --- /dev/null +++ b/sources/pyside2/PySide2/QtPrintSupport/typesystem_printsupport_common.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtQml/CMakeLists.txt b/sources/pyside2/PySide2/QtQml/CMakeLists.txt new file mode 100644 index 0000000..3c5dd43 --- /dev/null +++ b/sources/pyside2/PySide2/QtQml/CMakeLists.txt @@ -0,0 +1,63 @@ +project(QtQml) + +set(QtQml_registerType "${QtQml_SOURCE_DIR}/pysideqmlregistertype.cpp") + +set(QtQml_SRC +${QtQml_GEN_DIR}/qjsengine_wrapper.cpp +${QtQml_GEN_DIR}/qjsvalue_wrapper.cpp +${QtQml_GEN_DIR}/qjsvalueiterator_wrapper.cpp +${QtQml_GEN_DIR}/qqmlabstracturlinterceptor_wrapper.cpp +${QtQml_GEN_DIR}/qqmlapplicationengine_wrapper.cpp +${QtQml_GEN_DIR}/qqmlcomponent_wrapper.cpp +${QtQml_GEN_DIR}/qqmlcontext_wrapper.cpp +${QtQml_GEN_DIR}/qqmlerror_wrapper.cpp +${QtQml_GEN_DIR}/qqmldebuggingenabler_wrapper.cpp +${QtQml_GEN_DIR}/qqmlengine_wrapper.cpp +${QtQml_GEN_DIR}/qqmlexpression_wrapper.cpp +${QtQml_GEN_DIR}/qqmlextensioninterface_wrapper.cpp +${QtQml_GEN_DIR}/qqmltypesextensioninterface_wrapper.cpp +${QtQml_GEN_DIR}/qqmlextensionplugin_wrapper.cpp +${QtQml_GEN_DIR}/qqmlfile_wrapper.cpp +${QtQml_GEN_DIR}/qqmlfileselector_wrapper.cpp +${QtQml_GEN_DIR}/qqmlimageproviderbase_wrapper.cpp +${QtQml_GEN_DIR}/qqmlincubator_wrapper.cpp +${QtQml_GEN_DIR}/qqmlincubationcontroller_wrapper.cpp +#${QtQml_GEN_DIR}/qqmllistproperty_wrapper.cpp +${QtQml_GEN_DIR}/qqmllistreference_wrapper.cpp +${QtQml_GEN_DIR}/qqmlparserstatus_wrapper.cpp +${QtQml_GEN_DIR}/qqmlproperty_wrapper.cpp +${QtQml_GEN_DIR}/qqmlpropertymap_wrapper.cpp +${QtQml_GEN_DIR}/qqmlpropertyvaluesource_wrapper.cpp +${QtQml_GEN_DIR}/qqmlscriptstring_wrapper.cpp +${QtQml_GEN_DIR}/qqmlnetworkaccessmanagerfactory_wrapper.cpp +${QtQml_GEN_DIR}/qtqml_wrapper.cpp +# module is always needed +${QtQml_GEN_DIR}/qtqml_module_wrapper.cpp +) + +set(QtQml_include_dirs ${QtQml_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtQml_GEN_DIR}) + +set(QtQml_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES}) + +set(QtQml_deps QtGui QtNetwork) + +create_pyside_module(NAME QtQml + INCLUDE_DIRS QtQml_include_dirs + LIBRARIES QtQml_libraries + DEPS QtQml_deps + TYPESYSTEM_PATH QtQml_SOURCE_DIR + SOURCES QtQml_SRC + STATIC_SOURCES QtQml_registerType) diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp new file mode 100644 index 0000000..2b60c5c --- /dev/null +++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp @@ -0,0 +1,506 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pysideqmlregistertype.h" + +// shiboken +#include +#include + +// pyside +#include +#include +#include + +// auto generated headers +#include "pyside2_qtcore_python.h" +#include "pyside2_qtqml_python.h" + +#ifndef PYSIDE_MAX_QML_TYPES +// Maximum number of different Qt QML types the user can export to QML using +// qmlRegisterType. This limit exists because the QML engine instantiates objects +// by calling a function with one argument (a void *pointer where the object should +// be created), and thus does not allow us to choose which object to create. Thus +// we create a C++ factory function for each new registered type at compile time. +#define PYSIDE_MAX_QML_TYPES 50 +#endif + +// Forward declarations. +static void propListMetaCall(PySideProperty *pp, PyObject *self, QMetaObject::Call call, + void **args); + +// All registered python types and their creation functions. +static PyObject *pyTypes[PYSIDE_MAX_QML_TYPES]; +static void (*createFuncs[PYSIDE_MAX_QML_TYPES])(void *); + +// Mutex used to avoid race condition on PySide::nextQObjectMemoryAddr. +static QMutex nextQmlElementMutex; + +template +struct ElementFactoryBase +{ + static void createInto(void *memory) + { + QMutexLocker locker(&nextQmlElementMutex); + PySide::setNextQObjectMemoryAddr(memory); + Shiboken::GilState state; + PyObject *obj = PyObject_CallObject(pyTypes[N], 0); + if (!obj || PyErr_Occurred()) + PyErr_Print(); + PySide::setNextQObjectMemoryAddr(0); + } +}; + +template +struct ElementFactory : ElementFactoryBase +{ + static void init() + { + createFuncs[N] = &ElementFactoryBase::createInto; + ElementFactory::init(); + } +}; + +template<> +struct ElementFactory<0> : ElementFactoryBase<0> +{ + static void init() + { + createFuncs[0] = &ElementFactoryBase<0>::createInto; + } +}; + +int PySide::qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, + int versionMinor, const char *qmlName) +{ + using namespace Shiboken; + + static PyTypeObject *qobjectType = Shiboken::Conversions::getPythonTypeObject("QObject*"); + assert(qobjectType); + static int nextType = 0; + + if (nextType >= PYSIDE_MAX_QML_TYPES) { + PyErr_Format(PyExc_TypeError, "You can only export %d custom QML types to QML.", + PYSIDE_MAX_QML_TYPES); + return -1; + } + + PyTypeObject *pyObjType = reinterpret_cast(pyObj); + if (!PySequence_Contains(pyObjType->tp_mro, reinterpret_cast(qobjectType))) { + PyErr_Format(PyExc_TypeError, "A type inherited from %s expected, got %s.", + qobjectType->tp_name, pyObjType->tp_name); + return -1; + } + + const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObjType); + Q_ASSERT(metaObject); + + QQmlPrivate::RegisterType type; + type.version = 0; + + // Allow registering Qt Quick items. + bool registered = false; +#ifdef PYSIDE_QML_SUPPORT + QuickRegisterItemFunction quickRegisterItemFunction = getQuickRegisterItemFunction(); + if (quickRegisterItemFunction) { + registered = quickRegisterItemFunction(pyObj, uri, versionMajor, versionMinor, + qmlName, &type); + } +#endif + + // Register as simple QObject rather than Qt Quick item. + if (!registered) { + // Incref the type object, don't worry about decref'ing it because + // there's no way to unregister a QML type. + Py_INCREF(pyObj); + + pyTypes[nextType] = pyObj; + + // FIXME: Fix this to assign new type ids each time. + type.typeId = qMetaTypeId(); + type.listId = qMetaTypeId >(); + type.attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc(); + type.attachedPropertiesMetaObject = QQmlPrivate::attachedPropertiesMetaObject(); + + type.parserStatusCast = + QQmlPrivate::StaticCastSelector::cast(); + type.valueSourceCast = + QQmlPrivate::StaticCastSelector::cast(); + type.valueInterceptorCast = + QQmlPrivate::StaticCastSelector::cast(); + + int objectSize = static_cast(PySide::getSizeOfQObject( + reinterpret_cast(pyObj))); + type.objectSize = objectSize; + type.create = createFuncs[nextType]; + type.uri = uri; + type.versionMajor = versionMajor; + type.versionMinor = versionMinor; + type.elementName = qmlName; + + type.extensionObjectCreate = 0; + type.extensionMetaObject = 0; + type.customParser = 0; + ++nextType; + } + type.metaObject = metaObject; // Snapshot may have changed. + + int qmlTypeId = QQmlPrivate::qmlregister(QQmlPrivate::TypeRegistration, &type); + if (qmlTypeId == -1) { + PyErr_Format(PyExc_TypeError, "QML meta type registration of \"%s\" failed.", + qmlName); + } + return qmlTypeId; +} + +extern "C" +{ + +// This is the user data we store in the property. +struct QmlListProperty +{ + PyTypeObject *type; + PyObject *append; + PyObject *at; + PyObject *clear; + PyObject *count; +}; + +static int propListTpInit(PyObject *self, PyObject *args, PyObject *kwds) +{ + static const char *kwlist[] = {"type", "append", "at", "clear", "count", 0}; + PySideProperty *pySelf = reinterpret_cast(self); + QmlListProperty *data = new QmlListProperty; + memset(data, 0, sizeof(QmlListProperty)); + + if (!PyArg_ParseTupleAndKeywords(args, kwds, + "OO|OOO:QtQml.ListProperty", (char **) kwlist, + &data->type, + &data->append, + &data->at, + &data->clear, + &data->count)) { + return -1; + } + PySide::Property::setMetaCallHandler(pySelf, &propListMetaCall); + PySide::Property::setTypeName(pySelf, "QQmlListProperty"); + PySide::Property::setUserData(pySelf, data); + + return 0; +} + +void propListTpFree(void *self) +{ + auto pySelf = reinterpret_cast(self); + delete reinterpret_cast(PySide::Property::userData(pySelf)); + // calls base type constructor + Py_TYPE(pySelf)->tp_base->tp_free(self); +} + +static PyType_Slot PropertyListType_slots[] = { + {Py_tp_init, (void *)propListTpInit}, + {Py_tp_free, (void *)propListTpFree}, + {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {0, 0} +}; +static PyType_Spec PropertyListType_spec = { + "2:PySide2.QtQml.ListProperty", + sizeof(PySideProperty), + 0, + Py_TPFLAGS_DEFAULT, + PropertyListType_slots, +}; + + +PyTypeObject *PropertyListTypeF(void) +{ + static PyTypeObject *type = nullptr; + if (!type) { + PyObject *bases = Py_BuildValue("(O)", PySidePropertyTypeF()); + type = (PyTypeObject *)SbkType_FromSpecWithBases(&PropertyListType_spec, bases); + Py_XDECREF(bases); + } + return type; +} + +} // extern "C" + +// Implementation of QQmlListProperty::AppendFunction callback +void propListAppender(QQmlListProperty *propList, QObject *item) +{ + Shiboken::GilState state; + + Shiboken::AutoDecRef args(PyTuple_New(2)); + PyTuple_SET_ITEM(args, 0, Shiboken::Conversions::pointerToPython((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], propList->object)); + PyTuple_SET_ITEM(args, 1, Shiboken::Conversions::pointerToPython((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], item)); + + auto data = reinterpret_cast(propList->data); + Shiboken::AutoDecRef retVal(PyObject_CallObject(data->append, args)); + + if (PyErr_Occurred()) + PyErr_Print(); +} + +// Implementation of QQmlListProperty::CountFunction callback +int propListCount(QQmlListProperty *propList) +{ + Shiboken::GilState state; + + Shiboken::AutoDecRef args(PyTuple_New(1)); + PyTuple_SET_ITEM(args, 0, Shiboken::Conversions::pointerToPython((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], propList->object)); + + auto data = reinterpret_cast(propList->data); + Shiboken::AutoDecRef retVal(PyObject_CallObject(data->count, args)); + + // Check return type + int cppResult = 0; + PythonToCppFunc pythonToCpp = 0; + if (PyErr_Occurred()) + PyErr_Print(); + else if ((pythonToCpp = Shiboken::Conversions::isPythonToCppConvertible(Shiboken::Conversions::PrimitiveTypeConverter(), retVal))) + pythonToCpp(retVal, &cppResult); + return cppResult; +} + +// Implementation of QQmlListProperty::AtFunction callback +QObject *propListAt(QQmlListProperty *propList, int index) +{ + Shiboken::GilState state; + + Shiboken::AutoDecRef args(PyTuple_New(2)); + PyTuple_SET_ITEM(args, 0, Shiboken::Conversions::pointerToPython((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], propList->object)); + PyTuple_SET_ITEM(args, 1, Shiboken::Conversions::copyToPython(Shiboken::Conversions::PrimitiveTypeConverter(), &index)); + + auto data = reinterpret_cast(propList->data); + Shiboken::AutoDecRef retVal(PyObject_CallObject(data->at, args)); + + QObject *result = 0; + if (PyErr_Occurred()) + PyErr_Print(); + else if (PyType_IsSubtype(Py_TYPE(retVal), data->type)) + Shiboken::Conversions::pythonToCppPointer((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], retVal, &result); + return result; +} + +// Implementation of QQmlListProperty::ClearFunction callback +void propListClear(QQmlListProperty * propList) +{ + Shiboken::GilState state; + + Shiboken::AutoDecRef args(PyTuple_New(1)); + PyTuple_SET_ITEM(args, 0, Shiboken::Conversions::pointerToPython((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], propList->object)); + + auto data = reinterpret_cast(propList->data); + Shiboken::AutoDecRef retVal(PyObject_CallObject(data->clear, args)); + + if (PyErr_Occurred()) + PyErr_Print(); +} + +// qt_metacall specialization for ListProperties +static void propListMetaCall(PySideProperty *pp, PyObject *self, QMetaObject::Call call, void **args) +{ + if (call != QMetaObject::ReadProperty) + return; + + auto data = reinterpret_cast(PySide::Property::userData(pp)); + QObject *qobj; + Shiboken::Conversions::pythonToCppPointer((SbkObjectType *)SbkPySide2_QtCoreTypes[SBK_QOBJECT_IDX], self, &qobj); + QQmlListProperty declProp(qobj, data, &propListAppender, &propListCount, &propListAt, &propListClear); + + // Copy the data to the memory location requested by the meta call + void *v = args[0]; + *reinterpret_cast *>(v) = declProp; +} + +// VolatileBool (volatile bool) type definition. + +static PyObject * +QtQml_VolatileBoolObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + static const char *kwlist[] = {"x", 0}; + PyObject *x = Py_False; + long ok; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool", const_cast(kwlist), &x)) + return Q_NULLPTR; + ok = PyObject_IsTrue(x); + if (ok < 0) + return Q_NULLPTR; + + QtQml_VolatileBoolObject *self + = reinterpret_cast(type->tp_alloc(type, 0)); + + if (self != Q_NULLPTR) + self->flag = ok; + + return reinterpret_cast(self); +} + +static PyObject * +QtQml_VolatileBoolObject_get(QtQml_VolatileBoolObject *self) +{ + if (self->flag) + return Py_True; + return Py_False; +} + +static PyObject * +QtQml_VolatileBoolObject_set(QtQml_VolatileBoolObject *self, PyObject *args) +{ + PyObject *value = Py_False; + long ok; + + if (!PyArg_ParseTuple(args, "O:bool", &value)) { + return Q_NULLPTR; + } + + ok = PyObject_IsTrue(value); + if (ok < 0) { + PyErr_SetString(PyExc_TypeError, "Not a boolean value."); + return Q_NULLPTR; + } + + if (ok > 0) + self->flag = true; + else + self->flag = false; + + Py_RETURN_NONE; +} + +static PyMethodDef QtQml_VolatileBoolObject_methods[] = { + {"get", reinterpret_cast(QtQml_VolatileBoolObject_get), METH_NOARGS, + "B.get() -> Bool. Returns the value of the volatile boolean" + }, + {"set", reinterpret_cast(QtQml_VolatileBoolObject_set), METH_VARARGS, + "B.set(a) -> None. Sets the value of the volatile boolean" + }, + {Q_NULLPTR} /* Sentinel */ +}; + +static PyObject * +QtQml_VolatileBoolObject_repr(QtQml_VolatileBoolObject *self) +{ + PyObject *s; + + if (self->flag) + s = PyBytes_FromFormat("%s(True)", + Py_TYPE(self)->tp_name); + else + s = PyBytes_FromFormat("%s(False)", + Py_TYPE(self)->tp_name); + Py_XINCREF(s); + return s; +} + +static PyObject * +QtQml_VolatileBoolObject_str(QtQml_VolatileBoolObject *self) +{ + PyObject *s; + + if (self->flag) + s = PyBytes_FromFormat("%s(True) -> %p", + Py_TYPE(self)->tp_name, &(self->flag)); + else + s = PyBytes_FromFormat("%s(False) -> %p", + Py_TYPE(self)->tp_name, &(self->flag)); + Py_XINCREF(s); + return s; +} + +static PyType_Slot QtQml_VolatileBoolType_slots[] = { + {Py_tp_repr, (void *)reinterpret_cast(QtQml_VolatileBoolObject_repr)}, + {Py_tp_str, (void *)reinterpret_cast(QtQml_VolatileBoolObject_str)}, + {Py_tp_methods, (void *)QtQml_VolatileBoolObject_methods}, + {Py_tp_new, (void *)QtQml_VolatileBoolObject_new}, + {Py_tp_dealloc, (void *)Sbk_object_dealloc}, + {0, 0} +}; +static PyType_Spec QtQml_VolatileBoolType_spec = { + "2:PySide2.QtQml.VolatileBool", + sizeof(QtQml_VolatileBoolObject), + 0, + Py_TPFLAGS_DEFAULT, + QtQml_VolatileBoolType_slots, +}; + + +PyTypeObject *QtQml_VolatileBoolTypeF(void) +{ + static PyTypeObject *type = reinterpret_cast( + SbkType_FromSpec(&QtQml_VolatileBoolType_spec)); + return type; +} + +static const char *PropertyList_SignatureStrings[] = { + "PySide2.QtQml.ListProperty(type:type,append:typing.Callable," + "at:typing.Callable=None,clear:typing.Callable=None,count:typing.Callable=None)", + nullptr}; // Sentinel + +static const char *VolatileBool_SignatureStrings[] = { + "PySide2.QtQml.VolatileBool.get()->bool", + "PySide2.QtQml.VolatileBool.set(a:object)", + nullptr}; // Sentinel + +void PySide::initQmlSupport(PyObject *module) +{ + ElementFactory::init(); + + // Export QmlListProperty type + if (InitSignatureStrings(PropertyListTypeF(), PropertyList_SignatureStrings) < 0) { + PyErr_Print(); + qWarning() << "Error initializing PropertyList type."; + return; + } + + Py_INCREF(reinterpret_cast(PropertyListTypeF())); + PyModule_AddObject(module, PepType_GetNameStr(PropertyListTypeF()), + reinterpret_cast(PropertyListTypeF())); + + if (InitSignatureStrings(QtQml_VolatileBoolTypeF(), VolatileBool_SignatureStrings) < 0) { + PyErr_Print(); + qWarning() << "Error initializing VolatileBool type."; + return; + } + + Py_INCREF(QtQml_VolatileBoolTypeF()); + PyModule_AddObject(module, PepType_GetNameStr(QtQml_VolatileBoolTypeF()), + reinterpret_cast(QtQml_VolatileBoolTypeF())); +} diff --git a/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.h b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.h new file mode 100644 index 0000000..536348a --- /dev/null +++ b/sources/pyside2/PySide2/QtQml/pysideqmlregistertype.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PYSIDEQMLREGISTERTYPE_H +#define PYSIDEQMLREGISTERTYPE_H + +#include + +struct SbkObjectType; + +namespace PySide +{ + +extern void *nextQmlElementMemoryAddr; + +/** + * Init the QML support doing things like registering QtQml.ListProperty and create the necessary stuff for + * qmlRegisterType. + * + * \param module QtQml python module + */ +void initQmlSupport(PyObject *module); + +/** + * PySide implementation of qmlRegisterType function. + * + * \param pyObj Python type to be registered. + * \param uri QML element uri. + * \param versionMajor QML component major version. + * \param versionMinor QML component minor version. + * \param qmlName QML element name + * \return the metatype id of the registered type. + */ +int qmlRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor, + const char *qmlName); +} + +// Volatile Bool Ptr type definition. + +PyAPI_FUNC(PyTypeObject *) QtQml_VolatileBoolTypeF(void); + +#define VolatileBool_Check(op) (Py_TYPE(op) == QtQml_VolatileBoolTypeF()) + +#endif diff --git a/sources/pyside2/PySide2/QtQml/typesystem_qml.xml b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml new file mode 100644 index 0000000..0a12d44 --- /dev/null +++ b/sources/pyside2/PySide2/QtQml/typesystem_qml.xml @@ -0,0 +1,236 @@ + + + + + + + + + // Volatile Bool Ptr type definition. + + typedef struct { + PyObject_HEAD + volatile bool flag; + } QtQml_VolatileBoolObject; + + + + #include "pysideqmlregistertype.h" + + + + + + + + + + + + + + This function registers the Python type in the QML system with the name qmlName, in the library imported from uri having the version number composed from versionMajor and versionMinor. + Returns the QML type id. + + For example, this registers a Python class MySliderItem as a QML type named Slider for version 1.0 of a module called "com.mycompany.qmlcomponents": + + :: + + qmlRegisterType(MySliderItem, "com.mycompany.qmlcomponents", 1, 0, "Slider") + + Once this is registered, the type can be used in QML by importing the specified module name and version number: + + :: + + import com.mycompany.qmlcomponents 1.0 + + Slider { ... } + + Note that it's perfectly reasonable for a library to register types to older versions than the actual version of the library. Indeed, it is normal for the new library to allow QML written to previous versions to continue to work, even if more advanced versions of some of its types are available. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + volatile bool * %out = + &((reinterpret_cast<QtQml_VolatileBoolObject *>(%PYARG_1))->flag); + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtQuick/CMakeLists.txt b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt new file mode 100644 index 0000000..0f453c9 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuick/CMakeLists.txt @@ -0,0 +1,90 @@ +project(QtQuick) + +set(QtQuick_registerType "${QtQuick_SOURCE_DIR}/pysidequickregistertype.cpp") + +set(QtQuick_SRC +${QtQuick_GEN_DIR}/qquickframebufferobject_wrapper.cpp +${QtQuick_GEN_DIR}/qquickframebufferobject_renderer_wrapper.cpp +${QtQuick_GEN_DIR}/qquicktexturefactory_wrapper.cpp +${QtQuick_GEN_DIR}/qquickimageprovider_wrapper.cpp +${QtQuick_GEN_DIR}/qquicktransform_wrapper.cpp +${QtQuick_GEN_DIR}/qquickitem_wrapper.cpp +${QtQuick_GEN_DIR}/qquickitem_updatepaintnodedata_wrapper.cpp +${QtQuick_GEN_DIR}/qquickitemgrabresult_wrapper.cpp +${QtQuick_GEN_DIR}/qsharedpointer_qquickitemgrabresult_wrapper.cpp +${QtQuick_GEN_DIR}/qquickpainteditem_wrapper.cpp +${QtQuick_GEN_DIR}/qquickrendercontrol_wrapper.cpp +${QtQuick_GEN_DIR}/qquicktextdocument_wrapper.cpp +${QtQuick_GEN_DIR}/qquickview_wrapper.cpp +${QtQuick_GEN_DIR}/qquickwindow_wrapper.cpp +${QtQuick_GEN_DIR}/qsgabstractrenderer_wrapper.cpp +${QtQuick_GEN_DIR}/qsgbasicgeometrynode_wrapper.cpp +${QtQuick_GEN_DIR}/qsgclipnode_wrapper.cpp +${QtQuick_GEN_DIR}/qsgdynamictexture_wrapper.cpp +${QtQuick_GEN_DIR}/qsgengine_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgflatcolormaterial_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_attribute_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_attributeset_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_coloredpoint2d_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_point2d_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_texturedpoint2d_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometry_wrapper.cpp +${QtQuick_GEN_DIR}/qsggeometrynode_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgmaterial_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgmaterialshader_renderstate_wrapper.cpp +# Issue with virtual char const *const *attributeNames() +#${QtQuick_GEN_DIR}/qsgmaterialshader_wrapper.cpp +${QtQuick_GEN_DIR}/qsgmaterialtype_wrapper.cpp +${QtQuick_GEN_DIR}/qsgnode_wrapper.cpp +${QtQuick_GEN_DIR}/qsgopacitynode_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgopaquetexturematerial_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgsimplematerial_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgsimplematerialshader_wrapper.cpp +${QtQuick_GEN_DIR}/qsgsimplerectnode_wrapper.cpp +${QtQuick_GEN_DIR}/qsgsimpletexturenode_wrapper.cpp +${QtQuick_GEN_DIR}/qsgtexture_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgtexturematerial_wrapper.cpp +${QtQuick_GEN_DIR}/qsgtextureprovider_wrapper.cpp +${QtQuick_GEN_DIR}/qsgtransformnode_wrapper.cpp +#${QtQuick_GEN_DIR}/qsgvertexcolormaterial_wrapper.cpp +# module is always needed +${QtQuick_GEN_DIR}/qtquick_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Quick_VERSION VERSION_GREATER 5.5.1) + set(QtQuick_SRC ${QtQuick_SRC} + ${QtQuick_GEN_DIR}/qquickasyncimageprovider_wrapper.cpp + ${QtQuick_GEN_DIR}/qquickimageresponse_wrapper.cpp + ) +endif() + +set(QtQuick_include_dirs ${QtQuick_SOURCE_DIR} + ${QtQml_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtQml_GEN_DIR} + ${QtQuick_GEN_DIR}) + +set(QtQuick_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES}) + +set(QtQuick_deps QtGui QtNetwork QtQml) + +create_pyside_module(NAME QtQuick + INCLUDE_DIRS QtQuick_include_dirs + LIBRARIES QtQuick_libraries + DEPS QtQuick_deps + TYPESYSTEM_PATH QtQuick_SOURCE_DIR + SOURCES QtQuick_SRC + STATIC_SOURCES QtQuick_registerType) diff --git a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp new file mode 100644 index 0000000..a042ac2 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.cpp @@ -0,0 +1,253 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pysidequickregistertype.h" + +#include +#include +#include + +// Auto generated headers. +#include "qquickitem_wrapper.h" +#include "qquickpainteditem_wrapper.h" +#include "qquickframebufferobject_wrapper.h" +#include "pyside2_qtcore_python.h" +#include "pyside2_qtquick_python.h" +#include "pyside2_qtqml_python.h" + +#ifndef PYSIDE_MAX_QUICK_TYPES +// Maximum number of different Qt Quick types the user can export to QML using +// qmlRegisterType. This limit exists because the QML engine instantiates objects +// by calling a function with one argument (a void* pointer where the object should +// be created), and thus does not allow us to choose which object to create. Thus +// we create a C++ factory function for each new registered type at compile time. +# define PYSIDE_MAX_QUICK_TYPES 50 +#endif // !PYSIDE_MAX_QUICK_TYPES + +// All registered python types and their creation functions. +static PyObject *pyTypes[PYSIDE_MAX_QUICK_TYPES]; +static void (*createFuncs[PYSIDE_MAX_QUICK_TYPES])(void *); + +// Mutex used to avoid race condition on PySide::nextQObjectMemoryAddr. +static QMutex nextQmlElementMutex; + +// Python object factory functions. +template +struct ElementFactoryBase +{ + static void createQuickItem(void *memory) + { + QMutexLocker locker(&nextQmlElementMutex); + PySide::setNextQObjectMemoryAddr(memory); + Shiboken::GilState state; + PyObject *obj = PyObject_CallObject(pyTypes[N], 0); + if (!obj || PyErr_Occurred()) + PyErr_Print(); + PySide::setNextQObjectMemoryAddr(0); + } +}; + +template +struct ElementFactory : ElementFactoryBase +{ + static void init() + { + createFuncs[N] = &ElementFactoryBase::createQuickItem; + ElementFactory::init(); + } +}; + +template<> +struct ElementFactory<0> : ElementFactoryBase<0> +{ + static void init() + { + createFuncs[0] = &ElementFactoryBase<0>::createQuickItem; + } +}; + +#define PY_REGISTER_IF_INHERITS_FROM(className, typeToRegister,typePointerName, \ + typeListName, typeMetaObject, type, registered) \ + registerTypeIfInheritsFromClass(#className, typeToRegister, \ + typePointerName, typeListName, \ + typeMetaObject, type, registered) + +bool pyTypeObjectInheritsFromClass(PyTypeObject *pyObjType, QByteArray className) +{ + className.append('*'); + PyTypeObject *classPyType = Shiboken::Conversions::getPythonTypeObject(className.constData()); + bool isDerived = PySequence_Contains(pyObjType->tp_mro, + reinterpret_cast(classPyType)); + return isDerived; +} + +template +void registerTypeIfInheritsFromClass( + QByteArray className, + PyTypeObject *typeToRegister, + const QByteArray &typePointerName, + const QByteArray &typeListName, + const QMetaObject *typeMetaObject, + QQmlPrivate::RegisterType *type, + bool ®istered) +{ + bool shouldRegister = !registered && pyTypeObjectInheritsFromClass(typeToRegister, className); + if (shouldRegister) { + int ptrType = + QMetaType::registerNormalizedType( + typePointerName.constData(), + QtMetaTypePrivate::QMetaTypeFunctionHelper::Destruct, + QtMetaTypePrivate::QMetaTypeFunctionHelper::Construct, + sizeof(WrapperClass *), + static_cast< ::QFlags >(QtPrivate::QMetaTypeTypeFlags< + WrapperClass *>::Flags), + typeMetaObject); + if (ptrType == -1) { + PyErr_Format(PyExc_TypeError, "Meta type registration of \"%s\" for QML usage failed.", + typePointerName.constData()); + return; + } + + int lstType = + QMetaType::registerNormalizedType( + typeListName.constData(), + QtMetaTypePrivate::QMetaTypeFunctionHelper > + ::Destruct, + QtMetaTypePrivate::QMetaTypeFunctionHelper > + ::Construct, + sizeof(QQmlListProperty), + static_cast< ::QFlags >( + QtPrivate::QMetaTypeTypeFlags >::Flags), + nullptr); + if (lstType == -1) { + PyErr_Format(PyExc_TypeError, "Meta type registration of \"%s\" for QML usage failed.", + typeListName.constData()); + return; + } + + type->typeId = ptrType; + type->listId = lstType; + type->attachedPropertiesFunction = QQmlPrivate::attachedPropertiesFunc(); + type->attachedPropertiesMetaObject = + QQmlPrivate::attachedPropertiesMetaObject(); + type->parserStatusCast = + QQmlPrivate::StaticCastSelector::cast(); + type->valueSourceCast = + QQmlPrivate::StaticCastSelector::cast(); + type->valueInterceptorCast = + QQmlPrivate::StaticCastSelector::cast(); + type->objectSize = sizeof(WrapperClass); + registered = true; + } +} + +bool quickRegisterType(PyObject *pyObj, const char *uri, int versionMajor, int versionMinor, + const char *qmlName, QQmlPrivate::RegisterType *type) +{ + using namespace Shiboken; + static int nextType = 0; + + if (nextType >= PYSIDE_MAX_QUICK_TYPES) { + PyErr_Format(PyExc_TypeError, + "You can only export %d Qt Quick types to QML.", PYSIDE_MAX_QUICK_TYPES); + return false; + } + + PyTypeObject *pyObjType = reinterpret_cast(pyObj); + PyTypeObject *qQuickItemPyType = + Shiboken::Conversions::getPythonTypeObject("QQuickItem*"); + bool isQuickItem = PySequence_Contains(pyObjType->tp_mro, + reinterpret_cast(qQuickItemPyType)); + + // Register only classes that inherit QQuickItem or its children. + if (!isQuickItem) + return false; + + // Used inside macros to register the type. + const QMetaObject *metaObject = PySide::retrieveMetaObject(pyObj); + Q_ASSERT(metaObject); + + + // Incref the type object, don't worry about decref'ing it because + // there's no way to unregister a QML type. + Py_INCREF(pyObj); + + pyTypes[nextType] = pyObj; + + // Used in macro registration. + QByteArray pointerName(qmlName); + pointerName.append('*'); + QByteArray listName(qmlName); + listName.prepend("QQmlListProperty<"); + listName.append('>'); + + bool registered = false; + PY_REGISTER_IF_INHERITS_FROM(QQuickPaintedItem, pyObjType, pointerName, listName, metaObject, + type, registered); + PY_REGISTER_IF_INHERITS_FROM(QQuickFramebufferObject, pyObjType, pointerName, listName, + metaObject, type, registered); + PY_REGISTER_IF_INHERITS_FROM(QQuickItem, pyObjType, pointerName, listName, metaObject, + type, registered); + if (!registered) + return false; + + type->create = createFuncs[nextType]; + type->version = 0; + type->uri = uri; + type->versionMajor = versionMajor; + type->versionMinor = versionMinor; + type->elementName = qmlName; + type->metaObject = metaObject; + + type->extensionObjectCreate = 0; + type->extensionMetaObject = 0; + type->customParser = 0; + + ++nextType; + return true; +} + +void PySide::initQuickSupport(PyObject *module) +{ + Q_UNUSED(module); + ElementFactory::init(); +#ifdef PYSIDE_QML_SUPPORT + setQuickRegisterItemFunction(quickRegisterType); +#endif +} diff --git a/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.h b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.h new file mode 100644 index 0000000..1955413 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuick/pysidequickregistertype.h @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PYSIDE_QUICK_REGISTER_TYPE_H +#define PYSIDE_QUICK_REGISTER_TYPE_H + +#include + +struct SbkObjectType; + +namespace PySide +{ +void initQuickSupport(PyObject *module); +} + +#endif // PYSIDE_QUICK_REGISTER_TYPE_H diff --git a/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml new file mode 100644 index 0000000..223eff7 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuick/typesystem_quick.xml @@ -0,0 +1,175 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt b/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt new file mode 100644 index 0000000..8321d8a --- /dev/null +++ b/sources/pyside2/PySide2/QtQuickControls2/CMakeLists.txt @@ -0,0 +1,41 @@ +project(QtQuickControls2) + +set(QtQuickControls2_SRC +${QtQuickControls2_GEN_DIR}/qquickstyle_wrapper.cpp +# module is always needed +${QtQuickControls2_GEN_DIR}/qtquickcontrols2_module_wrapper.cpp +) + + +set(QtQuickControls2_include_dirs ${QtQuickControls2_SOURCE_DIR} + ${QtQml_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}QuickControls2_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtQml_GEN_DIR} + ${QtQuick_GEN_DIR} + ${QtQuickControls2_GEN_DIR}) + +set(QtQuickControls2_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}QuickControls2_LIBRARIES}) + +set(QtQuickControls2_deps QtGui QtNetwork QtQml QtQuick) + +create_pyside_module(NAME QtQuickControls2 + INCLUDE_DIRS QtQuickControls2_include_dirs + LIBRARIES QtQuickControls2_libraries + DEPS QtQuickControls2_deps + TYPESYSTEM_PATH QtQuickControls2_SOURCE_DIR + SOURCES QtQuickControls2_SRC) diff --git a/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml b/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml new file mode 100644 index 0000000..51d42b4 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuickControls2/typesystem_quickcontrols2.xml @@ -0,0 +1,47 @@ + + + + + + + + diff --git a/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt new file mode 100644 index 0000000..4da9bf8 --- /dev/null +++ b/sources/pyside2/PySide2/QtQuickWidgets/CMakeLists.txt @@ -0,0 +1,43 @@ +project(QtQuickWidgets) + +set(QtQuickWidgets_SRC +${QtQuickWidgets_GEN_DIR}/qquickwidget_wrapper.cpp +# module is always needed +${QtQuickWidgets_GEN_DIR}/qtquickwidgets_module_wrapper.cpp +) + +set(QtQuickWidgets_include_dirs ${QtQuickWidgets_SOURCE_DIR} + ${QtQml_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Quick_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Qml_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}QuickWidgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtGui_GEN_DIR} + ${QtCore_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtQuick_GEN_DIR} + ${QtQml_GEN_DIR} + ${QtQuickWidgets_GEN_DIR}) + +set(QtQuickWidgets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Quick_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Qml_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}QuickWidgets_LIBRARIES}) + +set(QtQuickWidgets_deps QtGui QtQml QtQuick QtWidgets QtNetwork) + +create_pyside_module(NAME QtQuickWidgets + INCLUDE_DIRS QtQuickWidgets_include_dirs + LIBRARIES QtQuickWidgets_libraries + DEPS QtQuickWidgets_deps + TYPESYSTEM_PATH QtQuickWidgets_SOURCE_DIR + SOURCES QtQuickWidgets_SRC) diff --git a/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml new file mode 100644 index 0000000..b272eec --- /dev/null +++ b/sources/pyside2/PySide2/QtQuickWidgets/typesystem_quickwidgets.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt b/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt new file mode 100644 index 0000000..98553b6 --- /dev/null +++ b/sources/pyside2/PySide2/QtRemoteObjects/CMakeLists.txt @@ -0,0 +1,45 @@ +project(QtRemoteObjects) + +set(QtRemoteObjects_SRC +${QtRemoteObjects_GEN_DIR}/qabstractitemmodelreplica_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectabstractpersistedstore_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectdynamicreplica_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjecthost_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjecthostbase_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectnode_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectpendingcall_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectpendingcallwatcher_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectregistry_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectregistryhost_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectreplica_wrapper.cpp +# ${QtRemoteObjects_GEN_DIR}/qtremoteobjects_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectsettingsstore_wrapper.cpp +${QtRemoteObjects_GEN_DIR}/qremoteobjectsourcelocationinfo_wrapper.cpp + +# module is always needed +${QtRemoteObjects_GEN_DIR}/qtremoteobjects_module_wrapper.cpp +) + +set(QtRemoteObjects_include_dirs ${QtRemoteObjects_SOURCE_DIR} + ${QtRemoteObjects_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}RemoteObjects_INCLUDE_DIRS} + ${SHIBOKEN_INCLUDE_DIR} + ${libpyside_SOURCE_DIR} + ${SHIBOKEN_PYTHON_INCLUDE_DIR} + ${QtCore_GEN_DIR}) + +set(QtRemoteObjects_libraries pyside2 + ${SHIBOKEN_PYTHON_LIBRARIES} + ${SHIBOKEN_LIBRARY} + ${Qt${QT_MAJOR_VERSION}RemoteObjects_LIBRARIES}) + +set(QtRemoteObjects_deps QtCore QtNetwork) + +create_pyside_module(NAME QtRemoteObjects + INCLUDE_DIRS QtRemoteObjects_include_dirs + LIBRARIES QtRemoteObjects_libraries + DEPS QtRemoteObjects_deps + TYPESYSTEM_PATH QtRemoteObjects_SOURCE_DIR + SOURCES QtRemoteObjects_SRC + TYPESYSTEM_NAME ${QtRemoteObjects_BINARY_DIR}/typesystem_remoteobjects.xml + ) diff --git a/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml b/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml new file mode 100644 index 0000000..b4f7ed1 --- /dev/null +++ b/sources/pyside2/PySide2/QtRemoteObjects/typesystem_remoteobjects.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtScript/CMakeLists.txt b/sources/pyside2/PySide2/QtScript/CMakeLists.txt new file mode 100644 index 0000000..81d6c03 --- /dev/null +++ b/sources/pyside2/PySide2/QtScript/CMakeLists.txt @@ -0,0 +1,42 @@ +project(QtScript) + +set(QtScript_SRC +${QtScript_GEN_DIR}/qscriptable_wrapper.cpp +${QtScript_GEN_DIR}/qscriptclass_wrapper.cpp +${QtScript_GEN_DIR}/qscriptclasspropertyiterator_wrapper.cpp +${QtScript_GEN_DIR}/qscriptcontext_wrapper.cpp +${QtScript_GEN_DIR}/qscriptcontextinfo_wrapper.cpp +${QtScript_GEN_DIR}/qscriptengineagent_wrapper.cpp +${QtScript_GEN_DIR}/qscriptprogram_wrapper.cpp +${QtScript_GEN_DIR}/qscriptengine_wrapper.cpp +${QtScript_GEN_DIR}/qscriptextensioninterface_wrapper.cpp +${QtScript_GEN_DIR}/qscriptextensionplugin_wrapper.cpp +${QtScript_GEN_DIR}/qscriptstring_wrapper.cpp +${QtScript_GEN_DIR}/qscriptvalue_wrapper.cpp +${QtScript_GEN_DIR}/qscriptvalueiterator_wrapper.cpp +# module is always needed +${QtScript_GEN_DIR}/qtscript_module_wrapper.cpp +) + +set(QtScript_glue_sources + "${QtScript_SOURCE_DIR}/qscript_value_iterator_glue.cpp" +) + +set(QtScript_include_dirs ${QtScript_SOURCE_DIR} + ${QtScript_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Script_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtScript_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Script_LIBRARIES}) +set(QtScript_deps QtCore) +create_pyside_module(NAME QtScript + INCLUDE_DIRS QtScript_include_dirs + LIBRARIES QtScript_libraries + DEPS QtScript_deps + TYPESYSTEM_PATH QtScript_SOURCE_DIR + SOURCES QtScript_SRC + GLUE_SOURCES QtScript_glue_sources) diff --git a/sources/pyside2/PySide2/QtScript/qscript_value_iterator_glue.cpp b/sources/pyside2/PySide2/QtScript/qscript_value_iterator_glue.cpp new file mode 100644 index 0000000..11dfd19 --- /dev/null +++ b/sources/pyside2/PySide2/QtScript/qscript_value_iterator_glue.cpp @@ -0,0 +1,3 @@ +%PYARG_0 = Shiboken::Object::newObject( + reinterpret_cast(Shiboken::SbkType< ::QScriptValueIterator >()), + new QScriptValueIterator(*%CPPSELF), true, true); diff --git a/sources/pyside2/PySide2/QtScript/typesystem_script.xml b/sources/pyside2/PySide2/QtScript/typesystem_script.xml new file mode 100644 index 0000000..1fdad5d --- /dev/null +++ b/sources/pyside2/PySide2/QtScript/typesystem_script.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt new file mode 100644 index 0000000..7c19856 --- /dev/null +++ b/sources/pyside2/PySide2/QtScriptTools/CMakeLists.txt @@ -0,0 +1,37 @@ +project(QtScriptTools) + +set(QtScriptTools_SRC +${QtScriptTools_GEN_DIR}/qscriptenginedebugger_wrapper.cpp +# module is always needed +${QtScriptTools_GEN_DIR}/qtscripttools_module_wrapper.cpp +) + +set(QtScriptTools_include_dirs ${QtScriptTools_SOURCE_DIR} + ${QtScriptTools_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Script_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}ScriptTools_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtScript_GEN_DIR} + ) + +set(QtScriptTools_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Script_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}ScriptTools_LIBRARIES}) + +set(QtScriptTools_deps QtCore QtScript QtGui QtWidgets) + +create_pyside_module(NAME QtScriptTools + INCLUDE_DIRS QtScriptTools_include_dirs + LIBRARIES QtScriptTools_libraries + DEPS QtScriptTools_deps + TYPESYSTEM_PATH QtScriptTools_SOURCE_DIR + SOURCES QtScriptTools_SRC) diff --git a/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml new file mode 100644 index 0000000..eefa09a --- /dev/null +++ b/sources/pyside2/PySide2/QtScriptTools/typesystem_scripttools.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtScxml/CMakeLists.txt b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt new file mode 100644 index 0000000..732253b --- /dev/null +++ b/sources/pyside2/PySide2/QtScxml/CMakeLists.txt @@ -0,0 +1,55 @@ +project(QtScxml) + +set(QtScxml_OPTIONAL_SRC ) +set(QtScxml_DROPPED_ENTRIES ) + +set(QtScxml_SRC +${QtScxml_GEN_DIR}/qscxmlcompiler_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlcompiler_loader_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlevent_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmldynamicscxmlservicefactory_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlinvokableservice_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlinvokableservicefactory_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlstaticscxmlservicefactory_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlstatemachine_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmltabledata_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlerror_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_assignmentinfo_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_evaluatorinfo_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_foreachinfo_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_invokeinfo_wrapper.cpp +${QtScxml_GEN_DIR}/qscxmlexecutablecontent_parameterinfo_wrapper.cpp +# module is always needed +${QtScxml_GEN_DIR}/qtscxml_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}Scxml_VERSION VERSION_EQUAL 5.12.0 + OR Qt${QT_MAJOR_VERSION}Scxml_VERSION VERSION_GREATER 5.12.0) + list(APPEND QtScxml_SRC + ${QtScxml_GEN_DIR}/qscxmldatamodel_wrapper.cpp + ${QtScxml_GEN_DIR}/qscxmldatamodel_foreachloopbody_wrapper.cpp + ${QtScxml_GEN_DIR}/qscxmlecmascriptdatamodel_wrapper.cpp + ${QtScxml_GEN_DIR}/qscxmlcppdatamodel_wrapper.cpp + ${QtScxml_GEN_DIR}/qscxmlnulldatamodel_wrapper.cpp) +endif() + +set(QtScxml_include_dirs ${QtScxml_SOURCE_DIR} + ${QtScxml_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Scxml_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtScxml_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Scxml_LIBRARIES}) + +set(QtScxml_deps QtCore) + +create_pyside_module(NAME QtScxml + INCLUDE_DIRS QtScxml_include_dirs + LIBRARIES QtScxml_libraries + DEPS QtScxml_deps + TYPESYSTEM_PATH QtScxml_SOURCE_DIR + SOURCES QtScxml_SRC + DROPPED_ENTRIES QtScxml_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml new file mode 100644 index 0000000..c00052c --- /dev/null +++ b/sources/pyside2/PySide2/QtScxml/typesystem_scxml.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtSensors/CMakeLists.txt b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt new file mode 100644 index 0000000..0bd6260 --- /dev/null +++ b/sources/pyside2/PySide2/QtSensors/CMakeLists.txt @@ -0,0 +1,100 @@ +project(QtSensors) + +set(QtSensors_OPTIONAL_SRC ) +set(QtSensors_DROPPED_ENTRIES ) + +set(QtSensors_SRC +# overrides QObject::metaObject() by private method +# ${QtSensors_GEN_DIR}/qsensorgesture_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorgesturemanager_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorgestureplugininterface_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorgesturerecognizer_wrapper.cpp + ${QtSensors_GEN_DIR}/qaccelerometer_wrapper.cpp + ${QtSensors_GEN_DIR}/qaccelerometerfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qaccelerometerreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qaltimeter_wrapper.cpp + ${QtSensors_GEN_DIR}/qaltimeterfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qaltimeterreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qambientlightfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qambientlightreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qambientlightsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qambienttemperaturefilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qambienttemperaturereading_wrapper.cpp + ${QtSensors_GEN_DIR}/qambienttemperaturesensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qcompass_wrapper.cpp + ${QtSensors_GEN_DIR}/qcompassfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qcompassreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qdistancefilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qdistancereading_wrapper.cpp + ${QtSensors_GEN_DIR}/qdistancesensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qgyroscope_wrapper.cpp + ${QtSensors_GEN_DIR}/qgyroscopefilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qgyroscopereading_wrapper.cpp + ${QtSensors_GEN_DIR}/qholsterfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qholsterreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qholstersensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qhumidityfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qhumidityreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qhumiditysensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qirproximityfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qirproximityreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qirproximitysensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qlidfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qlidreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qlidsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qlightfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qlightreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qlightsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qmagnetometer_wrapper.cpp + ${QtSensors_GEN_DIR}/qmagnetometerfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qmagnetometerreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qorientationfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qorientationreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qorientationsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qpressurefilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qpressurereading_wrapper.cpp + ${QtSensors_GEN_DIR}/qpressuresensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qproximityfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qproximityreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qproximitysensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qrotationfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qrotationreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qrotationsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qoutputrange_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorbackend_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorbackendfactory_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensormanager_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorchangesinterface_wrapper.cpp + ${QtSensors_GEN_DIR}/qsensorplugininterface_wrapper.cpp + ${QtSensors_GEN_DIR}/qtapfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qtapreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qtapsensor_wrapper.cpp + ${QtSensors_GEN_DIR}/qtiltfilter_wrapper.cpp + ${QtSensors_GEN_DIR}/qtiltreading_wrapper.cpp + ${QtSensors_GEN_DIR}/qtiltsensor_wrapper.cpp +# module is always needed + ${QtSensors_GEN_DIR}/qtsensors_module_wrapper.cpp +) + +set(QtSensors_include_dirs ${QtSensors_SOURCE_DIR} + ${QtSensors_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Sensors_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtSensors_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Sensors_LIBRARIES}) + +set(QtSensors_deps QtCore) + +create_pyside_module(NAME QtSensors + INCLUDE_DIRS QtSensors_include_dirs + LIBRARIES QtSensors_libraries + DEPS QtSensors_deps + TYPESYSTEM_PATH QtSensors_SOURCE_DIR + SOURCES QtSensors_SRC + DROPPED_ENTRIES QtSensors_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml b/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml new file mode 100644 index 0000000..31c0d2f --- /dev/null +++ b/sources/pyside2/PySide2/QtSensors/typesystem_sensors.xml @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt b/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt new file mode 100644 index 0000000..5242cad --- /dev/null +++ b/sources/pyside2/PySide2/QtSerialPort/CMakeLists.txt @@ -0,0 +1,31 @@ +project(QtSerialPort) + +set(QtSerialPort_OPTIONAL_SRC ) +set(QtSerialPort_DROPPED_ENTRIES ) + +set(QtSerialPort_SRC + ${QtSerialPort_GEN_DIR}/qserialport_wrapper.cpp + ${QtSerialPort_GEN_DIR}/qserialportinfo_wrapper.cpp +# module is always needed + ${QtSerialPort_GEN_DIR}/qtserialport_module_wrapper.cpp +) + +set(QtSerialPort_include_dirs ${QtSerialPort_SOURCE_DIR} + ${QtSerialPort_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}SerialPort_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtSerialPort_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}SerialPort_LIBRARIES}) + +set(QtSerialPort_deps QtCore) + +create_pyside_module(NAME QtSerialPort + INCLUDE_DIRS QtSerialPort_include_dirs + LIBRARIES QtSerialPort_libraries + DEPS QtSerialPort_deps + TYPESYSTEM_PATH QtSerialPort_SOURCE_DIR + SOURCES QtSerialPort_SRC + DROPPED_ENTRIES QtSerialPort_DROPPED_ENTRIES) diff --git a/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml new file mode 100644 index 0000000..8548c54 --- /dev/null +++ b/sources/pyside2/PySide2/QtSerialPort/typesystem_serialport.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtSql/CMakeLists.txt b/sources/pyside2/PySide2/QtSql/CMakeLists.txt new file mode 100644 index 0000000..40a2533 --- /dev/null +++ b/sources/pyside2/PySide2/QtSql/CMakeLists.txt @@ -0,0 +1,49 @@ +project(QtSql) + +set(QtSql_SRC +${QtSql_GEN_DIR}/qsql_wrapper.cpp +${QtSql_GEN_DIR}/qsqldatabase_wrapper.cpp +${QtSql_GEN_DIR}/qsqldriver_wrapper.cpp +${QtSql_GEN_DIR}/qsqldrivercreatorbase_wrapper.cpp +${QtSql_GEN_DIR}/qsqlerror_wrapper.cpp +${QtSql_GEN_DIR}/qsqlfield_wrapper.cpp +${QtSql_GEN_DIR}/qsqlindex_wrapper.cpp +${QtSql_GEN_DIR}/qsqlquery_wrapper.cpp +${QtSql_GEN_DIR}/qsqlquerymodel_wrapper.cpp +${QtSql_GEN_DIR}/qsqlrecord_wrapper.cpp +${QtSql_GEN_DIR}/qsqlrelation_wrapper.cpp +${QtSql_GEN_DIR}/qsqlrelationaldelegate_wrapper.cpp +${QtSql_GEN_DIR}/qsqlrelationaltablemodel_wrapper.cpp +${QtSql_GEN_DIR}/qsqlresult_wrapper.cpp +${QtSql_GEN_DIR}/qsqltablemodel_wrapper.cpp +# module is always needed +${QtSql_GEN_DIR}/qtsql_module_wrapper.cpp +) + +configure_file("${QtSql_SOURCE_DIR}/QtSql_global.pre.h.in" + "${QtSql_BINARY_DIR}/QtSql_global.pre.h" @ONLY) + +set(QtSql_include_dirs ${QtSql_SOURCE_DIR} + ${QtSql_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Sql_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ) +set(QtSql_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Sql_LIBRARIES}) +set(QtSql_deps QtWidgets) + +create_pyside_module(NAME QtSql + INCLUDE_DIRS QtSql_include_dirs + LIBRARIES QtSql_libraries + DEPS QtSql_deps + TYPESYSTEM_PATH QtSql_SOURCE_DIR + SOURCES QtSql_SRC) diff --git a/sources/pyside2/PySide2/QtSql/QtSql_global.pre.h.in b/sources/pyside2/PySide2/QtSql/QtSql_global.pre.h.in new file mode 100644 index 0000000..0c20c18 --- /dev/null +++ b/sources/pyside2/PySide2/QtSql/QtSql_global.pre.h.in @@ -0,0 +1,5 @@ +// QT_WIDGETS_LIB must be defined for QSqlRelationalDelegate to become visible. + +#if @Qt5Widgets_FOUND@ +# define QT_WIDGETS_LIB +#endif diff --git a/sources/pyside2/PySide2/QtSql/typesystem_sql.xml b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml new file mode 100644 index 0000000..408b5cd --- /dev/null +++ b/sources/pyside2/PySide2/QtSql/typesystem_sql.xml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtSvg/CMakeLists.txt b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt new file mode 100644 index 0000000..1976827 --- /dev/null +++ b/sources/pyside2/PySide2/QtSvg/CMakeLists.txt @@ -0,0 +1,36 @@ +project(QtSvg) + +set(QtSvg_SRC +${QtSvg_GEN_DIR}/qgraphicssvgitem_wrapper.cpp +${QtSvg_GEN_DIR}/qsvggenerator_wrapper.cpp +${QtSvg_GEN_DIR}/qsvgrenderer_wrapper.cpp +${QtSvg_GEN_DIR}/qsvgwidget_wrapper.cpp +# module is always needed +${QtSvg_GEN_DIR}/qtsvg_module_wrapper.cpp +) + +set(QtSvg_include_dirs ${QtSvg_SOURCE_DIR} + ${QtSvg_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Svg_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ) +set(QtSvg_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Svg_LIBRARIES} + ) +set(QtSvg_deps QtWidgets) + +create_pyside_module(NAME QtSvg + INCLUDE_DIRS QtSvg_include_dirs + LIBRARIES QtSvg_libraries + DEPS QtSvg_deps + TYPESYSTEM_PATH QtSvg_SOURCE_DIR + SOURCES QtSvg_SRC) diff --git a/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml new file mode 100644 index 0000000..079a79e --- /dev/null +++ b/sources/pyside2/PySide2/QtSvg/typesystem_svg.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtTest/CMakeLists.txt b/sources/pyside2/PySide2/QtTest/CMakeLists.txt new file mode 100644 index 0000000..04bb28c --- /dev/null +++ b/sources/pyside2/PySide2/QtTest/CMakeLists.txt @@ -0,0 +1,40 @@ +project(QtTest) + +set(QtTest_SRC +${QtTest_GEN_DIR}/qtest_pysideqtoucheventsequence_wrapper.cpp +${QtTest_GEN_DIR}/qtest_wrapper.cpp +# module is always needed +${QtTest_GEN_DIR}/qttest_module_wrapper.cpp +) + +configure_file("${QtTest_SOURCE_DIR}/QtTest_global.pre.h.in" + "${QtTest_BINARY_DIR}/QtTest_global.pre.h" @ONLY) + +configure_file("${QtTest_SOURCE_DIR}/QtTest_global.post.h.in" + "${QtTest_BINARY_DIR}/QtTest_global.post.h" @ONLY) + +set(QtTest_include_dirs ${QtTest_SOURCE_DIR} + ${QtTest_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Test_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ) +set(QtTest_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Test_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtTest_deps QtWidgets) + +create_pyside_module(NAME QtTest + INCLUDE_DIRS QtTest_include_dirs + LIBRARIES QtTest_libraries + DEPS QtTest_deps + TYPESYSTEM_PATH QtTest_SOURCE_DIR + SOURCES QtTest_SRC) diff --git a/sources/pyside2/PySide2/QtTest/QtTest_global.post.h.in b/sources/pyside2/PySide2/QtTest/QtTest_global.post.h.in new file mode 100644 index 0000000..ccd1815 --- /dev/null +++ b/sources/pyside2/PySide2/QtTest/QtTest_global.post.h.in @@ -0,0 +1 @@ +#include "pysideqtesttouch.h" diff --git a/sources/pyside2/PySide2/QtTest/QtTest_global.pre.h.in b/sources/pyside2/PySide2/QtTest/QtTest_global.pre.h.in new file mode 100644 index 0000000..65daf1b --- /dev/null +++ b/sources/pyside2/PySide2/QtTest/QtTest_global.pre.h.in @@ -0,0 +1,5 @@ +// QT_WIDGETS_LIB changes code generation in pysideqtesttouch.h + +#if @Qt5Widgets_FOUND@ +# define QT_WIDGETS_LIB +#endif diff --git a/sources/pyside2/PySide2/QtTest/typesystem_test.xml b/sources/pyside2/PySide2/QtTest/typesystem_test.xml new file mode 100644 index 0000000..f7facaf --- /dev/null +++ b/sources/pyside2/PySide2/QtTest/typesystem_test.xml @@ -0,0 +1,168 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt new file mode 100644 index 0000000..ebd95cf --- /dev/null +++ b/sources/pyside2/PySide2/QtTextToSpeech/CMakeLists.txt @@ -0,0 +1,30 @@ +project(QtTextToSpeech) + +set(QtTextToSpeech_SRC +${QtTextToSpeech_GEN_DIR}/qtexttospeech_wrapper.cpp +${QtTextToSpeech_GEN_DIR}/qtexttospeechengine_wrapper.cpp +${QtTextToSpeech_GEN_DIR}/qvoice_wrapper.cpp +# module is always needed +${QtTextToSpeech_GEN_DIR}/qttexttospeech_module_wrapper.cpp +) + +set(QtTextToSpeech_include_dirs ${QtTextToSpeech_SOURCE_DIR} + ${QtTextToSpeech_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}TextToSpeech_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR}) + +set(QtTextToSpeech_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Multimedia_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}TextToSpeech_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES}) + +set(QtTextToSpeech_deps QtCore QtMultimedia) + +create_pyside_module(NAME QtTextToSpeech + INCLUDE_DIRS QtTextToSpeech_include_dirs + LIBRARIES QtTextToSpeech_libraries + DEPS QtTextToSpeech_deps + TYPESYSTEM_PATH QtTextToSpeech_SOURCE_DIR + SOURCES QtTextToSpeech_SRC) diff --git a/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml new file mode 100644 index 0000000..48a5bc9 --- /dev/null +++ b/sources/pyside2/PySide2/QtTextToSpeech/typesystem_texttospeech.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt new file mode 100644 index 0000000..f9ca16e --- /dev/null +++ b/sources/pyside2/PySide2/QtUiTools/CMakeLists.txt @@ -0,0 +1,42 @@ +project(QtUiTools) + +set(QtUiTools_SRC +${QtUiTools_GEN_DIR}/quiloader_wrapper.cpp +# module is always needed +${QtUiTools_GEN_DIR}/qtuitools_module_wrapper.cpp +) + +set(QtUiTools_glue_sources + "${QtUiTools_SOURCE_DIR}/glue/plugins.h" +) + +set(QtUiTools_include_dirs ${QtUiTools_SOURCE_DIR} + ${QtUiTools_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Designer_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}UiTools_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${plugins_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtXml_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ) +set(QtUiTools_libraries pyside2 + uiplugin + ${Qt${QT_MAJOR_VERSION}UiTools_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ) +set(QtUiTools_deps QtWidgets QtXml) +create_pyside_module(NAME QtUiTools + INCLUDE_DIRS QtUiTools_include_dirs + LIBRARIES QtUiTools_libraries + DEPS QtUiTools_deps + TYPESYSTEM_PATH QtUiTools_SOURCE_DIR + SOURCES QtUiTools_SRC + GLUE_SOURCES QtUiTools_glue_sources) diff --git a/sources/pyside2/PySide2/QtUiTools/glue/plugins.h b/sources/pyside2/PySide2/QtUiTools/glue/plugins.h new file mode 100644 index 0000000..402965a --- /dev/null +++ b/sources/pyside2/PySide2/QtUiTools/glue/plugins.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef _PLUGIN_H_ +#define _PLUGIN_H_ + +#include "customwidgets.h" + +#include + +static inline PyCustomWidgets *findPlugin() +{ + const auto &instances = QPluginLoader::staticInstances(); + for (QObject *o : instances) { + if (auto plugin = qobject_cast(o)) + return plugin; + } + return nullptr; +} + +static void registerCustomWidget(PyObject *obj) +{ + static PyCustomWidgets *const plugin = findPlugin(); + + if (plugin) + plugin->registerWidgetType(obj); + else + qWarning("Qt for Python: Failed to find the static QUiLoader plugin."); +} + +#endif diff --git a/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml new file mode 100644 index 0000000..31f0b83 --- /dev/null +++ b/sources/pyside2/PySide2/QtUiTools/typesystem_uitools.xml @@ -0,0 +1,157 @@ + + + + + + + + + + + + + + + + + + + Registers a Python created custom widget to QUiLoader, so it can be recognized when + loading a `.ui` file. The custom widget type is passed via the ``customWidgetType`` argument. + This is needed when you want to override a virtual method of some widget in the interface, + since duck punching will not work with widgets created by QUiLoader based on the contents + of the `.ui` file. + + (Remember that `duck punching virtual methods is an invitation for your own demise! + <https://doc.qt.io/qtforpython/shiboken2/wordsofadvice.html#duck-punching-and-virtual-methods>`_) + + Let's see an obvious example. If you want to create a new widget it's probable you'll end up + overriding :class:`~PySide2.QtGui.QWidget`'s :meth:`~PySide2.QtGui.QWidget.paintEvent` method. + + .. code-block:: python + + class Circle(QWidget): + def paintEvent(self, event): + painter = QPainter(self) + painter.setPen(self.pen) + painter.setBrush(QBrush(self.color)) + painter.drawEllipse(event.rect().center(), 20, 20) + + # ... + + loader = QUiLoader() + loader.registerCustomWidget(Circle) + circle = loader.load('circle.ui') + circle.show() + + # ... + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt new file mode 100644 index 0000000..df95318 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebChannel/CMakeLists.txt @@ -0,0 +1,28 @@ +project(QtWebChannel) + +set(QtWebChannel_SRC +${QtWebChannel_GEN_DIR}/qwebchannel_wrapper.cpp +${QtWebChannel_GEN_DIR}/qwebchannelabstracttransport_wrapper.cpp +# module is always needed +${QtWebChannel_GEN_DIR}/qtwebchannel_module_wrapper.cpp +) + +set(QtWebChannel_include_dirs ${QtWebChannel_SOURCE_DIR} + ${QtWebChannel_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtWebChannel_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebChannel_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtWebChannel_deps QtCore) + +create_pyside_module(NAME QtWebChannel + INCLUDE_DIRS QtWebChannel_include_dirs + LIBRARIES QtWebChannel_libraries + DEPS QtWebChannel_deps + TYPESYSTEM_PATH QtWebChannel_SOURCE_DIR + SOURCES QtWebChannel_SRC) diff --git a/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml new file mode 100644 index 0000000..c47d5fa --- /dev/null +++ b/sources/pyside2/PySide2/QtWebChannel/typesystem_webchannel.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt new file mode 100644 index 0000000..e1460ff --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngine/CMakeLists.txt @@ -0,0 +1,27 @@ +project(QtWebEngine) + +set(QtWebEngine_SRC +${QtWebEngine_GEN_DIR}/qtwebengine_wrapper.cpp +# module is always needed +${QtWebEngine_GEN_DIR}/qtwebengine_module_wrapper.cpp +) + +set(QtWebEngine_include_dirs + ${QtWebEngine_SOURCE_DIR} + ${QtWebEngine_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtWebEngine_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebEngine_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtWebEngine_deps QtCore) +create_pyside_module(NAME QtWebEngine + INCLUDE_DIRS QtWebEngine_include_dirs + LIBRARIES QtWebEngine_libraries + DEPS QtWebEngine_deps + TYPESYSTEM_PATH QtWebEngine_SOURCE_DIR + SOURCES QtWebEngine_SRC) + diff --git a/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml b/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml new file mode 100644 index 0000000..7d0875a --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngine/typesystem_webengine.xml @@ -0,0 +1,45 @@ + + + + + + diff --git a/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt new file mode 100644 index 0000000..52a0716 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngineCore/CMakeLists.txt @@ -0,0 +1,41 @@ +project(QtWebEngineCore) + +set(QtWebEngineCore_SRC +${QtWebEngineCore_GEN_DIR}/qwebenginecookiestore_wrapper.cpp +${QtWebEngineCore_GEN_DIR}/qwebenginehttprequest_wrapper.cpp +${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestinfo_wrapper.cpp +${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestinterceptor_wrapper.cpp +${QtWebEngineCore_GEN_DIR}/qwebengineurlrequestjob_wrapper.cpp +${QtWebEngineCore_GEN_DIR}/qwebengineurlschemehandler_wrapper.cpp +# module is always needed +${QtWebEngineCore_GEN_DIR}/qtwebenginecore_module_wrapper.cpp +) + +if (Qt${QT_MAJOR_VERSION}WebEngineCore_VERSION VERSION_EQUAL 5.12.0 + OR Qt${QT_MAJOR_VERSION}WebEngineCore_VERSION VERSION_GREATER 5.12.0) + list(APPEND QtWebEngineCore_SRC + ${QtWebEngineCore_GEN_DIR}/qwebengineurlscheme_wrapper.cpp) +endif() + +set(QtWebEngineCore_include_dirs + ${QtWebEngineCore_SOURCE_DIR} + ${QtWebEngineCore_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtNetwork_GEN_DIR} + ) +set(QtWebEngineCore_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebEngineCore_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ) +set(QtWebEngineCore_deps QtCore QtNetwork) +create_pyside_module(NAME QtWebEngineCore + INCLUDE_DIRS QtWebEngineCore_include_dirs + LIBRARIES QtWebEngineCore_libraries + DEPS QtWebEngineCore_deps + TYPESYSTEM_PATH QtWebEngineCore_SOURCE_DIR + SOURCES QtWebEngineCore_SRC) + diff --git a/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml b/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml new file mode 100644 index 0000000..65c0e81 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngineCore/typesystem_webenginecore.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt new file mode 100644 index 0000000..b9fc1bc --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngineWidgets/CMakeLists.txt @@ -0,0 +1,55 @@ +project(QtWebEngineWidgets) + +set(QtWebEngineWidgets_SRC +${QtWebEngineWidgets_GEN_DIR}/qwebenginecertificateerror_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginedownloaditem_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginehistory_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginehistoryitem_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginepage_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebengineprofile_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginescript_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginescriptcollection_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginesettings_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebengineview_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginecontextmenudata_wrapper.cpp +${QtWebEngineWidgets_GEN_DIR}/qwebenginefullscreenrequest_wrapper.cpp +# module is always needed +${QtWebEngineWidgets_GEN_DIR}/qtwebenginewidgets_module_wrapper.cpp +) + +set(QtWebEngineWidgets_include_dirs + ${QtWebEngineWidgets_SOURCE_DIR} + ${QtWebEngineWidgets_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebChannel_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtWebEngineWidgets_GEN_DIR} + ${QtNetwork_GEN_DIR} + ${QtWebChannel_GEN_DIR} + ${QtWebEngineCore_GEN_DIR} + ${QtPrintSupport_GEN_DIR} + ) +set(QtWebEngineWidgets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebEngineWidgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}WebChannel_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}PrintSupport_LIBRARIES} + ) +set(QtWebEngineWidgets_deps QtGui QtWidgets QtNetwork QtWebChannel QtPrintSupport) +create_pyside_module(NAME QtWebEngineWidgets + INCLUDE_DIRS QtWebEngineWidgets_include_dirs + LIBRARIES QtWebEngineWidgets_libraries + DEPS QtWebEngineWidgets_deps + TYPESYSTEM_PATH QtWebEngineWidgets_SOURCE_DIR + SOURCES QtWebEngineWidgets_SRC) + diff --git a/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml new file mode 100644 index 0000000..2519101 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebEngineWidgets/typesystem_webenginewidgets.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt new file mode 100644 index 0000000..4220e46 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebKit/CMakeLists.txt @@ -0,0 +1,34 @@ +project(QtWebKit) + +set(QtWebKit_SRC +${QtWebKit_GEN_DIR}/webcore_wrapper.cpp +# module is always needed +${QtWebKit_GEN_DIR}/qtwebkit_module_wrapper.cpp +) + +set(QtWebKit_include_dirs ${QtWebKit_SOURCE_DIR} + ${QtWebKit_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebKit_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtNetwork_GEN_DIR} + ) +set(QtWebKit_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebKit_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtWebKit_deps QtGui QtNetwork) +create_pyside_module(NAME QtWebKit + INCLUDE_DIRS QtWebKit_include_dirs + LIBRARIES QtWebKit_libraries + DEPS QtWebKit_deps + TYPESYSTEM_PATH QtWebKit_SOURCE_DIR + SOURCES QtWebKit_SRC) + diff --git a/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml b/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml new file mode 100644 index 0000000..e92417f --- /dev/null +++ b/sources/pyside2/PySide2/QtWebKit/typesystem_webkit.xml @@ -0,0 +1,49 @@ + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt new file mode 100644 index 0000000..0bf660a --- /dev/null +++ b/sources/pyside2/PySide2/QtWebKitWidgets/CMakeLists.txt @@ -0,0 +1,65 @@ +project(QtWebKitWidgets) + +set(QtWebKitWidgets_SRC +${QtWebKitWidgets_GEN_DIR}/qgraphicswebview_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebdatabase_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebelement_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebelementcollection_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebframe_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebhistory_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebhistoryinterface_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebhistoryitem_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebhittestresult_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebinspector_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_choosemultiplefilesextensionoption_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_choosemultiplefilesextensionreturn_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_errorpageextensionoption_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_errorpageextensionreturn_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_extensionoption_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_extensionreturn_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_viewportattributes_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpage_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpluginfactory_mimetype_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpluginfactory_plugin_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebpluginfactory_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebsecurityorigin_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebsettings_wrapper.cpp +${QtWebKitWidgets_GEN_DIR}/qwebview_wrapper.cpp +# module is always needed +${QtWebKitWidgets_GEN_DIR}/qtwebkitwidgets_module_wrapper.cpp +) + +set(QtWebKitWidgets_include_dirs + ${QtWebKitWidgets_SOURCE_DIR} + ${QtWebKitWidgets_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebKit_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}PrintSupport_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebKitWidgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${QtPrintSupport_GEN_DIR} + ${QtWebKit_GEN_DIR} + ${QtNetwork_GEN_DIR} + ) +set(QtWebKitWidgets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebKit_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}WebKitWidgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) +set(QtWebKitWidgets_deps QtWidgets QtPrintSupport QtNetwork) +create_pyside_module(NAME QtWebKitWidgets + INCLUDE_DIRS QtWebKitWidgets_include_dirs + LIBRARIES QtWebKitWidgets_libraries + DEPS QtWebKitWidgets_deps + TYPESYSTEM_PATH QtWebKitWidgets_SOURCE_DIR + SOURCES QtWebKitWidgets_SRC) + diff --git a/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml new file mode 100644 index 0000000..7760c1c --- /dev/null +++ b/sources/pyside2/PySide2/QtWebKitWidgets/typesystem_webkitwidgets.xml @@ -0,0 +1,211 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt new file mode 100644 index 0000000..4a2c765 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebSockets/CMakeLists.txt @@ -0,0 +1,36 @@ +project(QtWebSockets) + +set(QtWebSockets_SRC +${QtWebSockets_GEN_DIR}/qmaskgenerator_wrapper.cpp +${QtWebSockets_GEN_DIR}/qwebsocket_wrapper.cpp +${QtWebSockets_GEN_DIR}/qwebsocketcorsauthenticator_wrapper.cpp +${QtWebSockets_GEN_DIR}/qwebsocketprotocol_wrapper.cpp +${QtWebSockets_GEN_DIR}/qwebsocketserver_wrapper.cpp +# module is always needed +${QtWebSockets_GEN_DIR}/qtwebsockets_module_wrapper.cpp +) + +set(QtWebSockets_include_dirs ${QtWebSockets_SOURCE_DIR} + ${QtWebSockets_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Network_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}WebSockets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtWebSockets_GEN_DIR} + ${QtNetwork_GEN_DIR} + ) +set(QtWebSockets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WebSockets_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Network_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ) + +set(QtWebSockets_deps QtNetwork) + +create_pyside_module(NAME QtWebSockets + INCLUDE_DIRS QtWebSockets_include_dirs + LIBRARIES QtWebSockets_libraries + DEPS QtWebSockets_deps + TYPESYSTEM_PATH QtWebSockets_SOURCE_DIR + SOURCES QtWebSockets_SRC) diff --git a/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml new file mode 100644 index 0000000..4257a99 --- /dev/null +++ b/sources/pyside2/PySide2/QtWebSockets/typesystem_websockets.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt new file mode 100644 index 0000000..506a6fc --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/CMakeLists.txt @@ -0,0 +1,236 @@ +project(QtWidgets) + +set(QtWidgets_SRC +${QtWidgets_GEN_DIR}/qaccessiblewidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractgraphicsshapeitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractitemdelegate_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractitemview_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractscrollarea_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractslider_wrapper.cpp +${QtWidgets_GEN_DIR}/qabstractspinbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qaction_wrapper.cpp +${QtWidgets_GEN_DIR}/qactiongroup_wrapper.cpp +${QtWidgets_GEN_DIR}/qapplication_wrapper.cpp +${QtWidgets_GEN_DIR}/qboxlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qbuttongroup_wrapper.cpp +${QtWidgets_GEN_DIR}/qcalendarwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qcheckbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qcolordialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qcolormap_wrapper.cpp +${QtWidgets_GEN_DIR}/qcolumnview_wrapper.cpp +${QtWidgets_GEN_DIR}/qcombobox_wrapper.cpp +${QtWidgets_GEN_DIR}/qcommandlinkbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qcommonstyle_wrapper.cpp +${QtWidgets_GEN_DIR}/qcompleter_wrapper.cpp +${QtWidgets_GEN_DIR}/qdatawidgetmapper_wrapper.cpp +${QtWidgets_GEN_DIR}/qdateedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qdatetimeedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qdesktopwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qdial_wrapper.cpp +${QtWidgets_GEN_DIR}/qdialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qdialogbuttonbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qdirmodel_wrapper.cpp +${QtWidgets_GEN_DIR}/qdockwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qdoublespinbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qerrormessage_wrapper.cpp +${QtWidgets_GEN_DIR}/qfiledialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qfileiconprovider_wrapper.cpp +${QtWidgets_GEN_DIR}/qfilesystemmodel_wrapper.cpp +${QtWidgets_GEN_DIR}/qfocusframe_wrapper.cpp +${QtWidgets_GEN_DIR}/qfontcombobox_wrapper.cpp +${QtWidgets_GEN_DIR}/qfontdialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qformlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qframe_wrapper.cpp +${QtWidgets_GEN_DIR}/qgesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qgestureevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgesturerecognizer_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsanchor_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsanchorlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsblureffect_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicscolorizeeffect_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsdropshadoweffect_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicseffect_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsellipseitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsgridlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsitemanimation_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsitemgroup_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicslayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicslayoutitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicslinearlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicslineitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsobject_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsopacityeffect_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicspathitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicspixmapitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicspolygonitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsproxywidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsrectitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsrotation_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscale_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscene_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenecontextmenuevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenedragdropevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicssceneevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenehelpevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenehoverevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenemouseevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenemoveevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicssceneresizeevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsscenewheelevent_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicssimpletextitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicstextitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicstransform_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicsview_wrapper.cpp +${QtWidgets_GEN_DIR}/qgraphicswidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qgridlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qgroupbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qhboxlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qheaderview_wrapper.cpp +${QtWidgets_GEN_DIR}/qinputdialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qitemdelegate_wrapper.cpp +${QtWidgets_GEN_DIR}/qitemeditorcreatorbase_wrapper.cpp +${QtWidgets_GEN_DIR}/qitemeditorfactory_wrapper.cpp +${QtWidgets_GEN_DIR}/qkeyeventtransition_wrapper.cpp +${QtWidgets_GEN_DIR}/qkeysequenceedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qlabel_wrapper.cpp +${QtWidgets_GEN_DIR}/qlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qlayoutitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qlcdnumber_wrapper.cpp +${QtWidgets_GEN_DIR}/qlineedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qlistview_wrapper.cpp +${QtWidgets_GEN_DIR}/qlistwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qlistwidgetitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qmainwindow_wrapper.cpp +${QtWidgets_GEN_DIR}/qmdiarea_wrapper.cpp +${QtWidgets_GEN_DIR}/qmdisubwindow_wrapper.cpp +${QtWidgets_GEN_DIR}/qmenu_wrapper.cpp +${QtWidgets_GEN_DIR}/qmenubar_wrapper.cpp +${QtWidgets_GEN_DIR}/qmessagebox_wrapper.cpp +${QtWidgets_GEN_DIR}/qmouseeventtransition_wrapper.cpp +${QtWidgets_GEN_DIR}/qopenglwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qpangesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qpinchgesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qplaintextdocumentlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qplaintextedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qprogressbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qprogressdialog_wrapper.cpp +${QtWidgets_GEN_DIR}/qproxystyle_wrapper.cpp +${QtWidgets_GEN_DIR}/qpushbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qradiobutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qrubberband_wrapper.cpp +${QtWidgets_GEN_DIR}/qscrollarea_wrapper.cpp +${QtWidgets_GEN_DIR}/qscrollbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qscroller_wrapper.cpp +${QtWidgets_GEN_DIR}/qscrollerproperties_wrapper.cpp +${QtWidgets_GEN_DIR}/qshortcut_wrapper.cpp +${QtWidgets_GEN_DIR}/qsizegrip_wrapper.cpp +${QtWidgets_GEN_DIR}/qsizepolicy_wrapper.cpp +${QtWidgets_GEN_DIR}/qslider_wrapper.cpp +${QtWidgets_GEN_DIR}/qspaceritem_wrapper.cpp +${QtWidgets_GEN_DIR}/qspinbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qsplashscreen_wrapper.cpp +${QtWidgets_GEN_DIR}/qsplitter_wrapper.cpp +${QtWidgets_GEN_DIR}/qsplitterhandle_wrapper.cpp +${QtWidgets_GEN_DIR}/qstackedlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qstackedwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qstatusbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyle_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleditemdelegate_wrapper.cpp +${QtWidgets_GEN_DIR}/qstylefactory_wrapper.cpp +${QtWidgets_GEN_DIR}/qstylehintreturn_wrapper.cpp +${QtWidgets_GEN_DIR}/qstylehintreturnmask_wrapper.cpp +${QtWidgets_GEN_DIR}/qstylehintreturnvariant_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoption_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptioncombobox_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptioncomplex_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiondockwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionfocusrect_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionframe_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiongraphicsitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiongroupbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionheader_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionmenuitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionprogressbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionrubberband_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionsizegrip_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionslider_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionspinbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontab_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontabbarbase_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontabwidgetframe_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontitlebar_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontoolbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontoolbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptiontoolbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qstyleoptionviewitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qstylepainter_wrapper.cpp +${QtWidgets_GEN_DIR}/qswipegesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qsystemtrayicon_wrapper.cpp +${QtWidgets_GEN_DIR}/qtabbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qtableview_wrapper.cpp +${QtWidgets_GEN_DIR}/qtablewidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qtablewidgetitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qtablewidgetselectionrange_wrapper.cpp +${QtWidgets_GEN_DIR}/qtabwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qtapandholdgesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qtapgesture_wrapper.cpp +${QtWidgets_GEN_DIR}/qtextbrowser_wrapper.cpp +${QtWidgets_GEN_DIR}/qtextedit_extraselection_wrapper.cpp +${QtWidgets_GEN_DIR}/qtextedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qtilerules_wrapper.cpp +${QtWidgets_GEN_DIR}/qtimeedit_wrapper.cpp +${QtWidgets_GEN_DIR}/qtoolbar_wrapper.cpp +${QtWidgets_GEN_DIR}/qtoolbox_wrapper.cpp +${QtWidgets_GEN_DIR}/qtoolbutton_wrapper.cpp +${QtWidgets_GEN_DIR}/qtooltip_wrapper.cpp +${QtWidgets_GEN_DIR}/qtreeview_wrapper.cpp +${QtWidgets_GEN_DIR}/qtreewidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qtreewidgetitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qtreewidgetitemiterator_wrapper.cpp +${QtWidgets_GEN_DIR}/qundocommand_wrapper.cpp +${QtWidgets_GEN_DIR}/qundogroup_wrapper.cpp +${QtWidgets_GEN_DIR}/qundostack_wrapper.cpp +${QtWidgets_GEN_DIR}/qundoview_wrapper.cpp +${QtWidgets_GEN_DIR}/qvboxlayout_wrapper.cpp +${QtWidgets_GEN_DIR}/qwhatsthis_wrapper.cpp +${QtWidgets_GEN_DIR}/qwidget_wrapper.cpp +${QtWidgets_GEN_DIR}/qwidgetaction_wrapper.cpp +${QtWidgets_GEN_DIR}/qwidgetitem_wrapper.cpp +${QtWidgets_GEN_DIR}/qwizard_wrapper.cpp +${QtWidgets_GEN_DIR}/qwizardpage_wrapper.cpp + +${SPECIFIC_OS_FILES} +# module is always needed +${QtWidgets_GEN_DIR}/qtwidgets_module_wrapper.cpp +) + +configure_file("${QtWidgets_SOURCE_DIR}/typesystem_widgets.xml.in" + "${QtWidgets_BINARY_DIR}/typesystem_widgets.xml" @ONLY) + +set(QtWidgets_include_dirs ${QtWidgets_SOURCE_DIR} + ${QtWidgets_BINARY_DIR} + ${pyside2_SOURCE_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ) +set(QtWidgets_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES} + ) +set(QtWidgets_deps QtGui) + +create_pyside_module(NAME QtWidgets + INCLUDE_DIRS QtWidgets_include_dirs + LIBRARIES QtWidgets_libraries + DEPS QtWidgets_deps + TYPESYSTEM_PATH QtWidgets_SOURCE_DIR + SOURCES QtWidgets_SRC + TYPESYSTEM_NAME ${QtWidgets_BINARY_DIR}/typesystem_widgets.xml) diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets.xml.in b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets.xml.in new file mode 100644 index 0000000..ea57b78 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets.xml.in @@ -0,0 +1,46 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml new file mode 100644 index 0000000..155591b --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml @@ -0,0 +1,3486 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +:: + + def callback_int(value_as_int): + print 'int value changed:', repr(value_as_int) + + app = QApplication(sys.argv) + spinbox = QSpinBox() + spinbox.valueChanged[unicode].connect(callback_unicode) + spinbox.show() + sys.exit(app.exec_()) + + + + +:: + + def callback_unicode(value_as_unicode): + print 'unicode value changed:', repr(value_as_unicode) + + app = QApplication(sys.argv) + spinbox = QSpinBox() + spinbox.valueChanged[unicode].connect(callback_unicode) + spinbox.show() + sys.exit(app.exec_()) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml new file mode 100644 index 0000000..af607ce --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_mac.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml new file mode 100644 index 0000000..4c51907 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_win.xml @@ -0,0 +1,42 @@ + + + diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml new file mode 100644 index 0000000..4c51907 --- /dev/null +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_x11.xml @@ -0,0 +1,42 @@ + + + diff --git a/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt new file mode 100644 index 0000000..6c877df --- /dev/null +++ b/sources/pyside2/PySide2/QtWinExtras/CMakeLists.txt @@ -0,0 +1,48 @@ +project(QtWinExtras) + +set(QtWinExtras_SRC +${QtWinExtras_GEN_DIR}/qtwin_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwincolorizationchangeevent_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwincompositionchangeevent_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinevent_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinjumplist_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinjumplistcategory_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinjumplistitem_wrapper.cpp +#${QtWinExtras_GEN_DIR}/qwinmime_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwintaskbarbutton_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwintaskbarprogress_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinthumbnailtoolbar_wrapper.cpp +${QtWinExtras_GEN_DIR}/qwinthumbnailtoolbutton_wrapper.cpp + +# module is always needed +${QtWinExtras_GEN_DIR}/qtwinextras_module_wrapper.cpp +) + +configure_file("${QtWinExtras_SOURCE_DIR}/QtWinExtras_global.pre.h.in" + "${QtWinExtras_BINARY_DIR}/QtWinExtras_global.pre.h" @ONLY) + +set(QtWinExtras_include_dirs ${QtWinExtras_SOURCE_DIR} + ${QtWinExtras_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}WinExtras_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Widgets_INCLUDE_DIRS} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${QtWidgets_GEN_DIR} + ${libpyside_SOURCE_DIR}) + +set(QtWinExtras_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}WinExtras_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Widgets_LIBRARIES}) + +set(QtWinExtras_deps QtCore QtGui QtWidgets) + +create_pyside_module(NAME QtWinExtras + INCLUDE_DIRS QtWinExtras_include_dirs + LIBRARIES QtWinExtras_libraries + DEPS QtWinExtras_deps + TYPESYSTEM_PATH QtWinExtras_SOURCE_DIR + SOURCES QtWinExtras_SRC) diff --git a/sources/pyside2/PySide2/QtWinExtras/QtWinExtras_global.pre.h.in b/sources/pyside2/PySide2/QtWinExtras/QtWinExtras_global.pre.h.in new file mode 100644 index 0000000..3a2b87c --- /dev/null +++ b/sources/pyside2/PySide2/QtWinExtras/QtWinExtras_global.pre.h.in @@ -0,0 +1,5 @@ +// QT_WIDGETS_LIB must be defined for the widget functions to become visible. + +#if @Qt5Widgets_FOUND@ +# define QT_WIDGETS_LIB +#endif diff --git a/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml b/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml new file mode 100644 index 0000000..69c90dd --- /dev/null +++ b/sources/pyside2/PySide2/QtWinExtras/typesystem_winextras.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt new file mode 100644 index 0000000..9008da7 --- /dev/null +++ b/sources/pyside2/PySide2/QtX11Extras/CMakeLists.txt @@ -0,0 +1,33 @@ +project(QtX11Extras) + +set(QtX11Extras_SRC +${QtX11Extras_GEN_DIR}/qx11info_wrapper.cpp +# module is always needed +${QtX11Extras_GEN_DIR}/qtx11extras_module_wrapper.cpp +) + +configure_file("${QtX11Extras_SOURCE_DIR}/QtX11Extras_global.post.h.in" + "${QtX11Extras_BINARY_DIR}/QtX11Extras_global.post.h" @ONLY) + +set(QtX11Extras_include_dirs ${QtX11Extras_SOURCE_DIR} + ${QtX11Extras_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}X11Extras_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Gui_INCLUDE_DIRS} + ${QtCore_GEN_DIR} + ${QtGui_GEN_DIR} + ${libpyside_SOURCE_DIR}) + +set(QtX11Extras_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}X11Extras_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}Gui_LIBRARIES}) + +set(QtX11Extras_deps QtCore QtGui) + +create_pyside_module(NAME QtX11Extras + INCLUDE_DIRS QtX11Extras_include_dirs + LIBRARIES QtX11Extras_libraries + DEPS QtX11Extras_deps + TYPESYSTEM_PATH QtX11Extras_SOURCE_DIR + SOURCES QtX11Extras_SRC) diff --git a/sources/pyside2/PySide2/QtX11Extras/QtX11Extras_global.post.h.in b/sources/pyside2/PySide2/QtX11Extras/QtX11Extras_global.post.h.in new file mode 100644 index 0000000..abdaf3d --- /dev/null +++ b/sources/pyside2/PySide2/QtX11Extras/QtX11Extras_global.post.h.in @@ -0,0 +1 @@ +#include diff --git a/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml b/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml new file mode 100644 index 0000000..73fc2b7 --- /dev/null +++ b/sources/pyside2/PySide2/QtX11Extras/typesystem_x11extras.xml @@ -0,0 +1,49 @@ + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtXml/CMakeLists.txt b/sources/pyside2/PySide2/QtXml/CMakeLists.txt new file mode 100644 index 0000000..eb64b47 --- /dev/null +++ b/sources/pyside2/PySide2/QtXml/CMakeLists.txt @@ -0,0 +1,55 @@ +project(QtXml) + +set(QtXml_SRC +${QtXml_GEN_DIR}/qdomattr_wrapper.cpp +${QtXml_GEN_DIR}/qdomcdatasection_wrapper.cpp +${QtXml_GEN_DIR}/qdomcharacterdata_wrapper.cpp +${QtXml_GEN_DIR}/qdomcomment_wrapper.cpp +${QtXml_GEN_DIR}/qdomdocument_wrapper.cpp +${QtXml_GEN_DIR}/qdomdocumentfragment_wrapper.cpp +${QtXml_GEN_DIR}/qdomdocumenttype_wrapper.cpp +${QtXml_GEN_DIR}/qdomelement_wrapper.cpp +${QtXml_GEN_DIR}/qdomentity_wrapper.cpp +${QtXml_GEN_DIR}/qdomentityreference_wrapper.cpp +${QtXml_GEN_DIR}/qdomimplementation_wrapper.cpp +${QtXml_GEN_DIR}/qdomnamednodemap_wrapper.cpp +${QtXml_GEN_DIR}/qdomnode_wrapper.cpp +${QtXml_GEN_DIR}/qdomnodelist_wrapper.cpp +${QtXml_GEN_DIR}/qdomnotation_wrapper.cpp +${QtXml_GEN_DIR}/qdomprocessinginstruction_wrapper.cpp +${QtXml_GEN_DIR}/qdomtext_wrapper.cpp +${QtXml_GEN_DIR}/qxmlattributes_wrapper.cpp +${QtXml_GEN_DIR}/qxmlcontenthandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmldeclhandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmldefaulthandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmldtdhandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmlentityresolver_wrapper.cpp +${QtXml_GEN_DIR}/qxmlerrorhandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmlinputsource_wrapper.cpp +${QtXml_GEN_DIR}/qxmllexicalhandler_wrapper.cpp +${QtXml_GEN_DIR}/qxmllocator_wrapper.cpp +${QtXml_GEN_DIR}/qxmlnamespacesupport_wrapper.cpp +${QtXml_GEN_DIR}/qxmlparseexception_wrapper.cpp +${QtXml_GEN_DIR}/qxmlreader_wrapper.cpp +${QtXml_GEN_DIR}/qxmlsimplereader_wrapper.cpp +# module is always needed +${QtXml_GEN_DIR}/qtxml_module_wrapper.cpp +) + +set(QtXml_include_dirs ${QtXml_SOURCE_DIR} + ${QtXml_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}Xml_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtXml_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Xml_LIBRARIES}) +set(QtXml_deps QtCore) + +create_pyside_module(NAME QtXml + INCLUDE_DIRS QtXml_include_dirs + LIBRARIES QtXml_libraries + DEPS QtXml_deps + TYPESYSTEM_PATH QtXml_SOURCE_DIR + SOURCES QtXml_SRC) diff --git a/sources/pyside2/PySide2/QtXml/typesystem_xml.xml b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml new file mode 100644 index 0000000..96d12ea --- /dev/null +++ b/sources/pyside2/PySide2/QtXml/typesystem_xml.xml @@ -0,0 +1,401 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt new file mode 100644 index 0000000..adc1be5 --- /dev/null +++ b/sources/pyside2/PySide2/QtXmlPatterns/CMakeLists.txt @@ -0,0 +1,41 @@ +project(QtXmlPatterns) + +set(QtXmlPatterns_SRC +${QtXmlPatterns_GEN_DIR}/qabstractmessagehandler_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qabstracturiresolver_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qabstractxmlnodemodel_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qabstractxmlreceiver_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qsourcelocation_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlformatter_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlitem_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlnamepool_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlname_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlnodemodelindex_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlquery_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlresultitems_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlschemavalidator_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlschema_wrapper.cpp +${QtXmlPatterns_GEN_DIR}/qxmlserializer_wrapper.cpp +## always needed +${QtXmlPatterns_GEN_DIR}/qtxmlpatterns_module_wrapper.cpp +) + +set(QtXmlPatterns_include_dirs ${QtXmlPatterns_SOURCE_DIR} + ${QtXmlPatterns_BINARY_DIR} + ${Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS} + ${Qt${QT_MAJOR_VERSION}XmlPatterns_INCLUDE_DIRS} + ${libpyside_SOURCE_DIR} + ${QtCore_GEN_DIR} + ) +set(QtXmlPatterns_libraries pyside2 + ${Qt${QT_MAJOR_VERSION}Core_LIBRARIES} + ${Qt${QT_MAJOR_VERSION}XmlPatterns_LIBRARIES}) +set(QtXmlPatterns_deps QtCore) + +create_pyside_module(NAME QtXmlPatterns + INCLUDE_DIRS QtXmlPatterns_include_dirs + LIBRARIES QtXmlPatterns_libraries + DEPS QtXmlPatterns_deps + TYPESYSTEM_PATH QtXmlPatterns_SOURCE_DIR + SOURCES QtXmlPatterns_SRC) + diff --git a/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml new file mode 100644 index 0000000..1e8eec0 --- /dev/null +++ b/sources/pyside2/PySide2/QtXmlPatterns/typesystem_xmlpatterns.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/__init__.py.in b/sources/pyside2/PySide2/__init__.py.in new file mode 100644 index 0000000..035cdd6 --- /dev/null +++ b/sources/pyside2/PySide2/__init__.py.in @@ -0,0 +1,107 @@ +from __future__ import print_function +import os +import sys +from textwrap import dedent + +__all__ = list("Qt" + body for body in + "@all_module_shortnames@" + .split(";")) +__version__ = "@FINAL_PACKAGE_VERSION@" +__version_info__ = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@") + + +def _additional_dll_directories(package_dir): + # Find shiboken2 relative to the package directory. + root = os.path.dirname(package_dir) + # Check for a flat .zip as deployed by cx_free(PYSIDE-1257) + if root.endswith('.zip'): + return [] + shiboken2 = os.path.join(root, 'shiboken2') + if os.path.isdir(shiboken2): # Standard case, only shiboken2 is needed + return [shiboken2] + # The below code is for the build process when generate_pyi.py + # is executed in the build directory. We need libpyside and Qt in addition. + shiboken2 = os.path.join(os.path.dirname(root), 'shiboken2', 'libshiboken') + if not os.path.isdir(shiboken2): + raise ImportError(shiboken2 + ' does not exist') + result = [shiboken2, os.path.join(root, 'libpyside')] + for path in os.environ.get('PATH').split(';'): + if path: + if os.path.exists(os.path.join(path, 'qmake.exe')): + result.append(path) + break + return result + + +def _setupQtDirectories(): + # On Windows we need to explicitly import the shiboken2 module so + # that the libshiboken.dll dependency is loaded by the time a + # Qt module is imported. Otherwise due to PATH not containing + # the shiboken2 module path, the Qt module import would fail + # due to the missing libshiboken dll. + # In addition, as of Python 3.8, the shiboken package directory + # must be added to the DLL search paths so that shiboken2.dll + # is found. + # We need to do the same on Linux and macOS, because we do not + # embed rpaths into the PySide2 libraries that would point to + # the libshiboken library location. Importing the module + # loads the libraries into the process memory beforehand, and + # thus takes care of it for us. + + pyside_package_dir = os.path.abspath(os.path.dirname(__file__)) + + if sys.platform == 'win32' and sys.version_info[0] == 3 and sys.version_info[1] >= 8: + for dir in _additional_dll_directories(pyside_package_dir): + os.add_dll_directory(dir) + + try: + import shiboken2 + except Exception: + paths = ', '.join(sys.path) + print('PySide2/__init__.py: Unable to import shiboken2 from {}'.format(paths), + file=sys.stderr) + raise + + # Trigger signature initialization. + try: + # PYSIDE-829: Avoid non-existent attributes in compiled code (Nuitka). + # We now use an explicit function instead of touching a signature. + _init_pyside_extension() + except AttributeError: + print(dedent('''\ + {stars} + PySide2/__init__.py: The `signature` module was not initialized. + This libshiboken module was loaded from + + "{shiboken2.__file__}". + + Please make sure that this is the real shiboken2 binary and not just a folder. + {stars} + ''').format(stars=79*"*", **locals()), file=sys.stderr) + raise + + if sys.platform == 'win32': + # PATH has to contain the package directory, otherwise plugins + # won't be able to find their required Qt libraries (e.g. the + # svg image plugin won't find Qt5Svg.dll). + os.environ['PATH'] = pyside_package_dir + os.pathsep + os.environ['PATH'] + + # On Windows, add the PySide2\openssl folder (created by setup.py's + # --openssl option) to the PATH so that the SSL DLLs can be found + # when Qt tries to dynamically load them. Tell Qt to load them and + # then reset the PATH. + openssl_dir = os.path.join(pyside_package_dir, 'openssl') + if os.path.exists(openssl_dir): + path = os.environ['PATH'] + try: + os.environ['PATH'] = openssl_dir + os.pathsep + path + try: + from . import QtNetwork + except ImportError: + pass + else: + QtNetwork.QSslSocket.supportsSsl() + finally: + os.environ['PATH'] = path + +_setupQtDirectories() diff --git a/sources/pyside2/PySide2/_config.py.in b/sources/pyside2/PySide2/_config.py.in new file mode 100644 index 0000000..740e9a0 --- /dev/null +++ b/sources/pyside2/PySide2/_config.py.in @@ -0,0 +1,16 @@ +built_modules = list(name for name in + "@all_module_shortnames@" + .split(";")) + +shiboken_library_soversion = str(@SHIBOKEN_SO_VERSION@) +pyside_library_soversion = str(@PYSIDE_SO_VERSION@) + +version = "@FINAL_PACKAGE_VERSION@" +version_info = (@BINDING_API_MAJOR_VERSION@, @BINDING_API_MINOR_VERSION@, @BINDING_API_MICRO_VERSION@, "@BINDING_API_PRE_RELEASE_VERSION_TYPE@", "@BINDING_API_PRE_RELEASE_VERSION@") + +@PACKAGE_BUILD_DATE@ +@PACKAGE_BUILD_COMMIT_DATE@ +@PACKAGE_BUILD_COMMIT_HASH@ +@PACKAGE_BUILD_COMMIT_HASH_DESCRIBED@ +@PACKAGE_SETUP_PY_PACKAGE_TIMESTAMP_ASSIGNMENT@ +@PACKAGE_SETUP_PY_PACKAGE_VERSION_ASSIGNMENT@ diff --git a/sources/pyside2/PySide2/global.h.in b/sources/pyside2/PySide2/global.h.in new file mode 100644 index 0000000..a23b0f3 --- /dev/null +++ b/sources/pyside2/PySide2/global.h.in @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Make "signals:", "slots:" visible as access specifiers +#define QT_ANNOTATE_ACCESS_SPECIFIER(a) __attribute__((annotate(#a))) + +// Q_PROPERTY is defined as class annotation which does not work since a +// sequence of properties will to expand to a sequence of annotations +// annotating nothing, causing clang to complain. Instead, define it away in a +// static assert with the stringified argument in a ','-operator (cf qdoc). + +#define QT_ANNOTATE_CLASS(type,...) static_assert(sizeof(#__VA_ARGS__),#type); + +#include + +#if @ENABLE_X11@ + #define Q_OS_X11 +#elif @ENABLE_MAC@ + #define Q_OS_MAC +#elif @ENABLE_WIN@ + #define Q_OS_WIN +#endif + +// There are symbols in Qt that exist in Debug but +// not in release +#define QT_NO_DEBUG + +// Here are now all configured modules appended: diff --git a/sources/pyside2/PySide2/glue/qtcharts.cpp b/sources/pyside2/PySide2/glue/qtcharts.cpp new file mode 100644 index 0000000..1828fec --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtcharts.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qchart-releaseownership +Shiboken::Object::releaseOwnership(%PYARG_1); +// @snippet qchart-releaseownership diff --git a/sources/pyside2/PySide2/glue/qtcore.cpp b/sources/pyside2/PySide2/glue/qtcore.cpp new file mode 100644 index 0000000..306a223 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtcore.cpp @@ -0,0 +1,2034 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// @snippet include-pyside +#include +#include +// @snippet include-pyside + +// @snippet pystring-check +bool py2kStrCheck(PyObject *obj) +{ +#ifdef IS_PY3K + return false; +#else + return PyString_Check(obj); +#endif +} +// @snippet pystring-check + +// @snippet qsettings-value +// If we enter the kwds, means that we have a defaultValue or +// at least a type. +// This avoids that we are passing '0' as defaultValue. +// defaultValue can also be passed as positional argument, +// not only as keyword. +QVariant out; +if (kwds || numArgs > 1) { + Py_BEGIN_ALLOW_THREADS + out = %CPPSELF.value(%1, %2); + Py_END_ALLOW_THREADS +} else { + Py_BEGIN_ALLOW_THREADS + out = %CPPSELF.value(%1); + Py_END_ALLOW_THREADS +} + +PyTypeObject *typeObj = reinterpret_cast(%PYARG_3); + +if (typeObj) { + if (typeObj == &PyList_Type) { + QByteArray out_ba = out.toByteArray(); + if (!out_ba.isEmpty()) { + QByteArrayList valuesList = out_ba.split(','); + const int valuesSize = valuesList.size(); + if (valuesSize > 0) { + PyObject *list = PyList_New(valuesSize); + for (int i = 0; i < valuesSize; i++) { + PyObject *item = PyUnicode_FromString(valuesList[i].data()); + PyList_SET_ITEM(list, i, item); + } + %PYARG_0 = list; + + } else { + %PYARG_0 = %CONVERTTOPYTHON[QVariant](out); + } + } else { + %PYARG_0 = PyList_New(0); + } + } else if (typeObj == &PyBytes_Type) { + QByteArray asByteArray = out.toByteArray(); + %PYARG_0 = PyBytes_FromString(asByteArray.data()); + } else if (typeObj == &PyUnicode_Type) { + QByteArray asByteArray = out.toByteArray(); + %PYARG_0 = PyUnicode_FromString(asByteArray.data()); +#ifdef IS_PY3K + } else if (typeObj == &PyLong_Type) { + float asFloat = out.toFloat(); + pyResult = PyLong_FromDouble(asFloat); +#else + } else if (typeObj == &PyInt_Type) { + float asFloat = out.toFloat(); + pyResult = PyInt_FromLong(long(asFloat)); +#endif + } else if (typeObj == &PyFloat_Type) { + float asFloat = out.toFloat(); + %PYARG_0 = PyFloat_FromDouble(asFloat); + } else if (typeObj == &PyBool_Type) { + if (out.toBool()) { + Py_INCREF(Py_True); + %PYARG_0 = Py_True; + } else { + Py_INCREF(Py_False); + %PYARG_0 = Py_False; + } + } + // TODO: PyDict_Type and PyTuple_Type +} +else { + if (!out.isValid()) { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; + } else { + %PYARG_0 = %CONVERTTOPYTHON[QVariant](out); + } +} + +// @snippet qsettings-value + +// @snippet qvariant-conversion +static const char *QVariant_resolveMetaType(PyTypeObject *type, int *typeId) +{ + if (PyObject_TypeCheck(type, SbkObjectType_TypeF())) { + auto sbkType = reinterpret_cast(type); + const char *typeName = Shiboken::ObjectType::getOriginalName(sbkType); + if (!typeName) + return nullptr; + const bool valueType = '*' != typeName[qstrlen(typeName) - 1]; + // Do not convert user type of value + if (valueType && Shiboken::ObjectType::isUserType(type)) + return nullptr; + int obTypeId = QMetaType::type(typeName); + if (obTypeId) { + *typeId = obTypeId; + return typeName; + } + // Do not resolve types to value type + if (valueType) + return nullptr; + // Find in base types. First check tp_bases, and only after check tp_base, because + // tp_base does not always point to the first base class, but rather to the first + // that has added any python fields or slots to its object layout. + // See https://mail.python.org/pipermail/python-list/2009-January/520733.html + if (type->tp_bases) { + for (int i = 0, size = PyTuple_GET_SIZE(type->tp_bases); i < size; ++i) { + const char *derivedName = QVariant_resolveMetaType(reinterpret_cast(PyTuple_GET_ITEM( + type->tp_bases, i)), typeId); + if (derivedName) + return derivedName; + } + } + else if (type->tp_base) { + return QVariant_resolveMetaType(type->tp_base, typeId); + } + } + *typeId = 0; + return nullptr; +} +static QVariant QVariant_convertToValueList(PyObject *list) +{ + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return QVariant(); + } + + Shiboken::AutoDecRef element(PySequence_GetItem(list, 0)); + int typeId; + const char *typeName = QVariant_resolveMetaType(element.cast(), &typeId); + if (typeName) { + QByteArray listTypeName("QList<"); + listTypeName += typeName; + listTypeName += '>'; + typeId = QMetaType::type(listTypeName); + if (typeId > 0) { + Shiboken::Conversions::SpecificConverter converter(listTypeName); + if (converter) { + QVariant var(typeId, nullptr); + converter.toCpp(list, &var); + return var; + } + qWarning() << "Type converter for :" << listTypeName << "not registered."; + } + } + return QVariant(); +} +static bool QVariant_isStringList(PyObject *list) +{ + if (!PySequence_Check(list)) { + // If it is not a list or a derived list class + // we assume that will not be a String list neither. + return false; + } + + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return false; + } + + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) + return false; + } + return true; +} +static QVariant QVariant_convertToVariantMap(PyObject *map) +{ + Py_ssize_t pos = 0; + Shiboken::AutoDecRef keys(PyDict_Keys(map)); + if (!QVariant_isStringList(keys)) + return QVariant(); + PyObject *key; + PyObject *value; + QMap ret; + while (PyDict_Next(map, &pos, &key, &value)) { + QString cppKey = %CONVERTTOCPP[QString](key); + QVariant cppValue = %CONVERTTOCPP[QVariant](value); + ret.insert(cppKey, cppValue); + } + return QVariant(ret); +} +static QVariant QVariant_convertToVariantList(PyObject *list) +{ + if (QVariant_isStringList(list)) { + QList lst = %CONVERTTOCPP[QList](list); + return QVariant(QStringList(lst)); + } + QVariant valueList = QVariant_convertToValueList(list); + if (valueList.isValid()) + return valueList; + + if (PySequence_Size(list) < 0) { + // clear the error if < 0 which means no length at all + PyErr_Clear(); + return QVariant(); + } + + QList lst; + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject *pyItem = PySequence_Fast_GET_ITEM(fast.object(), i); + QVariant item = %CONVERTTOCPP[QVariant](pyItem); + lst.append(item); + } + return QVariant(lst); +} +// @snippet qvariant-conversion + +// @snippet qvariantmap-check +static bool QVariantType_isStringList(PyObject *list) +{ + Shiboken::AutoDecRef fast(PySequence_Fast(list, "Failed to convert QVariantList")); + const Py_ssize_t size = PySequence_Fast_GET_SIZE(fast.object()); + for (Py_ssize_t i=0; i < size; i++) { + PyObject *item = PySequence_Fast_GET_ITEM(fast.object(), i); + if (!%CHECKTYPE[QString](item)) + return false; + } + return true; +} +static bool QVariantType_checkAllStringKeys(PyObject *dict) +{ + Shiboken::AutoDecRef keys(PyDict_Keys(dict)); + return QVariantType_isStringList(keys); +} +// @snippet qvariantmap-check + +// @snippet qt-qabs +double _abs = qAbs(%1); +%PYARG_0 = %CONVERTTOPYTHON[double](_abs); +// @snippet qt-qabs + +// @snippet qt-postroutine +namespace PySide { +static QStack globalPostRoutineFunctions; +void globalPostRoutineCallback() +{ + Shiboken::GilState state; + for (auto *callback : globalPostRoutineFunctions) { + Shiboken::AutoDecRef result(PyObject_CallObject(callback, nullptr)); + Py_DECREF(callback); + } + globalPostRoutineFunctions.clear(); +} +void addPostRoutine(PyObject *callback) +{ + if (PyCallable_Check(callback)) { + globalPostRoutineFunctions << callback; + Py_INCREF(callback); + } else { + PyErr_SetString(PyExc_TypeError, "qAddPostRoutine: The argument must be a callable object."); + } +} +} // namespace +// @snippet qt-postroutine + +// @snippet qt-addpostroutine +PySide::addPostRoutine(%1); +// @snippet qt-addpostroutine + +// @snippet qt-qaddpostroutine +qAddPostRoutine(PySide::globalPostRoutineCallback); +// @snippet qt-qaddpostroutine + +// @snippet qt-version +QList version = QByteArray(qVersion()).split('.'); +PyObject *pyQtVersion = PyTuple_New(3); +for (int i = 0; i < 3; ++i) + PyTuple_SET_ITEM(pyQtVersion, i, PyInt_FromLong(version[i].toInt())); +PyModule_AddObject(module, "__version_info__", pyQtVersion); +PyModule_AddStringConstant(module, "__version__", qVersion()); +// @snippet qt-version + +// @snippet qobject-connect +static bool isDecorator(PyObject *method, PyObject *self) +{ + Shiboken::AutoDecRef methodName(PyObject_GetAttr(method, Shiboken::PyMagicName::name())); + if (!PyObject_HasAttr(self, methodName)) + return true; + Shiboken::AutoDecRef otherMethod(PyObject_GetAttr(self, methodName)); + return PyMethod_GET_FUNCTION(otherMethod.object()) != PyMethod_GET_FUNCTION(method); +} + +static bool getReceiver(QObject *source, const char *signal, PyObject *callback, QObject **receiver, PyObject **self, QByteArray *callbackSig) +{ + bool forceGlobalReceiver = false; + if (PyMethod_Check(callback)) { + *self = PyMethod_GET_SELF(callback); + if (%CHECKTYPE[QObject *](*self)) + *receiver = %CONVERTTOCPP[QObject *](*self); + forceGlobalReceiver = isDecorator(callback, *self); + } else if (PyCFunction_Check(callback)) { + *self = PyCFunction_GET_SELF(callback); + if (*self && %CHECKTYPE[QObject *](*self)) + *receiver = %CONVERTTOCPP[QObject *](*self); + } else if (PyCallable_Check(callback)) { + // Ok, just a callable object + *receiver = nullptr; + *self = nullptr; + } + + bool usingGlobalReceiver = !*receiver || forceGlobalReceiver; + + // Check if this callback is a overwrite of a non-virtual Qt slot. + if (!usingGlobalReceiver && receiver && self) { + *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1(); + const QMetaObject *metaObject = (*receiver)->metaObject(); + int slotIndex = metaObject->indexOfSlot(callbackSig->constData()); + if (slotIndex != -1 && slotIndex < metaObject->methodOffset() && PyMethod_Check(callback)) + usingGlobalReceiver = true; + } + + const auto receiverThread = *receiver ? (*receiver)->thread() : nullptr; + + if (usingGlobalReceiver) { + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + *receiver = signalManager.globalReceiver(source, callback); + // PYSIDE-1354: Move the global receiver to the original receivers's thread + // so that autoconnections work correctly. + if (receiverThread && receiverThread != (*receiver)->thread()) + (*receiver)->moveToThread(receiverThread); + *callbackSig = PySide::Signal::getCallbackSignature(signal, *receiver, callback, usingGlobalReceiver).toLatin1(); + } + + return usingGlobalReceiver; +} + +static bool qobjectConnect(QObject *source, const char *signal, QObject *receiver, const char *slot, Qt::ConnectionType type) +{ + if (!signal || !slot) + return false; + + if (!PySide::Signal::checkQtSignal(signal)) + return false; + signal++; + + if (!PySide::SignalManager::registerMetaMethod(source, signal, QMetaMethod::Signal)) + return false; + + bool isSignal = PySide::Signal::isQtSignal(slot); + slot++; + PySide::SignalManager::registerMetaMethod(receiver, slot, isSignal ? QMetaMethod::Signal : QMetaMethod::Slot); + bool connection; + connection = QObject::connect(source, signal - 1, receiver, slot - 1, type); + return connection; +} + +static bool qobjectConnect(QObject *source, QMetaMethod signal, QObject *receiver, QMetaMethod slot, Qt::ConnectionType type) +{ + return qobjectConnect(source, signal.methodSignature(), receiver, slot.methodSignature(), type); +} + +static bool qobjectConnectCallback(QObject *source, const char *signal, PyObject *callback, Qt::ConnectionType type) +{ + if (!signal || !PySide::Signal::checkQtSignal(signal)) + return false; + signal++; + + int signalIndex = PySide::SignalManager::registerMetaMethodGetIndex(source, signal, QMetaMethod::Signal); + if (signalIndex == -1) + return false; + + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + + // Extract receiver from callback + QObject *receiver = nullptr; + PyObject *self = nullptr; + QByteArray callbackSig; + bool usingGlobalReceiver = getReceiver(source, signal, callback, &receiver, &self, &callbackSig); + if (receiver == nullptr && self == nullptr) + return false; + + const QMetaObject *metaObject = receiver->metaObject(); + const char *slot = callbackSig.constData(); + int slotIndex = metaObject->indexOfSlot(slot); + QMetaMethod signalMethod = metaObject->method(signalIndex); + + if (slotIndex == -1) { + if (!usingGlobalReceiver && self && !Shiboken::Object::hasCppWrapper(reinterpret_cast(self))) { + qWarning("You can't add dynamic slots on an object originated from C++."); + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; + } + + if (usingGlobalReceiver) + slotIndex = signalManager.globalReceiverSlotIndex(receiver, slot); + else + slotIndex = PySide::SignalManager::registerMetaMethodGetIndex(receiver, slot, QMetaMethod::Slot); + + if (slotIndex == -1) { + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; + } + } + bool connection; + connection = QMetaObject::connect(source, signalIndex, receiver, slotIndex, type); + if (connection) { + if (usingGlobalReceiver) + signalManager.notifyGlobalReceiver(receiver); + #ifndef AVOID_PROTECTED_HACK + source->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char * + #else + // Need to cast to QObjectWrapper * and call the public version of + // connectNotify when avoiding the protected hack. + reinterpret_cast(source)->connectNotify(signalMethod); //Qt5: QMetaMethod instead of char * + #endif + + return connection; + } + + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + return false; +} + + +static bool qobjectDisconnectCallback(QObject *source, const char *signal, PyObject *callback) +{ + if (!PySide::Signal::checkQtSignal(signal)) + return false; + + PySide::SignalManager &signalManager = PySide::SignalManager::instance(); + + // Extract receiver from callback + QObject *receiver = nullptr; + PyObject *self = nullptr; + QByteArray callbackSig; + QMetaMethod slotMethod; + bool usingGlobalReceiver = getReceiver(nullptr, signal, callback, &receiver, &self, &callbackSig); + if (receiver == nullptr && self == nullptr) + return false; + + const QMetaObject *metaObject = receiver->metaObject(); + int signalIndex = source->metaObject()->indexOfSignal(++signal); + int slotIndex = -1; + + slotIndex = metaObject->indexOfSlot(callbackSig); + slotMethod = metaObject->method(slotIndex); + + bool disconnected; + disconnected = QMetaObject::disconnectOne(source, signalIndex, receiver, slotIndex); + + if (disconnected) { + if (usingGlobalReceiver) + signalManager.releaseGlobalReceiver(source, receiver); + + #ifndef AVOID_PROTECTED_HACK + source->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char * + #else + // Need to cast to QObjectWrapper * and call the public version of + // connectNotify when avoiding the protected hack. + reinterpret_cast(source)->disconnectNotify(slotMethod); //Qt5: QMetaMethod instead of char * + #endif + return true; + } + return false; +} +// @snippet qobject-connect + +// @snippet qobject-connect-1 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %CPPSELF, %3, %4); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-1 + +// @snippet qobject-connect-2 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %3, %4, %5); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-2 + +// @snippet qobject-connect-3 +// %FUNCTION_NAME() - disable generation of function call. +bool %0 = qobjectConnect(%1, %2, %3, %4, %5); +%PYARG_0 = %CONVERTTOPYTHON[bool](%0); +// @snippet qobject-connect-3 + +// @snippet qobject-connect-4 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnectCallback(%1, %2, %PYARG_3, %4); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-4 + +// @snippet qobject-connect-5 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnectCallback(%CPPSELF, %1, %PYARG_2, %3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-5 + +// @snippet qobject-connect-6 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectConnect(%CPPSELF, %1, %2, %3, %4); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-connect-6 + +// @snippet qobject-emit +%RETURN_TYPE %0 = PySide::SignalManager::instance().emitSignal(%CPPSELF, %1, %PYARG_2); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-emit + +// @snippet qobject-disconnect-1 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectDisconnectCallback(%CPPSELF, %1, %2); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-disconnect-1 + +// @snippet qobject-disconnect-2 +// %FUNCTION_NAME() - disable generation of function call. +%RETURN_TYPE %0 = qobjectDisconnectCallback(%1, %2, %3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-disconnect-2 + +// @snippet qfatal +// qFatal doesn't have a stream version, so we do a +// qWarning call followed by a qFatal() call using a +// literal. +Py_BEGIN_ALLOW_THREADS +qWarning() << %1; +qFatal("[A qFatal() call was made from Python code]"); +Py_END_ALLOW_THREADS +// @snippet qfatal + +// @snippet moduleshutdown +PySide::runCleanupFunctions(); +// @snippet moduleshutdown + +// @snippet qt-qenum +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, false); +// @snippet qt-qenum + +// @snippet qt-qflag +%PYARG_0 = PySide::QEnum::QEnumMacro(%1, true); +// @snippet qt-qflag + +// @snippet qt-init-feature +PySide::Feature::init(); +// @snippet qt-init-feature + +// @snippet qt-pysideinit +Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "unicode"); +Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QSTRING_IDX], "str"); +Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QLIST_QVARIANT_IDX], "QVariantList"); +Shiboken::Conversions::registerConverterName(SbkPySide2_QtCoreTypeConverters[SBK_QTCORE_QMAP_QSTRING_QVARIANT_IDX], "QVariantMap"); + +PySide::registerInternalQtConf(); +PySide::init(module); +Py_AtExit(QtCoreModuleExit); +// @snippet qt-pysideinit + +// @snippet qt-messagehandler +// Define a global variable to handle qInstallMessageHandler callback +static PyObject *qtmsghandler = nullptr; + +static void msgHandlerCallback(QtMsgType type, const QMessageLogContext &ctx, const QString &msg) +{ + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(3)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QtMsgType](type)); + PyTuple_SET_ITEM(arglist, 1, %CONVERTTOPYTHON[QMessageLogContext &](ctx)); + QByteArray array = msg.toUtf8(); // Python handler requires UTF-8 + char *data = array.data(); + PyTuple_SET_ITEM(arglist, 2, %CONVERTTOPYTHON[char *](data)); + Shiboken::AutoDecRef ret(PyObject_CallObject(qtmsghandler, arglist)); +} +static void QtCoreModuleExit() +{ + PySide::SignalManager::instance().clear(); +} +// @snippet qt-messagehandler + +// @snippet qt-installmessagehandler +if (%PYARG_1 == Py_None) { + qInstallMessageHandler(0); + %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None; + qtmsghandler = 0; +} else if (!PyCallable_Check(%PYARG_1)) { + PyErr_SetString(PyExc_TypeError, "parameter must be callable"); +} else { + %PYARG_0 = qtmsghandler ? qtmsghandler : Py_None; + Py_INCREF(%PYARG_1); + qtmsghandler = %PYARG_1; + qInstallMessageHandler(msgHandlerCallback); +} + +if (%PYARG_0 == Py_None) + Py_INCREF(%PYARG_0); +// @snippet qt-installmessagehandler + +// @snippet qline-hash +namespace PySide { + template<> inline Py_ssize_t hash(const QLine &v) { + return qHash(qMakePair(qMakePair(v.x1(), v.y1()), qMakePair(v.x2(), v.y2()))); + } +}; +// @snippet qline-hash + +// @snippet qlinef-intersect +QPointF p; +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &p); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QPointF](p)); +// @snippet qlinef-intersect + +// @snippet qresource-data +const void *d = %CPPSELF.%FUNCTION_NAME(); +if (d) { + %PYARG_0 = Shiboken::Buffer::newObject(d, %CPPSELF.size()); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qresource-data + +// @snippet qdate-topython +if (!PyDateTimeAPI) + PySideDateTime_IMPORT; +%PYARG_0 = PyDate_FromDate(%CPPSELF.year(), %CPPSELF.month(), %CPPSELF.day()); +// @snippet qdate-topython + +// @snippet qdate-getdate +int year, month, day; +%CPPSELF.%FUNCTION_NAME(&year, &month, &day); +%PYARG_0 = PyTuple_New(3); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](year)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](month)); +PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](day)); +// @snippet qdate-getdate + +// @snippet qdate-weeknumber +int yearNumber; +int week = %CPPSELF.%FUNCTION_NAME(&yearNumber); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](week)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](yearNumber)); +// @snippet qdate-weeknumber + +// @snippet qdatetime-1 +QDate date(%1, %2, %3); +QTime time(%4, %5, %6, %7); +%0 = new %TYPE(date, time, Qt::TimeSpec(%8)); +// @snippet qdatetime-1 + +// @snippet qdatetime-2 +QDate date(%1, %2, %3); +QTime time(%4, %5, %6); +%0 = new %TYPE(date, time); +// @snippet qdatetime-2 + +// @snippet qdatetime-topython +QDate date = %CPPSELF.date(); +QTime time = %CPPSELF.time(); +if (!PyDateTimeAPI) PySideDateTime_IMPORT; +%PYARG_0 = PyDateTime_FromDateAndTime(date.year(), date.month(), date.day(), time.hour(), time.minute(), time.second(), time.msec()*1000); +// @snippet qdatetime-topython + +// @snippet qpoint +namespace PySide { + template<> inline Py_ssize_t hash(const QPoint &v) { + return qHash(qMakePair(v.x(), v.y())); + } +}; +// @snippet qpoint + +// @snippet qrect +namespace PySide { + template<> inline Py_ssize_t hash(const QRect &v) { + return qHash(qMakePair(qMakePair(v.x(), v.y()), qMakePair(v.width(), v.height()))); + } +}; +// @snippet qrect + +// @snippet qsize +namespace PySide { + template<> inline Py_ssize_t hash(const QSize &v) { + return qHash(qMakePair(v.width(), v.height())); + } +}; +// @snippet qsize + +// @snippet qtime-topython +if (!PyDateTimeAPI) + PySideDateTime_IMPORT; +%PYARG_0 = PyTime_FromTime(%CPPSELF.hour(), %CPPSELF.minute(), %CPPSELF.second(), %CPPSELF.msec()*1000); +// @snippet qtime-topython + +// @snippet qbitarray-len +return %CPPSELF.size(); +// @snippet qbitarray-len + +// @snippet qbitarray-getitem +if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} +bool ret = %CPPSELF.at(_i); +return %CONVERTTOPYTHON[bool](ret); +// @snippet qbitarray-getitem + +// @snippet qbitarray-setitem +PyObject *args = Py_BuildValue("(iiO)", _i, 1, _value); +PyObject *result = Sbk_QBitArrayFunc_setBit(self, args); +Py_DECREF(args); +Py_XDECREF(result); +return !result ? -1 : 0; +// @snippet qbitarray-setitem + +// @snippet unlock +%CPPSELF.unlock(); +// @snippet unlock + +// @snippet qabstractitemmodel-createindex +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, %PYARG_3); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qabstractitemmodel-createindex + +// @snippet qabstractitemmodel +qRegisterMetaType >("QVector"); +// @snippet qabstractitemmodel + +// @snippet qobject-metaobject +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qobject-metaobject + +// @snippet qobject-findchild-1 +static QObject *_findChildHelper(const QObject *parent, const QString &name, PyTypeObject *desiredType) +{ + for (auto *child : parent->children()) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) + && (name.isNull() || name == child->objectName())) { + return child; + } + } + + for (auto *child : parent->children()) { + QObject *obj = _findChildHelper(child, name, desiredType); + if (obj) + return obj; + } + return nullptr; +} + +static inline bool _findChildrenComparator(const QObject *&child, const QRegExp &name) +{ + return name.indexIn(child->objectName()) != -1; +} + +static inline bool _findChildrenComparator(const QObject *&child, const QRegularExpression &name) +{ + return name.match(child->objectName()).hasMatch(); +} + +static inline bool _findChildrenComparator(const QObject *&child, const QString &name) +{ + return name.isNull() || name == child->objectName(); +} + +template +static void _findChildrenHelper(const QObject *parent, const T& name, PyTypeObject *desiredType, PyObject *result) +{ + for (const auto *child : parent->children()) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + if (PyType_IsSubtype(Py_TYPE(pyChild), desiredType) && _findChildrenComparator(child, name)) + PyList_Append(result, pyChild); + _findChildrenHelper(child, name, desiredType, result); + } +} +// @snippet qobject-findchild-1 + +// @snippet qobject-findchild-2 +QObject *child = _findChildHelper(%CPPSELF, %2, reinterpret_cast(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[QObject *](child); +// @snippet qobject-findchild-2 + +// @snippet qobject-findchildren +%PYARG_0 = PyList_New(0); +_findChildrenHelper(%CPPSELF, %2, reinterpret_cast(%PYARG_1), %PYARG_0); +// @snippet qobject-findchildren + +// @snippet qobject-tr +QString result; +if (QCoreApplication::instance()) { + PyObject *klass = PyObject_GetAttr(%PYSELF, Shiboken::PyMagicName::class_()); + PyObject *cname = PyObject_GetAttr(klass, Shiboken::PyMagicName::name()); + result = QString(QCoreApplication::instance()->translate(Shiboken::String::toCString(cname), + /* %1, %2, QCoreApplication::CodecForTr, %3)); */ + %1, %2, %3)); + + Py_DECREF(klass); + Py_DECREF(cname); +} else { + result = QString(QString::fromLatin1(%1)); +} +%PYARG_0 = %CONVERTTOPYTHON[QString](result); +// @snippet qobject-tr + +// @snippet qobject-receivers +// Avoid return +1 because SignalManager connect to "destroyed()" signal to control object timelife +int ret = %CPPSELF.%FUNCTION_NAME(%1); +if (ret > 0 && ((strcmp(%1, SIGNAL(destroyed())) == 0) || (strcmp(%1, SIGNAL(destroyed(QObject*))) == 0))) + ret -= PySide::SignalManager::instance().countConnectionsWith(%CPPSELF); + +%PYARG_0 = %CONVERTTOPYTHON[int](ret); +// @snippet qobject-receivers + +// @snippet qregexp-replace +%1.replace(*%CPPSELF, %2); +%PYARG_0 = %CONVERTTOPYTHON[QString](%1); +// @snippet qregexp-replace + +// @snippet qbytearray-mgetitem +if (PyIndex_Check(_key)) { + Py_ssize_t _i; + _i = PyNumber_AsSsize_t(_key, PyExc_IndexError); + if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; + } else { + char res[2]; + res[0] = %CPPSELF.at(_i); + res[1] = 0; + return PyBytes_FromStringAndSize(res, 1); + } +} else if (PySlice_Check(_key)) { + Py_ssize_t start, stop, step, slicelength, cur; + +#ifdef IS_PY3K + PyObject *key = _key; +#else + PySliceObject *key = reinterpret_cast(_key); +#endif + if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) { + return nullptr; + } + + QByteArray ba; + if (slicelength <= 0) { + return %CONVERTTOPYTHON[QByteArray](ba); + } else if (step == 1) { + Py_ssize_t max = %CPPSELF.count(); + start = qBound(Py_ssize_t(0), start, max); + stop = qBound(Py_ssize_t(0), stop, max); + QByteArray ba; + if (start < stop) + ba = %CPPSELF.mid(start, stop - start); + return %CONVERTTOPYTHON[QByteArray](ba); + } else { + QByteArray ba; + for (cur = start; slicelength > 0; cur += static_cast(step), slicelength--) { + ba.append(%CPPSELF.at(cur)); + } + return %CONVERTTOPYTHON[QByteArray](ba); + } +} else { + PyErr_Format(PyExc_TypeError, + "list indices must be integers or slices, not %.200s", + Py_TYPE(_key)->tp_name); + return nullptr; +} +// @snippet qbytearray-mgetitem + +// @snippet qbytearray-msetitem +if (PyIndex_Check(_key)) { + Py_ssize_t _i = PyNumber_AsSsize_t(_key, PyExc_IndexError); + if (_i == -1 && PyErr_Occurred()) + return -1; + + if (_i < 0) + _i += %CPPSELF.count(); + + if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "QByteArray index out of range"); + return -1; + } + + // Provide more specific error message for bytes/str, bytearray, QByteArray respectively +#ifdef IS_PY3K + if (PyBytes_Check(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "bytes must be of size 1"); +#else + if (PyString_CheckExact(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "str must be of size 1"); +#endif + return -1; + } + } else if (PyByteArray_Check(_value)) { + if (Py_SIZE(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "bytearray must be of size 1"); + return -1; + } + } else if (reinterpret_cast(Py_TYPE(_value)) == reinterpret_cast(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX])) { + if (PyObject_Length(_value) != 1) { + PyErr_SetString(PyExc_ValueError, "QByteArray must be of size 1"); + return -1; + } + } else { +#ifdef IS_PY3K + PyErr_SetString(PyExc_ValueError, "a bytes, bytearray, QByteArray of size 1 is required"); +#else + PyErr_SetString(PyExc_ValueError, "a str, bytearray, QByteArray of size 1 is required"); +#endif + return -1; + } + + // Not support int or long. + %CPPSELF.remove(_i, 1); + PyObject *args = Py_BuildValue("(nO)", _i, _value); + PyObject *result = Sbk_QByteArrayFunc_insert(self, args); + Py_DECREF(args); + Py_XDECREF(result); + return !result ? -1 : 0; +} else if (PySlice_Check(_key)) { + Py_ssize_t start, stop, step, slicelength, value_length; + +#ifdef IS_PY3K + PyObject *key = _key; +#else + PySliceObject *key = reinterpret_cast(_key); +#endif + if (PySlice_GetIndicesEx(key, %CPPSELF.count(), &start, &stop, &step, &slicelength) < 0) { + return -1; + } + // The parameter candidates are: bytes/str, bytearray, QByteArray itself. + // Not support iterable which contains ints between 0~255 + + // case 1: value is nullpre, means delete the items within the range + // case 2: step is 1, means shrink or expanse + // case 3: step is not 1, then the number of slots have to equal the number of items in _value + QByteArray ba; + if (_value == nullptr || _value == Py_None) { + ba = QByteArray(); + value_length = 0; + } else if (!(PyBytes_Check(_value) || PyByteArray_Check(_value) || reinterpret_cast(Py_TYPE(_value)) == reinterpret_cast(SbkPySide2_QtCoreTypes[SBK_QBYTEARRAY_IDX]))) { + PyErr_Format(PyExc_TypeError, "bytes, bytearray or QByteArray is required, not %.200s", Py_TYPE(_value)->tp_name); + return -1; + } else { + value_length = PyObject_Length(_value); + } + + if (step != 1 && value_length != slicelength) { + PyErr_Format(PyExc_ValueError, "attempt to assign %s of size %d to extended slice of size %d", + Py_TYPE(_value)->tp_name, int(value_length), int(slicelength)); + return -1; + } + + if (step != 1) { + int i = start; + for (int j = 0; j < slicelength; j++) { + PyObject *item = PyObject_GetItem(_value, PyLong_FromLong(j)); + QByteArray temp; +#ifdef IS_PY3K + if (PyLong_Check(item)) { +#else + if (PyLong_Check(item) || PyInt_Check(item)) { +#endif + int overflow; + long ival = PyLong_AsLongAndOverflow(item, &overflow); + // Not suppose to bigger than 255 because only bytes, bytearray, QByteArray were accept + temp = QByteArray(reinterpret_cast(&ival)); + } else { + temp = %CONVERTTOCPP[QByteArray](item); + } + + %CPPSELF.replace(i, 1, temp); + i += step; + } + return 0; + } else { + ba = %CONVERTTOCPP[QByteArray](_value); + %CPPSELF.replace(start, slicelength, ba); + return 0; + } +} else { + PyErr_Format(PyExc_TypeError, "QBytearray indices must be integers or slices, not %.200s", + Py_TYPE(_key)->tp_name); + return -1; +} +// @snippet qbytearray-msetitem + +// @snippet qbytearray-bufferprotocol +extern "C" { +// QByteArray buffer protocol functions +// see: http://www.python.org/dev/peps/pep-3118/ + +static int SbkQByteArray_getbufferproc(PyObject *obj, Py_buffer *view, int flags) +{ + if (!view || !Shiboken::Object::isValid(obj)) + return -1; + + QByteArray * cppSelf = %CONVERTTOCPP[QByteArray *](obj); + //XXX /|\ omitting this space crashes shiboken! + #ifdef Py_LIMITED_API + view->obj = obj; + view->buf = reinterpret_cast(cppSelf->data()); + view->len = cppSelf->size(); + view->readonly = 0; + view->itemsize = 1; + view->format = const_cast("c"); + view->ndim = 1; + view->shape = (flags & PyBUF_ND) == PyBUF_ND ? &(view->len) : nullptr; + view->strides = &view->itemsize; + view->suboffsets = NULL; + view->internal = NULL; + + Py_XINCREF(obj); + return 0; +#else // Py_LIMITED_API + const int result = PyBuffer_FillInfo(view, obj, reinterpret_cast(cppSelf->data()), + cppSelf->size(), 0, flags); + if (result == 0) + Py_XINCREF(obj); + return result; +#endif +} + +#if PY_VERSION_HEX < 0x03000000 +static Py_ssize_t SbkQByteArray_segcountproc(PyObject *self, Py_ssize_t *lenp) +{ + if (lenp) + *lenp = Py_TYPE(self)->tp_as_sequence->sq_length(self); + return 1; +} + +static Py_ssize_t SbkQByteArray_readbufferproc(PyObject *self, Py_ssize_t segment, void **ptrptr) +{ + if (segment || !Shiboken::Object::isValid(self)) + return -1; + + QByteArray * cppSelf = %CONVERTTOCPP[QByteArray *](self); + //XXX /|\ omitting this space crashes shiboken! + *ptrptr = reinterpret_cast(cppSelf->data()); + return cppSelf->size(); +} + +PyBufferProcs SbkQByteArrayBufferProc = { + /*bf_getreadbuffer*/ &SbkQByteArray_readbufferproc, + /*bf_getwritebuffer*/ (writebufferproc) &SbkQByteArray_readbufferproc, + /*bf_getsegcount*/ &SbkQByteArray_segcountproc, + /*bf_getcharbuffer*/ (charbufferproc) &SbkQByteArray_readbufferproc, + /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc, +}; +#else + +static PyBufferProcs SbkQByteArrayBufferProc = { + /*bf_getbuffer*/ (getbufferproc)SbkQByteArray_getbufferproc, + /*bf_releasebuffer*/ (releasebufferproc)0, +}; + +#endif +} +// @snippet qbytearray-bufferprotocol + +// @snippet qbytearray-operatorplus-1 +QByteArray ba = QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)) + *%CPPSELF; +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-1 + +// @snippet qbytearray-operatorplus-2 +QByteArray ba = QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)) + *%CPPSELF; +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-2 + +// @snippet qbytearray-operatorplus-3 +QByteArray ba = *%CPPSELF + QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[QByteArray](ba); +// @snippet qbytearray-operatorplus-3 + +// @snippet qbytearray-operatorplusequal +*%CPPSELF += QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +// @snippet qbytearray-operatorplusequal + +// @snippet qbytearray-operatorequalequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF == ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorequalequal + +// @snippet qbytearray-operatornotequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF != ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatornotequal + +// @snippet qbytearray-operatorgreater +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF > ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorgreater + +// @snippet qbytearray-operatorgreaterequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF >= ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorgreaterequal + +// @snippet qbytearray-operatorlower +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF < ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorlower + +// @snippet qbytearray-operatorlowerequal +if (PyUnicode_CheckExact(%PYARG_1)) { + Shiboken::AutoDecRef data(PyUnicode_AsASCIIString(%PYARG_1)); + QByteArray ba = QByteArray(PyBytes_AsString(data.object()), PyBytes_GET_SIZE(data.object())); + bool cppResult = %CPPSELF <= ba; + %PYARG_0 = %CONVERTTOPYTHON[bool](cppResult); +} +// @snippet qbytearray-operatorlowerequal + +// @snippet qbytearray-repr +PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); +if (aux == nullptr) { + return nullptr; +} +QByteArray b(Py_TYPE(%PYSELF)->tp_name); +#ifdef IS_PY3K + %PYARG_0 = PyUnicode_FromFormat("%s(%R)", b.constData(), aux); +#else + aux = PyObject_Repr(aux); + b += '('; + b += QByteArray(PyBytes_AS_STRING(aux), PyBytes_GET_SIZE(aux)); + b += ')'; + %PYARG_0 = Shiboken::String::fromStringAndSize(b.constData(), b.size()); +#endif +Py_DECREF(aux); +// @snippet qbytearray-repr + +// @snippet qbytearray-1 +if (PyBytes_Check(%PYARG_1)) { + %0 = new QByteArray(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +} else if (Shiboken::String::check(%PYARG_1)) { + %0 = new QByteArray(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1)); +} +// @snippet qbytearray-1 + +// @snippet qbytearray-2 +%0 = new QByteArray(PyByteArray_AsString(%PYARG_1), PyByteArray_Size(%PYARG_1)); +// @snippet qbytearray-2 + +// @snippet qbytearray-3 +%0 = new QByteArray(PyBytes_AS_STRING(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +// @snippet qbytearray-3 + +// @snippet qbytearray-py3 +#if PY_VERSION_HEX < 0x03000000 +Shiboken::SbkType()->tp_as_buffer = &SbkQByteArrayBufferProc; +Shiboken::SbkType()->tp_flags |= Py_TPFLAGS_HAVE_NEWBUFFER; +#else +PepType_AS_BUFFER(Shiboken::SbkType()) = &SbkQByteArrayBufferProc; +#endif +// @snippet qbytearray-py3 + +// @snippet qbytearray-data +%PYARG_0 = PyBytes_FromStringAndSize(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.size()); +// @snippet qbytearray-data + +// @snippet qbytearray-fromrawdata +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(PyBytes_AsString(%PYARG_1), PyBytes_GET_SIZE(%PYARG_1)); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qbytearray-fromrawdata + +// @snippet qbytearray-str +PyObject *aux = PyBytes_FromStringAndSize(%CPPSELF.constData(), %CPPSELF.size()); +if (aux == nullptr) { + return nullptr; +} +#ifdef IS_PY3K + %PYARG_0 = PyObject_Repr(aux); + Py_DECREF(aux); +#else + %PYARG_0 = aux; +#endif +// @snippet qbytearray-str + +// @snippet qbytearray-len +return %CPPSELF.count(); +// @snippet qbytearray-len + +// @snippet qbytearray-getitem +if (_i < 0 || _i >= %CPPSELF.size()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} else { + char res[2]; + res[0] = %CPPSELF.at(_i); + res[1] = 0; + return PyBytes_FromStringAndSize(res, 1); +} +// @snippet qbytearray-getitem + +// @snippet qbytearray-setitem +%CPPSELF.remove(_i, 1); +PyObject *args = Py_BuildValue("(nO)", _i, _value); +PyObject *result = Sbk_QByteArrayFunc_insert(self, args); +Py_DECREF(args); +Py_XDECREF(result); +return !result ? -1 : 0; +// @snippet qbytearray-setitem + +// @snippet qfiledevice-unmap +uchar *ptr = reinterpret_cast(Shiboken::Buffer::getPointer(%PYARG_1)); +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(ptr); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qfiledevice-unmap + +// @snippet qfiledevice-map +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1, %2, %3), %2, Shiboken::Buffer::ReadWrite); +// @snippet qfiledevice-map + +// @snippet qiodevice-readdata +QByteArray ba(1 + int(%2), char(0)); +%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2)); +%PYARG_0 = Shiboken::String::fromCString(ba.constData()); +// @snippet qiodevice-readdata + +// @snippet qcryptographichash-adddata +%CPPSELF.%FUNCTION_NAME(Shiboken::String::toCString(%PYARG_1), Shiboken::String::len(%PYARG_1)); +// @snippet qcryptographichash-adddata + +// @snippet qsocketdescriptor +#ifdef WIN32 +using DescriptorType = Qt::HANDLE; +#else +using DescriptorType = int; +#endif +// @snippet qsocketdescriptor + +// @snippet qsocketnotifier +PyObject *socket = %PYARG_1; +if (socket != nullptr) { + // We use qintptr as PyLong, but we check for int + // since it is currently an alias to be Python2 compatible. + // Internally, ints are qlonglongs. + if (%CHECKTYPE[int](socket)) { + int cppSocket = %CONVERTTOCPP[int](socket); + qintptr socket = (qintptr)cppSocket; + %0 = new %TYPE(socket, %2, %3); + } else { + PyErr_SetString(PyExc_TypeError, + "QSocketNotifier: first argument (socket) must be an int."); + } +} +// @snippet qsocketnotifier + +// @snippet qtranslator-load +Py_ssize_t size; +uchar *ptr = reinterpret_cast(Shiboken::Buffer::getPointer(%PYARG_1, &size)); +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast(ptr), size); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qtranslator-load + +// @snippet qtimer-singleshot-1 +// %FUNCTION_NAME() - disable generation of c++ function call +(void) %2; // remove warning about unused variable +Shiboken::AutoDecRef emptyTuple(PyTuple_New(0)); +PyObject *pyTimer = reinterpret_cast(Shiboken::SbkType())->tp_new(Shiboken::SbkType(), emptyTuple, 0); +reinterpret_cast(Shiboken::SbkType())->tp_init(pyTimer, emptyTuple, 0); + +auto timer = %CONVERTTOCPP[QTimer *](pyTimer); +//XXX /|\ omitting this space crashes shiboken! +Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast("connect"), + const_cast("OsOs"), + pyTimer, + SIGNAL(timeout()), + %PYARG_2, + %3) +); +Shiboken::Object::releaseOwnership((SbkObject *)pyTimer); +Py_XDECREF(pyTimer); +timer->setSingleShot(true); +timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater())); +timer->start(%1); +// @snippet qtimer-singleshot-1 + +// @snippet qtimer-singleshot-2 +// %FUNCTION_NAME() - disable generation of c++ function call +Shiboken::AutoDecRef emptyTuple(PyTuple_New(0)); +PyObject *pyTimer = reinterpret_cast(Shiboken::SbkType())->tp_new(Shiboken::SbkType(), emptyTuple, 0); +reinterpret_cast(Shiboken::SbkType())->tp_init(pyTimer, emptyTuple, 0); +QTimer * timer = %CONVERTTOCPP[QTimer *](pyTimer); +timer->setSingleShot(true); + +if (PyObject_TypeCheck(%2, PySideSignalInstanceTypeF())) { + PySideSignalInstance *signalInstance = reinterpret_cast(%2); + Shiboken::AutoDecRef signalSignature(Shiboken::String::fromFormat("2%s", PySide::Signal::getSignature(signalInstance))); + Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast("connect"), + const_cast("OsOO"), + pyTimer, + SIGNAL(timeout()), + PySide::Signal::getObject(signalInstance), + signalSignature.object()) + ); +} else { + Shiboken::AutoDecRef result( + PyObject_CallMethod(pyTimer, + const_cast("connect"), + const_cast("OsO"), + pyTimer, + SIGNAL(timeout()), + %PYARG_2) + ); +} + +timer->connect(timer, SIGNAL(timeout()), timer, SLOT(deleteLater()), Qt::DirectConnection); +Shiboken::Object::releaseOwnership(reinterpret_cast(pyTimer)); +Py_XDECREF(pyTimer); +timer->start(%1); +// @snippet qtimer-singleshot-2 + +// @snippet qprocess-startdetached +qint64 pid; +%RETURN_TYPE retval = %TYPE::%FUNCTION_NAME(%1, %2, %3, &pid); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[qint64](pid)); +// @snippet qprocess-startdetached + +// @snippet qprocess-pid +long result; +#ifdef WIN32 + _PROCESS_INFORMATION *procInfo = %CPPSELF.%FUNCTION_NAME(); + result = procInfo ? procInfo->dwProcessId : 0; +#else + result = %CPPSELF.%FUNCTION_NAME(); +#endif +%PYARG_0 = %CONVERTTOPYTHON[long](result); +// @snippet qprocess-pid + +// @snippet qcoreapplication-init +static void QCoreApplicationConstructor(PyObject *self, PyObject *pyargv, QCoreApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QCoreApplicationWrapper(argc, argv); + Shiboken::Object::releaseOwnership(reinterpret_cast(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qcoreapplication-init + +// @snippet qcoreapplication-1 +QCoreApplicationConstructor(%PYSELF, args, &%0); +// @snippet qcoreapplication-1 + +// @snippet qcoreapplication-2 +PyObject *empty = PyTuple_New(2); +if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QCoreApplicationConstructor(%PYSELF, empty, &%0); +} +// @snippet qcoreapplication-2 + +// @snippet qcoreapplication-instance +PyObject *pyApp = Py_None; +if (qApp) { + pyApp = reinterpret_cast( + Shiboken::BindingManager::instance().retrieveWrapper(qApp)); + if (!pyApp) + pyApp = %CONVERTTOPYTHON[QCoreApplication *](qApp); + // this will keep app live after python exit (extra ref) +} +// PYSIDE-571: make sure that we return the singleton "None" +if (Py_TYPE(pyApp) == Py_TYPE(Py_None)) + Py_DECREF(MakeQAppWrapper(nullptr)); +%PYARG_0 = pyApp; +Py_XINCREF(%PYARG_0); +// @snippet qcoreapplication-instance + +// @snippet qdatastream-readrawdata +QByteArray data; +data.resize(%2); +int result = 0; +Py_BEGIN_ALLOW_THREADS +result = %CPPSELF.%FUNCTION_NAME(data.data(), data.size()); +Py_END_ALLOW_THREADS +if (result == -1) { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} else { + %PYARG_0 = PyBytes_FromStringAndSize(data.data(), result); +} +// @snippet qdatastream-readrawdata + +// @snippet qdatastream-writerawdata +int r = 0; +Py_BEGIN_ALLOW_THREADS +r = %CPPSELF.%FUNCTION_NAME(%1, Shiboken::String::len(%PYARG_1)); +Py_END_ALLOW_THREADS +%PYARG_0 = %CONVERTTOPYTHON[int](r); +// @snippet qdatastream-writerawdata + +// @snippet releaseownership +Shiboken::Object::releaseOwnership(%PYARG_0); +// @snippet releaseownership + +// @snippet qanimationgroup-clear +for (int counter = 0, count = %CPPSELF.animationCount(); counter < count; ++counter ) { + QAbstractAnimation *animation = %CPPSELF.animationAt(counter); + PyObject *obj = %CONVERTTOPYTHON[QAbstractAnimation *](animation); + Shiboken::Object::setParent(nullptr, obj); + Py_DECREF(obj); +} +%CPPSELF.clear(); +// @snippet qanimationgroup-clear + +// @snippet qeasingcurve +PySideEasingCurveFunctor::init(); +// @snippet qeasingcurve + +// @snippet qeasingcurve-setcustomtype +QEasingCurve::EasingFunction func = PySideEasingCurveFunctor::createCustomFuntion(%PYSELF, %PYARG_1); +if (func) + %CPPSELF.%FUNCTION_NAME(func); +// @snippet qeasingcurve-setcustomtype + +// @snippet qeasingcurve-customtype +//%FUNCTION_NAME() +%PYARG_0 = PySideEasingCurveFunctor::callable(%PYSELF); +// @snippet qeasingcurve-customtype + +// @snippet qsignaltransition +if (PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) { + PyObject *dataSource = PySide::Signal::getObject((PySideSignalInstance *)%PYARG_1); + Shiboken::AutoDecRef obType(PyObject_Type(dataSource)); + QObject * sender = %CONVERTTOCPP[QObject *](dataSource); + //XXX /|\ omitting this space crashes shiboken! + if (sender) { + const char *dataSignature = PySide::Signal::getSignature((PySideSignalInstance *)%PYARG_1); + QByteArray signature(dataSignature); // Append SIGNAL flag (2) + signature.prepend('2'); + %0 = new QSignalTransitionWrapper(sender, signature, %2); + } +} +// @snippet qsignaltransition + +// @snippet qstate-addtransition-1 +QString signalName(%2); +if (PySide::SignalManager::registerMetaMethod(%1, signalName.mid(1).toLatin1().data(), QMetaMethod::Signal)) { + QSignalTransition *%0 = %CPPSELF->addTransition(%1, %2, %3); + %PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qstate-addtransition-1 + +// @snippet qstate-addtransition-2 +// Obviously the label used by the following goto is a very awkward solution, +// since it refers to a name very tied to the generator implementation. +// Check bug #362 for more information on this +// http://bugs.openbossa.org/show_bug.cgi?id=362 +if (!PyObject_TypeCheck(%1, PySideSignalInstanceTypeF())) + goto Sbk_%TYPEFunc_%FUNCTION_NAME_TypeError; +PySideSignalInstance *signalInstance = reinterpret_cast(%1); +auto sender = %CONVERTTOCPP[QObject *](PySide::Signal::getObject(signalInstance)); +QSignalTransition *%0 = %CPPSELF->%FUNCTION_NAME(sender, PySide::Signal::getSignature(signalInstance),%2); +%PYARG_0 = %CONVERTTOPYTHON[QSignalTransition *](%0); +// @snippet qstate-addtransition-2 + +// @snippet qstatemachine-configuration +%PYARG_0 = PySet_New(0); +for (auto *abs_state : %CPPSELF.configuration()) { + Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractState *](abs_state)); + Shiboken::Object::setParent(self, obj); + PySet_Add(%PYARG_0, obj); +} +// @snippet qstatemachine-configuration + +// @snippet qstatemachine-defaultanimations +%PYARG_0 = PyList_New(0); +for (auto *abs_anim : %CPPSELF.defaultAnimations()) { + Shiboken::AutoDecRef obj(%CONVERTTOPYTHON[QAbstractAnimation *](abs_anim)); + Shiboken::Object::setParent(self, obj); + PyList_Append(%PYARG_0, obj); +} +// @snippet qstatemachine-defaultanimations + +// @snippet qt-signal +%PYARG_0 = Shiboken::String::fromFormat("2%s",QMetaObject::normalizedSignature(%1).constData()); +// @snippet qt-signal + +// @snippet qt-slot +%PYARG_0 = Shiboken::String::fromFormat("1%s",QMetaObject::normalizedSignature(%1).constData()); +// @snippet qt-slot + +// @snippet qt-registerresourcedata +QT_BEGIN_NAMESPACE +extern bool +qRegisterResourceData(int, + const unsigned char *, + const unsigned char *, + const unsigned char *); + +extern bool +qUnregisterResourceData(int, + const unsigned char *, + const unsigned char *, + const unsigned char *); +QT_END_NAMESPACE +// @snippet qt-registerresourcedata + +// @snippet qt-qregisterresourcedata +%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast(PyBytes_AS_STRING(%PYARG_2)), + reinterpret_cast(PyBytes_AS_STRING(%PYARG_3)), + reinterpret_cast(PyBytes_AS_STRING(%PYARG_4))); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qt-qregisterresourcedata + +// @snippet qt-qunregisterresourcedata +%RETURN_TYPE %0 = %FUNCTION_NAME(%1, reinterpret_cast(PyBytes_AS_STRING(%PYARG_2)), + reinterpret_cast(PyBytes_AS_STRING(%PYARG_3)), + reinterpret_cast(PyBytes_AS_STRING(%PYARG_4))); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qt-qunregisterresourcedata + +// @snippet use-stream-for-format-security +// Uses the stream version for security reasons +// see gcc man page at -Wformat-security +Py_BEGIN_ALLOW_THREADS +%FUNCTION_NAME() << %1; +Py_END_ALLOW_THREADS +// @snippet use-stream-for-format-security + +// @snippet qresource-registerResource + auto ptr = reinterpret_cast(Shiboken::Buffer::getPointer(%PYARG_1)); + %RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(const_cast(ptr), %2); + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +// @snippet qresource-registerResource + +// @snippet qstring-return +%PYARG_0 = %CONVERTTOPYTHON[QString](%1); +// @snippet qstring-return + +// @snippet stream-write-method +Py_BEGIN_ALLOW_THREADS +(*%CPPSELF) << %1; +Py_END_ALLOW_THREADS +// @snippet stream-write-method + +// @snippet stream-read-method +%RETURN_TYPE _cpp_result; +Py_BEGIN_ALLOW_THREADS +(*%CPPSELF) >> _cpp_result; +Py_END_ALLOW_THREADS +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](_cpp_result); +// @snippet stream-read-method + +// @snippet return-qstring-ref +QString &res = *%0; +%PYARG_0 = %CONVERTTOPYTHON[QString](res); +// @snippet return-qstring-ref + +// @snippet return-readData +%RETURN_TYPE %0 = 0; +if (PyBytes_Check(%PYARG_0)) { + %0 = PyBytes_GET_SIZE((PyObject *)%PYARG_0); + memcpy(%1, PyBytes_AS_STRING((PyObject *)%PYARG_0), %0); +} else if (Shiboken::String::check(%PYARG_0)) { + %0 = Shiboken::String::len((PyObject *)%PYARG_0); + memcpy(%1, Shiboken::String::toCString((PyObject *)%PYARG_0), %0); +} +// @snippet return-readData + +// @snippet qiodevice-readData +QByteArray ba(1 + int(%2), char(0)); +Py_BEGIN_ALLOW_THREADS +%CPPSELF.%FUNCTION_NAME(ba.data(), int(%2)); +Py_END_ALLOW_THREADS +%PYARG_0 = Shiboken::String::fromCString(ba.constData()); +// @snippet qiodevice-readData + +// @snippet qt-module-shutdown +{ // Avoid name clash + Shiboken::AutoDecRef regFunc(static_cast(nullptr)); + Shiboken::AutoDecRef atexit(Shiboken::Module::import("atexit")); + if (atexit.isNull()) { + qWarning("Module atexit not found for registering __moduleShutdown"); + PyErr_Clear(); + }else{ + regFunc.reset(PyObject_GetAttrString(atexit, "register")); + if (regFunc.isNull()) { + qWarning("Function atexit.register not found for registering __moduleShutdown"); + PyErr_Clear(); + } + } + if (!atexit.isNull() && !regFunc.isNull()){ + PyObject *shutDownFunc = PyObject_GetAttrString(module, "__moduleShutdown"); + Shiboken::AutoDecRef args(PyTuple_New(1)); + PyTuple_SET_ITEM(args, 0, shutDownFunc); + Shiboken::AutoDecRef retval(PyObject_Call(regFunc, args, 0)); + Q_ASSERT(!retval.isNull()); + } +} +// @snippet qt-module-shutdown + + +/********************************************************************* + * CONVERSIONS + ********************************************************************/ + +// @snippet conversion-pybool +%out = %OUTTYPE(%in == Py_True); +// @snippet conversion-pybool + +// @snippet conversion-pylong +%out = %OUTTYPE(PyLong_AsLong(%in)); +// @snippet conversion-pylong + +// @snippet conversion-pylong-unsigned +%out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); +// @snippet conversion-pylong-unsigned + +// @snippet conversion-pylong-quintptr +#if defined(IS_PY3K) && QT_POINTER_SIZE == 8 +%out = %OUTTYPE(PyLong_AsUnsignedLongLong(%in)); +#else +%out = %OUTTYPE(PyLong_AsUnsignedLong(%in)); +#endif +// @snippet conversion-pylong-quintptr + +// @snippet conversion-pyunicode +#ifndef Py_LIMITED_API +Py_UNICODE *unicode = PyUnicode_AS_UNICODE(%in); +# if defined(Py_UNICODE_WIDE) +// cast as Py_UNICODE can be a different type +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUcs4(reinterpret_cast(unicode)); +# else +%out = QString::fromUcs4(reinterpret_cast(unicode)); +# endif // Qt 6 +# else // Py_UNICODE_WIDE +# if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +%out = QString::fromUtf16(reinterpret_cast(unicode), PepUnicode_GetLength(%in)); +# else +%out = QString::fromUtf16(reinterpret_cast(unicode), PepUnicode_GetLength(%in)); +# endif // Qt 6 +# endif +#else +wchar_t *temp = PyUnicode_AsWideCharString(%in, NULL); +%out = QString::fromWCharArray(temp); +PyMem_Free(temp); +#endif +// @snippet conversion-pyunicode + +// @snippet conversion-pystring +#ifndef IS_PY3K +const char * str = %CONVERTTOCPP[const char *](%in); +//XXX /|\ omitting this space crashes shiboken! +%out = %OUTTYPE(str); +#endif +// @snippet conversion-pystring + +// @snippet conversion-pynone +%out = %OUTTYPE(); +// @snippet conversion-pynone + +// @snippet conversion-pystring-char +char c = %CONVERTTOCPP[char](%in); +%out = %OUTTYPE(c); +// @snippet conversion-pystring-char + +// @snippet conversion-pyint +int i = %CONVERTTOCPP[int](%in); +%out = %OUTTYPE(i); +// @snippet conversion-pyint + +// @snippet conversion-qlonglong +// PYSIDE-1250: For QVariant, if the type fits into an int; use int preferably. +qlonglong in = %CONVERTTOCPP[qlonglong](%in); +constexpr qlonglong intMax = qint64(std::numeric_limits::max()); +constexpr qlonglong intMin = qint64(std::numeric_limits::min()); +%out = in >= intMin && in <= intMax ? %OUTTYPE(int(in)) : %OUTTYPE(in); +// @snippet conversion-qlonglong + +// @snippet conversion-qstring +QString in = %CONVERTTOCPP[QString](%in); +%out = %OUTTYPE(in); +// @snippet conversion-qstring + +// @snippet conversion-qbytearray +QByteArray in = %CONVERTTOCPP[QByteArray](%in); +%out = %OUTTYPE(in); +// @snippet conversion-qbytearray + +// @snippet conversion-pyfloat +double in = %CONVERTTOCPP[double](%in); +%out = %OUTTYPE(in); +// @snippet conversion-pyfloat + +// @snippet conversion-sbkobject +// a class supported by QVariant? +int typeCode; +const char *typeName = QVariant_resolveMetaType(Py_TYPE(%in), &typeCode); +if (!typeCode || !typeName) { + // If the type was not encountered, return a default PyObjectWrapper + %out = QVariant::fromValue(PySide::PyObjectWrapper(%in)); +} +else { + QVariant var(typeCode, nullptr); + Shiboken::Conversions::SpecificConverter converter(typeName); + converter.toCpp(pyIn, var.data()); + %out = var; +} +// @snippet conversion-sbkobject + +// @snippet conversion-pydict +QVariant ret = QVariant_convertToVariantMap(%in); +%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pydict + +// @snippet conversion-pylist +QVariant ret = QVariant_convertToVariantList(%in); +%out = ret.isValid() ? ret : QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pylist + +// @snippet conversion-pyobject +// Is a shiboken type not known by Qt +%out = QVariant::fromValue(PySide::PyObjectWrapper(%in)); +// @snippet conversion-pyobject + +// @snippet conversion-qvariant-invalid +%out = QVariant::Invalid; +// @snippet conversion-qvariant-invalid + +// @snippet conversion-qvariant-pytypeobject +const char *typeName; +if (Shiboken::String::checkType(reinterpret_cast(%in))) + typeName = "QString"; +else if (%in == reinterpret_cast(&PyFloat_Type)) + typeName = "double"; // float is a UserType in QVariant. +else if (%in == reinterpret_cast(&PyLong_Type)) + typeName = "int"; // long is a UserType in QVariant. +else if (Py_TYPE(%in) == SbkObjectType_TypeF()) + typeName = Shiboken::ObjectType::getOriginalName((SbkObjectType *)%in); +else + typeName = reinterpret_cast(%in)->tp_name; +%out = QVariant::nameToType(typeName); +// @snippet conversion-qvariant-pytypeobject + +// @snippet conversion-qvariant-pystring +%out = QVariant::nameToType(Shiboken::String::toCString(%in)); +// @snippet conversion-qvariant-pystring + +// @snippet conversion-qvariant-pydict +%out = QVariant::nameToType("QVariantMap"); +// @snippet conversion-qvariant-pydict + +// @snippet conversion-qvariant-pysequence +%out = QVariantType_isStringList(%in) ? QVariant::StringList : QVariant::List; +// @snippet conversion-qvariant-pysequence + +// @snippet conversion-qjsonobject-pydict +QVariant dict = QVariant_convertToVariantMap(%in); +QJsonValue val = QJsonValue::fromVariant(dict); +%out = val.toObject(); +// @snippet conversion-qjsonobject-pydict + +// @snippet conversion-qpair-pysequence +%out.first = %CONVERTTOCPP[%OUTTYPE_0](PySequence_Fast_GET_ITEM(%in, 0)); +%out.second = %CONVERTTOCPP[%OUTTYPE_1](PySequence_Fast_GET_ITEM(%in, 1)); +// @snippet conversion-qpair-pysequence + +// @snippet conversion-qdate-pydate +int day = PyDateTime_GET_DAY(%in); +int month = PyDateTime_GET_MONTH(%in); +int year = PyDateTime_GET_YEAR(%in); +%out = %OUTTYPE(year, month, day); +// @snippet conversion-qdate-pydate + +// @snippet conversion-qdatetime-pydatetime +int day = PyDateTime_GET_DAY(%in); +int month = PyDateTime_GET_MONTH(%in); +int year = PyDateTime_GET_YEAR(%in); +int hour = PyDateTime_DATE_GET_HOUR(%in); +int min = PyDateTime_DATE_GET_MINUTE(%in); +int sec = PyDateTime_DATE_GET_SECOND(%in); +int usec = PyDateTime_DATE_GET_MICROSECOND(%in); +%out = %OUTTYPE(QDate(year, month, day), QTime(hour, min, sec, usec/1000)); +// @snippet conversion-qdatetime-pydatetime + +// @snippet conversion-qtime-pytime +int hour = PyDateTime_TIME_GET_HOUR(%in); +int min = PyDateTime_TIME_GET_MINUTE(%in); +int sec = PyDateTime_TIME_GET_SECOND(%in); +int usec = PyDateTime_TIME_GET_MICROSECOND(%in); +%out = %OUTTYPE(hour, min, sec, usec/1000); +// @snippet conversion-qtime-pytime + +// @snippet conversion-qbytearray-pybytes +#ifdef IS_PY3K +%out = %OUTTYPE(PyBytes_AS_STRING(%in), PyBytes_GET_SIZE(%in)); +#else +%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in)); +#endif +// @snippet conversion-qbytearray-pybytes + +// @snippet conversion-qbytearray-pybytearray +%out = %OUTTYPE(PyByteArray_AsString(%in), PyByteArray_Size(%in)); +// @snippet conversion-qbytearray-pybytearray + +// @snippet conversion-qbytearray-pystring +%out = %OUTTYPE(Shiboken::String::toCString(%in), Shiboken::String::len(%in)); +// @snippet conversion-qbytearray-pystring + +/********************************************************************* + * NATIVE TO TARGET CONVERSIONS + ********************************************************************/ + +// @snippet return-pybool +return PyBool_FromLong((bool)%in); +// @snippet return-pybool + +// @snippet return-pylong +return PyLong_FromLong(%in); +// @snippet return-pylong + +// @snippet return-pylong-unsigned +return PyLong_FromUnsignedLong(%in); +// @snippet return-pylong-unsigned + +// @snippet return-pylong-quintptr +#if defined(IS_PY3K) && QT_POINTER_SIZE == 8 +return PyLong_FromUnsignedLongLong(%in); +#else +return PyLong_FromUnsignedLong(%in); +#endif +// @snippet return-pylong-quintptr + +// @snippet return-pyunicode +QByteArray ba = %in.toUtf8(); +return PyUnicode_FromStringAndSize(ba.constData(), ba.size()); +// @snippet return-pyunicode + +// @snippet return-pyunicode-qstringref + const int N = %in.length(); + wchar_t *str = new wchar_t[N]; + %in.toString().toWCharArray(str); + PyObject *%out = PyUnicode_FromWideChar(str, N); + delete[] str; + return %out; +// @snippet return-pyunicode-qstringref + +// @snippet return-pyunicode-qchar +wchar_t c = (wchar_t)%in.unicode(); +return PyUnicode_FromWideChar(&c, 1); +// @snippet return-pyunicode-qchar + +// @snippet return-qvariant +if (!%in.isValid()) + Py_RETURN_NONE; + +if (qstrcmp(%in.typeName(), "QVariantList") == 0) { + QList var = %in.value(); + return %CONVERTTOPYTHON[QList](var); +} + +if (qstrcmp(%in.typeName(), "QStringList") == 0) { + QStringList var = %in.value(); + return %CONVERTTOPYTHON[QList](var); +} + +if (qstrcmp(%in.typeName(), "QVariantMap") == 0) { + QMap var = %in.value(); + return %CONVERTTOPYTHON[QMap](var); +} + +Shiboken::Conversions::SpecificConverter converter(cppInRef.typeName()); +if (converter) { + void *ptr = cppInRef.data(); + return converter.toPython(ptr); +} +PyErr_Format(PyExc_RuntimeError, "Can't find converter for '%s'.", %in.typeName()); +return 0; +// @snippet return-qvariant + +// @snippet return-qvariant-type +const char *typeName = QVariant::typeToName(%in); +PyObject *%out; +PyTypeObject *pyType = nullptr; +if (typeName) + pyType = Shiboken::Conversions::getPythonTypeObject(typeName); +%out = pyType ? (reinterpret_cast(pyType)) : Py_None; +Py_INCREF(%out); +return %out; +// @snippet return-qvariant-type + +// @snippet return-qjsonobject +// The QVariantMap returned by QJsonObject seems to cause a segfault, so +// using QJsonObject.toVariantMap() won't work. +// Wrapping it in a QJsonValue first allows it to work +QJsonValue val(%in); +QVariant ret = val.toVariant(); + +return %CONVERTTOPYTHON[QVariant](ret); +// @snippet return-qjsonobject + +// @snippet return-qpair +PyObject *%out = PyTuple_New(2); +PyTuple_SET_ITEM(%out, 0, %CONVERTTOPYTHON[%INTYPE_0](%in.first)); +PyTuple_SET_ITEM(%out, 1, %CONVERTTOPYTHON[%INTYPE_1](%in.second)); +return %out; +// @snippet return-qpair + +// @snippet qthread_pthread_cleanup +#ifdef Q_OS_UNIX +# include +# include +static void qthread_pthread_cleanup(void *arg) +{ + // PYSIDE 1282: When terminating a thread using QThread::terminate() + // (pthread_cancel()), QThread::run() is aborted and the lock is released, + // but ~GilState() is still executed for some reason. Prevent it from + // releasing. + auto gil = reinterpret_cast(arg); + gil->abandon(); +} +#endif // Q_OS_UNIX +// @snippet qthread_pthread_cleanup + +// @snippet qthread_pthread_cleanup_install +#ifdef Q_OS_UNIX +pthread_cleanup_push(qthread_pthread_cleanup, &gil); +#endif +// @snippet qthread_pthread_cleanup_install + +// @snippet qthread_pthread_cleanup_uninstall +#ifdef Q_OS_UNIX +pthread_cleanup_pop(0); +#endif +// @snippet qthread_pthread_cleanup_uninstall + +// @snippet qlibraryinfo_build +#if defined(IS_PY3K) && defined(Py_LIMITED_API) +auto suffix = PyUnicode_FromString(" [limited API]"); +auto oldResult = pyResult; +pyResult = PyUnicode_Concat(pyResult, suffix); +Py_DECREF(oldResult); +Py_DECREF(suffix); +#endif +// @snippet qlibraryinfo_build diff --git a/sources/pyside2/PySide2/glue/qtdatavisualization.cpp b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp new file mode 100644 index 0000000..119d79a --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtdatavisualization.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet releaseownership +Shiboken::Object::releaseOwnership(%PYARG_1); +// @snippet releaseownership diff --git a/sources/pyside2/PySide2/glue/qtgui.cpp b/sources/pyside2/PySide2/glue/qtgui.cpp new file mode 100644 index 0000000..a6b45b7 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtgui.cpp @@ -0,0 +1,547 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// @snippet qtransform-quadtoquad +QTransform _result; +if (QTransform::quadToQuad(%1, %2, _result)) { + %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qtransform-quadtoquad + +// @snippet qtransform-quadtosquare +QTransform _result; +if (QTransform::quadToSquare(%1, _result)) { + %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qtransform-quadtosquare + +// @snippet qtransform-squaretoquad +QTransform _result; +if (QTransform::squareToQuad(%1, _result)) { + %PYARG_0 = %CONVERTTOPYTHON[QTransform](_result); +} else { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} +// @snippet qtransform-squaretoquad + +// @snippet qbitmap-fromdata +uchar *buffer = reinterpret_cast(Shiboken::Buffer::getPointer(%PYARG_2)); +QBitmap %0 = QBitmap::fromData(%1, buffer, %3); +%PYARG_0 = %CONVERTTOPYTHON[QBitmap](%0); +// @snippet qbitmap-fromdata + +// @snippet qtextline-cursortox +%RETURN_TYPE %0 = %CPPSELF->::%TYPE::%FUNCTION_NAME(&%1, %2); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1)); +// @snippet qtextline-cursortox + +// @snippet qkeysequence-getitem +if (_i < 0 || _i >= %CPPSELF.count()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} +int item = (*%CPPSELF)[_i]; +return %CONVERTTOPYTHON[int](item); +// @snippet qkeysequence-getitem + +// @snippet qpicture-data +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.data(), %CPPSELF.size()); +// @snippet qpicture-data + +// @snippet qtextblock-setuserdata +const QTextDocument *doc = %CPPSELF.document(); +if (doc) { + Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument *](doc)); + Shiboken::Object::setParent(pyDocument, %PYARG_1); +} +// @snippet qtextblock-setuserdata + +// @snippet qtextblock-userdata +const QTextDocument *doc = %CPPSELF.document(); +if (doc) { + Shiboken::AutoDecRef pyDocument(%CONVERTTOPYTHON[QTextDocument *](doc)); + Shiboken::Object::setParent(pyDocument, %PYARG_0); +} +// @snippet qtextblock-userdata + +// @snippet qopenglshaderprogram_setuniformvalue_float +float value = %2; +%CPPSELF.setUniformValue(%1, value); +// @snippet qopenglshaderprogram_setuniformvalue_float + +// @snippet qopenglshaderprogram_setuniformvalue_int +int value = %2; +%CPPSELF.setUniformValue(%1, value); +// @snippet qopenglshaderprogram_setuniformvalue_int + +// @snippet qpolygon-reduce +PyObject *points = PyList_New(%CPPSELF.count()); +for (int i = 0, i_max = %CPPSELF.count(); i < i_max; ++i){ + int x, y; + %CPPSELF.point(i, &x, &y); + QPoint pt = QPoint(x, y); + PyList_SET_ITEM(points, i, %CONVERTTOPYTHON[QPoint](pt)); +} +// @snippet qpolygon-reduce + +// @snippet qpolygon-operatorlowerlower +// %FUNCTION_NAME() +*%CPPSELF << %1; +%PYARG_0 = %CONVERTTOPYTHON[QPolygon *](%CPPSELF); +// @snippet qpolygon-operatorlowerlower + +// @snippet qpixmap +%0 = new %TYPE(QPixmap::fromImage(%1)); +// @snippet qpixmap + +// @snippet qimage-constbits +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.byteCount()); +// @snippet qimage-constbits + +// @snippet qimage-bits +// byteCount() is only available on Qt4.7, so we use bytesPerLine * height +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(), %CPPSELF.bytesPerLine() * %CPPSELF.height(), Shiboken::Buffer::ReadWrite); +// @snippet qimage-bits + +// @snippet qimage-constscanline +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine()); +// @snippet qimage-constscanline + +// @snippet qimage-scanline +%PYARG_0 = Shiboken::Buffer::newObject(%CPPSELF.%FUNCTION_NAME(%1), %CPPSELF.bytesPerLine(), Shiboken::Buffer::ReadWrite); +// @snippet qimage-scanline + +// @snippet qcolor-setstate +Shiboken::AutoDecRef func(PyObject_GetAttr(%PYSELF, PyTuple_GET_ITEM(%1, 0))); +PyObject *args = PyTuple_GET_ITEM(%1, 1); +%PYARG_0 = PyObject_Call(func, args, NULL); +// @snippet qcolor-setstate + +// @snippet qcolor-reduce +switch (%CPPSELF.spec()) { + case QColor::Rgb: + { + qreal r, g, b, a; + %CPPSELF.getRgbF(&r, &g, &b, &a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), + "setRgbF", float(r), float(g), float(b), float(a)); + break; + } + case QColor::Hsv: + { + qreal h, s, v, a; + %CPPSELF.getHsvF(&h, &s, &v, &a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), + "setHsvF", float(h), float(s), float(v), float(a)); + break; + } + case QColor::Cmyk: + { + qreal c, m, y, k, a; + %CPPSELF.getCmykF(&c, &m, &y, &k, &a); + %PYARG_0 = Py_BuildValue("(ON(s(fffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), + "setCmykF", float(c), float(m), float(y), float(k), float(a)); + break; + } + case QColor::Hsl: + { + qreal h, s, l, a; + %CPPSELF.getHslF(&h, &s, &l, &a); + %PYARG_0 = Py_BuildValue("(ON(s(ffff)))", Py_TYPE(%PYSELF), PyTuple_New(0), + "setHslF", float(h), float(s), float(l), float(a)); + break; + } + default: + { + %PYARG_0 = Py_BuildValue("(N(O))", PyObject_Type(%PYSELF), Py_None); + } +} +// @snippet qcolor-reduce + +// @snippet qcolor-totuple +switch (%CPPSELF.spec()) { + case QColor::Rgb: + { + int r, g, b, a; + %CPPSELF.getRgb(&r, &g, &b, &a); + %PYARG_0 = Py_BuildValue("iiii", r, g, b, a); + break; + } + case QColor::Hsv: + { + int h, s, v, a; + %CPPSELF.getHsv(&h, &s, &v, &a); + %PYARG_0 = Py_BuildValue("iiii", h, s, v, a); + break; + } + case QColor::Cmyk: + { + int c, m, y, k, a; + %CPPSELF.getCmyk(&c, &m, &y, &k, &a); + %PYARG_0 = Py_BuildValue("iiiii", c, m, y, k, a); + break; + } + case QColor::Hsl: + { + int h, s, l, a; + %CPPSELF.getHsl(&h, &s, &l, &a); + %PYARG_0 = Py_BuildValue("iiii", h, s, l, a); + break; + } + default: + { + %PYARG_0 = 0; + } +} +// @snippet qcolor-totuple + +// @snippet qcolor +if (%1.type() == QVariant::Color) + %0 = new %TYPE(%1.value()); +else + PyErr_SetString(PyExc_TypeError, "QVariant must be holding a QColor"); +// @snippet qcolor + +// @snippet qfontmetricsf-boundingrect +int *array = nullptr; +bool errorOccurred = false; + +if (numArgs == 5) { + array = Shiboken::sequenceToIntArray(%PYARG_5, true); + if (PyErr_Occurred()) { + delete [] array; + errorOccurred = true; + } +} + +if (!errorOccurred) { + %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array); + + delete [] array; + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +} +// @snippet qfontmetricsf-boundingrect + +// @snippet qfontmetricsf-size +int *array = nullptr; +bool errorOccurred = false; + +if (numArgs == 4) { + array = Shiboken::sequenceToIntArray(%PYARG_4, true); + if (PyErr_Occurred()) { + delete [] array; + errorOccurred = true; + } +} + +if (!errorOccurred) { + %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array); + + delete [] array; + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +} +// @snippet qfontmetricsf-size + +// @snippet qfontmetrics-boundingrect-1 +int *array = nullptr; +bool errorOccurred = false; + +if (numArgs == 8) { + array = Shiboken::sequenceToIntArray(%PYARG_8, true); + if (PyErr_Occurred()) { + delete [] array; + errorOccurred = true; + } +} + +if (!errorOccurred) { + %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, %5, %6, %7, array); + + delete [] array; + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +} +// @snippet qfontmetrics-boundingrect-1 + +// @snippet qfontmetrics-boundingrect-2 +int *array = nullptr; +bool errorOccurred = false; + +if (numArgs == 5) { + array = Shiboken::sequenceToIntArray(%PYARG_5, true); + if (PyErr_Occurred()) { + delete [] array; + errorOccurred = true; + } +} + +if (!errorOccurred) { + %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, array); + + delete [] array; + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +} +// @snippet qfontmetrics-boundingrect-2 + +// @snippet qfontmetrics-size +int *array = nullptr; +bool errorOccurred = false; + +if (numArgs == 4) { + array = Shiboken::sequenceToIntArray(%PYARG_4, true); + if (PyErr_Occurred()) { + delete [] array; + errorOccurred = true; + } +} + +if (!errorOccurred) { + %RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, array); + + delete [] array; + + %PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +} +// @snippet qfontmetrics-size + +// @snippet qpixmapcache-find +QPixmap p; +if (%CPPSELF.%FUNCTION_NAME(%1, &p)) { + %PYARG_0 = %CONVERTTOPYTHON[QPixmap](p); +} else { + %PYARG_0 = Py_None; + Py_INCREF(%PYARG_0); +} +// @snippet qpixmapcache-find + +// @snippet qstandarditem-setchild-1 +// Clear parent from the old child +QStandardItem *_i = %CPPSELF->child(%1, %2); +if (_i) { + PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i); + Shiboken::Object::setParent(nullptr, _pyI); +} +// @snippet qstandarditem-setchild-1 + +// @snippet qstandarditem-setchild-2 +// Clear parent from the old child +QStandardItem *_i = %CPPSELF->child(%1); +if (_i) { + PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i); + Shiboken::Object::setParent(nullptr, _pyI); +} +// @snippet qstandarditem-setchild-2 + +// @snippet qkeyevent-operatornotequal +bool ret = !(&%CPPSELF == %1); +%PYARG_0 = %CONVERTTOPYTHON[bool](ret); +// @snippet qkeyevent-operatornotequal + +// @snippet qstandarditemmodel-setitem-1 +// Clear parent from the old child +QStandardItem *_i = %CPPSELF->item(%1, %2); +if (_i) { + PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i); + Shiboken::Object::setParent(nullptr, _pyI); +} +// @snippet qstandarditemmodel-setitem-1 + +// @snippet qstandarditemmodel-setitem-2 +// Clear parent from the old child +QStandardItem *_i = %CPPSELF->item(%1); +if (_i) { + PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i); + Shiboken::Object::setParent(nullptr, _pyI); +} +// @snippet qstandarditemmodel-setitem-2 + +// @snippet qstandarditemmodel-setverticalheaderitem +// Clear parent from the old child +QStandardItem *_i = %CPPSELF->verticalHeaderItem(%1); +if (_i) { + PyObject *_pyI = %CONVERTTOPYTHON[QStandardItem *](_i); + Shiboken::Object::setParent(nullptr, _pyI); +} +// @snippet qstandarditemmodel-setverticalheaderitem + +// @snippet qstandarditemmodel-clear +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +SbkObject *pyRoot = bm.retrieveWrapper(%CPPSELF.invisibleRootItem()); +if (pyRoot) { + Shiboken::Object::destroy(pyRoot, %CPPSELF.invisibleRootItem()); +} + +for (int r=0, r_max = %CPPSELF.rowCount(); r < r_max; r++) { + QList ri = %CPPSELF.takeRow(0); + + PyObject *pyResult = %CONVERTTOPYTHON[QList](ri); + Shiboken::Object::setParent(Py_None, pyResult); + Py_XDECREF(pyResult); +} +// @snippet qstandarditemmodel-clear + +// @snippet qclipboard-text +%BEGIN_ALLOW_THREADS +%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2); +%END_ALLOW_THREADS +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG1_TYPE](%1)); +// @snippet qclipboard-text + +// @snippet qpainter-drawpolygon +%CPPSELF.%FUNCTION_NAME(%1.data(), %1.size(), %2); +// @snippet qpainter-drawpolygon + +// @snippet qmatrix-map-point +QPoint p(%CPPSELF.%FUNCTION_NAME(%1)); +%PYARG_0 = %CONVERTTOPYTHON[QPoint](p); +// @snippet qmatrix-map-point + +// @snippet qmatrix4x4 +// PYSIDE-795: All PySequences can be made iterable with PySequence_Fast. +Shiboken::AutoDecRef seq(PySequence_Fast(%PYARG_1, "Can't turn into sequence")); +if (PySequence_Size(seq) == 16) { + float values[16]; + for (int i=0; i < 16; ++i) { + PyObject *pv = PySequence_Fast_GET_ITEM(seq.object(), i); + values[i] = PyFloat_AsDouble(pv); + } + + %0 = new %TYPE(values[0], values[1], values[2], values[3], + values[4], values[5], values[6], values[7], + values[8], values[9], values[10], values[11], + values[12], values[13], values[14], values[15]); +} +// @snippet qmatrix4x4 + +// @snippet qmatrix4x4-copydatato +float values[16]; +%CPPSELF.%FUNCTION_NAME(values); +%PYARG_0 = PyTuple_New(16); +for (int i = 0; i < 16; ++i) { + PyObject *v = PyFloat_FromDouble(values[i]); + PyTuple_SET_ITEM(%PYARG_0, i, v); +} +// @snippet qmatrix4x4-copydatato + +// @snippet qmatrix4x4-mgetitem +if (PySequence_Check(_key)) { + Shiboken::AutoDecRef key(PySequence_Fast(_key, "Invalid matrix index.")); + if (PySequence_Fast_GET_SIZE(key.object()) == 2) { + PyObject *posx = PySequence_Fast_GET_ITEM(key.object(), 0); + PyObject *posy = PySequence_Fast_GET_ITEM(key.object(), 1); + Py_ssize_t x = PyInt_AsSsize_t(posx); + Py_ssize_t y = PyInt_AsSsize_t(posy); + float ret = (*%CPPSELF)(x,y); + return %CONVERTTOPYTHON[float](ret); + } +} +PyErr_SetString(PyExc_IndexError, "Invalid matrix index."); +return 0; +// @snippet qmatrix4x4-mgetitem + +// @snippet qguiapplication-init +static void QGuiApplicationConstructor(PyObject *self, PyObject *pyargv, QGuiApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QGuiApplicationWrapper(argc, argv, 0); + Shiboken::Object::releaseOwnership(reinterpret_cast(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qguiapplication-init + +// @snippet qguiapplication-1 +QGuiApplicationConstructor(%PYSELF, args, &%0); +// @snippet qguiapplication-1 + +// @snippet qguiapplication-2 +PyObject *empty = PyTuple_New(2); +if (!PyTuple_SetItem(empty, 0, PyList_New(0))) { + QGuiApplicationConstructor(%PYSELF, empty, &%0); +} +// @snippet qguiapplication-2 + +// @snippet qscreen-grabWindow +WId id = %1; +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id, %2, %3, %4, %5); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +// @snippet qscreen-grabWindow + +// @snippet qwindow-fromWinId +WId id = %1; +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(id); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](retval); +// @snippet qwindow-fromWinId + +/********************************************************************* + * CONVERSIONS + ********************************************************************/ + +// @snippet conversion-pylong +%out = reinterpret_cast<%OUTTYPE>(PyLong_AsVoidPtr(%in)); +// @snippet conversion-pylong + +/********************************************************************* + * NATIVE TO TARGET CONVERSIONS + ********************************************************************/ + +// @snippet return-pylong-voidptr +return PyLong_FromVoidPtr(reinterpret_cast(%in)); +// @snippet return-pylong-voidptr diff --git a/sources/pyside2/PySide2/glue/qtmultimedia.cpp b/sources/pyside2/PySide2/glue/qtmultimedia.cpp new file mode 100644 index 0000000..cbe1367 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtmultimedia.cpp @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet upcast +%BEGIN_ALLOW_THREADS +QObject * upcastedArg = %CONVERTTOCPP[QObject *](%PYARG_1); +//XXX /|\ omitting this space crashes shiboken! +%CPPSELF.%FUNCTION_NAME(reinterpret_cast< %ARG1_TYPE >(upcastedArg)); +%END_ALLOW_THREADS +// @snippet upcast + +// @snippet qvideoframe-bits +%BEGIN_ALLOW_THREADS +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(); +%END_ALLOW_THREADS +%PYARG_0 = Shiboken::Buffer::newObject(%0, %CPPSELF.bytesPerLine() * %CPPSELF.height(), Shiboken::Buffer::ReadWrite); +// @snippet qvideoframe-bits diff --git a/sources/pyside2/PySide2/glue/qtnetwork.cpp b/sources/pyside2/PySide2/glue/qtnetwork.cpp new file mode 100644 index 0000000..cdb330c --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtnetwork.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qudpsocket-readdatagram +Shiboken::AutoArrayPointer data(%ARGUMENT_NAMES); +QHostAddress ha; +quint16 port; +%BEGIN_ALLOW_THREADS +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(data, %ARGUMENT_NAMES, &ha, &port); +%END_ALLOW_THREADS +QByteArray ba(data, retval); +%PYARG_0 = PyTuple_New(3); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QByteArray](ba)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QHostAddress](ha)); +PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[quint16](port)); +// @snippet qudpsocket-readdatagram + +// @snippet qipv6address-len +return 16; +// @snippet qipv6address-len + +// @snippet qipv6address-getitem +if (_i >= 16) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} +if (_i < 0) + _i = 16 - qAbs(_i); + +uint item = %CPPSELF.c[_i]; +return %CONVERTTOPYTHON[uint](item); +// @snippet qipv6address-getitem + +// @snippet qipv6address-setitem +if (_i >= 16) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return -1; +} +if (_i < 0) + _i = 16 - qAbs(_i); +quint8 item = %CONVERTTOCPP[quint8](_value); +%CPPSELF.c[_i] = item; +return 0; +// @snippet qipv6address-setitem diff --git a/sources/pyside2/PySide2/glue/qtopengl.cpp b/sources/pyside2/PySide2/glue/qtopengl.cpp new file mode 100644 index 0000000..25b6ee0 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtopengl.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qglbuffer-allocate +int size = (%2 < 0) ? %1.size() : %2; +%CPPSELF.allocate(static_cast(%1.data()), size); +// @snippet qglbuffer-allocate + +// @snippet qglbuffer-read +char *data = new char[%3]; +bool result = %CPPSELF.read(%1, data, %3); +QByteArray ret; +if (result) + ret.append(data, %3); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](result)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QByteArray](ret)); +delete[] data; +// @snippet qglbuffer-read + +// @snippet qglbuffer-write +int size = (%3 < 0) ? %2.size() : %3; +%CPPSELF.write(%1, static_cast(%2.data()), size); +// @snippet qglbuffer-write + +// @snippet qglbuffer-map +Py_ssize_t dataSize = %CPPSELF.size(); +void *data = %CPPSELF.map(%1); + +if (!data) { + Py_INCREF(Py_None); + %PYARG_0 = Py_None; +} else if (%1 == QGLBuffer::ReadOnly) { + %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadOnly); +} else { + %PYARG_0 = Shiboken::Buffer::newObject(data, dataSize, Shiboken::Buffer::ReadWrite); +} +// @snippet qglbuffer-map diff --git a/sources/pyside2/PySide2/glue/qtprintsupport.cpp b/sources/pyside2/PySide2/glue/qtprintsupport.cpp new file mode 100644 index 0000000..300a498 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtprintsupport.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet setpagesize +bool out = %CPPSELF.setPageSize(%1); +%PYARG_0 = %CONVERTTOPYTHON[bool](out); +// @snippet setpagesize diff --git a/sources/pyside2/PySide2/glue/qtqml.cpp b/sources/pyside2/PySide2/glue/qtqml.cpp new file mode 100644 index 0000000..1913204 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtqml.cpp @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qmlregistertype +int %0 = PySide::qmlRegisterType(%ARGUMENT_NAMES); +%PYARG_0 = %CONVERTTOPYTHON[int](%0); +// @snippet qmlregistertype + +// @snippet init +PySide::initQmlSupport(module); +// @snippet init + +// @snippet qjsengine-toscriptvalue +%RETURN_TYPE retval = %CPPSELF.%FUNCTION_NAME(%1); +return %CONVERTTOPYTHON[%RETURN_TYPE](retval); +// @snippet qjsengine-toscriptvalue diff --git a/sources/pyside2/PySide2/glue/qtquick.cpp b/sources/pyside2/PySide2/glue/qtquick.cpp new file mode 100644 index 0000000..b7c31af --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtquick.cpp @@ -0,0 +1,42 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qtquick +PySide::initQuickSupport(module); +// @snippet qtquick diff --git a/sources/pyside2/PySide2/glue/qtscript.cpp b/sources/pyside2/PySide2/glue/qtscript.cpp new file mode 100644 index 0000000..cf168d6 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtscript.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qscriptvalue-repr +if (%CPPSELF.isVariant() || %CPPSELF.isString()) { + QString format = QString::asprintf("%s(\"%s\")", + Py_TYPE(%PYSELF)->tp_name, + qPrintable(%CPPSELF.toString())); + %PYARG_0 = Shiboken::String::fromCString(qPrintable(format)); + } else { + %PYARG_0 = Shiboken::String::fromCString(Py_TYPE(%PYSELF)->tp_name); +} +// @snippet qscriptvalue-repr + +// @snippet qscriptvalue-mgetitem +Shiboken::AutoDecRef key(PyObject_Str(_key)); +QVariant res = %CPPSELF.property(Shiboken::String::toCString(key.object())).toVariant(); +if (res.isValid()) { + return %CONVERTTOPYTHON[QVariant](res); +} else { + PyObject *errorType = PyInt_Check(_key) ? PyExc_IndexError : PyExc_KeyError; + PyErr_SetString(errorType, "Key not found."); + return 0; +} +// @snippet qscriptvalue-mgetitem + +// @snippet qscriptvalueiterator-next +if (%CPPSELF.hasNext()) { + %CPPSELF.next(); + QString name = %CPPSELF.name(); + QVariant value = %CPPSELF.value().toVariant(); + %PYARG_0 = PyTuple_New(2); + PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[QString](name)); + PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QVariant](value)); +} else { + PyErr_SetNone(PyExc_StopIteration); +} +// @snippet qscriptvalueiterator-next diff --git a/sources/pyside2/PySide2/glue/qtuitools.cpp b/sources/pyside2/PySide2/glue/qtuitools.cpp new file mode 100644 index 0000000..d81f620 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtuitools.cpp @@ -0,0 +1,252 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +// @snippet uitools-loadui +/* + * Based on code provided by: + * Antonio Valentino + * Frédéric + */ + +#include +#include +#include +#include + +static void createChildrenNameAttributes(PyObject *root, QObject *object) +{ + for (auto *child : object->children()) { + const QByteArray name = child->objectName().toLocal8Bit(); + + if (!name.isEmpty() && !name.startsWith("_") && !name.startsWith("qt_")) { + Shiboken::AutoDecRef attrName(Py_BuildValue("s", name.constData())); + if (!PyObject_HasAttr(root, attrName)) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QObject *](child)); + PyObject_SetAttr(root, attrName, pyChild); + } + createChildrenNameAttributes(root, child); + } + createChildrenNameAttributes(root, child); + } +} + +static PyObject *QUiLoadedLoadUiFromDevice(QUiLoader *self, QIODevice *dev, QWidget *parent) +{ + QWidget *wdg = self->load(dev, parent); + + if (wdg) { + PyObject *pyWdg = %CONVERTTOPYTHON[QWidget *](wdg); + createChildrenNameAttributes(pyWdg, wdg); + if (parent) { + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent)); + Shiboken::Object::setParent(pyParent, pyWdg); + } + return pyWdg; + } + + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_RuntimeError, "Unable to open/read ui device"); + return nullptr; +} + +static PyObject *QUiLoaderLoadUiFromFileName(QUiLoader *self, const QString &uiFile, QWidget *parent) +{ + QFile fd(uiFile); + return QUiLoadedLoadUiFromDevice(self, &fd, parent); +} +// @snippet uitools-loadui + +// @snippet quiloader +Q_IMPORT_PLUGIN(PyCustomWidgets); +// @snippet quiloader + +// @snippet quiloader-registercustomwidget +registerCustomWidget(%PYARG_1); +%CPPSELF.addPluginPath(""); // force reload widgets +// @snippet quiloader-registercustomwidget + +// @snippet quiloader-load-1 +// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME() +%PYARG_0 = QUiLoadedLoadUiFromDevice(%CPPSELF, %1, %2); +// @snippet quiloader-load-1 + +// @snippet quiloader-load-2 +// Avoid calling the original function: %CPPSELF.%FUNCTION_NAME() +%PYARG_0 = QUiLoaderLoadUiFromFileName(%CPPSELF, %1, %2); +// @snippet quiloader-load-2 + +// @snippet loaduitype +/* +Arguments: + %PYARG_1 (uifile) +*/ +// 1. Generate the Python code from the UI file +#ifdef IS_PY3K +PyObject *strObj = PyUnicode_AsUTF8String(%PYARG_1); +char *arg1 = PyBytes_AsString(strObj); +QByteArray uiFileName(arg1); +Py_DECREF(strObj); +#else +QByteArray uiFileName(PyBytes_AsString(%PYARG_1)); +#endif + +QFile uiFile(uiFileName); + +if (!uiFile.exists()) { + qCritical().noquote() << "File" << uiFileName << "does not exists"; + Py_RETURN_NONE; +} + +if (uiFileName.isEmpty()) { + qCritical() << "Error converting the UI filename to QByteArray"; + Py_RETURN_NONE; +} + +// Use the 'pyside2-uic' wrapper instead of 'uic' +// This approach is better than rely on 'uic' since installing +// the wheels cover this case. +QString uicBin("pyside2-uic"); +QStringList uicArgs = {QString::fromUtf8(uiFileName)}; + +QProcess uicProcess; +uicProcess.start(uicBin, uicArgs); +if (!uicProcess.waitForFinished()) { + qCritical() << "Cannot run 'pyside2-uic': " << uicProcess.errorString() << " - " + << "Exit status " << uicProcess.exitStatus() + << " (" << uicProcess.exitCode() << ")\n" + << "Check if 'pyside2-uic' is in PATH"; + Py_RETURN_NONE; +} +QByteArray uiFileContent = uicProcess.readAllStandardOutput(); +QByteArray errorOutput = uicProcess.readAllStandardError(); + +if (!errorOutput.isEmpty()) { + qCritical().noquote() << errorOutput; + Py_RETURN_NONE; +} + +// 2. Obtain the 'classname' and the Qt base class. +QByteArray className; +QByteArray baseClassName; + +// Problem +// The generated Python file doesn't have the Qt Base class information. + +// Solution +// Use the XML file +if (!uiFile.open(QIODevice::ReadOnly)) + Py_RETURN_NONE; + +// This will look for the first tag, e.g.: +// +// and then extract the information from "class", and "name", +// to get the baseClassName and className respectively +QXmlStreamReader reader(&uiFile); +while (!reader.atEnd() && baseClassName.isEmpty() && className.isEmpty()) { + auto token = reader.readNext(); + if (token == QXmlStreamReader::StartElement && reader.name() == "widget") { + baseClassName = reader.attributes().value(QLatin1String("class")).toUtf8(); + className = reader.attributes().value(QLatin1String("name")).toUtf8(); + } +} + +uiFile.close(); + +if (className.isEmpty() || baseClassName.isEmpty() || reader.hasError()) { + qCritical() << "An error occurred when parsing the UI file while looking for the class info " + << reader.errorString(); + Py_RETURN_NONE; +} + +QByteArray pyClassName("Ui_"+className); + +PyObject *module = PyImport_ImportModule("__main__"); +PyObject *loc = PyModule_GetDict(module); + +// 3. exec() the code so the class exists in the context: exec(uiFileContent) +// The context of PyRun_SimpleString is __main__. +// 'Py_file_input' is the equivalent to using exec(), since it will execute +// the code, without returning anything. +Shiboken::AutoDecRef codeUi(Py_CompileString(uiFileContent.constData(), "", Py_file_input)); +if (codeUi.isNull()) { + qCritical() << "Error while compiling the generated Python file"; + Py_RETURN_NONE; +} +PyObject *uiObj = nullptr; +#ifdef IS_PY3K +uiObj = PyEval_EvalCode(codeUi, loc, loc); +#else +uiObj = PyEval_EvalCode(reinterpret_cast(codeUi.object()), loc, loc); +#endif + +if (uiObj == nullptr) { + qCritical() << "Error while running exec() on the generated code"; + Py_RETURN_NONE; +} + +// 4. eval() the name of the class on a variable to return +// 'Py_eval_input' is the equivalent to using eval(), since it will just +// evaluate an expression. +Shiboken::AutoDecRef codeClass(Py_CompileString(pyClassName.constData(),"", Py_eval_input)); +if (codeClass.isNull()) { + qCritical() << "Error while compiling the Python class"; + Py_RETURN_NONE; +} + +Shiboken::AutoDecRef codeBaseClass(Py_CompileString(baseClassName.constData(), "", Py_eval_input)); +if (codeBaseClass.isNull()) { + qCritical() << "Error while compiling the base class"; + Py_RETURN_NONE; +} + +#ifdef IS_PY3K +PyObject *classObj = PyEval_EvalCode(codeClass, loc, loc); +PyObject *baseClassObj = PyEval_EvalCode(codeBaseClass, loc, loc); +#else +PyObject *classObj = PyEval_EvalCode(reinterpret_cast(codeClass.object()), loc, loc); +PyObject *baseClassObj = PyEval_EvalCode(reinterpret_cast(codeBaseClass.object()), loc, loc); +#endif + +%PYARG_0 = PyTuple_New(2); +if (%PYARG_0 == nullptr) { + qCritical() << "Error while creating the return Tuple"; + Py_RETURN_NONE; +} +PyTuple_SET_ITEM(%PYARG_0, 0, classObj); +PyTuple_SET_ITEM(%PYARG_0, 1, baseClassObj); +// @snippet loaduitype diff --git a/sources/pyside2/PySide2/glue/qtwebenginewidgets.cpp b/sources/pyside2/PySide2/glue/qtwebenginewidgets.cpp new file mode 100644 index 0000000..5ee9f35 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtwebenginewidgets.cpp @@ -0,0 +1,157 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qwebenginepage-findtext +auto callable = %PYARG_3; +auto callback = [callable](bool found) +{ + if (!PyCallable_Check(callable)) { + qWarning("Argument 3 of %FUNCTION_NAME must be a callable."); + return; + } + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](found)); + Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist)); + Py_DECREF(callable); + +}; +Py_INCREF(callable); +%CPPSELF.%FUNCTION_NAME(%1, %2, callback); +// @snippet qwebenginepage-findtext + +// @snippet qwebenginepage-print +auto printer = %PYARG_1; +auto callable = %PYARG_2; +auto callback = [printer, callable](bool succeeded) +{ + if (!PyCallable_Check(callable)) { + qWarning("Argument 2 of %FUNCTION_NAME must be a callable."); + return; + } + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](succeeded)); + Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist)); + Py_DECREF(callable); + Py_DECREF(printer); + +}; +Py_INCREF(printer); // Add a reference to the printer until asynchronous printing has finished +Py_INCREF(callable); +%CPPSELF.%FUNCTION_NAME(%1, callback); +// @snippet qwebenginepage-print + +// @snippet qwebenginepage-convertto +auto callable = %PYARG_1; +auto callback = [callable](const QString &text) +{ + if (!PyCallable_Check(callable)) { + qWarning("Argument 1 of %FUNCTION_NAME must be a callable."); + return; + } + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](text)); + Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist)); + Py_DECREF(callable); + +}; +Py_INCREF(callable); +%CPPSELF.%FUNCTION_NAME(callback); +// @snippet qwebenginepage-convertto + +// @snippet qwebenginepage-runjavascript +auto callable = %PYARG_3; +auto callback = [callable](const QVariant &result) +{ + if (!PyCallable_Check(callable)) { + qWarning("Argument 3 of %FUNCTION_NAME must be a callable."); + return; + } + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + switch (result.type()) { + case QVariant::Bool: { + const bool value = result.toBool(); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](value)); + } + break; + case QVariant::Int: + case QVariant::UInt: + case QVariant::LongLong: + case QVariant::ULongLong: + case QVariant::Double: { + const double number = result.toDouble(); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[double](number)); + } + break; + default: { + const QString value = result.toString(); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QString](value)); + } + break; + } + // PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[bool](found)); + Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist)); + Py_DECREF(callable); + +}; +Py_INCREF(callable); +%CPPSELF.%FUNCTION_NAME(%1, %2, callback); +// @snippet qwebenginepage-runjavascript + +// @snippet qwebenginepage-printtopdf +auto callable = %PYARG_1; +auto callback = [callable](const QByteArray &pdf) +{ + if (!PyCallable_Check(callable)) { + qWarning("Argument 1 of %FUNCTION_NAME must be a callable."); + return; + } + Shiboken::GilState state; + Shiboken::AutoDecRef arglist(PyTuple_New(1)); + PyTuple_SET_ITEM(arglist, 0, %CONVERTTOPYTHON[QByteArray](pdf)); + Shiboken::AutoDecRef ret(PyObject_CallObject(callable, arglist)); + Py_DECREF(callable); + +}; +Py_INCREF(callable); +%CPPSELF.%FUNCTION_NAME(callback, %2); +// @snippet qwebenginepage-printtopdf diff --git a/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp b/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp new file mode 100644 index 0000000..c0f1827 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtwebkitwidgets.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qwebview-page +auto _pyReturn = reinterpret_cast(%PYARG_0); +if (!Shiboken::Object::hasParentInfo(_pyReturn)) + Shiboken::Object::setParent(%PYSELF, %PYARG_0); +// @snippet qwebview-page + +// @snippet qwebelementcollection-len +return %CPPSELF.count(); +// @snippet qwebelementcollection-len + +// @snippet qwebelementcollection-getitem +if (_i < 0 || _i >= %CPPSELF.count()) { + PyErr_SetString(PyExc_IndexError, "index out of bounds"); + return 0; +} +QWebElement element = %CPPSELF.at(_i); +return %CONVERTTOPYTHON[QWebElement](element); +// @snippet qwebelementcollection-getitem + +// @snippet qwebpage-qt-metacall +static int _signalIndex = -1; +static QMetaMethod _m; + +if (_signalIndex == -1) { + _signalIndex = QWebPage::staticMetaObject.indexOfSlot("shouldInterruptJavaScript()") + _m = QWebPage::staticMetaObject.method(_signalIndex); +} + +if (_signalIndex == id) { + Shiboken::GilState gil; + auto self = reinterpret_cast(Shiboken::BindingManager::instance().retrieveWrapper(this)); + + if (self) { + Shiboken::AutoDecRef _pyMethod(PyObject_GetAttrString(self, "shouldInterruptJavaScript")); + return PySide::SignalManager::callPythonMetaMethod(_m, args, _pyMethod, false); + } +} +// @snippet qwebpage-qt-metacall + +// @snippet qwebframe-metadata +%PYARG_0 = PyDict_New(); +const auto &keys = %0.keys(); +for (const auto &_key : keys) { + Shiboken::AutoDecRef _pyValueList(PyList_New(0)); + for (auto it = %0.lowerBound(key), end = %0.upperBound(key); it ! = end; ++it) { + Shiboken::AutoDecRef _pyValue(%CONVERTTOPYTHON[QString](it.value)); + PyList_Append(_pyValueList, _pyValue); + } + + Shiboken::AutoDecRef _pyKey(%CONVERTTOPYTHON[QString](_key)); + PyDict_SetItem(%PYARG_0, _pyKey, _pyValueList); +} +// @snippet qwebframe-metadata diff --git a/sources/pyside2/PySide2/glue/qtwidgets.cpp b/sources/pyside2/PySide2/glue/qtwidgets.cpp new file mode 100644 index 0000000..4f9baad --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtwidgets.cpp @@ -0,0 +1,663 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/********************************************************************* + * INJECT CODE + ********************************************************************/ + +// @snippet qtreewidgetitemiterator-next +if (**%CPPSELF) { + QTreeWidgetItemIterator *%0 = new QTreeWidgetItemIterator((*%CPPSELF)++); + %PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItemIterator *](%0); +} +// @snippet qtreewidgetitemiterator-next + +// @snippet qtreewidgetitemiterator-value +QTreeWidgetItem *%0 = %CPPSELF.operator *(); +%PYARG_0 = %CONVERTTOPYTHON[QTreeWidgetItem *](%0); +Shiboken::Object::releaseOwnership(%PYARG_0); +// @snippet qtreewidgetitemiterator-value + +// @snippet qgraphicsitem +PyObject *userTypeConstant = PyInt_FromLong(QGraphicsItem::UserType); +PyDict_SetItemString(reinterpret_cast(Sbk_QGraphicsItem_TypeF())->tp_dict, "UserType", userTypeConstant); +// @snippet qgraphicsitem + +// @snippet qgraphicsitem-scene-return-parenting +if (%0) { + QObject *parent = %0->parent(); + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QObject *](parent)); + Shiboken::Object::setParent(pyParent, %PYARG_0); +} +// @snippet qgraphicsitem-scene-return-parenting + +// @snippet qgraphicsitem-isblockedbymodalpanel +QGraphicsItem *item_ = NULL; +%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(&item_); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QGraphicsItem *](item_)); +// @snippet qgraphicsitem-isblockedbymodalpanel + +// @snippet qitemeditorfactory-registereditor +Shiboken::Object::releaseOwnership(%PYARG_2); +// @snippet qitemeditorfactory-registereditor + +// @snippet qitemeditorfactory-setdefaultfactory +//this function is static we need keep ref to default value, to be able to call python virtual functions +static PyObject *_defaultValue = nullptr; +%CPPSELF.%FUNCTION_NAME(%1); +Py_INCREF(%PYARG_1); +if (_defaultValue) + Py_DECREF(_defaultValue); + +_defaultValue = %PYARG_1; +// @snippet qitemeditorfactory-setdefaultfactory + +// @snippet qformlayout-fix-args +int _row; +QFormLayout::ItemRole _role; +%CPPSELF->%FUNCTION_NAME(%ARGUMENT_NAMES, &_row, &_role); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](_row)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QFormLayout::ItemRole](_role)); +// @snippet qformlayout-fix-args + +// @snippet qfiledialog-return +%RETURN_TYPE retval_ = %CPPSELF.%FUNCTION_NAME(%1, %2, %3, %4, &%5, %6); +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](retval_)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[%ARG5_TYPE](%5)); +// @snippet qfiledialog-return + +// @snippet qmenu-glue +inline PyObject *addActionWithPyObject(QMenu *self, const QIcon &icon, const QString &text, PyObject *callback, const QKeySequence &shortcut) +{ + QAction *act = self->addAction(text); + + if (!icon.isNull()) + act->setIcon(icon); + + if (!shortcut.isEmpty()) + act->setShortcut(shortcut); + + self->addAction(act); + + PyObject *pyAct = %CONVERTTOPYTHON[QAction *](act); + Shiboken::AutoDecRef result(PyObject_CallMethod(pyAct, + const_cast("connect"), + const_cast("OsO"), + pyAct, + SIGNAL(triggered()), callback)); + if (result.isNull()) { + Py_DECREF(pyAct); + return nullptr; + } + + return pyAct; +} +// @snippet qmenu-glue + +// @snippet qmenu-addaction-1 +%PYARG_0 = addActionWithPyObject(%CPPSELF, QIcon(), %1, %2, %3); +// @snippet qmenu-addaction-1 + +// @snippet qmenu-addaction-2 +%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2, %3, %4); +// @snippet qmenu-addaction-2 + +// @snippet qmenu-addaction-3 +%CPPSELF.addAction(%1); +// @snippet qmenu-addaction-3 + +// @snippet qmenu-clear +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +const auto &actions = %CPPSELF.actions(); +for (auto *act : actions) { + if (auto wrapper = bm.retrieveWrapper(act)) { + auto pyObj = reinterpret_cast(wrapper); + Py_INCREF(pyObj); + Shiboken::Object::setParent(NULL, pyObj); + Shiboken::Object::invalidate(pyObj); + Py_DECREF(pyObj); + } +} +// @snippet qmenu-clear + +// @snippet qmenubar-glue +inline PyObject * +addActionWithPyObject(QMenuBar *self, const QString &text, PyObject *callback) +{ + QAction *act = self->addAction(text); + + self->addAction(act); + + PyObject *pyAct = %CONVERTTOPYTHON[QAction *](act); + PyObject *result = PyObject_CallMethod(pyAct, + const_cast("connect"), + const_cast("OsO"), + pyAct, + SIGNAL(triggered(bool)), callback); + + if (result == nullptr || result == Py_False) { + if (result) + Py_DECREF(result); + Py_DECREF(pyAct); + return nullptr; + } + + return pyAct; +} +// @snippet qmenubar-glue + +// @snippet qmenubar-clear +const auto &actions = %CPPSELF.actions(); +for (auto *act : actions) { + Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction *](act)); + Shiboken::Object::setParent(NULL, pyAct); + Shiboken::Object::invalidate(pyAct); +} +// @snippet qmenubar-clear + +// @snippet qmenubar-addaction-1 +%PYARG_0 = addActionWithPyObject(%CPPSELF, %1, %2); +// @snippet qmenubar-addaction-1 + +// @snippet qmenubar-addaction-2 +%CPPSELF.addAction(%1); +// @snippet qmenubar-addaction-2 + +// @snippet qshortcut-1 +%0 = new %TYPE(%1, %2); +// @snippet qshortcut-1 + +// @snippet qshortcut-2 +Shiboken::AutoDecRef result(PyObject_CallMethod(%PYSELF, + const_cast("connect"), + const_cast("OsO"), + %PYSELF, SIGNAL(activated()), %PYARG_3) +); +if (!result.isNull()) + Shiboken::Object::setParent(%PYARG_2, %PYSELF); +// @snippet qshortcut-2 + +// @snippet qtoolbox-removeitem +QWidget *_widget = %CPPSELF.widget(%1); +if (_widget) { + Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](_widget)); + Shiboken::Object::setParent(0, pyWidget); +} +// @snippet qtoolbox-removeitem + +// @snippet qlayout-help-functions +void addLayoutOwnership(QLayout *layout, QLayoutItem *item); +void removeLayoutOwnership(QLayout *layout, QWidget *widget); + +inline QByteArray retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return Shiboken::String::toCString(objName); +} + +inline void addLayoutOwnership(QLayout *layout, QWidget *widget) +{ + //transfer ownership to parent widget + QWidget *lw = layout->parentWidget(); + QWidget *pw = widget->parentWidget(); + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget)); + + //Transfer parent to layout widget + if (pw && lw && pw != lw) + Shiboken::Object::setParent(0, pyChild); + + if (!lw && !pw) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](layout)); + Shiboken::Object::keepReference(reinterpret_cast(pyParent.object()), retrieveObjectName(pyParent).data(), pyChild, true); + } else { + if (!lw) + lw = pw; + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](lw)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void addLayoutOwnership(QLayout *layout, QLayout *other) +{ + //transfer all children widgets from other to layout parent widget + QWidget *parent = layout->parentWidget(); + if (!parent) { + //keep the reference while the layout is orphan + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](other)); + Shiboken::Object::keepReference(reinterpret_cast(pyParent.object()), + retrieveObjectName(pyParent).data(), pyChild, true); + return; + } + + for (int i=0, i_max=other->count(); i < i_max; i++) { + QLayoutItem *item = other->itemAt(i); + if (PyErr_Occurred() || !item) + return; + addLayoutOwnership(layout, item); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](other)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +inline void addLayoutOwnership(QLayout *layout, QLayoutItem *item) +{ + if (!item) + return; + + if (QWidget *w = item->widget()) { + addLayoutOwnership(layout, w); + } else { + if (QLayout *l = item->layout()) + addLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QLayout *](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem *](item)); + Shiboken::Object::setParent(pyParent, pyChild); +} + +static void removeWidgetFromLayout(QLayout *layout, QWidget *widget) +{ + QWidget *parent = widget->parentWidget(); + + if (!parent) { + //remove reference on layout + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](layout)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget)); + Shiboken::Object::removeReference(reinterpret_cast(pyParent.object()), + retrieveObjectName(pyParent).data(), pyChild); + } else { + //give the ownership to parent + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent)); + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](widget)); + Shiboken::Object::setParent(pyParent, pyChild); + } +} + +inline void removeLayoutOwnership(QLayout *layout, QLayoutItem *item) +{ + if (QWidget *w = item->widget()) { + removeWidgetFromLayout(layout, w); + } else { + QLayout *l = item->layout(); + if (l && item != l) + removeLayoutOwnership(layout, l); + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayoutItem *](item)); + Shiboken::Object::invalidate(pyChild); + Shiboken::Object::setParent(0, pyChild); +} + +inline void removeLayoutOwnership(QLayout *layout, QWidget *widget) +{ + if (!widget) + return; + + for (int i=0, i_max=layout->count(); i < i_max; i++) { + QLayoutItem *item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + if (item->widget() == widget) + removeLayoutOwnership(layout, item); + } +} +// @snippet qlayout-help-functions + +// @snippet qlayout-setalignment +%CPPSELF.setAlignment(%1); +// @snippet qlayout-setalignment + +// @snippet addownership-0 +addLayoutOwnership(%CPPSELF, %0); +// @snippet addownership-0 + +// @snippet addownership-1 +addLayoutOwnership(%CPPSELF, %1); +// @snippet addownership-1 + +// @snippet addownership-2 +addLayoutOwnership(%CPPSELF, %2); +// @snippet addownership-2 + +// @snippet removeownership-1 +removeLayoutOwnership(%CPPSELF, %1); +// @snippet removeownership-1 + +// @snippet qgridlayout-getitemposition +int a, b, c, d; +%CPPSELF.%FUNCTION_NAME(%1, &a, &b, &c, &d); +%PYARG_0 = PyTuple_New(4); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[int](a)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[int](b)); +PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](c)); +PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](d)); +// @snippet qgridlayout-getitemposition + +// @snippet qgraphicsscene-destroyitemgroup +QGraphicsItem *parentItem = %1->parentItem(); +Shiboken::AutoDecRef parent(%CONVERTTOPYTHON[QGraphicsItem *](parentItem)); +const auto &childItems = %1->childItems(); +for (auto *item : childItems) + Shiboken::Object::setParent(parent, %CONVERTTOPYTHON[QGraphicsItem *](item)); +%CPPSELF.%FUNCTION_NAME(%1); +// the arg was destroyed by Qt. +Shiboken::Object::invalidate(%PYARG_1); +// @snippet qgraphicsscene-destroyitemgroup + +// @snippet qgraphicsscene-addwidget +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2); +%PYARG_0 = %CONVERTTOPYTHON[%RETURN_TYPE](%0); +Shiboken::Object::keepReference(reinterpret_cast(%PYARG_0), "setWidget(QWidget*)1", %PYARG_1); +// @snippet qgraphicsscene-addwidget + +// @snippet qgraphicsscene-clear +const QList items = %CPPSELF.items(); +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +for (auto *item : items) { + SbkObject *obj = bm.retrieveWrapper(item); + if (obj) { + if (reinterpret_cast(obj)->ob_refcnt > 1) // If the refcnt is 1 the object will vannish anyway. + Shiboken::Object::invalidate(obj); + Shiboken::Object::removeParent(obj); + } +} +%CPPSELF.%FUNCTION_NAME(); +// @snippet qgraphicsscene-clear + +// @snippet qtreewidget-clear +QTreeWidgetItem *rootItem = %CPPSELF.invisibleRootItem(); +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); + +// PYSIDE-1251: +// Since some objects can be created with a parent and without +// being saved on a local variable (refcount = 1), they will be +// deleted when setting the parent to nullptr, so we change the loop +// to do this from the last child to the first, to avoid the case +// when the child(1) points to the original child(2) in case the +// first one was removed. +for (int i = rootItem->childCount() - 1; i >= 0; --i) { + QTreeWidgetItem *item = rootItem->child(i); + if (SbkObject *wrapper = bm.retrieveWrapper(item)) + Shiboken::Object::setParent(nullptr, reinterpret_cast(wrapper)); +} +// @snippet qtreewidget-clear + +// @snippet qtreewidgetitem +// Only call the parent function if this return some value +// the parent can be the TreeWidget +if (%0) + Shiboken::Object::setParent(%PYARG_0, %PYSELF); +// @snippet qtreewidgetitem + +// @snippet qlistwidget-clear +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +for (int i = 0, count = %CPPSELF.count(); i < count; ++i) { + QListWidgetItem *item = %CPPSELF.item(i); + if (auto wrapper = bm.retrieveWrapper(item)) { + auto pyObj = reinterpret_cast(wrapper); + Py_INCREF(pyObj); + Shiboken::Object::setParent(NULL, pyObj); + Shiboken::Object::invalidate(pyObj); + Py_DECREF(pyObj); + } +} +%CPPSELF.%FUNCTION_NAME(); +// @snippet qlistwidget-clear + +// @snippet qwidget-glue +static QString retrieveObjectName(PyObject *obj) +{ + Shiboken::AutoDecRef objName(PyObject_Str(obj)); + return QString(Shiboken::String::toCString(objName)); +} + + +// Transfer objects ownership from layout to widget +static inline void qwidgetReparentLayout(QWidget *parent, QLayout *layout) +{ + Shiboken::AutoDecRef pyParent(%CONVERTTOPYTHON[QWidget *](parent)); + + for (int i=0, i_count = layout->count(); i < i_count; i++) { + QLayoutItem *item = layout->itemAt(i); + if (PyErr_Occurred() || !item) + return; + + if (QWidget *w = item->widget()) { + QWidget *pw = w->parentWidget(); + if (pw != parent) { + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QWidget *](w)); + Shiboken::Object::setParent(pyParent, pyChild); + } + } else { + if (QLayout *l = item->layout()) + qwidgetReparentLayout(parent, l); + } + } + + Shiboken::AutoDecRef pyChild(%CONVERTTOPYTHON[QLayout *](layout)); + Shiboken::Object::setParent(pyParent, pyChild); + //remove previous references + Shiboken::Object::keepReference(reinterpret_cast(pyChild.object()), + qPrintable(retrieveObjectName(pyChild)), Py_None); +} + +static inline void qwidgetSetLayout(QWidget *self, QLayout *layout) +{ + if (!layout || self->layout()) + return; + + QObject *oldParent = layout->parent(); + if (oldParent && oldParent != self) { + if (oldParent->isWidgetType()) { + // remove old parent policy + Shiboken::AutoDecRef pyLayout(%CONVERTTOPYTHON[QLayout *](layout)); + Shiboken::Object::setParent(Py_None, pyLayout); + } else { + PyErr_Format(PyExc_RuntimeError, "QWidget::setLayout: Attempting to set QLayout \"%s\" on %s \"%s\", when the QLayout already has a parent", + qPrintable(layout->objectName()), self->metaObject()->className(), qPrintable(self->objectName())); + return; + } + } + + if (oldParent != self) { + qwidgetReparentLayout(self, layout); + if (PyErr_Occurred()) + return; + + self->setLayout(layout); + } +} +// @snippet qwidget-glue + +// @snippet qwidget-setstyle +Shiboken::Object::keepReference(reinterpret_cast(%PYSELF), "__style__", %PYARG_1); +// @snippet qwidget-setstyle + +// @snippet qwidget-style +QStyle *myStyle = %CPPSELF->style(); +if (myStyle && qApp) { +%PYARG_0 = %CONVERTTOPYTHON[QStyle *](myStyle); + QStyle *appStyle = qApp->style(); + if (appStyle == myStyle) { + Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication *](qApp)); + Shiboken::Object::setParent(pyApp, %PYARG_0); + Shiboken::Object::releaseOwnership(%PYARG_0); + } else { + Shiboken::Object::keepReference(reinterpret_cast(%PYSELF), "__style__", %PYARG_0); + } +} +// @snippet qwidget-style + +// @snippet qapplication-init +static void QApplicationConstructor(PyObject *self, PyObject *pyargv, QApplicationWrapper **cptr) +{ + static int argc; + static char **argv; + PyObject *stringlist = PyTuple_GET_ITEM(pyargv, 0); + if (Shiboken::listToArgcArgv(stringlist, &argc, &argv, "PySideApp")) { + *cptr = new QApplicationWrapper(argc, argv, 0); + Shiboken::Object::releaseOwnership(reinterpret_cast(self)); + PySide::registerCleanupFunction(&PySide::destroyQCoreApplication); + } +} +// @snippet qapplication-init + +// @snippet qapplication-setStyle +if (qApp) { + Shiboken::AutoDecRef pyApp(%CONVERTTOPYTHON[QApplication *](qApp)); + Shiboken::Object::setParent(pyApp, %PYARG_1); + Shiboken::Object::releaseOwnership(%PYARG_1); +} +// @snippet qapplication-setStyle + +// @snippet qwidget-setlayout +qwidgetSetLayout(%CPPSELF, %1); +// %FUNCTION_NAME() - disable generation of function call. +// @snippet qwidget-setlayout + +// @snippet qtabwidget-removetab +QWidget *tab = %CPPSELF.widget(%1); +if (tab) { + Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](tab)); + %CPPSELF.%FUNCTION_NAME(%1); +} +// @snippet qtabwidget-removetab + +// @snippet qtabwidget-clear +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +for (int i = 0, count = %CPPSELF.count(); i < count; ++i) { + QWidget *widget = %CPPSELF.widget(i); + if (bm.hasWrapper(widget)) { + Shiboken::AutoDecRef pyWidget(%CONVERTTOPYTHON[QWidget *](widget)); + Shiboken::Object::releaseOwnership(pyWidget); + } +} +%CPPSELF.%FUNCTION_NAME(); +// @snippet qtabwidget-clear + +// @snippet qlineedit-addaction +%CPPSELF.addAction(%1); +// @snippet qlineedit-addaction + +// @snippet qtoolbar-addaction-1 +QAction *action = %CPPSELF.addAction(%1, %2); +%PYARG_0 = %CONVERTTOPYTHON[QAction *](action); +Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0, + const_cast("connect"), + const_cast("OsO"), + %PYARG_0, SIGNAL(triggered()), %PYARG_3) +); +// @snippet qtoolbar-addaction-1 + +// @snippet qtoolbar-addaction-2 +QAction *action = %CPPSELF.addAction(%1); +%PYARG_0 = %CONVERTTOPYTHON[QAction *](action); +Shiboken::AutoDecRef result(PyObject_CallMethod(%PYARG_0, + const_cast("connect"), + const_cast("OsO"), + %PYARG_0, SIGNAL(triggered()), %PYARG_2) +); +// @snippet qtoolbar-addaction-2 + +// @snippet qtoolbar-addaction-3 +%CPPSELF.addAction(%1); +// @snippet qtoolbar-addaction-3 + +// @snippet qtoolbar-clear +QList lst; +Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); +const auto &toolButtonChildren = %CPPSELF.findChildren(); +for (auto *child : toolButtonChildren) { + if (bm.hasWrapper(child)) { + PyObject *pyChild = %CONVERTTOPYTHON[QToolButton *](child); + Shiboken::Object::setParent(0, pyChild); + lst << pyChild; + } +} + +//Remove actions +const auto &actions = %CPPSELF.actions(); +for (auto *act : actions) { + Shiboken::AutoDecRef pyAct(%CONVERTTOPYTHON[QAction *](act)); + Shiboken::Object::setParent(NULL, pyAct); + Shiboken::Object::invalidate(pyAct); +} + +%CPPSELF.clear(); +for (auto *obj : lst) { + Shiboken::Object::invalidate(reinterpret_cast(obj)); + Py_XDECREF(obj); +} +// @snippet qtoolbar-clear + +// @snippet qapplication-1 +QApplicationConstructor(%PYSELF, args, &%0); +// @snippet qapplication-1 + +// @snippet qapplication-2 +PyObject *empty = PyTuple_New(2); +if (!PyTuple_SetItem(empty, 0, PyList_New(0))) + QApplicationConstructor(%PYSELF, empty, &%0); +// @snippet qapplication-2 + +// @snippet qgraphicsproxywidget-setwidget +QWidget *_old = %CPPSELF.widget(); +if (_old) + Shiboken::Object::setParent(nullptr, %CONVERTTOPYTHON[QWidget *](_old)); +%CPPSELF.%FUNCTION_NAME(%1); +Shiboken::Object::setParent(%PYSELF, %PYARG_1); +// @snippet qgraphicsproxywidget-setwidget + +/********************************************************************* + * CONVERSIONS + ********************************************************************/ + +/********************************************************************* + * NATIVE TO TARGET CONVERSIONS + ********************************************************************/ diff --git a/sources/pyside2/PySide2/glue/qtxml.cpp b/sources/pyside2/PySide2/glue/qtxml.cpp new file mode 100644 index 0000000..684ff33 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtxml.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qxmlentityresolver-resolveentity +QXmlInputSource *_qxmlinputsource_arg_ = nullptr; +%BEGIN_ALLOW_THREADS +%RETURN_TYPE %0 = %CPPSELF.%FUNCTION_NAME(%1, %2, _qxmlinputsource_arg_); +%END_ALLOW_THREADS +%PYARG_0 = PyTuple_New(2); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[%RETURN_TYPE](%0)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QXmlInputSource *](_qxmlinputsource_arg_)); +// @snippet qxmlentityresolver-resolveentity + +// @snippet qdomdocument-setcontent +QString _errorMsg_; +int _errorLine_ = 0; +int _errorColumn_ = 0; +%BEGIN_ALLOW_THREADS +bool _ret_ = %CPPSELF.%FUNCTION_NAME(%ARGUMENT_NAMES, &_errorMsg_, &_errorLine_, + &_errorColumn_); +%END_ALLOW_THREADS +%PYARG_0 = PyTuple_New(4); +PyTuple_SET_ITEM(%PYARG_0, 0, %CONVERTTOPYTHON[bool](_ret_)); +PyTuple_SET_ITEM(%PYARG_0, 1, %CONVERTTOPYTHON[QString](_errorMsg_)); +PyTuple_SET_ITEM(%PYARG_0, 2, %CONVERTTOPYTHON[int](_errorLine_)); +PyTuple_SET_ITEM(%PYARG_0, 3, %CONVERTTOPYTHON[int](_errorColumn_)); +// @snippet qdomdocument-setcontent diff --git a/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp b/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp new file mode 100644 index 0000000..75ad3b2 --- /dev/null +++ b/sources/pyside2/PySide2/glue/qtxmlpatterns.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// @snippet qxmlschemavalidator-schema +QXmlSchema *%0 = new QXmlSchema(%CPPSELF.schema()); +%PYARG_0 = %CONVERTTOPYTHON[QXmlSchema *](%0); +// @snippet qxmlschemavalidator-schema diff --git a/sources/pyside2/PySide2/licensecomment.txt b/sources/pyside2/PySide2/licensecomment.txt new file mode 100644 index 0000000..9d271ba --- /dev/null +++ b/sources/pyside2/PySide2/licensecomment.txt @@ -0,0 +1,38 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ diff --git a/sources/pyside2/PySide2/py.typed.in b/sources/pyside2/PySide2/py.typed.in new file mode 100644 index 0000000..0e76a07 --- /dev/null +++ b/sources/pyside2/PySide2/py.typed.in @@ -0,0 +1 @@ +# this is a marker file for mypy diff --git a/sources/pyside2/PySide2/pysideqtesttouch.h b/sources/pyside2/PySide2/pysideqtesttouch.h new file mode 100644 index 0000000..115c783 --- /dev/null +++ b/sources/pyside2/PySide2/pysideqtesttouch.h @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PYSIDEQTESTTOUCH_H +#define PYSIDEQTESTTOUCH_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef QT_WIDGETS_LIB +#include +#endif + +QT_BEGIN_NAMESPACE + +namespace QTest +{ + + class PySideQTouchEventSequence + { + public: + ~PySideQTouchEventSequence() + { + if (commitWhenDestroyed) + commit(); + } + PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWindow *window = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(window, pt)); + p.setState(Qt::TouchPointPressed); + return this; + } + PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWindow *window = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(window, pt)); + p.setState(Qt::TouchPointMoved); + return this; + } + PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWindow *window = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(window, pt)); + p.setState(Qt::TouchPointReleased); + return this; + } + PySideQTouchEventSequence *stationary(int touchId) + { + QTouchEvent::TouchPoint &p = pointOrPreviousPoint(touchId); + p.setState(Qt::TouchPointStationary); + return this; + } + +#ifdef QT_WIDGETS_LIB + PySideQTouchEventSequence *press(int touchId, const QPoint &pt, QWidget *widget = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(widget, pt)); + p.setState(Qt::TouchPointPressed); + return this; + } + + PySideQTouchEventSequence *move(int touchId, const QPoint &pt, QWidget *widget = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(widget, pt)); + p.setState(Qt::TouchPointMoved); + return this; + } + + PySideQTouchEventSequence *release(int touchId, const QPoint &pt, QWidget *widget = nullptr) + { + QTouchEvent::TouchPoint &p = point(touchId); + p.setScreenPos(mapToScreen(widget, pt)); + p.setState(Qt::TouchPointReleased); + return this; + } +#endif + + void commit(bool processEvents = true) + { + if (!points.isEmpty()) { + if (targetWindow) + { + qt_handleTouchEvent(targetWindow, device, points.values()); + } +#ifdef QT_WIDGETS_LIB + else if (targetWidget) + { + qt_handleTouchEvent(targetWidget->windowHandle(), device, points.values()); + } +#endif + } + if (processEvents) + QCoreApplication::processEvents(); + previousPoints = points; + points.clear(); + } + +private: +#ifdef QT_WIDGETS_LIB + PySideQTouchEventSequence(QWidget *widget, QTouchDevice *aDevice, bool autoCommit) + : targetWidget(widget), targetWindow(0), device(aDevice), commitWhenDestroyed(autoCommit) + { + } +#endif + PySideQTouchEventSequence(QWindow *window, QTouchDevice *aDevice, bool autoCommit) + : +#ifdef QT_WIDGETS_LIB + targetWidget(0), +#endif + targetWindow(window), device(aDevice), commitWhenDestroyed(autoCommit) + { + } + + QTouchEvent::TouchPoint &point(int touchId) + { + if (!points.contains(touchId)) + points[touchId] = QTouchEvent::TouchPoint(touchId); + return points[touchId]; + } + + QTouchEvent::TouchPoint &pointOrPreviousPoint(int touchId) + { + if (!points.contains(touchId)) { + if (previousPoints.contains(touchId)) + points[touchId] = previousPoints.value(touchId); + else + points[touchId] = QTouchEvent::TouchPoint(touchId); + } + return points[touchId]; + } + +#ifdef QT_WIDGETS_LIB + QPoint mapToScreen(QWidget *widget, const QPoint &pt) + { + if (widget) + return widget->mapToGlobal(pt); + return targetWidget ? targetWidget->mapToGlobal(pt) : pt; + } +#endif + QPoint mapToScreen(QWindow *window, const QPoint &pt) + { + if(window) + return window->mapToGlobal(pt); + return targetWindow ? targetWindow->mapToGlobal(pt) : pt; + } + + QMap previousPoints; + QMap points; +#ifdef QT_WIDGETS_LIB + QWidget *targetWidget; +#endif + QWindow *targetWindow; + QTouchDevice *device; + bool commitWhenDestroyed; +#ifdef QT_WIDGETS_LIB + friend PySideQTouchEventSequence *generateTouchEvent(QWidget *, QTouchDevice *, bool); +#endif + friend PySideQTouchEventSequence *generateTouchEvent(QWindow *, QTouchDevice *, bool); + }; + +#ifdef QT_WIDGETS_LIB + inline + PySideQTouchEventSequence *generateTouchEvent(QWidget *widget, + QTouchDevice *device, + bool autoCommit = true) + { + return new PySideQTouchEventSequence(widget, device, autoCommit); + } +#endif + inline + PySideQTouchEventSequence *generateTouchEvent(QWindow *window, + QTouchDevice *device, + bool autoCommit = true) + { + return new PySideQTouchEventSequence(window, device, autoCommit); + } + +} + +QT_END_NAMESPACE + +#endif // PYSIDEQTESTTOUCH_H diff --git a/sources/pyside2/PySide2/pysidewtypes.h b/sources/pyside2/PySide2/pysidewtypes.h new file mode 100644 index 0000000..e147274 --- /dev/null +++ b/sources/pyside2/PySide2/pysidewtypes.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef __PYSIDEWTYPES__ +#define __PYSIDEWTYPES__ + +typedef struct HWND__ *HWND; +typedef unsigned UINT; +typedef long LONG; +typedef unsigned long DWORD; +typedef UINT WPARAM; +typedef LONG LPARAM; + +struct POINT +{ + LONG x; + LONG y; +}; + +struct MSG +{ + HWND hwnd; + UINT message; + WPARAM wParam; + LPARAM lParam; + DWORD time; + POINT pt; +}; + +#endif diff --git a/sources/pyside2/PySide2/qpytextobject.cpp b/sources/pyside2/PySide2/qpytextobject.cpp new file mode 100644 index 0000000..9bab45e --- /dev/null +++ b/sources/pyside2/PySide2/qpytextobject.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qpytextobject.h" + +/*! + \class QPyTextObject + \brief Workaround to make possible use QTextObjectInterface on PySide. + \ingroup richtext-processing + Due to the technical details of how to bind C++ classes to Python, you need to use this class when you need to implement + your own QTextObjectInterface rather than create a class inheriting from QObject and QTextObjectInterface. + + \sa QTextObjectInterface +*/ diff --git a/sources/pyside2/PySide2/qpytextobject.h b/sources/pyside2/PySide2/qpytextobject.h new file mode 100644 index 0000000..1968ac3 --- /dev/null +++ b/sources/pyside2/PySide2/qpytextobject.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt for Python. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QPYTEXTOBJECT +#define QPYTEXTOBJECT + +#include +#include + +// Qt5: no idea why this definition is not found automatically! It should come +// from which resolves to qabstracttextdocumentlayout.h +#ifdef Q_MOC_RUN +Q_DECLARE_INTERFACE(QTextObjectInterface, "org.qt-project.Qt.QTextObjectInterface") +#endif + +class QPyTextObject : public QObject, public QTextObjectInterface +{ + Q_OBJECT + Q_INTERFACES(QTextObjectInterface) +public: + QPyTextObject(QObject *parent = nullptr) : QObject(parent) {} + void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, + int posInDocument, const QTextFormat &format) = 0; + QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, const QTextFormat &format) = 0; +}; +#endif + + diff --git a/sources/pyside2/PySide2/qt.conf.in b/sources/pyside2/PySide2/qt.conf.in new file mode 100644 index 0000000..ff5b0a3 --- /dev/null +++ b/sources/pyside2/PySide2/qt.conf.in @@ -0,0 +1,2 @@ +[Paths] +Prefix = @QT_CONF_PREFIX@ diff --git a/sources/pyside2/PySide2/support/__init__.py b/sources/pyside2/PySide2/support/__init__.py new file mode 100644 index 0000000..8764fb5 --- /dev/null +++ b/sources/pyside2/PySide2/support/__init__.py @@ -0,0 +1,42 @@ +############################################################################# +## +## Copyright (C) 2017 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from shiboken2 import VoidPtr + +#eof diff --git a/sources/pyside2/PySide2/support/deprecated.py b/sources/pyside2/PySide2/support/deprecated.py new file mode 100644 index 0000000..57f33d9 --- /dev/null +++ b/sources/pyside2/PySide2/support/deprecated.py @@ -0,0 +1,80 @@ +# This Python file uses the following encoding: utf-8 +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import + +""" +deprecated.py + +This module contains deprecated things that are removed from the interface. +They are implemented in Python again, together with a deprecation warning. + +Functions that are to be called for + PySide2. must be named + fix_for_ . + +Note that this fixing code is run after all initializations, but before the +import is finished. But that is no problem since the module is passed in. +""" + +import warnings +from textwrap import dedent + + +class PySideDeprecationWarningRemovedInQt6(Warning): + pass + + +def constData(self): + cls = self.__class__ + name = cls.__qualname__ + warnings.warn(dedent(""" + {name}.constData is unpythonic and will be removed in Qt For Python 6.0 . + Please use {name}.data instead.""" + .format(**locals())), PySideDeprecationWarningRemovedInQt6, stacklevel=2) + return cls.data(self) + + +def fix_for_QtGui(QtGui): + for name, cls in QtGui.__dict__.items(): + if name.startswith("QMatrix") and "data" in cls.__dict__: + cls.constData = constData + +# eof diff --git a/sources/pyside2/PySide2/support/generate_pyi.py b/sources/pyside2/PySide2/support/generate_pyi.py new file mode 100644 index 0000000..d71ee33 --- /dev/null +++ b/sources/pyside2/PySide2/support/generate_pyi.py @@ -0,0 +1,327 @@ +# This Python file uses the following encoding: utf-8 +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of Qt for Python. +## +## $QT_BEGIN_LICENSE:LGPL$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 3 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL3 included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 3 requirements +## will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +## +## GNU General Public License Usage +## Alternatively, this file may be used under the terms of the GNU +## General Public License version 2.0 or (at your option) the GNU General +## Public license version 3 or any later version approved by the KDE Free +## Qt Foundation. The licenses are as published by the Free Software +## Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +## included in the packaging of this file. Please review the following +## information to ensure the GNU General Public License requirements will +## be met: https://www.gnu.org/licenses/gpl-2.0.html and +## https://www.gnu.org/licenses/gpl-3.0.html. +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import, unicode_literals + +""" +generate_pyi.py + +This script generates the .pyi files for all PySide modules. +""" + +import sys +import os +import io +import re +import subprocess +import argparse +from contextlib import contextmanager +from textwrap import dedent +import logging + + +# Make sure not to get .pyc in Python2. +sourcepath = os.path.splitext(__file__)[0] + ".py" + +# Can we use forward references? +USE_PEP563 = sys.version_info[:2] >= (3, 7) + +indent = " " * 4 +is_py3 = sys.version_info[0] == 3 +is_ci = os.environ.get("QTEST_ENVIRONMENT", "") == "ci" +is_debug = is_ci or os.environ.get("QTEST_ENVIRONMENT") + +logging.basicConfig(level=logging.DEBUG if is_debug else logging.INFO) +logger = logging.getLogger("generate_pyi") + + +class Writer(object): + def __init__(self, outfile): + self.outfile = outfile + self.history = [True, True] + + def print(self, *args, **kw): + # controlling too much blank lines + if self.outfile: + if args == () or args == ("",): + # Python 2.7 glitch: Empty tuples have wrong encoding. + # But we use that to skip too many blank lines: + if self.history[-2:] == [True, True]: + return + print("", file=self.outfile, **kw) + self.history.append(True) + else: + print(*args, file=self.outfile, **kw) + self.history.append(False) + + +class Formatter(Writer): + """ + Formatter is formatting the signature listing of an enumerator. + + It is written as context managers in order to avoid many callbacks. + The separation in formatter and enumerator is done to keep the + unrelated tasks of enumeration and formatting apart. + """ + def __init__(self, *args): + Writer.__init__(self, *args) + # patching __repr__ to disable the __repr__ of typing.TypeVar: + """ + def __repr__(self): + if self.__covariant__: + prefix = '+' + elif self.__contravariant__: + prefix = '-' + else: + prefix = '~' + return prefix + self.__name__ + """ + def _typevar__repr__(self): + return "typing." + self.__name__ + typing.TypeVar.__repr__ = _typevar__repr__ + + # Adding a pattern to substitute "Union[T, NoneType]" by "Optional[T]" + # I tried hard to replace typing.Optional by a simple override, but + # this became _way_ too much. + # See also the comment in layout.py . + brace_pat = build_brace_pattern(3) + pattern = (r"\b Union \s* \[ \s* {brace_pat} \s*, \s* NoneType \s* \]" + .format(**locals())) + replace = r"Optional[\1]" + optional_searcher = re.compile(pattern, flags=re.VERBOSE) + def optional_replacer(source): + return optional_searcher.sub(replace, str(source)) + self.optional_replacer = optional_replacer + # self.level is maintained by enum_sig.py + # self.after_enum() is a one-shot set by enum_sig.py . + + @contextmanager + def module(self, mod_name): + self.mod_name = mod_name + self.print("# Module", mod_name) + self.print("import PySide2") + from PySide2.support.signature import typing + self.print("try:") + self.print(" import typing") + self.print("except ImportError:") + self.print(" from PySide2.support.signature import typing") + self.print("from PySide2.support.signature.mapping import (") + self.print(" Virtual, Missing, Invalid, Default, Instance)") + self.print() + self.print("class Object(object): pass") + self.print() + self.print("import shiboken2 as Shiboken") + self.print("Shiboken.Object = Object") + self.print() + # This line will be replaced by the missing imports postprocess. + self.print("IMPORTS") + yield + + @contextmanager + def klass(self, class_name, class_str): + spaces = indent * self.level + while "." in class_name: + class_name = class_name.split(".", 1)[-1] + class_str = class_str.split(".", 1)[-1] + self.print() + if self.level == 0: + self.print() + here = self.outfile.tell() + if self.have_body: + self.print("{spaces}class {class_str}:".format(**locals())) + else: + self.print("{spaces}class {class_str}: ...".format(**locals())) + yield + + @contextmanager + def function(self, func_name, signature): + if self.after_enum() or func_name == "__init__": + self.print() + key = func_name + spaces = indent * self.level + if type(signature) == type([]): + for sig in signature: + self.print('{spaces}@typing.overload'.format(**locals())) + self._function(func_name, sig, spaces) + else: + self._function(func_name, signature, spaces) + if func_name == "__init__": + self.print() + yield key + + def _function(self, func_name, signature, spaces): + if "self" not in tuple(signature.parameters.keys()): + self.print('{spaces}@staticmethod'.format(**locals())) + signature = self.optional_replacer(signature) + self.print('{spaces}def {func_name}{signature}: ...'.format(**locals())) + + @contextmanager + def enum(self, class_name, enum_name, value): + spaces = indent * self.level + hexval = hex(value) + self.print("{spaces}{enum_name:25}: {class_name} = ... # {hexval}".format(**locals())) + yield + + +def get_license_text(): + with io.open(sourcepath) as f: + lines = f.readlines() + license_line = next((lno for lno, line in enumerate(lines) + if "$QT_END_LICENSE$" in line)) + return "".join(lines[:license_line + 3]) + + +def find_imports(text): + return [imp for imp in PySide2.__all__ if imp + "." in text] + + +def generate_pyi(import_name, outpath, options): + """ + Generates a .pyi file. + """ + plainname = import_name.split(".")[-1] + outfilepath = os.path.join(outpath, plainname + ".pyi") + top = __import__(import_name) + obj = getattr(top, plainname) + if not getattr(obj, "__file__", None) or os.path.isdir(obj.__file__): + raise ModuleNotFoundError("We do not accept a namespace as module " + "{plainname}".format(**locals())) + module = sys.modules[import_name] + + outfile = io.StringIO() + fmt = Formatter(outfile) + fmt.print(get_license_text()) # which has encoding, already + need_imports = not USE_PEP563 + if USE_PEP563: + fmt.print("from __future__ import annotations") + fmt.print() + fmt.print(dedent('''\ + """ + This file contains the exact signatures for all functions in module + {import_name}, except for defaults which are replaced by "...". + """ + '''.format(**locals()))) + HintingEnumerator(fmt).module(import_name) + fmt.print() + fmt.print("# eof") + # Postprocess: resolve the imports + with open(outfilepath, "w") as realfile: + wr = Writer(realfile) + outfile.seek(0) + while True: + line = outfile.readline() + if not line: + break + line = line.rstrip() + # we remove the IMPORTS marker and insert imports if needed + if line == "IMPORTS": + if need_imports: + for mod_name in find_imports(outfile.getvalue()): + imp = "PySide2." + mod_name + if imp != import_name: + wr.print("import " + imp) + wr.print("import " + import_name) + wr.print() + wr.print() + else: + wr.print(line) + logger.info("Generated: {outfilepath}".format(**locals())) + if is_py3 and (options.check or is_ci): + # Python 3: We can check the file directly if the syntax is ok. + subprocess.check_output([sys.executable, outfilepath]) + + +def generate_all_pyi(outpath, options): + ps = os.pathsep + if options.sys_path: + # make sure to propagate the paths from sys_path to subprocesses + sys_path = [os.path.normpath(_) for _ in options.sys_path] + sys.path[0:0] = sys_path + pypath = ps.join(sys_path) + os.environ["PYTHONPATH"] = pypath + + # now we can import + global PySide2, inspect, typing, HintingEnumerator, build_brace_pattern + import PySide2 + from PySide2.support.signature import inspect, typing + from PySide2.support.signature.lib.enum_sig import HintingEnumerator + from PySide2.support.signature.lib.tool import build_brace_pattern + + # propagate USE_PEP563 to the mapping module. + # Perhaps this can be automated? + PySide2.support.signature.mapping.USE_PEP563 = USE_PEP563 + + outpath = outpath or os.path.dirname(PySide2.__file__) + name_list = PySide2.__all__ if options.modules == ["all"] else options.modules + errors = ", ".join(set(name_list) - set(PySide2.__all__)) + if errors: + raise ImportError("The module(s) '{errors}' do not exist".format(**locals())) + quirk1, quirk2 = "QtMultimedia", "QtMultimediaWidgets" + if name_list == [quirk1]: + logger.debug("Note: We must defer building of {quirk1}.pyi until {quirk2} " + "is available".format(**locals())) + name_list = [] + elif name_list == [quirk2]: + name_list = [quirk1, quirk2] + for mod_name in name_list: + import_name = "PySide2." + mod_name + generate_pyi(import_name, outpath, options) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="This script generates the .pyi file for all PySide modules.") + parser.add_argument("modules", nargs="+", + help="'all' or the names of modules to build (QtCore QtGui etc.)") + parser.add_argument("--quiet", action="store_true", help="Run quietly") + parser.add_argument("--check", action="store_true", help="Test the output if on Python 3") + parser.add_argument("--outpath", + help="the output directory (default = binary location)") + parser.add_argument("--sys-path", nargs="+", + help="a list of strings prepended to sys.path") + options = parser.parse_args() + if options.quiet: + logger.setLevel(logging.WARNING) + outpath = options.outpath + if outpath and not os.path.exists(outpath): + os.makedirs(outpath) + logger.info("+++ Created path {outpath}".format(**locals())) + generate_all_pyi(outpath, options=options) +# eof diff --git a/sources/pyside2/PySide2/templates/core_common.xml b/sources/pyside2/PySide2/templates/core_common.xml new file mode 100644 index 0000000..6d02428 --- /dev/null +++ b/sources/pyside2/PySide2/templates/core_common.xml @@ -0,0 +1,393 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/templates/datavisualization_common.xml b/sources/pyside2/PySide2/templates/datavisualization_common.xml new file mode 100644 index 0000000..d5434dc --- /dev/null +++ b/sources/pyside2/PySide2/templates/datavisualization_common.xml @@ -0,0 +1,76 @@ + + + + + + + diff --git a/sources/pyside2/PySide2/templates/gui_common.xml b/sources/pyside2/PySide2/templates/gui_common.xml new file mode 100644 index 0000000..a139a5f --- /dev/null +++ b/sources/pyside2/PySide2/templates/gui_common.xml @@ -0,0 +1,298 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/templates/opengl_common.xml b/sources/pyside2/PySide2/templates/opengl_common.xml new file mode 100644 index 0000000..ee7b021 --- /dev/null +++ b/sources/pyside2/PySide2/templates/opengl_common.xml @@ -0,0 +1,61 @@ + + + + + diff --git a/sources/pyside2/PySide2/templates/openglfunctions_common.xml b/sources/pyside2/PySide2/templates/openglfunctions_common.xml new file mode 100644 index 0000000..117229a --- /dev/null +++ b/sources/pyside2/PySide2/templates/openglfunctions_common.xml @@ -0,0 +1,48 @@ + + + + + diff --git a/sources/pyside2/PySide2/templates/webkitwidgets_common.xml b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml new file mode 100644 index 0000000..9d0c8e5 --- /dev/null +++ b/sources/pyside2/PySide2/templates/webkitwidgets_common.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/templates/widgets_common.xml b/sources/pyside2/PySide2/templates/widgets_common.xml new file mode 100644 index 0000000..9ce01e7 --- /dev/null +++ b/sources/pyside2/PySide2/templates/widgets_common.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/PySide2/templates/xml_common.xml b/sources/pyside2/PySide2/templates/xml_common.xml new file mode 100644 index 0000000..0a6ae49 --- /dev/null +++ b/sources/pyside2/PySide2/templates/xml_common.xml @@ -0,0 +1,58 @@ + + + + + + + + + diff --git a/sources/pyside2/cmake/Macros/FindQt5Extra.cmake b/sources/pyside2/cmake/Macros/FindQt5Extra.cmake new file mode 100644 index 0000000..71846e4 --- /dev/null +++ b/sources/pyside2/cmake/Macros/FindQt5Extra.cmake @@ -0,0 +1,25 @@ +# +# Try to find QtMultimedia +# TODO: Remove this hack when cmake support QtMultimedia module +# CT: maybe we can remove this. +# For now, I just use the mapping to Qt5 + +find_package(Qt${QT_MAJOR_VERSION}Multimedia) + +if (NOT Qt${QT_MAJOR_VERSION}Multimedia_FOUND) + find_path(QT_QTMULTIMEDIA_INCLUDE_DIR QtMultimedia + PATHS ${QT_HEADERS_DIR}/QtMultimedia + ${QT_LIBRARY_DIR}/QtMultimedia.framework/Headers + NO_DEFAULT_PATH) + find_library(QT_QTMULTIMEDIA_LIBRARY QtMultimedia PATHS ${QT_LIBRARY_DIR} NO_DEFAULT_PATH) + if (QT_QTMULTIMEDIA_INCLUDE_DIR AND QT_QTMULTIMEDIA_LIBRARY) + set(QT_QTMULTIMEDIA_FOUND ON) + else() + #Replace this on documentation + set(if_QtMultimedia "") + endif() +endif () + +# Maemo is no longer supported +# QtDeclarative is no longer supported diff --git a/sources/pyside2/cmake/Macros/PySideModules.cmake b/sources/pyside2/cmake/Macros/PySideModules.cmake new file mode 100644 index 0000000..14707f9 --- /dev/null +++ b/sources/pyside2/cmake/Macros/PySideModules.cmake @@ -0,0 +1,253 @@ +include(CMakeParseArguments) + +# A version of cmake_parse_arguments that makes sure all arguments are processed and errors out +# with a message about ${type} having received unknown arguments. +macro(pyside_parse_all_arguments prefix type flags options multiopts) + cmake_parse_arguments(${prefix} "${flags}" "${options}" "${multiopts}" ${ARGN}) + if(DEFINED ${prefix}_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Unknown arguments were passed to ${type} (${${prefix}_UNPARSED_ARGUMENTS}).") + endif() +endmacro() + +macro(make_path varname) + # accepts any number of path variables + string(REPLACE ";" "${PATH_SEP}" ${varname} "${ARGN}") +endmacro() + +macro(unmake_path varname) + string(REPLACE "${PATH_SEP}" ";" ${varname} "${ARGN}") +endmacro() + +# Sample usage +# create_pyside_module(NAME QtGui +# INCLUDE_DIRS QtGui_include_dirs +# LIBRARIES QtGui_libraries +# DEPS QtGui_deps +# TYPESYSTEM_PATH QtGui_SOURCE_DIR +# SOURCES QtGui_SRC +# STATIC_SOURCES QtGui_static_sources +# TYPESYSTEM_NAME ${QtGui_BINARY_DIR}/typesystem_gui.xml +# DROPPED_ENTRIES QtGui_DROPPED_ENTRIES +# GLUE_SOURCES QtGui_glue_sources) +macro(create_pyside_module) + pyside_parse_all_arguments( + "module" # Prefix + "create_pyside_module" # Macro name + "" # Flags + "NAME;TYPESYSTEM_PATH;TYPESYSTEM_NAME" # Single value + "INCLUDE_DIRS;LIBRARIES;DEPS;SOURCES;STATIC_SOURCES;DROPPED_ENTRIES;GLUE_SOURCES" # Multival + ${ARGN} # Number of arguments given when the macros is called + ) + + if ("${module_NAME}" STREQUAL "") + message(FATAL_ERROR "create_pyside_module needs a NAME value.") + endif() + if ("${module_INCLUDE_DIRS}" STREQUAL "") + message(FATAL_ERROR "create_pyside_module needs at least one INCLUDE_DIRS value.") + endif() + if ("${module_TYPESYSTEM_PATH}" STREQUAL "") + message(FATAL_ERROR "create_pyside_module needs a TYPESYSTEM_PATH value.") + endif() + if ("${module_SOURCES}" STREQUAL "") + message(FATAL_ERROR "create_pyside_module needs at least one SOURCES value.") + endif() + + string(TOLOWER ${module_NAME} _module) + string(REGEX REPLACE ^qt "" _module ${_module}) + + if(${module_DROPPED_ENTRIES}) + string(REPLACE ";" "\\;" dropped_entries "${${module_DROPPED_ENTRIES}}") + else() + set (dropped_entries "") + endif() + + if(${module_GLUE_SOURCES}) + set (module_GLUE_SOURCES "${${module_GLUE_SOURCES}}") + else() + set (module_GLUE_SOURCES "") + endif() + + if (NOT EXISTS ${module_TYPESYSTEM_NAME}) + set(typesystem_path ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_${_module}.xml) + else() + set(typesystem_path ${module_TYPESYSTEM_NAME}) + endif() + + # Create typesystem XML dependencies list, so that whenever they change, shiboken is invoked + # automatically. + # First add the main file. + set(total_type_system_files ${typesystem_path}) + + get_filename_component(typesystem_root "${CMAKE_CURRENT_SOURCE_DIR}" DIRECTORY) + + set(deps ${module_NAME} ${${module_DEPS}}) + foreach(dep ${deps}) + set(glob_expression "${typesystem_root}/${dep}/*.xml") + file(GLOB type_system_files ${glob_expression}) + set(total_type_system_files ${total_type_system_files} ${type_system_files}) + endforeach(dep) + + # Remove any possible duplicates. + list(REMOVE_DUPLICATES total_type_system_files) + + # Contains include directories to pass to shiboken's preprocessor. + # Workaround: Added ${QT_INCLUDE_DIR}/QtCore until + # qtdeclarative/8d560d1bf0a747bf62f73fad6b6774095442d9d2 has reached qt5.git + string(REPLACE ";" ${PATH_SEP} core_includes "${Qt5Core_INCLUDE_DIRS}") + set(shiboken_include_dirs ${pyside2_SOURCE_DIR}${PATH_SEP}${QT_INCLUDE_DIR}${PATH_SEP}${core_includes}) + set(shiboken_framework_include_dirs_option "") + if(CMAKE_HOST_APPLE) + set(shiboken_framework_include_dirs "${QT_FRAMEWORK_INCLUDE_DIR}") + make_path(shiboken_framework_include_dirs ${shiboken_framework_include_dirs}) + set(shiboken_framework_include_dirs_option "--framework-include-paths=${shiboken_framework_include_dirs}") + endif() + + # Transform the path separators into something shiboken understands. + make_path(shiboken_include_dirs ${shiboken_include_dirs}) + + get_filename_component(pyside_binary_dir ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) + + # Install module glue files. + string(TOLOWER ${module_NAME} lower_module_name) + set(${module_NAME}_glue "${CMAKE_CURRENT_SOURCE_DIR}/../glue/${lower_module_name}.cpp") + set(${module_name}_glue_dependency "") + if(EXISTS ${${module_NAME}_glue}) + install(FILES ${${module_NAME}_glue} DESTINATION share/PySide2${pyside2_SUFFIX}/glue) + set(${module_NAME}_glue_dependency ${${module_NAME}_glue}) + endif() + + # Install standalone glue files into typesystems subfolder, so that the resolved relative + # paths remain correct. + if (module_GLUE_SOURCES) + install(FILES ${module_GLUE_SOURCES} DESTINATION share/PySide2${pyside2_SUFFIX}/typesystems/glue) + endif() + + add_custom_command( OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/mjb_rejected_classes.log" + BYPRODUCTS ${${module_SOURCES}} + COMMAND Shiboken2::shiboken2 ${GENERATOR_EXTRA_FLAGS} + "${pyside2_BINARY_DIR}/${module_NAME}_global.h" + --include-paths=${shiboken_include_dirs} + ${shiboken_framework_include_dirs_option} + --typesystem-paths=${pyside_binary_dir}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${${module_TYPESYSTEM_PATH}} + --output-directory=${CMAKE_CURRENT_BINARY_DIR} + --license-file=${CMAKE_CURRENT_SOURCE_DIR}/../licensecomment.txt + ${typesystem_path} + --api-version=${SUPPORTED_QT_VERSION} + --drop-type-entries="${dropped_entries}" + DEPENDS ${total_type_system_files} + ${module_GLUE_SOURCES} + ${${module_NAME}_glue_dependency} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Running generator for ${module_NAME}...") + + include_directories(${module_NAME} ${${module_INCLUDE_DIRS}} ${pyside2_SOURCE_DIR}) + add_library(${module_NAME} MODULE ${${module_SOURCES}} + ${${module_STATIC_SOURCES}}) + set_target_properties(${module_NAME} PROPERTIES + PREFIX "" + OUTPUT_NAME "${module_NAME}${SHIBOKEN_PYTHON_EXTENSION_SUFFIX}" + LIBRARY_OUTPUT_DIRECTORY ${pyside2_BINARY_DIR}) + if(WIN32) + set_target_properties(${module_NAME} PROPERTIES SUFFIX ".pyd") + # Sanitize windows.h as pulled by gl.h to prevent clashes with QAbstract3dAxis::min(), etc. + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DNOMINMAX") + endif() + + target_link_libraries(${module_NAME} ${${module_LIBRARIES}}) + target_link_libraries(${module_NAME} Shiboken2::libshiboken) + if(${module_DEPS}) + add_dependencies(${module_NAME} ${${module_DEPS}}) + endif() + create_generator_target(${module_NAME}) + + # build type hinting stubs + + # Need to set the LD_ env vars before invoking the script, because it might use build-time + # libraries instead of install time libraries. + if (WIN32) + set(ld_prefix_var_name "PATH") + elseif(APPLE) + set(ld_prefix_var_name "DYLD_LIBRARY_PATH") + else() + set(ld_prefix_var_name "LD_LIBRARY_PATH") + endif() + set(ld_prefix "${ld_prefix_var_name}=${pysidebindings_BINARY_DIR}/libpyside${PATH_SEP}${SHIBOKEN_SHARED_LIBRARY_DIR}") + + # Append any existing ld_prefix values, so existing PATH, LD_LIBRARY_PATH, etc. + # On Windows it is needed because pyside modules import Qt, + # and the Qt modules are found from PATH. + # On Linux and macOS, existing values might be set to find system libraries correctly. + # For example on openSUSE when compiling with icc, libimf.so from Intel has to be found. + if(WIN32) + # Get the value of PATH with CMake separators. + file(TO_CMAKE_PATH "$ENV{${ld_prefix_var_name}}" path_value) + + # Replace the CMake list separators with "\;"s, to avoid the PATH values being + # interpreted as CMake list elements, we actually want to pass the whole string separated + # by ";" to the command line. + if(path_value) + make_path(path_value "${path_value}") + string(APPEND ld_prefix "${PATH_SEP}${path_value}") + endif() + else() + # Handles both macOS and Linux. + set(env_value "$ENV{${ld_prefix_var_name}}") + if(env_value) + string(APPEND ld_prefix ":${env_value}") + endif() + endif() + set(generate_pyi_options ${module_NAME} --sys-path + "${pysidebindings_BINARY_DIR}" + "${SHIBOKEN_PYTHON_MODULE_DIR}") + if (QUIET_BUILD) + list(APPEND generate_pyi_options "--quiet") + endif() + + # Add target to generate pyi file, which depends on the module target. + add_custom_target("${module_NAME}_pyi" ALL + COMMAND ${CMAKE_COMMAND} -E env ${ld_prefix} + "${SHIBOKEN_PYTHON_INTERPRETER}" + "${CMAKE_CURRENT_SOURCE_DIR}/../support/generate_pyi.py" ${generate_pyi_options}) + add_dependencies("${module_NAME}_pyi" ${module_NAME}) + + # install + install(TARGETS ${module_NAME} LIBRARY DESTINATION "${PYTHON_SITE_PACKAGES}/PySide2") + + file(GLOB hinting_stub_files RELATIVE "${CMAKE_CURRENT_BINARY_DIR}/PySide2" "${CMAKE_CURRENT_BINARY_DIR}/PySide2/*.pyi") + install(FILES ${hinting_stub_files} + DESTINATION "${PYTHON_SITE_PACKAGES}/PySide2") + + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/PySide2/${module_NAME}/pyside2_${lower_module_name}_python.h + DESTINATION include/PySide2${pyside2_SUFFIX}/${module_NAME}/) + file(GLOB typesystem_files ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_*.xml ${typesystem_path}) + +# Copy typesystem files and remove module names from the element +# so that it works in a flat directory: +# +# " PARENT_SCOPE) + endif() +endmacro() + diff --git a/sources/pyside2/cmake/Macros/icecc.cmake b/sources/pyside2/cmake/Macros/icecc.cmake new file mode 100644 index 0000000..b2bf071 --- /dev/null +++ b/sources/pyside2/cmake/Macros/icecc.cmake @@ -0,0 +1,11 @@ +include (CMakeForceCompiler) +option(ENABLE_ICECC "Enable icecc checking, for distributed compilation") +if (ENABLE_ICECC) + find_program(ICECC icecc) + if (ICECC) + message(STATUS "icecc found! Distributed compilation for all!! huhuhu.") + cmake_force_cxx_compiler(${ICECC} icecc) + else(ICECC) + message(FATAL_ERROR "icecc NOT found! re-run cmake without -DENABLE_ICECC") + endif(ICECC) +endif(ENABLE_ICECC) diff --git a/sources/pyside2/cmake_uninstall.cmake b/sources/pyside2/cmake_uninstall.cmake new file mode 100644 index 0000000..df95fb9 --- /dev/null +++ b/sources/pyside2/cmake_uninstall.cmake @@ -0,0 +1,21 @@ +IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +STRING(REGEX REPLACE "\n" ";" files "${files}") +FOREACH(file ${files}) + MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + IF(EXISTS "$ENV{DESTDIR}${file}") + EXEC_PROGRAM( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval + ) + IF(NOT "${rm_retval}" STREQUAL 0) + MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + ENDIF(NOT "${rm_retval}" STREQUAL 0) + ELSE(EXISTS "$ENV{DESTDIR}${file}") + MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + ENDIF(EXISTS "$ENV{DESTDIR}${file}") +ENDFOREACH(file) diff --git a/sources/pyside2/doc/CMakeLists.txt b/sources/pyside2/doc/CMakeLists.txt new file mode 100644 index 0000000..ab5d694 --- /dev/null +++ b/sources/pyside2/doc/CMakeLists.txt @@ -0,0 +1,188 @@ +cmake_minimum_required(VERSION 3.1) +cmake_policy(VERSION 3.1) + +project(doc) + +if (WIN32) + set(PATH_SEP "\;") +else() + set(PATH_SEP ":") +endif() + +set(DOC_DATA_DIR "${CMAKE_CURRENT_BINARY_DIR}/qdoc-output") + +get_filename_component(ROOT ${CMAKE_CURRENT_BINARY_DIR} DIRECTORY) +set(TS_ROOT "${ROOT}/PySide2") + +file(REMOVE ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf ${CMAKE_CURRENT_LIST_DIR}/pyside.qdocconf.in) + +set(SHIBOKEN_INTERSPHINX_FILE "${ROOT}/pyside2/shiboken2/objects.inv") +set(HAS_WEBENGINE_WIDGETS 0) +set(SKIP_SPHINX_WARNINGS 1) +if (FULLDOCSBUILD) + set(SKIP_SPHINX_WARNINGS 0) + set(SHIBOKEN_INTERSPHINX_FILE "${CMAKE_BINARY_DIR}/doc/html/shiboken2/doc/html/objects.inv") + # For Qt modules that are part of the documentation build: + # - Configure the module docconf file + # - Write shiboken header consisting of pyside2_global.h and module includes + # - Build include path for qdoc for shiboken + + # The last element of the include list is the mkspec directory containing qplatformdefs.h + list(GET Qt${QT_MAJOR_VERSION}Core_INCLUDE_DIRS -1 mkspecInclude) + configure_file("pyside-config.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf" @ONLY) + + file(READ "${pyside2_BINARY_DIR}/pyside2_global.h" docHeaderContents) + file(READ "typesystem_doc.xml.in" typeSystemDocXmlContents) + + + foreach(moduleIn ${all_module_shortnames}) + string(TOLOWER "${moduleIn}" lowerModuleIn) + set(docConf "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-qt${lowerModuleIn}.qdocconf.in") + if(EXISTS "${docConf}") + string(REGEX REPLACE "(^.*)\.in" "\\1" OUTFILE ${docConf}) + get_filename_component(BASENAME ${OUTFILE} NAME) + configure_file(${docConf} "${CMAKE_CURRENT_LIST_DIR}/qtmodules/${BASENAME}" @ONLY) + file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/qtmodules/${BASENAME}\n") + # Handle docconf files in Qt that contain multiple modules + if ("${moduleIn}" STREQUAL "3DExtras") + set(modules 3DCore 3DRender 3DInput 3DLogic 3DAnimation "${moduleIn}") + elseif ("${moduleIn}" STREQUAL "QuickWidgets") + set(modules Qml Quick "${moduleIn}") + elseif ("${moduleIn}" STREQUAL "MultimediaWidgets") + set(modules Multimedia "${moduleIn}") + elseif ("${moduleIn}" STREQUAL "WebEngineWidgets") + set(modules WebEngine WebEngineCore "${moduleIn}") + set(HAS_WEBENGINE_WIDGETS 1) + else() + set(modules "${moduleIn}") + endif() + foreach(module ${modules}) + string(TOLOWER "${module}" lowerModule) + # -- @TODO fix this for macOS frameworks. + file(APPEND "${CMAKE_CURRENT_LIST_DIR}/pyside-config.qdocconf" + " -I ${QT_INCLUDE_DIR}Qt${module} \\\n" + " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION} \\\n" + " -I ${QT_INCLUDE_DIR}Qt${module}/${Qt${QT_MAJOR_VERSION}Core_VERSION}/Qt${module} \\\n") + + if (${moduleIn} STREQUAL "X11Extras") + set(globalHeader "QX11Info") + else() + set(globalHeader "Qt${module}") + endif() + set(docHeaderContents "${docHeaderContents}\n#include ") + set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n") + endforeach() + endif() + endforeach() + + #Appending the additional qdocconf that describes the pyside-examples + #doc project. + configure_file("qtmodules/pyside-examples.qdocconf.in" "${CMAKE_CURRENT_LIST_DIR}/qtmodules/pyside-examples.qdocconf" @ONLY) + file(APPEND "pyside.qdocconf.in" "\@CMAKE_CURRENT_LIST_DIR\@/qtmodules/pyside-examples.qdocconf\n") + + set(typeSystemDocXmlContents "${typeSystemDocXmlContents}\n\n") + file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml" "${typeSystemDocXmlContents}") + + set(docHeader "${pyside2_BINARY_DIR}/qdoc.h") + file(WRITE ${docHeader} "${docHeaderContents}") + configure_file("pyside.qdocconf.in" "pyside.qdocconf" @ONLY) + + + set(QDOC_TYPESYSTEM_PATH "${pyside2_SOURCE_DIR}${PATH_SEP}${pyside2_BINARY_DIR}") + + add_custom_target(qdoc + # Use dummy Qt version information, QDoc needs it but has no effect on WebXML output + COMMAND ${CMAKE_COMMAND} -E env BUILDDIR=${CMAKE_CURRENT_LIST_DIR}/src QT_INSTALL_DOCS=${QT_SRC_DIR}/doc + QT_VERSION=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} + QT_VER=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR} + QT_VERSION_TAG=${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH} + qdoc pyside.qdocconf -single-exec -installdir ${DOC_DATA_DIR} -outputdir ${DOC_DATA_DIR} + COMMENT "Running qdoc against Qt source code..." + SOURCE "pyside.qdocconf") +endif() + +# conditional tag for sphinx build +#string(JOIN "_" SPHINX_TAG ${DOC_OUTPUT_FORMAT} "format") +# Python script to replace the virtualFolder string in the QHP +set(py_cmd "from __future__ import print_function +import fileinput +import re +try: +\tfor line in fileinput.input('html/PySide.qhp',inplace=True,backup='.bak'): +\t\tline_copy=line.strip() +\t\tif not line_copy: # check for empty line +\t\t\tcontinue +\t\tmatch=re.match('(^.*virtualFolder.)doc(.*$)',line) +\t\tif match: +\t\t\trepl=''.join([match.group(1),'pyside2',match.group(2)]) +\t\t\tprint(line.replace(match.group(0),repl),end='') +\t\telse: +\t\t\tprint(line) +except: +\tpass\n") +file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/py_script.py CONTENT ${py_cmd}) + +add_custom_target(apidoc + COMMAND ${SHIBOKEN_PYTHON_INTERPRETER} ${SPHINX_BUILD} -b ${DOC_OUTPUT_FORMAT} ${CMAKE_CURRENT_BINARY_DIR}/rst html + COMMENT "Generating PySide htmls..." + ) + +# create a custom commands to copy the shiboken docs +# and generate offline help based on the output format. +if(DOC_OUTPUT_FORMAT STREQUAL "html") + add_custom_command(TARGET apidoc POST_BUILD + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2 + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_BINARY_DIR}/../../shiboken2/doc/html + ${CMAKE_CURRENT_BINARY_DIR}/html/shiboken2 + COMMENT "Copying Shiboken docs..." + VERBATIM) +else() + file(TO_NATIVE_PATH ${CMAKE_CURRENT_BINARY_DIR}/html/PySide.qhp QHP_FILE) + add_custom_command(TARGET apidoc POST_BUILD + COMMAND ${PYTHON_EXECUTABLE} py_script.py + COMMAND qhelpgenerator ${QHP_FILE} + COMMENT "Generating QCH from a QHP file..." + VERBATIM) +endif() + +# create conf.py based on conf.py.in +configure_file("conf.py.in" "rst/conf.py" @ONLY) + +add_custom_target("docrsts" + COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/rst + COMMAND Shiboken2::shiboken2 --generator-set=qtdoc ${docHeader} + --include-paths="${QT_INCLUDE_DIR}${PATH_SEP}${pyside2_SOURCE_DIR}${PATH_SEP}${TS_ROOT}" + --api-version=${SUPPORTED_QT_VERSION} + --typesystem-paths="${QDOC_TYPESYSTEM_PATH}" + --library-source-dir=${QT_SRC_DIR} + --documentation-data-dir=${DOC_DATA_DIR}/webxml + --output-directory=${CMAKE_CURRENT_BINARY_DIR}/rst + --documentation-code-snippets-dir=${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/doc/src/snippets${PATH_SEP}${CMAKE_CURRENT_BINARY_DIR}/rst/codesnippets/examples + --documentation-extra-sections-dir=${CMAKE_CURRENT_BINARY_DIR}/rst/extras + --additional-documentation=${CMAKE_CURRENT_BINARY_DIR}/rst/additionaldocs.lst + ${CMAKE_CURRENT_BINARY_DIR}/typesystem_doc.xml + WORKING_DIRECTORY ${${module}_SOURCE_DIR} + COMMENT "Running generator to generate documentation..." +) + +add_custom_target("licensedocrsts" + COMMAND ${PYTHON_EXECUTABLE} + ${CMAKE_CURRENT_LIST_DIR}/qtattributionsscannertorst.py + ${CMAKE_CURRENT_LIST_DIR}/../../.. + ${CMAKE_CURRENT_BINARY_DIR}/rst/licenses.rst + COMMENT "Creating 3rdparty license documentation..." +) + +if (FULLDOCSBUILD) + add_dependencies(apidoc docrsts licensedocrsts) + add_dependencies(licensedocrsts docrsts) + add_dependencies(docrsts qdoc) +endif() + +#install files +add_custom_target(apidocinstall + COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/share/doc/PySide2-${BINDING_API_VERSION} && cp -rv ${CMAKE_CURRENT_BINARY_DIR}/html/* ${CMAKE_INSTALL_PREFIX}/share/doc/PySide-${BINDING_API_VERSION} +) + +add_dependencies(apidocinstall apidoc) diff --git a/sources/pyside2/doc/_templates/layout.html b/sources/pyside2/doc/_templates/layout.html new file mode 100644 index 0000000..6ab1276 --- /dev/null +++ b/sources/pyside2/doc/_templates/layout.html @@ -0,0 +1,40 @@ +{% extends "!layout.html" %} + +# Invert sidebars +{%- block sidebar1 %}{{ sidebar() }}{%- endblock %} +{%- block sidebar2 %}{%- endblock %} + +{%- block header %} +
+
+
+ + +
+
+{%- endblock -%} + +{%- block footer %} + +
+{%- endblock %} + +# No top relbar. +{%- block relbar1 %}{%- endblock %} + +# No bottom relbar. +{%- block relbar2 %}{%- endblock %} diff --git a/sources/pyside2/doc/_themes/pysidedocs/domainindex.html b/sources/pyside2/doc/_themes/pysidedocs/domainindex.html new file mode 100644 index 0000000..c136cdd --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs/domainindex.html @@ -0,0 +1,57 @@ +{# + basic/domainindex.html + ~~~~~~~~~~~~~~~~~~~~~~ + + Template for domain indices (module index, ...). + + :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS. + :license: BSD, see LICENSE for details. +#} +{% extends "layout.html" %} +{% set title = indextitle %} +{% block extrahead %} +{{ super() }} +{% if not embedded and collapse_index %} + +{% endif %} +{% endblock %} +{% block body %} +
+ {%- set curr_group = 0 %} + +

{{ indextitle }}

+ +
+ {%- for (letter, entries) in content %} + {{ letter }} + {%- if not loop.last %} | {% endif %} + {%- endfor %} +
+ + + {%- for letter, entries in content %} + + + {%- for (name, grouptype, page, anchor, extra, qualifier, description) + in entries %} + {%- if grouptype == 1 %}{% set curr_group = curr_group + 1 %}{% endif %} + + + + {%- endfor %} + {%- endfor %} +
 
+ {{ letter }}
{% if grouptype == 1 -%} + + {%- endif %}{% if grouptype == 2 %}   {% endif %} + {% if page %}{% endif -%} + {{ name|e }} + {%- if page %}{% endif %} + {%- if extra %} ({{ extra|e }}){% endif -%} + {% if qualifier %}{{ qualifier|e }}:{% endif %} + {{ description|e }}
+
+{% endblock %} diff --git a/sources/pyside2/doc/_themes/pysidedocs/searchbox.html b/sources/pyside2/doc/_themes/pysidedocs/searchbox.html new file mode 100644 index 0000000..55a9721 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs/searchbox.html @@ -0,0 +1,12 @@ +{%- if pagename != "search" %} + + +{%- endif %} diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/bg_header.png b/sources/pyside2/doc/_themes/pysidedocs/static/bg_header.png new file mode 100644 index 0000000000000000000000000000000000000000..843e7e2c5a85f4ced9bc4d4f90dab4a6d82aa3f3 GIT binary patch literal 36012 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/bg_topo.jpg b/sources/pyside2/doc/_themes/pysidedocs/static/bg_topo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4229ae8db5242e11c8fc52dd1122735d198a3545 GIT binary patch literal 14237 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/fakebar.png b/sources/pyside2/doc/_themes/pysidedocs/static/fakebar.png new file mode 100644 index 0000000000000000000000000000000000000000..b45830e000eb123c3efab6bfc3b17809a3a08530 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0y~yVB`m~89A7Mq`$$QwLprqz$3Dlfr0M`2s2LA=92~r xihH^^hG*5B1h}~tn49EFcPMuw|ksYXn!PC{xWt~$(69Du$7_a~U literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/logo_python.jpg b/sources/pyside2/doc/_themes/pysidedocs/static/logo_python.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cd474efbaa633dde7998c09170e4500acc4a13ce GIT binary patch literal 2660 zcmb`IXHe5w7sme~g$OYaK&6YcMRr390r3+A|xavB_t5ih(D1=Af=?GkO)~>IXPKbWhEsg<%53%5*HWWi`XkK zEiJFO54BJ6Z{vSmh+Y9GIDiN0z#tSLh5~_6AW=I|u-mp67z6_CHu@J(m>5JH41(`! zUyXk_5GV{R1`?MBKwz*KL`+-^F7@Y`uPIOvs0{3op{)3MbzG!5y=N&o#g`K~VJ*6)Dq`KvT zk7yJ?fOo@DU=&~t2rnf4Uq}Xr&&_ps5U%Od5m+;`D@y2KU7y?K!B6dR!KI2x1LxVN zThjDpjo~?pE3=`Ze=@Jb4EMm#&Z{c%ktEbwOmjVc58a)c_v7 z^2MlLFz3o;viH}U20@|{zs+hPXm(CKkc{ah^>dxHUMB&Rz}^K5mOOeIT0MSp1h4W| z{KZjc8cj#1DX*cvzU5;{ea_mO#ks(Hwg>7&fPbG|8Lt1F^jAndImrqQ;f70!cj8Lz zf=*zz_gKE{4KUT8y|%vM)PKT{;Mp&@dekLDmofk)#)iE0fA8y%i}m0+U~I3oD$T(1 zA5XhUtWFjOtuwp1a2Ayt8a|EoZeXRPj%U;cpO7`SDT~c2j2PaDsE9ni%yz~{G1-;5 zbKH%~b6gIZdU5Mh-xOBlT*j1n4fS#I59QCk)ILI-#t+ z7_$S3!rDC|;1GE^zmZ69<;l#~X7#=_5TaCLh37`_yoV-QH9zgd+-o*z6DUQtdsYvP zkGK;RuhS0aJac)*>WJ>BEqsxY+skV1?DT$Ki$suO^i_$p<5h5tN`C=MpBmL!?erh0 z2mpADBDK&#)zhSCUh+jh!D3KP8unV&lW@rfm#B8miLFo8X$f$QMJy{M+R8|Y2I&OSoy*3L*Pf`l%ShmbEk&INIUFHoB73zAug?mpSwf~kJ&nRB0763oO#yn zm+u$RspIu*Zm4!MIxRM0^BrWpD{A)WqtG0`!XRk5H6$qg)^RTQ_xw#4M>Dl2QME_t zlzp+@Kd`^}wF#&if|5k1Q8j!&nA+1jwRCg8e@I4G>bPkPb%+omXC|gVj`yF-4b(JE zamB1jOX-H=j2p2Oga0s@%p~5-GI!`XgH-HDD(mPUr8hxrX3sX@yKQ|16``D{0c0^d zr~XHWVI;aR3yfRDS!D6>ceuX@*$USgX;`b6c~|*aDP#BwPRg4)VR5Uc9)W4fv{upo zUWJo+&(%}WKG6MOPUCTeDQ~@p+AFN8%VH8Z-x8z&Igm4g28Q1$xx$4_4t3g(0N>K__+vw>T|k23p)P0^n-=+A3i zY+H*fVf1`O%9E&$-#lDCTJxG9FfS1h-1_Cd@Lel1GbxF3e|-sn4kaf5_V0Db`*qBCX|R@#Ejf zKhjI7!&GMUh8DVM`Po^=Eh`~%sp=$S>kTjL#29|AYS43dCr-Hb!f8Mm^Q^bP(Gsd# z!WTBvI9VeqCj9AxQ@uM2Hi@c6FOqZ)B%TC>cjzYy&9Y9fcnicbJ&^Rq&P_G zrRg(kUMFj2KM0JkMi#k~O156rJV>u2RJ6>LV}7*`Pup9`TbehWH7D{;YrpZbw2#$@ zxp8Lxs#SiVCS4}EIi)Q`|9*BOMIlq+vDP>hpWo#!mrXm~&}1?ha~|Rnf!^>FXut8G znJWjSvIstupS7uj`>k%~Zh<2xZTUz_6LV=qSRI;vngJxvcdWnjN*h1HEdczWqS~ zku}LHT9*4G6hHzJ1wX#8>mK(U>Ui&EJJ@g|OQyrQ;b!L?QeQJnN8QLG+7KI29osqi zE}dBuaq(;!#lBlxZqTXl^{H*?D__4LTmK4e+J5sxWdrw}Gkp(2?G_(d%oaInxK{Z% zb2Ob})}LK8b+)k2n`OO9mT3Rj5!ZWPR(7(synXcyf$!M1G~Vrk>%Sf`#JbfG6Z30@ zY8!cnD92GAdKy_%THEI}C1vWA$7FIm&sFP({eSF&u3fno=skRc?{_0a8;-N|DqjT|?_BFWCv45f9)3Jho Lk^f!7iAMelGjO_W literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/logo_qt.png b/sources/pyside2/doc/_themes/pysidedocs/static/logo_qt.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc03b7c7e5581f9b56bd5505684d99c31df99d6 GIT binary patch literal 1936 zcmaJ?X;c$e6dnkuMX{n*tyUXjTNfmg1cD?I5fUOPhFuAYl#omyKr$g2B%o-(rJ}8Z zNO7YsRja7TLBS0bp=uQ+EMZ?2f&qeIQMRyjqN4p#I_J*3_wKphch`3&!NYBxx!HU( z007KcE(|YpU2Ax!V9;;c%{VQ(e2qAB5N}w3L~*4M;K+xAAS_G74TiiREr zF9!3YFZ4vig&>H83W8BlQTQlpJS+`Hu@nkOAb}*36>4E6ixwkXxs_P9WSoHk$#_zs z1QEhwtbvgm1VgDfoY&Ml8mLXg*4`MNBIFt!56!NKd)^;Qci9sL}=uSkUv#lM4VdrFLL$D(| zGAJab%{Z0;^CCr%7#YX%KVyj#Vhtl9lAxX$kW{!8;xnbN2>U*Ds&K+s=*|=JeZ=x7 zjD^me5DTKgfQAPDtKs7+bczhyPveUoK3xDvj84529dDzqd?o-GrF*RRaYnDm*w~ok z3$G92^un87o>ntt7ysB+#dnx1p5p zTPEO?1^bnSY(hmP+^h=qSA}j-g$0y{2bPPuJP*<{IaXz;O@pldmEDy znv(Z79XZgHa`5G`#8=0YUY$s8PCH_d-&2}TrM8?-Z8>wS- zUOLm7ezrCJf+pjlCi9XeGrcYAa$DAww(A+~*;yU8Z*<(b(Q!9ho13G(cT;=smiED& z&b)hX3i94O%F{j0*F7oF{av7Y`d8P}$6bX_yI(x(Ru*;_KS!mfwYF zRoYuo)?2B1TUGwHs_I=`^}D*7clEV>4Rw8u4Sg?P^{bl))GY(ATL(0n!S=Snj*g*D z?NFyq-=))ccj>!(^u0a9y?rD7{UZYdBZGq@L;6v@esp+vba-TRWOQs4?NPSl+U01s zOb{2{j+A+s7dgBJYIpE zE6(A^Jx@0?SprPXU1OR!TbR?i0HEcFY8TFbXq-8td&nejgT?09t321K6-M?RbIGZb zn!F_sJr%rA()1Qa4z*~ZV#kw+lXTaqZnt#LFY5tI%(Z+!z?Hq%C@9V} z7K%TEo8uxGZFHaEFEI-&i8^e|S;z^*eB+tC6o`y7WhrE#B=ha&_vdahnpEDr7_)xT z+?8XdxxVqX3a)$RBY4$8Ot__AWit*}Iz6+%y?CnRW)<@RaQg=fiv-Mf!zOG$#iA(s zsx_waqi_Yrzn3-(HX^iX;re5@?7!@)P4jG7o!61H4$RP)gb7^T)z*8?Y}?cFYhOUf z;H`lG&ASS_4nf(_iRIKpPm{)=hJEBDWob;DOTojqC$qf0uL*JwGZlq8fsmV;UCFzc4K5X1;+ma2r*h^ literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/minus.png b/sources/pyside2/doc/_themes/pysidedocs/static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css new file mode 100644 index 0000000..f6a1c5a --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs/static/pyside.css @@ -0,0 +1,2076 @@ +@import url('cookie-confirm.css') screen; + +/* -- admonitions -- */ + +div.admonition { + margin: 1.5em 0 1.5em; + padding: 0; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.admonition code { + font-family: inherit; +} + +p.admonition-title + p { + padding-left: 1em; +} + +div.admonition a:after { + content: ', '; +} + +div.admonition a:last-child:after { + content: ''; +} + +.body { + width: 100% +} +.bodywrapper .admonition p.admonition-title { + margin-bottom:5px +} + +.bodywrapper .admonition p { + margin:0 +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +div.warning, div.seealso, div.note { + padding: 6px 0px 6px 10px; + border: none; +} + +div.warning { + background-color: #ffe4e4; +} + +div.seealso { + background-color: #fff2d6; +} + +div.note { + background-color: #f3f3f4; +} + +table.docutils { + margin-right: auto; + margin-bottom: 10px; + border: none; + width: initial; +} + +table.docutils.colwidths-given td { + float: none; +} + +table.docutils th, +table.docutils td { + padding-left:0; + border: none; +} + +table.docutils td ul { + margin:0 +} + +table.docutils td ul > li { + margin: 0 0 0.5em; +} +h2 em { + float: right; + font-size: 10px; + position: relative; + top: -20px; +} + +.document { + padding-bottom: 20px; +} + +.documentwrapper { + margin-left: 255px; +} + +.body blockquote { + border: none; + padding-left: 0; + margin-bottom: 1.5em; +} + +.sphinxsidebar { + float: left; + width: 186px; + padding: 25px; + text-align: left; + background-color: #fff; +} + +.sphinxsidebar ul { + padding: 0px; + margin: 0px; + list-style-position: inside; +} + +.sphinxsidebar > ul { + padding: 0px; + margin: 0px; +} + +.sphinxsidebar ul li li { + margin-left: 10px; + padding: 0px; + font-size: 0.95em; +} + +.sphinxsidebar ul a, +.sphinxsidebar p.topless a { + word-break: break-word; +} + +.sphinxsidebar h3, .sphinxsidebar h3 a { + color: #333; +} + +.sphinxsidebar p.topless { + margin: 1em 0 1em; +} + +.pysidetoc ul { + list-style: none; + padding: 0px; + margin: 0px; +} + +.pysidetoc em { + font-style: normal; +} + +.pysidetoc strong { + display: block; + padding: 5px; + margin: 0 10px 10px 0; + border: none; + background-color: #e2e2e2; +} + +.section .docutils.container td { + float:left; +} + +.hide { + display: none; +} + +/* copy-notice */ +.document + p { + margin-left: 255px; + width: 70%; + font-size: 0.75em; + margin: 0 35px 15px 280px; +} + +#searchbox { + border-top: 1px solid #989898; + padding-top: 10px; + margin-left: -10px; + margin-right: -10px; + padding-left: 10px; + padding-right: 10px; +} + +#search_button { + border: 1px solid #3A393A; + background-color: #3A393A; + color: white; + cursor: pointer; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + +} + +form { + margin: 0px; + padding: 0px; +} + +#searchbox h3 { + padding: 10px 0 0 0; + margin-bottom: 5px; +} + +/* search field */ +form #q { + width: 136px; + /* height: 22px; */ + /* border: none; */ + margin: 0px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + margin-top: 2px; + padding: 4px; + line-height: 22px; +} + +#search-results h2 { + display: none; +} + +#search-results h2 { + display: none; +} + +#search-results ul.search { + margin: 0px; + padding: 0px; +} + +ul.search div.context { + padding-left: 40px; +} + +#installation td { + text-align: center; + font-weight: bold; +} + +em { + color: inherit; + font-style:italic; +} + +/******** REL bar *********/ + +.related { + display: inline; +} + +.related h3 { + display: none; +} + +.align-center { + text-align: center; +} + +.contentstable { + width: 100%; +} + +.contentstable td { + padding-left: 30px; + vertical-align: top; +} + +p.biglink a { + font-size: 20px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +p.highlight-link { + margin-top: 10px; + font-size: 0.8em; +} + +#synopsis table, table.field-list { + margin: 1em 0 1em 0; +} + +table.field-list tr { + text-align: left; +} + +tt.descname { + font-size: 120%; + font-weight: bold; +} + +#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul { + margin: 0; + padding: 6px; + border: 1px solid #ddd; + border-radius: 0; + background-color: #e2e2e2; +} + +#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p { + margin: 0; + padding: 0; +} + +#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li { + list-style: none; + margin: 5px; + padding: 0; + font-size: 90%; +} + +#synopsis span.pre { + color: #009491; + font-weight: bolder; +} + +#detailed-description .class dt, +#detailed-description .method dt, +#detailed-description .staticmethod dt, +#detailed-description .attribute dt { + margin: 0px; + margin-bottom: 10px; + padding: 10px; + font-weight: bold; + background-color: #e2e2e2; + border: none; + border-radius: 0; +} + +#detailed-description dd > blockquote, +#detailed-description dd > .field-list { + font-family: 'Droid Sans Mono'; + font-size: small; + border-left: 10px solid #e2e2e2; + padding-left: 10px; + margin-bottom: 1.5em; +} + +#detailed-description dd > blockquote blockquote { + border: none; + padding: 0; +} + +#detailed-description .class .field-odd, +#detailed-description .method .field-odd, +#detailed-description .staticmethod .field-odd, +#detailed-description .attribute .field-odd { + margin: 0; + padding: 1px 0 0 0; + background-color: #ffffff; + +} + +#detailed-description .class .field-even, +#detailed-description .method .field-even, +#detailed-description .staticmethod .field-even, +#detailed-description .attribute .field-even { + margin: 0; + padding: 1px 0 0 0; + background-color: #ffffff; +} + +#detailed-description .class .field-odd li, +#detailed-description .method .field-odd li, +#detailed-description .staticmethod .field-odd li, +#detailed-description .attribute .field-odd li { + list-style: none; + margin: 0; + padding: 0; + +} + +#detailed-description .class .field-even li, +#detailed-description .method .field-even li, +#detailed-description .staticmethod .field-even li, +#detailed-description .attribute .field-even li { + list-style: none; + margin: 0; + padding: 0; +} + +#detailed-description .class .field-odd p, +#detailed-description .method .field-odd p, +#detailed-description .staticmethod .field-odd p, +#detailed-description .attribute .field-odd p{ + margin: 0; + margin-left: 20px; + +} + +#detailed-description .class .field-even p, +#detailed-description .method .field-even p, +#detailed-description .staticmethod .field-even p, +#detailed-description .attribute .field-even p{ + margin: 0; + margin-left: 20px; +} + +#detailed-description .class .field-odd p:last-child, +#detailed-description .method .field-odd p:last-child, +#detailed-description .staticmethod .field-odd p:last-child, +#detailed-description .attribute .field-odd p:last-child { + margin-bottom: 10px; + +} + +#detailed-description .class .field-even p:last-child, +#detailed-description .method .field-even p:last-child, +#detailed-description .staticmethod .field-even p:last-child, +#detailed-description .attribute .field-even p:last-child{ + margin-bottom: 10px; +} + +.document dl.attribute, +.document dl.class, +.document dl.method, +.document dl.staticmethod { + margin-top: 2em; +} + +.document dl.attribute dd, +.document dl.class dd, +.document dl.method dd, +.document dl.staticmethod dd { + padding-left: 1em; +} + +#detailed-description .attribute td:nth-child(1) { + font-family: 'Droid Sans Mono'; +} + +/* Qt theme */ +#navbar { + position:fixed; + top:0; + left:0; + z-index:100; + background:#fff; + width:100% +} +#navbar .container, .fixed .container { + max-width:1280px; + margin:0 auto; + padding:0 3.9%; /* 0? */ + position:relative; + overflow:visible +} +#navbar .navbar-header { + position:relative +} +#menuextras li a:hover span { + color: #41cd52; +} +/* new header */ +#mm-wrap, #mm-wrap #mm-helper, +#mm-wrap #mm-helper li.mm-item, +#mm-wrap #mm-helper a.mm-link { + -moz-transition: none; + -o-transition: none; + -webkit-transition: none; + transition: none; + -webkit-border-radius: 0 0 0 0; + -moz-border-radius: 0 0 0 0; + -ms-border-radius: 0 0 0 0; + -o-border-radius: 0 0 0 0; + border-radius: 0 0 0 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + background: none; + border: 0; + bottom: auto; + box-sizing: border-box; + clip: auto; + color: #090e21; + display: block; + float: none; + font-family: inherit; + font-size: 14px; + height: auto; + left: auto; + line-height: 1.7; + list-style-type: none; + margin: 0; + min-height: 0; + opacity: 1; + outline: none; + overflow: visible; + padding: 0; + position: relative; + right: auto; + text-align: left; + text-decoration: none; + text-transform: none; + top: auto; + vertical-align: baseline; + visibility: inherit; + width: auto; +} +#mm-wrap #mm-helper { + visibility:visible; + text-align:right; + padding:0 0px 0 0px +} +#navbar #mm-wrap #mm-helper li.mm-item { + border-right:solid #f3f3f4 1px; + padding-right:30px; + padding-left:30px +} +#navbar #mm-wrap #mm-helper li.mm-item > a:hover { + opacity: .5 +} +#mm-wrap #mm-helper > li.mm-item { + margin:0 0 0 0; + display:inline-block; + height:auto; + vertical-align:middle +} +#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) { + border-right:0 +} +#mm-wrap #mm-helper a.mm-link { + cursor: pointer +} +@media (max-width: 1279px) { + #navbar { + padding:0; + position:relative; + } + #navbar .container { + max-width:100% + } + .container { + padding:0 2% + } + .sphinxsidebar { + top: 16px !important; + } +} +#navbar .navbar-oneQt { + display:inline; + float:left; + width:31px; + color:#41cd52 +} +#navbar .navbar-oneQt:before { + content:attr(data-icon); + position:absolute; + top:14px; + left:0; + color:#41cd52; + font-family:'Qt Icons'; + line-height:1; + font-size:40px; + transition:all 0.3s ease-in-out; +} +#mm-wrap { + clear:both; + background:rgba(255, 255, 255, 0.1); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px +} +#mm-wrap #mm-helper li.mm-item:last-child a { + background:transparent url("icon_avatar.png") 50% 50% no-repeat !important; + background-size:24px !important; + width:24px !important; + height:24px !important; +} +#navbar #mm-wrap #mm-helper li.mm-item > a { + opacity:1; + -webkit-transition:all 0.3s ease-in-out; + -moz-transition:all 0.3s ease-in-out; + -ms-transition:all 0.3s ease-in-out; + -o-transition:all 0.3s ease-in-out; + transition:all 0.3s ease-in-out; +} +#mm-wrap #mm-helper > li.mm-item > a.mm-link { + border-top:0px solid #fff; + border-left:0px solid #fff; + border-right:0px solid #fff; + border-bottom:0px solid #fff; + outline:none; + text-decoration:none; + padding:0 0 0 0; + line-height:70px; + font-weight:normal; + height:70px; + vertical-align:baseline; + text-align:left; + width:auto; + display:block; + color:#090e21; + text-transform:none; + text-decoration:none; + background:rgba(0, 0, 0, 0); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px; + font-family:inherit; + font-size:14px; +} +/* end new header */ +@media (min-width: 1320px) { + .body .flowListDiv dl.flowList { + -webkit-column-count:3; + -moz-column-count:3; + column-count:3 + } +} +@media (min-width: 1120px) { + #navbar.fixed { + -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + box-shadow:0px 0px 8px rgba(0,0,0,0.23) + } + #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link { + height:50px; + line-height:50px + } + #navbar.fixed .navbar-oneQt:before { + font-size:35px; + top:7px + } + + .flowListDiv dl.flowList { + -webkit-column-count:2; + -moz-column-count:2; + column-count:2 + } +} +@media (max-width: 1120px) { + #navbar { + padding:0; + position:relative + } + #navbar .navbar-oneQt:before { + left:10px + } + #navbar .container { + max-width:100%; + padding:0 + } + #footerbar .container { + padding:0 + } + body .main { + margin-top:0px + } + #footerbar .footer-main .footer-nav { + padding:3.9% 0 3.9% 3%; + border-bottom:1px solid #413d3b; + float:none; + display:block; + width:auto + } + #footerbar .footer-main .theqtcompany { + clear:both; + float:left; + margin:30px 0 8px 3% + } + #footerbar .footer-main .footer-social { + float:left; + padding:50px 0px 0px 3% + } + #footerbar #menu-footer-submenu { + clear:both; + float:none; + display:block; + padding:0px 0px 3.9% 3% + } + ul#menu-footer-submenu { + margin-left: 0 + } +} +.cookies_yum { + background-color:#cecfd5; + display:none; + width:100% +} +.cookies_yum img { + width:25px; + top:6px; + display:inline-block; + position:absolute; + left:13px +} +.cookies_yum div { + margin:0 auto; + max-width:1280px; + min-height:30px; + padding:6px 0px 6px 0px; + position:relative +} +.cookies_yum p { + color:#09102b; + margin:0px; + font-size:0.79em; + display:inline-block; + line-height:1.2; + padding:0 30px 0 50px +} +.cookies_yum p a { + white-space:nowrap +} +.cookies_yum a:hover { + color:#46a2da +} +.cookies_yum .close { + width:15px; + height:15px; + background-image:url("cookiebar-x.png"); + background-size:15px 30px; + background-position:top left; + cursor:pointer; + top:13px; + right:13px; + position:absolute; + transition:none +} +.cookies_yum .close:hover { + background-position:bottom left +} +#sidebar-toggle,#toc-toggle { + width:24px; + height:14px; + background-size:24px 28px; + cursor:pointer; + background-image:url("list_expand.png"); + float:right +} +#sidebar-toggle.collapsed, +#toc-toggle.collapsed { + background-position:bottom left +} +#sidebar-content > h2 { + display:none +} +#footerbar { + background:#222840; + color:#fff; + font-size: 0.9em; +} +#footerbar.fixed { + bottom:0; + left:0; + width:100% +} +#footerbar .footer-nav { + display:inline; + float:left +} +#footerbar .footer-main .footer-nav li { + float:left; + margin-right:1em +} +#footerbar .footer-main .footer-nav li a { + display:block; + padding:30px 0 10px 0; + line-height:20px; + height:20px; + color:#fff; + font-weight: 600; +} +#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a { + color:#eee +} +#footerbar .footer-main .footer-nav .sub-menu { + margin-left:0; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li { + float:none; + width: 100%; +} +#footerbar .footer-main .footer-nav .sub-menu ul { + padding:1px 1em; + font-size:0.786em; + line-height:8px; + float:none; + color:#5d5b59; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li a { + padding:2px 0; + font-size:1em; + float:none; + color:#cecfd5; + font-weight: 400; +} +#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a { + color:#eee +} +#footerbar .theqtcompany { + background:url("theqtcompany.png") no-repeat; + background-size:100%; + width:215px; + height:68px; + display:inline; + float:right; + margin:29px 0 28px 30px +} +#footerbar .footer-social { + display:inline; + float:right; + width:164px +} +#footerbar .footer-main .footer-social>div { + margin-left:0.1em; + margin-bottom:10px +} +#footerbar .disclaimer { + font-size:0.786em; + line-height:2.73; + color:#868584; + padding-top:20px; + padding-bottom:0.5% +} +#footerbar .disclaimer a { + color:#bdbebf +} +#footerbar .disclaimer a:hover { + color:#d6d6d6 +} +#footerbar .disclaimer ul li { + float:left; + vertical-align:middle; + margin-left:1.18em +} +#footerbar .disclaimer ul li:first-child { + margin-left:0 +} +#footerbar .disclaimer ul.lang-selector a { + color:#506a34; + color:rgba(128,195,66,0.3) +} +#footerbar .disclaimer ul.lang-selector a:hover { + color:#80c342; + color:rgba(128,195,66,0.7) +} +#menu-footer-menu, #menu-footer-menu ul { + margin-left:0; + margin-bottom:0 +} +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot"); + /* IE9 Compat Modes */ + src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-italic - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: italic; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-600 - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 600; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +@font-face { + font-family:'Droid Sans Mono'; + font-style:normal; + font-weight:400; + src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff") +} +@font-face { + font-family:'Qt Icons'; + src:url("../style/icomoon.eot?-tgjuoj"); + src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg"); + font-weight:normal; + font-style:normal +} +@font-face { + font-family:'social-icons'; + src:url("../style/social-icons.eot?54625607"); + src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"), + url("../style/social-icons.woff?54625607") format("woff"); + font-weight:normal; + font-style:normal +} +.clearfix:before,.clearfix:after { + content:" "; + display:table +} +.clearfix:after { + clear:both +} +.clearfix { + *zoom:1 +} +.clearfix .right { + float:right +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + margin:0; + padding:0; + border:0; + font-size:100% + line-height: 1.4; +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + vertical-align:baseline +} +h1,h2,h3,h4,h5,h6 { + font-weight:300 +} +.body h2,.body h3,.body h4,.body h5,.body h6 { + margin:1.5em 0 0.75em +} +.body h1 { + margin-bottom:0.75em; + font-size:2.25em; +} +.body h3.fn,.body h3.flags { + color:#26282a; + font-size:1.46em; + padding:15px 0 15px 0; + border-bottom:2px #eee solid; + word-wrap:break-word +} +.body .fngroup { + border-bottom:2px #eee solid; + padding-bottom:15px; + margin-bottom:1.5em +} +.body .fngroup h3.fngroupitem { + margin:0; + padding-bottom:0; + border:none +} +.body h3.fn .name, +.body h3 span.type, +.qmlname span.name { + font-weight: 400 +} +.qmlname { + font-size:1.46em +} +.qmlproto table { + border:none; + border-bottom:2px #eee solid +} +.qmlproto table p { + max-width:100% +} +.qmlproto table tr { + background-color:#fff +} +.qmlname td, .qmlname th { + border:none; + text-align:left; + padding:5px 0 0 0 +} +.qmlreadonly,.qmldefault { + padding:0 5px 0 5px; + font-size:0.75em; + background-color:#eee; + float:right +} +.qmlreadonly { + color:#414141 +} +.qmldefault { + color:#D14141 +} +.rightAlign { + padding:3px 5px 3px 10px; + text-align:right +} +.centerAlign.functionIndex { + text-align:center; + font-size:150%; + margin-bottom: 1em +} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { + display:block +} +body { + line-height:1; + font-family:'Titillium Web', Arial, Helvetica, sans-serif; + font-weight:400; + transition-duration:1s; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: 16px; + background-color:#f3f3f4; + color:#404244; +} +ol,ul { + list-style-type: square; + color: #17a81a; +} +.body ol,.body ul { + margin-top:0.75em; + margin-left:20px +} +.bodywrapper ol>li { + list-style-type:decimal; + margin-left:15px +} +.bodywrapper ol.a >li { + list-style-type:lower-alpha; +} +.bodywrapper ol.A >li { + list-style-type:upper-alpha; +} +.bodywrapper ol.i >li { + list-style-type:lower-roman; +} +.bodywrapper ol.I >li { + list-style-type:upper-roman; +} +.body li p { + margin-top:1em +} +blockquote,q { + quotes:none; + border-left:10px solid #ddd; + padding-left:10px +} +blockquote:before,blockquote:after,q:before,q:after { + content:''; + content:none; + width:100% +} +table { + border-collapse:collapse; + border-spacing:0; + margin-bottom:5px; + width:100% +} +a { + color:#17a81a; + text-decoration:none; + transition-duration:0.3s +} +a:hover { + color:#17a81a +} +.main,#footerbar>div { + max-width:1280px; + width:95%; + margin:0 auto +} +.main { + margin-top:80px +} +@media (max-width: 1120px) { + .main,.navbar-header,#footerbar>div { + width: 100%; + margin: 0; + } + .main .main-rounded { + padding: 0 15px; + } +} +.main_index { + background-color:#fff +} +.sectionlist { + margin-bottom:2em +} +[class*="col-"] { + letter-spacing:normal +} +.landing,.main_index .row { + letter-spacing:-0.31em +} +.main_index .row>div { + letter-spacing:normal +} +.col-1,.body { + display:inline-block; + background-color:#fff; + padding: 25px 35px 20px 30px; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; +} +.col-1 h2 { + font-size:1.8em; + font-weight:300; + line-height:1.1; + margin-bottom:0.83em; + margin-top:1em +} +.icons1of3 img { + display:inline-block; + float:left; + margin-right:0.75em; + margin-top:-5px; + width:2.75em +} +div.multi-column { + position:relative +} +div.multi-column div { + display:-moz-inline-box; + display:inline-block; + vertical-align:top; + margin-top:1em; + margin-right:2em; + width:16em +} +.sidebar { + display:block; + position:relative; + position:sticky; + float:left; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + width:20%; + padding-right:20px +} +.sidebar li { + text-overflow:ellipsis; + overflow:hidden +} +.toc,.sectionlist { + padding:25px; + background-color:#fff; + margin-bottom:1.25em +} +.sidebar .sectionlist p { + margin-bottom:0 +} +.sectionlist.promo { + padding:0; + background-color:#f3f3f4 +} +.sidebar-content:empty { + display:none; + visibility:hidden +} +.col-2 h2,.toc h3,.sidebar-content h2, +.sidebar-content h3,.sectionlist h2, +.sphinxsidebar { + position: -webkit-sticky; + position: sticky; + top: 64px; + overflow: scroll; + overflow-x: hidden; + overflow-y: hidden; +} +.sphinxsidebar h3 { + font-weight: bold; + margin-bottom:1em; +} +.toc h3 a { + color:#404244 +} +.title { + font-size:2.25em; + font-weight:300; + letter-spacing:-1px; + line-height:1.15em; + margin-bottom:0.5em; + word-wrap:break-word +} +.navigationbar,col-1 h2 { + font-size:0.85em +} +.navigationbar h1 { + font-size:2.5em; + margin-bottom:0.85em; + margin-top:0.85em +} +.navigationbar li { + display:inline-block; + margin-right:5px; + position:relative; + padding-right:10px; + color:#585a5c +} +.navigationbar ul:last-of-type li a { + color:#404244 +} +.sectionlist li, .sphinxsidebar li { + padding-bottom: 10px; + line-height: 1.75em; +} +.col-1 ul { + margin-bottom:1.56em +} +.bodywrapper li { + margin-top:0.5em; + line-height:1.25em +} +.bodywrapper li.level2 { + margin-left:10px; + margin-top:0.4em; + font-size:0.9375em; +} +.bodywrapper p, +.bodywrapper dd { + line-height:1.25em; + margin:1em 0 1em; + color:#404244 +} +.bodywrapper b { + font-weight:600 +} +.body ul,.body ol { + /* margin-bottom:1.5em */ +} +.bodywrapper ul ul { + margin-top:0.5em +} +.bodywrapper .naviNextPrevious { + margin-top:25px; + max-width:100% +} +.naviNextPrevious.headerNavi, +p.naviNextPrevious + p { + display:none +} +.nextPage { + float:right +} +.prevPage:before { + content:"< " +} +.nextPage:after { + content:" >" +} +.navigationbar li a { + color:#404244 +} +.navigationbar li:after { + color:#404244; + content:"›"; + display:inline-block; + font-size:1.5em; + line-height:1; + position:absolute; + right:-2px; + top:-4px +} +.sub-navigation { + margin-top:10px +} +.navigationbar li:last-child:after,.sub-navigation li:after { + content:none +} +.navigationbar { + margin-bottom:10px; + line-height:1em +} +#buildversion { + margin-bottom:10px; + font-style:italic; + font-size:small; + float:right +} +.copy-notice { + width:75%; + font-size:0.75em; + margin:20px 35px 0 10px; + line-height:1.75em; + float:right; + color:#585a5c +} +.copy-notice.index { + margin-top:10px; + float:none +} +li a.active { + color:#585a5c +} +.flowList { + padding:25px +} +.flowListDiv dl { + -webkit-column-count:1; + -moz-column-count:1; + column-count:1 +} +.flowList dd { + display:inline-block; + margin-left:10px; + width:90%; + line-height:1.15em; + overflow-x:hidden; + text-overflow:ellipsis +} +.alphaChar { + font-size:2em; + position:absolute +} +.flowList.odd { + background-color:#f9f9f9 +} +.body ul>li,.doc-column ul>li { + list-style-image:url("list_arrow.png"); + margin-left:15px; + color:#404244; + margin-top:0.65em; + line-height:1em +} +.bodywrapper table p { + margin:0px; + padding:0px +} +.bodywrapper table p { + margin:0px; + padding:0px; + min-height:1.25em +} +.bodywrapper .qmldoc { + margin-top:0.75em +} +.body h2 { + margin-top: 1.5em; + font-size:1.75em +} +.body h3 { + font-size:1.35em +} +.body h4 { + font-size:1.15em +} +.body p img { + margin-top:0.75em; + max-width:100% +} +.body .border img { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body .border .player { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body p.figCaption { + transform:translateY(-30px); + color:#606366; + font-size:95%; + margin-left:3px; + font-style:italic +} +.body table { + width:initial; + vertical-align:initial +} +table .odd { + background-color:#f9f9f9 +} +table thead { + text-align:left; + padding-left:20px +} +table,table td,table th { + border:1px solid #eee +} +table td,table th { + padding:5px 20px; + line-height:1.3 +} +.body .fixed table td { + min-width:50%; + width:50% +} +table.alignedsummary,table.propsummary { + width:initial +} +table.valuelist td.tblval { + font-size:0.75em +} +div.main_index .row { + border-bottom:10px solid #f3f3f4 +} +div.main_index .row { + position:relative +} +div.main_index .row>div { + display:inline-block; + width:50%; + vertical-align:top; + padding:2em 3em; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box +} +div.main_index h2 { + font-size:2.1875em; + margin-bottom:1em +} +#search_bar { + width:40%; + float:right +} +div.main_index .row:after { + content:""; + position:absolute; + top:0; + right:50%; + height:100%; + width:10px; + background-color:#f3f3f4 +} +div.table { + overflow-x:auto +} +.body tr > td > pre { + font-size:0.75em +} +p.qt_commercial { + border:3px solid #5caa15; + margin:0 auto; + padding:15px; + width:28%; + text-align:center; + clear:both +} +h1.qt_commercial { + padding:20px; + background-color:#5caa15; + display:inline; + float:right; + font-size:1.25em; + line-height:1.25em; + height:1.25em; + color:#fff +} +div.qt_commercial { + border-top:5px solid #5caa15; + margin-bottom:50px +} +div.pre { + position:relative; + height:auto +} +pre, .LegaleseLeft { + background-color:#222840; + color:#fff; + display:block; + font-family:"Droid Sans Mono"; + line-height:1.5; + overflow-x:auto; + margin-bottom:25px; + padding:25px; + margin-top:0.75em; + font-size: .8em; +} +.bodywrapper .LegaleseLeft p { + color:#fff; + white-space: pre-wrap +} +pre .str,code .str { + color:#aaaaaa +} +pre .kwd,code .kwd { + color:#ffff55 +} +pre .com,code .com { + color:#55ffff +} +pre .typ,code .typ { + color:#4f9d08 +} +pre a .typ,code a .typ { + color:#21be2b +} +pre .lit,code .lit { + color:#ff55ff +} +pre .pun,code .pun { + color:#fff +} +pre .pln,code .pln { + color:#fff +} +@media print { + pre { + background-color:#eee !important + } + pre .str,code .str { + color:#060 + } + pre .kwd,code .kwd{ + color:#006; + font-weight:bold + } + pre .com,code .com { + color:#600 + } + pre .typ,code .typ { + color:#404; + font-weight:bold + } + pre .lit,code .lit { + color:#044 + } + pre .pun,code .pun { + color:#440 + } + pre .pln,code .pln { + color:#000 + } +} +pre.wrap { + white-space:pre-wrap +} +pre span.wrap { + display:none; + background:url("wrap.png") no-repeat; + right:0; + top:2px; + position:absolute; + width:20px; + height:14px; + margin:4px; + opacity:0.65 +} + +span.pre { + color: #09102d; +} + +span.wrap:hover { + opacity:1 +} +span.wrap:active { + opacity:0.75 +} +.copy_text { + background-color:#46a2da; + color:#fff; + border:2px solid #46a2da; + padding:10px 16px; + margin-left:-10px; + margin-top:-50px; + position:absolute; + opacity:0; + cursor:pointer; + float:right +} +.copy_text:hover { + background-color:#fff; + color:#46a2da +} +code,.codelike { + font-family:"Droid Sans Mono" +} +#detailed-description .function dt > code, +#detailed-description .function dt > em { + font-weight:bold +} +h3.fn code { + font-size:0.75em; + float:right; + background-color:#eee; + padding:3px; + margin: 3px 0 0 20px +} +pre:hover>.copy_text { + display:inline-block; + opacity:1; + transition:0.5s ease +} +#main_title_bar { + background:url("pyside-logo.png") no-repeat; + background-size:100%; + width:366px; + height:86px; + margin:15px 0 15px 0 +} +#main_title_bar h1 { + visibility:hidden +} +#main_title_bar .search_bar { + letter-spacing:normal; + width:50%; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar h1 { + letter-spacing:normal; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar .search_bar * { + letter-spacing:normal; + padding:0; + margin:0; + border:none +} +#sidebar-toggle,#toc-toggle { + display:none +} +@media (max-width: 980px) { + body { + font-size:calc-em(14px) + } + #main_title_bar>h1,#main_title_bar .search_bar { + width:100% + } + #main_title_bar .search_bar { + margin-bottom:15px + } + .main { + margin-top:0px + } + .main_index .row { + border:none !important + } + .title { + font-size:1.5em; + font-weight:400; + word-wrap:break-word + } + .col-1,.body,.naviNextPrevious,.sidebar { + padding:10px + } + .sidebar { + position:relative; + padding-top:0 + } + .search .sidebar { + display:none; + visibility:hidden + } + .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 { + text-align:center; + margin-bottom:5px + } + div.main_index .row:after { + content:none + } + div.main_index .row>div { + display:block !important; + width:100%; + padding:15px; + margin:0 + } + .body,.sidebar,.col-1 { + width:100% + } + .sidebar-content,.col-2,.toc { + background-color:#fff; + margin-bottom:1em; + padding:20px + } + #sidebar-toggle,#toc-toggle { + display:block + } + #sidebar-toggle.collapsed + h2 { + display:block + } + .bodywrapper p { + margin-bottom:1em; + max-width:100% + } + table td,table th { + padding:5px 5px + } + .sectionlist { + padding:0 + } + .sidebar > .sectionlist { + padding:20px + } + .sectionlist.promo { + max-width:46%; + margin:0 auto 1em auto; + float:left; + padding:0 2% + } + .sidebar .sidebar-content { + clear:both + } + .copy-notice { + float:none; + width:initial + } +} +[id]:target > *:first-child, +dt[id]:target { + -webkit-animation:highlighter 3s; + animation:highlighter 3s +} +@-webkit-keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@-webkit-keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +@keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +#footer { + clear:both +} +.footer-social i { + font-family: "social-icons"; + font-style: normal; + font-size:150%; + margin: .55em; + color: #cecfd5 +} +.footer-social i:hover { + color: #eee +} +.footer-social .icon-twitter:before { + content: '\f099' +} +.footer-social .icon-facebook:before { + content: '\f09a' +} +.footer-social .icon-youtube:before { + content: '\f16a' +} +.menuextraslanguages { + display:none; + visibility:hidden +} +form.gsc-search-box { + font-size: 25px !important; + margin-top: 0 !important; + margin-right: 0 !important; + margin-bottom: 4px !important; + margin-left: 0 !important; + width: 102.5% !important; +} +table.gsc-search-box { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; + margin-bottom: 2px !important; +} + +table.gsc-search-box td { + vertical-align: middle !important; +} + +table.gsc-search-box td.gsc-input { + padding-right: 0px !important; +} +table.gsc-search-box td.gsc-input input { + background-position: 10px center !important; +} + +td.gsc-search-button { + width: 1% !important; +} + +td.gsc-clear-button { + width: 14px !important; + visibility:hidden !important; + display:none !important; +} +table.gsc-branding td, +table.gsc-branding { + margin: 0 0 0 0 !important; + padding: 0 0 0 0 !important; + border: none !important; +} + +table.gsc-branding { + border-style: none !important; + border-width: 0 !important; + border-spacing: 0 0 !important; + width: 100% !important; +} + +.gsc-branding-text { + color: #676767 !important; +} + +td.gsc-branding-text { + vertical-align: top !important; +} +td.gsc-branding-text div.gsc-branding-text { + padding-bottom: 2px !important; + text-align: right !important; + font-size: 11px !important; + margin-right: 2px !important; +} + +td.gsc-branding-img { + width: 65px !important; + vertical-align: bottom !important; +} + +img.gsc-branding-img { + padding-top: 1px !important; + margin: 0 0 0 0 !important; + padding-right: 0 !important; + padding-left: 0 !important; + padding-bottom: 0 !important; + border: none !important; + display: inline !important; +} + +input.gsc-search-button { + background-color: white !important; + height: 35px !important; + width: 25px !important; + color: transparent !important; + background-image: url("doc_search.png") !important; + background-size: 25px auto; + background-position: 0px 5px; + background-repeat: no-repeat; + margin-left: -43px !important; + overflow: hidden; + min-width: 20px !important; +} + +input.gsc-search-button:hover { + cursor: pointer; +} + +input.gsc-search-button:focus { + outline: none; + box-shadow: none; +} + +.gsc-search-box-tools .gsc-clear-button { + display: none !important; + visibility: none !important; +} + +.gsc-overflow-hidden { + overflow: hidden !important; +} + +input.gsc-input { + background-color: #fff !important; + border: 1px solid #d6d6d6 !important; + box-sizing: border-box !important; + -moz-box-sizing: border-box !important; + color: #868482 !important; + outline: 0 none !important; + padding: 9px 10px 10px !important; + transition: color 0.5s ease 0s, box-shadow 0.5s ease 0s, background-color 0.5s ease 0s !important; +} + +input { + font-family: 'Titillium Web', Arial, Helvetica, sans-serif !important; + line-height: 1.5 !important; + font-weight: 300 !important; + vertical-align:middle +} + +input:focus { + border-color: #46a2da; + box-shadow: 0 0 5px #46a2da; + color: #000; +} + +.animation { + width: 100%; + border-style: none; + border-width: 0 +} + +.player { + width: auto; + position: relative; + display: table; + margin-bottom:1.5em; +} + +.playcontrol { + display: none; + background: url("play_icon.svg") no-repeat center, + linear-gradient( + rgba(0,0,0,0.15), rgba(0,0,0,0.15) + ); + background-size: 25%; + width: 100%; + height: 100%; + position: absolute; + left: 0%; + right: 0%; + top: 0%; + bottom: 0%; + margin: auto +} + +/* expand/collapse code sections */ +pre input { + display:none; + visibility:hidden +} +pre label { + display:block; + margin:-3px 3px 0 -16px; + text-align:center; + color:#21be2b; + float:left; +} +pre label:hover { + color:#fff +} +pre label::before { + font-weight:600; + font-size:16px; + content:"+"; + display:inline-block; + width:16px; + height:16px +} +#ec_expand { + height:16px; + overflow:hidden; + transition:height 0.35s; +} +#ec_expand::before { + content:"...*/"; + color:#aaa; + background-color:#3a4055; + z-index:99 !important; + right:25px; + position:absolute +} +#ec_toggle:checked ~ #ec_expand { + height:initial +} +#ec_toggle:checked ~ #ec_expand::before { + content:"" +} +#ec_toggle:checked ~ label::before { + content:"-" +} + +/* permalinks */ +h1:hover > .headerlink, +h2:hover > .plink, +h2:hover > .headerlink, +h3:hover > .plink, +h3:hover > .headerlink, +h4:hover > .plink, +h4:hover > .headerlink, +h5:hover > .plink, +h5:hover > .headerlink { + opacity:1 +} +a.plink, a.headerlink { + opacity: 0; + padding-left: 8px; + font-size: 0.8em; + font-weight: 600; + transition: opacity 180ms ease-in-out +} +a.plink::before { + content:'\00B6' +} + +table.special { + border: 3px; + padding: 0px; + border-collapse: separate; + border-spacing: 20px; + line-height: 1.5em; +} + +.special p { + text-align: center; + color: #3a4055; +} + +.special a { + display: block; + border-bottom: 0; + text-decoration: none; +} + +.special a:hover { + border-bottom: 0; + text-decoration: none; +} + +.special strong { + color: #17a81a; + font-size: 110%; + font-weight: normal; +} + +table.special th, +table.special td { + border: 1px solid #888; + padding-top: 14px; + padding-bottom: 14px; + padding-left: 6px; + padding-right: 5px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; +} + +.special td:hover { + padding-top: 2px; + padding-bottom: 2px; + border-bottom: 4px solid #41cd52; +} diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png b/sources/pyside2/doc/_themes/pysidedocs/static/pysidelogo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2f2bd17d274bb2749d201fe4fdcf63d16b4b62 GIT binary patch literal 4936 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs/static/relbar_bg.png b/sources/pyside2/doc/_themes/pysidedocs/static/relbar_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..4036733a7bad6f210ffe961dbc394fce33800be6 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVC!3HF~cLcBlDNj!q#}JRsx6=-CG8k|$i|$$w zTw?G%WViDYU8g_t)58~aoe=wQ + DOCUMENTATION_OPTIONS.COLLAPSE_INDEX = true; + +{% endif %} +{% endblock %} +{% block body %} +
+ {%- set curr_group = 0 %} + +

{{ indextitle }}

+ +
+ {%- for (letter, entries) in content %} + {{ letter }} + {%- if not loop.last %} | {% endif %} + {%- endfor %} +
+ + + {%- for letter, entries in content %} + + + {%- for (name, grouptype, page, anchor, extra, qualifier, description) + in entries %} + {%- if grouptype == 1 %}{% set curr_group = curr_group + 1 %}{% endif %} + + + + {%- endfor %} + {%- endfor %} +
 
+ {{ letter }}
{% if grouptype == 1 -%} + + {%- endif %}{% if grouptype == 2 %}   {% endif %} + {% if page %}{% endif -%} + {{ name|e }} + {%- if page %}{% endif %} + {%- if extra %} ({{ extra|e }}){% endif -%} + {% if qualifier %}{{ qualifier|e }}:{% endif %} + {{ description|e }}
+
+{% endblock %} diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/fakebar.png new file mode 100644 index 0000000000000000000000000000000000000000..b45830e000eb123c3efab6bfc3b17809a3a08530 GIT binary patch literal 101 zcmeAS@N?(olHy`uVBq!ia0y~yVB`m~89A7Mq`$$QwLprqz$3Dlfr0M`2s2LA=92~r xihH^^hG*5B1h}~tn49EFcPMuw|ksYXn!PC{xWt~$(69Du$7_a~U literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_python.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cd474efbaa633dde7998c09170e4500acc4a13ce GIT binary patch literal 2660 zcmb`IXHe5w7sme~g$OYaK&6YcMRr390r3+A|xavB_t5ih(D1=Af=?GkO)~>IXPKbWhEsg<%53%5*HWWi`XkK zEiJFO54BJ6Z{vSmh+Y9GIDiN0z#tSLh5~_6AW=I|u-mp67z6_CHu@J(m>5JH41(`! zUyXk_5GV{R1`?MBKwz*KL`+-^F7@Y`uPIOvs0{3op{)3MbzG!5y=N&o#g`K~VJ*6)Dq`KvT zk7yJ?fOo@DU=&~t2rnf4Uq}Xr&&_ps5U%Od5m+;`D@y2KU7y?K!B6dR!KI2x1LxVN zThjDpjo~?pE3=`Ze=@Jb4EMm#&Z{c%ktEbwOmjVc58a)c_v7 z^2MlLFz3o;viH}U20@|{zs+hPXm(CKkc{ah^>dxHUMB&Rz}^K5mOOeIT0MSp1h4W| z{KZjc8cj#1DX*cvzU5;{ea_mO#ks(Hwg>7&fPbG|8Lt1F^jAndImrqQ;f70!cj8Lz zf=*zz_gKE{4KUT8y|%vM)PKT{;Mp&@dekLDmofk)#)iE0fA8y%i}m0+U~I3oD$T(1 zA5XhUtWFjOtuwp1a2Ayt8a|EoZeXRPj%U;cpO7`SDT~c2j2PaDsE9ni%yz~{G1-;5 zbKH%~b6gIZdU5Mh-xOBlT*j1n4fS#I59QCk)ILI-#t+ z7_$S3!rDC|;1GE^zmZ69<;l#~X7#=_5TaCLh37`_yoV-QH9zgd+-o*z6DUQtdsYvP zkGK;RuhS0aJac)*>WJ>BEqsxY+skV1?DT$Ki$suO^i_$p<5h5tN`C=MpBmL!?erh0 z2mpADBDK&#)zhSCUh+jh!D3KP8unV&lW@rfm#B8miLFo8X$f$QMJy{M+R8|Y2I&OSoy*3L*Pf`l%ShmbEk&INIUFHoB73zAug?mpSwf~kJ&nRB0763oO#yn zm+u$RspIu*Zm4!MIxRM0^BrWpD{A)WqtG0`!XRk5H6$qg)^RTQ_xw#4M>Dl2QME_t zlzp+@Kd`^}wF#&if|5k1Q8j!&nA+1jwRCg8e@I4G>bPkPb%+omXC|gVj`yF-4b(JE zamB1jOX-H=j2p2Oga0s@%p~5-GI!`XgH-HDD(mPUr8hxrX3sX@yKQ|16``D{0c0^d zr~XHWVI;aR3yfRDS!D6>ceuX@*$USgX;`b6c~|*aDP#BwPRg4)VR5Uc9)W4fv{upo zUWJo+&(%}WKG6MOPUCTeDQ~@p+AFN8%VH8Z-x8z&Igm4g28Q1$xx$4_4t3g(0N>K__+vw>T|k23p)P0^n-=+A3i zY+H*fVf1`O%9E&$-#lDCTJxG9FfS1h-1_Cd@Lel1GbxF3e|-sn4kaf5_V0Db`*qBCX|R@#Ejf zKhjI7!&GMUh8DVM`Po^=Eh`~%sp=$S>kTjL#29|AYS43dCr-Hb!f8Mm^Q^bP(Gsd# z!WTBvI9VeqCj9AxQ@uM2Hi@c6FOqZ)B%TC>cjzYy&9Y9fcnicbJ&^Rq&P_G zrRg(kUMFj2KM0JkMi#k~O156rJV>u2RJ6>LV}7*`Pup9`TbehWH7D{;YrpZbw2#$@ zxp8Lxs#SiVCS4}EIi)Q`|9*BOMIlq+vDP>hpWo#!mrXm~&}1?ha~|Rnf!^>FXut8G znJWjSvIstupS7uj`>k%~Zh<2xZTUz_6LV=qSRI;vngJxvcdWnjN*h1HEdczWqS~ zku}LHT9*4G6hHzJ1wX#8>mK(U>Ui&EJJ@g|OQyrQ;b!L?QeQJnN8QLG+7KI29osqi zE}dBuaq(;!#lBlxZqTXl^{H*?D__4LTmK4e+J5sxWdrw}Gkp(2?G_(d%oaInxK{Z% zb2Ob})}LK8b+)k2n`OO9mT3Rj5!ZWPR(7(synXcyf$!M1G~Vrk>%Sf`#JbfG6Z30@ zY8!cnD92GAdKy_%THEI}C1vWA$7FIm&sFP({eSF&u3fno=skRc?{_0a8;-N|DqjT|?_BFWCv45f9)3Jho Lk^f!7iAMelGjO_W literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/logo_qt.png new file mode 100644 index 0000000000000000000000000000000000000000..3bc03b7c7e5581f9b56bd5505684d99c31df99d6 GIT binary patch literal 1936 zcmaJ?X;c$e6dnkuMX{n*tyUXjTNfmg1cD?I5fUOPhFuAYl#omyKr$g2B%o-(rJ}8Z zNO7YsRja7TLBS0bp=uQ+EMZ?2f&qeIQMRyjqN4p#I_J*3_wKphch`3&!NYBxx!HU( z007KcE(|YpU2Ax!V9;;c%{VQ(e2qAB5N}w3L~*4M;K+xAAS_G74TiiREr zF9!3YFZ4vig&>H83W8BlQTQlpJS+`Hu@nkOAb}*36>4E6ixwkXxs_P9WSoHk$#_zs z1QEhwtbvgm1VgDfoY&Ml8mLXg*4`MNBIFt!56!NKd)^;Qci9sL}=uSkUv#lM4VdrFLL$D(| zGAJab%{Z0;^CCr%7#YX%KVyj#Vhtl9lAxX$kW{!8;xnbN2>U*Ds&K+s=*|=JeZ=x7 zjD^me5DTKgfQAPDtKs7+bczhyPveUoK3xDvj84529dDzqd?o-GrF*RRaYnDm*w~ok z3$G92^un87o>ntt7ysB+#dnx1p5p zTPEO?1^bnSY(hmP+^h=qSA}j-g$0y{2bPPuJP*<{IaXz;O@pldmEDy znv(Z79XZgHa`5G`#8=0YUY$s8PCH_d-&2}TrM8?-Z8>wS- zUOLm7ezrCJf+pjlCi9XeGrcYAa$DAww(A+~*;yU8Z*<(b(Q!9ho13G(cT;=smiED& z&b)hX3i94O%F{j0*F7oF{av7Y`d8P}$6bX_yI(x(Ru*;_KS!mfwYF zRoYuo)?2B1TUGwHs_I=`^}D*7clEV>4Rw8u4Sg?P^{bl))GY(ATL(0n!S=Snj*g*D z?NFyq-=))ccj>!(^u0a9y?rD7{UZYdBZGq@L;6v@esp+vba-TRWOQs4?NPSl+U01s zOb{2{j+A+s7dgBJYIpE zE6(A^Jx@0?SprPXU1OR!TbR?i0HEcFY8TFbXq-8td&nejgT?09t321K6-M?RbIGZb zn!F_sJr%rA()1Qa4z*~ZV#kw+lXTaqZnt#LFY5tI%(Z+!z?Hq%C@9V} z7K%TEo8uxGZFHaEFEI-&i8^e|S;z^*eB+tC6o`y7WhrE#B=ha&_vdahnpEDr7_)xT z+?8XdxxVqX3a)$RBY4$8Ot__AWit*}Iz6+%y?CnRW)<@RaQg=fiv-Mf!zOG$#iA(s zsx_waqi_Yrzn3-(HX^iX;re5@?7!@)P4jG7o!61H4$RP)gb7^T)z*8?Y}?cFYhOUf z;H`lG&ASS_4nf(_iRIKpPm{)=hJEBDWob;DOTojqC$qf0uL*JwGZlq8fsmV;UCFzc4K5X1;+ma2r*h^ literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/minus.png new file mode 100644 index 0000000000000000000000000000000000000000..da1c5620d10c047525a467a425abe9ff5269cfc2 GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^+#t-s1SHkYJtzcHoCO|{#XvD(5N2eUHAey{$X?>< z>&kweokM_|(Po{+Q=kw>iEBiObAE1aYF-J$w=>iB1I2R$WLpMkF=>bh=@O1TaS?83{1OVknK< z>&kweokM`jkU7Va11Q8%;u=xnoS&PUnpeW`?aZ|OK(QcC7sn8Z%gHvy&v=;Q4jejg zV8NnAO`-4Z@2~&zopr02WF_WB>pF literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css new file mode 100644 index 0000000..aee5e44 --- /dev/null +++ b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pyside.css @@ -0,0 +1,1943 @@ +@import url('cookie-confirm.css') screen; + +/* -- admonitions -- */ + +div.admonition { + margin: 1.5em 0 1.5em; + padding: 0; +} + +div.admonition dt { + font-weight: bold; +} + +div.admonition dl { + margin-bottom: 0; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.admonition code { + font-family: inherit; +} + +p.admonition-title + p { + padding-left: 1em; +} + +div.admonition a:after { + content: ', '; +} + +div.admonition a:last-child:after { + content: ''; +} + +.body { + width: 100% +} +.bodywrapper .admonition p.admonition-title { + margin-bottom:5px +} + +.bodywrapper .admonition p { + margin:0 +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +div.warning, div.seealso, div.note { + padding: 6px 0px 6px 10px; + border: none; +} + +div.warning { + background-color: #ffe4e4; +} + +div.seealso { + background-color: #fff2d6; +} + +div.note { + background-color: #f3f3f4; +} + +table.docutils { + margin-right: auto; + margin-bottom: 10px; + border: none; + width: initial; +} + +table.docutils.colwidths-given td { + float: none; +} + +table.docutils th, +table.docutils td { + padding-left:0; + border: none; +} + +table.docutils td ul { + margin:0 +} + +table.docutils td ul > li { + margin: 0 0 0.5em; +} +h2 em { + float: right; + font-size: 10px; + position: relative; + top: -20px; +} + +.document { + padding-bottom: 20px; +} + +.documentwrapper { + margin-left: 20px; +} + +.body blockquote { + border: none; + padding-left: 0; + margin-bottom: 1.5em; +} + +.sphinxsidebar { + float: left; + width: 186px; + padding: 25px; + text-align: left; + background-color: #fff; +} + +.sphinxsidebar ul { + padding: 0px; + margin: 0px; + list-style-position: inside; +} + +.sphinxsidebar > ul { + padding: 0px; + margin: 0px; +} + +.sphinxsidebar ul li li { + margin-left: 10px; + padding: 0px; + font-size: 0.95em; +} + +.sphinxsidebar ul a, +.sphinxsidebar p.topless a { + word-break: break-word; +} + +.sphinxsidebar h3, .sphinxsidebar h3 a { + color: #333; +} + +.sphinxsidebar p.topless { + margin: 1em 0 1em; +} + +.pysidetoc ul { + list-style: none; + padding: 0px; + margin: 0px; +} + +.pysidetoc em { + font-style: normal; +} + +.pysidetoc strong { + display: block; + padding: 5px; + margin: 0 10px 10px 0; + border: none; + background-color: #e2e2e2; +} + +.section .docutils.container td { + float:left; +} + +.hide { + display: none; +} + +/* copy-notice */ +.document + p { + margin-left: 255px; + width: 70%; + font-size: 0.75em; + margin: 0 35px 15px 280px; +} + +#searchbox { + border-top: 1px solid #989898; + padding-top: 10px; + margin-left: -10px; + margin-right: -10px; + padding-left: 10px; + padding-right: 10px; +} + +#search_button { + border: 1px solid #3A393A; + background-color: #3A393A; + color: white; + cursor: pointer; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + +} + +form { + margin: 0px; + padding: 0px; +} + +#searchbox h3 { + padding: 10px 0 0 0; + margin-bottom: 5px; +} + +/* search field */ +form #q { + width: 136px; + /* height: 22px; */ + /* border: none; */ + margin: 0px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; + margin-top: 2px; + padding: 4px; + line-height: 22px; +} + +#search-results h2 { + display: none; +} + +#search-results h2 { + display: none; +} + +#search-results ul.search { + margin: 0px; + padding: 0px; +} + +ul.search div.context { + padding-left: 40px; +} + +#installation td { + text-align: center; + font-weight: bold; +} + +em { + color: inherit; + font-style:italic; +} + +/******** REL bar *********/ + +.related { + display: inline; +} + +.related h3 { + display: none; +} + +.align-center { + text-align: center; +} + +.contentstable { + width: 100%; +} + +.contentstable td { + padding-left: 30px; + vertical-align: top; +} + +p.biglink a { + font-size: 20px; +} + +dt:target, .highlight { + background-color: #fbe54e; +} + +p.highlight-link { + margin-top: 10px; + font-size: 0.8em; +} + +#synopsis table, table.field-list { + margin: 1em 0 1em 0; +} + +table.field-list tr { + text-align: left; +} + +tt.descname { + font-size: 120%; + font-weight: bold; +} + +#functions ul, #virtual-functions ul, #slots ul, #signals ul, #static-functions ul { + margin: 0; + padding: 6px; + border: 1px solid #ddd; + border-radius: 0; + background-color: #e2e2e2; +} + +#functions p, #virtual-functions p, #slots p, #signals p, #static-functions p { + margin: 0; + padding: 0; +} + +#functions li, #virtual-functions li, #slots li, #signals li, #static-functions li { + list-style: none; + margin: 5px; + padding: 0; + font-size: 90%; +} + +#synopsis span.pre { + color: #009491; + font-weight: bolder; +} + +#detailed-description .class dt, +#detailed-description .method dt, +#detailed-description .staticmethod dt, +#detailed-description .attribute dt { + margin: 0px; + margin-bottom: 10px; + padding: 10px; + font-weight: bold; + background-color: #e2e2e2; + border: none; + border-radius: 0; +} + +#detailed-description dd > blockquote, +#detailed-description dd > .field-list { + font-family: monospace; + font-size: small; + border-left: 10px solid #e2e2e2; + padding-left: 10px; + margin-bottom: 1.5em; +} + +#detailed-description dd > blockquote blockquote { + border: none; + padding: 0; +} + +#detailed-description .class .field-odd, +#detailed-description .method .field-odd, +#detailed-description .staticmethod .field-odd, +#detailed-description .attribute .field-odd { + margin: 0; + padding: 1px 0 0 0; + background-color: #ffffff; + +} + +#detailed-description .class .field-even, +#detailed-description .method .field-even, +#detailed-description .staticmethod .field-even, +#detailed-description .attribute .field-even { + margin: 0; + padding: 1px 0 0 0; + background-color: #ffffff; +} + +#detailed-description .class .field-odd li, +#detailed-description .method .field-odd li, +#detailed-description .staticmethod .field-odd li, +#detailed-description .attribute .field-odd li { + list-style: none; + margin: 0; + padding: 0; + +} + +#detailed-description .class .field-even li, +#detailed-description .method .field-even li, +#detailed-description .staticmethod .field-even li, +#detailed-description .attribute .field-even li { + list-style: none; + margin: 0; + padding: 0; +} + +#detailed-description .class .field-odd p, +#detailed-description .method .field-odd p, +#detailed-description .staticmethod .field-odd p, +#detailed-description .attribute .field-odd p{ + margin: 0; + margin-left: 20px; + +} + +#detailed-description .class .field-even p, +#detailed-description .method .field-even p, +#detailed-description .staticmethod .field-even p, +#detailed-description .attribute .field-even p{ + margin: 0; + margin-left: 20px; +} + +#detailed-description .class .field-odd p:last-child, +#detailed-description .method .field-odd p:last-child, +#detailed-description .staticmethod .field-odd p:last-child, +#detailed-description .attribute .field-odd p:last-child { + margin-bottom: 10px; + +} + +#detailed-description .class .field-even p:last-child, +#detailed-description .method .field-even p:last-child, +#detailed-description .staticmethod .field-even p:last-child, +#detailed-description .attribute .field-even p:last-child{ + margin-bottom: 10px; +} + +.document dl.attribute, +.document dl.class, +.document dl.method, +.document dl.staticmethod { + margin-top: 2em; +} + +.document dl.attribute dd, +.document dl.class dd, +.document dl.method dd, +.document dl.staticmethod dd { + padding-left: 1em; +} + +#detailed-description .attribute td:nth-child(1) { + font-family: monospace; +} + +/* Qt theme */ +#navbar { + position:fixed; + top:0; + left:0; + z-index:100; + background:#fff; + width:100% +} +#navbar .container, .fixed .container { + max-width:1280px; + margin:0 auto; + padding:0 3.9%; /* 0? */ + position:relative; + overflow:visible +} +#navbar .navbar-header { + position:relative +} +#menuextras li a:hover span { + color: #41cd52; +} +/* new header */ +#mm-wrap, #mm-wrap #mm-helper, +#mm-wrap #mm-helper li.mm-item, +#mm-wrap #mm-helper a.mm-link { + -moz-transition: none; + -o-transition: none; + -webkit-transition: none; + transition: none; + -webkit-border-radius: 0 0 0 0; + -moz-border-radius: 0 0 0 0; + -ms-border-radius: 0 0 0 0; + -o-border-radius: 0 0 0 0; + border-radius: 0 0 0 0; + -webkit-box-shadow: none; + -moz-box-shadow: none; + -ms-box-shadow: none; + -o-box-shadow: none; + box-shadow: none; + background: none; + border: 0; + bottom: auto; + box-sizing: border-box; + clip: auto; + color: #090e21; + display: block; + float: none; + font-family: inherit; + font-size: 14px; + height: auto; + left: auto; + line-height: 1.7; + list-style-type: none; + margin: 0; + min-height: 0; + opacity: 1; + outline: none; + overflow: visible; + padding: 0; + position: relative; + right: auto; + text-align: left; + text-decoration: none; + text-transform: none; + top: auto; + vertical-align: baseline; + visibility: inherit; + width: auto; +} +#mm-wrap #mm-helper { + visibility:visible; + text-align:right; + padding:0 0px 0 0px +} +#navbar #mm-wrap #mm-helper li.mm-item { + border-right:solid #f3f3f4 1px; + padding-right:30px; + padding-left:30px +} +#navbar #mm-wrap #mm-helper li.mm-item > a:hover { + opacity: .5 +} +#mm-wrap #mm-helper > li.mm-item { + margin:0 0 0 0; + display:inline-block; + height:auto; + vertical-align:middle +} +#navbar #mm-wrap #mm-helper li.mm-item:nth-child(3) { + border-right:0 +} +#mm-wrap #mm-helper a.mm-link { + cursor: pointer +} +@media (max-width: 1279px) { + #navbar { + padding:0; + position:relative; + } + #navbar .container { + max-width:100% + } + .container { + padding:0 2% + } +} +#navbar .navbar-oneQt { + display:inline; + float:left; + width:31px; + color:#41cd52 +} +#navbar .navbar-oneQt:before { + content:attr(data-icon); + position:absolute; + top:14px; + left:0; + color:#41cd52; + font-family:'Qt Icons'; + line-height:1; + font-size:40px; + transition:all 0.3s ease-in-out; +} +#mm-wrap { + clear:both; + background:rgba(255, 255, 255, 0.1); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px +} +#mm-wrap #mm-helper li.mm-item:last-child a { + background:transparent url("icon_avatar.png") 50% 50% no-repeat !important; + background-size:24px !important; + width:24px !important; + height:24px !important; +} +#navbar #mm-wrap #mm-helper li.mm-item > a { + opacity:1; + -webkit-transition:all 0.3s ease-in-out; + -moz-transition:all 0.3s ease-in-out; + -ms-transition:all 0.3s ease-in-out; + -o-transition:all 0.3s ease-in-out; + transition:all 0.3s ease-in-out; +} +#mm-wrap #mm-helper > li.mm-item > a.mm-link { + border-top:0px solid #fff; + border-left:0px solid #fff; + border-right:0px solid #fff; + border-bottom:0px solid #fff; + outline:none; + text-decoration:none; + padding:0 0 0 0; + line-height:70px; + font-weight:normal; + height:70px; + vertical-align:baseline; + text-align:left; + width:auto; + display:block; + color:#090e21; + text-transform:none; + text-decoration:none; + background:rgba(0, 0, 0, 0); + -webkit-border-radius:0px 0px 0px 0px; + -moz-border-radius:0px 0px 0px 0px; + -ms-border-radius:0px 0px 0px 0px; + -o-border-radius:0px 0px 0px 0px; + border-radius:0px 0px 0px 0px; + font-family:inherit; + font-size:14px; +} +/* end new header */ +@media (min-width: 1320px) { + .body .flowListDiv dl.flowList { + -webkit-column-count:3; + -moz-column-count:3; + column-count:3 + } +} +@media (min-width: 1120px) { + #navbar.fixed { + -moz-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + -webkit-box-shadow:0px 0px 8px rgba(0,0,0,0.23); + box-shadow:0px 0px 8px rgba(0,0,0,0.23) + } + #navbar.fixed #mm-wrap #mm-helper > li.mm-item > a.mm-link { + height:50px; + line-height:50px + } + #navbar.fixed .navbar-oneQt:before { + font-size:35px; + top:7px + } + + .flowListDiv dl.flowList { + -webkit-column-count:2; + -moz-column-count:2; + column-count:2 + } +} +@media (max-width: 1120px) { + #navbar { + padding:0; + position:relative + } + #navbar .navbar-oneQt:before { + left:10px + } + #navbar .container { + max-width:100%; + padding:0 + } + #footerbar .container { + padding:0 + } + body .main { + margin-top:0px + } + #footerbar .footer-main .footer-nav { + padding:3.9% 0 3.9% 3%; + border-bottom:1px solid #413d3b; + float:none; + display:block; + width:auto + } + #footerbar .footer-main .theqtcompany { + clear:both; + float:left; + margin:30px 0 8px 3% + } + #footerbar .footer-main .footer-social { + float:left; + padding:50px 0px 0px 3% + } + #footerbar #menu-footer-submenu { + clear:both; + float:none; + display:block; + padding:0px 0px 3.9% 3% + } + ul#menu-footer-submenu { + margin-left: 0 + } +} +.cookies_yum { + background-color:#cecfd5; + display:none; + width:100% +} +.cookies_yum img { + width:25px; + top:6px; + display:inline-block; + position:absolute; + left:13px +} +.cookies_yum div { + margin:0 auto; + max-width:1280px; + min-height:30px; + padding:6px 0px 6px 0px; + position:relative +} +.cookies_yum p { + color:#09102b; + margin:0px; + font-size:0.79em; + display:inline-block; + line-height:1.2; + padding:0 30px 0 50px +} +.cookies_yum p a { + white-space:nowrap +} +.cookies_yum a:hover { + color:#46a2da +} +.cookies_yum .close { + width:15px; + height:15px; + background-image:url("cookiebar-x.png"); + background-size:15px 30px; + background-position:top left; + cursor:pointer; + top:13px; + right:13px; + position:absolute; + transition:none +} +.cookies_yum .close:hover { + background-position:bottom left +} +#sidebar-toggle,#toc-toggle { + width:24px; + height:14px; + background-size:24px 28px; + cursor:pointer; + background-image:url("list_expand.png"); + float:right +} +#sidebar-toggle.collapsed, +#toc-toggle.collapsed { + background-position:bottom left +} +#sidebar-content > h2 { + display:none +} +#footerbar { + background:#222840; + color:#fff; + font-size: 0.9em; +} +#footerbar.fixed { + bottom:0; + left:0; + width:100% +} +#footerbar .footer-nav { + display:inline; + float:left +} +#footerbar .footer-main .footer-nav li { + float:left; + margin-right:1em +} +#footerbar .footer-main .footer-nav li a { + display:block; + padding:30px 0 10px 0; + line-height:20px; + height:20px; + color:#fff; + font-weight: 600; +} +#footerbar .footer-main .footer-nav li a:hover,#footerbar .footer-main .footer-nav li.current-menu-item a { + color:#eee +} +#footerbar .footer-main .footer-nav .sub-menu { + margin-left:0; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li { + float:none; + width: 100%; +} +#footerbar .footer-main .footer-nav .sub-menu ul { + padding:1px 1em; + font-size:0.786em; + line-height:8px; + float:none; + color:#5d5b59; + margin-bottom:0 +} +#footerbar .footer-main .footer-nav .sub-menu li a { + padding:2px 0; + font-size:1em; + float:none; + color:#cecfd5; + font-weight: 400; +} +#footerbar .footer-main .footer-nav .sub-menu li a:hover,#footerbar .footer-main .footer-nav .sub-menu li.current-menu-item a { + color:#eee +} +#footerbar .theqtcompany { + background:url("theqtcompany.png") no-repeat; + background-size:100%; + width:215px; + height:68px; + display:inline; + float:right; + margin:29px 0 28px 30px +} +#footerbar .footer-social { + display:inline; + float:right; + width:164px +} +#footerbar .footer-main .footer-social>div { + margin-left:0.1em; + margin-bottom:10px +} +#footerbar .disclaimer { + font-size:0.786em; + line-height:2.73; + color:#868584; + padding-top:20px; + padding-bottom:0.5% +} +#footerbar .disclaimer a { + color:#bdbebf +} +#footerbar .disclaimer a:hover { + color:#d6d6d6 +} +#footerbar .disclaimer ul li { + float:left; + vertical-align:middle; + margin-left:1.18em +} +#footerbar .disclaimer ul li:first-child { + margin-left:0 +} +#footerbar .disclaimer ul.lang-selector a { + color:#506a34; + color:rgba(128,195,66,0.3) +} +#footerbar .disclaimer ul.lang-selector a:hover { + color:#80c342; + color:rgba(128,195,66,0.7) +} +#menu-footer-menu, #menu-footer-menu ul { + margin-left:0; + margin-bottom:0 +} +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot"); + /* IE9 Compat Modes */ + src: local("Titillium Web"), local("TitilliumWeb-Regular"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-regular.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-italic - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: italic; + font-weight: 400; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebItalic"), local("TitilliumWeb-Italic"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-italic.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +/* titillium-web-600 - latin_latin-ext */ +@font-face { + font-family: 'Titillium Web'; + font-style: normal; + font-weight: 600; + src: url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot"); + /* IE9 Compat Modes */ + src: local("Titillium WebSemiBold"), local("TitilliumWeb-SemiBold"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.eot?#iefix") format("embedded-opentype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff2") format("woff2"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.woff") format("woff"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.ttf") format("truetype"), url("//d33sqmjvzgs8hq.cloudfront.net/wp-content/themes/oneqt/assets/fonts/titillium-web-v4-latin_latin-ext-600.svg#TitilliumWeb") format("svg"); + /* Legacy iOS */ +} +@font-face { + font-family:monospace; + font-style:normal; + font-weight:400; + src:local("Droid Sans Mono"),local("DroidSansMono"),url(//fonts.gstatic.com/s/droidsansmono/v7/ns-m2xQYezAtqh7ai59hJUYuTAAIFFn5GTWtryCmBQ4.woff) format("woff") +} +@font-face { + font-family:'Qt Icons'; + src:url("../style/icomoon.eot?-tgjuoj"); + src:url("../style/icomoon.eot?#iefix-tgjuoj") format("embedded-opentype"),url("../style/icomoon.woff?-tgjuoj") format("woff"),url("../style/icomoon.ttf?-tgjuoj") format("truetype"),url("../style/icomoon.svg?-tgjuoj#icomoon") format("svg"); + font-weight:normal; + font-style:normal +} +@font-face { + font-family:'social-icons'; + src:url("../style/social-icons.eot?54625607"); + src:url("../style/social-icons.eot?54625607#iefix") format("embedded-opentype"), + url("../style/social-icons.woff?54625607") format("woff"); + font-weight:normal; + font-style:normal +} +.clearfix:before,.clearfix:after { + content:" "; + display:table +} +.clearfix:after { + clear:both +} +.clearfix { + *zoom:1 +} +.clearfix .right { + float:right +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + margin:0; + padding:0; + border:0; + font-size:100%; + line-height: 1.4; +} +html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,caption,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video { + vertical-align:baseline +} +h1,h2,h3,h4,h5,h6 { + font-weight:300 +} +.body h2,.body h3,.body h4,.body h5,.body h6 { + margin:1.5em 0 0.75em +} +.body h1 { + margin-bottom:0.75em; + font-size:2.25em; +} +.body h3.fn,.body h3.flags { + color:#26282a; + font-size:1.46em; + padding:15px 0 15px 0; + border-bottom:2px #eee solid; + word-wrap:break-word +} +.body .fngroup { + border-bottom:2px #eee solid; + padding-bottom:15px; + margin-bottom:1.5em +} +.body .fngroup h3.fngroupitem { + margin:0; + padding-bottom:0; + border:none +} +.body h3.fn .name, +.body h3 span.type, +.qmlname span.name { + font-weight: 400 +} +.qmlname { + font-size:1.46em +} +.qmlproto table { + border:none; + border-bottom:2px #eee solid +} +.qmlproto table p { + max-width:100% +} +.qmlproto table tr { + background-color:#fff +} +.qmlname td, .qmlname th { + border:none; + text-align:left; + padding:5px 0 0 0 +} +.qmlreadonly,.qmldefault { + padding:0 5px 0 5px; + font-size:0.75em; + background-color:#eee; + float:right +} +.qmlreadonly { + color:#414141 +} +.qmldefault { + color:#D14141 +} +.rightAlign { + padding:3px 5px 3px 10px; + text-align:right +} +.centerAlign.functionIndex { + text-align:center; + font-size:150%; + margin-bottom: 1em +} +article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section { + display:block +} +body { + line-height:1.25em; + font-family: Arial, Helvitica; + font-weight:400; + transition-duration:1s; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: 16px; + background-color:#f3f3f4; + color:#404244; +} +ol,ul { + list-style-type: square; + #color: #17a81a; +} +.body ol,.body ul { + margin-top:0.75em; + margin-left:20px +} +.bodywrapper ol>li { + list-style-type:decimal; + margin-left:15px +} +.bodywrapper ol.a >li { + list-style-type:lower-alpha; +} +.bodywrapper ol.A >li { + list-style-type:upper-alpha; +} +.bodywrapper ol.i >li { + list-style-type:lower-roman; +} +.bodywrapper ol.I >li { + list-style-type:upper-roman; +} +.body li p { + margin-top:1em +} +blockquote,q { + quotes:none; + border-left:10px solid #ddd; + padding-left:10px +} +blockquote:before,blockquote:after,q:before,q:after { + content:''; + content:none; + width:100% +} +table { + border-collapse:collapse; + border-spacing:0; + margin-bottom:5px; + width:100% +} +a { + color:#17a81a; + text-decoration:none; + transition-duration:0.3s +} +a:hover { + color:#17a81a +} +.main,#footerbar>div { + max-width:1280px; + width:95%; + margin:0 auto +} +.main { + margin-top:80px +} +@media (max-width: 1120px) { + .main,.navbar-header,#footerbar>div { + width: 100%; + margin: 0; + } + .main .main-rounded { + padding: 0 15px; + } +} +.main_index { + background-color:#fff +} +.sectionlist { + margin-bottom:2em +} +[class*="col-"] { + letter-spacing:normal +} +.landing,.main_index .row { + letter-spacing:-0.31em +} +.main_index .row>div { + letter-spacing:normal +} +.col-1,.body { + display:inline-block; + background-color:#fff; + padding: 25px 35px 20px 30px; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; +} +.col-1 h2 { + font-size:1.8em; + font-weight:300; + line-height:1.1; + margin-bottom:0.83em; + margin-top:1em +} +.icons1of3 img { + display:inline-block; + float:left; + margin-right:0.75em; + margin-top:-5px; + width:2.75em +} +div.multi-column { + position:relative +} +div.multi-column div { + display:-moz-inline-box; + display:inline-block; + vertical-align:top; + margin-top:1em; + margin-right:2em; + width:16em +} +.sidebar { + display:block; + position:relative; + position:sticky; + float:left; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + width:20%; + padding-right:20px +} +.sidebar li { + text-overflow:ellipsis; + overflow:hidden +} +.toc,.sectionlist { + padding:25px; + background-color:#fff; + margin-bottom:1.25em +} +.sidebar .sectionlist p { + margin-bottom:0 +} +.sectionlist.promo { + padding:0; + background-color:#f3f3f4 +} +.sidebar-content:empty { + display:none; + visibility:hidden +} +.col-2 h2,.toc h3,.sidebar-content h2, +.sidebar-content h3,.sectionlist h2, +.sphinxsidebar { + position: fixed; + overflow: scroll; + overflow-x: hidden; + overflow-y: hidden; +} +.sphinxsidebar h3 { + font-weight: bold; + margin-bottom:1em; +} +.toc h3 a { + color:#404244 +} +.title { + font-size:2.25em; + font-weight:300; + letter-spacing:-1px; + line-height:1.15em; + margin-bottom:0.5em; + word-wrap:break-word +} +.navigationbar,col-1 h2 { + font-size:0.85em +} +.navigationbar h1 { + font-size:2.5em; + margin-bottom:0.85em; + margin-top:0.85em +} +.navigationbar li { + display:inline-block; + margin-right:5px; + position:relative; + padding-right:10px; + color:#585a5c +} +.navigationbar ul:last-of-type li a { + color:#404244 +} +.sectionlist li, .sphinxsidebar li { + padding-bottom: 10px; + line-height: 1.75em; +} +.col-1 ul { + margin-bottom:1.56em +} +.bodywrapper li { + margin-top:0.5em; + line-height:1.25em +} +.bodywrapper li.level2 { + margin-left:10px; + margin-top:0.4em; + font-size:0.9375em; +} +.bodywrapper p, +.bodywrapper dd { + line-height:1.25em; + margin:1em 0 1em; + color:#404244 +} +.bodywrapper b { + font-weight:600 +} +.body ul,.body ol { + /* margin-bottom:1.5em */ +} +.bodywrapper ul ul { + margin-top:0.5em +} +.bodywrapper .naviNextPrevious { + margin-top:25px; + max-width:100% +} +.naviNextPrevious.headerNavi, +p.naviNextPrevious + p { + display:none +} +.nextPage { + float:right +} +.prevPage:before { + content:"< " +} +.nextPage:after { + content:" >" +} +.navigationbar li a { + color:#404244 +} +.navigationbar li:after { + color:#404244; + content:"›"; + display:inline-block; + font-size:1.5em; + line-height:1; + position:absolute; + right:-2px; + top:-4px +} +.sub-navigation { + margin-top:10px +} +.navigationbar li:last-child:after,.sub-navigation li:after { + content:none +} +.navigationbar { + margin-bottom:10px; + line-height:1em +} +#buildversion { + margin-bottom:10px; + font-style:italic; + font-size:small; + float:right +} +.copy-notice { + width:75%; + font-size:0.75em; + margin:20px 35px 0 10px; + line-height:1.75em; + float:right; + color:#585a5c +} +.copy-notice.index { + margin-top:10px; + float:none +} +li a.active { + color:#585a5c +} +.flowList { + padding:25px +} +.flowListDiv dl { + -webkit-column-count:1; + -moz-column-count:1; + column-count:1 +} +.flowList dd { + display:inline-block; + margin-left:10px; + width:90%; + line-height:1.15em; + overflow-x:hidden; + text-overflow:ellipsis +} +.alphaChar { + font-size:2em; + position:absolute +} +.flowList.odd { + background-color:#f9f9f9 +} +.body ul>li,.doc-column ul>li { + list-style-image:url("list_arrow.png"); + margin-left:15px; + color:#404244; + margin-top:0.65em; + line-height:1em +} +.bodywrapper table p { + margin:0px; + padding:0px +} +.bodywrapper table p { + margin:0px; + padding:0px; + min-height:1.25em +} +.bodywrapper .qmldoc { + margin-top:0.75em +} +.body h2 { + margin-top: 1.5em; + font-size:1.75em +} +.body h3 { + font-size:1.35em +} +.body h4 { + font-size:1.15em +} +.body p img { + margin-top:0.75em; + max-width:100% +} +.body .border img { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body .border .player { + box-shadow:3px 3px 8px 3px rgba(200,200,200,0.5) +} +.body p.figCaption { + transform:translateY(-30px); + color:#606366; + font-size:95%; + margin-left:3px; + font-style:italic +} +.body table { + width:initial; + vertical-align:initial +} +table .odd { + background-color:#f9f9f9 +} +table thead { + text-align:left; + padding-left:20px +} +table,table td,table th { + border:1px solid #eee +} +table td,table th { + padding:5px 20px; + line-height:1.3 +} +.body .fixed table td { + min-width:50%; + width:50% +} +table.alignedsummary,table.propsummary { + width:initial +} +table.valuelist td.tblval { + font-size:0.75em +} +div.main_index .row { + border-bottom:10px solid #f3f3f4 +} +div.main_index .row { + position:relative +} +div.main_index .row>div { + display:inline-block; + width:50%; + vertical-align:top; + padding:2em 3em; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box +} +div.main_index h2 { + font-size:2.1875em; + margin-bottom:1em +} +#search_bar { + width:40%; + float:right +} +div.main_index .row:after { + content:""; + position:absolute; + top:0; + right:50%; + height:100%; + width:10px; + background-color:#f3f3f4 +} +div.table { + overflow-x:auto +} +.body tr > td > pre { + font-size:0.75em +} +p.qt_commercial { + border:3px solid #5caa15; + margin:0 auto; + padding:15px; + width:28%; + text-align:center; + clear:both +} +h1.qt_commercial { + padding:20px; + background-color:#5caa15; + display:inline; + float:right; + font-size:1.25em; + line-height:1.25em; + height:1.25em; + color:#fff +} +div.qt_commercial { + border-top:5px solid #5caa15; + margin-bottom:50px +} +div.pre { + position:relative; + height:auto +} +pre, .LegaleseLeft { + background-color:#222840; + color:#fff; + display:block; + font-family:monospace; + line-height:1.5; + overflow-x:auto; + margin-bottom:25px; + padding:25px; + margin-top:0.75em; + font-size: .8em; +} +.bodywrapper .LegaleseLeft p { + color:#fff; + white-space: pre-wrap +} +pre .str,code .str { + color:#aaaaaa +} +pre .kwd,code .kwd { + color:#ffff55 +} +pre .com,code .com { + color:#55ffff +} +pre .typ,code .typ { + color:#4f9d08 +} +pre a .typ,code a .typ { + color:#21be2b +} +pre .lit,code .lit { + color:#ff55ff +} +pre .pun,code .pun { + color:#fff +} +pre .pln,code .pln { + color:#fff +} +@media print { + pre { + background-color:#eee !important + } + pre .str,code .str { + color:#060 + } + pre .kwd,code .kwd{ + color:#006; + font-weight:bold + } + pre .com,code .com { + color:#600 + } + pre .typ,code .typ { + color:#404; + font-weight:bold + } + pre .lit,code .lit { + color:#044 + } + pre .pun,code .pun { + color:#440 + } + pre .pln,code .pln { + color:#000 + } +} +pre.wrap { + white-space:pre-wrap +} +pre span.wrap { + display:none; + background:url("wrap.png") no-repeat; + right:0; + top:2px; + position:absolute; + width:20px; + height:14px; + margin:4px; + opacity:0.65 +} + +span.pre { + color: #09102d; +} + +span.wrap:hover { + opacity:1 +} +span.wrap:active { + opacity:0.75 +} +.copy_text { + background-color:#46a2da; + color:#fff; + border:2px solid #46a2da; + padding:10px 16px; + margin-left:-10px; + margin-top:-50px; + position:absolute; + opacity:0; + cursor:pointer; + float:right +} +.copy_text:hover { + background-color:#fff; + color:#46a2da +} +code,.codelike { + font-family:monospace; +} +#detailed-description .function dt > code, +#detailed-description .function dt > em { + font-weight:bold +} +h3.fn code { + font-size:0.75em; + float:right; + background-color:#eee; + padding:3px; + margin: 3px 0 0 20px +} +pre:hover>.copy_text { + display:inline-block; + opacity:1; + transition:0.5s ease +} +#main_title_bar { + background:url("pyside-logo.png") no-repeat; + background-size:100%; + width:366px; + height:86px; + margin:15px 0 15px 0 +} +#main_title_bar h1 { + visibility:hidden +} +#main_title_bar .search_bar { + letter-spacing:normal; + width:50%; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar h1 { + letter-spacing:normal; + display:inline-block; + -webkit-box-sizing:border-box; + -moz-box-sizing:border-box; + -ms-box-sizing:border-box; + box-sizing:border-box; + vertical-align:middle +} +#main_title_bar .search_bar * { + letter-spacing:normal; + padding:0; + margin:0; + border:none +} +#sidebar-toggle,#toc-toggle { + display:none +} +@media (max-width: 980px) { + body { + font-size:calc-em(14px) + } + #main_title_bar>h1,#main_title_bar .search_bar { + width:100% + } + #main_title_bar .search_bar { + margin-bottom:15px + } + .main { + margin-top:0px + } + .main_index .row { + border:none !important + } + .title { + font-size:1.5em; + font-weight:400; + word-wrap:break-word + } + .col-1,.body,.naviNextPrevious,.sidebar { + padding:10px + } + .sidebar { + position:relative; + padding-top:0 + } + .search .sidebar { + display:none; + visibility:hidden + } + .col-2 h2,.toc h3,.sidebar-content h2,.sidebar-content h3,.sectionlist h2 { + text-align:center; + margin-bottom:5px + } + div.main_index .row:after { + content:none + } + div.main_index .row>div { + display:block !important; + width:100%; + padding:15px; + margin:0 + } + .body,.sidebar,.col-1 { + width:100% + } + .sidebar-content,.col-2,.toc { + background-color:#fff; + margin-bottom:1em; + padding:20px + } + #sidebar-toggle,#toc-toggle { + display:block + } + #sidebar-toggle.collapsed + h2 { + display:block + } + .bodywrapper p { + margin-bottom:1em; + max-width:100% + } + table td,table th { + padding:5px 5px + } + .sectionlist { + padding:0 + } + .sidebar > .sectionlist { + padding:20px + } + .sectionlist.promo { + max-width:46%; + margin:0 auto 1em auto; + float:left; + padding:0 2% + } + .sidebar .sidebar-content { + clear:both + } + .copy-notice { + float:none; + width:initial + } +} +[id]:target > *:first-child, +dt[id]:target { + -webkit-animation:highlighter 3s; + animation:highlighter 3s +} +@-webkit-keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@keyframes highlighter { + 25% { + background-color:#d1e8f6; + color:#444 + } + 75% { + background-color:#d1e8f6; + color:#444 + } +} +@-webkit-keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +@keyframes copypaste { + 25% { + opacity:1 + } + 100% { + border-radius:10px; + margin-top:-50px; + opacity:1 + } +} +#footer { + clear:both +} +.footer-social i { + font-family: "social-icons"; + font-style: normal; + font-size:150%; + margin: .55em; + color: #cecfd5 +} +.footer-social i:hover { + color: #eee +} +.footer-social .icon-twitter:before { + content: '\f099' +} +.footer-social .icon-facebook:before { + content: '\f09a' +} +.footer-social .icon-youtube:before { + content: '\f16a' +} +.menuextraslanguages { + display:none; + visibility:hidden +} + +input:focus { + border-color: #46a2da; + box-shadow: 0 0 5px #46a2da; + color: #000; +} + +.animation { + width: 100%; + border-style: none; + border-width: 0 +} + +.player { + width: auto; + position: relative; + display: table; + margin-bottom:1.5em; +} + +.playcontrol { + display: none; + background: url("play_icon.svg") no-repeat center, + linear-gradient( + rgba(0,0,0,0.15), rgba(0,0,0,0.15) + ); + background-size: 25%; + width: 100%; + height: 100%; + position: absolute; + left: 0%; + right: 0%; + top: 0%; + bottom: 0%; + margin: auto +} + +/* expand/collapse code sections */ +pre input { + display:none; + visibility:hidden +} +pre label { + display:block; + margin:-3px 3px 0 -16px; + text-align:center; + color:#21be2b; + float:left; +} +pre label:hover { + color:#fff +} +pre label::before { + font-weight:600; + font-size:16px; + content:"+"; + display:inline-block; + width:16px; + height:16px +} +#ec_expand { + height:16px; + overflow:hidden; + transition:height 0.35s; +} +#ec_expand::before { + content:"...*/"; + color:#aaa; + background-color:#3a4055; + z-index:99 !important; + right:25px; + position:absolute +} +#ec_toggle:checked ~ #ec_expand { + height:initial +} +#ec_toggle:checked ~ #ec_expand::before { + content:"" +} +#ec_toggle:checked ~ label::before { + content:"-" +} + +/* permalinks */ +h1:hover > .headerlink, +h2:hover > .plink, +h2:hover > .headerlink, +h3:hover > .plink, +h3:hover > .headerlink, +h4:hover > .plink, +h4:hover > .headerlink, +h5:hover > .plink, +h5:hover > .headerlink { + opacity:1 +} +a.plink, a.headerlink { + opacity: 0; + padding-left: 8px; + font-size: 0.8em; + font-weight: 600; + transition: opacity 180ms ease-in-out +} +a.plink::before { + content:'\00B6' +} + +table.special { + border: 3px; + padding: 0px; + border-collapse: separate; + border-spacing: 20px; + line-height: 1.5em; +} + +.special p { + text-align: center; + color: #3a4055; +} + +.special a { + display: block; + border-bottom: 0; + text-decoration: none; +} + +.special a:hover { + border-bottom: 0; + text-decoration: none; +} + +.special strong { + color: #17a81a; + font-size: 110%; + font-weight: normal; +} + +table.special th, +table.special td { + border: 1px solid #888; + padding-top: 14px; + padding-bottom: 14px; + padding-left: 6px; + padding-right: 5px; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + -khtml-border-radius: 5px; +} + +.special td:hover { + padding-top: 2px; + padding-bottom: 2px; + border-bottom: 4px solid #41cd52; +} diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/pysidelogo.png new file mode 100644 index 0000000000000000000000000000000000000000..3a2f2bd17d274bb2749d201fe4fdcf63d16b4b62 GIT binary patch literal 4936 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png b/sources/pyside2/doc/_themes/pysidedocs_qthelp/static/relbar_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..4036733a7bad6f210ffe961dbc394fce33800be6 GIT binary patch literal 130 zcmeAS@N?(olHy`uVBq!ia0vp^{6MVC!3HF~cLcBlDNj!q#}JRsx6=-CG8k|$i|$$w zTw?G%WViDYU8g_t)58~aoe=wQ /dev/null +# if [ $? -ne 0 ] +# then +# if fgrep '' "$F" > /dev/null # Exclude reference only +# then +# egrep "( /dev/null || echo $F +# fi +# fi +# done +# A line enclosed in [] denotes a (relative) target directory +[pyside-examples] +all-pyside-examples.webxml +pyside2examples-widgets-dialogs-classwizard-classwizard-pyproject.webxml +pyside2examples-widgets-dialogs-classwizard-classwizard-py.webxml +pyside2examples-widgets-dialogs-classwizard-classwizard-qrc.webxml +pyside2examples-widgets-dialogs-classwizard-classwizard-rc-py.webxml +pyside2examples-widgets-dialogs-classwizard-example.webxml +pyside2examples-widgets-itemviews-stardelegate-example.webxml +pyside2examples-widgets-itemviews-stardelegate-stardelegate-pyproject.webxml +pyside2examples-widgets-itemviews-stardelegate-stardelegate-py.webxml +pyside2examples-widgets-itemviews-stardelegate-stareditor-py.webxml +pyside2examples-widgets-itemviews-stardelegate-starrating-py.webxml + +[overviews] +animation-overview.webxml +animation.webxml +application-windows.webxml +audiooverview.webxml +bearer-management.webxml +cameraoverview.webxml +# changes.webxml +codec-big5.webxml +codec-big5hkscs.webxml +codec-eucjp.webxml +codec-euckr.webxml +codec-gbk.webxml +codec-sjis.webxml +codec-tscii.webxml +codecs-jis.webxml +compatmap.webxml +# containers.webxml +coordsys.webxml +creating-a-sensor-plugin.webxml +custom-types.webxml +datastreamformat.webxml +datavisualization-examples.webxml +determining-the-default-sensor-for-a-type.webxml +dialogs.webxml +dnd.webxml +dynamic-sensor-backend-registration.webxml +events.webxml +eventsandfilters.webxml +examples-desktop.webxml +examples-dialogs.webxml +examples-graphicsview.webxml +examples-itemviews.webxml +examples-mainwindow.webxml +examples-network.webxml +examples-painting.webxml +examples-qthelp.webxml +examples-qtuitools.webxml +examples-richtext.webxml +examples-widgets-opengl.webxml +examples-widgets.webxml +focus.webxml +gallery.webxml +genericbackend.webxml +gestures-overview.webxml +graphicsview.webxml +guibooks.webxml +helpsystem.webxml +implicit-sharing.webxml +io-functions.webxml +io.webxml +json.webxml +layout.webxml +location-cpp-qml.webxml +location-maps-cpp.webxml +location-maps-qml.webxml +location-places-backend.webxml +location-places-cpp.webxml +location-places-qml.webxml +location-plugin-esri.webxml +location-plugin-here.webxml +location-plugin-itemsoverlay.webxml +location-plugin-mapbox.webxml +location-plugin-mapboxgl.webxml +location-plugin-osm.webxml +location-positioning-cpp.webxml +location-positioning-qml.webxml +mainwindow.webxml +metaobjects.webxml +model-view-programming.webxml +modelview.webxml +multimedia-examples.webxml +multimediabackend.webxml +multimediaoverview.webxml +object.webxml +objecttrees.webxml +painting.webxml +paintsystem-devices.webxml +paintsystem-drawing.webxml +paintsystem-images.webxml +paintsystem.webxml +pdf-licensing.webxml +plugins.webxml +positioning-cpp-qml.webxml +properties.webxml +qfloat16.webxml +qml-advtutorial.webxml +qml-dynamicview-tutorial.webxml +qml-location5-maps.webxml +qml-multimedia.webxml +qml-qtlocation5-maps.webxml +qml-tutorial.webxml +qml-tutorial1.webxml +qml-tutorial2.webxml +qml-tutorial3.webxml +qmlexampletoggleswitch.webxml +qt3d-advancedcustommaterial-example.webxml +qt3d-audio-visualizer-qml-example.webxml +qt3d-basicshapes-cpp-example.webxml +qt3d-cpp.webxml +qt3d-examples.webxml +qt3d-multiviewport-example.webxml +qt3d-overview.webxml +qt3d-pbr-materials-example.webxml +qt3d-planets-qml-example.webxml +qt3d-qml.webxml +qt3d-scene2d-example.webxml +qt3d-scene3d-example.webxml +qt3d-shadow-map-qml-example.webxml +qt3d-simple-cpp-example.webxml +qt3d-simple-qml-example.webxml +qt3d-simplecustommaterial-example.webxml +qt3d-wave-example.webxml +qt3d-widgets-scene3d-example.webxml +qt3d-wireframe-example.webxml +qt3drender-framegraph.webxml +qt3drender-geometry.webxml +qt3drender-protips.webxml +qtalgorithms.webxml +qtconcurrent-imagescaling-example.webxml +qtconcurrent-map-example.webxml +qtconcurrent-progressdialog-example.webxml +qtconcurrent-runfunction-example.webxml +qtconcurrent-wordcount-example.webxml +qtconcurrentfilter.webxml +qtconcurrentmap.webxml +qtconcurrentrun.webxml +qtcore-ipc-localfortuneclient-example.webxml +qtcore-ipc-localfortuneserver-example.webxml +qtcore-ipc-sharedmemory-example.webxml +qtcore-mimetypes-mimetypebrowser-example.webxml +qtcore-serialization-savegame-example.webxml +qtcore-threads-mandelbrot-example.webxml +qtcore-threads-queuedcustomtype-example.webxml +qtcore-threads-semaphores-example.webxml +qtcore-threads-waitconditions-example.webxml +qtcore-tools-contiguouscache-example.webxml +qtcore-tools-customtype-example.webxml +qtdatavisualization-audiolevels-example.webxml +qtdatavisualization-bars-example.webxml +qtdatavisualization-custominput-example.webxml +qtdatavisualization-customitems-example.webxml +qtdatavisualization-customproxy-example.webxml +qtdatavisualization-data-handling.webxml +qtdatavisualization-draggableaxes-example.webxml +qtdatavisualization-interacting-with-data.webxml +qtdatavisualization-itemmodel-example.webxml +qtdatavisualization-known-issues.webxml +qtdatavisualization-overview.webxml +qtdatavisualization-qmlaxisdrag-example.webxml +qtdatavisualization-qmlaxisformatter-example.webxml +qtdatavisualization-qmlbars-example.webxml +qtdatavisualization-qmlcustominput-example.webxml +qtdatavisualization-qmllegend-example.webxml +qtdatavisualization-qmlmultigraph-example.webxml +qtdatavisualization-qmloscilloscope-example.webxml +qtdatavisualization-qmlscatter-example.webxml +qtdatavisualization-qmlspectrogram-example.webxml +qtdatavisualization-qmlsurface-example.webxml +qtdatavisualization-qmlsurfacelayers-example.webxml +qtdatavisualization-rotations-example.webxml +qtdatavisualization-scatter-example.webxml +qtdatavisualization-surface-example.webxml +qtdatavisualization-texturesurface-example.webxml +qtdatavisualization-volumetric-example.webxml +qtest-overview.webxml +qtest-tutorial.webxml +qtglobal.webxml +qtgui-analogclock-example.webxml +qtgui-hellovulkancubes-example.webxml +qtgui-hellovulkantexture-example.webxml +qtgui-hellovulkantriangle-example.webxml +qtgui-hellovulkanwidget-example.webxml +qtgui-hellovulkanwindow-example.webxml +qtgui-openglwindow-example.webxml +qtgui-rasterwindow-example.webxml +qthelp-framework.webxml +qthelpproject.webxml +qtlocation-changes.webxml +qtlocation-cpp.webxml +qtlocation-examples.webxml +qtlocation-geoservices.webxml +qtlocation-mapviewer-example.webxml +qtlocation-minimal-map-example.webxml +qtlocation-places-example.webxml +qtlocation-places-list-example.webxml +qtlocation-places-map-example.webxml +qtlocation-planespotter-example.webxml +qtmath.webxml +qtmultimedia-ios.webxml +qtmultimedia-multimedia-audiodevices-example.webxml +qtmultimedia-multimedia-audioengine-example.webxml +qtmultimedia-multimedia-audioinput-example.webxml +qtmultimedia-multimedia-audiooutput-example.webxml +qtmultimedia-multimedia-audiorecorder-example.webxml +qtmultimedia-multimedia-declarative-camera-example.webxml +qtmultimedia-multimedia-declarative-radio-example.webxml +qtmultimedia-multimedia-spectrum-example.webxml +qtmultimedia-multimedia-video-qmlvideo-example.webxml +qtmultimedia-multimedia-video-qmlvideofx-example.webxml +qtmultimedia-multimediawidgets-camera-example.webxml +qtmultimedia-multimediawidgets-player-example.webxml +qtmultimedia-multimediawidgets-videographicsitem-example.webxml +qtmultimedia-multimediawidgets-videowidget-example.webxml +qtmultimedia-windows.webxml +qtnetwork-blockingfortuneclient-example.webxml +qtnetwork-broadcastreceiver-example.webxml +qtnetwork-broadcastsender-example.webxml +qtnetwork-download-example.webxml +qtnetwork-downloadmanager-example.webxml +qtnetwork-fortuneclient-example.webxml +qtnetwork-fortuneserver-example.webxml +qtnetwork-googlesuggest-example.webxml +qtnetwork-http-example.webxml +qtnetwork-loopback-example.webxml +qtnetwork-multicastreceiver-example.webxml +qtnetwork-multicastsender-example.webxml +qtnetwork-network-chat-example.webxml +qtnetwork-programming.webxml +qtnetwork-securesocketclient-example.webxml +qtnetwork-threadedfortuneserver-example.webxml +qtnetwork-torrent-example.webxml +qtopengl-2dpainting-example.webxml +qtopengl-cube-example.webxml +qtopengl-hellogl2-example.webxml +qtpositioning-examples.webxml +qtpositioning-geoflickr-example.webxml +qtpositioning-logfilepositionsource-example.webxml +qtpositioning-plugins.webxml +qtpositioning-satelliteinfo-example.webxml +qtpositioning-weatherinfo-example.webxml +qtquick-animation-example.webxml +qtquick-bestpractices.webxml +qtquick-canvas-example.webxml +qtquick-codesamples.webxml +qtquick-convenience-topic.webxml +qtquick-cppextensionpoints.webxml +qtquick-customitems-dialcontrol-example.webxml +qtquick-customitems-flipable-example.webxml +qtquick-customitems-painteditem-example.webxml +qtquick-customitems-scrollbar-example.webxml +qtquick-customitems-tabwidget-example.webxml +qtquick-demos-calqlatr-example.webxml +qtquick-demos-clocks-example.webxml +qtquick-demos-maroon-example.webxml +qtquick-demos-photosurface-example.webxml +qtquick-demos-photoviewer-example.webxml +qtquick-demos-rssnews-example.webxml +qtquick-demos-samegame-example.webxml +qtquick-demos-stocqt-example.webxml +qtquick-demos-tweetsearch-example.webxml +qtquick-draganddrop-example.webxml +qtquick-effects-particles.webxml +qtquick-effects-sprites.webxml +qtquick-effects-topic.webxml +qtquick-effects-transformations.webxml +qtquick-externaldraganddrop-example.webxml +qtquick-imageelements-example.webxml +qtquick-imageprovider-example.webxml +qtquick-imageresponseprovider-example.webxml +qtquick-input-focus.webxml +qtquick-input-mouseevents.webxml +qtquick-input-textinput.webxml +qtquick-input-topic.webxml +qtquick-keyinteraction-example.webxml +qtquick-layouts-example.webxml +qtquick-localstorage-example.webxml +qtquick-modelviewsdata-cppmodels.webxml +qtquick-modelviewsdata-modelview.webxml +qtquick-modelviewsdata-topic.webxml +qtquick-mousearea-example.webxml +qtquick-particles-affectors-example.webxml +qtquick-particles-customparticle-example.webxml +qtquick-particles-emitters-example.webxml +qtquick-particles-imageparticle-example.webxml +qtquick-particles-performance.webxml +qtquick-particles-system-example.webxml +qtquick-positioners-example.webxml +qtquick-positioning-anchors.webxml +qtquick-positioning-layouts.webxml +qtquick-positioning-righttoleft.webxml +qtquick-positioning-topic.webxml +qtquick-quick-accessibility-example.webxml +qtquick-righttoleft-example.webxml +qtquick-scenegraph-customgeometry-example.webxml +qtquick-scenegraph-materials.webxml +qtquick-scenegraph-nodes.webxml +qtquick-scenegraph-openglunderqml-example.webxml +qtquick-scenegraph-simplematerial-example.webxml +qtquick-shadereffects-example.webxml +qtquick-shapes-example.webxml +qtquick-statesanimations-animations.webxml +qtquick-statesanimations-behaviors.webxml +qtquick-statesanimations-states.webxml +qtquick-statesanimations-topic.webxml +qtquick-text-example.webxml +qtquick-text-validator.webxml +qtquick-threading-example.webxml +qtquick-threading-threadedlistmodel-example.webxml +qtquick-tools-and-utilities.webxml +qtquick-touchinteraction-example.webxml +qtquick-tutorials-dynamicview-dynamicview1-example.webxml +qtquick-tutorials-dynamicview-dynamicview2-example.webxml +qtquick-tutorials-dynamicview-dynamicview3-example.webxml +qtquick-tutorials-dynamicview-dynamicview4-example.webxml +qtquick-tutorials-samegame-samegame1-example.webxml +qtquick-tutorials-samegame-samegame2-example.webxml +qtquick-tutorials-samegame-samegame3-example.webxml +qtquick-tutorials-samegame-samegame4-example.webxml +qtquick-views-example.webxml +qtquick-visualcanvas-adaptations-d3d12.webxml +qtquick-visualcanvas-adaptations-openvg.webxml +qtquick-visualcanvas-adaptations-software.webxml +qtquick-visualcanvas-adaptations.webxml +qtquick-visualcanvas-coordinates.webxml +qtquick-visualcanvas-scenegraph-renderer.webxml +qtquick-visualcanvas-scenegraph.webxml +qtquick-visualcanvas-topic.webxml +qtquick-visualcanvas-visualparent.webxml +qtquick-visualtypes-topic.webxml +qtquick-window-example.webxml +qtquicklayouts-overview.webxml +qtsensorgestures-cpp.webxml +qtsensors-accelbubble-example.webxml +qtsensors-cpp.webxml +qtsensors-examples.webxml +qtsensors-grue-example.webxml +qtsensors-maze-example.webxml +qtsensors-porting.webxml +qtsensors-qmlqtsensors-example.webxml +qtsensors-qmlsensorgestures-example.webxml +qtsensors-sensor-explorer-example.webxml +qtsensors-sensorgestures-example.webxml +qtsensors-shakeit-example.webxml +qtsql-books-example.webxml +qtsql-cachedtable-example.webxml +qtsql-drilldown-example.webxml +qtsql-masterdetail-example.webxml +qtsql-sqlwidgetmapper-example.webxml +qtsvg-richtext-textobject-example.webxml +qtsvg-svggenerator-example.webxml +qtsvg-svgviewer-example.webxml +qttestlib-tutorial1-example.webxml +qttestlib-tutorial2-example.webxml +qttestlib-tutorial3-example.webxml +qttestlib-tutorial4-example.webxml +qttestlib-tutorial5-example.webxml +qttestlib-tutorial6.webxml +qtuitools-multipleinheritance-example.webxml +qtuitools-textfinder-example.webxml +qtwidgets-animation-easing-example.webxml +qtwidgets-animation-moveblocks-example.webxml +qtwidgets-animation-stickman-example.webxml +qtwidgets-animation-sub-attaq-example.webxml +qtwidgets-desktop-screenshot-example.webxml +qtwidgets-desktop-systray-example.webxml +qtwidgets-dialogs-classwizard-example.webxml +qtwidgets-dialogs-extension-example.webxml +qtwidgets-dialogs-findfiles-example.webxml +qtwidgets-dialogs-licensewizard-example.webxml +qtwidgets-dialogs-tabdialog-example.webxml +qtwidgets-dialogs-trivialwizard-example.webxml +qtwidgets-draganddrop-draggableicons-example.webxml +qtwidgets-draganddrop-dropsite-example.webxml +qtwidgets-draganddrop-fridgemagnets-example.webxml +qtwidgets-draganddrop-puzzle-example.webxml +qtwidgets-effects-blurpicker-example.webxml +qtwidgets-effects-fademessage-example.webxml +qtwidgets-gestures-imagegestures-example.webxml +qtwidgets-graphicsview-anchorlayout-example.webxml +qtwidgets-graphicsview-basicgraphicslayouts-example.webxml +qtwidgets-graphicsview-boxes-example.webxml +qtwidgets-graphicsview-chip-example.webxml +qtwidgets-graphicsview-collidingmice-example.webxml +qtwidgets-graphicsview-diagramscene-example.webxml +qtwidgets-graphicsview-dragdroprobot-example.webxml +qtwidgets-graphicsview-elasticnodes-example.webxml +qtwidgets-graphicsview-embeddeddialogs-example.webxml +qtwidgets-graphicsview-flowlayout-example.webxml +qtwidgets-graphicsview-padnavigator-example.webxml +qtwidgets-graphicsview-simpleanchorlayout-example.webxml +qtwidgets-graphicsview-weatheranchorlayout-example.webxml +qtwidgets-itemviews-addressbook-example.webxml +qtwidgets-itemviews-chart-example.webxml +qtwidgets-itemviews-coloreditorfactory-example.webxml +qtwidgets-itemviews-combowidgetmapper-example.webxml +qtwidgets-itemviews-customsortfiltermodel-example.webxml +qtwidgets-itemviews-dirview-example.webxml +qtwidgets-itemviews-editabletreemodel-example.webxml +qtwidgets-itemviews-fetchmore-example.webxml +qtwidgets-itemviews-frozencolumn-example.webxml +qtwidgets-itemviews-pixelator-example.webxml +qtwidgets-itemviews-puzzle-example.webxml +qtwidgets-itemviews-simpledommodel-example.webxml +qtwidgets-itemviews-simpletreemodel-example.webxml +qtwidgets-itemviews-simplewidgetmapper-example.webxml +qtwidgets-itemviews-spinboxdelegate-example.webxml +qtwidgets-itemviews-stardelegate-example.webxml +qtwidgets-layouts-basiclayouts-example.webxml +qtwidgets-layouts-borderlayout-example.webxml +qtwidgets-layouts-dynamiclayouts-example.webxml +qtwidgets-layouts-flowlayout-example.webxml +qtwidgets-mainwindows-application-example.webxml +qtwidgets-mainwindows-dockwidgets-example.webxml +qtwidgets-mainwindows-menus-example.webxml +qtwidgets-painting-affine-example.webxml +qtwidgets-painting-basicdrawing-example.webxml +qtwidgets-painting-composition-example.webxml +qtwidgets-painting-concentriccircles-example.webxml +qtwidgets-painting-deform-example.webxml +qtwidgets-painting-fontsampler-example.webxml +qtwidgets-painting-gradients-example.webxml +qtwidgets-painting-imagecomposition-example.webxml +qtwidgets-painting-painterpaths-example.webxml +qtwidgets-painting-pathstroke-example.webxml +qtwidgets-painting-transformations-example.webxml +qtwidgets-richtext-calendar-example.webxml +qtwidgets-richtext-orderform-example.webxml +qtwidgets-richtext-syntaxhighlighter-example.webxml +qtwidgets-statemachine-eventtransitions-example.webxml +qtwidgets-statemachine-factorial-example.webxml +qtwidgets-statemachine-pingpong-example.webxml +qtwidgets-statemachine-rogue-example.webxml +qtwidgets-statemachine-trafficlight-example.webxml +qtwidgets-statemachine-twowaybutton-example.webxml +qtwidgets-tools-codecs-example.webxml +qtwidgets-tools-completer-example.webxml +qtwidgets-tools-customcompleter-example.webxml +qtwidgets-tools-echoplugin-example.webxml +qtwidgets-tools-plugandpaint-app-example.webxml +qtwidgets-tools-plugandpaint-plugins-basictools-example.webxml +qtwidgets-tools-plugandpaint-plugins-extrafilters-example.webxml +qtwidgets-tools-regularexpression-example.webxml +qtwidgets-tools-styleplugin-example.webxml +qtwidgets-tools-treemodelcompleter-example.webxml +qtwidgets-tools-undo-example.webxml +qtwidgets-tools-undoframework-example.webxml +qtwidgets-tutorials-addressbook-part1-example.webxml +qtwidgets-tutorials-addressbook-part2-example.webxml +qtwidgets-tutorials-addressbook-part3-example.webxml +qtwidgets-tutorials-addressbook-part4-example.webxml +qtwidgets-tutorials-addressbook-part5-example.webxml +qtwidgets-tutorials-addressbook-part6-example.webxml +qtwidgets-tutorials-addressbook-part7-example.webxml +qtwidgets-tutorials-notepad-example.webxml +qtwidgets-tutorials-widgets-childwidget-example.webxml +qtwidgets-tutorials-widgets-nestedlayouts-example.webxml +qtwidgets-tutorials-widgets-toplevel-example.webxml +qtwidgets-tutorials-widgets-windowlayout-example.webxml +qtwidgets-widgets-analogclock-example.webxml +qtwidgets-widgets-calculator-example.webxml +qtwidgets-widgets-calendarwidget-example.webxml +qtwidgets-widgets-charactermap-example.webxml +qtwidgets-widgets-codeeditor-example.webxml +qtwidgets-widgets-digitalclock-example.webxml +qtwidgets-widgets-elidedlabel-example.webxml +qtwidgets-widgets-groupbox-example.webxml +qtwidgets-widgets-icons-example.webxml +qtwidgets-widgets-imageviewer-example.webxml +qtwidgets-widgets-lineedits-example.webxml +qtwidgets-widgets-mousebuttons-example.webxml +qtwidgets-widgets-movie-example.webxml +qtwidgets-widgets-scribble-example.webxml +qtwidgets-widgets-shapedclock-example.webxml +qtwidgets-widgets-sliders-example.webxml +qtwidgets-widgets-spinboxes-example.webxml +qtwidgets-widgets-styles-example.webxml +qtwidgets-widgets-stylesheet-example.webxml +qtwidgets-widgets-tablet-example.webxml +qtwidgets-widgets-tetrix-example.webxml +qtwidgets-widgets-tooltips-example.webxml +qtwidgets-widgets-wiggly-example.webxml +qtwidgets-widgets-windowflags-example.webxml +qtxml-dombookmarks-example.webxml +qtxml-saxbookmarks-example.webxml +qtxml-streambookmarks-example.webxml +qtxml-xmlstreamlint-example.webxml +qtxmlpatterns-filetree-example.webxml +qtxmlpatterns-recipes-example.webxml +qtxmlpatterns-schema-example.webxml +qtxmlpatterns-xquery-example.webxml +qwidget-styling.webxml +radiooverview.webxml +resources.webxml +richtext-advanced-processing.webxml +richtext-common-tasks.webxml +richtext-cursor.webxml +richtext-html-subset.webxml +richtext-layouts.webxml +richtext-structure.webxml +richtext.webxml +senorfwbackend.webxml +sensorgesture-emulator-topics.webxml +sensorgesture-plugins-topics.webxml +sensors-backend-topics.webxml +shared.webxml +signalsandslots.webxml +sql-connecting.webxml +sql-driver.webxml +sql-forms.webxml +sql-model.webxml +sql-presenting.webxml +sql-programming.webxml +sql-sqlstatements.webxml +sql-types.webxml +ssl.webxml +statemachine-api.webxml +statemachine.webxml +style-reference.webxml +stylesheet-customizing.webxml +stylesheet-designer.webxml +stylesheet-examples.webxml +stylesheet-reference.webxml +stylesheet-syntax.webxml +stylesheet.webxml +svgrendering.webxml +textedit-example.webxml +timers.webxml +tutorials-addressbook.webxml +videooverview.webxml +widget-classes.webxml +widgets-tutorial.webxml +xml-dom-tml.webxml +xml-namespaces.webxml +xml-processing.webxml +xml-sax.webxml +xml-streaming.webxml +xml-tools.webxml +xmlpattern-examples.webxml +xmlprocessing.webxml +xquery-introduction.webxml diff --git a/sources/pyside2/doc/api.rst b/sources/pyside2/doc/api.rst new file mode 100644 index 0000000..337d383 --- /dev/null +++ b/sources/pyside2/doc/api.rst @@ -0,0 +1,90 @@ +.. _pyside-api: + +|project| Modules +================= + +Basic modules +------------- + +These are the main modules that help you build a Widget-based UI. + ++---------------------------------------+--------------------------------------------------------+ +| :mod:`Qt Core ` | Provides core non-GUI functionality, like signal and | +| | slots, properties, base classes of item models, | +| | serialization, and more. | ++---------------------------------------+--------------------------------------------------------+ +| :mod:`Qt GUI ` | Extends QtCore with GUI functionality: Events, windows | +| | and screens, OpenGL and raster-based 2D painting, as | +| | well as images. | ++---------------------------------------+--------------------------------------------------------+ +| :mod:`Qt Widgets ` | Provides ready to use Widgets for your application, | +| | including graphical elements for your UI. | ++---------------------------------------+--------------------------------------------------------+ + +QML and Qt Quick +---------------- + +Use these modules to interact with the `QML Language `, +from Python. + ++-------------------------------------------------+----------------------------------------------+ +| :mod:`Qt QML ` | The base Python API to interact with the | +| | module. | ++-------------------------------------------------+----------------------------------------------+ +| :mod:`Qt Quick ` | Provides classes to embed Qt Quick in Qt | +| | applications. | ++-------------------------------------------------+----------------------------------------------+ +| :mod:`Qt QuickWidgets ` | Provides the QQuickWidget class to embed Qt | +| | Quick in widget-based applications. | ++-------------------------------------------------+----------------------------------------------+ + +Data visualization +------------------ + +Charts, diagrams, animations: these modules provide classes to help you include these elements in +your UI. + ++------------------------------------------------------------+-----------------------------------+ +| :mod:`Qt Charts ` | Provides a set of easy to use | +| | chart components. | ++------------------------------------------------------------+-----------------------------------+ +| :mod:`Qt DataVisualization ` | Provides a way to visualize data | +| | in 3D as bar, scatter, or surface | +| | graphs. | ++------------------------------------------------------------+-----------------------------------+ + +Multimedia +----------- + +Audio, video, and hardware interaction: use these modules for multimedia solutions. + ++------------------------------------------------------------+-----------------------------------+ +| :mod:`Qt Multimedia ` | Provides low-level multimedia | +| | functionality. | ++------------------------------------------------------------+-----------------------------------+ +| :mod:`Qt MultimediaWidgets ` | Provides the widget-based | +| | multimedia API. | ++------------------------------------------------------------+-----------------------------------+ + +WebEngine +--------- + +If your project is based on a browser or the features around Web-based applications, use these +modules to interact with them. + ++---------------------------------------------------------+--------------------------------------+ +| :mod:`Qt WebEngineWidgets ` | Provides widgets to handle Web | +| | content. | ++---------------------------------------------------------+--------------------------------------+ +| :mod:`Qt WebChannel ` | Enables peer-to-peer communication | +| | between a server and a client | +| | (HTML/JavaScript or QML application).| ++---------------------------------------------------------+--------------------------------------+ + +All the modules +--------------- + +There are many other modules currently supported by |pymodname|, here you can find a complete list +of them. + + :doc:`Check all the modules ` diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/accessibilityslidersnippet.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/accessibilityslidersnippet.cpp new file mode 100644 index 0000000..6c479cd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/accessibilityslidersnippet.cpp @@ -0,0 +1,271 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +//! [0] +QAccessibleSlider::QAccessibleSlider(QWidget *w) +: QAccessibleAbstractSlider(w) +{ + Q_ASSERT(slider()); + addControllingSignal(QLatin1String("valueChanged(int)")); +} +//! [0] + +QSlider *QAccessibleSlider::slider() const +{ + return qobject_cast(object()); +} + +//! [1] +QRect QAccessibleSlider::rect(int child) const +{ +//! [1] + QRect rect; + if (!slider()->isVisible()) + return rect; + const QStyleOptionSlider option = qt_qsliderStyleOption(slider()); + QRect srect = slider()->style()->subControlRect(QStyle::CC_Slider, &option, + QStyle::SC_SliderHandle, slider()); + +//! [2] + switch (child) { + case PageLeft: + if (slider()->orientation() == Qt::Vertical) + rect = QRect(0, 0, slider()->width(), srect.y()); + else + rect = QRect(0, 0, srect.x(), slider()->height()); + break; + case Position: + rect = srect; + break; + case PageRight: + if (slider()->orientation() == Qt::Vertical) + rect = QRect(0, srect.y() + srect.height(), slider()->width(), slider()->height()- srect.y() - srect.height()); + else + rect = QRect(srect.x() + srect.width(), 0, slider()->width() - srect.x() - srect.width(), slider()->height()); + break; + default: + return QAccessibleAbstractSlider::rect(child); + } +//! [2] //! [3] + + QPoint tp = slider()->mapToGlobal(QPoint(0,0)); + return QRect(tp.x() + rect.x(), tp.y() + rect.y(), rect.width(), rect.height()); +} +//! [3] + +int QAccessibleSlider::childCount() const +{ + if (!slider()->isVisible()) + return 0; + return PageRight; +} + +//! [4] +QString QAccessibleSlider::text(Text t, int child) const +{ + if (!slider()->isVisible()) + return QString(); + switch (t) { + case Value: + if (!child || child == 2) + return QString::number(slider()->value()); + return QString(); + case Name: + switch (child) { + case PageLeft: + return slider()->orientation() == Qt::Horizontal ? + QSlider::tr("Page left") : QSlider::tr("Page up"); + case Position: + return QSlider::tr("Position"); + case PageRight: + return slider()->orientation() == Qt::Horizontal ? + QSlider::tr("Page right") : QSlider::tr("Page down"); + } + break; + default: + break; + } + return QAccessibleAbstractSlider::text(t, child); +} +//! [4] + +//! [5] +QAccessible::Role QAccessibleSlider::role(int child) const +{ + switch (child) { + case PageLeft: + case PageRight: + return PushButton; + case Position: + return Indicator; + default: + return Slider; + } +} +//! [5] + +//! [6] +QAccessible::State QAccessibleSlider::state(int child) const +{ + const State parentState = QAccessibleAbstractSlider::state(0); +//! [6] + + if (child == 0) + return parentState; + + // Inherit the Invisible state from parent. + State state = parentState & QAccessible::Invisible; + + // Disable left/right if we are at the minimum/maximum. + const QSlider * const slider = QAccessibleSlider::slider(); +//! [7] + switch (child) { + case PageLeft: + if (slider->value() <= slider->minimum()) + state |= Unavailable; + break; + case PageRight: + if (slider->value() >= slider->maximum()) + state |= Unavailable; + break; + case Position: + default: + break; + } + + return state; +} +//! [7] + +int QAccessibleSlider::defaultAction(int child) const +{ + switch (child) { + case SliderSelf: + return SetFocus; + case PageLeft: + return Press; + case PageRight: + return Press; + } + + return 0; +} + +// Name, Description, Value, Help, Accelerator +static const char * const actionTexts[][5] = +{ + {"Press", "Decreases the value of the slider", "", "", "Ctrl+L"}, + {"Press", "Increaces the value of the slider", "", "", "Ctrl+R"} +}; + +QString QAccessibleSlider::actionText(int action, Text text, int child) const +{ + if (action != Press || child < 1 || child > 2) + return QAccessibleAbstractSlider::actionText(action, text, child); + + return actionTexts[child - 1][t]; +} + +bool QAccessibleSlider::doAction(int action, int child) +{ + if (action != Press || child < 1 || child > 2) + return false; + + if (child == PageLeft) + slider()->setValue(slider()->value() - slider()->pageStep()); + else + slider()->setValue(slider()->value() + slider()->pageStep()); +} + +QAccessibleAbstractSlider::QAccessibleAbstractSlider(QWidget *w, Role r) + : QAccessibleWidgetEx(w, r) +{ + Q_ASSERT(qobject_cast(w)); +} + +QVariant QAccessibleAbstractSlider::invokeMethodEx(Method method, int child, const QVariantList ¶ms) +{ + switch (method) { + case ListSupportedMethods: { + QSet set; + set << ListSupportedMethods; + return qVariantFromValue(set | qvariant_cast >( + QAccessibleWidgetEx::invokeMethodEx(method, child, params))); + } + default: + return QAccessibleWidgetEx::invokeMethodEx(method, child, params); + } +} + +QVariant QAccessibleAbstractSlider::currentValue() +{ + return abstractSlider()->value(); +} + +void QAccessibleAbstractSlider::setCurrentValue(const QVariant &value) +{ + abstractSlider()->setValue(value.toInt()); +} + +QVariant QAccessibleAbstractSlider::maximumValue() +{ + return abstractSlider()->maximum(); +} + +QVariant QAccessibleAbstractSlider::minimumValue() +{ + return abstractSlider()->minimum(); +} + +QAbstractSlider *QAccessibleAbstractSlider::abstractSlider() const +{ + return static_cast(object()); +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp new file mode 100644 index 0000000..78c2c54 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/alphachannel.cpp @@ -0,0 +1,64 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + pixmap = QPixmap(100, 100) + pixmap.fill(Qt.transparent) + + gradient = QRadialGradient(50, 50, 50, 50, 50) + gradient.setColorAt(0, QColor.fromRgbF(1, 0, 0, 1)) + gradient.setColorAt(1, QColor.fromRgbF(0, 0, 0, 0)) + painter = QPainter(pixmap) + painter.fillRect(0, 0, 100, 100, gradient) + + channelImage = pixmap.alphaChannel() + update() +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/audio/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/audio/main.cpp new file mode 100644 index 0000000..09d1aa4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/audio/main.cpp @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +class Window2 (QWidget): +//![0] + @Slot(QAudio.State) + def stateChanged(self, newState): + if newState == QAudio.StopState: + if self.input.error() != QAudio.NoError: + # Error handling +//![0] + +class Window (QWidget): + def __init__(self): + QWidget.__init__(self) + self.output = QAudioOutput() + self.output.stateChanged[QAudio.State].connect(self.stateChanged) + + def setupFormat(self): +//![1] + format = QAudioFormat() + format.setFrequency(44100) +//![1] + format.setChannels(2) + format.setSampleSize(16) + format.setCodec("audio/pcm") + format.setByteOrder(QAudioFormat.LittleEndian) +//![2] + format.setSampleType(QAudioFormat.SignedInt) + + info = QAudioDeviceInfo(QAudioDeviceInfo.defaultOutputDevice()) + + if not info.isFormatSupported(format): + format = info.nearestFormat(format) +//![2] + +//![3] + @Slot(QAudio.State) + def stateChanged(self, newState): + if newState == QAudio.StopState: + if self.output.error() != QAudio.NoError: + # Perform error handling + else: + # Normal stop +//![3] + + # Handle + elif newState == QAudio.ActiveState: + # Handle active state... + +app = QApplication(sys.argv) + +window = Window() +window.show() +sys.exit(app.exec_()) + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/qt-logo.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/qt-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..d609c1e1e5b46d571cc46378cf7ae74b250aa82b GIT binary patch literal 15518 zcmeI3eNDl)3V!MHsK5a=b`HaB8$q1Ch=XAJuqt7h$ z`x-$kHj`3`Um_HnrHSHzk{nxxB$@Lt60KY(vn$mq$#R2SsWqtdnx9Kl3Z;%zXh@|& zrc@ijTceN!Us6i~h)f>3z?f-W85|D$XOKoX)73ypYL+XBKrpKD*4#keLk6m3Zt7kS~sQ3A~U}3Z@i9Gz+7YQpP1j zwW94IA9snz;Rj9INyfoAK?)BjD5K8BUBn3-U&O@#80wCRQD6&Vun>DJyt3kC=Gi3{< z&a`DbY$-#p^l(o9K6g_do)Nc?Svs|ULI*>z82lU1$j+Q<@Oo6SuV+ST_rK#RE2r z*)Y9zs>8v~a$!Qt1CBK#WfzZb3r~T?HIe?KZmKPOQGpC`pnxFCn$E6#XQam-!&}6- zBDXudRRdOjRcsTUD-gVthe<31J7Tt{QNVe6YV0BGMU<XB$4Lnm)=3pIq}x?!BEya0F-@W01Y5J8qQqfVg-vT zI9fzAlqLRT1z==>+cd_a(`waP6B*eYnUTTz7)Oqk1&1mxZWT2c$)6M15jAmLtVF0I zm>4Jp=!VK)DS=jSy9VwQ$K*kss5)mxGxL_K{7~?`Bf&~~COamEX zTu4N)0ONvbAY+URi3k>8Trdq}jBz0m!2*m6rh$wxE+isYfN{YzkTJ%EL<9>kE|>-~ z#<-A(U;)Mj(?G@;7ZMRHz_?%<$Qa{7B7y}N7fb^gV_Zl?umIzNX&_^a3yBC8U|cW_ zWQ=hk5y1kC3#NgLF)kz`Sb%ZCG>|dIg+v4kFfNz|GJYVggz&?cj0-$*=>?Bgem~!O z4m_4Av8QI*2%>xmK~%g*5dWP7-#r9Tq9BMHc?4m6ogjX|?R@^sN`i>fW;~mn0&*rN zClebp;dfGFR`RFW)=$@@i0@xN)ASo#Q*L_G`t*zIe|3>s^EsXSW%2rEM_#kb-m-yi z@h~lXQEN$2YbkrlyW#St(yum`w{3l)?T;1zuH15U`_`*FwzcnixqWwK`=4LA_LrSs z@7>k0Z+FN3*E-+c(^<8rtLlxe1N*uTzS;fWTiw-fcOQPI`|!d49DVotvFhu`4_!Zg zq^IU+PtCC#e>-vWWX;XL*W9cH0foPTg(z@a`uc-#vS}_v|OV z7yjAXc($+cd|y*z|L33ef6+AX$-hla+7hwqP!+`l(EF*-IeHa0OnJ~2KqIRS8; z>K|SWz|9jf)3XR-iLCSH=>-)!fb=J6*2HZ6`Nmyq*M79(i7ji-Em`*1kCv^vRrgd* zM)s|_k8Rv8JvTo2W}fc+i_4F6Hg^2uLfZxJPV*bN7uy&2#aC42y}s$S=T~nsZ(DJH zzqNYdJG)*wQ(3p8Vc}ah_HB2UEaJD$InqMRec`~)mU+hy#m_%gJ*eGXwY6-^pIDtb z@6m%#_AIJsK5EfjsF3Y_zxS0xC-48^g!6l<_HWlNGf9r-CjWTd0vG*WT>4+DK3bId zoa80-g8j<(=f2we#EvWT1|Pq@xMS{UMO@Fr)iv{(9RuHLkgcjrE3Vt@9QhsB)3yGC zW;6NQjmMtb`_qY@0~;RAaEzYJ@ughJUDY~%&RQGq*3SEGU;U!5S9H!FY4|Mu8WF!# rX+L3EYOU*da^tnu%HO+}*T? + +class RenderArea : public QWidget +{ + Q_OBJECT + +public: + RenderArea(QBrush *brush, QWidget *parent = 0); + QSize minimumSizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); + +private: + QBrush *currentBrush; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/stylewidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/stylewidget.h new file mode 100644 index 0000000..57223cb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/brushstyles/stylewidget.h @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STYLEWIDGET_H +#define STYLEWIDGET_H + +#include +#include +#include "renderarea.h" + +class QLabel; + +class StyleWidget : public QWidget +{ + Q_OBJECT + +public: + StyleWidget(QWidget *parent = 0); + +private: + RenderArea *solid; + RenderArea *dense1; + RenderArea *dense2; + RenderArea *dense3; + RenderArea *dense4; + RenderArea *dense5; + RenderArea *dense6; + RenderArea *dense7; + RenderArea *no; + RenderArea *hor; + RenderArea *ver; + RenderArea *cross; + RenderArea *bdiag; + RenderArea *fdiag; + RenderArea *diagCross; + RenderArea *linear; + RenderArea *radial; + RenderArea *conical; + RenderArea *texture; + + QLabel *solidLabel; + QLabel *dense1Label; + QLabel *dense2Label; + QLabel *dense3Label; + QLabel *dense4Label; + QLabel *dense5Label; + QLabel *dense6Label; + QLabel *dense7Label; + QLabel *noLabel; + QLabel *horLabel; + QLabel *verLabel; + QLabel *crossLabel; + QLabel *bdiagLabel; + QLabel *fdiagLabel; + QLabel *diagCrossLabel; + QLabel *linearLabel; + QLabel *radialLabel; + QLabel *conicalLabel; + QLabel *textureLabel; +}; +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.h new file mode 100644 index 0000000..a06b59b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLIPWINDOW_H +#define CLIPWINDOW_H + +#include + +class QClipboard; +class QComboBox; +class QLabel; +class QListWidget; +class QMimeData; +class QWidget; + +class ClipWindow : public QMainWindow +{ + Q_OBJECT + +public: + ClipWindow(QWidget *parent = 0); + +public slots: + void updateClipboard(); + void updateData(const QString &format); + +private: + int currentItem; + QClipboard *clipboard; + QComboBox *mimeTypeCombo; + QLabel *dataInfoLabel; + QListWidget *previousItems; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py new file mode 100644 index 0000000..1cbd562 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/clipboard/clipwindow.py @@ -0,0 +1,105 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +form PySide2.QtGui import * + + +def __init__(self, parent): + QMainWindow.__init__(self, parent) + clipboard = QApplication.clipboard() + + centralWidget = QWidget(self) + currentItem = QWidget(centralWidget) + mimeTypeLabel = QLabel(tr("MIME types:"), currentItem) + mimeTypeCombo = QComboBox(currentItem) + dataLabel = QLabel(tr("Data:"), currentItem) + dataInfoLabel = QLabel("", currentItem) + + previousItems = QListWidget(centralWidget) + +//! [0] + clipboard.dataChanged.connect(self.updateClipboard) +//! [0] + mimeTypeCombo.activated[str].connect(self.updateData) + + currentLayout = QVBoxLayout(currentItem) + currentLayout.addWidget(mimeTypeLabel) + currentLayout.addWidget(mimeTypeCombo) + currentLayout.addWidget(dataLabel) + currentLayout.addWidget(dataInfoLabel) + currentLayout.addStretch(1) + + mainLayout = QHBoxLayout(centralWidget) + mainLayout.addWidget(currentItem, 1) + mainLayout.addWidget(previousItems) + + setCentralWidget(centralWidget) + setWindowTitle(tr("Clipboard")) + +//! [1] +def updateClipboard(self): + formats = clipboard.mimeData().formats() + data = clipboard.mimeData().data(format) +//! [1] + + mimeTypeCombo.clear() + mimeTypeCombo.insertStringList(formats) + + size = clipboard.mimeData().data(formats[0]).size() + Item = QListWidgetItem(previousItems) + Item.setText(tr("%1 (%2 bytes)").arg(formats[0]).arg(size)) + + updateData(formats[0]) +//! [2] +//! [2] + +def updateData(self, format) + data = clipboard.mimeData().data(format) + dataInfoLabel.setText(tr("%1 bytes").arg(data.size())) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qnamespace.qdoc b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qnamespace.qdoc new file mode 100644 index 0000000..b63810f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qnamespace.qdoc @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QObject::connect: Cannot queue arguments of type 'MyType' +//! [0] + + +//! [1] +# An important event +ImportantEventPriority = Qt.HighEventPriority +# A more important event +MoreImportantEventPriority = ImportantEventPriority + 1 +# A critical event +CriticalEventPriority = 100 * MoreImportantEventPriority +# Not that important +StatusEventPriority = Qt.LowEventPriority +# These are less important than Status events +IdleProcessingDoneEventPriority = StatusEventPriority - 1 +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py new file mode 100644 index 0000000..4696bd3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtcore.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtCore +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py new file mode 100644 index 0000000..84e7e91 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtnetwork.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import PySide2.QtNetwork +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py new file mode 100644 index 0000000..63c5665 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtopengl.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtOpenGL +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py new file mode 100644 index 0000000..fb55416 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtprintsupport.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 20188888888 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import PySide2.QtPrintSupport +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py new file mode 100644 index 0000000..3eeb024 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtqml.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtQml +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py new file mode 100644 index 0000000..bf55f0c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtquick.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtQuick +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py new file mode 100644 index 0000000..31849e7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtsql.py @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//! [0] +import PySide2.QtSql +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py new file mode 100644 index 0000000..34dd7bb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qttest.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtTest +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py new file mode 100644 index 0000000..a0deee9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtwidgets.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import PySide2.QtWidgets +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py new file mode 100644 index 0000000..077be43 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/doc_src_qtxml.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtXml +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.gui.text.qtextdocumentwriter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.gui.text.qtextdocumentwriter.cpp new file mode 100644 index 0000000..bfe7b30 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.gui.text.qtextdocumentwriter.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + writer = QTextDocumentWriter() + writer.setFormat("odf") # same as writer.setFormat("ODF"); +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingcall.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingcall.cpp new file mode 100644 index 0000000..549d7a6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingcall.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +{ +//! [0] + QDBusPendingCall async = iface->asyncCall("RemoteMethod", value1, value2); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(async, this); + + QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), + this, SLOT(callFinishedSlot(QDBusPendingCallWatcher*))); +//! [0] + +} + +//! [1] +void MyClass::callFinishedSlot(QDBusPendingCallWatcher *call) +{ + QDBusPendingReply reply = *call; + if (reply.isError()) { + showError(); + } else { + QString text = reply.argumentAt<0>(); + QByteArray data = reply.argumentAt<1>(); + showReply(text, data); + } +} +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp new file mode 100644 index 0000000..5029d3a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.qdbus.qdbuspendingreply.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +{ +//! [0] + QDBusPendingReply reply = interface->asyncCall("RemoteMethod"); + reply.waitForFinished(); + if (reply.isError()) + // call failed. Show an error condition. + showError(reply.error()); + else + // use the returned value + useValue(reply.value()); +//! [0] + +//! [2] + QDBusPendingReply reply = interface->asyncCall("RemoteMethod"); + reply.waitForFinished(); + if (!reply.isError()) { + if (reply.argumentAt<0>()) + showSuccess(reply.argumentAt<1>()); + else + showFailure(reply.argumentAt<1>()); + } +//! [2] +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp new file mode 100644 index 0000000..53c4a9e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src.scripttools.qscriptenginedebugger.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + engine = QScriptEngine() + debugger = QScriptEngineDebugger() + debugger.attachTo(engine) +//! [0] + +//! [1] + engine.evaluate("debugger") +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp new file mode 100644 index 0000000..7cbfc4e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodec.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +encodedString = QByteArray("...") +codec = QTextCodec.codecForName("KOI8-R") +string = codec.toUnicode(encodedString) +//! [0] + + +//! [1] +string = u"..." +codec = QTextCodec.codecForName("KOI8-R") +encodedString = codec.fromUnicode(string) +//! [1] + + +//! [2] +codec = QTextCodec.codecForName("Shift-JIS") +decoder = codec.makeDecoder() + +string = u'' +while new_data_available(): + chunk = get_new_data() + string += decoder.toUnicode(chunk) + +//! [2] + + +//! [3] +def main(): + app = QApplication([]) + QTextCodec.setCodecForTr(QTextCodec.codecForName("eucKR")) + ... +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodecplugin.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodecplugin.cpp new file mode 100644 index 0000000..3538b65 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_codecs_qtextcodecplugin.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +def names(self): + return list = ["IBM01140", "hp15-tw"] + +def createForName(name): + if (name == "IBM01140"): + return Ibm01140Codec() + else if (name == "hp15-tw"): + return Hp15TwCodec() + return None +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuture.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuture.cpp new file mode 100644 index 0000000..7dcc705 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuture.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QFuture future = ...; + +QFuture::const_iterator i; +for (i = future.constBegin(); i != future.constEnd(); ++i) + cout << *i << endl; +//! [0] + + +//! [1] +QFuture future; +... +QFutureIterator i(future); +while (i.hasNext()) + qDebug() << i.next(); +//! [1] + + +//! [2] +QFutureIterator i(future); +i.toBack(); +while (i.hasPrevious()) + qDebug() << i.previous(); +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturesynchronizer.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturesynchronizer.cpp new file mode 100644 index 0000000..014c5b1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturesynchronizer.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +void someFunction() +{ + QFutureSynchronizer synchronizer; + + ... + + synchronizer.addFuture(QtConcurrent::run(anotherFunction)); + synchronizer.addFuture(QtConcurrent::map(list, mapFunction)); + + return; // QFutureSynchronizer waits for all futures to finish +} +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturewatcher.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturewatcher.cpp new file mode 100644 index 0000000..9c536b8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qfuturewatcher.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +// Instantiate the objects and connect to the finished signal. +MyClass myObject; +QFutureWatcher watcher; +connect(&watcher, SIGNAL(finished()), &myObject, SLOT(handleFinished())); + +// Start the computation. +QFuture future = QtConcurrent::run(...); +watcher.setFuture(future); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp new file mode 100644 index 0000000..da4254a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentexception.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +class MyException : public QtConcurrent::Exception +{ +public: + void raise() const { throw *this; } + Exception *clone() const { return new MyException(*this); } +}; + +//! [0] + + +//! [1] + +try { + QtConcurrent::blockingMap(list, throwFunction); // throwFunction throws MyException +} catch (MyException &e) { + // handle exception +} + +//! [1] + + +//! [2] + +void MyException::raise() const { throw *this; } + +//! [2] + + +//! [3] + +MyException *MyException::clone() const { return new MyException(*this); } + +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentfilter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentfilter.cpp new file mode 100644 index 0000000..a0f6778 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentfilter.cpp @@ -0,0 +1,181 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +bool function(const T &t); +//! [0] + + +//! [1] +bool allLowerCase(const QString &string) +{ + return string.lowered() == string; +} + +QStringList strings = ...; +QFuture lowerCaseStrings = QtConcurrent::filtered(strings, allLowerCase); +//! [1] + + +//! [2] +QStringList strings = ...; +QFuture future = QtConcurrent::filter(strings, allLowerCase); +//! [2] + + +//! [3] +V function(T &result, const U &intermediate) +//! [3] + + +//! [4] +void addToDictionary(QSet &dictionary, const QString &string) +{ + dictionary.insert(string); +} + +QStringList strings = ...; +QFuture > dictionary = QtConcurrent::filteredReduced(strings, allLowerCase, addToDictionary); +//! [4] + + +//! [5] +QStringList strings = ...; +QFuture lowerCaseStrings = QtConcurrent::filtered(strings.constBegin(), strings.constEnd(), allLowerCase); + +// filter in-place only works on non-const iterators +QFuture future = QtConcurrent::filter(strings.begin(), strings.end(), allLowerCase); + +QFuture > dictionary = QtConcurrent::filteredReduced(strings.constBegin(), strings.constEnd(), allLowerCase, addToDictionary); +//! [5] + + +//! [6] +QStringList strings = ...; + +// each call blocks until the entire operation is finished +QStringList lowerCaseStrings = QtConcurrent::blockingFiltered(strings, allLowerCase); + + +QtConcurrent::blockingFilter(strings, allLowerCase); + +QSet dictionary = QtConcurrent::blockingFilteredReduced(strings, allLowerCase, addToDictionary); +//! [6] + + +//! [7] +// keep only images with an alpha channel +QList images = ...; +QFuture alphaImages = QtConcurrent::filter(strings, &QImage::hasAlphaChannel); + +// keep only gray scale images +QList images = ...; +QFuture grayscaleImages = QtConcurrent::filtered(images, &QImage::isGrayscale); + +// create a set of all printable characters +QList characters = ...; +QFuture > set = QtConcurrent::filteredReduced(characters, &QChar::isPrint, &QSet::insert); +//! [7] + + +//! [8] +// can mix normal functions and member functions with QtConcurrent::filteredReduced() + +// create a dictionary of all lower cased strings +extern bool allLowerCase(const QString &string); +QStringList strings = ...; +QFuture > averageWordLength = QtConcurrent::filteredReduced(strings, allLowerCase, QSet::insert); + +// create a collage of all gray scale images +extern void addToCollage(QImage &collage, const QImage &grayscaleImage); +QList images = ...; +QFuture collage = QtConcurrent::filteredReduced(images, &QImage::isGrayscale, addToCollage); +//! [8] + + +//! [9] +bool QString::contains(const QRegExp ®exp) const; +//! [9] + + +//! [10] +boost::bind(&QString::contains, QRegExp("^\\S+$")); // matches strings without whitespace +//! [10] + + +//! [11] +bool contains(const QString &string) +//! [11] + + +//! [12] +QStringList strings = ...; +boost::bind(static_cast( &QString::contains ), QRegExp("..." )); +//! [12] + +//! [13] +struct StartsWith +{ + StartsWith(const QString &string) + : m_string(string) { } + + typedef bool result_type; + + bool operator()(const QString &testString) + { + return testString.startsWith(m_string); + } + + QString m_string; +}; + +QList strings = ...; +QFuture fooString = QtConcurrent::filtered(images, StartsWith(QLatin1String("Foo"))); +//! [13] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp new file mode 100644 index 0000000..e61b736 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentmap.cpp @@ -0,0 +1,194 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +U function(const T &t); +//! [0] + + +//! [1] +QImage scaled(const QImage &image) +{ + return image.scaled(100, 100); +} + +QList images = ...; +QFuture thumbnails = QtConcurrent::mapped(images, scaled); +//! [1] + + +//! [2] +U function(T &t); +//! [2] + + +//! [3] +void scale(QImage &image) +{ + image = image.scaled(100, 100); +} + +QList images = ...; +QFuture future = QtConcurrent::map(images, scale); +//! [3] + + +//! [4] +V function(T &result, const U &intermediate) +//! [4] + + +//! [5] +void addToCollage(QImage &collage, const QImage &thumbnail) +{ + QPainter p(&collage); + static QPoint offset = QPoint(0, 0); + p.drawImage(offset, thumbnail); + offset += ...; +} + +QList images = ...; +QFuture collage = QtConcurrent::mappedReduced(images, scaled, addToCollage); +//! [5] + + +//! [6] +QList images = ...; + +QFuture thumbnails = QtConcurrent::mapped(images.constBegin(), images.constEnd(), scaled); + +// map in-place only works on non-const iterators +QFuture future = QtConcurrent::map(images.begin(), images.end(), scale); + +QFuture collage = QtConcurrent::mappedReduced(images.constBegin(), images.constEnd(), scaled, addToCollage); +//! [6] + + +//! [7] +QList images = ...; + +// each call blocks until the entire operation is finished +QList future = QtConcurrent::blockingMapped(images, scaled); + +QtConcurrent::blockingMap(images, scale); + +QImage collage = QtConcurrent::blockingMappedReduced(images, scaled, addToCollage); +//! [7] + + +//! [8] +// squeeze all strings in a QStringList +QStringList strings = ...; +QFuture squeezedStrings = QtConcurrent::map(strings, &QString::squeeze); + +// swap the rgb values of all pixels on a list of images +QList images = ...; +QFuture bgrImages = QtConcurrent::mapped(images, &QImage::rgbSwapped); + +// create a set of the lengths of all strings in a list +QStringList strings = ...; +QFuture > wordLengths = QtConcurrent::mappedReduced(string, &QString::length, &QSet::insert); +//! [8] + + +//! [9] +// can mix normal functions and member functions with QtConcurrent::mappedReduced() + +// compute the average length of a list of strings +extern void computeAverage(int &average, int length); +QStringList strings = ...; +QFuture averageWordLength = QtConcurrent::mappedReduced(strings, &QString::length, computeAverage); + +// create a set of the color distribution of all images in a list +extern int colorDistribution(const QImage &string); +QList images = ...; +QFuture > totalColorDistribution = QtConcurrent::mappedReduced(images, colorDistribution, QSet::insert); +//! [9] + + +//! [10] +QImage QImage::scaledToWidth(int width, Qt::TransformationMode) const; +//! [10] + + +//! [11] +boost::bind(&QImage::scaledToWidth, 100, Qt::SmoothTransformation) +//! [11] + + +//! [12] +QImage scaledToWith(const QImage &image) +//! [12] + + +//! [13] +QList images = ...; +QFuture thumbnails = QtConcurrent::mapped(images, boost::bind(&QImage::scaledToWidth, 100 Qt::SmoothTransformation)); +//! [13] + +//! [14] +struct Scaled +{ + Scaled(int size) + : m_size(size) { } + + typedef QImage result_type; + + QImage operator()(const QImage &image) + { + return image.scaled(m_size, m_size); + } + + int m_size; +}; + +QList images = ...; +QFuture thumbnails = QtConcurrent::mapped(images, Scaled(100)); +//! [14] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentrun.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentrun.cpp new file mode 100644 index 0000000..3c55ef7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qtconcurrentrun.cpp @@ -0,0 +1,110 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +extern void aFunction(); +QFuture future = QtConcurrent::run(aFunction); +//! [0] + + +//! [1] +extern void aFunctionWithArguments(int arg1, double arg2, const QString &string); + +int integer = ...; +double floatingPoint = ...; +QString string = ...; + +QFuture future = QtConcurrent::run(aFunctionWithArguments, integer, floatingPoint, string); +//! [1] + + +//! [2] +extern QString functionReturningAString(); +QFuture future = QtConcurrent::run(functionReturningAString); +... +QString result = future.result(); +//! [2] + + +//! [3] +extern QString someFunction(const QByteArray &input); + +QByteArray bytearray = ...; + +QFuture future = QtConcurrent::run(someFunction, bytearray); +... +QString result = future.result(); +//! [3] + + +//! [4] +// call 'QStringList QString::split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const' in a separate thread +QString string = ...; +QFuture future = QtConcurrent::run(string, &QString::split, QString(", "), QString::KeepEmptyParts, Qt::CaseSensitive); +... +QStringList result = future.result(); +//! [4] + + +//! [5] +// call 'void QImage::invertPixels(InvertMode mode)' in a separate thread +QImage image = ...; +QFuture future = QtConcurrent::run(image, &QImage::invertPixels, QImage::InvertRgba); +... +future.waitForFinished(); +// At this point, the pixels in 'image' have been inverted +//! [5] + + +//! [6] +void someFunction(int arg1, double arg2); +QFuture future = QtConcurrent::run(boost::bind(someFunction, 1, 2.0)); +... +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qthreadpool.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qthreadpool.cpp new file mode 100644 index 0000000..f552f34 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_concurrent_qthreadpool.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class HelloWorldTask(QRunnable): + def run(self): + print "Hello world from thread", QThread.currentThread() + +hello = HelloWorldTask() +# QThreadPool takes ownership and deletes 'hello' automatically +QThreadPool.globalInstance().start(hello) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp new file mode 100644 index 0000000..878259f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qabstractfileengine.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class ZipEngineHandler(QAbstractFileEngineHandler): + def create(self, fileName): + # ZipEngineHandler returns a ZipEngine for all .zip files + if fileName.toLower().endsWith(".zip"): + return ZipEngine(fileName) + else + return None + +def main(): + app = QApplication(sys.argv) + + engine = ZipEngineHandler() + + window = MainWindow() + window.show() + + return app.exec() +//! [0] + + +//! [1] +def create(fileName): + # ZipEngineHandler returns a ZipEngine for all .zip files + if fileName.lower().endswith(".zip"): + return ZipEngine(fileName) + else + return None +//! [1] + + +//! [2] +# @arg filters QDir.Filters +# @arg filterNames [str, ...] +# @return QAbstractFileEngineIterator +def beginEntryList(filters, filterNames): + return CustomFileEngineIterator(filters, filterNames) +//! [2] + + +//! [3] +class CustomIterator(QAbstractFileEngineIterator): + def __init__(self, nameFilters, filters): + QAbstractFileEngineIterator.__init__(self, nameFilters, filters) + + self.index = 0 + # In a real iterator, these entries are fetched from the + # file system based on the value of path(). + self.entries << "entry1" << "entry2" << "entry3" + + def hasNext(self): + return self.index < self.entries.size() - 1 + + def next(self): + if not self.hasNext(): + return None + index += 1 + return currentFilePath() + + def currentFileName(self): + return self.entries.at(index) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdatastream.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdatastream.cpp new file mode 100644 index 0000000..79e64d4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdatastream.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +void wrapInFunction() +{ + +//! [0] +file_ = QFile("file.dat") +file_.open(QIODevice.WriteOnly) +# we will serialize the data into the file +out = QDataStream(file_) +# serialize a string +out.writeQString("the answer is") +# serialize an integer +out.writeInt32(42) +//! [0] + + +//! [1] +file_ = QFile("file.dat") +file_.open(QIODevice.ReadOnly) +# read the data serialized from the file +i = QDataStream(file_) +string = '' +a = 0 +# extract "the answer is" and 42 +string = i.readQString() +a = i.readInt32() +//! [1] + + +//! [2] +stream.setVersion(QDataStream.Qt_4_0) +//! [2] + + +//! [3] +file_ = QFile("file.xxx") +file_.open(QIODevice.WriteOnly) +out = QDataStream(file_) + +# Write a header with a "magic number" and a version +out.writeInt32(0xA0B0C0D0) +out.writeInt32(123) + +out.setVersion(QDataStream.Qt_4_0) + +// Write the data +out << lots_of_interesting_data +//! [3] + + +//! [4] +file_ = QFile("file.xxx") +file_.open(QIODevice.ReadOnly) +i = QDataStream(file_) + +// Read and check the header +magic = i.readInt32() +if magic != 0xA0B0C0D0: + return XXX_BAD_FILE_FORMAT + +// Read the version +version = i.readInt32() +if version < 100: + return XXX_BAD_FILE_TOO_OLD +if version > 123: + return XXX_BAD_FILE_TOO_NEW + +if version <= 110: + in_.setVersion(QDataStream.Qt_3_2) +else: + in_.setVersion(QDataStream.Qt_4_0) + +// Read the data +in_ >> lots_of_interesting_data +if version >= 120: + in_ >> data_new_in_XXX_version_1_2 +in_ >> other_interesting_data +//! [4] + + +//! [5] +out = QDataStream(file_) +out.setVersion(QDataStream.Qt_4_0) +//! [5] + +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdir.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdir.cpp new file mode 100644 index 0000000..16f20c2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdir.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +void wrapInFunction() +{ + +//! [0] +QDir("/home/user/Documents") +QDir("C:/Documents and Settings") +//! [0] + + +//! [1] +QDir("images/landscape.png") +//! [1] + + +//! [2] +QDir("Documents/Letters/Applications").dirName() # "Applications" +QDir().dirName() # "." +//! [2] + + +//! [3] +directory = QDir("Documents/Letters") +path = directory.filePath("contents.txt") +absolutePath = directory.absoluteFilePath("contents.txt") +//! [3] + + +//! [4] +dir = QDir("example") +if not dir.exists(): + print "Cannot find the example directory" +//! [4] + + +//! [5] +dir = QDir.root() # "/" +if not dir.cd("tmp"): # "/tmp" + print "Cannot find the \"/tmp\" directory" +else: + file = QFile(dir.filePath("ex1.txt")) # "/tmp/ex1.txt" + if !file.open(QIODevice.ReadWrite): + print "Cannot create the file %s" % (file.name()) +//! [5] + + +//! [6] +bin = "/local/bin" # where /local/bin is a symlink to /usr/bin +binDir = QDir(bin) +canonicalBin = binDir.canonicalPath() +# canonicalBin now equals "/usr/bin" + +ls = "/local/bin/ls" # where ls is the executable "ls" +lsDir = QDir(ls) +canonicalLs = lsDir.canonicalPath() +# canonicalLS now equals "/usr/bin/ls". +//! [6] + + +//! [7] +dir = QDir("/home/bob") + +s = dir.relativeFilePath("images/file.jpg") # s is "images/file.jpg" +s = dir.relativeFilePath("/home/mary/file.txt") # s is "../mary/file.txt" +//! [7] + + +//! [8] +QDir.setSearchPaths("icons", [QDir.homePath() + "/images"]) +QDir.setSearchPaths("docs", [":/embeddedDocuments"]) +... +pixmap = QPixmap("icons:undo.png") # will look for undo.png in QDir::homePath() + "/images" +file = QFile("docs:design.odf") # will look in the :/embeddedDocuments resource path +//! [8] + + +//! [9] +dir = QDir("/tmp/root_link") +dir = dir.canonicalPath() +if dir.isRoot(): + print "It is a root link" +//! [9] + + +//! [10] +# The current directory is "/usr/local" +d1 = QDir("/usr/local/bin") +d2 = QDir("bin") +if d1 == d2: + print "They're the same" +//! [10] + + +//! [11] +// The current directory is "/usr/local" +d1 = QDir("/usr/local/bin") +d1.setFilter(QDir.Executable) +d2 = QDir("bin") +if d1 != d2: + print "They differ" +//! [11] + + +//! [12] +C:/Documents and Settings/Username +//! [12] + + +//! [13] +Q_INIT_RESOURCE(myapp); +//! [13] + + +//! [14] +def initMyResource(): + Q_INIT_RESOURCE(myapp) + +class MyNamespace + ... + + def myFunction(self): + initMyResource() +//! [14] + + +//! [15] +Q_CLEANUP_RESOURCE(myapp); +//! [15] + +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdiriterator.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdiriterator.cpp new file mode 100644 index 0000000..be68a5d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qdiriterator.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +it = QDirIterator("/etc", QDirIterator.Subdirectories) +while it.hasNext(): + print it.next() + + # /etc/. + # /etc/.. + # /etc/X11 + # /etc/X11/fs + # ... + +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfile.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfile.cpp new file mode 100644 index 0000000..1e9d102 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfile.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +file = QFile() +QDir.setCurrent("/tmp") +file.setFileName("readme.txt") +QDir.setCurrent("/home") +file.open(QIODevice.ReadOnly) # opens "/home/readme.txt" under Unix +//! [0] + + +//! [1] +def myEncoderFunc(fileName): +//! [1] + + +//! [2] +def myDecoderFunc(localFileName): +//! [2] + + +//! [3] + +def printError(msg): + file = QFile() + file.open(sys.stderr.fileno(), QIODevice.WriteOnly) + file.write(msg, size(msg)) # write to stderr + file.close() +//! [3] + + +//! [4] +CONFIG += console +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp new file mode 100644 index 0000000..1027525 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qfileinfo.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![newstuff] + fi = QFileInfo("c:/temp/foo") => fi.absoluteFilePath() => "C:/temp/foo" +//![newstuff] + +//! [0] +info1 = QFileInfo("/home/bob/bin/untabify") +info1.isSymLink() # returns true +info1.absoluteFilePath() # returns "/home/bob/bin/untabify" +info1.size() # returns 56201 +info1.symLinkTarget() # returns "/opt/pretty++/bin/untabify" + +info2 = QFileInfo(info1.symLinkTarget()) +info1.isSymLink() # returns False +info1.absoluteFilePath() # returns "/opt/pretty++/bin/untabify" +info1.size() # returns 56201 + +//! [0] + + +//! [1] +info1 = QFileInfo("C:\\Documents and Settings\\Bob\\untabify.lnk") +info1.isSymLink() # returns True +info1.absoluteFilePath() # returns "C:/Documents and Settings/Bob/untabify.lnk" +info1.size() # returns 743 +info1.symLinkTarget() # returns "C:/Pretty++/untabify" + +info2 = QFileInfo(info1.symLinkTarget()) +info1.isSymLink() # returns False +info1.absoluteFilePath() # returns "C:/Pretty++/untabify" +info1.size() # returns 63942 +//! [1] + + +//! [2] +absolute = "/local/bin" +relative = "local/bin" +absFile = QFileInfo(absolute) +relFile = QFileInfo(relative) + +QDir.setCurrent(QDir.rootPath()) +# absFile and relFile now point to the same file + +QDir.setCurrent("/tmp") +# absFile now points to "/local/bin", +# while relFile points to "/tmp/local/bin" +//! [2] + + +//! [3] +fi = QFileInfo("/tmp/archive.tar.gz") +name = fi.fileName() # name = "archive.tar.gz" +//! [3] + + +//! [4] +fi = QFileInfo("/Applications/Safari.app") +bundle = fi.bundleName() # name = "Safari" +//! [4] + + +//! [5] +fi = QFileInfo("/tmp/archive.tar.gz") +base = fi.baseName() # base = "archive" +//! [5] + + +//! [6] +fi = QFileInfo("/tmp/archive.tar.gz") +base = fi.completeBaseName() # base = "archive.tar" +//! [6] + + +//! [7] +fi = QFileInfo("/tmp/archive.tar.gz") +ext = fi.completeSuffix() # ext = "tar.gz" +//! [7] + + +//! [8] +fi = QFileInfo("/tmp/archive.tar.gz") +ext = fi.suffix(); # ext = "gz" +//! [8] + + +//! [9] +info = QFileInfo(fileName) +if info.isSymLink(): + fileName = info.symLinkTarget() +//! [9] + + +//! [10] +fi = QFileInfo("/tmp/archive.tar.gz") +if fi.permission(QFile.WriteUser | QFile.ReadGroup): + print "I can change the file; my group can read the file" +if fi.permission(QFile.WriteGroup | QFile.WriteOther): + print "The group or others can change the file" +//! [10] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qiodevice.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qiodevice.cpp new file mode 100644 index 0000000..d8f155c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qiodevice.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +gzip = QProcess() +gzip.start("gzip", ["-c"]) +if not gzip.waitForStarted(): + return False + +gzip.write("uncompressed data") + +compressed = QByteArray() +while gzip.waitForReadyRead(): + compressed += gzip.readAll() +//! [0] + + +//! [1] +def bytesAvailable(self): + return buffer.size() + QIODevice.bytesAvailable() +//! [1] + + +//! [2] +file = QFile("box.txt") +if file.open(QFile.ReadOnly): + buf = file.readLine(1024) + if buf.size(): + # the line is available in buf +//! [2] + + +//! [3] +def canReadLine(self): + return buffer.contains('\n') or QIODevice.canReadLine() +//! [3] + + +//! [4] +def isExeFile(file_): + buf = file_.peek(2) + if buf.size() == 2: + return buf[0] == 'M' and buf[1] == 'Z' + return False +//! [4] + + +//! [5] +def isExeFile(file_): + return file_.peek(2) == "MZ" +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qprocess.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qprocess.cpp new file mode 100644 index 0000000..a4b74ae --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qprocess.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +def wrapInFunction(): + +//! [0] +builder = QProcess() +builder.setProcessChannelMode(QProcess.MergedChannels) +builder.start("make", ["-j2"]) + +import sys +if not builder.waitForFinished(): + sys.stderr.write("Make failed:" + builder.errorString()) +else + sys.stderr.write("Make output:" + builder.readAll()) +//! [0] + + +//! [1] +more = QProcess() +more.start("more") +more.write("Text to display") +more.closeWriteChannel() +#QProcess will emit readyRead() once "more" starts printing +//! [1] + + +//! [2] +command1 | command2 +//! [2] + + +//! [3] +process1 = QProcess() +process2 = QProcess() + +process1.setStandardOutputProcess(process2) + +process1.start("command1") +process2.start("command2") +//! [3] + + +//! [4] +class SandboxProcess(QProcess): + def setupChildProcess(self) + # Drop all privileges in the child process, and enter + # a chroot jail. + os.setgroups(0, 0) + os.chroot("/etc/safe") + os.chdir("/") + os.setgid(safeGid) + os.setuid(safeUid) + os.umask(0) + +//! [4] + + +//! [5] +process = QProcess() +process.start("del /s *.txt") +# same as process.start("del", ["/s", "*.txt"]) +... +//! [5] + + +//! [6] +process = QProcess() +process.start("dir \"My Documents\"") +//! [6] + + +//! [7] +process = QProcess() +process.start("dir \"\"\"My Documents\"\"\"") +//! [7] + + +//! [8] +environment = QProcess.systemEnvironment() +# environment = [PATH=/usr/bin:/usr/local/bin", +# "USER=greg", "HOME=/home/greg"] +//! [8] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qsettings.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qsettings.cpp new file mode 100644 index 0000000..11bb9af --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qsettings.cpp @@ -0,0 +1,327 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +settings = QSettings("MySoft", "Star Runner") +color = QColor(settings.value("DataPump/bgcolor")) +//! [0] + + +//! [1] +settings = QSettings("MySoft", "Star Runner") +color = palette().background().color() +settings.setValue("DataPump/bgcolor", color) +//! [1] + + +//! [2] +settings = QSettings("/home/petra/misc/myapp.ini", + QSettings.IniFormat) +//! [2] + + +//! [3] +settings = QSettings("/Users/petra/misc/myapp.plist", + QSettings.NativeFormat) +//! [3] + + +//! [4] +settings = QSettings("HKEY_CURRENT_USER\\Software\\Microsoft\\Office", + QSettings.NativeFormat) +//! [4] + + +//! [5] +settings.setValue("11.0/Outlook/Security/DontTrustInstalledFiles", 0) +//! [5] + + +//! [6] +settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy", "Milkyway") +settings.setValue("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Sun", "OurStar") +settings.value("HKEY_CURRENT_USER\\MySoft\\Star Runner\\Galaxy\\Default") # returns "Milkyway" +//! [6] + + +//! [7] + organizationName = "grenoullelogique.fr" if sys.platform.startswith('darwin') else "Grenoulle Logique" + settings = QSettings(organizationName, "Squash") +//! [7] + + +//! [8] +pos = @Point(100 100) +//! [8] + + +//! [9] +windir = C:\Windows +//! [9] + + +//! [10] +settings = QSettings("Moose Tech", "Facturo-Pro") +//! [10] + + +//! [11] +settings = QSettings("Moose Soft", "Facturo-Pro") +//! [11] + + +//! [12] +QCoreApplication.setOrganizationName("Moose Soft") +QCoreApplication.setApplicationName("Facturo-Pro") +settings = QSettings() +//! [12] + + +//! [13] +settings.beginGroup("mainwindow") +settings.setValue("size", win.size()) +settings.setValue("fullScreen", win.isFullScreen()) +settings.endGroup() + +settings.beginGroup("outputpanel") +settings.setValue("visible", panel.isVisible()) +settings.endGroup() +//! [13] + + +//! [14] +settings.beginGroup("alpha") +# settings.group() == "alpha" + +settings.beginGroup("beta") +# settings.group() == "alpha/beta" + +settings.endGroup() +# settings.group() == "alpha" + +settings.endGroup() +# settings.group() == "" +//! [14] + + +//! [15] +class Login: + userName = '' + password = '' + + logins = [] + ... + + settings = QSettings() + size = settings.beginReadArray("logins") + for i in range(size): + settings.setArrayIndex(i) + login = Login() + login.userName = settings.value("userName") + login.password = settings.value("password") + logins.append(login) + + settings.endArray() +//! [15] + + +//! [16] +class Login: + userName = '' + password = '' + + logins = [] + ... + + settings = QSettings() + settings.beginWriteArray("logins") + for i in range(logins.size()): + settings.setArrayIndex(i) + settings.setValue("userName", list.at(i).userName) + settings.setValue("password", list.at(i).password) + + settings.endArray() +//! [16] + + +//! [17] +settings = QSettings() +settings.setValue("fridge/color", Qt.white) +settings.setValue("fridge/size", QSize(32, 96)) +settings.setValue("sofa", True) +settings.setValue("tv", False) + +keys = settings.allKeys(); +# keys: ["fridge/color", "fridge/size", "sofa", "tv"] +//! [17] + + +//! [18] +settings.beginGroup("fridge") +keys = settings.allKeys() +# keys: ["color", "size"] +//! [18] + + +//! [19] +settings = QSettings() +settings.setValue("fridge/color", Qt.white) +settings.setValue("fridge/size", QSize(32, 96)) +settings.setValue("sofa", True) +settings.setValue("tv", False) + +keys = settings.childKeys() +# keys: ["sofa", "tv"] +//! [19] + + +//! [20] +settings.beginGroup("fridge") +keys = settings.childKeys() +# keys: ["color", "size"] +//! [20] + + +//! [21] +settings = QSettings() +settings.setValue("fridge/color", Qt.white) +settings.setValue("fridge/size", QSize(32, 96)); +settings.setValue("sofa", True) +settings.setValue("tv", False) + +groups = settings.childGroups() +# group: ["fridge"] +//! [21] + + +//! [22] +settings.beginGroup("fridge") +groups = settings.childGroups() +# groups: [] +//! [22] + + +//! [23] +settings = QSettings() +settings.setValue("interval", 30) +settings.value("interval") # returns 30 + +settings.setValue("interval", 6.55) +settings.value("interval") # returns 6.55 +//! [23] + + +//! [24] +settings = QSettings() +settings.setValue("ape") +settings.setValue("monkey", 1) +settings.setValue("monkey/sea", 2) +settings.setValue("monkey/doe", 4) + +settings.remove("monkey") +keys = settings.allKeys() +# keys: ["ape"] +//! [24] + + +//! [25] +settings = QSettings() +settings.setValue("ape") +settings.setValue("monkey", 1) +settings.setValue("monkey/sea", 2) +settings.setValue("monkey/doe", 4) + +settings.beginGroup("monkey") +settings.remove("") +settings.endGroup() + +keys = settings.allKeys() +# keys: ["ape"] +//! [25] + + +//! [26] +settings = QSettings() +settings.setValue("animal/snake", 58) +settings.value("animal/snake", 1024) # returns 58 +settings.value("animal/zebra", 1024) # returns 1024 +settings.value("animal/zebra") # returns 0 +//! [26] + + +//! [27] +# @arg device QIODevice +# @arg map QSettings.SettingsMap +# @return bool +def myReadFunc(device, map): +//! [27] + + +//! [28] +# @arg device QIODevice +# @arg map QSettings.SettingsMap +# @return bool +def myWriteFunc(device, map) +//! [28] + + +//! [29] +# @arg device QIODevice +# @arg map QSettings.SettingsMap +# @return bool +def readXmlFile(device, map): +def writeXmlFile(device, map): + +def main(): + XmlFormat = QSettings::registerFormat("xml", readXmlFile, writeXmlFile) + settings = QSettings(XmlFormat, QSettings.UserSettings, + "MySoft", "Star Runner") + ... +//! [29] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtemporaryfile.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtemporaryfile.cpp new file mode 100644 index 0000000..7244c22 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtemporaryfile.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +{ +//! [0] + # Within a function/method... + + file_ = QTemporaryFile() + if file_.open(): + # file_.fileName() returns the unique file name + + # The QTemporaryFile destructor removes the temporary file + # as it goes out of scope. +//! [0] +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtextstream.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtextstream.cpp new file mode 100644 index 0000000..cf67a61 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qtextstream.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +data = QFile("output.txt") +if data.open(QFile.WriteOnly | QFile.Truncate): + out = QTextStream(&data) + out << "Result: " << qSetFieldWidth(10) << left << 3.14 << 2.7 + # writes "Result: 3.14 2.7 " + +//! [0] + + +//! [1] +stream = QTextStream(sys.stdin.fileno()) + +while(True): + line = stream.readLine() + if line.isNull(): + break; +//! [1] + + +//! [2] +in_ = QTextStream("0x50 0x20") +firstNumber = 0 +secondNumber = 0 + +in_ >> firstNumber # firstNumber == 80 +in_ >> dec >> secondNumber # secondNumber == 0 + +ch = None +in_ >> ch # ch == 'x' +//! [2] + + +//! [3] +def main(): + # read numeric arguments (123, 0x20, 4.5...) + for i in sys.argv(): + number = None + QTextStream in_(i) + in_ >> number + ... +//! [3] + + +//! [4] +str = QString() +in_ = QTextStream(sys.stdin.fileno()) +in_ >> str +//! [4] + + +//! [5] +s = QString() +out = QTextStream(s) +out.setFieldWidth(10) +out.setFieldAlignment(QTextStream::AlignCenter) +out.setPadChar('-') +out << "Qt" << "rocks!" +//! [5] + + +//! [6] +----Qt------rocks!-- +//! [6] + + +//! [7] +in_ = QTextStream(file) +ch1 = QChar() +ch2 = QChar() +ch3 = QChar() +in_ >> ch1 >> ch2 >> ch3; +//! [7] + + +//! [8] +out = QTextStream(sys.stdout.fileno()) +out << "Qt rocks!" << endl +//! [8] + + +//! [9] +stream << '\n' << flush +//! [9] + + +//! [10] +out = QTextStream(file) +out.setCodec("UTF-8") +//! [10] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qurl.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qurl.cpp new file mode 100644 index 0000000..d32a7b9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_io_qurl.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +url = QUrl("http://www.example.com/List of holidays.xml") +# url.toEncoded() == "http://www.example.com/List%20of%20holidays.xml" +//! [0] + + +//! [1] +url = QUrl.fromEncoded("http://qtsoftware.com/List%20of%20holidays.xml") +//! [1] + + +//! [2] +def checkUrl(url): + if !url.isValid(): + print "Invalid URL: %s" % url.toString() + return False + + return True + +//! [2] + + +//! [3] +ftp = QFtp() +ftp.connectToHost(url.host(), url.port(21)) +//! [3] + + +//! [4] +http://www.example.com/cgi-bin/drawgraph.cgi?type-pie/color-green +//! [4] + + +//! [5] +baseUrl = QUrl("http://qtsoftware.com/support") +relativeUrl = QUrl("../products/solutions") +print baseUrl.resolved(relativeUrl).toString() +# prints "http://qtsoftware.com/products/solutions" +//! [5] + + +//! [6] +ba = QUrl.toPercentEncoding("{a fishy string?}", "{}", "s") +print ba +# prints "{a fi%73hy %73tring%3F}" +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp new file mode 100644 index 0000000..a531f22 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp @@ -0,0 +1,3 @@ +//! [0] +bool myEventFilter(void *message); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp new file mode 100644 index 0000000..f2a9e82 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +beginInsertRows(parent, 2, 4) +//! [0] + + +//! [1] +beginInsertRows(parent, 4, 5) +//! [1] + + +//! [2] +beginRemoveRows(parent, 2, 3) +//! [2] + + +//! [3] +beginInsertColumns(parent, 4, 6) +//! [3] + + +//! [4] +beginInsertColumns(parent, 6, 8) +//! [4] + + +//! [5] +beginRemoveColumns(parent, 4, 6) +//! [5] + + +//! [6] +beginMoveRows(sourceParent, 2, 4, destinationParent, 2) +//! [6] + + +//! [7] +beginMoveRows(sourceParent, 2, 4, destinationParent, 6) +//! [7] + + +//! [8] +beginMoveRows(parent, 2, 2, parent, 0) +//! [8] + + +//! [9] +beginMoveRows(parent, 2, 2, parent, 4) +//! [9] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp new file mode 100644 index 0000000..115c766 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qcoreapplication.cpp @@ -0,0 +1,128 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +event = QMouseEvent(QEvent.MouseButtonPress, pos, 0, 0, 0) +QApplication.sendEvent(mainWindow, event) +//! [0] + + +//! [1] +quitButton = QPushButton("Quit") +quitButton.clicked.connect(app.quit) +//! [1] + + +//! [2] +for path in app.libraryPaths(): + do_something(path) +//! [2] + + +//! [3] +myEventFilter(message, result) +//! [3] + + +//! [4] +def cleanup_stuff(): + # do the cleanup stuff + +def init_stuff(): + qAddPostRoutine(cleanup_stuff) +//! [4] + + +//! [5] +class MyPrivateInitStuff : public QObject +{ +public: + static MyPrivateInitStuff *initStuff(QObject *parent) + { + if (!p) + p = new MyPrivateInitStuff(parent); + return p; + } + + ~MyPrivateInitStuff() + { + // cleanup goes here + } + +private: + MyPrivateInitStuff(QObject *parent) + : QObject(parent) + { + // initialization goes here + } + + MyPrivateInitStuff *p; +}; +//! [5] + + +//! [6] +static inline QString tr(const char *sourceText, + const char *comment = 0); +static inline QString trUtf8(const char *sourceText, + const char *comment = 0); +//! [6] + + +//! [7] +class MyMfcView : public CView +{ + Q_DECLARE_TR_FUNCTIONS(MyMfcView) + +public: + MyMfcView(); + ... +}; +//! [7] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp new file mode 100644 index 0000000..79fe7f0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetaobject.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +void wrapInFunction() +{ + +//! [0] +class MyClass: + + Q_CLASSINFO("author", "Sabrina Schweinsteiger") + Q_CLASSINFO("url", "http://doc.moosesoft.co.uk/1.0/") + + ... +//! [0] + + +//! [1] +normType = QMetaObject.normalizedType(" int const *") +# normType is now "const int*" +//! [1] + + +//! [2] +QMetaObject.invokeMethod(pushButton, "animateClick", + Qt.QueuedConnection) +//! [2] + + +//! [3] +QMetaObject.invokeMethod: Unable to handle unregistered datatype 'MyType' +//! [3] + + +//! [4] +retVal = QString() +QMetaObject.invokeMethod(obj, "compute", Qt::DirectConnection, + Q_RETURN_ARG(QString, retVal), + Q_ARG(QString, "sqrt"), + Q_ARG(int, 42), + Q_ARG(double, 9.7)); +//! [4] + + +//! [5] +class MyClass: + Q_CLASSINFO("author", "Sabrina Schweinsteiger") + Q_CLASSINFO("url", "http://doc.moosesoft.co.uk/1.0/") +//! [5] + + +//! [propertyCount] +metaObject = obj.metaObject() +properties = [metaObject.property(i).name() for i in range(metaObject.propertyOffset(), metaObject.propertyCount())] +//! [propertyCount] + + +//! [methodCount] +metaObject = obj.metaObject() +methods = [metaObject.method(i).signature() for i in range(metaObject.methodOffset(), metaObject.methodCount())] +//! [methodCount] + +//! [6] +methodIndex = pushButton.metaObject().indexOfMethod("animateClick()") +method = metaObject.method(methodIndex) +method.invoke(pushButton, Qt.QueuedConnection) +//! [6] + +//! [7] +QMetaMethod.invoke: Unable to handle unregistered datatype 'MyType' +//! [7] + +//! [8] +retVal = QString() +normalizedSignature = QMetaObject.normalizedSignature("compute(QString, int, double)") +methodIndex = obj.metaObject().indexOfMethod(normalizedSignature) +method = metaObject.method(methodIndex) +method.invoke(obj, + Qt.DirectConnection, + Q_RETURN_ARG(QString, retVal), + Q_ARG(QString, "sqrt"), + Q_ARG(int, 42), + Q_ARG(double, 9.7)); +//! [8] + +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp new file mode 100644 index 0000000..14f07a1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmetatype.cpp @@ -0,0 +1,119 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +struct MyStruct +{ + int i; + ... +}; + +Q_DECLARE_METATYPE(MyStruct) +//! [0] + + +//! [1] +namespace MyNamespace +{ + ... +} + +Q_DECLARE_METATYPE(MyNamespace::MyStruct) +//! [1] + + +//! [2] +MyStruct s; +QVariant var; +var.setValue(s); // copy s into the variant + +... + +// retrieve the value +MyStruct s2 = var.value(); +//! [2] + + +//! [3] +int id = QMetaType::type("MyClass"); +if (id == 0) { + void *myClassPtr = QMetaType::construct(id); + ... + QMetaType::destroy(id, myClassPtr); + myClassPtr = 0; +} +//! [3] + + +//! [4] +qRegisterMetaType("MyClass"); +//! [4] + + +//! [5] +qRegisterMetaTypeStreamOperators("MyClass"); +//! [5] + + +//! [6] +QDataStream &operator<<(QDataStream &out, const MyClass &myObj); +QDataStream &operator>>(QDataStream &in, MyClass &myObj); +//! [6] + + +//! [7] +int id = qRegisterMetaType(); +//! [7] + + +//! [8] +int id = qMetaTypeId(); // id is now QMetaType::QString +id = qMetaTypeId(); // compile error if MyStruct not declared +//! [8] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp new file mode 100644 index 0000000..46c7e31 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qmimedata.cpp @@ -0,0 +1,107 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def dragEnterEvent(self, event): + if event.mimeData().hasUrls(): + event.acceptProposedAction() + +def dropEvent(self, event): + if event->mimeData().hasUrls(): + for url in event.mimeData().urls(): + ... +//! [0] + + +//! [1] +csvData = QByteArray(...) + +mimeData = QMimeData() +mimeData.setData("text/csv", csvData) +//! [1] + + +//! [2] +def dropEvent(self, event): + myData = event->mimeData() + if myData: + # access myData's data directly (not through QMimeData's API) +} +//! [2] + + +//! [3] +application/x-qt-windows-mime;value="" +//! [3] + + +//! [4] +application/x-qt-windows-mime;value="FileGroupDescriptor" +application/x-qt-windows-mime;value="FileContents" +//! [4] + + +//! [5] +if event.mimeData().hasImage(): + image = QImage(event.mimeData().imageData()) + ... +//! [5] + + +//! [6] +mimeData.setImageData(QImage("beautifulfjord.png")) +//! [6] + + +//! [7] +if event.mimeData().hasColor(): + color = QColor(event.mimeData().colorData()) + ... +//! [7] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py new file mode 100644 index 0000000..7e50f67 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qobject.py @@ -0,0 +1,375 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +lineEdit = qt_find_obj_child(myWidget, "QLineEdit", "my line edit") +if lineEdit: + lineEdit.setText("Default") +//! [0] + + +//! [1] +obj = QPushButton() +obj.metaObject().className() # returns "QPushButton" + +QPushButton.staticMetaObject.className() # returns "QPushButton" +//! [1] + + +//! [2] +QPushButton.staticMetaObject.className() # returns "QPushButton" + +obj = QPushButton() +obj.metaObject().className() # returns "QPushButton" +//! [2] + + +//! [3] +obj = QTimer() # QTimer inherits QObject + +timer = obj +# timer == (QObject *)obj + +button = obj +# button == 0 +//! [3] + + +//! [4] +timer = QTimer() # QTimer inherits QObject +timer.inherits("QTimer") # returns true +timer.inherits("QObject") # returns true +timer.inherits("QAbstractButton") # returns false + +# QLayout inherits QObject and QLayoutItem +layout = QLayout() +layout.inherits("QObject") # returns true +layout.inherits("QLayoutItem") # returns false +//! [4] + + +//! [5] +print("MyClass.setPrecision(): ({}) invalid precision {}".format(qPrintable(objectName()), + newPrecision)) +//! [5] + + +//! [6] +class MainWindow(QMainWindow): + def __init__(self): + self.textEdit = QTextEdit() + setCentralWidget(self.textEdit) + textEdit.installEventFilter(self) + + def eventFilter(self, obj, event): + if obj == textEdit: + if event.type() == QEvent.KeyPress: + keyEvent = event + print("Ate key press", keyEvent.key()) + return true + else: + return false + else: + # pass the event on to the parent class + return QMainWindow.eventFilter(self, obj, event) +//! [6] + + +//! [7] +myObject.moveToThread(QApplication.instance().thread()) +//! [7] + + +//! [8] +class MyObject(QObject): + def __init__(self, parent): + QObject.__init__(self, parent) + + self.startTimer(50) # 50-millisecond timer + self.startTimer(1000) # 1-second timer + self.startTimer(60000) # 1-minute timer + + + def timerEvent(self, event): + print("Timer ID:", event.timerId()) + +//! [8] + + +//! [9] +a_list = window().queryList("QAbstractButton") +for obj in a_list: + obj.setEnabled(false) +//! [9] + + +//! [10] +button = parentWidget.findChild(QPushButton, "button1") +//! [10] + + +//! [11] +a_list = parentWidget.findChild(QListWidget) +//! [11] + + +//! [12] +widgets = parentWidget.findChildren(QWidget, "widgetname") +//! [12] + + +//! [13] +allPButtons = parentWidget.findChildren(QPushButton) +//! [13] + + +//! [14] +monitoredObj.installEventFilter(filterObj) +//! [14] + + +//! [15] +class KeyPressEater(QObject): + def eventFilter(self, obj, event): + if event.type() == QEvent.KeyPress: + print("Ate key press", event.key()) + return True + else: + # standard event processing + return QObject.eventFilter(self, obj, event) +//! [15] + + +//! [16] +keyPressEater = KeyPressEater(self) +pushButton = QPushButton(self) +listView = QListView(self) + +pushButton.installEventFilter(keyPressEater) +listView.installEventFilter(keyPressEater) +//! [16] + + +//! [17] +def __init__(self): + senderLabel = QLabel(self.tr("Name:")) + recipientLabel = QLabel(self.tr("Name:", "recipient")) + # ... +//! [17] + + +//! [18] +n = messages.count(); +showMessage(self.tr("%n message(s) saved", "", n)); +//! [18] + + +//! [19] +if n == 1: + self.tr("%n message saved") +else: + self.tr("%n messages saved") +//! [19] + + +//! [20] +label.setText(self.tr("F\374r \310lise")) +//! [20] + + +//! [21] +if receivers(SIGNAL('valueChanged()')) > 0: + data = get_the_value() # expensive operation + self.valueChanged(data) +//! [21] + + +//! [22] +label = QLabel() +scrollBar = QScrollBar() +QObject.connect(scrollBar, SIGNAL('valueChanged(int)'), + label, SLOT('setNum(int)')); +# or scrollBar.valueChanged.connect(label.setNum) +//! [22] + + +//! [23] +// WRONG +QObject.connect(scrollBar, SIGNAL('valueChanged(int value)'), + label, SLOT('setNum(int value)')); +//! [23] + + +//! [24] +class MyWidget(QWidget): + def __init__(self): + myButton = QPushButton(self) + myButton.clicked.connect(self.buttonClicked) +//! [24] + + +//! [25] +QObject.connect: Cannot queue arguments of type 'MyType' +(Make sure 'MyType' is registered using qRegisterMetaType().) +//! [25] + + +//! [26] +disconnect(myObject, 0, 0, 0) +//! [26] + + +//! [27] +myObject.disconnect() +//! [27] + + +//! [28] +disconnect(myObject, SIGNAL('mySignal()'), 0, 0) +//! [28] + + +//! [29] +myObject.disconnect(SIGNAL('mySignal()')) +//! [29] + + +//! [30] +disconnect(myObject, 0, myReceiver, 0) +//! [30] + + +//! [31] +myObject.disconnect(myReceiver) +//! [31] + + +//! [32] +if QLatin1String(signal) == SIGNAL('valueChanged()'): + # signal is valueChanged() +//! [32] + + +//! [33] +def on__() +//! [33] + + +//! [34] +def on_button1_clicked() +//! [34] + + +//! [35] +class MyClass(QObject): + Q_CLASSINFO("Author", "Pierre Gendron") + Q_CLASSINFO("URL", "http://www.my-organization.qc.ca") + +//! [35] + + +//! [36] +Q_PROPERTY(type name + READ getFunction + [WRITE setFunction] + [RESET resetFunction] + [DESIGNABLE bool] + [SCRIPTABLE bool] + [STORED bool] + [USER bool]) +//! [36] + + +//! [37] +Q_PROPERTY(QString title READ title WRITE setTitle USER true) +//! [37] + + +//! [38] +#this does not apply to Python +class MyClass(QObject): + + #Q_OBJECT, not needed + #Q_ENUMS(Priority), not supported + + def __init__(self, parent=None): + pass + + class Priority(Enum): + High = 1 + Low = 2 + VeryHigh = 3 + VeryLow 4 + + def setPriority(self, priority): + pass + + priority = Property(...) +}; +//! [38] + + +//! [39] +#this does not apply to Python +Q_FLAGS(Options Alignment) +//! [39] + + +//! [40] +# This name refers to a host name. +hostNameLabel.setText(self.tr("Name:")) + +# This text refers to a C++ code example. +example = self.tr("Example") +//! [40] + +//! [explicit tr context] +text = QScrollBar.tr("Page up") +//! [explicit tr context] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp new file mode 100644 index 0000000..2a93852 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qsystemsemaphore.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +sem = QSystemSemaphore("market", 3, QSystemSemaphore.Create) +# resources available == 3 +sem.acquire() # resources available == 2 +sem.acquire() # resources available == 1 +sem.acquire() # resources available == 0 +sem.release() # resources available == 1 +sem.release(2) # resources available == 3 +//! [0] + + +//! [1] +sem = QSystemSemaphore("market", 5, QSystemSemaphore.Create) +sem.acquire(5) # acquire all 5 resources +sem.release(5) # release the 5 resources +//! [1] + + +//! [2] +sem.release(10) # "create" 10 new resources +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qtimer.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qtimer.cpp new file mode 100644 index 0000000..c0c703d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_kernel_qtimer.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +from PySide2.QtCore import QApplication, QTimer + +def main(): + + app = QApplication([]) + QTimer.singleShot(600000, app, SLOT('quit()')) + ... + return app.exec_() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_qlibrary.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_qlibrary.cpp new file mode 100644 index 0000000..310cf5d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_qlibrary.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QLibrary myLib("mylib"); +typedef void (*MyPrototype)(); +MyPrototype myFunction = (MyPrototype) myLib.resolve("mysymbol"); +if (myFunction) + myFunction(); +//! [0] + + +//! [1] +typedef void (*MyPrototype)(); +MyPrototype myFunction = + (MyPrototype) QLibrary::resolve("mylib", "mysymbol"); +if (myFunction) + myFunction(); +//! [1] + + +//! [2] +typedef int (*AvgFunction)(int, int); + +AvgFunction avg = (AvgFunction) library->resolve("avg"); +if (avg) + return avg(5, 8); +else + return -1; +//! [2] + + +//! [3] +extern "C" MY_EXPORT int avg(int a, int b) +{ + return (a + b) / 2; +} +//! [3] + + +//! [4] +#ifdef Q_WS_WIN +#define MY_EXPORT __declspec(dllexport) +#else +#define MY_EXPORT +#endif +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_quuid.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_quuid.cpp new file mode 100644 index 0000000..90eafb9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_plugin_quuid.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +# {67C8770B-44F1-410A-AB9A-F9B5446F13EE} +IID_MyInterface = QUuid(0x67c8770b, 0x44f1, 0x410a, 0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_statemachine_qstatemachine.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_statemachine_qstatemachine.cpp new file mode 100644 index 0000000..6a78e19 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_statemachine_qstatemachine.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [simple state machine] +button = QPushButton() + +machine = QStateMachine() +s1 = QState() +s1.assignProperty(button, "text", "Click me") + +s2 = QFinalState() +s1.addTransition(button, SIGNAL('clicked()'), s2) + +machine.addState(s1) +machine.addState(s2) +machine.setInitialState(s1) +machine.start() +//! [simple state machine] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qatomic.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qatomic.cpp new file mode 100644 index 0000000..7c999e5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qatomic.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +MySharedType &MySharedType::operator=(const MySharedType &other) +{ + (void) other.data->atomicInt.ref(); + if (!data->atomicInt.deref()) { + // The last reference has been released + delete d; + } + d = other.d; + return *this; +} +//! [0] + + +//! [1] +if (currentValue == expectedValue) { + currentValue = newValue; + return true; +} +return false; +//! [1] + + +//! [2] +int originalValue = currentValue; +currentValue = newValue; +return originalValue; +//! [2] + + +//! [3] +int originalValue = currentValue; +currentValue += valueToAdd; +return originalValue; +//! [3] + + +//! [4] +if (currentValue == expectedValue) { + currentValue = newValue; + return true; +} +return false; +//! [4] + + +//! [5] +T *originalValue = currentValue; +currentValue = newValue; +return originalValue; +//! [5] + + +//! [6] +T *originalValue = currentValue; +currentValue += valueToAdd; +return originalValue; +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutex.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutex.cpp new file mode 100644 index 0000000..e799cbb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutex.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +number = 6 + +def method1(): + number *= 5 + number /= 4 + +def method2(): + number *= 3 + number /= 2 +//! [0] + + +//! [1] +# method1() +number *= 5 # number is now 30 +number /= 4 # number is now 7 + +# method2() +number *= 3 # number is now 21 +number /= 2 # number is now 10 +//! [1] + + +//! [2] +# Thread 1 calls method1() +number *= 5 # number is now 30 + +# Thread 2 calls method2(). +# +# Most likely Thread 1 has been put to sleep by the operating +# system to allow Thread 2 to run. +number *= 3 # number is now 90 +number /= 2 # number is now 45 + +# Thread 1 finishes executing. +number /= 4 # number is now 11, instead of 10 +//! [2] + + +//! [3] +mutex = QMutex() +number = 6 + +def method1(): + mutex.lock() + number *= 5 + number /= 4 + mutex.unlock() + +def method2(): + mutex.lock() + number *= 3 + number /= 2 + mutex.unlock() +//! [3] + + +//! [4] +def complexFunction(flag): + mutex.lock() + + retVal = 0 + + if flag == 0 or flag == 1: + mutex.unlock() + return moreComplexFunction(flag) + elif flag == 2: + status = anotherFunction() + if status < 0: + mutex.unlock() + return -2 + retVal = status + flag + else: + if flag > 10: + mutex.unlock() + return -1 + + mutex.unlock() + return retVal +//! [4] + + +//! [5] +def complexFunction(flag): + locker = QMutexLocker(mutex) + + retVal = 0 + + if flag == 0 or flag == 1: + return moreComplexFunction(flag) + elif flag == 2: + status = anotherFunction() + if status < 0: + return -2 + retVal = status + flag + else: + if flag > 10: + return -1 + + return retVal +//! [5] + + +//! [6] +class SignalWaiter: + def __init__(mutex): + self.locker = mutex + + def waitForSignal(): + # ... + while not signalled: + waitCondition.wait(self.locker.mutex()) + # ... +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutexpool.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutexpool.cpp new file mode 100644 index 0000000..622cb18 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qmutexpool.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class Number: + def __init__(n): + self.num = n +//! [0] + + +//! [1] +def calcSquare(number): + locker = QMutexLocker(mutexpool.get(number)) + number.num = number.num * number.num +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp new file mode 100644 index 0000000..d441042 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qreadwritelock.cpp @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +lock = QReadWriteLock() + +class ReaderThread: + # ... + def run(): + # ... + lock.lockForRead() + read_file() + lock.unlock() + # ... + +class WriterThread: + #... + def run(): + # ... + lock.lockForWrite() + write_file() + lock.unlock() + # ... +//! [0] + + +//! [1] +lock = QReadWriteLock() + +def readData(): + locker = QReadLocker(lock) + # ... + return data +//! [1] + + +//! [2] +lock = QReadWriteLock() + +def readData(): + locker.lockForRead() + # ... + locker.unlock() + return data +//! [2] + + +//! [3] +lock = QReadWriteLock() + +def writeData(data): + locker = QWriteLocker(lock) + # ... +//! [3] + + +//! [4] +lock = QReadWriteLock() + +def writeData(data): + locker.lockForWrite() + # ... + locker.unlock() +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qsemaphore.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qsemaphore.cpp new file mode 100644 index 0000000..086b105 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qsemaphore.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +sem = QSemaphore(5) # sem.available() == 5 + +sem.acquire(3) # sem.available() == 2 +sem.acquire(2) # sem.available() == 0 +sem.release(5) # sem.available() == 5 +sem.release(5) # sem.available() == 10 + +sem.tryAcquire(1) # sem.available() == 9, returns true +sem.tryAcquire(250) # sem.available() == 9, returns false +//! [0] + + +//! [1] +sem = QSemaphore(5) # a semaphore that guards 5 resources +sem.acquire(5) # acquire all 5 resources +sem.release(5) # release the 5 resources +sem.release(10) # "create" 10 new resources +//! [1] + + +//! [2] +sem = QSemaphore(5) # sem.available() == 5 +sem.tryAcquire(250) # sem.available() == 5, returns false +sem.tryAcquire(3) # sem.available() == 2, returns true +//! [2] + + +//! [3] +sem = QSemaphore(5) # sem.available() == 5 +sem.tryAcquire(250, 1000) # sem.available() == 5, waits 1000 milliseconds and returns false +sem.tryAcquire(3, 30000) # sem.available() == 2, returns true without waiting +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qthread.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qthread.cpp new file mode 100644 index 0000000..5470e8a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qthread.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyThread (QThread): + def run(): + socket = QTcpSocket() + # connect QTcpSocket's signals somewhere meaningful + # ... + socket.connectToHost(hostName, portNumber) + self.exec_() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qwaitcondition_unix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qwaitcondition_unix.cpp new file mode 100644 index 0000000..f652e5f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_thread_qwaitcondition_unix.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +while True: + mutex.lock() + keyPressed.wait(mutex) + do_something() + mutex.unlock() +//! [0] + + +//! [1] +while True: + getchar() + keyPressed.wakeAll() + +//! [1] + + +//! [2] +while True: + mutex.lock() + keyPressed.wait(&mutex) + count += 1 + mutex.unlock() + + do_something() + + mutex.lock() + count -= 1 + mutex.unlock() +//! [2] + + +//! [3] +while True: + getchar() + + mutex.lock() + # Sleep until there are no busy worker threads + while count > 0: + mutex.unlock() + sleep(1) + mutex.lock() + keyPressed.wakeAll() + mutex.unlock() +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbitarray.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbitarray.cpp new file mode 100644 index 0000000..2edd35b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbitarray.cpp @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +ba = QBitArray(200) +//! [0] + + +//! [1] +ba = QBitArray() +ba.resize(3) +ba[0] = True +ba[1] = False +ba[2] = True +//! [1] + + +//! [2] +ba = QBitArray(3) +ba.setBit(0, True) +ba.setBit(1, False) +ba.setBit(2, True) +//! [2] + + +//! [3] +x = QBitArray(5) +x.setBit(3, True) +# x: [ 0, 0, 0, 1, 0 ] + +y = QBitArray(5) +y.setBit(4, True) +# y: [ 0, 0, 0, 0, 1 ] + +x |= y +# x: [ 0, 0, 0, 1, 1 ] +//! [3] + + +//! [4] +QBitArray().isNull() # returns True +QBitArray().isEmpty() # returns True + +QBitArray(0).isNull() # returns False +QBitArray(0).isEmpty() # returns True + +QBitArray(3).isNull() # returns False +QBitArray(3).isEmpty() # returns False +//! [4] + + +//! [5] +QBitArray().isNull() # returns True +QBitArray(0).isNull() # returns False +QBitArray(3).isNull() # returns False +//! [5] + + +//! [6] +ba = QBitArray(8) +ba.fill(True) +# ba: [ 1, 1, 1, 1, 1, 1, 1, 1 ] + +ba.fill(False, 2) +# ba: [ 0, 0 ] +//! [6] + + +//! [7] +a = QBitArray(3) +a[0] = False +a[1] = True +a[2] = a[0] ^ a[1] +//! [7] + + +//! [8] +a = QBitArray(3) +b = QBitArray(2) +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +a &= b +# a: [ 1, 0, 0 ] +//! [8] + + +//! [9] +a = QBitArray(3) +b = QBitArray(2) +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +a |= b +# a: [ 1, 1, 1 ] +//! [9] + + +//! [10] +a = QBitArray(3) +b = QBitArray(2) +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +a ^= b +# a: [ 0, 1, 1 ] +//! [10] + + +//! [11] +a = QBitArray(3) +b = QBitArray() +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b = ~a +# b: [ 0, 1, 0 ] +//! [11] + + +//! [12] +a = QBitArray(3) +b = QBitArray(2) +c = QBitArray() +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +c = a & b +# c: [ 1, 0, 0 ] +//! [12] + + +//! [13] +a = QBitArray(3) +QBitArray b(2) +QBitArray c +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +c = a | b +# c: [ 1, 1, 1 ] +//! [13] + + +//! [14] +a = QBitArray(3) +b = QBitArray(2) +c = QBitArray() +a[0] = 1 +a[1] = 0 +a[2] = 1 +# a: [ 1, 0, 1 ] + +b[0] = 1 +b[1] = 0 +# b: [ 1, 1 ] + +c = a ^ b +# c: [ 0, 1, 1 ] +//! [14] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp new file mode 100644 index 0000000..bb0bc7d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qbytearray.cpp @@ -0,0 +1,402 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +void wrapInFunction() +{ + +//! [0] +ba = QByteArray("Hello") +//! [0] + + +//! [1] +ba = QByteArray() +ba.resize(5) +ba[0] = 'H' +ba[1] = 'e' +ba[2] = 'l' +ba[3] = 'l' +ba[4] = 'o' +//! [1] + + +//! [2] +for i in range(0, ba.size()): + if ba.at(i) >= 'a' and ba.at(i) <= 'f': + print "Found character in range [a-f]" +//! [2] + + +//! [3] +x = QByteArray("and") +x.prepend("rock ") # x == "rock and" +x.append(" roll") # x == "rock and roll" +x.replace(5, 3, "&") # x == "rock & roll" +//! [3] + + +//! [4] +ba = QByteArray("We must be bold, very bold") +j = 0 +while (j = ba.indexOf("", j)) != -1: + print "Found tag at index position %d" % j + ++j +//! [4] + + +//! [5] +QByteArray().isNull() # returns true +QByteArray().isEmpty() # returns true + +QByteArray("").isNull() # returns false +QByteArray("").isEmpty() # returns true + +QByteArray("abc").isNull() # returns false +QByteArray("abc").isEmpty() # returns false +//! [5] + + +//! [6] +ba = QByteArray("Hello") +n = ba.size() # n == 5 +ba.data()[0] # returns 'H' +ba.data()[4] # returns 'o' +//! [6] + + +//! [7] +QByteArray().isEmpty() # returns true +QByteArray("").isEmpty() # returns true +QByteArray("abc").isEmpty() # returns false +//! [7] + + +//! [8] +ba = QByteArray("Hello world"); +print ba.data(); +//! [8] + + +//! [9] +ba = QByteArray() +for i in range(0, 10): + ba[i] = 'A' + str(i) +# ba == "ABCDEFGHIJ" +//! [9] + + +//! [10] +ba = QByteArray("Stockholm") +ba.truncate(5) # ba == "Stock" +//! [10] + + +//! [11] +ba = QByteArray("STARTTLS\r\n") +ba.chop(2) # ba == "STARTTLS" +//! [11] + + +//! [12] +x = QByteArray("free") +y = QByteArray("dom"); +x += y +# x == "freedom" +//! [12] + + +//! [13] +QByteArray().isNull() # returns true +QByteArray("").isNull() # returns false +QByteArray("abc").isNull() # returns false +//! [13] + + +//! [14] +ba = QByteArray("Istambul") +ba.fill('o') +# ba == "oooooooo" + +ba.fill('X', 2) +# ba == "XX" +//! [14] + + +//! [15] +x = QByteArray("ship") +y = QByteArray("air") +x.prepend(y) +# x == "airship" +//! [15] + + +//! [16] +x = QByteArray("free") +y = QByteArray("dom") +x.append(y) +# x == "freedom" +//! [16] + + +//! [17] +ba = QByteArray("Meal") +ba.insert(1, QByteArray("ontr")) +# ba == "Montreal" +//! [17] + + +//! [18] +ba = QByteArray("Montreal") +ba.remove(1, 4) +# ba == "Meal" +//! [18] + + +//! [19] +x = QByteArray("Say yes!") +y = QByteArray("no") +x.replace(4, 3, y) +# x == "Say no!" +//! [19] + + +//! [20] +ba = QByteArray("colour behaviour flavour neighbour") +ba.replace(QByteArray("ou"), QByteArray("o")) +# ba == "color behavior flavor neighbor" +//! [20] + + +//! [21] +x = QByteArray("sticky question") +y = QByteArray("sti") +x.indexOf(y) # returns 0 +x.indexOf(y, 1) # returns 10 +x.indexOf(y, 10) # returns 10 +x.indexOf(y, 11) # returns -1 +//! [21] + + +//! [22] +ba = QByteArray("ABCBA") +ba.indexOf("B") # returns 1 +ba.indexOf("B", 1) # returns 1 +ba.indexOf("B", 2) # returns 3 +ba.indexOf("X") # returns -1 +//! [22] + + +//! [23] +x = QByteArray("crazy azimuths") +y = QByteArray("azy") +x.lastIndexOf(y) # returns 6 +x.lastIndexOf(y, 6) # returns 6 +x.lastIndexOf(y, 5) # returns 2 +x.lastIndexOf(y, 1) # returns -1 +//! [23] + + +//! [24] +ba = QByteArray("ABCBA") +ba.lastIndexOf("B") # returns 3 +ba.lastIndexOf("B", 3) # returns 3 +ba.lastIndexOf("B", 2) # returns 1 +ba.lastIndexOf("X") # returns -1 +//! [24] + + +//! [25] +url = QByteArray("ftp://ftp.qt-project.org/") +if url.startsWith("ftp:"): + ... +//! [25] + + +//! [26] +url = QByteArray("http://qtsoftware.com/index.html") +if url.endsWith(".html"): + ... +//! [26] + + +//! [27] +x = QByteArray("Pineapple") +y = x.left(4) +# y == "Pine" +//! [27] + + +//! [28] +x = QByteArray("Pineapple") +y = x.right(5) +# y == "apple" +//! [28] + + +//! [29] +x = QByteArray("Five pineapples") +y = x.mid(5, 4) # y == "pine" +z = x.mid(5) # z == "pineapples" +//! [29] + + +//! [30] +x = QByteArray("Qt by THE QT COMPANY") +y = x.toLower() +# y == "qt by the qt company" +//! [30] + + +//! [31] +x = QByteArray("Qt by THE QT COMPANY") +y = x.toUpper() +# y == "QT BY THE QT COMPANY" +//! [31] + + +//! [32] +ba = QByteArray(" lots\t of\nwhitespace\r\n ") +ba = ba.simplified() +# ba == "lots of whitespace"; +//! [32] + + +//! [33] +ba = QByteArray(" lots\t of\nwhitespace\r\n "); +ba = ba.trimmed(); +# ba == "lots\t of\nwhitespace"; +//! [33] + + +//! [34] +x = QByteArray("apple") +y = x.leftJustified(8, '.') # y == "apple..." +//! [34] + + +//! [35] +x = QByteArray("apple") +y = x.rightJustified(8, '.') # y == "...apple" +//! [35] + + +//! [36] +string = QByteArray("FF") +(hex, ok) = string.toInt(16) # hex == 255, ok == true +(dec, ok) = string.toInt(10) # dec == 0, ok == false +//! [36] + + +//! [37] +string = QByteArray("FF") +(hex, ok) = str.toLong(16); # hex == 255, ok == true +(dec, ok) = str.toLong(10); # dec == 0, ok == false +//! [37] + + +//! [38] +string = QByteArray("1234.56") +(a, ok) = string.toDouble() # a == 1234.56, ok == true +//! [38] + + +//! [39] +text = QByteArray("Qt is great!") +text.toBase64() # returns "UXQgaXMgZ3JlYXQh" +//! [39] + + +//! [40] +ba = QByteArray() +n = 63 +ba.setNum(n) # ba == "63" +ba.setNum(n, 16) # ba == "3f" +//! [40] + + +//! [41] +n = 63; +QByteArray.number(n) # returns "63" +QByteArray.number(n, 16) # returns "3f" +QByteArray.number(n, 16).toUpper() # returns "3F" +//! [41] + + +//! [42] +ba = QByteArray.number(12.3456, 'E', 3) +# ba == 1.235E+01 +//! [42] + + +//! [43] +mydata = '\x00\x00\x03\x84\x78\x9c\x3b\x76'\ + '\xec\x18\xc3\x31\x0a\xf1\xcc\x99'\ + ... + '\x6d\x5b' + +data = QByteArray.fromRawData(mydata) +in_ = QDataStream(data, QIODevice.ReadOnly) +... +//! [43] + + +//! [44] +text = QByteArray.fromBase64("UXQgaXMgZ3JlYXQh") +text.data() # returns "Qt is great!" +//! [44] + + +//! [45] +text = QByteArray.fromHex("517420697320677265617421") +text.data() # returns "Qt is great!" +//! [45] + +} + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qdatetime.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qdatetime.cpp new file mode 100644 index 0000000..ea8c044 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qdatetime.cpp @@ -0,0 +1,156 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +d1 = QDate(1995, 5, 17) # May 17, 1995 +d2 = QDate(1995, 5, 20) # May 20, 1995 +d1.daysTo(d2) # returns 3 +d2.daysTo(d1) # returns -3 +//! [0] + + +//! [1] +date = QDate.fromString("1MM12car2003", "d'MM'MMcaryyyy") +# date is 1 December 2003 +//! [1] + + +//! [2] +date = QDate.fromString("130", "Md") # invalid +//! [2] + + +//! [3] +QDate.fromString("1.30", "M.d") # January 30 1900 +QDate.fromString("20000110", "yyyyMMdd") # January 10, 2000 +QDate.fromString("20000110", "yyyyMd") # January 10, 2000 +//! [3] + + +//! [4] +QDate.isValid(2002, 5, 17) # True +QDate.isValid(2002, 2, 30) # False (Feb 30 does not exist) +QDate.isValid(2004, 2, 29) # True (2004 is a leap year) +QDate.isValid(2000, 2, 29) # True (2000 is a leap year) +QDate.isValid(2006, 2, 29) # False (2006 is not a leap year) +QDate.isValid(2100, 2, 29) # False (2100 is not a leap year) +QDate.isValid(1202, 6, 6) # True (even though 1202 is pre-Gregorian) +//! [4] + + +//! [5] +n = QTime(14, 0, 0) # n == 14:00:00 +t = QTime() +t = n.addSecs(70) # t == 14:01:10 +t = n.addSecs(-70) # t == 13:58:50 +t = n.addSecs(10 * 60 * 60 + 5) # t == 00:00:05 +t = n.addSecs(-15 * 60 * 60) # t == 23:00:00 +//! [5] + + +//! [6] +time = QTime.fromString("1mm12car00", "m'mm'hcarss") +# time is 12:01.00 +//! [6] + + +//! [7] +time = QTime.fromString("00:710", "hh:ms") # invalid +//! [7] + + +//! [8] +time = QTime.fromString("1.30", "m.s") +# time is 00:01:30.000 +//! [8] + + +//! [9] +QTime.isValid(21, 10, 30) # returns True +QTime.isValid(22, 5, 62) # returns False +//! [9] + + +//! [10] +t = QTime() +t.start() +some_lengthy_task() +print ("Time elapsed: %d ms" % t.elapsed()) +//! [10] + + +//! [11] +now = QDateTime.currentDateTime() +xmas(QDate(now.date().year(), 12, 25), QTime(0, 0)) +print("There are %d seconds to Christmas" % now.secsTo(xmas)) +//! [11] + + +//! [12] +time1 = QTime.fromString("131", "HHh") +# time1 is 13:00:00 +time1 = QTime.fromString("1apA", "1amAM") +# time1 is 01:00:00 + +dateTime2 = QDateTime.fromString("M1d1y9800:01:02", + "'M'M'd'd'y'yyhh:mm:ss") +# dateTime is 1 January 1998 00:01:02 +//! [12] + + +//! [13] +dateTime = QDateTime.fromString("130", "Mm") # invalid +//! [13] + + +//! [14] +dateTime = QDateTime.fromString("1.30.1", "M.d.s") +# dateTime is January 30 in 1900 at 00:00:01. +//! [14] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qhash.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qhash.cpp new file mode 100644 index 0000000..985c7da --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qhash.cpp @@ -0,0 +1,309 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QHash hash; +//! [0] + + +//! [1] +hash["one"] = 1; +hash["three"] = 3; +hash["seven"] = 7; +//! [1] + + +//! [2] +hash.insert("twelve", 12); +//! [2] + + +//! [3] +int num1 = hash["thirteen"]; +int num2 = hash.value("thirteen"); +//! [3] + + +//! [4] +int timeout = 30; +if (hash.contains("TIMEOUT")) + timeout = hash.value("TIMEOUT"); +//! [4] + + +//! [5] +int timeout = hash.value("TIMEOUT", 30); +//! [5] + + +//! [6] +// WRONG +QHash hash; +... +for (int i = 0; i < 1000; ++i) { + if (hash[i] == okButton) + cout << "Found button at index " << i << endl; +} +//! [6] + + +//! [7] +QHashIterator i(hash); +while (i.hasNext()) { + i.next(); + cout << i.key() << ": " << i.value() << endl; +} +//! [7] + + +//! [8] +QHash::const_iterator i = hash.constBegin(); +while (i != hash.constEnd()) { + cout << i.key() << ": " << i.value() << endl; + ++i; +} +//! [8] + + +//! [9] +hash.insert("plenty", 100); +hash.insert("plenty", 2000); +// hash.value("plenty") == 2000 +//! [9] + + +//! [10] +QList values = hash.values("plenty"); +for (int i = 0; i < values.size(); ++i) + cout << values.at(i) << endl; +//! [10] + + +//! [11] +QHash::iterator i = hash.find("plenty"); +while (i != hash.end() && i.key() == "plenty") { + cout << i.value() << endl; + ++i; +} +//! [11] + + +//! [12] +QHash hash; +... +foreach (int value, hash) + cout << value << endl; +//! [12] + + +//! [13] +#ifndef EMPLOYEE_H +#define EMPLOYEE_H + +class Employee +{ +public: + Employee() {} + Employee(const QString &name, const QDate &dateOfBirth); + ... + +private: + QString myName; + QDate myDateOfBirth; +}; + +inline bool operator==(const Employee &e1, const Employee &e2) +{ + return e1.name() == e2.name() + && e1.dateOfBirth() == e2.dateOfBirth(); +} + +inline uint qHash(const Employee &key) +{ + return qHash(key.name()) ^ key.dateOfBirth().day(); +} + +#endif // EMPLOYEE_H +//! [13] + + +//! [14] +QHash hash; +hash.reserve(20000); +for (int i = 0; i < 20000; ++i) + hash.insert(keys[i], values[i]); +//! [14] + + +//! [15] +QHash objectHash; +... +QHash::iterator i = objectHash.find(obj); +while (i != objectHash.end() && i.key() == obj) { + if (i.value() == 0) { + i = objectHash.erase(i); + } else { + ++i; + } +} +//! [15] + + +//! [16] +QHash hash; +... +QHash::const_iterator i = hash.find("HDR"); +while (i != hash.end() && i.key() == "HDR") { + cout << i.value() << endl; + ++i; +} +//! [16] + + +//! [17] +QHash hash; +hash.insert("January", 1); +hash.insert("February", 2); +... +hash.insert("December", 12); + +QHash::iterator i; +for (i = hash.begin(); i != hash.end(); ++i) + cout << i.key() << ": " << i.value() << endl; +//! [17] + + +//! [18] +QHash::iterator i; +for (i = hash.begin(); i != hash.end(); ++i) + i.value() += 2; +//! [18] + + +//! [19] +QHash::iterator i = hash.begin(); +while (i != hash.end()) { + if (i.key().startsWith("_")) + i = hash.erase(i); + else + ++i; +} +//! [19] + + +//! [20] +QHash::iterator i = hash.begin(); +while (i != hash.end()) { + QHash::iterator prev = i; + ++i; + if (prev.key().startsWith("_")) + hash.erase(prev); +} +//! [20] + + +//! [21] +// WRONG +while (i != hash.end()) { + if (i.key().startsWith("_")) + hash.erase(i); + ++i; +} +//! [21] + + +//! [22] +if (i.key() == "Hello") + i.value() = "Bonjour"; +//! [22] + + +//! [23] +QHash hash; +hash.insert("January", 1); +hash.insert("February", 2); +... +hash.insert("December", 12); + +QHash::const_iterator i; +for (i = hash.constBegin(); i != hash.constEnd(); ++i) + cout << i.key() << ": " << i.value() << endl; +//! [23] + + +//! [24] +QMultiHash hash1, hash2, hash3; + +hash1.insert("plenty", 100); +hash1.insert("plenty", 2000); +// hash1.size() == 2 + +hash2.insert("plenty", 5000); +// hash2.size() == 1 + +hash3 = hash1 + hash2; +// hash3.size() == 3 +//! [24] + + +//! [25] +QList values = hash.values("plenty"); +for (int i = 0; i < values.size(); ++i) + cout << values.at(i) << endl; +//! [25] + + +//! [26] +QMultiHash::iterator i = hash.find("plenty"); +while (i != hash.end() && i.key() == "plenty") { + cout << i.value() << endl; + ++i; +} +//! [26] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp new file mode 100644 index 0000000..947594a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlinkedlist.cpp @@ -0,0 +1,214 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QLinkedList integerList; +QLinkedList timeList; +//! [0] + + +//! [1] +QLinkedList list; +list << "one" << "two" << "three"; +// list: ["one", "two", "three"] +//! [1] + + +//! [2] +QLinkedList list; +... +while (!list.isEmpty()) + delete list.takeFirst(); +//! [2] + + +//! [3] +QLinkedList list; +list.append("one"); +list.append("two"); +list.append("three"); +// list: ["one", "two", "three"] +//! [3] + + +//! [4] +QLinkedList list; +list.prepend("one"); +list.prepend("two"); +list.prepend("three"); +// list: ["three", "two", "one"] +//! [4] + + +//! [5] +QList list; +list << "sun" << "cloud" << "sun" << "rain"; +list.removeAll("sun"); +// list: ["cloud", "rain"] +//! [5] + + +//! [6] +QList list; +list << "sun" << "cloud" << "sun" << "rain"; +list.removeOne("sun"); +// list: ["cloud", "sun", "rain"] +//! [6] + + +//! [7] +QLinkedList list; +list.append("January"); +list.append("February"); +... +list.append("December"); + +QLinkedList::iterator i; +for (i = list.begin(); i != list.end(); ++i) + cout << *i << endl; +//! [7] + + +//! [8] +QLinkedList list; +... +QLinkedList::iterator it = qFind(list.begin(), + list.end(), "Joel"); +if (it != list.end()) + cout << "Found Joel" << endl; +//! [8] + + +//! [9] +QLinkedList::iterator i; +for (i = list.begin(); i != list.end(); ++i) + *i += 2; +//! [9] + + +//! [10] +QLinkedList list; +... +QLinkedList::iterator i = list.begin(); +while (i != list.end()) { + if ((*i).startsWith("_")) + i = list.erase(i); + else + ++i; +} +//! [10] + + +//! [11] +QLinkedList::iterator i = list.begin(); +while (i != list.end()) { + QLinkedList::iterator previous = i; + ++i; + if ((*previous).startsWith("_")) + list.erase(previous); +} +//! [11] + + +//! [12] +// WRONG +while (i != list.end()) { + if ((*i).startsWith("_")) + list.erase(i); + ++i; +} +//! [12] + + +//! [13] +if (*it == "Hello") + *it = "Bonjour"; +//! [13] + + +//! [14] +QLinkedList list; +list.append("January"); +list.append("February"); +... +list.append("December"); + +QLinkedList::const_iterator i; +for (i = list.constBegin(); i != list.constEnd(); ++i) + cout << *i << endl; +//! [14] + + +//! [15] +QLinkedList list; +... +QLinkedList::iterator it = qFind(list.constBegin(), + list.constEnd(), "Joel"); +if (it != list.constEnd()) + cout << "Found Joel" << endl; +//! [15] + + +//! [16] +std::list stdlist; +list.push_back(1.2); +list.push_back(0.5); +list.push_back(3.14); + +QLinkedList list = QLinkedList::fromStdList(stdlist); +//! [16] + + +//! [17] +QLinkedList list; +list << 1.2 << 0.5 << 3.14; + +std::list stdlist = list.toStdList(); +//! [17] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp new file mode 100644 index 0000000..d90d932 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlistdata.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QList integerList; +QList dateList; +//! [0] + + +//! [1] +QList list; +list << "one" << "two" << "three"; +// list: ["one", "two", "three"] +//! [1] + + +//! [2] +if (list[0] == "Bob") + list[0] = "Robert"; +//! [2] + + +//! [3] +for (int i = 0; i < list.size(); ++i) { + if (list.at(i) == "Jane") + cout << "Found Jane at position " << i << endl; +} +//! [3] + + +//! [4] +QList list; +... +while (!list.isEmpty()) + delete list.takeFirst(); +//! [4] + + +//! [5] +int i = list.indexOf("Jane"); +if (i != -1) + cout << "First occurrence of Jane is at position " << i << endl; +//! [5] + + +//! [6] +QList list; +list.append("one"); +list.append("two"); +list.append("three"); +// list: ["one", "two", "three"] +//! [6] + + +//! [7] +QList list; +list.prepend("one"); +list.prepend("two"); +list.prepend("three"); +// list: ["three", "two", "one"] +//! [7] + + +//! [8] +QList list; +list << "alpha" << "beta" << "delta"; +list.insert(2, "gamma"); +// list: ["alpha", "beta", "gamma", "delta"] +//! [8] + + +//! [9] +QList list; +list << "sun" << "cloud" << "sun" << "rain"; +list.removeAll("sun"); +// list: ["cloud", "rain"] +//! [9] + + +//! [10] +QList list; +list << "sun" << "cloud" << "sun" << "rain"; +list.removeOne("sun"); +// list: ["cloud", ,"sun", "rain"] +//! [10] + + +//! [11] +QList list; +list << "A" << "B" << "C" << "D" << "E" << "F"; +list.move(1, 4); +// list: ["A", "C", "D", "E", "B", "F"] +//! [11] + + +//! [12] +QList list; +list << "A" << "B" << "C" << "D" << "E" << "F"; +list.swap(1, 4); +// list: ["A", "E", "C", "D", "B", "F"] +//! [12] + + +//! [13] +QList list; +list << "A" << "B" << "C" << "B" << "A"; +list.indexOf("B"); // returns 1 +list.indexOf("B", 1); // returns 1 +list.indexOf("B", 2); // returns 3 +list.indexOf("X"); // returns -1 +//! [13] + + +//! [14] +QList list; +list << "A" << "B" << "C" << "B" << "A"; +list.lastIndexOf("B"); // returns 3 +list.lastIndexOf("B", 3); // returns 3 +list.lastIndexOf("B", 2); // returns 1 +list.lastIndexOf("X"); // returns -1 +//! [14] + + +//! [15] +QList list; +list.append("January"); +list.append("February"); +... +list.append("December"); + +QList::iterator i; +for (i = list.begin(); i != list.end(); ++i) + cout << *i << endl; +//! [15] + + +//! [16] +QList::iterator i; +for (i = list.begin(); i != list.end(); ++i) + *i += 2; +//! [16] + + +//! [17] +QList list; +... +qDeleteAll(list.begin(), list.end()); +//! [17] + + +//! [18] +if (*it == "Hello") + *it = "Bonjour"; +//! [18] + + +//! [19] +QList list; +list.append("January"); +list.append("February"); +... +list.append("December"); + +QList::const_iterator i; +for (i = list.constBegin(); i != list.constEnd(); ++i) + cout << *i << endl; +//! [19] + + +//! [20] +QList list; +... +qDeleteAll(list.constBegin(), list.constEnd()); +//! [20] + + +//! [21] +QVector vect; +vect << 20.0 << 30.0 << 40.0 << 50.0; + +QList list = QVector::fromVector(vect); +// list: [20.0, 30.0, 40.0, 50.0] +//! [21] + + +//! [22] +QStringList list; +list << "Sven" << "Kim" << "Ola"; + +QVector vect = list.toVector(); +// vect: ["Sven", "Kim", "Ola"] +//! [22] + + +//! [23] +QSet set; +set << 20.0 << 30.0 << 40.0 << ... << 70.0; + +QList list = QList::fromSet(set); +qSort(list); +//! [23] + + +//! [24] +QStringList list; +list << "Julia" << "Mike" << "Mike" << "Julia" << "Julia"; + +QSet set = list.toSet(); +set.contains("Julia"); // returns true +set.contains("Mike"); // returns true +set.size(); // returns 2 +//! [24] + + +//! [25] +std::list stdlist; +list.push_back(1.2); +list.push_back(0.5); +list.push_back(3.14); + +QList list = QList::fromStdList(stdlist); +//! [25] + + +//! [26] +QList list; +list << 1.2 << 0.5 << 3.14; + +std::list stdlist = list.toStdList(); +//! [26] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlocale.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlocale.cpp new file mode 100644 index 0000000..4be07da --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qlocale.cpp @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +egyptian = QLocale(QLocale.Arabic, QLocale.Egypt) +s1 = egyptian.toString(1.571429E+07, 'e') +s2 = egyptian.toString(10) + +(d, ok) = egyptian.toDouble(s1) +(i, ok) = egyptian.toInt(s2) +//! [0] + + +//! [1] +QLocale.setDefault(QLocale(QLocale.Hebrew, QLocale.Israel)) +hebrew = QLocale() # Constructs a default QLocale +s1 = hebrew.toString(15714.3, 'e') + +QLocale.setDefault(QLocale(QLocale.C)) +c = QLocale() +(d, ok) = c.toDouble("1234,56") # ok == false +(d, ok) = c.toDouble("1234.56") # ok == true, d == 1234.56 + +QLocale.setDefault(QLocale(QLocale.German)) +german = QLocale() +(d, ok) = german.toDouble("1234,56") # ok == true, d == 1234.56 +(d, ok) = german.toDouble("1234.56") # ok == true, d == 1234.56 + +QLocale.setDefault(QLocale(QLocale.English, QLocale.UnitedStates)) +english = QLocale() +string = '%s %s %10x' % (12345, english.toString(12345), 12345) +# string == "12345 12,345 3039" +//! [1] + + +//! [2] +korean = QLocale("ko") +swiss = QLocale("de_CH") +//! [2] + + +//! [3] +c = QLocale(QLocale.C) +(d, ok) = c.toDouble( "1234.56" ) # ok == true, d == 1234.56 +(d, ok) = c.toDouble( "1,234.56" ) # ok == true, d == 1234.56 +(d, ok) = c.toDouble( "1234,56" ) # ok == false + +german = QLocale(QLocale.German) +(d, ok) = german.toDouble( "1234,56" ) # ok == true, d == 1234.56 +(d, ok) = german.toDouble( "1.234,56" ) # ok == true, d == 1234.56 +(d, ok) = german.toDouble( "1234.56" ) # ok == false + +(d, ok) = german.toDouble( "1.234" ) # ok == true, d == 1234.0 +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qmap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qmap.cpp new file mode 100644 index 0000000..5bd7dc6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qmap.cpp @@ -0,0 +1,323 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QMap map; +//! [0] + + +//! [1] +map["one"] = 1; +map["three"] = 3; +map["seven"] = 7; +//! [1] + + +//! [2] +map.insert("twelve", 12); +//! [2] + + +//! [3] +int num1 = map["thirteen"]; +int num2 = map.value("thirteen"); +//! [3] + + +//! [4] +int timeout = 30; +if (map.contains("TIMEOUT")) + timeout = map.value("TIMEOUT"); +//! [4] + + +//! [5] +int timeout = map.value("TIMEOUT", 30); +//! [5] + + +//! [6] +// WRONG +QMap map; +... +for (int i = 0; i < 1000; ++i) { + if (map[i] == okButton) + cout << "Found button at index " << i << endl; +} +//! [6] + + +//! [7] +QMapIterator i(map); +while (i.hasNext()) { + i.next(); + cout << i.key() << ": " << i.value() << endl; +} +//! [7] + + +//! [8] +QMap::const_iterator i = map.constBegin(); +while (i != map.constEnd()) { + cout << i.key() << ": " << i.value() << endl; + ++i; +} +//! [8] + + +//! [9] +map.insert("plenty", 100); +map.insert("plenty", 2000); +// map.value("plenty") == 2000 +//! [9] + + +//! [10] +QList values = map.values("plenty"); +for (int i = 0; i < values.size(); ++i) + cout << values.at(i) << endl; +//! [10] + + +//! [11] +QMap::iterator i = map.find("plenty"); +while (i != map.end() && i.key() == "plenty") { + cout << i.value() << endl; + ++i; +} +//! [11] + + +//! [12] +QMap map; +... +foreach (int value, map) + cout << value << endl; +//! [12] + + +//! [13] +#ifndef EMPLOYEE_H +#define EMPLOYEE_H + +class Employee +{ +public: + Employee() {} + Employee(const QString &name, const QDate &dateOfBirth); + ... + +private: + QString myName; + QDate myDateOfBirth; +}; + +inline bool operator<(const Employee &e1, const Employee &e2) +{ + if (e1.name() != e2.name()) + return e1.name() < e2.name(); + return e1.dateOfBirth() < e2.dateOfBirth(); +} + +#endif // EMPLOYEE_H +//! [13] + + +//! [14] +QMap map; +... +QMap::const_iterator i = map.find("HDR"); +while (i != map.end() && i.key() == "HDR") { + cout << i.value() << endl; + ++i; +} +//! [14] + + +//! [15] +QMap map; +map.insert(1, "one"); +map.insert(5, "five"); +map.insert(10, "ten"); + +map.lowerBound(0); // returns iterator to (1, "one") +map.lowerBound(1); // returns iterator to (1, "one") +map.lowerBound(2); // returns iterator to (5, "five") +map.lowerBound(10); // returns iterator to (10, "ten") +map.lowerBound(999); // returns end() +//! [15] + + +//! [16] +QMap map; +... +QMap::const_iterator i = map.lowerBound("HDR"); +QMap::const_iterator upperBound = map.upperBound("HDR"); +while (i != upperBound) { + cout << i.value() << endl; + ++i; +} +//! [16] + + +//! [17] +QMap map; +map.insert(1, "one"); +map.insert(5, "five"); +map.insert(10, "ten"); + +map.upperBound(0); // returns iterator to (1, "one") +map.upperBound(1); // returns iterator to (5, "five") +map.upperBound(2); // returns iterator to (5, "five") +map.upperBound(10); // returns end() +map.upperBound(999); // returns end() +//! [17] + + +//! [18] +QMap map; +map.insert("January", 1); +map.insert("February", 2); +... +map.insert("December", 12); + +QMap::iterator i; +for (i = map.begin(); i != map.end(); ++i) + cout << i.key() << ": " << i.value() << endl; +//! [18] + + +//! [19] +QMap::iterator i; +for (i = map.begin(); i != map.end(); ++i) + i.value() += 2; +//! [19] + + +//! [20] +QMap::iterator i = map.begin(); +while (i != map.end()) { + if (i.key().startsWith("_")) + i = map.erase(i); + else + ++i; +} +//! [20] + + +//! [21] +QMap::iterator i = map.begin(); +while (i != map.end()) { + QMap::iterator prev = i; + ++i; + if (prev.key().startsWith("_")) + map.erase(prev); +} +//! [21] + + +//! [22] +// WRONG +while (i != map.end()) { + if (i.key().startsWith("_")) + map.erase(i); + ++i; +} +//! [22] + + +//! [23] +if (i.key() == "Hello") + i.value() = "Bonjour"; +//! [23] + + +//! [24] +QMap map; +map.insert("January", 1); +map.insert("February", 2); +... +map.insert("December", 12); + +QMap::const_iterator i; +for (i = map.constBegin(); i != map.constEnd(); ++i) + cout << i.key() << ": " << i.value() << endl; +//! [24] + + +//! [25] +QMultiMap map1, map2, map3; + +map1.insert("plenty", 100); +map1.insert("plenty", 2000); +// map1.size() == 2 + +map2.insert("plenty", 5000); +// map2.size() == 1 + +map3 = map1 + map2; +// map3.size() == 3 +//! [25] + + +//! [26] +QList values = map.values("plenty"); +for (int i = 0; i < values.size(); ++i) + cout << values.at(i) << endl; +//! [26] + + +//! [27] +QMultiMap::iterator i = map.find("plenty"); +while (i != map.end() && i.key() == "plenty") { + cout << i.value() << endl; + ++i; +} +//! [27] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qpoint.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qpoint.cpp new file mode 100644 index 0000000..e6a5e0c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qpoint.cpp @@ -0,0 +1,161 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +p = QPoint() + +p.setX(p.x() + 1) +p += QPoint(1, 0) +//! [0] + + +//! [1] +p = QPoint(1, 2) +#p.rx()--; // p becomes (0, 2) +//! [1] + + +//! [2] +p = QPoint(1, 2) +#p.ry()++; // p becomes (1, 3) +//! [2] + + +//! [3] +p = QPoint( 3, 7) +q = QPoint(-1, 4) +p += q # p becomes (2, 11) +//! [3] + + +//! [4] +p = QPoint( 3, 7) +q = QPoint(-1, 4) +p -= q # p becomes (4, 3) +//! [4] + + +//! [5] +p = QPoint(-1, 4) +p *= 2.5 # p becomes (-3, 10) +//! [5] + + +//! [6] +p = QPoint(-3, 10) +p /= 2.5 # p becomes (-1, 4) +//! [6] + + +//! [7] + +class MyWidget(QWidget): + + self.oldPosition = QPointer() + + # event : QMouseEvent + def mouseMoveEvent(QMouseEvent event): + point = event.pos() - self.oldPosition + if (point.manhattanLength() > 3): + # the mouse has moved more than 3 pixels since the oldPosition + pass +//! [7] + + +//! [8] +trueLength = sqrt(pow(x(), 2) + pow(y(), 2)) +//! [8] + + +//! [9] +p = QPointF() + +p.setX(p.x() + 1.0) +p += QPointF(1.0, 0.0) +#p.rx()++; +//! [9] + + +//! [10] + p = QPointF(1.1, 2.5) + #p.rx()--; // p becomes (0.1, 2.5) +//! [10] + + +//! [11] +p = QPointF(1.1, 2.5) +#p.ry()++; // p becomes (1.1, 3.5) +//! [11] + + +//! [12] +p = QPointF( 3.1, 7.1) +q = QPointF(-1.0, 4.1) +p += q # p becomes (2.1, 11.2) +//! [12] + + +//! [13] +p = QPointF( 3.1, 7.1) +q = QPointF(-1.0, 4.1) +p -= q # p becomes (4.1, 3.0) +//! [13] + + +//! [14] +p = QPointF(-1.1, 4.1) +p *= 2.5 # p becomes (-2.75, 10.25) +//! [14] + + +//! [15] +p = QPointF(-2.75, 10.25) +p /= 2.5 # p becomes (-1.1, 4.1) +//! [15] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qqueue.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qqueue.cpp new file mode 100644 index 0000000..a0ea405 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qqueue.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QQueue queue; +queue.enqueue(1); +queue.enqueue(2); +queue.enqueue(3); +while (!queue.isEmpty()) + cout << queue.dequeue() << endl; +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qrect.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qrect.cpp new file mode 100644 index 0000000..a388275 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qrect.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +r1 = QRect(100, 200, 11, 16) +r2 = QRect(QPoint(100, 200), QSize(11, 16)) +//! [0] + + +//! [1] +r1 = QRectF(100, 200, 11, 16) +r2 = QRectF(QPoint(100, 200), QSize(11, 16)) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qregexp.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qregexp.cpp new file mode 100644 index 0000000..d3f45bb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qregexp.cpp @@ -0,0 +1,225 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +rx = QRegExp("(\\d+)") +txt = "Offsets: 12 14 99 231 7" +lst = [] + +pos = rx.indexIn(txt, 0) + +while pos != -1: + lst.append(rx.cap(1)) + pos += rx.matchedLength() + pos = rx.indexIn(txt, pos) + +# lst: ["12", "14", "99", "231", "7"] +//! [0] + + +//! [1] +rx = QRegExp("*.txt") +rx.setPatternSyntax(QRegExp.Wildcard) +rx.exactMatch("README.txt") # returns True +rx.exactMatch("welcome.txt.bak") # returns False +//! [1] + + +//! [2] +rx = QRegExp("ro+m") +rx.setMinimal(True) +//! [2] + + +//! [3] +mark = QRegExp("\\b" # word boundary + "[Mm]ark" # the word we want to match + ) +//! [3] + + +//! [4] +rx = QRegExp("^\\d\\d?$") # match integers 0 to 99 +rx.indexIn("123") # returns -1 (no match) +rx.indexIn("-6") # returns -1 (no match) +rx.indexIn("6") # returns 0 (matched as position 0) +//! [4] + + +//! [5] +rx = QRegExp("^\\S+$") # match strings without whitespace +rx.indexIn("Hello world") # returns -1 (no match) +rx.indexIn("This_is-OK") # returns 0 (matched at position 0) +//! [5] + + +//! [6] +rx = QRegExp("\\b(mail|letter|correspondence)\\b") +rx.indexIn("I sent you an email") # returns -1 (no match) +rx.indexIn("Please write the letter") # returns 17 +//! [6] + + +//! [7] +captured = rx.cap(1) # captured == "letter" +//! [7] + + +//! [8] +rx = QRegExp("&(?!amp;)") # match ampersands but not & +line1 = QString("This & that") +line1.replace(rx, "&") # line1 == "This & that" +line2 = QString("His & hers & theirs") +line2.replace(rx, "&") # line2 == "His & hers & theirs" +//! [8] + + +//! [9] +txt = QString("One Eric another Eirik, and an Ericsson. How many Eiriks, Eric?") +rx = QRegExp("\\b(Eric|Eirik)\\b") # match Eric or Eirik +pos = 0 # where we are in the string +count = 0 # how many Eric and Eirik's we've counted + +while pos >= 0: + pos = rx.indexIn(txt, pos) + if pos >= 0: + pos += 1 # move along in str + count += 1 # count our Eric or Eirik +//! [9] + + +//! [10] +txt = "The Qt Company Ltd\tqt.io\tFinland" +rx.setPattern("^([^\t]+)\t([^\t]+)\t([^\t]+)$"); +if rx.indexIn(txt) != -1: + company = rx.cap(1) + web = rx.cap(2) + country = rx.cap(3) +//! [10] + + +//! [11] +field = txt.split("\t") +//! [11] + + +//! [12] +rx = QRegExp("*.html") +rx.setPatternSyntax(QRegExp.Wildcard) +rx.exactMatch("index.html") # returns True +rx.exactMatch("default.htm") # returns False +rx.exactMatch("readme.txt") # returns False +//! [12] + + +//! [13] +txt = QString("offsets: 1.23 .50 71.00 6.00") +rx = QRegExp("\\d*\\.\\d+") # primitive floating point matching +count = 0 +pos = rx.indexIn(txt, 0) +while pos != -1: + count += 1 + pos += rx.matchedLength() + pos = rx.indexIn(txt, pos) + +# pos will be 9, 14, 18 and finally 24; count will end up as 4 +//! [13] + + +//! [14] +rx = QRegExp("(\\d+)(\\s*)(cm|inch(es)?)") +pos = rx.indexIn("Length: 36 inches") +lst = rx.capturedTexts() +# lst is now ("36 inches", "36", " ", "inches", "es") +//! [14] + + +//! [15] +rx = QRegExp("(\\d+)(?:\\s*)(cm|inch(?:es)?)") +pos = rx.indexIn("Length: 36 inches") +lst = rx.capturedTexts() +# lst is now ("36 inches", "36", "inches") +//! [15] + + +//! [16] +for a in rx.capturedTexts(): + myProcessing(a) +//! [16] + + +//! [17] +rxlen = QRegExp("(\\d+)(?:\\s*)(cm|inch)") +pos = rxlen.indexIn("Length: 189cm") +if pos > -1: + value = rxlen.cap(1) # "189" + unit = rxlen.cap(2) # "cm" +//! [17] + + +//! [18] +rx = QRegExp("/([a-z]+)/([a-z]+)") +rx.indexIn("Output /dev/null") # returns 7 (position of /dev/null) +rx.pos(0) # returns 7 (position of /dev/null) +rx.pos(1) # returns 8 (position of dev) +rx.pos(2) # returns 12 (position of null) +//! [18] + + +//! [19] +s1 = QRegExp.escape("bingo") # s1 == "bingo" +s2 = QRegExp.escape("f(x)") # s2 == "f\\(x\\)" +//! [19] + + +//! [20] +rx = QRegExp("(" + QRegExp.escape(name) + "|" + QRegExp.escape(alias) + ")") +//! [20] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qsize.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qsize.cpp new file mode 100644 index 0000000..ef8b297 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qsize.cpp @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +t1 = QSize(10, 12) +t1.scale(60, 60, Qt.IgnoreAspectRatio) +# t1 is (60, 60) + +t2 = QSize(10, 12) +t2.scale(60, 60, Qt.KeepAspectRatio) +# t2 is (50, 60) + +t3 = QSize(10, 12) +t3.scale(60, 60, Qt.KeepAspectRatioByExpanding) +# t3 is (60, 72) +//! [0] + + +//! [1] +size = QSize(100, 10) +size.rwidth() += 20 + +#size becomes (120,10) +//! [1] + + +//! [2] +size = QSize(100, 10) +size.rheight() += 5 + +# size becomes (100,15) +//! [2] + + +//! [3] +s = QSize( 3, 7) +r = QSize(-1, 4) +s += r + +# s becomes (2,11) +//! [3] + + +//! [4] +s = QSize( 3, 7) +r = QSize(-1, 4) +s -= r + +# s becomes (4,3) +//! [4] + + +//! [5] +t1 = QSizeF(10, 12) +t1.scale(60, 60, Qt.IgnoreAspectRatio) +# t1 is (60, 60) + +t2 = QSizeF(10, 12) +t2.scale(60, 60, Qt.KeepAspectRatio) +# t2 is (50, 60) + +t3 = QSizeF(10, 12) +t3.scale(60, 60, Qt.KeepAspectRatioByExpanding) +# t3 is (60, 72) +//! [5] + + +//! [6] +size = QSizeF(100.3, 10) +size.rwidth() += 20.5 + +# size becomes (120.8,10) +//! [6] + + +//! [7] +size = QSizeF(100, 10.2) +size.rheight() += 5.5 + +# size becomes (100,15.7) +//! [7] + + +//! [8] +s = QSizeF( 3, 7) +r = QSizeF(-1, 4) +s += r + +# s becomes (2,11) +//! [8] + + +//! [9] +s = QSizeF( 3, 7) +r = QSizeF(-1, 4) +s -= r + +# s becomes (4,3) +//! [9] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qstring.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qstring.cpp new file mode 100644 index 0000000..8225d16 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qstring.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +DEFINES += QT_NO_CAST_FROM_ASCII \ + QT_NO_CAST_TO_ASCII +//! [0] + + +//! [1] +url = QLatin1String("http://www.unicode.org/") +//! [1] + + +//! [2] +d = 12.34; +str = QString("delta: %1").arg(d, 0, 'E', 3) +# str == "delta: 1.234E+01" +//! [2] + + +//! [3] +if str == "auto" || str == "extern" || str == "static" || str == "register": + ... +//! [3] + + +//! [4] +if str == QString("auto") || + str == QString("extern") || + str == QString("static") || + str == QString("register"): + ... +//! [4] + + +//! [5] +if str == QLatin1String("auto") || + str == QLatin1String("extern") || + str == QLatin1String("static") || + str == QLatin1String("register"): + ... +//! [5] + + +//! [6] +label = QLabel(QLatin1String("MOD"), self) +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qtimeline.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qtimeline.cpp new file mode 100644 index 0000000..480731a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qtimeline.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +... +progressBar = QProgressBar(self) +progressBar.setRange(0, 100) + +# Construct a 1-second timeline with a frame range of 0 - 100 +timeLine = QTimeLine(1000, self) +timeLine.setFrameRange(0, 100) +timeLine.frameChanged[int].connect(progressBar.setValue) + +# Clicking the push button will start the progress bar animation +pushButton = QPushButton(QObject.tr("Start animation"), self) +pushButton.clicked.connect(timeLine.start) +... +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qvector.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qvector.cpp new file mode 100644 index 0000000..57ffcae --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_tools_qvector.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QVector integerVector; +QVector stringVector; +//! [0] + + +//! [1] +QVector vector(200); +//! [1] + + +//! [2] +QVector vector(200, "Pass"); +//! [2] + + +//! [3] +if (vector[0] == "Liz") + vector[0] = "Elizabeth"; +//! [3] + + +//! [4] +for (int i = 0; i < vector.size(); ++i) { + if (vector.at(i) == "Alfonso") + cout << "Found Alfonso at position " << i << endl; +} +//! [4] + + +//! [5] +int i = vector.indexOf("Harumi"); +if (i != -1) + cout << "First occurrence of Harumi is at position " << i << endl; +//! [5] + + +//! [6] +QVector vector(10); +int *data = vector.data(); +for (int i = 0; i < 10; ++i) + data[i] = 2 * i; +//! [6] + + +//! [7] +QVector vector(0); +vector.append("one"); +vector.append("two"); +vector.append("three"); +// vector: ["one", "two", "three"] +//! [7] + + +//! [8] +QVector vector; +vector.prepend("one"); +vector.prepend("two"); +vector.prepend("three"); +// vector: ["three", "two", "one"] +//! [8] + + +//! [9] +QVector vector; +vector << "alpha" << "beta" << "delta"; +vector.insert(2, "gamma"); +// vector: ["alpha", "beta", "gamma", "delta"] +//! [9] + + +//! [10] +QVector vector; +vector << 2.718 << 1.442 << 0.4342; +vector.insert(1, 3, 9.9); +// vector: [2.718, 9.9, 9.9, 9.9, 1.442, 0.4342] +//! [10] + + +//! [11] +QVector vector(3); +vector.fill("Yes"); +// vector: ["Yes", "Yes", "Yes"] + +vector.fill("oh", 5); +// vector: ["oh", "oh", "oh", "oh", "oh"] +//! [11] + + +//! [12] +QVector vector; +vector << "A" << "B" << "C" << "B" << "A"; +vector.indexOf("B"); // returns 1 +vector.indexOf("B", 1); // returns 1 +vector.indexOf("B", 2); // returns 3 +vector.indexOf("X"); // returns -1 +//! [12] + + +//! [13] +QList vector; +vector << "A" << "B" << "C" << "B" << "A"; +vector.lastIndexOf("B"); // returns 3 +vector.lastIndexOf("B", 3); // returns 3 +vector.lastIndexOf("B", 2); // returns 1 +vector.lastIndexOf("X"); // returns -1 +//! [13] + + +//! [14] +QVector vect; +vect << "red" << "green" << "blue" << "black"; + +QList list = vect.toList(); +// list: ["red", "green", "blue", "black"] +//! [14] + + +//! [15] +QStringList list; +list << "Sven" << "Kim" << "Ola"; + +QVector vect = QVector::fromList(list); +// vect: ["Sven", "Kim", "Ola"] +//! [15] + + +//! [16] +std::vector stdvector; +vector.push_back(1.2); +vector.push_back(0.5); +vector.push_back(3.14); + +QVector vector = QVector::fromStdVector(stdvector); +//! [16] + + +//! [17] +QVector vector; +vector << 1.2 << 0.5 << 3.14; + +std::vector stdvector = vector.toStdVector(); +//! [17] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp new file mode 100644 index 0000000..f03a906 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_corelib_xml_qxmlstream.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +xml = QXmlStreamReader() +... +while not xml.atEnd(): + xml.readNext(); + ... # do processing + +if xml.hasError(): + ... # do error handling + +//! [0] + + +//! [1] +writeStartElement(qualifiedName) +writeCharacters(text) +writeEndElement() +//! [1] + + +//! [2] +writeStartElement(namespaceUri, name) +writeCharacters(text) +writeEndElement() +//! [2] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp new file mode 100644 index 0000000..9971983 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_accessible_qaccessible.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +child = QAccessibleInterface() +targetChild = object.navigate(Accessible.Child, 1, child) +if child: + # ... + del child +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp new file mode 100644 index 0000000..db6a8a8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qabstractprintdialog.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +printDialog = QPrintDialog(printer, parent) +if printDialog.exec_() == QDialog.Accepted: + # print ... +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp new file mode 100644 index 0000000..dd5f81b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfiledialog.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +fileName = QFileDialog.getOpenFileName(self, + tr("Open Image"), "/home/jana", tr("Image Files (*.png *.jpg *.bmp)")) +//! [0] + + +//! [1] +"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)" +//! [1] + + +//! [2] +dialog = QFileDialog(self) +dialog.setFileMode(QFileDialog.AnyFile) +//! [2] + + +//! [3] +dialog.setNameFilter(tr("Images (*.png *.xpm *.jpg)")) +//! [3] + + +//! [4] +dialog.setViewMode(QFileDialog.Detail) +//! [4] + + +//! [5] +if dialog.exec_(): + fileNames = dialog.selectedFiles() +//! [5] + + +//! [6] +dialog.setNameFilter("All C++ files (*.cpp *.cc *.C *.cxx *.c++)") +dialog.setNameFilter("*.cpp *.cc *.C *.cxx *.c++") +//! [6] + + +//! [7] +filters = QStringList() +filters << "Image files (*.png *.xpm *.jpg)" + << "Text files (*.txt)" + << "Any files (*)" + +dialog = QFileDialog(this) +dialog.setNameFilters(filters) +dialog.exec_() +//! [7] + + +//! [8] +fileName = QFileDialog.getOpenFileName(self, tr("Open File"), + "/home", + tr("Images (*.png *.xpm *.jpg)")) +//! [8] + + +//! [9] +files = QFileDialog.getOpenFileNames(self, + "Select one or more files to open", + "/home", + "Images (*.png *.xpm *.jpg)") +//! [9] + + +//! [10] +for it in list: + myProcessing(it) + it++ +//! [10] + + +//! [11] +fileName = QFileDialog.getSaveFileName(self, tr("Save F:xile"), + "/home/jana/untitled.png", + tr("Images (*.png *.xpm *.jpg)")) +//! [11] + + +//! [12] +dir = QFileDialog.getExistingDirectory(self, tr("Open Directory"), + "/home", + QFileDialog.ShowDirsOnly + | QFileDialog.DontResolveSymlinks) +//! [12] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp new file mode 100644 index 0000000..6c91d21 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qfontdialog.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +(ok, font) = QFontDialog.getFont(QFont("Helvetica [Cronyx]", 10), self) +if ok: + # the user clicked OK and font is set to the font the user selected +else: + # the user canceled the dialog; font is set to the initial + # value, in this case Helvetica [Cronyx], 10 +//! [0] + + +//! [1] +myWidget.setFont(QFontDialog.getFont(0, myWidget.font())) +//! [1] + + +//! [2] +(ok, font) = QFontDialog.getFont(QFont("Times", 12), self) +if ok: + # font is set to the font the user selected +else: + # the user canceled the dialog; font is set to the initial + # value, in this case Times, 12. +//! [2] + + +//! [3] +myWidget.setFont(QFontDialog.getFont(0, myWidget.font())) +//! [3] + + +//! [4] + +(ok, font) = QFontDialog.getFont(self) +if ok: + # font is set to the font the user selected +else: + # the user canceled the dialog; font is set to the default + # application font, QApplication.font() +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qwizard.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qwizard.cpp new file mode 100644 index 0000000..9db90a7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_dialogs_qwizard.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def nextId(self): + id = self.currentId() + if id == Page_Intro: + if field("intro.evaluate").toBool(): + return Page_Evaluate + else: + return Page_Register + elif id == Page_Evaluate: + return Page_Conclusion + elif id == Page_Register: + if field("register.upgradeKey").toString().isEmpty(): + return Page_Details + else: + return Page_Conclusion + elif id == Page_Details: + return Page_Conclusion + else: + return -1 +//! [0] + + +//! [1] +class MyWizard(QWizard): + def __init__(self, parent): + QWizard.__ini__(self, parent) + ... + layout = [QWizard.Stretch, QWizard.BackButton, QWizard.CancelButton, QWizard.NextButton, QWizard.FinishButton] + setButtonLayout(layout); + ... +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp new file mode 100644 index 0000000..d4b47fa --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_effects_qgraphicseffect.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def draw(self, painter): + # Fully opaque draw directly without going through a pixmap. + if qFuzzyCompare(self.opacity, 1): + drawSource(painter) + return + # ... +//! [0] + +//! [1] +def draw(self, painter): + # ... + offset = QPoint() + if self.sourceIsPixmap(): + # No point in drawing in device coordinates (pixmap will be scaled anyways). + pixmap = sourcePixmap(Qt.LogicalCoordinates, offset) + ... + painter.drawPixmap(offset, pixmap) + else: + # Draw pixmap in device coordinates to avoid pixmap scaling + pixmap = sourcePixmap(Qt.DeviceCoordinates, offset) + painter.setWorldTransform(QTransform()) + # ... + painter.drawPixmap(offset, pixmap) + # ... +//! [1] + +//! [2] +# ... +alphaGradient = QLinearGradient(rect.topLeft(), rect.bottomLeft()) +alphaGradient.setColorAt(0.0, Qt.transparent) +alphaGradient.setColorAt(0.5, Qt.black) +alphaGradient.setColorAt(1.0, Qt.transparent) +effect = QGraphicsOpacityEffect() +effect.setOpacityMask(alphaGradient) +# ... +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsgridlayout.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsgridlayout.cpp new file mode 100644 index 0000000..4d138db --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsgridlayout.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +scene = QGraphicsScene() +textEdit = scene.addWidget(QTextEdit()) +pushButton = scene.addWidget(QPushButton()) + +layout = QGraphicsGridLayout() +layout.addItem(textEdit, 0, 0) +layout.addItem(pushButton, 0, 1) + +form = QGraphicsWidget() +form.setLayout(layout) +scene.addItem(form) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp new file mode 100644 index 0000000..59f26c7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class SimpleItem(QGraphicsItem): + + def boundingRect(self): + penWidth = 1.0 + return QRectF(-10 - penWidth / 2, -10 - penWidth / 2, + 20 + penWidth, 20 + penWidth) + + def paint(self, painter, option, widget): + painter.drawRoundedRect(-10, -10, 20, 20, 5, 5) +//! [0] + + +//! [1] +class CustomItem(QGraphicsItem): + ... + self.Type = QGraphicsItem.UserType + 1 + + def type(self): + # Enable the use of qgraphicsitem_cast with this item. + return self.Type + ... + +//! [1] + + +//! [2] +item.setCursor(Qt.IBeamCursor) +//! [2] + + +//! [3] +item.setCursor(Qt.IBeamCursor) +//! [3] + + +//! [4] +rect = QGraphicsRectItem() +rect.setPos(100, 100) + +rect.sceneTransform().map(QPointF(0, 0)) +# returns QPointF(100, 100) + +rect.sceneTransform().inverted().map(QPointF(100, 100)) +# returns QPointF(0, 0); +//! [4] + + +//! [5] +rect = QGraphicsRectItem() +rect.setPos(100, 100) + +rect.deviceTransform(view.viewportTransform()).map(QPointF(0, 0)) +# returns the item's (0, 0) point in view's viewport coordinates + +rect.deviceTransform(view.viewportTransform()).inverted().map(QPointF(100, 100)) +# returns view's viewport's (100, 100) coordinate in item coordinates +//! [5] + + +//! [6] +# Rotate an item 45 degrees around (0, 0) +item.rotate(45) + +# Rotate an item 45 degrees around (x, y) +item.setTransform(QTransform().translate(x, y).rotate(45).translate(-x, -y)) +//! [6] + + +//! [7] +# Scale an item by 3x2 from its origin +item.scale(3, 2) + +# Scale an item by 3x2 from (x, y) +item.setTransform(QTransform().translate(x, y).scale(3, 2).translate(-x, -y)) +//! [7] + + +//! [8] +def boundingRect(self): + penWidth = 1.0 + return QRectF(-radius - penWidth / 2, -radius - penWidth / 2, + diameter + penWidth, diameter + penWidth) +//! [8] + + +//! [9] +def shape(self): + path = QPainterPath() + path.addEllipse(boundingRect()) + return path +//! [9] + + +//! [10] +def paint(self, painter, option, widget): + painter.drawRoundedRect(-10, -10, 20, 20, 5, 5) +//! [10] + + +//! [11] +ObjectName = 0; + +item = scene.itemAt(100, 50) +if len(item.data(ObjectName)) == 0: + if isinstance(ButtonItem, item): + item.setData(ObjectName, "Button") +//! [11] + + +//! [12] +scene = QGraphicsScene() +ellipse = scene.addEllipse(QRectF(-10, -10, 20, 20)) +line = scene.addLine(QLineF(-10, -10, 20, 20)) + +line.installSceneEventFilter(ellipse) +# line's events are filtered by ellipse's sceneEventFilter() function. + +ellipse.installSceneEventFilter(line) +# ellipse's events are filtered by line's sceneEventFilter() function. +//! [12] + + +//! [13] +def contextMenuEvent(self, event): + menu = QMenu() + removeAction = menu.addAction("Remove") + markAction = menu.addAction("Mark") + selectedAction = menu.exec(event.screenPos()) + // ... +//! [13] + + +//! [14] +def __init__(self): + self.setAcceptDrops(true) + ... + +def dragEnterEvent(self, event): + event.setAccepted(event.mimeData().hasFormat("text/plain")) +//! [14] + + +//! [15] +def itemChange(self, change, value): + if change == ItemPositionChange && scene(): + # value is the new position. + rect = scene().sceneRect() + if !rect.contains(value): + # Keep the item inside the scene rect. + value.setX(qMin(rect.right(), qMax(value.x(), rect.left()))) + value.setY(qMin(rect.bottom(), qMax(value.y(), rect.top()))) + return value + return QGraphicsItem.itemChange(self, change, value) +//! [15] + + +//! [16] +def setRadius(self, newRadius): + if radius != newRadius: + prepareGeometryChange() + radius = newRadius +//! [16] + + +//! [17] +# Group all selected items together +group = scene.createItemGroup(scene.selecteditems()) + +# Destroy the group, and delete the group item +scene.destroyItemGroup(group) +//! [17] + + +//! [QGraphicsItem type] +class CustomItem(QGraphicsItem): + ... + self.Type = QGraphicsItem.UserType + 1 + + def type(self): + # Enable the use of qgraphicsitem_cast with this item. + return self.Type + ... +//! [QGraphicsItem type] + +//! [18] +class QGraphicsPathItem (QAbstractGraphicsShapeItem): + Type = 2 + + def type(self): + return QGraphicsPathItem.Type +# ... +//! [18] + +//! [19] +xform = item.deviceTransform(view.viewportTransform()) +deviceRect = xform.mapRect(rect).toAlignedRect() +view.viewport().scroll(dx, dy, deviceRect) +//! [19] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicslinearlayout.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicslinearlayout.cpp new file mode 100644 index 0000000..8e7dcc4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicslinearlayout.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +scene = QGraphicsScene() +textEdit = scene.addWidget(QTextEdit()) +pushButton = scene.addWidget(QPushButton()) + +layout = QGraphicsLinearLayout() +layout.addItem(textEdit) +layout.addItem(pushButton) + +form = QGraphicsWidget() +form.setLayout(layout) +scene.addItem(form) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp new file mode 100644 index 0000000..d0d21a6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsproxywidget.cpp @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import sys + +QApplication app(sys.argv) + +tabWidget = QTabWidget() + +scene = QGraphicsScene() +proxy = scene.addWidget(tabWidget) + +view = QGraphicsView(scene) +view.show() + +return app.exec_() +//! [0] + +//! [1] +groupBox = QGroupBox("Contact Details") +numberLabel = QLabel("Telephone number") +numberEdit = QLineEdit() + +layout = QFormLayout() +layout.addRow(numberLabel, numberEdit) +groupBox.setLayout(layout) + +scene = QGraphicsScene() +proxy = scene.addWidget(groupBox) + +view = QGraphicsView(scene) +view.show() +//! [1] + +//! [2] +scene = QGraphicsScene() + +edit = QLineEdit() +proxy = scene.addWidget(edit) + +edit.isVisible() // returns true +proxy.isVisible() // also returns true + +edit.hide() + +edit.isVisible() // returns false +proxy.isVisible() // also returns false +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp new file mode 100644 index 0000000..1f1316b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsscene.cpp @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +scene = QGraphicsScene() +scene.addText("Hello, world!") + +view = QGraphicsView(&scene) +view.show() +//! [0] + + +//! [1] +scene = QGraphicsScene +scene.addItem(... +... +printer = QPrinter(QPrinter.HighResolution) +printer.setPaperSize(QPrinter.A4) + +painter = QPainter(printer) +scene.render(&painter) +//! [1] + + +//! [2] +segmentSize = sceneRect().size() / math.pow(2, depth - 1) +//! [2] + + +//! [3] +scene = QGraphicsScene() +view = QGraphicsView(scene) +view.show() + +# a blue background +scene.setBackgroundBrush(Qt.blue) + +# a gradient background +gradient = QRadialGradient(0, 0, 10) +gradient.setSpread(QGradient.RepeatSpread) +scene.setBackgroundBrush(gradient) +//! [3] + + +//! [4] +scene = QGraphicsScene() +view = QGraphicsView(scene) +view.show() + +# a white semi-transparent foreground +scene.setForegroundBrush(QColor(255, 255, 255, 127)) + +# a grid foreground +scene.setForegroundBrush(QBrush(Qt.lightGray, Qt.CrossPattern)) +//! [4] + + +//! [5] +class TileScene (QGraphicsScene): + # ... + def rectForTile(x, y): + # Return the rectangle for the tile at position (x, y). + return QRectF(x * self.tileWidth, y * self.tileHeight, self.tileWidth, self.tileHeight) + + def setTile(x, y, pixmap): + # Sets or replaces the tile at position (x, y) with pixmap. + if x >= 0 && x < self.numTilesH && y >= 0 && y < self.numTilesV: + self.tiles[y][x] = pixmap + invalidate(rectForTile(x, y), BackgroundLayer) + + def drawBackground(painter, exposed): + # Draws all tiles that intersect the exposed area. + for y in range(0, self.numTilesV: + for x in range(0, self.numTilesH: + rect = rectForTile(x, y) + if exposed.intersects(rect): + painter.drawPixmap(rect.topLeft(), tiles[y][x]) +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp new file mode 100644 index 0000000..afb5f9f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicssceneevent.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +setDropAction(proposedAction()) + +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp new file mode 100644 index 0000000..d13cee8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicsview.cpp @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +scene = QGraphicsScene() +scene.addText("Hello, world!") + +view = QGraphicsView(scene) +view.show() +//! [0] + + +//! [1] +scene = QGraphicsScene() +scene.addRect(QRectF(-10, -10, 20, 20)) + +view = QGraphicsView(scene) +view.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) +view.show() +//! [1] + + +//! [2] +view = QGraphicsView() +view.setBackgroundBrush(QImage(":/images/backgroundtile.png")) +view.setCacheMode(QGraphicsView.CacheBackground) +//! [2] + + +//! [3] +scene = QGraphicsScene() +scene.addText("GraphicsView rotated clockwise") + +view = QGraphicsView(scene) +view.rotate(90) # the text is rendered with a 90 degree clockwise rotation +view.show() +//! [3] + + +//! [4] +scene = QGraphicsScene() +scene.addItem(... +... + +view = QGraphicsView(scene) +view.show() +... + +printer = QPrinter(QPrinter.HighResolution) +printer.setPageSize(QPrinter.A4) +painter = QPainter(printer) + +# print, fitting the viewport contents into a full page +view.render(painter) + +# print the upper half of the viewport into the lower. +# half of the page. +viewport = view.viewport()->rect() +view.render(painter, + QRectF(0, printer.height() / 2, + printer.width(), printer.height() / 2), + viewport.adjusted(0, 0, 0, -viewport.height() / 2)) + +//! [4] + + +//! [5] +def mousePressEvent(self, event): + print "There are", items(event->pos()).size(), "items at position", mapToScene(event->pos()) +//! [5] + + +//! [6] +def mousePressEvent(self, event): + if (item = itemAt(event.pos()): + print "You clicked on item", item + else: + print "You didn't click on an item." +//! [6] + + +//! [7] +scene = QGraphicsScene() +scene.addText("GraphicsView rotated clockwise") + +view = QGraphicsView(scene) +view.rotate(90) # the text is rendered with a 90 degree clockwise rotation +view.show() +//! [7] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp new file mode 100644 index 0000000..ffba7a1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_graphicsview_qgraphicswidget.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyGroupBoxWidget (QStyleOptionGroupBox): + # ... + def initStyleOption(option): + QGraphicsWidget.initStyleOption(self, option) + if isinstance(option, QStyleOptionGroupBox): + # Add group box specific state. + box.flat = isFlat() + # ... +//! [0] + + +//! [1] +setTabOrder(a, b) # a to b +setTabOrder(b, c) # a to b to c +setTabOrder(c, d) # a to b to c to d +//! [1] + + +//! [2] +# WRONG +setTabOrder(c, d) # c to d +setTabOrder(a, b) # a to b AND c to d +setTabOrder(b, c) # a to b to c, but not c to d +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qbitmap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qbitmap.cpp new file mode 100644 index 0000000..aab995f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qbitmap.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +uchar arrow_bits[] = { 0x3f, 0x1f, 0x0f, 0x1f, 0x3b, 0x71, 0xe0, 0xc0 }; +QBitmap bm(8, 8, arrow_bits, true); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qicon.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qicon.cpp new file mode 100644 index 0000000..d40f485 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qicon.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +button = QToolButton() +button.setIcon(QIcon("open.xpm")) +//! [0] + + +//! [1] +button.setIcon(QIcon()) +//! [1] + + +//! [2] +def drawIcon(self, painter, pos): + enabledStatus = QIcon.Normal + if not isEnabled(): + enabledStatus = QIcon::Disabled + + onOff = QIcon.On + if not isOn(): + onOff = QIcon.Off + + pixmap = self.icon.pixmap(QSize(22, 22), enabledStatus, onOff) + painter.drawPixmap(pos, pixmap) +//! [2] + +//! [3] + undoicon = QIcon.fromTheme("edit-undo") +//! [3] + +//! [4] + undoicon = QIcon.fromTheme("edit-undo", QIcon(":/undo.png")) +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimage.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimage.cpp new file mode 100644 index 0000000..e100624 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimage.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +image = QImage(3, 3, QImage.Format_RGB32) + +value = qRgb(189, 149, 39) # 0xffbd9527 +image.setPixel(1, 1, value) + +value = qRgb(122, 163, 39) # 0xff7aa327 +image.setPixel(0, 1, value) +image.setPixel(1, 0, value) + +value = qRgb(237, 187, 51) # 0xffedba31 +image.setPixel(2, 1, value) +//! [0] + + +//! [1] +image = QImage(3, 3, QImage.Format_Indexed8) +value = qRgb(122, 163, 39) # 0xff7aa327 +image.setColor(0, value) + +value = qRgb(237, 187, 51) # 0xffedba31 +image.setColor(1, value) + +value = qRgb(189, 149, 39) # 0xffbd9527 +image.setColor(2, value) + +image.setPixel(0, 1, 0) +image.setPixel(1, 0, 0) +image.setPixel(1, 1, 2) +image.setPixel(2, 1, 1) +//! [1] + + +//! [2] +start_xpm = ["16 15 8 1", "a c #cec6bd", .... +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagereader.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagereader.cpp new file mode 100644 index 0000000..2e36ba8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagereader.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +reader = QImageReader() +reader.setFormat("png") # same as reader.setFormat("PNG") +//! [0] + + +//! [1] +reader = QImageReader("image.png") +# reader.format() == "png" +//! [1] + + +//! [2] +icon = QImage(64, 64, QImage.Format_RGB32) +reader = QImageReader("icon_64x64.bmp") +if reader.read(icon): + # Display icon +//! [2] + + +//! [3] +reader = QImageReader(":/image.png") +if reader.supportsOption(QImageIOHandler.Size): + print "Size:", str(reader.size()) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagewriter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagewriter.cpp new file mode 100644 index 0000000..b656817 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qimagewriter.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +writer = QImageWriter() +writer.setFormat("png") # same as writer.setFormat("PNG") +//! [0] + + +//! [1] +image = QImage("some/image.jpeg") +writer = QImageWriter("images/outimage.png", "png") +writer.setText("Author", "John Smith") +writer.write(image) +//! [1] + + +//! [2] +writer = QImageWriter(fileName) +if writer.supportsOption(QImageIOHandler.Description): + writer.setText("Author", "John Smith") +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qmovie.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qmovie.cpp new file mode 100644 index 0000000..050213e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qmovie.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +label = QLabel() +movie = QMovie("animations/fire.gif") + +label.setMovie(movie) +movie.start() +//! [0] + + +//! [1] +movie = QMovie("racecar.gif") +movie.setSpeed(200) // 2x speed +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmap.cpp new file mode 100644 index 0000000..76d359a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmap.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +static const char * const start_xpm[]={ + "16 15 8 1", + "a c #cec6bd", +.... +//! [0] + + +//! [1] +myPixmap = QPixmap() +myPixmap.setMask(myPixmap.createHeuristicMask()) +//! [1] + +//! [2] +pixmap = QPixmap("background.png") +exposed = QRegion() +pixmap.scroll(10, 10, pixmap.rect(), exposed) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp new file mode 100644 index 0000000..6112031 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapcache.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +pm = QPixmap() +if not QPixmapCache.find("my_big_image", pm): + pm.load("bigimage.png") + QPixmapCache.insert("my_big_image", pm) +painter.drawPixmap(0, 0, pm) +//! [0] + + +//! [1] +pm = QPixmap() +if not QPixmapCache.find("my_big_image", pm): + pm.load("bigimage.png") + QPixmapCache.insert("my_big_image", pm) +painter.drawPixmap(0, 0, pm) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp new file mode 100644 index 0000000..4fa6e79 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_image_qpixmapfilter.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +myFilter = QPixmapColorFilter() +myFilter.setColor(QColor(128, 0, 0)) +myFilter.draw(painter, QPoint(0, 0), originalPixmap) +//! [0] + +//! [1] +myFilter = QPixmapConvolutionFilter() +kernel = [ + 0.0,-1.0, 0.0, + -1.0, 5.0,-1.0, + 0.0,-1.0, 0.0 + ] +myFilter.setConvolutionKernel(kernel, 3, 3) +myFilter.sdraw(painter, QPoint(0, 0), originalPixmap) +//! [1] + +//! [2] +myFilter = QPixmapDropShadowFilter() +myFilter.draw(painter, QPoint(0, 0), originalPixmap) +//! [2] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp new file mode 100644 index 0000000..0d89ff7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qabstractitemview.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def resizeEvent(self, event): + horizontalScrollBar().setRange(0, realWidth - width()) + ... +//! [0] + +//! [1] +setIndexWidget(index, QLineEdit()) +... +setIndexWidget(index, QTextEdit()) +//! [1] + +//! [2] +m = view->selectionModel() +view->setModel(model()) +del m +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp new file mode 100644 index 0000000..54687e7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +mapper = QDataWidgetMapper +mapper.setModel(model) +mapper.addMapping(mySpinBox, 0) +mapper.addMapping(myLineEdit, 1) +mapper.addMapping(myCountryChooser, 2) +mapper.toFirst() +//! [0] + + +//! [1] +mapper = QDataWidgetMapper() +mapper.setModel(myModel) +mapper.addMapping(nameLineEdit, 0) +mapper.addMapping(ageSpinBox, 1) +//! [1] + + +//! [2] +mapper = QDataWidgetMapper() +connect(myTableView.selectionModel(), SIGNAL("currentRowChanged(QModelIndex,QModelIndex)"), + mapper, SLOT(setCurrentModelIndex(QModelIndex))) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemeditorfactory.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemeditorfactory.cpp new file mode 100644 index 0000000..44d0594 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemeditorfactory.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +Q_PROPERTY(QColor color READ color WRITE setColor USER true) +//! [0] + + +//! [1] +QItemEditorCreator *itemCreator = + new QItemEditorCreator("myProperty"); + +QItemEditorFactory *factory = new QItemEditorFactory; +//! [1] + + +//! [2] +QItemEditorFactory *editorFactory = new QItemEditorFactory; +QItemEditorCreatorBase *creator = new QStandardItemEditorCreator(); +editorFactory->registerEditor(QVariant::DateType, creator); +//! [2] + + +//! [3] +Q_PROPERTY(QColor color READ color WRITE setColor USER true) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp new file mode 100644 index 0000000..62861d9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qitemselectionmodel.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +selection = QItemSelection(topLeft, bottomRight) +//! [0] + + +//! [1] +selection = QItemSelection() +... +selection.select(topLeft, bottomRight) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp new file mode 100644 index 0000000..42a64fb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qstandarditemmodel.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +model = QStandardItemModel (4, 4) +for row in range(4): + for column in range(4): + item = QStandardItem("row %d, column %d" % (row, column)) + model.setItem(row, column, item) +//! [0] + + +//! [1] +model = QStandardItemModel() +parentItem = model.invisibleRootItem() +for i in range(4): + item = QStandardItem("item %d" % i) + parentItem.appendRow(item) + parentItem = item +//! [1] + + +//! [2] +treeView = QTreeView(self) +treeView.setModel(myStandardItemModel) +treeView.clicked[QModelIndex].connect(self.clicked) +//! [2] + + +//! [3] +def clicked(self, index): + item = myStandardItemModel.itemFromIndex(index) + # Do stuff with the item ... +//! [3] + + +//! [4] +treeView.scrollTo(item.index()) +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtablewidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtablewidget.cpp new file mode 100644 index 0000000..ca7c0db --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtablewidget.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +setCellWidget(index, QLineEdit()) +... +setCellWidget(index, QTextEdit()) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp new file mode 100644 index 0000000..ecdb794 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_itemviews_qtreewidget.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +treeWidget = QTreeWidget() +treeWidget.setColumnCount(1) +items = [] +for i in range(10): + items.append(QTreeWidgetItem(None, QStringList(QString("item: %1").arg(i)))) +treeWidget.insertTopLevelItems(None, items) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qaction.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qaction.cpp new file mode 100644 index 0000000..31a83e2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qaction.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +app = QApplication(argv) +app.setAttribute(Qt.AA_DontShowIconsInMenus) # Icons are *no longer shown* in menus +// ... +myAction = QAction() +// ... +myAction.setIcon(SomeIcon) +myAction.setIconVisibleInMenu(True) # Icon *will* be shown in menus for *this* action. +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication.cpp new file mode 100644 index 0000000..fe02c93 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication.cpp @@ -0,0 +1,167 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def main(): + useGUI = not '-no-gui' in sys.argv + app = QApplication(sys.argv) if useGUI else QCoreApplication(sys.argv) + ... + return app.exec_() +//! [0] + + +//! [1] +QApplication.setStyle(QWindowsStyle()) +//! [1] + + +//! [2] +def main(): + QApplication.setColorSpec(QApplication.ManyColor) + QApplication app(sys.argv) + ... + return app.exec_() + +//! [2] + + +//! [3] +class MyWidget (QWidget): + # ... + def sizeHint(self): + return QSize(80, 25).expandedTo(QApplication.globalStrut()) +//! [3] + + +//! [4] +def showAllHiddenTopLevelWidgets(): + for widget in QApplication.topLevelWidgets(): + if widget.isHidden(): + widget.show() +//! [4] + + +//! [5] +def updateAllWidgets(): + for widget in QApplication.allWidgets() + widget.update() +//! [5] + + +//! [6] +if __name__ == '__main__': + QApplication.setDesktopSettingsAware(False) + app = QApplication(sys.argv) + # ... + return app.exec_() +//! [6] + + +//! [7] +if (startPos - currentPos).manhattanLength() >= QApplication.startDragDistance(): + startTheDrag() +//! [7] + + +//! [8] +class MyApplication (QApplication): +# ... + def commitData(QSessionManager& manager) + if manager.allowsInteraction(): + ret = QMessageBox.warning( + mainWindow, + QObject.tr("My Application"), + QObject.tr("Save changes to document?"), + QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) + + if ret == QMessageBox.Save: + manager.release() + if not saveDocument(): + manager.cancel() + elif ret == QMessageBox.Discard: + pass + else: + manager.cancel() + else: + # we did not get permission to interact, then + # do something reasonable instead + pass +//! [8] + + +//! [9] +appname -session id +//! [9] + + +//! [10] +for command in mySession.restartCommand(): + do_something(command) +//! [10] + + +//! [11] +for command in mySession.discardCommand(): + do_something(command) +//! [11] + + +//! [12] +widget = qApp.widgetAt(x, y) +if widget: + widget = widget.window() +//! [12] + + +//! [13] +widget = qApp.widgetAt(point) +if widget: + widget = widget.window() +//! [13] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp new file mode 100644 index 0000000..5c90b99 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qapplication_x11.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) +calculateHugeMandelbrot() # lunch time... +QApplication.restoreOverrideCursor() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qclipboard.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qclipboard.cpp new file mode 100644 index 0000000..0148351 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qclipboard.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +clipboard = QGuiApplication.clipboard() +originalText = clipboard.text() +... +clipboard.setText(newText) +//! [0] + + +//! [1] +data = QMimeData() +data.setImageData(image) +clipboard.setMimeData(data, mode) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qevent.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qevent.cpp new file mode 100644 index 0000000..38d18d0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qevent.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def wheelEvent(self, event): + numDegrees = event.delta() / 8 + numSteps = numDegrees / 15 + + if event->orientation() == Qt.Horizontal: + scrollHorizontally(numSteps) + else: + scrollVertically(numSteps) + event.accept() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qformlayout.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qformlayout.cpp new file mode 100644 index 0000000..1b3e580 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qformlayout.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +formLayout = QFormLayout() +formLayout.addRow(self.tr("&Name:"), nameLineEdit) +formLayout.addRow(self.tr("&Email:"), emailLineEdit) +formLayout.addRow(self.tr("&Age:"), ageSpinBox) +setLayout(formLayout) +//! [0] + + +//! [1] +nameLabel = QLabel(self.tr("&Name:")) +nameLabel.setBuddy(nameLineEdit) + +emailLabel = QLabel(self.tr("&Name:")) +emailLabel.setBuddy(emailLineEdit) + +ageLabel = QLabel(self.tr("&Name:")) +ageLabel.setBuddy(ageSpinBox) + +gridLayout = QGridLayout() +gridLayout.addWidget(nameLabel, 0, 0) +gridLayout.addWidget(nameLineEdit, 0, 1) +gridLayout.addWidget(emailLabel, 1, 0) +gridLayout.addWidget(emailLineEdit, 1, 1) +gridLayout.addWidget(ageLabel, 2, 0) +gridLayout.addWidget(ageSpinBox, 2, 1) +setLayout(gridLayout) +//! [1] + + +//! [2] +formLayout.trowWrapPolicy(QFormLayout.DontWrapRows) +formLayout.setFieldGrowthPolicy(QFormLayout.FieldsStayAtSizeHint) +formLayout.setFormAlignment(Qt.AlignHCenter | Qt.AlignTop) +formLayout.setLabelAlignment(Qt.AlignLeft) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp new file mode 100644 index 0000000..25d5ee2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qkeysequence.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QKeySequence(QKeySequence.Print) +QKeySequence(tr("Ctrl+P")) +QKeySequence(tr("Ctrl+p")) +QKeySequence(Qt.CTRL + Qt.Key_P) +//! [0] + + +//! [1] +QKeySequence(tr("Ctrl+X, Ctrl+C")) +QKeySequence(Qt.CTRL + Qt.Key_X, Qt.CTRL + Qt.Key_C) +//! [1] + + +//! [2] +file = QMenu(self) +file.addAction(tr("&Open..."), self, SLOT("open()"), + QKeySequence(tr("Ctrl+O", "File|Open"))) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayout.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayout.cpp new file mode 100644 index 0000000..867e73b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayout.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +def paintLayout(self, painter, item): + layout = item.layout() + + if layout: + for layout_item in layout: + self.paintLayout(painter, layout_item) + + painter.drawRect(item.geometry()) + +def paintEvent(self, event): + painter = QPainter(self) + if self.layout(): + self.paintLayout(painter, self.layout()) + +//! [0] + + +//! [1] +child = layout.takeAt(0) +while child: + ... + del child +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayoutitem.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayoutitem.cpp new file mode 100644 index 0000000..8749f53 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qlayoutitem.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def heightForWidth(self, w): + if cache_dirty or cached_width != w: + h = calculateHeightForWidth(w) + self.cached_hfw = h + return h + return cached_hfw +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcut.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcut.cpp new file mode 100644 index 0000000..baaf605 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcut.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +shortcut = QShortcut(QKeySequence(self.tr("Ctrl+O", "File|Open")), + parent) +//! [0] + + +//! [1] +setKey(0) # no signal emitted +setKey(QKeySequence()) # no signal emitted +setKey(0x3b1) # Greek letter alpha +setKey(Qt.Key_D) # 'd', e.g. to delete +setKey('q') # 'q', e.g. to quit +setKey(Qt.CTRL + Qt.Key_P) # Ctrl+P, e.g. to print document +setKey("Ctrl+P") # Ctrl+P, e.g. to print document +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp new file mode 100644 index 0000000..48f63f6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qshortcutmap.cpp @@ -0,0 +1,3 @@ +//! [0] +key = QKeySequence() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qsound.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qsound.cpp new file mode 100644 index 0000000..6ad7ef4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qsound.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QSound.play("mysounds/bells.wav") +//! [0] + + +//! [1] +bells = QSound("mysounds/bells.wav") +bells.play() +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qwidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qwidget.cpp new file mode 100644 index 0000000..efa0f05 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_kernel_qwidget.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +w.setWindowState(w.windowState() ^ Qt.WindowFullScreen) +//! [0] + + +//! [1] +w.setWindowState(w.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) +//! [1] + + +//! [2] +width = widget.baseSize().width() + i * widget.sizeIncrement().width() +height = widget.baseSize().height() + j * widget.sizeIncrement().height() +//! [2] + + +//! [3] +aWidget.window().setWindowTitle("New Window Title") +//! [3] + + +//! [4] +font = QFont("Helvetica", 12, QFont.Bold) +widget.setFont(font) +//! [4] + + +//! [5] +font = QFont() +font.setBold(false) +widget.setFont(font) +//! [5] + + +//! [6] +widget.setCursor(Qt.IBeamCursor) +//! [6] + + +//! [7] +pixmap = QPixmap(widget.size()) +widget.render(&pixmap) +//! [7] + + +//! [8] +painter = QPainter(self) +... +painter.end() +myWidget.render(self) +//! [8] + + +//! [9] +widget.setTabOrder(a, b) # a to b +widget.setTabOrder(b, c) # a to b to c +widge.tsetTabOrder(c, d) # a to b to c to d +//! [9] + + +//! [10] +# WRONG +widget.setTabOrder(c, d) # c to d +widget.setTabOrder(a, b) # a to b AND c to d +widget.setTabOrder(b, c) # a to b to c, but not c to d +//! [10] + + +//! [11] +class MyWidget(QWidget): + + self.settings = None + + def closeEvent(event): + # event is a QCloseEvent + self.settings = QSettings("MyCompany", "MyApp") + self.settings.setValue("geometry", self.saveGeometry()) + QWidget.closeEvent(self, event) +//! [11] + + +//! [12] +settings = QSettings("MyCompany", "MyApp") +myWidget.restoreGeometry(settings.value("myWidget/geometry").toByteArray()) +//! [12] + + +//! [13] +widget.setUpdatesEnabled(False) +widget.bigVisualChanges() +widget.setUpdatesEnabled(True) +//! [13] + + +//! [14] +... +extern void qt_x11_set_global_double_buffer(bool); +qt_x11_set_global_double_buffer(false); +... +//! [14] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qbrush.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qbrush.cpp new file mode 100644 index 0000000..55fa8a7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qbrush.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +painter = QPainter(self) + +painter.setBrush(Qt.cyan) +painter.setPen(Qt.darkCyan) +painter.drawRect(0, 0, 100,100) + +painter.setBrush(Qt.NoBrush) +painter.setPen(Qt.darkGreen) +painter.drawRect(40, 40, 100, 100) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qcolor.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qcolor.cpp new file mode 100644 index 0000000..cac026a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qcolor.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +# Specify semi-transparent red +painter.setBrush(QColor(255, 0, 0, 127)) +painter.drawRect(0, 0, self.width()/2, self.height()) + +# Specify semi-transparent blue +painter.setBrush(QColor(0, 0, 255, 127)) +painter.drawRect(0, 0, self.width(), self.height()/2) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qdrawutil.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qdrawutil.cpp new file mode 100644 index 0000000..1f76792 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qdrawutil.cpp @@ -0,0 +1,108 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +frame = QFrame() +frame.setFrameStyle(QFrame.HLine | QFrame.Sunken) +//! [0] + + +//! [1] +frame = QFrame() +frame.setFrameStyle(QFrame.Box | QFrame.Raised) +//! [1] + + +//! [2] +frame = QFrame() +frame.setFrameStyle( QFrame.Panel | QFrame.Sunken) +//! [2] + + +//! [3] +frame = QFrame() +frame.setFrameStyle(QFrame.WinPanel | QFrame.Raised) +//! [3] + + +//! [4] +frame = QFrame() +frame.setFrameStyle(QFrame.Box | QFrame.Plain) +//! [4] + + +//! [5] +frame = QFrame() +frame.setFrameStyle(QFrame.HLine | QFrame.Sunken) +//! [5] + + +//! [6] +frame = QFrame() +frame.setFrameStyle(QFrame.Box | QFrame.Raised) +//! [6] + + +//! [7] +frame = QFrame() +frame.setFrameStyle( QFrame.Panel | QFrame.Sunken) +//! [7] + + +//! [8] +frame = QFrame() +frame.setFrameStyle(QFrame.WinPanel | QFrame.Raised) +//! [8] + + +//! [9] +frame = QFrame() +frame.setFrameStyle(QFrame.Box | QFrame.Plain) +//! [9] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qmatrix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qmatrix.cpp new file mode 100644 index 0000000..73ce084 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qmatrix.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +//! [0] + + +//! [1] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +//! [1] + + +//! [2] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +//! [2] + + +//! [3] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainter.cpp new file mode 100644 index 0000000..e295f66 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainter.cpp @@ -0,0 +1,261 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def paintEvent(self, paintEvent): + painter = QPainter(self) + painter.setPen(Qt.blue) + painter.setFont(QFont("Arial", 30)) + painter.drawText(rect(), Qt.AlignCenter, "Qt") +//! [0] + + +//! [1] +def paintEvent(self, paintEvent): + p = QPainter() + p.begin(self) + p.drawLine(...) # drawing code + p.end() +//! [1] + + +//! [2] +self paintEvent(self, paintEvent): + p = QPainter(self) + p.drawLine(...) # drawing code + +//! [2] + + +//! [3] +painter.begin(0) # impossible - paint device cannot be 0 + +image = QPixmap(0, 0) +painter.begin(&image) # impossible - image.isNull() == true + +painter.begin(myWidget) +painter2.begin(myWidget) # impossible - only one painter at a time +//! [3] + + +//! [4] +def rotate(self, angle): + matrix = QMatrix() + matrix.rotate(angle) + setWorldMatrix(matrix, true) +//! [4] + + +//! [5] +path = QPainterPath() +path.moveTo(20, 80) +path.lineTo(20, 30) +path.cubicTo(80, 0, 50, 50, 80, 80) + +painter = QPainter(self) +painter.drawPath(path) +//! [5] + + +//! [6] +line = QLineF(10.0, 80.0, 90.0, 20.0) + +painter = QPainter(self) +painter.drawLine(line) +//! [6] + + +//! [7] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) + +painter = QPainter(self) +painter.drawRect(rectangle) +//! [7] + + +//! [8] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) + +painter = QPainter(self) +painter.drawRoundedRect(rectangle, 20.0, 15.0) +//! [8] + + +//! [9] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) + +painter = QPainter(self) +painter.drawEllipse(rectangle) +//! [9] + + +//! [10] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) +startAngle = 30 * 16 +spanAngle = 120 * 16 + +painter = QPainter(self) +painter.drawArc(rectangle, startAngle, spanAngle) +//! [10] + + +//! [11] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) +startAngle = 30 * 16 +spanAngle = 120 * 16 + +painter = QPainter(self) +painter.drawPie(rectangle, startAngle, spanAngle) +//! [11] + + +//! [12] +rectangle = QRectF(10.0, 20.0, 80.0, 60.0) +startAngle = 30 * 16 +spanAngle = 120 * 16 + +painter = QPainter(self) +painter.drawChord(rect, startAngle, spanAngle) +//! [12] + + +//! [13] +points = [ + QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), +] + +painter = QPainter(self) +painter.drawPolyline(points, 3) +//! [13] + + +//! [14] +points = [ + QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), + QPointF(90.0, 70.0) +] + +painter = QPainter(self) +painter.drawPolygon(points, 4) +//! [14] + + +//! [15] +points = [ + QPointF(10.0, 80.0), + QPointF(20.0, 10.0), + QPointF(80.0, 30.0), + QPointF(90.0, 70.0) +] + +painter = QPainter(self) +painter.drawConvexPolygon(points, 4) +//! [15] + + +//! [16] +target = QRectF(10.0, 20.0, 80.0, 60.0) +source = QRectF(0.0, 0.0, 70.0, 40.0) +pixmap = QPixmap(":myPixmap.png") + +painter = QPainter(self) +painter.drawPixmap(target, image, source) +//! [16] + + +//! [17] +painter = QPainter(self) +painter.drawText(rect, Qt.AlignCenter, tr("Qt\nProject")) +//! [17] + + +//! [18] +picture = QPicture() +point = QPointF(10.0, 20.0) +picture.load("drawing.pic") + +painter = QPainter(self) +painter.drawPicture(0, 0, picture) +//! [18] + + +//! [19] +fillRect(rectangle, background()) +//! [19] + + +//! [20] +target = QRectF(10.0, 20.0, 80.0, 60.0) +source = QRectF(0.0, 0.0, 70.0, 40.0) +image = QImage(":/images/myImage.png") + +painter = QPainter(self) +painter.drawImage(target, image, source) +//! [20] + +//! [21] +painter = QPainter(self) +painter.fillRect(0, 0, 128, 128, Qt.green) +painter.beginNativePainting() + +glEnable(GL_SCISSOR_TEST) +glScissor(0, 0, 64, 64) + +glClearColor(1, 0, 0, 1) +glClear(GL_COLOR_BUFFER_BIT) + +glDisable(GL_SCISSOR_TEST) + +painter.endNativePainting() +//! [21] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainterpath.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainterpath.cpp new file mode 100644 index 0000000..cbf1aab --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpainterpath.cpp @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +path = QPainterPath() +path.addRect(20, 20, 60, 60) + +path.moveTo(0, 0) +path.cubicTo(99, 0, 50, 50, 99, 99) +path.cubicTo(0, 99, 50, 50, 0, 0) + +QPainter painter(self) +painter.fillRect(0, 0, 100, 100, Qt.white) +painter.setPen(QPen(QColor(79, 106, 25), 1, Qt.SolidLine, + Qt.FlatCap, Qt.MiterJoin)) +painter.setBrush(QColor(122, 163, 39)) + +painter.drawPath(path) +//! [0] + + +//! [1] +myGradient = QLinearGradient() +myPen = QPen() + +myPath = QPainterPath() +myPath.cubicTo(c1, c2, endPoint) + +painter = QPainter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [1] + + +//! [2] +myGradient = QLinearGradient() +myPen = QPen() + +startPoint = QPointF() +center = QPointF() + +myPath = QPainterPath() +myPath.moveTo(center) +myPath.arcTo(boundingRect, startAngle, + sweepLength) + +painter = QPainter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [2] + + +//! [3] +myGradient = QLinearGradient() +myPen = QPen() +myRectangle = QRectF() + +myPath = QPainterPath() +myPath.addRect(myRectangle) + +painter = QPainter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [3] + + +//! [4] +myGradient = QLinearGradient() +myPen = QPen() +myPolygon = QPolygonF() + +myPath = QPainterPath() +myPath.addPolygon(myPolygon) + +QPainter painter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [4] + + +//! [5] +myGradient = QLinearGradient() +myPen = QPen() +boundingRectangle = QRectF() + +myPath = QPainterPath() +myPath.addEllipse(boundingRectangle) + +QPainter painter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [5] + + +//! [6] +myGradient = QLinearGradient() +myPen = QPen() +myFont = QFont() +QPointF baseline(x, y) + +myPath = QPainterPath() +myPath.addText(baseline, myFont, tr("Qt")) + +painter QPainter(self) +painter.setBrush(myGradient) +painter.setPen(myPen) +painter.drawPath(myPath) +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpen.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpen.cpp new file mode 100644 index 0000000..871935c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qpen.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +painter = QPainter(self) +pen = QPen(Qt.green, 3, Qt.DashDotLine, Qt.RoundCap, Qt.RoundJoin) +painter.setPen(pen) +//! [0] + + +//! [1] +painter = QPainter(self) +pen = QPen() # creates a default pen + +pen.setStyle(Qt.DashDotLine) +pen.setWidth(3) +pen.setBrush(Qt.green) +pen.setCapStyle(Qt.RoundCap) +pen.setJoinStyle(Qt.RoundJoin) + +painter.setPen(pen) +//! [1] + + +//! [2] +pen = QPen() +space = 4; +dashes = [1, space, 3, space, 9, space, 27, space, 9, space] +pen.setDashPattern(dashes) +//! [2] + + +//! [3] +pen = QPen() +space = 4; +dashes = [1, space, 3, space, 9, space, 27, space, 9, space] +pen.setDashPattern(dashes) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion.cpp new file mode 100644 index 0000000..08e9c22 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyWidget (QWidget): + # ... + def paintEvent(self): + r1 = QRegion(QRect(100, 100, 200, 80), QRegion.Ellipse) # r1: elliptic region + ) + r2 = QRect(100, 120, 90, 30) # r2: rectangular region + r3 = r1.intersected(r2) # r3: intersection + + painter = QPainter(self) + painter.setClipRegion(r3) + ... # paint clipped graphics +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion_unix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion_unix.cpp new file mode 100644 index 0000000..b347fb3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qregion_unix.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +r1 = QRegion(10, 10, 20, 20) +r1.isNull() // false +r1.isEmpty() // false + +r2 = QRegion(40, 40, 20, 20) +r3 = QRegion() +r3.isNull() // true +r3.isEmpty() // true + +r3 = r1.intersected(r2) // r3: intersection of r1 and r2 +r3.isNull() // false +r3.isEmpty() // true + +r3 = r1.united(r2) // r3: union of r1 and r2 +r3.isNull() // false +r3.isEmpty() // false +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qtransform.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qtransform.cpp new file mode 100644 index 0000000..71ff406 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_painting_qtransform.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +if is not affine: + w' = m13*x + m23*y + m33 + x' /= w' + y' /= w' +//! [0] + + +//! [1] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +if is not affine: + w' = m13*x + m23*y + m33 + x' /= w' + y' /= w' +//! [1] + + +//! [2] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +if is not affine: + w' = m13*x + m23*y + m33 + x' /= w' + y' /= w' +//! [2] + + +//! [3] +x' = m11*x + m21*y + dx +y' = m22*y + m12*x + dy +if is not affine: + w' = m13*x + m23*y + m33 + x' /= w' + y' /= w' +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyle.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyle.cpp new file mode 100644 index 0000000..be555b4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyle.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +python myapplication.py -style windows +//! [0] + + +//! [1] +python myapplication.py -style custom +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyleoption.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyleoption.cpp new file mode 100644 index 0000000..c46066a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_styles_qstyleoption.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def styleHint(self, stylehint, opt, widget, returnData): + if stylehint == SH_RubberBand_Mask: + if isinstance(QStyleHintReturnMask, hint): + ... + ... +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfont.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfont.cpp new file mode 100644 index 0000000..43537f9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfont.cpp @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +serifFont = QFont("Times", 10, QFont.Bold) +sansFont = QFont("Helvetica [Cronyx]", 12) +//! [0] + + +//! [1] +f = QFont("Helvetica") +//! [1] + + +//! [2] +f = QFont("Helvetica [Cronyx]") +//! [2] + + +//! [3] +info = QFontInfo(f1) +family = info.family() +//! [3] + + +//! [4] +fm = QFontMetrics(f1) +textWidthInPixels = fm.width("How many pixels wide is this text?") +textHeightInPixels = fm.height() +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfontmetrics.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfontmetrics.cpp new file mode 100644 index 0000000..a184a00 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qfontmetrics.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +font = QFont("times", 24) +fm = QFontMetrics(font) +pixelsWide = fm.width("What's the width of this text?") +pixelsHigh = fm.height() +//! [0] + + +//! [1] +font = QFont("times", 24) +fm = QFontMetricsF(font) +pixelsWide = fm.width("What's the width of this text?") +pixelsHigh = fm.height() +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qsyntaxhighlighter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qsyntaxhighlighter.cpp new file mode 100644 index 0000000..2188be0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qsyntaxhighlighter.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +editor = QTextEdit() +highlighter = MyHighlighter(editor.document()) +//! [0] + + +//! [1] +class MyHighlighter(QSyntaxHighlighter): + def highlightBlock(self, text): + myClassFormat = QTextCharFormat() + myClassFormat.setFontWeight(QFont.Bold) + myClassFormat.setForeground(Qt.darkMagenta) + pattern = QString("\\bMy[A-Za-z]+\\b") + + expression = QRegExp(pattern) + index = text.indexOf(expression) + while index >= 0: + length = expression.matchedLength() + setFormat(index, length, myClassFormat) + index = text.indexOf(expression, index + length) +//! [1] + + +//! [2] +multiLineCommentFormat = QTextCharFormat() +multiLineCommentFormat.setForeground(Qt.red) + +startExpression = QRegExp("/\\*") +endExpression = QRegExp("\\*/") + +setCurrentBlockState(0) + +startIndex = 0 +if previousBlockState() != 1: + startIndex = text.indexOf(startExpression) + +while startIndex >= 0: + endIndex = text.indexOf(endExpression, startIndex) + if endIndex == -1: + setCurrentBlockState(1) + commentLength = text.length() - startIndex + else: + commentLength = endIndex - startIndex + + endExpression.matchedLength() + + setFormat(startIndex, commentLength, multiLineCommentFormat) + startIndex = text.indexOf(startExpression, + startIndex + commentLength) +//! [2] + + +//! [3] +class MyHighlighter(QSyntaxHighlighter): + def highlightBlock(self, text): + myClassFormat = QTextCharFormat() + myClassFormat.setFontWeight(QFont.Bold) + myClassFormat.setForeground(Qt.darkMagenta) + pattern = QString("\\bMy[A-Za-z]+\\b") + + expression = QRegExp(pattern) + index = text.indexOf(expression) + while index >= 0: + length = expression.matchedLength() + setFormat(index, length, myClassFormat) + index = text.indexOf(expression, index + length) +//! [3] + + +//! [4] +class BlockData(QTextBlockUserData): + def __init__(self): + # ... + self.parentheses = [] +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextcursor.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextcursor.cpp new file mode 100644 index 0000000..12189bf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextcursor.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +cursor.clearSelection() +cursor.movePosition(QTextCursor.NextWord, QTextCursor.KeepAnchor) +cursor.insertText("Hello World") +//! [0] + + +//! [1] +img = ... # A QImage +textDocument.addResource(QTextDocument.ImageResource, QUrl("myimage"), img) +cursor.insertImage("myimage") +//! [1] + + +//! [2] +cursor = QTextCursor(textDocument) +cursor.beginEditBlock() +cursor.insertText("Hello") +cursor.insertText("World") +cursor.endEditBlock() + +textDocument.undo() +//! [2] + + +//! [3] +cursor = QTextCursor(textDocument) +cursor.beginEditBlock() +cursor.insertText("Hello") +cursor.insertText("World") +cursor.endEditBlock() + +... + +cursor.joinPreviousEditBlock() +cursor.insertText("Hey") +cursor.endEditBlock() + +textDocument.undo() +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextlayout.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextlayout.cpp new file mode 100644 index 0000000..33cde13 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_text_qtextlayout.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +leading = fontMetrics.leading() +height = 0 +widthUsed = 0 +textLayout.beginLayout() +while True: + line = textLayout.createLine() + if not line.isValid(): + break + + line.setLineWidth(lineWidth) + height += leading + line.setPosition(QPointF(0, height)) + height += line.height() + widthUsed = qMax(widthUsed, line.naturalTextWidth()) +textLayout.endLayout() +//! [0] + + +//! [1] +painter = QPainter(self) +textLayout.draw(painter, QPoint(0, 0)) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qcompleter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qcompleter.cpp new file mode 100644 index 0000000..a9ba16a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qcompleter.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +wordList = ["alpha", "omega", "omicron", "zeta"] + +lineEdit = QLineEdit(self) + +completer = QCompleter(wordList, self) +completer.setCaseSensitivity(Qt.CaseInsensitive) +lineEdit.setCompleter(completer) +//! [0] + + +//! [1] +completer = QCompleter(self) +completer.setModel(QDirModel(completer)) +lineEdit.setCompleter(completer) +//! [1] + + +//! [2] +i = 0 +while completer.setCurrentRow(i): + print "%s is match number %d" % (completer.currentCompletion(), i) + i += 1 +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp new file mode 100644 index 0000000..f79f1ed --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qdesktopservices.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def showHelp(url): + # ... + pass + +QDesktopServices.setUrlHandler("help", showHelp); +//! [0] + +//! [1] +mailto:user@foo.com?subject=Test&body=Just a test +//! [1] + +//! [2] +QDesktopServices.openUrl(QUrl("file:///C:/Documents and Settings/All Users/Desktop", QUrl.TolerantMode)) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qundostack.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qundostack.cpp new file mode 100644 index 0000000..9875747 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qundostack.cpp @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class AppendText(QUndoCommand): + self.m_document = '' + self.m_text = '' + + def AppendText(self, doc, text): + self.m_document = doc + self.m_text = text + self.setText("append text") + + def undo(self): + self.m_document.chop(self.m_text.length()) + + def redo(self): + self.m_document->append(self.m_text) +//! [0] + + +//! [1] +command1 = MyCommand() +stack.push(command1) +command2 = MyCommand() +stack.push(command2) + +stack.undo() + +command3 = MyCommand() +stack.push(command3) # command2 gets deleted +//! [1] + + +//! [2] +insertRed = QUndoCommand() # an empty command +insertRed.setText("insert red text") + +InsertText(document, idx, text, insertRed) # becomes child of insertRed +SetColor(document, idx, text.length(), Qt.red, insertRed) + +stack.push(insertRed) +//! [2] + + +//! [3] +class AppendText(QUndoCommand): + ... + def mergeWith(self, other): + if other.id() != self.id(): # make sure other is also an AppendText command + return False + m_text += other.m_text + return True +//! [3] + + +//! [4] +stack.beginMacro("insert red text") +stack.push(InsertText(document, idx, text)) +stack.push(SetColor(document, idx, text.length(), Qt.red)) +stack.endMacro() # indexChanged() is emitted +//! [4] + + +//! [5] +insertRed = QUndoCommand() # an empty command +insertRed.setText("insert red text") + +InsertText(document, idx, text, insertRed) # becomes child of insertRed +SetColor(document, idx, text.length(), Qt.red, insertRed) + +stack.push(insertRed) +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qvalidator.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qvalidator.cpp new file mode 100644 index 0000000..df55131 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_util_qvalidator.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +validator = QIntValidator(100, 999, self) +edit = QLineEdit(self) + +# the edit lineedit will only accept integers between 100 and 999 +edit.setValidator(validator) +//! [0] + + +//! [1] +pos = 0 +v = QIntValidator(100, 900, self) + +str = "1" +v.validate(str, pos) # returns Intermediate +str = "012" +v.validate(str, pos) # returns Intermediate + +str = "123" +v.validate(str, pos) # returns Acceptable +str = "678" +v.validate(str, pos) # returns Acceptable + +str = "999" +v.validate(str, pos) # returns Intermediate + +str = "1234" +v.validate(str, pos) # returns Invalid +str = "-123" +v.validate(str, pos) # returns Invalid +str = "abc" +v.validate(str, pos) # returns Invalid +str = "12cm" +v.validate(str, pos) # returns Invalid +//! [1] + + +//! [2] +pos = 0 + +s = "abc" +v.validate(s, pos) # returns Invalid + +s = "5" +v.validate(s, pos) # returns Intermediate + +s = "50" +v.validate(s, pos) # returns Acceptable +//! [2] + + +//! [3] +# regexp: optional '-' followed by between 1 and 3 digits +rx = QRegExp("-?\\d{1,3}") +validator = QRegExpValidator(rx, self) + +edit = QLineEdit(self) +edit.setValidator(validator) +//! [3] + + +//! [4] +# integers 1 to 9999 +rx = QRegExp("[1-9]\\d{0,3}") +# the validator treats the regexp as "^[1-9]\\d{0,3}$" +v = QRegExpValidator(rx, 0) +pos = 0 + +s = "0" +v.validate(s, pos) # returns Invalid +s = "12345" +v.validate(s, pos) # returns Invalid +s = "1" +v.validate(s, pos) # returns Acceptable + +rx.setPattern("\\S+") # one or more non-whitespace characters +v.setRegExp(rx) +s = "myfile.txt" +v.validate(s, pos) # Returns Acceptable +s = "my file.txt" +v.validate(s, pos) # Returns Invalid + +# A, B or C followed by exactly five digits followed by W, X, Y or Z +rx.setPattern("[A-C]\\d{5}[W-Z]") +v.setRegExp(rx) +s = "a12345Z" +v.validate(s, pos) # Returns Invalid +s = "A12345Z" +v.validate(s, pos) # Returns Acceptable +s = "B12" +v.validate(s, pos) # Returns Intermediate + +# match most 'readme' files +rx.setPattern("read\\S?me(\.(txt|asc|1st))?") +rx.setCaseSensitive(false) +v.setRegExp(rx) +s = "readme" +v.validate(s, pos) # Returns Acceptable +s = "README.1ST" +v.validate(s, pos) # Returns Acceptable +s = "read me.txt" +v.validate(s, pos) # Returns Invalid +s = "readm" +v.validate(s, pos) # Returns Intermediate +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp new file mode 100644 index 0000000..c4219b3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractbutton.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +button = QPushButton(QObject.tr("Ro&ck && Roll"), self) +//! [0] + + +//! [1] +button.setIcon(QIcon(":/images/print.png")) +button.setShortcut(tr("Alt+F7")) +//! [1] + + +//! [2] +class MyWidget (QWidget): + #... + def reactToToggle(checked): + if checked: + // Examine the button states. + ... +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractspinbox.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractspinbox.cpp new file mode 100644 index 0000000..c8d60d0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qabstractspinbox.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +spinBox = QSpinBox(self) +spinBox.setRange(0, 100) +spinBox.setWrapping(True) +spinBox.setValue(100) +spinBox.stepBy(1) +// value is 0 +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp new file mode 100644 index 0000000..9d83f0b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcalendarwidget.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +calendar.setGridVisible(True) +//! [0] + + +//! [1] +calendar.setGridVisible(True) +calendar.setMinimumDate(QDate(2006, 6, 19)) +//! [1] + + +//! [2] +calendar.setGridVisible(True) +calendar.setMaximumDate(QDate(2006, 7, 3)) +//! [2] + + +//! [3] + +calendar.setDateRange(min, max) +//! [3] + + +//! [4] + +calendar.setMinimumDate(min) +calendar.setMaximumDate(max) +//! [4] + + +//! [5] +calendar.setGridVisible(True) +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp new file mode 100644 index 0000000..c8aa50a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qcheckbox.cpp @@ -0,0 +1,3 @@ +//! [0] +checkbox = QCheckBox("C&ase sensitive", self) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdatetimeedit.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdatetimeedit.cpp new file mode 100644 index 0000000..1dd6947 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdatetimeedit.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +dateEdit = QDateTimeEdit(QDate.currentDate()) +dateEdit.setMinimumDate(QDate.currentDate().addDays(-365)) +dateEdit.setMaximumDate(QDate.currentDate().addDays(365)) +dateEdit.setDisplayFormat("yyyy.MM.dd") +//! [0] + + +//! [1] +setDateTimeRange(min, max) +//! [1] + + +//! [2] +setMinimumDateTime(min) +setMaximumDateTime(max) +//! [2] + + +//! [3] +setDateRange(min, max) +//! [3] + + +//! [4] +setMinimumDate(min) +setMaximumDate(max) +//! [4] + + +//! [5] +setTimeRange(min, max) +//! [5] + + +//! [6] +setMinimumTime(min) +setMaximumTime(max) +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp new file mode 100644 index 0000000..c9da19b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qdockwidget.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +dockWidget = parentWidget() +if dockWidget.features() & QDockWidget.DockWidgetVerticalTitleBar: + # I need to be vertical +else: + # I need to be horizontal +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qframe.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qframe.cpp new file mode 100644 index 0000000..a41f1c4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qframe.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +label = QLabel() +label.setFrameStyle(QFrame.Panel | QFrame.Raised) +label.setLineWidth(2) + +pbar = QProgressBar() +label.setFrameStyle(QFrame.NoFrame) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qgroupbox.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qgroupbox.cpp new file mode 100644 index 0000000..d236d91 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qgroupbox.cpp @@ -0,0 +1,3 @@ +//! [0] +g.setTitle("&User information") +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlabel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlabel.cpp new file mode 100644 index 0000000..4a73a18 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlabel.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +label = QLabel(self) +label.setFrameStyle(QFrame.Panel | QFrame.Sunken) +label.setText("first line\nsecond line") +label.setAlignment(Qt.AlignBottom | Qt.AlignRight) +//! [0] + + +//! [1] +phoneEdit = QLineEdit(self) +phoneLabel = QLabel("&Phone:", self) +phoneLabel.setBuddy(phoneEdit) +//! [1] + + +//! [2] +nameEd = QLineEdit(self) +nameLb = QLabel("&Name:", self) +nameLb.setBuddy(nameEd) +phoneEd = QLineEdit(self) +phoneLb = QLabel("&Phone:", self) +phoneLb.setBuddy(phoneEd) +# (layout setup not shown) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlineedit.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlineedit.cpp new file mode 100644 index 0000000..bf093ba --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qlineedit.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def contextMenuEvent(event): + menu = createStandardContextMenu() + menu.addAction(QObject.tr("My Menu Item")) + #... + menu.exec_(event.globalPos()) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp new file mode 100644 index 0000000..a510470 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmainwindow.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def closeEvent(self, event): + settings = QSettings("MyCompany", "MyApp") + settings.setValue("geometry", self.saveGeometry()) + settings.setValue("windowState", self.saveState()) + QMainWindow.closeEvent(self, event) +//! [0] + + +//! [1] +def readSettings(self): + settings = QSettings("MyCompany", "MyApp") + restoreGeometry(settings.value("myWidget/geometry")) + restoreState(settings.value("myWidget/windowState")) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenu.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenu.cpp new file mode 100644 index 0000000..6bf1bf8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenu.cpp @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +exec_(QCursor.pos()) +//! [0] + + +//! [1] +exec_(somewidget.mapToGlobal(QPoint(0,0))) +//! [1] + + +//! [2] +exec_(e.globalPos()) +//! [2] + + +//! [3] +exec_(QCursor.pos()) +//! [3] + + +//! [4] +exec_(somewidget.mapToGlobal(QPoint(0, 0))) +//! [4] + + +//! [5] +exec_(e.globalPos()) +//! [5] + + +//! [6] +menu = QMenu() +at = actions[0] // Assumes actions is not empty +for a in actions: + menu.addAction(a) +menu.exec_(pos, at) +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenubar.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenubar.cpp new file mode 100644 index 0000000..fa5bb3b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qmenubar.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +menubar.addMenu(fileMenu) +//! [0] + + +//! [1] +menuBar = QMenuBar() +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp new file mode 100644 index 0000000..674f786 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qplaintextedit.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyQPlainTextEdit(QPlainTextEdit): + def contextMenuEvent(self, event): + menu = createStandardContextMenu() + menu.addAction(tr("My Menu Item")) + # ... + menu.exec_(event.globalPos()) + del menu +//! [0] + + +//! [1] +edit.textCursor().insertText(text) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qpushbutton.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qpushbutton.cpp new file mode 100644 index 0000000..74b4cf8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qpushbutton.cpp @@ -0,0 +1,3 @@ +//! [0] +button = QPushButton("&Download", self) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qradiobutton.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qradiobutton.cpp new file mode 100644 index 0000000..dbee868 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qradiobutton.cpp @@ -0,0 +1,3 @@ +//! [0] +button = QRadioButton("Search from the &cursor", self) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qrubberband.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qrubberband.cpp new file mode 100644 index 0000000..61f784a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qrubberband.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class Widget: + def mousePressEvent(self, event): + origin = event.pos() + if not self.rubberBand: + self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) + rubberBand.setGeometry(QRect(origin, QSize())) + rubberBand.show() + + def mouseMoveEvent(self, event): + rubberBand.setGeometry(QRect(origin, event.pos()).normalized()) + + def mouseReleaseEvent(self, event): + rubberBand.hide() + # determine selection, for example using QRect.intersects() + # and QRect.contains(). +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp new file mode 100644 index 0000000..7172efd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qscrollarea.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +imageLabel = QLabel() +image = QImage("happyguy.png") +imageLabel.setPixmap(QPixmap.fromImage(image)) + +scrollArea = QScrollArea() +scrollArea.setBackgroundRole(QPalette.Dark) +scrollArea.setWidget(imageLabel) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qspinbox.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qspinbox.cpp new file mode 100644 index 0000000..77273e2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qspinbox.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +sb.setPrefix("$") +//! [0] + + +//! [1] +sb.setSuffix(" km") +//! [1] + + +//! [2] +setRange(minimum, maximum) +//! [2] + + +//! [3] +setMinimum(minimum) +setMaximum(maximum) +//! [3] + + +//! [4] +spinbox.setPrefix("$") +//! [4] + + +//! [5] +spinbox.setSuffix(" km") +//! [5] + + +//! [6] +setRange(minimum, maximum) +//! [6] + + +//! [7] +setMinimum(minimum) +setMaximum(maximum) +//! [7] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplashscreen.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplashscreen.cpp new file mode 100644 index 0000000..2bddb83 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplashscreen.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +pixmap = QPixmap(":/splash.png") +splash = QSplashScreen(pixmap) +splash.show() + +... # Loading some items +splash.showMessage("Loaded modules") + +qApp.processEvents() + +... # Establishing connections +splash.showMessage("Established connections") + +qApp.processEvents() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplitter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplitter.cpp new file mode 100644 index 0000000..c5dfcd8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qsplitter.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +widget = splitter.widget(index) +policy = widget.sizePolicy() +policy.setHorizontalStretch(stretch) +policy.setVerticalStretch(stretch) +widget.setSizePolicy(policy) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qstatusbar.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qstatusbar.cpp new file mode 100644 index 0000000..8b972b6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qstatusbar.cpp @@ -0,0 +1,3 @@ +//! [0] +statusBar().addWidget(MyReadWriteIndication()) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextbrowser.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextbrowser.cpp new file mode 100644 index 0000000..e35b40c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextbrowser.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +backaction.setToolTip(browser.historyTitle(-1)) +forwardaction.setToolTip(browser.historyTitle(+1)) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextedit.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextedit.cpp new file mode 100644 index 0000000..fad9f6b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qtextedit.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyTextEdit(QTextEdit): + def contextMenuEvent(self, event): + menu = createStandardContextMenu() + menu.addAction(tr("My Menu Item")) + #... + menu.exec_(event->globalPos()) + del menu +//! [0] + + +//! [1] +edit.textCursor().insertText(text) +//! [1] + + +//! [2] +edit.textCursor().insertHtml(fragment) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qworkspace.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qworkspace.cpp new file mode 100644 index 0000000..1c77733 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_gui_widgets_qworkspace.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MainWindow(...): + def __init__(self): + self.workspace = QWorkspace() + self.setCentralWidget(workspace) + ... +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qftp.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qftp.cpp new file mode 100644 index 0000000..d0426fd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qftp.cpp @@ -0,0 +1,109 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +ftp = QFtp(parent) +ftp.connectToHost("ftp.qt-project.org") +ftp.login() +//! [0] + + +//! [1] +ftp.connectToHost("ftp.qt-project.org") # id == 1 +ftp.login() # id == 2 +ftp.cd("qt") # id == 3 +ftp.get("INSTALL") # id == 4 +ftp.close() # id == 5 +//! [1] + + +//! [2] +start(1) +stateChanged(HostLookup) +stateChanged(Connecting) +stateChanged(Connected) +finished(1, false) + +start(2) +stateChanged(LoggedIn) +finished(2, false) + +start(3) +finished(3, false) + +start(4) +dataTransferProgress(0, 3798) +dataTransferProgress(2896, 3798) +readyRead() +dataTransferProgress(3798, 3798) +readyRead() +finished(4, false) + +start(5) +stateChanged(Closing) +stateChanged(Unconnected) +finished(5, false) + +done(false) +//! [2] + + +//! [3] +start(1) +stateChanged(HostLookup) +stateChanged(Connecting) +stateChanged(Connected) +finished(1, false) + +start(2) +finished(2, true) + +done(true) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qhttp.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qhttp.cpp new file mode 100644 index 0000000..333ea2b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qhttp.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +content-type: text/html +//! [0] + + +//! [1] +header.setValue("content-type", "text/html") +contentType = header.value("content-type") +//! [1] + + +//! [2] +header = QHttpRequestHeader("GET", QUrl.toPercentEncoding("/index.html")) +header.setValue("Host", "qtsoftware.com") +http.setHost("qtsoftware.com") +http.request(header) +//! [2] + + +//! [3] +http.setHost("qtsoftware.com") # id == 1 +http.get(QUrl.toPercentEncoding("/index.html")) # id == 2 +//! [3] + + +//! [4] +requestStarted(1) +requestFinished(1, False) + +requestStarted(2) +stateChanged(Connecting) +stateChanged(Sending) +dataSendProgress(77, 77) +stateChanged(Reading) +responseHeaderReceived(responseheader) +dataReadProgress(5388, 0) +readyRead(responseheader) +dataReadProgress(18300, 0) +readyRead(responseheader) +stateChanged(Connected) +requestFinished(2, False) + +done(False) + +stateChanged(Closing) +stateChanged(Unconnected) +//! [4] + + +//! [5] +http.setHost("www.foo.bar") # id == 1 +http.get("/index.html") # id == 2 +http.post("register.html", data) # id == 3 +//! [5] + + +//! [6] +requestStarted(1) +requestFinished(1, False) + +requestStarted(2) +stateChanged(HostLookup) +requestFinished(2, True) + +done(True) + +stateChanged(Unconnected) +//! [6] + + +//! [7] +def getTicks(self): + http = QHttp(self) + self.connect(http, SIGNAL('done(bool)'), self, SLOT('showPage()')) + http.setProxy("proxy.example.com", 3128) + http.setHost("ticker.example.com") + http.get("/ticks.asp") + +def showPage(self): + self.display(http.readAll()) + +//! [7] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp new file mode 100644 index 0000000..4784725 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkaccessmanager.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +manager = QNetworkAccessManager(self) +manager.finished[QNetworkReply].connect(self.replyFinished) + +manager.get(QNetworkRequest(QUrl("http://qt-project.org"))) +//! [0] + + +//! [1] +request = QNetworkRequest() +request.setUrl(QUrl("http://qt-project.org")) +request.setRawHeader("User-Agent", "MyOwnBrowser 1.0") + +reply = manager.get(request) +reply.readyRead.connect(self.slotReadyRead) +reply.error[QNetworkReply.NetworkError].connect(self..slotError) +reply.sslErrors.connect(self.slotSslErrors) +//! [1] + +//! [2] +manager = QNetworkConfigurationManager() +networkAccessManager.setConfiguration(manager.defaultConfiguration()) +//! [2] + +//! [3] +networkAccessManager.setConfiguration(QNetworkConfiguration()) +//! [3] + +//! [4] +networkAccessManager.setNetworkAccessible(QNetworkAccessManager.NotAccessible) +//! [4] + +//! [5] +networkAccessManager.setNetworkAccessible(QNetworkAccessManager.Accessible) +//! [5] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp new file mode 100644 index 0000000..c8c81ad --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkdiskcache.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +manager = QNetworkAccessManager(self) +diskCache = QNetworkDiskCache(self) +diskCache.setCacheDirectory("cacheDir") +manager.setCache(diskCache) +//! [0] + +//! [1] +# do a normal request (preferred from network, as this is the default) +request = QNetworkRequest(QUrl("http://qt-project.org")) +manager.get(request) + +# do a request preferred from cache +request2 = QNetworkRequest(QUrl("http://qt-project.org")) +request2.setAttribute(QNetworkRequest.CacheLoadControlAttribute, QNetworkRequest.PreferCache) +manager.get(request2) +//! [1] + +//! [2] +@Slot(QNetworkReply) +def replyFinished(reply): + fromCache = reply.attribute(QNetworkRequest.SourceIsFromCacheAttribute) + print("page from cache? %d" % fromCache) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkrequest.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkrequest.cpp new file mode 100644 index 0000000..9156597 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_access_qnetworkrequest.cpp @@ -0,0 +1,3 @@ +//! [0] +request.setRawHeader("Last-Modified", "Sun, 06 Nov 1994 08:49:37 GMT") +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp new file mode 100644 index 0000000..d30aca2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_bearer_qnetworkconfigmanager.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +mgr = QNetworkConfigurationManager() +activeConfigs = mgr.allConfigurations(QNetworkConfiguration.Active) +if activeConfigs: + assert(mgr.isOnline()) +else: + assert(not mgr.isOnline()) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostaddress.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostaddress.cpp new file mode 100644 index 0000000..e45b6d5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostaddress.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +addr = hostAddr.toIPv6Address() +# addr contains 16 unsigned characters + +for i in range(0, 16): + # process addr[i] +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp new file mode 100644 index 0000000..b1430a4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qhostinfo.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +# To find the IP address of qt-project.org +QHostInfo.lookupHost("qt-project.org", self, SLOT("printResults(QHostInfo)")) + +# To find the host name for 4.2.2.1 +QHostInfo.lookupHost("4.2.2.1", self, SLOT("printResults(QHostInfo)")) +//! [0] + + +//! [1] +info = QHostInfo.fromName("qt-project.org") +//! [1] + + +//! [2] +QHostInfo.lookupHost("www.kde.org", self.lookedUp) +//! [2] + + +//! [3] +def lookedUp(host): + if host.error() != QHostInfo.NoError: + print "Lookup failed: %s" % host.errorString() + return + + for address in host.addresses(): + print "Found address: %s" % address.toString() +//! [3] + + +//! [4] +QHostInfo.lookupHost("4.2.2.1", self.lookedUp) +//! [4] + + +//! [5] +info = QHostInfo() +... +if not info.addresses().isEmpty(): + address = info.addresses().first() + # use the first IP address +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp new file mode 100644 index 0000000..29c6a8e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_kernel_qnetworkproxy.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +proxy = QNetworkProxy() +proxy.setType(QNetworkProxy.Socks5Proxy) +proxy.setHostName("proxy.example.com") +proxy.setPort(1080) +proxy.setUser("username") +proxy.setPassword("password") +QNetworkProxy.setApplicationProxy(proxy) +//! [0] + + +//! [1] +serverSocket.setProxy(QNetworkProxy.NoProxy) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qabstractsocket.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qabstractsocket.cpp new file mode 100644 index 0000000..ea70b1f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qabstractsocket.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +socket.connectToHost("imap", 143) +if socket.waitForConnected(1000): + print "Connected!" +//! [0] + + +//! [1] +socket.disconnectFromHost() + if socket.state() == QAbstractSocket.UnconnectedState or \ + socket.waitForDisconnected(1000): + print "Disconnected!" +//! [1] + + +//! [2] +class SocketClass(...): + def readyReadSlot(self): + # This slot is connected to QAbstractSocket::readyRead() + while not socket.atEnd(): + data = socket.read(100) + ... +//! [2] + + +//! [3] +socket.setProxy(QNetworkProxy.NoProxy) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp new file mode 100644 index 0000000..1687fe6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qlocalsocket_unix.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +socket.connectToServer("market") +if (socket.waitForConnected(1000)) + print("Connected!") +//! [0] + + +//! [1] +socket.disconnectFromServer() +if (socket.waitForDisconnected(1000)) + print("Disconnected!") +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp new file mode 100644 index 0000000..9fda752 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qnativesocketengine.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +socketLayer = QNativeSocketEngine() +socketLayer.initialize(QAbstractSocket.TcpSocket, QAbstractSocket.IPv4Protocol) +socketLayer.connectToHost(QHostAddress.LocalHost, 22) +# returns False + +socketLayer.waitForWrite() +socketLayer.connectToHost(QHostAddress.LocalHost, 22) +# returns True +//! [0] + + +//! [1] +socketLayer = QNativeSocketEngine() +socketLayer.bind(QHostAddress.Any, 4000) +socketLayer.listen() +if socketLayer.waitForRead(): + clientSocket = socketLayer.accept() + # a client is connected + +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qtcpserver.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qtcpserver.cpp new file mode 100644 index 0000000..b685462 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qtcpserver.cpp @@ -0,0 +1,3 @@ +//! [0] +server.setProxy(QNetworkProxy.NoProxy) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qudpsocket.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qudpsocket.cpp new file mode 100644 index 0000000..cbeb0be --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_socket_qudpsocket.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def initSocket(self): + udpSocket = QUdpSocket(self) + udpSocket.bind(QHostAddress.LocalHost, 7755) + + self.connect(udpSocket, SIGNAL('readyRead()'), + self, SLOT('readPendingDatagrams()')) + +def readPendingDatagrams(self): + while udpSocket.hasPendingDatagrams(): + datagram = QByteArray() + datagram.resize(udpSocket.pendingDatagramSize()) + + (sender, senderPort) = udpSocket.readDatagram(datagram.data(), datagram.size()) + + processTheDatagram(datagram) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp new file mode 100644 index 0000000..d13d4dd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +for cert in QSslCertificate.fromPath('C:/ssl/certificate.*.pem', QSsL.Pem, QRegExp.Wildcard): + print cert.issuerInfo(QSslCertificate.Organization) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslconfiguration.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslconfiguration.cpp new file mode 100644 index 0000000..1ba2170 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslconfiguration.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +config = sslSocket.sslConfiguration() +config.setProtocol(QSsl.TlsV1) +sslSocket.setSslConfiguration(config) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp new file mode 100644 index 0000000..d822b80 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_network_ssl_qsslsocket.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +socket = QSslSocket(self) +QObject.connect(socket, SIGNAL("encrypted()"), self, SLOT("ready()")) + +socket.connectToHostEncrypted("imap.example.com", 993) +//! [0] + + +//! [1] +def incomingConnection(socketDescriptor): + serverSocket = QSslSocket() + if serverSocket.setSocketDescriptor(socketDescriptor): + QObject.connect(serverSocket, SIGNAL("encrypted()"), self, SLOT("ready()")) + serverSocket.startServerEncryption() +//! [1] + + +//! [2] +socket = QSslSocket() +socket.connectToHostEncrypted("http.example.com", 443) +if not socket.waitForEncrypted(): + print socket.errorString() + return false + +socket.write("GET / HTTP/1.0\r\n\r\n") +while socket.waitForReadyRead(): + print socket.readAll().data() +//! [2] + + +//! [3] +socket = QSslSocket() +QObject.connect(socket, SIGNAL("encrypted()"), receiver, SLOT("socketEncrypted()")) + +socket.connectToHostEncrypted("imap", 993) +socket.write("1 CAPABILITY\r\n") +//! [3] + + +//! [4] +socket = QSslSocket() +socket.setCiphers("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA") +//! [4] + + +//! [5] +socket.connectToHostEncrypted("imap", 993) +if socket.waitForEncrypted(1000): + print "Encrypted!" +//! [5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qgl.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qgl.cpp new file mode 100644 index 0000000..264cf08 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qgl.cpp @@ -0,0 +1,168 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +fmt = QGLFormat() +fmt.setAlpha(True) +fmt.setStereo(True) +QGLFormat.setDefaultFormat(fmt) +//! [0] + + +//! [1] +fmt = QGLFormat() +fmt.setDoubleBuffer(False) # single buffer +fmt.setDirectRendering(False) # software rendering +myWidget = MyGLWidget(fmt, ...) +//! [1] + + +//! [2] +fmt = QGLFormat() +fmt.setOverlay(True) +fmt.setStereo(True) +myWidget = MyGLWidget(fmt, ...) +if !myWidget.format().stereo(): + # ok, goggles off + if !myWidget.format().hasOverlay(): + print "Cool hardware required" +//! [2] + + +//! [3] +# The rendering in MyGLWidget depends on using +# stencil buffer and alpha channel + +class MyGLWidget(QGLWidget): + def __init__(self, parent): + QGLWidget.__init__(self, QGLFormat(QGL.StencilBuffer | QGL.AlphaChannel), parent) + + if !format().stencil(): + print "Could not get stencil buffer results will be suboptimal" + if !format().alpha(): + print "Could not get alpha channel results will be suboptimal" + ... +//! [3] + + +//! [4] +a = QApplication([]) +f = QGLFormat() +f.setDoubleBuffer(False) +QGLFormat.setDefaultFormat(f) +//! [4] + + +//! [5] +f = QGLFormat.defaultOverlayFormat() +f.setDoubleBuffer(True) +QGLFormat.setDefaultOverlayFormat(f) +//! [5] + + +//! [6] +# ...continued from above +myWidget = MyGLWidget(QGLFormat(QGL.HasOverlay), ...) +if myWidget.format().hasOverlay(): + # Yes, we got an overlay, let's check _its_ format: + olContext = myWidget.overlayContext() + if olContext.format().doubleBuffer(): + # yes, we got a double buffered overlay + else: + # no, only single buffered overlays are available +//! [6] + + +//! [7] +cx = QGLContext() +# ... +f = QGLFormat() +f.setStereo(True) +cx.setFormat(f) +if !cx.create(): + exit() # no OpenGL support, or cannot render on the specified paintdevice +if !cx.format().stereo(): + exit() # could not create stereo context +//! [7] + + +//! [8] +class MyGLDrawer(QGLWidget): + + def __init__(self, parent): + QGLWidget.__init__(self, parent) + pass + + def initializeGL(self): + # Set up the rendering context, define display lists etc.: + ... + glClearColor(0.0, 0.0, 0.0, 0.0) + glEnable(GL_DEPTH_TEST) + ... + + def resizeGL(self, w, h): + # setup viewport, projection etc.: + glViewport(0, 0, w, h) + ... + glFrustum(...) + ... + + def paintGL(self): + # draw the scene: + ... + glRotatef(...) + glMaterialfv(...) + glBegin(GL_QUADS) + glVertex3f(...) + glVertex3f(...) + ... + glEnd() + ... +//! [8] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglcolormap.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglcolormap.cpp new file mode 100644 index 0000000..7f8a144 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglcolormap.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import sys + +from PySide2.QtGui import QApplication, qRgb +from PySide2.QtOpenGL import QGLColormap + +def main(argv): + app = QApplication(argv) + + widget = MySuperGLWidget() # a QGLWidget in color-index mode + colormap = QGLColormap() + + # This will fill the colormap with colors ranging from + # black to white. + for i in range(0, colormap.size()): + colormap.setEntry(i, qRgb(i, i, i)) + + widget.setColormap(colormap) + widget.show() + return app.exec_() + +if __name__ == "__main__": + main(sys.argv) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp new file mode 100644 index 0000000..fd8c504 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglpixelbuffer.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +pbuffer QGLPixelBuffer(...) +... +pbuffer.makeCurrent() +dynamicTexture = pbuffer.generateDynamicTexture() +pbuffer.bindToDynamicTexture(dynamicTexture) +... +pbuffer.releaseFromDynamicTexture() +//! [0] + + +//! [1] +pbuffer QGLPixelBuffer(...) +... +pbuffer.makeCurrent() +dynamicTexture = pbuffer.generateDynamicTexture() +... +pbuffer.updateDynamicTexture(dynamicTexture) +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp new file mode 100644 index 0000000..102867f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_opengl_qglshaderprogram.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +shader = QGLShader(QGLShader.Vertex) +shader.compileSourceCode(code) + +program = QGLShaderProgram(context) +program.addShader(shader) +program.link() + +program.bind() +//! [0] + +//! [1] +program.addShaderFromSourceCode(QGLShader.Vertex, + "attribute highp vec4 vertex\n" \ + "attribute mediump mat4 matrix\n" \ + "void main(void)\n" \ + "{\n" \ + " gl_Position = matrix * vertex\n" \ + "}") +program.addShaderFromSourceCode(QGLShader.Fragment, + "uniform mediump vec4 color\n" \ + "void main(void)\n" \ + "{\n" \ + " gl_FragColor = color\n" \ + "}") +program.link() +program.bind() + +vertexLocation = program.attributeLocation("vertex") +matrixLocation = program.attributeLocation("matrix") +colorLocation = program.uniformLocation("color") +//! [1] + +//! [2] +triangleVertices = ( + 60.0f, 10.0f, 0.0f, + 110.0f, 110.0f, 0.0f, + 10.0f, 110.0f, 0.0f) + +color = QColor(0, 255, 0, 255) + +pmvMatrix = QMatrix4x4() +pmvMatrix.ortho(self.rect()) + +program.enableAttributeArray(vertexLocation) +program.setAttributeArray(vertexLocation, triangleVertices, 3) +program.setUniformValue(matrixLocation, pmvMatrix) +program.setUniformValue(colorLocation, color) + +glDrawArrays(GL_TRIANGLES, 0, 3) + +program.disableAttributeArray(vertexLocation) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_qtestlib_qtestcase.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_qtestlib_qtestcase.cpp new file mode 100644 index 0000000..8ff2a6e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_qtestlib_qtestcase.cpp @@ -0,0 +1,237 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QVERIFY(1 + 1 == 2) +//! [0] + + +//! [1] +QVERIFY2(1 + 1 == 2, "A breach in basic arithmetic occured.") +//! [1] + + +//! [2] +QCOMPARE(QString("hello").toUpper(), QString("HELLO")) +//! [2] + + +//! [3] +void TestQString.toInt_data() +{ + QTest.addColumn("aString") + QTest.addColumn("expected") + + QTest.newRow("positive value") << "42" << 42 + QTest.newRow("negative value") << "-42" << -42 + QTest.newRow("zero") << "0" << 0 +} +//! [3] + + +//! [4] +void TestQString.toInt() +{ + QFETCH(QString, aString) + QFETCH(int, expected) + + QCOMPARE(aString.toInt(), expected) +} +//! [4] + + +//! [5] +if (sizeof(int) != 4) + QFAIL("This test has not been ported to this platform yet.") +//! [5] + + +//! [6] +QFETCH(QString, myString) +QCOMPARE(QString("hello").toUpper(), myString) +//! [6] + + +//! [7] +QTEST(QString("hello").toUpper(), "myString") +//! [7] + + +//! [8] +if (!QSqlDatabase.drivers().contains("SQLITE")) + QSKIP("This test requires the SQLITE database driver", SkipAll) +//! [8] + + +//! [9] +QEXPECT_FAIL("", "Will fix in the next release", Continue) +QCOMPARE(i, 42) +QCOMPARE(j, 43) +//! [9] + + +//! [10] +QEXPECT_FAIL("data27", "Oh my, this is soooo broken", Abort) +QCOMPARE(i, 42) +//! [10] + + +//! [11] +class TestQString: public QObject { ... } +QTEST_MAIN(TestQString) +//! [11] + + +//! [12] +#ifdef Q_WS_X11 + QTEST_MAIN(MyX11Test) +#else + // do nothing on non-X11 platforms + QTEST_NOOP_MAIN +#endif +//! [12] + + +//! [13] +QTest.keyClick(myWidget, 'a') +//! [13] + + +//! [14] +QTest.keyClick(myWidget, Qt.Key_Escape) + +QTest.keyClick(myWidget, Qt.Key_Escape, Qt.ShiftModifier, 200) +//! [14] + + +//! [15] +QTest.keyClicks(myWidget, "hello world") +//! [15] + + +//! [16] +namespace QTest { + template<> + char *toString(const MyPoint &point) + { + QByteArray ba = "MyPoint(" + ba += QByteArray.number(point.x()) + ", " + QByteArray.number(point.y()) + ba += ")" + return qstrdup(ba.data()) + } +} +//! [16] + + +//! [17] +int i = 0 +while (myNetworkServerNotResponding() && i++ < 50) + QTest.qWait(250) +//! [17] + + +//! [18] +MyFirstTestObject test1 +QTest.qExec(&test1) + +MySecondTestObject test2 +QTest.qExec(&test2) +//! [18] + + +//! [19] +QDir dir + +QTest.ignoreMessage(QtWarningMsg, "QDir.mkdir: Empty or null file name(s)") +dir.mkdir("") +//! [19] + + +//! [20] +void myTestFunction_data() +{ + QTest.addColumn("aString") + QTest.newRow("just hello") << QString("hello") + QTest.newRow("a null string") << QString() +} +//! [20] + + +//! [21] +void myTestFunction_data() { + QTest.addColumn("intval") + QTest.addColumn("str") + QTest.addColumn("dbl") + + QTest.newRow("row1") << 1 << "hello" << 1.5 +} +//! [21] + + +//! [22] +void MyTestClass.cleanup() +{ + if (qstrcmp(currentTestFunction(), "myDatabaseTest") == 0) { + // clean up all database connections + closeAllDatabases() + } +} +//! [22] + + +//! [23] +QTest.qSleep(250) +//! [23] + +//! [24] +widget = QWidget() +widget.show() +QTest.qWaitForWindowShown(widget) +//! [24] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptable.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptable.cpp new file mode 100644 index 0000000..ac181e7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptable.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class MyScriptableObject(QObject, QScriptable): +... + def doSomething(self): + ... + def doSomethingElse(self): + ... +//! [0] + + +//! [1] + +def doSomething(self): + self.context().throwError('Threw an error from a slot') + +def doSomethingElse(self): + return self.thisObject() + +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptclass.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptclass.cpp new file mode 100644 index 0000000..94601aa --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptclass.cpp @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +if extension == Callable: + context = argument + engine = context.engine() + sum = 0 + for i in range(0, context.argumentCount()): + sum += context.argument(i).toNumber() + return sum +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptcontext.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptcontext.cpp new file mode 100644 index 0000000..632283d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptcontext.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +foo(20.5, "hello", Object()) +//! [0] + + +//! [1] +def Person_prototype_fullName(context, engine): + self = context.selfObject() + result = self.property("firstName").toString() + result += QLatin1String(" ") + result += self.property("lastName").toString() + return result +//! [1] + + +//! [2] +def myInclude(ctx, eng): + fileName = ctx.argument(0).toString() + contents = readTheFile(fileName) + ctx.setActivationObject(ctx.parentContext().activationObject()) + ctx.setThisObject(ctx.parentContext().selfObject()) + return eng.evaluate(contents, fileName) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengine.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengine.cpp new file mode 100644 index 0000000..4005e2c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengine.cpp @@ -0,0 +1,320 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +myEngine = QScriptEngine() +three = myEngine.evaluate("1 + 2") +//! [0] + + +//! [1] +fun = myEngine.evaluate("function(a, b) { return a + b }"); +args = QScriptValueList() +args << 1 << 2 +threeAgain = fun.call(QScriptValue(), args) +//! [1] + + +//! [2] +fileName = "helloworld.qs" +scriptFile = QFile(fileName) +if !scriptFile.open(QIODevice.ReadOnly): + # handle error +stream = QTextStream(scriptFile) +contents = stream.readAll() +scriptFile.close() +myEngine.evaluate(contents, fileName) +//! [2] + + +//! [3] +myEngine.globalObject().setProperty("myNumber", 123) +... +myNumberPlusOne = myEngine.evaluate("myNumber + 1") +//! [3] + + +//! [4] +result = myEngine.evaluate(...) +if myEngine.hasUncaughtException(): + line = myEngine.uncaughtExceptionLineNumber() + print "uncaught exception at line", line, ":", result.toString() +//! [4] + + +//! [5] +button = QPushButton() +QScriptValue scriptButton = myEngine.QObject(button) +myEngine.globalObject().setProperty("button", scriptButton) + +myEngine.evaluate("button.checkable = True") + +print scriptButton.property("checkable").toBoolean() +scriptButton.property("show").call() # call the show() slot +//! [5] + + +//! [6] +def myAdd(context, engine): + a = context.argument(0) + b = context.argument(1) + return a.toNumber() + b.toNumber() +//! [6] + + +//! [7] +fun = myEngine.Function(myAdd) +myEngine.globalObject().setProperty("myAdd", fun) +//! [7] + + +//! [8] +result = myEngine.evaluate("myAdd(myNumber, 1)") +//! [8] + + +//! [9] +def Foo(context, engine): + if context.calledAsConstructor(): + # initialize the object + context.selfObject().setProperty("bar", ...) + # ... + # return a non-object value to indicate that the + # selfObject() should be the result of the " Foo()" expression + return engine.undefinedValue() + else: + # not called as " Foo()", just "Foo()" + # create our own object and return that one + object = engine.Object() + object.setPrototype(context.callee().property("prototype")) + object.setProperty("baz", ...) + return object +... + +fooProto = engine.Object() +fooProto.setProperty("whatever", ...) +engine.globalObject().setProperty("Foo", engine->Function(Foo, fooProto)) +//! [9] + + +//! [10] +class Bar: + ... + +def constructBar(context, engine): + bar = Bar() + # initialize from arguments in context, if desired + ... + return engine.toScriptValue(bar) + +class BarPrototype(QObject, QScriptable): +# provide the scriptable interface of self type using slots and properties +... + +... + +# create and register the Bar prototype and constructor in the engine +barPrototypeObject = BarPrototype(...) +barProto = engine.QObject(barPrototypeObject) +engine.setDefaultPrototype(qMetaTypeId(Bar), barProto) +barCtor = engine.Function(constructBar, barProto) +engine.globalObject().setProperty("Bar", barCtor) +//! [10] + + +//! [11] +def getSetFoo(context,engine): + callee = context.callee() + if context.argumentCount() == 1: # writing? + callee.setProperty("value", context.argument(0)) + return callee.property("value") +} + +.... + +object = engine.Object() +object.setProperty("foo", engine.Function(getSetFoo), + QScriptValue.PropertyGetter | QScriptValue::PropertySetter) +//! [11] + + +//! [12] +object = engine.Object() +object.setProperty("foo", engine.Function(getFoo), QScriptValue.PropertyGetter) +object.setProperty("foo", engine.Function(setFoo), QScriptValue.PropertySetter) +//! [12] + + +//! [13] +Q_SCRIPT_DECLARE_QMETAOBJECT(QLineEdit, QWidget*) + +... + +lineEditClass = engine.scriptValueFromQMetaObject(QLineEdit) +engine.globalObject().setProperty("QLineEdit", lineEditClass) +//! [13] + + +//! [14] +if hello && world: + print("hello world") +//! [14] + + +//! [15] +if hello && +//! [15] + + +//! [16] +0 = 0 +//! [16] + + +//! [17] +./test.js +//! [17] + + +//! [18] +foo["bar"] +//! [18] + + +//! [19] +engine = QScriptEngine() +context = engine.pushContext() +context.activationObject().setProperty("myArg", 123) +engine.evaluate("var tmp = myArg + 42") +... +engine.popContext() +//! [19] + + +//! [20] +class MyStruct: + x = 0 + y = 0 +//! [20] + + +//! [21] +Q_DECLARE_METATYPE(MyStruct) +//! [21] + + +//! [22] +def toScriptValue(engine, s): + obj = engine.Object() + obj.setProperty("x", s.x) + obj.setProperty("y", s.y) + return obj + +def fromScriptValue(obj, s): + s.x = obj.property("x").toInt32() + s.y = obj.property("y").toInt32() +//! [22] + + +//! [23] +qScriptRegisterMetaType(engine, toScriptValue, fromScriptValue) +//! [23] + + +//! [24] +s = context.argument(0) +... +s2 = MyStruct() +s2.x = s.x + 10 +s2.y = s.y + 20 +v = engine.toScriptValue(s2) +//! [24] + + +//! [25] +def createMyStruct(cx, engine): + s = MyStruct() + s.x = 123 + s.y = 456 + return engine.toScriptValue(s) +... + +ctor = engine.Function(createMyStruct) +engine.globalObject().setProperty("MyStruct", ctor) +//! [25] + + +//! [26] +Q_DECLARE_METATYPE(QVector) + +... + +qScriptRegisterSequenceMetaType >(engine) +... +v = engine.evaluate("[5, 1, 3, 2]") +v.sort() +a = engine.toScriptValue(v) +print a.toString() # outputs "[1, 2, 3, 5]" +//! [26] + +//! [27] +def mySpecialQObjectConstructor(context, engine): + parent = context.argument(0).toQObject() + object = QObject(parent) + return engine.QObject(object, QScriptEngine.ScriptOwnership) + +... + +ctor = engine.Function(mySpecialQObjectConstructor) +metaObject = engine.QMetaObject(QObject.staticMetaObject, ctor) +engine.globalObject().setProperty("QObject", metaObject) + +result = engine.evaluate(" QObject()") +//! [27] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengineagent.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengineagent.cpp new file mode 100644 index 0000000..91541f5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptengineagent.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +var a = Math.random() + 2; +//! [0] + + +//! [1] +function cube(a) { + return a * a * a; +} + +var a = cube(3); +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalue.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalue.cpp new file mode 100644 index 0000000..18109bd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalue.cpp @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +myEngine = QScriptEngine() +myObject = myEngine.newObject() +myOtherObject = myEngine.newObject() +myObject.setProperty("myChild", myOtherObject) +myObject.setProperty("name", "John Doe") +//! [0] + + +//! [1] +val = QScriptValue(myEngine, 123) +myObject.setProperty("myReadOnlyProperty", val, QScriptValue.ReadOnly) +//! [1] + + +//! [2] +engine = QScriptEngine() +engine.evaluate("function fullName() { return this.firstName + ' ' + this.lastName; }") +engine.evaluate("somePerson = { firstName: 'John', lastName: 'Doe' }") + +global_ = engine.globalObject() +fullName = global_.property("fullName") +who = global_.property("somePerson") +print fullName.call(who).toString() # "John Doe" + +engine.evaluate("function cube(x) { return x * x * x; }") +QScriptValue cube = global_.property("cube") +args = QScriptValueList() +args << 3 +print cube.call(QScriptValue(), args).toNumber() # 27 +//! [2] + + +//! [3] + +def myNativeFunction(context, engine): + otherFunction = ... + + return otherFunction.call(context.thisObject(), context.argumentsObject()) + +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalueiterator.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalueiterator.cpp new file mode 100644 index 0000000..f940148 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_script_qscriptvalueiterator.cpp @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +object = QScriptValue() +... +it = QScriptValueIterator(object) +while it.hasNext(): + it.next() + print "%s:%s" % (it.name(), it.value().toString()) +//! [0] + + +//! [1] +QScriptValue obj = ... // the object to iterate over +while obj.isObject(): + it = QScriptValueIterator(obj) + while it.hasNext(): + it.next() + print it.name() + obj = obj.prototype() +//! [1] + + +//! [2] +while it.hasNext(): + it.next() + if it.flags() & QScriptValue::SkipInEnumeration: + continue + print "found enumerated property: %s" % it.name() +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp new file mode 100644 index 0000000..cedc675 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqldriver.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +db = QSqlDatabase.addDatabase("SQLITE3") +v = QVariant(db.driver().handle()) +if v.isValid() && v.typeName() == "sqlite3*": + # v.data() returns a pointer to the handle + sqlite3 *handle = *static_cast(v.data()) + if handle != 0: # check that it is not NULL + doSomething() +//! [0] + + +//! [1] +# Impossible to translate to python +if (v.typeName() == "PGconn*") { + PGconn *handle = *static_cast(v.data()) + if (handle != 0) ... +} + +if (v.typeName() == "MYSQL*") { + MYSQL *handle = *static_cast(v.data()) + if (handle != 0) ... +} +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlerror.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlerror.cpp new file mode 100644 index 0000000..ea0c870 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlerror.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +model = QSqlQueryModel() +model.setQuery("select * from myTable") +if model.lastError().isValid(): + print model.lastError() +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlindex.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlindex.cpp new file mode 100644 index 0000000..3af6ef4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlindex.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +strlist = myIndex.toStringList() +for i in strlist: + myProcessing(i) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlquery.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlquery.cpp new file mode 100644 index 0000000..8e32368 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlquery.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +SELECT forename, surname FROM people +//! [0] + + +//! [1] +q = QSqlQuery("select * from employees") +rec = q.record() + +print "Number of columns: %d" % rec.count() + +nameCol = rec.indexOf("name") # index of the field "name" +while q.next(): + print q.value(nameCol) # output all names +//! [1] + + +//! [2] +q = QSqlQuery() +q.prepare("insert into myTable values (?, ?)") + +ints = [1, 2, 3, 4] +q.addBindValue(ints) + +names = ["Harald", "Boris", "Trond", ""] +q.addBindValue(names) + +if not q.execBatch(): + print q.lastError() +//! [2] + + +//! [3] +1 Harald +2 Boris +3 Trond +4 NULL +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlresult.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlresult.cpp new file mode 100644 index 0000000..3ba3277 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_kernel_qsqlresult.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +q = QSqlQuery() +q.prepare("insert into test (i1, i2, s) values (?, ?, ?)") + +col1 = [1, 3] +col2 = [2, 4] +col3 = ["hello", "world"] + +q.bindValue(0, col1) +q.bindValue(1, col2) +q.bindValue(2, col3) + +if not q.execBatch(): + print q.lastError() +//! [0] + + +//! [1] +query = QSqlQuery ... +v = query.result().handle() +if v.isValid() and (v.typeName() == "sqlite3_stmt*"): + # v.data() returns a pointer to the handle + handle = v.data() + if handle != 0: # check that it is not NULL + ... +//! [1] + + +//! [2] +if v.typeName() == "PGresult*": + handle = v.data() + if handle != 0 ... + +if v.typeName() == "MYSQL_STMT*": + handle = v.data() + if handle != 0 ... +} +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp new file mode 100644 index 0000000..fc5c398 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_sql_models_qsqlquerymodel.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +while myModel.canFetchMore(): + myModel.fetchMore() +//! [0] + + +//! [1] +model = QSqlQueryModel() +model.setQuery("select * from MyTable") +if model.lastError().isValid(): + print model.lastError() +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_dom_qdom.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_dom_qdom.cpp new file mode 100644 index 0000000..6396cbc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_dom_qdom.cpp @@ -0,0 +1,230 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +doc = QDomDocument() +impl = QDomImplementation() + +# This will create the element, but the resulting XML document will +# be invalid, because '~' is not a valid character in a tag name. +impl.setInvalidDataPolicy(QDomImplementation.AcceptInvalidData) +elt1 = doc.createElement("foo~bar") + +# This will create an element with the tag name "foobar". +impl.setInvalidDataPolicy(QDomImplementation.DropInvalidData) +elt2 = doc.createElement("foo~bar") + +# This will create a null element. +impl.setInvalidDataPolicy(QDomImplementation::ReturnNullNode) +elt3 = doc.createElement("foo~bar") +//! [0] + + +//! [1] +d = QDomDocument() +d.setContent(someXML) +n = d.firstChild() +while !n.isNull(): + if n.isElement(): + e = n.toElement() + print "Element name: %s" % e.tagName() + break + n = n.nextSibling() +//! [1] + + +//! [2] +QDomDocument document +QDomElement element1 = document.documentElement() +QDomElement element2 = element1 +//! [2] + + +//! [3] +QDomElement element3 = document.createElement("MyElement") +QDomElement element4 = document.createElement("MyElement") +//! [3] + + +//! [4] + +

Heading

+

Hello you

+ +//! [4] + + +//! [5] +

Heading

+

The text...

+

Next heading

+//! [5] + + +//! [6] +

Heading

+

The text...

+

Next heading

+//! [6] + + +//! [7] + +//! [7] + + +//! [8] +e = # some QDomElement... +#... +a = e.attributeNode("href") +print a.value() # prints "http://qt-project.org.com" +a.setValue("http://qt-project.org/doc") # change the node's attribute +a2 = e.attributeNode("href") +print a2.value() # prints "http://qt-project.org/doc" +//! [8] + + +//! [9] +e = # some QDomElement... +#... +s = e.text() +//! [9] + + +//! [10] +text = QString() +element = doc.documentElement() + +n = element.firstChild() +while True: + if not n.isNull() + break + t = n.toText() + if !t.isNull(): + text += t.data() + + n = n.nextSibling() +//! [10] + + +//! [11] +doc = # some QDomDocument ... +root = doc.firstChildElement("database") +elt = root.firstChildElement("entry") +while True: + if not elt.isNull(): + break + # ... + elt = elt.nextSiblingElement("entry") +//! [11] + + +//! [12] + +//! [12] + + +//! [13] +

Hello Qt ]]>

+//! [13] + + +//! [14] +Hello Qt +//! [14] + + +//! [15] + +//! [15] + + +//! [16] +doc = QDomDocument("mydocument") +file = QFile("mydocument.xml") +if not file.open(QIODevice::ReadOnly): + return +if not doc.setContent(&file): + file.close() + return +file.close() + +# print out the element names of all elements that are direct children +# of the outermost element. +docElem = doc.documentElement() + +n = docElem.firstChild() +while not n.isNull(): + e = n.toElement() # try to convert the node to an element. + if not e.isNull(): + print e.tagName() # the node really is an element. + n = n.nextSibling() +} + +# Here we append a new element to the end of the document +elem = doc.createElement("img") +elem.setAttribute("src", "myimage.png") +docElem.appendChild(elem) +//! [16] + + +//! [17] +doc = QDomDocument("MyML") +root = doc.createElement("MyML") +doc.appendChild(root) + +tag = doc.createElement("Greeting") +root.appendChild(tag) + +t = doc.createTextNode("Hello World") +tag.appendChild(t) + +xml = doc.toString() +//! [17] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_sax_qxml.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_sax_qxml.cpp new file mode 100644 index 0000000..9df91ab --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xml_sax_qxml.cpp @@ -0,0 +1,3 @@ +//! [0] +xmlReader.setFeature("http://xml.org/sax/features/namespace-prefixes", True) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp new file mode 100644 index 0000000..990a849 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstracturiresolver.cpp @@ -0,0 +1,3 @@ +//! [0] +return baseURI.resolved(relative); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp new file mode 100644 index 0000000..f31ea3f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlforwarditerator.cpp @@ -0,0 +1,3 @@ +//! [0] +OutputType inputToOutputItem(const InputType &inputType) const; +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp new file mode 100644 index 0000000..0ba6de2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlnodemodel.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +myInstance = QXmlNodeModelIndex(); +//! [0] + +//! [1] +QFile queryFile(argv[1]); +QFile chemistryData(argv[2]); +QString moleculeName = argv[3]; + +QXmlQuery query; +query.setQuery(&queryFile, QUrl::fromLocalFile(queryFile.fileName())); + +ChemistryNodeModel myNodeModel(query.namePool(), chemistryData); +QXmlNodeModelIndex startNode = myNodeModel.nodeFor(moleculeName); +query.bindVariable("queryRoot", startNode); + +QFile out; +out.open(stdout, QIODevice::WriteOnly); + +QXmlSerializer serializer(query, &out); +query.evaluateTo(&serializer); +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp new file mode 100644 index 0000000..32397e3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qabstractxmlreceiver.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlSerializer serializer(query, myOutputDevice); +query.evaluateTo(&serializer); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp new file mode 100644 index 0000000..80147c8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qsimplexmlnodemodel.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlNodeModelIndex MyTreeModel::nextFromSimpleAxis(SimpleAxis axis, const QXmlNodeModelIndex &ni) const +{ + // Convert the QXmlNodeModelIndex to a value that is specific to what we represent. + const MyValue value = toMyValue(ni); + + switch(axis) + { + case Parent: + return toNodeIndex(value.parent()); + case FirstChild: + case PreviousSibling: + case NextSibling: + // and so on + ; + } + return QXmlNodeModelIndex(); +} +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp new file mode 100644 index 0000000..3695d41 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlformatter.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlFormatter formatter(query, myOutputDevice); +formatter.setIndentationDepth(2); +query.evaluateTo(&formatter); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp new file mode 100644 index 0000000..0337570 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlname.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +// Fills the bits from begin to end with 1s and leaves the rest as 0. + +template +inline IntegralT bitmask(IntegralT begin, IntegralT end) +{ + IntegralT filled_bits = (1 << (end - begin + 1)) - 1; + return filled_bits << begin; +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp new file mode 100644 index 0000000..a5a2706 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlquery.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QXmlNamePool namePool(query.namePool()); + query.bindVariable(QXmlName(namePool, localName), value); +//! [0] + + +{ +//! [1] + QByteArray myDocument; + QBuffer buffer(&myDocument); // This is a QIODevice. + buffer.open(QIODevice::ReadOnly); + QXmlQuery query; + query.bindVariable("myDocument", &buffer); + query.setQuery("doc($myDocument)"); +//! [1] +} + + +{ + QIODevice *device = 0; +//! [2] + QXmlNamePool namePool(query.namePool()); + query.bindVariable(QXmlName(namePool, localName), device); +//! [2] + +} + +{ + QIODevice *myOutputDevice = 0; +//! [3] + QFile xq("myquery.xq"); + + QXmlQuery query; + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlSerializer serializer(query, myOutputDevice); + query.evaluateTo(&serializer); +//! [3] +} + +{ + QIODevice *myOutputDevice = 0; +//! [4] + QFile xq("myquery.xq"); + QString fileName("the filename"); + QString publisherName("the publisher"); + qlonglong year = 1234; + + QXmlQuery query; + + query.bindVariable("file", QVariant(fileName)); + query.bindVariable("publisher", QVariant(publisherName)); + query.bindVariable("year", QVariant(year)); + + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlSerializer serializer(query, myOutputDevice); + query.evaluateTo(&serializer); +//! [4] +} + +{ +//! [5] + QFile xq("myquery.xq"); + QString fileName("the filename"); + QString publisherName("the publisher"); + qlonglong year = 1234; + + QXmlQuery query; + + query.bindVariable("file", QVariant(fileName)); + query.bindVariable("publisher", QVariant(publisherName)); + query.bindVariable("year", QVariant(year)); + + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlResultItems result; + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + if (item.isAtomicValue()) { + QVariant v = item.toAtomicValue(); + switch (v.type()) { + case QVariant::LongLong: + // xs:integer + break; + case QVariant::String: + // xs:string + break; + default: + // error + break; + } + } + else if (item.isNode()) { + QXmlNodeModelIndex i = item.toNodeModelIndex(); + // process node + } + item = result.next(); + } +//! [5] +} + +{ +//! [6] + QFile xq("myquery.xq"); + + QXmlQuery query; + query.setQuery(&xq, QUrl::fromLocalFile(xq.fileName())); + + QXmlResultItems result; + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + if (item.isAtomicValue()) { + QVariant v = item.toAtomicValue(); + switch (v.type()) { + case QVariant::LongLong: + // xs:integer + break; + case QVariant::String: + // xs:string + break; + default: + if (v.userType() == qMetaTypeId()) { + QXmlName n = qVariantValue(v); + // process QXmlName n... + } + else { + // error + } + break; + } + } + else if (item.isNode()) { + QXmlNodeModelIndex i = item.toNodeModelIndex(); + // process node + } + item = result.next(); + } +//! [6] +} + +{ + QIODevice *out = 0; +//! [7] + QXmlQuery query(QXmlQuery::XSLT20); + query.setFocus(QUrl("myInput.xml")); + query.setQuery(QUrl("myStylesheet.xsl")); + query.evaluateTo(out); +//! [7] +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp new file mode 100644 index 0000000..62bb471 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlresultitems.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery(", 1, 'two'"); +QXmlResultItems result; + +if (query.isValid()) { + query.evaluateTo(&result); + QXmlItem item(result.next()); + while (!item.isNull()) { + // use item + item = result.next(); + } + if (result.hasError()) + /* Runtime error! */; +} +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp new file mode 100644 index 0000000..32397e3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/src_xmlpatterns_api_qxmlserializer.cpp @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +QXmlQuery query; +query.setQuery("doc('index.html')/html/body/p[1]"); + +QXmlSerializer serializer(query, myOutputDevice); +query.evaluateTo(&serializer); +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp new file mode 100644 index 0000000..c0baf89 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_assistant_compat_lib_qassistantclient.cpp @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QProcess *process = new QProcess(this); + QString app = QLibraryInfo::location(QLibraryInfo::BinariesPath) + + QLatin1String("/assistant"); + + process->start(app, QStringList() << QLatin1String("-enableRemoteControl")); + if (!process->waitForStarted()) { + QMessageBox::critical(this, tr("Remote Control"), + tr("Could not start Qt Assistant from %1.").arg(app)); + return; + } + + // show index page + QTextStream str(process); + str << QLatin1String("SetSource qthelp://mycompany.com/doc/index.html") + << QLatin1Char('\0') << endl; + } +//! [0] + + +//! [1] + CONFIG += assistant +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp new file mode 100644 index 0000000..4f6de9e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_default_extensionfactory.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QObject *ANewExtensionFactory::createExtension(QObject *object, + const QString &iid, QObject *parent) const + { + if (iid != Q_TYPEID(QDesignerContainerExtension)) + return 0; + + if (MyCustomWidget *widget = qobject_cast + (object)) + return new MyContainerExtension(widget, parent); + + return 0; + } +//! [0] + + +//! [1] + QObject *AGeneralExtensionFactory::createExtension(QObject *object, + const QString &iid, QObject *parent) const + { + MyCustomWidget *widget = qobject_cast(object); + + if (widget && (iid == Q_TYPEID(QDesignerTaskMenuExtension))) { + return new MyTaskMenuExtension(widget, parent); + + } else if (widget && (iid == Q_TYPEID(QDesignerContainerExtension))) { + return new MyContainerExtension(widget, parent); + + } else { + return 0; + } + } +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp new file mode 100644 index 0000000..14fe376 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_extension.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerPropertySheetExtension *propertySheet; + QExtensionManager manager = formEditor->extensionManager(); + + propertySheet = qt_extension(manager, widget); + + if(propertySheet) {...} +//! [0] + + +//! [1] + Q_DECLARE_EXTENSION_INTERFACE(MyExtension, "com.mycompany.myproduct.myextension") +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_qextensionmanager.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_qextensionmanager.cpp new file mode 100644 index 0000000..dabd9f7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_extension_qextensionmanager.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + void MyPlugin::initialize(QDesignerFormEditorInterface *formEditor) + { + if (initialized) + return; + + QExtensionManager *manager = formEditor->extensionManager(); + Q_ASSERT(manager != 0); + + manager->registerExtensions(new MyExtensionFactory(manager), + Q_TYPEID(QDesignerTaskMenuExtension)); + + initialized = true; + } +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformeditor.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformeditor.cpp new file mode 100644 index 0000000..2fe32e6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformeditor.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerObjectInspectorInterface *objectInspector = 0; + objectInspector = formEditor->objectInspector(); + + QDesignerFormWindowManagerInterface *manager = 0; + manager = formEditor->formWindowManager(); + + objectInspector->setFormWindow(manager->formWindow(0)); +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py new file mode 100644 index 0000000..6cf5dd2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindow.py @@ -0,0 +1,74 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + formWindow = QDesignerFormWindowInterface() + formWindow = QDesignerFormWindowInterface.findFormWindow(myWidget) +//! [0] + + +//! [1] + forms = [] # QList + formWindow = QDesignerFormWindowInterface() + + manager = formEditor.formWindowManager() + + for i in range(manager.formWindowCount()): + formWindow = manager.formWindow(i) + forms.append(formWindow) +//! [1] + + +//! [2] + if formWindow.isManaged(myWidget): + formWindow.manageWidget(myWidget.childWidget) +//! [2] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowcursor.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowcursor.cpp new file mode 100644 index 0000000..79b98f0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowcursor.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerFormWindowInterface *formWindow = 0; + formWindow = QDesignerFormWindowInterface::findFormWindow(myWidget); + + formWindow->cursor()->setProperty(myWidget, myProperty, newValue); +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowmanager.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowmanager.cpp new file mode 100644 index 0000000..d6654b3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractformwindowmanager.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerFormWindowManagerInterface *manager = 0; + QDesignerFormWindowInterface *formWindow = 0; + + manager = formEditor->formWindowManager(); + formWindow = manager->formWindow(0); + + manager->setActiveFormWindow(formWindow); +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractobjectinspector.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractobjectinspector.cpp new file mode 100644 index 0000000..2fe32e6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractobjectinspector.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerObjectInspectorInterface *objectInspector = 0; + objectInspector = formEditor->objectInspector(); + + QDesignerFormWindowManagerInterface *manager = 0; + manager = formEditor->formWindowManager(); + + objectInspector->setFormWindow(manager->formWindow(0)); +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py new file mode 100644 index 0000000..1e2ac50 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractpropertyeditor.py @@ -0,0 +1,71 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + propertyEdit = QDesignerPropertyEditorInterface() + propertyEditor = formEditor.propertyEditor() + + propertyEditor.propertyChanged.connect(self.checkProperty) +//! [0] + + +//! [1] + def checkProperty(self, property, value): + propertyEditor = QDesignerPropertyEditorInterface() + propertyEditor = formEditor.propertyEditor() + + object = propertyeditor.object() + widget = MyCustomWidget(object) + + if (widget and property == aProperty and value != expectedValue): + # ... +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp new file mode 100644 index 0000000..7c0a415 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_sdk_abstractwidgetbox.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QDesignerWidgetBoxInterface *widgetBox = 0: + widgetBox = formEditor->widgetBox(); + + widgetBox->load(); +//! [0] + + +//! [1] + QString originalFile = widgetBox->fileName(); + + widgetBox->setFileName("myWidgetBox.xml"); + widgetBox->save(); +//! [1] + + +//! [2] + widgetBox->setFileName(originalFile); + widgetBox->load(); +//! [2] + + +//! [3] + if (widgetBox->filename() != "myWidgetBox.xml") { + widgetBox->setFileName("myWidgetBox.xml"); + widgetBox->load(); + } +//! [3] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp new file mode 100644 index 0000000..781ce75 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_abstractformbuilder.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + MyForm::MyForm(QWidget *parent) + : QWidget(parent) + { + QFormBuilder builder; + QFile file(":/forms/myWidget.ui"); + file.open(QFile::ReadOnly); + QWidget *myWidget = builder.load(&file, this); + file.close(); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(myWidget); + setLayout(layout); + } +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp new file mode 100644 index 0000000..fc58aa5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_designer_src_lib_uilib_formbuilder.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + MyForm::MyForm(QWidget *parent) + : QWidget(parent) + { + QFormBuilder builder; + QFile file(":/forms/myWidget.ui"); + file.open(QFile::ReadOnly); + QWidget *myWidget = builder.load(&file, this); + file.close(); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(myWidget); + setLayout(layout); + } +//! [0] + + +//! [1] + + + mywidget.ui + + +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_patternist_qapplicationargumentparser.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_patternist_qapplicationargumentparser.cpp new file mode 100644 index 0000000..91bd24b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_patternist_qapplicationargumentparser.cpp @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + \include main.cpp +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp new file mode 100644 index 0000000..a9c6a26 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtgradienteditor_qtgradientdialog.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + bool ok; + QGradient gradient = QtGradientDialog::getGradient(&ok, QRadialGradient(), this); + if (ok) { + // the user clicked OK and gradient is set to the gradient the user selected + } else { + // the user canceled the dialog; gradient is set to the initial + // value, in this case radial gradient + } +//! [0] + + +//! [1] + bool detailsVisible; + QColor::Spec spec; + QGradient gradient; + + QtGradientDialog dlg(this); + dlg.setDetailsVisible(detailsVisible); + dlg.setSpec(spec); + dlg.setGradient(gradient); + if (dlg.exec() != QDialog::Accepted) + return; + + gradient = dlg.gradient(); + // detailsVisible and spec properties can be changed interactively by the user too, + // we store the values of these properties for the next time QtGradientDialog is executed. + detailsVisible = dlg.detailsVisible(); + spec = dlg.spec(); +//! [1] + + +//! [2] + QtGradientDialog dlg; + dlg.setBackgroundCheckered(true); +//! [2] + + +//! [3] + QtGradientDialog dlg; + dlg.setBackgroundCheckered(false); +//! [3] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp new file mode 100644 index 0000000..64bdb67 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtpropertybrowser.cpp @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QtSpinBoxFactory *factory; + QSet managers = factory->propertyManagers(); +//! [0] + + +//! [1] + QtBrowserItem *item; + QList childrenItems = item->children(); + + QList childrenProperties = item->property()->subProperties(); +//! [1] + + +//! [2] + QtProperty *property1, *property2, *property3; + + property2->addSubProperty(property1); + property3->addSubProperty(property2); + + QtAbstractPropertyBrowser *editor; + + editor->addProperty(property1); + editor->addProperty(property2); + editor->addProperty(property3); +//! [2] + + +//! [3] + QtIntPropertyManager *intManager; + QtDoublePropertyManager *doubleManager; + + QtProperty *myInteger = intManager->addProperty(); + QtProperty *myDouble = doubleManager->addProperty(); + + QtSpinBoxFactory *spinBoxFactory; + QtDoubleSpinBoxFactory *doubleSpinBoxFactory; + + QtAbstractPropertyBrowser *editor; + editor->setFactoryForManager(intManager, spinBoxFactory); + editor->setFactoryForManager(doubleManager, doubleSpinBoxFactory); + + editor->addProperty(myInteger); + editor->addProperty(myDouble); +//! [3] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp new file mode 100644 index 0000000..95de10d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qtpropertybrowser_qtvariantproperty.cpp @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QtVariantPropertyManager *variantPropertyManager; + QtProperty *property; + + variantPropertyManager->setValue(property, 10); +//! [0] + + +//! [1] + QtVariantPropertyManager *variantPropertyManager; + QtVariantProperty *property; + + property->setValue(10); +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp new file mode 100644 index 0000000..93a9b53 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/code/tools_shared_qttoolbardialog_qttoolbardialog.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + QtToolBarManager *toolBarManager; + + void MyMainWindow::customize() + { + QtToolBarDialog dialog(this); + dialog.setToolBarManager(toolBarManager); + dialog.exec(); + } +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/console/dbus_pingpong.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/console/dbus_pingpong.txt new file mode 100644 index 0000000..3c700db --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/console/dbus_pingpong.txt @@ -0,0 +1,3 @@ +[qtuser@workstation:~/dev/qt-4.4/examples/dbus/pingpong]$ ./pong & +[qtuser@workstation:~/dev/qt-4.4/examples/dbus/pingpong]$ ./ping Hello +Reply was: ping("Hello") got called diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/customstyle/customstyle.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/customstyle/customstyle.h new file mode 100644 index 0000000..8aead8e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/customstyle/customstyle.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CUSTOMSTYLE_H +#define CUSTOMSTYLE_H + +#include + +//! [0] +class CustomStyle(QProxyStyle): + ... + + def drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const; + # element : PrimitiveElement + # option : QStyleOption + # painter : QPainter + # widget : QWidget + ... +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.h new file mode 100644 index 0000000..d5852c9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IMAGEDIALOG_H +#define IMAGEDIALOG_H + +#include "ui_imagedialog.h" + +//! [0] +class ImageDialog : public QDialog, private Ui::ImageDialog +{ + Q_OBJECT + +public: + ImageDialog(QWidget *parent = 0); + +private slots: + void on_okButton_clicked(); +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.ui new file mode 100644 index 0000000..1c5e546 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/autoconnection/imagedialog.ui @@ -0,0 +1,389 @@ + + + ImageDialog + + + ImageDialog + + + + 0 + 0 + 320 + 180 + + + + Create Image + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + widthLabel + + + + 1 + 27 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Width: + + + Qt::AutoText + + + + + + + heightLabel + + + + 1 + 55 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Height: + + + Qt::AutoText + + + + + + + colorDepthCombo + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QComboBox::InsertAtBottom + + + + + + + nameLineEdit + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 1 + 0 + + + + Untitled image + + + QLineEdit::Normal + + + + + + + spinBox + + + + 74 + 1 + 227 + 20 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + spinBox_2 + + + + 74 + 27 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + nameLabel + + + + 1 + 1 + 67 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Name: + + + Qt::AutoText + + + + + + + colorDepthLabel + + + + 1 + 83 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Color depth: + + + Qt::AutoText + + + + + + + + + + + + + 9 + 121 + 302 + 18 + + + + Qt::Vertical + + + + + + + + + + 1 + + + 6 + + + + + + + + + 1 + 1 + 128 + 24 + + + + Qt::Horizontal + + + + + + + okButton + + + + 135 + 1 + 80 + 24 + + + + OK + + + + + + + cancelButton + + + + 221 + 1 + 80 + 24 + + + + Cancel + + + + + + + + + + nameLineEdit + spinBox + spinBox_2 + colorDepthCombo + okButton + cancelButton + + + + nameLineEdit + returnPressed() + okButton + animateClick() + + + -1 + 7 + + + -1 + 7 + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/imagedialog/imagedialog.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/imagedialog/imagedialog.ui new file mode 100644 index 0000000..1c5e546 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/imagedialog/imagedialog.ui @@ -0,0 +1,389 @@ + + + ImageDialog + + + ImageDialog + + + + 0 + 0 + 320 + 180 + + + + Create Image + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + widthLabel + + + + 1 + 27 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Width: + + + Qt::AutoText + + + + + + + heightLabel + + + + 1 + 55 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Height: + + + Qt::AutoText + + + + + + + colorDepthCombo + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QComboBox::InsertAtBottom + + + + + + + nameLineEdit + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 1 + 0 + + + + Untitled image + + + QLineEdit::Normal + + + + + + + spinBox + + + + 74 + 1 + 227 + 20 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + spinBox_2 + + + + 74 + 27 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + nameLabel + + + + 1 + 1 + 67 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Name: + + + Qt::AutoText + + + + + + + colorDepthLabel + + + + 1 + 83 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Color depth: + + + Qt::AutoText + + + + + + + + + + + + + 9 + 121 + 302 + 18 + + + + Qt::Vertical + + + + + + + + + + 1 + + + 6 + + + + + + + + + 1 + 1 + 128 + 24 + + + + Qt::Horizontal + + + + + + + okButton + + + + 135 + 1 + 80 + 24 + + + + OK + + + + + + + cancelButton + + + + 221 + 1 + 80 + 24 + + + + Cancel + + + + + + + + + + nameLineEdit + spinBox + spinBox_2 + colorDepthCombo + okButton + cancelButton + + + + nameLineEdit + returnPressed() + okButton + animateClick() + + + -1 + 7 + + + -1 + 7 + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.h new file mode 100644 index 0000000..1b95cb3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IMAGEDIALOG_H +#define IMAGEDIALOG_H + +#include "ui_imagedialog.h" + +class ImageDialog : public QDialog, private Ui::ImageDialog +{ + Q_OBJECT + +public: + ImageDialog(QWidget *parent = 0); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.ui new file mode 100644 index 0000000..1c5e546 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/multipleinheritance/imagedialog.ui @@ -0,0 +1,389 @@ + + + ImageDialog + + + ImageDialog + + + + 0 + 0 + 320 + 180 + + + + Create Image + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + widthLabel + + + + 1 + 27 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Width: + + + Qt::AutoText + + + + + + + heightLabel + + + + 1 + 55 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Height: + + + Qt::AutoText + + + + + + + colorDepthCombo + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QComboBox::InsertAtBottom + + + + + + + nameLineEdit + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 1 + 0 + + + + Untitled image + + + QLineEdit::Normal + + + + + + + spinBox + + + + 74 + 1 + 227 + 20 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + spinBox_2 + + + + 74 + 27 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + nameLabel + + + + 1 + 1 + 67 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Name: + + + Qt::AutoText + + + + + + + colorDepthLabel + + + + 1 + 83 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Color depth: + + + Qt::AutoText + + + + + + + + + + + + + 9 + 121 + 302 + 18 + + + + Qt::Vertical + + + + + + + + + + 1 + + + 6 + + + + + + + + + 1 + 1 + 128 + 24 + + + + Qt::Horizontal + + + + + + + okButton + + + + 135 + 1 + 80 + 24 + + + + OK + + + + + + + cancelButton + + + + 221 + 1 + 80 + 24 + + + + Cancel + + + + + + + + + + nameLineEdit + spinBox + spinBox_2 + colorDepthCombo + okButton + cancelButton + + + + nameLineEdit + returnPressed() + okButton + animateClick() + + + -1 + 7 + + + -1 + 7 + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.h new file mode 100644 index 0000000..16ff0ec --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IMAGEDIALOG_H +#define IMAGEDIALOG_H + +#include "ui_imagedialog.h" + +//! [0] +class ImageDialog : public QDialog, private Ui::ImageDialog +{ + Q_OBJECT + +public: + ImageDialog(QWidget *parent = 0); + +private slots: + void checkValues(); +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.ui new file mode 100644 index 0000000..1c5e546 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/noautoconnection/imagedialog.ui @@ -0,0 +1,389 @@ + + + ImageDialog + + + ImageDialog + + + + 0 + 0 + 320 + 180 + + + + Create Image + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + widthLabel + + + + 1 + 27 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Width: + + + Qt::AutoText + + + + + + + heightLabel + + + + 1 + 55 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Height: + + + Qt::AutoText + + + + + + + colorDepthCombo + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QComboBox::InsertAtBottom + + + + + + + nameLineEdit + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 1 + 0 + + + + Untitled image + + + QLineEdit::Normal + + + + + + + spinBox + + + + 74 + 1 + 227 + 20 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + spinBox_2 + + + + 74 + 27 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + nameLabel + + + + 1 + 1 + 67 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Name: + + + Qt::AutoText + + + + + + + colorDepthLabel + + + + 1 + 83 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Color depth: + + + Qt::AutoText + + + + + + + + + + + + + 9 + 121 + 302 + 18 + + + + Qt::Vertical + + + + + + + + + + 1 + + + 6 + + + + + + + + + 1 + 1 + 128 + 24 + + + + Qt::Horizontal + + + + + + + okButton + + + + 135 + 1 + 80 + 24 + + + + OK + + + + + + + cancelButton + + + + 221 + 1 + 80 + 24 + + + + Cancel + + + + + + + + + + nameLineEdit + spinBox + spinBox_2 + colorDepthCombo + okButton + cancelButton + + + + nameLineEdit + returnPressed() + okButton + animateClick() + + + -1 + 7 + + + -1 + 7 + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.h new file mode 100644 index 0000000..a14a628 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef IMAGEDIALOG_H +#define IMAGEDIALOG_H + +#include "ui_imagedialog.h" + +class ImageDialog : public QDialog +{ + Q_OBJECT + +public: + ImageDialog(QWidget *parent = 0); + +private: + Ui::ImageDialog ui; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.ui new file mode 100644 index 0000000..1c5e546 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/designer/singleinheritance/imagedialog.ui @@ -0,0 +1,389 @@ + + + ImageDialog + + + ImageDialog + + + + 0 + 0 + 320 + 180 + + + + Create Image + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + widthLabel + + + + 1 + 27 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Width: + + + Qt::AutoText + + + + + + + heightLabel + + + + 1 + 55 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Height: + + + Qt::AutoText + + + + + + + colorDepthCombo + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QComboBox::InsertAtBottom + + + + + + + nameLineEdit + + + + 74 + 83 + 227 + 22 + + + + + 5 + 0 + 1 + 0 + + + + Untitled image + + + QLineEdit::Normal + + + + + + + spinBox + + + + 74 + 1 + 227 + 20 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + spinBox_2 + + + + 74 + 27 + 227 + 22 + + + + + 5 + 0 + 0 + 0 + + + + QAbstractSpinBox::UpDownArrows + + + 32 + + + 1024 + + + 1 + + + + + + + nameLabel + + + + 1 + 1 + 67 + 20 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Name: + + + Qt::AutoText + + + + + + + colorDepthLabel + + + + 1 + 83 + 67 + 22 + + + + QFrame::NoFrame + + + QFrame::Plain + + + Color depth: + + + Qt::AutoText + + + + + + + + + + + + + 9 + 121 + 302 + 18 + + + + Qt::Vertical + + + + + + + + + + 1 + + + 6 + + + + + + + + + 1 + 1 + 128 + 24 + + + + Qt::Horizontal + + + + + + + okButton + + + + 135 + 1 + 80 + 24 + + + + OK + + + + + + + cancelButton + + + + 221 + 1 + 80 + 24 + + + + Cancel + + + + + + + + + + nameLineEdit + spinBox + spinBox_2 + colorDepthCombo + okButton + cancelButton + + + + nameLineEdit + returnPressed() + okButton + animateClick() + + + -1 + 7 + + + -1 + 7 + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py new file mode 100644 index 0000000..7bdcb0c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dialogs/dialogs.py @@ -0,0 +1,123 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] +def find(self): + if not self.findDialog: + self.findDialog = FindDialog(self) + self.findDialog.findNext.connect(self.findNext) + + self.findDialog.show() + self.findDialog.raise() + self.findDialog.activateWindow() + +//! [0] + +//! [1] +def countWords(self): + dialog = WordCountDialog(self) + dialog.setWordCount(document().wordCount()) + dialog.exec_() + +//! [1] + +//! [2] + mb = QMessageBox("Application Name", + "Hardware failure.\n\nDisk error detected\nDo you want to stop?", + QMessageBox.Question, + QMessageBox.Yes | QMessageBox.Default, + QMessageBox.No | QMessageBox.Escape, + QMessageBox.NoButton) + if mb.exec() == QMessageBox.No: + # try again +//! [2] + +//! [3] + progress = QProgressDialog("Copying files...", "Abort Copy", 0, numFiles, self) + progress.setWindowModality(Qt.WindowModal) + + for i in range(numFiles): + progress.setValue(i) + + if progress.wasCanceled(): + break + #... copy one file + + progress.setValue(numFiles) +//! [3] + +//! [4] +# Operation constructor +def __init__(self, parent=None): + QObject.__init__(self, parent) + + pd = QProgressDialog("Operation in progress.", "Cancel", 0, 100) + pd.canceled.connect(self.cancel) + t = QTimer(self) + t.timeout.connect(self.perform) + t.start(0) + +//! [4] //! [5] + +def perform(self): + pd.setValue(steps) + #... perform one percent of the operation + steps += 1 + if steps > pd.maximum(): + t.stop() + +//! [5] //! [6] + +def cancel(self): + t.stop() + #... cleanup + +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py new file mode 100644 index 0000000..bfc35e1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtcharts.py @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtCharts +//! [0] + +//! [3] +series = QtCharts.QLineSeries() +series.append(0,6) +series.append(2,4) +... +chartView = QtCharts.QChartView() +chartView.chart().addSeries(series) +chartView.chart().createDefaultAxes() +chartView.show() +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py new file mode 100644 index 0000000..11c3cf5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtgui.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtCore +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py new file mode 100644 index 0000000..4941453 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtmultimedia.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +import PySide2.QtMultimedia +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py new file mode 100644 index 0000000..c3363e9 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/doc_src_qtxmlpatterns.py @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +//! [0] +import PySide2.QtXmlPatterns +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/modules.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/modules.html new file mode 100644 index 0000000..9c67393 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/modules.html @@ -0,0 +1,28 @@ + + + + + + Qt 4.0: Qt Classes by Module + + + + + +

Qt Classes by Module

+ + + + + + + +
QtCoreCore classes used by other modules.
QtGuiGraphical User Interface components
QtNetworkClasses for network programming.
QtOpenGLOpenGL support classes.
QtSqlClasses for database integration using SQL.
QtXmlClasses for handling XML.
+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtcore.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtcore.html new file mode 100644 index 0000000..947ad40 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtcore.html @@ -0,0 +1,122 @@ + + + + + + Qt 4.0: QtCore Classes + + + + + + +

QtCore Classes

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QAbstractEventDispatcherManages Qt's event queue, excluding GUI-related events
QAbstractItemModelThe abstract interface for item model classes
QAbstractListModelAbstract model that can be subclassed to create one-dimensional list models
QAbstractTableModelAbstract model that can be subclassed to create table models
QBasicTimerTimer events for
QBitArrayArray of bits
QBufferQIODevice interface for a QByteArray
QByteArrayArray of bytes
QByteArrayMatcherHolds a sequence of bytes that can be quickly matched in a byte array
QCacheTemplate class that provides a cache
QChar16-bit Unicode character
QChildEventEvent parameters for child object events
QCoreApplicationEvent loop for Qt applications
QCustomEventSupport for custom events
QDataStreamSerialization of binary data to a QIODevice
QDateDate functions
QDateTimeDate and time functions
QDirAccess to directory structures and their contents
QEventThe base class of all event classes. Event objects contain event parameters
QFileInterface for reading from and writing to files
QFileEngineAbstraction for accessing the filesystem
QFileEngineHandlerAllows custom QFileEngines to be plugged into Qt
QFileInfoSystem-independent file information
QHashTemplate class that provides a hash-table-based dictionary
QIODeviceThe base interface class of all I/O devices in Qt
QLatin1Char8-bit ASCII/Latin-1 character
QLatin1StringThin wrapper around an ASCII/Latin-1 encoded string literal
QLibraryLoads shared libraries at runtime
QLibraryInfoInformation about the Qt library
QLineTwo-dimensional vector that uses integer point coordinates for accuracy
QLineFTwo-dimensional vector that uses floating point coordinates for accuracy
QLinkedListTemplate class that provides linked lists
QListTemplate class that provides lists
QLocaleConverts between numbers and their string representations in various languages
QMapTemplate class that provides a skip-list-based dictionary
QMetaClassInfoAdditional information about a class
QMetaEnumMeta data about an enumerator
QMetaMemberMeta data about a member function
QMetaObjectMeta information about Qt objects
QMetaPropertyMeta data about a property
QMetaTypeManages named types in the meta object system
QMimeDataContainer for data that records information about its MIME type
QModelIndexUsed to locate data in a data model
QMultiHashConvenience QHash subclass that provides multi-valued hashes
QMultiMapConvenience QMap subclass that provides multi-valued maps
QMutexAccess serialization between threads
QMutexLockerConvenience class that simplifies locking and unlocking mutexes
QObjectThe base class of all Qt objects
QObjectCleanupHandlerWatches the lifetime of multiple QObjects
QPairTemplate class that stores a pair of items
QPersistentModelIndexUsed to locate data in a data model
QPluginLoaderLoads a plugin at runtime
QPointDefines a point in the plane
QPointFPoint object that uses floating point coordinates for accuracy
QPointerTemplate class that provides guarded pointers to QObjects
QProcessUsed to start external programs and to communicate with them
QQueueGeneric container that provides a queue
QReadLockerConvenience class that simplifies locking and unlocking read-write locks for read access
QReadWriteLockRead-write locking
QRectDefines a rectangle in the plane
QRectFDefines a rectangle in the plane using floating point coordinates for accuracy
QRegExpPattern matching using regular expressions
QResourceAccess to application resource data
QSemaphoreGeneral counting semaphore
QSetTemplate class that provides a hash-table-based set
QSettingsPersistent platform-independent application settings
QSharedDataBase class for shared data objects
QSharedDataPointerPointer to a shared data object
QSignalCan be used to send signals for classes that do not inherit QObject
QSignalMapperBundles signals from identifiable senders
QSizeDefines the size of a two-dimensional object
QSizeFDefines the size of a two-dimensional object using floating point values for accuracy
QSocketNotifierSupport for monitoring activity on a file descriptor
QStackTemplate class that provides a stack
QStringUnicode character string
QStringListList of strings
QTemporaryFileI/O device that operates on temporary files
QTextCodecConversions between text encodings
QTextCodecPluginAbstract base for custom QTextCodec plugins
QTextDecoderState-based decoder
QTextEncoderState-based encoder
QTextIStreamConvenience class for input streams
QTextOStreamConvenience class for output streams
QTextStreamConvenient interface for reading and writing text
QThreadPlatform-independent threads
QThreadStoragePer-thread data storage
QTimeClock time functions
QTimerRepetitive and single-shot timers
QTimerEventParameters that describe a timer event
QTranslatorInternationalization support for text output
QTranslatorMessageTranslator message and its properties
QTsciiCodecConversion to and from the Tamil TSCII encoding
QUrlConvenient interface for working with URLs
QUuidDefines a Universally Unique Identifier (UUID)
QVarLengthArrayLow-level variable-length array
QVariantActs like a union for the most common Qt data types
QVectorTemplate class that provides a dynamic array
QWaitConditionCondition variable for synchronizing threads
QWriteLockerConvenience class that simplifies locking and unlocking read-write locks for write access

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtgui.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtgui.html new file mode 100644 index 0000000..9182b4c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtgui.html @@ -0,0 +1,276 @@ + + + + + + Qt 4.0: QtGui Classes + + + + + + +

QtGui Classes

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QAbstractButtonThe abstract base class of button widgets, providing functionality common to buttons
QAbstractItemDelegateUsed to display and edit data items from a model
QAbstractItemViewThe basic functionality for item view classes
QAbstractScrollAreaScrolling area with on-demand scroll bars
QAbstractSliderInteger value within a range
QAbstractSpinBoxSpinwidget and a line edit to display values
QAbstractTextDocumentLayoutAbstract base class used to implement custom layouts for QTextDocuments
QAccessibleEnums and static functions relating to accessibility
QAccessibleInterfaceDefines an interface that exposes information about accessible objects
QAccessibleObjectImplements parts of the QAccessibleInterface for QObjects
QAccessiblePluginAbstract base for accessibility plugins
QAccessibleWidgetImplements the QAccessibleInterface for QWidgets
QActionAbstract user interface action that can be inserted into widgets with QWidget::addAction()
QActionGroupGroups actions together
QApplicationManages the GUI application's control flow and main settings
QBitmapMonochrome (1-bit depth) pixmaps
QBoxLayoutLines up child widgets horizontally or vertically
QBrushDefines the fill pattern of shapes drawn by a QPainter
QButtonGroupContainer to organize groups of button widgets
QCDEStyleCDE look and feel
QCheckBoxCheckbox with a text label
QClipboardAccess to the window system clipboard
QCloseEventParameters that describe a close event
QColorColors based on RGB or HSV values
QColorDialogDialog widget for specifying colors
QColorGroup
QComboBoxCombined button and popup list
QCommonStyleEncapsulates the common Look and Feel of a GUI
QConicalGradientUsed in combination with QBrush to specify a conical gradient brush
QContextMenuEventParameters that describe a context menu event
QCopChannelCommunication capabilities between several clients
QCursorMouse cursor with an arbitrary shape
QDateTimeEditWidget for editing dates and times
QDecorationAllows the appearance of the Qtopia Core Window Manager to be customized
QDecorationFactoryCreates QDecoration objects
QDecorationPluginAbstract base for custom QDecoration plugins
QDesktopWidgetAccess to screen information on multi-head systems
QDialRounded range control (like a speedometer or potentiometer)
QDialogThe base class of dialog windows
QDirModelData model for the local filesystem
QDirectPainterDirect access to the video hardware
QDockWidgetWidget that can be docked inside a QMainWindow or floated as a top-level window on the desktop
QDoubleSpinBoxSpin box widget that takes doubles
QDoubleValidatorRange checking of floating-point numbers
QDragSupport for MIME-based drag and drop data transfer
QDragEnterEventEvent which is sent to a widget when a drag and drop action enters it
QDragLeaveEventEvent that is sent to a widget when a drag and drop action leaves it
QDragMoveEventEvent which is sent while a drag and drop action is in progress
QDropEventEvent which is sent when a drag and drop action is completed
QErrorMessageError message display dialog
QFileDialogDialog that allow users to select files or directories
QFileIconProviderFile icon for the QDirModel class
QFileOpenEventEvent that will be sent when there is a request to open a file
QFocusEventEvent parameters for widget focus events
QFocusFrameFocus frame which can be outside of a widget's normal paintable area
QFontFont used for drawing text
QFontDatabaseInformation about the fonts available in the underlying window system
QFontDialogDialog widget for selecting a font
QFontInfoGeneral information about fonts
QFontMetricsFont metrics information
QFontMetricsFFont metrics information
QFrameThe base class of widgets that can have a frame
QGfxDriverFactoryCreates QScreen objects for Qtopia Core
QGfxDriverPluginAbstract base for Qtopia Core graphics driver plugins
QGradientUsed in combination with QBrush to specify gradient fills
QGridLayoutLays out widgets in a grid
QGridWidgetSimple geometry management of its children
QGroupBoxGroup box frame with a title
QHBoxLayoutLines up widgets horizontally
QHBoxWidgetHorizontal geometry management for its child widgets
QHeaderViewHeader row or header column for item views
QHideEventEvent which is sent after a widget is hidden
QHoverEventParameters that describe a mouse event
QIconScalable icons in different modes and states
QIconDragEventIndicates that a main icon drag has begun
QIconEngineAbstract base class for QIcon renderers
QIconEnginePluginAbstract base for custom QIconEngine plugins
QImageHardware-independent pixmap that allows direct access to the pixel data, and can be used as a paint device
QImageIOHandlerDefines the common image I/O interface for all image formats in Qt
QImageIOHandlerFactoryInterfaceThe factory interface for QImageIOPlugin
QImageIOPluginDefines an interface for writing an image format plugin
QImageReaderFormat independent interface for reading images from files or other devices
QImageWriterFormat independent interface for writing images to files or other devices
QInputContextAbstracts the input method dependent data and composing state
QInputContextPluginAbstract base for custom QInputContext plugins
QInputDialogSimple convenience dialog to get a single value from the user
QInputEventThe base class for events that describe user input
QInputMethodEventParameters for input method events
QIntValidatorValidator that ensures a string contains a valid integer within a specified range
QItemDelegateDisplay and editing facilities for data items from a model
QItemSelectionManages information about selected items in a model
QItemSelectionModelKeeps track of a view's selected items
QItemSelectionRangeManages information about a range of selected items in a model
QKbdDriverFactoryCreates QWSKeyboardHandler objects for Qtopia Core
QKbdDriverPluginAbstract base for Qtopia Core keyboard driver plugins
QKeyEventDescribes a key event
QKeySequenceEncapsulates a key sequence as used by shortcuts
QLCDNumberDisplays a number with LCD-like digits
QLabelText or image display
QLayoutThe base class of geometry managers
QLayoutItemAbstract item that a QLayout manipulates
QLineEditOne-line text editor
QLinearGradientUsed in combination with QBrush to specify a linear gradient brush
QListViewDefault model/view implementation of a list, and of an icon view
QListWidgetItem-based list widget
QListWidgetItemItem for use with the QListWidget item view class
QMacMimeMaps open-standard MIME to Mac flavors
QMacStyleImplements an Appearance Manager style
QMainWindowMain application window
QMatrix2D transformations of a coordinate system
QMenuMenu widget for use in menu bars, context menus, and other popup menus
QMenuBarHorizontal menu bar
QMenuItemRepresents an item in a menu
QMessageBoxModal dialog with a short message, an icon, and some buttons
QMotifPlusStyleMore sophisticated Motif-ish look and feel
QMotifStyleMotif look and feel
QMouseDriverFactoryCreates QWSMouseHandler objects for Qtopia Core
QMouseDriverPluginAbstract base for Qtopia Core mouse driver plugins
QMouseEventParameters that describe a mouse event
QMoveEventEvent parameters for move events
QMovieConvenience class for playing movies with QImageReader
QPaintDeviceThe base class of objects that can be painted
QPaintEngineAbstract definition of how QPainter draws to a given device on a given platform
QPaintEventEvent parameters for paint events
QPainterDoes low-level painting e.g. on widgets
QPainterPathContainer for painting operations, enabling graphical shapes to be constructed and reused
QPaletteColor groups for each widget state
QPenDefines how a QPainter should draw lines and outlines of shapes
QPicturePaint device that records and replays QPainter commands
QPictureFormatPluginAbstract base for custom picture format plugins
QPictureIOParameters for loading and saving pictures
QPixmapOff-screen, pixel-based paint device
QPixmapCacheApplication-wide cache for pixmaps
QPlatinumStyleMac/Platinum look and feel
QPolygonVector of points
QPolygonFVector of points
QPrintEngineDefines an interface for how QPrinter interacts with a given printing subsystem
QPrinterPaint device that paints on a printer
QProgressBarHorizontal progress bar
QProgressDialogFeedback on the progress of a slow operation
QProxyModelSupport for filtering and sorting data that is passed between another model and a view
QPushButtonCommand button
QRadialGradientUsed in combination with QBrush to specify a radial gradient brush
QRadioButtonRadio button with a text label
QRegExpValidatorUsed to check a string against a regular expression
QRegionClip region for a painter
QResizeEventEvent parameters for resize events
QRubberBandRectangle or line that can indicate a selection or a boundary
QSGIStyleSGI/Irix look and feel
QScreenAnd its descendants manage the framebuffer and palette
QScrollAreaScrolling view onto another widget
QScrollBarVertical or horizontal scroll bar
QSessionManagerAccess to the session manager
QShortcutUsed to create keyboard shortcuts
QShowEventEvent that is sent when a widget is shown
QSizeGripCorner-grip for resizing a top-level window
QSizePolicyLayout attribute describing horizontal and vertical resizing policy
QSliderVertical or horizontal slider
QSoundAccess to the platform audio facilities
QSpacerItemBlank space in a layout
QSpinBoxSpin box widget
QSplashScreenSplash screen that can be shown during application startup
QSplitterImplements a splitter widget
QSplitterHandleHandle functionality of the splitter
QStackedLayoutStack of widgets where only one widget is visible at a time
QStackedWidgetStack of widgets where only one widget is visible at a time
QStandardItemModel
QStatusBarHorizontal bar suitable for presenting status information
QStyleAbstract base class that encapsulates the look and feel of a GUI
QStyleFactoryCreates QStyle objects
QStyleHintReturn
QStyleOptionStores the parameters used by QStyle functions
QStyleOptionButtonUsed to describe the parameters for drawing buttons
QStyleOptionComboBoxUsed to describe the parameter for drawing a combobox
QStyleOptionComplexUsed to hold parameters that are common to all complex controls
QStyleOptionDockWidgetUsed to describe the parameters for drawing a dock window
QStyleOptionFocusRectUsed to describe the parameters for drawing a focus rectangle with QStyle
QStyleOptionFrameUsed to describe the parameters for drawing a frame
QStyleOptionHeaderUsed to describe the parameters for drawing a header
QStyleOptionMenuItemUsed to describe the parameter necessary for drawing a menu item
QStyleOptionProgressBarUsed to describe the parameters necessary for drawing a progress bar
QStyleOptionQ3DockWindowUsed to describe the parameters for drawing various parts of a
QStyleOptionQ3ListViewUsed to describe the parameters for drawing a Q3ListView
QStyleOptionQ3ListViewItemUsed to describe an item drawn in a Q3ListView
QStyleOptionSliderUsed to describe the parameters needed for drawing a slider
QStyleOptionSpinBoxUsed to describe the parameters necessary for drawing a spin box
QStyleOptionTabUsed to describe the parameters for drawing a tab bar
QStyleOptionTitleBarUsed to describe the parameters for drawing a title bar
QStyleOptionToolBoxUsed to describe the parameters needed for drawing a tool box
QStyleOptionToolButtonUsed to describe the parameters for drawing a tool button
QStyleOptionViewItemUsed to describe the parameters used to draw an item in a view widget
QStylePainterConvenience class for drawing QStyle elements inside a widget
QStylePluginAbstract base for custom QStyle plugins
QTabBarTab bar, e.g. for use in tabbed dialogs
QTabWidgetStack of tabbed widgets
QTableViewDefault model/view implementation of a table view
QTableWidgetItem-based table view with a default model
QTableWidgetItemItem for use with the QTableWidget class
QTableWidgetSelectionRange
QTabletEventParameters that describe a Tablet event
QTextBlockContainer for text fragments in a QTextDocument
QTextBlockFormatFormatting information for blocks of text in a QTextDocument
QTextBlockGroupContainer for text blocks within a QTextDocument
QTextBrowserRich text browser with hypertext navigation
QTextCharFormatFormatting information for characters in a QTextDocument
QTextCursorOffers an API to access and modify QTextDocuments
QTextDocumentHolds formatted text that can be viewed and edited using a QTextEdit
QTextDocumentFragmentRepresents a piece of formatted text from a QTextDocument
QTextEditWidget that is used to edit and display both plain and rich text
QTextFormatFormatting information for a QTextDocument
QTextFragmentHolds a piece of text in a QTextDocument with a single QTextCharFormat
QTextFrameRepresents a frame in a QTextDocument
QTextFrameFormatFormatting information for frames in a QTextDocument
QTextImageFormatFormatting information for images in a QTextDocument
QTextInlineObjectRepresents an inline object in a QTextLayout
QTextLayoutUsed to lay out and paint a single paragraph of text
QTextLengthEncapsulates the different types of length used in a QTextDocument
QTextLineRepresents a line of text inside a QTextLayout
QTextListDecorated list of items in a QTextDocument
QTextListFormatFormatting information for lists in a QTextDocument
QTextObjectBase class for different kinds of objects that can group parts of a QTextDocument together
QTextOptionDescription of general rich text properties
QTextTableRepresents a table in a QTextDocument
QTextTableCellRepresents the properties of a cell in a QTextTable
QTextTableFormatFormatting information for tables in a QTextDocument
QToolBarMovable panel that contains a set of controls
QToolBarChangeEventEvent that is sent whenever a the toolbar button is clicked on Mac OS X
QToolBoxColumn of tabbed widget items
QToolButtonQuick-access button to commands or options, usually used inside a QToolBar
QToolTipTool tips (balloon help) for any widget
QTreeViewDefault model/view implementation of a tree view
QTreeWidgetTree view that uses a predefined tree model
QTreeWidgetItemItem for use with the QTreeWidget convenience class
QVBoxLayoutLines up widgets vertically
QVBoxWidgetVertical geometry management of its child widgets
QValidatorValidation of input text
QWSInputMethodInternational input methods for Qtopia Core
QWSKeyboardHandlerImplements the keyboard driver for Qtopia Core
QWSMouseHandlerMouse driver for Qtopia Core
QWSServerServer-specific functionality in Qtopia Core
QWSWindowServer-specific functionality in Qtopia Core
QWhatsThisSimple description of any widget, i.e. answering the question "What's this?"
QWhatsThisActionReady-made action to invoke "What's This" context help
QWheelEventParameters that describe a wheel event
QWidgetThe base class of all user interface objects
QWidgetContainerPluginAbstract base for complex custom container QWidget plugins
QWidgetItemLayout item that represents a widget
QWidgetPluginAbstract base for custom QWidget plugins
QWindowsMimeMaps open-standard MIME to Window Clipboard formats
QWindowsStyleMicrosoft Windows-like look and feel
QWindowsXPStyleMicrosoft WindowsXP-like look and feel
QWorkspaceWorkspace window that be used in an MDI application
QX11InfoInformation about the X display configuration

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtnetwork.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtnetwork.html new file mode 100644 index 0000000..01e1fa4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtnetwork.html @@ -0,0 +1,35 @@ + + + + + + Qt 4.0: QtNetwork Classes + + + + + + +

QtNetwork Classes

+

+ + + + + + + + + + + + +
QAbstractSocketThe base functionality common to all socket types
QFtpImplementation of the FTP protocol
QHostAddressIP address
QHostInfoStatic functions for host name lookups
QHttpImplementation of the HTTP protocol
QHttpHeaderHeader information for HTTP
QHttpRequestHeaderRequest header information for HTTP
QHttpResponseHeaderResponse header information for HTTP
QTcpServerTCP-based server
QTcpSocketTCP socket
QUdpSocketUDP socket
QUrlInfoStores information about URLs

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtopengl.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtopengl.html new file mode 100644 index 0000000..c42c4ae --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtopengl.html @@ -0,0 +1,27 @@ + + + + + + Qt 4.0: QtOpenGL Classes + + + + + + +

QtOpenGL Classes

+

+ + + + +
QGLColormapUsed for installing custom colormaps into QGLWidgets
QGLContextEncapsulates an OpenGL rendering context
QGLFormatThe display format of an OpenGL rendering context
QGLWidgetWidget for rendering OpenGL graphics

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtsql.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtsql.html new file mode 100644 index 0000000..db44d6d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtsql.html @@ -0,0 +1,39 @@ + + + + + + Qt 4.0: QtSql Classes + + + + + + +

QtSql Classes

+

+ + + + + + + + + + + + + + + + +
QSqlDatabaseRepresents a connection to a database
QSqlDriverAbstract base class for accessing specific SQL databases
QSqlDriverCreatorTemplate class that provides a SQL driver factory for a specific driver type
QSqlDriverCreatorBaseThe base class for SQL driver factories
QSqlDriverPluginAbstract base for custom QSqlDriver plugins
QSqlErrorSQL database error information
QSqlFieldManipulates the fields in SQL database tables and views
QSqlIndexFunctions to manipulate and describe database indexes
QSqlQueryMeans of executing and manipulating SQL statements
QSqlQueryModelRead-only data model for SQL result sets
QSqlRecordEncapsulates a database record
QSqlRelationStores information about an SQL foreign key
QSqlRelationalDelegate
QSqlRelationalTableModelEditable data model for a single database table, with foreign key support
QSqlResultAbstract interface for accessing data from specific SQL databases
QSqlTableModelEditable data model for a single database table

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtxml.html b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtxml.html new file mode 100644 index 0000000..d10d542 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/qtxml.html @@ -0,0 +1,53 @@ + + + + + + Qt 4.0: QtXml Classes + + + + + +

QtXml Classes

+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
QDomAttrRepresents one attribute of a QDomElement
QDomCDATASectionRepresents an XML CDATA section
QDomCharacterDataRepresents a generic string in the DOM
QDomCommentRepresents an XML comment
QDomDocumentRepresents an XML document
QDomDocumentFragmentTree of QDomNodes which is not usually a complete QDomDocument
QDomDocumentTypeThe representation of the DTD in the document tree
QDomElementRepresents one element in the DOM tree
QDomEntityRepresents an XML entity
QDomEntityReferenceRepresents an XML entity reference
QDomImplementationInformation about the features of the DOM implementation
QDomNamedNodeMapCollection of nodes that can be accessed by name
QDomNodeThe base class for all the nodes in a DOM tree
QDomNodeListList of QDomNode objects
QDomNotationRepresents an XML notation
QDomProcessingInstructionRepresents an XML processing instruction
QDomTextRepresents text data in the parsed XML document
QXmlAttributesXML attributes
QXmlContentHandlerInterface to report the logical content of XML data
QXmlDTDHandlerInterface to report DTD content of XML data
QXmlDeclHandlerInterface to report declaration content of XML data
QXmlDefaultHandlerDefault implementation of all the XML handler classes
QXmlEntityResolverInterface to resolve external entities contained in XML data
QXmlErrorHandlerInterface to report errors in XML data
QXmlInputSourceThe input data for the QXmlReader subclasses
QXmlLexicalHandlerInterface to report the lexical content of XML data
QXmlLocatorThe XML handler classes with information about the parsing position within a file
QXmlNamespaceSupportHelper class for XML readers which want to include namespace support
QXmlParseExceptionUsed to report errors with the QXmlErrorHandler interface
QXmlReaderInterface for XML readers (i.e. parsers)
QXmlSimpleReaderImplementation of a simple XML parser

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/titles.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/titles.txt new file mode 100644 index 0000000..016825d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/Resources/titles.txt @@ -0,0 +1,7 @@ +Qt Classes by Module :/Resources/modules.html +QtCore :/Resources/qtcore.html +QtGui :/Resources/qtgui.html +QtNetwork :/Resources/qtnetwork.html +QtOpenGL :/Resources/qtopengl.html +QtSql :/Resources/qtsql.html +QtXml :/Resources/qtxml.html diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/dockwidgets.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/dockwidgets.qrc new file mode 100644 index 0000000..8c462a5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/dockwidgets.qrc @@ -0,0 +1,12 @@ + + + Resources/titles.txt + Resources/modules.html + Resources/qtcore.html + Resources/qtgui.html + Resources/qtnetwork.html + Resources/qtopengl.html + Resources/qtsql.html + Resources/qtxml.html + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/mainwindow.h new file mode 100644 index 0000000..e9891d6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dockwidgets/mainwindow.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class QDockWidget; +class QListWidget; +class QListWidgetItem; +class QTextBrowser; + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +private slots: + void updateText(QListWidgetItem *item); + +private: + void setupContents(); + void setupDockWindow(); + void setupMenus(); + + QDockWidget *contentsWindow; + QListWidget *headingList; + QTextBrowser *textBrowser; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/dragwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/dragwidget.h new file mode 100644 index 0000000..88bff66 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/dragwidget.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DRAGWIDGET_H +#define DRAGWIDGET_H + +#include +#include +#include +#include + +class QComboBox; +class QFrame; +class QLabel; +class QTextBrowser; + +class DragWidget : public QFrame +{ + Q_OBJECT + +public: + DragWidget(QWidget *parent); + void setData(const QString &mimetype, const QByteArray &newData); + +signals: + void dragResult(const QString &actionText); + void mimeTypes(const QStringList &types); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + QByteArray data; + QLabel *dragDropLabel; + QPoint dragStartPosition; + QString mimeType; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/mainwindow.h new file mode 100644 index 0000000..ece2a81 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/draganddrop/mainwindow.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +class QComboBox; +class QLabel; +class QLineEdit; +class QMouseEvent; +class QTextEdit; +class DragWidget; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + +public slots: + void setDragResult(const QString &actionText); + void setMimeTypes(const QStringList &types); + +private: + QComboBox *mimeTypeCombo; + DragWidget *dragWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images.qrc new file mode 100644 index 0000000..30b8a29 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images.qrc @@ -0,0 +1,5 @@ + + + images/file.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images/file.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/dragging/images/file.png new file mode 100644 index 0000000000000000000000000000000000000000..9520080ed0bce0fb7a294663addd4ec947d4baa6 GIT binary patch literal 313 zcmV-90mlA`P))5pFc`-1f2AlQ;_Bky0lb2E2UjO24}9WccyC zACOpReq#Q?QBXpnAIW)n8*Uug5=osq*x1`3%vc88!(y>P*pSw^gA0ob3Ls%!<6h4d z&JlzJSb1Dc7CH>L0I=Y0xraX^3NYfzo)mzWzPbv>jM;G~Lx3}f?-+z3QzlL&rRT!g zX^(FC>T5Xjup6Q#=WVc_Z1iokNN$Bqn*pDkRQ%BJy!p2ZKT&wzE&5 +#include +#include + +class QLabel; +class QLineEdit; +class QMouseEvent; +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + +protected: + void mousePressEvent(QMouseEvent *event); + +private: + QLabel *iconLabel; + QLineEdit *nameEdit; + QPixmap iconPixmap; + QPoint dragStartPosition; + QTextEdit *commentEdit; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dropactions/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropactions/window.h new file mode 100644 index 0000000..8607b69 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropactions/window.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include + +class QComboBox; +class QFrame; +class QTextBrowser; + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(QWidget *parent = 0); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private: + QComboBox *mimeTypeCombo; + QFrame *dropFrame; + QTextBrowser *textBrowser; + QString oldText; + QStringList oldMimeTypes; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp new file mode 100644 index 0000000..6628520 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/droparea.cpp @@ -0,0 +1,147 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * + + +DropArea.DropArea(QWidget *parent) + : QLabel(parent) +{ + setMinimumSize(200, 200) + setFrameStyle(QFrame.Sunken | QFrame::StyledPanel) + setAlignment(Qt.AlignCenter) + setAcceptDrops(True) + setAutoFillBackground(True) + clear() +} + +void DropArea.dragEnterEvent(QDragEnterEvent *event) +{ + setText(tr("")) + setBackgroundRole(QPalette.Highlight) + + event.acceptProposedAction() + emit changed(event.mimeData()) +} + +void DropArea.dragMoveEvent(QDragMoveEvent *event) +{ + event.acceptProposedAction() +} + +void DropArea.dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event.mimeData() + + if (mimeData.hasImage()) { + setPixmap(qvariant_cast(mimeData.imageData())) + } else if (mimeData.hasHtml()) { + setText(mimeData.html()) + setTextFormat(Qt.RichText) + } else if (mimeData.hasText()) { + setText(mimeData.text()) + setTextFormat(Qt.PlainText) + } else { + setText(tr("Cannot display data")) + } + + setBackgroundRole(QPalette.Dark) + event.acceptProposedAction() +} + +//![0] +def paste(self): + clipboard = QGuiApplication.clipboard() + mimeData = clipboard.mimeData() + + if mimeData.hasImage(): + setPixmap(mimeData.imageData()) + elif mimeData.hasHtml(): + setText(mimeData.html()) + setTextFormat(Qt.RichText) + elif (mimeData.hasText(): + setText(mimeData.text()) + setTextFormat(Qt.PlainText) + else: + setText(tr("Cannot display data")) +//![0] + + emit changed(mimeData) + setBackgroundRole(QPalette.Dark) + //event.acceptProposedAction() +} + +void DropArea.dragLeaveEvent(QDragLeaveEvent *event) +{ + clear() + event.accept() +} + +void DropArea.clear() +{ + setText(tr("")) + setBackgroundRole(QPalette.Dark) + + emit changed() +} + +QPixmap DropArea.extractPixmap(const QByteArray &data, const QString &format) +{ + QList imageFormats = QImageReader.supportedImageFormats() + QPixmap pixmap + + foreach (QByteArray imageFormat, imageFormats) { + if (format.mid(6) == QString(imageFormat)) { + pixmap.loadFromData(data, imageFormat) + break + } + } + return pixmap +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py new file mode 100644 index 0000000..66a6a7b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/dropevents/window.py @@ -0,0 +1,65 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtWidgets import QWidget, QComboBox, QFrame, QTextBrowser + +class Window(QWidget): + + def __init__(self, parent=None): + self.mimeTypeCombo = QComboBox() + self.dropFrame = QFrame() + self.textBrowser = QTextBrowser() + self.oldText = "" + self.oldMimeTypes = [] + + def dragEnterEvent(self, event): + pass + def dropEvent(self, event): + pass diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/droprectangle/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/droprectangle/window.h new file mode 100644 index 0000000..e7854bc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/droprectangle/window.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include + +class QComboBox; +class QFrame; +class QTextBrowser; + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(QWidget *parent = 0); + +protected: + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + +private: + QComboBox *mimeTypeCombo; + QFrame *dropFrame; + QTextBrowser *textBrowser; + QString oldText; + QStringList oldMimeTypes; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/eventfilters/filterobject.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/eventfilters/filterobject.h new file mode 100644 index 0000000..18fd7b8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/eventfilters/filterobject.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FILTEROBJECT_H +#define FILTEROBJECT_H + +#include + +class FilterObject : public QObject +{ + Q_OBJECT + +public: + FilterObject(QObject *parent = 0); + bool eventFilter(QObject *object, QEvent *event); + void setFilteredObject(QObject *object); + +private: + QObject *target; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/explicitlysharedemployee/employee.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/explicitlysharedemployee/employee.h new file mode 100644 index 0000000..66ca6b3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/explicitlysharedemployee/employee.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EMPLOYEE_H +#define EMPLOYEE_H + +#include +#include + +class EmployeeData : public QSharedData +{ +public: + EmployeeData(); + EmployeeData(const EmployeeData &other); + ~EmployeeData(); + + int id; + QString *name; +}; + +class Employee +{ +public: + Employee(); + Employee(int id, const QString &name); + + void setId(int id) { d->id = id; } + void setName(const QString &name); + + int id() const { return d->id; } + QString name() const; + +private: + QExplicitlySharedDataPointer d; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.h new file mode 100644 index 0000000..0f49fe2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYCLASS_H +#define MYCLASS_H + +#include + +//! [0] +class MyClass +{ + Q_DECLARE_TR_FUNCTIONS(MyClass) + +public: + MyClass(); +//! [0] + /* ... */ +//! [1] +}; +//! [1] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.ts b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.ts new file mode 100644 index 0000000..9bd90f2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/myclass.ts @@ -0,0 +1,12 @@ + + + + MyClass + + + Hello Qt! + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/resources.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/resources.qrc new file mode 100644 index 0000000..903ac85 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/resources.qrc @@ -0,0 +1,6 @@ + + + translations/i18n-non-qt-class_en.qm + translations/i18n-non-qt-class_fr.qm + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_en.ts b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_en.ts new file mode 100644 index 0000000..54f1886 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_en.ts @@ -0,0 +1,12 @@ + + + + MyClass + + + Hello Qt! + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_fr.ts b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_fr.ts new file mode 100644 index 0000000..3f3cebc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/i18n-non-qt-class/translations/i18n-non-qt-class_fr.ts @@ -0,0 +1,13 @@ + + + + MyClass + + + Hello Qt! + + Bonjour Qt! + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/image/image.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/image/image.cpp new file mode 100644 index 0000000..a35f95c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/image/image.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + image = QImage() + ba = QByteArray() + buffer(ba) + buffer.open(QIODevice.WriteOnly) + image.save(buffer, "PNG") # writes image into ba in PNG format +//! [0] +//! [1] + pixmap = QPixmap() + bytes = QByteArray() + buffer(bytes) + buffer.open(QIODevice.WriteOnly) + pixmap.save(buffer, "PNG") # writes pixmap into bytes in PNG format +//! [1] +//! [2] + alpha = QPixmap("image-with-alpha.png") + alphacopy = alpha + alphacopy.setMask(alphacopy.mask()) +//! [2] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/image/supportedformat.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/image/supportedformat.cpp new file mode 100644 index 0000000..2d8459f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/image/supportedformat.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + writer = QImageWriter() + writer.setFormat("png") + if writer.supportsOption(QImageIOHandler.Description): + print "Png supports embedded text" +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/inherited-slot/button.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/inherited-slot/button.h new file mode 100644 index 0000000..855bea0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/inherited-slot/button.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +//! [Button class with reimplemented slot] +class Button : public QPushButton +{ + Q_OBJECT + +public: + Button(QWidget *parent = 0); + +public slots: + void animateClick(); +}; +//! [Button class with reimplemented slot] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/itemselection/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/itemselection/model.h new file mode 100644 index 0000000..6b40768 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/itemselection/model.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp new file mode 100644 index 0000000..9bcc5db --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/layouts/layouts.cpp @@ -0,0 +1,126 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + window = QWidget() +//! [0] //! [1] + button1 = QPushButton("One") +//! [1] //! [2] + button2 = QPushButton("Two") + button3 = QPushButton("Three") + button4 = QPushButton("Four") + button5 = QPushButton("Five") +//! [2] + +//! [3] + layout = QHBoxLayout() +//! [3] //! [4] + layout.addWidget(button1) + layout.addWidget(button2) + layout.addWidget(button3) + layout.addWidget(button4) + layout.addWidget(button5) + + window.setLayout(layout) +//! [4] //! [5] + window.show() +//! [5] + +//! [6] + window = QWidget() +//! [6] //! [7] + button1 = QPushButton("One") +//! [7] //! [8] + button2 = QPushButton("Two") + button3 = QPushButton("Three") + button4 = QPushButton("Four") + button5 = QPushButton("Five") +//! [8] + +//! [9] + layout = QVBoxLayout() + +//! [9] //! [10] + layout.addWidget(button1) + layout.addWidget(button2) + layout.addWidget(button3) + layout.addWidget(button4) + layout.addWidget(button5) + + window.setLayout(layout) +//! [10] //! [11] + window.show() +//! [11] + +//! [12] + window = QWidget() +//! [12] //! [13] + button1 = QPushButton("One") +//! [13] //! [14] + button2 = QPushButton("Two") + button3 = QPushButton("Three") + button4 = QPushButton("Four") + button5 = QPushButton("Five") +//! [14] + +//! [15] + layout = QGridLayout() + +//! [15] //! [16] + layout.addWidget(button1, 0, 0) + layout.addWidget(button2, 0, 1) + layout.addWidget(button3, 1, 0, 1, 2) + layout.addWidget(button4, 2, 0) + layout.addWidget(button5, 2, 1) + + window.setLayout(layout) +//! [16] //! [17] + window.show() +//! [17] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp new file mode 100644 index 0000000..1b0f94e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/mainwindowsnippet.cpp @@ -0,0 +1,58 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + dockWidget = QDockWidget(tr("Dock Widget"), self) + dockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | + Qt.RightDockWidgetArea) + dockWidget.setWidget(dockWidgetContents) + addDockWidget(Qt.LeftDockWidgetArea, dockWidget) +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp new file mode 100644 index 0000000..369d25a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/matrix/matrix.cpp @@ -0,0 +1,112 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +def paintEvent(self, event): + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) + painter.drawRect(0, 0, 100, 100) + + painter.rotate(45) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QMatrix") +//! [0] + + +//! [1] +def paintEvent(self, event) + + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) + painter.drawRect(0, 0, 100, 100) + + matrix = QMatrix() + matrix.translate(50, 50) + matrix.rotate(45) + matrix.scale(0.5, 1.0) + painter.setMatrix(matrix) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QMatrix") + +//! [1] + + +//! [2] +def paintEvent(self, event) + + pi = 3.14 + + a = pi/180 * 45.0 + sina = sin(a) + cosa = cos(a) + + translationMatrix = QMatrix(1, 0, 0, 1, 50.0, 50.0) + rotationMatrix = QMatrix(cosa, sina, -sina, cosa, 0, 0) + scalingMatrix = QMatrix(0.5, 0, 0, 1.0, 0, 0) + + matrix = QMatrix() + matrix = scalingMatrix * rotationMatrix * translationMatrix + + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt::DashLine)) + painter.drawRect(0, 0, 100, 100) + + painter.setMatrix(matrix) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QMatrix") + +//! [2] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp new file mode 100644 index 0000000..f7d07c8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/mdiareasnippets.cpp @@ -0,0 +1,66 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + mainWindow = QMainWindow() + mainWindow.setCentralWidget(mdiArea) +//! [0] + +//! [1] + mdiArea = QMdiArea() + subWindow1 = QMdiSubWindow() + subWindow1.setWidget(internalWidget1) + subWindow1.setAttribute(Qt.WA_DeleteOnClose) + mdiArea.addSubWindow(subWindow1) + + subWindow2 = QMdiSubWindow() + mdiArea.addSubWindow(internalWidget2) +//! [1] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass1.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass1.h new file mode 100644 index 0000000..0391b48 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass1.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYCLASS1_H +#define MYCLASS1_H + +#include + +#define MyClass MyClass1 + +//! [0] +class MyClass : public QObject +{ + Q_OBJECT + +public: + MyClass(QObject *parent = 0); + ~MyClass(); + +signals: + void mySignal(); + +public slots: + void mySlot(); +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass2.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass2.h new file mode 100644 index 0000000..e39cb6a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass2.h @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYCLASS2_H +#define MYCLASS2_H + +#include + +#define MyClass MyClass2 + +//! [0] +class MyClass : public QObject +{ + Q_OBJECT + Q_PROPERTY(Priority priority READ priority WRITE setPriority) + Q_ENUMS(Priority) + +public: + enum Priority { High, Low, VeryHigh, VeryLow }; + + MyClass(QObject *parent = 0); + ~MyClass(); + + void setPriority(Priority priority); + Priority priority() const; +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass3.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass3.h new file mode 100644 index 0000000..5110c62 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/moc/myclass3.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYCLASS3_H +#define MYCLASS3_H + +#include + +//! [0] +class MyClass : public QObject +{ + Q_OBJECT + Q_CLASSINFO("Author", "Oscar Peterson") + Q_CLASSINFO("Status", "Active") + +public: + MyClass(QObject *parent = 0); + ~MyClass(); +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/model.h new file mode 100644 index 0000000..e9f8587 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/model.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class LinearModel : public QAbstractListModel +{ + Q_OBJECT +public: + LinearModel(QObject *parent = 0) + : QAbstractListModel(parent) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int row, int column = 0, const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + +private: + QVector values; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/view.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/view.h new file mode 100644 index 0000000..f6a5e71 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/view.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIEW_H +#define VIEW_H + +#include +#include +#include +#include +#include +#include +#include + +class LinearView : public QAbstractItemView +{ + Q_OBJECT +public: + LinearView(QWidget *parent = 0); + + QRect itemViewportRect(const QModelIndex &index) const; + void ensureVisible(const QModelIndex &index); + QModelIndex itemAt(int x, int y) const; + +protected slots: + /*void dataChanged(const QModelIndex &topLeft, const QModelIndex + &bottomRight);*/ + void rowsInserted(const QModelIndex &parent, int start, int end); + void rowsRemoved(const QModelIndex &parent, int start, int end); + /*void selectionChanged(const QItemSelection &deselected, const QItemSelection &selected); + void verticalScrollbarAction(int action); + void horizontalScrollbarAction(int action);*/ + +protected: + void setSelection(const QRect&, QItemSelectionModel::SelectionFlags command); + QRect selectionViewportRect(const QItemSelection &selection) const; + QRect itemRect(const QModelIndex &item) const; + bool isIndexHidden(const QModelIndex &index) const; + int horizontalOffset() const; + int verticalOffset() const; + QModelIndex moveCursor(QAbstractItemView::CursorAction cursorAction, + Qt::KeyboardModifiers modifiers); + + void paintEvent(QPaintEvent *event); + void resizeEvent(QResizeEvent *event); + QSize sizeHint() const; + +private: + int rows(const QModelIndex &index = QModelIndex()) const; + void updateGeometries(); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/window.h new file mode 100644 index 0000000..ac4988f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/modelview-subclasses/window.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include + +#include "model.h" +#include "view.h" + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow::MainWindow(QWidget *parent = 0); + +public slots: + void selectOpenFile(); + +private: + void setupModelView(); + void openFile(const QString &fileName); + + LinearModel *model; + LinearView *view; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/myscrollarea.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/myscrollarea.cpp new file mode 100644 index 0000000..2e6869c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/myscrollarea.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtCore import * +from PySide2.QtGui import * +import sys + +class MyScrollArea (QAbstractScrollArea): + widget = None + + def __init__(widget): + self.setWidget(widget); + + def setWidget(w): + self.widget = w; + self.widget.setParent(viewport()); + if not self.widget.testAttribute(Qt.WA_Resized): + self.widget.resize(widget.sizeHint()) + + self.verticalScrollBar().setValue(0) + self.verticalScrollBar().setValue(0) + + self.updateArea() + + + def updateWidgetPosition(): +//! [0] + hvalue = self.horizontalScrollBar().value() + vvalue = self.verticalScrollBar().value() + topLeft = self.viewport().rect().topLeft() + + self.widget.move(topLeft.x() - hvalue, topLeft.y() - vvalue) +//! [0] + + + def scrollContentsBy(dx, dy): + self.updateWidgetPosition() + + def updateArea(): +//! [1] + areaSize = viewport().size() + widgetSize = widget.size() + + self.verticalScrollBar().setPageStep(widgetSize.height()) + self.horizontalScrollBar().setPageStep(widgetSize.width()) + self.verticalScrollBar().setRange(0, widgetSize.height() - areaSize.height()) + self.horizontalScrollBar().setRange(0, widgetSize.width() - areaSize.width()) + self.updateWidgetPosition() +//! [1] + + def resizeEvent(QResizeEvent): + self.updateArea() + +app = QApplication(sys.argv) +pixmap = QPixmap("mypixmap.png") +label = QLabel() +label.setPixmap(pixmap) +area = MyScrollArea(label) +area.resize(300, 300) +area.show() + +area.setWidget(label) + +app.exec_(); + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp new file mode 100644 index 0000000..fc7d278 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/network/tcpwait.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtGui import * +from PySide2.QtNetwork import QTcpSocket + +def main(): + app = QCoreApplication() + + socket = QTcpSocket() + socket.connectToHost("localhost", 1025) + +//! [0] + numRead = 0 + numReadTotal = 0 + + while(True): + buffer = socket.read(50) + # do whatever with array + numReadTotal += buffer.size() + if (buffer.size() == 0 && !socket.waitForReadyRead()): + break +//! [0] + return app.exec_() diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/ntfsp.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/ntfsp.cpp new file mode 100644 index 0000000..c50c3cd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/ntfsp.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +//! [0] +extern Q_CORE_EXPORT int qt_ntfs_permission_lookup; +//! [0] + +//! [1] +qt_ntfs_permission_lookup += 1 // turn checking on +qt_ntfs_permission_lookup += 1 // turn it off again +//! [1] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyHTMLElement.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyHTMLElement.xq new file mode 100644 index 0000000..9f5ee12 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyHTMLElement.xq @@ -0,0 +1 @@ +doc('data.xml')/*:body diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyXLinkAttribute.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyXLinkAttribute.xq new file mode 100644 index 0000000..059bcc0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/anyXLinkAttribute.xq @@ -0,0 +1,2 @@ +declare namespace xlink = "http://www.w3.org/1999/xlink"; +doc('image.svg')//@xlink:* diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncluded.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncluded.xq new file mode 100644 index 0000000..3961c28 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncluded.xq @@ -0,0 +1 @@ +{sum((1, 2, 3))} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncludedResult.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncludedResult.xml new file mode 100644 index 0000000..0004c71 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesIncludedResult.xml @@ -0,0 +1 @@ +6 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmitted.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmitted.xq new file mode 100644 index 0000000..ffbadd0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmitted.xq @@ -0,0 +1 @@ +sum({(1, 2, 3)}) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmittedResult.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmittedResult.xml new file mode 100644 index 0000000..744fb8f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/bracesOmittedResult.xml @@ -0,0 +1,2 @@ + +sum(1 2 3) \ No newline at end of file diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/computedTreeFragment.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/computedTreeFragment.xq new file mode 100644 index 0000000..c5b93ad --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/computedTreeFragment.xq @@ -0,0 +1,14 @@ +declare default element namespace "http://example.com/Namespace"; +declare variable $documentElementName := "doc"; + +element {$documentElementName} +{ + attribute xml:base {"http://example.com/"}, + element anotherElement + { + comment {" a comment "}, + processing-instruction target {"data"}, + element anotherElement {()}, + text {"some text"} + } +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyAttribute.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyAttribute.xq new file mode 100644 index 0000000..40e4494 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyAttribute.xq @@ -0,0 +1,9 @@ + + +

+ { + doc('feed.rss')/rss/@version + } +

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyID.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyID.xq new file mode 100644 index 0000000..2409caf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/copyID.xq @@ -0,0 +1,3 @@ +(: Copy the value of xml:id attribute from other.html. This is a comment by the way! :) + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/directTreeFragment.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/directTreeFragment.xq new file mode 100644 index 0000000..96bc963 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/directTreeFragment.xq @@ -0,0 +1,7 @@ + + + + + + some text + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/doc.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/doc.txt new file mode 100644 index 0000000..d30b057 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/doc.txt @@ -0,0 +1,35 @@ + +

+ 1 + 2 +

+

+ 3 + 4 +

+

+ 5 + 6 +

+

+ 7 + 8 +

+

+ 9 + a +

+

+ b + c +

+

+ d + e +

+

+ f + 0 +

+
+ diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML.xq new file mode 100644 index 0000000..622bec8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML.xq @@ -0,0 +1 @@ +doc("myPlainHTML.html")/body diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML2.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML2.xq new file mode 100644 index 0000000..5e7fbae --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/docPlainHTML2.xq @@ -0,0 +1 @@ +doc("myPlainHTML.html")/html/body diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML.xq new file mode 100644 index 0000000..b513922 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML.xq @@ -0,0 +1,10 @@ +declare default element namespace "http://www.w3.org/1999/xhtml"; + + + { + for $i in doc("testResult.xml")/tests/test[@status = "failure"] + order by $i/@name + return

{$i/@name}

+ } + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML2.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML2.xq new file mode 100644 index 0000000..754ddba --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/embedDataInXHTML2.xq @@ -0,0 +1,10 @@ +declare namespace x = "http://www.w3.org/1998/xhtml"; + + + { + for $i in doc("testResult.xml")/tests/test[@status = "failure"] + order by $i/@name + return {$i/@name} + } + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/emptyParagraphs.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/emptyParagraphs.xq new file mode 100644 index 0000000..6024d28 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/emptyParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')//p[string-length(.) = 0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeCurlyBraces.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeCurlyBraces.xq new file mode 100644 index 0000000..669e7c1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeCurlyBraces.xq @@ -0,0 +1,4 @@ + + This is one left followed by one right curly brace: {{ }} + Here they are again, but with character references: { } + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xml new file mode 100644 index 0000000..425ccb0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xml @@ -0,0 +1,2 @@ +

"I hate quotations" -- Ralph Waldo Emerson" + '"I hate quotations"" -- Ralph Waldo Emerson"', appeared above

\ No newline at end of file diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xq new file mode 100644 index 0000000..4a6054b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/escapeStringLiterals.xq @@ -0,0 +1,7 @@ +

+{ + """I hate quotations"" -- Ralph Waldo Emerson""", + " ", + '''"I hate quotations"" -- Ralph Waldo Emerson"'', appeared above' +} +

diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/expressionInsideAttribute.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/expressionInsideAttribute.xq new file mode 100644 index 0000000..97f46b1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/expressionInsideAttribute.xq @@ -0,0 +1,2 @@ +declare variable $additionalClass := "example"; +

diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnPath.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnPath.xq new file mode 100644 index 0000000..d23dfe8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnPath.xq @@ -0,0 +1,2 @@ +let $doc := doc('doc.txt') +return ($doc/doc/p/span)[1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnStep.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnStep.xq new file mode 100644 index 0000000..46b77fa --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/filterOnStep.xq @@ -0,0 +1,2 @@ +let $doc := doc('doc.txt') +return $doc/doc/p/span[1] \ No newline at end of file diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/firstParagraph.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/firstParagraph.xq new file mode 100644 index 0000000..db5e2c7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/firstParagraph.xq @@ -0,0 +1 @@ +doc("index.html")/html/body/p[@xml:id = "thatSpecialOne"] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/fnStringOnAttribute.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/fnStringOnAttribute.xq new file mode 100644 index 0000000..b26e9f2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/fnStringOnAttribute.xq @@ -0,0 +1,9 @@ + + +

+ { + string(doc('feed.rss')/rss/@version) + } +

+ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause.xq new file mode 100644 index 0000000..a412dca --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause.xq @@ -0,0 +1,3 @@ +for $i in(reverse(1 to 10)), + $d in xs:integer(doc("numbers.xml")/numbers/number) +return ($i + $d) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause2.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause2.xq new file mode 100644 index 0000000..4fa505d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClause2.xq @@ -0,0 +1,3 @@ +for $i in(reverse(1 to 10)), + $d in xs:integer(doc("numbers.xml")/numbers/number) +return $i + $d diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClauseOnFeed.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClauseOnFeed.xq new file mode 100644 index 0000000..9ec3339 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/forClauseOnFeed.xq @@ -0,0 +1,6 @@ +for $item in doc('feed.rss')//item +return

+ { + $item/description/node() + } +

diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/indented.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/indented.xml new file mode 100644 index 0000000..a312c63 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/indented.xml @@ -0,0 +1,5 @@ + + + +

Some Text

+
diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introAcneRemover.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introAcneRemover.xq new file mode 100644 index 0000000..4e6ee80 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introAcneRemover.xq @@ -0,0 +1,8 @@ + + The following skin care products have shipped, ordered by shipping date(oldest first): + { + for $i in doc("myOrders.xml")/orders/order[@product = "Acme Skin Care"] + order by xs:date($i/@shippingDate) descending + return $i + } + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introExample2.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introExample2.xq new file mode 100644 index 0000000..411cc17 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introExample2.xq @@ -0,0 +1,5 @@ + +{ + doc($file)/bib/book[publisher = $publisher and @year > $year]/{title} +} + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introFileHierarchy.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introFileHierarchy.xml new file mode 100644 index 0000000..cfa6151 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introFileHierarchy.xml @@ -0,0 +1,14 @@ + + + + + + + + + ... + + + ... + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introNavigateFS.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introNavigateFS.xq new file mode 100644 index 0000000..1f5a3a7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introNavigateFS.xq @@ -0,0 +1,12 @@ +declare variable $myRoot := ; (: This line is a dummy and shouldn't appear in the documentation. :) + + + { + $myRoot//file[@mimetype = 'text/xml' or @mimetype = 'application/xml'] + / + (if(doc-available(@uri)) + then () + else

Failed to parse file {@uri}.

) + } + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introductionExample.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introductionExample.xq new file mode 100644 index 0000000..1a309dd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/introductionExample.xq @@ -0,0 +1,3 @@ + +{doc("library.xml")/bib/book[publisher="Addison-Wesley" and @year>1991]/{title}} + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/invalidLetOrderBy.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/invalidLetOrderBy.xq new file mode 100644 index 0000000..d65f240 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/invalidLetOrderBy.xq @@ -0,0 +1,3 @@ +let $i := (2, 3, 1) +order by $i[1] +return $i diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/items.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/items.xq new file mode 100644 index 0000000..0b46ec1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/items.xq @@ -0,0 +1,5 @@ +, +xs:base64Binary("FFFF"), +current-date(), +3e3, (: A floating point value :) +attribute {"name"} {()} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/letOrderBy.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/letOrderBy.xq new file mode 100644 index 0000000..f4106d2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/letOrderBy.xq @@ -0,0 +1,4 @@ +for $a in (8, -4, 2) +let $b := ($a * -1, $a) +order by $a +return $b diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/literalsAndOperators.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/literalsAndOperators.xq new file mode 100644 index 0000000..ec4af33 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/literalsAndOperators.xq @@ -0,0 +1,2 @@ +declare variable $date := fn:current-date(); (: This line should not be part of the example. It exists in order to make the query valid. :) +fn:current-date() - $date > xs:dayTimeDuration("P365D") diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/mobeyDick.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/mobeyDick.xml new file mode 100644 index 0000000..32d0b6c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/mobeyDick.xml @@ -0,0 +1,4 @@ + + Mobey Dick ... + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nextLastParagraph.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nextLastParagraph.xq new file mode 100644 index 0000000..9424f79 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nextLastParagraph.xq @@ -0,0 +1 @@ +doc('index.html')//p[last() - 1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq new file mode 100644 index 0000000..ce36e84 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsAreExpressions.xq @@ -0,0 +1,4 @@ +let $docURI := 'maybeNotWellformed.xml' +return if(doc-available($docURI)) + then doc($docURI)//p/{./node()} + else Failed to load {$docURI} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsInPaths.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsInPaths.xq new file mode 100644 index 0000000..beb294f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeConstructorsInPaths.xq @@ -0,0 +1 @@ +doc('feed.rss')//item/

{description/node()}

diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeTestChildElement.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeTestChildElement.xq new file mode 100644 index 0000000..7aa7b34 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/nodeTestChildElement.xq @@ -0,0 +1 @@ +doc('index.html')/descendant-or-self::element(p)/child::element(span) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/notIndented.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/notIndented.xml new file mode 100644 index 0000000..b3321f2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/notIndented.xml @@ -0,0 +1 @@ +

Some Text

diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/oneElementConstructor.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/oneElementConstructor.xq new file mode 100644 index 0000000..b7eb615 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/oneElementConstructor.xq @@ -0,0 +1 @@ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq new file mode 100644 index 0000000..16438d1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsExceptTheFiveFirst.xq @@ -0,0 +1 @@ +doc('index.html')//p[position() > 5] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsWithTables.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsWithTables.xq new file mode 100644 index 0000000..dbb9fcf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/paragraphsWithTables.xq @@ -0,0 +1 @@ +doc('index.html')/html/body/p[table] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathAB.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathAB.xq new file mode 100644 index 0000000..26fd1e5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathAB.xq @@ -0,0 +1 @@ +doc('index.html')//p/span diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathsAllParagraphs.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathsAllParagraphs.xq new file mode 100644 index 0000000..ba47900 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/pathsAllParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')//p diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleHTML.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleHTML.xq new file mode 100644 index 0000000..93ac31e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleHTML.xq @@ -0,0 +1 @@ +doc("index.html")/html/body/p[@class="example"] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleXHTML.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleXHTML.xq new file mode 100644 index 0000000..fda5371 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/simpleXHTML.xq @@ -0,0 +1,2 @@ +declare namespace x = "http://www.w3.org/1999/xhtml/"; +doc("index.html")/x:html/x:body/x:p[@class="example"] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/svgDocumentElement.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/svgDocumentElement.xml new file mode 100644 index 0000000..0c7be4e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/svgDocumentElement.xml @@ -0,0 +1 @@ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/tablesInParagraphs.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/tablesInParagraphs.xq new file mode 100644 index 0000000..fc92cf0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/tablesInParagraphs.xq @@ -0,0 +1 @@ +doc('index.html')/html/body/p/table diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/twoSVGElements.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/twoSVGElements.xq new file mode 100644 index 0000000..ab4fe35 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/twoSVGElements.xq @@ -0,0 +1,5 @@ +declare namespace s = "http://www.w3.org/2000/svg"; +declare default element namespace "http://www.w3.org/2000/svg"; +let $doc := doc('image.svg') +return ($doc/svg, + $doc/s:svg) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xmlStylesheet.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xmlStylesheet.xq new file mode 100644 index 0000000..9e02208 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xmlStylesheet.xq @@ -0,0 +1 @@ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsBooleanTrue.xq b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsBooleanTrue.xq new file mode 100644 index 0000000..897a99e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsBooleanTrue.xq @@ -0,0 +1 @@ +xs:boolean("true") diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsvgDocumentElement.xml b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsvgDocumentElement.xml new file mode 100644 index 0000000..fb6a236 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/patternist/xsvgDocumentElement.xml @@ -0,0 +1 @@ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/mainwindow.h new file mode 100644 index 0000000..8f8c36f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/mainwindow.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include + +class QAbstractItemModel; +class QAction; +class QItemSelectionModel; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget *parent = 0); + +private slots: + void insertItem(); + void removeItem(); + void updateMenus(const QModelIndex ¤tIndex); + +private: + QAbstractItemModel *model; + QAction *insertAction; + QAction *removeAction; + QItemSelectionModel *selectionModel; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/model.h new file mode 100644 index 0000000..0dbd0b8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/persistentindexes/model.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class StringListModel : public QAbstractListModel +{ + Q_OBJECT +public: + StringListModel(const QStringList &strings, QObject *parent = 0) + : QAbstractListModel(parent), stringList(strings) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + +private: + QStringList stringList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp new file mode 100644 index 0000000..6d4ef56 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/picture/picture.cpp @@ -0,0 +1,121 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + picture = QPicture() + painter = QPainter() + painter.begin(picture) # paint in picture + painter.drawEllipse(10,20, 80,70) # draw an ellipse + painter.end() # painting done + picture.save("drawing.pic") # save picture +//! [0] + +//! [1] + picture = QPicture() + picture.load("drawing.pic") # load picture + painter = QPainter() + painter.begin(myImage) # paint in myImage + painter.drawPicture(0, 0, picture) # draw the picture at (0,0) + painter.end() # painting done +//! [1] + +//! [2] + list = QPicture.inputFormatList() + for string in list: + myProcessing(string) +//! [2] + +//! [3] + list = QPicture.outputFormatList() + for string in list: + myProcessing(string) +//! [3] + +//! [4] + iio = QPictureIO() + pixmap = QPixmap() + iio.setFileName("vegeburger.pic") + if iio.read(): # OK + picture = iio.picture() + painter = QPainter(pixmap) + painter.drawPicture(0, 0, picture) + +//! [4] + +//! [5] + iio = QPictureIO() + picture = QPicture() + painter = QPainter(picture) + painter.drawPixmap(0, 0, pixmap) + iio.setPicture(picture) + iio.setFileName("vegeburger.pic") + iio.setFormat("PIC") + if iio.write(): + return True # returned true if written successfully +//! [5] + +//! [6] +def readSVG(picture): + # read the picture using the picture.ioDevice() + +//! [6] + + +//! [7] +def writeSVG(picture): + # write the picture using the picture.ioDevice() + +//! [7] + + +//! [8] + # add the SVG picture handler + # ... +//! [8] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/plaintextlayout/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/plaintextlayout/window.h new file mode 100644 index 0000000..1d14ed0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/plaintextlayout/window.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); + +private: + QFont font; + QString text; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp new file mode 100644 index 0000000..03c9f40 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/polygon/polygon.cpp @@ -0,0 +1,96 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + polygon = QPolygon() + polygon << QPoint(10, 20) << QPoint(20, 30) +//! [0] + +//! [1] + polygon = QPolygonF() + polygon << QPointF(10.4, 20.5) << QPointF(20.2, 30.2) +//! [1] + +//! [2] + points = [ 10, 20, 30, 40 ] + polygon = QPolygon() + polygon.setPoints(2, points) +//! [2] + +//! [3] + polygon = QPolygon() + polygon.setPoints(2, 10, 20, 30, 40) +//! [3] + +//! [4] + polygon = QPolygon(1) + polygon[0] = QPoint(4, 5) + polygon.putPoints(1, 2, 6,7, 8,9) +//! [4] + +//! [5] + polygon = QPolygon(3) + polygon.putPoints(0, 3, 4,5, 0,0, 8,9) + polygon.putPoints(1, 1, 6,7) +//! [5] + +//! [6] + polygon1 = QPolygon() + polygon1.putPoints(0, 3, 1,2, 0,0, 5,6) + # polygon1 is now the three-point polygon(1,2, 0,0, 5,6) + + polygon2 = QPolygon() + polygon2.putPoints(0, 3, 4,4, 5,5, 6,6) + # polygon2 is now (4,4, 5,5, 6,6) + + polygon1.putPoints(2, 3, polygon2) + # polygon1 is now the five-point polygon(1,2, 0,0, 4,4, 5,5, 6,6) +//! [6] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/porting4-dropevents/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/porting4-dropevents/window.h new file mode 100644 index 0000000..56bab84 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/porting4-dropevents/window.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include + +class QComboBox; +class QFrame; +class QLabel; + +class MyWidget : public QWidget +{ + Q_OBJECT + +public: + MyWidget(QWidget *parent = 0); + +protected: + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + QComboBox *mimeTypeCombo; + QFrame *dropFrame; + QLabel *dataLabel; + QString oldText; + QStringList oldMimeTypes; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/errors.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/errors.cpp new file mode 100644 index 0000000..8c71d1e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/errors.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + printer = QPrinter() + printer.setOutputFormat(QPrinter.PdfFormat) + printer.setOutputFileName("/foobar/nonwritable.pdf") + QPainter painter + if painter.begin(printer): # failed to open file + print "failed to open file, is it writable?" + return 1 + + painter.drawText(10, 10, "Test") + if !printer.Page(): + print "failed in flushing page to disk, disk full?" + return 1 + + painter.drawText(10, 10, "Test 2") + painter.end() +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/object.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/object.h new file mode 100644 index 0000000..a70dcd1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/printing-qprinter/object.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +class Object : public QObject +{ + Q_OBJECT + +public: + Object(QObject *parent = 0); + +public slots: + void print(); +}; diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qabstractsliderisnippet.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qabstractsliderisnippet.cpp new file mode 100644 index 0000000..db93f8e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qabstractsliderisnippet.cpp @@ -0,0 +1,519 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +QAbstractSliderPrivate::QAbstractSliderPrivate() + : minimum(0), maximum(99), singleStep(1), pageStep(10), + value(0), position(0), pressValue(-1), tracking(true), blocktracking(false), pressed(false), + invertedAppearance(false), invertedControls(false), + orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction) +{ +} + +QAbstractSliderPrivate::~QAbstractSliderPrivate() +{ +} + +oid QAbstractSlider::setRange(int min, int max) +{ + Q_D(QAbstractSlider); + int oldMin = d->minimum; + int oldMax = d->maximum; + d->minimum = min; + d->maximum = qMax(min, max); + if (oldMin != d->minimum || oldMax != d->maximum) { + sliderChange(SliderRangeChange); + emit rangeChanged(d->minimum, d->maximum); + setValue(d->value); // re-bound + } +} + + +void QAbstractSliderPrivate::setSteps(int single, int page) +{ + Q_Q(QAbstractSlider); + singleStep = qAbs(single); + pageStep = qAbs(page); + q->sliderChange(QAbstractSlider::SliderStepsChange); +} + +AbstractSlider::QAbstractSlider(QWidget *parent) + :QWidget(*new QAbstractSliderPrivate, parent, 0) +{ +} + +QAbstractSlider::QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent) + :QWidget(dd, parent, 0) +{ +} + +QAbstractSlider::~QAbstractSlider() +{ +} + +void QAbstractSlider::setOrientation(Qt::Orientation orientation) +{ + Q_D(QAbstractSlider); + if (d->orientation == orientation) + return; + + d->orientation = orientation; + if (!testAttribute(Qt::WA_WState_OwnSizePolicy)) { + QSizePolicy sp = sizePolicy(); + sp.transpose(); + setSizePolicy(sp); + setAttribute(Qt::WA_WState_OwnSizePolicy, false); + } + update(); + updateGeometry(); +} + +Qt::Orientation QAbstractSlider::orientation() const +{ + Q_D(const QAbstractSlider); + return d->orientation; +} + + +void QAbstractSlider::setMinimum(int min) +{ + Q_D(QAbstractSlider); + setRange(min, qMax(d->maximum, min)); +} + +int QAbstractSlider::minimum() const +{ + Q_D(const QAbstractSlider); + return d->minimum; +} + + +void QAbstractSlider::setMaximum(int max) +{ + Q_D(QAbstractSlider); + setRange(qMin(d->minimum, max), max); +} + +int QAbstractSlider::maximum() const +{ + Q_D(const QAbstractSlider); + return d->maximum; +} + + + +void QAbstractSlider::setSingleStep(int step) +{ + Q_D(QAbstractSlider); + d->setSteps(step, d->pageStep); +} + +int QAbstractSlider::singleStep() const +{ + Q_D(const QAbstractSlider); + return d->singleStep; +} + + +void QAbstractSlider::setPageStep(int step) +{ + Q_D(QAbstractSlider); + d->setSteps(d->singleStep, step); +} + +int QAbstractSlider::pageStep() const +{ + Q_D(const QAbstractSlider); + return d->pageStep; +} + +oid QAbstractSlider::setTracking(bool enable) +{ + Q_D(QAbstractSlider); + d->tracking = enable; +} + +bool QAbstractSlider::hasTracking() const +{ + Q_D(const QAbstractSlider); + return d->tracking; +} + + + +void QAbstractSlider::setSliderDown(bool down) +{ + Q_D(QAbstractSlider); + bool doEmit = d->pressed != down; + + d->pressed = down; + + if (doEmit) { + if (down) + emit sliderPressed(); + else + emit sliderReleased(); + } + + if (!down && d->position != d->value) + triggerAction(SliderMove); +} + +bool QAbstractSlider::isSliderDown() const +{ + Q_D(const QAbstractSlider); + return d->pressed; +} + + +void QAbstractSlider::setSliderPosition(int position) +{ + Q_D(QAbstractSlider); + position = d->bound(position); + if (position == d->position) + return; + d->position = position; + if (!d->tracking) + update(); + if (d->pressed) + emit sliderMoved(position); + if (d->tracking && !d->blocktracking) + triggerAction(SliderMove); +} + +int QAbstractSlider::sliderPosition() const +{ + Q_D(const QAbstractSlider); + return d->position; +} + + + +int QAbstractSlider::value() const +{ + Q_D(const QAbstractSlider); + return d->value; +} + +//! [0] +void QAbstractSlider::setValue(int value) +//! [0] +{ + Q_D(QAbstractSlider); + value = d->bound(value); + if (d->value == value && d->position == value) + return; + d->value = value; + if (d->position != value) { + d->position = value; + if (d->pressed) + emit sliderMoved((d->position = value)); + } +#ifndef QT_NO_ACCESSIBILITY +//! [1] + QAccessible::updateAccessibility(this, 0, QAccessible::ValueChanged); +//! [1] +#endif + sliderChange(SliderValueChange); + emit valueChanged(value); +//! [2] +} +//! [2] + +bool QAbstractSlider::invertedAppearance() const +{ + Q_D(const QAbstractSlider); + return d->invertedAppearance; +} + +void QAbstractSlider::setInvertedAppearance(bool invert) +{ + Q_D(QAbstractSlider); + d->invertedAppearance = invert; + update(); +} + + + +bool QAbstractSlider::invertedControls() const +{ + Q_D(const QAbstractSlider); + return d->invertedControls; +} + +void QAbstractSlider::setInvertedControls(bool invert) +{ + Q_D(QAbstractSlider); + d->invertedControls = invert; +} + +void QAbstractSlider::triggerAction(SliderAction action) +{ + Q_D(QAbstractSlider); + d->blocktracking = true; + switch (action) { + case SliderSingleStepAdd: + setSliderPosition(d->value + d->singleStep); + break; + case SliderSingleStepSub: + setSliderPosition(d->value - d->singleStep); + break; + case SliderPageStepAdd: + setSliderPosition(d->value + d->pageStep); + break; + case SliderPageStepSub: + setSliderPosition(d->value - d->pageStep); + break; + case SliderToMinimum: + setSliderPosition(d->minimum); + break; + case SliderToMaximum: + setSliderPosition(d->maximum); + break; + case SliderMove: + case SliderNoAction: + break; + }; + emit actionTriggered(action); + d->blocktracking = false; + setValue(d->position); +} + +void QAbstractSlider::setRepeatAction(SliderAction action, int thresholdTime, int repeatTime) +{ + Q_D(QAbstractSlider); + if ((d->repeatAction = action) == SliderNoAction) { + d->repeatActionTimer.stop(); + } else { + d->repeatActionTime = repeatTime; + d->repeatActionTimer.start(thresholdTime, this); + } +} + +QAbstractSlider::SliderAction QAbstractSlider::repeatAction() const +{ + Q_D(const QAbstractSlider); + return d->repeatAction; +} + +void QAbstractSlider::timerEvent(QTimerEvent *e) +{ + Q_D(QAbstractSlider); + if (e->timerId() == d->repeatActionTimer.timerId()) { + if (d->repeatActionTime) { // was threshold time, use repeat time next time + d->repeatActionTimer.start(d->repeatActionTime, this); + d->repeatActionTime = 0; + } + if (d->repeatAction == SliderPageStepAdd) + d->setAdjustedSliderPosition(d->value + d->pageStep); + else if (d->repeatAction == SliderPageStepSub) + d->setAdjustedSliderPosition(d->value - d->pageStep); + else + triggerAction(d->repeatAction); + } +} + +oid QAbstractSlider::sliderChange(SliderChange) +{ + update(); +} + + +#ifndef QT_NO_WHEELEVENT +void QAbstractSlider::wheelEvent(QWheelEvent * e) +{ + Q_D(QAbstractSlider); + e->ignore(); + if (e->orientation() != d->orientation && !rect().contains(e->pos())) + return; + + static qreal offset = 0; + static QAbstractSlider *offset_owner = 0; + if (offset_owner != this){ + offset_owner = this; + offset = 0; + } + + int step = qMin(QApplication::wheelScrollLines() * d->singleStep, d->pageStep); + if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) + step = d->pageStep; + offset += e->delta() * step / 120; + if (d->invertedControls) + offset = -offset; + + if (qAbs(offset) < 1) + return; + + int prevValue = d->value; + d->position = d->value + int(offset); // value will be updated by triggerAction() + triggerAction(SliderMove); + if (prevValue == d->value) { + offset = 0; + } else { + offset -= int(offset); + e->accept(); + } +} +#endif +void QAbstractSlider::keyPressEvent(QKeyEvent *ev) +{ + Q_D(QAbstractSlider); + SliderAction action = SliderNoAction; + switch (ev->key()) { +#ifdef QT_KEYPAD_NAVIGATION + case Qt::Key_Select: + if (QApplication::keypadNavigationEnabled()) + setEditFocus(!hasEditFocus()); + else + ev->ignore(); + break; + case Qt::Key_Back: + if (QApplication::keypadNavigationEnabled() && hasEditFocus()) { + setValue(d->origValue); + setEditFocus(false); + } else + ev->ignore(); + break; +#endif + + // It seems we need to use invertedAppearance for Left and right, otherwise, things look weird. + case Qt::Key_Left: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + ev->ignore(); + return; + } + if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical) + action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd; + else +#endif + action = !d->invertedAppearance ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Right: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled() && !hasEditFocus()) { + ev->ignore(); + return; + } + if (QApplication::keypadNavigationEnabled() && d->orientation == Qt::Vertical) + action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub; + else +#endif + action = !d->invertedAppearance ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_Up: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled()) { + ev->ignore(); + break; + } +#endif + action = d->invertedControls ? SliderSingleStepSub : SliderSingleStepAdd; + break; + case Qt::Key_Down: +#ifdef QT_KEYPAD_NAVIGATION + if (QApplication::keypadNavigationEnabled()) { + ev->ignore(); + break; + } +#endif + action = d->invertedControls ? SliderSingleStepAdd : SliderSingleStepSub; + break; + case Qt::Key_PageUp: + action = d->invertedControls ? SliderPageStepSub : SliderPageStepAdd; + break; + case Qt::Key_PageDown: + action = d->invertedControls ? SliderPageStepAdd : SliderPageStepSub; + break; + case Qt::Key_Home: + action = SliderToMinimum; + break; + case Qt::Key_End: + action = SliderToMaximum; + break; + default: + ev->ignore(); + break; + } + if (action) + triggerAction(action); +} + +void QAbstractSlider::changeEvent(QEvent *ev) +{ + Q_D(QAbstractSlider); + switch (ev->type()) { + case QEvent::EnabledChange: + if (!isEnabled()) { + d->repeatActionTimer.stop(); + setSliderDown(false); + } + // fall through... + default: + QWidget::changeEvent(ev); + } +} + +bool QAbstractSlider::event(QEvent *e) +{ +#ifdef QT_KEYPAD_NAVIGATION + Q_D(QAbstractSlider); + switch (e->type()) { + case QEvent::FocusIn: + d->origValue = d->value; + break; + default: + break; + } +#endif + + return QWidget::event(e); +} + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-listfiles/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-listfiles/main.cpp new file mode 100644 index 0000000..9bd6399 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-listfiles/main.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + +from PySide2.QtCore import QDir, QCoreApplication +import sys + +app = QCoreApplication(sys.argv) +directory = QDir() +directory.setFilter(QDir.Files | QDir.Hidden | QDir.NoSymLinks) +directory.setSorting(QDir.Size | QDir.Reversed) + +for entry in directory.entryInfoList(): + print "%s %s" % (entry.size(), entry.fileName()) + +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-namefilters/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-namefilters/main.cpp new file mode 100644 index 0000000..ab22163 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qdir-namefilters/main.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtCore import * + +def main(): + dir_ = QDir() + dir_.setFilter(QDir.Files | QDir.Hidden | QDir.NoSymLinks) + dir_.setSorting(QDir.Size | QDir.Reversed) + +//! [0] + filters = ["*.cpp", "*.cxx", "*.cc"] + dir_.setNameFilters(filters) +//! [0] +// + lst = d.entryInfoList() + + print " Bytes Filename" + for fileInfo in lst: + print '%d %s' % (fileInfo.size(), fileInfo.fileName()) + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp new file mode 100644 index 0000000..bc199b2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qfontdatabase/main.cpp @@ -0,0 +1,74 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + database = QFontDatabase() + fontTree = QTreeWidget() + fontTree.setColumnCount(2) + fontTree.setHeaderLabels(QStringList() << "Font" << "Smooth Sizes") + + for family in database.families(): + familyItem = QTreeWidgetItem(fontTree) + familyItem.setText(0, family) + + for style in database.styles(family): + styleItem = QTreeWidgetItem(familyItem) + styleItem.setText(0, style) + + sizes = 0 + for points in database.smoothSizes(family, style): + sizes += QString.number(points) + " " + + styleItem.setText(1, sizes.trimmed()) + +//! [0] //! [1] + +//! [1] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlineargradient/paintwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlineargradient/paintwidget.h new file mode 100644 index 0000000..d43ff3e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlineargradient/paintwidget.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PAINTWIDGET_H +#define PAINTWIDGET_H + +#include + +class QPaintEvent; + +class PaintWidget : public QWidget +{ + Q_OBJECT + +public: + PaintWidget(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/mainwindow.h new file mode 100644 index 0000000..9788231 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/mainwindow.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QListView; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setupListItems(); + + QListView *listView; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/model.h new file mode 100644 index 0000000..5ced99c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-dnd/model.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include + +class DragDropListModel : public QStringListModel +{ + Q_OBJECT + +public: + DragDropListModel(const QStringList &strings, QObject *parent = 0); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + QMimeData *mimeData(const QModelIndexList &indexes) const; + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/mainwindow.h new file mode 100644 index 0000000..848ef6b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/mainwindow.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include + +class QAction; +class QListView; +class StringListModel; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void insertItem(); + void removeItem(); + void sortAscending(); + void sortDescending(); + void updateMenus(const QModelIndex ¤t); + +private: + QAction *insertAction; + QAction *removeAction; + QListView *listView; + StringListModel *model; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/model.h new file mode 100644 index 0000000..6451ac2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistview-using/model.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class StringListModel : public QAbstractListModel +{ + Q_OBJECT + +public: + StringListModel(const QStringList &strings, QObject *parent = 0) + : QAbstractListModel(parent), stringList(strings) {} + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &index = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &index = QModelIndex()); + +private: + QStringList stringList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-dnd/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-dnd/mainwindow.h new file mode 100644 index 0000000..ca6e41c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-dnd/mainwindow.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QListWidget; +class QListWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setupListItems(); + + QListWidget *listWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-using/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-using/mainwindow.h new file mode 100644 index 0000000..b03749d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qlistwidget-using/mainwindow.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QListWidget; +class QListWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void insertItem(); + void removeItem(); + void sortAscending(); + void sortDescending(); + void updateMenus(QListWidgetItem *current); + +private: + void setupListItems(); + + QAction *insertAction; + QAction *removeAction; + QListWidget *listWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmacnativewidget/main.mm b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmacnativewidget/main.mm new file mode 100644 index 0000000..12794b1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmacnativewidget/main.mm @@ -0,0 +1,144 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#ifdef QT_MAC_USE_COCOA +#import +#else +#include +#endif + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); +#ifdef QT_MAC_USE_COCOA +//![0] + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(200, app.desktop()->height() - 200, 239, 200) + styleMask:NSTitledWindowMask | NSClosableWindowMask + | NSMiniaturizableWindowMask | NSResizableWindowMask + backing:NSBackingStoreBuffered defer:NO]; + + QMacNativeWidget *nativeWidget = new QMacNativeWidget(); + nativeWidget->move(0, 0); + nativeWidget->setPalette(QPalette(Qt::red)); + nativeWidget->setAutoFillBackground(true); + QVBoxLayout *layout = new QVBoxLayout(); + QPushButton *pushButton = new QPushButton("An Embedded Qt Button!", nativeWidget); + pushButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // Don't use the layout rect calculated from QMacStyle. + layout->addWidget(pushButton); + nativeWidget->setLayout(layout); + + // Adjust Cocoa layouts + NSView *nativeWidgetView = reinterpret_cast(nativeWidget->winId()); + NSView *contentView = [window contentView]; + [contentView setAutoresizesSubviews:YES]; + [nativeWidgetView setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [nativeWidgetView setAutoresizesSubviews:YES]; + NSView *pushButtonView = reinterpret_cast(pushButton->winId()); + [pushButtonView setAutoresizingMask:NSViewWidthSizable]; + + // Add the nativeWidget to the window. + [contentView addSubview:nativeWidgetView positioned:NSWindowAbove relativeTo:nil]; + nativeWidget->show(); + pushButton->show(); + + // Show the window. + [window makeKeyAndOrderFront:window]; + [pool release]; +//![0] +#else +//![1] + Rect contentRect; + SetRect(&contentRect, 200, 200, 400, 400); + HIWindowRef windowRef; + CreateNewWindow(kDocumentWindowClass, kWindowStandardDocumentAttributes | kWindowCompositingAttribute | kWindowStandardHandlerAttribute | kWindowLiveResizeAttribute, &contentRect, &windowRef); + HIViewRef contentView = 0; + GetRootControl(windowRef, &contentView); + + QMacNativeWidget *nativeWidget = new QMacNativeWidget(); + nativeWidget->move(0, 0); + nativeWidget->setPalette(QPalette(Qt::red)); + nativeWidget->setAutoFillBackground(true); + QVBoxLayout *layout = new QVBoxLayout(); + QPushButton *pushButton = new QPushButton("An Embedded Qt Button!", nativeWidget); + pushButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); // Don't use the layout rect calculated from QMacStyle. + layout->addWidget(pushButton); + nativeWidget->setLayout(layout); + HIViewRef nativeWidgetView = reinterpret_cast(nativeWidget->winId()); + // Add the nativeWidget to the window. + HIViewAddSubview(contentView, nativeWidgetView); + + // Adjust Carbon layouts + HILayoutInfo layoutInfo; + layoutInfo.version = kHILayoutInfoVersionZero; + HIViewGetLayoutInfo(nativeWidgetView, &layoutInfo); + + layoutInfo.binding.top.toView = contentView; + layoutInfo.binding.top.kind = kHILayoutBindTop; + layoutInfo.binding.left.toView = contentView; + layoutInfo.binding.left.kind = kHILayoutBindLeft; + layoutInfo.binding.right.toView = contentView; + layoutInfo.binding.right.kind = kHILayoutBindRight; + layoutInfo.binding.bottom.toView = contentView; + layoutInfo.binding.bottom.kind = kHILayoutBindBottom; + + HIViewSetLayoutInfo(nativeWidgetView, &layoutInfo); + HIViewApplyLayout(nativeWidgetView); + + pushButton->show(); + nativeWidget->show(); + // Show the window. + ShowWindow(windowRef); +//![1] +#endif + return app.exec(); // gives us the same behavior in both +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/delegate.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/delegate.h new file mode 100644 index 0000000..ff07205 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/delegate.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/main.cpp new file mode 100644 index 0000000..ff07205 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/main.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.cpp new file mode 100644 index 0000000..ff07205 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.cpp @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.h new file mode 100644 index 0000000..ff07205 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/model.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/paintwidget_unix.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/paintwidget_unix.cpp new file mode 100644 index 0000000..e4361c6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/paintwidget_unix.cpp @@ -0,0 +1,54 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +int main(int argc, char *argv[]) +{ + return 0; +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/view.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/view.h new file mode 100644 index 0000000..ff07205 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmake/view.h @@ -0,0 +1,50 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qmetaobject-invokable/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmetaobject-invokable/window.h new file mode 100644 index 0000000..7c87111 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qmetaobject-invokable/window.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +//! [Window class with invokable method] +class Window : public QWidget +{ + Q_OBJECT + +public: + Window(); + void normalMethod(); + Q_INVOKABLE void invokableMethod(); +}; +//! [Window class with invokable method] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qquickview-ex.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qquickview-ex.cpp new file mode 100644 index 0000000..380989e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qquickview-ex.cpp @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + + qmlFile = os.path.join(os.path.dirname(__file__), 'view.qml') + view.setSource(QUrl.fromLocalFile(os.path.abspath(qmlFile))) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + + app.exec_() + # Deleting the view before it goes out of scope is required to make + # sure all child QML instances are destroyed in the correct order. + del view +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/buttonwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/buttonwidget.h new file mode 100644 index 0000000..6763da0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/buttonwidget.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BUTTONWIDGET_H +#define BUTTONWIDGET_H + +#include + +class QSignalMapper; +class QString; +class QStringList; + +//! [0] + +class ButtonWidget(QWidget): + def __init__(self, texts, parent=None): + QWidget.__init__(self, parent) + ... +//! [0] //! [1] + +//! [1] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/mainwindow.h new file mode 100644 index 0000000..18037fa --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsignalmapper/mainwindow.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow() + { + statusBar()->showMessage(tr("Ready")); + } + +public slots: + void buttonPressed(const QString &text) + { + statusBar()->showMessage(tr("Chose %1").arg(text)); + } +}; diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp new file mode 100644 index 0000000..9b097f3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsortfilterproxymodel-details/main.cpp @@ -0,0 +1,79 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] //! [1] + treeView = QTreeView() +//! [0] + model = MyItemModel(self) + + treeView.setModel(model) +//! [1] + +//! [2] + sourceModel = MyItemModel(self) + proxyModel = QSortFilterProxyModel(self) + + proxyModel.setSourceModel(sourceModel) + treeView.setModel(proxyModel) +//! [2] + +//! [3] + treeView.setSortingEnabled(True) +//! [3] + +//! [4] + proxyModel.sort(2, Qt.AscendingOrder) +//! [4] //! [5] + proxyModel.setFilterRegExp(QRegExp(".png", Qt.CaseInsensitive, + QRegExp.FixedString)) + proxyModel.setFilterKeyColumn(1) +//! [5] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp new file mode 100644 index 0000000..33b48f7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/main.cpp @@ -0,0 +1,66 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] +def main(): + app = QApplication(sys.argv) + pixmap = QPixmap(":/splash.png") + splash = QSplashScreen(pixmap) + splash.show() + app.processEvents() +//! [0] + +//! [1] + window = QMainWindow() + window.show() + splash.finish(&window) + return app.exec_() +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/mainwindow.h new file mode 100644 index 0000000..2213203 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/mainwindow.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/qsplashscreen.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/qsplashscreen.qrc new file mode 100644 index 0000000..330ec78 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/qsplashscreen.qrc @@ -0,0 +1,5 @@ + + + splash.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/splash.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsplashscreen/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..d82f6d21844a9eabd058a5ecaa2fd72fa2b56ca2 GIT binary patch literal 27926 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 RVUYj;002ovPDHLkV1n}eJAeQH literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py new file mode 100644 index 0000000..1841284 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedlayout/main.py @@ -0,0 +1,87 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtWidgets import QApplication, QWidget, QStackedLayout, QComboBox + +class Widget(QWidget) + def __init__(self, parent=None): + QWidget.__init__(self, parent) +//! [0] + self.firstPageWidget = QWidget() + self.secondPageWidget = QWidget() + self.thirdPageWidget = QWidget() + + self.stackedLayout = QStackedLayout() + self.stackedLayout.addWidget(self.firstPageWidget) + self.stackedLayout.addWidget(self.secondPageWidget) + self.stackedLayout.addWidget(self.thirdPageWidget) + +//! [0] //! [1] + self.pageComboBox = QComboBox() + self.pageComboBox.addItem(tr("Page 1")) + self.pageComboBox.addItem(tr("Page 2")) + self.pageComboBox.addItem(tr("Page 3")) + self.pageComboBox.activated.connect(self.stackedLayout.setCurrentIndex) +//! [1] + +//! [2] + self.mainLayout = QVBoxLayout() +//! [2] + self.mainLayout.addWidget(self.pageComboBox) +//! [3] + self.mainLayout.addLayout(self.stackedLayout) + self.setLayout(self.mainLayout) +//! [3] + +if __name__ == "__main__": + app = QApplication(sys.argv) + widget = Widget() + widget.show() + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py new file mode 100644 index 0000000..6f2c49d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstackedwidget/main.py @@ -0,0 +1,77 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] + firstPageWidget = QWidget() + secondPageWidget = QWidget() + thirdPageWidget = QWidget() + + stackedWidget = QStackedWidget() + stackedWidget.addWidget(firstPageWidget) + stackedWidget.addWidget(secondPageWidget) + stackedWidget.addWidget(thirdPageWidget) + +//! [0] //! [1] + pageComboBox = QComboBox() + pageComboBox.addItem(tr("Page 1")) + pageComboBox.addItem(tr("Page 2")) + pageComboBox.addItem(tr("Page 3")) + pageComboBox.activated[int].connect(stackedWidget.setCurrentIndex) + +//! [1] //! [2] + layout = QVBoxLayout() +//! [2] + layout.addWidget(pageComboBox) +//! [3] + layout.addWidget(stackedWidget) + setLayout(layout) +//! [3] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstatustipevent/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstatustipevent/main.cpp new file mode 100644 index 0000000..0ba3895 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstatustipevent/main.cpp @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] //! [1] +def __init__(self, parent): + QMainWindow.__init__(self, parent) +//! [0] + myWidget = QWidget() + myWidget.setStatusTip(tr("This is my widget.")) + + setCentralWidget(myWidget) +//! [1] + +//! [2] + fileMenu = menuBar().addMenu(tr("File")) + + Act = QAction(self.tr("&New"), self) + Act.setStatusTip(tr("Create a new file.")) + fileMenu.addAction(Act) +//! [2] + + statusBar().showMessage(self.tr("Ready")) + setWindowTitle(tr("QStatusTipEvent")) +//! [3] + +//! [3] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qstyleoption/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstyleoption/main.cpp new file mode 100644 index 0000000..12fb026 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qstyleoption/main.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def paintEvent(self, qpaintevent): + option = QStyleOptionButton() + option.initFrom(self) + if isDown(): + option.state = QStyle.State_Sunken + else: + option.state = QStyle.State_Raised + + if self.isDefault(): + option.features = option.features or QStyleOptionButton.DefaultButton + option.text = self.text() + option.icon = self.icon() + + painter = QPainter(self) + self.style().drawControl(QStyle.CE_PushButton, option, painter, self) +//! [0] +//! [1] + option = QStyleOptionFrame() + + if isinstance(option, QStyleOptionFrameV2): + frameOptionV2 = QStyleOptionFrameV2(option) + + # draw the frame using frameOptionV2 + +//! [1] + +//! [2] + if isinstance(option, QStyleOptionProgressBarV2): + progressBarV2 = QStyleOptionProgressBarV2(option) + + # draw the progress bar using progressBarV2 + +//! [2] + +//! [3] + if isinstance(option, QStyleOptionTabV2): + tabV2 = QStyleOptionTabV2(option) + + # draw the tab using tabV2 + +//! [3] + + +//! [4] +def drawPrimitive(self, element, option, painter, widget): + if element == self.PE_FrameFocusRect: + focusRectOption = QStyleOptionFocusRect(option) + if focusRectOption: + # ... + + + # ... + +//! [4] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/qsvgwidget.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/qsvgwidget.qrc new file mode 100644 index 0000000..13d8b36 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/qsvgwidget.qrc @@ -0,0 +1,5 @@ + + + spheres.svg + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/spheres.svg b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/spheres.svg new file mode 100644 index 0000000..9e38193 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/spheres.svg @@ -0,0 +1,79 @@ + + + Spheres + Gradient filled spheres with different colors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/sunflower.svg b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/sunflower.svg new file mode 100644 index 0000000..b60dd11 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qsvgwidget/sunflower.svg @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/cubed.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/cubed.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd9048ca6ba463b6a0f31d94ed6420346693df9 GIT binary patch literal 437 zcmV;m0ZRUfP)AYzJ8A$Jsu3gLE0jsrCbVwz^E~U-XNTt+ikC{v7xCypdngXa*zW?L0~UJ z1s$s`p$H509F^yJu5X`D4l-3Tl`1Kvq?EEE0wN-?Ab^0VtiTE@oX%*nR9F?3)50ZO ztZs)<1_HtW20QvoPdg1302mByXRv+$@z$6_wv92E9G$rR^VYEg5CE=gN7FWVtN-x* zMC*zGcPDe$%+zIHvk!Lr^TSdRz^9F0S1vqyzPP-(GT+|Vlk=UFe7^g4^GWa7#)sbO zk-6ieqFm1sI(lyIQdz$I<4rZ~!@80x!ZEr2yEl97e z3~&fL>X+l!Q*Yz!FfkYeF59o>PVZE!C(qOX05WaoTf5kH2H%%nuS_-A7-3g^F7EYS z?0#7}KMVj|?nFASo@%1|uX}H*&QL^VuBEb9MkOb@)lQU@lu|_yyE#T2>}yOG&Tz_x flubw&jKTi_Ge!*bk)o;&00000NkvXXu0mjf)3C*+ literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/squared.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/Images/squared.png new file mode 100644 index 0000000000000000000000000000000000000000..bfdf99328950607c9173e5e2b931a798e87b9189 GIT binary patch literal 440 zcmV;p0Z0CcP)GY6nC@~(NbFlIYpD32rf-gPSW5KK})k^gE>Tz z2nG!e5_MXT(I50W(#JcW>-YRV?_Mu&Y;1o0w)OqT&)+-E*5BQ%eUSevq5}YC2mkI~CY6Q;4RF8&AW$r=-I|t=1Assf2iAYhE-jXVxg;S3!n#LmXD1WD z0Z<6CBF31GylLLfTn?at%5YLt4waQQmL3EN2hjSnho7nom*>;=ozC3zBT+6;+?!t* zoijb!3Nzy;E*%(-P*P8?ELQFhpBzbVOx`=*H5{b${dW1--4Aak2J=>PyKCTr*#BA8 zT4zJGXzp%Ej%49w|8?_scCMWu5ICr(wK9G>>wPtLCIA4qi0Nj$7SqO;o2$!*3nYXi z^}eRQUw)B&Tt4460OXMDPdurH&c&;JQ$qn60tf3}sD~s!_4Kjw1O(s!*{(tUXGbOw i2$vvn33Epv1o{tvNn + + Images/squared.png + Images/cubed.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/mainwindow.h new file mode 100644 index 0000000..8387de5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-dnd/mainwindow.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTableWidget; +class QTableWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void averageItems(); + void sumItems(); + +private: + void setupTableItems(); + + QAction *removeAction; + QTableWidget *tableWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-resizing/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-resizing/mainwindow.h new file mode 100644 index 0000000..8eaaa7e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-resizing/mainwindow.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTableWidget; +class QTableWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void changeHeight(); + void changeWidth(); + +private: + void setupTableItems(); + + QTableWidget *tableWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/cubed.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/cubed.png new file mode 100644 index 0000000000000000000000000000000000000000..2cd9048ca6ba463b6a0f31d94ed6420346693df9 GIT binary patch literal 437 zcmV;m0ZRUfP)AYzJ8A$Jsu3gLE0jsrCbVwz^E~U-XNTt+ikC{v7xCypdngXa*zW?L0~UJ z1s$s`p$H509F^yJu5X`D4l-3Tl`1Kvq?EEE0wN-?Ab^0VtiTE@oX%*nR9F?3)50ZO ztZs)<1_HtW20QvoPdg1302mByXRv+$@z$6_wv92E9G$rR^VYEg5CE=gN7FWVtN-x* zMC*zGcPDe$%+zIHvk!Lr^TSdRz^9F0S1vqyzPP-(GT+|Vlk=UFe7^g4^GWa7#)sbO zk-6ieqFm1sI(lyIQdz$I<4rZ~!@80x!ZEr2yEl97e z3~&fL>X+l!Q*Yz!FfkYeF59o>PVZE!C(qOX05WaoTf5kH2H%%nuS_-A7-3g^F7EYS z?0#7}KMVj|?nFASo@%1|uX}H*&QL^VuBEb9MkOb@)lQU@lu|_yyE#T2>}yOG&Tz_x flubw&jKTi_Ge!*bk)o;&00000NkvXXu0mjf)3C*+ literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/squared.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/Images/squared.png new file mode 100644 index 0000000000000000000000000000000000000000..bfdf99328950607c9173e5e2b931a798e87b9189 GIT binary patch literal 440 zcmV;p0Z0CcP)GY6nC@~(NbFlIYpD32rf-gPSW5KK})k^gE>Tz z2nG!e5_MXT(I50W(#JcW>-YRV?_Mu&Y;1o0w)OqT&)+-E*5BQ%eUSevq5}YC2mkI~CY6Q;4RF8&AW$r=-I|t=1Assf2iAYhE-jXVxg;S3!n#LmXD1WD z0Z<6CBF31GylLLfTn?at%5YLt4waQQmL3EN2hjSnho7nom*>;=ozC3zBT+6;+?!t* zoijb!3Nzy;E*%(-P*P8?ELQFhpBzbVOx`=*H5{b${dW1--4Aak2J=>PyKCTr*#BA8 zT4zJGXzp%Ej%49w|8?_scCMWu5ICr(wK9G>>wPtLCIA4qi0Nj$7SqO;o2$!*3nYXi z^}eRQUw)B&Tt4460OXMDPdurH&c&;JQ$qn60tf3}sD~s!_4Kjw1O(s!*{(tUXGbOw i2$vvn33Epv1o{tvNn + + Images/squared.png + Images/cubed.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/mainwindow.h new file mode 100644 index 0000000..9571090 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtablewidget-using/mainwindow.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTableWidget; +class QTableWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void averageItems(); + void sumItems(); + +private: + void setupTableItems(); + + QAction *removeAction; +//! [0] + QTableWidget *tableWidget; +//! [0] +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtcast/qtcast.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtcast/qtcast.h new file mode 100644 index 0000000..eb0278f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtcast/qtcast.h @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QTCAST_H +#define QTCAST_H + +#include + +class MyWidget : public QWidget +{ + Q_OBJECT + +public: + MyWidget(); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/dragdropmodel.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/dragdropmodel.h new file mode 100644 index 0000000..6c89f16 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/dragdropmodel.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DRAGDROPMODEL_H +#define DRAGDROPMODEL_H + +#include "treemodel.h" + +class DragDropModel : public TreeModel +{ + Q_OBJECT + +public: + DragDropModel(const QStringList &strings, QObject *parent = 0); + + Qt::ItemFlags flags(const QModelIndex &index) const; + + bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent); + QMimeData *mimeData(const QModelIndexList &indexes) const; + QStringList mimeTypes() const; + Qt::DropActions supportedDropActions() const; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/mainwindow.h new file mode 100644 index 0000000..d526dce --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/mainwindow.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QTreeView; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +private: + void setupItems(); + + QTreeView *treeView; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treeitem.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treeitem.h new file mode 100644 index 0000000..4f3a167 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treeitem.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TREEITEM_H +#define TREEITEM_H + +#include +#include + +class TreeItem +{ +public: + TreeItem(const QList &data, TreeItem *parent = 0); + ~TreeItem(); + + void appendChild(TreeItem *child); + + TreeItem *child(int row); + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + bool insertChild(int row, TreeItem *item); + TreeItem *parent(); + bool removeChild(int row); + int row() const; + bool setData(int column, const QVariant &data); + +private: + QList childItems; + QList itemData; + TreeItem *parentItem; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treemodel.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treemodel.h new file mode 100644 index 0000000..faf970e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreeview-dnd/treemodel.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TREEMODEL_H +#define TREEMODEL_H + +#include +#include +#include + +class TreeItem; + +class TreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + TreeModel(const QStringList &strings, QObject *parent = 0); + ~TreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + +private: + void setupModelData(const QStringList &lines, TreeItem *parent); + + TreeItem *rootItem; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp new file mode 100644 index 0000000..c7b355c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.cpp @@ -0,0 +1,111 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + treeWidget = QTreeWidget(self) +//! [0] + +//! [1] + treeWidget.setColumnCount(2) +//! [1] //! [2] + headers = QStringList() + headers << tr("Subject") << tr("Default") + treeWidget.setHeaderLabels(headers) +//! [2] + +//! [3] + cities = QTreeWidgetItem(treeWidget) + cities.setText(0, tr("Cities")) + osloItem = QTreeWidgetItem(cities) + osloItem.setText(0, tr("Oslo")) + osloItem.setText(1, tr("Yes")) +//! [3] + +//! [4] //! [5] + planets = QTreeWidgetItem(treeWidget, cities) +//! [4] + planets.setText(0, tr("Planets")) +//! [5] + +//! [6] + item = QTreeWidgetItem() +//! [6] + +//! [7] + found = treeWidget.findItems(itemText, Qt.MatchWildcard) + + for item in found: + treeWidget.setItemSelected(item, True) + # Show the item.text(0) for each item. + +//! [7] + +//! [8] + parent = currentItem.parent() + if parent: + Item = QTreeWidgetItem(parent, treeWidget.currentItem()) + else +//! [8] //! [9] + Item = QTreeWidgetItem(treeWidget, treeWidget.currentItem()) +//! [9] + +//! [10] + parent = currentItem.parent() + + if parent: + index = parent.indexOfChild(treeWidget->currentItem()) + delete parent.takeChild(index) + else: + index = treeWidget.indexOfTopLevelItem(treeWidget->currentItem()) + delete treeWidget.takeTopLevelItem(index) +//! [10] //! [11] + +//! [11] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.h new file mode 100644 index 0000000..876ceba --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidget-using/mainwindow.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTreeWidget; +class QTreeWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void findItems(); + void insertItem(); + void removeItem(); + void sortAscending(); + void sortDescending(); + void updateMenus(QTreeWidgetItem *current); + void updateSortItems(); + +private: + void setupTreeItems(); + + QAction *ascendingAction; + QAction *autoSortAction; + QAction *descendingAction; + QAction *insertAction; + QAction *removeAction; + QTreeWidget *treeWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp new file mode 100644 index 0000000..3cbe3e6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.cpp @@ -0,0 +1,59 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] + it = QTreeWidgetItemIterator(treeWidget) + while it: + if it.text(0) == itemText: + *it.setSelected(True) + ++it +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.h new file mode 100644 index 0000000..876ceba --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtreewidgetitemiterator-using/mainwindow.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QAction; +class QTreeWidget; +class QTreeWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void findItems(); + void insertItem(); + void removeItem(); + void sortAscending(); + void sortDescending(); + void updateMenus(QTreeWidgetItem *current); + void updateSortItems(); + +private: + void setupTreeItems(); + + QAction *ascendingAction; + QAction *autoSortAction; + QAction *descendingAction; + QAction *insertAction; + QAction *removeAction; + QTreeWidget *treeWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/registeringobjects/myobject.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/registeringobjects/myobject.h new file mode 100644 index 0000000..fa86f16 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/registeringobjects/myobject.h @@ -0,0 +1,67 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYOBJECT_H +#define MYOBJECT_H + +#include + +class MyObject : public QObject +{ + Q_OBJECT + +public: + MyObject(); + +public slots: + int calculate(int value) const; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/object.js b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/object.js new file mode 100644 index 0000000..44ad0e6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/object.js @@ -0,0 +1,18 @@ +function Object(timer, editor) +{ + this.editor = editor; + this.counter = 0; + timer.timeout.connect(notify); + timer.timeout.connect(this, this.addLine); +} + +Object.prototype.addLine = function() +{ + this.editor.append(this.counter); + this.counter += 1; +} + +function notify() +{ + print("timeout() received"); +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/scriptedslot.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/scriptedslot.qrc new file mode 100644 index 0000000..fc7ff67 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qtscript/scriptedslot/scriptedslot.qrc @@ -0,0 +1,5 @@ + + + object.js + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py new file mode 100644 index 0000000..141189a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/doc_src_qtuiloader.py @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] +import PySide2.QtUiTools +//! [1] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/myform.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/myform.ui new file mode 100644 index 0000000..00702e8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/myform.ui @@ -0,0 +1,130 @@ + + + + + Form + + + + 0 + 0 + 258 + 224 + + + + Export Document + + + + 8 + + + 6 + + + + + Export Options + + + + 8 + + + 6 + + + + + &DocBook + + + + + + + &LaTeX + + + true + + + + + + + Include p&ictures + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + &Compress + + + + + + + &HTML + + + + + + + &PostScript + + + + + + + PD&F + + + + + + + Include &metadata + + + + + + + Create inde&x + + + true + + + + + + + + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.h new file mode 100644 index 0000000..66e9235 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MYWIDGET_H +#define MYWIDGET_H + +#include + +class MyWidget : public QWidget +{ +public: + MyWidget(QWidget *parent = 0); +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.qrc new file mode 100644 index 0000000..47684d6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/quiloader/mywidget.qrc @@ -0,0 +1,5 @@ + + +myform.ui + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qx11embedwidget/embedwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/qx11embedwidget/embedwidget.h new file mode 100644 index 0000000..1d54f70 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qx11embedwidget/embedwidget.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EMBEDWIDGET_H +#define EMBEDWIDGET_H + +#include +#include +#include + +class QPaintEvent; + +class EmbedWidget : public QX11EmbedWidget +{ + Q_OBJECT + +public: + EmbedWidget(QWidget *parent = 0); + QSize sizeHint() const; + +protected: + void paintEvent(QPaintEvent *event); + +private: + QRadialGradient gradient; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py new file mode 100644 index 0000000..16c12b7 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlquery/bindingExample.py @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + device = QBuffer() + device.setData(myQString.toUtf8()) + device.open(QIODevice.ReadOnly) + + query = QXmlQuery() + query.setQuery("doc($inputDocument)/query[theDocument]") + query.bindVariable("inputDocument", device) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlschemavalidator/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlschemavalidator/main.cpp new file mode 100644 index 0000000..0d81b91 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/qxmlschemavalidator/main.cpp @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +def validateFromUrl(): +//! [0] + schema = getSchema() + + url = QUrl("http://www.schema-example.org/test.xml") + + validator = QXmlSchemaValidator(schema) + if validator.validate(url): + print "instance document is valid" + else: + print "instance document is invalid" +//! [0] + +def validateFromFile(): +//! [1] + schema = getSchema() + + file = QFile("test.xml") + file.open(QIODevice.ReadOnly) + + validator = QXmlSchemaValidator(schema) + if validator.validate(file, QUrl.fromLocalFile(file.fileName())): + print "instance document is valid" + else: + print "instance document is invalid" +//! [1] +} + +def validateFromData(): +//! [2] + schema = getSchema() + + data = QByteArray("") + + buffer = QBuffer(data) + buffer.open(QIODevice.ReadOnly) + + QXmlSchemaValidator validator(schema) + if validator.validate(buffer): + print "instance document is valid" + else: + print "instance document is invalid" +//! [2] + +def validateComplete(): +//! [3] + schemaUrl = QUrl("file:///home/user/schema.xsd") + + schema = QXmlSchema() + schema.load(schemaUrl) + + if schema.isValid(): + file = QFile("test.xml") + file.open(QIODevice.ReadOnly) + + validator = QXmlSchemaValidator(schema) + if validator.validate(file, QUrl.fromLocalFile(file.fileName())): + print "instance document is valid" + else: + print "instance document is invalid" + } +//! [3] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/model.h new file mode 100644 index 0000000..6b40768 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/model.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/window.h new file mode 100644 index 0000000..7bebf72 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/reading-selections/window.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +private slots: + void fillSelection(); + void clearSelection(); + void selectAll(); + +private: + QAbstractItemModel *model; + QItemSelectionModel *selectionModel; + QTableView *table; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/finalwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/finalwidget.h new file mode 100644 index 0000000..2b40e76 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/finalwidget.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FINALWIDGET_H +#define FINALWIDGET_H + +#include +#include +#include +#include + +class QGridLayout; +class QLabel; +class QMouseEvent; +class QWidget; + +class FinalWidget : public QFrame +{ + Q_OBJECT + +public: + FinalWidget(QWidget *parent, const QString &name, const QSize &labelSize); + void setPixmap(const QPixmap &pixmap); + const QPixmap *pixmap() const; + +protected: + void mouseMoveEvent(QMouseEvent *event); + void mousePressEvent(QMouseEvent *event); + +private: + void createImage(); + + bool hasImage; + QImage originalImage; + QLabel *imageLabel; + QLabel *nameLabel; + QPoint dragStartPosition; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/screenwidget.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/screenwidget.h new file mode 100644 index 0000000..2991e75 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/screenwidget.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SCREENWIDGET_H +#define SCREENWIDGET_H + +#include +#include +#include +#include + +class QGridLayout; +class QLabel; +class QPushButton; +class QWidget; + +class ScreenWidget : public QFrame +{ + Q_OBJECT +public: + enum Separation { Cyan, Magenta, Yellow }; + + ScreenWidget(QWidget *parent, QColor initialColor, const QString &name, + Separation mask, const QSize &labelSize); + void setImage(QImage &image); + QImage* image(); + +signals: + void imageChanged(); + +public slots: + void setColor(); + void invertImage(); + +private: + void createImage(); + + bool inverted; + QColor paintColor; + QImage newImage; + QImage originalImage; + QLabel *imageLabel; + QLabel *nameLabel; + QPushButton *colorButton; + QPushButton *invertButton; + Separation maskColor; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/viewer.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/viewer.h new file mode 100644 index 0000000..3713c27 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/separations/viewer.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VIEWER_H +#define VIEWER_H + +#include +#include +#include + +class QAction; +class QFrame; +class QGridLayout; +class QLabel; +class QMenu; +class FinalWidget; +class ScreenWidget; + +class Viewer : public QMainWindow +{ + Q_OBJECT +public: + enum Brightness { None, Quarter, Half, ThreeQuarters, Full }; + Viewer(); + +public slots: + void chooseFile(); + void setBrightness(QAction *action); + void createImage(); + void saveImage(); + +private: + void createMenus(); + QFrame *createCentralWidget(); + void openImageFile(QString &filePath); + + FinalWidget *finalWidget; + int brightness; + QAction *currentBrightness; + QAction *saveAction; + QGridLayout *grid; + QImage scaledImage; + QMap menuMap; + QMenu *brightnessMenu; + QMenu *fileMenu; + QString path; + ScreenWidget *cyanWidget; + ScreenWidget *magentaWidget; + ScreenWidget *yellowWidget; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp new file mode 100644 index 0000000..338d131 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/shareddirmodel/main.cpp @@ -0,0 +1,90 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +""" + main.cpp + + A simple example of how to view a model in several views, and share a + selection model. +""" + +from PySide2.QtGui import * + + +//! [0] //! [1] +def main(): + app = QApplication(sys.argv) + splitter = QSplitter() + +//! [2] //! [3] + model = QFileSystemModel() + model.setRootPath(QDir.currentPath()) +//! [0] //! [2] //! [4] //! [5] + tree = QTreeView() +//! [3] //! [6] + tree.setModel(model) +//! [4] //! [6] //! [7] + tree.setRootIndex(model.index(QDir.currentPath())) +//! [7] + + list = QListView(splitter) + list.setModel(model) + list.setRootIndex(model.index(QDir.currentPath())) + +//! [5] + selection = QItemSelectionModel(model) + tree.setSelectionModel(selection) + list.setSelectionModel(selection) + +//! [8] + splitter.setWindowTitle("Two views onto the same directory model") + splitter.show() + return app.exec_() +//! [1] //! [8] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedemployee/employee.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedemployee/employee.h new file mode 100644 index 0000000..23ffcdd --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedemployee/employee.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EMPLOYEE_H +#define EMPLOYEE_H + +//! [0] +#include +#include + +class EmployeeData : public QSharedData +{ + public: + EmployeeData() : id(-1) { name.clear(); } + EmployeeData(const EmployeeData &other) + : QSharedData(other), id(other.id), name(other.name) { } + ~EmployeeData() { } + + int id; + QString name; +}; + +class Employee +{ + public: +//! [1] + Employee() { d = new EmployeeData; } +//! [1] //! [2] + Employee(int id, QString name) { + d = new EmployeeData; + setId(id); + setName(name); + } +//! [2] //! [7] + Employee(const Employee &other) + : d (other.d) + { + } +//! [7] +//! [3] + void setId(int id) { d->id = id; } +//! [3] //! [4] + void setName(QString name) { d->name = name; } +//! [4] + +//! [5] + int id() const { return d->id; } +//! [5] //! [6] + QString name() const { return d->name; } +//! [6] + + private: + QSharedDataPointer d; +}; +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedtablemodel/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedtablemodel/model.h new file mode 100644 index 0000000..6b40768 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/sharedtablemodel/model.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/accountsfile.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/accountsfile.txt new file mode 100644 index 0000000..2ec5ffb --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/accountsfile.txt @@ -0,0 +1 @@ +1 + 1 = 2 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/filereader.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/filereader.h new file mode 100644 index 0000000..6509951 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/filereader.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FILEREADER_H +#define FILEREADER_H + +#include +#include +#include + +class FileReader : public QWidget +{ + Q_OBJECT + +public: + FileReader(QWidget *parent=0); + void readFromFile(QString filename); + +public slots: + void readFile(const QString &); + +private: + QTextEdit *textEdit; + QPushButton *taxFileButton; + QPushButton *accountFileButton; + QPushButton *reportFileButton; + QSignalMapper *signalMapper; +}; + +#endif + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/reportfile.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/reportfile.txt new file mode 100644 index 0000000..30123cc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/reportfile.txt @@ -0,0 +1,2 @@ +Tax this year = 50% +Total profit = 2 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/taxfile.txt b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/taxfile.txt new file mode 100644 index 0000000..a682e0a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalmapper/taxfile.txt @@ -0,0 +1 @@ +Tax this year = 50% diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/lcdnumber.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/lcdnumber.h new file mode 100644 index 0000000..68563e0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/lcdnumber.h @@ -0,0 +1,98 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +#ifndef LCDNUMBER_H +//! [0] //! [1] +#define LCDNUMBER_H +//! [1] + +//! [2] +#include +//! [2] + +//! [3] +class LcdNumber : public QFrame +//! [3] //! [4] +{ +//! [4] //! [5] + Q_OBJECT +//! [5] + +//! [6] +public: +//! [6] //! [7] + LcdNumber(QWidget *parent = 0); +//! [7] + +//! [8] +signals: +//! [8] //! [9] + void overflow(); +//! [9] + +//! [10] +public slots: +//! [10] //! [11] + void display(int num); + void display(double num); + void display(const QString &str); + void setHexMode(); + void setDecMode(); + void setOctMode(); + void setBinMode(); + void setSmallDecimalPoint(bool point); +//! [11] //! [12] +}; +//! [12] + +//! [13] +#endif +//! [13] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/signalsandslots.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/signalsandslots.h new file mode 100644 index 0000000..c89e83d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/signalsandslots/signalsandslots.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SIGNALSANDSLOTS_H +#define SIGNALSANDSLOTS_H + +#define Counter PlainCounter + +//! [0] +class Counter +{ +public: + Counter() { m_value = 0; } + + int value() const { return m_value; } + void setValue(int value); + +private: + int m_value; +}; +//! [0] + +#undef Counter +#define Counter ObjectCounter + +//! [1] +#include +//! [1] + +//! [2] +class Counter : public QObject +//! [2] //! [3] +{ + Q_OBJECT + +public: + Counter() { m_value = 0; } + + int value() const { return m_value; } + +public slots: + void setValue(int value); + +signals: + void valueChanged(int newValue); + +private: + int m_value; +}; +//! [3] + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/simpleparse/handler.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/simpleparse/handler.h new file mode 100644 index 0000000..ea1b8b3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/simpleparse/handler.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef HANDLER_H +#define HANDLER_H + +#include +#include + +class Handler : public QXmlDefaultHandler +{ +public: + bool startDocument(); + bool startElement(const QString &, const QString &, const QString &qName, + const QXmlAttributes &); + bool endElement(const QString &, const QString &, const QString &); + + bool fatalError(const QXmlParseException &exception); + + QStringList& names(); + QList& indentations(); + +private: + int indentationLevel; + QStringList elementName; + QList elementIndentation; +}; + +#endif + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp new file mode 100644 index 0000000..90fd928 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitter/splitter.cpp @@ -0,0 +1,76 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] + splitter = QSplitter(parent) + listview = QListView() + treeview = QTreeView() + textedit = QTextEdit() + splitter.addWidget(listview) + splitter.addWidget(treeview) + splitter.addWidget(textedit) +//! [0] + +//! [1] + settings = QSettings() + settings.setValue("splitterSizes", splitter.saveState()) +//! [1] + +//! [2] + settings = QSettings() + splitter.restoreState(settings.value("splitterSizes").toByteArray()) +//! [2] + +//! [3] + for it in splitter.sizes(): + processSize(it.next()) +//! [3] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h new file mode 100644 index 0000000..5ecaafc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/splitterhandle/splitter.h @@ -0,0 +1,61 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +class Splitter(QSplitter): + def __init__(self, orientation, parent): + ... + + def createHandle(self): + ... +} +//! [0] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py new file mode 100644 index 0000000..7c28cf5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/sqldatabase/sqldatabase.py @@ -0,0 +1,489 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * +from PySide2.QtSql import * + + +def tr(text): + return QApplication.translate(text, text) + +def QSqlDatabase_snippets(): +//! [0] + db = QSqlDatabase.addDatabase("QPSQL") + db.setHostName("acidalia") + db.setDatabaseName("customdb") + db.setUserName("mojito") + db.setPassword("J0a1m8") + ok = db.open() +//! [0] + +//! [1] + db = QSqlDatabase.database() +//! [1] + +def QSqlField_snippets(): +//! [2] + field = QSqlField("age", QVariant.Int) + field.setValue(QPixmap()) # WRONG +//! [2] + +//! [3] + field = QSqlField("age", QVariant.Int) + field.setValue(str(123)) # casts str to int +//! [3] + +//! [4] + query = QSqlQuery() +//! [4] //! [5] + record = query.record() +//! [5] //! [6] + field = record.field("country") +//! [6] + +def doSomething(str): + pass + +def QSqlQuery_snippets(): + # typical loop +//! [7] + query = QSqlQuery("SELECT country FROM artist") + while query.next(): + country = query.value(0) + doSomething(country) +//! [7] + + + # field index lookup +//! [8] + query = QSqlQuery("SELECT * FROM artist") + fieldNo = query.record().indexOf("country") + while query.next(): + country = query.value(fieldNo) + doSomething(country) +//! [8] + + # named with named +//! [9] + query = QSqlQuery() + query.prepare("INSERT INTO person (id, forename, surname) " + "VALUES (:id, :forename, :surname)") + query.bindValue(":id", 1001) + query.bindValue(":forename", "Bart") + query.bindValue(":surname", "Simpson") + query.exec_() +//! [9] + + # positional with named +//! [10] + query = QSqlQuery() + query.prepare("INSERT INTO person (id, forename, surname) " + "VALUES (:id, :forename, :surname)") + query.bindValue(0, 1001) + query.bindValue(1, "Bart") + query.bindValue(2, "Simpson") + query.exec_() +//! [10] + + # positional 1 +//! [11] + query = QSqlQuery() + query.prepare("INSERT INTO person (id, forename, surname) " + "VALUES (?, ?, ?)") + query.bindValue(0, 1001) + query.bindValue(1, "Bart") + query.bindValue(2, "Simpson") + query.exec_() +//! [11] + + # positional 2 +//! [12] + query = QSqlQuery() + query.prepare("INSERT INTO person (id, forename, surname) " + "VALUES (?, ?, ?)") + query.addBindValue(1001) + query.addBindValue("Bart") + query.addBindValue("Simpson") + query.exec_() +//! [12] + + # stored +//! [13] + query = QSqlQuery() + query.prepare("CALL AsciiToInt(?, ?)") + query.bindValue(0, "A") + query.bindValue(1, 0, QSql.Out) + query.exec_() + i = query.boundValue(1) # i is 65 +//! [13] + + query = QSqlQuery() + + # examine with named binding +//! [14] + i = query.boundValues() + while i.hasNext(): + i.next() + print i.key(), ": ", i.value() +//! [14] + + # examine with positional binding +//! [15] + list_ = query.boundValues().values() + for item in list: + print item +//! [15] + +def QSqlQueryModel_snippets(): + +//! [16] + model = QSqlQueryModel() + model.setQuery("SELECT name, salary FROM employee") + model.setHeaderData(0, Qt.Horizontal, tr("Name")) + model.setHeaderData(1, Qt.Horizontal, tr("Salary")) + +//! [17] + view = QTableView() +//! [17] //! [18] + view.setModel(model) +//! [18] //! [19] + view.show() +//! [16] //! [19] //! [20] + view.setEditTriggers(QAbstractItemView.NoEditTriggers) +//! [20] + +//! [21] + model = QSqlQueryModel() + model.setQuery("SELECT * FROM employee") + salary = model.record(4).value("salary") +//! [21] + +//! [22] + salary = model.data(model.index(4, 2)) +//! [22] + + for row in range(model.rowCount()): + for (col in range(model.columnCount())): + print model.data(model.index(row, col)) + + +class MyModel(QSqlQueryModel) + m_specialColumnNo = 0 + def data(item, role): +//! [23] + if item.column() == self.m_specialColumnNo: + # handle column separately + pass + + return QSqlQueryModel.data(item, role) + +//! [23] + + +def QSqlTableModel_snippets(): + +//! [24] + model = QSqlTableModel() + model.setTable("employee") + model.setEditStrategy(QSqlTableModel.OnManualSubmit) + model.select() + model.removeColumn(0) # don't show the ID + model.setHeaderData(0, Qt.Horizontal, tr("Name")) + model.setHeaderData(1, Qt.Horizontal, tr("Salary")) + + view = QTableView() + view.setModel(model) + view.show() +//! [24] + + +//! [25] + model = QSqlTableModel() + model.setTable("employee") + name = model.record(4).value("name") +//! [25] + +def sql_intro_snippets(): + +//! [26] + db = QSqlDatabase.addDatabase("QMYSQL") + db.setHostName("bigblue") + db.setDatabaseName("flightdb") + db.setUserName("acarlson") + db.setPassword("1uTbSbAs") + ok = db.open() +//! [26] + +//! [27] + firstDB = QSqlDatabase.addDatabase("QMYSQL", "first") + secondDB = QSqlDatabase.addDatabase("QMYSQL", "second") +//! [27] + +//! [28] + defaultDB = QSqlDatabase.database() +//! [28] //! [29] + firstDB = QSqlDatabase.database("first") +//! [29] //! [30] + secondDB = QSqlDatabase.database("second") +//! [30] + + # SELECT1 +//! [31] + query = QSqlQuery() + query.exec_("SELECT name, salary FROM employee WHERE salary > 50000") +//! [31] + +//! [32] + while query.next(): + name = query.value(0) + salary = query.value(1) + print name, salary +//! [32] + + # FEATURE +//! [33] + query = QSqlQuery() + query.exec_("SELECT name, salary FROM employee WHERE salary > 50000") + + defaultDB = QSqlDatabase.database() + if defaultDB.driver().hasFeature(QSqlDriver.QuerySize): + numRows = query.size() + else: + # self can be very slow + query.last() + numRows = query.at() + 1 +//! [33] + + # INSERT1 +//! [34] + query = QSqlQuery() + query.exec_("INSERT INTO employee (id, name, salary) " + "VALUES (1001, 'Thad Beaumont', 65000)") +//! [34] + + # NAMED BINDING +//! [35] + query = QSqlQuery() + query.prepare("INSERT INTO employee (id, name, salary) " + "VALUES (:id, :name, :salary)") + query.bindValue(":id", 1001) + query.bindValue(":name", "Thad Beaumont") + query.bindValue(":salary", 65000) + query.exec_() +//! [35] + + # POSITIONAL BINDING +//! [36] + query = QSqlQuery() + query.prepare("INSERT INTO employee (id, name, salary) " + "VALUES (?, ?, ?)") + query.addBindValue(1001) + query.addBindValue("Thad Beaumont") + query.addBindValue(65000) + query.exec_() +//! [36] + + # UPDATE1 +//! [37] + query = QSqlQuery() + query.exec_("UPDATE employee SET salary = 70000 WHERE id = 1003") +//! [37] + + # DELETE1 +//! [38] + query = QSqlQuery() + query.exec_("DELETE FROM employee WHERE id = 1007") +//! [38] + + # TRANSACTION +//! [39] + QSqlDatabase.database().transaction() + query = QSqlQuery() + query.exec_("SELECT id FROM employee WHERE name = 'Torild Halvorsen'") + if query.next(): + employeeId = query.value(0) + query.exec_("INSERT INTO project (id, name, ownerid) " + "VALUES (201, 'Manhattan Project', " + + str(employeeId) + ')') + + QSqlDatabase.database().commit() +//! [39] + + # SQLQUERYMODEL1 +//! [40] + model = QSqlQueryModel() + model.setQuery("SELECT * FROM employee") + + for i in range(model.rowCount()): + _id = model.record(i).value("id") + name = model.record(i).value("name") + print _id, name + +//! [40] + } + + { + # SQLTABLEMODEL1 +//! [41] + model = QSqlTableModel() + model.setTable("employee") + model.setFilter("salary > 50000") + model.setSort(2, Qt.DescendingOrder) + model.select() + + for i in range(model.rowCount()): + name = model.record(i).value("name") + salary = model.record(i).value("salary") + print "%s: %d" % (name, salary) + +//! [41] + + # SQLTABLEMODEL2 + model = QSqlTableModel() + model.setTable("employee") + +//! [42] + for i in range(model.rowCount()): + record = model.record(i) + salary = record.value("salary") + salary *= 1.1 + record.setValue("salary", salary) + model.setRecord(i, record) + + model.submitAll() +//! [42] + + # SQLTABLEMODEL3 + row = 1 + column = 2 +//! [43] + model.setData(model.index(row, column), 75000) + model.submitAll() +//! [43] + + # SQLTABLEMODEL4 +//! [44] + model.insertRows(row, 1) + model.setData(model.index(row, 0), 1013) + model.setData(model.index(row, 1), "Peter Gordon") + model.setData(model.index(row, 2), 68500) + model.submitAll() +//! [44] + +//! [45] + model.removeRows(row, 5) +//! [45] + +//! [46] + model.submitAll() +//! [46] + +//! [47] +class XyzResult(QSqlResult): + def __init__(driver): + QSqlResult.__init__(self, driver) + pass + + def data(self, index): + return QVariant() + + def isNull(self, index): + return False + + def reset(self, query): + return False + + def fetch(self, index): + return False + + def fetchFirst(self): + return False + + def fetchLast(self): + return False + + def size(self): + return 0 + + def numRowsAffected(self): + return 0 + + def record(self): + return QSqlRecord() + +//! [47] + +//! [48] +class XyzDriver(QSqlDriver) + def hasFeature(self, feature): + return False + + def open(self, db, user, password, host, port, options): + return False + + def close(self): + pass + + def createResult(self): + return XyzResult(self) + +//! [48] + +def main(): + app = QApplication([]) + + QSqlDatabase_snippets() + QSqlField_snippets() + QSqlQuery_snippets() + QSqlQueryModel_snippets() + QSqlTableModel_snippets() + + driver = XyzDriver() + result = XyzResult(driver) diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.cpp new file mode 100644 index 0000000..79c449d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.cpp @@ -0,0 +1,170 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/* + model.cpp + + A simple model that uses a QStringList as its data source. +*/ + +/*! + Returns the number of items in the string list as the number of rows + in the model. +*/ + +//! [0] +def rowCount(self, parent): + return len(self.stringList) +//! [0] + +/*! + Returns an appropriate value for the requested data. + If the view requests an invalid index, an invalid variant is returned. + Any valid index that corresponds to a string in the list causes that + string to be returned. +*/ + +//! [1] +def data(self, index, role): + if not index.isValid(): + return None + + if index.row() >= stringList.size(): + return None + + if role == Qt.DisplayRole: + return stringList[index.row()] + else + return None +//! [1] + +/*! + Returns the appropriate header string depending on the orientation of + the header and the section. If anything other than the display role is + requested, we return an invalid variant. +*/ + +//! [2] +def headerData(self, section, orientation, role): + if role != Qt::DisplayRole: + return None + + if orientation == Qt::Horizontal: + return "Column %s" % section + else: + return "Row %s" % section +//! [2] + +/*! + Returns an appropriate value for the item's flags. Valid items are + enabled, selectable, and editable. +*/ + +//! [3] +def flags(self, index): + if not index.isValid() + return Qt.ItemIsEnabled + + return QAbstractItemModel.flags(index) | Qt.ItemIsEditable +//! [3] + +/*! + Changes an item in the string list, but only if the following conditions + are met: + + * The index supplied is valid. + * The index corresponds to an item to be shown in a view. + * The role associated with editing text is specified. + + The dataChanged() signal is emitted if the item is changed. +*/ + +//! [4] +def setData(self, index, value, role): + if index.isValid() and role == Qt.EditRole: + self.stringList[index.row()] = value + self.dataChanged.emit(index, index) + return True; +//! [4] //! [5] + return False; +} +//! [5] + +/*! + Inserts a number of rows into the model at the specified position. +*/ + +//! [6] +def insertRows(self, position, rows, parent): + self.beginInsertRows(QModelIndex(), position, position+rows-1) + + for row in range(0, rows): + self.stringList.insert(position, "") + + self.endInsertRows() + return True; +//! [6] //! [7] +//! [7] + +/*! + Removes a number of rows from the model at the specified position. +*/ + +//! [8] +def removeRows(self, position, rows, parent): + self.beginRemoveRows(QModelIndex(), position, position+rows-1) + + for row in range(0, rows): + del self.stringList[position] + + self.endRemoveRows() + return True; +//! [8] //! [9] +//! [9] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.h new file mode 100644 index 0000000..5868952 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/stringlistmodel/model.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class StringListModel (QAbstractListModel): + def __init__(strings, parent = None): + QAbstractListModel.__init__(self, parent) +//! [5] + self.stringList = strings +//! [5] + + def rowCount(self, parent = QModelIndex()): + # ... + def data(self, index, role): + # ... + def headerData(self, section, orientation, +//! [0] //! [1] + role = Qt.DisplayRole): +//! [1] + +//! [2] + def flags(self, index): + # ... + def setData(self, index, value, +//! [2] //! [3] + role = Qt.EditRole) +//! [3] + +//! [4] + def insertRows(self, position, rows, index = QModelIndex()): + # ... + def removeRows(self, position, rows, index = QModelIndex()): + # ... +//! [4] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/styles/styles.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/styles/styles.cpp new file mode 100644 index 0000000..b174451 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/styles/styles.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] //! [1] +def paintEvent(self, event): +//! [0] +//! [2] + painter = QPainter(self) +//! [2] + + option = QStyleOptionFocusRect() + option.initFrom(self) + option.backgroundColor = palette().color(QPalette.Background) + +//! [3] + style().drawPrimitive(QStyle.PE_FrameFocusRect, option, painter, self) +//! [3] +//! [1] + +def paintEvent2(event): +//! [4] +//! [4] //! [5] //! [6] + painter = QStylePainter(self) +//! [5] + + option = QStyleOptionFocusRect() + option.initFrom(self) + option.backgroundColor = palette().color(QPalette.Background) + +//! [7] + painter.drawPrimitive(QStyle.PE_FrameFocusRect, option) +//! [7] +//! [6] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/stylesheet/common-mistakes.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/stylesheet/common-mistakes.cpp new file mode 100644 index 0000000..a8dfe25 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/stylesheet/common-mistakes.cpp @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [1] + QPushButton { + color: grey; + border-image: url(/home/kamlie/code/button.png) 3 10 3 10; + border-top: 3px transparent; + border-bottom: 3px transparent; + border-right: 10px transparent; + border-left: 10px transparent; + } +//! [1] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/mainwindow.h new file mode 100644 index 0000000..4b691b5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/mainwindow.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void insertCalendar(); + void saveFile(); + +private: + bool writeXml(const QString &fileName); + + QTextEdit *editor; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/xmlwriter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/xmlwriter.h new file mode 100644 index 0000000..56ce140 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textblock-fragments/xmlwriter.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XMLWRITER_H +#define XMLWRITER_H + +#include + +class QTextDocument; + +class XmlWriter +{ +public: + XmlWriter(QTextDocument *document) : textDocument(document) {} + QDomDocument *toXml(); + +private: + void readFragment(const QTextBlock ¤tBlock, QDomElement blockElement, + QDomDocument *document); + void processBlock(const QTextBlock ¤tBlock); + void processFragment(const QTextFragment ¤tFragment); + + QDomDocument *document; + QTextDocument *textDocument; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/mainwindow.h new file mode 100644 index 0000000..4b691b5 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/mainwindow.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void insertCalendar(); + void saveFile(); + +private: + bool writeXml(const QString &fileName); + + QTextEdit *editor; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/xmlwriter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/xmlwriter.h new file mode 100644 index 0000000..562ce5d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-blocks/xmlwriter.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XMLWRITER_H +#define XMLWRITER_H + +#include + +class QTextDocument; + +class XmlWriter +{ +public: + XmlWriter(QTextDocument *document) : textDocument(document) {} + QDomDocument *toXml(); + +private: + void createItems(QDomElement &parent, const QTextBlock &block); + + QDomDocument *document; + QTextDocument *textDocument; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp new file mode 100644 index 0000000..987489d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-css/main.cpp @@ -0,0 +1,58 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] + browser = QTextBrowser() + linkColor = QColor(Qt.red) + sheet = QString.fromLatin1("a { text-decoration: underline color: %1 }").arg(linkColor.name()) + browser.document().setDefaultStyleSheet(sheet) +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/mainwindow.h new file mode 100644 index 0000000..9aad859 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/mainwindow.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void saveFile(); + +private: + bool writeXml(const QString &fileName); + + QTextEdit *editor; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/xmlwriter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/xmlwriter.h new file mode 100644 index 0000000..707af51 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-frames/xmlwriter.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XMLWRITER_H +#define XMLWRITER_H + +#include + +class QTextDocument; + +class XmlWriter +{ +public: + XmlWriter(QTextDocument *document) : textDocument(document) {} + QDomDocument *toXml(); + +private: + void processBlock(QDomElement &parent, const QTextBlock &block); + void processFrame(QDomElement &parent, QTextFrame *frame); + + QDomDocument *document; +//! [0] + QTextDocument *textDocument; +//! [0] +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imagedrop/textedit.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imagedrop/textedit.h new file mode 100644 index 0000000..a80481a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imagedrop/textedit.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TEXTEDIT_H +#define TEXTEDIT_H + +#include + +class TextEdit : public QTextEdit +{ + Q_OBJECT + +public: + TextEdit(QWidget *parent=0); + bool canInsertFromMimeData( const QMimeData *source ) const; + void insertFromMimeData( const QMimeData *source ); +}; + +#endif \ No newline at end of file diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images.qrc new file mode 100644 index 0000000..6473daf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images.qrc @@ -0,0 +1,6 @@ + + + images/advert.png + images/newimage.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images/advert.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-imageformat/images/advert.png new file mode 100644 index 0000000000000000000000000000000000000000..40e10d5225dc1bdb09932ea11ba2eca3d0dd72a8 GIT binary patch literal 16291 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images.qrc new file mode 100644 index 0000000..09e305e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images.qrc @@ -0,0 +1,5 @@ + + + images/advert.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images/advert.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-images/images/advert.png new file mode 100644 index 0000000000000000000000000000000000000000..40e10d5225dc1bdb09932ea11ba2eca3d0dd72a8 GIT binary patch literal 16291 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 +#include +#include + +class QAction; +class QTextDocument; +class QTextEdit; +class QTextList; +class QTreeWidgetItem; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void insertList(); + void highlightListItems(); + void showList(); + +private: + QString currentFile; + QTextEdit *editor; + QTextDocument *document; + QList listStructures; + QList previousItems; + QList parentItems; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-lists/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-lists/mainwindow.h new file mode 100644 index 0000000..a52fa76 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-lists/mainwindow.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include + +class QAction; +class QTextDocument; +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void cutSelection(); + void copySelection(); + void insertList(); + void pasteSelection(); + void selectWord(); + void selectLine(); + void selectBlock(); + void selectFrame(); + void updateMenus(); + +private: + QAction *cutAction; + QAction *copyAction; + QAction *pasteAction; + QString currentFile; + QTextEdit *editor; + QTextDocument *document; + QTextDocumentFragment selection; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-printing/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-printing/mainwindow.h new file mode 100644 index 0000000..c80d42b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-printing/mainwindow.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include + +class QAction; +class QTextDocument; +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void openFile(); + void printFile(); + void printPdf(); + +private: + QAction *printAction; + QAction *pdfPrintAction; + QString currentFile; + QTextEdit *editor; + QTextDocument *document; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-selections/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-selections/mainwindow.h new file mode 100644 index 0000000..ba88919 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-selections/mainwindow.h @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include + +class QAction; +class QTextDocument; +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void cutSelection(); + void copySelection(); + void openFile(); + void pasteSelection(); + void selectWord(); + void selectLine(); + void selectBlock(); + void selectFrame(); + void updateMenus(); + +private: + QAction *cutAction; + QAction *copyAction; + QAction *pasteAction; + QString currentFile; + QTextEdit *editor; + QTextDocument *document; + QTextDocumentFragment selection; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp new file mode 100644 index 0000000..cf43b08 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.cpp @@ -0,0 +1,125 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] //! [1] + cursor = QTextCursor(editor.textCursor()) +//! [0] + cursor.movePosition(QTextCursor.Start) +//! [1] + +//! [2] + tableFormat = QTextTableFormat() + tableFormat.setBackground(QColor("#e0e0e0")) + QVector constraints + constraints << QTextLength(QTextLength.PercentageLength, 16) + constraints << QTextLength(QTextLength.PercentageLength, 28) + constraints << QTextLength(QTextLength.PercentageLength, 28) + constraints << QTextLength(QTextLength.PercentageLength, 28) + tableFormat.setColumnWidthConstraints(constraints) +//! [3] + table = cursor.insertTable(rows, columns, tableFormat) +//! [2] //! [3] + +//! [4] + cell = table.cellAt(0, 0) + cellCursor = cell.firstCursorPosition() + cellCursor.insertText(tr("Week"), charFormat) +//! [4] + +//! [5] + for column in range(columns): + cell = table.cellAt(0, column) + cellCursor = cell.firstCursorPosition() + cellCursor.insertText(tr("Team %1").arg(column), charFormat) + + + for row in range(rows): + cell = table.cellAt(row, 0) + cellCursor = cell.firstCursorPosition() + cellCursor.insertText(tr("%1").arg(row), charFormat) + + for column in range(columns) + if (row-1) % 3 == column-1: +//! [5] //! [6] + cell = table.cellAt(row, column) + cellCursor = cell.firstCursorPosition() + cellCursor.insertText(tr("On duty"), charFormat) + +//! [6] //! [7] + +//! [7] //! [8] + +//! [8] + +//! [9] + for row in range(table.rows()): + for column in range(table.columns()): + tableCell = table.cellAt(row, column) +//! [9] + QTextFrame.iterator it + QString text + for (it = tableCell.begin() !(it.atEnd()); ++it): + QTextBlock childBlock = it.currentBlock() + if (childBlock.isValid()) + text += childBlock.text() + + Item = QTableWidgetItem(text) + tableWidget.setItem(row, column, Item) + +//! [10] + processTableCell(tableCell) +//! [10] + +//! [11] + +//! [11] //! [12] + +//! [12] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.h new file mode 100644 index 0000000..36fd197 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/mainwindow.h @@ -0,0 +1,75 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + +class QTextEdit; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + +public slots: + void saveFile(); + void showTable(); + +private: + bool writeXml(const QString &fileName); + + QTextEdit *editor; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/xmlwriter.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/xmlwriter.h new file mode 100644 index 0000000..ebfbc82 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-tables/xmlwriter.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XMLWRITER_H +#define XMLWRITER_H + +#include + +class QTextDocument; + +class XmlWriter +{ +public: + XmlWriter(QTextDocument *document) : textDocument(document) {} + QDomDocument *toXml(); + +private: + void processBlock(QDomElement &parent, const QTextBlock &block); + void processFrame(QDomElement &parent, QTextFrame *frame); + void processTable(QDomElement &parent, QTextTable *table); + void processTableCell(QDomElement &parent, const QTextTableCell &cell); + + QDomDocument *document; + QTextDocument *textDocument; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp new file mode 100644 index 0000000..b662263 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/textdocument-texttable/main.cpp @@ -0,0 +1,56 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + table.mergeCells(0, 0, 1, 2) +//! [0] //! [1] + table.splitCell(0, 0, 1, 1) +//! [1] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/threads/threads.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/threads/threads.h new file mode 100644 index 0000000..2c48943 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/threads/threads.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +//! [0] +class MyThread : public QThread +{ + Q_OBJECT + +protected: + void run(); +}; +//! [0] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/timers/timers.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/timers/timers.cpp new file mode 100644 index 0000000..fbbd46a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/timers/timers.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtCore import QTimer + +class Foo : public QObject +{ +public: + Foo() +} + +Foo::Foo() +{ +//! [0] + timer = QTimer(self) +//! [0] //! [1] + timer.timeout.connect(self.updateCaption) +//! [1] //! [2] + timer.start(1000) +//! [2] + +//! [3] + QTimer.singleShot(200, self.updateCaption) +//! [3] + + { + // ZERO-CASE +//! [4] + timer = QTimer(self) +//! [4] //! [5] + timer.timeout.connect(self.processOneThing) +//! [5] //! [6] + timer.start() +//! [6] + } +} + +int main() +{ + +} diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp new file mode 100644 index 0000000..325ea1c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/transform/main.cpp @@ -0,0 +1,110 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] +def paintEvent(self, event) + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) + painter.drawRect(0, 0, 100, 100) + + painter.rotate(45) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QTransform") +//! [0] + +//! [1] +def paintEvent(self, event) + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) + painter.drawRect(0, 0, 100, 100) + + transform = QTransform() + transform.translate(50, 50) + transform.rotate(45) + transform.scale(0.5, 1.0) + painter.setTransform(transform) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QTransform") +//! [1] + + +//! [2] +def paintEvent(self, event) + pi = 3.14 + + a = pi/180 * 45.0 + sina = sin(a) + cosa = cos(a) + + translationTransform = QTransform(1, 0, 0, 1, 50.0, 50.0) + rotationTransform = QTransform(cosa, sina, -sina, cosa, 0, 0) + scalingTransform = QTransform(0.5, 0, 0, 1.0, 0, 0) + + transform = QTransform() + transform = scalingTransform * rotationTransform * translationTransform + + painter = QPainter(self) + painter.setPen(QPen(Qt.blue, 1, Qt.DashLine)) + painter.drawRect(0, 0, 100, 100) + + painter.setTransform(transform) + + painter.setFont(QFont("Helvetica", 24)) + painter.setPen(QPen(Qt.black, 1)) + painter.drawText(20, 10, "QTransform") + +//! [2] + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/uitools/calculatorform/calculatorform.ui b/sources/pyside2/doc/codesnippets/doc/src/snippets/uitools/calculatorform/calculatorform.ui new file mode 100644 index 0000000..dda0e62 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/uitools/calculatorform/calculatorform.ui @@ -0,0 +1,303 @@ + + + + + CalculatorForm + + + CalculatorForm + + + + 0 + 0 + 276 + 98 + + + + + 5 + 5 + 0 + 0 + + + + Calculator Builder + + + + + + + 9 + + + 6 + + + + + + + + 1 + + + 6 + + + + + + + + 1 + + + 6 + + + + + label + + + + 1 + 1 + 45 + 19 + + + + Input 1 + + + + + + + inputSpinBox1 + + + + 1 + 26 + 45 + 25 + + + + true + + + + + + + + + label_3 + + + + 54 + 1 + 7 + 52 + + + + + + + + Qt::AlignCenter + + + + + + + + + + 1 + + + 6 + + + + + label_2 + + + + 1 + 1 + 45 + 19 + + + + Input 2 + + + + + + + inputSpinBox2 + + + + 1 + 26 + 45 + 25 + + + + true + + + + + + + + + label_3_2 + + + + 120 + 1 + 7 + 52 + + + + = + + + Qt::AlignCenter + + + + + + + + + + 1 + + + 6 + + + + + label_2_2_2 + + + + 1 + 1 + 37 + 17 + + + + Output + + + + + + + outputWidget + + + + 1 + 24 + 37 + 27 + + + + QFrame::Box + + + QFrame::Sunken + + + 0 + + + Qt::AlignAbsolute|Qt::AlignBottom|Qt::AlignCenter|Qt::AlignHCenter|Qt::AlignHorizontal_Mask|Qt::AlignJustify|Qt::AlignLeading|Qt::AlignLeft|Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing|Qt::AlignVCenter|Qt::AlignVertical_Mask + + + + + + + + + + + verticalSpacer + + + + 85 + 69 + 20 + 20 + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + horizontalSpacer + + + + 188 + 26 + 79 + 20 + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/model.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/model.h new file mode 100644 index 0000000..6b40768 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/model.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MODEL_H +#define MODEL_H + +#include +#include +#include + +class TableModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + TableModel(int rows = 1, int columns = 1, QObject *parent = 0); + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + QVariant data(const QModelIndex &index, int role) const; + QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole) const; + + Qt::ItemFlags flags(const QModelIndex &index) const; + bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); + + bool insertRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool insertColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + bool removeRows(int position, int rows, const QModelIndex &parent = QModelIndex()); + bool removeColumns(int position, int columns, const QModelIndex &parent = QModelIndex()); + +private: + QList rowList; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/window.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/window.h new file mode 100644 index 0000000..ba4a36a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/updating-selections/window.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow(QWidget *parent = 0); + +public slots: + void updateSelection(const QItemSelection &selected, + const QItemSelection &deselected); + void changeCurrent(const QModelIndex ¤t, const QModelIndex &previous); + +private: + QAbstractItemModel *model; + QItemSelectionModel *selectionModel; + QTableView *table; +}; + +#endif diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp new file mode 100644 index 0000000..ea97d1e --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/whatsthis/whatsthis.cpp @@ -0,0 +1,57 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] + Act = QAction(tr("&New"), self) + Act.setShortcut(tr("Ctrl+N")) + Act.setStatusTip(QObject.tr("Create a new file")) + Act.setWhatsThis(QObject.tr("Click self option to create a new file.")) +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/mask.qrc b/sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/mask.qrc new file mode 100644 index 0000000..92f2272 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/mask.qrc @@ -0,0 +1,5 @@ + + + tux.png + + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/tux.png b/sources/pyside2/doc/codesnippets/doc/src/snippets/widget-mask/tux.png new file mode 100644 index 0000000000000000000000000000000000000000..a95527f3f2c3077f25e2c17fb9b91aa5816b3490 GIT binary patch literal 12191 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/widgetdelegate.cpp b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgetdelegate.cpp new file mode 100644 index 0000000..960d501 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgetdelegate.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +class WidgetDelegate (QStyledItemDelegate): + # ... + + def paint(painter, option, index): + if index.column() == 1: + progress = index.data().toInt() + + progressBarOption = QStyleOptionProgressBar() + progressBarOption.rect = option.rect + progressBarOption.minimum = 0 + progressBarOption.maximum = 100 + progressBarOption.progress = progress + progressBarOption.text = QString::number(progress) + "%" + progressBarOption.textVisible = True + + QApplication.style().drawControl(QStyle.CE_ProgressBar, progressBarOption, painter) + else: + QStyledItemDelegate.paint(self, painter, option, index) + +//![0] + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py new file mode 100644 index 0000000..d38829f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/widgets-tutorial/template.py @@ -0,0 +1,66 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [main.cpp body] +import sys +from PySide2.QtWidgets import QApplication + +# Include header files for application components. +# ... + +if __name__ == "__main__": + app = QApplication(sys.argv) + + # Set up and show widgets. + # ... + + sys.exit(app.exec_()) +} +//! [main.cpp body] diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/handler.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/handler.h new file mode 100644 index 0000000..89acb5d --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/handler.h @@ -0,0 +1,84 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef HANDLER_H +#define HANDLER_H + +#include +#include +#include + +/* Note that QObject must precede QXmlDefaultHandler in the following list. */ + +class Handler : public QObject, public QXmlDefaultHandler +{ + Q_OBJECT +public: + bool startDocument(); + bool startElement(const QString &, const QString &, const QString &qName, + const QXmlAttributes &attr); + bool endElement(const QString &, const QString &, const QString &qName); + bool characters(const QString &chars); + + bool fatalError(const QXmlParseException &exception); + +signals: + void newItem(QString &title, QString &link); + +private: + QString titleString; + QString linkString; + bool inItem; + bool inTitle; + bool inLink; +}; + +#endif + diff --git a/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/rsslisting.h b/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/rsslisting.h new file mode 100644 index 0000000..c7d7552 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/doc/src/snippets/xml/rsslisting/rsslisting.h @@ -0,0 +1,96 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef RSSLISTING_H +#define RSSLISTING_H + +#include +#include +#include +#include + +#include "handler.h" + +class QLineEdit; +class QTreeWidget; +class QTreeWidgetItem; +class QPushButton; + +class RSSListing : public QWidget +{ + Q_OBJECT +public: + RSSListing(QWidget *widget = 0); + +public slots: + void addItem(QString &title, QString &link); + void fetch(); + void finished(int id, bool error); + void readData(const QHttpResponseHeader &); + +private: + Handler *handler; + QXmlInputSource xmlInput; + QXmlSimpleReader xmlReader; + + bool newInformation; + + QHttp http; + int connectionId; + + QLineEdit *lineEdit; + QTreeWidget *treeWidget; + QTreeWidgetItem *lastItemCreated; + QPushButton *abortButton; + QPushButton *fetchButton; +}; + +#endif + diff --git a/sources/pyside2/doc/codesnippets/examples/dbus/example-client.py b/sources/pyside2/doc/codesnippets/examples/dbus/example-client.py new file mode 100755 index 0000000..52ad733 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dbus/example-client.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## # Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## # Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## # Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# -*- coding: utf-8 -*- + +# DBUS Client using PySide integration + +import sys +from traceback import print_exc + +# import python dbus module +import dbus +# import python dbus GLib mainloop support +import dbus.mainloop.glib +# import QtCore +from PySide2.QtCore import * + +# signal handler +def button_clicked(): + print "button clicked" + +# main function +if __name__ == '__main__': + + # Enable glib main loop support + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + # Get the session bus + bus = dbus.SessionBus() + + try: + # Get the remote object + remote_object = bus.get_object("com.example.SampleService", + "/DBusWidget") + # Get the remote interface for the remote object + iface = dbus.Interface(remote_object, "com.example.SampleWidget") + except dbus.DBusException: + print_exc() + sys.exit(1) + + # Start the application + app = QCoreApplication([]) + + # Call some methods of the remote interface + iface.show() + iface.setText("Emit signal") + # connect the DBus signal clicked to the function button_clicked + iface.connect_to_signal("clicked", button_clicked) + iface.connect_to_signal("lastWindowClosed", app.quit) + + # enter in the main loop + app.exec_() diff --git a/sources/pyside2/doc/codesnippets/examples/dbus/example-server.py b/sources/pyside2/doc/codesnippets/examples/dbus/example-server.py new file mode 100755 index 0000000..c42b869 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dbus/example-server.py @@ -0,0 +1,119 @@ +#!/usr/bin/env python + +############################################################################# +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the documentation of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## # Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## # Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## # Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +# -*- coding: utf-8 -*- + +# DBUS Server Example of use PySide with PyDBus library + +import dbus +import dbus.service +import dbus.mainloop.glib +import random + +from PySide2.QtCore import * +from PySide2.QtGui import QPushButton, QApplication + +# The adaptor, MUST inherit dbus.service.Object +class DBusWidget(dbus.service.Object): + def __init__(self, name, session): + # export this object to dbus + dbus.service.Object.__init__(self, name, session) + + # create a simple widget + self.widget = QPushButton() + self.widget.resize(200, 50) + + # To export a Qt signal as a DBus-signal, you need to connect it to a method in this class. + # The method MUST have the signal annotation, so python-dbus will export it as a dbus-signal + QObject.connect(self.widget, SIGNAL("clicked()"), self.clicked) + QObject.connect(QApplication.instance(), SIGNAL("lastWindowClosed()"), self.lastWindowClosed) + + # You can export methods to dbus like you do in python-dbus. + @dbus.service.method("com.example.SampleWidget", in_signature='', out_signature='') + def show(self): + self.widget.show() + + # Another method... now with a parameter + @dbus.service.method("com.example.SampleWidget", in_signature='s', out_signature='') + def setText(self, value): + self.widget.setText(value) + + # Another one... + @dbus.service.method("com.example.SampleWidget", in_signature='', out_signature='') + def exit(self): + qApp().quit() + + # A signal that will be exported to dbus + @dbus.service.signal("com.example.SampleWidget", signature='') + def clicked(self): + pass + + # Another signal that will be exported to dbus + @dbus.service.signal("com.example.SampleWidget", signature='') + def lastWindowClosed(self): + pass + + +if __name__ == '__main__': + app = QApplication([]) + # Use qt/glib mainloop integration to get dbus mainloop working + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) + + session_bus = dbus.SessionBus() + # Export the service + name = dbus.service.BusName("com.example.SampleService", session_bus) + # Export the object + widget = DBusWidget(session_bus, '/DBusWidget') + + print "Running example service." + app.exec_() + diff --git a/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugin.cpp b/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugin.cpp new file mode 100644 index 0000000..4b8b923 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugin.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +class TimeModel (QObject): + hour = Property(int, getHour, notify = timeChanged) + minute = Property(int, getMinute, notify = timeChanged) +//![0] + +//![plugin] +class QExampleQmlPlugin (QDeclarativeExtensionPlugin): + + def registerTypes(self, uri): + assert(uri == "com.nokia.TimeExample") + qmlRegisterType(TimeModel, uri, 1, 0, "Time") +//![plugin] + +//![export] +# This isn't supported by PySide yet. +# Q_EXPORT_PLUGIN2(qmlqtimeexampleplugin, QExampleQmlPlugin); +//![export] diff --git a/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugins.qml b/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugins.qml new file mode 100644 index 0000000..4155318 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/declarative/cppextensions/plugins/plugins.qml @@ -0,0 +1,62 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +//![0] +import com.nokia.TimeExample 1.0 // import types from the plugin + +Clock { // this class is defined in QML (com/nokia/TimeExample/Clock.qml) + + Time { // this class is defined in C++ (plugin.cpp) + id: time + } + + hours: time.hour + minutes: time.minute +} +//![0] diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py new file mode 100644 index 0000000..08032cf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.py @@ -0,0 +1,254 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] //! [1] +def __init__(self, parent): + QWizard.__init__(self, parent): + self.addPage(IntroPage()) + self.addPage(ClassInfoPage()) + self.addPage(CodeStylePage()) + self.addPage(OutputFilesPage()) + self.addPage(ConclusionPage()) +//! [0] + + self.setPixmap(QWizard.BannerPixmap, QPixmap(":/images/banner.png")) + self.setPixmap(QWizard.BackgroundPixmap, QPixmap(":/images/background.png")) + + self.setWindowTitle(self.tr("Class Wizard")) +//! [2] + +//! [1] //! [2] + +//! [3] +def accept(self): +//! [3] //! [4] + className = self.field("className") + baseClass = self.field("baseClass") + macroName = self.field("macroName") + baseInclude = self.field("baseInclude") + + outputDir = self.field("outputDir") + header = self.field("header") + implementation = self.field("implementation") +//! [4] + +... + +//! [5] + QDialog.accept(self) +//! [5] //! [6] +} +//! [6] + +//! [7] +class IntroPage (QWizardPage): + + def __init__(self, parent): + QWizardPage.__init__(self, parent) + + self.setTitle(tr("Introduction")) + self.setPixmap(QWizard.WatermarkPixmap, QPixmap(":/images/watermark1.png")) + + label = QLabel(self.tr("This wizard will generate a skeleton C++ class " \ + "definition, including a few functions. You simply " \ + "need to specify the class name and set a few " \ + "options to produce a header file and an " \ + "implementation file for your new C++ class.")) + label.setWordWrap(True) + + layout = QVBoxLayout() + layout.addWidget(label) + self.setLayout(layout) +} +//! [7] + +//! [8] //! [9] +class ClassInfoPage(QWizardPage): + + def __init__(self, parent): + QWizardPage.__init__(self, parent) +//! [8] + self.setTitle(self.tr("Class Information")) + self.setSubTitle(self.tr("Specify basic information about the class for which you " \ + "want to generate skeleton source code files.")) + self.setPixmap(QWizard.LogoPixmap, QPixmap(":/images/logo1.png")) + +//! [10] + classNameLabel = QLabel(self.tr("&Class name:")) + classNameLineEdit = QLineEdit() + classNameLabel.setBuddy(classNameLineEdit) + + baseClassLabel = QLabel(self.tr("B&ase class:")) + baseClassLineEdit = QLineEdit() + baseClassLabel.setBuddy(baseClassLineEdit) + + qobjectMacroCheckBox = QCheckBox(self.tr("Generate Q_OBJECT ¯o")) + +//! [10] + groupBox = QGroupBox(self.tr("C&onstructor")) +//! [9] + + qobjectCtorRadioButton = QRadioButton(self.tr("&QObject-style constructor")) + qwidgetCtorRadioButton = QRadioButton(self.tr("Q&Widget-style constructor")) + defaultCtorRadioButton = QRadioButton(self.tr("&Default constructor")) + copyCtorCheckBox = QCheckBox(self.tr("&Generate copy constructor and operator=")) + + defaultCtorRadioButton.setChecked(True) + + defaultCtorRadioButton.toggled[bool].connect(copyCtorCheckBox.setEnabled) + +//! [11] //! [12] + registerField("className*", classNameLineEdit) + registerField("baseClass", baseClassLineEdit) + registerField("qobjectMacro", qobjectMacroCheckBox) +//! [11] + registerField("qobjectCtor", qobjectCtorRadioButton) + registerField("qwidgetCtor", qwidgetCtorRadioButton) + registerField("defaultCtor", defaultCtorRadioButton) + registerField("copyCtor", copyCtorCheckBox) + + groupBoxLayout = QVBoxLayout() +//! [12] + groupBoxLayout.addWidget(qobjectCtorRadioButton) + groupBoxLayout.addWidget(qwidgetCtorRadioButton) + groupBoxLayout.addWidget(defaultCtorRadioButton) + groupBoxLayout.addWidget(copyCtorCheckBox) + groupBox.setLayout(groupBoxLayout) + + layout = QGridLayout() + layout.addWidget(classNameLabel, 0, 0) + layout.addWidget(classNameLineEdit, 0, 1) + layout.addWidget(baseClassLabel, 1, 0) + layout.addWidget(baseClassLineEdit, 1, 1) + layout.addWidget(qobjectMacroCheckBox, 2, 0, 1, 2) + layout.addWidget(groupBox, 3, 0, 1, 2) + self.setLayout(layout) +//! [13] + +//! [13] + +//! [14] +class CodeStylePage(QWizardPage): + + def __init__(self, parent): + QWizardPage.__init__(self, parent) + self.setTitle(tr("Code Style Options")) + self.setSubTitle(tr("Choose the formatting of the generated code.")) + self.setPixmap(QWizard.LogoPixmap, QPixmap(":/images/logo2.png")) + + commentCheckBox = QCheckBox(self.tr("&Start generated files with a comment")) +//! [14] + commentCheckBox.setChecked(True) + + protectCheckBox = QCheckBox(self.tr("&Protect header file against multiple " \ + "inclusions")) + protectCheckBox.setChecked(True) + + macroNameLabel = QLabel(self.tr("&Macro name:")) + macroNameLineEdit = QLineEdit() + macroNameLabel.setBuddy(macroNameLineEdit) + + includeBaseCheckBox = QCheckBox(self.tr("&Include base class definition")) + baseIncludeLabel = QLabel(self.tr("Base class include:")) + baseIncludeLineEdit = QLineEdit() + baseIncludeLabel.setBuddy(baseIncludeLineEdit) + + protectCheckBox.toggled[bool].connect(macroNameLabel.setEnabled) + protectCheckBox.toggled[bool].connect(macroNameLineEdit.setEnabled) + includeBaseCheckBox.toggled[bool].connect(baseIncludeLabel.setEnabled) + includeBaseCheckBox.toggled[bool].connect(baseIncludeLineEdit.setEnabled) + + self.registerField("comment", commentCheckBox) + self.registerField("protect", protectCheckBox) + self.registerField("macroName", macroNameLineEdit) + self.registerField("includeBase", includeBaseCheckBox) + self.registerField("baseInclude", baseIncludeLineEdit) + + layout = QGridLayout() + layout.setColumnMinimumWidth(0, 20) + layout.addWidget(commentCheckBox, 0, 0, 1, 3) + layout.addWidget(protectCheckBox, 1, 0, 1, 3) + layout.addWidget(macroNameLabel, 2, 1) + layout.addWidget(macroNameLineEdit, 2, 2) + layout.addWidget(includeBaseCheckBox, 3, 0, 1, 3) + layout.addWidget(baseIncludeLabel, 4, 1) + layout.addWidget(baseIncludeLineEdit, 4, 2) +//! [15] + self.setLayout(layout) +} +//! [15] + +//! [16] + def initializePage(self): + className = self.field("className") + self.macroNameLineEdit.setText(className.upper() + "_H") + + baseClass = self.field("baseClass") + + self.includeBaseCheckBox.setChecked(len(baseClass)) + self.includeBaseCheckBox.setEnabled(len(baseClass)) + self.baseIncludeLabel.setEnabled(len(baseClass)) + self.baseIncludeLineEdit.setEnabled(len(baseClass)) + + if not baseClass: + self.baseIncludeLineEdit.clear() + elsif QRegExp("Q[A-Z].*").exactMatch(baseClass): + baseIncludeLineEdit.setText("<" + baseClass + ">") + else: + baseIncludeLineEdit.setText("\"" + baseClass.lower() + ".h\"") +//! [16] + +//! [17] + def initializePage(self): + className = field("className") + self.headerLineEdit.setText(className.lower() + ".h") + self.implementationLineEdit.setText(className.lower() + ".cpp") + self.outputDirLineEdit.setText(QDir.convertSeparators(QDir.tempPath())) +//! [17] diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.qrc b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.qrc new file mode 100644 index 0000000..41a5ddc --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/classwizard.qrc @@ -0,0 +1,11 @@ + + + images/background.png + images/banner.png + images/logo1.png + images/logo2.png + images/logo3.png + images/watermark1.png + images/watermark2.png + + diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/background.png b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..44c7badb8568ff756804d2a5a651f8fff9961a1f GIT binary patch literal 22578 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 FV1kZVGdKVM literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo1.png b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo1.png new file mode 100644 index 0000000000000000000000000000000000000000..f9b594aafcd6f944f6d950aeaab01017ddaef68a GIT binary patch literal 1619 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo3.png b/sources/pyside2/doc/codesnippets/examples/dialogs/classwizard/images/logo3.png new file mode 100644 index 0000000000000000000000000000000000000000..9fd3ea23589d5cd1e36995fb7930fbb65537e2c9 GIT binary patch literal 1619 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

~pmFwck7jhkKr6uo?q0+;sEMYfP3VosyR1 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 + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QLabel; +class QLineEdit; +class QRadioButton; +QT_END_NAMESPACE + +//! [0] //! [1] +class LicenseWizard (QWizard): +//! [0] +//! [2] + Page_Intro = 1 + Page_Evaluate = 2 + Page_Register = 3 + Page_Details = 4 + Page_Conclusion = 5 +//! [2] + + def __init__(self, parent): + ... + + def showHelp(self): + ... +//! [3] + +//! [1] //! [3] + +//! [4] +class IntroPage : public QWizardPage +{ + Q_OBJECT + +public: + IntroPage(QWidget *parent = 0); + + int nextId() const; + +private: + QLabel *topLabel; + QRadioButton *registerRadioButton; + QRadioButton *evaluateRadioButton; +}; +//! [4] + +//! [5] +class EvaluatePage : public QWizardPage +{ + Q_OBJECT + +public: + EvaluatePage(QWidget *parent = 0); + + int nextId() const; + +private: + QLabel *nameLabel; + QLabel *emailLabel; + QLineEdit *nameLineEdit; + QLineEdit *emailLineEdit; +}; +//! [5] + +class RegisterPage : public QWizardPage +{ + Q_OBJECT + +public: + RegisterPage(QWidget *parent = 0); + + int nextId() const; + +private: + QLabel *nameLabel; + QLabel *upgradeKeyLabel; + QLineEdit *nameLineEdit; + QLineEdit *upgradeKeyLineEdit; +}; + +class DetailsPage : public QWizardPage +{ + Q_OBJECT + +public: + DetailsPage(QWidget *parent = 0); + + int nextId() const; + +private: + QLabel *companyLabel; + QLabel *emailLabel; + QLabel *postalLabel; + QLineEdit *companyLineEdit; + QLineEdit *emailLineEdit; + QLineEdit *postalLineEdit; +}; + +//! [6] +class ConclusionPage : public QWizardPage +{ + Q_OBJECT + +public: + ConclusionPage(QWidget *parent = 0); + + void initializePage(); + int nextId() const; + void setVisible(bool visible); + +private slots: + void printButtonClicked(); + +private: + QLabel *bottomLabel; + QCheckBox *agreeCheckBox; +}; +//! [6] + +#endif diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/licensewizard.qrc b/sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/licensewizard.qrc new file mode 100644 index 0000000..b069938 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/licensewizard/licensewizard.qrc @@ -0,0 +1,6 @@ + + + images/logo.png + images/watermark.png + + diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp new file mode 100644 index 0000000..db11e22 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/standarddialogs/dialog.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] + i, ok = QInputDialog().getInteger(self, "QInputDialog().getInteger()", + "Percentage:", 25, 0, 100, 1) + if ok: + self.integerLabel.setText("{}%".format(i)) +//! [0] + +//! [1] + d, ok = QInputDialog().getDouble(self, "QInputDialog().getDouble()", + "Amount:", 37.56, -10000, 10000, 2) + if ok: + doubleLabel.setText("${}".format()) +//! [1] + +//! [2] + items = ["Spring", "Summer", "Fall", "Winter"] + + item, ok = QInputDialog().getItem(self, "QInputDialog().getItem()", + "Season:", items, 0, False) + if ok and not item.isEmpty(): + itemLabel.setText(item) +//! [2] + +//! [3] + text, ok = QInputDialog().getText(self, "QInputDialog().getText()", + "User name:", QLineEdit.Normal, + QDir().home().dirName()) + if ok and text: + textLabel.setText(text) +//! [3] diff --git a/sources/pyside2/doc/codesnippets/examples/dialogs/tabdialog/tabdialog.cpp b/sources/pyside2/doc/codesnippets/examples/dialogs/tabdialog/tabdialog.cpp new file mode 100644 index 0000000..4fff4d6 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/dialogs/tabdialog/tabdialog.cpp @@ -0,0 +1,193 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class TabDialog (QDialog): + def __init__(self, fileName, parent = None): + QDialog.__init__(self, parent) + fileInfo = QFileInfo(fileName) + + self.tabWidget = QTabWidget() + self.tabWidget.addTab(GeneralTab(fileInfo), "General") + self.tabWidget.addTab(PermissionsTab(fileInfo), "Permissions") + self.tabWidget.addTab(ApplicationsTab(fileInfo), "Applications") +//! [0] + +//! [1] //! [2] + self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok +//! [1] //! [3] + | QDialogButtonBox.Cancel) + + self.buttonBox.accepted.connect(self.accept) + self.buttonBox.rejected.connect(self.reject) +//! [2] //! [3] + +//! [4] + mainLayout = QVBoxLayout() + mainLayout.addWidget(tabWidget) + mainLayout.addWidget(buttonBox) + self.setLayout(mainLayout) +//! [4] + +//! [5] + self.setWindowTitle("Tab Dialog") +//! [5] + +//! [6] +class GeneralTab (QWidget): + def __init__(self, fileInfo, parent = None): + QWidget.__init__(self, parent) + fileNameLabel = QLabel("File Name:") + fileNameEdit = QLineEdit(fileInfo.fileName()) + + pathLabel = QLabel("Path:") + pathValueLabel = QLabel(fileInfo.absoluteFilePath()) + pathValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + sizeLabel = QLabel("Size:") + size = fileInfo.size()/1024 + sizeValueLabel = QLabel("%d K" % size) + sizeValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + lastReadLabel = QLabel("Last Read:") + lastReadValueLabel = QLabel(fileInfo.lastRead().toString()) + lastReadValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + lastModLabel = QLabel("Last Modified:") + lastModValueLabel = QLabel(fileInfo.lastModified().toString()) + lastModValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + mainLayout = QVBoxLayout() + mainLayout.addWidget(fileNameLabel) + mainLayout.addWidget(fileNameEdit) + mainLayout.addWidget(pathLabel) + mainLayout.addWidget(pathValueLabel) + mainLayout.addWidget(sizeLabel) + mainLayout.addWidget(sizeValueLabel) + mainLayout.addWidget(lastReadLabel) + mainLayout.addWidget(lastReadValueLabel) + mainLayout.addWidget(lastModLabel) + mainLayout.addWidget(lastModValueLabel) + mainLayout.addStretch(1) + self.setLayout(mainLayout) +//! [6] + +//! [7] +class PermissionsTab (QWidget): + def __init__(self, fileInfo, parent = None): + QWidget.__init__(self, parent) + permissionsGroup = QGroupBox("Permissions") + + readable = QCheckBox("Readable") + if fileInfo.isReadable(): + readable.setChecked(True) + + writable = QCheckBox("Writable") + if fileInfo.isWritable(): + writable.setChecked(True) + + executable = QCheckBox("Executable") + if fileInfo.isExecutable(): + executable.setChecked(True) + + ownerGroup = QGroupBox("Ownership") + + ownerLabel = QLabel("Owner") + ownerValueLabel = QLabel(fileInfo.owner()) + ownerValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + groupLabel = QLabel("Group") + groupValueLabel = QLabel(fileInfo.group()) + groupValueLabel.setFrameStyle(QFrame.Panel | QFrame.Sunken) + + permissionsLayout = QVBoxLayout() + permissionsLayout.addWidget(readable) + permissionsLayout.addWidget(writable) + permissionsLayout.addWidget(executable) + permissionsGroup.setLayout(permissionsLayout) + + ownerLayout = QVBoxLayout() + ownerLayout.addWidget(ownerLabel) + ownerLayout.addWidget(ownerValueLabel) + ownerLayout.addWidget(groupLabel) + ownerLayout.addWidget(groupValueLabel) + ownerGroup.setLayout(ownerLayout) + + mainLayout = QVBoxLayout() + mainLayout.addWidget(permissionsGroup) + mainLayout.addWidget(ownerGroup) + mainLayout.addStretch(1) + self.setLayout(mainLayout) +//! [7] + +//! [8] +class ApplicationsTab (QWidget): + def __init__(self, fileInfo, parent = None): + QWidget.__init__(self, parent) + topLabel = QLabel("Open with:") + + applicationsListBox = QListWidget() + applications = [] + + for i in range(30): + applications.append("Application %d" %s i) + applicationsListBox.insertItems(0, applications) + + if fileInfo.suffix().isEmpty(): + alwaysCheckBox = QCheckBox("Always use this application to open this type of file") + else: + alwaysCheckBox = QCheckBox("Always use this application to open files with the extension '%s'" % fileInfo.suffix()) + + layout = QVBoxLayout() + layout.addWidget(topLabel) + layout.addWidget(applicationsListBox) + layout.addWidget(alwaysCheckBox) + self.setLayout(layout) +//! [8] diff --git a/sources/pyside2/doc/codesnippets/examples/graphicsview/simpleanchorlayout/main.cpp b/sources/pyside2/doc/codesnippets/examples/graphicsview/simpleanchorlayout/main.cpp new file mode 100644 index 0000000..818d865 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/graphicsview/simpleanchorlayout/main.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [adding a corner anchor in two steps] +layout.addAnchor(a, Qt.AnchorTop, layout, Qt.AnchorTop) +layout.addAnchor(a, Qt.AnchorLeft, layout, Qt.AnchorLeft) +//! [adding a corner anchor in two steps] + +//! [adding a corner anchor] +layout.addCornerAnchors(a, Qt.TopLeftCorner, layout, Qt.TopLeftCorner) +//! [adding a corner anchor] + +//! [adding anchors] +layout.addAnchor(b, Qt.AnchorLeft, a, Qt.AnchorRight) +layout.addAnchor(b, Qt.AnchorTop, a, Qt.AnchorBottom) +//! [adding anchors] + +//! [adding anchors to match sizes in two steps] +layout.addAnchor(b, Qt.AnchorLeft, c, Qt.AnchorLeft) +layout.addAnchor(b, Qt.AnchorRight, c, Qt.AnchorRight) +//! [adding anchors to match sizes in two steps] + +//! [adding anchors to match sizes] +layout.addAnchors(b, c, Qt.Horizontal) +//! [adding anchors to match sizes] diff --git a/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider-example.qml b/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider-example.qml new file mode 100644 index 0000000..58f2599 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider-example.qml @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "ImageProviderCore" // import the plugin that registers the color image provider + +//![0] +Column { + Image { source: "image://colors/yellow" } + Image { source: "image://colors/red" } +} +//![0] diff --git a/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider.cpp b/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider.cpp new file mode 100644 index 0000000..b389011 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/imageprovider/imageprovider.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//![0] +class ColorImageProvider (QQuickImageProvider): + def __init__(self): + QQuickImageProvider.__init__(self, QQuickImageProvider.Pixmap) + + def requestPixmap(id, size, requestedSize): + width = 100 + height = 50 + + if size: + size.setWidth(width) + size.setHeight(height) + + if requestedSize.width() > 0: + width = requestedSize.width() + if requestedSize.height() > 0: + height = requestedSize.height() + + pixmap = QPixmap(width, height) + pixmap.fill(QColor(id).rgba()) +//![0] + # write the color name + painter = QPainter(pixmap) + f = painter.font() + f.setPixelSize(20) + painter.setFont(f) + painter.setPen(Qt.black) + if requestedSize.isValid(): + painter.scale(requestedSize.width() / width, requestedSize.height() / height) + painter.drawText(QRectF(0, 0, width, height), Qt.AlignCenter, id) +//![1] + return pixmap +//![1] diff --git a/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp b/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp new file mode 100644 index 0000000..f99b7e1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/itemviews/customsortfiltermodel/mysortfilterproxymodel.cpp @@ -0,0 +1,109 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +def __init__(self, parent): + QSortFilterProxyModel.__init__(self, parent) +//! [0] + +//! [1] +def setFilterMinimumDate(self, date): + self.minDate = date + self.invalidateFilter() + +//! [1] + +//! [2] +def setFilterMaximumDate(self, date): + self.maxDate = date + self.invalidateFilter() + +//! [2] + +//! [3] +def filterAcceptsRow(self, sourceRow, sourceParent): + index0 = sourceModel().index(sourceRow, 0, sourceParent) + index1 = sourceModel().index(sourceRow, 1, sourceParent) + index2 = sourceModel().index(sourceRow, 2, sourceParent) + + regex = filterRegExp() + return (regex.indexIn(sourceModel().data(index0)) != -1 + or regex.indexIn(sourceModel().data(index1)) != -1 + and dateInRange(sourceModel().data(index2)) +//! [3] + +//! [4] //! [5] +def lessThan(self, left, right): + leftData = sourceModel().data(left) + rightData = sourceModel().data(right) +//! [4] + +//! [6] + if isinstance(leftData, QDateTime): + return leftData < rightData + else: + emailPattern = QRegExp("([\\w\\.]*@[\\w\\.]*)") + + if left.column() == 1 && emailPattern.indexIn(leftData) != -1: + leftData = emailPattern.cap(1) + + if right.column() == 1 && emailPattern.indexIn(rightData) != -1: + rightData = emailPattern.cap(1) + + return leftString < rightString + +//! [5] //! [6] + +//! [7] +def dateInRange(self, date): + return (!minDate.isValid() || date > minDate) + && (!maxDate.isValid() || date < maxDate) + +//! [7] diff --git a/sources/pyside2/doc/codesnippets/examples/itemviews/pixelator/pixeldelegate.cpp b/sources/pyside2/doc/codesnippets/examples/itemviews/pixelator/pixeldelegate.cpp new file mode 100644 index 0000000..7c207d1 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/itemviews/pixelator/pixeldelegate.cpp @@ -0,0 +1,103 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def __init__(self, parent): + QAbstractItemDelegate.__init__(self, parent) + self.pixelSize = 12 +//! [0] + +//! [1] +def paint(self, painter, option, index): +//! [2] + if option.state and QStyle.State_Selected: + painter.fillRect(option.rect, option.palette.highlight()) +//! [1] + +//! [3] + size = qMin(option.rect.width(), option.rect.height()) +//! [3] //! [4] + brightness = index.model().data(index, Qt.DisplayRole).toInt() + radius = (size/2.0) - (brightness/255.0 * size/2.0) + if radius == 0.0: + return +//! [4] + +//! [5] + painter.save() +//! [5] //! [6] + painter.setRenderHint(QPainter.Antialiasing, true) +//! [6] //! [7] + painter.setPen(Qt.NoPen) +//! [7] //! [8] + if option.state and QStyle.State_Selected: +//! [8] //! [9] + painter.setBrush(option.palette.highlightedText()) + else +//! [2] + painter.setBrush(QBrush(Qt.black)) +//! [9] + +//! [10] + painter.drawEllipse(QRectF(option.rect.x() + option.rect.width()/2 - radius, + option.rect.y() + option.rect.height()/2 - radius, + 2*radius, 2*radius)) + painter.restore() +//! [10] + +//! [11] +def sizeHint(self, option, index): + return QSize(self.pixelSize, self.pixelSize) +//! [11] + +//! [12] +def setPixelSize(self, size): + self.pixelSize = size +//! [12] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h new file mode 100644 index 0000000..bdb7bcf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.h @@ -0,0 +1,112 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtWidgets import (QAction, QApplication, QMainWindow, QMenu, + QPlainTextEdit, QSessionManager) + + +//! [0] +class MainWindow(QMainWindow): + def __init__(self, parent=None): + self.textEdit = QPlainTextEdit() + self.curFile = "" + # ... + + def loadFile(self, fileName): + pass + + def closeEvent(self, event): + pass + + def newFile(self): + pass + + def open(self): + pass + + def save(self): + pass + + def saveAs(self): + pass + + def about(self): + pass + + def documentWasModified(self): + pass + # Enable this only if QT_NO_SESSIONMANAGER is not defined + # def commitData(self): + # pass + + def createActions(self): + pass + + def createStatusBar(self): + pass + + def readSettings(self): + pass + + def writeSettings(self): + pass + + def maybeSave(self): + pass + + def saveFile(self, fileName): + pass + + def setCurrentFile(self, fileName): + pass + + def strippedName(self, fullFileName): + pass +//! [0] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py new file mode 100644 index 0000000..f976bb8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/application/mainwindow.py @@ -0,0 +1,357 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +from PySide2.QtCore import Qt, QFile, QFileInfo, QSettings, QTextStream +from PySide2.QtGui import QIcon +from PySide2.Widgets import (QAction, QApplication, QFileDialog, QMainWindow, + QPlainTextEdit, QFileDialog, QMessageBox, ) +//! [0] + +//! [1] +def __init__(self, parent=None): + QMainWindow.__init__(self) +//! [1] //! [2] + self.textEdit = QPlainTextEdit() + self.setCentralWidget(textEdit) + + self.createActions() + self.createMenus() + self.createToolBars() + self.createStatusBar() + + self.readSettings() + + self.textEdit.document().contentsChanged.connect(self.documentWasModified) + + self.setCurrentFile("") + self.setUnifiedTitleAndToolBarOnMac(True) + +//! [2] + +//! [3] +def closeEvent(self, event): +//! [3] //! [4] + if maybeSave(): + writeSettings() + event.accept() + else: + event.ignore() +//! [4] + +//! [5] +def File(self): +//! [5] //! [6] + if maybeSave(): + textEdit.clear() + setCurrentFile("") +//! [6] + +//! [7] +def open(self): +//! [7] //! [8] + if maybeSave(): + fileName = QFileDialog.getOpenFileName(self) + if not fileName.isEmpty(): + loadFile(fileName) +//! [8] + +//! [9] +def save(self): +//! [9] //! [10] + if curFile.isEmpty(): + return saveAs() + else: + return saveFile(curFile) +//! [10] + +//! [11] +def saveAs(self): +//! [11] //! [12] + fileName = QFileDialog.getSaveFileName(self) + if fileName.isEmpty(): + return False + + return saveFile(fileName) +//! [12] + +//! [13] +def about(self): +//! [13] //! [14] + QMessageBox.about(self, tr("About Application"), + tr("The Application example demonstrates how to " + "write modern GUI applications using Qt, with a menu bar, " + "toolbars, and a status bar.")) + +//! [14] + +//! [15] +def documentWasModified(self): +//! [15] //! [16] + setWindowModified(textEdit.document().isModified()) +//! [16] + +//! [17] +def MainWindow.createActions(self): +//! [17] //! [18] + Act = QAction(QIcon(":/images/new.png"), tr("&New"), self) + Act.setShortcuts(QKeySequence.New) + Act.setStatusTip(tr("Create a new file")) + Act.triggered.connect(newFile) + +//! [19] + openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self) + openAct.setShortcuts(QKeySequence.Open) + openAct.setStatusTip(tr("Open an existing file")) + openAct.triggered.connect(open) +//! [18] //! [19] + + saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self) + saveAct.setShortcuts(QKeySequence.Save) + saveAct.setStatusTip(tr("Save the document to disk")) + saveAct.triggered.connect(save) + + saveAsAct = QAction(tr("Save &As..."), self) + saveAsAct.setShortcuts(QKeySequence.SaveAs) + saveAsAct.setStatusTip(tr("Save the document under a name")) + saveAsAct.triggered.connect(saveAs) + +//! [20] + exitAct = QAction(tr("E&xit"), self) + exitAct.setShortcut(tr("Ctrl+Q")) +//! [20] + exitAct.setStatusTip(tr("Exit the application")) + exitAct.triggered.connect(close) + +//! [21] + cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self) +//! [21] + cutAct.setShortcuts(QKeySequence.Cut) + cutAct.setStatusTip(tr("Cut the current selection's contents to the " + "clipboard")) + cutAct.triggered.connect(cut) + + copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self) + copyAct.setShortcuts(QKeySequence.Copy) + copyAct.setStatusTip(tr("Copy the current selection's contents to the " + "clipboard")) + copyAct.triggered.connect(copy) + + pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self) + pasteAct.setShortcuts(QKeySequence.Paste) + pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " + "selection")) + pasteAct.triggered.connect(textEdit.paste) + + aboutAct = QAction(tr("&About"), self) + aboutAct.setStatusTip(tr("Show the application's About box")) + aboutAct.triggered.connect(about) + +//! [22] + aboutQtAct = QAction(tr("About &Qt"), self) + aboutQtAct.setStatusTip(tr("Show the Qt library's About box")) + aboutQtAct.triggered.connect(qApp.aboutQt) +//! [22] + +//! [23] + cutAct.setEnabled(False) +//! [23] //! [24] + copyAct.setEnabled(False) + textEdit.copyAvailable[bool].connect(cutAct.setEnabled) + textEdit.copyAvailable[bool].connect(copyAct.setEnabled) +} +//! [24] + +//! [25] //! [26] +def createMenus(self): +//! [25] //! [27] + fileMenu = menuBar().addMenu(tr("&File")) + fileMenu.addAction(Act) +//! [28] + fileMenu.addAction(openAct) +//! [28] + fileMenu.addAction(saveAct) +//! [26] + fileMenu.addAction(saveAsAct) + fileMenu.addSeparator() + fileMenu.addAction(exitAct) + + editMenu = menuBar().addMenu(tr("&Edit")) + editMenu.addAction(cutAct) + editMenu.addAction(copyAct) + editMenu.addAction(pasteAct) + + menuBar().addSeparator() + + helpMenu = menuBar().addMenu(tr("&Help")) + helpMenu.addAction(aboutAct) + helpMenu.addAction(aboutQtAct) + +//! [27] + +//! [29] //! [30] +def createToolBars(self): + fileToolBar = addToolBar(tr("File")) + fileToolBar.addAction(Act) +//! [29] //! [31] + fileToolBar.addAction(openAct) +//! [31] + fileToolBar.addAction(saveAct) + + editToolBar = addToolBar(tr("Edit")) + editToolBar.addAction(cutAct) + editToolBar.addAction(copyAct) + editToolBar.addAction(pasteAct) +//! [30] + +//! [32] +def createStatusBar(self): +//! [32] //! [33] + statusBar().showMessage(tr("Ready")) + +//! [33] + +//! [34] //! [35] +def readSettings(self): +//! [34] //! [36] + settings("Trolltech", "Application Example") + pos = settings.value("pos", QPoint(200, 200)).toPoint() + size = settings.value("size", QSize(400, 400)).toSize() + resize(size) + move(pos) + +//! [35] //! [36] + +//! [37] //! [38] +def writeSettings(self): +//! [37] //! [39] + settings = QSettings("Trolltech", "Application Example") + settings.setValue("pos", pos()) + settings.setValue("size", size()) + +//! [38] //! [39] + +//! [40] +def maybeSave(self): +//! [40] //! [41] + if textEdit.document()->isModified(): + ret = QMessageBox.warning(self, tr("Application"), + tr("The document has been modified.\n" + "Do you want to save your changes?"), + QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) + if ret == QMessageBox.Save: + return save() + elif ret == QMessageBox.Cancel: + return False + return True +//! [41] + +//! [42] +def loadFile(self, fileName): +//! [42] //! [43] + file = QFile(fileName) + if !file.open(QFile.ReadOnly | QFile.Text): + QMessageBox.warning(self, tr("Application"), tr("Cannot read file " + "{}:\n{}.".format(fileName, file.errorString()))) + return + + in = QTextStream(file) + QApplication.setOverrideCursor(Qt::WaitCursor) + textEdit.setPlainText(in.readAll()) + QApplication.restoreOverrideCursor() + + self.setCurrentFile(fileName) + self.statusBar().showMessage(tr("File loaded"), 2000) + +//! [43] + +//! [44] +def saveFile(self, fileName): +//! [44] //! [45] + file = QFile(fileName) + if !file.open(QFile.WriteOnly | QFile::Text): + QMessageBox.warning(self, tr("Application"), + tr("Cannot write file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())) + return False + + out = QTextStream(file) + QApplication.setOverrideCursor(Qt.WaitCursor) + out << textEdit.toPlainText() + QApplication.restoreOverrideCursor() + + setCurrentFile(fileName) + statusBar().showMessage(tr("File saved"), 2000) + return True + +//! [45] + +//! [46] +def setCurrentFile(fileName): +//! [46] //! [47] + curFile = fileName + textEdit.document().setModified(False) + setWindowModified(False) + + if curFile.isEmpty(): + shownName = "untitled.txt" + else: + shownName = strippedName(curFile) + + setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Application"))) + +//! [47] + +//! [48] +def strippedName(self, fullFileName): +//! [48] //! [49] + return QFileInfo(fullFileName).fileName() +//! [49] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py new file mode 100644 index 0000000..55d551c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/dockwidgets/mainwindow.py @@ -0,0 +1,253 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +//! [0] +from PySide2.QtGui import * +//! [0] + +//! [1] +def __init__(self): + textEdit = QTextEdit() + setCentralWidget(textEdit) + + createActions() + createMenus() + createToolBars() + createStatusBar() + createDockWindows() + + setWindowTitle(tr("Dock Widgets")) + + Letter() + setUnifiedTitleAndToolBarOnMac(True) +//! [1] + +//! [2] +def Letter(self) + textEdit.clear() + + cursor = QTextCursor(textEdit.textCursor()) + cursor.movePosition(QTextCursor.Start) + topFrame = cursor.currentFrame() + topFrameFormat = topFrame.frameFormat() + topFrameFormat.setPadding(16) + topFrame.setFrameFormat(topFrameFormat) + + textFormat = QTextCharFormat() + boldFormat = QTextCharFormat() + boldFormat.setFontWeight(QFont.Bold) + italicFormat = QTextCharFormat() + italicFormat.setFontItalic(True) + + tableFormat = QTextTableFormat() + tableFormat.setBorder(1) + tableFormat.setCellPadding(16) + tableFormat.setAlignment(Qt.AlignRight) + cursor.insertTable(1, 1, tableFormat) + cursor.insertText("The Firm", boldFormat) + cursor.insertBlock() + cursor.insertText("321 City Street", textFormat) + cursor.insertBlock() + cursor.insertText("Industry Park") + cursor.insertBlock() + cursor.insertText("Some Country") + cursor.setPosition(topFrame.lastPosition()) + cursor.insertText(QDate.currentDate().toString("d MMMM yyyy"), textFormat) + cursor.insertBlock() + cursor.insertBlock() + cursor.insertText("Dear ", textFormat) + cursor.insertText("NAME", italicFormat) + cursor.insertText(",", textFormat) + for i in range(3): + cursor.insertBlock() + cursor.insertText(tr("Yours sincerely,"), textFormat) + for i in range(3): + cursor.insertBlock() + cursor.insertText("The Boss", textFormat) + cursor.insertBlock() + cursor.insertText("ADDRESS", italicFormat) +//! [2] + +//! [3] +def print(self) + document = textEdit.document() + printer = QPrinter() + + dlg = QPrintDialog(&printer, self) + if dlg.exec() != QDialog.Accepted: + return + + document.print(printer) + statusBar().showMessage(tr("Ready"), 2000) +//! [3] + +//! [4] +def save(self): + fileName = QFileDialog.getSaveFileName(self, + tr("Choose a file name"), ".", + tr("HTML (*.html *.htm)")) + if fileName.isEmpty(): + return + file = QFile(fileName) + if !file.open(QFile.WriteOnly | QFile::Text): + QMessageBox.warning(self, tr("Dock Widgets"), + tr("Cannot write file %1:\n%2.") + .arg(fileName) + .arg(file.errorString())) + return + + + out = QTextStream(file) + QApplication.setOverrideCursor(Qt::WaitCursor) + out << textEdit.toHtml() + QApplication.restoreOverrideCursor() + + statusBar().showMessage(tr("Saved '%1'").arg(fileName), 2000) + +//! [4] + +//! [5] +def undo(self): + document = textEdit.document() + document.undo() + +//! [5] + +//! [6] +def insertCustomer(self, customer): + if customer.isEmpty(): + return + + customerList = customer.split(", ") + document = textEdit.document() + cursor = document.find("NAME") + if not cursor.isNull(): + cursor.beginEditBlock() + cursor.insertText(customerList.at(0)) + oldcursor = cursor + cursor = document.find("ADDRESS") + if not cursor.isNull(): + for i in range(customerList.size()): + cursor.insertBlock() + cursor.insertText(customerList.at(i)) + + cursor.endEditBlock() + else: + oldcursor.endEditBlock() +//! [6] + +//! [7] +def addParagraph(self, paragraph): + if (paragraph.isEmpty()) + return + + document = textEdit.document() + cursor = document.find(tr("Yours sincerely,")) + if cursor.isNull(): + return + cursor.beginEditBlock() + cursor.movePosition(QTextCursor.PreviousBlock, QTextCursor.MoveAnchor, 2) + cursor.insertBlock() + cursor.insertText(paragraph) + cursor.insertBlock() + cursor.endEditBlock() + +//! [7] + + +//! [8] +def createStatusBar(self): + statusBar().showMessage(tr("Ready")) + +//! [8] + +//! [9] +def createDockWindows(self): + dock = QDockWidget(tr("Customers"), self) + dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) + customerList = QListWidget(dock) + customerList.addItems(QStringList() + << "John Doe, Harmony Enterprises, 12 Lakeside, Ambleton" + << "Jane Doe, Memorabilia, 23 Watersedge, Beaton" + << "Tammy Shea, Tiblanka, 38 Sea Views, Carlton" + << "Tim Sheen, Caraba Gifts, 48 Ocean Way, Deal" + << "Sol Harvey, Chicos Coffee, 53 New Springs, Eccleston" + << "Sally Hobart, Tiroli Tea, 67 Long River, Fedula") + dock.setWidget(customerList) + addDockWidget(Qt.RightDockWidgetArea, dock) + viewMenu.addAction(dock.toggleViewAction()) + + dock = QDockWidget(tr("Paragraphs"), self) + paragraphsList = QListWidget(dock) + paragraphsList.addItems(QStringList() + << "Thank you for your payment which we have received today." + << "Your order has been dispatched and should be with you " + "within 28 days." + << "We have dispatched those items that were in stock. The " + "rest of your order will be dispatched once all the " + "remaining items have arrived at our warehouse. No " + "additional shipping charges will be made." + << "You made a small overpayment (less than $5) which we " + "will keep on account for you, or return at your request." + << "You made a small underpayment (less than $1), but we have " + "sent your order anyway. We'll add self underpayment to " + "your next bill." + << "Unfortunately you did not send enough money. Please remit " + "an additional $. Your order will be dispatched as soon as " + "the complete amount has been received." + << "You made an overpayment (more than $5). Do you wish to " + "buy more items, or should we return the excess to you?") + dock.setWidget(paragraphsList) + addDockWidget(Qt.RightDockWidgetArea, dock) + viewMenu.addAction(dock.toggleViewAction()) + + customerList.currentTextChanged[str].connect(self.insertCostumer) + paragraphsList.currentTextChanged[str].connect(self.addParagraph) +//! [9] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py new file mode 100644 index 0000000..b0bbed8 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mainwindow.py @@ -0,0 +1,366 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * + +//! [0] +def __init__(self): + Q__init__(self) + + widget = QWidget() + setCentralWidget(widget) +//! [0] + +//! [1] + topFiller = QWidget() + topFiller.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + infoLabel = QLabel(tr("Choose a menu option, or right-click to " + "invoke a context menu")) + infoLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) + infoLabel.setAlignment(Qt.AlignCenter) + + bottomFiller = QWidget() + bottomFiller.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + layout = QVBoxLayout() + layout.setMargin(5) + layout.addWidget(topFiller) + layout.addWidget(infoLabel) + layout.addWidget(bottomFiller) + widget.setLayout(layout) +//! [1] + +//! [2] + createActions() + createMenus() + + message = tr("A context menu is available by right-clicking") + statusBar().showMessage(message) + + setWindowTitle(tr("Menus")) + setMinimumSize(160, 160) + resize(480, 320) + +//! [2] + +//! [3] +def contextMenuEvent(self, event): + menu = QMenu(self) + menu.addAction(cutAct) + menu.addAction(copyAct) + menu.addAction(pasteAct) + menu.exec_(event.globalPos()") + +//! [3] + +def File(self): + infoLabel.setText(tr("Invoked File|New")) + + +def open(self): + infoLabel.setText(tr("Invoked File|Open")) + + +def save(self): + infoLabel.setText(tr("Invoked File|Save")) + +def print_(self): + infoLabel.setText(tr("Invoked File|Print")) + +def undo(self): + infoLabel.setText(tr("Invoked Edit|Undo")) + +def redo(self): + infoLabel.setText(tr("Invoked Edit|Redo")) + +def cut(self): + + infoLabel.setText(tr("Invoked Edit|Cut")) + + +def copy(self): + + infoLabel.setText(tr("Invoked Edit|Copy")) + + +def paste(self): + + infoLabel.setText(tr("Invoked Edit|Paste")) + + +def bold(self): + + infoLabel.setText(tr("Invoked Edit|Format|Bold")) + + +def italic(self): + + infoLabel.setText(tr("Invoked Edit|Format|Italic")) + + +def leftAlign(self): + + infoLabel.setText(tr("Invoked Edit|Format|Left Align")) + + +def rightAlign(self): + + infoLabel.setText(tr("Invoked Edit|Format|Right Align")) + + +def justify(self): + + infoLabel.setText(tr("Invoked Edit|Format|Justify")) + + +def center(self): + + infoLabel.setText(tr("Invoked Edit|Format|Center")) + + +def setLineSpacing(self): + + infoLabel.setText(tr("Invoked Edit|Format|Set Line Spacing")) + + +def setParagraphSpacing(self): + + infoLabel.setText(tr("Invoked Edit|Format|Set Paragraph Spacing")) + + +def about(self): + + infoLabel.setText(tr("Invoked Help|About")) + QMessageBox.about(self, tr("About Menu"), + tr("The Menu example shows how to create " + "menu-bar menus and context menus.")) + + +def aboutQt(self): + + infoLabel.setText(tr("Invoked Help|About Qt")) + + +//! [4] +def createActions(self): + +//! [5] + Act = new QAction(tr("&New"), self) + Act.setShortcuts(QKeySequence.New) + Act.setStatusTip(tr("Create a new file")) + Act.triggered.connect(newFile) +//! [4] + + openAct = QAction(tr("&Open..."), self) + openAct.setShortcuts(QKeySequence.Open) + openAct.setStatusTip(tr("Open an existing file")) + openAct.triggered.connect(open) +//! [5] + + saveAct = QAction(tr("&Save"), self) + saveAct.setShortcuts(QKeySequence.Save) + saveAct.setStatusTip(tr("Save the document to disk")) + saveAct.triggered.connect(save) + + printAct = QAction(tr("&Print..."), self) + printAct.setShortcuts(QKeySequence.Print) + printAct.setStatusTip(tr("Print the document")) + printAct.triggered.connect(print_) + + exitAct = QAction(tr("E&xit"), self) + exitAct.setShortcut(tr("Ctrl+Q")) + exitAct.setStatusTip(tr("Exit the application")) + exitAct.triggered.connect(close) + + undoAct = QAction(tr("&Undo"), self) + undoAct.setShortcuts(QKeySequence.Undo) + undoAct.setStatusTip(tr("Undo the last operation")) + undoAct.triggered.connect(undo) + + redoAct = QAction(tr("&Redo"), self) + redoAct.setShortcuts(QKeySequence.Redo) + redoAct.setStatusTip(tr("Redo the last operation")) + redoAct.triggered.connect(redo) + + cutAct = QAction(tr("Cu&t"), self) + cutAct.setShortcuts(QKeySequence.Cut) + cutAct.setStatusTip(tr("Cut the current selection's contents to the " + "clipboard")) + cutAct.triggered.connect(cut) + + copyAct = QAction(tr("&Copy"), self) + copyAct.setShortcut(tr("Ctrl+C")) + copyAct.setStatusTip(tr("Copy the current selection's contents to the " + "clipboard")) + copyAct.triggered.connect(copy) + + pasteAct = QAction(tr("&Paste"), self) + pasteAct.setShortcuts(QKeySequence.Paste) + pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " + "selection")) + pasteAct.triggered.connect(paste) + + boldAct = QAction(tr("&Bold"), self) + boldAct.setCheckable(True) + boldAct.setShortcut(tr("Ctrl+B")) + boldAct.setStatusTip(tr("Make the text bold")) + boldAct.triggered.connect(bold) + + QFont boldFont = boldAct.font() + boldFont.setBold(True) + boldAct.setFont(boldFont) + + italicAct = QAction(tr("&Italic"), self) + italicAct.setCheckable(True) + italicAct.setShortcut(tr("Ctrl+I")) + italicAct.setStatusTip(tr("Make the text italic")) + italicAct.triggered.connect(italic) + + QFont italicFont = italicAct.font() + italicFont.setItalic(True) + italicAct.setFont(italicFont) + + setLineSpacingAct = QAction(tr("Set &Line Spacing..."), self) + setLineSpacingAct.setStatusTip(tr("Change the gap between the lines of a " + "paragraph")) + setLineSpacingAct.triggered.connect(setLineSpacing) + + setParagraphSpacingAct = QAction(tr("Set &Paragraph Spacing..."), self) + setLineSpacingAct.setStatusTip(tr("Change the gap between paragraphs")) + setParagraphSpacingAct.triggered.connect(setParagraphSpacing) + + aboutAct = QAction(tr("&About"), self) + aboutAct.setStatusTip(tr("Show the application's About box")) + aboutAct.triggered.connect(about) + + aboutQtAct = QAction(tr("About &Qt"), self) + aboutQtAct.setStatusTip(tr("Show the Qt library's About box")) + aboutQtAct.triggered.connect(qApp.aboutQt) + aboutQtAct.triggered.connect(aboutQt) + + leftAlignAct = QAction(tr("&Left Align"), self) + leftAlignAct.setCheckable(True) + leftAlignAct.setShortcut(tr("Ctrl+L")) + leftAlignAct.setStatusTip(tr("Left align the selected text")) + leftAlignAct.triggered.connect(leftAlign) + + rightAlignAct = QAction(tr("&Right Align"), self) + rightAlignAct.setCheckable(True) + rightAlignAct.setShortcut(tr("Ctrl+R")) + rightAlignAct.setStatusTip(tr("Right align the selected text")) + rightAlignAct.triggered.connect.(rightAlign) + + justifyAct = QAction(tr("&Justify"), self) + justifyAct.setCheckable(True) + justifyAct.setShortcut(tr("Ctrl+J")) + justifyAct.setStatusTip(tr("Justify the selected text")) + justifyAct.triggered.connect(justify) + + centerAct = QAction(tr("&Center"), self) + centerAct.setCheckable(True) + centerAct.setShortcut(tr("Ctrl+E")) + centerAct.setStatusTip(tr("Center the selected text")) + centerAct.triggered.connect(center) + +//! [6] //! [7] + alignmentGroup = QActionGroup(self) + alignmentGroup.addAction(leftAlignAct) + alignmentGroup.addAction(rightAlignAct) + alignmentGroup.addAction(justifyAct) + alignmentGroup.addAction(centerAct) + leftAlignAct.setChecked(True) +//! [6] + +//! [7] + +//! [8] +def createMenus(self): + +//! [9] //! [10] + fileMenu = menuBar().addMenu(tr("&File")) + fileMenu.addAction(Act) +//! [9] + fileMenu.addAction(openAct) +//! [10] + fileMenu.addAction(saveAct) + fileMenu.addAction(printAct) +//! [11] + fileMenu.addSeparator() +//! [11] + fileMenu.addAction(exitAct) + + editMenu = menuBar().addMenu(tr("&Edit")) + editMenu.addAction(undoAct) + editMenu.addAction(redoAct) + editMenu.addSeparator() + editMenu.addAction(cutAct) + editMenu.addAction(copyAct) + editMenu.addAction(pasteAct) + editMenu.addSeparator() + + helpMenu = menuBar().addMenu(tr("&Help")) + helpMenu.addAction(aboutAct) + helpMenu.addAction(aboutQtAct) +//! [8] + +//! [12] + formatMenu = editMenu.addMenu(tr("&Format")) + formatMenu.addAction(boldAct) + formatMenu.addAction(italicAct) + formatMenu.addSeparator()->setText(tr("Alignment")) + formatMenu.addAction(leftAlignAct) + formatMenu.addAction(rightAlignAct) + formatMenu.addAction(justifyAct) + formatMenu.addAction(centerAct) + formatMenu.addSeparator() + formatMenu.addAction(setLineSpacingAct) + formatMenu.addAction(setParagraphSpacingAct) +//! [12] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py new file mode 100644 index 0000000..41f5158 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/mdi/mainwindow.py @@ -0,0 +1,360 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * + +class QMdiSubWindow(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + + mdiArea = QMdiArea() + mdiArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) + mdiArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) + setCentralWidget(mdiArea) + mdiArea.subWindowActivated[QMdiSubWindow].connect(updateMenus) + windowMapper = QSignalMapper(self) + windowMapper.mapped[QWidget].connect(setActiveSubWindow) + + self.createActions() + self.createMenus() + self.createToolBars() + self.createStatusBar() + self.updateMenus() + self.readSettings() + self.setWindowTitle(tr("MDI")) + self.setUnifiedTitleAndToolBarOnMac(True) + + + def closeEvent(self, event): + mdiArea.closeAllSubWindows() + if self.activeMdiChild(): + event.ignore() + else: + self.writeSettings() + event.accept() + + def File(self): + child = self.createMdiChild() + child.File() + child.show() + + + def open(self): + fileName = QFileDialog.getOpenFileName(self) + if not fileName.isEmpty(): + existing = self.findMdiChild(fileName) + if existing: + mdiArea.setActiveSubWindow(existing) + return + + child = createMdiChild() + if child.loadFile(fileName): + statusBar().showMessage(tr("File loaded"), 2000) + child.show() + else: + child.close() + + def save(self): + if self.activeMdiChild() and self.activeMdiChild().save(): + self.statusBar().showMessage(tr("File saved"), 2000) + + def saveAs(self): + if self.activeMdiChild() and self.activeMdiChild().saveAs(): + self.statusBar().showMessage(tr("File saved"), 2000) + + def cut(self): + if self.activeMdiChild(): + self.activeMdiChild().cut() + + def copy(self): + if self.activeMdiChild(): + activeMdiChild().copy() + + def paste(self): + if self.activeMdiChild(): + activeMdiChild().paste() + + def about(self): + QMessageBox.about(self, tr("About MDI"), + tr("The MDI example demonstrates how to write multiple " + "document interface applications using Qt.")) + + def updateMenus(self): + hasMdiChild = (activeMdiChild() != 0) + self.saveAct.setEnabled(hasMdiChild) + self.saveAsAct.setEnabled(hasMdiChild) + self.pasteAct.setEnabled(hasMdiChild) + self.closeAct.setEnabled(hasMdiChild) + self.closeAllAct.setEnabled(hasMdiChild) + self.tileAct.setEnabled(hasMdiChild) + self.cascadeAct.setEnabled(hasMdiChild) + self.nextAct.setEnabled(hasMdiChild) + self.previousAct.setEnabled(hasMdiChild) + self.separatorAct.setVisible(hasMdiChild) + + hasSelection = (self.activeMdiChild() and + self.activeMdiChild().textCursor().hasSelection()) + self.cutAct.setEnabled(hasSelection) + self.copyAct.setEnabled(hasSelection) + + def updateWindowMenu(self): + self.windowMenu.clear() + self.windowMenu.addAction(closeAct) + self.windowMenu.addAction(closeAllAct) + self.windowMenu.addSeparator() + self.windowMenu.addAction(tileAct) + self.windowMenu.addAction(cascadeAct) + self.windowMenu.addSeparator() + self.windowMenu.addAction(nextAct) + self.windowMenu.addAction(previousAct) + self.windowMenu.addAction(separatorAct) + + windows = mdiArea.subWindowList() + separatorAct.setVisible(not windows.isEmpty()) + + for i in range(0, windows.size()): + child = windows.at(i).widget() + + text = "" + if i < 9: + text = "{} {}".format(i + 1, child.userFriendlyCurrentFile()) + else: + text = "{} {}".format(i + 1, child.userFriendlyCurrentFile()) + + action = windowMenu.addAction(text) + action.setCheckable(True) + action.setChecked(child == activeMdiChild()) + action.triggered.connect(windowMapper.map) + windowMapper.setMapping(action, windows.at(i)) + + createMdiChild = MdiChild() + + child = MdiChild() + mdiArea.addSubWindow(child) + + child.copyAvailable[bool].connect(cutAct.setEnabled) + child.copyAvailable[bool].connect(copyAct.setEnabled) + + return child + + + def createActions(self): + + Act = QAction(QIcon(":/images/new.png"), tr("&New"), self) + Act.setShortcuts(QKeySequence.New) + Act.setStatusTip(tr("Create a new file")) + Act.triggered.connect(self.newFile) + + openAct = QAction(QIcon(":/images/open.png"), tr("&Open..."), self) + openAct.setShortcuts(QKeySequence.Open) + openAct.setStatusTip(tr("Open an existing file")) + openAct.triggered.connect(self.open) + + saveAct = QAction(QIcon(":/images/save.png"), tr("&Save"), self) + saveAct.setShortcuts(QKeySequence.Save) + saveAct.setStatusTip(tr("Save the document to disk")) + saveAct.triggered.connect(self.save) + + saveAsAct = QAction(tr("Save &As..."), self) + saveAsAct.setShortcuts(QKeySequence.SaveAs) + saveAsAct.setStatusTip(tr("Save the document under a name")) + saveAsAct.triggered.connect(self.saveAs) + +//! [0] + exitAct = QAction(tr("E&xit"), self) + exitAct.setShortcut(tr("Ctrl+Q")) + exitAct.setStatusTip(tr("Exit the application")) + exitAct.triggered.connect(qApp.closeAllWindows) +//! [0] + + cutAct = QAction(QIcon(":/images/cut.png"), tr("Cu&t"), self) + cutAct.setShortcuts(QKeySequence.Cut) + cutAct.setStatusTip(tr("Cut the current selection's contents to the " + "clipboard")) + cutAct.triggered.connect(self.cut) + + copyAct = QAction(QIcon(":/images/copy.png"), tr("&Copy"), self) + copyAct.setShortcuts(QKeySequence.Copy) + copyAct.setStatusTip(tr("Copy the current selection's contents to the " + "clipboard")) + copyAct.triggered.connect(self.copy) + + pasteAct = QAction(QIcon(":/images/paste.png"), tr("&Paste"), self) + pasteAct.setShortcuts(QKeySequence.Paste) + pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " + "selection")) + pasteAct.triggered.connect(self.paste) + + closeAct = QAction(tr("Cl&ose"), self) + closeAct.setShortcut(tr("Ctrl+F4")) + closeAct.setStatusTip(tr("Close the active window")) + closeAct.triggered.connect(mdiArea.closeActiveSubWindow) + + closeAllAct = QAction(tr("Close &All"), self) + closeAllAct.setStatusTip(tr("Close all the windows")) + closeAllAct.triggered.connect(mdiArea.closeAllSubWindows) + + tileAct = QAction(tr("&Tile"), self) + tileAct.setStatusTip(tr("Tile the windows")) + tileAct.triggered.connect(mdiArea.tileSubWindows) + + cascadeAct = QAction(tr("&Cascade"), self) + cascadeAct.setStatusTip(tr("Cascade the windows")) + cascadeAct.triggered.connect(mdiArea.cascadeSubWindows) + + nextAct = QAction(tr("Ne&xt"), self) + nextAct.setShortcuts(QKeySequence.NextChild) + nextAct.setStatusTip(tr("Move the focus to the next window")) + nextAct.triggered.connect(mdiArea.activateNextSubWindow) + + previousAct = QAction(tr("Pre&vious"), self) + previousAct.setShortcuts(QKeySequence.PreviousChild) + previousAct.setStatusTip(tr("Move the focus to the previous " + "window")) + previousAct.triggered.connect(mdiArea.activatePreviousSubWindow) + + separatorAct = QAction(self) + separatorAct.setSeparator(True) + + aboutAct = QAction(tr("&About"), self) + aboutAct.setStatusTip(tr("Show the application's About box")) + aboutAct.triggered.connect(self.about) + + aboutQtAct = QAction(tr("About &Qt"), self) + aboutQtAct.setStatusTip(tr("Show the Qt library's About box")) + aboutQtAct.triggered.connect(qApp.aboutQt) + + + def createMenus(self): + + fileMenu = menuBar().addMenu(tr("&File")) + fileMenu.addAction(Act) + fileMenu.addAction(openAct) + fileMenu.addAction(saveAct) + fileMenu.addAction(saveAsAct) + fileMenu.addSeparator() + action = fileMenu.addAction(tr("Switch layout direction")) + action.triggered.connect(self.switchLayoutDirection) + fileMenu.addAction(exitAct) + + editMenu = menuBar().addMenu(tr("&Edit")) + editMenu.addAction(cutAct) + editMenu.addAction(copyAct) + editMenu.addAction(pasteAct) + + windowMenu = menuBar().addMenu(tr("&Window")) + updateWindowMenu() + windowMenu.aboutToShow.connect(self.updateWindowMenu) + + menuBar().addSeparator() + + helpMenu = menuBar().addMenu(tr("&Help")) + helpMenu.addAction(aboutAct) + helpMenu.addAction(aboutQtAct) + + + def createToolBars(self): + fileToolBar = addToolBar(tr("File")) + fileToolBar.addAction(Act) + fileToolBar.addAction(openAct) + fileToolBar.addAction(saveAct) + + editToolBar = addToolBar(tr("Edit")) + editToolBar.addAction(cutAct) + editToolBar.addAction(copyAct) + editToolBar.addAction(pasteAct) + + + def createStatusBar(self): + statusBar().showMessage(tr("Ready")) + + + def readSettings(self): + settings = QSettings("Trolltech", "MDI Example") + QPoint pos = settings.value("pos", QPoint(200, 200)").toPoint() + QSize size = settings.value("size", QSize(400, 400)").toSize() + move(pos) + resize(size) + + def writeSettings(self): + QSettings settings("Trolltech", "MDI Example") + settings.setValue("pos", pos()") + settings.setValue("size", size()") + + + activeMdiChild = MdiChild() + activeSubWindow = mdiArea.activeSubWindow() + if activeSubWindow: + return activeSubWindow.widget() + return 0 + + + def findMdiChild(self, fileName): + + canonicalFilePath = QFileInfo(fileName).canonicalFilePath() + + for window in mdiArea.subWindowList(): + mdiChild = window.widget() + if mdiChild.currentFile() == canonicalFilePath: + return window + return 0 + + + def switchLayoutDirection(self) + if layoutDirection() == Qt.LeftToRight: + qApp.setLayoutDirection(Qt.RightToLeft) + else: + qApp.setLayoutDirection(Qt.LeftToRight) + + + def setActiveSubWindow(self, window): + if not window: + return + mdiArea.setActiveSubWindow(window) diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py new file mode 100644 index 0000000..6505f1f --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/menus/mainwindow.py @@ -0,0 +1,366 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * + +//! [0] +def __init__(self): + Q__init__(self) + + widget = QWidget() + setCentralWidget(widget) +//! [0] + +//! [1] + topFiller = QWidget() + topFiller.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + infoLabel = QLabel(tr("Choose a menu option, or right-click to " + "invoke a context menu")) + infoLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken) + infoLabel.setAlignment(Qt.AlignCenter) + + bottomFiller = QWidget() + bottomFiller.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) + + layout = QVBoxLayout() + layout.setMargin(5) + layout.addWidget(topFiller) + layout.addWidget(infoLabel) + layout.addWidget(bottomFiller) + widget.setLayout(layout) +//! [1] + +//! [2] + createActions() + createMenus() + + message = tr("A context menu is available by right-clicking") + statusBar().showMessage(message) + + setWindowTitle(tr("Menus")) + setMinimumSize(160, 160) + resize(480, 320) + +//! [2] + +//! [3] +def contextMenuEvent(self, event): + menu = QMenu(self) + menu.addAction(cutAct) + menu.addAction(copyAct) + menu.addAction(pasteAct) + menu.exec_(event.globalPos()") + +//! [3] + +def File(self): + infoLabel.setText(tr("Invoked File|New")) + + +def open(self): + infoLabel.setText(tr("Invoked File|Open")) + + +def save(self): + infoLabel.setText(tr("Invoked File|Save")) + +def print_(self): + infoLabel.setText(tr("Invoked File|Print")) + +def undo(self): + infoLabel.setText(tr("Invoked Edit|Undo")) + +def redo(self): + infoLabel.setText(tr("Invoked Edit|Redo")) + +def cut(self): + + infoLabel.setText(tr("Invoked Edit|Cut")) + + +def copy(self): + + infoLabel.setText(tr("Invoked Edit|Copy")) + + +def paste(self): + + infoLabel.setText(tr("Invoked Edit|Paste")) + + +def bold(self): + + infoLabel.setText(tr("Invoked Edit|Format|Bold")) + + +def italic(self): + + infoLabel.setText(tr("Invoked Edit|Format|Italic")) + + +def leftAlign(self): + + infoLabel.setText(tr("Invoked Edit|Format|Left Align")) + + +def rightAlign(self): + + infoLabel.setText(tr("Invoked Edit|Format|Right Align")) + + +def justify(self): + + infoLabel.setText(tr("Invoked Edit|Format|Justify")) + + +def center(self): + + infoLabel.setText(tr("Invoked Edit|Format|Center")) + + +def setLineSpacing(self): + + infoLabel.setText(tr("Invoked Edit|Format|Set Line Spacing")) + + +def setParagraphSpacing(self): + + infoLabel.setText(tr("Invoked Edit|Format|Set Paragraph Spacing")) + + +def about(self): + + infoLabel.setText(tr("Invoked Help|About")) + QMessageBox.about(self, tr("About Menu"), + tr("The Menu example shows how to create " + "menu-bar menus and context menus.")) + + +def aboutQt(self): + + infoLabel.setText(tr("Invoked Help|About Qt")) + + +//! [4] +def createActions(self): + +//! [5] + Act = new QAction(tr("&New"), self) + Act.setShortcuts(QKeySequence.New) + Act.setStatusTip(tr("Create a new file")) + Act.triggered.connect(newFile) +//! [4] + + openAct = QAction(tr("&Open..."), self) + openAct.setShortcuts(QKeySequence.Open) + openAct.setStatusTip(tr("Open an existing file")) + openAct.triggered.connect(open) +//! [5] + + saveAct = QAction(tr("&Save"), self) + saveAct.setShortcuts(QKeySequence.Save) + saveAct.setStatusTip(tr("Save the document to disk")) + saveAct.triggered.connect(save) + + printAct = QAction(tr("&Print..."), self) + printAct.setShortcuts(QKeySequence.Print) + printAct.setStatusTip(tr("Print the document")) + printAct.triggered.connect(print_) + + exitAct = QAction(tr("E&xit"), self) + exitAct.setShortcut(tr("Ctrl+Q")) + exitAct.setStatusTip(tr("Exit the application")) + exitAct.triggered.connect(close) + + undoAct = QAction(tr("&Undo"), self) + undoAct.setShortcuts(QKeySequence.Undo) + undoAct.setStatusTip(tr("Undo the last operation")) + undoAct.triggered.connect(undo) + + redoAct = QAction(tr("&Redo"), self) + redoAct.setShortcuts(QKeySequence.Redo) + redoAct.setStatusTip(tr("Redo the last operation")) + redoAct.triggered.connect(redo) + + cutAct = QAction(tr("Cu&t"), self) + cutAct.setShortcuts(QKeySequence.Cut) + cutAct.setStatusTip(tr("Cut the current selection's contents to the " + "clipboard")) + cutAct.triggered.connect(cut) + + copyAct = QAction(tr("&Copy"), self) + copyAct.setShortcut(tr("Ctrl+C")) + copyAct.setStatusTip(tr("Copy the current selection's contents to the " + "clipboard")) + copyAct.triggered.connect(copy) + + pasteAct = QAction(tr("&Paste"), self) + pasteAct.setShortcuts(QKeySequence.Paste) + pasteAct.setStatusTip(tr("Paste the clipboard's contents into the current " + "selection")) + pasteAct.triggered.connect(paste) + + boldAct = QAction(tr("&Bold"), self) + boldAct.setCheckable(True) + boldAct.setShortcut(tr("Ctrl+B")) + boldAct.setStatusTip(tr("Make the text bold")) + boldAct.triggered.connect(bold) + + QFont boldFont = boldAct.font() + boldFont.setBold(True) + boldAct.setFont(boldFont) + + italicAct = QAction(tr("&Italic"), self) + italicAct.setCheckable(True) + italicAct.setShortcut(tr("Ctrl+I")) + italicAct.setStatusTip(tr("Make the text italic")) + italicAct.triggered.connect(italic) + + QFont italicFont = italicAct.font() + italicFont.setItalic(True) + italicAct.setFont(italicFont) + + setLineSpacingAct = QAction(tr("Set &Line Spacing..."), self) + setLineSpacingAct.setStatusTip(tr("Change the gap between the lines of a " + "paragraph")) + setLineSpacingAct.triggered.connect(setLineSpacing) + + setParagraphSpacingAct = QAction(tr("Set &Paragraph Spacing..."), self) + setLineSpacingAct.setStatusTip(tr("Change the gap between paragraphs")) + setParagraphSpacingAct.triggered.connect(setParagraphSpacing) + + aboutAct = QAction(tr("&About"), self) + aboutAct.setStatusTip(tr("Show the application's About box")) + aboutAct.triggered.connect(about) + + aboutQtAct = QAction(tr("About &Qt"), self) + aboutQtAct.setStatusTip(tr("Show the Qt library's About box")) + aboutQtAct.triggered.connect(qApp.aboutQt) + aboutQtAct.triggered.connect(aboutQt) + + leftAlignAct = QAction(tr("&Left Align"), self) + leftAlignAct.setCheckable(True) + leftAlignAct.setShortcut(tr("Ctrl+L")) + leftAlignAct.setStatusTip(tr("Left align the selected text")) + leftAlignAct.triggered.connect(leftAlign) + + rightAlignAct = QAction(tr("&Right Align"), self) + rightAlignAct.setCheckable(True) + rightAlignAct.setShortcut(tr("Ctrl+R")) + rightAlignAct.setStatusTip(tr("Right align the selected text")) + rightAlignAct.triggered.connect(rightAlign) + + justifyAct = QAction(tr("&Justify"), self) + justifyAct.setCheckable(True) + justifyAct.setShortcut(tr("Ctrl+J")) + justifyAct.setStatusTip(tr("Justify the selected text")) + justifyAct.triggered.connect(justify) + + centerAct = QAction(tr("&Center"), self) + centerAct.setCheckable(True) + centerAct.setShortcut(tr("Ctrl+E")) + centerAct.setStatusTip(tr("Center the selected text")) + centerAct.triggered.connect(center) + +//! [6] //! [7] + alignmentGroup = QActionGroup(self) + alignmentGroup.addAction(leftAlignAct) + alignmentGroup.addAction(rightAlignAct) + alignmentGroup.addAction(justifyAct) + alignmentGroup.addAction(centerAct) + leftAlignAct.setChecked(True) +//! [6] + +//! [7] + +//! [8] +def createMenus(self): + +//! [9] //! [10] + fileMenu = menuBar().addMenu(tr("&File")) + fileMenu.addAction(Act) +//! [9] + fileMenu.addAction(openAct) +//! [10] + fileMenu.addAction(saveAct) + fileMenu.addAction(printAct) +//! [11] + fileMenu.addSeparator() +//! [11] + fileMenu.addAction(exitAct) + + editMenu = menuBar().addMenu(tr("&Edit")) + editMenu.addAction(undoAct) + editMenu.addAction(redoAct) + editMenu.addSeparator() + editMenu.addAction(cutAct) + editMenu.addAction(copyAct) + editMenu.addAction(pasteAct) + editMenu.addSeparator() + + helpMenu = menuBar().addMenu(tr("&Help")) + helpMenu.addAction(aboutAct) + helpMenu.addAction(aboutQtAct) +//! [8] + +//! [12] + formatMenu = editMenu.addMenu(tr("&Format")) + formatMenu.addAction(boldAct) + formatMenu.addAction(italicAct) + formatMenu.addSeparator()->setText(tr("Alignment")) + formatMenu.addAction(leftAlignAct) + formatMenu.addAction(rightAlignAct) + formatMenu.addAction(justifyAct) + formatMenu.addAction(centerAct) + formatMenu.addSeparator() + formatMenu.addAction(setLineSpacingAct) + formatMenu.addAction(setParagraphSpacingAct) +//! [12] diff --git a/sources/pyside2/doc/codesnippets/examples/mainwindows/sdi/mainwindow.cpp b/sources/pyside2/doc/codesnippets/examples/mainwindows/sdi/mainwindow.cpp new file mode 100644 index 0000000..de169b2 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/mainwindows/sdi/mainwindow.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [implicit tr context] +def createMenus(self): + fileMenu = menuBar().addMenu("&File") +//! [implicit tr context] + +//! [0] + fileToolBar = addToolBar("File") + fileToolBar.addAction(newAct) + fileToolBar.addAction(openAct) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/examples/quick/plugins/plugins.qml b/sources/pyside2/doc/codesnippets/examples/quick/plugins/plugins.qml new file mode 100644 index 0000000..f1b5c23 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/quick/plugins/plugins.qml @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +renderer = QSvgRenderer(QLatin1String("SvgCardDeck.svg")) +black = QGraphicsSvgItem() +red = QGraphicsSvgItem() + +black.setSharedRenderer(renderer) +black.setElementId(QLatin1String("black_joker")) + +red.setSharedRenderer(renderer) +red.setElementId(QLatin1String("red_joker")) +//! [0] diff --git a/sources/pyside2/doc/codesnippets/examples/relationaltablemodel/relationaltablemodel.cpp b/sources/pyside2/doc/codesnippets/examples/relationaltablemodel/relationaltablemodel.cpp new file mode 100644 index 0000000..48803f0 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/relationaltablemodel/relationaltablemodel.cpp @@ -0,0 +1,120 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * +from PySide2.QtSql import * + +def initializeModel(model): +//! [0] + model.setTable("employee") +//! [0] + + model.setEditStrategy(QSqlTableModel.OnManualSubmit) +//! [1] + model.setRelation(2, QSqlRelation("city", "id", "name")) +//! [1] //! [2] + model.setRelation(3, QSqlRelation("country", "id", "name")) +//! [2] + +//! [3] + model.setHeaderData(0, Qt.Horizontal, QObject::tr("ID")) + model.setHeaderData(1, Qt.Horizontal, QObject::tr("Name")) + model.setHeaderData(2, Qt.Horizontal, QObject::tr("City")) + model.setHeaderData(3, Qt.Horizontal, QObject::tr("Country")) +//! [3] + + model.select() + + +def createView(title, model): +//! [4] + view = QTableView() + view.setModel(model) + view.setItemDelegate(QSqlRelationalDelegate(view)) +//! [4] + view.setWindowTitle(title) + return view + + +def createRelationalTables(): + query = QSqlQuery() + query.exec_("create table employee(id int primary key, name varchar(20), city int, country int)") + query.exec_("insert into employee values(1, 'Espen', 5000, 47)") + query.exec_("insert into employee values(2, 'Harald', 80000, 49)") + query.exec_("insert into employee values(3, 'Sam', 100, 1)") + + query.exec_("create table city(id int, name varchar(20))") + query.exec_("insert into city values(100, 'San Jose')") + query.exec_("insert into city values(5000, 'Oslo')") + query.exec_("insert into city values(80000, 'Munich')") + + query.exec_("create table country(id int, name varchar(20))") + query.exec_("insert into country values(1, 'USA')") + query.exec_("insert into country values(47, 'Norway')") + query.exec_("insert into country values(49, 'Germany')") + + +def main(): + + app = QApplication([]) + if !createConnection(): + return 1 + + createRelationalTables() + + model = QSqlRelationalTableModel() + + initializeModel(model) + + view = createView(QObject.tr("Relational Table Model"), model) + view.show() + + return app.exec_() + diff --git a/sources/pyside2/doc/codesnippets/examples/richtext/textobject/svgtextobject.h b/sources/pyside2/doc/codesnippets/examples/richtext/textobject/svgtextobject.h new file mode 100644 index 0000000..d0b9abf --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/richtext/textobject/svgtextobject.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SVGTEXTOBJECT_H +#define SVGTEXTOBJECT_H + +#include + +QT_BEGIN_NAMESPACE +class QTextDocument; +class QTextFormat; +class QPainter; +class QRectF; +class QSizeF; +QT_END_NAMESPACE + +//![0] //![1] +class SvgTextObject(QObject, QTextObjectInterface): + def __init__(self,...): + super(SvgTextObject, self).__init__(...) + ... +//![1] + +public: + QSizeF intrinsicSize(QTextDocument *doc, int posInDocument, + const QTextFormat &format); + void drawObject(QPainter *painter, const QRectF &rect, QTextDocument *doc, + int posInDocument, const QTextFormat &format); +}; +//![0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/groupbox/window.cpp b/sources/pyside2/doc/codesnippets/examples/widgets/groupbox/window.cpp new file mode 100644 index 0000000..a24e353 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/widgets/groupbox/window.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +def __init__(self, parent = None): + QWidget.__init__(self, parent) + + grid = QGridLayout() + grid.addWidget(createFirstExclusiveGroup(), 0, 0) + grid.addWidget(createSecondExclusiveGroup(), 1, 0) + grid.addWidget(createNonExclusiveGroup(), 0, 1) + grid.addWidget(createPushButtonGroup(), 1, 1) + setLayout(grid) + + setWindowTitle("Group Boxes") + resize(480, 320) + +//! [0] + +//! [1] +def createFirstExclusiveGroup(self): +//! [2] + groupBox = QGroupBox("Exclusive Radio Buttons") + + radio1 = QRadioButton("&Radio button 1") + radio2 = QRadioButton("R&adio button 2") + radio3 = QRadioButton("Ra&dio button 3") + + radio1.setChecked(True) +//! [1] //! [3] + + vbox = QVBoxLayout() + vbox.addWidget(radio1) + vbox.addWidget(radio2) + vbox.addWidget(radio3) + vbox.addStretch(1) + groupBox.setLayout(vbox) +//! [2] + return groupBox +//! [3] + +//! [4] +def createSecondExclusiveGroup(self): + groupBox = QGroupBox("E&xclusive Radio Buttons") + groupBox.setCheckable(True) + groupBox.setChecked(False) +//! [4] + +//! [5] + radio1 = QRadioButton("Rad&io button 1") + radio2 = QRadioButton("Radi&o button 2") + radio3 = QRadioButton("Radio &button 3") + radio1.setChecked(True) + checkBox = QCheckBox("Ind&ependent checkbox") + checkBox.setChecked(True) +//! [5] + +//! [6] + vbox = QVBoxLayout() + vbox.addWidget(radio1) + vbox.addWidget(radio2) + vbox.addWidget(radio3) + vbox.addWidget(checkBox) + vbox.addStretch(1) + groupBox.setLayout(vbox) + + return groupBox +//! [6] + +//! [7] +def createNonExclusiveGroup(self): + groupBox = QGroupBox("Non-Exclusive Checkboxes") + groupBox.setFlat(True) +//! [7] + +//! [8] + checkBox1 = QCheckBox("&Checkbox 1") + checkBox2 = QCheckBox("C&heckbox 2") + checkBox2.setChecked(True) + tristateBox = QCheckBox("Tri-&state button") + tristateBox.setTristate(True) +//! [8] + tristateBox.setCheckState(Qt.PartiallyChecked) + +//! [9] + vbox = QVBoxLayout() + vbox.addWidget(checkBox1) + vbox.addWidget(checkBox2) + vbox.addWidget(tristateBox) + vbox.addStretch(1) + groupBox.setLayout(vbox) + + return groupBox +//! [9] + +//! [10] +def createPushButtonGroup(self): + groupBox = QGroupBox("&Push Buttons") + groupBox.setCheckable(True) + groupBox.setChecked(True) +//! [10] + +//! [11] + pushButton = QPushButton("&Normal Button") + toggleButton = QPushButton("&Toggle Button") + toggleButton.setCheckable(True) + toggleButton.setChecked(True) + flatButton = QPushButton("&Flat Button") + flatButton.setFlat(True) +//! [11] + +//! [12] + popupButton = QPushButton("Pop&up Button") + menu = QMenu(self) + menu.addAction("&First Item") + menu.addAction("&Second Item") + menu.addAction("&Third Item") + menu.addAction("F&ourth Item") + popupButton.setMenu(menu) +//! [12] + + newAction = menu.addAction("Submenu") + QMenu *subMenu = QMenu("Popup Submenu") + subMenu.addAction("Item 1") + subMenu.addAction("Item 2") + subMenu.addAction("Item 3") + newAction.setMenu(subMenu) + +//! [13] + vbox = QVBoxLayout() + vbox.addWidget(pushButton) + vbox.addWidget(toggleButton) + vbox.addWidget(flatButton) + vbox.addWidget(popupButton) + vbox.addStretch(1) + groupBox.setLayout(vbox) + + return groupBox +} +//! [13] diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp b/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp new file mode 100644 index 0000000..a289c5c --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/widgets/icons/iconsizespinbox.cpp @@ -0,0 +1,72 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + + +//! [0] +def __init__(self, parent): + QSpinBox.__init__(self, parent) + +//! [0] + +//! [1] +def valueFromText(self, text): + regExp = QRegExp(tr("(\\d+)(\\s*[xx]\\s*\\d+)?")) + + if regExp.exactMatch(text): + return regExp.cap(1).toInt() + else: + return 0 +//! [1] + +//! [2] +def textFromValue(self, value): + return self.tr("%1 x %1").arg(value) + +//! [2] diff --git a/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py new file mode 100644 index 0000000..40fe28b --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/widgets/spinboxes/window.py @@ -0,0 +1,247 @@ +############################################################################ +## +## Copyright (C) 2016 The Qt Company Ltd. +## Contact: https://www.qt.io/licensing/ +## +## This file is part of the examples of Qt for Python. +## +## $QT_BEGIN_LICENSE:BSD$ +## Commercial License Usage +## Licensees holding valid commercial Qt licenses may use this file in +## accordance with the commercial license agreement provided with the +## Software or, alternatively, in accordance with the terms contained in +## a written agreement between you and The Qt Company. For licensing terms +## and conditions see https://www.qt.io/terms-conditions. For further +## information use the contact form at https://www.qt.io/contact-us. +## +## BSD License Usage +## Alternatively, you may use this file under the terms of the BSD license +## as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################ + +from PySide2.QtGui import * + +//! [0] +def __init__(self): + createSpinBoxes() + createDateTimeEdits() + createDoubleSpinBoxes() + + layout = QHBoxLayout() + layout.addWidget(spinBoxesGroup) + layout.addWidget(editsGroup) + layout.addWidget(doubleSpinBoxesGroup) + setLayout(layout) + + setWindowTitle(tr("Spin Boxes")) +//! [0] + +//! [1] +def createSpinBoxes(self): + spinBoxesGroup = QGroupBox(tr("Spinboxes")) + + integerLabel = QLabel(tr("Enter a value between " + "%1 and %2:").arg(-20).arg(20)) + integerSpinBox = QSpinBox() + integerSpinBox.setRange(-20, 20) + integerSpinBox.setSingleStep(1) + integerSpinBox.setValue(0) +//! [1] + +//! [2] + zoomLabel = QLabel(tr("Enter a zoom value between " + "%1 and %2:").arg(0).arg(1000)) +//! [3] + zoomSpinBox = QSpinBox() + zoomSpinBox.setRange(0, 1000) + zoomSpinBox.setSingleStep(10) + zoomSpinBox.setSuffix("%") + zoomSpinBox.setSpecialValueText(tr("Automatic")) + zoomSpinBox.setValue(100) +//! [2] //! [3] + +//! [4] + priceLabel = QLabel(tr("Enter a price between " + "%1 and %2:").arg(0).arg(999)) + priceSpinBox = QSpinBox() + priceSpinBox.setRange(0, 999) + priceSpinBox.setSingleStep(1) + priceSpinBox.setPrefix("$") + priceSpinBox.setValue(99) +//! [4] //! [5] + + spinBoxLayout = QVBoxLayout() + spinBoxLayout.addWidget(integerLabel) + spinBoxLayout.addWidget(integerSpinBox) + spinBoxLayout.addWidget(zoomLabel) + spinBoxLayout.addWidget(zoomSpinBox) + spinBoxLayout.addWidget(priceLabel) + spinBoxLayout.addWidget(priceSpinBox) + spinBoxesGroup.setLayout(spinBoxLayout) + +//! [5] + +//! [6] +def createDateTimeEdits(self): + editsGroup = QGroupBox(tr("Date and time spin boxes")) + + dateLabel = QLabel() + dateEdit = QDateEdit(QDate.currentDate()) + dateEdit.setDateRange(QDate(2005, 1, 1), QDate(2010, 12, 31)) + dateLabel.setText(tr("Appointment date (between %0 and %1):") + .arg(dateEdit.minimumDate().toString(Qt.ISODate)) + .arg(dateEdit.maximumDate().toString(Qt.ISODate))) +//! [6] + +//! [7] + timeLabel = QLabel() + timeEdit = QTimeEdit(QTime.currentTime()) + timeEdit.setTimeRange(QTime(9, 0, 0, 0), QTime(16, 30, 0, 0)) + timeLabel.setText(tr("Appointment time (between %0 and %1):") + .arg(timeEdit.minimumTime().toString(Qt.ISODate)) + .arg(timeEdit.maximumTime().toString(Qt.ISODate))) +//! [7] + +//! [8] + meetingLabel = QLabel() + meetingEdit = QDateTimeEdit(QDateTime.currentDateTime()) +//! [8] + +//! [9] + formatLabel = QLabel(tr("Format string for the meeting date " + "and time:")) + formatComboBox = QComboBox() + formatComboBox.addItem("yyyy-MM-dd hh:mm:ss (zzz 'ms')") + formatComboBox.addItem("hh:mm:ss MM/dd/yyyy") + formatComboBox.addItem("hh:mm:ss dd/MM/yyyy") + formatComboBox.addItem("hh:mm:ss") + formatComboBox.addItem("hh:mm ap") +//! [9] //! [10] + + formatComboBox.activated[str].connect(setFormatString) +//! [10] + + setFormatString(formatComboBox.currentText()) + +//! [11] + editsLayout = QVBoxLayout() + editsLayout.addWidget(dateLabel) + editsLayout.addWidget(dateEdit) + editsLayout.addWidget(timeLabel) + editsLayout.addWidget(timeEdit) + editsLayout.addWidget(meetingLabel) + editsLayout.addWidget(meetingEdit) + editsLayout.addWidget(formatLabel) + editsLayout.addWidget(formatComboBox) + editsGroup.setLayout(editsLayout) +//! [11] + +//! [12] +def setFormatString(self, formatString): + meetingEdit.setDisplayFormat(formatString) +//! [12] //! [13] + if meetingEdit.displayedSections() & QDateTimeEdit.DateSections_Mask: + meetingEdit.setDateRange(QDate(2004, 11, 1), QDate(2005, 11, 30)) + meetingLabel.setText(tr("Meeting date (between %0 and %1):") + .arg(meetingEdit.minimumDate().toString(Qt.ISODate)) + .arg(meetingEdit.maximumDate().toString(Qt.ISODate))) + else: + meetingEdit.setTimeRange(QTime(0, 7, 20, 0), QTime(21, 0, 0, 0)) + meetingLabel.setText(tr("Meeting time (between %0 and %1):") + .arg(meetingEdit.minimumTime().toString(Qt.ISODate)) + .arg(meetingEdit.maximumTime().toString(Qt.ISODate))) +//! [13] + +//! [14] +def createDoubleSpinBoxes(): + doubleSpinBoxesGroup = QGroupBox(tr("Double precision spinboxes")) + + precisionLabel = QLabel(tr("Number of decimal places " + "to show:")) + precisionSpinBox = QSpinBox() + precisionSpinBox.setRange(0, 100) + precisionSpinBox.setValue(2) +//! [14] + +//! [15] + doubleLabel = QLabel(tr("Enter a value between " + "%1 and %2:").arg(-20).arg(20)) + doubleSpinBox = QDoubleSpinBox () + doubleSpinBox.setRange(-20.0, 20.0) + doubleSpinBox.setSingleStep(1.0) + doubleSpinBox.setValue(0.0) +//! [15] + +//! [16] + scaleLabel = QLabel(tr("Enter a scale factor between " + "%1 and %2:").arg(0).arg(1000.0)) + scaleSpinBox = QDoubleSpinBox() + scaleSpinBox.setRange(0.0, 1000.0) + scaleSpinBox.setSingleStep(10.0) + scaleSpinBox.setSuffix("%") + scaleSpinBox.setSpecialValueText(tr("No scaling")) + scaleSpinBox.setValue(100.0) +//! [16] + +//! [17] + priceLabel = QLabel(tr("Enter a price between " + "%1 and %2:").arg(0).arg(1000)) + priceSpinBox = QDoubleSpinBox() + priceSpinBox.setRange(0.0, 1000.0) + priceSpinBox.setSingleStep(1.0) + priceSpinBox.setPrefix("$") + priceSpinBox.setValue(99.99) + + precisionSpinBox.valueChanged[int].connect(changePrecision) +//! [17] + +//! [18] + spinBoxLayout = QVBoxLayout() + spinBoxLayout.addWidget(precisionLabel) + spinBoxLayout.addWidget(precisionSpinBox) + spinBoxLayout.addWidget(doubleLabel) + spinBoxLayout.addWidget(doubleSpinBox) + spinBoxLayout.addWidget(scaleLabel) + spinBoxLayout.addWidget(scaleSpinBox) + spinBoxLayout.addWidget(priceLabel) + spinBoxLayout.addWidget(priceSpinBox) + doubleSpinBoxesGroup.setLayout(spinBoxLayout) +} +//! [18] + +//! [19] +def changePrecision(self, int) + doubleSpinBox.setDecimals(decimals) + scaleSpinBox.setDecimals(decimals) + priceSpinBox.setDecimals(decimals) + +//! [19] diff --git a/sources/pyside2/doc/codesnippets/examples/xml/streambookmarks/xbelreader.h b/sources/pyside2/doc/codesnippets/examples/xml/streambookmarks/xbelreader.h new file mode 100644 index 0000000..cb72073 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/examples/xml/streambookmarks/xbelreader.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef XBELREADER_H +#define XBELREADER_H + +#include +#include + +QT_BEGIN_NAMESPACE +class QTreeWidget; +class QTreeWidgetItem; +QT_END_NAMESPACE + +//! [0] +class XbelReader (QXmlStreamReader): +//! [1] + def __init__(self, treeWidget): + ... +//! [1] + + def read(self, device); + ... + +//! [2] + def readUnknownElement(self): + ... + def readXBEL(self): + ... + def readTitle(self, item): + ... + def readSeparator(self, item): + ... + def readFolder(self, item): + ... + def readBookmark(self, item): + ... + def createChildItem(self, item): + ... +//! [2] +//! [0] + +#endif diff --git a/sources/pyside2/doc/codesnippets/snippets/customstyle/main.cpp b/sources/pyside2/doc/codesnippets/snippets/customstyle/main.cpp new file mode 100644 index 0000000..877c63a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/snippets/customstyle/main.cpp @@ -0,0 +1,61 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [using a custom style] +import sys +from PySide2.QtGui import * + +QApplication.setStyle(CustomStyle()) +app = QApplication(sys.argv) +spinBox = QSpinBox() +spinBox.show() +sys.exit(app.exec_()) + +//! [using a custom style] diff --git a/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp b/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp new file mode 100644 index 0000000..79dc151 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebinspector_snippet.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +def wrapInFunction(): +//! [0] + # ... + page = QWebPage() + # ... + + inspector = QWebInspector() + inspector.setPage(page) +//! [0] + diff --git a/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebview_snippet.cpp b/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebview_snippet.cpp new file mode 100644 index 0000000..268f434 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/webkitsnippets/qtwebkit_qwebview_snippet.cpp @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +def wrapInFunction(): +//! [0] + view.page().history() +//! [0] + + +//! [1] + view.page().settings() +//! [1] + + +//! [2] + view.triggerAction(QWebPage.Copy) +//! [2] + + +//! [3] + view.page().triggerPageAction(QWebPage.Stop) +//! [3] + + +//! [4] + view.page().triggerPageAction(QWebPage.GoBack) +//! [4] + + +//! [5] + view.page().triggerPageAction(QWebPage.GoForward) +//! [5] + diff --git a/sources/pyside2/doc/codesnippets/webkitsnippets/simple/main.cpp b/sources/pyside2/doc/codesnippets/webkitsnippets/simple/main.cpp new file mode 100644 index 0000000..1382cd4 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/webkitsnippets/simple/main.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +from PySide2.QtCore import * +from PySide2.QtGui import * +from PySide2.QtWebKit import * +import sys + +app = QApplication(sys.argv) +parent = None +//! [Using QWebView] +view = QWebView(parent) +view.load(QUrl("http://qt-project.org/")) +view.show() +//! [Using QWebView] +sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/codesnippets/webkitsnippets/webelement/main.cpp b/sources/pyside2/doc/codesnippets/webkitsnippets/webelement/main.cpp new file mode 100644 index 0000000..67e101a --- /dev/null +++ b/sources/pyside2/doc/codesnippets/webkitsnippets/webelement/main.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +def traverse(): +//! [Traversing with QWebElement] + frame.setHtml("

First Paragraph

Second Paragraph

") + doc = frame.documentElement() + body = doc.firstChild() + firstParagraph = body.firstChild() + secondParagraph = firstParagraph.nextSibling() +//! [Traversing with QWebElement] + +def findButtonAndClick(): + frame.setHtml("
" \ + "" \ + "" \ + "
") + +//! [Calling a DOM element method] + + document = frame.documentElement() + # Assume that the document has the following structure: + # + #
+ # + # + #
+ + button = document.findFirst("input[type=submit]") + button.evaluateJavaScript("click()") + +//! [Calling a DOM element method] + +def autocomplete1(): + document = frame.documentElement() +//! [autocomplete1] + firstTextInput = document.findFirst("input[type=text]") + storedText = firstTextInput.attribute("value") +//! [autocomplete1] + +def autocomplete2(): + document = frame.documentElement() + storedText = "text" + +//! [autocomplete2] + firstTextInput = document.findFirst("input[type=text]") + textInput.setAttribute("value", storedText) +//! [autocomplete2] + +def findAll(): +//! [FindAll] + document = frame.documentElement() + # Assume the document has the following structure: + # + #

+ # Intro + # Snippets + #

+ #

+ # Content + # Here + #

+ +//! [FindAll intro] + allSpans = document.findAll("span") + introSpans = document.findAll("p.intro span") +//! [FindAll intro] //! [FindAll] diff --git a/sources/pyside2/doc/codesnippets/webkitsnippets/webpage/main.cpp b/sources/pyside2/doc/codesnippets/webkitsnippets/webpage/main.cpp new file mode 100644 index 0000000..b64a4f3 --- /dev/null +++ b/sources/pyside2/doc/codesnippets/webkitsnippets/webpage/main.cpp @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//! [0] +class Thumbnailer (QObject): + def __init__(self, url): +//! [1] + QObject.__init__(self) + self.page = QWebPage() + self.page.mainFrame().load(url) + page.loadFinished[bool].connect(self.render) +//! [1] + + finished = Signal() + +//! [2] + def render(self): + self.page.setViewportSize(self.page.mainFrame().contentsSize()) + image = QImage(self.page.viewportSize(), QImage.Format_ARGB32) + painter = QPainter(image) + + self.page.mainFrame().render(painter) + painter.end() + + thumbnail = image.scaled(400, 400) + thumbnail.save("thumbnail.png") + + self.finished.emit() +//! [2] +//! [0] + +app = QApplication(sys.argv) + +thumbnail = Thumbnailer(QUrl("http://qt-project.org")) +thumbnail.finished.connect(app.quit) +sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/conf.py.in b/sources/pyside2/doc/conf.py.in new file mode 100644 index 0000000..ae1bc64 --- /dev/null +++ b/sources/pyside2/doc/conf.py.in @@ -0,0 +1,190 @@ +# -*- coding: utf-8 -*- +# +# PySide documentation build configuration file, created by +# sphinx-quickstart on Wed Apr 22 15:04:20 2009. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@') +sys.path.append('@pyside_BINARY_DIR@') +if @HAS_WEBENGINE_WIDGETS@: + sys.path.append('@CMAKE_CURRENT_SOURCE_DIR@/../../../examples/webenginewidgets/tabbedbrowser') + +# -- General configuration ----------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = ['sphinx.ext.todo', 'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude'] +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.ifconfig', +'sphinx.ext.coverage', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', +'sphinx.ext.graphviz', 'inheritance_diagram', 'pysideinclude', +'sphinx.ext.viewcode'] + +output_format='@DOC_OUTPUT_FORMAT@' + +def setup(app): + app.add_config_value('output_format','qthelp','env') + +rst_epilog = """ +.. |project| replace:: Qt for Python +.. |pymodname| replace:: PySide2 +""" + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'PySide' +copyright = u'© 2018 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the
GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.' +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '@BINDING_API_VERSION@' +# The full version, including alpha/beta/rc tags. +release = '@BINDING_API_VERSION_FULL@' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_patterns = ['_build', 'extras'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'pysidedocs' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = { +#} + +# Add any paths that contain custom themes here, relative to this directory. +html_theme_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_themes'] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +html_title = u'Qt for Python' + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['@CMAKE_CURRENT_SOURCE_DIR@/_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = { '' : ''} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = { 'index' : 'index.html'} + +# If false, no module index is generated. +#html_use_modindex = True + +# If false, no index is generated. +html_use_index = False + +# If true, the index is split into individual pages for each letter. +html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +#htmlhelp_basename = 'PySideDoc' + +# Link to the shiboken2 sphinx project to enable linking +# between the two projects. +intersphinx_mapping = {'shiboken2': ('shiboken2','@SHIBOKEN_INTERSPHINX_FILE@')} + +add_module_names = False + +# Skip some warnings when building the documentation with +# 'build_rst_docs' due to the lack of qdoc generated files, in charge +# of sphinx modules (autodoc) and references. +if @SKIP_SPHINX_WARNINGS@: + suppress_warnings = ["autodoc", "autodoc.import_object", "ref.ref"] + +# -- Options for qthelp output --------------------------------------------------- +qthelp_theme = 'pysidedocs_qthelp' + diff --git a/sources/pyside2/doc/considerations.rst b/sources/pyside2/doc/considerations.rst new file mode 100644 index 0000000..b5eae7d --- /dev/null +++ b/sources/pyside2/doc/considerations.rst @@ -0,0 +1,149 @@ +.. _pysideapi2: + +|project| Considerations +========================= + +API Changes +----------- + +One of the goals of |pymodname| is to be API compatible with PyQt5, +with certain exceptions. + +The latest considerations and known issues will be also reported +in the `wiki `_. + +__hash__() function return value +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The hash value returned for the classes :class:`PySide2.QtCore.QDate`, +:class:`PySide2.QtCore.QDateTime`, :class:`PySide2.QtCore.QTime`, :class:`PySide2.QtCore.QUrl` +will be based on their string representations, thus objects with the same value will produce the +same hash. + + +QString +~~~~~~~ + +Methods and functions that change the contents of a QString argument were modified to receive an +immutable Python Unicode (or str) and return another Python Unicode/str as the modified string. + +The following methods had their return types modified this way: + +**Classes:** QAbstractSpinBox, QDateTimeEdit, QDoubleSpinBox, QSpinBox, QValidator + +* ``fixup(string): string`` +* ``validate(string, int): [QValidator.State, string, int]`` + +**Classes:** QDoubleValidator, QIntValidator, QRegExpValidator + +* ``validate(string, int): [QValidator.State, string, int]`` + +**Class:** QClipboard + +* ``text(string, QClipboard.Mode mode=QClipboard.Clipboard): [string, string]`` + +**Class:** QFileDialog + +Instead of ``getOpenFileNameAndFilter()``, ``getOpenFileNamesAndFilter()`` and +``getSaveFileNameAndFilter()`` like PyQt does, PySide has modified the original methods to return +a tuple. + +* ``getOpenFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]`` +* ``getOpenFileNames(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [list(string), filter]`` +* ``getSaveFileName(QWidget parent=None, str caption=None, str dir=None, str filter=None, QFileDialog.Options options=0): [string, filter]`` + +**Class:** QWebPage + +* ``javaScriptPrompt(QWebFrame, string, string): [bool, string]`` + +**Classes:** QFontMetrics and QFontMetricsF + +They had two new methods added. Both take a string of one character and convert to a QChar +(to call the C++ counterpart): + +* ``widthChar(string)`` +* ``boundingRectChar(string)`` + + +QTextStream +~~~~~~~~~~~ + +Inside this class some renames were applied to avoid clashes with native Python functions. +They are: ``bin_()``, ``hex_()`` and ``oct_()``. +The only modification was the addition of the '_' character. + + +QVariant +~~~~~~~~ + +As ``QVariant`` was removed, any function expecting it can receive any Python object (``None`` is +an invalid ``QVariant``). +The same rule is valid when returning something: the returned ``QVariant`` will be converted to +its original Python object type. + +When a method expects a ``QVariant::Type`` the programmer can use a string (the type name) or the +type itself. + + +qApp "macro" +~~~~~~~~~~~~ + +The C++ API of QtWidgets provides a macro called ``qApp`` that roughly expands to +``QtWidgets::QApplication->instance()``. + +In PySide, we tried to create a macro-like experience. +For that, the ``qApp`` variable was implemented as a normal variable +that lives in the builtins. +After importing ``PySide2``, you can immediately use ``qApp``. + +As a useful shortcut for the action "create an application if it was not created", we recommend:: + + qApp or QtWidgets.QApplication() + +or if you want to check if there is one, simply use the truth value:: + + if qApp: + # do something if an application was created + pass + +Comparing to ``None`` is also possible, but slightly over-specified. + + +Testing support ++++++++++++++++ + +For testing purposes, you can also get rid of the application by calling:: + + qApp.shutdown() + +As for 5.14.2, this is currently an experimental feature that is not fully tested. + + +Embedding status +++++++++++++++++ + +In embedded mode, application objects that are pre-created in C++ don't have a Python wrapper. +The ``qApp`` variable is created together with a wrapped application. +Therefore, ``qApp`` does not exist in that embedded mode. +Please note that you always can use ``QtWidgets.QApplication.instance()`` instead. + + +Abandoned Alternative ++++++++++++++++++++++ + +We also tried an alternative implementation with a ``qApp()`` function that was more *pythonic* +and problem free, but many people liked the ``qApp`` macro better for its brevity, so here it is. + + +Rich Comparison +~~~~~~~~~~~~~~~ + +There was a long-standing bug in the ``tp_richcompare`` implementation of PySide classes. + +* When a class did not implement it, the default implementation of ``object`` is used. + This implements ``==`` and ``!=`` like the ``is`` operator. + +* When a class implements only a single function like ``<``, then the default implementation + was disabled, and expressions like ``obj in sequence`` failed with ``NotImplemented``. + +This oversight was fixed in version 5.15.1 . diff --git a/sources/pyside2/doc/contents.rst b/sources/pyside2/doc/contents.rst new file mode 100644 index 0000000..598a65c --- /dev/null +++ b/sources/pyside2/doc/contents.rst @@ -0,0 +1,23 @@ +|project| Documentation +*************************** + +.. toctree:: + :maxdepth: 2 + + quickstart.rst + gettingstarted.rst + api.rst + tutorials/index.rst + examples/index.rst + videos.rst + deployment.rst + licenses.rst + modules.rst + considerations.rst + shiboken2/index.rst + +Module Index +============ + +* :ref:`modindex` + diff --git a/sources/pyside2/doc/deployment-briefcase.rst b/sources/pyside2/doc/deployment-briefcase.rst new file mode 100644 index 0000000..a5179a2 --- /dev/null +++ b/sources/pyside2/doc/deployment-briefcase.rst @@ -0,0 +1,199 @@ +|project| & Briefcase +####################### + +`Briefcase `_ is a packaging tool that lets you create a standalone package for a Python application. It supports the following installer formats: + + * .app application bundle for macOS + * MSI installer for Windows + * AppImage for Linux + +For more details, see the `official documentation `_. + +Preparation +=========== + +Install `Briefcase` using the following **pip** command:: + + pip install briefcase + +You also need : docker on linux, `WixToolset`_ on windows, + +If you're using a virtual environment, remember to activate it before installing `Briefcase`. + +After installation, the `briefcase` binary is located in your virtual environment's `bin/` +directory, or where your Python executable is located. + +You can either create a brand new project using the briefcase assistant or setup your own. + +.. _`WixToolset`: https://wixtoolset.org/ + +Use Briefcase Assistant +======================= + +Run the following command and answer the questions to get started:: + + briefcase new + +Ensure that `PySide2` is chosen as the `GUI toolkit choice`. +Your PySide2 application is now configured. You can jump to `Build the package`_. + + +Set up your project +=================== + +Create a pyproject.toml +----------------------- + +At the root level of your project, create a `pyproject.toml` file:: + + [tool.briefcase] + project_name = "MyPySideApp" + bundle = "com.example" + version = "0.0.1" + url = "https://somwhere/on/the/net" + license = "GNU General Public License v3 (GPLv3)" + author = 'MyName Firstname' + author_email = "cool@mailexample.com" + + [tool.briefcase.app.mypysideapp] + formal_name = "A Cool App" + description = "The coolest app ever" + icon = "src/mypysideapp/resources/appicon" # Briecase will choose the right extension depending the os (png,ico,...) + sources = ['src/mypysideapp'] + requires = ['pyside2==5.15.0', + 'pony>=0.7.11,<0.8', + 'dickens==1.0.1', + 'Pillow==7.1.2', + 'mako==1.1.2', + 'beautifulsoup4'] + + + [tool.briefcase.app.mypysideapp.macOS] + requires = [] + + [tool.briefcase.app.mypysideapp.linux] + requires = [] + system_requires = [] + + [tool.briefcase.app.mypysideapp.windows] + requires = [] + + +Write some code +---------------- + +Let's say your project tree is like this:: + + pyproject.toml + setup.cfg + pytest.ini + src/ + + mypysideapp/ + resources/ + appicon.png + appicon.ico + __init__.py + __main__.py + app.py + + +Content of `__main__.py`:: + + import sys + from PySide2.QtWidgets import QApplication + from mypysideapp.app import MyWidget + + if __name__ == "__main__": + app = QApplication(sys.argv) + + widget = MyWidget() + widget.resize(800, 600) + widget.show() + + sys.exit(app.exec_()) + + +Content of `app.py`:: + + import random + from PySide2.QtWidgets import (QLabel, QPushButton, + QVBoxLayout, QWidget) + from PySide2.QtCore import Slot, Qt + + class MyWidget(QWidget): + def __init__(self): + QWidget.__init__(self) + + self.hello = ["Hallo Welt", "你好,世界", "Hei maailma", + "Hola Mundo", "Привет мир"] + + self.button = QPushButton("Click me!") + self.text = QLabel("Hello World") + self.text.setAlignment(Qt.AlignCenter) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.text) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + # Connecting the signal + self.button.clicked.connect(self.magic) + + @Slot() + def magic(self): + self.text.setText(random.choice(self.hello)) + + +Build the package +================== + +Initialize the package +------------------------ + +Just run:: + + briefcase create + +Run the following command to initialize the building the packages for Windows, Linux, and macOS. +It creates a subdirectory each for the different platforms. +This step takes longer as it adds the packages listed in `requires` sections in the `pyproject.toml` file. + +Build the application +--------------------- +:: + + briefcase build + +You'll get:: + + macOS/A Cool App/A Cool App.app + or + linux/A Cool App-x86_64-0.0.1.AppImage + or + windows\A Cool App + + +Run the application +------------------- +:: + + briefcase run + +.. note:: You can run your project in `dev` mode (your source code not packaged) with `briefcase dev` + + +Build the installer (only Windows and macOS) +--------------------------------------------- + +macOS:: + + briefcase package --no-sign + +It's possible to sign, see the `documentation `_. You get `macOS/A Cool App-0.0.1.dmg` + +Windows:: + + briefcase package + +You get `windows\A_Cool_App-0.0.1.msi` diff --git a/sources/pyside2/doc/deployment-cxfreeze.rst b/sources/pyside2/doc/deployment-cxfreeze.rst new file mode 100644 index 0000000..f0a71ca --- /dev/null +++ b/sources/pyside2/doc/deployment-cxfreeze.rst @@ -0,0 +1,130 @@ +===================== +|project| & cx_Freeze +===================== + +`cx_Freeze `_ lets you +freeze your Python application into executables. The supported +platforms are Linux, macOS, Windows, FreeBSD, among others. + +You can read the `official documentation `_ +to clarify any further question, and remember to contribute to +the project by `filing issues `_ +if you find any, or contributing to `their development `_. + +Preparation +=========== + +Installing `cx_Freeze` can be done using **pip**:: + + pip install cx_freeze + +If you are using a virtual environment, remember to activate it before +installing `cx_Freeze` into it. + +After the installation, you will have the `cxfreeze` binary to deploy +your application. + +Freezing an application +======================= + +There are three options to work with `cx_Freeze`: + + 1. Using the `cxfreeze` script. + 2. Creating `setup.py` script to build the project. + 3. Using the module classes directly (for advanced purposes). + +The following sections cover the first two use cases. + +Creating an example +------------------- + +Now, consider the following simple script, named `hello.py`:: + + import sys + import random + from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, + QVBoxLayout, QWidget) + from PySide2.QtCore import Slot, Qt + + class MyWidget(QWidget): + def __init__(self): + QWidget.__init__(self) + + self.hello = ["Hallo Welt", "你好,世界", "Hei maailma", + "Hola Mundo", "Привет мир"] + + self.button = QPushButton("Click me!") + self.text = QLabel("Hello World") + self.text.setAlignment(Qt.AlignCenter) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.text) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + # Connecting the signal + self.button.clicked.connect(self.magic) + + @Slot() + def magic(self): + self.text.setText(random.choice(self.hello)) + + if __name__ == "__main__": + app = QApplication(sys.argv) + + widget = MyWidget() + widget.resize(800, 600) + widget.show() + + sys.exit(app.exec_()) + + +Using `cxfreeze` executable +--------------------------- + +Now that we have an application, try freezing it with the following +command:: + + cxfreeze hello.py + +This command creates a `dist/` directory containing the executable. +and a `lib/` directory containing all the shared libraries. + +To launch the application, go to the `dist/` directory and execute +the file:: + + cd dist/ + ./main + + +Using a setuptools script +------------------------- + +For this process, you need an additional script called `setup.py`:: + + import sys + from cx_Freeze import setup, Executable + + setup(name = "MyApp", + version = "0.1", + description = "My GUI App", + executables = [Executable("hello.py")]) + +Now, build the project using it:: + + python setup.py build + +This step creates a `build/` directory with the following structure:: + + build + └── exe.linux-x86_64-3.7 + └── lib + └── main + +The first directory inside `build/` depends on the platform +you are using, in this case a `x86_64` Linux using Python 3.7. +The structure is the same as previously described, and you can simply +enter the directory and execute the file:: + + cd build/exe.linux-x86_64-3.7 + ./main diff --git a/sources/pyside2/doc/deployment-fbs.rst b/sources/pyside2/doc/deployment-fbs.rst new file mode 100644 index 0000000..a90b499 --- /dev/null +++ b/sources/pyside2/doc/deployment-fbs.rst @@ -0,0 +1,97 @@ +|project| & fbs +#################### + +`fbs`_ provides a powerful environment for packaging, creating installers, and signing your +application. It also lets you manage updates to your application. Since `fbs` is based on +PyInstaller, it supports Linux, macOS, and Windows. + +For more details, see the `fbs tutorial`_ and the `fbs manual`_. + +.. _fbs: https://build-system.fman.io/ +.. _fbs tutorial: https://github.com/mherrmann/fbs-tutorial +.. _fbs manual: https://build-system.fman.io/manual/ + +Preparation +=========== + +Installing `fbs`_ (>= 0.7.6) is done via **pip**:: + + pip install fbs + +If you're using a virtual environment, remember to activate it before installing `fbs`_. + +After the installation, you can use the `fbs`_ executable. + +Starting a new project +====================== + +`fbs`_ provides useful features for you to create a base project structure with the following +command:: + + fbs startproject + +This command prompts you to answer a few questions to configure the details of your project, like: + + * Application name + * Author name + * Qt bindings (PySide2 or PyQt5) + * Bundle indentified (for macOS) + +Afterwards, you have a `src/` directory that contains the following structure:: + + └── src + ├── build + │ └── settings + └── main + ├── icons + │ ├── base + │ ├── linux + │ └── mac + └── python + +Inside the `settings` directory, there are a few JSON files that can be edited to include more +information about your project. + +The `main` file is in the `python` directory, and its default content is:: + + from fbs_runtime.application_context import ApplicationContext + from PySide2.QtWidgets import QMainWindow + + import sys + + if __name__ == '__main__': + appctxt = ApplicationContext() # 1. Instantiate ApplicationContext + window = QMainWindow() + window.resize(250, 150) + window.show() + exit_code = appctxt.app.exec_() # 2. Invoke appctxt.app.exec_() + sys.exit(exit_code) + +This example shows an empty `QMainWindow`. You can run it using the following command:: + + fbs run + +Freezing the application +======================== + +Once you've verified that the application is working properly, you can continue with the freezing +process using the following command:: + + fbs freeze + +After the process completes, you see a message stating the location of your executable. For +example:: + + Done. You can now run `target/MyApp/MyApp`. If that doesn't work, see + https://build-system.fman.io/troubleshooting. + + +Now, you can try to run the application. The result is the same window as the one you saw with the +`fbs run` command:: + + cd target/MyApp/ + ./MyApp + +.. note:: This is the case for Linux. For other platforms like macOS, you need to enter the + directory: `target/MyApp.app/Contents/macOS`. For Windows, you need to find the `MyApp.exe` + executable. diff --git a/sources/pyside2/doc/deployment-pyinstaller.rst b/sources/pyside2/doc/deployment-pyinstaller.rst new file mode 100644 index 0000000..e7ed643 --- /dev/null +++ b/sources/pyside2/doc/deployment-pyinstaller.rst @@ -0,0 +1,158 @@ +|project| & PyInstaller +####################### + +`PyInstaller `_ lets you freeze your python application into a +stand-alone executable. This installer supports Linux, macOS, Windows, and more; and is also +compatible with 3rd-party Python modules, such as |pymodname|. + +For more details, see the `official documentation `_. + +Preparation +=========== + +Install the `PyInstaller` via **pip** with the following command:: + + pip install pyinstaller + +If you're using a virtual environment, remember to activate it before installing `PyInstaller`. + +After installation, the `pyinstaller` binary is located in your virtual environment's `bin/` +directory, or where your Python executable is located. If that directory isn't in your `PATH`, +include the whole path when you run `pyinstaller`. + +.. warning:: If you already have a PySide2 or Shiboken2 version installed in your + system path, PyInstaller uses them instead of your virtual environment version. + +Freeze an application +======================= + +`PyInstaller` has many options that you can use. To list them all, run `pyinstaller -h`. + +There are two main features: + + * the option to package the whole project (including shared libraries) into one executable file + (`--onefile`) + * the option to place it in a directory containing the libraries + +Additionally, on Windows when the command is running, you can open a console with the `-c` option +(or `--console` or `--nowindowed` equivalent). + +Otherwise, you can specify to not open such a console window on macOS and Windows with the `-w` +option (or `--windowed` or `--noconsole` equivalent). + +Create an example +----------------- + +Now, consider the following script, named `hello.py`:: + + import sys + import random + from PySide2.QtWidgets import (QApplication, QLabel, QPushButton, + QVBoxLayout, QWidget) + from PySide2.QtCore import Slot, Qt + + class MyWidget(QWidget): + def __init__(self): + QWidget.__init__(self) + + self.hello = ["Hallo Welt", "你好,世界", "Hei maailma", + "Hola Mundo", "Привет мир"] + + self.button = QPushButton("Click me!") + self.text = QLabel("Hello World") + self.text.setAlignment(Qt.AlignCenter) + + self.layout = QVBoxLayout() + self.layout.addWidget(self.text) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + # Connecting the signal + self.button.clicked.connect(self.magic) + + @Slot() + def magic(self): + self.text.setText(random.choice(self.hello)) + + if __name__ == "__main__": + app = QApplication(sys.argv) + + widget = MyWidget() + widget.resize(800, 600) + widget.show() + + sys.exit(app.exec_()) + + +Since it has a UI, you use the `--windowed` option. + +The command line to proceed looks like this:: + + pyinstaller --name="MyApplication" --windowed hello.py + +This process creates two directories: `dist/` and `build/`. The application executable and the +required shared libraries are placed in `dist/MyApplication`. + +To run the application, go to `dist/MyApplication` and run the program:: + + cd dist/MyApplication/ + ./MyApplication + +.. note:: The directory inside `dist/` and the executable have the same name. + +Use the `--onefile` option if you prefer to have everything bundled into one executable, without +the shared libraries next to it:: + + pyinstaller --name="MyApplication" --windowed --onefile hello.py + +This process takes a bit longer, but in the end you have one executable in the `dist/` directory:: + + cd dist/ + ./MyApplication + + +Some Caveats +============ + + +PyInstaller Issue +----------------- + +As mentioned before, if available, `PyInstaller` picks a system installation of PySide2 or +Shiboken2 instead of your `virtualenv` version without notice. This is negligible if those +two versions are the same. + +If you're working with different versions, this can result in frustrating debugging sessions +when you think you are testing the latest version, but `PyInstaller` is working with an older +version. + +Issue with numpy in Python 2.7.16 +--------------------------------- + +A recent issue with PyInstaller is the appearance of Python 2.7.16. This Python version creates +an issue that is known from Python 3 as a `Tcl/Tk` problem. This rarely shows up in Python 3 +because `Tcl/Tk` is seldom used with `PyInstaller`. + +On Python 2.7.16, this problem is common, as many developers use numpy. For some reason, +installing `numpy` creates a dependency to `Tcl/Tk`, which can be circumvented only by explicitly +excluding `Tcl/Tk` by adding this line to spec-file's analysis section:: + + excludes=['FixTk', 'tcl', 'tk', '_tkinter', 'tkinter', 'Tkinter'], + + +Safety Instructions +------------------- + +- When using `PyInstaller` with `virtualenv`, make sure that there is no system + installation of PySide2 or shiboken2. + +- Before compiling, use `pip -uninstall pyside2 shiboken2 -y` multiple times, until + none of the programs are found anymore. + +- Pip is usually a good tool. But to be 100 % sure, you should directly remove + the PySide2 and shiboken2 folders from site-packages. + +- Be sure to use the right version of pip. The safest way to really run the right + pip, is to use the Python that you mean: Instead of the pip command, better use:: + + python -m pip diff --git a/sources/pyside2/doc/deployment.rst b/sources/pyside2/doc/deployment.rst new file mode 100644 index 0000000..3d6aa21 --- /dev/null +++ b/sources/pyside2/doc/deployment.rst @@ -0,0 +1,120 @@ +|project| Deployment +==================== + + +Deploying or freezing an application is an important part of a Python project, +this means to bundle all required resources so that the application finds everything it needs to +be able to run on a client's machine. +However, because most large projects aren't based on a single Python file, distributing these +applications can be a challenge. + +Here are a few distribution options that you can use: + 1. Send a normal ZIP file with the application's content. + 2. Build a proper `Python package (wheel) `_. + 3. Freeze the application into a single binary file or directory. + 4. Provide native installer (msi, dmg) + +If you choose Option 3, consider using one of these tools: + * `fbs`_ + * `PyInstaller`_ + * `cx_Freeze`_ + * `py2exe`_ + * `py2app`_ + * `briefcase`_ + +.. _fbs: https://build-system.fman.io/ +.. _PyInstaller: https://www.pyinstaller.org/ +.. _cx_Freeze: https://anthony-tuininga.github.io/cx_Freeze/ +.. _py2exe: http://www.py2exe.org/ +.. _py2app: https://py2app.readthedocs.io/en/latest/ +.. _briefcase: https://briefcase.readthedocs.io + +Since |project| is a cross-platform framework, we focus on solutions for the three major +platforms that Qt supports: Windows, Linux, and macOS. + +The following table summarizes the platform support for those packaging tools: + +.. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameLicenseLinuxmacOSWindows

fbs

GPL

yes

yes

yes

PyInstaller

GPL

yes

yes

yes

cx_Freeze

MIT

yes

yes

yes

py2exe

MIT

no

no

yes

py2app

MIT

no

yes

no

briefcase

BSD3

yes

yes

yes

+ +Notice that only *fbs*, *cx_Freeze*, *briefcase*, and *PyInstaller* meet our cross-platform requirement. + +Since these are command-line tools, you'll need special hooks or scripts to handle resources +such as images, icons, and meta-information, before adding them to your package. Additionally, +these tools don't offer a mechanism to update your application packages. + +To create update packages, use the `PyUpdater `_, which is a tool +built around PyInstaller. + +The `fbs`_ tool offers a nice UI for the user to install the +application step-by-step. + +.. note:: + + Deployment is supported only from Qt for Python 5.12.2 and later. + +Here's a set of tutorials on how to use these tools: + +.. toctree:: + :name: mastertoc + :maxdepth: 2 + + deployment-fbs.rst + deployment-pyinstaller.rst + deployment-cxfreeze.rst + deployment-briefcase.rst diff --git a/sources/pyside2/doc/examples/images/tabbedbrowser.png b/sources/pyside2/doc/examples/images/tabbedbrowser.png new file mode 100644 index 0000000000000000000000000000000000000000..27c3daa097b3dac5334fcada87cff286550e2b74 GIT binary patch literal 37147 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. + + +Details about Qt Flags: +----------------------- + +There are some small differences between Qt flags and Python flags. +In Qt, we have for instance these declarations: + +:: + + enum QtGui::RenderHint { Antialiasing, TextAntialiasing, SmoothPixmapTransform, + HighQualityAntialiasing, NonCosmeticDefaultPen } + flags QtGui::RenderHints + +The equivalent Python notation would look like this: + +:: + + @QFlag + class RenderHints(enum.Flag) + Antialiasing = auto() + TextAntialiasing = auto() + SmoothPixmapTransform = auto() + HighQualityAntialiasing = auto() + NonCosmeticDefaultPen = auto() + + +As another example, the Qt::AlignmentFlag flag has 'AlignmentFlag' as the enum +name, but 'Alignment' as the type name. Non flag enums have the same type and +enum names. + +:: + + enum Qt::AlignmentFlag + flags Qt::Alignment + +The Python way to specify this would be + +:: + + @QFlag + class Alignment(enum.Flag): + ... + +We are considering to map all builtin enums and flags to Python enums as well +in a later release. + diff --git a/sources/pyside2/doc/extras/QtCore.Signal.rst b/sources/pyside2/doc/extras/QtCore.Signal.rst new file mode 100644 index 0000000..a0660f8 --- /dev/null +++ b/sources/pyside2/doc/extras/QtCore.Signal.rst @@ -0,0 +1,39 @@ +.. currentmodule:: PySide2.QtCore +.. _Signal: + +Signal +****** + +Synopsis +-------- + +Functions +^^^^^^^^^ + ++---------------------------------------------------------------------------------------------+ +|def :meth:`connect` (receiver) | ++---------------------------------------------------------------------------------------------+ +|def :meth:`disconnect` (receiver) | ++---------------------------------------------------------------------------------------------+ +|def :meth:`emit` (\*args) | ++---------------------------------------------------------------------------------------------+ + +Detailed Description +-------------------- + + The :class:`~.Signal` class provides a way to declare and connect Qt signals in a pythonic way. + + PySide adopt PyQt's new signal and slot syntax as-is. The PySide implementation is functionally compatible with the PyQt 4.5 one, with the exceptions listed bellow. + +.. method:: Signal.connect(receiver[, type=Qt.AutoConnection]) + + Create a connection between this signal and a `receiver`, the `receiver` can be a Python callable, a :class:`Slot` or a :class:`Signal`. + +.. method:: Signal.disconnect(receiver) + + Disconnect this signal from a `receiver`, the `receiver` can be a Python callable, a :class:`Slot` or a :class:`Signal`. + +.. method:: Signal.emit(*args) + + `args` is the arguments to pass to any connected slots, if any. + diff --git a/sources/pyside2/doc/extras/QtCore.Slot.rst b/sources/pyside2/doc/extras/QtCore.Slot.rst new file mode 100644 index 0000000..5a59a2a --- /dev/null +++ b/sources/pyside2/doc/extras/QtCore.Slot.rst @@ -0,0 +1,39 @@ +.. currentmodule:: PySide2.QtCore +.. _Slot: + +Slot +**** + +Detailed Description +-------------------- + + PySide2 adopt PyQt5's new signal and slot syntax as-is. The PySide2 + implementation is functionally compatible with the PyQt5 one, with the + exceptions listed below. + + PyQt5's new signal and slot style utilizes method and decorator names + specific to their implementation. These will be generalized according to + the table below: + + ======= ======================= ============= + Module PyQt5 factory function PySide2 class + ======= ======================= ============= + QtCore pyqtSignal Signal + QtCore pyqtSlot Slot + ======= ======================= ============= + +Q_INVOKABLE +----------- + + There is no equivalent of the Q_INVOKABLE macro of Qt + since PySide2 slots can actually have return values. + If you need to create a invokable method that returns some value, + declare it as a slot, e.g.: + + :: + + class Foo(QObject): + + @Slot(float, result=int) + def getFloatReturnInt(self, f): + return int(f) diff --git a/sources/pyside2/doc/extras/QtCore.rst b/sources/pyside2/doc/extras/QtCore.rst new file mode 100644 index 0000000..d3277a4 --- /dev/null +++ b/sources/pyside2/doc/extras/QtCore.rst @@ -0,0 +1,5 @@ +All other Qt modules rely on this module. To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtCore diff --git a/sources/pyside2/doc/extras/QtGui.rst b/sources/pyside2/doc/extras/QtGui.rst new file mode 100644 index 0000000..e16329c --- /dev/null +++ b/sources/pyside2/doc/extras/QtGui.rst @@ -0,0 +1,7 @@ +To include the definitions of modules classes, use the following directive: + +:: + + import PySide2.QtGui + +.. seealso:: :mod:`PySide2.QtCore` diff --git a/sources/pyside2/doc/extras/QtHelp.rst b/sources/pyside2/doc/extras/QtHelp.rst new file mode 100644 index 0000000..239f4fa --- /dev/null +++ b/sources/pyside2/doc/extras/QtHelp.rst @@ -0,0 +1,5 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtHelp diff --git a/sources/pyside2/doc/extras/QtMultimedia.rst b/sources/pyside2/doc/extras/QtMultimedia.rst new file mode 100644 index 0000000..5088db4 --- /dev/null +++ b/sources/pyside2/doc/extras/QtMultimedia.rst @@ -0,0 +1,7 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtMultimedia + + diff --git a/sources/pyside2/doc/extras/QtNetwork.rst b/sources/pyside2/doc/extras/QtNetwork.rst new file mode 100644 index 0000000..07303b1 --- /dev/null +++ b/sources/pyside2/doc/extras/QtNetwork.rst @@ -0,0 +1,5 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtNetwork diff --git a/sources/pyside2/doc/extras/QtOpenGL.rst b/sources/pyside2/doc/extras/QtOpenGL.rst new file mode 100644 index 0000000..38783d9 --- /dev/null +++ b/sources/pyside2/doc/extras/QtOpenGL.rst @@ -0,0 +1,14 @@ +OpenGL is a standard API for rendering 3D graphics. OpenGL only deals with 3D rendering and provides little or no support for GUI programming issues. The user interface for an OpenGL application must be created with another toolkit, such as Motif on the X platform, Microsoft Foundation Classes (MFC) under Windows, or Qt on both platforms. + +.. note:: OpenGL is a trademark of Silicon Graphics, Inc. in the United States and other countries. + +The Qt OpenGL module makes it easy to use OpenGL in Qt applications. It provides an OpenGL widget class that can be used just like any other Qt widget, except that it opens an OpenGL display buffer where you can use the OpenGL API to render the contents. +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtOpenGL + +The Qt OpenGL module is implemented as a platform-independent wrapper around the platform-dependent GLX (version 1.3 or later), WGL, or AGL C APIs. Although the basic functionality provided is very similar to Mark Kilgard's GLUT library, applications using the Qt OpenGL module can take advantage of the whole Qt API for non-OpenGL-specific GUI functionality. + +The QtOpenGL module is available on Windows, X11 and Mac OS X. Qt for Embedded Linux and OpenGL supports OpenGL ES (OpenGL for Embedded Systems). \ No newline at end of file diff --git a/sources/pyside2/doc/extras/QtScript.rst b/sources/pyside2/doc/extras/QtScript.rst new file mode 100644 index 0000000..8ce7681 --- /dev/null +++ b/sources/pyside2/doc/extras/QtScript.rst @@ -0,0 +1,21 @@ +The QtScript module only provides core scripting facilities; the QtScriptTools module provides additional Qt Script-related components that application developers may find useful. + +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtScript + +License Information +------------------- + +Qt Commercial Edition licensees that wish to distribute applications that use the QtScript module need to be aware of their obligations under the GNU Library General Public License (LGPL). + +Developers using the Open Source Edition can choose to redistribute the module under the appropriate version of the GNU LGPL. +QtScript is licensed under the GNU Library General Public License. Individual contributor names and copyright dates can be found inline in the code. + +This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. + +You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. diff --git a/sources/pyside2/doc/extras/QtScriptTools.rst b/sources/pyside2/doc/extras/QtScriptTools.rst new file mode 100644 index 0000000..a54ed91 --- /dev/null +++ b/sources/pyside2/doc/extras/QtScriptTools.rst @@ -0,0 +1,5 @@ +Applications that use the Qt Script Tools classes need to be configured to be built against the QtScriptTools module. To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtScriptTools diff --git a/sources/pyside2/doc/extras/QtSql.rst b/sources/pyside2/doc/extras/QtSql.rst new file mode 100644 index 0000000..fcdd6ba --- /dev/null +++ b/sources/pyside2/doc/extras/QtSql.rst @@ -0,0 +1,5 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtSql diff --git a/sources/pyside2/doc/extras/QtSvg.rst b/sources/pyside2/doc/extras/QtSvg.rst new file mode 100644 index 0000000..7817e53 --- /dev/null +++ b/sources/pyside2/doc/extras/QtSvg.rst @@ -0,0 +1,5 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtSvg diff --git a/sources/pyside2/doc/extras/QtTest.rst b/sources/pyside2/doc/extras/QtTest.rst new file mode 100644 index 0000000..0b89a22 --- /dev/null +++ b/sources/pyside2/doc/extras/QtTest.rst @@ -0,0 +1,7 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtTest + +.. note:: All macros in the C++ version of QtTest were not binded in PySide, this module is useful only for GUI testing and benchmarking, for ordinary unit testing you should use the ``unittest`` Python module. diff --git a/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst b/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst new file mode 100644 index 0000000..9ca330d --- /dev/null +++ b/sources/pyside2/doc/extras/QtUiTools.loadUiType.rst @@ -0,0 +1,36 @@ +.. currentmodule:: PySide2.QtUiTools +.. _loadUiType: + +loadUiType +*********** + +.. py:function:: loadUiType(uifile: str) -> tuple(object, object) + + :param str uifile: The name of the `.ui` file + :return: tuple(object, object) + + This function generates and loads a `.ui` file at runtime, and it returns + a `tuple` containing the reference to the Python class, and the base class. + + We recommend not to use this approach as the workflow should be to generate a Python file + from the `.ui` file, and then import and load it to use it, but we do understand that + there are some corner cases when such functionality is required. + + The internal process relies on `uic` being in the PATH. + The `pyside2-uic` wrapper uses a shipped `uic` that is located in the + `site-packages/PySide2/uic`, so PATH needs to be updated to use that if there + is no `uic` in the system. + + A simple use case is:: + + from PySide2.QtUiTools import loadUiType + + generated_class, base_class = loadUiType("themewidget.ui") + # the values will be: + # (, ) + + widget = base_class() + form = generated_class() + form.setupUi(widget) + # form.a_widget_member.a_method_of_member() + widget.show() diff --git a/sources/pyside2/doc/extras/QtUiTools.rst b/sources/pyside2/doc/extras/QtUiTools.rst new file mode 100644 index 0000000..598d69d --- /dev/null +++ b/sources/pyside2/doc/extras/QtUiTools.rst @@ -0,0 +1,9 @@ +These forms are processed at run-time to produce dynamically-generated user interfaces. In order to generate a form at run-time, a resource file containing a UI file is needed. + +A form loader object, provided by the QUiLoader class, is used to construct the user interface. This user interface can be retrieved from any QIODevice; for example, a QFile object can be used to obtain a form stored in a project's resources. The :meth:`PySide2.QtUiTools.QUiLoader.load` function takes the user interface description contained in the file and constructs the form widget. + +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide.QtUiTools diff --git a/sources/pyside2/doc/extras/QtWebKit.rst b/sources/pyside2/doc/extras/QtWebKit.rst new file mode 100644 index 0000000..58f9230 --- /dev/null +++ b/sources/pyside2/doc/extras/QtWebKit.rst @@ -0,0 +1,94 @@ +QtWebKit provides a Web browser engine that makes it easy to embed content from the World Wide Web into your Qt application. At the same time Web content can be enhanced with native controls. + +QtWebKit provides facilities for rendering of HyperText Markup Language (HTML), Extensible HyperText Markup Language (XHTML) and Scalable Vector Graphics (SVG) documents, styled using Cascading Style Sheets (CSS) and scripted with JavaScript. + +A bridge between the JavaScript execution environment and the Qt object model makes it possible for custom QObjects to be scripted. Integration with the Qt networking module enables Web pages to be transparently loaded from Web servers, the local file system or even the Qt resource system. + +In addition to providing pure rendering features, HTML documents can be made fully editable to the user through the use of the contenteditable attribute on HTML elements. + +QtWebKit is based on the Open Source WebKit engine. More information about WebKit itself can be found on the _`WebKit Open Source Project ` Web site. + +Including In Your Project +------------------------- + +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtWebKit + + +.. note:: Web site icons, also known as "FavIcons", are currently not supported on Windows. We plan to address this in a future release. + +Architecture +------------ + +The easiest way to render content is through the QWebView class. As a widget it can be embedded into your forms or a graphics view, and it provides convenience functions for downloading and rendering web sites. + +:: + + view = QWebView(parent) + view.load(QUrl("http://qt.nokia.com/")) + view.show() + +QWebView is used to view Web pages. An instance of QWebView has one QWebPage. QWebPage provides access to the document structure in a page, describing features such as frames, the navigation history, and the undo/redo stack for editable content. + +HTML documents can be nested using frames in a frameset. An individual frame in HTML is represented using the QWebFrame class. This class includes the bridge to the JavaScript window object and can be painted using QPainter. Each QWebPage has one QWebFrame object as its main frame, and the main frame may contain many child frames. + +Individual elements of an HTML document can be accessed via DOM JavaScript interfaces from within a web page. The equivalent of this API in QtWebKit is represented by QWebElement. QWebElement objects are obtained using QWebFrame's findAllElements() and findFirstElement() functions with CSS selector queries. + +Common web browser features, defaults and other settings can be configured through the QWebSettings class. It is possible to provide defaults for all QWebPage instances through the default settings. Individual attributes can be overidden by the page specific settings object. + +Netscape Plugin Support +----------------------- + +.. note:: Netscape plugin support is only available on desktop platforms. + +Since WebKit supports the Netscape Plugin API, Qt applications can display Web pages that embed common plugins on platforms for which those plugins are available. To enable plugin support, the user must have the appropriate binary files for those plugins installed and the ``QWebSettings.PluginsEnabled`` attribute must be enabled for the application. + +The following locations are searched for plugins: + +* Linux/Unix (X11) + * .mozilla/plugins in the user's home directory + * .netscape/plugins in the user's home directory + * System locations, such as + * /usr/lib/browser/plugins + * /usr/local/lib/mozilla/plugins + * /usr/lib/firefox/plugins + * /usr/lib64/browser-plugins + * /usr/lib/browser-plugins + * /usr/lib/mozilla/plugins + * /usr/local/netscape/plugins + * /opt/mozilla/plugins + * /opt/mozilla/lib/plugins + * /opt/netscape/plugins + * /opt/netscape/communicator/plugins + * /usr/lib/netscape/plugins + * /usr/lib/netscape/plugins-libc5 + * /usr/lib/netscape/plugins-libc6 + * /usr/lib64/netscape/plugins + * /usr/lib64/mozilla/plugins + * Locations specified by environment variables: + * $MOZILLA_HOME/plugins + * $MOZ_PLUGIN_PATH + * $QTWEBKIT_PLUGIN_PATH +* Windows + * The user's Application Data\Mozilla\plugins directory + * Standard system locations of plugins for Quicktime, Flash, etc. +* Mac OS X + * Library/Internet Plug-Ins in the user's home directory + * The system /Library/Internet Plug-Ins directory + +License Information +------------------- + +Qt Commercial Edition licensees that wish to distribute applications that use the QtWebKit module need to be aware of their obligations under the GNU Library General Public License (LGPL). + +Developers using the Open Source Edition can choose to redistribute the module under the appropriate version of the GNU LGPL. +WebKit is licensed under the GNU Library General Public License. Individual contributor names and copyright dates can be found inline in the code. + +This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. + +You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. \ No newline at end of file diff --git a/sources/pyside2/doc/extras/QtXml.rst b/sources/pyside2/doc/extras/QtXml.rst new file mode 100644 index 0000000..4b48ef2 --- /dev/null +++ b/sources/pyside2/doc/extras/QtXml.rst @@ -0,0 +1,5 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtXml diff --git a/sources/pyside2/doc/extras/QtXmlPatterns.rst b/sources/pyside2/doc/extras/QtXmlPatterns.rst new file mode 100644 index 0000000..99254ad --- /dev/null +++ b/sources/pyside2/doc/extras/QtXmlPatterns.rst @@ -0,0 +1,12 @@ +To include the definitions of the module's classes, use the following directive: + +:: + + import PySide2.QtXmlPatterns + +Further Reading +--------------- + +General overviews of XQuery and XSchema can be found in the XQuery document. + +An introduction to the XQuery language can be found in A Short Path to XQuery. diff --git a/sources/pyside2/doc/faq.rst b/sources/pyside2/doc/faq.rst new file mode 100644 index 0000000..b7e9816 --- /dev/null +++ b/sources/pyside2/doc/faq.rst @@ -0,0 +1,37 @@ +.. _faq: + +:orphan: + +Frequently Asked Questions +========================== + +**When did The Qt Company adopt PySide2?** + In April 2016 `The Qt Company `_ decided to properly support the port. For more + information, see ``_. + +**Why use PySide2 and not PySide?** + Since PySide was developed for Qt 4, we now use PySide2 to imply that it is for a newer version, + after it was ported to support Qt 5. + +**Where I can find information about the old PySide project?** + The project's old wiki page is available on PySide, but the project is now deprecated and not + supported. + +**There are three wheels (pyside2, shiboken2, and shiboken2_generator), what's the difference?** + + Before the official release, everything was in one big wheel, so it made sense to split these + into separate wheels, each for the major projects currently in development: + + * **pyside2**: contains all the PySide2 modules to use the Qt framework; also depends on the + shiboken2 module. + * **shiboken2**: contains the shiboken2 module with helper functions for PySide2. + * **shiboken2_generator**: contains the generator binary that can work with a C++ project and a + typesystem to generate Python bindings. + If you want to generate bindings for a Qt/C++ project, there won't be any linking to the Qt + shared libraries; you need to do this by hand. We recommend building PySide2 from scratch + to have everything properly linked. + +**Why is the shiboken2_generator not installed automatically?** + It's not necessary to install the shiboken2_generator to use PySide2. The package is a result of + the wheel splitting process. To use the generator, it's recommended to build it from scratch to + have the proper Qt linking. diff --git a/sources/pyside2/doc/gettingstarted-linux.rst b/sources/pyside2/doc/gettingstarted-linux.rst new file mode 100644 index 0000000..0474d45 --- /dev/null +++ b/sources/pyside2/doc/gettingstarted-linux.rst @@ -0,0 +1,96 @@ +Getting Started on Linux +========================== + +Requirements +------------ + + * Qt package from `here`_ or a custom build of Qt 5.12+ (preferably 5.15) + * A Python interpreter (version Python 3.5+ or Python 2.7). + You can either use the one provided by your OS, or get it + from the `official website`_. + * GCC + * `CMake`_ version 3.1 or greater + * Git version 2 or greater + * `libclang`_ from your system or the prebuilt version from the ``Qt Downloads`` page is + recommended. libclang10 is required for PySide 5.15. + * ``sphinx`` package for the documentation (optional). + * Depending on your linux distribution, the following dependencies might also be required: + + * ``libgl-dev``, + * ``python-dev``, + * ``python-distutils``, + * and ``python-setuptools``. + +.. _here: https://qt.io/download +.. _official website: https://www.python.org/downloads/ +.. _CMake: https://cmake.org/download/ +.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/ + + +Building from source +-------------------- + +Creating a virtual environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``venv`` module allows you to create a local, user-writeable copy of a python environment into +which arbitrary modules can be installed and which can be removed after use:: + + python -m venv testenv + source testenv/bin/activate + pip install -r requirements.txt # General dependencies, documentation, and examples. + +will create and use a new virtual environment, which is indicated by the command prompt changing. + +Setting up CLANG +~~~~~~~~~~~~~~~~ + +If you don't have libclang already in your system, you can download from the Qt servers:: + + wget https://download.qt.io/development_releases/prebuilt/libclang/libclang-release_100-based-linux-Rhel7.6-gcc5.3-x86_64.7z + +Extract the files, and leave it on any desired path, and then set these two required +environment variables:: + + 7z x libclang-release_100-based-linux-Rhel7.6-gcc5.3-x86_64.7z + export CLANG_INSTALL_DIR=$PWD/libclang + +Getting PySide2 +~~~~~~~~~~~~~~~ + +Cloning the official repository can be done by:: + + git clone --recursive https://code.qt.io/pyside/pyside-setup + +Checking out the version that we want to build, e.g. 5.15:: + + cd pyside-setup && git checkout 5.15 + +.. note:: Keep in mind you need to use the same version as your Qt installation. + Additionally, ``git checkout -b 5.15 --track origin/5.14`` could be a better option + in case you want to work on it. + +Building PySide2 +~~~~~~~~~~~~~~~~ + +Check your Qt installation path, to specifically use that version of qmake to build PySide2. +e.g. ``/opt/Qt/5.14.0/gcc_64/bin/qmake``. + +Build can take a few minutes, so it is recommended to use more than one CPU core:: + + python setup.py build --qmake=/opt/Qt/5.15.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8 + +Installing PySide2 +~~~~~~~~~~~~~~~~~~ + +To install on the current directory, just run:: + + python setup.py install --qmake=/opt/Qt/5.15.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8 + +Test installation +~~~~~~~~~~~~~~~~~ + +You can execute one of the examples to verify the process is properly working. +Remember to properly set the environment variables for Qt and PySide2:: + + python examples/widgets/widgets/tetrix.py diff --git a/sources/pyside2/doc/gettingstarted-macOS.rst b/sources/pyside2/doc/gettingstarted-macOS.rst new file mode 100644 index 0000000..fd1bf89 --- /dev/null +++ b/sources/pyside2/doc/gettingstarted-macOS.rst @@ -0,0 +1,95 @@ +Getting Started on macOS +======================== + +Requirements +------------ + + * Qt package from `here`_ or a custom build of Qt 5.12+ (preferably 5.15) + * A Python interpreter (version Python 3.5+ or Python 2.7). + You can use the one provided by HomeBrew, or you can get + python from the `official website`_. + * `XCode`_ 8.2 (macOS 10.11), 8.3.3 (macOS 10.12), 9 (macOS 10.13), 10.1 (macOS 10.14) + * `CMake`_ version 3.1 or greater + * Git version 2 or greater + * `libclang`_ from your system or the prebuilt version from the ``Qt Downloads`` page is + recommended. libclang10 is required for PySide 5.15. + * ``sphinx`` package for the documentation (optional). + * Depending on your OS, the following dependencies might also be required: + + * ``libgl-dev``, + * ``python-dev``, + * ``python-distutils``, + * and ``python-setuptools``. + +.. _XCode: https://developer.apple.com/xcode/ +.. _here: https://qt.io/download +.. _official website: https://www.python.org/downloads/ +.. _CMake: https://cmake.org/download/ +.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/ + + +Building from source +-------------------- + +Creating a virtual environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``venv`` module allows you to create a local, user-writeable copy of a python environment into +which arbitrary modules can be installed and which can be removed after use:: + + python -m venv testenv # your interpreter could be called 'python3' + source testenv/bin/activate + pip install -r requirements.txt # General dependencies, documentation, and examples. + +will create and use a new virtual environment, which is indicated by the command prompt changing. + +Setting up CLANG +~~~~~~~~~~~~~~~~ + +If you don't have libclang already in your system, you can download from the Qt servers:: + + wget http://download.qt.io/development_releases/prebuilt/libclang/libclang-release_100-based-mac.7z + +Extract the files, and leave it on any desired path, and then set these two required +environment variables:: + + 7z x libclang-release_100-based-mac.7z + export CLANG_INSTALL_DIR=$PWD/libclang + +Getting PySide2 +~~~~~~~~~~~~~~~ + +Cloning the official repository can be done by:: + + git clone --recursive https://code.qt.io/pyside/pyside-setup + +Checking out the version that we want to build, e.g. 5.15:: + + cd pyside-setup && git checkout 5.15 + +.. note:: Keep in mind you need to use the same version as your Qt installation + +Building PySide2 +~~~~~~~~~~~~~~~~ + +Check your Qt installation path, to specifically use that version of qmake to build PySide2. +e.g. ``/opt/Qt/5.15.0/gcc_64/bin/qmake``. + +Build can take a few minutes, so it is recommended to use more than one CPU core:: + + python setup.py build --qmake=/opt/Qt/5.15.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8 + +Installing PySide2 +~~~~~~~~~~~~~~~~~~ + +To install on the current directory, just run:: + + python setup.py install --qmake=/opt/Qt/5.15.0/gcc_64/bin/qmake --build-tests --ignore-git --parallel=8 + +Test installation +~~~~~~~~~~~~~~~~~ + +You can execute one of the examples to verify the process is properly working. +Remember to properly set the environment variables for Qt and PySide2:: + + python examples/widgets/widgets/tetrix.py diff --git a/sources/pyside2/doc/gettingstarted-windows.rst b/sources/pyside2/doc/gettingstarted-windows.rst new file mode 100644 index 0000000..069358e --- /dev/null +++ b/sources/pyside2/doc/gettingstarted-windows.rst @@ -0,0 +1,104 @@ +Getting Started on Windows +========================== + +The Qt library has to be built with the same version of MSVC as Python and PySide2, this can be +selected when using the online installer. + +Requirements +------------ + + * Qt package from `here`_ or a custom build of Qt 5.12+ (preferably Qt 5.15) + * A Python interpreter (version Python 3.5+). Preferably get it from the `official website`_. + * `MSVC2017`_ (or MSVC2019) for Python 3 on Windows, + * `CMake`_ version 3.1 or greater + * `Git`_ version 2 or greater + * `libclang`_ prebuilt version from the ``Qt Downloads`` page is recommended. We recommend + libclang10 for PySide 5.15. + * `OpenSSL`_ (optional for SSL support, Qt must have been configured using the same SSL library). + * ``venv`` or ``virtualenv`` is strongly recommended, but optional. + * ``sphinx`` package for the documentation (optional). + +.. note:: Python 2.7 interpreter is not supported. + The official Python 2.7 binary package offerred on the + `official website`_ is built using MSVC 2007, while + the Qt libraries are built using MSVC 2015/2017. + If you intend to use Python 2.7, build the interpreter yourself + with MSVC 2015 or later, and build Qt for Python with it. + +.. note:: Python 3.8.0 was missing some API required for PySide/Shiboken so it's not possible + to use it for a Windows build. + + +.. _here: https://qt.io/download +.. _official website: https://www.python.org/downloads/ +.. _MSVC2017: https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools +.. _CMake: https://cmake.org/download/ +.. _Git: https://git-scm.com/download/win +.. _libclang: http://download.qt.io/development_releases/prebuilt/libclang/ +.. _OpenSSL: https://sourceforge.net/projects/openssl/ + + +Building from source on Windows 10 +---------------------------------- + +Creating a virtual environment +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The ``venv`` module allows you to create a local, user-writeable copy of a python environment into +which arbitrary modules can be installed and which can be removed after use:: + + python -m venv testenv + call testenv\Scripts\activate + pip install -r requirements.txt # General dependencies, documentation, and examples. + +will create and use a new virtual environment, which is indicated by the command prompt changing. + +Setting up CLANG +~~~~~~~~~~~~~~~~ + +If you don't have libclang already in your system, you can download from the Qt servers, +e.g. ``libclang-release_100-based-windows-vs2019_64.7z``. + +Extract the files, and leave it on any desired path, e.g ``c:\``, and then set these two required +environment variables:: + + set LLVM_INSTALL_DIR=c:\libclang + set PATH=C:\libclang\bin;%PATH% + +Getting PySide2 +~~~~~~~~~~~~~~~ + +Cloning the official repository can be done by:: + + git clone --recursive https://code.qt.io/pyside/pyside-setup + +Checking out the version that we want to build, e.g. 5.15:: + + cd pyside-setup && git checkout 5.15 + +.. note:: Keep in mind you need to use the same version as your Qt installation + +Building PySide2 +~~~~~~~~~~~~~~~~ + +Check your Qt installation path, to specifically use that version of qmake to build PySide2. +e.g. ``E:\Qt\5.15.0\msvc2019_64\bin\qmake.exe``. + +Build can take a few minutes, so it is recommended to use more than one CPU core:: + + python setup.py build --qmake=c:\path\to\qmake.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8 + +Installing PySide2 +~~~~~~~~~~~~~~~~~~ + +To install on the current directory, just run:: + + python setup.py install --qmake=c:\path\to\qmake.exe --openssl=c:\path\to\openssl\bin --build-tests --ignore-git --parallel=8 + +Test installation +~~~~~~~~~~~~~~~~~ + +You can execute one of the examples to verify the process is properly working. +Remember to properly set the environment variables for Qt and PySide2:: + + python examples/widgets/widgets/tetrix.py diff --git a/sources/pyside2/doc/gettingstarted.rst b/sources/pyside2/doc/gettingstarted.rst new file mode 100644 index 0000000..1623538 --- /dev/null +++ b/sources/pyside2/doc/gettingstarted.rst @@ -0,0 +1,218 @@ +|project| Getting Started +========================== + +This page is focused on building |project| from source, if you just want to install |pymodname| +with ``pip`` you need to run:: + + pip install pyside2 + +for more details, refer to our `Quick Start`_ guide. Additionally, you can +check the :ref:`FAQ ` related to the project. + +.. _Quick Start: quickstart.html + +General Requirements +-------------------- + + * **Python**: 3.5+ and 2.7 + * **Qt:** 5.12+ is recommended + * **libclang:** The libclang library, recommended: version 10 for PySide2 5.15. + Prebuilt versions of it can be `downloaded here`_. + * **CMake:** 3.1+ is needed. + +.. _downloaded here: http://download.qt.io/development_releases/prebuilt/libclang/ + +Guides per platform +------------------- + +You can refer to the following pages for platform specific instructions: + + * `Windows`_ + * `macOS`_ + * `Linux`_ + * Mobile platforms (iOS/Android) **(no support)** + * Embedded platforms **(no official support)** + + .. note:: Most Linux-based embedded OS provide PySide2 with their official + package manager (e.g. `Raspbian`_ and `ArchlinuxARM`_). + +.. _Windows: gettingstarted-windows.html +.. _macOS: gettingstarted-macOS.html +.. _Linux: gettingstarted-linux.html +.. _Raspbian: https://www.raspbian.org/ +.. _ArchlinuxARM: https://archlinuxarm.org/ + +A normal building command will look like this:: + + python setup.py install --qmake=/path/to/qmake \ + --ignore-git \ + --debug \ + --build-tests \ + --parallel=8 \ + --make-spec=ninja \ + --verbose-build \ + --module-subset=Core,Gui,Widgets + +Which will build and install the project with **debug** symbols, including the **tests**, +using **ninja** (instead of make), and considering only the **module subset** of QtCore, QtGUI +and QtWidgets. + +Other important options to consider are: + * ``--cmake``, to specify the path to the cmake binary, + * ``--reuse-build``, to rebuild only the modified files, + * ``--openssl=/path/to/openssl/bin``, to use a different path for OpenSSL, + * ``--standalone``, to copy over the Qt libraries into the final package + to make it work on other machines, + * ``--doc-build-online``, to build documentation using the online template. + +Testing the installation +------------------------ + +Once the installation finishes, you will be able to execute any of our examples:: + + python examples/widgets/widgets/tetrix.py + +Running Tests +------------- + +Using the ``--build-tests`` option will enable us to run all the auto tests inside the project:: + + python testrunner.py test > testlog.txt + +.. note:: On Windows, don't forget to have qmake in your path + (``set PATH=E:\Path\to\Qt\5.15\msvc2017_64\bin;%PATH%``) + +You can also run a specific test (for example ``qpainter_test``) by running:: + + ctest -R qpainter_test --verbose + +Building the documentation +-------------------------- + +Starting from 5.15, there are two options to build the documentation: + +1. Building rst-only documentation (no API) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The process of parsing Qt headers to generate the PySide API documentation can take several +minutes, this means that modifying a specific section of the rst files we currently have, might +become a hard task. + +For this, you can install ``sphinx`` on a virtual environment, and execute the following command:: + + python setup.py build_rst_docs + +which will generate a ``html/`` directory with the following structure:: + + html + └── pyside2 + ├── index.html + ├── ... + └── shiboken2 + ├── index.html + └── ... + +so you can open the main page ``html/pyside2/index.html`` on your browser to check the generated +files. + +This is useful when updating the general sections of the documentation, adding tutorials, +modifying the build instructions, and more. + +2. Building the documentation (rst + API) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The documentation is being generated using **qdoc** to get the API information, and also **sphinx** +for the local Python related notes. + +The system required ``libxml2`` and ``libxslt``, also on the Python environment, ``sphinx`` and +``graphviz`` need to be installed before running the installation process:: + + pip install graphviz sphinx + +After installing ``graphviz``, the ``dot`` command needs to be in PATH, otherwise, +the process will fail. Installing ``graphviz`` system-wide is also an option. + +Since the process rely on a Qt installation, you need to specify where the ``qtbase`` directory +you will use with your ``qmake`` is located:: + + export QT_SRC_DIR=/path/to/qtbase + +Once the build process finishes, you can go to the generated ``*_build/*_release/pyside2`` +directory, and run:: + + make apidoc + +.. note:: The ``apidoc`` make target builds offline documenation in QCH (Qt Creator Help) format + by default. You can switch to building for the online use with the ``--doc-build-online`` + configure option. + +Finally, you will get a ``html`` directory containing all the generated documentation. The offline +help files, ``PySide.qch`` and ``Shiboken.qch``, can be moved to any directory of your choice. You +can find ``Shiboken.qch`` in the build directory, ``*_build\*_release\shiboken2\doc\html``. + +Viewing offline documentation +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The offline documentation (QCH) can be viewed using the Qt Creator IDE or Qt Assistant, which is +a standalone application for viewing QCH files. + +To view the QCH using Qt Creator, following the instructions outlined in +`Using Qt Creator Help Mode `_. If you chose to +use Qt Assistant instead, use the following command to register the QCH file before launching +Qt Assistant: + + assistant -register PySide.qch + +.. note:: Qt Assistant renders the QCH content using the QTextBrowser backend, which supports + a subset of the CSS styles, However, Qt Creator offers an alternative litehtml-based + backend, which offers better browsing experience. At the moment, this is not the default + backend, so you have to select the litehtml backend + explicitly under the ``General`` tab in ``Qt Creator >> Tools >> Options >> Help``. + +Using the internal tools +------------------------ + +A set of tools can be found under the ``tools/`` directory inside the ``pyside-setup`` repository. + +* ``checklibs.py``: Script to analyze dynamic library dependencies of Mach-O binaries. + To use this utility, just run:: + + python checklibs.py /path/to/some.app/Contents/MacOS/Some + + This script was fetched from this repository_. + +* ``create_changelog.py``: Script used to create the CHANGELOG that you can find in the ``dist/`` + directory. Usage:: + + python create_changelog.py -r 5.15.1 -v v5.15.0..5.15 -t bug-fix + +* ``debug_windows.py``: This script can be used to find out why PySide2 modules + fail to load with various DLL errors like Missing DLL or Missing symbol in DLL. + + You can think of it as a Windows version of ``ldd`` / ``LD_DEBUG``. + + Underneath it uses the ``cdb.exe`` command line debugger, and the ``gflags.exe`` tool, both + installed with the latest Windows Kit. + + The aim is to ask users to run this script when they encounter PySide2 imports not working on + Windows. The user should then provide the generated log file. + + Incidentally it can also be used for any Windows executables, not just Python. + To use it just run:: + + python debug_windows.py + +* ``missing_bindings.py``: This script is used to compare the state of PySide2 and PyQt5 + regarding available modules and classses. This content is displayed in our `wiki page`_, + and can be used as follows:: + + python missing_bindings.py --qt-version 5.15.1 -w all + + Please keep in mind we rely on BeautifulSoup_ to parse the content, so you will be to install + it besides PySide2 and PyQt5 (Including additional modules like DataVisualiztion, QtCharts, + WebEngine, etc). + + +.. _repository: https://github.com/liyanage/macosx-shell-scripts/ +.. _`wiki page`: https://wiki.qt.io/Qt_for_Python_Missing_Bindings +.. _BeautifulSoup: https://www.crummy.com/software/BeautifulSoup/ diff --git a/sources/pyside2/doc/index.rst b/sources/pyside2/doc/index.rst new file mode 100644 index 0000000..6c62334 --- /dev/null +++ b/sources/pyside2/doc/index.rst @@ -0,0 +1,104 @@ +|project| +********* + +.. ifconfig:: output_format == 'html' + + **Qt for Python** offers the official Python bindings for `Qt`_, and + has two main components: + + * `PySide2`_, so that you can use Qt5 APIs in your Python applications, and + * `Shiboken2 `__, a binding generator tool, which can + be used to expose C++ projects to Python, and a Python module with + some utility functions. + +.. ifconfig:: output_format == 'qthelp' + + **Qt for Python** offers the official Python bindings for `Qt`_, and + has two main components: + + * `PySide2`_, so that you can use Qt5 APIs in your Python applications, and + * `Shiboken2 <../shiboken2/index.html>`__, a binding generator tool, which can + be used to expose C++ projects to Python, and a Python module with + some utility functions. + +This project is available under the LGPLv3/GPLv3 and the `Qt commercial license`_. + +.. _Qt: https://doc.qt.io +.. _PySide2: quickstart.html +.. _`Qt commercial license`: https://www.qt.io/licensing/ + + + +Documentation +============= + +.. ifconfig:: output_format == 'html' + + .. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + +

Check It Out!
Write your first Qt app.

Getting Started
Install and build from source.

API Docs
Qt for Python API reference.

Tutorials
Learn with step-by-step guides.

Examples
Check all the available examples.

Videos
Watch webinars, Talks, and more.

Deployment
Learn to deploy your apps.

Considerations
API differences and known issues.

Shiboken
Generate C++ to Python binding.

+ +.. ifconfig :: output_format == 'qthelp' + + .. raw:: html + + + + + + + + + + + + + + + + + + + + + + + + +

Check It Out!
Write your first Qt app.

Getting Started
Install and build from source.

API Docs
Qt for Python API reference.

Tutorials
Learn with step-by-step guides.

Examples
Check all the available examples.

Videos
Watch webinars, Talks, and more.

Deployment
Learn to deploy your apps.

Considerations
API differences and known issues.

Shiboken
Generate C++ to Python binding.

+ +We have also a `wiki page`_ where you can find how to report bugs, contribute or contact the community. + +.. _`wiki page`: https://wiki.qt.io/Qt_for_Python + +.. toctree:: + :hidden: + :glob: + + contents.rst + gettingstarted* + pyside-examples/pyside2examples* + overviews/* diff --git a/sources/pyside2/doc/inheritance_diagram.py b/sources/pyside2/doc/inheritance_diagram.py new file mode 100644 index 0000000..875e17b --- /dev/null +++ b/sources/pyside2/doc/inheritance_diagram.py @@ -0,0 +1,372 @@ +# -*- coding: utf-8 -*- +r""" + sphinx.ext.inheritance_diagram + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Defines a docutils directive for inserting inheritance diagrams. + + Provide the directive with one or more classes or modules (separated + by whitespace). For modules, all of the classes in that module will + be used. + + Example:: + + Given the following classes: + + class A: pass + class B(A): pass + class C(A): pass + class D(B, C): pass + class E(B): pass + + .. inheritance-diagram: D E + + Produces a graph like the following: + + A + / \ + B C + / \ / + E D + + The graph is inserted as a PNG+image map into HTML and a PDF in + LaTeX. + + :copyright: Copyright 2007-2011 by the Sphinx team, see AUTHORS. + :copyright: Copyright 2010-2011 by the PySide team. + :license: BSD, see LICENSE for details. +""" + +import os +import re +import sys +import inspect +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +from docutils import nodes +from docutils.parsers.rst import directives, Directive + +from sphinx.ext.graphviz import render_dot_html, render_dot_latex + +class InheritanceException(Exception): + pass + +# When passed something like: +# PySide2.QtCore.QStateMachine.SignalEvent +# try to import the underlying module and return a +# handle to the object. In a loop, import +# PySide2.QtCore.QStateMachine.SignalEvent +# PySide2.QtCore.QStateMachine +# PySide2.QtCore +# until the import succeeds and walk up the attributes +# to obtain the object + +def importClassOrModule(name): + components = name.split('.') + for i in range(len(components), 0, -1): + importPath = '.'.join(components[: i]) + try: + __import__(importPath) + except ImportError: + continue + if i == len(components): + return sys.modules[importPath] + remaining = components[i :] + cls = sys.modules[importPath] + for component in remaining: + try: + cls = getattr(cls, component) + except Exception: # No such attribute + return None + return cls + return None + +class InheritanceGraph(object): + """ + Given a list of classes, determines the set of classes that they inherit + from all the way to the root "object", and then is able to generate a + graphviz dot graph from them. + """ + def __init__(self, class_names, currmodule, show_builtins=False, parts=0): + """ + *class_names* is a list of child classes to show bases from. + + If *show_builtins* is True, then Python builtins will be shown + in the graph. + """ + self.class_names = class_names + classes = self._import_classes(class_names, currmodule) + self.class_info = self._class_info(classes, show_builtins, parts) + if not self.class_info: + raise InheritanceException('No classes found for ' + 'inheritance diagram') + + def _import_class_or_module(self, name, currmodule): + """ + Import a class using its fully-qualified *name*. + """ + todoc = importClassOrModule(name) + if not todoc and currmodule is not None: + todoc = importClassOrModule(currmodule + '.' + name) + if not todoc: + moduleStr = '(module {})'.format(currmodule) if currmodule else '' + raise InheritanceException('Could not import class {} specified for ' + 'inheritance diagram {}.'.format(name, moduleStr)) + if inspect.isclass(todoc): + return [todoc] + elif inspect.ismodule(todoc): + classes = [] + for cls in todoc.__dict__.values(): + if inspect.isclass(cls) and cls.__module__ == todoc.__name__: + classes.append(cls) + return classes + raise InheritanceException('%r specified for inheritance diagram is ' + 'not a class or module' % name) + + def _import_classes(self, class_names, currmodule): + """Import a list of classes.""" + classes = [] + for name in class_names: + classes.extend(self._import_class_or_module(name, currmodule)) + return classes + + def _class_info(self, classes, show_builtins, parts): + """Return name and bases for all classes that are ancestors of + *classes*. + + *parts* gives the number of dotted name parts that is removed from the + displayed node names. + """ + all_classes = {} + builtins = __builtins__.values() + + def recurse(cls): + if not show_builtins and cls in builtins: + return + + nodename = self.class_name(cls, parts) + fullname = self.class_name(cls, 0) + + baselist = [] + all_classes[cls] = (nodename, fullname, baselist) + for base in cls.__bases__: + if not show_builtins and base in builtins: + continue + if base.__name__ == "Object" and base.__module__ == "Shiboken": + continue + baselist.append(self.class_name(base, parts)) + if base not in all_classes: + recurse(base) + + for cls in classes: + recurse(cls) + + return list(all_classes.values()) + + def class_name(self, cls, parts=0): + """Given a class object, return a fully-qualified name. + + This works for things I've tested in matplotlib so far, but may not be + completely general. + """ + module = cls.__module__ + if module == '__builtin__': + fullname = cls.__name__ + else: + fullname = '%s.%s' % (module, cls.__qualname__) + if parts == 0: + return fullname + name_parts = fullname.split('.') + return '.'.join(name_parts[-parts:]) + + def get_all_class_names(self): + """ + Get all of the class names involved in the graph. + """ + return [fullname for (_, fullname, _) in self.class_info] + + # These are the default attrs for graphviz + default_graph_attrs = { + 'rankdir': 'LR', + 'size': '"8.0, 12.0"', + } + default_node_attrs = { + 'shape': 'box', + 'fontsize': 10, + 'height': 0.25, + 'fontname': '"Vera Sans, DejaVu Sans, Liberation Sans, ' + 'Arial, Helvetica, sans"', + 'style': '"setlinewidth(0.5)"', + } + default_edge_attrs = { + 'arrowsize': 0.5, + 'style': '"setlinewidth(0.5)"', + } + + def _format_node_attrs(self, attrs): + return ','.join(['%s=%s' % x for x in attrs.items()]) + + def _format_graph_attrs(self, attrs): + return ''.join(['%s=%s;\n' % x for x in attrs.items()]) + + def generate_dot(self, name, urls={}, env=None, + graph_attrs={}, node_attrs={}, edge_attrs={}): + """ + Generate a graphviz dot graph from the classes that + were passed in to __init__. + + *name* is the name of the graph. + + *urls* is a dictionary mapping class names to HTTP URLs. + + *graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing + key/value pairs to pass on as graphviz properties. + """ + g_attrs = self.default_graph_attrs.copy() + n_attrs = self.default_node_attrs.copy() + e_attrs = self.default_edge_attrs.copy() + g_attrs.update(graph_attrs) + n_attrs.update(node_attrs) + e_attrs.update(edge_attrs) + if env: + g_attrs.update(env.config.inheritance_graph_attrs) + n_attrs.update(env.config.inheritance_node_attrs) + e_attrs.update(env.config.inheritance_edge_attrs) + + res = [] + res.append('digraph %s {\n' % name) + res.append(self._format_graph_attrs(g_attrs)) + + for name, fullname, bases in self.class_info: + # Write the node + this_node_attrs = n_attrs.copy() + url = urls.get(fullname) + if url is not None: + this_node_attrs['URL'] = '"%s"' % url + res.append(' "%s" [%s];\n' % + (name, self._format_node_attrs(this_node_attrs))) + + # Write the edges + for base_name in bases: + res.append(' "%s" -> "%s" [%s];\n' % + (base_name, name, + self._format_node_attrs(e_attrs))) + res.append('}\n') + return ''.join(res) + + +class inheritance_diagram(nodes.General, nodes.Element): + """ + A docutils node to use as a placeholder for the inheritance diagram. + """ + pass + + +class InheritanceDiagram(Directive): + """ + Run when the inheritance_diagram directive is first encountered. + """ + has_content = False + required_arguments = 1 + optional_arguments = 0 + final_argument_whitespace = True + option_spec = { + 'parts': directives.nonnegative_int, + } + + def run(self): + node = inheritance_diagram() + node.document = self.state.document + env = self.state.document.settings.env + class_names = self.arguments[0].split() + class_role = env.get_domain('py').role('class') + # Store the original content for use as a hash + node['parts'] = self.options.get('parts', 0) + node['content'] = ', '.join(class_names) + + # Create a graph starting with the list of classes + try: + graph = InheritanceGraph( + class_names, env.temp_data.get('py:module'), + parts=node['parts']) + except InheritanceException as err: + return [node.document.reporter.warning(err.args[0], + line=self.lineno)] + + # Create xref nodes for each target of the graph's image map and + # add them to the doc tree so that Sphinx can resolve the + # references to real URLs later. These nodes will eventually be + # removed from the doctree after we're done with them. + for name in graph.get_all_class_names(): + refnodes, x = class_role( + 'class', ':class:`%s`' % name, name, 0, self.state) + node.extend(refnodes) + # Store the graph object so we can use it to generate the + # dot file later + node['graph'] = graph + return [node] + + +def get_graph_hash(node): + hashString = node['content'] + str(node['parts']) + return md5(hashString.encode('utf-8')).hexdigest()[-10:] + + +def html_visit_inheritance_diagram(self, node): + """ + Output the graph for HTML. This will insert a PNG with clickable + image map. + """ + graph = node['graph'] + + graph_hash = get_graph_hash(node) + name = 'inheritance%s' % graph_hash + + # Create a mapping from fully-qualified class names to URLs. + urls = {} + for child in node: + if child.get('refuri') is not None: + urls[child['reftitle']] = child.get('refuri') + elif child.get('refid') is not None: + urls[child['reftitle']] = '#' + child.get('refid') + + dotcode = graph.generate_dot(name, urls, env=self.builder.env) + render_dot_html(self, node, dotcode, {}, 'inheritance', 'inheritance', + alt='Inheritance diagram of ' + node['content']) + raise nodes.SkipNode + + +def latex_visit_inheritance_diagram(self, node): + """ + Output the graph for LaTeX. This will insert a PDF. + """ + graph = node['graph'] + + graph_hash = get_graph_hash(node) + name = 'inheritance%s' % graph_hash + + dotcode = graph.generate_dot(name, env=self.builder.env, + graph_attrs={'size': '"6.0,6.0"'}) + render_dot_latex(self, node, dotcode, {}, 'inheritance') + raise nodes.SkipNode + + +def skip(self, node): + raise nodes.SkipNode + + +def setup(app): + app.setup_extension('sphinx.ext.graphviz') + app.add_node( + inheritance_diagram, + latex=(latex_visit_inheritance_diagram, None), + html=(html_visit_inheritance_diagram, None), + text=(skip, None), + man=(skip, None)) + app.add_directive('inheritance-diagram', InheritanceDiagram) + app.add_config_value('inheritance_graph_attrs', {}, False), + app.add_config_value('inheritance_node_attrs', {}, False), + app.add_config_value('inheritance_edge_attrs', {}, False), diff --git a/sources/pyside2/doc/modules.rst b/sources/pyside2/doc/modules.rst new file mode 100644 index 0000000..bb4b112 --- /dev/null +++ b/sources/pyside2/doc/modules.rst @@ -0,0 +1,101 @@ +Qt Modules +=========== + +.. toctree:: + :hidden: + :glob: + + PySide2/Qt*/index + +.. list-table:: + :widths: 150, 150 + :align: left + + * - :mod:`Qt Core ` + Provides core non-GUI functionality. + - :mod:`Qt 3D Animation ` + Provides basic elements required to animate 3D objects. + * - :mod:`Qt Gui ` + Extends QtCore with GUI functionality. + - :mod:`Qt Help ` + Provides classes for integrating online documentation in applications. + * - :mod:`Qt Network ` + Offers classes that let you to write TCP/IP clients and servers. + - :mod:`Qt OpenGL ` + Offers classes that make it easy to use OpenGL in Qt applications. + * - :mod:`Qt PrintSupport ` + Provides extensive cross-platform support for printing. + - :mod:`Qt Qml ` + Python API for Qt QML. + * - :mod:`Qt Charts ` + Provides a set of easy to use chart components. + - :mod:`Qt Quick ` + Provides classes for embedding Qt Quick in Qt applications. + * - :mod:`Qt DataVisualization ` + Provides a way to visualize data in 3D as bar, scatter, and surface graphs. + - :mod:`Qt QuickWidgets ` + Provides the QQuickWidget class for embedding Qt Quick in widget-based applications. + * - :mod:`Qt TextToSpeech ` + Provides API to access text-to-speech engines. + - :mod:`Qt Sql ` + Helps you provide seamless database integration to your Qt applications. + * - :mod:`Qt Multimedia ` + Provides low-level multimedia functionality. + - :mod:`Qt MultimediaWidgets ` + Provides the widget-based multimedia API. + * - :mod:`Qt MacExtras ` + Provides classes and functions specific to + macOS and iOS operating systems. + - :mod:`Qt Svg ` + Provides classes for displaying the contents of SVG files. + * - :mod:`Qt UiTools ` + Provides classes to handle forms created with Qt Designer. + - :mod:`Qt Test ` + Provides classes for unit testing Qt applications and libraries. + * - :mod:`Qt Concurrent ` + Provides high-level APIs that make it possible + to write multi-threaded programs without using low-level threading + primitives such as mutexes, read-write locks, wait conditions, or semaphores. + - :mod:`Qt AxContainer ` + Provides QAxObject and QAxWidget which act as + containers for COM objects and ActiveX controls. + * - :mod:`Qt WebEngineCore ` + Provides the core functionality to integrate web content. + - :mod:`Qt WebEngineWidgets ` + Provides widgets that can handle web content. + * - :mod:`Qt WebChannel ` + Enables peer-to-peer communication between a server and a client + (HTML/JavaScript or QML application). + - :mod:`Qt WebSockets ` + Provides interfaces that enable Qt applications + to act as a server that can process WebSocket requests, or a client that + can consume data received from the server, or both. + * - :mod:`Qt Widgets ` + Extends Qt GUI with C++ widget functionality. + - :mod:`Qt WinExtras ` + Provides classes and functions for using some Windows APIs in a Qt way. + * - :mod:`Qt X11Extras ` + Provides information about the X display configuration. + - :mod:`Qt Xml ` + Provides C++ implementations of SAX and DOM. + * - :mod:`Qt XmlPatterns ` + Provides support for XPath, XQuery, XSLTi, and XML Schema validation. + - :mod:`Qt 3D Core ` + Contains functionality to support near-realtime simulation systems. + * - :mod:`Qt 3D Extras ` + Provides a set of prebuilt elements to help you get started with Qt 3D. + - :mod:`Qt 3D Input ` + Provides classes for handling user input in applications using Qt 3D. + * - :mod:`Qt 3D Logic ` + Enables synchronizing frames with the Qt 3D backend. + - :mod:`Qt 3D Render ` + Contains functionality to support 2D and 3D rendering using Qt 3D. + * - :mod:`Qt Positioning ` + Provides positioning information via QML and Python interfaces. + - :mod:`Qt Location ` + Helps you create viable mapping solutions using the data available from some of the popular location services. + * - :mod:`Qt Sensors ` + Provides access to sensor hardware via QML and Python interfaces and a motion gesture recognition API for devices. + - :mod:`Qt Scxml ` + Provides classes to create and use state machines from SCXML files. + diff --git a/sources/pyside2/doc/pyside-config.qdocconf.in b/sources/pyside2/doc/pyside-config.qdocconf.in new file mode 100644 index 0000000..3fd5671 --- /dev/null +++ b/sources/pyside2/doc/pyside-config.qdocconf.in @@ -0,0 +1,19 @@ +buildversion = @PYSIDE_QT_VERSION@ +navigation.homepage = Qt for Python + +macro.nullptr = "\\c{None}" + +outputdir = @DOC_DATA_DIR@ +outputformats = WebXML +WebXML.quotinginformation = true +WebXML.nosubdirs = true +WebXML.outputsubdir = webxml + +spurious += "Hostile character .*" + +#excludes qdoc statements that are not relevant for PySide2 +defines += qtforpython + +includepaths += \ + -I @QT_INCLUDE_DIR@ \ + -I @mkspecInclude@ \ diff --git a/sources/pyside2/doc/pyside-examples/examples.qdoc b/sources/pyside2/doc/pyside-examples/examples.qdoc new file mode 100644 index 0000000..748c4f8 --- /dev/null +++ b/sources/pyside2/doc/pyside-examples/examples.qdoc @@ -0,0 +1,37 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:FDL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Free Documentation License Usage +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of +** this file. Please review the following information to ensure +** the GNU Free Documentation License version 1.3 requirements +** will be met: https://www.gnu.org/licenses/fdl-1.3.html. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \group all-pyside-examples + \title All Qt for Python Examples + \brief A varied selection of examples can be found in the 'examples' directory of the + pyside-setup repository. This can be accessed after installing + PySide2 via pip, checking the 'site-packages/PySide2/examples' directory. + + This page aims to document the most important use cases of the module + and it will be extended with each release. +*/ diff --git a/sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png b/sources/pyside2/doc/pyside-examples/images/pyside2example-classwizard.png new file mode 100644 index 0000000000000000000000000000000000000000..1706772d86ebbaae9ce61b849b91d029fb8eb6c3 GIT binary patch literal 57931 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 JLe?VmKL7%ro!S5Z literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/pyside-examples/images/screenshot_hello.png b/sources/pyside2/doc/pyside-examples/images/screenshot_hello.png new file mode 100644 index 0000000000000000000000000000000000000000..41ebbf01b9029b516a7f65704fa466eaae1a5897 GIT binary patch literal 21193 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 p4)mwadGf`8s9;L;&hz1dFH*w%`_. +The following table lists parts of Qt for Python that incorporates +code licensed under third-party opensource licenses: + +""" + +def rstHeadline(title): + return '{}\n{}\n'.format(title, '-' * len(title)) + +def rstUrl(title, url): + return '`{} <{}>`_'.format(title, url) + +def rstLiteralBlock(lines): + return '::\n\n' + indent(lines, ' ') + '\n\n' + +def rstLiteralBlockFromText(text): + return rstLiteralBlock(text.strip().split('\n')) + +def readFile(fileName): + with open(fileName, 'r') as file: + return file.readlines() + +def runScanner(directory, targetFileName): + # qtattributionsscanner recursively searches for qt_attribution.json files + # and outputs them in JSON with the paths of the 'LicenseFile' made absolute + command = 'qtattributionsscanner --output-format json {}'.format(directory) + jsonS = subprocess.check_output(command, shell=True) + if not jsonS: + raise RuntimeError('{} failed to produce output.'.format(command)) + + with open(targetFileName, 'w') as targetFile: + targetFile.write(rstHeader) + for entry in json.loads(jsonS.decode('utf-8')): + content = '{}\n{}\n{}\n\n'.format(rstHeadline(entry['Name']), + entry['Description'], entry['QtUsage']) + url = entry['Homepage'] + version = entry['Version'] + if url and version: + content += '{}, upstream version: {}\n\n'.format( + rstUrl('Project Homepage', url), version) + copyright = entry['Copyright'] + if copyright: + content += rstLiteralBlockFromText(copyright) + content += entry['License'] + '\n\n' + licenseFile = entry['LicenseFile'] + if licenseFile: + if os.path.isfile(licenseFile): + content += rstLiteralBlock(readFile(licenseFile)) + else: + warnings.warn('"{}" is not a file'.format(licenseFile), + RuntimeWarning) + targetFile.write(content) + +if len(sys.argv) < 3: + print("Usage: qtattributionsscannertorst [directory] [file]'") + sys.exit(0) + +directory = sys.argv[1] +targetFileName = sys.argv[2] +runScanner(directory, targetFileName) diff --git a/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in new file mode 100644 index 0000000..14808f2 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-examples.qdocconf.in @@ -0,0 +1,12 @@ +include(@QT_SRC_DIR@/doc/global/qt-module-defaults.qdocconf) + +project = Pyside2Examples +description = Qt for Python Examples +version = $QT_VERSION + +sourcedirs += @CMAKE_CURRENT_SOURCE_DIR@/pyside-examples +exampledirs = @CMAKE_CURRENT_SOURCE_DIR@/../../../examples +examples.fileextensions += *.py *.pyproject +imagedirs += @CMAKE_CURRENT_SOURCE_DIR@/pyside-examples/images +url.examples = "https://code.qt.io/cgit/pyside/pyside-setup.git/tree/examples/\1?h=$QT_VER" +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qt3dextras.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qt3dextras.qdocconf.in new file mode 100644 index 0000000..20bd8d7 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qt3dextras.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qt3d/src/doc/qt3d.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qt3d/src/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtcharts.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtcharts.qdocconf.in new file mode 100644 index 0000000..1a58c2d --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtcharts.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtcharts/src/charts/doc/qtcharts.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtconcurrent.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtconcurrent.qdocconf.in new file mode 100644 index 0000000..a6976c2 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtconcurrent.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/concurrent/doc/qtconcurrent.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtcore.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtcore.qdocconf.in new file mode 100644 index 0000000..5fb7248 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtcore.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/corelib/doc/qtcore.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in new file mode 100644 index 0000000..c9fcb31 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtdatavisualization.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtdatavis3d/src/datavisualization/doc/qtdatavis3d.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtgui.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtgui.qdocconf.in new file mode 100644 index 0000000..77e7e6e --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtgui.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/gui/doc/qtgui.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qthelp.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qthelp.qdocconf.in new file mode 100644 index 0000000..9336909 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qthelp.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qttools/src/assistant/help/doc/qthelp.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtlocation.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtlocation.qdocconf.in new file mode 100644 index 0000000..5536e0c --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtlocation.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtlocation/src/location/doc/qtlocation.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtlocation/src/location/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtmacextras.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtmacextras.qdocconf.in new file mode 100644 index 0000000..3e0e400 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtmacextras.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtmacextras/src/macextras/doc/qtmacextras.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in new file mode 100644 index 0000000..5415c39 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtmultimediawidgets.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtmultimedia/src/multimedia/doc/qtmultimedia.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtmultimedia/src/multimedia/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtnetwork.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtnetwork.qdocconf.in new file mode 100644 index 0000000..addec9a --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtnetwork.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/network/doc/qtnetwork.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtopengl.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtopengl.qdocconf.in new file mode 100644 index 0000000..34895f0 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtopengl.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/opengl/doc/qtopengl.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtpositioning.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtpositioning.qdocconf.in new file mode 100644 index 0000000..4a2c677 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtpositioning.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtlocation/src/positioning/doc/qtpositioning.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtlocation/src/positioning/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtprintsupport.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtprintsupport.qdocconf.in new file mode 100644 index 0000000..04c5544 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtprintsupport.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/printsupport/doc/qtprintsupport.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtqml.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtqml.qdocconf.in new file mode 100644 index 0000000..546ea7b --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtqml.qdocconf.in @@ -0,0 +1,5 @@ +#The index page for QtQml lists only the APIs. Including this qdocconf +#should also include the text and snippets from the module page +include(@QT_SRC_DIR@/../qtdeclarative/src/qml/doc/qtqml.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/qml/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in new file mode 100644 index 0000000..6f59645 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtquickwidgets.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtdeclarative/src/quick/doc/qtquick.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtdeclarative/src/quick/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtscxml.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtscxml.qdocconf.in new file mode 100644 index 0000000..30b61a7 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtscxml.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtscxml/src/scxml/doc/qtscxml.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtscxml/src/scxml/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtsensors.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtsensors.qdocconf.in new file mode 100644 index 0000000..b407db7 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtsensors.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtsensors/src/sensors/doc/qtsensors.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtsensors/src/sensors/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtsql.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtsql.qdocconf.in new file mode 100644 index 0000000..8f41c55 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtsql.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/sql/doc/qtsql.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtsvg.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtsvg.qdocconf.in new file mode 100644 index 0000000..e3c39a6 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtsvg.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtsvg/src/svg/doc/qtsvg.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qttest.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qttest.qdocconf.in new file mode 100644 index 0000000..b092d92 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qttest.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/testlib/doc/qttestlib.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qttexttospeech.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qttexttospeech.qdocconf.in new file mode 100644 index 0000000..ed49121 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qttexttospeech.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtspeech/src/doc/qtspeech.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtspeech/src/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtuitools.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtuitools.qdocconf.in new file mode 100644 index 0000000..7bd3941 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtuitools.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qttools/src/designer/src/uitools/doc/qtuitools.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtwebchannel.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtwebchannel.qdocconf.in new file mode 100644 index 0000000..f3f2f5c --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtwebchannel.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtwebchannel/src/webchannel/doc/qtwebchannel.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in new file mode 100644 index 0000000..038c803 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtwebenginewidgets.qdocconf.in @@ -0,0 +1,3 @@ +include(@QT_SRC_DIR@/../qtwebengine/src/webengine/doc/qtwebengine.qdocconf) +includepaths += -I @QT_SRC_DIR@/../qtwebengine/src/webengine/doc +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtwebsockets.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtwebsockets.qdocconf.in new file mode 100644 index 0000000..082b948 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtwebsockets.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtwebsockets/src/websockets/doc/qtwebsockets.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtwidgets.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtwidgets.qdocconf.in new file mode 100644 index 0000000..90e887f --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtwidgets.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/widgets/doc/qtwidgets.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtwinextras.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtwinextras.qdocconf.in new file mode 100644 index 0000000..d2c1d5b --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtwinextras.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtwinextras/src/winextras/doc/qtwinextras.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtx11extras.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtx11extras.qdocconf.in new file mode 100644 index 0000000..9315fa5 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtx11extras.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtx11extras/src/x11extras/doc/qtx11extras.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtxml.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtxml.qdocconf.in new file mode 100644 index 0000000..f9ccce7 --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtxml.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/src/xml/doc/qtxml.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/qtmodules/pyside-qtxmlpatterns.qdocconf.in b/sources/pyside2/doc/qtmodules/pyside-qtxmlpatterns.qdocconf.in new file mode 100644 index 0000000..9e132ff --- /dev/null +++ b/sources/pyside2/doc/qtmodules/pyside-qtxmlpatterns.qdocconf.in @@ -0,0 +1,2 @@ +include(@QT_SRC_DIR@/../qtxmlpatterns/src/xmlpatterns/doc/qtxmlpatterns.qdocconf) +include(../pyside-config.qdocconf) diff --git a/sources/pyside2/doc/quickstart.rst b/sources/pyside2/doc/quickstart.rst new file mode 100644 index 0000000..87471a8 --- /dev/null +++ b/sources/pyside2/doc/quickstart.rst @@ -0,0 +1,118 @@ +|project| Quick start +====================== + +Requirements +------------ + +Before you can install |project|, first you must install the following software: + + * Python 2.7 or 3.5+ (we recommend 3.5+), + * We recommend using a virtual environment, such as + `venv `_ or + `virtualenv `_ + +Creating and activating an environment +-------------------------------------- + +You can do this by running the following on a terminal:: + + $ python -m venv env/ # Your binary is maybe called 'python3' + $ source env/bin/activate # for Linux and macOS + $ env\Scripts\activate.bat # for Windows + + + +Installation +------------ + +Now you are ready to install the |project| packages using ``pip``. +From the terminal, run the following command:: + + # For the latest version on PyPi + pip install PySide2 + + # For a specific version + pip install PySide2==5.15.0 + +or:: + + pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.15/latest pyside2 --trusted-host download.qt.io + +Test your Installation +---------------------- + +Now that you have |project| installed, you can test your setup by running the following Python +constructs to print version information:: + + import PySide2.QtCore + + # Prints PySide2 version + print(PySide2.__version__) + + # Prints the Qt version used to compile PySide2 + print(PySide2.QtCore.__version__) + +.. note:: + + As it happened in 5.14.2, PySide had a couple of new releases to fix + issues in 5.14.2, adding yet another version level. In that case, you + will have different versions being shown for Qt and PySide. + +Create a Simple Application +--------------------------- + +Your |project| setup is ready. You can explore it further by developing a simple application +that prints "Hello World" in several languages. The following instructions will +guide you through the development process: + +1. Create a new file named :code:`hello_world.py`, and add the following imports to it.:: + + import sys + import random + from PySide2 import QtCore, QtWidgets, QtGui + + The |pymodname| Python module provides access to the Qt APIs as its submodule. + In this case, you are importing the :code:`QtCore`, :code:`QtWidgets`, and :code:`QtGui` submodules. + +2. Define a class named :code:`MyWidget`, which extends QWidget and includes a QPushButton and + QLabel.:: + + class MyWidget(QtWidgets.QWidget): + def __init__(self): + super().__init__() + + self.hello = ["Hallo Welt", "Hei maailma", "Hola Mundo", "Привет мир"] + + self.button = QtWidgets.QPushButton("Click me!") + self.text = QtWidgets.QLabel("Hello World", + alignment=QtCore.Qt.AlignCenter) + + self.layout = QtWidgets.QVBoxLayout() + self.layout.addWidget(self.text) + self.layout.addWidget(self.button) + self.setLayout(self.layout) + + self.button.clicked.connect(self.magic) + + @QtCore.Slot() + def magic(self): + self.text.setText(random.choice(self.hello)) + + The MyWidget class has the :code:`magic` member function that randomly chooses an item from the + :code:`hello` list. When you click the button, the :code:`magic` function is called. + +3. Now, add a main function where you instantiate :code:`MyWidget` and :code:`show` it.:: + + if __name__ == "__main__": + app = QtWidgets.QApplication([]) + + widget = MyWidget() + widget.resize(800, 600) + widget.show() + + sys.exit(app.exec_()) + +Run your example. Try clicking the button at the bottom to see which greeting you get. + +.. image:: pyside-examples/images/screenshot_hello.png + :alt: Hello World application diff --git a/sources/pyside2/doc/src/README.md b/sources/pyside2/doc/src/README.md new file mode 100644 index 0000000..df37cf6 --- /dev/null +++ b/sources/pyside2/doc/src/README.md @@ -0,0 +1 @@ +Any qdoc source files in this directory will be parsed when generating docs. diff --git a/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst new file mode 100644 index 0000000..accb54a --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/clickablebutton.rst @@ -0,0 +1,90 @@ +A Simple Button Tutorial +************************ + +In this tutorial, we'll show you how to handle **signals and slots** +using Qt for Python. **Signals and slots** is a Qt feature that lets +your graphical widgets communicate with other graphical widgets or +your python code. Our application creates a button that logs the +`Button clicked, Hello!` message to the python console each time you +click it. + +Let's start by importing the necessary PySide2 classes and python +`sys` module: +:: + + import sys + from PySide2.QtWidgets import QApplication, QPushButton + from PySide2.QtCore import Slot + +Let's also create a python function that logs the message to the +console: +:: + + # Greetings + @Slot() + def say_hello(): + print("Button clicked, Hello!") + +.. note:: The `@Slot()` is a decorator that identifies a function as + a slot. It is not important to understand why for now, + but use it always to avoid unexpected behavior. + +Now, as mentioned in previous examples you must create the +`QApplication` to run your PySide2 code: +:: + + # Create the Qt Application + app = QApplication(sys.argv) + +Let's create the clickable button, which is a `QPushButton` instance. +To label the button, we pass a python string to the constructor: +:: + + # Create a button + button = QPushButton("Click me") + +Before we show the button, we must connect it to the `say_hello()` +function that we defined earlier. There are two ways of doing this; +using the old style or the new style, which is more pythonic. Let's +use the new style in this case. You can find more information about +both these styles in the +`Signals and Slots in PySide2 `_ +wiki page. + +The `QPushButton` has a predefined signal called **clicked**, which +is triggered every time the button is clicked. We'll connect this +signal to the `say_hello()` function: +:: + + # Connect the button to the function + button.clicked.connect(say_hello) + +Finally, we show the button and start the Qt main loop: +:: + + # Show the button + button.show() + # Run the main Qt loop + app.exec_() + +Here is the complete code for this example: +:: + + #!/usr/bin/python + + import sys + from PySide2.QtWidgets import QApplication, QPushButton + from PySide2.QtCore import Slot + + @Slot() + def say_hello(): + print("Button clicked, Hello!") + + # Create the Qt Application + app = QApplication(sys.argv) + # Create a button, connect it and show it + button = QPushButton("Click me") + button.clicked.connect(say_hello) + button.show() + # Run the main Qt loop + app.exec_() diff --git a/sources/pyside2/doc/tutorials/basictutorial/dialog.rst b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst new file mode 100644 index 0000000..cdb356b --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/dialog.rst @@ -0,0 +1,145 @@ +Creating a Simple PySide2 Dialog Application +********************************************* + +This tutorial shows how to build a simple dialog with some +basic widgets. The idea is to let users provide their name +in a `QLineEdit`, and the dialog greets them on click of a +`QPushButton`. + +Let us just start with a simple stub that creates and shows +a dialog. This stub is updated during the course of this +tutorial, but you can use this stub as is if you need to: +:: + + import sys + from PySide2.QtWidgets import QApplication, QDialog, QLineEdit, QPushButton + + class Form(QDialog): + + def __init__(self, parent=None): + super(Form, self).__init__(parent) + self.setWindowTitle("My Form") + + + if __name__ == '__main__': + # Create the Qt Application + app = QApplication(sys.argv) + # Create and show the form + form = Form() + form.show() + # Run the main Qt loop + sys.exit(app.exec_()) + +The imports aren't new to you, the same for the creation of the +`QApplication` and the execution of the Qt main loop. +The only novelty here is the **class definition**. + +You can create any class that subclasses PySide2 widgets. +In this case, we are subclassing `QDialog` to define a custom +dialog, which we name as **Form**. We have also implemented the +`init()` method that calls the `QDialog`'s init method with the +parent widget, if any. Also, the new `setWindowTitle()` method +just sets the title of the dialog window. In `main()`, you can see +that we are creating a *Form object* and showing it to the world. + +Create the Widgets +=================== + +We are going to create two widgets: a `QLineEdit` where users can +enter their name, and a `QPushButton` that prints the contents of +the `QLineEdit`. +So, let's add the following code to the `init()` method of our Form: +:: + + # Create widgets + self.edit = QLineEdit("Write my name here..") + self.button = QPushButton("Show Greetings") + +It's obvious from the code that both widgets will show the corresponding +texts. + +Create a layout to organize the Widgets +======================================== + +Qt comes with layout-support that helps you organize the widgets +in your application. In this case, let's use `QVBoxLayout` to lay out +the widgets vertically. Add the following code to the `init()` method, +after creating the widgets: +:: + + # Create layout and add widgets + layout = QVBoxLayout() + layout.addWidget(self.edit) + layout.addWidget(self.button) + # Set dialog layout + self.setLayout(layout) + +So, we create the layout, add the widgets with `addWidget()`, +and finally we say that our **Form** will have our `QVBoxLayout` +as its layout. + +Create the function to greet and connect the Button +==================================================== + +Finally, we just have to add a function to our custom **Form** +and *connect* our button to it. Our function will be a part of +the Form, so you have to add it after the `init()` function: +:: + + # Greets the user + def greetings(self): + print ("Hello {}".format(self.edit.text())) + +Our function just prints the contents of the `QLineEdit` to the +python console. We have access to the text by means of the +`QLineEdit.text()` method. + +Now that we have everything, we just need to *connect* the +`QPushButton` to the `Form.greetings()` method. To do so, add the +following line to the `init()` method: +:: + + # Add button signal to greetings slot + self.button.clicked.connect(self.greetings) + +Once executed, you can enter your name in the `QLineEdit` and watch +the console for greetings. + +Complete code +============= + +Here is the complete code for this tutorial: +:: + + import sys + from PySide2.QtWidgets import (QLineEdit, QPushButton, QApplication, + QVBoxLayout, QDialog) + + class Form(QDialog): + + def __init__(self, parent=None): + super(Form, self).__init__(parent) + # Create widgets + self.edit = QLineEdit("Write my name here") + self.button = QPushButton("Show Greetings") + # Create layout and add widgets + layout = QVBoxLayout() + layout.addWidget(self.edit) + layout.addWidget(self.button) + # Set dialog layout + self.setLayout(layout) + # Add button signal to greetings slot + self.button.clicked.connect(self.greetings) + + # Greets the user + def greetings(self): + print ("Hello %s" % self.edit.text()) + + if __name__ == '__main__': + # Create the Qt Application + app = QApplication(sys.argv) + # Create and show the form + form = Form() + form.show() + # Run the main Qt loop + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons.png b/sources/pyside2/doc/tutorials/basictutorial/icons.png new file mode 100644 index 0000000000000000000000000000000000000000..0bcfd7d777f8b6b54ca079ae890a720ccfbdc168 GIT binary patch literal 3202 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 Xp`F~rs09^s00000NkvXXu0mjfudJ~P literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/play.png b/sources/pyside2/doc/tutorials/basictutorial/icons/play.png new file mode 100644 index 0000000000000000000000000000000000000000..345685337432ed97aa888ae83b4127097c56d051 GIT binary patch literal 970 zcmV;*12z1KP)EX>4Tx04R}tkv&MmKpe$iQ;VV%1v`j1M5y9mK~%(1t5Adrp;l;lcSTOimEM7-bHv;>vMmOZZ%^uz$X&VGQ+fqH;AV< zZG-bZafsz*mH3=^%%lqvKXP61_>FVUWr1gg%w%GoI7BSwnpkOKmNzxxDdMoI>69;| zJXSexan_1uR=+2IVKAewEOVXaAYxd=5+sOFP(}eo*oe@olVTx3`_UHu0oN~)OCeVQ zj2sInL4)l2!T;cQw^nv?!b=K9fxwI7d<+BayFjhtIN!&PQ#%3t&%l-5@RzE<%qQuU zh88{odbWX!>xQQ60hc>K|C1q`vMc#%3fV01en#Jv2KsJ+&NZ*M`aVt{fFyMlzX1*o zfsq_#ueW%2M{{rgo~ifu18`n)rb+*pCIA2c24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jm3{5Gfms_CX>@2HM@dakSAh-}0004@Nklt15gbYk`Io$bY z=AVCt|MtvQY4fcguQ7>1e8&!c^$OH57Ewor8=PVRBfS7Hj-SZe_<1jYbOMm0g-uj3 zP-Y9V4j^(guz`ux0Qy4}zJ_e`F8&A0WmM!1KH)3^M2=(3m(iB@IEn<3VGp%fqV`3+ zIl@8EhQXj6l@7Y{64RK)7%syYH&Rq%1WRZ}RwTy-R#I|g0CV^jvWf-M!fqK;^C3(^ zEJs#S11KtT5TPAKOYZDN0suo8eZ;>GQ)j=3>&O-~f>tD%h6S8FVjAlBh*wX|xEhvG zE0X!=_?%*c78-C7$@Xo$P1WaWxQeofz&|jRiewXEHzIHot6_U4 zv6(Ix(S5&6MX-WoHC#oKY(4dDSc_nIhTkc(zHj?of?o$ADdiCD1faNb=E@9SwBWc+ s;F&T5S00e?T^Of2w(#ZQ`uykY7Q`14>GGG*mH+?%07*qoM6N<$f&`kV0RR91 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png b/sources/pyside2/doc/tutorials/basictutorial/icons/previous.png new file mode 100644 index 0000000000000000000000000000000000000000..979f185655294634eb8dd91c7bb77419607ce948 GIT binary patch literal 1050 zcmV+#1m*jQP)EX>4Tx04R}tkv&MmKpe$iQ;VV%1v`j1M5y9mK~%(1t5Adrp;l;lcSTOimEM7-bHv;>vMmOZZ%^uz$X&VGQ+fqH;AV< zZG-bZafsz*mH3=^%%lqvKXP61_>FVUWr1gg%w%GoI7BSwnpkOKmNzxxDdMoI>69;| zJXSexan_1uR=+2IVKAewEOVXaAYxd=5+sOFP(}eo*oe@olVTx3`_UHu0oN~)OCeVQ zj2sInL4)l2!T;cQw^nv?!b=K9fxwI7d<+BayFjhtIN!&PQ#%3t&%l-5@RzE<%qQuU zh88{odbWX!>xQQ60hc>K|C1q`vMc#%3fV01en#Jv2KsJ+&NZ*M`aVt{fFyMlzX1*o zfsq_#ueW%2M{{rgo~ifu18`n)rb+*pCIA2c24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jm3{5Go8L8`w4g000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0005;Nkly-QnB7{-5gsLLG+{sS3Imp})zDS>9} z*rAZoPMr!0PEL2S;6EUOP!WVqg(6rSiiHk^CbWWs=%Nr}i6BkEl9=S?c6kq64);B| z_r?!|yzoxv;W_Wea~=-db4=VY-(%n@FbhlpC%|{$d=%1Wz&qeGunkmzCkl2N*a9wq zF7OL@Giq1wfqy^<1i%sSJO)>k3kQNV_%EYeUI01~LPNS>;XL4*g)@2Jy5N!H%mY?| z$ppH21_(W38Y7Tq@mP$4o0xhgd!dGFznmDFNZ;>*XQpS1upiPu0gK_^|{V~pdKL^FZnkbY7}+(|Ij0QjVE6y>ZV z`lEX>4Tx04R}tkv&MmKpe$iQ;VV%1v`j1M5y9mK~%(1t5Adrp;l;lcSTOimEM7-bHv;>vMmOZZ%^uz$X&VGQ+fqH;AV< zZG-bZafsz*mH3=^%%lqvKXP61_>FVUWr1gg%w%GoI7BSwnpkOKmNzxxDdMoI>69;| zJXSexan_1uR=+2IVKAewEOVXaAYxd=5+sOFP(}eo*oe@olVTx3`_UHu0oN~)OCeVQ zj2sInL4)l2!T;cQw^nv?!b=K9fxwI7d<+BayFjhtIN!&PQ#%3t&%l-5@RzE<%qQuU zh88{odbWX!>xQQ60hc>K|C1q`vMc#%3fV01en#Jv2KsJ+&NZ*M`aVt{fFyMlzX1*o zfsq_#ueW%2M{{rgo~ifu18`n)rb+*pCIA2c24YJ`L;(K){{a7>y{D4^000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jm3{5Gpd|dc~ap000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}00061Nkl8*3{;#UF(r2!etlQ4A&sCPd*p#4|B>m$RA3vh3{c++DhS zVK{DfmhX4oeBZpc4dcTE4q-Cy*KWLT-XeONVDxTwXWLGnh2wpD} za5xgWY?v1^VJ^dD*l|)O?7>yEbEGR3yN%&}WFt{Da6EIJ4nhXJ4XK!l7X{?)*y3$r zK@a4`SPo&&IC<_qR_#G<(&pc7Hv z9ip1GB0jrNCIFrmJl}~ki2{~NZroCwh+HDGi2|CDay?(C5EbQbzv7)HuHaQL^WVru zmg}gG-Guqu?so7@H=%gd>J9r50k^_YbV5!K(-*Yr2>38!^HEk$?$;48y$R%fyu?(j z4&+VM#`Z+#=R4sip)Fs+$JFnGM>UPLg3q{%Q{!yEr|_(xzw3qZ4%b5ZjZE68_{=(j iy}`lBq1?h2>fj$zD_xvhSU`(A(T*-p;Fe6eHY0(S;|g^QpX`nMAK%MeJI=5M+qlF zwy_LmY*_|lnK2m4_ssdO@1OXtb6s4n`OR;B^S;k}KlgnW z!w7+3XG0*^%zrrmSCofR_~6e$Z!Jq71cFNse*M@Cb^2Bj2q6{i8`n$%-!G1a+)t*n z?X7ev<|02ZLUgUOFQ4m=W0xv_b?A_l;Y3n6`882sD3f?g0dqzpR?PF_(8TtcUFXu~ zH@7h9arus(2d-UR`o*LBdUg39hiDq&N$Os?1HEg^2vQKikvDiUlf;lb#n&|#l-k>) zN?i+W=wb}oNMplD@)fsc;}edWd0XmaFAW$lI3WKJT&EZaLPfrh}vSVaq5A=+n7VGA5`d%0veZ`@5zc+Ef^WG!P?gP z+jOxZ?Bh^M7rk5K1cP@sXXsm$lETVLGu>C`yW_*Q9fRt5%H$ps7YVPVtdrinQCv_c z87Oo~3pJCMmmjV`VYq};@&@jN*(R0;)7|kA?xv>6^Yin*q)$mDdPP?}-Kn@gIl@xlYBlKPz7 z)L@-Ek5-yZaht2{GLnjlmR|UsN-jaAY~gJ(=VUM!0^t)Q!JdlVa&vNambi4OH~38O z8Lx)T9M&T{-pcE8MXIaqZFc#sFIYl_+`lWI*X~kTi*f$`IwL0L2%W*8;P5+(ADQ=@ zoZLP?;W%{Uh{@f%ndtShw7Ie_)t91DmZdl7bh;9HyGqn;w8qb>^8TAAPoA{Y86c5J zD?GYh2)*IJv48(;Mx@XQe;xbH)#7}YzK7Ra|uxOmCZ+i1)bJhAmM7ZRiru%Q)yeY1z81$84psn3qU|Lw@K#lsH zo7+Lq0^j*urXlagkK2nwWtyKqe-7T;VPJdNdZvxpQG}xIlz_4P@NfjHJ0^#714yCf zP(N0s=zA(c@na!WByw}=W#ZIj&h)}UU1^N2wzhUDanaq=(=03u&&%%T=cl8ilPLP^ z>C-$MZeVNV`7xO-52B|_H7BBR*0wjR6&^;*Rol@{3)`)(vnx?jQldfsxO;mqTX~u# z_Kl4dfB$}qgOjr`H&-)kk4f6`>}qfC&DMTNTPW*t?=LVd9lGy0W(K9L^dRQoNNDR? z|HabX?Vp$NEBqXmaMTi#lKmu73C1p1``NQ+I=60_=2 zDU7yAl=Jy{%Y#^{m)JKtip7luw|g;HR#pnISi!a3eTeVAdLs7SnKy&yK455tcXo7G zg$7u_IbA5;x1@z+jQ9jo>lv&jn$uL7gETS|8VrgsBL4`B~@oL5ibl=(AGS^OQ8vg-(YHDVdGuN9-IfmbOW*0QgJ3TX_ zTT}Prwu?*d&#ttR{zCJkA<_m&dJ>vZOA?otHw|MFNiB361mfq%H`~%r8jSb9yX@8Q zFZ=nqEPR^+%Bo*!;SXN;)apqqMj*V^V_fgr`})$%cf&C4@)^pP2sA)+oyP~XXvGdrc__-}6vwvtvd~TJvc7TJ!7UvOC zZ%3!m@@i|Xfdw2K93EZ~;8`8qw{KrTet!4TXl*}W0t$kHzBjl1wrusFc9exT6sl0# zt}YMSUfvS|0w%`BFNcSRO>At6 zXf)cvp%$$`6(Lh|^TP6S6U}&`iYM*PWo~Ur;;afMy?_5`be*&6PZLwqd@NS)n6%AC z8*y@Cf+cW8MMac4m&O+f;i1g+{HiJoq4-wnWP+=gm${x^EPMrgdA7K5&bjmF7i#L9 zK6Y)c&Co$2@_=eU{6HDHL2sOJ#Oakl+K@|{Tl*_1cMp$b-_3LtLvHfJY7;xVV%T`c z>x=4TE?s8c-XBS!1%-tbPVIbtzP{&9p1ca+=HX)#iq}j@Nr9~;4N#InF&aXdzN=H( ztYZfmV|AO@J!|zKIGFYIwnhKKni?yhI&(+ItPxM#Uv|Os^kA0Ot*$;qZjd8*8iX4= z3JMBz>`Kf7M*RkOsR86hHYgCPCFaiom)7vTuITWIiMyfwt>%*}fxZia7k5DJ656K$ z^0zfK{)&!{mUC>0p~#9NuUyIN=`l*V^5Bcoh5r72H*fFT{3|R)pE8i^qMb70B2dYR-b(Om{!1hITU)`+U%%#MXWuw@ z@Zj4^E^)Ada`aAcMS1x@6nYzlUQl0en}*)X2eI=TunmX}5xQYu5HBGi;XCyYH_MM4 zld;=wyW7ztw4^kKQou%@d{_#-&c6o)7vW_w0f_9V8EI)ZE49<@QU|UQ&ZEnuC4*FXvr^LK;;!Pau2e&zFSjx zGbJo8D#{Qj5w^!Aa3x(ml50~iJl7zt_}SrOaT}3qI`Bs4dqqd&tETZ6P2|l`jr{Qm?PCPn5==zVqqsGuU-fN(#35`7sojD1wYI>FL*4{>y-V z-RFE#MkXeGc{pNEPbStHH&6Z?0i`Vciy5iP`K}{}Otx=sZIuL8NJvPq!g;0u$o)b9 zX7Y;iY$Nv{squ^KC^G6_Y*c>l{c^df%7An5zQTu`ocYv{rEUV&8d~9Ge5>P*`qIKe z9}t$Qtt~ca?dRM&(JSqv@qXwEs0NzTp?0+R{d<8AA3n@M7Y{dt){=gNftbINwk@#s ztaiG-J`UwV&)}QBeEH+V3HP1)iV9OFCnv)0(0v7`d-r0h*F%DXw;LKFxde?YEM70w zGweX%@;`pO&CSg{T=gJJev5qgaf)&PsOfD3E1CEU%r=hMMk)!v{zke~biu(61wUt*XEPt|q!QrWq znkrqt`U5M__rSR9wEb-1ZbA&=$h5DLyi2D5I1|^&mRP00<#ZtTGq$R?nVkk+V|A8r zY7*zp-S+e>{?gRc>i5k8h*WiRiU&W=c=6&lAXo8o=d^&O|8@B4$A9}R9SBcSM8xsB zh6q5Qt-T%V;0cR<`gDJDON$kbI#S&`tOggrVReAWeJ9@1);0_btO6l8H@Es?5{eH` z{c!U+-?us6d1caO+>?k1mOr1T&Gi!2s1!=??hcbqjyM{(Me!^fDk^zH#e;(aeHi%u z=90YEmA-f&pDx~D=dV_m;zLk^rt##)6tF^_G+eY?ZXnrjRLwSy)U# zNy)(aBGHfNfpc3Lsn*fg7ou0sgY0;W)|kSqh0a0*1qJDVeS?xzgfjgprZpYT#zsbo z40Tp#eRZ|2GT_6q9C)?A+W!&=~&9o+jYU z=zgQ6PS0g!W##XF-Yp6$gEY36>KBKLPDimTCan!2+hD&(CwR zvOQGHYiczI2Z#8@i`_NX)oWB_WfNyS0|t4I3lxMSq7F4)PRJ^8=}T*xL)dr`v>E}( zbW`E@zhKEWHt&J2%_vzW-1WsIno@(;|+;eE*DlTRiVSGX1ccHkX@L0AvTobF!EU6pBwc5ZRRR_3I5u zS+ptW&i7 z<;?W-#v1p#Dqo=O1Oyfs$Xhx(HS^m~8XK?TOV+eBPom4@4E9`_!u&GnJ^j=pBTrS3 zwms@NcTs8|2qEup_I<-1Rob`ynG2UG8@eAI7e|ALv(uo<1064FtLh4q0g63kfMN=&0pRxop#*PJn4W&s zIOmoji^3vXkwWp%vODXi;r02rxP=A`*#}VYfl?z$9HbxabdShL&+#Ul; zCPqe?F!viGamB^bp)1YD&?4NITsm3&1Uw*ZTQkKt1f)#qRHm9}Y5nu`2m=5wDJ`vk z)*v;BhOa)BtDjOT#ucn01ml}U+9a_x!(1jN3EYL2*5C5w)aM0&2uY0&%&}M&*MPQU z5j|@?lDdv>I3MKVGK24d>DYA#y}8;I?KS!W6iNKlsn1^Jzg7u}(R>>*o4b#hgo?ca zj^IZFFK4EvVm2P^gRmeWVH~Fw3kPOyj`63CN#TfC@HwNQjM3=W*nVImzws{|6w}Qg zYm*>vESsev$i|ZSrA_$W~7ysRnqI%8x?8C`1qU`=_wD7`NMufj^GldM zlEjVWfX{jP_~JG`335gL>`aj?89+&KEGScdzGGvl?q~?LzU|vLLp!@va1bUyYs14< zC6V4ZYHXzO=4$@6 zp(CgEKY9r_J_v8sYmW|(QW5;o-JJmm$sCNfKVXdiOE2ai1O#9(9{TtsCnRK4RaF_5 zoSXGkGPSVC+t>*7AT`)V9u;1`~PYlvftYDfLxvP*^dDhbj7u5{XU@CEtq=7&BxA|c9mG6Ni`N6cn%Ci`; z(a}cNu6?fRQbY$G@Nshbz$L6&1f=d45KvfBLPeSD03{N%5Hm2v=b(MCHq}N9QW)N>$RY!B1UxZRgdgs!p%biI<&RJ= z(I|iZ{(B}oC6pRM>IIeB(U(7RI-0>&oTchDX-IGtR@9s7C_!bwycDmX>c=`oFu2#>bcB z05dBGEcJokV37bm!;U10hZT;{$DFD&|BBlUT76-!Y1|J3gqW2HmM*Abq z0FvZ(Mvi_8D*zN!L)(BZ_ZC@}iHQb2y2x|lL;)}j%R|a{}o&pv-V)f}qK*3pAStHPCa4{^m5Am+p_Na&&7(f<_@NB(qq_^N5N6r^v zrqz#bh#+}yo0@)rS7|4q>G+>lPBIW>a$X4c-_T` zi3t-ElWchYnC$uiHx#N&)n6&4t)oMbF&(AaF#U#yhX)&##uXWH#(<5??`nguE-Ncz z4ZLeJU6Q9yUxy}o3$ek+%SoT&Rwawk%<+Sw=Kyvu|Y*#+DWpWuM8uWXqPyXc|ltC5$!0 z$QV?NF(DayX3Tr~{`CF4|G@i8Kb`YA_jAtk+{<;{*L@y4J6a3!N%Da}AVFIjOBWCb z%mD&%c<_LMC+If5bHIfYZf@(w!^1QA-RT<$BzDi%@|;_Y&+-&+L(y#K{u_!fj2* zeSRWQugrjaDT(`qjh;z}u5vo2Xm-a;@o-?dp#EH@#h<q^f{eQ9D%hMf?#NNSANcmbpJDwZDA4gI<~8DWZ8UwFVTPU0WO#cfF&BLt3| zzTBU822LAPH)YLcm`WQ&UT5#IqNihNeHv{`fq)VD~kE?xcB35xrL%bf!ooe zXKyb78~C)BYWfj=fB(3)m#X^GMxdtnw%2)1VN>P}Z_h({KsrJ$mQi)fPy#pxL3JDk zA28mc|EZ;Sv+30C!(;9q-bmE9F%REjoe-!? zZ%s{6B&2qa_4}hRux{<3{P|Jj)mC;MYLx*5l7U#&`QY2X;UDcwS>5hpYFTcp{ z(jR&aF>C0XJd4Gkm#uHPW}b*%ZW&i-^y@?U!LkopMCOsMvRPX)df~9zogm3(dEkHx zW?*Bl{>8t6k<{&Q@rLph{oDpZpweWEXEOTS7Lc8K#wBhpJN_L88=)0Whu!ODF*Av~ zTkLjCyBrWN>US+mYY)hy;;*)q_tiI{1`G;(s4BWN<-`?7LwaSu&PinBTe3=0c=Ld6 z*JG(L^aUvYNC~xq!iR*G>+dxsu@(W$)E~lT`~}zrE*0ov6}Zx8aPIsDqjK8b!K=T> zP1uu8bkLosd~vsMU(cb{6sd6iFfw{$+}E^Ts0-$N*UwO?p7`+C?TeB%YF66DuL)V& z9uj<&c;EXwYeS~QOxUe2Ry)n;eZPrLrqqYpe>N7MwWLAK>KjtRHkaS5T@39WR0X**Jw;cd1@#{@~oM0mO1dRsn7apYOMQnl$@V z&wpO=uyfqfYimjDr3jo(MW%rDh>+hQ6-wR~phrOJt7o z9*}+YmWy01sQ=@UyvsG8$ljCrinh4?d{nCn_2+{j?F)uQuS}Kbd%h~DN69p(-(A7uUq0crzXM9vQ5$ZwV21~u z(aEjhBfTn^`(O0S9;9N6 z?z+#gH21$8IkW&U5Nu_9I5f58gja-l=V5@UiurFXVasl(tH%9B5)FJTM&m_sA3+)* zXfoa`!-#Wi53c+Wu*tqMgdk(g&hsR>tCA5B&HLOHK-+W&&yCB5*hCe<%Il z489&XCCs`fZwC0`D0}(nFzG5o-f_!iEcFp;ayjS377kYB&Xd(AzGx z^Z$-G0-8&rE%km0om**Nb4)yE+=kQLt-W{5tL%z~lAzgzCnJSocF5AGK4ez9McQ$0 zz!78qO8LB}zf%Mxvi-{@Jjf}cs!$PD*Cy;hY{&z%k1HwuT+T%>1o0{i8>rw^QuGu$ z5_)~{TY5|K)!ICXZV`i_DqjRl!064UD8)^9YVFrb56{IN^=*&2nd(XIeBZ^a$(wkkWin==z_vaX z<(BGfoae-w%auyTBcw7Lo70YiF^&qur-cFm^mAnO$%$K^=d?qq^$Mj;RN;a)yw7^> z6RRz=&XAr8^wAV$HF!3gu-1uZu6@o$$l3k@nqdJz+L9$VXFrdXK+F|}o+c_OCsq3l zTGuwYPLf0~flYzd8pNqt;0V7Myl*6eKq5>C7^nsD5@uoVZd}pr=_eHiB?sH9Vj-Nv zSEsWP8&l#Xv1=@LF>{&`!S=p*3Vd*TZM-yGs^!v#F32rFG%%18qGOllZr^->UK!AO zTB;!+dS*$Tf=^)y8f3q`wdZh6 zD{ga1Ld(C>6-KbA3c*aw70kDH$q#%cE?k!D6h;0tQpGWZIK#Txg5 zHu>oS&gb_E7!7w%G}nK&s-m$Gr971G{`GA>f3Vv;%%0we-z10Be(KJU@%7NktXJPE z^l#o?uhpWtPOtPRFmeYO?_A574%*2X}u>pPIqK}5}T+r@WpQ*SJp zoTcJ7Qxr@?F39R7_~RN0-1%&}E+7vZVj8>bAqX8_^aRYgg6Ri7Bku60J)ff~GE7I^ z9UOq)J{p05s*oUu7aTbCo?@9cvD@tt2n11nOg?ly=q7?lnUC>$0Q9!oKSyi3lv@ydkp4-TA_Z5`WoiTO#dWaA859k&s^RBwpya)z>P4v*A}J0m6NUh^+TR zacMT@*7RRGbAM@~IY6V$a%|zQs&~P$ALb3YlRsh#K3A(-cH^GRwO8<8f33nFfo-hF zOHe=MxH64fGkr6Yy0GATvx+-*Ct<__YX( zfFP$(z`4pBx2h&%wVa*T7sn&$BURL>g!CE_>`84)tR8v<^Fu#b=TxSbj}?A?VjPhw zh!@S`{`&l*55hHK&?TCd(nC3dV6Jx4Ai>_8&L;{|H8XewWK4`^iHw-+k6H58(uv#O zvBtODe>7nNH&UFYvp>#hVbx{!QDY#vkxwOc>QLPYiw+(!e>J}9@GEI&ics!g6x|{1 zps4Zc=y)u3b!v3iKraM@l|hdcumAYOEaV}&4&HZ>1}h~Fp5CA1{FB5fq%S*kg&HF* zp=zvs$s_eCm^SpoT_v)@^irh~_(WW6j`f`8AwH|RU9}K#lN~+HF6KpO5Aldd>sy~U9?AeT(ZV`daQ04rtH{=5?)2zI#yZ?pUIx%3^tEbI$P_0BH3%8p>XuvU zlwtB`;q|p{|1g6Pfi7!Xxx=}(tM?B(_B?S_B}oOVdEq*;bLJGW5WwHNap>6tO5^P)(G^Ul8tef^1jdah)7>vQkMXg-@8(|+{#C+16#PTMKNS2!!T%TqWjQ=dQ%+pm$`G>K S2>3e + + + icons/play.png + icons/pause.png + icons/stop.png + icons/previous.png + icons/forward.png + + + + +Generating a Python file +========================= + +Now that the `icons.qrc` file is ready, use the `pyside2-rcc` tool to generate +a Python class containing the binary information about the resources + +To do this, we need to run:: + + pyside2-rcc icons.rc -o rc_icons.py + +The `-o` option lets you specify the output filename, +which is `rc_icons.py` in this case. + +To use the generated file, add the following import at the top of your main Python file:: + + import rc_icons + + +Changes in the code +=================== + +As you are modifying an existing example, you need to modify the following +lines: + +.. code-block:: python + + from PySide2.QtGui import QIcon, QKeySequence + playIcon = self.style().standardIcon(QStyle.SP_MediaPlay) + previousIcon = self.style().standardIcon(QStyle.SP_MediaSkipBackward) + pauseIcon = self.style().standardIcon(QStyle.SP_MediaPause) + nextIcon = self.style().standardIcon(QStyle.SP_MediaSkipForward) + stopIcon = self.style().standardIcon(QStyle.SP_MediaStop) + +and replace them with the following: + +.. code-block:: python + + from PySide2.QtGui import QIcon, QKeySequence, QPixmap + playIcon = QIcon(QPixmap(":/icons/play.png")) + previousIcon = QIcon(QPixmap(":/icons/previous.png")) + pauseIcon = QIcon(QPixmap(":/icons/pause.png")) + nextIcon = QIcon(QPixmap(":/icons/forward.png")) + stopIcon = QIcon(QPixmap(":/icons/stop.png")) + +This ensures that the new icons are used instead of the default ones provided +by the application theme. +Notice that the lines are not consecutive, but are in different parts +of the file. + +After all your imports, add the following + +.. code-block:: python + + import rc_icons + +Now, the constructor of your class should look like this: + +.. code-block:: python + + def __init__(self): + super(MainWindow, self).__init__() + + self.playlist = QMediaPlaylist() + self.player = QMediaPlayer() + + toolBar = QToolBar() + self.addToolBar(toolBar) + + fileMenu = self.menuBar().addMenu("&File") + openAction = QAction(QIcon.fromTheme("document-open"), + "&Open...", self, shortcut=QKeySequence.Open, + triggered=self.open) + fileMenu.addAction(openAction) + exitAction = QAction(QIcon.fromTheme("application-exit"), "E&xit", + self, shortcut="Ctrl+Q", triggered=self.close) + fileMenu.addAction(exitAction) + + playMenu = self.menuBar().addMenu("&Play") + playIcon = QIcon(QPixmap(":/icons/play.png")) + self.playAction = toolBar.addAction(playIcon, "Play") + self.playAction.triggered.connect(self.player.play) + playMenu.addAction(self.playAction) + + previousIcon = QIcon(QPixmap(":/icons/previous.png")) + self.previousAction = toolBar.addAction(previousIcon, "Previous") + self.previousAction.triggered.connect(self.previousClicked) + playMenu.addAction(self.previousAction) + + pauseIcon = QIcon(QPixmap(":/icons/pause.png")) + self.pauseAction = toolBar.addAction(pauseIcon, "Pause") + self.pauseAction.triggered.connect(self.player.pause) + playMenu.addAction(self.pauseAction) + + nextIcon = QIcon(QPixmap(":/icons/forward.png")) + self.nextAction = toolBar.addAction(nextIcon, "Next") + self.nextAction.triggered.connect(self.playlist.next) + playMenu.addAction(self.nextAction) + + stopIcon = QIcon(QPixmap(":/icons/stop.png")) + self.stopAction = toolBar.addAction(stopIcon, "Stop") + self.stopAction.triggered.connect(self.player.stop) + playMenu.addAction(self.stopAction) + + # many lines were omitted + +Executing the example +===================== + +Run the application by calling `python main.py` to checkout the new icon-set: + +.. image:: player-new.png + :alt: New Multimedia Player Qt Example + +.. _`Qt Resource System`: https://doc.qt.io/qt-5/resources.html diff --git a/sources/pyside2/doc/tutorials/basictutorial/style.qss b/sources/pyside2/doc/tutorials/basictutorial/style.qss new file mode 100644 index 0000000..b84b98f --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/style.qss @@ -0,0 +1,23 @@ +QListWidget { + color: #FFFFFF; + background-color: #33373B; +} + +QListWidget::item { + height: 50px; +} + +QListWidget::item:selected { + background-color: #2ABf9E; +} + +QLabel { + background-color: #FFFFFF; + qproperty-alignment: AlignCenter; +} + +QPushButton { + background-color: #2ABf9E; + padding: 20px; + font-size: 18px; +} diff --git a/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst new file mode 100644 index 0000000..9823846 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/uifiles.rst @@ -0,0 +1,187 @@ +Using `.ui` files from Designer or QtCreator with `QUiLoader` and `pyside2-uic` +******************************************************************************* + +This page describes the use of Qt Creator to create graphical +interfaces for your Qt for Python project. +You will need **Qt Creator** to design and modify your interface (UI file). + +If you don't know how to use Qt Creator, refer to the +`Using Qt Designer `_ +documentation page. + +At Qt Creator, create a new Qt Design Form, choose "Main Window" for template. +And save as `mainwindow.ui`. +Add a `QPushButton` to the center of the centralwidget. + +Your file ``mainwindow.ui`` should look something like this: + +.. code-block:: xml + + + + MainWindow + + + + 0 + 0 + 400 + 300 + + + + MainWindow + + + + + + 110 + 80 + 201 + 81 + + + + PushButton + + + + + + + 0 + 0 + 400 + 20 + + + + + + TopToolBarArea + + + false + + + + + + + + + +Now we are ready to decide how to use the **UI file** from Python. + +Option A: Generating a Python class +=================================== + +Another option to interact with a **UI file** is to generate a Python +class from it. This is possible thanks to the `pyside2-uic` tool. +To use this tool, you need to run the following command on a console:: + + pyside2-uic mainwindow.ui > ui_mainwindow.py + +We redirect all the output of the command to a file called `ui_mainwindow.py`, +which will be imported directly:: + + from ui_mainwindow import Ui_MainWindow + +Now to use it, we should create a personalized class for our widget +to **setup** this generated design. + +To understand the idea, let's take a look at the whole code: + +.. code-block:: python + + import sys + from PySide2.QtWidgets import QApplication, QMainWindow + from PySide2.QtCore import QFile + from ui_mainwindow import Ui_MainWindow + + class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + if __name__ == "__main__": + app = QApplication(sys.argv) + + window = MainWindow() + window.show() + + sys.exit(app.exec_()) + +What is inside the *if* statement is already known from the previous +examples, and our new basic class contains only two new lines +that are in charge of loading the generated python class from the UI +file: + +.. code-block:: python + + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + +.. note:: + + You must run `pyside2-uic` again every time you make changes + to the **UI file**. + +Option B: Loading it directly +============================= + +To load the UI file directly, we will need a class from the **QtUiTools** +module: + +.. code-block:: python + + from PySide2.QtUiTools import QUiLoader + +The `QUiLoader` lets us load the **ui file** dynamically +and use it right away: + +.. code-block:: python + + ui_file = QFile("mainwindow.ui") + ui_file.open(QFile.ReadOnly) + + loader = QUiLoader() + window = loader.load(ui_file) + window.show() + +The complete code of this example looks like this: + +.. code-block:: python + + # File: main.py + import sys + from PySide2.QtUiTools import QUiLoader + from PySide2.QtWidgets import QApplication + from PySide2.QtCore import QFile, QIODevice + + if __name__ == "__main__": + app = QApplication(sys.argv) + + ui_file_name = "mainwindow.ui" + ui_file = QFile(ui_file_name) + if not ui_file.open(QIODevice.ReadOnly): + print("Cannot open {}: {}".format(ui_file_name, ui_file.errorString())) + sys.exit(-1) + loader = QUiLoader() + window = loader.load(ui_file) + ui_file.close() + if not window: + print(loader.errorString()) + sys.exit(-1) + window.show() + + sys.exit(app.exec_()) + +Then to execute it we just need to run the following on a +command prompt: + +.. code-block:: python + + python main.py diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgets.rst b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst new file mode 100644 index 0000000..41e4742 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgets.rst @@ -0,0 +1,45 @@ +Your First QtWidgets Application +********************************* + +As with any other programming framework, +you start with the traditional "Hello World" program. + +Here is a simple example of a Hello World application in PySide2: + +.. code-block:: python + + import sys + from PySide2.QtWidgets import QApplication, QLabel + + app = QApplication(sys.argv) + label = QLabel("Hello World!") + label.show() + app.exec_() + + +For a widget application using PySide2, you must always start by +importing the appropriate class from the `PySide2.QtWidgets` module. + +After the imports, you create a `QApplication` instance. As Qt can +receive arguments from command line, you may pass any argument to +the QApplication object. Usually, you don't need to pass any +arguments so you can leave it as is, or use the following approach: + +.. code-block:: python + + app = QApplication([]) + +After the creation of the application object, we have created a +`QLabel` object. A `QLabel` is a widget that can present text +(simple or rich, like html), and images: + +.. code-block:: python + + # This HTML approach will be valid too! + label = QLabel("Hello World!") + +.. note:: After creating the label, we call `show()` on it. + +Finally, we call `app.exec_()` to enter the Qt main loop and start +to execute the Qt code. In reality, it is only here where the label +is shown, but this can be ignored for now. diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-no.png new file mode 100644 index 0000000000000000000000000000000000000000..c30dd621ba2143c89e462642889608f659e13f4b GIT binary patch literal 26444 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 yeB>`lK(04MN1Pap6EC6EfYDc{ul<*&PQDB7t literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling-simple-yes.png new file mode 100644 index 0000000000000000000000000000000000000000..5a714977ee30a1ee93f083e9e56489cfceeacea8 GIT binary patch literal 4743 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py new file mode 100644 index 0000000..41af464 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.py @@ -0,0 +1,95 @@ +############################################################################# +## +## Copyright (C) 2020 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +from PySide2.QtCore import Qt +from PySide2.QtWidgets import (QApplication, QHBoxLayout, QLabel, QListWidget, + QListWidgetItem, QPushButton, QVBoxLayout, + QWidget) + +_placeholder = """ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod +tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim +veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea +commodo consequat. Duis aute irure dolor in reprehenderit in voluptate +velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint +occaecat cupidatat non proident, sunt in culpa qui officia deserunt +mollit anim id est laborum +""" + + +class Widget(QWidget): + def __init__(self, parent=None): + super(Widget, self).__init__(parent) + + menu_widget = QListWidget() + for i in range(10): + item = QListWidgetItem("Item {}".format(i)) + item.setTextAlignment(Qt.AlignCenter) + menu_widget.addItem(item) + + text_widget = QLabel(_placeholder) + button = QPushButton("Something") + + content_layout = QVBoxLayout() + content_layout.addWidget(text_widget) + content_layout.addWidget(button) + main_widget = QWidget() + main_widget.setLayout(content_layout) + + layout = QHBoxLayout() + layout.addWidget(menu_widget, 1) + layout.addWidget(main_widget, 4) + self.setLayout(layout) + + +if __name__ == "__main__": + app = QApplication() + + w = Widget() + w.show() + + _style = None + with open("style.qss", "r") as f: + _style = f.read() + app.setStyleSheet(_style) + + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst new file mode 100644 index 0000000..a79f9c8 --- /dev/null +++ b/sources/pyside2/doc/tutorials/basictutorial/widgetstyling.rst @@ -0,0 +1,169 @@ +Widget Styling +************** + +Qt Widgets application use a default theme depending on the platform. +In some cases, there are system-wide configurations that modify the Qt theme, +and applications are displayed differently. + +However, you can take care of your own widgets and provide a custom style +to each component. As an example, look at the following simple snippet: + +.. code-block:: python + + import sys + from PySide2.QtCore import Qt + from PySide2.QtWidgets import QApplication, QLabel + + if __name__ == "__main__": + app = QApplication() + w = QLabel("This is a placeholder text") + w.setAlignment(Qt.AlignCenter) + w.show() + sys.exit(app.exec_()) + +When you execute this code, you will see a simple `QLabel` aligned at the +center, and with a placeholder text. + +.. image:: widgetstyling-simple-no.png + :alt: Simple Widget with no style + +You can style your application using the CSS-like syntax. +For more information, see `Qt Style Sheets Reference`_. + +A `QLabel` can be styled differently by setting some of its CSS +properties, such as `background-color` and `font-family`, +so let's see how does the code look like with these changes: + +.. code-block:: python + + import sys + from PySide2.QtCore import Qt + from PySide2.QtWidgets import QApplication, QLabel + + if __name__ == "__main__": + app = QApplication() + w = QLabel("This is a placeholder text") + w.setAlignment(Qt.AlignCenter) + w.setStyleSheet(""" + background-color: #262626; + color: #FFFFFF; + font-family: Titillium; + font-size: 18px; + """) + w.show() + sys.exit(app.exec_()) + +Now when you run the code, notice that the `QLabel` looks different with your +custom style: + +.. image:: widgetstyling-simple-yes.png + :alt: Simple Widget with Style + + +.. note:: + + If you don't have the font `Titillium` installed, you can try with any + other you prefer. + Remember you can list your installed fonts using `QFontDatabase`, + specifically the `families()` method. + + +Styling each UI element separately like you did in the previous snippet is a +lot of work. The easier alternative for this is to use Qt Style Sheets, +which is one or more `.qss` files defining the style for the UI elements in +your application. + +More examples can be found in the `Qt Style Sheet Examples`_ documentation +page. + + +.. _`Qt Style Sheets Reference`: https://doc.qt.io/qt-5/stylesheet-reference.html +.. _`Qt Style Sheet Examples`: https://doc.qt.io/qt-5/stylesheet-examples.html + +Qt Style Sheets +=============== + +.. warning:: + + Before starting modifying your application, keep in mind that you will be + responsible for all the graphical details of the application. + Altering margins, and sizes might end up looking strange or incorrect, so you + need to be careful when altering the style. + It's recommended to create a full new Qt style to cover all the possible + corner cases. + +A `qss` file is quite similar to a CSS file, but you need to specify the Widget +component and optionally the name of the object:: + + QLabel { + background-color: red; + } + + QLabel#title { + font-size: 20px; + } + +The first style defines a `background-color` for all `QLabel` objects in your +application, whereas the later one styles the `title` object only. + +.. note:: + + You can set object names with the `setObjectName(str)` function to any Qt + object, for example: for a `label = QLabel("Test")`, you can write + `label.setObjectName("title")` + + +Once you have a `qss` file for your application, you can apply it by reading +the file and using the `QApplication.setStyleSheet(str)` function: + +.. code-block:: python + + if __name__ == "__main__": + app = QApplication() + + w = Widget() + w.show() + + with open("style.qss", "r") as f: + _style = f.read() + app.setStyleSheet(_style) + + sys.exit(app.exec_()) + +Having a general `qss` file allows you to decouple the styling aspects of +the code, without mixing it in the middle of the general functionality, and you +can simply enable it or disable it. + +Look at this new example, with more widgets components: + +.. literalinclude:: widgetstyling.py + :linenos: + :lines: 59-81 + +This displays a two column widget, with a `QListWidget` on the left and a +`QLabel` and a `QPushButton` on the right. It looks like this when you run the +code: + +.. image:: widgetstyling-no.png + :alt: Widget with no style + +If you add content to the previously described `style.qss` file, you can modify +the look-n-feel of the previous example: + +.. literalinclude:: style.qss + :linenos: + +The style changes mainly the color of the different widgets, alter the +alignment, and includes some spacing. +You can also use state-based styling on the QListWidget *items* for example, to +style them differently depending on whether they are *selected* or not. + +After applying all the styling alternatives you explored in this topic, notice +that the `QLabel` example looks a lot different now. +Try running the code to check its new look: + +.. image:: widgetstyling-yes.png + :alt: Widget with style + +You have the freedom to tune your style sheets and provide a really nice +look-n-feel to all your applications. diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst new file mode 100644 index 0000000..95b2092 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_chart.rst @@ -0,0 +1,20 @@ +Chapter 5 - Add a chart view +============================= + +A table is nice to present data, but a chart is even better. For this, you +need the QtCharts module that provides many types of plots and options to +graphically represent data. + +The placeholder for a plot is a QChartView, and inside that Widget you can +place a QChart. As a first step, try including only this without any data to +plot. + +Make the following highlighted changes to :code:`main_widget.py` from the +previous chapter to add a QChartView: + +.. literalinclude:: datavisualize5/main_widget.py + :linenos: + :lines: 40- + :emphasize-lines: 2-3,6,22-36,48-50 + + diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst b/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst new file mode 100644 index 0000000..a9ff38a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_mainwindow.rst @@ -0,0 +1,32 @@ +Chapter 3 - Create an empty QMainWindow +========================================== + +You can now think of presenting your data in a UI. A QMainWindow provides a +convenient structure for GUI applications, such as a menu bar and status bar. +The following image shows the layout that QMainWindow offers out-of-the box: + +.. image:: images/QMainWindow-layout.png + :alt: QMainWindow layout + :align: right + +In this case, let your application inherit from QMainWindow, and add the +following UI elements: + +* A "File" menu to open a File dialog. +* An "Exit" menu close the window. +* A status message on the status bar when the application starts. + +In addition, you can define a fixed size for the window or adjust it based on +the resolution you currently have. In the following snippet, you will see how +window size is defined based on available screen width (80%) and height (70%). + +.. note:: You can achieve a similar structure using other Qt elements like + QMenuBar, QWidget, and QStatusBar. Refer the QMainWindow layout for + guidance. + +.. literalinclude:: datavisualize3/main_window.py + :language: python + :linenos: + :lines: 40- + +Try running the script to see what output you get with it. diff --git a/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst new file mode 100644 index 0000000..7209180 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/add_tableview.rst @@ -0,0 +1,70 @@ +Chapter 4 - Add a QTableView +============================= + +Now that you have a QMainWindow, you can include a centralWidget to your +interface. Usually, a QWidget is used to display data in most data-driven +applications. Use a table view to display your data. + +The first step is to add a horizontal layout with just a QTableView. You +can create a QTableView object and place it inside a QHBoxLayout. Once the +QWidget is properly built, pass the object to the QMainWindow as its central +widget. + +Remember that a QTableView needs a model to display information. In this case, +you can use a QAbstractTableModel instance. + +.. note:: You could also use the default item model that comes with a + QTableWidget instead. QTableWidget is a convenience class that reduces + your codebase considerably as you don't need to implement a data model. + However, it's less flexible than a QTableView, as QTableWidget cannot be + used with just any data. For more insight about Qt's model-view framework, + refer to the + `Model View Programming ` + documentation. + +Implementing the model for your QTableView, allows you to: +- set the headers, +- manipulate the formats of the cell values (remember we have UTC time and float +numbers), +- set style properties like text alignment, +- and even set color properties for the cell or its content. + +To subclass the QAbstractTable, you must reimplement its virtual methods, +rowCount(), columnCount(), and data(). This way, you can ensure that the data +is handled properly. In addition, reimplement the headerData() method to +provide the header information to the view. + +Here is a script that implements the CustomTableModel: + +.. literalinclude:: datavisualize4/table_model.py + :language: python + :linenos: + :lines: 40- + +Now, create a QWidget that has a QTableView, and connect it to your +CustomTableModel. + +.. literalinclude:: datavisualize4/main_widget.py + :language: python + :linenos: + :emphasize-lines: 12-17 + :lines: 40- + +You also need minor changes to the :code:`main_window.py` and +:code:`main.py` from chapter 3 to include the Widget inside the +MainWindow. + +In the following snippets you'll see those changes highlighted: + +.. literalinclude:: datavisualize4/main_window.py + :language: python + :linenos: + :lines: 40- + :emphasize-lines: 8,11 + +.. literalinclude:: datavisualize4/main.py + :language: python + :linenos: + :lines: 40- + :emphasize-lines: 46-47 + diff --git a/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv b/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv new file mode 100644 index 0000000..400947c --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/all_hour.csv @@ -0,0 +1,8 @@ +time,latitude,longitude,depth,mag,magType,nst,gap,dmin,rms,net,id,updated,place,type,horizontalError,depthError,magError,magNst,status,locationSource,magSource +2019-01-10T12:11:24.810Z,34.1281662,-117.7754974,4.46,1.18,ml,22,69,0.04475,0.13,ci,ci38421072,2019-01-10T12:13:30.138Z,"3km NNW of La Verne, CA",earthquake,0.3,0.55,0.246,6,automatic,ci,ci +2019-01-10T12:04:26.320Z,19.4433327,-155.6159973,0.72,1.79,md,22,99,0.04026,0.3,hv,hv70763571,2019-01-10T12:07:28.690Z,"26km E of Honaunau-Napoopoo, Hawaii",earthquake,0.6,1.79,0.28,6,automatic,hv,hv +2019-01-10T11:57:48.980Z,33.3225,-116.3931667,4.84,0.62,ml,15,211,0.05776,0.16,ci,ci38421064,2019-01-10T12:01:29.166Z,"8km NNW of Borrego Springs, CA",earthquake,0.71,0.68,0.111,11,automatic,ci,ci +2019-01-10T11:52:09.490Z,38.8356667,-122.8366699,1.28,2.74,md,25,77,0.003061,0.04,nc,nc73131566,2019-01-10T12:14:02.757Z,"10km NW of The Geysers, CA",earthquake,0.19,0.29,0.06,7,automatic,nc,nc +2019-01-10T11:25:44.854Z,65.1082,-149.3701,20.6,2.1,ml,,,,1.02,ak,ak019gq2oer,2019-01-10T11:37:07.060Z,"60km NNW of North Nenana, Alaska",earthquake,,0.3,,,automatic,ak,ak +2019-01-10T11:25:23.786Z,69.1518,-144.4977,10.4,3.7,ml,,,,0.74,ak,ak019gq2ndz,2019-01-10T11:47:11.284Z,"114km SSW of Kaktovik, Alaska",earthquake,,1.6,,,reviewed,ak,ak +2019-01-10T11:16:11.761Z,61.3318,-150.0708,20.1,2.7,ml,,,,0.83,ak,ak019gq0ozj,2019-01-10T11:29:24.610Z,"15km NW of Anchorage, Alaska",earthquake,,0.4,,,automatic,ak,ak diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 b/sources/pyside2/doc/tutorials/datavisualize/datavisualize.tar.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..5fe12769a3d23844f6b57ce6134f817c00deddf9 GIT binary patch literal 6086 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 MBAh5lKov`10PpfX&j0`b literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py new file mode 100644 index 0000000..8a8a1df --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize1/main.py @@ -0,0 +1,55 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import argparse +import pandas as pd + + +def read_data(fname): + return pd.read_csv(fname) + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + print(data) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py new file mode 100644 index 0000000..33bd347 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize2/main.py @@ -0,0 +1,78 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + print(data) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py new file mode 100644 index 0000000..dd07a68 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + window = MainWindow() + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py new file mode 100644 index 0000000..188e493 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize3/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py new file mode 100644 index 0000000..43c5cd5 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main.py @@ -0,0 +1,90 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + widget = Widget(data) + window = MainWindow(widget) + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py new file mode 100644 index 0000000..0c78024 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_widget.py @@ -0,0 +1,80 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtWidgets import (QHBoxLayout, QHeaderView, QSizePolicy, + QTableView, QWidget) + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode( + QHeaderView.ResizeToContents + ) + self.vertical_header.setSectionResizeMode( + QHeaderView.ResizeToContents + ) + self.horizontal_header.setStretchLastSection(True) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + ## Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py new file mode 100644 index 0000000..6a0374a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + self.setCentralWidget(widget) + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + ## Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py new file mode 100644 index 0000000..d2eafb2 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize4/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return QColor(Qt.white) + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py new file mode 100644 index 0000000..43c5cd5 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main.py @@ -0,0 +1,90 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + widget = Widget(data) + window = MainWindow(widget) + window.show() + + sys.exit(app.exec_()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py new file mode 100644 index 0000000..08406d3 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_widget.py @@ -0,0 +1,91 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import QDateTime, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView, + QSizePolicy) +from PySide2.QtCharts import QtCharts + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode(QHeaderView.ResizeToContents) + self.vertical_header.setSectionResizeMode(QHeaderView.ResizeToContents) + self.horizontal_header.setStretchLastSection(True) + + # Creating QChart + self.chart = QtCharts.QChart() + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + + # Creating QChartView + self.chart_view = QtCharts.QChartView(self.chart) + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + ## Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + ## Right Layout + size.setHorizontalStretch(4) + self.chart_view.setSizePolicy(size) + self.main_layout.addWidget(self.chart_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py new file mode 100644 index 0000000..5f9003a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/main_window.py @@ -0,0 +1,69 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + self.setCentralWidget(widget) + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py new file mode 100644 index 0000000..d2eafb2 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize5/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return QColor(Qt.white) + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py new file mode 100644 index 0000000..441d81a --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main.py @@ -0,0 +1,92 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import argparse +import pandas as pd + +from PySide2.QtCore import QDateTime, QTimeZone +from PySide2.QtWidgets import QApplication + +from main_window import MainWindow +from main_widget import Widget + + +def transform_date(utc, timezone=None): + utc_fmt = "yyyy-MM-ddTHH:mm:ss.zzzZ" + new_date = QDateTime().fromString(utc, utc_fmt) + if timezone: + new_date.setTimeZone(timezone) + return new_date + + +def read_data(fname): + # Read the CSV content + df = pd.read_csv(fname) + + # Remove wrong magnitudes + df = df.drop(df[df.mag < 0].index) + magnitudes = df["mag"] + + # My local timezone + timezone = QTimeZone(b"Europe/Berlin") + + # Get timestamp transformed to our timezone + times = df["time"].apply(lambda x: transform_date(x, timezone)) + + return times, magnitudes + + +if __name__ == "__main__": + options = argparse.ArgumentParser() + options.add_argument("-f", "--file", type=str, required=True) + args = options.parse_args() + data = read_data(args.file) + + # Qt Application + app = QApplication(sys.argv) + + # QWidget + widget = Widget(data) + # QMainWindow using QWidget as central widget + window = MainWindow(widget) + + window.show() + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py new file mode 100644 index 0000000..2d2452b --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_widget.py @@ -0,0 +1,131 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import QDateTime, Qt +from PySide2.QtGui import QPainter +from PySide2.QtWidgets import (QWidget, QHeaderView, QHBoxLayout, QTableView, + QSizePolicy) +from PySide2.QtCharts import QtCharts + +from table_model import CustomTableModel + + +class Widget(QWidget): + def __init__(self, data): + QWidget.__init__(self) + + # Getting the Model + self.model = CustomTableModel(data) + + # Creating a QTableView + self.table_view = QTableView() + self.table_view.setModel(self.model) + + # QTableView Headers + resize = QHeaderView.ResizeToContents + self.horizontal_header = self.table_view.horizontalHeader() + self.vertical_header = self.table_view.verticalHeader() + self.horizontal_header.setSectionResizeMode(resize) + self.vertical_header.setSectionResizeMode(resize) + self.horizontal_header.setStretchLastSection(True) + + # Creating QChart + self.chart = QtCharts.QChart() + self.chart.setAnimationOptions(QtCharts.QChart.AllAnimations) + self.add_series("Magnitude (Column 1)", [0, 1]) + + # Creating QChartView + self.chart_view = QtCharts.QChartView(self.chart) + self.chart_view.setRenderHint(QPainter.Antialiasing) + + # QWidget Layout + self.main_layout = QHBoxLayout() + size = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) + + # Left layout + size.setHorizontalStretch(1) + self.table_view.setSizePolicy(size) + self.main_layout.addWidget(self.table_view) + + # Right Layout + size.setHorizontalStretch(4) + self.chart_view.setSizePolicy(size) + self.main_layout.addWidget(self.chart_view) + + # Set the layout to the QWidget + self.setLayout(self.main_layout) + + def add_series(self, name, columns): + # Create QLineSeries + self.series = QtCharts.QLineSeries() + self.series.setName(name) + + # Filling QLineSeries + for i in range(self.model.rowCount()): + # Getting the data + t = self.model.index(i, 0).data() + date_fmt = "yyyy-MM-dd HH:mm:ss.zzz" + + x = QDateTime().fromString(t, date_fmt).toSecsSinceEpoch() + y = float(self.model.index(i, 1).data()) + + if x > 0 and y > 0: + self.series.append(x, y) + + self.chart.addSeries(self.series) + + # Setting X-axis + self.axis_x = QtCharts.QDateTimeAxis() + self.axis_x.setTickCount(10) + self.axis_x.setFormat("dd.MM (h:mm)") + self.axis_x.setTitleText("Date") + self.chart.addAxis(self.axis_x, Qt.AlignBottom) + self.series.attachAxis(self.axis_x) + # Setting Y-axis + self.axis_y = QtCharts.QValueAxis() + self.axis_y.setTickCount(10) + self.axis_y.setLabelFormat("%.2f") + self.axis_y.setTitleText("Magnitude") + self.chart.addAxis(self.axis_y, Qt.AlignLeft) + self.series.attachAxis(self.axis_y) + + # Getting the color from the QChart to use it on the QTableView + self.model.color = "{}".format(self.series.pen().color().name()) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py new file mode 100644 index 0000000..5c2c009 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/main_window.py @@ -0,0 +1,70 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Slot +from PySide2.QtGui import QKeySequence +from PySide2.QtWidgets import QMainWindow, QAction + + +class MainWindow(QMainWindow): + def __init__(self, widget): + QMainWindow.__init__(self) + self.setWindowTitle("Eartquakes information") + + # Menu + self.menu = self.menuBar() + self.file_menu = self.menu.addMenu("File") + + # Exit QAction + exit_action = QAction("Exit", self) + exit_action.setShortcut(QKeySequence.Quit) + exit_action.triggered.connect(self.close) + + self.file_menu.addAction(exit_action) + + # Status Bar + self.status = self.statusBar() + self.status.showMessage("Data loaded and plotted") + + # Window dimensions + geometry = qApp.desktop().availableGeometry(self) + self.setFixedSize(geometry.width() * 0.8, geometry.height() * 0.7) + self.setCentralWidget(widget) + diff --git a/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py new file mode 100644 index 0000000..99e1cf1 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/datavisualize6/table_model.py @@ -0,0 +1,88 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtCore import Qt, QAbstractTableModel, QModelIndex +from PySide2.QtGui import QColor + + +class CustomTableModel(QAbstractTableModel): + def __init__(self, data=None): + QAbstractTableModel.__init__(self) + self.color = None + self.load_data(data) + + def load_data(self, data): + self.input_dates = data[0].values + self.input_magnitudes = data[1].values + + self.column_count = 2 + self.row_count = len(self.input_magnitudes) + + def rowCount(self, parent=QModelIndex()): + return self.row_count + + def columnCount(self, parent=QModelIndex()): + return self.column_count + + def headerData(self, section, orientation, role): + if role != Qt.DisplayRole: + return None + if orientation == Qt.Horizontal: + return ("Date", "Magnitude")[section] + else: + return "{}".format(section) + + def data(self, index, role=Qt.DisplayRole): + column = index.column() + row = index.row() + + if role == Qt.DisplayRole: + if column == 0: + raw_date = self.input_dates[row] + date = "{}".format(raw_date.toPython()) + return date[:-3] + elif column == 1: + return "{:.2f}".format(self.input_magnitudes[row]) + elif role == Qt.BackgroundRole: + return (QColor(Qt.white), QColor(self.color))[column] + elif role == Qt.TextAlignmentRole: + return Qt.AlignRight + + return None diff --git a/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst new file mode 100644 index 0000000..b06b2fa --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/filter_data.rst @@ -0,0 +1,29 @@ +Chapter 2 - Filtering data +=========================== + +In the previous chapter, you learned how to read and print data that is a +bit raw. Now, try to select a few columns and handle them properly. + +Start with these two columns: Time (time) and Magnitude (mag). After getting +the information from these columns, filter and adapt the data. Try formatting +the date to Qt types. + +There is not much to do for the Magnitude column, as it's just a floating point +number. You could take special care to check if the data is correct. This could +be done by filtering the data that follows the condition, "magnitude > 0", to +avoid faulty data or unexpected behavior. + +The Date column provides data in UTC format (for example, +2018-12-11T21:14:44.682Z), so you could easily map it to a QDateTime object +defining the structure of the string. Additionally, you can adapt the time +based on the timezone you are in, using QTimeZone. + +The following script filters and formats the CSV data as described earlier: + +.. literalinclude:: datavisualize2/main.py + :language: python + :linenos: + :lines: 40- + +Now that you have a tuple of QDateTime and float data, try improving the +output further. That's what you'll learn in the following chapters. diff --git a/sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png b/sources/pyside2/doc/tutorials/datavisualize/images/QMainWindow-layout.png new file mode 100644 index 0000000000000000000000000000000000000000..075d796b8e8ab426c8fde86bd26f0eca8b8ed9cd GIT binary patch literal 17272 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 TU%&bRK1NcIQIRf}G!FV-Ny}n` literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png b/sources/pyside2/doc/tutorials/datavisualize/images/datavisualization_app.png new file mode 100644 index 0000000000000000000000000000000000000000..ddac43fc3dc2e92969e39654ca46aa51e923375d GIT binary patch literal 40458 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%0DfZE6UnVZ>OaSbqv{_YpDU}>tX;Fv!Jt9d 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/datavisualize/index.rst b/sources/pyside2/doc/tutorials/datavisualize/index.rst new file mode 100644 index 0000000..ff18c65 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/index.rst @@ -0,0 +1,26 @@ +Data Visualization Tool Tutorial +********************************* + +In this tutorial, you'll learn about the data visualization capabilities +of |project|. To start with, find some open data to visualize. For example, +data about the magnitude of earthquakes during the last hour published on the +US Geological Survey website. You could download the +`All earthquakes `_ +open data in a CSV format for this tutorial. + +In the following chapters of this tutorial you'll learn how to +visualize data from a CSV in a line chart. + +.. toctree:: + :glob: + :titlesonly: + + read* + filter* + add_main* + add_tab* + add_chart* + plot* + +You can download the sources from :download:`here `. + diff --git a/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst b/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst new file mode 100644 index 0000000..8ebdd2b --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/plot_datapoints.rst @@ -0,0 +1,25 @@ +Chapter 6 - Plot the data in the ChartView +=========================================== + +The last step of this tutorial is to plot the CSV data inside our QChart. For +this, you need to go over our data and include the data on a QLineSeries. + +After adding the data to the series, you can modify the axis to properly +display the QDateTime on the X-axis, and the magnitude values on the Y-axis. + +Here is the updated :code:`main_widget.py` that includes an additional +function to plot data using a QLineSeries: + +.. literalinclude:: datavisualize6/main_widget.py + :language: python + :linenos: + :lines: 40- + :emphasize-lines: 33,56-91 + +Now, run the application to visualize the earthquake magnitudes +data at different times. + +.. image:: images/datavisualization_app.png + +Try modifying the sources to get different output. For example, you could try +to plot more data from the CSV. diff --git a/sources/pyside2/doc/tutorials/datavisualize/read_data.rst b/sources/pyside2/doc/tutorials/datavisualize/read_data.rst new file mode 100644 index 0000000..f7bf933 --- /dev/null +++ b/sources/pyside2/doc/tutorials/datavisualize/read_data.rst @@ -0,0 +1,41 @@ +Chapter 1 - Reading data from a CSV +=================================== + +There are several ways to read data from a CSV file. The following are the most +common ways: + +- Native reading +- the `CSV module `_ +- the `numpy module `_ +- the `pandas module `_ + +In this chapter, you will learn to use pandas to read and filter CSV data. +In addition, you could pass the data file through a command-line option to your +script. + +The following python script, :code:`main.py`, demonstrates how to do it: + +.. literalinclude:: datavisualize1/main.py + :language: python + :linenos: + :lines: 40- + +The Python script uses the :code:`argparse` module to accept and parse input +from the command line. It then uses the input, which in this case is the filename, +to read and print data to the prompt. + +Try running the script in the following way to check if you get desired output: + +:: + + $python datavisualize1/main.py -f all_hour.csv + time latitude longitude depth ... magNst status locationSource magSource + 0 2019-01-10T12:11:24.810Z 34.128166 -117.775497 4.46 ... 6.0 automatic ci ci + 1 2019-01-10T12:04:26.320Z 19.443333 -155.615997 0.72 ... 6.0 automatic hv hv + 2 2019-01-10T11:57:48.980Z 33.322500 -116.393167 4.84 ... 11.0 automatic ci ci + 3 2019-01-10T11:52:09.490Z 38.835667 -122.836670 1.28 ... 7.0 automatic nc nc + 4 2019-01-10T11:25:44.854Z 65.108200 -149.370100 20.60 ... NaN automatic ak ak + 5 2019-01-10T11:25:23.786Z 69.151800 -144.497700 10.40 ... NaN reviewed ak ak + 6 2019-01-10T11:16:11.761Z 61.331800 -150.070800 20.10 ... NaN automatic ak ak + + [7 rows x 22 columns] diff --git a/sources/pyside2/doc/tutorials/expenses/expenses.rst b/sources/pyside2/doc/tutorials/expenses/expenses.rst new file mode 100644 index 0000000..640feb4 --- /dev/null +++ b/sources/pyside2/doc/tutorials/expenses/expenses.rst @@ -0,0 +1,314 @@ +###################### +Expenses Tool Tutorial +###################### + +In this tutorial you will learn the following concepts: + * creating user interfaces programatically, + * layouts and widgets, + * overloading Qt classes, + * connecting signal and slots, + * interacting with QWidgets, + * and building your own application. + +The requirements: + * A simple window for the application + (`QMainWindow `_). + * A table to keep track of the expenses + (`QTableWidget `_). + * Two input fields to add expense information + (`QLineEdit `_). + * Buttons to add information to the table, plot data, clear table, and exit the application + (`QPushButton `_). + * A verification step to avoid invalid data entry. + * A chart to visualize the expense data + (`QChart `_) that will + be embedded in a chart view + (`QChartView `_). + +Empty window +------------ + +The base structure for a `QApplication` is located inside the `if __name__ == "__main__":` +code block. + +.. code-block:: python + :linenos: + + if __name__ == "__main__": + app = QApplication([]) + # ... + sys.exit(app.exec_()) + +Now, to start the development, create an empty window called `MainWindow`. +You could do that by defining a class that inherits from `QMainWindow`. + +.. literalinclude:: steps/01-expenses.py + :linenos: + :lines: 45-59 + :emphasize-lines: 1-4 + +Now that our class is defined, create an instance of it and call `show()`. + +.. literalinclude:: steps/01-expenses.py + :linenos: + :lines: 45-59 + :emphasize-lines: 10-12 + +Menu bar +-------- + +Using a `QMainWindow` gives some features for free, among them a *menu bar*. To use it, you need +to call the method `menuBar()` and populate it inside the `MainWindow` class. + +.. literalinclude:: steps/02-expenses.py + :linenos: + :lines: 46-58 + :emphasize-lines: 6 + +Notice that the code snippet adds a *File* menu with the *Exit* option only. + +First signal/slot connection +---------------------------- + +The *Exit* option must be connected to a slot that triggers the application to exit. The main +idea to achieve this, is the following: + +.. code-block:: python + + element.signal_name.connect(slot_name) + +All the interface's elements could be connected through signals to certain slots, +in the case of a `QAction`, the signal `triggered` can be used: + +.. code-block:: python + + exit_action.triggered.connect(slot_name) + +.. note:: Now a *slot* needs to be defined to exit the application, which can be done using + `QApplication.quit()`. If we put all these concepts together you will end up with the + following code: + +.. literalinclude:: steps/03-expenses.py + :linenos: + :lines: 56-65 + :emphasize-lines: 4, 8-10 + +Notice that the decorator `@Slot()` is required for each slot you declare to properly +register them. Slots are normal functions, but the main difference is that they +will be invokable from `Signals` of QObjects when connected. + +Empty widget and data +--------------------- + +The `QMainWindow` enables us to set a central widget that will be displayed when showing the window +(`read more `_). +This central widget could be another class derived from `QWidget`. + +Additionally, you will define example data to visualize later. + +.. literalinclude:: steps/04-expenses.py + :linenos: + :lines: 46-53 + +With the `Widget` class in place, modify `MainWindow`'s initialization code + +.. literalinclude:: steps/04-expenses.py + :linenos: + :lines: 80-84 + +Window layout +------------- + +Now that the main empty window is in place, you need to start adding widgets to achieve the main +goal of creating an expenses application. + +After declaring the example data, you can visualize it on a simple `QTableWidget`. To do so, you +will add this procedure to the `Widget` constructor. + +.. warning:: Only for the example purpose a QTableWidget will be used, + but for more performance-critical applications the combination + of a model and a QTableView is encouraged. + +.. literalinclude:: steps/05-expenses.py + :linenos: + :lines: 48-73 + +As you can see, the code also includes a `QHBoxLayout` that provides the container to place widgets +horizontally. + +Additionally, the `QTableWidget` allows for customizing it, like adding the labels for the two +columns that will be used, and to *stretch* the content to use the whole `Widget` space. + +The last line of code refers to *filling the table**, and the code to perform that task is +displayed below. + +.. literalinclude:: steps/05-expenses.py + :linenos: + :lines: 75-81 + +Having this process on a separate method is a good practice to leave the constructor more readable, +and to split the main functions of the class in independent processes. + + +Right side layout +----------------- + +Because the data that is being used is just an example, you are required to include a mechanism to +input items to the table, and extra buttons to clear the table's content, and also quit the +application. + +To distribute these input lines and buttons, you will use a `QVBoxLayout` that allows you to place +elements vertically inside a layout. + +.. literalinclude:: steps/06-expenses.py + :linenos: + :lines: 64-80 + +Leaving the table on the left side and these newly included widgets to the right side +will be just a matter to add a layout to our main `QHBoxLayout` as you saw in the previous +example: + +.. literalinclude:: steps/06-expenses.py + :linenos: + :lines: 42-47 + +The next step will be connecting those new buttons to slots. + + +Adding elements +--------------- + +Each `QPushButton` have a signal called *clicked*, that is emitted when you click on the button. +This will be more than enough for this example, but you can see other signals in the `official +documentation `_. + +.. literalinclude:: steps/07-expenses.py + :linenos: + :lines: 92-95 + +As you can see on the previous lines, we are connecting each *clicked* signal to different slots. +In this example slots are normal class methods in charge of perform a determined task associated +with our buttons. It is really important to decorate each method declaration with a `@Slot()`, in +that way PySide2 knows internally how to register them into Qt. + +.. literalinclude:: steps/07-expenses.py + :linenos: + :lines: 100-129 + :emphasize-lines: 2,16,28 + +Since these slots are methods, we can access the class variables, like our `QTableWidget` to +interact with it. + +The mechanism to add elements into the table is described as the following: + + * get the *description* and *price* from the fields, + * insert a new empty row to the table, + * set the values for the empty row in each column, + * clear the input text fields, + * include the global count of table rows. + +To exit the application you can use the `quit()` method of the unique `QApplication` instance, and +to clear the content of the table you can just set the table *row count*, and the internal count to +zero. + +Verification step +----------------- + +Adding information to the table needs to be a critical action that require a verification step +to avoid adding invalid information, for example, empty information. + +You can use a signal from `QLineEdit` called *textChanged[str]* which will be emitted every +time something inside changes, i.e.: each key stroke. +Notice that this time, there is a *[str]* section on the signal, this means that the signal +will also emit the value of the text that was changed, which will be really useful to verify +the current content of the `QLineEdit`. + +You can connect two different object's signal to the same slot, and this will be the case +for your current application: + +.. literalinclude:: steps/08-expenses.py + :linenos: + :lines: 99-100 + +The content of the *check_disable* slot will be really simple: + +.. literalinclude:: steps/08-expenses.py + :linenos: + :lines: 119-124 + +You have two options, write a verification based on the current value +of the string you retrieve, or manually get the whole content of both +`QLineEdit`. The second is preferred in this case, so you can verify +if the two inputs are not empty to enable the button *Add*. + +.. note:: Qt also provides a special class called + `QValidator `_ + that you can use to validate any input. + +Empty chart view +---------------- + +New items can be added to the table, and the visualization is so far +OK, but you can accomplish more by representing the data graphically. + +First you will include an empty `QChartView` placeholder into the right +side of your application. + +.. literalinclude:: steps/09-expenses.py + :linenos: + :lines: 66-68 + +Additionally the order of how you include widgets to the right +`QVBoxLayout` will also change. + +.. literalinclude:: steps/09-expenses.py + :linenos: + :lines: 81-91 + :emphasize-lines: 9 + +Notice that before we had a line with `self.right.addStretch()` +to fill up the vertical space between the *Add* and the *Clear* buttons, +but now, with the `QChartView` it will not be necessary. + +Also, you need include a *Plot* button if you want to do it on-demand. + +Full application +---------------- + +For the final step, you will need to connect the *Plot* button +to a slot that creates a chart and includes it into your `QChartView`. + +.. literalinclude:: steps/10-expenses.py + :linenos: + :lines: 103-109 + :emphasize-lines: 6 + +That is nothing new, since you already did it for the other buttons, +but now take a look at how to create a chart and include it into +your `QChartView`. + +.. literalinclude:: steps/10-expenses.py + :linenos: + :lines: 139-151 + +The following steps show how to fill a `QPieSeries`: + + * create a `QPieSeries`, + * iterate over the table row IDs, + * get the items at the *i* position, + * add those values to the *series*. + +Once the series has been populated with our data, you create a new `QChart`, +add the series on it, and optionally set an alignment for the legend. + +The final line `self.chart_view.setChart(chart)` is in charge of bringing +your newly created chart to the `QChartView`. + +The application will look like this: + +.. image:: expenses_tool.png + +And now you can see the whole code: + +.. literalinclude:: main.py + :linenos: diff --git a/sources/pyside2/doc/tutorials/expenses/expenses_tool.png b/sources/pyside2/doc/tutorials/expenses/expenses_tool.png new file mode 100644 index 0000000000000000000000000000000000000000..7a6f6d1f040e1cde683141038d5e50d0e31d0296 GIT binary patch literal 47826 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 Mo~dr>g)4Xd4YB#1rT_o{ literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h b/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h new file mode 100644 index 0000000..773e3fb --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/initdb.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INITDB_H +#define INITDB_H + +#include + +void addBook(QSqlQuery &q, const QString &title, int year, const QVariant &authorId, + const QVariant &genreId, int rating) +{ + q.addBindValue(title); + q.addBindValue(year); + q.addBindValue(authorId); + q.addBindValue(genreId); + q.addBindValue(rating); + q.exec(); +} + +QVariant addGenre(QSqlQuery &q, const QString &name) +{ + q.addBindValue(name); + q.exec(); + return q.lastInsertId(); +} + +QVariant addAuthor(QSqlQuery &q, const QString &name, const QDate &birthdate) +{ + q.addBindValue(name); + q.addBindValue(birthdate); + q.exec(); + return q.lastInsertId(); +} + +const auto BOOKS_SQL = QLatin1String(R"( + create table books(id integer primary key, title varchar, author integer, + genre integer, year integer, rating integer) + )"); + +const auto AUTHORS_SQL = QLatin1String(R"( + create table authors(id integer primary key, name varchar, birthdate date) + )"); + +const auto GENRES_SQL = QLatin1String(R"( + create table genres(id integer primary key, name varchar) + )"); + +const auto INSERT_AUTHOR_SQL = QLatin1String(R"( + insert into authors(name, birthdate) values(?, ?) + )"); + +const auto INSERT_BOOK_SQL = QLatin1String(R"( + insert into books(title, year, author, genre, rating) + values(?, ?, ?, ?, ?) + )"); + +const auto INSERT_GENRE_SQL = QLatin1String(R"( + insert into genres(name) values(?) + )"); + +QSqlError initDb() +{ + QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); + db.setDatabaseName(":memory:"); + + if (!db.open()) + return db.lastError(); + + QStringList tables = db.tables(); + if (tables.contains("books", Qt::CaseInsensitive) + && tables.contains("authors", Qt::CaseInsensitive)) + return QSqlError(); + + QSqlQuery q; + if (!q.exec(BOOKS_SQL)) + return q.lastError(); + if (!q.exec(AUTHORS_SQL)) + return q.lastError(); + if (!q.exec(GENRES_SQL)) + return q.lastError(); + + if (!q.prepare(INSERT_AUTHOR_SQL)) + return q.lastError(); + QVariant asimovId = addAuthor(q, QLatin1String("Isaac Asimov"), QDate(1920, 2, 1)); + QVariant greeneId = addAuthor(q, QLatin1String("Graham Greene"), QDate(1904, 10, 2)); + QVariant pratchettId = addAuthor(q, QLatin1String("Terry Pratchett"), QDate(1948, 4, 28)); + + if (!q.prepare(INSERT_GENRE_SQL)) + return q.lastError(); + QVariant sfiction = addGenre(q, QLatin1String("Science Fiction")); + QVariant fiction = addGenre(q, QLatin1String("Fiction")); + QVariant fantasy = addGenre(q, QLatin1String("Fantasy")); + + if (!q.prepare(INSERT_BOOK_SQL)) + return q.lastError(); + addBook(q, QLatin1String("Foundation"), 1951, asimovId, sfiction, 3); + addBook(q, QLatin1String("Foundation and Empire"), 1952, asimovId, sfiction, 4); + addBook(q, QLatin1String("Second Foundation"), 1953, asimovId, sfiction, 3); + addBook(q, QLatin1String("Foundation's Edge"), 1982, asimovId, sfiction, 3); + addBook(q, QLatin1String("Foundation and Earth"), 1986, asimovId, sfiction, 4); + addBook(q, QLatin1String("Prelude to Foundation"), 1988, asimovId, sfiction, 3); + addBook(q, QLatin1String("Forward the Foundation"), 1993, asimovId, sfiction, 3); + addBook(q, QLatin1String("The Power and the Glory"), 1940, greeneId, fiction, 4); + addBook(q, QLatin1String("The Third Man"), 1950, greeneId, fiction, 5); + addBook(q, QLatin1String("Our Man in Havana"), 1958, greeneId, fiction, 4); + addBook(q, QLatin1String("Guards! Guards!"), 1989, pratchettId, fantasy, 3); + addBook(q, QLatin1String("Night Watch"), 2002, pratchettId, fantasy, 3); + addBook(q, QLatin1String("Going Postal"), 2004, pratchettId, fantasy, 3); + + return QSqlError(); +} + +#endif diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py b/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py new file mode 100644 index 0000000..7e94e4c --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter1/main.py @@ -0,0 +1,59 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys + +from PySide2.QtSql import QSqlQueryModel +from PySide2.QtWidgets import QTableView, QApplication + +import createdb + +if __name__ == "__main__": + app = QApplication() + createdb.init_db() + + model = QSqlQueryModel() + model.setQuery("select * from books") + + table_view = QTableView() + table_view.setModel(model) + table_view.resize(800, 600) + table_view.show() + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp new file mode 100644 index 0000000..4115f80 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.cpp @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bookdelegate.h" + +#include + +BookDelegate::BookDelegate(QObject *parent) + : QSqlRelationalDelegate(parent), star(QPixmap(":images/star.png")) +{ +} + +void BookDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + if (index.column() != 5) { + QStyleOptionViewItem opt = option; + // Since we draw the grid ourselves: + opt.rect.adjust(0, 0, -1, -1); + QSqlRelationalDelegate::paint(painter, opt, index); + } else { + const QAbstractItemModel *model = index.model(); + QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? + (option.state & QStyle::State_Active) ? + QPalette::Normal : + QPalette::Inactive : + QPalette::Disabled; + + if (option.state & QStyle::State_Selected) + painter->fillRect( + option.rect, + option.palette.color(cg, QPalette::Highlight)); + + int rating = model->data(index, Qt::DisplayRole).toInt(); + int width = star.width(); + int height = star.height(); + int x = option.rect.x(); + int y = option.rect.y() + (option.rect.height() / 2) - (height / 2); + for (int i = 0; i < rating; ++i) { + painter->drawPixmap(x, y, star); + x += width; + } + // Since we draw the grid ourselves: + drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)); + } + + QPen pen = painter->pen(); + painter->setPen(option.palette.color(QPalette::Mid)); + painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); + painter->drawLine(option.rect.topRight(), option.rect.bottomRight()); + painter->setPen(pen); +} + +QSize BookDelegate::sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + if (index.column() == 5) + return QSize(5 * star.width(), star.height()) + QSize(1, 1); + // Since we draw the grid ourselves: + return QSqlRelationalDelegate::sizeHint(option, index) + QSize(1, 1); +} + +bool BookDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) +{ + if (index.column() != 5) + return QSqlRelationalDelegate::editorEvent(event, model, option, index); + + if (event->type() == QEvent::MouseButtonPress) { + QMouseEvent *mouseEvent = static_cast(event); + int stars = qBound(0, int(0.7 + qreal(mouseEvent->pos().x() + - option.rect.x()) / star.width()), 5); + model->setData(index, QVariant(stars)); + // So that the selection can change: + return false; + } + + return true; +} + +QWidget *BookDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem &option, + const QModelIndex &index) const +{ + if (index.column() != 4) + return QSqlRelationalDelegate::createEditor(parent, option, index); + + // For editing the year, return a spinbox with a range from -1000 to 2100. + QSpinBox *sb = new QSpinBox(parent); + sb->setFrame(false); + sb->setMaximum(2100); + sb->setMinimum(-1000); + + return sb; +} diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h new file mode 100644 index 0000000..f1b4326 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef BOOKDELEGATE_H +#define BOOKDELEGATE_H + +#include +#include +#include +#include + +QT_FORWARD_DECLARE_CLASS(QPainter) + +class BookDelegate : public QSqlRelationalDelegate +{ +public: + BookDelegate(QObject *parent); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + QSize sizeHint(const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + + bool editorEvent(QEvent *event, QAbstractItemModel *model, + const QStyleOptionViewItem &option, + const QModelIndex &index) override; + + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, + const QModelIndex &index) const override; + +private: + QPixmap star; +}; + +#endif diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py new file mode 100644 index 0000000..57d8f0f --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/bookdelegate.py @@ -0,0 +1,134 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import copy, os +from PySide2.QtSql import QSqlRelationalDelegate +from PySide2.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate, + QStyle, QStyleOptionViewItem) +from PySide2.QtGui import QMouseEvent, QPixmap, QPalette, QImage +from PySide2.QtCore import QEvent, QSize, Qt, QUrl + +class BookDelegate(QSqlRelationalDelegate): + """Books delegate to rate the books""" + + def __init__(self, parent=None): + QSqlRelationalDelegate.__init__(self, parent) + star_png = os.path.dirname(__file__) + "\images\star.png" + self.star = QPixmap(star_png) + + def paint(self, painter, option, index): + """ Paint the items in the table. + + If the item referred to by is a StarRating, we + handle the painting ourselves. For the other items, we + let the base class handle the painting as usual. + + In a polished application, we'd use a better check than + the column number to find out if we needed to paint the + stars, but it works for the purposes of this example. + """ + if index.column() != 5: + # Since we draw the grid ourselves: + opt = copy.copy(option) + opt.rect = option.rect.adjusted(0, 0, -1, -1) + QSqlRelationalDelegate.paint(self, painter, opt, index) + else: + model = index.model() + if option.state & QStyle.State_Enabled: + if option.state & QStyle.State_Active: + color_group = QPalette.Normal + else: + color_group = QPalette.Inactive + else: + color_group = QPalette.Disabled + + if option.state & QStyle.State_Selected: + painter.fillRect(option.rect, + option.palette.color(color_group, QPalette.Highlight)) + rating = model.data(index, Qt.DisplayRole) + width = self.star.width() + height = self.star.height() + x = option.rect.x() + y = option.rect.y() + (option.rect.height() / 2) - (height / 2) + for i in range(rating): + painter.drawPixmap(x, y, self.star) + x += width + + # Since we draw the grid ourselves: + self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)) + + pen = painter.pen() + painter.setPen(option.palette.color(QPalette.Mid)) + painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight()) + painter.drawLine(option.rect.topRight(), option.rect.bottomRight()) + painter.setPen(pen) + + def sizeHint(self, option, index): + """ Returns the size needed to display the item in a QSize object. """ + if index.column() == 5: + size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1) + return size_hint + # Since we draw the grid ourselves: + return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1) + + def editorEvent(self, event, model, option, index): + if index.column() != 5: + return False + + if event.type() == QEvent.MouseButtonPress: + mouse_pos = event.pos() + new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width()) + stars = max(0, min(new_stars, 5)) + model.setData(index, stars) + # So that the selection can change + return False + + return True + + def createEditor(self, parent, option, index): + if index.column() != 4: + return QSqlRelationalDelegate.createEditor(self, parent, option, index) + + # For editing the year, return a spinbox with a range from -1000 to 2100. + spinbox = QSpinBox(parent) + spinbox.setFrame(False) + spinbox.setMaximum(2100) + spinbox.setMinimum(-1000) + return spinbox diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst b/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst new file mode 100644 index 0000000..a574218 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/chapter2.rst @@ -0,0 +1,93 @@ +Chapter 2: ``bookdelegate.cpp`` to ``bookdelegate.py`` +******************************************************* + +Now that your database is in place, port the C++ code for the +``BookDelegate`` class. This class offers a delegate to present +and edit the data in a ``QTableView``. It inherits +``QSqlRelationalDelegate`` interface, which offers features +specific for handling relational databases, such as a combobox +editor for foreign key fields. To begin with, create +``bookdelegate.py`` and add the following imports to it: + +.. literalinclude:: bookdelegate.py + :language: python + :linenos: + :lines: 40-47 + +After the necessary ``import`` statements, port the +constructor code for the ``BookDelegate`` class. Both +the C++ and Python versions of this code initialize a +``QSqlRelationalDelegate`` and ``QPixmap`` instance. +Here is how they look: + +C++ version +------------- + +.. literalinclude:: bookdelegate.cpp + :language: c++ + :linenos: + :lines: 54-59 + +Python version +--------------- + +.. literalinclude:: bookdelegate.py + :language: python + :linenos: + :lines: 47-54 + +.. note:: The Python version loads the ``QPixmap`` using + the absolute path of ``star.png`` in the local + filesystem. + +As the default functionality offered by the +``QSqlRelationalDelegate`` is not enough to present +the books data, you must reimplement a few functions. +For example, painting stars to represent the rating for +each book in the table. Here is how the reimplemented +code looks like: + +C++ version +------------ + +.. literalinclude:: bookdelegate.cpp + :language: c++ + :linenos: + :lines: 59- + +Python version +--------------- + +.. literalinclude:: bookdelegate.py + :language: python + :linenos: + :lines: 55- + +Now that the delegate is in place, run the following +``main.py`` to see how the data is presented: + +.. literalinclude:: main.py + :language: python + :linenos: + :lines: 40- + +Here is how the application will look when you run it: + +.. image:: images/chapter2_books.png + :alt: Books table data + +The only difference you'll notice now in comparison to +:doc:`chapter 1 <../chapter1/chapter1>` is that the +``rating`` column looks different. + +Try improving the table even further by adding these +features: + +* Title for each column +* SQL relation for the ``author_id`` and ``genre_id`` columns +* Set a title to the window + +With these features, this is how your table will look like: + +.. image:: images/chapter2_books_with_relation.png + :alt: Books table with SQL relation diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py b/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py new file mode 100644 index 0000000..8fb20cd --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter2/createdb.py @@ -0,0 +1,131 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtSql import QSqlDatabase, QSqlError, QSqlQuery +from datetime import date + + +def add_book(q, title, year, authorId, genreId, rating): + q.addBindValue(title) + q.addBindValue(year) + q.addBindValue(authorId) + q.addBindValue(genreId) + q.addBindValue(rating) + q.exec_() + + +def add_genre(q, name): + q.addBindValue(name) + q.exec_() + return q.lastInsertId() + + +def add_author(q, name, birthdate): + q.addBindValue(name) + q.addBindValue(str(birthdate)) + q.exec_() + return q.lastInsertId() + +BOOKS_SQL = """ + create table books(id integer primary key, title varchar, author integer, + genre integer, year integer, rating integer) + """ +AUTHORS_SQL = """ + create table authors(id integer primary key, name varchar, birthdate text) + """ +GENRES_SQL = """ + create table genres(id integer primary key, name varchar) + """ +INSERT_AUTHOR_SQL = """ + insert into authors(name, birthdate) values(?, ?) + """ +INSERT_GENRE_SQL = """ + insert into genres(name) values(?) + """ +INSERT_BOOK_SQL = """ + insert into books(title, year, author, genre, rating) + values(?, ?, ?, ?, ?) + """ + +def init_db(): + """ + init_db() + Initializes the database. + If tables "books" and "authors" are already in the database, do nothing. + Return value: None or raises ValueError + The error value is the QtSql error instance. + """ + def check(func, *args): + if not func(*args): + raise ValueError(func.__self__.lastError()) + db = QSqlDatabase.addDatabase("QSQLITE") + db.setDatabaseName(":memory:") + + check(db.open) + + q = QSqlQuery() + check(q.exec_, BOOKS_SQL) + check(q.exec_, AUTHORS_SQL) + check(q.exec_, GENRES_SQL) + check(q.prepare, INSERT_AUTHOR_SQL) + + asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1)) + greeneId = add_author(q, "Graham Greene", date(1904, 10, 2)) + pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28)) + + check(q.prepare,INSERT_GENRE_SQL) + sfiction = add_genre(q, "Science Fiction") + fiction = add_genre(q, "Fiction") + fantasy = add_genre(q, "Fantasy") + + check(q.prepare,INSERT_BOOK_SQL) + add_book(q, "Foundation", 1951, asimovId, sfiction, 3) + add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4) + add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3) + add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3) + add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4) + add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3) + add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3) + add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4) + add_book(q, "The Third Man", 1950, greeneId, fiction, 5) + add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4) + add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3) + add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3) + add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3) diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books.png new file mode 100644 index 0000000000000000000000000000000000000000..e456b7d8f92cece99aa8bde1e0ef06cbca9b703e GIT binary patch literal 34658 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 CjD>Ij literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/chapter2_books_with_relation.png new file mode 100644 index 0000000000000000000000000000000000000000..82a5f449cca134a51456d22d15445c52e772d768 GIT binary patch literal 44122 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 AQUCw| literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png b/sources/pyside2/doc/tutorials/portingguide/chapter2/images/star.png new file mode 100644 index 0000000000000000000000000000000000000000..87f4464bd5ea7af0c0ff30aad5464569a5df1b31 GIT binary patch literal 782 zcmV+p1M&QcP)Gk7=GnC00006VoOIv0RI600RN!9r;`8x0-H%h zK~y-)W0*Q)9wR#D{PkJQ|JUdI z{@>o9^?yZ_>`xXJR_kdq=c5MV6N#Z+5elIEd5SEKu8pu z0ZdRV2E-Xad?Gu_@aO6I2LFNV13S0I?nr7X$Ip zs6gGHtqDpX1O5Q is a StarRating, we + handle the painting ourselves. For the other items, we + let the base class handle the painting as usual. + + In a polished application, we'd use a better check than + the column number to find out if we needed to paint the + stars, but it works for the purposes of this example. + """ + if index.column() != 5: + # Since we draw the grid ourselves: + opt = copy.copy(option) + opt.rect = option.rect.adjusted(0, 0, -1, -1) + QSqlRelationalDelegate.paint(self, painter, opt, index) + else: + model = index.model() + if option.state & QStyle.State_Enabled: + if option.state & QStyle.State_Active: + color_group = QPalette.Normal + else: + color_group = QPalette.Inactive + else: + color_group = QPalette.Disabled + + if option.state & QStyle.State_Selected: + painter.fillRect(option.rect, + option.palette.color(color_group, QPalette.Highlight)) + rating = model.data(index, Qt.DisplayRole) + width = self.star.width() + height = self.star.height() + x = option.rect.x() + y = option.rect.y() + (option.rect.height() / 2) - (height / 2) + for i in range(rating): + painter.drawPixmap(x, y, self.star) + x += width + + # Since we draw the grid ourselves: + self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)) + + pen = painter.pen() + painter.setPen(option.palette.color(QPalette.Mid)) + painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight()) + painter.drawLine(option.rect.topRight(), option.rect.bottomRight()) + painter.setPen(pen) + + def sizeHint(self, option, index): + """ Returns the size needed to display the item in a QSize object. """ + if index.column() == 5: + size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1) + return size_hint + # Since we draw the grid ourselves: + return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1) + + def editorEvent(self, event, model, option, index): + if index.column() != 5: + return False + + if event.type() == QEvent.MouseButtonPress: + mouse_pos = event.pos() + new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width()) + stars = max(0, min(new_stars, 5)) + model.setData(index, stars) + # So that the selection can change + return False + + return True + + def createEditor(self, parent, option, index): + if index.column() != 4: + return QSqlRelationalDelegate.createEditor(self, parent, option, index) + + # For editing the year, return a spinbox with a range from -1000 to 2100. + spinbox = QSpinBox(parent) + spinbox.setFrame(False) + spinbox.setMaximum(2100) + spinbox.setMinimum(-1000) + return spinbox diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py new file mode 100644 index 0000000..087b0c2 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookdelegate.py @@ -0,0 +1,133 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import copy, os +from PySide2.QtSql import QSqlRelationalDelegate +from PySide2.QtWidgets import (QItemDelegate, QSpinBox, QStyledItemDelegate, + QStyle, QStyleOptionViewItem) +from PySide2.QtGui import QMouseEvent, QPixmap, QPalette, QImage +from PySide2.QtCore import QEvent, QSize, Qt, QUrl + +class BookDelegate(QSqlRelationalDelegate): + """Books delegate to rate the books""" + + def __init__(self, star_png, parent=None): + QSqlRelationalDelegate.__init__(self, parent) + self.star = QPixmap(":/images/star.png") + + def paint(self, painter, option, index): + """ Paint the items in the table. + + If the item referred to by is a StarRating, we + handle the painting ourselves. For the other items, we + let the base class handle the painting as usual. + + In a polished application, we'd use a better check than + the column number to find out if we needed to paint the + stars, but it works for the purposes of this example. + """ + if index.column() != 5: + # Since we draw the grid ourselves: + opt = copy.copy(option) + opt.rect = option.rect.adjusted(0, 0, -1, -1) + QSqlRelationalDelegate.paint(self, painter, opt, index) + else: + model = index.model() + if option.state & QStyle.State_Enabled: + if option.state & QStyle.State_Active: + color_group = QPalette.Normal + else: + color_group = QPalette.Inactive + else: + color_group = QPalette.Disabled + + if option.state & QStyle.State_Selected: + painter.fillRect(option.rect, + option.palette.color(color_group, QPalette.Highlight)) + rating = model.data(index, Qt.DisplayRole) + width = self.star.width() + height = self.star.height() + x = option.rect.x() + y = option.rect.y() + (option.rect.height() / 2) - (height / 2) + for i in range(rating): + painter.drawPixmap(x, y, self.star) + x += width + + # Since we draw the grid ourselves: + self.drawFocus(painter, option, option.rect.adjusted(0, 0, -1, -1)) + + pen = painter.pen() + painter.setPen(option.palette.color(QPalette.Mid)) + painter.drawLine(option.rect.bottomLeft(), option.rect.bottomRight()) + painter.drawLine(option.rect.topRight(), option.rect.bottomRight()) + painter.setPen(pen) + + def sizeHint(self, option, index): + """ Returns the size needed to display the item in a QSize object. """ + if index.column() == 5: + size_hint = QSize(5 * self.star.width(), self.star.height()) + QSize(1, 1) + return size_hint + # Since we draw the grid ourselves: + return QSqlRelationalDelegate.sizeHint(self, option, index) + QSize(1, 1) + + def editorEvent(self, event, model, option, index): + if index.column() != 5: + return False + + if event.type() == QEvent.MouseButtonPress: + mouse_pos = event.pos() + new_stars = int(0.7 + (mouse_pos.x() - option.rect.x()) / self.star.width()) + stars = max(0, min(new_stars, 5)) + model.setData(index, stars) + # So that the selection can change + return False + + return True + + def createEditor(self, parent, option, index): + if index.column() != 4: + return QSqlRelationalDelegate.createEditor(self, parent, option, index) + + # For editing the year, return a spinbox with a range from -1000 to 2100. + spinbox = QSpinBox(parent) + spinbox.setFrame(False) + spinbox.setMaximum(2100) + spinbox.setMinimum(-1000) + return spinbox diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc b/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc new file mode 100644 index 0000000..d6ad213 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/books.qrc @@ -0,0 +1,5 @@ + + + images/star.png + + diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp new file mode 100644 index 0000000..76f3c9d --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.cpp @@ -0,0 +1,171 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "bookwindow.h" +#include "bookdelegate.h" +#include "initdb.h" + +#include + +BookWindow::BookWindow() +{ + ui.setupUi(this); + + if (!QSqlDatabase::drivers().contains("QSQLITE")) + QMessageBox::critical( + this, + "Unable to load database", + "This demo needs the SQLITE driver" + ); + + // Initialize the database: + QSqlError err = initDb(); + if (err.type() != QSqlError::NoError) { + showError(err); + return; + } + + // Create the data model: + model = new QSqlRelationalTableModel(ui.bookTable); + model->setEditStrategy(QSqlTableModel::OnManualSubmit); + model->setTable("books"); + + // Remember the indexes of the columns: + authorIdx = model->fieldIndex("author"); + genreIdx = model->fieldIndex("genre"); + + // Set the relations to the other database tables: + model->setRelation(authorIdx, QSqlRelation("authors", "id", "name")); + model->setRelation(genreIdx, QSqlRelation("genres", "id", "name")); + + // Set the localized header captions: + model->setHeaderData(authorIdx, Qt::Horizontal, tr("Author Name")); + model->setHeaderData(genreIdx, Qt::Horizontal, tr("Genre")); + model->setHeaderData(model->fieldIndex("title"), + Qt::Horizontal, tr("Title")); + model->setHeaderData(model->fieldIndex("year"), Qt::Horizontal, tr("Year")); + model->setHeaderData(model->fieldIndex("rating"), + Qt::Horizontal, tr("Rating")); + + // Populate the model: + if (!model->select()) { + showError(model->lastError()); + return; + } + + // Set the model and hide the ID column: + ui.bookTable->setModel(model); + ui.bookTable->setItemDelegate(new BookDelegate(ui.bookTable)); + ui.bookTable->setColumnHidden(model->fieldIndex("id"), true); + ui.bookTable->setSelectionMode(QAbstractItemView::SingleSelection); + + // Initialize the Author combo box: + ui.authorEdit->setModel(model->relationModel(authorIdx)); + ui.authorEdit->setModelColumn( + model->relationModel(authorIdx)->fieldIndex("name")); + + ui.genreEdit->setModel(model->relationModel(genreIdx)); + ui.genreEdit->setModelColumn( + model->relationModel(genreIdx)->fieldIndex("name")); + + // Lock and prohibit resizing of the width of the rating column: + ui.bookTable->horizontalHeader()->setSectionResizeMode( + model->fieldIndex("rating"), + QHeaderView::ResizeToContents); + + QDataWidgetMapper *mapper = new QDataWidgetMapper(this); + mapper->setModel(model); + mapper->setItemDelegate(new BookDelegate(this)); + mapper->addMapping(ui.titleEdit, model->fieldIndex("title")); + mapper->addMapping(ui.yearEdit, model->fieldIndex("year")); + mapper->addMapping(ui.authorEdit, authorIdx); + mapper->addMapping(ui.genreEdit, genreIdx); + mapper->addMapping(ui.ratingEdit, model->fieldIndex("rating")); + + connect(ui.bookTable->selectionModel(), + &QItemSelectionModel::currentRowChanged, + mapper, + &QDataWidgetMapper::setCurrentModelIndex + ); + + ui.bookTable->setCurrentIndex(model->index(0, 0)); + createMenuBar(); +} + +void BookWindow::showError(const QSqlError &err) +{ + QMessageBox::critical(this, "Unable to initialize Database", + "Error initializing database: " + err.text()); +} + +void BookWindow::createMenuBar() +{ + QAction *quitAction = new QAction(tr("&Quit"), this); + QAction *aboutAction = new QAction(tr("&About"), this); + QAction *aboutQtAction = new QAction(tr("&About Qt"), this); + + QMenu *fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(quitAction); + + QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); + helpMenu->addAction(aboutAction); + helpMenu->addAction(aboutQtAction); + + connect(quitAction, &QAction::triggered, this, &BookWindow::close); + connect(aboutAction, &QAction::triggered, this, &BookWindow::about); + connect(aboutQtAction, &QAction::triggered, qApp, &QApplication::aboutQt); +} + +void BookWindow::about() +{ + QMessageBox::about(this, tr("About Books"), + tr("

The Books example shows how to use Qt SQL classes " + "with a model/view framework.")); +} diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py new file mode 100644 index 0000000..33b9287 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.py @@ -0,0 +1,137 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from __future__ import print_function, absolute_import + +from PySide2.QtWidgets import (QAction, QAbstractItemView, QDataWidgetMapper, + QHeaderView, QMainWindow, QMessageBox) +from PySide2.QtGui import QKeySequence +from PySide2.QtSql import (QSqlRelation, QSqlRelationalTableModel, QSqlTableModel, + QSqlError) +from PySide2.QtCore import QAbstractItemModel, QObject, QSize, Qt, Slot +import createdb +from ui_bookwindow import Ui_BookWindow +from bookdelegate import BookDelegate + + +class BookWindow(QMainWindow, Ui_BookWindow): + # """A window to show the books available""" + + def __init__(self): + QMainWindow.__init__(self) + self.setupUi(self) + + #Initialize db + createdb.init_db() + + model = QSqlRelationalTableModel(self.bookTable) + model.setEditStrategy(QSqlTableModel.OnManualSubmit) + model.setTable("books") + + # Remember the indexes of the columns: + author_idx = model.fieldIndex("author") + genre_idx = model.fieldIndex("genre") + + # Set the relations to the other database tables: + model.setRelation(author_idx, QSqlRelation("authors", "id", "name")) + model.setRelation(genre_idx, QSqlRelation("genres", "id", "name")) + + # Set the localized header captions: + model.setHeaderData(author_idx, Qt.Horizontal, self.tr("Author Name")) + model.setHeaderData(genre_idx, Qt.Horizontal, self.tr("Genre")) + model.setHeaderData(model.fieldIndex("title"), Qt.Horizontal, self.tr("Title")) + model.setHeaderData(model.fieldIndex("year"), Qt.Horizontal, self.tr("Year")) + model.setHeaderData(model.fieldIndex("rating"), Qt.Horizontal, self.tr("Rating")) + + if not model.select(): + print(model.lastError()) + + # Set the model and hide the ID column: + self.bookTable.setModel(model) + self.bookTable.setItemDelegate(BookDelegate(self.bookTable)) + self.bookTable.setColumnHidden(model.fieldIndex("id"), True) + self.bookTable.setSelectionMode(QAbstractItemView.SingleSelection) + + # Initialize the Author combo box: + self.authorEdit.setModel(model.relationModel(author_idx)) + self.authorEdit.setModelColumn(model.relationModel(author_idx).fieldIndex("name")) + + self.genreEdit.setModel(model.relationModel(genre_idx)) + self.genreEdit.setModelColumn(model.relationModel(genre_idx).fieldIndex("name")) + + # Lock and prohibit resizing of the width of the rating column: + self.bookTable.horizontalHeader().setSectionResizeMode(model.fieldIndex("rating"), + QHeaderView.ResizeToContents) + + mapper = QDataWidgetMapper(self) + mapper.setModel(model) + mapper.setItemDelegate(BookDelegate(self)) + mapper.addMapping(self.titleEdit, model.fieldIndex("title")) + mapper.addMapping(self.yearEdit, model.fieldIndex("year")) + mapper.addMapping(self.authorEdit, author_idx) + mapper.addMapping(self.genreEdit, genre_idx) + mapper.addMapping(self.ratingEdit, model.fieldIndex("rating")) + + selection_model = self.bookTable.selectionModel() + selection_model.currentRowChanged.connect(mapper.setCurrentModelIndex) + + self.bookTable.setCurrentIndex(model.index(0, 0)) + self.create_menubar() + + def showError(err): + QMessageBox.critical(self, "Unable to initialize Database", + "Error initializing database: " + err.text()) + + def create_menubar(self): + file_menu = self.menuBar().addMenu(self.tr("&File")) + quit_action = file_menu.addAction(self.tr("&Quit")) + quit_action.triggered.connect(qApp.quit) + + help_menu = self.menuBar().addMenu(self.tr("&Help")) + about_action = help_menu.addAction(self.tr("&About")) + about_action.setShortcut(QKeySequence.HelpContents) + about_action.triggered.connect(self.about) + aboutQt_action = help_menu.addAction("&About Qt") + aboutQt_action.triggered.connect(qApp.aboutQt) + + def about(self): + QMessageBox.about(self, self.tr("About Books"), + self.tr("

The Books example shows how to use Qt SQL classes " + "with a model/view framework.")) diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui new file mode 100644 index 0000000..e166828 --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/bookwindow.ui @@ -0,0 +1,149 @@ + + + + + BookWindow + + + + 0 + 0 + 601 + 420 + + + + Books + + + + + 9 + + + 6 + + + + + Books + + + + 9 + + + 6 + + + + + QAbstractItemView::SelectRows + + + + + + + Details + + + + + + <b>Title:</b> + + + + + + + true + + + + + + + <b>Author: </b> + + + + + + + true + + + + + + + <b>Genre:</b> + + + + + + + true + + + + + + + <b>Year:</b> + + + + + + + true + + + + + + 2100 + + + -1000 + + + + + + + <b>Rating:</b> + + + + + + + 5 + + + + + + + + + + + + + + + bookTable + titleEdit + authorEdit + genreEdit + yearEdit + + + + diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst b/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst new file mode 100644 index 0000000..6d7db9e --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/chapter3.rst @@ -0,0 +1,121 @@ +Chapter 3: Port ``bookdwindow.cpp`` to ``bookwindow.py`` +********************************************************* + +After the bookdelegate, port the C++ code for the +``BookWindow`` class. It offers a QMainWindow, containing a +``QTableView`` to present the books data, and a **Details** +section with a set of input fields to edit the selected row +in the table. To begin with, create the ``bookwindow.py`` +and add the following imports to it: + +.. literalinclude:: bookwindow.py + :language: python + :linenos: + :lines: 40-53 + +.. note:: The imports include the ``BookDelegate`` you + ported earlier and the ``Ui_BookWindow``. The pyside-uic + tool generates the ``ui_bookwindow`` Python code based + on the ``bookwindow.ui`` XML file. + +To generate this Python code, run the following command on the +prompt: + +.. code-block:: + + pyside2-uic bookwindow.ui > ui_bookwindow.py + +Try porting the remaining code now. To begin with, here is +how both the versions of the constructor code looks: + +C++ version +------------ + +.. literalinclude:: bookwindow.cpp + :language: c++ + :linenos: + :lines: 57-140 + +Python version +--------------- + +.. literalinclude:: bookwindow.py + :language: python + :linenos: + :lines: 53-116 + +.. note:: The Python version of the ``BookWindow`` class + definition inherits from both ``QMainWindow`` and + ``Ui_BookWindow``, which is defined in the + ``ui_bookwindow.py`` file that you generated earlier. + +Here is how the rest of the code looks like: + +C++ version +------------ + +.. literalinclude:: bookwindow.cpp + :language: c++ + :linenos: + :lines: 115- + +Python version +--------------- + +.. literalinclude:: bookwindow.py + :language: python + :linenos: + :lines: 117- + +Now that all the necessary pieces are in place, try to put +them together in ``main.py``. + +.. literalinclude:: main.py + :language: python + :linenos: + :lines: 40- + +Try running this to see if you get the following output: + +.. image:: images/chapter3-books.png + :alt: BookWindow with a QTableView and a few input fields + +Now, if you look back at :doc:`chapter2 <../chapter2/chapter2>`, +you'll notice that the ``bookdelegate.py`` loads the +``star.png`` from the filesytem. Instead, you could add it +to a ``qrc`` file, and load from it. The later approach is +rececommended if your application is targeted for +different platforms, as most of the popular platforms +employ stricter file access policy these days. + +To add the ``star.png`` to a ``.qrc``, create a file called +``books.qrc`` and the following XML content to it: + +.. literalinclude:: books.qrc + :linenos: + +This is a simple XML file defining a list all resources that +your application needs. In this case, it is the ``star.png`` +image only. + +Now, run the ``pyside2-rcc`` tool on the ``books.qrc`` file +to generate ``rc_books.py``. + +.. code-block:: + + pyside2-rcc books.qrc > rc_books.py + +Once you have the Python script generated, make the +following changes to ``bookdelegate.py`` and ``main.py``: + +.. literalinclude:: bookdelegate.py + :diff: ../chapter2/bookdelegate.py + +.. literalinclude:: main.py + :diff: main-old.py + +Although there will be no noticeable difference in the UI +after these changes, using a ``.qrc`` is a better approach. + +Now that you have successfully ported the SQL Books example, +you know how easy it is. Try porting another C++ application. diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py b/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py new file mode 100644 index 0000000..8fb20cd --- /dev/null +++ b/sources/pyside2/doc/tutorials/portingguide/chapter3/createdb.py @@ -0,0 +1,131 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +from PySide2.QtSql import QSqlDatabase, QSqlError, QSqlQuery +from datetime import date + + +def add_book(q, title, year, authorId, genreId, rating): + q.addBindValue(title) + q.addBindValue(year) + q.addBindValue(authorId) + q.addBindValue(genreId) + q.addBindValue(rating) + q.exec_() + + +def add_genre(q, name): + q.addBindValue(name) + q.exec_() + return q.lastInsertId() + + +def add_author(q, name, birthdate): + q.addBindValue(name) + q.addBindValue(str(birthdate)) + q.exec_() + return q.lastInsertId() + +BOOKS_SQL = """ + create table books(id integer primary key, title varchar, author integer, + genre integer, year integer, rating integer) + """ +AUTHORS_SQL = """ + create table authors(id integer primary key, name varchar, birthdate text) + """ +GENRES_SQL = """ + create table genres(id integer primary key, name varchar) + """ +INSERT_AUTHOR_SQL = """ + insert into authors(name, birthdate) values(?, ?) + """ +INSERT_GENRE_SQL = """ + insert into genres(name) values(?) + """ +INSERT_BOOK_SQL = """ + insert into books(title, year, author, genre, rating) + values(?, ?, ?, ?, ?) + """ + +def init_db(): + """ + init_db() + Initializes the database. + If tables "books" and "authors" are already in the database, do nothing. + Return value: None or raises ValueError + The error value is the QtSql error instance. + """ + def check(func, *args): + if not func(*args): + raise ValueError(func.__self__.lastError()) + db = QSqlDatabase.addDatabase("QSQLITE") + db.setDatabaseName(":memory:") + + check(db.open) + + q = QSqlQuery() + check(q.exec_, BOOKS_SQL) + check(q.exec_, AUTHORS_SQL) + check(q.exec_, GENRES_SQL) + check(q.prepare, INSERT_AUTHOR_SQL) + + asimovId = add_author(q, "Isaac Asimov", date(1920, 2, 1)) + greeneId = add_author(q, "Graham Greene", date(1904, 10, 2)) + pratchettId = add_author(q, "Terry Pratchett", date(1948, 4, 28)) + + check(q.prepare,INSERT_GENRE_SQL) + sfiction = add_genre(q, "Science Fiction") + fiction = add_genre(q, "Fiction") + fantasy = add_genre(q, "Fantasy") + + check(q.prepare,INSERT_BOOK_SQL) + add_book(q, "Foundation", 1951, asimovId, sfiction, 3) + add_book(q, "Foundation and Empire", 1952, asimovId, sfiction, 4) + add_book(q, "Second Foundation", 1953, asimovId, sfiction, 3) + add_book(q, "Foundation's Edge", 1982, asimovId, sfiction, 3) + add_book(q, "Foundation and Earth", 1986, asimovId, sfiction, 4) + add_book(q, "Prelude to Foundation", 1988, asimovId, sfiction, 3) + add_book(q, "Forward the Foundation", 1993, asimovId, sfiction, 3) + add_book(q, "The Power and the Glory", 1940, greeneId, fiction, 4) + add_book(q, "The Third Man", 1950, greeneId, fiction, 5) + add_book(q, "Our Man in Havana", 1958, greeneId, fiction, 4) + add_book(q, "Guards! Guards!", 1989, pratchettId, fantasy, 3) + add_book(q, "Night Watch", 2002, pratchettId, fantasy, 3) + add_book(q, "Going Postal", 2004, pratchettId, fantasy, 3) diff --git a/sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png b/sources/pyside2/doc/tutorials/portingguide/chapter3/images/chapter3-books.png new file mode 100644 index 0000000000000000000000000000000000000000..952cb14e8d811c3bad3ae0e6f0e9bdc6066b6e1a GIT binary patch literal 34624 zcmd432Q-{t+de8)5-klu5E2r-6J<#B8ojrOGP;BrWf&rY=)Jdy7Hvdl7$Sl&dhZf_ zj6pEkDCd#i`+MK-{nk0(I{*K9&pO9ivt~W_vu8iMJ$v8ReOL6W+8IK$ z*PYl5*sh)z)3Jj%S`&TV7<^1b^ngf7_PLH{`udDtyzvrzlhDTy<@fT{tAab0>x++G zcDjfACq5cZs2IF*8OE|QjTICz6HIbb-Tb75vA-hx zXA?8u7WSu6U+?!1o1PJpxJS0ly_#2+)P`uP?(v7G_+|LwB5Xo|YTk;>cI(63$vSwyxss3B2+le?&OJS1j8wdoPb$NIwfmdOsQ0CO zJu{?1^PNL7(?(Ct&BmP=;9CaRHu6J5* zK#;sZ>)lKQM0zT(zl60__DL4cUGq~ugU_?6xBPJH0~MTK_DK>-DDpVQAP@L?c|U{w z_zL~KhG_2zT9dwTc=_7s(vHokcgs6nF~8Hs<({;ardzGU$0~C>HLa>9@`6jA0=ZVs z(yg-Rui9J5)8A3pW_5`rwtH+>nalzb_0mRmQJd!cpV5h=_MNfMP4}7(M;$sp&U#=Z zOp%_MRNZB$!^5Pef-5S$B40X^2lLq~x0E|7lrOi^_Vg`3Ij{88fN!`>O(61$Vye1IC< zqot%#;m9x9+jxBYd`3gUqq@<^6zF*Y%RKnkBTM!H!=e{ik<0&A-~@0W`1!qwrfk3INxfN zB7^fHP(+307uJ1KbszA%oVIQ2l(dlKJ@~$Mi;qRysLD1bk=wK=PbF#XWYe#iiqqgD z2{rfX5F<)n#KaeV$y=4p=;-y8gdaii(|S~aPwqsqQ!4AJR?^X+*=V}h%Q=RIE8GtU zUNc=Q?;B4TiYd7}Wih8GYq_Kebnuys>Qw8Xy!l(5%t&1aqJ}ve$`4Pq%a=vp#rXT% zrQ{dZ&iNXbHJ>6+Pv*?Wuw~5%kvSigmA>Wzb+c24qwmCY*JZoFJ^XIQRU)?PeqFZa z$~T-Q7PpNVFE~x!j@2UEu+xv=6n`i}tH&Fo%ZW=De)<{D#71dN#RK#mLJStu6S?xR z5_{`S?yH{4{SVy@4_d!mjKN@1ep40xtM2*$A=#HPKwLBzw@4(o}E@7RkJwYi#G|$h=yHzQ@75mP6m*OM73t~ zp?tQX^qM7($$;pI6>g&otyc~2faR)0S*`asJn9eo9L{EeY2Yjt$ceFbVz%TT;7OgHp=vd~0xM-dwgm5JPV2{7gbA>d~3UKW(OzsMUM1Wko*6-zI0cQ_f~wl zNa6H%S~f~u!`~)0i$G_-uJeJ)8`OQ~@4)sZz#wAEwwH^4HdujD8jcNki;q`_SRY5a zsGI!UX>TiR6SZ$-6n%Cup?35`LGqK=&T=)R0cao*5>5F~fo}7bAreyfs@bCeSRmtr z-$=>HZ@)jk?Ix>TXc!O>KzrX2=6Qa=zZG@X8`?h~&1VAFWY3EnL_WKGeq;0hCzq47 zAFSqsfc3VGn+{Pw!Wf)4?!^uRVC5%m#Z&evYMJHy;;u97`)+;DB0`Tt)>r43R?7LF z36Tx}F*C8a<*Qa63sKpr{{n18y9F(yPV66lUDs|coq7Nm-b%K;gr47NaM{I-}U{t15PySokQtP-3~ezMJ7a zw4}^t@0idIZbvW1GUa``eC}>N<08AtY{>F1(y&ru-*!<5DU|KVSsL=|*)P=FAdm04 z!-{xAMC!a&?>tAcMor*SXx?KTBQ>p;p3<1)cv?(sCIe8(N0J`j(UK60D{Ey>mi8T7 z^g^B7Rm&+&%Aza8VjW5zktJ0gbg@v{8`i&aMc95(D{xM!P{QYhZl z%P(N=%A3_u*Yj~X`LX}(QQ}7L96jc5LvzcTzuKQY3F&xuzoZMQ*uj4F-D34z7ykAe zGT=8qdpis(Loa>JiKNNn5A}fDn45^_D3;~rCfKKVYJ@nd+9CCUVsDF%)p|n1J5^PJ zEG6VQonUlZv)pP)9QhDulsu`7Cc%689*PMl_>8PQ)Z3ibe6}1hw6rREIPm3N2-#)& z^E&~Ed!lPQ6tw4Eczb+m{bzD+`d>T0B;PvmkUf$EMriqUfy#Mjc3ENnzHYCwV5aNc z{&vo+G-C4$3dBvxfucli*9r~KzyBY3XaCK!8(Z-Iv7pRpT4e0eJdAmFUcK!zx{J3s zo*JxeD@)8Cq0U>m3Ub2Us<&9VkRj@pzbp1-=PK^-Tj{5rKYes5G}J#CU4aB-4(v0s z{5kHI#pXIblu(%H9&IMM&lx2mmxM=K(fkNB_0CrY_4tAhGf3n2(m=(}z=u>HBu>A& zgL1^HFjUw%9$b^|m`jp7!;@SW`f)a=<|fYmtqRq{7q^kV1Oeni0~o^U6}CI*JaZHX z8f_+Fdo^cz_Q`jn_4j#OK0Ehg-^Inn37ts_3hL}_f@{pn@}_W`(;qX4V=LyPJMdrk zz>wD7OUUB!=dL5BN6WpN*drXp>hFeFWZMwGaMa_fs+*8UVSWdPVK8}-Rkva=RRc?k zZJ zWDk>ajTbFa=CjOvp4B=_eaay2UF9as7mux7#SQGu&6Uo<*0~d03hNin+x`;~Lwwwn zXEPIfjM#{-0-r79WrkK4)032%71Qm8n;q9Ta%pdMXM$kuP7jWCJuqqFF43722yB?8 zY_iNfpoZ1D-s6wiD!fdE5(mJTwUCKZ#J5L1T?jAUfR*q{F1~f2ePGweoqzM(brkDv zezwTMF|rm^U7S~Z(TE45c*@ejtnjE*|0lbbaXX@)pm|cOj2JYXo5nCq1HT~JN>KOz zp)z?w7%efJ+CVA~av{A}$Y3^v&A!WIJh;(K7e9HC^~MI?Ycpv6B?J=72j7nbSDhTa zXGjvlCZd8D^AwuRh2749z}sG1+b^((>^40}ivsfW6dGRN5z{ElTjvoxFqnIT%uAQ1 zQJf19mF)(kWgqo!V4gzNPD~%>$61Ar3iyUaT0IF+%d>)e=f{i0Q69${_ft{P&UFBa z5)l<`(+ZS$Z!M9N>78R7-hx{n&dpo&f8Ii(x&OfB%*$etgRdK)(%DBq&2PyY2ncZ_ zBr1`ZId-?hoW{As1|;gWovVj1nJ7QWkW-s*0q5ZO;da?!F6&KFcSP1}Q9x_7rO#)v++BVu*$&nW~=>U9t_F_`_pu^@B! zlN!NA^wQaOeHOg&`YK}vx%@R*n1-*QNnJ|G$&ILG7V9b=T?4)beZrxjdy?w(QYyZA zkXm+xCnS7c=qwVE$f#SV+;I2tMR}ER#*(_KjJ=u!;oJrLx!S6QmV5h>&P7+~Gf06- zkIZD#ECbI-od)vXp11_2fi_6RShelhxF%2pG?yauo*cZel_iStIu&)WSc`AwF{N4?@a18QuIXG=NjCy6c_APv(*pD15dt( zV6L(je@Cz~q>mglxuNz`a*D1n&D;#X`GJT&mXV%KFq4TTu5I*bG0LriqP~-d2@;WV z#L1TEezHwLs&30U@7B`a(d8|tMJN$|)a>Vyt-zhTD9mmm66P2=Vt$QliBvNEY>&=g zajy9O$Mg_!t;brL*iGn=r=u6a%~4ebyHxGx^6SR?8rz|*WvxCvYgi(VHgQQzKQhO5 zeNqfjkYsJL<3$fGiBH3^Y>MO>aO$u-px6z#`s#c@;0zwAs}2*}$J@vSozI(4t11r7 z5-49DU8wL{26zQu0>w2B%OM=h%lAWbedziv~Mw@mfNoVb>2{?{4{2TxMeE_++vm#*#H98)ApvY6)*Rx4Dj z49sqH+Lj)IevR9H!Da;Qf1^BLYpG;`t&K=>exx<9+|;c-K)dwjz6`tl58ijmXi7n_1&n+_HEBqRFN+it!^_{XH<~&Q-q7~EiUtd;9(MBF-l;*x}V4JY1?oYYSp-N zIxT7H!9!EVR!6^S6MN5k@YM?lN&ET**k}>wk~!S4^s-@&$sdZRt*^

OD$xI!u|p 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�E3k!RJn{v+)9$E}Z04SzyrM=MP6us=uc zz<5e8{NsZfM_ghf%mf4=OWwMLU@0N*{_&}S^MB|Vf$C$y7fRXNBbkSZgqeP~z?3<} zcfFrypW=u$uOEVcXOsQ+d-^6lwADm}52SoHlIFm1)riB$rDQ|^6P?>%N|yj%*fCm@o^5;u(!U(hJ|N@ES15zPXP-=rv5NjY z6fLmbFZ8$=y~-#@c{&KQdvK8_L(uHz2s>S($(;*~J7BZG9?^7&OJU@WjTC?iO^gbY zi!@R$2Gfmvd^L3`;LixNf5(HTu$Vz_Ob>faQ$gthvFvK{sgG=hE}>O}jPj$2y6?fE z^7H#B&=r<^;VT!p;C#9{&Q_1xV#4zR2Ee^D12RXk!Moi%*AM5y`k5?=scEdwLNv>6 z$FOK6cFT;r$U>*lSwNM`Ib-X&&m(>r`w65~i*AB2xr)hlJdFm8k7)(Lvyfg9?irJ~EEPD6$&v&0g%|Dx9jBuXn zuT_>muVZ&6;J5te{!QejGIf}Y5Xm5SbrTHWcF!KnIg zU*|ZPn^_4&o*Do)Z7{Y)VD*aJ5Tl=9zHV(mH49{YCa>H=B(oSIa?T;|zMILTQZNy^ zI(0SPLe(mUKqehM8njHewu^pmTKn%_0Zs{(3h(}N@=HNZT(l{y-JdLP6yZ~ z^VJONKaYPOD&5Jnsb3g)aH-{UmOzb}ZRX@G0&C*x2ifla0VJ`23cC8Ze2#fa2$0JUL4J53n z$0hynhxanUp=p+Qq7Vya`T(G2PHOsEHZW>jDOp$P63Ju=+JJdE1zsxM!-tv({K6Yf!<<5X_ z%jg;I3`-je@CbaM87(s2Zu>Ipex51(WT&b^E&b?SszcCrlt@uy22mrJ8GJ1^^wsV{ z^E)m8O}fpGCYEq9NA_|zmdvci3>BY%jeFZJH;}i`MYWoL#pzyWT*k!`nq3=n&uIZJ~-)orU(y* z1L)920mLs&$bHtDEf3hLNAn(GD3KMif)U+am;qxPPWtH&515RKU1l<|eG<4`^xxwI))LG`%C#KfC?!`Yk|BVX}?x_=$t=RJ7IkjTF!s84*W8^k*JF%J9 zSCBy@w>-L*3UWG_OXOkzsxvP_ZA*42Ctf}`=e#AV&I6s__C4|5%XVT<^Dyix3Fd+5 z2bSCz^B6pocx>1**#hs~CcK^%<9WO&h&2e5V>509G;AOhWglcH1d+C+9-5gmXWpe- z&=Ex0pN_@9KGaEbd(qkg!(<;}wK^Zhdq8vNW>@JAKoDno4L$Z+bee929S8Ivwfh$06FwM; zm6c?ktXZ}NWIVP###96t8z`SB&+lZmh4=Kc3Q7B7qkuF|{qTSzWI15X8PQG|A~9u& z+b7Z`8ht*yXleh)*UGFd>ag`5m!kCLN*70!gK0b9;-k`vdJ`6Q*z0Y!Lf$hRtr|cE z-D7=7C_b6G2K~mjGwzj2$KFbH1ilkBjy4VS)6a~7%xN-!s|_sbI;qb=(bALd5I4R` zJBRK^iiy)DrnR@KW_IL^iV`x8?eF?sP%+BuN?NK(Q9bFsq1avz0kEd}sL`i?!kXqe zF_6~vai@QcHI+74IZok9Yd&Z~ar_3?EA%N}on1k;PrLx`X$eN$_0@Ah#AH0*m4R4s z3&UXdkv03BqjjMMMZZ3Vt}eddpwE8P&BWkxxoCan;Klt&q7O;N6?K>DR*mPyN&T@)f~Qy(b>+SQ`z1}ql5%4Ht&6+_iM`Aob`g>7otY2&#CRZ`f?ECWEtO_AFKy5-VcZ4c;uC`?bwkW8dLAg{SlKQi?;^HythR_=`=k@q%}YxXy%YQa@KH~!-B)seaHKHlz=H2-XIxb?YRlIfGR zsd~Zt>{ zx!L@hs}7~($}@KyAMclsa4mkbDM^~w)qSB5-td*97MImqV+HnH80r#FY`Y$0@TW5S zYBhBRsl>3F)aixjd2OOe|ikNMBvZUT_UGjV;FvhEFleb@|W**xf^ZXJzvV_ zauiId)D6oowh5csnciFErI<-#RJ%QpH|UDwAx(qKrpgs-hBWPau@7146;R3G0kQ0` zu_d8lM%yAwKBA2h8DKTrN5Ni;O#1}vcp|pd!`#BjG~7x^tJJ38Y4bq2{D)x%>X8OU z>FbdNuJ(mB(`evN=ajZp!d{qDw)^({ct4)p!Jj$o=wpoGBdA0awU1rkUDPqXm!Q9B zaK3EUX7YhqIANrL1UL)dkyEn;BIX&=!_5M)sE$@!4_F-{thDOENY0z1@=V zdw`{@q_k#`_+flF2kbQkpF~JQj}7(+ToLYc6R+UQPyFdCnm)Z>U-V#S8ql=Y&AfNF zx9u6++#b(ENa`viZ57EH`}Z#vEL_bzU&WxrD*GvU_!xb~P53jIMxxzNhtU9h=e*ad z5d@gt(V@x}YFZ9mmZp9wGY)q58PK+CoySj?0hqI^!kJRtrL(Z+KAOl76f^i2{sOsh z9^mj)ls9)55lW2ehBD_)nsVzJ0Zn>tEK;)x#VYB@z-z{zf1Rlk5mob-wyXK%+U`QO zGT)j4@_kc(;oIKLq!{76mI~d#`Sv)bXG7w-rdy&QUVYfac6YqJ95f6>e>q zQA+rZd@T2LSTP70X%2*=V)$2(m1NHj+N+)YfCZ&SBWia=_eKAb|Esm?2pVhF5d&sy z4P!UoMR>bsS)9LW;$6Fm7@5yVx9&$;dyCDNRut2d;Qf(uR9C|n{3FwPcvYEgeO{I&*1y--Nzu}=yVJgt^(auJ@8E7o^nep*Zx&u4n-i zMLP!S_44}NPd7R_6f;I%zm5|x#kN>mpQ$Mq>BRQUomzDD$yE^2Tb!jYlaE`f_`Ycs zWqT&vB6k%XSt#sdGIV%vuljjIkF_h$6ehCp7Fkr$4p8Cw#N6hmM1HQ%4)<`psyKilnEU%msN8Hj#jLU8zVpOYO-+ ztk{xh1tIc29rZ33ZHOW;W+iUM)!{r!0$ReJv*_*NpJR?!wFDW^ax;0h=C1r=WlxM= zyi4lwYt2z#i?L(cL&(JoyKB0UhPYYq72J9?vY#-EMo4UpY*!KD1CK?sswn9E5^62DFxo<9?6k|FNK<-03I*W|LU0EEq z5*pLt9%0as4`Dxv)B~>N>l+KlkC#M^gyfUxep5yJP8U=J=BSB6Hb+nZO+F3o=9~2TltgAXkH!dY$xC~Dh z1V<3{#PO2F6F~KU)$^SDbbog-)!_#C1kgMyMFkl{-2%;P#!&6{fTur3_;`k9pgwSS zy=D$gm7EtIl2x}XP({&U4CaEskCWR3RUb9hIRKE!it?qz_38+fOZ8HyXf%E82bdI;Avq8gkjO%*J!3$fJmC%~H_Pt{uaXN0)&)};5C}+*_>L74@ z#nY9qW46g3-Hn>m=co~AJ_y!A1XA^knR_imD|_0W|5i9>4Td{&ln?y4km8XP2eHF@ zW9^TXpJbIwx$h74&3hgUl}h<|DAOAbr+QJCjWo{>QlJ~>oB(x)YRi%hb_Hq=U>z?i(`T9rCOH(*5(_enye}O4+U_OtB3#=CWEHyE6TsnqXrV>2Cj7)_S z))HKGL9m3X+r-4%PiHwQ1%x%TT-OmB!^ zPSb+bj_k2O8pEOXy{R=?L*`Z68+eE599HJ#fxr**77xa!bEXhqFl&mxda5HKwR`-m zfNAwL#m3&=otk~`N~H>70D3`Gk@UE_xigo9ZyF&oXG*t(aTh5J!&|2aK`O%n3bx z=l^1N(WA;c5`u& z*FtzNROU{tRy>p4`4CksyZ2Vj5D9|5Af}2s#7l+a*An;}_bgy6mibZ24L-io48ShX zaY!@Hjg}4hRdw4Wpr!1`D~P0gLr`KSY8Eekx}jGgJuBM4CD!hkWXc1y$KgJq&0le> zq(sjR8_+@?j9(~X&owYr*!kdH&3@W@(uIdzP1L4WtiKXhdHBu_SK-kw*kHcCaVH39 z3OCl$p`j{;F25tUt#w6rUa@Y8}ykL&kUR+J}UVpz$)|OA^L1LYQ+Wh`4dJeqdW8?S5w^{iHhRb`+G_~NUm7^VS|X zM(3->3=j|6_II$iAIXsN+0JNKhflap*wuRJLbbM3u2gt*ulfQ7qne=(gY4akKNzE& zqTu4~k)!QNqZmVLUIj5da=h!0@$Z{gA!%LVk!DBX@);v<7{qc}U@U%;0STNu7k6zz zF!?tJy{8P+6YX!~^fLTD_-}IQE4MOG)2EM&tR^fxYWhAX1!?uhgew!vSkM|20<<3^ z7AaV@+5h7tijUD zpK=0MThyg6*$bRV-Qih|w2TvD(47X6AS2s-p)Suy+l`N1o_NW%bATW3KiN2vPGR-c zOl0q#i8hWTlv`xlOy_{EH9)shtF4E_D4EM6{@|)Hupn@`v;k@5Y~oFBRY#?|+O@od zExM64U2Q@s9TqHm0Wa#23rh1FEd7!jsUUwDuuyc6|62V5sO2OL z$8A_PqWg22US?A@jD)SqrIEKF&1AsTQa5U#K(@_k6@lgzHjV8<7xoPwo_>7$gHDg1Mf3Cq3X zJ6$~Hwr?7q!@$EGIXZg>84n{`L*4LQ0=2iR-0qdV?DSJi`LvKAMh`6lcR%L+j)_!q~T&vPk)Dzx!{b3*}TFTycNC+29u0xcJC1O$t%L)|Yx%1KQwS&zqh5a|*=Nyf=M>JL{^qR*_NjpAaroU`6 z315jMvlNN(qi9AdG`Kx2LwePO6XR?BM7yCkH=w*|<}#*4Jaor*_NS*Iwzq2uSd4Gn zQc_dFEg@1L*QOe3BSlKn9NvfUV8*ISVe0T3ad2(@qfRM(v^DW@Cag03`S6kb~n!&|;!2U++VIoib)P~--d5_04 zKVw^{{c_ixJh8zI`iB5Pi>KGeaIi)yrtcC&<5!)br1+QhRH)P41>3KTF3xu<72BD^ z#9;>U5Se_o3CAg;&UMj5jqX)~(cU4mw`LGK;6{h`t*x;t)-zC+{zxm`oUsAX))TRF|bu^vViLjh7+u6Be9;Vp}Swi zB6E31l47BsAkGlm&#*XT#46l~jAy-h4G;cPq2euIbCo{_xY$O^`ZI?KxeE`r0aMea zKSQcski_}8y8@rEFHvUZS;&Ox@_p#KT+a#Vk>^9ai7$!qLj$_dq;x}`IjgrGrkdEj zqM@lcW&?j6wq9m&TB38h8s8lQD8C&WZooaI)?|CJ6R>^ysP4otJYnSc_`;u(Ee0_^ z@={Z<;R!w*x|!c>t|p)xxD+(O>~KggJfhKZ`{zPav75!H`Qb!~_#x^kc))&rYM9r$ zf&8-TV+&XD9Aiv!@nn}0DC#ok0TW8;sHAldRC}5+H57=MHZV@$PsIOLXod4%pXefo zf!X}oCj+j!n>=$pX7CH1Z`Gw`o$~TTqQZ8Q7Lw!>{l?JxUIN^1FK44GL_^SuUndhE z*aA`wZ?W@>UtV6TSKVXXTlXQKaYD%ro(O=6k7DS=AAwFJ=0x#DM6tkuvx?xg?kUjSE;{{2tT z0W+kQH#n?N>l++CnrZS)zB;R}57dn-`yCIhs%H{o!f#Nj?y$ZT0&HyJHoZh7DIxTdRQeC42N!WnVFNQ!)``E$X}fkuF|^)Kd2(IObAAN$y4y}y_@4*X#vcbx@c_WGTGPQEY^EK(5i z%0jTqjNc|#L*2yk+vAvy&Tv5ntdpRLy5dRl$|s z<&bzaaRmUK<;i~-YXZBph?~?HxV8(0PGHujYa59mRr<@m0McJLv32aEk-@4Lsu=g$ zNSg;ZKl6ic-3k8#c%_A9_))gXtZ6zMV=kUpj=81sYE@2Yz*T*d0?Jc0s zwTFzoeEH2e^)cnMsN9V@!DLSkidh+wAIzBi@{$fsDv4VeWUKm;nsb0&{f#u2X=ClO zH}GC`BpjNF?#L1~7wJoYkUFA!{hgA@&c^LBwc?qh?$Y8j#VnGjfGz;O@yF0_34oKg zdI{k>C9HQ;!*ffc)ZvLl_<|FgMzCp0d^L2`oAgTVqePvQH0F_Pp+FO!xY=MSL&X&xJ1lw-t`89H6Jrq1R;hSt1f!n!K4j~w zV0X`gmsife@CI3_05kG+d=o+_MsH5tjIPuHm)|X+(!RQv5UXYVQMamV2w+ql5HDof zH{1>MD9R+oRetL45gdSB#(QA(@gZ9TgB*Y)VnpVA?dztlUcMnbVoDyApuoa&i5HIJ zc&ZnBpTw+g{$75y>XI?w_Wt6(mNf_Do$w?eo#x4(n(@_Kdc_m_u-W5o#qbI99rzY2 zVC2E`vFS|qqKT^Zy}c=JF3ONe%FYjRg97@8U?r&GSx#jJ%C9m zy<=IfV_@LQS6f%tQL0-q4E4O1Gqj@_|GLkut>h`Sc4hkWBoQ8|V%TS~O@kO(5|Qou z7Rq@biLvA8+IOp=&(WfXlDY6rx#^qNNSPBIr`mYuJ)p;LQ=F)-vj!YjG;KvV{332( z24>p|o}QTu+w1xwMzq2X5>(Kh3$7p zVn(0K%onI{LQVfSH|eJjz&*pmo&lL6z$ngTo~4geO9#9GTb#*|U=AEud|D*Naqp6v{bi-rPDHu{Ou~GNowt7Uej@q|3(F%aH)<#aT zL@d~uJvEgYGY5dnPtt*+Z}qBzLxB=(bls0cM6SveWB%Q@1(?ve^~N>VZ-k~WUgW&e z5#Sn;j|KAq_n_WNX&N;9BYy$UzdkiCI%G{u88@J@oKN8Pl0eJ*?&1!_A_4QlU_h343 zm~K7HNGNm+@gZViJ*Qkg-_t`-e=Io(GG$W$ns2M~-pTOR+bRcq*6MOV=F!`>=U2Ag z^+5^0h%92sc7q+9E`n@|N^6&j+ik>FA}!6NpvU}1=GAX|0AF1*)F05QH| zirOXDfA)&?T&3*TQy}V?%p`=wu${j(CGe2eFn^vgpf^Sb-dT;VX{ck1Je$ zaZtk_C-ncIHQ4Z3NDkcf-B^NaTjt$D%y*g1K@8XxmCm+vX|9!e(4f9E>3rk;nZK8N zn(BuTu>{l6y_ZWJ@+wPtpGlH3{y`!sxJj-L2$$guNYUo=f?LSe)j|?Cj9PIB1yH}F zp;+yU(QNk%sPvU2h3-%6dz~&b zg9N!%ZZVpdivt?ygMJja%9l}&7Z5~-EY`3eeG3A2t34vP7c!tVtWWJTJ4^05zl92ho&5Qb2&IJTUriz8zoAu-+))5j!S9nH43NcNK(0YRJIk^4%)mv03G=K z3uyHvz+>{W=6gtjzA_L+@4XS+3Edc88vp(hwpQGnht%I{bnv6$zA0IH;Qew&0w5fM z{OL;px)wlNUiP;jdG@Vb``%R4)h+AUJ2_PtBP-iy0sS!46ANaAg zfIObB{Nf`%&p89gQ1&J5DeNLIjkgan*gpcd zlwNNo&oXNE2gkS)5Ai`vr5hzTqMr+kPQt$UWf;r5R;D@Fk>b-`)#^$6%Q;cLOpmmm zUC|AUN5qhpbWLS-wdOyB3y*>No1y*wc>=FVBMbJpUKro4*^Xr;c$25Cf`#Gk7=GnC00006VoOIv0RI600RN!9r;`8x0-H%h zK~y-)W0*Q)9wR#D{PkJQ|JUdI z{@>o9^?yZ_>`xXJR_kdq=c5MV6N#Z+5elIEd5SEKu8pu z0ZdRV2E-Xad?Gu_@aO6I2LFNV13S0I?nr7X$Ip zs6gGHtqDpX1O5Q` for more +information. In addition, familiarize yourself with the +basic differences between Qt in C++ and in Python. + +Basic differences +================== + +This section highlights some of the basic differences +between C++ and Python, and how Qt differs between these +two contexts. + +C++ vs Python +-------------- + +* In the interest of code reuse, both C++ and Python + provide ways for one file of code to use facilities + provided by another. In C++, this is done using the + ``#include`` directive to access the API definition of + the reused code. The Python equivalent is an ``import`` + statement. +* The constructor of a C++ class shares the name of its + class and automatically calls the constructor of any + base-classes (in a predefined order) before it runs. + In Python, the ``__init__()`` method is the constructor + of the class, and it can explicitly call base-class + constructors in any order. +* C++ uses the keyword, ``this``, to implicitly refer to + the current object. In python, you need to explicitly + mention the current object as the first parameter + to each instance method of the class; it is conventionally + named ``self``. +* And more importantly, forget about curly braces, {}, and + semi-colon, ;. +* Precede variable definitions with the ``global`` keyword, + only if they need global scope. + +.. code:: python + + var = None + def func(key, value = None): + """Does stuff with a key and an optional value. + + If value is omitted or None, the value from func()'s + last call is reused. + """ + global var + if value is None: + if var is None: + raise ValueError("Must pass a value on first call", key, value) + value = var + else: + var = value + doStuff(key, value) + +In this example, ``func()`` would treat ``var`` as a local +name without the ``global`` statement. This would lead to +a ``NameError`` in the ``value is None`` handling, on +accessing ``var``. For more information about this, see +`Python refernce documentation `_. + +.. _python refdoc: https://docs.python.org/3/reference/simple_stmts.html#the-global-statement + +.. tip:: Python being an interpreted language, most often + the easiest way is to try your idea in the interperter. + You could call the ``help()`` function in the + interpreter on any built-in function or keyword in + Python. For example, a call to ``help(import)`` should + provide documentation about the ``import`` statment + +Last but not the least, try out a few examples to +familiarize yourself with the Python coding style and +follow the guidelines outlined in the +`PEP8 - Style Guide `_. + +.. _pep8: + +.. code-block:: python + + import sys + + from PySide2.QtWidgets import QApplication, QLabel + + app = QApplication(sys.argv) + label = QLabel("Hello World") + label.show() + sys.exit(app.exec_()) + +.. note:: Qt provides classes that are meant to manage + the application-specific requirements depending on + whether the application is console-only + (QCoreApplication), GUI with QtWidgets (QApplication), + or GUI without QtWidgets (QGuiApplication). These + classes load necessary plugins, such as the GUI + libraries required by an application. In this case, it is + QApplication that is initialized first as the application + has a GUI with QtWidgets. + +Qt in the C++ and Python context +--------------------------------- + +Qt behaves the same irrespective of whether it is used +in a C++ or a Python application. Considering that C++ +and Python use different language semantics, some +differences between the two variants of Qt are inevitable. +Here are a few important ones that you must be aware of: + +* **Qt Properties**: ``Q_PROPERTY`` macros are used in C++ to add a + public member variable with getter and setter functions. Python's + alternative for this is the ``@property`` decorator before the + getter and setter function definitions. +* **Qt Signals and Slots**: Qt offers a unique callback mechanism, + where a signal is emitted to notify the occurrence of an event, so + that slots connected to this signal can react to it. In C++, + the class definition must define the slots under the + ``public Q_SLOTS:`` and signals under ``Q_SIGNALS:`` + access specifier. You connect these two using one of the + several variants of the QObject::connect() function. Python's + equivalent for this is the `@Slot`` decorator just before the + function definition. This is necessary to register the slots + with the QtMetaObject. +* **QString, QVariant, and other types** + + - Qt for Python does not provide access to QString and + QVariant. You must use Python's native types instead. + - QChar and QStringRef are represented as Python strings, + and QStringList is converted to a list of strings. + - QDate, QDateTime, QTime, and QUrl's __hash__() methods + return a string representation so that identical dates + (and identical date/times or times or URLs) have + identical hash values. + - QTextStream's bin(), hex(), and oct() functions are + renamed to bin_(), hex_(), and oct_() respectively. This + should avoid name conflicts with Python's built-in + functions. + +* **QByteArray**: A QByteArray is treated as a list of + bytes without encoding. The equivalent type in Python + varies; Python 2 uses "str" type, whereas Python 3 uses + "bytes". To avoid confusion, a QString is represented as + an encoded human readable string, which means it is + a "unicode" object in Python 2, and a "str" in Python 3. + +Here is the improved version of the Hello World example, +demonstrating some of these differences: + +.. literalinclude:: hello_world_ex.py + :linenos: + :lines: 40- + +.. note:: The ``if`` block is just a good practice when + developing a Python application. It lets the Python file + behave differently depending on whether it is imported + as a module in another file or run directly. The + ``__name__`` variable will have different values in + these two scenarios. It is ``__main__`` when the file is + run directly, and the module's file name + (``hello_world_ex`` in this case) when imported as a + module. In the later case, everything defined in the + module except the ``if`` block is available to the + importing file. + +Notice that the QPushButton's ``clicked`` signal is +connected to the ``magic`` function to randomly change the +QLabel's ``text`` property. The `@Slot`` decorator marks +the methods that are slots and informs the QtMetaObject about +them. + +Porting a Qt C++ example +========================= + +Qt offers several C++ examples to showcase its features and help +beginners learn. You can try porting one of these C++ examples to +Python. The +`books SQL example `_ +is a good starting point as it does not require you to write UI-specific code in +Python, but can use its ``.ui`` file instead. + +The following chapters guides you through the porting process: + +.. toctree:: + :glob: + :titlesonly: + + chapter1/chapter1 + chapter2/chapter2 + chapter3/chapter3 diff --git a/sources/pyside2/doc/tutorials/qmlapp/logo.png b/sources/pyside2/doc/tutorials/qmlapp/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..30c621c9c669457e8fb338a79d25a86501916de1 GIT binary patch literal 6208 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 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/qmlapp/main.py b/sources/pyside2/doc/tutorials/qmlapp/main.py new file mode 100644 index 0000000..54edf0e --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlapp/main.py @@ -0,0 +1,82 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +#!/usr/bin/env python +# -*- conding: utf-8 -*- + +import os, sys, urllib.request, json +import PySide2.QtQml +from PySide2.QtQuick import QQuickView +from PySide2.QtCore import QStringListModel, Qt, QUrl +from PySide2.QtGui import QGuiApplication + +if __name__ == '__main__': + + #get our data + url = "http://country.io/names.json" + response = urllib.request.urlopen(url) + data = json.loads(response.read().decode('utf-8')) + + #Format and sort the data + data_list = list(data.values()) + data_list.sort() + + #Set up the application window + app = QGuiApplication(sys.argv) + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + + #Expose the list to the Qml code + my_model = QStringListModel() + my_model.setStringList(data_list) + view.rootContext().setContextProperty("myModel",my_model) + + #Load the QML file + qml_file = os.path.join(os.path.dirname(__file__),"view.qml") + view.setSource(QUrl.fromLocalFile(os.path.abspath(qml_file))) + + #Show the window + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + + #execute and cleanup + app.exec_() + del view diff --git a/sources/pyside2/doc/tutorials/qmlapp/newpyproject.png b/sources/pyside2/doc/tutorials/qmlapp/newpyproject.png new file mode 100644 index 0000000000000000000000000000000000000000..93968a52dddb0178058f482bee4510979555725e GIT binary patch literal 16091 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 Bon!z2 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/qmlapp/projectsmode.png b/sources/pyside2/doc/tutorials/qmlapp/projectsmode.png new file mode 100644 index 0000000000000000000000000000000000000000..c66d88723af88fd9a1345519977089d35694d379 GIT binary patch literal 8848 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 Lv=nRPKZN`rLp*g0 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/qmlapp/pyprojname.png b/sources/pyside2/doc/tutorials/qmlapp/pyprojname.png new file mode 100644 index 0000000000000000000000000000000000000000..98328074d16e35abd64aea1e2c33d68c424aecfd GIT binary patch literal 8068 zcmZu$cT`htlMg5_3W9(LNEayzh9V+J2Ss}CL3%UvPNer1dhaMD2vP(?@4W{Molpaz z_uc}_`|h`U_S@Y*?m2Vk&irQPInO-vyZ45xC`l6$P!j+E03unLk7@t_E(id?fjqc( zr)hXt2mt`@0aO$;q+Y&yJB0ih_}vkUof^Epy}=$IV{dM6Z?mduKgfGc>`xjd^*gFa zfA5@pCR=KoSTs3P+X0XB*Y{}IzD}`H8tM8rK0dChruN0W)GwvAva$k}_N}9%qdLXG zUfFVdYh!EwC^xkMgGTDRg$TV>Ox5+NsA|?V{}JRk6nMD5(VOmIqT?NyJ{Xskm+fa9Ts5a8uLKS*nyTsS>>0q^;g6Tu znd>xEHf(OLe*T)KlD4w7wIwAezJ0J&4QpMP8mn*UXl!h3YpxfwY;Ks^S99&Pv9Xz4 z*^lks`JU=!XaTJVkejKE_SK0rH8Z>3?Fy+Sd}+yH_i%CHY6w(-DOOy}AB1-@fbl|61HWb8t_y z`o8Gv92S-sC2#Cg)VFEp;fKDy`59!b%lppOEmzck7`Z&(80LMsKM`c6IX%@ok47ik znx%*T@-Lo2FU_~rSD?{ozsy``7w7KfldOUHtruFa6KK1sru}9{6f>?v%No}JL-mu@-n=o)n>bj^27brZEC-#$BecQ8_1g8 zVAt)8tqnC)>uT~W3U}vcSE|29WCz;Yc$BBttvaRlMtgeoPA{C!eB%YxW>)oyNtyQb z^_7*E71~-F$|yO6rS^;?qKhUs`~M(^hg8gC0_yf*Fqo-<_C9(bAt^rRXM?SlwuFol zVsH$D*{bXs(+o#KLVx5(rs~Rwh5FcddqJJNB7c{ZrNPP(y%m3UvCF90f`St4(VBy$ zuP@lXq_on^${wELS-EginVr}*vma`&8y)5!3G1v5v-3;)g+ie=_C~g_w}zIf?%_>d z9-cp7FhQrj)7i?=NmQVYs)3F(W~R5d`di09i{MKk%tY0~F;+>|7FiU487S=e(VRp| z&~(=l4;^H5odE#i&c835Bo1O40DzWV_M?Ob1ZR7;B4Sy9w&!5O$DT1zg^sGMR;*U{ zLB0k-gX6~GUt(R20S>&l9Zu&@PjO1n>=MLo4bvGW5nJOwrYHs8_w71xchNI<#Vz3H zF;k})GB0u05$-%C32vbHs68@o1?q%{fk}CQCVva@-(p>s;9(kiGx1vbqCgY9f)bYt zqPUk;1tlE$QsgfPEBYk#UH~vzrdCYafQ1Z)q_s>x}ZTS1rHGI3=~8cvov&5{YIs+ z`mZ~I(^g$;P{1LJnkz0q1=R?{3o876r z$Mu?=dQtqEWuBhfJsq~d`DF`+xfW9n*LhlkHMoK3%}q^Xrb&3+Bi+Y=>|Ch(l!KQ! z(1H{n2?nxQ*!%qXbthjM+Rw-VJrGt>L5d>ztSP0&_90`?A?8UlU+WoB1-_ZWNqX{bG}zo#*z|-4M;-yC zGs3S3q$amoe!R~D%x7LBsu-jdCdMC4fsZk!9!fZv);_;^&o^Z88=St{W^C@9vqn1F z4D{Xm9#S#63%7bkz6_XNHUCvsIm#Vfefn}T#?&i?($KW2G3|(?fVwoD&+gGEvV3@W z*pQ(m`Cy4x$t4oI-mdmWT|8pvf~4#<0fRq_fTn19jbJ|9V4;eKH6=O$@kk;Cg=@3s zV4AAM(S^k}kwetckes0Fqoj2l>Eh^bsKWu@o7^7rz?|gvx7E4N{XfBrB zW9K*MyqDD6b0Yn%aF)}d_{P)PGBZx8_Yb)5GapVKZ0w5_2S1I@vl`Tq(TaIMykWDm z-ZwrN-q@^EBABkbe`}@3f-Lu)U8h~~CS35QXqnHaFiBtz@hyCLf3beneusHU2~E5G z=_+jYqUta*XQ}aBrr%o_U*q6={g0;NWNn_-$w8LM>U~5ap709BO*m{q1~EH4@rdci zRENfE%BJ;3(M$=C*=OWDno_ad@JtS0+?6xq^+ZI8Nu?MtKjwNOMw8h;9V;uZj9XJU ztg5bk5eml@k(~_@Nw^j+A));EM5iEl8H4N3D=XO{iqFiK)@W}JXA7|mF>eT0}hWTIJ(t?NJL0(v%(-E{Le3Ku}qrNdy<90t!L&clRY%I z;%EiL^uEtwRiQi3bja6QMxP5ilLoX9 zKa?_f?|Hf>`gCZAs9KIf;M!`>$1lD1NHp3rMZS4zRAMiYmNeGD>&tsRXaE6GOmAP; zgj3ADr_P=GJtQx+M8sb`c=1s5EiWc+zQ=!c7j2815Uq!B{!KqFu0<^jR? zz?Y>OtJ8Q@R#gRwa3?PVqJx@&-S~b_H-4IcCxpm1vnxwWj*v;?Wl3t2lP{)GYZrTZ zNM$?$M(UOmd&I*0VXAcIW0&J!2EZd~rSH=Bz}Ovo8&JayHawK4#`(}>R84vfZv=T5 zDW`t67#5t++5OI6awkN0{Hr$J{THF|sY=m{m4wO1dwdK^(1j(91sjr5?#-FW?6boj zyOtvTq%F-R&xnITpyT})!SLE&wUv=Ve4U4HSXo6Qm1-d*7yMnTbi3n+XcVP-@^sN( z1~MFN51s?BzK@>&`p~^5TEjGf4=Qrmn%CoW%{E4I3_q;)IOa^JsNAfyZYzovm^aVo zGl7Iavacxhg&wztSDRM17HKIdzL|5-H$PUNvw z+5Rqm^jSTVj*qy zk*SBcy&0v5oPO*Qn(mz!i(A8P1A$OaGl82;+NwQJz^B#l1ul z+1p(;D6fG4_JEJFxu3{crVWuH_-5Q#fO-Pd?BZB~K ze^1THO<6Pm_Mrg9{S&Axk?&)w1o6=8PPxh6#i5ypaQW%~zJ~1)?nI-1q^H)GwOQgZ zUvAUlKRZWFVhSz)$fzqNAw`pk2g&n19vRvFCnTtLO0ceo|~Ue)weSjo+RkEa~{W_ zVR^}&9P63QEtRdmhUb&cr`vKrOD*a#*bAb}jNAo_!DrF&;%siQ_0TYI(R}>xmf9E3 zCu@CtODiqP3eh2qzxB`SORo6aej-yKGuguILUZB@65}p=a-)i~hrx8)T3@|!{7o8w zUE_ttu;8n7dJ8?h;}hbmOAAy?qEPl0lRE!s->CBAL7U+zIzy2U>+74I6EE0dcrr7lppqd`$+{@5xr^9~% zIhu|#dlmSinj_<;7ZE-iOV@2yBX43Fg|{v7TYG>o92_xMuCQY8mXFoIi>hH_Z>q{o z)tBka7b%`tRjV!EWKlJ{yXL08-Pd8$xjlhRC^vktVBu@TbD`j9wKy!Jyz)*mt*&BT zotJXpLrLAF`3_!FAL$eRQc8=aEjck7v6=a$qm8Ok1(%2Jvrkg(;<-FRXmWsqhd0an zv`je}vgI!8kfW!#c8{x%Ei%Ejie!$ac29n?@$auP3>iZS6p0eTQSxDmas0Qj!rDbi z76p?*S+)e_sxU~|XRXDyn0dY_ky1C!L&WCDqW^bzwf2zNC;`|c<&0SjJ!YRDinTt ziMn@KgI`;iX<`bp66RILkgthhxM>b$?H8!cXG?@iL=1#d*mCrB3JpjQ{-6td|$cd8JTgukH&_gMD6 zs>o9v{QlWO>Lxa-y(Cg4YQAGLN>K6RGp1T?j_sXAjt+hEja$ksO8;(?=r(sY3btPJ zv0^&vzvY2HoUL+^dmog4t8e!<9+c9imcMR|MEJ9HT?mT!D{wFxC{snH555ZMCUeHD z&V+d?Gh(lg5cD7 z_3IC9PDu_H7`~|rZONI+)47yEb$mRh5Oz9Dr9DOivJGEI+djLTstudo2zoJ?K98#S zMaAf|IwMK_R2-BpPm$YB6?o5j8apm%@xr}jX}p{(&C9$^|MQup`&AyU%vRUS1d*{+ zt!;L`wVbsahUS|3Dzlg|3Gw50VdTA5SD;T52hL)s6#$Hb#1#km!S4h{;6Fkv1tYMv zCG^3a&VCR-ACH^ql?>tjBUSr>q1ps%&8UT=Qo;LyVHKjdpWPWCKKfBB6 zzpR0zH)MborTeiI07TXQ$S_L!pP-HJiV}|jM!Wgs$a?_w`~n6C0C)pmVEOZ1mZWz+ zNZfop8Nz@3^6~!h`2R}$?_hwxtz##A3I3^GAvW1ZoZzmQmmffW_m~#n(*Iwes4|1RpiT<1TKdrTfO=j!QNX@9C5 z|LQMUm)KPXg9_fxix(x*=SzZ~P$E74WYQnxvfv;+dL!gaM60gD!REUK(q>v;ZD9># zo>W{oZ6B4bCo%=*F-c;4K%huF8>9~lHv?td<%y`UzP$*>d(y9a_%olZrsgl($^y?DIy*sJbEu8&aFDCmRYrxjUrD6{k)!} z?h-AKhfL259aE*G-pZMvpG0Be8qeM4rcXy+EVby9SSd6yyzlxGZeecH5G|9em#qEf z$8xYv%E;;Gs|Q~XgA@tDB6^a9lcDuHuSxJJEm8)B%`Ho&2Yt73;ucgjee3kul$+`8 zn^MALfpuA=)Lz03)oWH*%t(5AU6C}DaQk+)+S)z~%? zf2i2NN#U7GDJhUBogOLHJVqpmk0PgV_?MT!7cYud*%Hzjf#-kV(bk`Ez-`JhTa6lm zK1h)9irnMM%6wzB0cj+f=9#U9^iB1>D2`gvo`@DziN|Ppy!)4OTUl={*JzfROS?HF z$CLlMBp!8Iw|j9rcj*Ay#5K-Vr;HPRZ?{C7q(@r;3IBa0zb;W}AOGMuapD3+$^i$1{)UooL~PWFjOMgUOX^swC#0y5HlsfpKP<<>siKu7 z{GnWZ#)M?`Pd%D|_8%RLcf5ANlQH^XdfiY{bx#3%d&{e@ZW_cwMq09Eho%Idaj%_( zJ7}(da>bZ`k+J3$vE#-2;U0GBzDC>jl4bAs<2h%|Iu-9TG z2(S=V;kf9Yg`D(blgd(-EZA+wmS>tk3goCx4&vP)Q!Qj^uc7X@p~oO3g_)SP4e#Si z{ZlvIXXg~TJaE_vR%#Tz+PErhc`5}}pX1bh@SxkSysFfs?)zLtp7tp!dm0;h&;I(R z;{{t5nR9=~fby`+|;Zw z<=J@z-wK{jbMc0kZR1pQrRyVKHwGQbdqtO~tJB`HWc7}ymg}x#>a_xRX03t6CH4{H zJa~dP6T6!I0W%}~%K4M}7oU>W-l9I`#Z}f6uKAtY(l-5yP#h?QLM(ja_$e*$&uc40 z96d{W!{%3rBsli4f31#^CUz?xYTK(i6oP-U^&H%&^uelF-=4|mxLCV6xSk}ZI~8^^ z8>kC33`sR_ihAO-QNgO5z@JL&I<#uCZ0Rdaap=%;<(Ia*{Cc+eHDunQ_R8|0!FGbB zTRBNGhmIAL-v{o)L!?%reC*&f>&TlxdT2aMwaxR9#t0KG`q51wscT}x2MOK&tB0)2x>Vq%Xf?~4dT6cZ%)!^kCpOD@`C91K{W@fI2H_rJw|p7@ zN~{oZ_@Ubf~}UjzXAAVcK-6TVU=YOQ|av7`Gg*7PFuT+ER=gAXgvH?#|spbcZoy>dij zb(#$9sqnRKcYC~%NkJEpN5hMk@&kqy(yfM$f!6KA>x_;Gvko(uq^RwcZ|?C!5j4qW zQeIyb9sNa6F+?@Lh9s=s&I~Fa<@!?Vk~Q3%%>GPX$zy4u`H-;65s4Vh8vSH|>&8=g zXsYf1Fj33lzWMHu+E<3T^>{rd#?^=cMMF0=31*>JpZ6MI@8{f?@__~8(IHsDehqfT zc}RKC3Z|Iw^df!{?A<=9s{U@y&S|z`P$S;K2vxy-I4uNGGdb^;s1j%qZ7 z#AQn~j8)s65Z{N&UGt5~?J}idBcd$6Ka)=R71}l^m4tW7aXCcZNf>T=_iaRz)A1x` zmSk?)_qVq|Dc@&M9PYfd37&b1N~m4>o2t>3(G8G^_7bwV=psIip&{kvFBG%u z6MadP^UjNvz7_|N$|VP^AX*F7Ne$0mnSp6N)g-$xBd-be`t z#`A-V<_)e}8XY=4$)CTYSFGdRmBy7xym=xEGm%yrE9FqbxLdK^=|e|a^O+2oCA1~m zk)1`zdpE74>1v?9Fe8bNhME7mXRpekO!IPaaXT)XY-Vb7nneuhtSNqdcQ&^VW+QN_ z>)kMdZOH8OqCxzC`4|0ptD~Nq$*-qN5L&Ufefz!sdZiz+A_V<2oh2JZ)cbp?@6K!3 z;&Lc|!z@^UJE{~0Mel1uaovaW2D4oU@%5t^Tu86k3R%dyiJwGY4qR$KT+im1FMq;V z`W)%`<@HqR6NTD4#+pXrXMmJ@4rt0BR|0s*a)bc7hrz;r{ys=th%<8Gp*R<~l>MasWge=r#Yvbb)tt68UFDrZnVN;Ga|yu>aBe zBg}JG`lkuuu@o{{<={`o0>G%>7UX4$VQ_J)0Ju>jj7170v&FfQ3d6Yf5rT;%K$Vel zt^=C*MH`9m4DWRwky3CaHt2G1t5O^$wweEyd;WS?T z*8A#UFaOr&Ea0wR~Ad z_qK%>oSNLwM>)PzbkJK=S{`_vOm1~Yg{j+j&1h@4@COiFH1v_@^~s41 zCT(R9`+j=}F8DdHafH`GeAC9omVCFs)s{RmlkFqO=#3z9Nq_!}0E0A$o71&2rbY)BU}q*Nfx|~WwKTUZ#3jWnf}b?))|r~!N|iS z$XbkU-?XqhQ9KQogVx@1>c0k(d24EPBG9Z-Osc9yGM$PJzayp|?snU~WRcQ1zI`wH X`a#ttf%e_6M1ZW6(#JAMqk#VanRHH6 literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/qmlapp/pyprojxplor.png b/sources/pyside2/doc/tutorials/qmlapp/pyprojxplor.png new file mode 100644 index 0000000000000000000000000000000000000000..e01e2ebeb979c967b5469968d376372569b29bc9 GIT binary patch literal 10062 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⁢`%QoSN9~C?|%KL-MVIpA#aAr^HG+ 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 R{232TRZ&x+3T*lD{{W!lTW|mX literal 0 HcmV?d00001 diff --git a/sources/pyside2/doc/tutorials/qmlapp/qmlapplication.rst b/sources/pyside2/doc/tutorials/qmlapp/qmlapplication.rst new file mode 100644 index 0000000..0cb2960 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlapp/qmlapplication.rst @@ -0,0 +1,132 @@ +######################### +QML Application Tutorial +######################### + +This tutorial provides a quick walk-through of a python application +that loads a QML file. QML is a declarative language that lets you +design UIs faster than a traditional language, such as C++. The +QtQml and QtQuick modules provides the necessary infrastructure for +QML-based UIs. + +In this tutorial, you'll also learn how to provide data from Python +as a QML context property, which is then consumed by the ListView +defined in the QML file. + +Before you begin, install the following prerequisites: + +* The `PySide2 `_ Python packages. +* Qt Creator v4.9 beta1 or later from + `http://download.qt.io + `_. + + +The following step-by-step instructions guide you through application +development process using Qt Creator: + +#. Open Qt Creator and select **File > New File or Project..** menu item + to open following dialog: + + .. image:: newpyproject.png + +#. Select **Qt for Python - Empty** from the list of application templates + and select **Choose**. + + .. image:: pyprojname.png + +#. Give a **Name** to your project, choose its location in the + filesystem, and select **Finish** to create an empty ``main.py`` + and ``main.pyproject``. + + .. image:: pyprojxplor.png + + This should create a ``main.py`` and ```main.pyproject`` files + for the project. + +#. Download :download:`view.qml` and :download:`logo.png ` + and move them to your project folder. + +#. Double-click on ``main.pyproject`` to open it in edit mode, and append + ``view.qml`` and ``logo.png`` to the **files** list. This is how your + project file should look after this change: + + .. code:: + + { + "files": ["main.py", "view.qml", "logo.png"] + } + +#. Now that you have the necessary bits for the application, import the + Python modules in your ``main.py``, and download country data and + format it: + + .. literalinclude:: main.py + :linenos: + :lines: 40-60 + :emphasize-lines: 12-20 + +#. Now, set up the application window using + :ref:`PySide2.QtGui.QGuiApplication`, which manages the application-wide + settings. + + .. literalinclude:: main.py + :linenos: + :lines: 40-65 + :emphasize-lines: 23-25 + + .. note:: Setting the resize policy is important if you want the + root item to resize itself to fit the window or vice-a-versa. + Otherwise, the root item will retain its original size on + resizing the window. + +#. You can now expose the ``data_list`` variable as a QML context + property, which will be consumed by the QML ListView item in ``view.qml``. + + .. literalinclude:: main.py + :linenos: + :lines: 40-70 + :emphasize-lines: 27-30 + +#. Load the ``view.qml`` to the ``QQuickView`` and call ``show()`` to + display the application window. + + .. literalinclude:: main.py + :linenos: + :lines: 40-79 + :emphasize-lines: 33-39 + +#. Finally, execute the application to start the event loop and clean up. + + .. literalinclude:: main.py + :linenos: + :lines: 40- + :emphasize-lines: 41-43 + +#. Your application is ready to be run now. Select **Projects** mode to + choose the Python version to run it. + + .. image:: projectsmode.png + +Run the application by using the ``CTRL+R`` keyboard shortcut to see if it +looks like this: + +.. image:: qmlapplication.png + +You could also watch the following video tutorial for guidance to develop +this application: + +.. raw:: html + +

+ +
+ +******************** +Related information +******************** + +* `QML Reference `_ +* :doc:`../qmlintegration/qmlintegration` diff --git a/sources/pyside2/doc/tutorials/qmlapp/view.qml b/sources/pyside2/doc/tutorials/qmlapp/view.qml new file mode 100644 index 0000000..c75052b --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlapp/view.qml @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the examples of Qt for Python. +** +** $QT_BEGIN_LICENSE:BSD$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** BSD License Usage +** Alternatively, you may use this file under the terms of the BSD license +** as follows: +** +** "Redistribution and use in source and binary forms, with or without +** modification, are permitted provided that the following conditions are +** met: +** * Redistributions of source code must retain the above copyright +** notice, this list of conditions and the following disclaimer. +** * Redistributions in binary form must reproduce the above copyright +** notice, this list of conditions and the following disclaimer in +** the documentation and/or other materials provided with the +** distribution. +** * Neither the name of The Qt Company Ltd nor the names of its +** contributors may be used to endorse or promote products derived +** from this software without specific prior written permission. +** +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Controls 2.12 + +Page { + width: 640 + height: 480 + + header: Label { + color: "#15af15" + text: qsTr("Where do people use Qt?") + font.pointSize: 17 + font.bold: true + font.family: "Arial" + renderType: Text.NativeRendering + horizontalAlignment: Text.AlignHCenter + padding: 10 + } + Rectangle { + id: root + width: parent.width + height: parent.height + + Image { + id: image + fillMode: Image.PreserveAspectFit + anchors.centerIn: root + source: "./logo.png" + opacity: 0.5 + + } + + ListView { + id: view + anchors.fill: root + anchors.margins: 25 + model: myModel + delegate: Text { + anchors.leftMargin: 50 + font.pointSize: 15 + horizontalAlignment: Text.AlignHCenter + text: display + } + } + } + NumberAnimation { + id: anim + running: true + target: view + property: "contentY" + duration: 500 + } +} diff --git a/sources/pyside2/doc/tutorials/qmlintegration/main.py b/sources/pyside2/doc/tutorials/qmlintegration/main.py new file mode 100644 index 0000000..3451c65 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/main.py @@ -0,0 +1,113 @@ +############################################################################# +## +## Copyright (C) 2019 The Qt Company Ltd. +## Contact: http://www.qt.io/licensing/ +## +## This file is part of the Qt for Python examples of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:BSD$ +## You may use this file under the terms of the BSD license as follows: +## +## "Redistribution and use in source and binary forms, with or without +## modification, are permitted provided that the following conditions are +## met: +## * Redistributions of source code must retain the above copyright +## notice, this list of conditions and the following disclaimer. +## * Redistributions in binary form must reproduce the above copyright +## notice, this list of conditions and the following disclaimer in +## the documentation and/or other materials provided with the +## distribution. +## * Neither the name of The Qt Company Ltd nor the names of its +## contributors may be used to endorse or promote products derived +## from this software without specific prior written permission. +## +## +## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +from os.path import abspath, dirname, join + +from PySide2.QtCore import QObject, Slot +from PySide2.QtGui import QGuiApplication +from PySide2.QtQml import QQmlApplicationEngine + +from style_rc import * + + +class Bridge(QObject): + + @Slot(str, result=str) + def getColor(self, color_name): + if color_name.lower() == "red": + return "#ef9a9a" + elif color_name.lower() == "green": + return "#a5d6a7" + elif color_name.lower() == "blue": + return "#90caf9" + else: + return "white" + + @Slot(float, result=int) + def getSize(self, s): + size = int(s * 42) # Maximum font size + if size <= 0: + return 1 + else: + return size + + @Slot(str, result=bool) + def getItalic(self, s): + if s.lower() == "italic": + return True + else: + return False + + @Slot(str, result=bool) + def getBold(self, s): + if s.lower() == "bold": + return True + else: + return False + + @Slot(str, result=bool) + def getUnderline(self, s): + if s.lower() == "underline": + return True + else: + return False + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + engine = QQmlApplicationEngine() + + # Instance of the Python object + bridge = Bridge() + + # Expose the Python object to QML + context = engine.rootContext() + context.setContextProperty("con", bridge) + + # Get the path of the current directory, and then add the name + # of the QML file, to load it. + qmlFile = join(dirname(__file__), 'view.qml') + engine.load(abspath(qmlFile)) + + if not engine.rootObjects(): + sys.exit(-1) + + sys.exit(app.exec_()) diff --git a/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst new file mode 100644 index 0000000..62336ee --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/qmlintegration.rst @@ -0,0 +1,111 @@ +######################## +QML Integration Tutorial +######################## + +This tutorial provides a quick walk-through of a python application that loads, and interacts with +a QML file. QML is a declarative language that lets you design UIs faster than a traditional +language, such as C++. The QtQml and QtQuick modules provides the necessary infrastructure for +QML-based UIs. + +In this tutorial, you will learn how to integrate Python with a QML application through a context +property. This mechanism will help us to understand how to use Python as a backend for certain +signals from the UI elements in the QML interface. Additionally, you will learn how to provide +a modern look to your QML application using one of the features from Qt Quick Controls 2. + +The tutorial is based on an application that allow you to set many text properties, like increasing +the font size, changing the color, changing the style, and so on. Before you begin, install the +`PySide2 `_ Python packages. + +The following step-by-step process will guide you through the key elements of the QML based +application and PySide2 integration: + +#. First, let's start with the following QML-based UI: + + .. image:: textproperties_default.png + + The design is based on a `GridLayout`, containing two `ColumnLayout`. + Inside the UI you will find many `RadioButton`, `Button`, and a `Slider`. + +#. With the QML file in place, you can load it from Python: + + .. literalinclude:: main.py + :linenos: + :lines: 98-108 + :emphasize-lines: 6,9 + + Notice that we specify the name of the context property, **con**, + and also we explicitly load our QML file. + +#. Define the `Bridge` class, containing all the logic for the context property: + + .. literalinclude:: main.py + :linenos: + :lines: 51-91 + +#. Now, go back to the QML file and connect the signals to the slots defined in the `Bridge` class: + + .. literalinclude:: view.qml + :linenos: + :lines: 85-93 + :emphasize-lines: 5-7 + + The properties *Italic*, *Bold*, and *Underline* are mutually + exclusive, this means only one can be active at any time. + To achieve this each time we select one of these options, we + check the three properties via the context property as you can + see in the above snippet. + Only one of the three will return *True*, while the other two + will return *False*, that is how we make sure only one is being + applied to the text. + +#. Each slot verifies if the selected option contains the text associated + to the property: + + .. literalinclude:: main.py + :linenos: + :lines: 79-84 + :emphasize-lines: 4,6 + + Returning *True* or *False* allows you to activate and deactivate + the properties of the QML UI elements. + + It is also possible to return other values that are not *Boolean*, + like the slot in charge of returning the font size: + + .. literalinclude:: main.py + :linenos: + :lines: 64-70 + +#. Now, for changing the look of our application, you have two options: + + 1. Use the command line: execute the python file adding the option, `--style`:: + + python main.py --style material + + 2. Use a `qtquickcontrols2.conf` file: + + .. literalinclude:: qtquickcontrols2.conf + :linenos: + + Then add it to your `.qrc` file: + + .. literalinclude:: style.qrc + :linenos: + + Generate the *rc* file running, `pyside2-rcc style.qrc > style_rc.py` + And finally import it from your `main.py` script. + + .. literalinclude:: main.py + :linenos: + :lines: 41-48 + :emphasize-lines: 8 + + You can read more about this configuration file + `here `_. + + The final look of your application will be: + + .. image:: textproperties_material.png + +You can :download:`view.qml ` and +:download:`main.py ` to try this example. diff --git a/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf b/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf new file mode 100644 index 0000000..8506460 --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/qtquickcontrols2.conf @@ -0,0 +1,10 @@ +[Controls] +Style=Material + +[Universal] +Theme=System +Accent=Red + +[Material] +Theme=Dark +Accent=Red diff --git a/sources/pyside2/doc/tutorials/qmlintegration/style.qrc b/sources/pyside2/doc/tutorials/qmlintegration/style.qrc new file mode 100644 index 0000000..e313f5e --- /dev/null +++ b/sources/pyside2/doc/tutorials/qmlintegration/style.qrc @@ -0,0 +1,5 @@ + + + qtquickcontrols2.conf + + diff --git a/sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png b/sources/pyside2/doc/tutorials/qmlintegration/textproperties_default.png new file mode 100644 index 0000000000000000000000000000000000000000..cfeac93681d04d93e61a0d2a45e0607013edd159 GIT binary patch literal 19347 zcmeIaWmJ@J^foFef`k}^v`R?}h)9D7NF!ZCNS7cr)Xad0sFbwCkkZ{9f^>H?C^0Yt zj4*V~8BqMc>#X;DIbY7Z&iZ{B7I1SvckI2dYhQamd{R@9BO#Q}B@ zy?^Bj&KCk)>`$iTBF(U0uDU#z*CZeynE9!?aOKMVEAlU-G(C(q=72tAV@DlZ8}d)Z z-e1G@d*Ve-M#P@-@ntj%dzveG1AE#dgciien=*<+*BTf1^TfMhO*P4HpPt~|x$~Uh z*7N6tYzga|D0zy<@8$U(TxFUXXxwDr^InM)LecRU4(XHYq z*E47@7a`gFi~8^KaIQU}xNl-ZtRQr`Vqf1jfy>1aSaV7?58sP&zFfo=oFKc)#oZdz z_4Uo*eYE^<5!j7hF7CgLUL4bZH+pV!|35Tcf%L?(RSkZXiu|&CJiwzoJA1kF3(r2p z&5VZy=ui5;yIay!q+CWa>r{%3UjajP~B<+c%6{l}nhd&5bH9QLjCMxOw%e zRwxg6XLGXWWEVl|yxN1m2{y~aERe29jQ?DJr28cy8mh67|AK2*E`#~cnzYF8n`mjN z^_;4nZH@aHBvlXZUjvJHeo^ma$kWPSsjyp03Q&(%n4*OTNS+e@W6YkV`PSw}sRrb~vdB5(D z&j>5m7PHSBP(DKMOHl7QS?4Hm{RwE?)mL1Kxu2CFuA1k2f`2sW&OLO1Nw>rs3a#c02o@v^=OsD7W+8K!A^MrMchLzi+_u$b!$tieFErpH}bT6V~1z&^R@Rs0USQTvcSHLhQyT7w<&;^9ga*GO)k$5-30&25K0l^;?K zBStDv#yg0t85c2q)vtT)zQ5I*f-3qBFpXR2XdsW??w+^Z=2v$O$-U4v22h=Yqo0PA zMD5C=4r%ptLb}%+(7*tt4tJEOc5Xi@ppx5%uepx5=4CZhR#14U6bt+R>xd_4Uvpy#%tB0YYbYVJuc3KAG#}y`_adG>Jm_k90=3)-+;(&~j zPj@QLYzusfXoX5gqPQd&=4;t_n*ihQgqmo11=d8|)$-J>5-K*(VKL0BEsoT0&BlM} z*;Ua25jz3iXZw43d7m)`&9^+p0E@LTU)`5G=c`T@bNC^X?vFY|($EX|^fkxvUMuRX zS{^3@MG|pahpHl^7Kjr@Zj>i{GQ1)FIQqab$jnaSY$;X~HGZ{YcKsL*N2wZ=b8o(9 zD|ZMB4+}+&{E!>FlB$nCeF2=+pCq?hb$z&Ne8u)o-!uwCRpEl}(^0A{pf=EuEL7ZQ zY4}MNKQik^!KrAl3}m0Cmp-YDffO}e5 zEfWvF30w><8Xck$yNVp&dP*L>^O1IYXfu&NnsC1!RGJQ6bCM*DS6P}eHB7U=1fb4M-2g+Vc2Q@OBYK>U_v47w@sUL$Yb;yyH65@?PjFlE$^Y7La_r zrItiH0p{E5!RJ9oa(4s+yw+XIe)(Du6OcG~Y<$CP^sqZU+o<^@A?m3mS@WrCbfA^t z!g+5U$oUHC%3LLnJzMNl5Q`U=+wi+9P<+;A1kZ>!#hXzm zTo@pG)7DnF{#T^qFHBssQL$Cmy734n7d~u6sCZSA#4-|@D&OF`kVr4=7MC+$HE^&L zo+m9v?A0*T)F;NHvT4-e>2XR5Npzxn21I6IS2KBw-*)d8+>rqNWsy36=ql{+WSIt+ z@HJ(l5Jc7V6S~UkULnZgjN{bI$DC|nfok4mn`8fppcTrnggfV5oXPTo-*gv1?@f5C zIJX0}+1d9@?>?jMd?S4~mAuNx(lXLwPzYUCI?(GDk6$!~7IUvqwFWmx>@_v6~y2ka-fL>d_zx6E1LsKony#hEgW7Lf@#1 z8uwO>hymSxs~8I+gXXflBkLT_5@BUN+ze0Gof)*~%AOzvcL>(bPbb~)ZV8^cj)}D4S*NLzGsrY`|ufA zf_REe-gT=m87jmJ89eGlD*U^{iiyF@Onmt}Cx^~AIa^H&9Ye-z!#8SgdLGQ7fSZO- zG7s0wPY8hv-z1L-YLP-NVq6=Kg(R8?Enyx^G2yDU`NGA-8as&KMkQkbGt5iE6@pJ!uzjodc&X_6v12+f=o0u>HIe(Pxh)g0a3roJo`t*AQ_WxNhAg@qG%m+ zTXHCty49h=q>;!K(@)Q1d`*laH=T@B8n5M#P|YrFSQY$O{xxzaVb|Csn7iIKLlS=4 zK7Vqu-4VeNWgWY=9k({YcPIlUlZ&i18-$OGGy`k zz~9d-p^QAN14d~R&WxqKL#^zO%8+CV$t=P;&>n0wjm!zCG6iH`>3eEgYYx1}x)a{(8dmvLV~ct+>L(DOL2GT$}98-*Pm zb41lNd0gg>9g7sk4qa=#CoQxmaER%RO27KHT5^aE$WP+*@i-#Vd!~2MF;Qjg=4V@{ zJb|<;zi)1s*8~t9ZZ)lJ&dhi)@nBrLN@e&VLT_w@%$Ihhm`Sa-cb=?40}d2RUyw_mklBWXGAhV&!NKCX+c z*P6h8qF_D{hoiWU(Pehy94?qry&2fkZ_xY+Cn*V|jZIq55Xf}VNYbgfS*EI7+&p;C zo-O$(1o4$Hw1e&dzQgV!zUz2zKHcxZMiy}15WJ-Hqjbag1QE<7w32y>s#e%CvbPA8 zH26d0$ndIV(mI{xpHkDzo&Egv-s}`}Iudo(*VOptcdEO*vNB|g&8nwJVG_+Ew+a+jB|BY+8wUj zBo~U=zY*Ts?E>`2j}%t2Z2ZZgv$0fOt7NFnE|s*}cAFI9dbaTCMiHdOeXpmfSKQ57 z`nSMc%RUdVHHY4VvL78}{M(B>rO7^sraUm_&3xFQyY$Xg>0~anJqdjhg(}ZLnd6aX zrRNeP?Q__n4 zgfJEB*b6#1N`JpVBfA?LjZg%g)HM`aXC7|FQocD{3xc_r(-kDq(X+jIh%7MRlm)FN zq?gXew)LQs^QOrJUZ2^bvf5P+P~AC^+Dcs0BMWq6$SKlHiIK7&r>ZqG2#ejv$!J^Y z$hICtPVG#FYLW!wx#&<`1Bg>Q)kpq+m}M)MY{wQ$TD=T3&WtdyID>)z(jQ_x9=s^#*R z9@Wjg-L!;?@_KNZ!u+CW(;*G*uR`7_@I2N2piGrO?)5!Wk+C`52{AW!;>o?M2Csa- zX?Qo{n9else$xDx9nQO^}m8!A=P}(9sOeh--9V@D%i*`^+8e~M$mKC4r$SL zTY#Yf@*)@}oXWWe3+V7hKuJj=ViZx;v zqCkbUn2_)Xa-kL?!AUr7(ghujAjEtuSUHma#>e0%lS88Wg1n;};y#b5yP*Kp2V|Q|&i?$Cp!k}B^~c@{2N?A)}Otu7Sex51RpEI5f9{UWxbBDXi+ zd3v zpCH`ITDO8ta$cw1#vYhcs4pXzxVSRIBAmHKem;cC=k!|+W`h4dqre2mBx+J8lEK4K z<3s;wHYSfjeEwBz#7em(YQA73BS|Ck=^JaOMPCkdjB=ujFhHJxD74VvH|UkI7>~Ed z=8~64sNmW?MCatm_$uYTE9A_dRoMF*-9XiKPp004CtD+QtZp9$X_Df%HGxgRqoQ^I z7-JBt*v{EF=YTtDZ#?Zb{Ac?{YjC@-aJvMI3cVWfLh#-XA-WL4ZD%4Phr_mEJ{rX%~4T;W%ZpwvDLeH} zbx!>G?MAkh#Xf|t*6#!u^DC4;mLvADKuE{ZsE;K2eXn)UV2H2xXzD|52f~#I4j2VW zL1O-F#i4J|H0cbOl`qm(gs9V&s82dQ88&E=tOR_{zo~CLj1ANkTF?(Cvq7J$8t--OivqAs9 zDp8T_fo3TXDlroFuqA(|a#tZ)$_@5C&(yr(-D%w~0E8;8!T%kS0`%@`gX*aqsNr5m zOP%-L255#Tui;oitYoTIzG{#9+0uBU8Jy}(!n0@H*?BYQ5;>k@^dU~ebrSkP;K9!N zSs1C^tNMo}jo`Z-ze-NuG*k=}1NSRy7ROgMi&fsvC9pJLeg^Veg2XX3H@!2Pn)otC z@ltqp*@M$0s2Lq0d*25c=n*ih!7pGC{Q-;9kN1rvv+!uD>vG$q{4w9$=zwxT5h&BV z3A>gC-h?EYQQ+_9M(LzEGB;Q{=<__|uTd&$Svcfr?rJUdnbh+@ks|?K#16@ICGaCe zto*4L3B8Y96E9IPP>J^5tGK}*1ln#G3HE+coNKwUzDDq=lfqb7Q>*?&dvC$c&J({HO7lKBO*)$I)iy_pcA-X?0{aO*{t4!{a}1?%RBx z7e^ISCLwICF@h_hA;UCcyCUEc%_oR z-WjgN%94vm?ls;k0rStSzu3D_-(Puz%Ygq+pdCn-ETZduJMjN9nCS66_S!Ogb zj^Ymz=mLSKP;pVFNsU-Uhp_RmkLl!f@5Um$SNo{_GH7j z=+!|^93N{{p;GT)f^`0Ms2EfI5S#GKp2du+?q@ktLbQr9&#(|vK0=XnepJCwu6s{Q zVx8xXK7}1%XR~;-Y=WEH6Q-Cta-Eb%HEX^Ooc>#bR}i!~(8bEZf0m|Jp6Sqi2HJdg z)uo--Q4lp6mmn${?4GbOTA}?VI?jv$?Ih-|{v`ofJF#9qv+UiV;#i^&6-FKX3{epn zn6BpJ&Evb8c`ZNQ{ku~m7D<$^C9;AOwtm*)sfHl8#u#B4tnJCa9ZDR(*BR4s^S-dK zkB?e`7213R8$`^$C$O2$59KY1PdvpFBk^vDPhQ+y10D+yVNkKIS^aCS&m01*RB44l zCwK90E=_D5yX@6*1kneJoR*X;b`o3f?7ssxis?K57~o%jm*l?71zs6X8nS;%EhgH> zjM|+-qiN^C^AUH~h0UNJb_;5ms6GmT@4wRNsQkGIoUqV>fdQ-hF0@B)+6ASJ7~JP@ z0yk4=IgizbKc!gqz1tO8Hr4>W?9qNebpyZW_uEWXrX@VRsy^^>2Vo#l^s!X4y1VJQ zo~BmP{K?n~5`MBZS5*ZNu;_>_tLpc8-K~g|3~pkbp&qa7Sw196KK6hQ%ZR*bK-Ju+ z^n`pZq;-xQcv~kj`yk3R6O`PrGenMR5=BKuD}pBzqmZ|U(-imB=E7a%T`GH%cPGj_ z<~>=K%EoRSiiZfh+Qf-2PRWQ+_#DCWJLXSSp;JBkN#!4^kmKTJEBr2`iFHjP_HVr^ zsec#UaQA1vU%I$U*Gpq`yp^KCdKHo-ZX@!P&ib)!%c)$V)pK|h-uP_yNAWLiD@P`i z9LcmB=UA%Htmov^>MVy?`>I*J4;it-1Gva^)Xq$BdE4r$!+uunQ-dp*c`Q&UiIZE7 zBSH}|O5n$k+3H3h@w3{kJQ-Mpt=5+f`r8~Bl+Ysno9efn3!8vrfN8g4$PAyudYRo` zR|prX9wbrtmaH2l-UhruMC!w9v*c%hqMwC$=qz@%LJEv)Rb(k?1Dm{mh5Db$5pM|8 zmkI56CczpFK!b(+Q+t@5NUj05bVcK@zmeVR)8L676Q#LY*RruyQ(oZ>8wj`8W&=5L zk#CuL7`}PBHQ`eiY(P$X@@uU_jK01O*4z%kJYGznv@^(@{A>x>fSwL!gZu+Y?|A@$ zAnoD)3fLQ`Fge}jc;WK5HD?DokfG3mc<~Aw1tRGP4epxR_XDiK&)f&Tp80=RRexH~ z=QZB#L8Vu*(ov`nbr5j_kpCz;6@!+N#tU$z0vLX$m zGb#ez+~V<;x#bgf1y?{NWh7c>tlFhflePX_K_Ml99x>qlRZyS_eI6pHp7(Tr)K4r; zAHx=$$26b3xDYn5AEQ{}Jt{Orcv)js1v9)dJ-GYDh;Qy~Du;MM> zyX*z{-)(0Vs*+V3Q~pN=JKv=mb2C8A;)JtgMP=@~U1*Ml$9omc|+tkrENv4W{@FS?3qCkX%L~ziD>0x6KO5${}H4vDVC8^5V;qF9{;U ze&ly{b}lR|IO}hdVv+e0^A}ba+oS7C#TZOmtRT>S65fJ zM|8QKX4w55zOaJ3Y{8;a8<9O)Y$_eCbf@L@>(@)0sXzFp0)jJ!Lo6?+O}N%gtm|y` zn47y$eGL&D#PLPGJ%a7`EJwa_ED`9Ba(o3x0Jj@Q(Xyhao+GZL5WJo{`rTYE4#O>D zE-UIXKX!7b{O>?Nea4jf+;_9IQFou7kQ0G7g2C1iY|_?#botdgW@L|y$2 zR#8#IJpKszO?=Xr1gO0pl~BOVz_}PGm=m^ecL8PLx|B&T`o*VZ6P7KXE~%LFXnA6z z22Te8QsJR+98i}3sMx;^)v>9NvI#*8JXN_q+R$#jYqagORuVmce$5T4|Ew1FHL2n%N&q z`jmI6gWG3kUJ$}TPzVP&op}6S9iR*jdTpLZYv1@6OZ<~!00^*Nq5=&540B7a8c zLaXsS|44<-Kv(1L2;Ju`g{+Z@PoX&6z*BNAR4hH= z5M}gux9ms^`2#F+oK^43M``{WDSDLj+Z5A?s!3<88|?`*s2cNvHw6j^ow}MH1}^=r zBixc)cz5Gbut`@7VYi}x(uDj=Hn!~IypcO|1uzS@&np?;Zi$bP4I*iDIbDIOOWtnr zJ6jxLgy1+aWMEXNncSS0bZlpuNU(cyOhc_~oW+x#pA(rAZa=-IhK7CCSrv^C@fhSu zn1lg6rH9^eE#cg&XHOFT1tTK1l-THT#j#ky8T;AlS1~OSZj*T))}FUhIp2-tXt4VG zt!l_9x?eOCVVei38B@M^GZ6;_1js*S=gc2QTAKse9%j7M5m<3vc=4C1NfO}%_%d5q ztSb~vure`eF5fDxBg;8@tgF@U2fAc)enC7bw8g=)X6EMKf+d)lnV~SDuF$ToE^JhQ z8sqK#BSE&=zRt}N{nzmEJAVB5(bfi)YmWe!cdV{jv#Co1o;h5))IvQTS&YpyjUG3k zYFY#*1@-OQrV(Sg>_?sT95wupq>bFRj(F%^2Z)I5&58I*PDaLr)YmJ}o*+uK za8ew%jU9Vo(ZKOZd%HK~{o@rt&X=t7#NynhNA+>EaC*kP^%xY@qs(*u;mpjknEy5l ztzI5LJ=UB@+dR8Mhmh{F)p86snm{+#Zur)vSv%SJ@g+ZWwIdhCGUq=NYf53OGkBuz z|DtRZwn0;Y-TrcpYq|HaH8ouNx_@C!0n4D7$t(ZGO08SiwkVu1z~!ajFk|Ur1mVm- z^I*qT4|9Dx3NJmvHv&tk&YKOz^~xI2GaXoWKTeenjEIcPDEaoNOIiS`lzB?A zXd*BmK)`yi+4_mLZshfU3wI#TerA%9nc3dap;#WV#FXrOpXq&<+-q%fb8{yrCn2uG ze|bfA8!q`Z&KpW4B_$Dg4<9~M%KVICrJ$f-VPfjk)p2!oJ+#TENEjCQyEZ2mziqxq z4uHI-?PPJP0?Q3kUS3}3eYMwd>(ATO*JSxG_n?exahr|6!d(ktQkvciiG9e&m?VU<1>czdJ5aLVwwjTa z)SH{#`R;K*t!QxfIlyXV5FG!zegTzpX!O$IQv_tH=ERK|sRUY_yYDv>p}vFv*{%gH zA&#PUxieR{+HRpjbA-COTB_#Htp=J2Os#vtiQ^nFp8Z5)PN9j25OD|y!FnjVER zzPJB_5}yoF_74%NU*HnD6q}E!=_zaGp~JD$*yMU|3l4-Cf2E{p9N;|~0d)p=py0vnuiu93+WFDXCc;|Jv3Jzr5t{D{pP zA@`$UR3l((WSX4E807JDJvlVlcC|c%b@R-{+fX5NdrqdKtJT|mUHr=%4bEQKORHQ^ zCp?e1-q)9vpXo!Rq9Wc|XphugPbN;9HEFB!m;UbSIRv%7ZEuL}r0IEUGtnz0?P zNO9@|;SZaIYHZe{fjxcZ`7Ul#@BaEfmZSWn_$ebonKd$*qS5rgAAin$W`RE3 zMxyU*JIo%6{=GsHnC4AtjpTxxhOQ1(&2=d^wVm-_TM;eyG*iH8C<&gO`$h#vJNC9i zNJUjplQm#L^3p+?Yj6n}buW+@v8XZbigpQ#s*=GHwo-i$S+`ACQKOGYij~JS*Fe7> z|Ms?}=b=ha;NfUWRBTg|oD{h6R0+pQ3hXyDbF3-TkX2MwlmF{)F%ZiMxj*@~5X7{- z#)kVLg#9-x%vZ-ZG+Xj?_HaBNwHfVPTnKHTYO9<4g*g!^0-IkQ;Kw6&YiV`es@qHE zoR1){Ta*kP>Eden>}TWm_cSP#B~7nk1BWVwHo=V>LrYB9Svm7Gr;qfCe$cGfuoiz{Ys-pXLma7d~wl>2z~yHZ$ZsE+Kh z_j}`+^bm(0QdoiF@4DqpaT2ca_E-QN!1BY$H%hWgUVd$qXq8zd+Lp_)a;o}mIyN-P zB8b>3qbP6Fi+U7mWT{;DZ)teh2AKSKi4>!*I03VarjM|hL+LA1Q&X*4);h)8Y%;aE zgp8NrK{Dhn)^>;Ssp^K2yEks!&{_*y=a$J8C)SR3F){wo zmxlvYO3j>|OUc63;W~Z||B!>49SiT@__w`QzJC2$U0sdt)GZBKzeh(`uoDWWCTz3$ z3&U4%Z7*=UEDyPv^nzKB^U1@9E#~Y+C3ZYknN9^#I92ekA*Kc)84w=A3Ty8mm%5>Hy1Z1Z=zH@<{Vw( z;^Lkra7joQSN2?lj#BNqZ`@r*`JHOW!dt@c|DJX4KqkC_#Hi*xjyC?;%&VW`W(s)8na8MkFU`<`$T$ai%zB& zX*e}|-X~kPXV?siJa@{yKk@fyOEtfIM|kP4U3?>qJX;Xky2F#i$$elhpy+q>cIM*o zz7<);IMO9FV}-ryqAGD=&nW@EElfbqyDA z)z?NQno3t;{8=`NiXWBxi9T9eSH%qr0w@GK-{SgLv zq0=-J*M0_N?O(UP`Q_bSeehjYl19G|i^so)IZ0kWM0g~2+3l^jzC8|`x=JH>V_)Zf zt|8Dm%PY*G1$qJnWmHSK`KYhcngdw%Ltc8OI&MA>{U6Khy~` zV?g^|s{O7U(X`lJSGg%~jDnkQ``=i$Fpo=EMX>xQi+{+NVOSJUXjpN#j;}CbZ!wHR zo5#CBaXZbkscSUftY;n!L5(@)9~>Sp=TXc%92}1pPnMvPAnww~6EOvV8rLy|4CyiW z^jAITn zt7?VGPo}?El)^&rXo*x03>YWa-5O$1KhLivO&`Y*hqkovb3A)SM6}@**|lnGyIo4r z#&LKrSQaY!`H@EEHjya8D_PhyC@f4y#}z&l6S+7@6UM?s3l!M5hQUAAwlQj6FS-IF ze6v9%nx9m76%lg1fmRmY+0#EXRTe=?`%Hi#Z*x}+>D~G99>XPoN)}+1uu@%4At51s zJkE3HQt7BOO<%}Q#t0iu_6Y=tIlz(@!M8(j$>J#-w{JSq`n*QM*!pjh>^llC7qI;9UgV|*f&9 zzY|%<8Zs{SxYj`0v)O5G|5*PNKK5X@KkuH%-`vyJfDpSTJzY~+BS_z-lRaHI{>iIc zOY3I`rL*967^?1Jt-HwV0sQoapzqKt=anrxiC~IDaEI>?pQ6#e$ z9lt#v;c5Kdjb3Q8zhH)V-kE1`(4^Ubh=%LXd=q0?Sm`6=yJTveVs}2Yw6rkMkW*-{1@K|zk#O~Id5FUq7wx~poczvXFs*!h;f@#R z`Sa&mq3m^v;kl&#TFbPPl$WAF^#N9*?Xi9$D=XW5prNildziG@SJ`=bVyp4-O5Dc_=U%Fd}=Y)Ak!k{$y+6uP_AeGqHEQ zPQ88mHj9R52*A7Re-TkU=9>sb{w9@@Aru!X3PkjgGNxHIvk{SK zt`hwtA1klxJ?gQos5K(s@;AWpseBf8BtX7A!sKUJnwBQG|DM(vg` z$;iia_x6@g*&iMrmICJaA33&!S4=az$?v_E`4A75ayq+wpqrnXhtac{AqtWPFG0{LU6$ z6IBmKzsUGNLX#_6$%*6&a_iB5d8fymk}pP~3Naq+t2GC{-H(4hHYJ9j6DlWX;yScf}XBQ@_Ud-+`x&I6M_AYm$klaNbHhUR&+fs+RfX=wsWcqffoUYyTZ4=N@so`Z%pqz@@fen3~Bw?NdQKP8cUD<93Nm|sVkB} zDWUT1VkTDOi=U?yfI~2#{oTzuMP)?+2lI$J(Gcqj{jn#7YYt0=*_^L_!r@sHNIO?! z0$qV4_~H^)!19ZKaDNRE#M78h1^^P!cs=i1(33Flk9yi0>WlM|8h0%uu2b)jn?Ka_Xoo_^+ zXE0}k{0-l6_pXMeg+>T|68axz)4&ELm@PgRGyO0eMyHmP)YIp=d9ej2}gV zgM;tizn`lEqCa;l?glvPETkJc18dV{p(giNs8wXn2YffG@J&kmnYL`HsQW&LhvY`>nmv@{cVGdf(% z=v7Ykk3Uim@Ya_MspaoHH8UE!B0^X>%%<8tN8~^!P@KJJiCe;|OGi_o_UK?ywOd}N zFzMx08?i&T?H}uH^qn1w>_9B@jIeVT-9OKonelkQJkMThT_Xb*V@)DT z#GlVS2t)6D=Y9JuwNaIQYCTrDW4hQ>aFJTf||k@JsJt0gMf@cyOZJ9w(qU6O~Tl2qGLRB z`Inw4M)Y|SVZqB@^v2_&uK``uUa45njvM9GzLTS5nkM~j7P^u-wpcpT2rY%xCDA5;CSoE7Lwa-!n{aHb89dXhxd0hq| zqJXW$XonAOUTw8h#-OGRjB5L