summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bumpversion.cfg2
-rw-r--r--.travis.yml21
-rw-r--r--CHANGELOG.md73
-rw-r--r--ci/win-test.bat5
-rw-r--r--debian/changelog14
-rw-r--r--debian/compat1
-rw-r--r--debian/control8
-rw-r--r--debian/python-taurus.links1
-rw-r--r--debian/python3-taurus.links13
-rw-r--r--debian/python3-taurus.manpages1
-rwxr-xr-xdebian/rules2
-rw-r--r--doc/how_to_release.md216
-rwxr-xr-xdoc/makeman2
-rw-r--r--doc/man/taurus.121
-rw-r--r--doc/man/taurusconfigbrowser.142
-rw-r--r--doc/man/tauruscurve.148
-rw-r--r--doc/man/taurusdemo.142
-rw-r--r--doc/man/taurusdesigner.122
-rw-r--r--doc/man/taurusdevicepanel.145
-rw-r--r--doc/man/taurusform.148
-rw-r--r--doc/man/taurusgui.154
-rw-r--r--doc/man/taurusiconcatalog.140
-rw-r--r--doc/man/taurusimage.151
-rw-r--r--doc/man/tauruspanel.142
-rw-r--r--doc/man/taurusplot.160
-rw-r--r--doc/man/taurustestsuite.124
-rw-r--r--doc/man/taurustrend.167
-rw-r--r--doc/man/taurustrend1d.158
-rw-r--r--doc/man/taurustrend2d.158
-rw-r--r--doc/source/conf.py11
-rw-r--r--doc/source/devel/coding_guide.rst17
-rw-r--r--doc/source/devel/designer_tutorial.rst4
-rw-r--r--doc/source/devel/examples.rst6
-rw-r--r--doc/source/devel/examples/edit01.py2
-rw-r--r--doc/source/devel/examples/edit02.py2
-rw-r--r--doc/source/devel/examples/edit03.py2
-rw-r--r--doc/source/devel/examples/forms01.py2
-rw-r--r--doc/source/devel/examples/forms02.py2
-rw-r--r--doc/source/devel/examples/label01.py2
-rw-r--r--doc/source/devel/examples/label02.py2
-rw-r--r--doc/source/devel/examples/label03.py2
-rw-r--r--doc/source/devel/examples/label04.py2
-rw-r--r--doc/source/devel/examples/label05.py2
-rw-r--r--doc/source/devel/examples/label06.py2
-rw-r--r--doc/source/devel/examples/parentmodel_issue_demo.py2
-rw-r--r--doc/source/devel/examples/taurusplot01.py2
-rw-r--r--doc/source/devel/examples/taurusplot02.py2
-rw-r--r--doc/source/devel/examples/taurusplot03.py2
-rw-r--r--doc/source/devel/examples/taurustrend01.py2
-rw-r--r--doc/source/devel/examples/taurusvalue01.py2
-rw-r--r--doc/source/devel/icon_example.py2
-rw-r--r--doc/source/devel/icon_guide.rst2
-rw-r--r--doc/source/devel/taurus3to4.rst262
-rw-r--r--doc/source/devel/taurusgui_newgui.rst4
-rw-r--r--[-rwxr-xr-x]doc/source/index.rst0
-rw-r--r--doc/source/numpy.inv5
-rw-r--r--doc/source/tep/TEP14.md13
-rw-r--r--[-rwxr-xr-x]doc/source/tep/index.rst0
-rw-r--r--[-rwxr-xr-x]doc/source/tep/res/tep0_workflow.pngbin22871 -> 22871 bytes
-rw-r--r--[-rwxr-xr-x]doc/source/tep/res/tep14_merge_Attr_and_Conf.pngbin24672 -> 24672 bytes
-rw-r--r--doc/source/users/getting_started.rst77
-rw-r--r--doc/source/users/introduction.rst4
-rw-r--r--doc/source/users/ui/configurations.rst6
-rw-r--r--doc/source/users/ui/devpanels.rst8
-rw-r--r--doc/source/users/ui/forms.rst6
-rw-r--r--doc/source/users/ui/plot.rst21
-rw-r--r--doc/source/users/ui/taurusdemo.rst6
-rw-r--r--doc/source/users/ui/taurusgui.rst53
-rw-r--r--doc/source/users/ui/taurusimage.rst26
-rw-r--r--doc/source/users/ui/trend.rst8
-rw-r--r--lib/taurus/cli/__init__.py40
-rw-r--r--lib/taurus/cli/cli.py116
-rw-r--r--lib/taurus/core/epics/__init__.py4
-rw-r--r--lib/taurus/core/epics/epicsattribute.py8
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/epics/test/test_epicsattribute.py0
-rw-r--r--lib/taurus/core/evaluation/evalattribute.py6
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/evaluation/evalfactory.py0
-rw-r--r--lib/taurus/core/evaluation/test/res/dev_example.py2
-rw-r--r--lib/taurus/core/evaluation/test/res/ipap_example.py2
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/evaluation/test/test_evalattribute.py0
-rw-r--r--lib/taurus/core/init_bkcomp.py1
-rw-r--r--lib/taurus/core/release.py2
-rw-r--r--lib/taurus/core/resource/resvalidator.py4
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/resource/test/res/__init__.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/resource/test/res/attr_resources_file.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/resource/test/test_resfactory.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/resource/test/test_resvalidator.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/tango/tangoattribute.py17
-rw-r--r--lib/taurus/core/tango/tangodatabase.py31
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/tango/tangodevice.py2
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/tango/test/test_tangofactory.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/tango/util/formatter.py0
-rw-r--r--lib/taurus/core/taurusattribute.py14
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/taurusdevice.py0
-rw-r--r--lib/taurus/core/taurusfactory.py11
-rw-r--r--lib/taurus/core/taurushelper.py20
-rw-r--r--[-rwxr-xr-x]lib/taurus/core/taurusmanager.py0
-rw-r--r--lib/taurus/core/test/test_taurushelper.py14
-rw-r--r--lib/taurus/core/units.py1
-rw-r--r--lib/taurus/core/util/argparse/taurusargparse.py6
-rw-r--r--lib/taurus/core/util/codecs.py90
-rw-r--r--lib/taurus/core/util/console.py3
-rw-r--r--lib/taurus/core/util/constant.py6
-rw-r--r--lib/taurus/core/util/containers.py2
-rw-r--r--lib/taurus/core/util/decorator/__init__.py28
-rw-r--r--lib/taurus/core/util/decorator/decorator.py38
-rw-r--r--lib/taurus/core/util/decorator/typecheck.py35
-rw-r--r--lib/taurus/core/util/event.py3
-rw-r--r--lib/taurus/core/util/parse_args.py6
-rw-r--r--lib/taurus/core/util/property_parser.py2
-rw-r--r--lib/taurus/core/util/propertyfile.py3
-rw-r--r--lib/taurus/core/util/remotelogmonitor.py58
-rw-r--r--lib/taurus/core/util/tablepprint.py35
-rw-r--r--lib/taurus/core/util/test/test_codecs.py2
-rw-r--r--lib/taurus/core/util/whichexecutable.py2
-rw-r--r--[-rwxr-xr-x]lib/taurus/external/qt/QtHelp.py0
-rw-r--r--lib/taurus/external/qt/QtWebKit.py12
-rw-r--r--lib/taurus/external/qt/__init__.py5
-rw-r--r--[-rwxr-xr-x]lib/taurus/external/qt/compat.py10
-rw-r--r--lib/taurus/qt/qtcore/communication/communication.py5
-rw-r--r--lib/taurus/qt/qtcore/configuration/configuration.py10
-rw-r--r--lib/taurus/qt/qtcore/taurusqlistener.py2
-rw-r--r--lib/taurus/qt/qtcore/util/__init__.py1
-rw-r--r--lib/taurus/qt/qtcore/util/emitter.py11
-rw-r--r--lib/taurus/qt/qtcore/util/properties.py14
-rw-r--r--lib/taurus/qt/qtcore/util/signal.py24
-rw-r--r--lib/taurus/qt/qtdesigner/containerplugin.py14
-rw-r--r--lib/taurus/qt/qtdesigner/taurusdesigner.py57
-rw-r--r--lib/taurus/qt/qtdesigner/tauruspluginplugin.py3
-rw-r--r--lib/taurus/qt/qtgui/__init__.py10
-rw-r--r--lib/taurus/qt/qtgui/application/taurusapplication.py98
-rw-r--r--lib/taurus/qt/qtgui/base/taurusbase.py80
-rw-r--r--lib/taurus/qt/qtgui/button/qbuttonbox.py2
-rw-r--r--lib/taurus/qt/qtgui/button/taurusbutton.py8
-rw-r--r--lib/taurus/qt/qtgui/compact/abstractswitcher.py6
-rw-r--r--lib/taurus/qt/qtgui/compact/basicswitcher.py2
-rw-r--r--lib/taurus/qt/qtgui/container/taurusmainwindow.py157
-rw-r--r--lib/taurus/qt/qtgui/display/qled.py2
-rw-r--r--lib/taurus/qt/qtgui/display/qlogo.py2
-rw-r--r--lib/taurus/qt/qtgui/display/test/test_tauruslabel.py6
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/cli.py42
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/curve.py2
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/curvesmodel.py8
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/image.py4
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/plot.py66
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/taurustrend2d.py92
-rw-r--r--lib/taurus/qt/qtgui/extra_guiqwt/tools.py2
-rw-r--r--lib/taurus/qt/qtgui/extra_nexus/taurusnexuswidget.py2
-rw-r--r--lib/taurus/qt/qtgui/graphic/jdraw/jdraw.py2
-rw-r--r--lib/taurus/qt/qtgui/graphic/jdraw/jdraw_view.py7
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/graphic/taurusgraphic.py26
-rw-r--r--lib/taurus/qt/qtgui/icon/catalog.py14
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_off.pngbin0 -> 29069 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_on.pngbin0 -> 29069 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_off.pngbin0 -> 44340 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_on.pngbin0 -> 53415 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_off.pngbin0 -> 46475 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_on.pngbin0 -> 52137 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_off.pngbin0 -> 33008 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_on.pngbin0 -> 35547 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_off.pngbin0 -> 29804 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_on.pngbin0 -> 34363 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_off.pngbin0 -> 29069 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_off.pngbin0 -> 46366 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_on.pngbin0 -> 51438 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_off.pngbin0 -> 46567 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_on.pngbin0 -> 53680 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_off.pngbin0 -> 262963 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_on.pngbin0 -> 29566 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_off.pngbin0 -> 48203 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_on.pngbin0 -> 52122 bytes
-rw-r--r--lib/taurus/qt/qtgui/icon/icon.py2
-rw-r--r--lib/taurus/qt/qtgui/input/choicedlg.py4
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/input/qwheel.py87
-rw-r--r--lib/taurus/qt/qtgui/input/tauruscombobox.py4
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/input/tauruslineedit.py2
-rw-r--r--lib/taurus/qt/qtgui/input/taurusspinbox.py2
-rw-r--r--lib/taurus/qt/qtgui/model/qbasemodel.py10
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/panel/qdataexportdialog.py6
-rw-r--r--lib/taurus/qt/qtgui/panel/qdoublelist.py2
-rw-r--r--lib/taurus/qt/qtgui/panel/qrawdatachooser.py2
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusconfigeditor.py38
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/panel/taurusconfigurationpanel.py0
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusdemo.py17
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusdevicepanel.py169
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusform.py80
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusmodelchooser.py138
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusmodellist.py20
-rw-r--r--lib/taurus/qt/qtgui/panel/taurusvalue.py29
-rw-r--r--lib/taurus/qt/qtgui/panel/test/test_taurusvalue.py4
-rw-r--r--lib/taurus/qt/qtgui/panel/ui/TaurusDevPanel.ui4
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/plot/__init__.py0
-rw-r--r--lib/taurus/qt/qtgui/qwt5/arrayedit.py2
-rw-r--r--lib/taurus/qt/qtgui/qwt5/cli.py103
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/qwt5/curveprops.py10
-rw-r--r--lib/taurus/qt/qtgui/qwt5/curvesAppearanceChooserDlg.py4
-rw-r--r--lib/taurus/qt/qtgui/qwt5/monitor.py2
-rw-r--r--lib/taurus/qt/qtgui/qwt5/taurusplot.py90
-rw-r--r--lib/taurus/qt/qtgui/qwt5/taurusplotconf.py4
-rw-r--r--lib/taurus/qt/qtgui/qwt5/taurustrend.py105
-rw-r--r--lib/taurus/qt/qtgui/resource/taurus_resource_utils.py2
-rw-r--r--lib/taurus/qt/qtgui/table/qlogtable.py38
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/table/taurusdevicepropertytable.py3
-rw-r--r--lib/taurus/qt/qtgui/table/taurusgrid.py6
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/table/taurusvaluestable.py0
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/__init__.py3
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/appsettingswizard.py27
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/taurusgui/conf/gui_noconf.py2
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/taurusgui/conf/gui_selfconf.py2
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/tgconf_macrogui.ini11
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/paneldescriptionwizard.py8
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/res/init.template16
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/res/setup.template5
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/taurusgui.py588
-rw-r--r--lib/taurus/qt/qtgui/taurusgui/utils.py2
-rw-r--r--lib/taurus/qt/qtgui/test/base.py3
-rw-r--r--lib/taurus/qt/qtgui/util/qdraganddropdebug.py2
-rw-r--r--lib/taurus/qt/qtgui/util/tauruswidgettree.py2
-rw-r--r--lib/taurus/qt/qtgui/util/ui.py2
-rw-r--r--[-rwxr-xr-x]lib/taurus/qt/qtgui/util/validator.py0
-rw-r--r--[-rwxr-xr-x]lib/taurus/tauruscustomsettings.py9
-rw-r--r--lib/taurus/test/moduleexplorer.py30
-rw-r--r--lib/taurus/test/skip.py2
-rw-r--r--lib/taurus/test/test_import.py7
-rw-r--r--lib/taurus/test/testsuite.py49
-rwxr-xr-xscripts/taurusdoc178
-rwxr-xr-xscripts/taurusremotelogmonitor95
-rw-r--r--setup.py44
228 files changed, 2745 insertions, 2409 deletions
diff --git a/.bumpversion.cfg b/.bumpversion.cfg
index 3ebf6dff..fde7f42a 100644
--- a/.bumpversion.cfg
+++ b/.bumpversion.cfg
@@ -3,7 +3,7 @@ commit = True
message = Bump version {current_version} to {new_version}
tag = False
tag_name = {new_version}
-current_version = 4.5.0
+current_version = 4.6.1
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?
serialize =
{major}.{minor}.{patch}-{release}
diff --git a/.travis.yml b/.travis.yml
index 1dee1f72..eb159203 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -16,7 +16,6 @@ env:
- secure: "CCVtBQ8xIrOwUJGXxd81wyD1ng72Hf6d9y2U+5X88aVGTrOa8/hut10C+Jmnyf0NTZmGh/49eVvoWRvLDhjpECFMuO/bLkiNtVjz0VtWAHT2W98QJYmeymPzx86tGa+iAZCwlgXeRQFJCw1eqQvBYnjumMZWb9kj3fqgpqpSRH5SWnuRCmbxOoelmtTTUC8YKkzasAHYs03faR0DCq0oBmDy9nU2cfcRN7oE5wXUfEnDwNaoHbiQA4wiJbzNpBV432bIDtzD7gsFdiIT6ExJVFHi1gWB32bGZdbiDPpej7I2fW5qunbzUXS5doVhoBU67qqhI241RJ+AOBVb+sQnF8gwwi9/5/mcORiSBX7yI59YsOXYwo2YW+8PGr3OlF3t0+z92Q3uPytUXysdtVO4dExnLbV8OEzgmWCkv2M3GIajjE3isYAaBItqSBJHJnRClza4nNg2WLwmqLPBgM4AuSUZEpB/8kbz9kTecVEb13WrlTCNc8KVRGR+EGa4KmWADwOOxurxeb/NsTteOnzdyfrP2TXKeGOkN2uqBGYJaI7OoefsgLG7VF/+Sz4MTETMs/gZojwpO6igKBS1sJlcXujz/kt125b8gcSnrAiU1TjbZIBew/D40H64tpBcuk+dqF6i6HCoV2QmZ1QEpHOSoDk9FEaKMlgKhQj59/cWcI8="
matrix:
- - DOCKER_IMG=cpascual/taurus-test:debian-jessie
- DOCKER_IMG=cpascual/taurus-test:debian-stretch
- DOCKER_IMG=cpascual/taurus-test:debian-buster
- DOCKER_IMG=cpascual/taurus-test:debian-stretch-py3
@@ -24,8 +23,7 @@ env:
matrix:
allow_failures:
- - env: DOCKER_IMG=cpascual/taurus-test:debian-jessie
- - env: DOCKER_IMG=cpascual/taurus-test:debian-buster
+ - env: DOCKER_IMG=cpascual/taurus-test:debian-stretch-py3
before_install:
- docker run -d --name=taurus-test -h taurus-test --volume=`pwd`:/taurus $DOCKER_IMG
@@ -35,7 +33,7 @@ script:
- python -c "import fcntl; fcntl.fcntl(1, fcntl.F_SETFL, 0)"
- set -e
- docker exec -t taurus-test /bin/bash -c "cd /taurus ; python setup.py install"
- - docker exec -t taurus-test /bin/bash -c "TAURUS_STARTER_WAIT=5 taurustestsuite -e 'taurus\.core\.util\.test\.test_timer'"
+ - docker exec -t taurus-test /bin/bash -c "TAURUS_STARTER_WAIT=5 taurus testsuite -e 'taurus\.core\.util\.test\.test_timer'"
- docker exec -t taurus-test /bin/bash -c "cd /taurus ; sphinx-build -qW doc/source/ build/sphinx/html"
# deploy sphinx-built docs to taurus-doc repo
- if [[ "$DOCKER_IMG" == "cpascual/taurus-test:debian-stretch" && "$TRAVIS_REPO_SLUG" == "taurus-org/taurus" ]]; then
@@ -54,3 +52,18 @@ doctr:
require-master: false
sync: true
built-docs: build/sphinx/html/
+
+before_deploy:
+ - docker exec -t taurus-test /bin/bash -c "cd /taurus ; python setup.py sdist"
+
+deploy:
+ # deploy to pypi when a version tag is pushed to the official repo
+ - provider: pypi
+ user: taurus_bot
+ skip_existing: true
+ password:
+ secure: "QjqutDroKg1ZcSXUAEGtaut9kwxHifSQKkisE+Pvd8UXElr6+inJqUbtLGkBRDDJsjVrSZi4TeLu/NfZyey/9kTQvwqrSHio80KgQ7HzuktgdmnFKfU4TWFEt4wd8LzYF4O5ljtYj4/k6txQ0zMVsLN5/SAQl44E0KSRBZBifrbeEXL3k9YI6nhw7cBiV+9XVFJBuBP5IVGhk4mOAFDT0UGyuCpMBKacfmtgDtZnYqb1SnRkFb9vT2kSPy8j3ZfZ3YPfZECwVWZtvG98/ujz1S6+mZKyErGNZc5RocBNdQFAG6AP8Epl05k+UmHO0mtHkSC+Mmh3J2grZXCKmojqcsrgJ/oP82WOQQtzZvLjYylIBC6tJ8GI0AJxUa7yukXS+x7ihkK3Xd9SoUuQri6dRlbE7iEJr7z6ZqwoiossY0feqN/v03fyJgze3KOsZ/sR1jQ2A8jdN62NzzM674w+UGhK7Q7hRRsiaODNzNrwcOrhYh4mjIXk9T8Iij223AjTixSJ29l2GUMyFgFU3KsgEUhgx8ZcL4G0olirokoMAn3wnqCbocQt7nWwUFGvQE384Br27iW598mka2njvAuww05xGCW6+/n3/aPXZYoE+DgMtYQLF8yHy7Ucvc+8mVfkrlNSkPzCF5W05JgkvVpNYznIMvnzjRcO5yoXdVUDcRM="
+ on:
+ repo: taurus-org/taurus
+ tags: true
+ condition: "$TRAVIS_TAG =~ ^[0-9]+.[0-9]+.[0-9]+$"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9c2a2f2c..422d7b03 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,74 @@ Note: changes in the [support-3.x] branch (which was split from
the master branch after [3.7.1] and maintained in parallel to the
develop branch) won't be reflected in this file.
+## [4.6.1] - 2019-08-19
+Hotfix for auto-deployment in PyPI with Travis. No other difference from 4.6.0.
+
+### Fixed
+- Travis not deploying tar.gz (#990)
+
+## [4.6.0] - 2019-08-19
+[Jul19 milestone](https://github.com/taurus-org/taurus/milestone/13)
+
+### Added
+- New CLI API based on click and `taurus` command supporting pluggable subcommands (#856)
+- TaurusGui now accepts a `settingsname` argument to specify the settings file to
+ be loaded. Also accessible from the CLI as `taurus gui --ini NAME` (#570)
+- `TaurusModelSelector` and `TaurusModelSelectorItem` classes and the
+ (experimental) `"taurus.qt.qtgui.panel.TaurusModelSelector.items"` entry point (#869)
+- `TaurusFactory.getValidatorFromName` method and `getValidatorFromName` helper (#893)
+- New options API for TaurusMainWindow and TaurusGui (#858)
+- New optional set of color-blind friendly LED icons for Tango states (#902)
+- New configuration options in QWheelEdit to customize its internal editor (#832)
+- New `Utf8Codec` (#960)
+- Support for RGB24 in VideoImageCodec (#832)
+
+### Removed
+- Functions implementing the old CLI scripts (#856).
+ Note: these functions and the corresponding console scripts are still provided
+ by the "[taurus_legacy_cli]" plugin. (#856)
+- Unused ini file `<taurus>/qt/qtgui/taurusgui/conf/tgconf_macrogui/tgconf_macrogui.ini`
+
+### Changed
+- Old CLI scripts (taurusform, taurusdemo, etc.) are replaced by equivalent
+ subcommands to the `taurus` command. (#856)
+- TaurusDevPanel now is able to show the attributes independently of the
+ state of the device (#946)
+- `JsonCodec.encode` now outputs strings (in v4.5, it was inconsistently returning bytes when in py3) (#960)
+- TaurusDevPanel is now a TaurusGui (new panels can be added by the user) (#939)
+- Taurus mixin classes (e.g. `TaurusBaseComponent`) are now `super()`-friendly (#934)
+
+### Deprecated
+- `taurus.core.util.argparse` (#856)
+- `TaurusAttribute._(un)subscribeEvents` API (#876)
+- `TaurusBaseComponent` "taurus popup menu" API (#906)
+- `TaurusMainWindow` old option names (`_heartbeat`, `_show*Menu`, `_showLogger`,
+ `_supportUserPerspectives`, `_splashLogo`, `_splashMessage`) (#858)
+
+### Fixed
+- taurusgui not running if tango not installed (#912)
+- Outdated template for new guis created with `taurus newgui` (#933)
+- wrong return value of `isValidName` in some cases (#897)
+- exception when calling TangoAtribute.write with a list of integers (#915)
+- several issues related to py2+p3 simultaneous support (#878, #879, #881, #885, #886, #894, #947)
+- several issues related to multiple Qt bindings support (#875, #890, #895, #962)
+- Some modules not being autodocumented (#941)
+- TaurusArrayEditorButton used in forms even if Qwt5 is not available (#973)
+- TaurusGuis do not show output in console on Windows (#868)
+- TaurusConfigEditor not working on Windows (#950, #957)
+- TaurusDesigner not working on Windows (#955, #968)
+- Other (#956, #954, #948, #925)
+
+## [4.5.1] - 2019-02-15
+
+Together with [4.5.0], they cover the [Jan19 milestone](https://github.com/taurus-org/taurus/milestone/12)
+
+### Fixed
+- redundant units shown in TaurusForm write widget (#860)
+- deprecation warning in tauruspanel
+- infinite recursion issue in TangoDevice
+- Other (#855)
+
## [4.5.0] - 2019-01-29
This is a special release for meeting the deadline of debian buster
@@ -54,6 +122,7 @@ freeze (debian 10).
- `taurus.external.qt.QtCore.to_qvariant`
## [4.4.0] - 2018-07-26
+[Jul18 milestone](https://github.com/taurus-org/taurus/milestone/11)
### Deprecated
- pint, enum, unittest and argparse submodules of taurus.external (#723)
@@ -402,6 +471,9 @@ and several other places](https://sf.net/p/tauruslib/tickets/milestone/Jul15/)
[TEP14]: http://www.taurus-scada.org/tep/?TEP14.md
[TEP15]: http://www.taurus-scada.org/tep/?TEP15.md
[Unreleased]: https://github.com/taurus-org/taurus/tree/develop
+[4.6.1]: https://github.com/taurus-org/taurus/tree/release-4.6.1
+[4.6.0]: https://github.com/taurus-org/taurus/tree/release-4.6.0
+[4.5.1]: https://github.com/taurus-org/taurus/tree/release-4.5.1
[4.5.0]: https://github.com/taurus-org/taurus/tree/release-4.5.0
[4.4.0]: https://github.com/taurus-org/taurus/tree/4.4.0
[4.3.1]: https://github.com/taurus-org/taurus/tree/4.3.1
@@ -414,6 +486,7 @@ and several other places](https://sf.net/p/tauruslib/tickets/milestone/Jul15/)
[3.7.0]: https://github.com/taurus-org/taurus/tree/3.7.0
[3.6.0]: https://github.com/taurus-org/taurus/tree/3.6.0
[support-3.x]: https://github.com/taurus-org/taurus/tree/support-3.x
+[taurus_legacy_cli] https://github.com/taurus-org/taurus_legacy_cli
diff --git a/ci/win-test.bat b/ci/win-test.bat
index 1ba3d319..c5491477 100644
--- a/ci/win-test.bat
+++ b/ci/win-test.bat
@@ -14,9 +14,12 @@ pip install pint
:: Install enum34
pip install enum34
-:: Install enum34
+:: Install future
pip install future
+:: Install click
+pip install click
+
:: Install guiqwt
:: TODO, install guiqwt from pypi
:: pip install --upgrade guiqwt
diff --git a/debian/changelog b/debian/changelog
index 2e73725b..c02e6a32 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,18 @@
+taurus (4.6.1+dfsg-1) unstable; urgency=medium
+
+ [ Carlos Pascual ]
+ * New upstream version 4.6.1
+ * Standards-Version bump to 4.4.0 (nothing to do)
+ * Use debhelper-compat instead of debian/compat.
+ * d/changelog: Remove trailing whitespaces.
+ * Rename taurus script to taurus-py2 in taurus-python
+ * Add man page for taurus script
+
+ -- Picca Frédéric-Emmanuel <picca@debian.org> Tue, 27 Aug 2019 21:04:54 +0200
+
taurus (4.5.0+dfsg-2) unstable; urgency=medium
- * Add python3-taurus package
+ * Add python3-taurus package
-- Carlos Pascual <cpascual@cells.es> Tue, 05 Feb 2019 16:15:03 +0100
diff --git a/debian/compat b/debian/compat
deleted file mode 100644
index ec635144..00000000
--- a/debian/compat
+++ /dev/null
@@ -1 +0,0 @@
-9
diff --git a/debian/control b/debian/control
index 294605b8..54e9549f 100644
--- a/debian/control
+++ b/debian/control
@@ -3,10 +3,11 @@ Maintainer: Debian Science Maintainers <debian-science-maintainers@lists.alioth.
Uploaders: Picca Frédéric-Emmanuel <picca@debian.org>, Carlos Pascual <cpascual@cells.es>
Section: science
Priority: optional
-Build-Depends: debhelper (>= 9),
+Build-Depends: debhelper-compat (= 9),
dh-python,
graphviz,
python-all,
+ python-click,
python-enum34,
python-future,
python-guiqwt,
@@ -24,6 +25,7 @@ Build-Depends: debhelper (>= 9),
python-spyder,
python-tango,
python3-all,
+ python3-click,
python3-future,
python3-guiqwt,
python3-h5py,
@@ -45,7 +47,7 @@ Build-Depends: debhelper (>= 9),
symlinks,
xauth,
xvfb
-Standards-Version: 4.3.0
+Standards-Version: 4.4.0
Vcs-Browser: https://salsa.debian.org/science-team/taurus
Vcs-Git: https://salsa.debian.org/science-team/taurus.git
Homepage: http://www.taurus-scada.org
@@ -55,6 +57,7 @@ Architecture: all
Section: python
Depends: ${misc:Depends},
${python:Depends},
+ python-click,
python-enum34,
python-future,
python-guiqwt,
@@ -86,6 +89,7 @@ Architecture: all
Section: python
Depends: ${misc:Depends},
${python3:Depends},
+ python3-click,
python3-future,
python3-guiqwt,
python3-h5py,
diff --git a/debian/python-taurus.links b/debian/python-taurus.links
new file mode 100644
index 00000000..57176d35
--- /dev/null
+++ b/debian/python-taurus.links
@@ -0,0 +1 @@
+usr/share/python-taurus/scripts/taurus usr/bin/taurus-py2
diff --git a/debian/python3-taurus.links b/debian/python3-taurus.links
deleted file mode 100644
index b0e56fc3..00000000
--- a/debian/python3-taurus.links
+++ /dev/null
@@ -1,13 +0,0 @@
-usr/share/python3-taurus/scripts/taurusconfigbrowser usr/bin/taurusconfigbrowser3
-usr/share/python3-taurus/scripts/tauruscurve usr/bin/tauruscurve3
-usr/share/python3-taurus/scripts/taurusdemo usr/bin/taurusdemo3
-usr/share/python3-taurus/scripts/taurusdesigner usr/bin/taurusdesigner3
-usr/share/python3-taurus/scripts/taurusdevicepanel usr/bin/taurusdevicepanel3
-usr/share/python3-taurus/scripts/taurusform usr/bin/taurusform3
-usr/share/python3-taurus/scripts/taurusgui usr/bin/taurusgui3
-usr/share/python3-taurus/scripts/taurusiconcatalog usr/bin/taurusiconcatalog3
-usr/share/python3-taurus/scripts/taurusimage usr/bin/taurusimage3
-usr/share/python3-taurus/scripts/tauruspanel usr/bin/tauruspanel3
-usr/share/python3-taurus/scripts/taurustestsuite usr/bin/taurustestsuite3
-usr/share/python3-taurus/scripts/taurustrend1d usr/bin/taurustrend1d3
-usr/share/python3-taurus/scripts/taurustrend2d usr/bin/taurustrend2d3
diff --git a/debian/python3-taurus.manpages b/debian/python3-taurus.manpages
new file mode 100644
index 00000000..ddf17ba6
--- /dev/null
+++ b/debian/python3-taurus.manpages
@@ -0,0 +1 @@
+doc/man/taurus.1
diff --git a/debian/rules b/debian/rules
index 97adbf97..82071432 100755
--- a/debian/rules
+++ b/debian/rules
@@ -3,7 +3,7 @@
export PYBUILD_NAME=taurus
export PYBUILD_AFTER_INSTALL=dh_numpy
export PYBUILD_DISABLE=test
-export PYBUILD_INSTALL_ARGS_python3=--install-scripts=/usr/share/python3-taurus/scripts/
+export PYBUILD_INSTALL_ARGS_python2=--install-scripts=/usr/share/python-taurus/scripts/
%:
dh $@ --with python2,python3,sphinxdoc --buildsystem=pybuild
diff --git a/doc/how_to_release.md b/doc/how_to_release.md
index 04fb88bd..bc7ce6ce 100644
--- a/doc/how_to_release.md
+++ b/doc/how_to_release.md
@@ -1,4 +1,4 @@
-# How to release (draft)
+# How to release
This is a guide for taurus release managers: it details the
steps for making an official release, including a checklist
@@ -12,27 +12,33 @@ of stuff that should be manually tested.
4. Create the release branch if it was not done already in the previous step and:
1. Review and update the CHANGELOG.md if necessary. See [this](http://keepachangelog.com)
2. Bump version using `bumpversion <major|minor|patch>` (use [semver](http://semver.org/) criteria to choose amongst `major`, `minor` or `patch`
- 3. Update man pages:
- ```
- cd <taurus>/doc
- ./makeman
- git add man
- git commit -m "Update man pages"
- ```
- 4. Create a PR to merge the `release-XXX` against the **`master`** branch of the taurus-org repo
+ 3. Create a PR to merge the `release-XXX` against the **`master`** branch of the taurus-org repo
5. Request reviews in the PR from at least one integrator from each participating institute. The master branch is protected, so the reviews need to be cleared (or dismissed with an explanation) before the release can be merged.
6. Perform manual tests (see checklist below). You may use the CI artifacts (e.g., from appveyor). To avoid spamming the PR comments with the manual test results, a new issue can be created to report the tests results on each platform (and just use a single check for each platform in the PR).
7. Once all reviews a cleared, update the date of the release in the CHANGELOG.md, run `bumpversion release`, push and merge the PR and tag in master
-8. Merge also the `release-XXX` branch into develop, and bump the version of develop with `bumpversion patch`
-9. Release to PyPI **from a clean checkout** and using [twine](https://github.com/pypa/twine):
- ```
- cd /tmp
- git clone https://github.com/taurus-org/taurus.git -b <RELEASE_TAG>
- cd taurus
- python setup.py sdist bdist_wheel
- twine upload dist/*
- ```
-
+8. Check that travis-ci correctly uploaded to PyPI (triggered on tag push).
+
+ Previously:
+ ~~Release to PyPI **from a clean checkout** and using [twine](https://github.com/pypa/twine):~~
+ > ```
+ > cd /tmp
+ > git clone https://github.com/taurus-org/taurus.git -b <RELEASE_TAG>
+ > cd taurus
+ > python setup.py sdist bdist_wheel
+ >twine upload dist/*
+ > ```
+
+9. Merge also the `release-XXX` branch into develop, and bump the version of develop with `bumpversion patch`
+10. Complete GitHub release (upload artifacts, edit text)
+11. Create news in www.tango-controls.org
+ 1. On the News page click on Submit a news and fill up the form (if it doesn't work, try opening in new tab):
+ * Title: New Release Of Taurus X.X.X (Jan|JulXX)
+ * Ilustration: Taurus official logo (use png)
+ * Summary: short summary of the news (do not include the whole changelog here..)
+ * Categories: Release
+ 2. After submitting click on Modify this content text of the area \<\<Content\>\> and provide detailes of the release e.g. changelog.
+12. Notify mailing lists (taurus-users@lists.sourceforge.net, taurus-devel@lists.sourceforge.net, info@tango-controls.org)
+
## Manual test checklist
@@ -44,83 +50,60 @@ and access to a Tango system with the TangoTest DS running.
Hint: this list can be used as a template to be copy-pasted on an issue linked from the release PR
```
### Installation
-- [ ] Install Taurus from the tar.gz : `pip install <tarball_artifact_URL>`
-### Taurusdemo
+For tips on how to prepare an environment for installation, see
+http://taurus-scada.org/users/getting_started.html
+
+
+- [ ] Install Taurus from the an artifact of Appveyor (tgz or msi): `pip install <tarball_artifact_URL>`
+- [ ] Install taurus-pyqtgraph from the master branch of its repo:
+ `pip install https://github.com/taurus-org/taurus_pyqtgraph/archive/master.zip`.
+- [ ] Check installed version of taurus: `taurus --version`
+- [ ] Check installed version of taurus_pyqtgraph: `taurus tpg --version`
-- [ ] Test all of the buttons of the taurusdemo. All demos should launch correctly and without raising exceptions
+### taurus demo
+
+- [ ] Execute `taurus demo`
+- [ ] Test all of the buttons of the taurus demo. All demos should launch correctly and without raising exceptions
- [ ] For TaurusLabel, check foreground role, the background role, the prefix, the suffix, the formatter, etc.
- [ ] For TaurusLabel, in order to test the background role=value, you can use the following attribute: `eval:["FAULT","ON","OFF","ALARM"][randint(4)]`
-- [ ] For TaurusLabel, use a model with fragment (e.g., `sys/tg_test/1/ampli#rvalue.magnitude`, `eval:Q('1mm')#rvalue.unit"`, `eval:10*arange(9)#rvalue[3:4]`)
+- [ ] For TaurusLabel, use a model with fragment (e.g., `sys/tg_test/1/ampli#rvalue.magnitude`, `eval:Q('1mm')#rvalue.units`, `eval:10*arange(9)#rvalue[3:4]`)
- [ ] For LCD: Test the foreground roles and the background role
- [ ] For Led: Test the colors, ON color, Off color. (hint: you can use `eval:False` as a model for testing)
-### taurusplot
-(basically try all features described in the [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+### taurus guiqwt image
-- [ ] Execute: `taurusplot "eval:Q(rand(333),'mm')" sys/tg_test/1/wave`
-- [ ] Check region Zoom in and out with region zoom and go back stacked zoom levels with the mouse middle button
-- [ ] Check mouse wheel Zoom
-- [ ] Test panning (dragging with CTRL pressed)
-- [ ] Test inspector mode
-- [ ] Test pause mode
-- [ ] Move curves between axes by clicking on legend (and test zoom on Y2)
-- [ ] Test plot configuration dialog
-- [ ] Test changing curve titles
-- [ ] Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)
-- [ ] Open the "Input data selection" dialog and add/remove/reorder /edit models
-- [ ] export one curve data to ASCII and then load it using "Input data selection" -> raw data -> open file
-- [ ] ... other features from [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+- [ ] Execute `taurus guiqwt image --demo`
+- [ ] try to resize the image and pan it using the mouse.
+- [ ] check the cross section tools, the color maps, etc.
+- [ ] replace the image using the "Change Taurus Model" button (choose , eg, sys/tg_test/1/double_image_ro)
-### taurustrend
-(basically try all features described in the [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+### taurus guiqwt trend2d
-- [ ] Execute: `taurustrend "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
-- [ ] Execute: `taurustrend -xe "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
-- [ ] Check region Zoom in and out with region zoom and go back stacked zoom levels with the mouse middle button
-- [ ] Check mouse wheel Zoom
-- [ ] Test panning (dragging with CTRL pressed)
-- [ ] Test inspector mode
-- [ ] Test pause mode
-- [ ] Move curves between axes by clicking on legend (and test zoom on Y2)
-- [ ] Test plot configuration dialog
-- [ ] Test Forced reading mode
-- [ ] Test autopanning mode
-- [ ] Test autoscale x mode
-- [ ] Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)
-- [ ] ... other features from [user's guide](http://taurus-scada.org/users/ui/index.html)
-
-### Test taurusimage
-
-- [ ] Execute `taurusimage --demo`
-- [ ] try to resize the image and move it using the mouse.
+- [ ] Execute: `taurus --polling-period 333 guiqwt trend2d --demo`
+- [ ] Execute: `taurus --polling-period 333 guiqwt trend2d -xt --demo` **(known to fail in 4.1.0)**
+- [ ] Execute: `taurus --polling-period 333 guiqwt trend2d -xe --demo`
+- [ ] Test auto-scroll and auto-scale tools (from context menu)
-### taurustrend2d
-
-- [ ] Execute: `taurustrend2d --demo --taurus-polling-period 333`
-- [ ] Execute: `taurustrend2d -xt --demo --taurus-polling-period 333` **(known to fail in 4.1.0)**
-- [ ] Execute: `taurustrend2d -xe --demo --taurus-polling-period 333`
-- [ ] Test auto-scroll and auto-scale tools
-- [ ] Test Save & restore config (change axes range, zoom, tool status colormap etc & check that everything is restored)
-
-### taurusdesigner
-- [ ] Check that taurusdesigner is correctly opened and taurus widgets are present in the catalog
+### taurus designer
+- [ ] Execute `taurus designer`. Check that the taurus widgets are present in the catalog
- [ ] Create an empty widget and drag various taurus widgets to it (they should be correctly dropped)
-### taurusdevicepanel
-- [ ] Execute: `taurusdevicepanel sys/tg_test/1`
+### taurus device
+- [ ] Execute: `taurus device sys/tg_test/1`
- [ ] Check that it opens correctly and that the attrs and commands are populated
- [ ] Execute SwitchStates command (see that the state label changes to FAULT and its color to red)
and then execute the Init command and the label returns to RUNNING (blue)
-
-### tauruspanel
-- [ ] Execute: `tauruspanel`
+
+### taurus panel
+- [ ] Execute: `taurus panel`
- [ ] Navigate in the tree and select the TangoTest device (the attr an command panels should be populated)
+- [ ] Execute SwitchStates command to put it in FAULT, close the GUI and reopen it. Repeat previous point again.
-### taurusform
+### taurus form
(basically try all features described in the [user's guide](http://taurus-scada.org/users/ui/index.html)
-- [ ] Launch `taurusform sys/tg_test/1/short_scalar`
+- [ ] Launch `taurus form sys/tg_test/1/short_scalar`
- [ ] go to label context menu, change the configuration and set range to (-1000, 1000), alarm to (-500, 500) and unit to `mm`. Close the form and relaunch. The new units should be used. Change the the write value and check that the orange color is used when in warning values, and that the write widget does not allow to write values out of range.
- [ ] Test to drag and drop of this attribute onto the same form many times (4 times)
(If it crashes, you are seeing bug #96)
@@ -135,31 +118,94 @@ Hint: this list can be used as a template to be copy-pasted on an issue linked f
- [ ] Test the different "show" buttons (tables, images, spectra)
- [ ] Change the write widget of double_scalar by a TaurusWheelEdit
- [ ] Change other read and write widgets
+- [ ] After the previous changes, you should have a quite "custom" form. Use "Save current Settings" and save
+ to "tf.pck". Close the form and reopen it with `taurus form --config tf.pck`
- [ ] ... other features from [user's guide](http://taurus-scada.org/users/ui/index.html)
-### taurusgui
+### taurus gui
(basically try all features described in the [user's guide](http://taurus-scada.org/users/ui/index.html)
-- [ ] Launch `taurusgui example01`
+- [ ] Launch `taurus gui example01`
- [ ] Test (un)lock view
- [ ] Create a new panel (a TaurusForm) and drag and drop several models from other forms
- [ ] Move panels around (with view unlocked!) and hide ("close") and re-show them
- [ ] Test saving and restoring perspectives
-- [ ] Test drag&drop from a form to a trend
+- [ ] Test drag&drop from a form to a trend (won't work if using the tpg.TaurusTrend, until [this](https://github.com/taurus-org/taurus_pyqtgraph/issues/25)) is fixed
+- [ ] Test drag&drop from a form to a plot
- [ ] Test clicking on "example01 synoptic" elements and check that the panels raised
- [ ] Test that selecting a panel changes the selection on "example01 synoptic"
- [ ] Test the actions in the menus
-- [ ] Create a new TaurusGui (call it `foogui`) with `taurusgui --new-gui` (follow the wizard)
+- [ ] Create a new TaurusGui (call it `foogui`) with `taurus newgui` (follow the wizard)
- [ ] Install `foogui` with pip (using a virtualenv may be a good idea)
- [ ] launch `foogui` using the script that has been installed
- [ ] ... other features from [user's guide](http://taurus-scada.org/users/ui/index.html)
+### taurus config
+- [ ] Open an ini file with taurus config and check that it is loaded correctly.
-### taurusconfigbrowser
-- [ ] Open an ini file with taurusconfigbrowser and check that it is loaded correctly.
-
-### taurusiconcatalog
-- [ ] Launch `taurusiconcatalog`. Several tabs with an array of icons [should be displayed](http://taurus-scada.org/en/latest/devel/icon_guide.html#taurus-icon-catalog)
+### taurus icons catalog
+- [ ] Launch `taurus icons`. Several tabs with an array of icons [should be displayed](http://taurus-scada.org/en/latest/devel/icon_guide.html#taurus-icon-catalog)
- [ ] Check that tooltips give info on each icon
- [ ] Click on some icons and check that they give a bigger view of the icon and more info.
+
+### taurus tpg plot (needs taurus_pyqtgraph installed)
+- [ ] Execute: `taurus tpg plot "eval:Q(rand(333),'mm')" sys/tg_test/1/wave`
+- [ ] Check zoom / panning (drag with right / left button), and Use (A) button to auto-range
+- [ ] Test inspector tool
+- [ ] Move curves between axes by using the plot configuration option in context menu
+- [ ] With curves in Y1 and Y2, test zooms and panning on separate axes (drag with right/left on the axis)
+- [ ] Test plot configuration dialog
+- [ ] Test changing curve titles
+- [ ] Open the "Input data selection" dialog and add/remove/reorder/edit models. Try adding models both for X and Y
+- [ ] NOT YET READY <s>Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)</s>
+
+### taurus tpg trend (needs taurus_pyqtgraph installed)
+- [ ] Execute: `taurus tpg trend "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
+- [ ] Execute: `taurus tpg trend -xe "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
+- [ ] Check zoom / panning (drag with right / left button), and Use (A) button to auto-range
+- [ ] Test inspector tool
+- [ ] Move curves between axes by using the plot configuration option in context menu
+- [ ] With curves in Y1 and Y2, test zooms and panning on separate axes (drag with right/left on the axis)
+- [ ] Test plot configuration dialog
+- [ ] Test Forced reading tool
+- [ ] Test Fixed Range Scale tool
+- [ ] Test autoscale x mode
+- [ ] NOT YET READY <s> Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)</s>
+
+### taurus qwt5 plot _Only if using py2 qt4_
+(basically try all features described in the [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+
+- [ ] Execute: `taurus qwt5 plot "eval:Q(rand(333),'mm')" sys/tg_test/1/wave`
+- [ ] Check region Zoom in and out with region zoom and go back stacked zoom levels with the mouse middle button
+- [ ] Check mouse wheel Zoom
+- [ ] Test panning (dragging with CTRL pressed)
+- [ ] Test inspector mode
+- [ ] Test pause mode
+- [ ] Move curves between axes by clicking on legend (and test zoom on Y2)
+- [ ] Test plot configuration dialog
+- [ ] Test changing curve titles
+- [ ] Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)
+- [ ] Open the "Input data selection" dialog and add/remove/reorder /edit models
+- [ ] export one curve data to ASCII and then load it using "Input data selection" -> raw data -> open file
+ (Note: make sure to select the X colum as 0)
+- [ ] ... other features from [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+
+### taurus qwt5 trend _Only if using py2 qt4_
+(basically try all features described in the [user's guide](http://taurus-scada.org/en/latest/users/ui/index.html)
+
+- [ ] Execute: `taurus qwt5 trend "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
+- [ ] Execute: `taurus qwt5 trend -xn "eval:Q(rand(),'mm')" sys/tg_test/1/ampli`
+- [ ] Check region Zoom in and out with region zoom and go back stacked zoom levels with the mouse middle button
+- [ ] Check mouse wheel Zoom
+- [ ] Test panning (dragging with CTRL pressed)
+- [ ] Test inspector mode
+- [ ] Test pause mode
+- [ ] Move curves between axes by clicking on legend (and test zoom on Y2)
+- [ ] Test plot configuration dialog
+- [ ] Test Forced reading mode
+- [ ] Test autopanning mode
+- [ ] Test autoscale x mode
+- [ ] Test Save & restore config (change curve properties, zoom, etc & check that everything is restored)
+- [ ] ... other features from [user's guide](http://taurus-scada.org/users/ui/index.html)
+
```
diff --git a/doc/makeman b/doc/makeman
index 9bba9cf8..51ac4d68 100755
--- a/doc/makeman
+++ b/doc/makeman
@@ -50,6 +50,8 @@ for f in `ls`
V=`./$f --version 2>/dev/null |egrep -o '[0-9]+.[0-9]+(.[0-9])?'`
echo help2man -N -o "$DOCDIR/man/$f.1" --version-string=$V ./$f
help2man -N -o "$DOCDIR/man/$f.1" --version-string=$V ./$f
+ # scripts are installed with 755 permissions, but manpages should be 644
+ chmod 644 "$DOCDIR/man/$f.1"
done
cd $DOCDIR
diff --git a/doc/man/taurus.1 b/doc/man/taurus.1
new file mode 100644
index 00000000..16b73ac1
--- /dev/null
+++ b/doc/man/taurus.1
@@ -0,0 +1,21 @@
+.TH TAURUS 1
+.SH NAME
+taurus \- Taurus command line interface
+.SH SYNOPSIS
+.TP
+\fBtaurus\fP [\fIoptions\fP] [\fIsubcommand\fP [\fIsuboptions\fP] [\fIargs\fP] ... ]
+.SH OVERVIEW
+Taurus is a python framework for control and data acquisition CLIs and
+GUIs in scientific/industrial environments.
+
+The \fBtaurus\fP command is the main CLI access to launch Taurus
+tools. It uses subcommands (e.g. `form', `gui', ...) to provide
+functionality.
+
+The subcommands can be dynamically provided by plugins, so the best
+source for information about the available options and subcommands is
+to run `taurus --help`. Each subcommand will also provide more detailed help
+about its own options and arguments if run as `taurus <command> --help`
+
+For more information about the Taurus project, visit
+http://taurus-scada.org.
diff --git a/doc/man/taurusconfigbrowser.1 b/doc/man/taurusconfigbrowser.1
deleted file mode 100644
index e1ed971f..00000000
--- a/doc/man/taurusconfigbrowser.1
+++ /dev/null
@@ -1,42 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSCONFIGBROWSER "1" "July 2018" "taurusconfigbrowser 4.4.0" "User Commands"
-.SH NAME
-taurusconfigbrowser \- manual page for taurusconfigbrowser 4.4.0
-.SH SYNOPSIS
-.B taurusconfigbrowser
-[\fI\,options\/\fR] [\fI\,INIFILENAME\/\fR]
-.SH DESCRIPTION
-taurus configuration editor
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/tauruscurve.1 b/doc/man/tauruscurve.1
deleted file mode 100644
index 8094d70b..00000000
--- a/doc/man/tauruscurve.1
+++ /dev/null
@@ -1,48 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSCURVE "1" "July 2018" "tauruscurve 4.4.0" "User Commands"
-.SH NAME
-tauruscurve \- manual page for tauruscurve 4.4.0
-.SH SYNOPSIS
-.B tauruscurve
-[\fI\,options\/\fR] [\fI\,<model1> \/\fR[\fI\,<model2>\/\fR] ...]
-.SH DESCRIPTION
-a taurus application for plotting 1D data sets
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-demo\fR
-show a demo of the widget
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusdemo.1 b/doc/man/taurusdemo.1
deleted file mode 100644
index 6831abb2..00000000
--- a/doc/man/taurusdemo.1
+++ /dev/null
@@ -1,42 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSDEMO "1" "July 2018" "taurusdemo 1.0" "User Commands"
-.SH NAME
-taurusdemo \- manual page for taurusdemo 1.0
-.SH SYNOPSIS
-.B taurusdemo
-[\fI\,options\/\fR]
-.SH DESCRIPTION
-A demo application for taurus
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusdesigner.1 b/doc/man/taurusdesigner.1
deleted file mode 100644
index 370c3e8c..00000000
--- a/doc/man/taurusdesigner.1
+++ /dev/null
@@ -1,22 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSDESIGNER "1" "July 2018" "taurusdesigner 4.4.0" "User Commands"
-.SH NAME
-taurusdesigner \- manual page for taurusdesigner 4.4.0
-.SH SYNOPSIS
-.B taurusdesigner
-[\fI\,options\/\fR] \fI\,<ui file(s)>\/\fR
-.SH DESCRIPTION
-The Qt designer application customized for taurus
-.SH OPTIONS
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-taurus\-path\fR=\fI\,TAURUSPATH\/\fR
-additional directories to look for taurus widgets
-.TP
-\fB\-\-qt\-designer\-path\fR=\fI\,PYQTDESIGNERPATH\/\fR
-additional directories to look for python qt widgets
diff --git a/doc/man/taurusdevicepanel.1 b/doc/man/taurusdevicepanel.1
deleted file mode 100644
index 6117f9df..00000000
--- a/doc/man/taurusdevicepanel.1
+++ /dev/null
@@ -1,45 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSDEVICEPANEL "1" "July 2018" "taurusdevicepanel 4.4.0" "User Commands"
-.SH NAME
-taurusdevicepanel \- manual page for taurusdevicepanel 4.4.0
-.SH SYNOPSIS
-.B taurusdevicepanel
-[\fI\,options\/\fR] [\fI\,devname \/\fR[\fI\,attrs\/\fR]]
-.SH DESCRIPTION
-Taurus Application inspired in Jive and Atk Panel
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-config\-file\fR=\fI\,CONFIG_FILE\/\fR
-load a config file (TODO: document this option)
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusform.1 b/doc/man/taurusform.1
deleted file mode 100644
index 0fd99c92..00000000
--- a/doc/man/taurusform.1
+++ /dev/null
@@ -1,48 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSFORM "1" "July 2018" "taurusform 4.4.0" "User Commands"
-.SH NAME
-taurusform \- manual page for taurusform 4.4.0
-.SH SYNOPSIS
-.B taurusform
-[\fI\,options\/\fR] [\fI\,model1 \/\fR[\fI\,model2 \/\fR...]]
-.SH DESCRIPTION
-the taurus form panel application
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-config\fR=\fI\,CONFIG_FILE\/\fR, \fB\-\-config\-file\fR=\fI\,CONFIG_FILE\/\fR
-use the given config file for initialization
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusgui.1 b/doc/man/taurusgui.1
deleted file mode 100644
index 8f0694b7..00000000
--- a/doc/man/taurusgui.1
+++ /dev/null
@@ -1,54 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSGUI "1" "July 2018" "taurusgui 4.4.0" "User Commands"
-.SH NAME
-taurusgui \- manual page for taurusgui 4.4.0
-.SH SYNOPSIS
-.B taurusgui
-[\fI\,options\/\fR] \fI\,confname\/\fR
-.SH DESCRIPTION
-The taurus GUI application
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-config\-dir\fR=\fI\,CONFIG_DIR\/\fR
-use the given configuration directory for
-initialization
-.TP
-\fB\-\-new\-gui\fR
-launch a wizard for creating a new TaurusGUI
-application
-.TP
-\fB\-\-fail\-proof\fR
-launch in fail proof mode (it prevents potentially
-problematic configs from being loaded)
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusiconcatalog.1 b/doc/man/taurusiconcatalog.1
deleted file mode 100644
index f9c04120..00000000
--- a/doc/man/taurusiconcatalog.1
+++ /dev/null
@@ -1,40 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSICONCATALOG "1" "July 2018" "taurusiconcatalog 4.4.0" "User Commands"
-.SH NAME
-taurusiconcatalog \- manual page for taurusiconcatalog 4.4.0
-.SH SYNOPSIS
-.B taurusiconcatalog
-[\fI\,options\/\fR]
-.SH OPTIONS
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusimage.1 b/doc/man/taurusimage.1
deleted file mode 100644
index 150f699e..00000000
--- a/doc/man/taurusimage.1
+++ /dev/null
@@ -1,51 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSIMAGE "1" "July 2018" "taurusimage 4.4.0" "User Commands"
-.SH NAME
-taurusimage \- manual page for taurusimage 4.4.0
-.SH SYNOPSIS
-.B taurusimage
-[\fI\,options\/\fR] \fI\,<model>\/\fR
-.SH DESCRIPTION
-a Taurus application for plotting Image Attributes
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-demo\fR
-show a demo of the widget
-.TP
-\fB\-\-rgb\fR
-assume image is RGB
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/tauruspanel.1 b/doc/man/tauruspanel.1
deleted file mode 100644
index ac70730f..00000000
--- a/doc/man/tauruspanel.1
+++ /dev/null
@@ -1,42 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSPANEL "1" "July 2018" "tauruspanel 4.4.0" "User Commands"
-.SH NAME
-tauruspanel \- manual page for tauruspanel 4.4.0
-.SH SYNOPSIS
-.B tauruspanel
-[\fI\,options\/\fR] [\fI\,devname\/\fR]
-.SH DESCRIPTION
-Taurus Application inspired in Jive and Atk Panel
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurusplot.1 b/doc/man/taurusplot.1
deleted file mode 100644
index fb2e1ad4..00000000
--- a/doc/man/taurusplot.1
+++ /dev/null
@@ -1,60 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSPLOT "1" "July 2018" "taurusplot 4.4.0" "User Commands"
-.SH NAME
-taurusplot \- manual page for taurusplot 4.4.0
-.SH SYNOPSIS
-.B taurusplot
-[\fI\,options\/\fR] [\fI\,<model1> \/\fR[\fI\,<model2>\/\fR] ...]
-.SH DESCRIPTION
-a taurus application for plotting 1D data sets
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-x\fR t|n, \fB\-\-x\-axis\-mode\fR=\fI\,t\/\fR|n
-interprete X values as either timestamps (t) or
-numbers (n). Accepted values: t|n (e is also accepted
-as a synonim of n)
-.TP
-\fB\-\-config\fR=\fI\,CONFIG_FILE\/\fR, \fB\-\-config\-file\fR=\fI\,CONFIG_FILE\/\fR
-use the given config file for initialization
-.TP
-\fB\-\-import\-ascii\fR=\fI\,IMPORT_ASCII\/\fR
-import the given ascii file into the plot
-.TP
-\fB\-\-export\fR=\fI\,EXPORT_FILE\/\fR, \fB\-\-export\-file\fR=\fI\,EXPORT_FILE\/\fR
-use the given file to as output instead of showing the
-plot
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurustestsuite.1 b/doc/man/taurustestsuite.1
deleted file mode 100644
index fac013af..00000000
--- a/doc/man/taurustestsuite.1
+++ /dev/null
@@ -1,24 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSTESTSUITE "1" "July 2018" "taurustestsuite 4.4.0" "User Commands"
-.SH NAME
-taurustestsuite \- manual page for taurustestsuite 4.4.0
-.SH DESCRIPTION
-usage: taurustestsuite [\-h] [\-\-skip\-gui\-tests] [\-e EXCLUDE_PATTERN]
-.IP
-[\-\-version]
-.PP
-Main test suite for Taurus
-.SS "optional arguments:"
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-\-skip\-gui\-tests\fR
-Do not perform tests requiring GUI
-.TP
-\fB\-e\fR EXCLUDE_PATTERN, \fB\-\-exclude\-pattern\fR EXCLUDE_PATTERN
-regexp pattern matching test ids to be excluded. (e.g.
-\&'taurus\e.core\e..*' would exclude taurus.core tests)
-.TP
-\fB\-\-version\fR
-show program's version number and exit
diff --git a/doc/man/taurustrend.1 b/doc/man/taurustrend.1
deleted file mode 100644
index e5e581a2..00000000
--- a/doc/man/taurustrend.1
+++ /dev/null
@@ -1,67 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSTREND "1" "July 2018" "taurustrend 4.4.0" "User Commands"
-.SH NAME
-taurustrend \- manual page for taurustrend 4.4.0
-.SH SYNOPSIS
-.B taurustrend
-[\fI\,options\/\fR] [\fI\,<model1> \/\fR[\fI\,<model2>\/\fR] ...]
-.SH DESCRIPTION
-a taurus application for plotting trends
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-x\fR t|e, \fB\-\-x\-axis\-mode\fR=\fI\,t\/\fR|e
-interprete X values as either timestamps (t) or event
-numbers (e). Accepted values: t|e
-.TP
-\fB\-b\fR MAX_BUFFER_SIZE, \fB\-\-buffer\fR=\fI\,MAX_BUFFER_SIZE\/\fR
-maximum number of values per curve to be plotted
-(default = 65536) (when reached, the oldest values
-will be discarded)
-.TP
-\fB\-\-config\fR=\fI\,CONFIG_FILE\/\fR, \fB\-\-config\-file\fR=\fI\,CONFIG_FILE\/\fR
-use the given config file for initialization
-.TP
-\fB\-\-export\fR=\fI\,EXPORT_FILE\/\fR, \fB\-\-export\-file\fR=\fI\,EXPORT_FILE\/\fR
-use the given file to as output instead of showing the
-plot
-.TP
-\fB\-r\fR MILLISECONDS, \fB\-\-forced\-read\fR=\fI\,MILLISECONDS\/\fR
-force Taurustrend to re\-read the attributes every
-MILLISECONDS ms
-.HP
-\fB\-a\fR, \fB\-\-use\-archiving\fR
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurustrend1d.1 b/doc/man/taurustrend1d.1
deleted file mode 100644
index 32c30ac7..00000000
--- a/doc/man/taurustrend1d.1
+++ /dev/null
@@ -1,58 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSTREND1D "1" "July 2018" "taurustrend1d 4.4.0" "User Commands"
-.SH NAME
-taurustrend1d \- manual page for taurustrend1d 4.4.0
-.SH SYNOPSIS
-.B taurustrend1d
-[\fI\,options\/\fR] \fI\,<model>\/\fR
-.SH DESCRIPTION
-a Taurus application for plotting trends of scalars
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-x\fR t|d|e, \fB\-\-x\-axis\-mode\fR=\fI\,t\/\fR|d|e
-interpret X values as timestamps (t), time deltas (d)
-or event numbers (e). Accepted values: t|d|e
-.TP
-\fB\-b\fR MAX_BUFFER_SIZE, \fB\-\-buffer\fR=\fI\,MAX_BUFFER_SIZE\/\fR
-maximum number of values to be plotted (when reached,
-the oldest values will be discarded)
-.HP
-\fB\-a\fR, \fB\-\-use\-archiving\fR
-.TP
-\fB\-\-demo\fR
-show a demo of the widget
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/man/taurustrend2d.1 b/doc/man/taurustrend2d.1
deleted file mode 100644
index fa4f224b..00000000
--- a/doc/man/taurustrend2d.1
+++ /dev/null
@@ -1,58 +0,0 @@
-.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4.
-.TH TAURUSTREND2D "1" "July 2018" "taurustrend2d 4.4.0" "User Commands"
-.SH NAME
-taurustrend2d \- manual page for taurustrend2d 4.4.0
-.SH SYNOPSIS
-.B taurustrend2d
-[\fI\,options\/\fR] \fI\,<model>\/\fR
-.SH DESCRIPTION
-a Taurus application for plotting trends of arrays (aka "spectrograms")
-.SH OPTIONS
-.TP
-\fB\-h\fR, \fB\-\-help\fR
-show this help message and exit
-.TP
-\fB\-x\fR t|d|e, \fB\-\-x\-axis\-mode\fR=\fI\,t\/\fR|d|e
-interpret X values as timestamps (t), time deltas (d)
-or event numbers (e). Accepted values: t|d|e
-.TP
-\fB\-b\fR MAX_BUFFER_SIZE, \fB\-\-buffer\fR=\fI\,MAX_BUFFER_SIZE\/\fR
-maximum number of values to be stacked (when reached,
-the oldest values will be discarded)
-.HP
-\fB\-a\fR, \fB\-\-use\-archiving\fR
-.TP
-\fB\-\-demo\fR
-show a demo of the widget
-.TP
-\fB\-\-window\-name\fR=\fI\,WINDOW_NAME\/\fR
-Name of the window
-.TP
-\fB\-\-version\fR
-show program's version number and exit
-.IP
-Taurus Options:
-.IP
-Basic options present in any taurus application
-.TP
-\fB\-\-taurus\-log\-level\fR=\fI\,LEVEL\/\fR
-taurus log level. Allowed values are (case
-insensitive): critical, error, warning/warn, info,
-debug, trace
-.TP
-\fB\-\-taurus\-polling\-period\fR=\fI\,MILLISEC\/\fR
-taurus global polling period in milliseconds
-.TP
-\fB\-\-taurus\-serialization\-mode\fR=\fI\,SERIAL\/\fR
-taurus serialization mode. Allowed values are (case
-insensitive): serial, concurrent (default)
-.TP
-\fB\-\-tango\-host\fR=\fI\,TANGO_HOST\/\fR
-Tango host name (either HOST:PORT or a Taurus URI,
-e.g. tango://foo:1234)
-.TP
-\fB\-\-remote\-console\-port\fR=\fI\,PORT\/\fR
-enables remote debugging using the given port
-.TP
-\fB\-\-default\-formatter\fR=\fI\,FORMATTER\/\fR
-Override the default formatter
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 63d63c0e..5384947e 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -56,7 +56,8 @@ def _build_doc_api():
auto_rst4api = imp.load_module(name, *data)
API_Creator = auto_rst4api.Auto_rst4API_Creator
# prepare api creator
- excl = ['_[^\.]*[^_]',
+ excl = ['.*\._[^\.]+[^_]', # exclude private objects
+ '.*\.(object|zip|str)', # avoid warnings from builtins
'.*\.test',
'taurus\.external',
'taurus\.qt\.qtgui\.extra_sardana',
@@ -64,11 +65,11 @@ def _build_doc_api():
'taurus\.qt\.qtgui\.extra_macroexecutor',
'taurus\.qt\.qtgui\.resource',
'taurus\.qt\.qtgui\.taurusgui\.conf',
+ 'taurus\.qt\.qtgui\.qwt5\.taurusplotconf', # Under Construction
]
if sys.version_info.major > 2:
excl += [
'taurus\.qt\.qtgui\.qwt5', # qwt5 not available in PY3
- '.*\.(object|zip|str)', # avoid warnings from builtins
]
rstCreator = API_Creator(exclude_patterns=excl,
@@ -298,8 +299,8 @@ inheritance_graph_attrs = dict(rankdir="UD", ratio='compress')
intersphinx_mapping = {
'python': ('https://docs.python.org/dev', None),
- 'numpy': ('http://www.numpy.org', None),
+ 'numpy': ('https://numpy.org', 'numpy.inv'), # work around err 403
'sardana': ('https://sardana-controls.org', None),
- 'pint': ('http://pint.readthedocs.io/en/stable/', None),
- 'PyTango': ('http://pytango.readthedocs.io/en/stable/', None),
+ 'pint': ('https://pint.readthedocs.io/en/stable/', None),
+ 'PyTango': ('https://pytango.readthedocs.io/en/stable/', None),
}
diff --git a/doc/source/devel/coding_guide.rst b/doc/source/devel/coding_guide.rst
index a6b477d3..67ad6e29 100644
--- a/doc/source/devel/coding_guide.rst
+++ b/doc/source/devel/coding_guide.rst
@@ -130,6 +130,20 @@ PyQt4, PyQt5 and PySide versions.
from taurus.external.qt import QtWebKit
from taurus.external.qt import Qwt5
+.. note:: this guideline applies to code which is part of the taurus module or its
+ plugins. For end-user applications that use taurus, this rule may not apply,
+ as mentioned in `TEP18`_:
+
+ *For an end-user application based on taurus* it is probably better to import
+ directly from a specific binding (PyQt5 is the best supported) and let taurus to
+ adapt to that choice. In this way, one can write idiomatic code that better
+ matches the chosen binding. Using the ``taurus.external.qt`` shim
+ is also possible if one wants to make the code binding-agnostic, but in that
+ case one must keep in mind that the resulting code will be less idiomatic
+ and that the shim's API may be eventually altered to better fit with taurus
+ own requirements (and that those changes may not be aligned with the
+ application needs).
+
2. Since Taurus v>=4.0, Qt-based code in Taurus assumes
that `PyQt API v2`_ is used. PyQt API 1 code is not accepted in taurus.
@@ -208,4 +222,5 @@ PyQt4, PyQt5 and PySide versions.
.. _LGPL: http://www.gnu.org/licenses/lgpl.html
.. _`PyQt API v2`: http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html
.. _`new-style signals`: http://pyqt.sourceforge.net/Docs/PyQt4/new_style_signals_slots.html
-.. _future: https://python-future.org/ \ No newline at end of file
+.. _future: https://python-future.org/
+.. _TEP18: http://taurus-scada.org/tep/?TEP18.md
diff --git a/doc/source/devel/designer_tutorial.rst b/doc/source/devel/designer_tutorial.rst
index 1443543c..aae60de9 100644
--- a/doc/source/devel/designer_tutorial.rst
+++ b/doc/source/devel/designer_tutorial.rst
@@ -6,13 +6,13 @@ Taurus Qt Designer tutorial
Taurus widgets behave just as any other Qt widget, and as such, they can be used
to create GUIs in a regular way, both programmatically or using the Qt designer.
-For convenience, Taurus provides the `taurusdesigner` command that launches the
+For convenience, Taurus provides the `taurus designer` command that launches the
standard Qt designer application extended to show also the widgets provided by
Taurus.
To launch it, just execute::
- taurusdesigner
+ taurus designer
.. tip::
diff --git a/doc/source/devel/examples.rst b/doc/source/devel/examples.rst
index 31bfed96..aee0542e 100644
--- a/doc/source/devel/examples.rst
+++ b/doc/source/devel/examples.rst
@@ -49,7 +49,7 @@ header::
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
@@ -79,7 +79,7 @@ code::
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None,)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
@@ -369,7 +369,7 @@ feature-rich and very configurable GUIs by using existing widgets as "panels".
TaurusGuis can be created via a wizard application (no programming at all!) with
a few clicks. You can try it out by running::
- taurusgui --new-gui
+ taurus newgui
For more details and tricks regarding TaurusGui, check :ref:`this <taurusgui_newgui>`.
diff --git a/doc/source/devel/examples/edit01.py b/doc/source/devel/examples/edit01.py
index d3d35e31..57d76848 100644
--- a/doc/source/devel/examples/edit01.py
+++ b/doc/source/devel/examples/edit01.py
@@ -2,7 +2,7 @@ import sys
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/edit02.py b/doc/source/devel/examples/edit02.py
index cb960cf6..6be264b6 100644
--- a/doc/source/devel/examples/edit02.py
+++ b/doc/source/devel/examples/edit02.py
@@ -5,7 +5,7 @@ from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.input import TaurusValueSpinBox
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = TaurusWidget()
layout = Qt.QHBoxLayout()
diff --git a/doc/source/devel/examples/edit03.py b/doc/source/devel/examples/edit03.py
index a9776390..f5011381 100644
--- a/doc/source/devel/examples/edit03.py
+++ b/doc/source/devel/examples/edit03.py
@@ -5,7 +5,7 @@ from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.input import TaurusWheelEdit
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = TaurusWidget()
layout = Qt.QHBoxLayout()
diff --git a/doc/source/devel/examples/forms01.py b/doc/source/devel/examples/forms01.py
index a62aabfc..4cb82416 100644
--- a/doc/source/devel/examples/forms01.py
+++ b/doc/source/devel/examples/forms01.py
@@ -2,7 +2,7 @@ import sys
from taurus.qt.qtgui.panel import TaurusForm
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = TaurusForm()
props = ['state', 'status', 'position', 'velocity', 'acceleration']
diff --git a/doc/source/devel/examples/forms02.py b/doc/source/devel/examples/forms02.py
index 3dd1a7fe..67c6cfe5 100644
--- a/doc/source/devel/examples/forms02.py
+++ b/doc/source/devel/examples/forms02.py
@@ -3,7 +3,7 @@ from taurus.qt.qtgui.panel import TaurusForm
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = TaurusForm()
props = ['state', 'status', 'position', 'velocity', 'acceleration']
diff --git a/doc/source/devel/examples/label01.py b/doc/source/devel/examples/label01.py
index cda00694..5fb71424 100644
--- a/doc/source/devel/examples/label01.py
+++ b/doc/source/devel/examples/label01.py
@@ -2,7 +2,7 @@ import sys
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/label02.py b/doc/source/devel/examples/label02.py
index f3a5e79c..1339763d 100644
--- a/doc/source/devel/examples/label02.py
+++ b/doc/source/devel/examples/label02.py
@@ -2,7 +2,7 @@ import sys
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/label03.py b/doc/source/devel/examples/label03.py
index ef3655f3..0f25a64d 100644
--- a/doc/source/devel/examples/label03.py
+++ b/doc/source/devel/examples/label03.py
@@ -2,7 +2,7 @@ import sys
from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QHBoxLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/label04.py b/doc/source/devel/examples/label04.py
index cfa5d8f3..1c3c61fe 100644
--- a/doc/source/devel/examples/label04.py
+++ b/doc/source/devel/examples/label04.py
@@ -4,7 +4,7 @@ from taurus.qt.qtgui.container import TaurusWidget
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = TaurusWidget()
layout = Qt.QVBoxLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/label05.py b/doc/source/devel/examples/label05.py
index febd388e..143a9975 100644
--- a/doc/source/devel/examples/label05.py
+++ b/doc/source/devel/examples/label05.py
@@ -3,7 +3,7 @@ from taurus.external.qt import Qt
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
w = TaurusLabel(panel)
w.setModel('sys/taurustest/1/state')
diff --git a/doc/source/devel/examples/label06.py b/doc/source/devel/examples/label06.py
index 0dfbe2a0..b3ca726e 100644
--- a/doc/source/devel/examples/label06.py
+++ b/doc/source/devel/examples/label06.py
@@ -3,7 +3,7 @@ from taurus.external.qt import Qt
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QGridLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/examples/parentmodel_issue_demo.py b/doc/source/devel/examples/parentmodel_issue_demo.py
index 364daaac..bd8c54ca 100644
--- a/doc/source/devel/examples/parentmodel_issue_demo.py
+++ b/doc/source/devel/examples/parentmodel_issue_demo.py
@@ -15,7 +15,7 @@ from taurus.qt.qtgui.display import TaurusLabel
import sys
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
# The problem arises in some situations when the Taurus parenting is not the same
# as the Qt parenting. For demonstration we use 3 widgets:
diff --git a/doc/source/devel/examples/taurusplot01.py b/doc/source/devel/examples/taurusplot01.py
index 0ec508e1..3fa3b759 100644
--- a/doc/source/devel/examples/taurusplot01.py
+++ b/doc/source/devel/examples/taurusplot01.py
@@ -4,7 +4,7 @@ import sys
from taurus.qt.qtgui.plot import TaurusPlot
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
##########################
# BEGUIN EXAMPLE CODE
##########################
diff --git a/doc/source/devel/examples/taurusplot02.py b/doc/source/devel/examples/taurusplot02.py
index c065bfc7..173bf2a6 100644
--- a/doc/source/devel/examples/taurusplot02.py
+++ b/doc/source/devel/examples/taurusplot02.py
@@ -4,7 +4,7 @@ import sys
from taurus.qt.qtgui.plot import TaurusPlot
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
##########################
# BEGUIN EXAMPLE CODE
##########################
diff --git a/doc/source/devel/examples/taurusplot03.py b/doc/source/devel/examples/taurusplot03.py
index 55966be2..41559b61 100644
--- a/doc/source/devel/examples/taurusplot03.py
+++ b/doc/source/devel/examples/taurusplot03.py
@@ -4,7 +4,7 @@ import sys
from taurus.external.qt import Qt
from taurus.qt.qtgui.plot import TaurusPlot, CurveAppearanceProperties
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
##########################
# BEGIN EXAMPLE CODE
##########################
diff --git a/doc/source/devel/examples/taurustrend01.py b/doc/source/devel/examples/taurustrend01.py
index fcdd011d..db6b447b 100644
--- a/doc/source/devel/examples/taurustrend01.py
+++ b/doc/source/devel/examples/taurustrend01.py
@@ -4,7 +4,7 @@ import sys
from taurus.qt.qtgui.plot import TaurusTrend
from taurus.qt.qtgui.application import TaurusApplication
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
##########################
# BEGIN EXAMPLE CODE
##########################
diff --git a/doc/source/devel/examples/taurusvalue01.py b/doc/source/devel/examples/taurusvalue01.py
index c2cbc9a4..bc274378 100644
--- a/doc/source/devel/examples/taurusvalue01.py
+++ b/doc/source/devel/examples/taurusvalue01.py
@@ -3,7 +3,7 @@ from taurus.external.qt import Qt
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.panel import TaurusValue
-app = TaurusApplication(sys.argv)
+app = TaurusApplication(sys.argv, cmd_line_parser=None)
panel = Qt.QWidget()
layout = Qt.QGridLayout()
panel.setLayout(layout)
diff --git a/doc/source/devel/icon_example.py b/doc/source/devel/icon_example.py
index e6ed4b1d..f594b442 100644
--- a/doc/source/devel/icon_example.py
+++ b/doc/source/devel/icon_example.py
@@ -23,7 +23,7 @@ class MyGUI(Qt.QMainWindow):
if __name__ == "__main__":
import sys
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
gui = MyGUI()
gui.show()
sys.exit(app.exec_())
diff --git a/doc/source/devel/icon_guide.rst b/doc/source/devel/icon_guide.rst
index c7c0c6c6..446b34de 100644
--- a/doc/source/devel/icon_guide.rst
+++ b/doc/source/devel/icon_guide.rst
@@ -32,7 +32,7 @@ Taurus icon catalog
-------------------
In order to explore the icon collections provided by Taurus, you can use the
-`taurusiconcatalog` application, which will let you browse the icons.
+`taurus icons` application, which will let you browse the icons.
.. figure:: /_static/taurusiconcatalog-01.png
:align: center
diff --git a/doc/source/devel/taurus3to4.rst b/doc/source/devel/taurus3to4.rst
index 46fdb5e6..21fbe704 100644
--- a/doc/source/devel/taurus3to4.rst
+++ b/doc/source/devel/taurus3to4.rst
@@ -4,22 +4,262 @@
Taurus 3.x to 4.x migration guide
==================================
-This chapter explains how to migrate from an application written using Taurus 3.x
-to Taurus 4.x.
+Taurus 4 was released in July 2016 with the main goal of making Taurus scheme-agnostic
+(i.e. not relying on Tango for its core functionalities).
-.. todo::
- This section needs to be expanded. **Help wanted!**.
- In the meanwhile, the following documents may be useful:
+Being a major version change,
+it is not fully backwards-compatible with the previous taurus 3.x versions.
- - TEP3_
- - TEP14_
- - `Taurus 4 API changes`_
- - `Taurus 4 slides`_
+However, a design goal for the 4.x series was to smooth the transition from 3.x as much
+as possible, and a backwards-compatibility layer which will mark old taurus code as
+deprecated but otherwise attempt to transparently support it in Taurus4 whenever that
+is possible.
+
+Thanks to this compatibility layer, a Taurus 3 application is likely to run on taurus 4
+after minimal or even no changes (but typically producing deprecation warnings and
+possibly with some functionality slightly altered).
+
+A good strategy for migrating a taurus 3 application or widget to taurus 4 is to attempt
+to run it as-is with taurus 4 and then try to remove any deprecation warnings one by one.
+Most changes will be related to one of the following:
+
+- renamed methods and APIs (see the *API changes* section below),
+- differences between Tango states and Taurus states (see the *Working with States* section below)
+- Use of quantities for values (see the *Working with quantities* section below)
+
+
+.. note::
+ The main sources of information regarding the changes introduced in
+ Taurus 4 are the following two Enhancement proposals:
+
+ - TEP3_
+ - TEP14_
+
+ These changes are also treated in the `Taurus 4 slides`_
+
+
+API Changes
+------------
+
+The following is a table of Taurus 3.x public members (classes, methods, attributes, etc) that became deprecated in Taurus 4
+
+This list is a best-effort to document changes, but it may not be 100% complete (please feel free to suggest changes)
+
+**IMPORTANT**: in some cases, the proposed alternative can be used as a drop-in replacement of the deprecated code, but in some others the code may need some adaptation.
+
++-----------------------------------------------+---------------------------------------------------------------+
+| Member | Alternative(s) |
++===============================================+===============================================================+
+| TaurusConfigValue | TaurusAttribute / TaurusAttrValue |
++-----------------------------------------------+---------------------------------------------------------------+
+| TaurusConfigurationProxy | TaurusAttribute |
++-----------------------------------------------+---------------------------------------------------------------+
+| TaurusConfiguration | TaurusAttribute |
++-----------------------------------------------+---------------------------------------------------------------+
+| Configuration (helper) | Attribute (helper) |
++-----------------------------------------------+---------------------------------------------------------------+
+| Database (helper) | Authority (helper) |
++-----------------------------------------------+---------------------------------------------------------------+
+| TaurusManager.{g,s}etOperationMode | -- |
++-----------------------------------------------+---------------------------------------------------------------+
++-----------------------------------------------+---------------------------------------------------------------+
+| xxxAttrValue.<foo> | |
+| *(where <foo> is any config option)* | xxxAttribute.<foo> |
++-----------------------------------------------+---------------------------------------------------------------+
+| xxxAttribute.value | xxxAttribute.rvalue |
++-----------------------------------------------+---------------------------------------------------------------+
+| xxxAttribute.w_value | xxxAttribute.wvalue |
++-----------------------------------------------+---------------------------------------------------------------+
+| xxxAttribute.has_failed | xxxAttribute.error |
++-----------------------------------------------+---------------------------------------------------------------+
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.{g,s}etDescription | TangoAttribute.description |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.isInformDeviceOfErrors | -- |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.displayValue | str |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getDisplayValue | TangoAttribute.getLabel |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getDisplayUnit | TangoAttribute.rvalue.units |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getStandardUnit | TangoAttribute.rvalue.units |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getUnit | TangoAttribute.rvalue.units |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.unit | TangoAttribute.rvalue.units |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getDisplayWriteValue | -- |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getWritable | TangoAttribute.isWritable |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.is{Scalar,Spectrum,Image} | TangoAttribute.data_format |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMaxDim{X,Y} | TangoAttribute.getMaxDim |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getShape | *introspect the value shape if applicable* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getParam | TangoAttribute.getAttributeInfoEx |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.setParam | *use PyTango* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getConfig | self *(merged)* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getCRanges | TangoAttribute .range + .alarms + .warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getCLimits | TangoAttribute.range |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMinValue | TangoAttribute.range |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMaxValue | TangoAttribute.range |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.climits | TangoAttribute.range |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getCAlarms | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMinAlarm | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMaxAlarm | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.min_alarm | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.max_alarm | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.calarms | TangoAttribute.alarms |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getCWarnings | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMinWarning | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.getMaxWarning | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.min_warning | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.max_warning | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAttribute.cwarnings | TangoAttribute.warnings |
++-----------------------------------------------+---------------------------------------------------------------+
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getState | TangoDevice.stateObj.read().rvalue *tango* or |
+| | .state *agnostic* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getStateObj | TangoDevice.stateObj *tango* or |
+| | .factory.getAttribute(state_full_name) *agnostic* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getSWState | TangoDevice.state |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getValueObj | TangoDevice.state *agnostic or* stateObj.read *tango* |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getDisplayValue | TangoDevice.state().name |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getHWObj | TangoDevice.getDeviceProxy |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.isValidDev | (TangoDevice.getDeviceProxy() is not None) |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.getDescription | TangoDevice.description |
++-----------------------------------------------+---------------------------------------------------------------+
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDatabase | TangoAuthority |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAuthority.getHWObj | TangoAuthority.getDeviceProxy |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAuthority.getValueObj | TangoAuthority.getTangoDB |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAuthority.getDisplayValue | TangoAuthority.getFullName |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoAuthority.getDescription | TangoAuthority.description |
++-----------------------------------------------+---------------------------------------------------------------+
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoFactory.getAttributeInfo | TangoFactory.getAttribute |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoFactory.getConfiguration | TangoFactory.getAttribute |
++-----------------------------------------------+---------------------------------------------------------------+
+| TangoDevice.{g,s}etOperationMode | -- |
++-----------------------------------------------+---------------------------------------------------------------+
+
+
+Working with quantities
+------------------------
+
+One of the most visible changes in Taurus 4 is its use of quantities for the values
+of numeric attributes.
+
+In Taurus 4 all the values of numeric (float or integer) attributes and their associated
+properties (such as limits, warning levels, etc.) are :class:`pint.Quantity` objects provided
+by the :mod:`pint` python module. A Quantity is essentially the combination of a `magnitude`
+and a `unit`. In taurus 3.x all values were just "magnitudes", and their units were either
+implicit or loosely described as a free string property, but not enforced in any way.
+
+By using Quantities Taurus 4 can automatically verify the dimensional validity of
+operations and provide support for I/O using user-preferred units.
+
+Taurus 3 applications use `.value` or `.w_value` to get the read or write
+magnitude of a taurus value, respectively. In taurus 4 these would be equivalent
+to `.rvalue.magnitude` and `.wvalue.magnitude`, but the recommended way to adapt
+a Taurus 3 application is to use the Quantity objects, not their magnitudes
+(i.e., `rvalue` and `wvalue`) and refactor the code if necessary.
+
+For example, given the following taurus 3 code **where we assume that ampli is in meters**::
+
+ v = taurus.Attribute('sys/tg_test/1/ampli').read()
+ foo = 5 + v.value # here "5" is implicitly assumed to mean "5 meters"
+
+a lazy conversion to avoid deprecation warnings in taurus 4 would be::
+
+ v = taurus.Attribute('sys/tg_test/1/ampli').read()
+ foo = 5 + v.rvalue.magnitude
+
+...which is a very direct translation (and exactly what the automated backwards
+compatibility layer already does for you). However, the recommended
+conversion should use Quantities rather than magnitudes, e.g::
+
+ from taurus.core.units import UR # import the taurus unit registry
+ v = taurus.Attribute('sys/tg_test/1/ampli').read()
+ foo = 5 * UR.meters + v.value # use explicit units
+
+Or, using the Quantity constructor instead of the `Unit Registry`::
+
+ from taurus.core.units import Q_ # import the taurus Quantity factory
+ v = taurus.Attribute('sys/tg_test/1/ampli').read()
+ foo = Q_("5 meters") + v.value
+
+Finally, note that when using Quantities, you do not need to care about
+matching the units, as long as they are dimensionally compatible::
+
+ foo = Q_("15 feet") + v.value
+
+
+Working with Device states
+--------------------------
+
+Taurus 4 is all about being "scheme-agnostic". This means that the taurus core
+(and ideally the main widgets as well) should not assume that the model objects
+(attributes, devices, authorities) are of one specific source type (Tango, Epics,
+Evaluation...)
+
+This implies that the APIs should be scheme-agnostic. In Taurus 3, the concept
+of *device state* is completely "tango-centric" and it has been replaced in
+Taurus 4 by a much more generic one where the devices are either "ready" or "not
+ready" (this is of course much less informative, but it is generic enough to
+accomodate schemes where the sources of data may not even be hardware-related).
+
+In Taurus 4, the Taurus device states are defined in the
+`taurus.core.TaurusDevState` enumeration, and the tango device states are
+supported by the tango scheme in `taurus.core.tango.DevState` enumeration, which
+is a numerically-compatible translation of `PyTango.DevState`
+
+Some taurus 3.x applications may implement logic that depends on Tango states,
+or maybe display information based on the rich palette of Tango state colors.
+In these cases, when converting the application to Taurus 4 one needs to decide
+if the simple Taurus states are enough (in which case one should refactor the
+logic and use `device.state` to get the *Taurus* device state) or if the richer
+tango states are required to the point of sacrificing the scheme-agnosticism of
+the application (in which case one can use `device.stateObj.read().rvalue` to
+obtain the *Tango* device state)
.. _TEP3: http://sf.net/p/tauruslib/wiki/TEP3
.. _TEP14: http://sf.net/p/tauruslib/wiki/TEP14
-.. _`Taurus 4 API changes`: http://sf.net/p/tauruslib/wiki/Taurus4-API_changes
-.. _`Taurus 4 slides`: https://indico.esrf.fr/indico/event/4/session/6/contribution/17/material/slides/ \ No newline at end of file
+.. _`Taurus 4 slides`: https://indico.esrf.fr/indico/event/4/session/6/contribution/17/material/slides/
diff --git a/doc/source/devel/taurusgui_newgui.rst b/doc/source/devel/taurusgui_newgui.rst
index b76fdf99..2e72f206 100644
--- a/doc/source/devel/taurusgui_newgui.rst
+++ b/doc/source/devel/taurusgui_newgui.rst
@@ -7,7 +7,7 @@ Creating GUIs with the TaurusGUI framework
The easiest way to create a new GUI using Taurus is by invoking::
- taurusgui --new-gui
+ taurus newgui
This shows a "wizard" application that will guide you through
the process of creating a :class:`TaurusGui`-based GUI in a few minutes
@@ -41,7 +41,7 @@ more advanced control can be exerted at several levels:
- First, it is possible to edit the configuration files that define a
TaurusGUI-based application. These are declarative python and XML files
(editable as plain text) complemented by Qt settings files (editable with
- the provided :ref:`taurusconfigbrowser <configurations>` application).
+ the provided :ref:`taurus config <configurations>` application).
- On a lower level, custom specific widgets (created either programmatically, as in
the :ref:`examples` or via the :ref:`Qt designer <taurusqtdesigner-tutorial>`)
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 460ffce3..460ffce3 100755..100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
diff --git a/doc/source/numpy.inv b/doc/source/numpy.inv
new file mode 100644
index 00000000..8cb1f0a0
--- /dev/null
+++ b/doc/source/numpy.inv
@@ -0,0 +1,5 @@
+# Sphinx inventory version 2
+# Project: NumPy
+# Version:
+# The remainder of this file is compressed using zlib.
+xÚuŽË‚0D÷ýŠ&ºÅÄ­;ãÊ…J¢{R{¯@ìƒPšÈß ´…ÖǪÍÌœ;õ”VÕ]OM;Ðœf[ʃ¸©:)è­Bz¶2ïƒp­Àò.¥&É1.ЀT?†w²J°;ŠOnµþC–¨jøJÑ ºÎãø%KÌïŠÓm"jŽÊ`œñR¼ÝKIz.Žóóæ@H ?¶6} WsÒ`úÕZ@ÁÚ–õEÃø“•hâyß®;q€-ÝͽC ²–Wi¹Ótu~>„É>ç´î \ No newline at end of file
diff --git a/doc/source/tep/TEP14.md b/doc/source/tep/TEP14.md
index d5713ec5..80d0ba9d 100644
--- a/doc/source/tep/TEP14.md
+++ b/doc/source/tep/TEP14.md
@@ -158,7 +158,7 @@ Summary of API changes
The deprecations introduced by this proposal can be identified in the code by the use of the `@tep14_deprecation` decorator and the calls to the `deprecated` function with the `rel='tep14'` argument.
-The [Taurus4-API_changes](https://sourceforge.net/p/tauruslib/wiki/Taurus4-API_changes/) document is an attempt to explicitly list all the changes (it is not considered part of this TEP because it is likely to be modified to include more comments or missing changes)
+The [Taurus4-API_changes](http://taurus-scada.org/devel/taurus3to4.html#api-changes) document is an attempt to explicitly list all the changes (it is not considered part of this TEP because it is likely to be modified to include more comments or missing changes)
Links to more details and discussions
@@ -215,18 +215,21 @@ Changes
2015-04-28
-[cpascual](http://sf.net/u/cpascual/) First draft based on parts moved from [TEP3][] and previous discussions with [tiagocoutinho](http://sf.net/u/tiagocoutinho/), [cfalcon](https://sf.net/u/cmft/) and [zreszela](http://sf.net/u/zreszela/)
+[cpascual](https://github.com/cpascual/) First draft based on parts moved from [TEP3][] and previous discussions with [tiagocoutinho](http://sf.net/u/tiagocoutinho/), [cfalcon](https://sf.net/u/cmft/) and [zreszela](http://sf.net/u/zreszela/)
2015-11-23
-[cpascual](http://sf.net/u/cpascual/) Implementation proposal uploaded to taurus4-preview branch of official repo
+[cpascual](https://github.com/cpascual/) Implementation proposal uploaded to taurus4-preview branch of official repo
2016-03-11
-[cpascual](http://sf.net/u/cpascual/) Completed missing sections, rewritted existing ones and passed to CANDIDATE
+[cpascual](https://github.com/cpascual/) Completed missing sections, rewritted existing ones and passed to CANDIDATE
2016-03-16
-[cpascual](http://sf.net/u/cpascual/) Passing to ACCEPTED
+[cpascual](https://github.com/cpascual/) Passing to ACCEPTED
2016-11-16
[mrosanes](https://github.com/sagiss/) Adapt TEP format and URL according TEP16
+2019-04-03
+[cpascual](https://github.com/cpascual/) Update outdated sf.net links
+
[TEP3]: http://www.taurus-scada.org/tep?TEP3.md
diff --git a/doc/source/tep/index.rst b/doc/source/tep/index.rst
index 9162ad27..9162ad27 100755..100644
--- a/doc/source/tep/index.rst
+++ b/doc/source/tep/index.rst
diff --git a/doc/source/tep/res/tep0_workflow.png b/doc/source/tep/res/tep0_workflow.png
index e8cbf8c2..e8cbf8c2 100755..100644
--- a/doc/source/tep/res/tep0_workflow.png
+++ b/doc/source/tep/res/tep0_workflow.png
Binary files differ
diff --git a/doc/source/tep/res/tep14_merge_Attr_and_Conf.png b/doc/source/tep/res/tep14_merge_Attr_and_Conf.png
index 6248caff..6248caff 100755..100644
--- a/doc/source/tep/res/tep14_merge_Attr_and_Conf.png
+++ b/doc/source/tep/res/tep14_merge_Attr_and_Conf.png
Binary files differ
diff --git a/doc/source/users/getting_started.rst b/doc/source/users/getting_started.rst
index 5570282a..8378176a 100644
--- a/doc/source/users/getting_started.rst
+++ b/doc/source/users/getting_started.rst
@@ -26,22 +26,6 @@ Note: pip is already included in python>2.7.9
Note: some "extra" features of taurus have additional dependencies_.
-Installing from sources manually (platform-independent)
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You may alternatively install from a downloaded release package:
-
-#. Download the latest sources of taurus from http://pypi.python.org/pypi/taurus
-#. Extract the downloaded source into a temporary directory and change to it
-#. run::
-
- pip install .
-
-#. test the installation::
-
- python -c "import taurus; print taurus.Release.version"
-
-Note: some "extra" features of taurus have additional dependencies_.
Linux (Debian-based)
~~~~~~~~~~~~~~~~~~~~
@@ -52,22 +36,22 @@ doing (as root)::
aptitude install python-taurus
-(see more detailed instructions in `this step-by-step howto
-<https://sourceforge.net/p/sardana/wiki/Howto-SardanaFromScratch/>`__)
+Note: `python3-taurus` and `python3-taurus-pyqtgraph` packages are already
+built in https://salsa.debian.org , but are not yet part of the official debian
+repositories
-Windows
-~~~~~~~
+Installing in a conda environment (Windows and linux)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-#. Install the `Python(x,y)`_ bundle (alternatively, you could install Python,
- PyQt_, PLY_, and other dependencies_ independently, but `Python(x,y)`_
- will save you much worries about versions).
-#. Download the latest Taurus windows binary from http://pypi.python.org/pypi/taurus
-#. Run the installation executable
-#. test the installation::
+First create a Conda_ environment with all the dependencies and activate it::
- C:\Python27\python -c "import taurus; print taurus.Release.version"
+ conda config --add channels conda-forge
+ conda config --add channels tango-controls # for windows, use "tcoutinho" instead of "tango-controls"
+ conda create -n py3qt5 python=3 pyqt=5 itango pytango lxml future guidata guiqwt ipython pillow pint ply pyqtgraph pythonqwt numpy scipy pymca
+ conda activate py3qt5
+Then install taurus and taurus_pyqtgraph using pip (as explained above)
Working from Git source directly (in develop mode)
--------------------------------------------------
@@ -75,15 +59,15 @@ Working from Git source directly (in develop mode)
If you intend to do changes to Taurus itself, or want to try the latest
developments, it is convenient to work directly from the git source in
"develop" (aka "editable") mode, so that you do not need to re-install
-on each change.
-
-You can clone taurus from our main git repository::
-
- git clone https://github.com/taurus-org/taurus.git taurus
+on each change::
-Then, to work in develop mode, just do::
+ # install taurus in develop mode
+ git clone https://github.com/taurus-org/taurus.git
+ pip install -e ./taurus # <-- Note the -e !!
- pip install -e ./taurus
+ # install taurus_pyqtgraph in develop mode
+ git clone https://github.com/taurus-org/taurus_pyqtgraph.git
+ pip install -e ./taurus_pyqtgraph # <-- Note the -e !!
.. _dependencies:
@@ -104,7 +88,7 @@ expected of Taurus (which are considered "extras"). For example:
is done with PyQt4 and PyQt5, so many features may not be
regularly tested with PySide and PySide2.
-- The :mod:`taurus.qt.qtgui.plot` module requires PyQwt_, which is
+- The :mod:`taurus.qt.qtgui.qwt5` module requires PyQwt_, which is
only available when using PyQt4 and python2. As an alternative
that supports both python2 and python3 and all the Qt bindings,
refer to the taurus_pyqtgraph_ plugin.
@@ -130,24 +114,11 @@ How you install the required dependencies depends on your preferred
installation method:
- For GNU/Linux, it is in general better to install the dependencies from
- your distribution repositories if available.
-
-- For Windows users: many of these dependencies are already satisfied
- by installing the `Python(x,y)`_ bundle. Also, most can be installed
- from PyPI_ (e.g. using pip). For some versions, PyPI may not provide
- pre-built windows binaries, so pip may try to compile from sources,
- which takes long and may not succeed without some further work. In
- those cases, one may use windows binaries from other versions and/or
- wheel packages from the Silx_WheelHouse_.
-
-- In general, you can use pip to install dependencies for a given
- extra feature (if they are in PyPI or in one of your configured
- indexes). Use::
-
- pip install taurus[NAME_OF_EXTRA]
+ your distribution repositories if available. A Conda_ environment can be
+ used alternatively (interesting for testing new features in isolation)
-- The Conda_ package management system may also be used to install
- most of the required dependencies.
+- For Windows users, the recommended option is to use a Conda_ environment
+ (see above).
- The `taurus-test Docker container`_ provides a Docker container (based
on Debian) with all the dependencies pre-installed (including Tango and
@@ -159,7 +130,6 @@ installation method:
.. _pint: http://pint.readthedocs.org/
.. _future: https://python-future.org/
.. _PLY: http://www.dabeaz.com/ply/
-.. _Python(x,y): http://python-xy.github.io/
.. _Tango: http://www.tango-controls.org/
.. _PyTango: http://pytango.readthedocs.io
.. _Qt: http://qt.nokia.com/products/
@@ -173,7 +143,6 @@ installation method:
.. _pyepics: http://pypi.python.org/pypi/pyepics
.. _spyder: http://pythonhosted.org/spyder
.. _lxml: http://lxml.de
-.. _Silx_WheelHouse: http://www.silx.org/pub/wheelhouse/
.. _PyPI: http://pypi.python.org/pypi
.. _Conda: http://conda.io/docs/
.. _taurus-test Docker container: http://hub.docker.com/r/cpascual/taurus-test/
diff --git a/doc/source/users/introduction.rst b/doc/source/users/introduction.rst
index a8526ff3..d22bcc06 100644
--- a/doc/source/users/introduction.rst
+++ b/doc/source/users/introduction.rst
@@ -47,7 +47,7 @@ four attributes (state, position, velocity, acceleration) of a Tango device
from taurus.qt.qtgui.panel import TaurusForm
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
attrs = [ 'state', 'position', 'velocity', 'acceleration' ]
model = [ 'motor/icepap/01/%s' % attr for attr in attrs ]
@@ -66,7 +66,7 @@ four attributes (state, position, velocity, acceleration) of a Tango device
The above example can even be achieved even without typing any code::
% cd taurus/qt/qtgui/panel
- % taurusform motor/icepap/01/state motor/icepap/01/position motor/icepap/01/velocity
+ % taurus form motor/icepap/01/state motor/icepap/01/position motor/icepap/01/velocity
For many more examples, See the :ref:`examples` page.
diff --git a/doc/source/users/ui/configurations.rst b/doc/source/users/ui/configurations.rst
index 8522aabf..f4e55539 100644
--- a/doc/source/users/ui/configurations.rst
+++ b/doc/source/users/ui/configurations.rst
@@ -18,14 +18,14 @@ Taurus Configuration Browser Application
----------------------------------------
You may browse the configuration of a TaurusMainWindow-based application
-(e.g. any TaurusGUI) by launching the taurusconfigbrowser application
+(e.g. any TaurusGUI) by launching the taurus config application
with the following command::
- taurusconfigbrowser [<configuration.ini>]
+ taurus config [<configuration.ini>]
Run the following command for more details::
- taurusconfigbrowser --help
+ taurus config --help
In the figure below the taurusconfigbrowser application shows a taurus
configuration .ini file containing three perspectives: 'LAST',
diff --git a/doc/source/users/ui/devpanels.rst b/doc/source/users/ui/devpanels.rst
index 0cf80e9f..77921cef 100644
--- a/doc/source/users/ui/devpanels.rst
+++ b/doc/source/users/ui/devpanels.rst
@@ -19,11 +19,11 @@ TaurusDevicePanel as a stand-alone application
The :class:`TaurusDevicePanel` can be launched as a stand-alone application with
the following command::
- taurusdevicepanel [options] [<device_name>]
+ taurus dev [options] [<device_name>]
Run the following command for more details::
- taurusdevicepanel --help
+ taurus dev --help
.. _tauruspanel:
@@ -33,10 +33,10 @@ TaurusPanel as a stand-alone application
The :class:`TaurusDevPanel` can be launched as a stand-alone application with
the following command::
- tauruspanel [options] [<device_name>]
+ taurus panel [options] [<device_name>]
Run the following command for more details::
- tauruspanel --help
+ taurus panel --help
diff --git a/doc/source/users/ui/forms.rst b/doc/source/users/ui/forms.rst
index 04702810..5b9b2a47 100644
--- a/doc/source/users/ui/forms.rst
+++ b/doc/source/users/ui/forms.rst
@@ -47,11 +47,11 @@ You may also use TaurusForm as a stand-alone application for controlling some
attributes or devices from the control system. You can launch the stand-alone TaurusForm
with the following command::
- taurusform [options] [<model_list>]
+ taurus form [options] [<model_list>]
Run the following command for more details::
- taurusform --help
+ taurus form --help
The model list is optional and is a space-separated list of models for
TaurusForm. Valid models are: attribute names, device names or alias. See
@@ -66,7 +66,7 @@ representing its attributes and/or widgets.
.. figure:: /_static/forms03.png
:align: center
- A taurusform created with the following command `taurusform sys/tg_test/1
+ A Taurus form created with the following command `taurus form sys/tg_test/1
sys/tg_test/1/state sys/tg_test/1/status sys/tg_test/1/string_scalar
sys/tg_test/1/boolean_scalar sys/tg_test/1/boolean_spectrum
sys/tg_test/1/float_scalar sys/tg_test/1/float_spectrum
diff --git a/doc/source/users/ui/plot.rst b/doc/source/users/ui/plot.rst
index 53aafe6d..5ce2a8d3 100644
--- a/doc/source/users/ui/plot.rst
+++ b/doc/source/users/ui/plot.rst
@@ -33,11 +33,11 @@ You may also use :class:`TaurusPlot` as a stand-alone application for displaying
attributes from the control system or for plotting a function. You can launch the
stand-alone :class:`TaurusPlot` with the following command::
- taurusplot [options] [<model_list>]
+ taurus qwt5 plot [options] [<model_list>]
Run the following command for more details::
- taurusplot --help
+ taurus qwt5 plot --help
The <model_list> is a space-separated list of models for :class:`TaurusPlot`. Valid models are:
SPECTRUM attribute names or alias, and `Xattrname|Yattrname` constructions for indicating X-Y scatter plots.
@@ -283,24 +283,7 @@ Here are some tips for entering valid date/time values:
the units are case-sensitive (e.g., "-1D" is not valid)
- also, the keyword "now" (case-insensitive) can be used as a synonym of
"+0s".
-
-.. _tauruscurve:
-TaurusCurveDialog
-=================
-
-Taurus also offers an alternative widget for plotting one-dimensional data:
-:class:`TaurusCurveDialog`. This widget is based on the guiqwt_ library and
-is currently less developed and tested than :class`TaurusPlot`.
-
-The :class:`TaurusCurveDialog` widget can be launched as a stand-alone
-application with the following command::
-
- tauruscurve [options] [<model_list>]
-
-Run the following command for more details::
-
- tauruscurve --help
.. references
.. _numpy: http://numpy.scipy.org/
diff --git a/doc/source/users/ui/taurusdemo.rst b/doc/source/users/ui/taurusdemo.rst
index 3f5aac9a..49bd73c2 100644
--- a/doc/source/users/ui/taurusdemo.rst
+++ b/doc/source/users/ui/taurusdemo.rst
@@ -15,15 +15,15 @@ demonstration purposes.
Taurus Demo Application
-----------------------
-taurusdemo is an application that gives an overview of some of the
+Taurus demo is an application that gives an overview of some of the
widgets available in Taurus. taurusdemo can be launched with the following
command::
- taurusdemo
+ taurus demo
Run the following command for more details::
- taurusdemo --help
+ taurus demo --help
.. figure:: /_static/taurusdemo.png
:align: center
diff --git a/doc/source/users/ui/taurusgui.rst b/doc/source/users/ui/taurusgui.rst
index e75cea59..b7f7804c 100644
--- a/doc/source/users/ui/taurusgui.rst
+++ b/doc/source/users/ui/taurusgui.rst
@@ -36,44 +36,13 @@ opposed to launching TaurusGUI directly), so you should refer to the specific
instructions for launching that GUI.
Still, you may want to launch TaurusGui directly for debugging an specific
-application or for creating a new GUI from scratch. For this, use the following
-command::
-
- taurusgui [options]
-
-Options::
-
- -h, --help show this help message and exit
- --config-dir=CONFIG_DIR
- use the given configuration directory for
- initialization
- --new-gui launch a wizard for creating a new TaurusGUI
- application
- --version show program's version number and exit
-
- Taurus Options:
- Basic options present in any taurus application
-
- --taurus-log-level=LEVEL
- taurus log level. Allowed values are (case
- insensitive): critical, error, warning/warn, info,
- debug, trace
- --taurus-polling-period=MILLISEC
- taurus global polling period in milliseconds
- --taurus-serialization-mode=SERIAL
- taurus serialization mode. Allowed values are (case
- insensitive): serial, concurrent (default)
- --tango-host=TANGO_HOST
- Tango host name
-
-
-
-.. note::
- for backwards compatibility:
- taurusgui CONFIG_DIR
-
- is equivalent to:
- taurusgui --config-dir=CONFIG_DIR
+application. For this, use the following command::
+
+ taurus gui [options]
+
+For creating a new taurusgui from scratch, use::
+
+ taurus newgui
General structure of a TaurusGUI application
@@ -305,7 +274,7 @@ Also, some other temporary panels may be dynamically created depending on the ex
- `1D Scans`, :ref:`a trend <trend_ui>` that plots the values of scalar attributes during some scan macro executions.
-.. note:: You can run `taurusgui macrogui` for seeing an example of a TaurusGUI-
+.. note:: You can run `taurus gui macrogui` for seeing an example of a TaurusGUI-
based application that provides the aforementioned panels
.. figure:: /_static/macrogui01.png
@@ -313,7 +282,7 @@ Also, some other temporary panels may be dynamically created depending on the ex
:width: 80%
Macro-related panels (taken from the macrogui example that can be launched
- with `taurusgui macrogui`)
+ with `taurus gui macrogui`)
In most specific GUIs the macroserver and door name to use are pre-configured and
the user does not need to change them. Sometimes though, you may want to alter it.
@@ -344,10 +313,10 @@ Taurus includes examples of TaurusGUI-based applications for demonstration purpo
- launch command
- Comment
* - example01
- - taurusgui example01
+ - taurus gui example01
- Included in Taurus (<taurus>/qt/qtgui/taurusgui/conf/tgconf_example01)
* - Macrogui
- - taurusgui macrogui
+ - taurus gui macrogui
- Included in Taurus (<taurus>/qt/qtgui/taurusgui/conf/tgconf_macrogui)
* - Alba's beam lines control GUIs
- ctblxx (xx is the beamline number)
diff --git a/doc/source/users/ui/taurusimage.rst b/doc/source/users/ui/taurusimage.rst
index 3bf5715b..ea859146 100644
--- a/doc/source/users/ui/taurusimage.rst
+++ b/doc/source/users/ui/taurusimage.rst
@@ -40,28 +40,8 @@ You may also use TaurusImageDialog as a stand-alone application for showing imag
attributes from the control system. You can launch the stand-alone Taurus Image
with the following command::
- taurusimage [options] <model>
-
-Options::
+ taurus guiqwt image [options] <model>
- -h, --help show this help message and exit
- --demo show a demo of the widget
- --version show program's version number and exit
+Run the following command for more details::
- Taurus Options:
- Basic options present in any taurus application
-
- --taurus-log-level=LEVEL
- taurus log level. Allowed values are (case
- insensitive): critical, error, warning/warn, info,
- debug, trace
- --taurus-polling-period=MILLISEC
- taurus global polling period in milliseconds
- --taurus-serialization-mode=SERIAL
- taurus serialization mode. Allowed values are (case
- insensitive): serial, concurrent (default)
- --tango-host=TANGO_HOST
- Tango host name
-
-
-The model is the name of a taurus image attribute \ No newline at end of file
+ taurus guiqwt image --help \ No newline at end of file
diff --git a/doc/source/users/ui/trend.rst b/doc/source/users/ui/trend.rst
index 581c4658..0fe2efc8 100644
--- a/doc/source/users/ui/trend.rst
+++ b/doc/source/users/ui/trend.rst
@@ -37,11 +37,11 @@ You may also use TaurusTrend as a stand-alone application for showing trends of
attributes from the control system. You can launch the stand-alone TaurusTrend
with the following command::
- taurustrend [options] [<model_list>]
+ taurus qwt5 trend [options] [<model_list>]
Run the following command for more details::
- taurustrend --help
+ taurus qwt5 trend --help
The model list is optional and is a space-separated list of models for TaurusTrend.
@@ -208,11 +208,11 @@ guiqwt_.
The :class:`TaurusTrend2DDialog` widget can be launched as a
stand-alone application with the following command::
- taurustrend2d <array_attribute_name>
+ taurus guiqwt trend2d <array_attribute_name>
Run the following command for more details::
- taurustrend2d --help
+ taurus guiqwt trend2d --help
.. _guiqwt: https://pypi.python.org/pypi/guiqwt
diff --git a/lib/taurus/cli/__init__.py b/lib/taurus/cli/__init__.py
new file mode 100644
index 00000000..beaad79a
--- /dev/null
+++ b/lib/taurus/cli/__init__.py
@@ -0,0 +1,40 @@
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+"""
+This module provides the taurus Command Line Interface
+
+It is based on the click module to provide CLI utilities.
+
+It defines a `taurus` command which can accept subcommands defined in
+other taurus submodules or even in plugins.
+
+To define a subcommand for taurus, you need to register it using the
+`taurus_subcommands` entry point via setuptools.
+
+.. todo:: add click link , add code snippet for plugins, etc.
+
+
+"""
+
+from .cli import main \ No newline at end of file
diff --git a/lib/taurus/cli/cli.py b/lib/taurus/cli/cli.py
new file mode 100644
index 00000000..c6bbc4bf
--- /dev/null
+++ b/lib/taurus/cli/cli.py
@@ -0,0 +1,116 @@
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+import pkg_resources
+import click
+import taurus
+
+@click.group('taurus')
+@click.option('--log-level', 'log_level',
+ type=click.Choice(['Critical', 'Error', 'Warning', 'Info',
+ 'Debug', 'Trace']),
+ default='Info', show_default=True,
+ help='Show only logs with priority LEVEL or above')
+@click.option("--polling-period", "polling_period",
+ type=click.INT, metavar="MILLISEC", default=None,
+ help='Change the Default Taurus polling period')
+@click.option("--serialization-mode", "serialization_mode",
+ type=click.Choice(['Serial', 'Concurrent', 'TangoSerial']),
+ default=None, show_default=True,
+ help=("Set the default Taurus serialization mode for those "
+ + "models that do not explicitly define it)"))
+@click.option("--rconsole", "rconsole_port", type=click.INT,
+ metavar="PORT", default=None,
+ help="Enable remote debugging with rfoo on the given PORT")
+@click.option("--default-formatter", "default_formatter",
+ type=click.STRING, metavar="FORMATTER", default=None,
+ help="Override the default formatter (use with caution!)")
+@click.version_option(version=taurus.Release.version)
+def taurus_cmd(log_level, polling_period, serialization_mode, rconsole_port,
+ default_formatter):
+ """The main taurus command"""
+
+ # set log level
+ taurus.setLogLevel(getattr(taurus, log_level))
+
+ # set polling period
+ if polling_period is not None:
+ taurus.changeDefaultPollingPeriod(polling_period)
+
+ # set serialization mode
+ if serialization_mode is not None:
+ from taurus.core.taurusbasetypes import TaurusSerializationMode
+ m = getattr(TaurusSerializationMode, serialization_mode)
+ taurus.Manager().setSerializationMode(m)
+
+ # enable the remote console port
+ if rconsole_port is not None:
+ try:
+ import rfoo.utils.rconsole
+ rfoo.utils.rconsole.spawn_server(port=rconsole_port)
+ taurus.info(("rconsole started. "
+ + "You can connect to it by typing: rconsole -p %d"),
+ rconsole_port
+ )
+ except Exception as e:
+ taurus.warning("Cannot spawn debugger. Reason: %s", e)
+
+ # set the default formatter
+ if default_formatter is not None:
+ from taurus import tauruscustomsettings
+ setattr(tauruscustomsettings, 'DEFAULT_FORMATTER', default_formatter)
+
+
+def main():
+ # set the log level to WARNING avoid spamming the CLI while loading
+ # subcommands
+ # it will be restored to the desired one first thing in taurus_cmd()
+ taurus.setLogLevel(taurus.Warning)
+
+ # Add subcommands from the taurus_subcommands entry point
+ for ep in pkg_resources.iter_entry_points('taurus.cli.subcommands'):
+ try:
+ subcommand = ep.load()
+ taurus_cmd.add_command(subcommand)
+ except Exception as e:
+ # -----------------------------------------------------------
+ # Use info instead of warning in case of nonimportable Qwt5
+ # (e.g. when using py3 or Qt5) to avoid spam
+ # This special case can be removed when taurus.qt.qtgui.qwt5
+ # is moved to a separate plugin, since the entry point will
+ # be registered only if the plugin is installed
+ if ep.name == 'qwt5':
+ taurus.info(
+ 'Cannot add "%s" subcommand to taurus. Reason: %r',
+ ep.name, e)
+ continue
+ # -----------------------------------------------------------
+ taurus.warning('Cannot add "%s" subcommand to taurus. Reason: %r',
+ ep.name, e)
+
+ # launch the taurus command
+ taurus_cmd()
+
+
+if __name__ == '__main__':
+ main() \ No newline at end of file
diff --git a/lib/taurus/core/epics/__init__.py b/lib/taurus/core/epics/__init__.py
index b39cf4a2..1f8123a8 100644
--- a/lib/taurus/core/epics/__init__.py
+++ b/lib/taurus/core/epics/__init__.py
@@ -54,11 +54,11 @@ Epics attributes (should) work just as other Taurus attributes and can be
referred by their model name wherever a Taurus Attribute model is expected. For
example, you can launch a `TaurusForm` with an epics attribute::
- $> taurusform ca:my:example
+ $> taurus form ca:my:example
Similarly, you can combine epics attributes with attributes from other schemes::
- $> taurusform 'ca:my:example' 'tango:sys/tg_test/1/float_scalar'\
+ $> taurus form 'ca:my:example' 'tango:sys/tg_test/1/float_scalar'\
'eval:{ca:my:example}*{tango:sys/tg_test/1/float_scalar}'
Currently, the taurus epics scheme just supports epics PVs, implementing them as
diff --git a/lib/taurus/core/epics/epicsattribute.py b/lib/taurus/core/epics/epicsattribute.py
index bba58f84..11680af2 100644
--- a/lib/taurus/core/epics/epicsattribute.py
+++ b/lib/taurus/core/epics/epicsattribute.py
@@ -226,14 +226,6 @@ class EpicsAttribute(TaurusAttribute):
def isUsingEvents(self):
return True # TODO: implement this
-
- def _subscribeEvents(self):
- raise NotImplementedError("Not allowed to call AbstractClass" +
- " TaurusAttribute._subscribeEvents")
-
- def _unsubscribeEvents(self):
- raise NotImplementedError("Not allowed to call AbstractClass" +
- " TaurusAttribute._unsubscribeEvents")
# ------------------------------------------------------------------------------
def factory(self):
diff --git a/lib/taurus/core/epics/test/test_epicsattribute.py b/lib/taurus/core/epics/test/test_epicsattribute.py
index 3a32c91f..3a32c91f 100755..100644
--- a/lib/taurus/core/epics/test/test_epicsattribute.py
+++ b/lib/taurus/core/epics/test/test_epicsattribute.py
diff --git a/lib/taurus/core/evaluation/evalattribute.py b/lib/taurus/core/evaluation/evalattribute.py
index f7277f2e..1e414519 100644
--- a/lib/taurus/core/evaluation/evalattribute.py
+++ b/lib/taurus/core/evaluation/evalattribute.py
@@ -445,12 +445,6 @@ class EvaluationAttribute(TaurusAttribute):
v = self.read(cache=False)
self.fireEvent(TaurusEventType.Periodic, v)
- def _subscribeEvents(self):
- pass
-
- def _unsubscribeEvents(self):
- pass
-
def isUsingEvents(self):
# if this attributes depends from others, then we consider it uses
# events
diff --git a/lib/taurus/core/evaluation/evalfactory.py b/lib/taurus/core/evaluation/evalfactory.py
index f7bd6c5c..f7bd6c5c 100755..100644
--- a/lib/taurus/core/evaluation/evalfactory.py
+++ b/lib/taurus/core/evaluation/evalfactory.py
diff --git a/lib/taurus/core/evaluation/test/res/dev_example.py b/lib/taurus/core/evaluation/test/res/dev_example.py
index cc093eb5..21ef55c7 100644
--- a/lib/taurus/core/evaluation/test/res/dev_example.py
+++ b/lib/taurus/core/evaluation/test/res/dev_example.py
@@ -81,7 +81,7 @@ def test2():
import sys
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.panel import TaurusForm
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w = TaurusForm()
attrname = 'eval:@taurus.core.evaluation.test.res.dev_example.FreeSpaceDevice/getFreeSpace("/")'
diff --git a/lib/taurus/core/evaluation/test/res/ipap_example.py b/lib/taurus/core/evaluation/test/res/ipap_example.py
index de47bbad..2e391459 100644
--- a/lib/taurus/core/evaluation/test/res/ipap_example.py
+++ b/lib/taurus/core/evaluation/test/res/ipap_example.py
@@ -44,7 +44,7 @@ def _test2():
import sys
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.display import TaurusLabel
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
tl = TaurusLabel()
tl.setModel(ATTR_IPAP_POS)
diff --git a/lib/taurus/core/evaluation/test/test_evalattribute.py b/lib/taurus/core/evaluation/test/test_evalattribute.py
index 6e9a7388..6e9a7388 100755..100644
--- a/lib/taurus/core/evaluation/test/test_evalattribute.py
+++ b/lib/taurus/core/evaluation/test/test_evalattribute.py
diff --git a/lib/taurus/core/init_bkcomp.py b/lib/taurus/core/init_bkcomp.py
index 26f64052..3a480733 100644
--- a/lib/taurus/core/init_bkcomp.py
+++ b/lib/taurus/core/init_bkcomp.py
@@ -42,6 +42,7 @@ from .taurusmanager import *
from .taurusoperation import *
from .tauruspollingtimer import *
from .taurusvalidator import *
+from .units import *
# enable compatibility code with tau V1 if tauv1 package is present
try:
diff --git a/lib/taurus/core/release.py b/lib/taurus/core/release.py
index 00dda8f6..820800f5 100644
--- a/lib/taurus/core/release.py
+++ b/lib/taurus/core/release.py
@@ -47,7 +47,7 @@ name = 'taurus'
# we use semantic versioning (http://semver.org/) and we update it using the
# bumpversion script (https://github.com/peritus/bumpversion)
-version = '4.5.0'
+version = '4.6.1'
# generate version_info and revision (**deprecated** since version 4.0.2-dev).
if '-' in version:
diff --git a/lib/taurus/core/resource/resvalidator.py b/lib/taurus/core/resource/resvalidator.py
index 6e3e99a6..581ededd 100644
--- a/lib/taurus/core/resource/resvalidator.py
+++ b/lib/taurus/core/resource/resvalidator.py
@@ -29,8 +29,8 @@ from taurus.core.taurusvalidator import (TaurusAttributeNameValidator,
TaurusAuthorityNameValidator)
from taurus.core.taurushelper import getSchemeFromName, Factory
-__all__ = ['ResDeviceNameValidator',
- 'ResAttributeNameValidator']
+__all__ = ['ResourceAuthorityNameValidator', 'ResourceDeviceNameValidator',
+ 'ResourceAttributeNameValidator']
# Pattern for python variables
PY_VAR = r'(?<![\.a-zA-Z0-9_])[a-zA-Z_][a-zA-Z0-9_]*'
diff --git a/lib/taurus/core/resource/test/res/__init__.py b/lib/taurus/core/resource/test/res/__init__.py
index e69de29b..e69de29b 100755..100644
--- a/lib/taurus/core/resource/test/res/__init__.py
+++ b/lib/taurus/core/resource/test/res/__init__.py
diff --git a/lib/taurus/core/resource/test/res/attr_resources_file.py b/lib/taurus/core/resource/test/res/attr_resources_file.py
index 0db7a6e0..0db7a6e0 100755..100644
--- a/lib/taurus/core/resource/test/res/attr_resources_file.py
+++ b/lib/taurus/core/resource/test/res/attr_resources_file.py
diff --git a/lib/taurus/core/resource/test/test_resfactory.py b/lib/taurus/core/resource/test/test_resfactory.py
index e80714a4..e80714a4 100755..100644
--- a/lib/taurus/core/resource/test/test_resfactory.py
+++ b/lib/taurus/core/resource/test/test_resfactory.py
diff --git a/lib/taurus/core/resource/test/test_resvalidator.py b/lib/taurus/core/resource/test/test_resvalidator.py
index 4384e97b..4384e97b 100755..100644
--- a/lib/taurus/core/resource/test/test_resvalidator.py
+++ b/lib/taurus/core/resource/test/test_resvalidator.py
diff --git a/lib/taurus/core/tango/tangoattribute.py b/lib/taurus/core/tango/tangoattribute.py
index 9bd9af00..b0620881 100755..100644
--- a/lib/taurus/core/tango/tangoattribute.py
+++ b/lib/taurus/core/tango/tangoattribute.py
@@ -119,8 +119,10 @@ class TangoAttrValue(TaurusAttrValue):
for _ in range(len(shape) - 1):
p.value = [p.value]
- rvalue = p.value
- wvalue = p.w_value
+ # Protect against DeviceAttribute not providing .value in some cases,
+ # seen e.g. in PyTango 9.3.0
+ rvalue = getattr(p, 'value', None)
+ wvalue = getattr(p, 'w_value', None)
if numerical:
units = self._attrRef._units
if rvalue is not None:
@@ -324,6 +326,7 @@ class TangoAttribute(TaurusAttribute):
def cleanUp(self):
self.trace("[TangoAttribute] cleanUp")
self._unsubscribeConfEvents()
+ self._unsubscribeChangeEvents()
TaurusAttribute.cleanUp(self)
self.__dev_hw_obj = None
self._pytango_attrinfoex = None
@@ -417,7 +420,7 @@ class TangoAttribute(TaurusAttribute):
elif fmt in (DataFormat._1D, DataFormat._2D):
if PyTango.is_int_type(tgtype):
# cast to integer because the magnitude conversion gives floats
- attrvalue = magnitude.astype('int64')
+ attrvalue = numpy.array(magnitude, copy=False, dtype='int64')
elif tgtype == PyTango.CmdArgType.DevUChar:
attrvalue = magnitude.view('uint8')
else:
@@ -600,7 +603,7 @@ class TangoAttribute(TaurusAttribute):
assert len(listeners) >= 1
if self.__subscription_state == SubscriptionState.Unsubscribed and len(listeners) == 1:
- self._subscribeEvents()
+ self._subscribeChangeEvents()
# if initial_subscription_state == SubscriptionState.Subscribed:
if (len(listeners) > 1
@@ -630,7 +633,7 @@ class TangoAttribute(TaurusAttribute):
return ret
if self.__subscription_state != SubscriptionState.Unsubscribed:
- self._unsubscribeEvents()
+ self._unsubscribeChangeEvents()
return ret
@@ -654,7 +657,7 @@ class TangoAttribute(TaurusAttribute):
def _process_event_exception(self, ex):
pass
- def _subscribeEvents(self):
+ def _subscribeChangeEvents(self):
""" Enable subscription to the attribute events. If change events are
not supported polling is activated """
@@ -705,7 +708,7 @@ class TangoAttribute(TaurusAttribute):
return self.__chg_evt_id
- def _unsubscribeEvents(self):
+ def _unsubscribeChangeEvents(self):
# Careful in this method: This is intended to be executed in the cleanUp
# so we should not access external objects from the factory, like the
# parent object
diff --git a/lib/taurus/core/tango/tangodatabase.py b/lib/taurus/core/tango/tangodatabase.py
index 0d29365b..cb138566 100644
--- a/lib/taurus/core/tango/tangodatabase.py
+++ b/lib/taurus/core/tango/tangodatabase.py
@@ -643,21 +643,22 @@ def get_env_var(env_var_name):
if not os.path.exists(fname):
return None
- for line in file(fname):
- strippedline = line.split('#', 1)[0].strip()
-
- if not strippedline:
- # empty line
- continue
-
- tup = strippedline.split('=', 1)
- if len(tup) != 2:
- # illegal line!
- continue
-
- key, val = list(map(str.strip, tup))
- if key == env_var_name:
- return val
+ with open(fname) as f:
+ for line in f:
+ strippedline = line.split('#', 1)[0].strip()
+
+ if not strippedline:
+ # empty line
+ continue
+
+ tup = strippedline.split('=', 1)
+ if len(tup) != 2:
+ # illegal line!
+ continue
+
+ key, val = list(map(str.strip, tup))
+ if key == env_var_name:
+ return val
class TangoAuthority(TaurusAuthority):
diff --git a/lib/taurus/core/tango/tangodevice.py b/lib/taurus/core/tango/tangodevice.py
index 562faa66..60e979c8 100755..100644
--- a/lib/taurus/core/tango/tangodevice.py
+++ b/lib/taurus/core/tango/tangodevice.py
@@ -75,7 +75,7 @@ class TangoDevice(TaurusDevice):
# This way we can call for example read_attribute on an object of this
# class
def __getattr__(self, name):
- if self._deviceObj is not None:
+ if name != "_deviceObj" and self._deviceObj is not None:
return getattr(self._deviceObj, name)
cls_name = self.__class__.__name__
raise AttributeError("'%s' has no attribute '%s'" % (cls_name, name))
diff --git a/lib/taurus/core/tango/test/test_tangofactory.py b/lib/taurus/core/tango/test/test_tangofactory.py
index 7c7c3a8a..7c7c3a8a 100755..100644
--- a/lib/taurus/core/tango/test/test_tangofactory.py
+++ b/lib/taurus/core/tango/test/test_tangofactory.py
diff --git a/lib/taurus/core/tango/util/formatter.py b/lib/taurus/core/tango/util/formatter.py
index ce5ebd0d..ce5ebd0d 100755..100644
--- a/lib/taurus/core/tango/util/formatter.py
+++ b/lib/taurus/core/tango/util/formatter.py
diff --git a/lib/taurus/core/taurusattribute.py b/lib/taurus/core/taurusattribute.py
index 9f61d5e1..eba0365a 100644
--- a/lib/taurus/core/taurusattribute.py
+++ b/lib/taurus/core/taurusattribute.py
@@ -79,7 +79,11 @@ class TaurusAttribute(TaurusModel):
def cleanUp(self):
self.trace("[TaurusAttribute] cleanUp")
- self._unsubscribeEvents()
+ if hasattr(self, '_unsuscribeEvents'):
+ self.deprecated(
+ dep='TaurusAttribute._unsuscribeEvents API',
+ alt='If you need it called in cleanUp, re-implement cleanUp')
+ self._unsuscribeEvents()
TaurusModel.cleanUp(self)
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
@@ -146,14 +150,6 @@ class TaurusAttribute(TaurusModel):
raise NotImplementedError("Not allowed to call AbstractClass" +
" TaurusAttribute.poll")
- def _subscribeEvents(self):
- raise NotImplementedError("Not allowed to call AbstractClass" +
- " TaurusAttribute._subscribeEvents")
-
- def _unsubscribeEvents(self):
- raise NotImplementedError("Not allowed to call AbstractClass" +
- " TaurusAttribute._unsubscribeEvents")
-
def isUsingEvents(self):
raise NotImplementedError("Not allowed to call AbstractClass" +
" TaurusAttribute.isUsingEvents")
diff --git a/lib/taurus/core/taurusdevice.py b/lib/taurus/core/taurusdevice.py
index ae605e1f..ae605e1f 100755..100644
--- a/lib/taurus/core/taurusdevice.py
+++ b/lib/taurus/core/taurusdevice.py
diff --git a/lib/taurus/core/taurusfactory.py b/lib/taurus/core/taurusfactory.py
index 01a48148..230c2151 100644
--- a/lib/taurus/core/taurusfactory.py
+++ b/lib/taurus/core/taurusfactory.py
@@ -396,6 +396,17 @@ class TaurusFactory(object):
ret.append(TaurusElementType.Authority)
return ret
+ def getValidatorFromName(self, name):
+ """
+ Obtain the validator object corresponding to the given model
+ name. If the model name is not valid for any TaurusModel class,
+ it returns None
+ """
+ modeltypes = self.getValidTypesForName(name)
+ if not modeltypes:
+ return None
+ return self.elementTypesMap[modeltypes[0]].getNameValidator()
+
def findObjectClass(self, absolute_name):
"""
Obtain the class object corresponding to the given name.
diff --git a/lib/taurus/core/taurushelper.py b/lib/taurus/core/taurushelper.py
index a6de167b..07fb7d32 100644
--- a/lib/taurus/core/taurushelper.py
+++ b/lib/taurus/core/taurushelper.py
@@ -42,7 +42,8 @@ __all__ = ['check_dependencies', 'log_dependencies', 'getSchemeFromName',
'resetLogLevel', 'resetLogFormat',
'enableLogOutput', 'disableLogOutput',
'log', 'trace', 'debug', 'info', 'warning', 'error', 'fatal',
- 'critical', 'deprecated', 'changeDefaultPollingPeriod']
+ 'critical', 'deprecated', 'changeDefaultPollingPeriod',
+ 'getValidatorFromName']
__docformat__ = "restructuredtext"
@@ -134,6 +135,21 @@ def getSchemeFromName(name, implicit=True):
return None
+def getValidatorFromName(name):
+ """Helper for obtaining the validator object corresponding to the
+ given name.
+
+ :return: model name validator or None if name is not a supported model name
+ """
+
+ try:
+ factory = Factory(scheme=getSchemeFromName(name))
+ except:
+ return None
+ return factory.getValidatorFromName(name)
+
+
+
def makeSchemeExplicit(name, default=None):
"""return the name guaranteeing that the scheme is present. If name already
contains the scheme, it is returned unchanged.
@@ -200,7 +216,7 @@ def isValidName(name, etypes=None, strict=None):
for e in etypes:
if e in validtypes:
return True
- return False
+ return False
def Manager():
diff --git a/lib/taurus/core/taurusmanager.py b/lib/taurus/core/taurusmanager.py
index 5ef57107..5ef57107 100755..100644
--- a/lib/taurus/core/taurusmanager.py
+++ b/lib/taurus/core/taurusmanager.py
diff --git a/lib/taurus/core/test/test_taurushelper.py b/lib/taurus/core/test/test_taurushelper.py
index 252471ba..5febe0a7 100644
--- a/lib/taurus/core/test/test_taurushelper.py
+++ b/lib/taurus/core/test/test_taurushelper.py
@@ -466,5 +466,19 @@ class AttributeTestCase(unittest.TestCase):
self.assertTrue(chk, msg)
+class ValidatorFromName(unittest.TestCase):
+ """TestCase for the taurus.getValidatorFromName helper"""
+
+ def test_getValidatorFromName(self):
+ """check that getValidatorFromName returns the expected values"""
+
+ self.assertIsInstance(
+ taurus.getValidatorFromName('eval:@foo'),
+ taurus.core.evaluation.evalvalidator.EvaluationDeviceNameValidator
+ )
+ self.assertIsNone(taurus.getValidatorFromName('eval:@/'))
+ self.assertIsNone(taurus.getValidatorFromName('unsupported:scheme'))
+
+
if __name__ == '__main__':
pass
diff --git a/lib/taurus/core/units.py b/lib/taurus/core/units.py
index 0d6ad349..64a1250e 100644
--- a/lib/taurus/core/units.py
+++ b/lib/taurus/core/units.py
@@ -27,6 +27,7 @@ This module provides a pint unit registry instance (`UR`) to be used by all
taurus objects. It also provides the `Quantity` factory from that registry
(also aliased as `Q_`).
"""
+__all__ = ['UR', 'Quantity', 'Q_']
from pint import UnitRegistry
diff --git a/lib/taurus/core/util/argparse/taurusargparse.py b/lib/taurus/core/util/argparse/taurusargparse.py
index b21e717a..4555f019 100644
--- a/lib/taurus/core/util/argparse/taurusargparse.py
+++ b/lib/taurus/core/util/argparse/taurusargparse.py
@@ -84,6 +84,12 @@ __all__ = ["get_taurus_parser", "init_taurus_args", "parse_taurus_args",
__docformat__ = "restructuredtext"
+from taurus.core.util import log as __log
+
+__log.deprecated(dep='taurus.core.util.argparse', rel='4.5.4',
+ alt='argparse or (better) click')
+
+
def get_taurus_parser(parser=None):
""" Returns a :class:`optparse.OptionParser` initialized with a
:class:`optparse.OptionGroup` containning some taurus options.
diff --git a/lib/taurus/core/util/codecs.py b/lib/taurus/core/util/codecs.py
index 0b91df54..15cdd0ee 100644
--- a/lib/taurus/core/util/codecs.py
+++ b/lib/taurus/core/util/codecs.py
@@ -63,7 +63,7 @@ A Taurus related example::
>>> f, d = codec.decode((v.format, v.value))
"""
from __future__ import absolute_import
-from builtins import str
+from builtins import str, bytes
import copy
@@ -79,7 +79,8 @@ from .log import Logger
from .containers import CaselessDict
__all__ = ["Codec", "NullCodec", "ZIPCodec", "BZ2Codec", "JSONCodec",
- "FunctionCodec", "PlotCodec", "CodecPipeline", "CodecFactory"]
+ "Utf8Codec", "FunctionCodec", "PlotCodec", "CodecPipeline",
+ "CodecFactory"]
__docformat__ = "restructuredtext"
@@ -171,7 +172,7 @@ class ZIPCodec(Codec):
'Hello world\\nHello wo'"""
def encode(self, data, *args, **kwargs):
- """encodes the given data to a gzip string. The given data **must** be a string
+ """encodes the given data to gzip bytes. The given data **must** be bytes
:param data: (sequence[str, obj]) a sequence of two elements where the first item is the encoding format of the second item object
@@ -183,7 +184,7 @@ class ZIPCodec(Codec):
return format, zlib.compress(data[1])
def decode(self, data, *args, **kwargs):
- """decodes the given data from a gzip string.
+ """decodes the given data from a gzip bytes.
:param data: (sequence[str, obj]) a sequence of two elements where the first item is the encoding format of the second item object
@@ -214,7 +215,7 @@ class BZ2Codec(Codec):
'Hello world\\nHello wo'"""
def encode(self, data, *args, **kwargs):
- """encodes the given data to a bz2 string. The given data **must** be a string
+ """encodes the given data to bz2 bytes. The given data **must** be bytes
:param data: (sequence[str, obj]) a sequence of two elements where the first item is the encoding format of the second item object
@@ -226,7 +227,7 @@ class BZ2Codec(Codec):
return format, bz2.compress(data[1])
def decode(self, data, *args, **kwargs):
- """decodes the given data from a bz2 string.
+ """decodes the given data from bz2 bytes.
:param data: (sequence[str, obj]) a sequence of two elements where the first item is the encoding format of the second item object
@@ -259,7 +260,7 @@ class PickleCodec(Codec):
{'hello': 'world', 'goodbye': 1000}"""
def encode(self, data, *args, **kwargs):
- """encodes the given data to a pickle string. The given data **must** be
+ """encodes the given data to pickle bytes. The given data **must** be
a python object that :mod:`pickle` is able to convert.
:param data: (sequence[str, obj]) a sequence of two elements where the
@@ -331,7 +332,7 @@ class JSONCodec(Codec):
format += '_%s' % data[0]
# make it compact by default
kwargs['separators'] = kwargs.get('separators', (',', ':'))
- return format, json.dumps(data[1], *args, **kwargs).encode('utf-8')
+ return format, json.dumps(data[1], *args, **kwargs)
def decode(self, data, *args, **kwargs):
"""decodes the given data from a json string.
@@ -350,8 +351,6 @@ class JSONCodec(Codec):
if isinstance(data[1], buffer_types):
data = data[0], str(data[1])
- elif isinstance(data[1], bytes):
- data = data[0], data[1].decode('utf-8')
data = json.loads(data[1])
if ensure_ascii:
@@ -380,6 +379,56 @@ class JSONCodec(Codec):
return newdict
+class Utf8Codec(Codec):
+ """A codec able to encode/decode utf8 strings to/from bytes.
+ Useful to adapt i/o encodings in a codec pipe.
+
+ Example::
+
+ >>> from taurus.core.util.codecs import CodecFactory
+
+ >>> cf = CodecFactory()
+ >>> codec = cf.getCodec('zip_utf8_json')
+ >>>
+ >>> # first encode something
+ >>> data = { 'hello' : 'world', 'goodbye' : 1000 }
+ >>> format, encoded_data = codec.encode(("", data))
+ >>>
+ >>> # now decode it
+ >>> _, decoded_data = codec.decode((format, encoded_data))
+ >>> print decoded_data
+ """
+
+ def encode(self, data, *args, **kwargs):
+ """
+ Encodes the given utf8 string to bytes.
+
+ :param data: (sequence[str, obj]) a sequence of two elements where the
+ first item is the encoding format of the second item object
+
+ :return: (sequence[str, obj]) a sequence of two elements where the
+ first item is the encoding format of the second item object
+ """
+ format = 'utf8'
+ fmt, data = data
+ if len(fmt):
+ format += '_%s' % fmt
+ return format, str(data).encode()
+
+ def decode(self, data, *args, **kwargs):
+ """decodes the given data from a bytes.
+
+ :param data: (sequence[str, obj]) a sequence of two elements where the
+ first item is the encoding format of the second item object
+
+ :return: (sequence[str, obj]) a sequence of two elements where the
+ first item is the encoding format of the second item object
+ """
+ fmt, data = data
+ fmt = fmt.partition('_')[2]
+ return fmt, bytes(data).decode()
+
+
class BSONCodec(Codec):
"""A codec able to encode/decode to/from bson format. It uses the
:mod:`bson` module.
@@ -550,7 +599,19 @@ class VideoImageCodec(Codec):
imgBuffer = data[1][struct.calcsize(self.VIDEO_HEADER_FORMAT):]
dtype = self.__getDtypeId(header['imageMode'])
- if header['imageMode'] == 7:
+
+ if header['imageMode'] == 6:
+ # RGB24, 3 bytes per pixel
+ rgba = numpy.fromstring(imgBuffer, dtype)
+ bbuf = rgba[0::3]
+ gbuf = rgba[1::3]
+ rbuf = rgba[2::3]
+ r = rbuf.reshape(header['height'], header['width'])
+ g = gbuf.reshape(header['height'], header['width'])
+ b = bbuf.reshape(header['height'], header['width'])
+ img2D = numpy.dstack((r, g, b))
+
+ elif header['imageMode'] == 7:
# RGBA 4 bytes per pixel
rgba = numpy.fromstring(imgBuffer, dtype)
bbuf = rgba[0::4]
@@ -698,7 +759,7 @@ class VideoImageCodec(Codec):
# TODO: other modes
#'RGB555' : 4,#Core.RGB555,
#'RGB565' : 5,#Core.RGB565,
- #'RGB24' : 6,#Core.RGB24,
+ 'RGB24': 6, # Core.RGB24,
'RGB32': 7, # Core.RGB32,
#'BGR24' : 8,#Core.BGR24,
#'BGR32' : 9,#Core.BGR32,
@@ -719,7 +780,7 @@ class VideoImageCodec(Codec):
3: 'L',
#'RGB555' : Core.RGB555,
#'RGB565' : Core.RGB565,
- #'RGB24' : Core.RGB24,
+ 6: 'RGB24', # Core.RGB24,
7: 'RGB32', # Core.RGB32,
# 8 : 'BGR24',#Core.BGR24,
#'BGR32' : Core.BGR32,
@@ -740,7 +801,7 @@ class VideoImageCodec(Codec):
3: 'uint64',
#'RGB555' : Core.RGB555,
#'RGB565' : Core.RGB565,
- # 6 : 'uint8', # Core.RGB24,
+ 6: 'uint8', # Core.RGB24,
7: 'uint8', # Core.RGB32,
#'BGR24' : Core.BGR24,
#'BGR32' : Core.BGR32,
@@ -854,6 +915,7 @@ class CodecFactory(Singleton, Logger):
#: Default minimum map of registered codecs
CODEC_MAP = CaselessDict({
'json': JSONCodec,
+ 'utf8': Utf8Codec,
'bson': BSONCodec,
'bz2': BZ2Codec,
'zip': ZIPCodec,
diff --git a/lib/taurus/core/util/console.py b/lib/taurus/core/util/console.py
index 051f721d..7ffe55c5 100644
--- a/lib/taurus/core/util/console.py
+++ b/lib/taurus/core/util/console.py
@@ -34,8 +34,7 @@ __docformat__ = "restructuredtext"
def make_color_table(in_class, use_name=False, fake=False):
"""Build a set of color attributes in a class.
-
- Helper function for building the *TermColors classes."""
+ Helper function for building the TermColors classes."""
color_templates = (
("Black", "0;30"),
("Red", "0;31"),
diff --git a/lib/taurus/core/util/constant.py b/lib/taurus/core/util/constant.py
index c793322e..ae217333 100644
--- a/lib/taurus/core/util/constant.py
+++ b/lib/taurus/core/util/constant.py
@@ -69,5 +69,7 @@ class _consttype(object):
def __del__(self):
self.__dict__.clear()
-import sys
-sys.modules[__name__] = _consttype()
+
+if __name__ == '__main__':
+ import sys
+ sys.modules[__name__] = _consttype()
diff --git a/lib/taurus/core/util/containers.py b/lib/taurus/core/util/containers.py
index bbc8d762..8fbd5ce6 100644
--- a/lib/taurus/core/util/containers.py
+++ b/lib/taurus/core/util/containers.py
@@ -498,6 +498,8 @@ class LoopList(object):
self._index += 1
return self.current()
+ next = __next__
+
def previous(self):
'''goes one item back in the list and returns it'''
self._index -= 1
diff --git a/lib/taurus/core/util/decorator/__init__.py b/lib/taurus/core/util/decorator/__init__.py
index e69de29b..2ff6c9a0 100644
--- a/lib/taurus/core/util/decorator/__init__.py
+++ b/lib/taurus/core/util/decorator/__init__.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python
+
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+"""
+This module provides a few convenience decorators
+""" \ No newline at end of file
diff --git a/lib/taurus/core/util/decorator/decorator.py b/lib/taurus/core/util/decorator/decorator.py
index e26227f1..a3fef8af 100644
--- a/lib/taurus/core/util/decorator/decorator.py
+++ b/lib/taurus/core/util/decorator/decorator.py
@@ -23,36 +23,10 @@
##
#############################################################################
-"""\
-Allow to use decorator either with arguments or not. Example::
-
- @decorator
- def apply(func, *args, **kw):
- return func(*args, **kw)
-
- @decorator
- class apply:
- def __init__(self, *args, **kw):
- self.args = args
- self.kw = kw
-
- def __call__(self, func):
- return func(*self.args, **self.kw)
-
- #
- # Usage in both cases:
- #
- @apply
- def test():
- return 'test'
-
- assert test == 'test'
-
- @apply(2, 3)
- def test(a, b):
- return a + b
-
- assert test == 5"""
+"""
+Provides a decorator to decorate decorators so that they can be used both
+with and without args
+"""
__all__ = ["decorator"]
@@ -63,7 +37,8 @@ import inspect
def decorator(func):
- """Allow to use decorator either with arguments or not. Example::
+ """
+ Allow to use decorator either with arguments or not. Example::
@decorator
def apply(func, *args, **kw):
@@ -92,6 +67,7 @@ def decorator(func):
return a + b
assert test == 5
+
"""
def isFuncArg(*args, **kw):
diff --git a/lib/taurus/core/util/decorator/typecheck.py b/lib/taurus/core/util/decorator/typecheck.py
index 88ec269e..1b015e35 100644
--- a/lib/taurus/core/util/decorator/typecheck.py
+++ b/lib/taurus/core/util/decorator/typecheck.py
@@ -26,12 +26,15 @@
"""
One of three degrees of enforcement may be specified by passing
the 'debug' keyword argument to the decorator:
- 0 -- NONE: No type-checking. Decorators disabled.
- 1 -- MEDIUM: Print warning message to stderr. (Default)
- 2 -- STRONG: Raise TypeError with message.
+
+ - 0 -- NONE: No type-checking. Decorators disabled.
+ - 1 -- MEDIUM: Print warning message to stderr. (Default)
+ - 2 -- STRONG: Raise TypeError with message.
+
If 'debug' is not passed to the decorator, the default level is used.
-Example usage:
+Example usage::
+
>>> NONE, MEDIUM, STRONG = 0, 1, 2
>>>
>>> @accepts(int, int, int)
@@ -47,7 +50,7 @@ Example usage:
TypeWarning: 'average' method returns (float), but result is (int)
15
-Needed to cast params as floats in function def (or simply divide by 2.0).
+Needed to cast params as floats in function def (or simply divide by 2.0)::
>>> TYPE_CHECK = STRONG
>>> @accepts(int, debug=TYPE_CHECK)
@@ -71,15 +74,12 @@ __all__ = ["accepts", "returns"]
__docformat__ = "restructuredtext"
def accepts(*types, **kw):
- """ Function decorator. Checks that inputs given to decorated function
+ """
+ Function decorator. Checks that inputs given to decorated function
are of the expected type.
- Parameters:
- types -- The expected types of the inputs to the decorated function.
- Must specify type for each parameter.
- kw -- Optional specification of 'debug' level (this is the only valid
- keyword argument, no other should be given).
- debug = ( 0 | 1 | 2 )
+ :param types: The expected type of the decorated function's return value
+ :param debug: Optional specification of 'debug' level (0 | 1 | 2)
"""
if not kw:
@@ -111,15 +111,12 @@ def accepts(*types, **kw):
def returns(ret_type, **kw):
- """ Function decorator. Checks that return value of decorated function
+ """
+ Function decorator. Checks that return value of decorated function
is of the expected type.
- Parameters:
- ret_type -- The expected type of the decorated function's return value.
- Must specify type for each parameter.
- kw -- Optional specification of 'debug' level (this is the only valid
- keyword argument, no other should be given).
- debug=(0 | 1 | 2)
+ :param ret_type: The expected type of the decorated function's return value.
+ :param debug: Optional specification of 'debug' level (0 | 1 | 2)
"""
try:
diff --git a/lib/taurus/core/util/event.py b/lib/taurus/core/util/event.py
index d2e67449..e77f6f20 100644
--- a/lib/taurus/core/util/event.py
+++ b/lib/taurus/core/util/event.py
@@ -106,7 +106,8 @@ def CallableRef(object, del_cb=None):
:type del_cb: callable object or None
:return: a weak reference for the given callable
- :rtype: BoundMethodWeakref or weakref.ref"""
+ :rtype: taurus.core.util.BoundMethodWeakref or weakref.ref
+ """
im_self = None
if hasattr(object, '__self__'):
im_self = object.__self__
diff --git a/lib/taurus/core/util/parse_args.py b/lib/taurus/core/util/parse_args.py
index 3da75c67..034c4abb 100644
--- a/lib/taurus/core/util/parse_args.py
+++ b/lib/taurus/core/util/parse_args.py
@@ -33,10 +33,10 @@ def parse_args(s, strip_pars=False):
corresponding args and kwargs.
:param s: string representing arguments to a method
- :type strip_pars: (bool) If True, expect s to include surrounding
- parenthesis
+ :param strip_pars: (bool) If True, expect s to include surrounding
+ parenthesis
:return: args, kwargs (a list of positional arguments and a dict of keyword
- arguments)
+ arguments)
"""
s = s.strip()
if strip_pars:
diff --git a/lib/taurus/core/util/property_parser.py b/lib/taurus/core/util/property_parser.py
index 784055c2..4b981b21 100644
--- a/lib/taurus/core/util/property_parser.py
+++ b/lib/taurus/core/util/property_parser.py
@@ -101,7 +101,7 @@ def t_STRING(t):
def t_KEY(t):
- r'[a-zA-Z0-9_\.\/]+'
+ r'[a-zA-Z0-9/_\.\/]+'
t.type = reserved.get(t.value, 'KEY') # Check for reserved words
return t
diff --git a/lib/taurus/core/util/propertyfile.py b/lib/taurus/core/util/propertyfile.py
index a608b884..91182aaf 100644
--- a/lib/taurus/core/util/propertyfile.py
+++ b/lib/taurus/core/util/propertyfile.py
@@ -246,9 +246,6 @@ class Properties(object):
def load(self, stream):
""" Load properties from an open file stream """
- # For the time being only accept file input streams
- if type(stream) is not file:
- raise TypeError('Argument should be a file object!')
# Check for the opened mode
if stream.mode != 'r':
raise ValueError('Stream should be opened in read-only mode!')
diff --git a/lib/taurus/core/util/remotelogmonitor.py b/lib/taurus/core/util/remotelogmonitor.py
index 9b7988be..9fbf673f 100644
--- a/lib/taurus/core/util/remotelogmonitor.py
+++ b/lib/taurus/core/util/remotelogmonitor.py
@@ -38,6 +38,7 @@ import logging
import logging.handlers
import struct
import weakref
+import click
import socketserver
@@ -181,47 +182,26 @@ def log(host, port, name=None, level=None):
print("\nCancelled", msg)
-def main(argv=None):
- import optparse
- import socket
-
- import taurus.core.util.log
-
- taurus.setLogLevel(taurus.Trace)
-
- dft_port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
-
+@click.command('logmon')
+@click.option('--port', 'port', type=int,
+ default=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
+ show_default=True,
+ help='port where log server is running')
+@click.option('--log-name', 'log_name', default=None,
+ help='filter specific log object')
+@click.option('--log-level', 'log_level',
+ type=click.Choice(['critical', 'error', 'warning', 'info',
+ 'debug', 'trace']),
+ default='debug', show_default=True,
+ help='filter specific log level')
+def logmon_cmd(port, log_name, log_level):
+ """Show the console-based Taurus Remote Log Monitor"""
+ import taurus
host = socket.gethostname()
+ level = getattr(taurus, log_level.capitalize(), taurus.Trace)
- help_port = "port where log server is running [default: %d]" % dft_port
- help_name = "filter specific log object [default: None, meaning don't " \
- "filter]"
- help_level = "filter specific log level." \
- "Allowed values are (case insensitive): critical, "\
- "error, warning/warn, info, debug, trace [default: debug]."
-
- parser = optparse.OptionParser()
- parser.add_option("--log-port", dest="log_port", default=dft_port,
- type="int", help=help_port)
- parser.add_option("--log-name", dest="log_name", default=None,
- type="string", help=help_name)
- parser.add_option("--log-level", dest="log_level", default="debug",
- type="string", help=help_level)
-
- if argv is None:
- import sys
- argv = sys.argv
-
- options, args = parser.parse_args(args=argv)
-
- port, name = options.log_port, options.log_name
- level_str = options.log_level.capitalize()
-
- level = None
- if hasattr(taurus, level_str):
- level = getattr(taurus, level_str)
+ log(host=host, port=port, name=log_name, level=level)
- log(host, port, name=name, level=level)
if __name__ == '__main__':
- main()
+ logmon_cmd()
diff --git a/lib/taurus/core/util/tablepprint.py b/lib/taurus/core/util/tablepprint.py
index cab4c13e..70552cfe 100644
--- a/lib/taurus/core/util/tablepprint.py
+++ b/lib/taurus/core/util/tablepprint.py
@@ -41,23 +41,21 @@ __docformat__ = "restructuredtext"
def indent(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left',
separateRows=False, prefix='', postfix='', wrapfunc=lambda x: x):
"""Indents a table by column.
- - rows: A sequence of sequences of items, one sequence per row.
- - hasHeader: True if the first row consists of the columns' names.
- - headerChar: Character to be used for the row separator line
- (if hasHeader==True or separateRows==True).
- - delim: The column delimiter.
- - justify: Determines how are data justified in their column.
- Valid values are 'left','right' and 'center'.
- - separateRows: True if rows are to be separated by a line
- of 'headerChar's.
- - prefix: A string prepended to each printed row.
- - postfix: A string appended to each printed row.
- - wrapfunc: A function f(text) for wrapping text; each element in
- the table is first wrapped by this function.
-
- Returns a list of strings. One for each row of the table
+ :param rows: A sequence of sequences of items, one sequence per row.
+ :param hasHeader: True if the first row consists of the columns' names.
+ :param headerChar: Character to be used for the row separator line
+ (if hasHeader==True or separateRows==True).
+ :param delim: The column delimiter.
+ :param justify: Determines how are data justified in their column.
+ Valid values are 'left','right' and 'center'.
+ :param separateRows: True if rows are to be separated by a line of
+ 'headerChar's.
+ :param prefix: A string prepended to each printed row.
+ :param postfix: A string appended to each printed row.
+ :param wrapfunc: A function f(text) for wrapping text;
+ each element in the table is first wrapped by this function.
+ :return: a list of strings. One for each row of the table
"""
-
# closure for breaking logical rows to physical, using wrapfunc
def rowWrapper(row):
newRows = [wrapfunc(item).split('\n') for item in row]
@@ -102,10 +100,9 @@ def indent(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left',
def wrap_onspace(text, width):
- """
- A word-wrap function that preserves existing line breaks
+ """A word-wrap function that preserves existing line breaks
and most spaces in the text. Expects that existing line
- breaks are posix newlines (\n).
+ breaks are posix newlines (\\\\n).
"""
return reduce(lambda line, word, width=width: '%s%s%s' %
(line,
diff --git a/lib/taurus/core/util/test/test_codecs.py b/lib/taurus/core/util/test/test_codecs.py
index 0543ca87..0746a5d8 100644
--- a/lib/taurus/core/util/test/test_codecs.py
+++ b/lib/taurus/core/util/test/test_codecs.py
@@ -38,7 +38,7 @@ import numpy
@insertTest(helper_name='encDec', cname='json', data=[1, 2, 3])
@insertTest(helper_name='encDec', cname='zip', data=b'foobar')
-@insertTest(helper_name='encDec', cname='zip_json', data=[1, 2, 3])
+@insertTest(helper_name='encDec', cname='zip_utf8_json', data=[1, 2, 3])
@insertTest(helper_name='encDec', cname='videoimage',
data=numpy.ones((2, 2), dtype='uint8'))
@insertTest(helper_name='encDec', cname='zip_null_zip_videoimage',
diff --git a/lib/taurus/core/util/whichexecutable.py b/lib/taurus/core/util/whichexecutable.py
index 29ce10e6..926e0980 100644
--- a/lib/taurus/core/util/whichexecutable.py
+++ b/lib/taurus/core/util/whichexecutable.py
@@ -42,7 +42,7 @@ def whichfile(filename, exts=None):
Example::
# on a debian machine with taurus installed in the default path:
- whichfile('taurusform') --> '/usr/bin/taurusform'
+ whichfile('taurus') --> '/usr/bin/taurus'
# or, on a winXP machine:
whichfile('command') --> 'C:\\WINDOWS\\system32\\command.COM'
diff --git a/lib/taurus/external/qt/QtHelp.py b/lib/taurus/external/qt/QtHelp.py
index 233c9e02..233c9e02 100755..100644
--- a/lib/taurus/external/qt/QtHelp.py
+++ b/lib/taurus/external/qt/QtHelp.py
diff --git a/lib/taurus/external/qt/QtWebKit.py b/lib/taurus/external/qt/QtWebKit.py
index 37bdc8d4..c40a5d2b 100644
--- a/lib/taurus/external/qt/QtWebKit.py
+++ b/lib/taurus/external/qt/QtWebKit.py
@@ -29,16 +29,16 @@ from . import PYQT5, PYQT4, PYSIDE, PYSIDE2, PythonQtError
if PYQT5:
- from PyQt5.WebKit import *
+ from PyQt5.QtWebKit import *
# import * from QtWebkitWidgets for PyQt4 style compat
- from PyQt5.WebKitWidgets import *
+ from PyQt5.QtWebKitWidgets import *
elif PYSIDE2:
- from PySide2.WebKit import *
+ from PySide2.QtWebKit import *
# import * from QtWebkitWidgets for PyQt4 style compat
- from PySide2.WebKitWidgets import *
+ from PySide2.QtWebKitWidgets import *
elif PYQT4:
- from PyQt4.WebKit import *
+ from PyQt4.QtWebKit import *
elif PYSIDE:
- from PySide.WebKit import *
+ from PySide.QtWebKit import *
else:
raise PythonQtError('No Qt bindings could be found')
diff --git a/lib/taurus/external/qt/__init__.py b/lib/taurus/external/qt/__init__.py
index ee38d171..c149d197 100644
--- a/lib/taurus/external/qt/__init__.py
+++ b/lib/taurus/external/qt/__init__.py
@@ -230,10 +230,11 @@ if PYQT5 and getattr(__config, 'QT_AVOID_ABORT_ON_EXCEPTION', True):
# TODO: check if we also want to do this for PySide(2)
__addExceptHook()
-__log.info('Using %s (v%s , with Qt %s)',
+__log.info('Using %s (v%s with Qt %s and Python %s)',
API_NAME,
PYQT_VERSION or PYSIDE_VERSION,
- QT_VERSION)
+ QT_VERSION,
+ sys.version.split()[0])
# --------------------------------------------------------------------------
diff --git a/lib/taurus/external/qt/compat.py b/lib/taurus/external/qt/compat.py
index 735c207f..df105614 100755..100644
--- a/lib/taurus/external/qt/compat.py
+++ b/lib/taurus/external/qt/compat.py
@@ -41,4 +41,12 @@ getOpenFileName = getattr(QFileDialog, 'getOpenFileNameAndFilter',
getOpenFileNames = getattr(QFileDialog, 'getOpenFileNamesAndFilter',
QFileDialog.getOpenFileNames)
-del QFileDialog \ No newline at end of file
+# Provide a common constant for the PyObject name (to be used in signal
+# signatures)
+from taurus.external.qt import PYQT5, PYQT4
+if PYQT5 or PYQT4:
+ PY_OBJECT = 'PyQt_PyObject'
+else:
+ PY_OBJECT = 'PyObject'
+
+del QFileDialog, PYQT5, PYQT4 \ No newline at end of file
diff --git a/lib/taurus/qt/qtcore/communication/communication.py b/lib/taurus/qt/qtcore/communication/communication.py
index e7771522..5535dcf9 100644
--- a/lib/taurus/qt/qtcore/communication/communication.py
+++ b/lib/taurus/qt/qtcore/communication/communication.py
@@ -29,7 +29,8 @@ comunications.py:
from __future__ import print_function
-from taurus.external.qt import QtCore
+from taurus.external.qt import QtCore, compat
+
import weakref
_DEBUG = False
@@ -56,7 +57,7 @@ class DataModel(QtCore.QObject):
DataModels are singletons.
'''
- dataChanged = QtCore.pyqtSignal(object)
+ dataChanged = QtCore.pyqtSignal(compat.PY_OBJECT)
def __init__(self, parent, dataUID, defaultData=None):
'''
diff --git a/lib/taurus/qt/qtcore/configuration/configuration.py b/lib/taurus/qt/qtcore/configuration/configuration.py
index cee021bc..fef4ef51 100644
--- a/lib/taurus/qt/qtcore/configuration/configuration.py
+++ b/lib/taurus/qt/qtcore/configuration/configuration.py
@@ -137,7 +137,7 @@ class BaseConfigurableClass(object):
# the latest element of this list is considered the current version
_supportedConfigVersions = ("__UNVERSIONED__",)
- def __init__(self):
+ def __init__(self, **kwargs):
self.resetConfigurableItems()
@staticmethod
@@ -444,8 +444,8 @@ class BaseConfigurableClass(object):
)
if not ofile:
return
- if not isinstance(ofile, file):
- ofile = open(ofile, 'w')
+ if isinstance(ofile, string_types):
+ ofile = open(ofile, 'wb')
configdict = self.createConfig(allowUnpickable=False)
self.info("Saving current settings in '%s'" % ofile.name)
pickle.dump(configdict, ofile)
@@ -465,8 +465,8 @@ class BaseConfigurableClass(object):
self, 'Load Configuration', '', 'Configuration File (*.pck)')
if not ifile:
return
- if not isinstance(ifile, file):
- ifile = open(ifile, 'r')
+ if isinstance(ifile, string_types):
+ ifile = open(ifile, 'rb')
configdict = pickle.load(ifile)
self.applyConfig(configdict)
diff --git a/lib/taurus/qt/qtcore/taurusqlistener.py b/lib/taurus/qt/qtcore/taurusqlistener.py
index c62542f1..8610fd37 100644
--- a/lib/taurus/qt/qtcore/taurusqlistener.py
+++ b/lib/taurus/qt/qtcore/taurusqlistener.py
@@ -31,7 +31,7 @@ __all__ = ["QTaurusBaseListener", "QObjectTaurusListener"]
__docformat__ = 'restructuredtext'
-from taurus.qt.qtcore.util.signal import baseSignal
+from taurus.qt.qtcore.util import baseSignal
from taurus.core.util.log import deprecation_decorator
from taurus.core.tauruslistener import TaurusListener
from taurus.external.qt import Qt
diff --git a/lib/taurus/qt/qtcore/util/__init__.py b/lib/taurus/qt/qtcore/util/__init__.py
index 64ccc147..b3017304 100644
--- a/lib/taurus/qt/qtcore/util/__init__.py
+++ b/lib/taurus/qt/qtcore/util/__init__.py
@@ -27,5 +27,6 @@
from __future__ import absolute_import
from .tauruslog import *
+from .signal import baseSignal
__docformat__ = 'restructuredtext'
diff --git a/lib/taurus/qt/qtcore/util/emitter.py b/lib/taurus/qt/qtcore/util/emitter.py
index 2105a53a..205e1351 100644
--- a/lib/taurus/qt/qtcore/util/emitter.py
+++ b/lib/taurus/qt/qtcore/util/emitter.py
@@ -91,9 +91,6 @@ class QEmitter(Qt.QObject):
class TaurusEmitterThread(Qt.QThread):
"""
- The TaurusEmitterThread Class
- ==========================
-
This object get items from a python Queue and performs a thread safe
operation on them.
It is useful to serialize Qt tasks in a background thread.
@@ -106,8 +103,7 @@ class TaurusEmitterThread(Qt.QThread):
:param cursor: if True or QCursor a custom cursor is set while
the Queue is not empty
- How TaurusEmitterThread works
- --------------------------
+ How TaurusEmitterThread works:
TaurusEmitterThread is a worker thread that processes a queue of iterables
passed as arguments to the specified method every time that
@@ -126,7 +122,7 @@ class TaurusEmitterThread(Qt.QThread):
to ``self.todo queue``
+ every time that a *somethingDone* signal arrives ``next()`` is called.
+ ``next()`` can be called also externally to ensure that the main queue
- is being processed.
+ is being processed.
+ the queue can be accessed externally using ``getQueue()``
+ ``getQueue().qsize()`` returns number of remaining objects in queue.
+ while there are objects in queue the ``.next()`` method will
@@ -139,8 +135,7 @@ class TaurusEmitterThread(Qt.QThread):
- if an object is found, it is sent in a *doSomething* signal.
- if *"exit"* is found the loop exits.
- Usage example
- -------------
+ Usage example:
.. code-block:: python
diff --git a/lib/taurus/qt/qtcore/util/properties.py b/lib/taurus/qt/qtcore/util/properties.py
index b7b225ed..7c70e834 100644
--- a/lib/taurus/qt/qtcore/util/properties.py
+++ b/lib/taurus/qt/qtcore/util/properties.py
@@ -117,17 +117,21 @@ COMMON_PROPERTIES = (
)
-def set_property_methods(obj, name, type_="QString", default=None, getter=None, setter=None, reset=None, get_callback=None, set_callback=None, reset_callback=None, qt=False, config=False):
+def set_property_methods(obj, name, type_="QString", default=None, getter=None,
+ setter=None, reset=None, get_callback=None,
+ set_callback=None, reset_callback=None, qt=False,
+ config=False):
"""
- This method allows to add QProperties dynamically with calls like:
- <pre>
+ This method allows to add QProperties dynamically with calls like::
+
set_property_methods(self,'Filters','QString',default='',
set_callback=lambda s=self:s.loadTree(s.getFilters(),clear=True),
reset_callback=lambda s=self:s.loadTree('',clear=True)
)
- </pre>
- @TODO: This method should be refactored using python descriptors/properties and types.MethodType
+
+ .. todo: This method should be refactored using python
+ descriptors/properties and types.MethodType
"""
klass = obj.__class__
mname = '%s%s' % (name[0].upper(), name[1:])
diff --git a/lib/taurus/qt/qtcore/util/signal.py b/lib/taurus/qt/qtcore/util/signal.py
index af3e2bfe..ec197b74 100644
--- a/lib/taurus/qt/qtcore/util/signal.py
+++ b/lib/taurus/qt/qtcore/util/signal.py
@@ -1,3 +1,27 @@
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+
"""Provide a Signal class for non-QObject objects"""
from __future__ import print_function
diff --git a/lib/taurus/qt/qtdesigner/containerplugin.py b/lib/taurus/qt/qtdesigner/containerplugin.py
index 70009e0a..83a87cb4 100644
--- a/lib/taurus/qt/qtdesigner/containerplugin.py
+++ b/lib/taurus/qt/qtdesigner/containerplugin.py
@@ -23,17 +23,21 @@
##
#############################################################################
-""" Every TaurusWidget should have the following Qt Designer extended capabilities:
+"""
+Every TaurusWidget should have the following Qt Designer extended
+capabilities:
- Task menu:
it means when you right click on the widget in the designer, it will have
the following additional items:
- - 'Edit model...' - opens a customized dialog for editing the widget model
+
+ - 'Edit model...': opens a customized dialog for editing the widget model
- Property Sheet:
it means that in the Qt Designer property sheet it will have the following
properties customized:
- - 'model' - will have a '...' button that will open a customized dialog for
+
+ - 'model': will have a '...' button that will open a customized dialog for
editing the widget model (same has 'Edit model...' task menu item
"""
@@ -103,8 +107,8 @@ class QGroupWidgetExtensionFactory(QtDesigner.QExtensionFactory):
def create_plugin():
- #from .taurusplugin.taurusplugin import TaurusWidgetPlugin # - after futurize stage1
- from taurusplugin.taurusplugin import TaurusWidgetPlugin # + after futurize stage1
+ from taurus.qt.qtdesigner.taurusplugin.taurusplugin import (
+ TaurusWidgetPlugin)
class QGroupWidgetPlugin(TaurusWidgetPlugin):
diff --git a/lib/taurus/qt/qtdesigner/taurusdesigner.py b/lib/taurus/qt/qtdesigner/taurusdesigner.py
index 3ceee990..2d8c17b4 100644
--- a/lib/taurus/qt/qtdesigner/taurusdesigner.py
+++ b/lib/taurus/qt/qtdesigner/taurusdesigner.py
@@ -25,10 +25,12 @@
from builtins import str
import sys
+import click
import os.path
-import optparse
+import subprocess
import taurus
+import taurus.tauruscustomsettings
from taurus.external.qt import Qt
from taurus.core.util.log import deprecation_decorator
@@ -73,17 +75,24 @@ def append_or_create_env_list(env, env_name, env_value):
def get_qtdesigner_bin():
+ designer_bin = getattr(taurus.tauruscustomsettings, 'QT_DESIGNER_PATH', None)
+ if designer_bin:
+ return designer_bin
designer_bin = str(Qt.QLibraryInfo.location(Qt.QLibraryInfo.BinariesPath))
plat = sys.platform
if plat == "darwin":
designer_bin = os.path.join(
- designer_bin, "Designer.app", "Contents", "MacOS")
+ designer_bin, "Designer.app", "Contents", "MacOS", "designer")
elif plat in ("win32", "nt"):
- import PyQt4
- designer_bin = os.path.abspath(os.path.dirname(PyQt4.__file__))
-
- designer_bin = os.path.join(designer_bin, "designer")
+ designer_bin = os.path.join(designer_bin, "designer.exe")
+ if not os.path.exists(designer_bin):
+ # some installations don't properly install designer
+ # in QLibraryInfo.BinariesPath. We do a best effort to find it
+ designer_bin = subprocess.check_output('where designer')
+ designer_bin = designer_bin.decode().strip()
+ else:
+ designer_bin = os.path.join(designer_bin, "designer")
return designer_bin
@@ -151,31 +160,17 @@ def qtdesigner_start(args, env=None):
return designer.exitCode()
-def main(env=None):
- if env is not None:
- taurus.info('ignoring obsolete env parameter to qtdesigner_start')
-
- version = "taurusdesigner %s" % (taurus.Release.version)
- usage = "Usage: %prog [options] <ui file(s)>"
- description = "The Qt designer application customized for taurus"
- parser = optparse.OptionParser(
- version=version, usage=usage, description=description)
- parser.add_option("--taurus-path", dest="tauruspath", default="",
- help="additional directories to look for taurus widgets")
- parser.add_option("--qt-designer-path", dest="pyqtdesignerpath", default="",
- help="additional directories to look for python qt widgets")
-
- options, args = parser.parse_args()
-
- taurus_extra_path = None
- # Set TAURUSQTDESIGNERPATH
- if len(options.tauruspath) > 0:
- taurus_extra_path = options.tauruspath
-
- if env is None:
- env = get_taurus_designer_env(taurus_extra_path=taurus_extra_path)
+@click.command('designer')
+@click.argument('ui_files', nargs=-1)
+@click.option("--taurus-path", "tauruspath",
+ metavar='TAURUSPATH',
+ default=None,
+ help="additional directories to look for taurus widgets")
+def designer_cmd(ui_files, tauruspath):
+ """Launch a Taurus-customized Qt Designer application"""
- sys.exit(qtdesigner_start(args, env=env))
+ env = get_taurus_designer_env(taurus_extra_path=tauruspath)
+ sys.exit(qtdesigner_start(ui_files, env=env))
if __name__ == "__main__":
- main()
+ designer_cmd()
diff --git a/lib/taurus/qt/qtdesigner/tauruspluginplugin.py b/lib/taurus/qt/qtdesigner/tauruspluginplugin.py
index 2abb98f9..5a875ffe 100644
--- a/lib/taurus/qt/qtdesigner/tauruspluginplugin.py
+++ b/lib/taurus/qt/qtdesigner/tauruspluginplugin.py
@@ -32,8 +32,7 @@ from taurus.external.qt import QtDesigner
def build_qtdesigner_widget_plugin(klass):
- #from . import taurusplugin # - after futurize stage 1
- import taurusplugin.taurusplugin as taurusplugin # + after futurize stage 1
+ from taurus.qt.qtdesigner.taurusplugin import taurusplugin
class Plugin(taurusplugin.TaurusWidgetPlugin):
WidgetClass = klass
diff --git a/lib/taurus/qt/qtgui/__init__.py b/lib/taurus/qt/qtgui/__init__.py
index 85e7ce55..d4fe4fe3 100644
--- a/lib/taurus/qt/qtgui/__init__.py
+++ b/lib/taurus/qt/qtgui/__init__.py
@@ -36,7 +36,8 @@ import sys
import glob
import pkg_resources
from taurus import tauruscustomsettings as __S
-from taurus import debug as __debug
+from taurus import info as __info
+from taurus import warning as __warning
__docformat__ = 'restructuredtext'
@@ -63,11 +64,12 @@ for __p in pkg_resources.iter_entry_points('taurus.qt.qtgui'):
setattr(sys.modules[__name__], __p.name, __mod)
# Add it to sys.modules
sys.modules[__modname] = __mod
- __debug('Plugin "%s" loaded as "%s"', __p.module_name, __modname)
+ __info('Plugin "%s" loaded as "%s"', __p.module_name, __modname)
except Exception as e:
- __debug('Could not load plugin "%s". Reason: %s', __p.module_name, e)
+ __warning('Could not load plugin "%s". Reason: %s', __p.module_name, e)
# ------------------------------------------------------------------------
-del os, glob, __icon, icon_dir, pkg_resources, sys, __mod, __modname, __debug
+del (os, glob, __icon, icon_dir, pkg_resources, sys, __mod, __modname, __info,
+ __warning)
diff --git a/lib/taurus/qt/qtgui/application/taurusapplication.py b/lib/taurus/qt/qtgui/application/taurusapplication.py
index 07a6c127..40eea105 100644
--- a/lib/taurus/qt/qtgui/application/taurusapplication.py
+++ b/lib/taurus/qt/qtgui/application/taurusapplication.py
@@ -37,7 +37,6 @@ import threading
from taurus.external.qt import Qt
from taurus.core.util.log import LogExceptHook, Logger
-import taurus.core.util.argparse
__all__ = ["TaurusApplication"]
@@ -123,64 +122,45 @@ class STD(Logger):
class TaurusApplication(Qt.QApplication, Logger):
- """A QApplication that additionally parses the command line looking
- for taurus options. This is done using the
- :mod:`taurus.core.util.argparse`.
- To create a TaurusApplication object you should use the same parameters
- as in QApplication.
+ """A QApplication that performs some taurus-specific initializations
+ and (optionally but deprecated) also parses the command line for taurus
+ options.
The optional keyword parameters:
- app_name: (str) application name
- app_version: (str) application version
- org_name: (str) organization name
- org_domain: (str) organization domain
+ - cmd_line_parser (None [or DEPRECATED :class:`optparse.OptionParser`])
- ...And at last the 'cmd_line_parser' which should be an instance of
- :class:`optparse.OptionParser`. Simple example::
+ If cmd_line_parser is explicitly set to None (recommended), no parsing will
+ be done at all. If a :class:`optparse.OptionParser` instance is passed as
+ cmd_line_parser (deprecated), it will be used for parsing the command line
+ arguments. If it is not explicitly passed (not recommended), a default
+ parser will be assumed with the default taurus options.
- import sys
- import taurus.qt.qtgui.application
- import taurus.qt.qtgui.display
-
- app = taurus.qt.qtgui.application.TaurusApplication()
-
- w = taurus.qt.qtgui.display.TaurusLabel()
- w.model = 'sys/tg_test/1/double_scalar'
- w.show()
-
- sys.exit(app.exec_())
-
- A more complex example showing how to add options and a usage help::
+ Simple example::
import sys
- import taurus.core.util.argparse
- import taurus.qt.qtgui.application
+ from taurus.qt.qtgui.application import TaurusApplication
import taurus.qt.qtgui.display
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.usage = "%prog [options] <model>"
- parser.add_option("--hello")
-
- app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser)
- args = app.get_command_line_args()
- if len(args) < 1:
- sys.stderr.write("Need to supply model attribute")
- sys.exit(1)
+ app = TaurusApplication(cmd_line_parser=None)
w = taurus.qt.qtgui.display.TaurusLabel()
- w.model = args[1]
+ w.model = 'sys/tg_test/1/double_scalar'
w.show()
sys.exit(app.exec_())
- For more details on taurus command line parsing check
- :mod:`taurus.core.util.argparse`.
"""
def __init__(self, *args, **kwargs):
"""The constructor. Parameters are the same as QApplication plus a
- keyword parameter: 'cmd_line_parser' which should be an instance of
- :class:`optparse.OptionParser`"""
+ keyword parameter: 'cmd_line_parser' which should be None or an
+ instance of :class:`optparse.OptionParser`. If cmd_line_parser is None
+ no command line parsing will be done ()
+ """
# lock to safely get singleton elements (like IPython taurus
# console app)
@@ -189,18 +169,11 @@ class TaurusApplication(Qt.QApplication, Logger):
if len(args) == 0:
args = getattr(sys, 'argv', []),
- parser = None
- app_name, app_version, org_name, org_domain = None, None, None, None
- if 'app_name' in kwargs:
- app_name = kwargs.pop('app_name')
- if 'app_version' in kwargs:
- app_version = kwargs.pop('app_version')
- if 'org_name' in kwargs:
- org_name = kwargs.pop('org_name')
- if 'org_domain' in kwargs:
- org_domain = kwargs.pop('org_domain')
- if 'cmd_line_parser' in kwargs:
- parser = kwargs.pop('cmd_line_parser')
+ app_name = kwargs.pop('app_name', None)
+ app_version = kwargs.pop('app_version', None)
+ org_name = kwargs.pop('org_name', None)
+ org_domain = kwargs.pop('org_domain', None)
+ parser = kwargs.pop('cmd_line_parser', optparse.OptionParser())
#######################################################################
# Workaround for XInitThreads-related crash.
@@ -235,21 +208,21 @@ class TaurusApplication(Qt.QApplication, Logger):
if org_domain is not None:
self.setOrganizationDomain(org_domain)
- # if the constructor was called without a parser or with a parser that
- # doesn't contain version information and with an application
- # name and/or version, then add the --version capability
- if (parser is None or parser.version is None) and app_version:
- v = app_version
- if app_name:
- v = app_name + " " + app_version
- if parser is None:
- parser = optparse.OptionParser(version=v)
- elif parser.version is None:
+ if parser is None:
+ p, opt, args = None, None, None
+ else:
+ if parser.version is None and app_version:
+ # if the parser does not contain version information
+ # but we have an application version, add the
+ # --version capability
+ v = app_version
+ if app_name:
+ v = app_name + " " + app_version
parser.version = v
parser._add_version_option()
- p, opt, args = \
- taurus.core.util.argparse.init_taurus_args(
+ import taurus.core.util.argparse
+ p, opt, args = taurus.core.util.argparse.init_taurus_args(
parser=parser, args=args[0][1:])
self._cmd_line_parser = p
@@ -306,6 +279,7 @@ class TaurusApplication(Qt.QApplication, Logger):
:return: the parser used in the command line
:rtype: :class:`optparse.OptionParser`"""
+ # TODO: issue a warning if this is uninitialized (cmd_line_parser=None)
return self._cmd_line_parser
def get_command_line_options(self):
@@ -314,6 +288,7 @@ class TaurusApplication(Qt.QApplication, Logger):
:return: the command line options
:rtype: :class:`optparse.Option`"""
+ # TODO: issue a warning if this is uninitialized (cmd_line_parser=None)
return self._cmd_line_options
def get_command_line_args(self):
@@ -322,6 +297,7 @@ class TaurusApplication(Qt.QApplication, Logger):
:return: the command line arguments
:rtype: list of strings"""
+ # TODO: issue a warning if this is uninitialized (cmd_line_parser=None)
return self._cmd_line_args
def setTaurusStyle(self, styleName):
diff --git a/lib/taurus/qt/qtgui/base/taurusbase.py b/lib/taurus/qt/qtgui/base/taurusbase.py
index 931b6d60..8ffd6206 100644
--- a/lib/taurus/qt/qtgui/base/taurusbase.py
+++ b/lib/taurus/qt/qtgui/base/taurusbase.py
@@ -47,7 +47,7 @@ from taurus.core.tauruslistener import TaurusListener, TaurusExceptionListener
from taurus.core.taurusoperation import WriteAttrOperation
from taurus.core.util.eventfilters import filterEvent
from taurus.core.util.log import deprecation_decorator
-from taurus.qt.qtcore.util.signal import baseSignal
+from taurus.qt.qtcore.util import baseSignal
from taurus.qt.qtcore.configuration import BaseConfigurableClass
from taurus.qt.qtcore.mimetypes import TAURUS_ATTR_MIME_TYPE
from taurus.qt.qtcore.mimetypes import TAURUS_DEV_MIME_TYPE
@@ -110,7 +110,7 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
taurusEvent = baseSignal('taurusEvent', object, object, object)
- def __init__(self, name='', parent=None, designMode=False):
+ def __init__(self, name='', parent=None, designMode=False, **kwargs):
"""Initialization of TaurusBaseComponent"""
self.modelObj = None
self.modelName = ''
@@ -121,8 +121,12 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
BaseConfigurableClass.__init__(self)
- self.taurusMenu = None
- self.taurusMenuData = ''
+ # --------------------------------------------------------------
+ # Deprecated API for context menu
+ self.taurusMenu = None # deprecated since 4.5.3a. Do not use
+ self.taurusMenuData = '' # deprecated since 4.5.3a. Do not use
+ self.__explicitPopupMenu = False
+ # --------------------------------------------------------------
# attributes storing property values
self._format = None
@@ -165,6 +169,12 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
'formatter')
self.resetModelInConfig()
+ # connect taurusEvent signal to filterEvent
+ try:
+ self.taurusEvent.connect(self.filterEvent)
+ except Exception as e:
+ self.warning('Could not connect taurusEvent signal: %r', e)
+
@deprecation_decorator(rel='4.0')
def getSignaller(self):
return self
@@ -213,18 +223,39 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
return taurus.Factory(scheme)
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
- # Popup menu behavior
+ # Context menu behavior
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
def contextMenuEvent(self, event):
- """Handle the popup menu event
+ """
+ DEPRECATED:
+ Until v4.5.3a, the default implementation of contextMenuEvent showed
+ the content of taurusMenu as a context menu. But this resulted in
+ unwanted behaviour when the widget already implemented its own context
+ menu (see https://github.com/taurus-org/taurus/issues/905 )
- :param event: the popup menu event
+ Therefore this feature was disabled in 4.5.3a.
+
+ If you still want to show the contents of taurusMenu as a context menu,
+ you can explicitly reimplement the contextMenuEvent method as::
+
+ def contextMenuEvent(self, event):
+ self.taurusMenu.exec_(event.globalPos())
"""
if self.taurusMenu is not None:
- self.taurusMenu.exec_(event.globalPos())
- else:
- event.ignore()
+ if self.__explicitPopupMenu:
+ # bck-compat: show taurusMenu as a contextMenu if it was
+ # explicitly created via the (deprecated) "setTaurusPopupMenu"
+ # API
+ self.taurusMenu.exec_(event.globalPos())
+ return
+ else:
+ self.deprecated(
+ dep='taurusMenu context Menu API',
+ alt='custom contextMenuEvent to show taurusMenu',
+ rel='4.5.3a'
+ )
+ event.ignore()
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# Mandatory methods to be implemented in subclass implementation
@@ -895,15 +926,11 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
def preAttach(self):
"""Called inside self.attach() before actual attach is performed.
- Default implementation just emits a signal.
+ Default implementation does nothing.
Override when necessary.
"""
- try:
- self.taurusEvent.connect(self.filterEvent)
- except:
- # self.error("In %s.preAttach() ... failed!" % str(type(self)))
- pass
+ pass
def postAttach(self):
"""Called inside self.attach() after actual attach is performed.
@@ -915,15 +942,11 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
def preDetach(self):
"""Called inside self.detach() before actual deattach is performed.
- Default implementation just disconnects a signal.
+ Default implementation does nothing.
Override when necessary.
"""
- try:
- self.taurusEvent.disconnect(self.filterEvent)
- except:
- # self.error("In %s.preDetach() ... failed!" % str(type(self)))
- pass
+ pass
def postDetach(self):
"""Called inside self.detach() after actual deattach is performed.
@@ -1238,14 +1261,18 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
"""Resets the showing of the display value to True"""
self.setShowText(True)
+ @deprecation_decorator(rel='4.5.3a')
def setTaurusPopupMenu(self, menuData):
"""Sets/unsets the taurus popup menu
:param menuData: (str) an xml representing the popup menu"""
self.taurusMenuData = str(menuData)
+ self.__explicitPopupMenu = True
factory = ActionFactory()
self.taurusMenu = factory.getNewMenu(self, self.taurusMenuData)
+
+ @deprecation_decorator(rel='4.5.3a')
def getTaurusPopupMenu(self):
"""Returns an xml string representing the current taurus popup menu
@@ -1253,9 +1280,11 @@ class TaurusBaseComponent(TaurusListener, BaseConfigurableClass):
"""
return self.taurusMenuData
+ @deprecation_decorator(rel='4.5.3a')
def resetTaurusPopupMenu(self):
"""Resets the taurus popup menu to empty"""
self.taurusMenuData = ''
+ self.__explicitPopupMenu = False
def isModifiableByUser(self):
'''whether the user can change the contents of the widget
@@ -1306,7 +1335,7 @@ class TaurusBaseWidget(TaurusBaseComponent):
_dragEnabled = False
- def __init__(self, name='', parent=None, designMode=False):
+ def __init__(self, name='', parent=None, designMode=False, **kwargs):
self._disconnect_on_hide = False
self._supportedMimeTypes = None
self._autoTooltip = True
@@ -1727,7 +1756,7 @@ class TaurusBaseWidget(TaurusBaseComponent):
formats = mimeData.formats()
for mtype in supported:
if mtype in formats:
- d = bytes(mimeData.data(mtype))
+ d = bytes(mimeData.data(mtype)).decode('utf-8')
if d is None:
return None
try:
@@ -1910,7 +1939,8 @@ class TaurusBaseWritableWidget(TaurusBaseWidget):
applied = baseSignal('applied')
- def __init__(self, name='', taurus_parent=None, designMode=False):
+ def __init__(self, name='', taurus_parent=None, designMode=False,
+ **kwargs):
self.call__init__(TaurusBaseWidget, name,
parent=taurus_parent, designMode=designMode)
diff --git a/lib/taurus/qt/qtgui/button/qbuttonbox.py b/lib/taurus/qt/qtgui/button/qbuttonbox.py
index dc364620..4de8f98c 100644
--- a/lib/taurus/qt/qtgui/button/qbuttonbox.py
+++ b/lib/taurus/qt/qtgui/button/qbuttonbox.py
@@ -118,7 +118,7 @@ if __name__ == "__main__":
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
bb = QButtonBox()
bb.okClicked.connect(on_ok)
bb.cancelClicked.connect(on_cancel)
diff --git a/lib/taurus/qt/qtgui/button/taurusbutton.py b/lib/taurus/qt/qtgui/button/taurusbutton.py
index 9649065e..6489549d 100644
--- a/lib/taurus/qt/qtgui/button/taurusbutton.py
+++ b/lib/taurus/qt/qtgui/button/taurusbutton.py
@@ -31,7 +31,7 @@ from builtins import map
from builtins import str
from future.utils import string_types
-from taurus.external.qt import Qt
+from taurus.external.qt import Qt, compat
from taurus.core.taurusbasetypes import LockStatus, TaurusLockInfo
from taurus.core.taurusdevice import TaurusDevice
from taurus.qt.qtgui.base import TaurusBaseWidget
@@ -265,7 +265,7 @@ class TaurusCommandButton(Qt.QPushButton, TaurusBaseWidget):
.. seealso:: :class:`TaurusCommandsForm` provides a good example of use of
TaurusCommandButton (including managing the return value) '''
# TODO: tango-centric
- commandExecuted = Qt.pyqtSignal(object)
+ commandExecuted = Qt.pyqtSignal(compat.PY_OBJECT)
def __init__(self, parent=None, designMode=False, command=None,
parameters=None, icon=None, text=None,
@@ -659,7 +659,7 @@ def commandButtonMain():
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
form = TaurusCommandButton(parent=None, designMode=False, command='DevBoolean', parameters=[
123], icon='logos:taurus.png', text='launch: DevBoolean 123')
form.setModel('sys/tg_test/1')
@@ -677,7 +677,7 @@ def launcherButtonMain():
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
# Creating button giving the widget
# from taurus.qt.qtgui.plot import TaurusPlot
diff --git a/lib/taurus/qt/qtgui/compact/abstractswitcher.py b/lib/taurus/qt/qtgui/compact/abstractswitcher.py
index 610eea45..8459c29b 100644
--- a/lib/taurus/qt/qtgui/compact/abstractswitcher.py
+++ b/lib/taurus/qt/qtgui/compact/abstractswitcher.py
@@ -336,7 +336,7 @@ def demo1():
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.input import TaurusValueLineEdit
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w = TaurusReadWriteSwitcher(readWClass=TaurusLabel,
writeWClass=TaurusValueLineEdit)
@@ -359,7 +359,7 @@ def demo2():
writeWClass = TaurusValueLineEdit
exitEditTriggers = ('editingFinished()', Qt.Qt.Key_Escape)
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
f = TaurusForm()
f.model = ['sys/tg_test/1/long_scalar', 'sys/tg_test/1/long_scalar']
@@ -379,7 +379,7 @@ def demo3():
from taurus.qt.qtgui.display import TaurusLabel, TaurusLed
from taurus.qt.qtgui.input import TaurusValueLineEdit, TaurusValueCheckBox
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w1 = TaurusReadWriteSwitcher(readWClass=TaurusLabel,
writeWClass=TaurusValueLineEdit)
diff --git a/lib/taurus/qt/qtgui/compact/basicswitcher.py b/lib/taurus/qt/qtgui/compact/basicswitcher.py
index b21f371f..3a029a54 100644
--- a/lib/taurus/qt/qtgui/compact/basicswitcher.py
+++ b/lib/taurus/qt/qtgui/compact/basicswitcher.py
@@ -59,7 +59,7 @@ def _demo():
from taurus.qt.qtgui.panel import TaurusForm
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
f = TaurusForm()
f.model = ['sys/tg_test/1/long_scalar', 'sys/tg_test/1/long_scalar',
diff --git a/lib/taurus/qt/qtgui/container/taurusmainwindow.py b/lib/taurus/qt/qtgui/container/taurusmainwindow.py
index 8464dcd8..3bf50b9e 100644
--- a/lib/taurus/qt/qtgui/container/taurusmainwindow.py
+++ b/lib/taurus/qt/qtgui/container/taurusmainwindow.py
@@ -187,35 +187,62 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
perspectiveChanged = Qt.pyqtSignal('QString')
# customization options:
- # blinking semi-period in ms. Set to None for not showing the Heart beat
- # LED
- _heartbeat = 1500
- _showFileMenu = True
- _showViewMenu = True
- _showTaurusMenu = True
- _showToolsMenu = True
- _showHelpMenu = True
- # Allows the user to change/create/delete perspectives
- _supportUserPerspectives = True
- _showLogger = True
- #
- # set to None for disabling splash screen
- _splashLogo = "large:TaurusSplash.png"
- _splashMessage = "Initializing Main window..."
+ #: Heartbeat LED blinking semi-period in ms. Set to None for not showing it
+ HEARTBEAT = 1500
+ #: Whether to show the File menu
+ FILE_MENU_ENABLED = True
+ #: Whether to show the View menu
+ VIEW_MENU_ENABLED = True
+ #: Whether to show the Taurus menu
+ TAURUS_MENU_ENABLED = True
+ #: Whether to show the Tools menu
+ TOOLS_MENU_ENABLED = True
+ #: Whether to show the Help menu
+ HELP_MENU_ENABLED = True
+ #: Whether to show the Full Screen Toolbar
+ FULLSCREEN_TOOLBAR_ENABLED = True
+ #: Whether to show actions for user perspectives
+ USER_PERSPECTIVES_ENABLED = True
+ #: Whether add a dockwidget with the logger widget
+ LOGGER_WIDGET_ENABLED = True
+ #: Name of logo image for splash screen. Set to None for disabling splash
+ SPLASH_LOGO_NAME = "large:TaurusSplash.png"
+ #: Message for splash screen
+ SPLASH_MESSAGE = "Initializing Main window..."
+
+ _old_options_api = {
+ '_heartbeat': 'HEARTBEAT',
+ '_showFileMenu': 'FILE_MENU_ENABLED',
+ '_showViewMenu': 'VIEW_MENU_ENABLED',
+ '_showTaurusMenu': 'TAURUS_MENU_ENABLED',
+ '_showToolsMenu': 'TOOLS_MENU_ENABLED',
+ '_showHelpMenu': 'HELP_MENU_ENABLED',
+ '_showLogger': 'LOGGER_WIDGET_ENABLED',
+ '_supportUserPerspectives': 'USER_PERSPECTIVES_ENABLED',
+ '_splashLogo': 'SPLASH_LOGO_NAME',
+ '_splashMessage': 'SPLASH_MESSAGE',
+ }
def __init__(self, parent=None, designMode=False, splash=None):
name = self.__class__.__name__
self.call__init__wo_kw(Qt.QMainWindow, parent)
self.call__init__(TaurusBaseContainer, name, designMode=designMode)
+
+ # Provide bck-compat with old options API
+ for old, new in self._old_options_api.items():
+ if hasattr(self, old):
+ self.deprecated(dep=old, alt=new, rel='4.5.3a')
+ setattr(self, new, getattr(self, old))
+
if splash is None:
- splash = bool(self._splashLogo)
+ splash = bool(self.SPLASH_LOGO_NAME)
self.__splashScreen = None
if splash and not designMode:
self.__splashScreen = Qt.QSplashScreen(
- Qt.QPixmap(self._splashLogo))
+ Qt.QPixmap(self.SPLASH_LOGO_NAME))
self.__splashScreen.show()
- self.__splashScreen.showMessage(self._splashMessage)
+ self.__splashScreen.showMessage(self.SPLASH_MESSAGE)
self.__tangoHost = ""
self.__settings = None
@@ -224,10 +251,12 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
self.helpManualDW = None
self.helpManualBrowser = None
- self.resetHelpManualURI()
+
+ if self.HELP_MENU_ENABLED:
+ self.resetHelpManualURI()
# Heartbeat
- if self._heartbeat is not None:
+ if self.HEARTBEAT is not None:
from taurus.qt.qtgui.display import QLed
self.heartbeatLed = QLed()
self.heartbeatLed.setToolTip(
@@ -244,34 +273,49 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
self.__createActions()
# logger dock widget
- if self._showLogger:
+ if self.LOGGER_WIDGET_ENABLED:
self.addLoggerWidget()
# Create Menus
- if self._showFileMenu: # File menu
+ if self.FILE_MENU_ENABLED: # File menu
self.createFileMenu()
- if self._showViewMenu: # View menu
+ if self.VIEW_MENU_ENABLED: # View menu
self.createViewMenu()
- if self._showTaurusMenu: # Taurus Menu
+ if self.TAURUS_MENU_ENABLED: # Taurus Menu
self.createTaurusMenu()
- if self._showToolsMenu: # Tools Menu
+ if self.TOOLS_MENU_ENABLED: # Tools Menu
self.createToolsMenu()
- if self._showHelpMenu: # Help Menu
+ if self.HELP_MENU_ENABLED: # Help Menu
self.createHelpMenu()
# View Toolbar
- self.viewToolBar = self.addToolBar("View")
- self.viewToolBar.setObjectName("viewToolBar")
- self.viewToolBar.addAction(self.toggleFullScreenAction)
+ if self.FULLSCREEN_TOOLBAR_ENABLED:
+ self.viewToolBar = self.addToolBar("View")
+ self.viewToolBar.setObjectName("viewToolBar")
+ self.viewToolBar.addAction(self.toggleFullScreenAction)
# Perspectives Toolbar
- if self._supportUserPerspectives:
+ if self.USER_PERSPECTIVES_ENABLED:
self.createPerspectivesToolBar()
# disable the configuration action if there is nothing to configure
self.configurationAction.setEnabled(
self.configurationDialog._tabwidget.count())
+ def __setattr__(self, key, value):
+ super(TaurusMainWindow, self).__setattr__(key, value)
+ if key in self._old_options_api:
+ new = self._old_options_api[key]
+ setattr(self, new, value)
+ self.deprecated(dep=key, alt=new, rel='4.5.3a')
+
+ def contextMenuEvent(self, event):
+ """Reimplemented to avoid deprecation warning related to:
+ https://github.com/taurus-org/taurus/issues/905
+ """
+ # TODO: Remove this once the deprecation of the Popup menu is enforced
+ event.ignore()
+
def addLoggerWidget(self, hidden=True):
'''adds a QLoggingWidget as a dockwidget of the main window (and hides it by default)'''
from taurus.qt.qtgui.table import QLoggingWidget
@@ -286,7 +330,7 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
def createFileMenu(self):
'''adds a "File" Menu'''
self.fileMenu = self.menuBar().addMenu("File")
- if self._supportUserPerspectives:
+ if self.USER_PERSPECTIVES_ENABLED:
self.fileMenu.addAction(self.importSettingsFileAction)
self.fileMenu.addAction(self.exportSettingsFileAction)
# self.fileMenu.addAction(self.resetSettingsAction)
@@ -296,12 +340,12 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
def createViewMenu(self):
'''adds a "View" Menu'''
self.viewMenu = self.menuBar().addMenu("View")
- if self._showLogger:
+ if self.LOGGER_WIDGET_ENABLED:
self.viewMenu.addAction(self.__loggerDW.toggleViewAction())
self.viewToolBarsMenu = self.viewMenu.addMenu("Tool Bars")
self.viewMenu.addSeparator()
self.viewMenu.addAction(self.toggleFullScreenAction)
- if self._supportUserPerspectives:
+ if self.USER_PERSPECTIVES_ENABLED:
self.viewMenu.addSeparator()
self.perspectivesMenu = Qt.QMenu("Load Perspectives", self)
self.viewMenu.addMenu(self.perspectivesMenu)
@@ -341,7 +385,7 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
pbutton.setMenu(self.perspectivesMenu)
self.perspectivesToolBar.addWidget(pbutton)
self.perspectivesToolBar.addAction(self.savePerspectiveAction)
- if self._showViewMenu:
+ if self.VIEW_MENU_ENABLED:
self.viewToolBarsMenu.addAction(
self.perspectivesToolBar.toggleViewAction())
@@ -351,9 +395,10 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
.. note:: This method may need be called by derived classes at the end
of their initialization.
- :return: (QMenu) the updated perspectives menu (or None if self._supportUserPerspectives is False)
+ :return: (QMenu) the updated perspectives menu (or None if
+ self.USER_PERSPECTIVES_ENABLED is False)
'''
- if not self._supportUserPerspectives:
+ if not self.USER_PERSPECTIVES_ENABLED:
return None
self.perspectivesMenu.clear()
for pname in self.getPerspectivesList():
@@ -641,8 +686,10 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
ba = settings.value("TaurusConfig") or Qt.QByteArray()
self.applyQConfig(ba)
except Exception as e:
- msg = 'Problem loading configuration from "%s". Some settings may not be restored.\n Details: %s' % (
- str(settings.fileName()), repr(e))
+ msg = ('Problem loading configuration from "{}". '
+ + 'Some settings may not be restored.\n'
+ + ' Reason: {}'
+ ).format(str(settings.fileName()), e)
self.error(msg)
Qt.QMessageBox.warning(
self, 'Error Loading settings', msg, Qt.QMessageBox.Ok)
@@ -673,6 +720,10 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
saved (no prefix by default)
'''
settings = self.getQSettings()
+ if not settings.isWritable():
+ self.info('Settings cannot be saved in "%s"', settings.fileName())
+ return
+
if group is not None:
settings.beginGroup(group)
# main window geometry
@@ -683,7 +734,7 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
settings.setValue("TaurusConfig", self.createQConfig())
if group is not None:
settings.endGroup()
- self.info('MainWindow settings saved in "%s"' % settings.fileName())
+ self.info('Settings saved in "%s"' % settings.fileName())
@Qt.pyqtSlot()
@Qt.pyqtSlot('QString')
@@ -878,12 +929,12 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
self.extAppsBar.setObjectName("External Applications")
self.extAppsBar.setToolButtonStyle(
Qt.Qt.ToolButtonTextBesideIcon)
- if self._showViewMenu:
+ if self.VIEW_MENU_ENABLED:
self.viewToolBarsMenu.addAction(
self.extAppsBar.toggleViewAction())
self.extAppsBar.addAction(extapp)
- if toMenu and self._showToolsMenu:
+ if toMenu and self.TOOLS_MENU_ENABLED:
if self.toolsMenu is None:
self.createToolsMenu()
self.externalAppsMenu.addAction(extapp)
@@ -1059,7 +1110,7 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
def resetHeartbeat(self):
'''resets the heartbeat interval'''
- self.setHeartbeat(self.__class__._heartbeat)
+ self.setHeartbeat(self.__class__.HEARTBEAT)
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# Public slots for apply/restore changes
@@ -1106,24 +1157,24 @@ class TaurusMainWindow(Qt.QMainWindow, TaurusBaseContainer):
if __name__ == "__main__":
- import taurus.qt.qtgui.application
- app = taurus.qt.qtgui.application.TaurusApplication()
+ from taurus.qt.qtgui.application import TaurusApplication
+ app = TaurusApplication(cmd_line_parser=None)
app.setApplicationName('TaurusMainWindow-test')
app.setOrganizationName('ALBA')
app.basicConfig()
class MyMainWindow(TaurusMainWindow):
- _heartbeat = 300 # blinking semi-period in ms. Set to None for not showing the Heart beat LED
- _showFileMenu = True
- _showViewMenu = True
- _showTaurusMenu = False
- _showToolsMenu = True
- _showHelpMenu = True
+ HEARTBEAT = 300 # blinking semi-period in ms. Set to None for not showing the Heart beat LED
+ FILE_MENU_ENABLED = True
+ VIEW_MENU_ENABLED = True
+ TAURUS_MENU_ENABLED = False
+ TOOLS_MENU_ENABLED = True
+ HELP_MENU_ENABLED = True
# Allows the user to change/create/delete perspectives
- _supportUserPerspectives = True
- _showLogger = True
+ USER_PERSPECTIVES_ENABLED = True
+ LOGGER_WIDGET_ENABLED = True
# set to None for disabling splash screen
- _splashLogo = "large:TaurusSplash.png"
+ SPLASH_LOGO_NAME = "large:TaurusSplash.png"
_splashMessage = "Initializing Main window..."
def __init__(self):
diff --git a/lib/taurus/qt/qtgui/display/qled.py b/lib/taurus/qt/qtgui/display/qled.py
index 0cb1e040..799c3020 100644
--- a/lib/taurus/qt/qtgui/display/qled.py
+++ b/lib/taurus/qt/qtgui/display/qled.py
@@ -383,7 +383,7 @@ def main():
if owns_app:
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
w = Qt.QWidget()
layout = Qt.QGridLayout()
diff --git a/lib/taurus/qt/qtgui/display/qlogo.py b/lib/taurus/qt/qtgui/display/qlogo.py
index d2664a0e..5510d29b 100644
--- a/lib/taurus/qt/qtgui/display/qlogo.py
+++ b/lib/taurus/qt/qtgui/display/qlogo.py
@@ -82,7 +82,7 @@ def main():
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
w = QLogo()
w.show()
sys.exit(app.exec_())
diff --git a/lib/taurus/qt/qtgui/display/test/test_tauruslabel.py b/lib/taurus/qt/qtgui/display/test/test_tauruslabel.py
index bedc02be..e231faa3 100644
--- a/lib/taurus/qt/qtgui/display/test/test_tauruslabel.py
+++ b/lib/taurus/qt/qtgui/display/test/test_tauruslabel.py
@@ -34,6 +34,8 @@ from taurus.qt.qtgui.container import TaurusWidget
from taurus.core.tango.test import TangoSchemeTestLauncher
import functools
from taurus.core.util.colors import ATTRIBUTE_QUALITY_DATA, DEVICE_STATE_DATA
+from pint import UnitRegistry as ur
+import numpy
DEV_NAME = TangoSchemeTestLauncher.DEV_NAME
@@ -102,7 +104,9 @@ testOldFgroles = functools.partial(insertTest, helper_name='text', maxdepr=1,
# ------------------------------------------------------------------------------
@insertTest(helper_name='text',
model='tango:' + DEV_NAME + '/double_image#rvalue[1,::2]',
- expected='[ 1.23 1.23] mm')
+ expected='{:~}'.format(numpy.array([1.23,1.23])*ur().mm)
+ # expected is not explicit to support pint v<0.8 particularities
+ )
@insertTest(helper_name='text',
model='tango:' + DEV_NAME + '/double_spectrum#rvalue[1]',
expected='1.23 mm')
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/cli.py b/lib/taurus/qt/qtgui/extra_guiqwt/cli.py
new file mode 100644
index 00000000..1a00f8df
--- /dev/null
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/cli.py
@@ -0,0 +1,42 @@
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+import click
+
+
+from .plot import image_cmd
+from .taurustrend2d import trend2d_cmd
+
+
+@click.group('guiqwt')
+def guiqwt():
+ """guiqwt related commands (image, trend2d)"""
+ pass
+
+
+guiqwt.add_command(image_cmd)
+guiqwt.add_command(trend2d_cmd)
+
+if __name__ == '__main__':
+ guiqwt()
+
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/curve.py b/lib/taurus/qt/qtgui/extra_guiqwt/curve.py
index 18f3d6bf..a4cf9df4 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/curve.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/curve.py
@@ -30,7 +30,7 @@ from builtins import next
from taurus.external.qt import Qt
from taurus.qt.qtgui.base import TaurusBaseComponent
-from taurus.qt.qtcore.util.signal import baseSignal
+from taurus.qt.qtcore.util import baseSignal
import taurus
from guiqwt.curve import CurveItem
from taurus.qt.qtgui.extra_guiqwt.styles import TaurusCurveParam, TaurusTrendParam
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/curvesmodel.py b/lib/taurus/qt/qtgui/extra_guiqwt/curvesmodel.py
index 8dc49bde..2175a284 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/curvesmodel.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/curvesmodel.py
@@ -30,6 +30,7 @@ curvesmodel Model and view for new CurveItem configuration
from __future__ import print_function
from builtins import next
from builtins import str
+from builtins import bytes
from builtins import range
from builtins import object
@@ -320,11 +321,12 @@ class TaurusCurveItemTableModel(Qt.QAbstractTableModel):
else:
column = parent.columnCount()
if data.hasFormat(TAURUS_ATTR_MIME_TYPE):
- self.setData(self.index(row, column),
- value=str(data.data(TAURUS_ATTR_MIME_TYPE)))
+ model = bytes(data.data(TAURUS_ATTR_MIME_TYPE)).decode("utf-8")
+ self.setData(self.index(row, column), value=model)
return True
elif data.hasFormat(TAURUS_MODEL_LIST_MIME_TYPE):
- models = str(data.data(TAURUS_MODEL_LIST_MIME_TYPE)).split()
+ d = bytes(data.data(TAURUS_MODEL_LIST_MIME_TYPE))
+ models = d.decode("utf-8").split()
if len(models) == 1:
self.setData(self.index(row, column), value=models[0])
return True
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/image.py b/lib/taurus/qt/qtgui/extra_guiqwt/image.py
index 1781043f..885b19a9 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/image.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/image.py
@@ -33,7 +33,7 @@ __all__ = ["TaurusImageItem", "TaurusRGBImageItem", "TaurusTrend2DItem",
from taurus.core.units import Quantity
from taurus.external.qt import Qt
from taurus.qt.qtgui.base import TaurusBaseComponent
-from taurus.qt.qtcore.util.signal import baseSignal
+from taurus.qt.qtcore.util import baseSignal
import taurus.core
from taurus.core.util.containers import ArrayBuffer
@@ -601,7 +601,7 @@ def test1():
from guiqwt.plot import ImageDialog
from taurus.qt.qtgui.extra_guiqwt.builder import make
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
# define a taurus image
#model1 = 'sys/tg_test/1/short_image_ro'
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/plot.py b/lib/taurus/qt/qtgui/extra_guiqwt/plot.py
index 2ec85ac9..8ba2579b 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/plot.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/plot.py
@@ -29,6 +29,7 @@ Extension of :mod:`guiqwt.plot`
from builtins import next
from builtins import str
+import click
import copy
from future.utils import string_types
@@ -62,7 +63,7 @@ class TaurusCurveDialog(CurveDialog, TaurusBaseWidget):
'''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
TaurusBaseWidget.__init__(self, 'TaurusCurveDialog')
- self.deprecated(rel='4.1', dep='TaurusCurveDialog', alt='TaurusPlot / taurusplot launcher')
+ self.deprecated(rel='4.1', dep='TaurusCurveDialog', alt='TaurusPlot / taurus tpg plot launcher')
self.setWindowFlags(Qt.Qt.Widget)
self._designMode = designMode
self._modelNames = CaselessList()
@@ -209,7 +210,7 @@ class TaurusTrendDialog(CurveDialog, TaurusBaseWidget):
'''see :class:`guiqwt.plot.CurveDialog` for other valid initialization parameters'''
CurveDialog.__init__(self, parent=parent, toolbar=toolbar, **kwargs)
TaurusBaseWidget.__init__(self, 'TaurusTrendDialog')
- self.deprecated(rel='4.1', dep='TaurusTrendDialog', alt='TaurusTrend / taurustrend launcher')
+ self.deprecated(rel='4.1', dep='TaurusTrendDialog', alt='TaurusTrend / taurus tpg trend launcher')
self.setWindowFlags(Qt.Qt.Widget)
self._designMode = designMode
self._modelNames = CaselessList()
@@ -627,49 +628,48 @@ def taurusTrendDlgMain():
sys.exit(app.exec_())
-def taurusImageDlgMain():
+@click.command('image')
+@click.argument('model', nargs=1, required=False)
+@click.option('-c', '--color-mode', 'color_mode',
+ type=click.Choice(['gray', 'rgb']),
+ default='gray',
+ show_default=True,
+ help=('Color mode expected from the attribute')
+ )
+@click.option("--demo", is_flag=True, help="show a demo of the widget")
+@click.option('--window-name', 'window_name',
+ default='TaurusPlot (qwt5)',
+ help='Name of the window')
+def image_cmd(model, color_mode, demo, window_name):
from taurus.qt.qtgui.application import TaurusApplication
- import taurus.core
import sys
- # prepare options
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.set_usage("%prog [options] <model>")
- parser.set_description(
- 'a Taurus application for plotting Image Attributes')
- parser.add_option("--demo", action="store_true", dest="demo",
- default=False, help="show a demo of the widget")
- parser.add_option("--rgb", action="store_true", dest="rgb_mode",
- default=False, help="assume image is RGB")
- parser.add_option("--window-name", dest="window_name",
- default="Taurus Image", help="Name of the window")
- app = TaurusApplication(
- cmd_line_parser=parser, app_name="Taurus Image Dialog", app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
+ app = TaurusApplication(cmd_line_parser=None,
+ app_name="Taurus Image Dialog")
- # check & process options
- if options.demo:
- if options.rgb_mode:
- args.append('eval:randint(0,256,(10,20,3))')
+ rgb_mode = (color_mode == 'rgb')
+
+ # TODO: is "-c rgb --demo" doing the right thing?? Check it.
+ if demo:
+ if color_mode == 'rgb':
+ model = 'eval:randint(0,256,(10,20,3))'
else:
- args.append('eval:rand(256,128)')
- w = TaurusImageDialog(wintitle=options.window_name)
+ model = 'eval:rand(256,128)'
- w.setRGBmode(options.rgb_mode)
+ w = TaurusImageDialog(wintitle=window_name)
+
+ w.setRGBmode(rgb_mode)
# set model
- if len(args) == 1:
- w.setModel(args[0])
- else:
- parser.print_help(sys.stderr)
- sys.exit(1)
+ if model:
+ w.setModel(model)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
- taurusCurveDlgMain()
+ image_cmd()
+ # taurusCurveDlgMain()
# taurusTrendDlgMain()
-# taurusImageDlgMain()
+ # taurusImageDlgMain()
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/taurustrend2d.py b/lib/taurus/qt/qtgui/extra_guiqwt/taurustrend2d.py
index af564905..90090ff4 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/taurustrend2d.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/taurustrend2d.py
@@ -28,6 +28,8 @@ taurustrend.py: Generic trend widget for Taurus
"""
__all__ = ["TaurusTrend2DDialog"]
+import click
+
from guiqwt.plot import ImageDialog
from taurus.external.qt import Qt
import taurus.core
@@ -306,68 +308,46 @@ class TaurusTrend2DDialog(ImageDialog, TaurusBaseWidget):
TaurusBaseWidget.resetModifiableByUser)
-def taurusTrend2DMain():
+@click.command('trend2d')
+@click.argument('model', nargs=1, required=False)
+@click.option("-x", "--x-axis-mode", "x_axis_mode",
+ type=click.Choice(['t', 'd', 'e']),
+ default='d',
+ show_default=True,
+ help=("interpret X values as timestamps (t), "
+ + "time deltas (d) or event numbers (e). ")
+ )
+@click.option('-b', '--buffer', 'max_buffer_size', type=int,
+ default=512,
+ show_default=True,
+ help=("maximum number of values to be stacked "
+ + "(when reached, the oldest values will be "
+ + "discarded)")
+ )
+@click.option("--demo", is_flag=True, help="show a demo of the widget")
+@click.option('--window-name', 'window_name',
+ default='TaurusPlot (qwt5)',
+ help='Name of the window')
+def trend2d_cmd(model, x_axis_mode, max_buffer_size,
+ demo, window_name):
from taurus.qt.qtgui.application import TaurusApplication
- import taurus.core
import sys
- # prepare options
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.set_usage("%prog [options] <model>")
- parser.set_description('a Taurus application for plotting trends of ' +
- 'arrays (aka "spectrograms")')
- parser.add_option("-x", "--x-axis-mode", dest="x_axis_mode", default='d',
- metavar="t|d|e",
- help=("interpret X values as timestamps (t), " +
- "time deltas (d) or event numbers (e). " +
- "Accepted values: t|d|e")
- )
- parser.add_option("-b", "--buffer", dest="max_buffer_size", default='512',
- help=("maximum number of values to be stacked " +
- "(when reached, the oldest values will be " +
- "discarded)")
- )
- parser.add_option("-a", "--use-archiving",
- action="store_true", dest="use_archiving", default=False)
- parser.add_option("--demo", action="store_true", dest="demo",
- default=False, help="show a demo of the widget")
- parser.add_option("--window-name", dest="window_name",
- default="Taurus Trend 2D", help="Name of the window")
-
- app = TaurusApplication(cmd_line_parser=parser, app_name="Taurus Trend 2D",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
-
- # check & process options
- stackModeMap = dict(t='datetime', d='deltatime', e='event')
- if options.x_axis_mode.lower() not in stackModeMap:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- stackMode = stackModeMap[options.x_axis_mode.lower()]
-
- if options.demo:
- args.append('eval:x=linspace(0,3,40);t=rand();sin(x+t)')
-
- w = TaurusTrend2DDialog(stackMode=stackMode, wintitle=options.window_name,
- buffersize=int(options.max_buffer_size))
-
- # set archiving
- if options.use_archiving:
- raise NotImplementedError('Archiving support is not yet implemented')
- w.setUseArchiving(True)
-
- # set model
- if len(args) == 1:
- w.setModel(args[0])
- else:
- parser.print_help(sys.stderr)
- sys.exit(1)
+ if demo:
+ model = 'eval:x=linspace(0,3,40);t=rand();sin(x+t)'
+
+ app = TaurusApplication(cmd_line_parser=None, app_name="Taurus Trend 2D")
+
+ stackMode = dict(t='datetime', d='deltatime', e='event')[x_axis_mode]
+
+ w = TaurusTrend2DDialog(stackMode=stackMode, wintitle=window_name,
+ buffersize=max_buffer_size)
+ if model:
+ w.setModel(model)
w.show()
sys.exit(app.exec_())
if __name__ == "__main__":
- taurusTrend2DMain()
+ trend2d_cmd()
diff --git a/lib/taurus/qt/qtgui/extra_guiqwt/tools.py b/lib/taurus/qt/qtgui/extra_guiqwt/tools.py
index 25920c4f..fa752fb5 100644
--- a/lib/taurus/qt/qtgui/extra_guiqwt/tools.py
+++ b/lib/taurus/qt/qtgui/extra_guiqwt/tools.py
@@ -355,7 +355,7 @@ def testTool(tool):
from taurus.qt.qtgui.application import TaurusApplication
from guiqwt.plot import CurveDialog
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
win = CurveDialog(edit=False, toolbar=True)
win.add_tool(tool)
win.show()
diff --git a/lib/taurus/qt/qtgui/extra_nexus/taurusnexuswidget.py b/lib/taurus/qt/qtgui/extra_nexus/taurusnexuswidget.py
index c5715f19..570e41c1 100644
--- a/lib/taurus/qt/qtgui/extra_nexus/taurusnexuswidget.py
+++ b/lib/taurus/qt/qtgui/extra_nexus/taurusnexuswidget.py
@@ -203,7 +203,7 @@ if __name__ == "__main__":
else:
fname = None
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
w = TaurusNeXusBrowser()
w.openFile(fname)
w.show()
diff --git a/lib/taurus/qt/qtgui/graphic/jdraw/jdraw.py b/lib/taurus/qt/qtgui/graphic/jdraw/jdraw.py
index 5f99ead1..d20944ab 100644
--- a/lib/taurus/qt/qtgui/graphic/jdraw/jdraw.py
+++ b/lib/taurus/qt/qtgui/graphic/jdraw/jdraw.py
@@ -425,5 +425,5 @@ class TaurusJDrawGraphicsFactory(Singleton, TaurusBaseGraphicsFactory, Logger):
return
if __name__ == "__main__":
- from . import jdraw_view
+ from taurus.qt.qtgui.graphic.jdraw import jdraw_view
jdraw_view.jdraw_view_main()
diff --git a/lib/taurus/qt/qtgui/graphic/jdraw/jdraw_view.py b/lib/taurus/qt/qtgui/graphic/jdraw/jdraw_view.py
index f8dcd4c8..0e476a58 100644
--- a/lib/taurus/qt/qtgui/graphic/jdraw/jdraw_view.py
+++ b/lib/taurus/qt/qtgui/graphic/jdraw/jdraw_view.py
@@ -41,8 +41,7 @@ from taurus.qt.qtgui.graphic.taurusgraphic import parseTangoUri, TaurusGraphicsI
from taurus.qt.qtcore.mimetypes import TAURUS_ATTR_MIME_TYPE, TAURUS_DEV_MIME_TYPE, TAURUS_MODEL_MIME_TYPE
from taurus.qt.qtgui.base import TaurusBaseWidget
-from . import jdraw_parser
-
+from taurus.qt.qtgui.graphic.jdraw.jdraw_parser import parse
__all__ = ["TaurusJDrawSynopticsView"]
@@ -389,7 +388,7 @@ class TaurusJDrawSynopticsView(Qt.QGraphicsView, TaurusBaseWidget):
self.debug("Starting to parse %s" % filename)
self.path = os.path.dirname(filename)
factory = self.getGraphicsFactory(delayed=delayed)
- scene = jdraw_parser.parse(filename, factory)
+ scene = parse(filename, factory)
scene.setSelectionStyle(self._selectionStyle)
self.debug("Obtained %s(%s)", type(scene).__name__, filename)
if not scene:
@@ -477,7 +476,7 @@ def jdraw_view_main():
taurus.setLogLevel(taurus.Info)
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
#form = Qt.QDialog()
# ly=Qt.QVBoxLayout(form)
diff --git a/lib/taurus/qt/qtgui/graphic/taurusgraphic.py b/lib/taurus/qt/qtgui/graphic/taurusgraphic.py
index eb242535..e27fa7b1 100755..100644
--- a/lib/taurus/qt/qtgui/graphic/taurusgraphic.py
+++ b/lib/taurus/qt/qtgui/graphic/taurusgraphic.py
@@ -51,7 +51,7 @@ from taurus.core.util.log import Logger, deprecation_decorator
from taurus.core.taurusdevice import TaurusDevice
from taurus.core.taurusattribute import TaurusAttribute
from taurus.core.util.enumeration import Enumeration
-from taurus.external.qt import Qt
+from taurus.external.qt import Qt, compat
from taurus.qt.qtgui.base import TaurusBaseComponent
from taurus.qt.qtgui.util import (QT_ATTRIBUTE_QUALITY_PALETTE, QT_DEVICE_STATE_PALETTE,
ExternalAppAction, TaurusWidgetFactory)
@@ -110,7 +110,7 @@ def parseTangoUri(name):
class QEmitter(Qt.QObject):
- updateView = Qt.pyqtSignal(object)
+ updateView = Qt.pyqtSignal(compat.PY_OBJECT)
class TaurusGraphicsUpdateThread(Qt.QThread):
@@ -867,12 +867,21 @@ class QGraphicsTextBoxing(Qt.QGraphicsItemGroup):
_TEXT_RATIO = 0.8
def __init__(self, parent=None, scene=None):
- Qt.QGraphicsItemGroup.__init__(self, parent, scene)
- self._rect = Qt.QGraphicsRectItem(self, scene)
+ Qt.QGraphicsItemGroup.__init__(self, parent)
+ if scene is not None:
+ scene.addItem(self)
+ self._rect = Qt.QGraphicsRectItem(self)
+ if scene is not None:
+ scene.addItem(self._rect)
self._rect.setBrush(Qt.QBrush(Qt.Qt.NoBrush))
self._rect.setPen(Qt.QPen(Qt.Qt.NoPen))
- self._text = Qt.QGraphicsTextItem(self, scene)
- self._text.scale(self._TEXT_RATIO, self._TEXT_RATIO)
+ self._text = Qt.QGraphicsTextItem(self)
+ if scene is not None:
+ scene.addItem(self._text)
+ self._text.setTransform(
+ Qt.QTransform.fromScale(self._TEXT_RATIO, self._TEXT_RATIO),
+ True)
+
self._validBackground = None
# using that like the previous code create a worst result
self.__layoutValide = True
@@ -1163,8 +1172,9 @@ class TaurusGraphicsAttributeItem(TaurusGraphicsItem):
_frName = None
else:
_frName = 'rvalue.magnitude'
- text = self._currText = self.getDisplayValue(fragmentName=_frName)
- self._currText = text.decode('unicode-escape')
+ text = self.getDisplayValue(fragmentName=_frName)
+
+ self._currText = text
self._currHtmlText = None
TaurusGraphicsItem.updateStyle(self)
diff --git a/lib/taurus/qt/qtgui/icon/catalog.py b/lib/taurus/qt/qtgui/icon/catalog.py
index 58cb7293..1e101691 100644
--- a/lib/taurus/qt/qtgui/icon/catalog.py
+++ b/lib/taurus/qt/qtgui/icon/catalog.py
@@ -30,6 +30,7 @@ from __future__ import print_function
from builtins import str
import os
+import click
import hashlib
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.input import GraphicalChoiceWidget
@@ -38,7 +39,7 @@ from taurus.external.qt import Qt
class QIconCatalogPage(GraphicalChoiceWidget):
- """A widget that shows all icons available under a given searchPath preffix
+ """A widget that shows all icons available under a given searchPath prefix
"""
def __init__(self, prefix, iconSize=24, columns=10):
@@ -139,6 +140,7 @@ class QIconCatalogPage(GraphicalChoiceWidget):
dlg.setIconPixmap(getCachedPixmap(name, size=128))
dlg.exec_()
+
class QIconCatalog(Qt.QTabWidget):
"""
A widget that shows a tab for each registered search path prefix.
@@ -166,11 +168,11 @@ class QIconCatalog(Qt.QTabWidget):
progress.setValue(nprefix)
-def main():
- """launcher of QIconCatalog"""
+@click.command('icons')
+def icons_cmd():
+ """Show the Taurus icon catalog"""
import sys
- from taurus import Release
- app = TaurusApplication(app_version=Release.version)
+ app = TaurusApplication(cmd_line_parser=None)
w = QIconCatalog()
w.setWindowTitle('Taurus Icon Catalog')
w.show()
@@ -178,4 +180,4 @@ def main():
if __name__ == "__main__":
- main()
+ icons_cmd()
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_off.png
new file mode 100644
index 00000000..1b7f04b0
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_on.png
new file mode 100644
index 00000000..1b7f04b0
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_black_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_off.png
new file mode 100644
index 00000000..ab5ae4e3
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_on.png
new file mode 100644
index 00000000..ed0e0392
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_blue_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_off.png
new file mode 100644
index 00000000..a6d4ffac
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_on.png
new file mode 100644
index 00000000..0e71615e
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_green_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_off.png
new file mode 100644
index 00000000..5991ccd2
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_on.png
new file mode 100644
index 00000000..61116762
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_grenoble_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_off.png
new file mode 100644
index 00000000..df2628ed
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_on.png
new file mode 100644
index 00000000..f13784b7
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_magenta_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_off.png
new file mode 100644
index 00000000..1b7f04b0
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_off.png
new file mode 100644
index 00000000..e6ef7f64
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_on.png
new file mode 100644
index 00000000..23839531
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_orange_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_off.png
new file mode 100644
index 00000000..33eecf62
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_on.png
new file mode 100644
index 00000000..8c444ae6
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_red_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_off.png
new file mode 100644
index 00000000..c702c33d
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_on.png
new file mode 100644
index 00000000..efbc5d39
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_white_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_off.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_off.png
new file mode 100644
index 00000000..0d27b936
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_off.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_on.png b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_on.png
new file mode 100644
index 00000000..92386b7f
--- /dev/null
+++ b/lib/taurus/qt/qtgui/icon/extra-icons/leds/images256icons/led_yellow_on.png
Binary files differ
diff --git a/lib/taurus/qt/qtgui/icon/icon.py b/lib/taurus/qt/qtgui/icon/icon.py
index 0299849f..78c7ded4 100644
--- a/lib/taurus/qt/qtgui/icon/icon.py
+++ b/lib/taurus/qt/qtgui/icon/icon.py
@@ -327,7 +327,7 @@ def getDevStatePixmap(state, size=None):
if __name__ == '__main__':
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
icons = [
# null because of non-existent path
diff --git a/lib/taurus/qt/qtgui/input/choicedlg.py b/lib/taurus/qt/qtgui/input/choicedlg.py
index b8f2cdfa..e32a235e 100644
--- a/lib/taurus/qt/qtgui/input/choicedlg.py
+++ b/lib/taurus/qt/qtgui/input/choicedlg.py
@@ -249,7 +249,7 @@ def testWidget():
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
w = GraphicalChoiceWidget(None, True)
w.show()
sys.exit(app.exec_())
@@ -260,7 +260,7 @@ def main():
from taurus.qt.qtgui.icon import getCachedPixmap
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
pixmaps = {}
choices = [['TaurusForm', 'TaurusTrend'], ['TaurusPlot', 'Qub']]
diff --git a/lib/taurus/qt/qtgui/input/qwheel.py b/lib/taurus/qt/qtgui/input/qwheel.py
index 7965ea31..8b3ac6f0 100755..100644
--- a/lib/taurus/qt/qtgui/input/qwheel.py
+++ b/lib/taurus/qt/qtgui/input/qwheel.py
@@ -212,7 +212,9 @@ class QWheelEdit(Qt.QFrame):
self._maxValue = numpy.finfo('d').max # inf
self._editor = None
self._editing = False
+ self._hideEditWidget = True
self._showArrowButtons = True
+ self._forwardReturn = False
self._setDigits(QWheelEdit.DefaultIntDigitCount,
QWheelEdit.DefaultDecDigitCount)
self._setValue(0)
@@ -321,7 +323,7 @@ class QWheelEdit(Qt.QFrame):
ed = _NumericEditor(self)
ed.returnPressed.connect(self.editingFinished)
- ed.editingFinished.connect(ed.hide)
+ ed.editingFinished.connect(self.hideEditWidget)
rect = Qt.QRect(l.cellRect(1, 0).topLeft(),
l.cellRect(1, l.columnCount() - 1).bottomRight())
ed.setGeometry(rect)
@@ -504,7 +506,12 @@ class QWheelEdit(Qt.QFrame):
return
self._previous_value = self._value
self._value = v
- self._buildValueStr(v)
+
+ str_value = self._buildValueStr(v)
+ ed = self.getEditWidget()
+ if ed is not None:
+ ed.setText(str_value)
+
def setWarning(self, msg):
"""setWarning(self, msg) -> None
@@ -534,8 +541,11 @@ class QWheelEdit(Qt.QFrame):
@param[in] b (_ArrowButton) the button which was pressed
"""
- self._setValue(self.getValue() + b._inc)
- self._updateValue()
+ if self._editing:
+ self.hideEditWidget()
+ else:
+ self._setValue(self.getValue() + b._inc)
+ self._updateValue()
def setDigitCount(self, int_nb, dec_nb):
"""setDigitCount(self, int_nb, dec_nb) -> None
@@ -770,6 +780,7 @@ class QWheelEdit(Qt.QFrame):
ed.selectAll()
ed.setFocus()
ed.setVisible(True)
+ self._editing = True
def hideEditWidget(self):
"""hideEditWidget(self) -> None
@@ -778,6 +789,7 @@ class QWheelEdit(Qt.QFrame):
"""
ed = self.getEditWidget()
ed.setVisible(False)
+ self._editing = False
self.setFocus()
def wheelEvent(self, evt):
@@ -803,7 +815,6 @@ class QWheelEdit(Qt.QFrame):
widget when this happens
"""
self.showEditWidget()
- self._editing = True
def keyPressEvent(self, key_event):
"""keyPressEvent(self, key_event) -> None
@@ -815,20 +826,16 @@ class QWheelEdit(Qt.QFrame):
if k == Qt.Qt.Key_F2:
if self._editing:
self.hideEditWidget()
- self._editing = False
else:
self.showEditWidget()
- self._editing = True
return
elif k == Qt.Qt.Key_Escape:
if self._editing:
self.hideEditWidget()
- self._editing = False
return
elif k in (Qt.Qt.Key_Return, Qt.Qt.Key_Enter):
if self._editing:
self.hideEditWidget()
- self._editing = False
else:
self.returnPressed.emit()
@@ -845,6 +852,63 @@ class QWheelEdit(Qt.QFrame):
def resetShowArrowButtons(self):
self.setShowArrowButtons(True)
+ def getHideEditWidget(self):
+ """getHideEditWidget(self) -> bool
+
+ Gets the info if edition widget should be hidden when 'focusOut' event
+ occurs.
+
+ @return (bool)
+ """
+ return self._hideEditWidget
+
+ def setHideEditWidget(self, focus_out=True):
+ """setFocusOut(self, focus_out=True) -> None
+
+ Sets if edition widget should be hidden when 'focusOut' event occurs.
+ If set to False, edition widget is hidden only when 'F2', 'Esc',
+ 'Enter' and arrow button are pressed. Default set to True.
+
+ @param[in] focus_out (bool) whether or not to hide edition widget
+ after 'focusOut' event.
+ """
+ if focus_out and not self._hideEditWidget:
+ ed = self.getEditWidget()
+ ed.editingFinished.connect(self.hideEditWidget)
+ self._hideEditWidget = True
+ elif not focus_out and self._hideEditWidget:
+ ed = self.getEditWidget()
+ ed.editingFinished.disconnect(self.hideEditWidget)
+ self._hideEditWidget = False
+
+ def isReturnForwarded(self):
+ """isReturnForwarded(self) -> bool
+
+ Gets the info if returnPressed is forwarded.
+
+ @return (bool)
+ """
+ return self._forwardReturn
+
+ def setReturnForwarded(self, forward_rtn=False):
+ """setReturnForwarded(self, forward_rtn=False) -> None
+
+ Sets forwarding of returnPressed. If set to True, returnPressed from
+ edition widget emits returnPressed of 'QWheelEdit' widget.
+
+ @param[in] forward_rtn (bool) whether or not to forward returnPressed
+ signal
+ """
+ if forward_rtn and not self._forwardReturn:
+ ed = self.getEditWidget()
+ ed.returnPressed.connect(self.returnPressed)
+ self._forwardReturn = True
+
+ elif not forward_rtn and self._forwardReturn:
+ ed = self.getEditWidget()
+ ed.returnPressed.disconnect(self.returnPressed)
+ self._forwardReturn = False
+
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# QT properties
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
@@ -893,6 +957,7 @@ def main():
def setNone():
arrowWidget.setValue(None)
+
a = Qt.QApplication([])
panel = Qt.QWidget()
l = Qt.QFormLayout(panel)
@@ -904,6 +969,8 @@ def main():
resetbutton.setDefault(True)
nanbutton = Qt.QPushButton("Set NAN", panel)
nonebutton = Qt.QPushButton("Set None", panel)
+ hideEditCB = Qt.QCheckBox()
+ hideEditCB.setChecked(True)
showarrowbutton = Qt.QCheckBox("", panel)
l.addRow("Value", arrowWidget)
@@ -912,6 +979,7 @@ def main():
l.addRow("Minimum value:", minv)
l.addRow("Maximum value:", maxv)
l.addRow("Show arrows:", showarrowbutton)
+ l.addRow("hideEditCB", hideEditCB)
l.addRow(button_layout)
button_layout.addWidget(nanbutton)
button_layout.addWidget(nonebutton)
@@ -929,6 +997,7 @@ def main():
showarrowbutton.stateChanged.connect(arrowWidget.setShowArrowButtons)
nanbutton.clicked.connect(setNAN)
nonebutton.clicked.connect(setNone)
+ hideEditCB.toggled.connect(arrowWidget.setHideEditWidget)
resetbutton.clicked.connect(resetAll)
panel.setVisible(True)
a.exec_()
diff --git a/lib/taurus/qt/qtgui/input/tauruscombobox.py b/lib/taurus/qt/qtgui/input/tauruscombobox.py
index d7ec3602..7b21557f 100644
--- a/lib/taurus/qt/qtgui/input/tauruscombobox.py
+++ b/lib/taurus/qt/qtgui/input/tauruscombobox.py
@@ -366,7 +366,7 @@ class TaurusAttrListComboBox(Qt.QComboBox, TaurusBaseWidget):
def _taurusAttrListTest():
"""tests taurusAttrList. Model: an attribute containing a list of strings"""
from taurus.qt.qtgui.application import TaurusApplication
- a = TaurusApplication()
+ a = TaurusApplication(cmd_line_parser=None)
# model = sys.argv[1]
# model = "eval:['foo','bar']"
model = "sys/tg_test/1/string_spectrum"
@@ -387,7 +387,7 @@ def _taurusValueComboboxTest():
('name2', 2),
('name3', 3)
]
- a = TaurusApplication()
+ a = TaurusApplication(cmd_line_parser=None)
w = Qt.QWidget()
w.setLayout(Qt.QVBoxLayout())
diff --git a/lib/taurus/qt/qtgui/input/tauruslineedit.py b/lib/taurus/qt/qtgui/input/tauruslineedit.py
index 135460ae..4abeaf75 100755..100644
--- a/lib/taurus/qt/qtgui/input/tauruslineedit.py
+++ b/lib/taurus/qt/qtgui/input/tauruslineedit.py
@@ -89,7 +89,7 @@ class TaurusValueLineEdit(Qt.QLineEdit, TaurusBaseWritableWidget):
def _updateValidator(self, value):
"""This method sets a validator depending on the data type"""
val = None
- if isinstance(value.wvalue, Quantity):
+ if value is not None and isinstance(value.wvalue, Quantity):
val = self.validator()
if not isinstance(val, PintValidator):
val = PintValidator(self)
diff --git a/lib/taurus/qt/qtgui/input/taurusspinbox.py b/lib/taurus/qt/qtgui/input/taurusspinbox.py
index e7edf2cc..53d53b00 100644
--- a/lib/taurus/qt/qtgui/input/taurusspinbox.py
+++ b/lib/taurus/qt/qtgui/input/taurusspinbox.py
@@ -291,7 +291,7 @@ if __name__ == "__main__":
main()
# import sys
# from taurus.qt.qtgui.application import TaurusApplication
-# app = TaurusApplication()
+# app = TaurusApplication(cmd_line_parser=None)
# w = TaurusValueSpinBox()
# w.setModel('sys/tg_test/1/double_scalar')
diff --git a/lib/taurus/qt/qtgui/model/qbasemodel.py b/lib/taurus/qt/qtgui/model/qbasemodel.py
index a43db539..99827359 100644
--- a/lib/taurus/qt/qtgui/model/qbasemodel.py
+++ b/lib/taurus/qt/qtgui/model/qbasemodel.py
@@ -32,7 +32,7 @@ __all__ = ["QBaseModelWidget", "TaurusBaseModelWidget",
__docformat__ = 'restructuredtext'
-from taurus.external.qt import Qt
+from taurus.external.qt import Qt, compat
from taurus.qt.qtgui.util import ActionFactory
from taurus.qt.qtgui.base import TaurusBaseWidget
@@ -221,7 +221,7 @@ class RefreshToolBar(BaseToolBar):
class PerspectiveToolBar(BaseToolBar):
- perspectiveChanged = Qt.pyqtSignal(str)
+ perspectiveChanged = Qt.pyqtSignal(compat.PY_OBJECT)
def __init__(self, perspective, view=None, parent=None, designMode=False):
BaseToolBar.__init__(self, name="Taurus refresh toolbar", view=view,
@@ -275,10 +275,10 @@ class QBaseModelWidget(Qt.QMainWindow):
KnownPerspectives = {}
DftPerspective = None
- itemClicked = Qt.pyqtSignal(object, int)
- itemDoubleClicked = Qt.pyqtSignal(object, int)
+ itemClicked = Qt.pyqtSignal(compat.PY_OBJECT, int)
+ itemDoubleClicked = Qt.pyqtSignal(compat.PY_OBJECT, int)
itemSelectionChanged = Qt.pyqtSignal()
- currentItemChanged = Qt.pyqtSignal(object, object)
+ currentItemChanged = Qt.pyqtSignal(compat.PY_OBJECT, compat.PY_OBJECT)
def __init__(self, parent=None, designMode=False, with_filter_widget=True,
with_selection_widget=True, with_refresh_widget=True,
diff --git a/lib/taurus/qt/qtgui/panel/qdataexportdialog.py b/lib/taurus/qt/qtgui/panel/qdataexportdialog.py
index bdd5db54..5977be27 100755..100644
--- a/lib/taurus/qt/qtgui/panel/qdataexportdialog.py
+++ b/lib/taurus/qt/qtgui/panel/qdataexportdialog.py
@@ -28,6 +28,8 @@ one or more curves"""
from __future__ import print_function
+from future.utils import string_types
+
import os.path
from datetime import datetime
@@ -112,7 +114,7 @@ class QDataExportDialog(Qt.QDialog):
if not ofile:
return False
try:
- if not isinstance(ofile, file):
+ if isinstance(ofile, string_types):
ofile = open(str(ofile), "w")
if self.dataSetCB.currentText() == self.allInMultipleFiles:
# 1 file per curve
@@ -257,7 +259,7 @@ if __name__ == "__main__":
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = QDataExportDialog()
form.show()
sys.exit(app.exec_())
diff --git a/lib/taurus/qt/qtgui/panel/qdoublelist.py b/lib/taurus/qt/qtgui/panel/qdoublelist.py
index 5d7b69a5..51062cd2 100644
--- a/lib/taurus/qt/qtgui/panel/qdoublelist.py
+++ b/lib/taurus/qt/qtgui/panel/qdoublelist.py
@@ -132,7 +132,7 @@ class QDoubleListDlg(Qt.QDialog):
def main():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
dlg = QDoubleListDlg(winTitle='foo', mainLabel='bla, bla', label1='1', label2='2',
list1=['11', '22'], list2=['123', '33'])
diff --git a/lib/taurus/qt/qtgui/panel/qrawdatachooser.py b/lib/taurus/qt/qtgui/panel/qrawdatachooser.py
index 90fe1fb5..651e374e 100644
--- a/lib/taurus/qt/qtgui/panel/qrawdatachooser.py
+++ b/lib/taurus/qt/qtgui/panel/qrawdatachooser.py
@@ -85,7 +85,7 @@ if __name__ == "__main__":
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = QRawDataWidget()
form.show()
sys.exit(app.exec_())
diff --git a/lib/taurus/qt/qtgui/panel/taurusconfigeditor.py b/lib/taurus/qt/qtgui/panel/taurusconfigeditor.py
index 1f6b6660..d9362b61 100644
--- a/lib/taurus/qt/qtgui/panel/taurusconfigeditor.py
+++ b/lib/taurus/qt/qtgui/panel/taurusconfigeditor.py
@@ -33,10 +33,11 @@ standard_library.install_aliases()
from taurus.external.qt import Qt, compat
import pickle
import os
+import shutil
import tempfile
+import click
from taurus.qt.qtcore.configuration import BaseConfigurableClass
from taurus.qt.qtgui.container import TaurusWidget
-import shutil
__all__ = ["QConfigEditor"]
@@ -80,10 +81,8 @@ class QConfigEditorModel(Qt.QStandardItemModel):
:param iniFileName: (str)
'''
- self.originalFile = str(iniFileName)
- self._file = tempfile.NamedTemporaryFile()
- self._temporaryFile = str(self._file.name)
-
+ self.originalFile = iniFileName
+ self._temporaryFile = tempfile.NamedTemporaryFile(delete=False).name
shutil.copyfile(self.originalFile, self._temporaryFile)
self._settings = Qt.QSettings(
@@ -346,7 +345,7 @@ class QConfigEditorModel(Qt.QStandardItemModel):
'''
result = None
qstate = self._settings.value(key)
- if qstate is not None and not qstate.isNull():
+ if qstate is not None:
try:
result = pickle.loads(qstate.data())
except Exception as e:
@@ -366,6 +365,8 @@ class QConfigEditorModel(Qt.QStandardItemModel):
'''
if self.markedItems == []:
return
+ self._settings.sync()
+
shutil.copyfile(self._temporaryFile, self.originalFile)
self.clearChanges()
# self.reloadFile()
@@ -395,7 +396,7 @@ class QConfigEditorModel(Qt.QStandardItemModel):
'''
if self.markedItems == []:
return
- shutil.copyfile(self.originalFile, self._temporaryFile)
+
self.reloadFile()
def clearChanges(self):
@@ -493,26 +494,23 @@ class QConfigEditor(TaurusWidget):
self.tree.restoreOriginal()
-def main():
+@click.command('config')
+@click.argument('config_file', type=click.Path(exists=True), required=False)
+def config_cmd(config_file):
+ """Open the taurus configuration editor"""
from taurus.qt.qtgui.application import TaurusApplication
- from taurus.core.util import argparse
- from taurus import Release
import sys
- parser = argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [INIFILENAME]")
- parser.set_description("taurus configuration editor")
- app = TaurusApplication(cmd_line_parser=parser,
- app_name="taurusconfigeditor",
- app_version=Release.version)
- args = app.get_command_line_args()
+ app = TaurusApplication(cmd_line_parser=None)
+
w = QConfigEditor()
w.setMinimumSize(500, 500)
w.show()
- if len(args) == 1:
- w.loadFile(args[0])
+ if config_file:
+ w.loadFile(config_file)
sys.exit(app.exec_())
+
if __name__ == '__main__':
- main()
+ config_cmd()
diff --git a/lib/taurus/qt/qtgui/panel/taurusconfigurationpanel.py b/lib/taurus/qt/qtgui/panel/taurusconfigurationpanel.py
index 06c8226b..06c8226b 100755..100644
--- a/lib/taurus/qt/qtgui/panel/taurusconfigurationpanel.py
+++ b/lib/taurus/qt/qtgui/panel/taurusconfigurationpanel.py
diff --git a/lib/taurus/qt/qtgui/panel/taurusdemo.py b/lib/taurus/qt/qtgui/panel/taurusdemo.py
index 405a76a6..b826077e 100644
--- a/lib/taurus/qt/qtgui/panel/taurusdemo.py
+++ b/lib/taurus/qt/qtgui/panel/taurusdemo.py
@@ -25,6 +25,7 @@
from __future__ import print_function
import sys
+import click
import taurus.core.util
import taurus.qt.qtgui.util
@@ -122,17 +123,13 @@ class TaurusDemoPanel(Qt.QWidget):
d.showMessage(str(e))
-def main():
- import taurus.core.util.argparse
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.set_description("A demo application for taurus")
- app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser,
- app_name="taurusdemo",
- app_version="1.0",
- org_domain="Taurus",
- org_name="Tango community")
+@click.command('demo')
+def demo_cmd():
+ """A demo application for taurus"""
+ from taurus.qt.qtgui.application import TaurusApplication
+ app = TaurusApplication(cmd_line_parser=None)
gui = TaurusDemoPanel()
- gui.setWindowTitle(app.applicationName())
+ gui.setWindowTitle('Taurus demo')
gui.show()
sys.exit(app.exec_())
diff --git a/lib/taurus/qt/qtgui/panel/taurusdevicepanel.py b/lib/taurus/qt/qtgui/panel/taurusdevicepanel.py
index 63dd4926..8fb0763e 100644
--- a/lib/taurus/qt/qtgui/panel/taurusdevicepanel.py
+++ b/lib/taurus/qt/qtgui/panel/taurusdevicepanel.py
@@ -28,10 +28,10 @@ TaurusDevicePanel.py:
"""
from builtins import str
-from future.utils import string_types
import re
import traceback
+import click
from future.utils import string_types
@@ -42,7 +42,8 @@ from taurus import tauruscustomsettings
from taurus.core.taurusbasetypes import TaurusDevState, TaurusElementType
from taurus.core.taurusattribute import TaurusAttribute
from taurus.core.taurusdevice import TaurusDevice
-from taurus.qt.qtgui.container import TaurusWidget, TaurusMainWindow
+from taurus.qt.qtgui.container import TaurusWidget
+from taurus.qt.qtgui.taurusgui import TaurusGui
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.panel.taurusform import TaurusForm
from taurus.qt.qtgui.panel.taurusform import TaurusCommandsForm
@@ -276,10 +277,8 @@ class TaurusDevicePanel(TaurusWidget):
self.setModel(model)
def loadConfigFile(self, ifile=None):
- self.info('In TaurusDevicePanel.loadConfigFile(%s)' % ifile)
- if isinstance(ifile, file) or isinstance(ifile, string_types) and not ifile.endswith('.py'):
- TaurusWidget.loadConfigFile(self, ifile)
- else:
+ self.debug('In TaurusDevicePanel.loadConfigFile(%s)' % ifile)
+ if isinstance(ifile, string_types) and ifile.endswith('.py'):
from imp import load_source
config_file = load_source('config_file', ifile)
af, cf, im = [getattr(config_file, x, None) for x in (
@@ -290,6 +289,8 @@ class TaurusDevicePanel(TaurusWidget):
self.setCommandFilters(cf)
if im is not None:
self.setIconMap(im)
+ else:
+ TaurusWidget.loadConfigFile(self, ifile)
self.debug('AttributeFilters are:\n%s' % self.getAttributeFilters())
def duplicate(self):
@@ -504,16 +505,17 @@ def filterNonExported(obj):
@UILoadable(with_ui='_ui')
-class TaurusDevPanel(TaurusMainWindow):
- '''
+class TaurusDevPanel(TaurusGui):
+ """
TaurusDevPanel is a Taurus Application inspired in Jive and Atk Panel.
It Provides a Device selector and several dockWidgets for interacting and
displaying information from the selected device.
- '''
+ """
+ HELP_MENU_ENABLED = False
def __init__(self, parent=None, designMode=False):
- TaurusMainWindow.__init__(self, parent, designMode=designMode)
+ TaurusGui.__init__(self, parent)
self.loadUi()
# setting up the device Tree.
@@ -528,12 +530,6 @@ class TaurusDevPanel(TaurusMainWindow):
# self.deviceTree.insertFilter(filterNonExported)
self.setCentralWidget(self.deviceTree)
- # needed because of a limitation in when using the useParentModel
- # property from designer and taurus parents are not the same as Qt
- # Parents
- self._ui.taurusAttrForm.recheckTaurusParent()
- self._ui.taurusCommandsForm.recheckTaurusParent()
-
# register subwidgets for configuration purposes
# self.registerConfigDelegate(self.taurusAttrForm)
# self.registerConfigDelegate(self.deviceTree)
@@ -551,7 +547,7 @@ class TaurusDevPanel(TaurusMainWindow):
self.splashScreen().finish(self)
def createActions(self):
- '''create actions '''
+ """create actions"""
# View Menu
self.showAttrAction = self.viewMenu.addAction(
self._ui.attrDW.toggleViewAction())
@@ -559,8 +555,8 @@ class TaurusDevPanel(TaurusMainWindow):
self._ui.commandsDW.toggleViewAction())
def setTangoHost(self, host):
- '''extended from :class:setTangoHost'''
- TaurusMainWindow.setTangoHost(self, host)
+ """extended from :class:setTangoHost"""
+ TaurusGui.setTangoHost(self, host)
self.deviceTree.setModel(host)
# self.deviceTree.insertFilter(filterNonExported)
@@ -586,28 +582,20 @@ class TaurusDevPanel(TaurusMainWindow):
self.setDevice(devname)
def setDevice(self, devname):
- # try to connect with the device
+ """set the device to be shown by the commands and attr forms"""
self.setModel(devname)
- dev = self.getModelObj()
- state = dev.state
- # test the connection
- if state == TaurusDevState.Ready:
- msg = 'Connected to "%s"' % devname
- self.statusBar().showMessage(msg)
- self._ui.attrDW.setWindowTitle('Attributes - %s' % devname)
- self._ui.commandsDW.setWindowTitle('Commands - %s' % devname)
- else:
- # reset the model if the connection failed
- msg = 'Connection to "%s" failed (state = %s)' % (devname,
- state.name)
- self.statusBar().showMessage(msg)
- self.info(msg)
- Qt.QMessageBox.warning(self, "Device unreachable", msg)
- self.setModel('')
+ self._ui.attrDW.setWindowTitle('Attributes - %s' % devname)
+ self._ui.commandsDW.setWindowTitle('Commands - %s' % devname)
+
+ def setModel(self, name):
+ """Reimplemented to delegate model to the commands and attrs forms"""
+ TaurusGui.setModel(self, name)
+ self._ui.taurusAttrForm.setModel(name)
+ self._ui.taurusCommandsForm.setModel(name)
@classmethod
def getQtDesignerPluginInfo(cls):
- ret = TaurusMainWindow.getQtDesignerPluginInfo()
+ ret = TaurusGui.getQtDesignerPluginInfo()
ret['module'] = 'taurus.qt.qtgui.panel'
return ret
@@ -616,80 +604,89 @@ class TaurusDevPanel(TaurusMainWindow):
#=========================================================================
-def TaurusDevicePanelMain():
- '''A launcher for TaurusDevicePanel.'''
+@click.command('device')
+@click.argument('dev', nargs=1, default=None, required=False)
+@click.option('-f', '--filter',
+ help=('regexp to filter for attributes to show '
+ + '(it can be passed more than once)'),
+ multiple=True,
+ )
+@click.option('--config', 'config_file', type=click.File('rb'),
+ help='configuration file for initialization')
+def device_cmd(dev, filter, config_file):
+ """Show a Device Panel"""
import sys
from taurus.qt.qtgui.application import TaurusApplication
- from taurus.core.util import argparse
- parser = argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [devname [attrs]]")
- parser.set_description("Taurus Application inspired in Jive and Atk Panel")
- parser.add_option("", "--config-file", dest="config_file", default=None,
- help="load a config file (TODO: document this option)")
- app = TaurusApplication(cmd_line_parser=parser, app_name="TaurusDevicePanel",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
+ app = TaurusApplication(cmd_line_parser=None, app_name="TaurusDevicePanel")
w = TaurusDevicePanel()
w.show()
- if len(args) == 0:
+ if dev is None:
from taurus.qt.qtgui.panel import TaurusModelChooser
- models, ok = TaurusModelChooser.modelChooserDlg(w,
- selectables=[
- TaurusElementType.Member],
- singleModel=True)
- model = models[0] if ok and models else None
- filters = ''
- else:
- model = args[0]
- filters = args[1:]
+ models, ok = TaurusModelChooser.modelChooserDlg(
+ w, selectables=[TaurusElementType.Member], singleModel=True
+ )
+ dev = models[0] if ok and models else None
- if options.config_file is not None:
- w.loadConfigFile(options.config_file)
- elif model and filters:
- w.setAttributeFilters({model: filters})
+ if config_file is not None:
+ w.loadConfigFile(config_file)
+ elif dev and filter:
+ w.setAttributeFilters({dev: list(filter)})
- w.setModel(model)
+ w.setModel(dev)
sys.exit(app.exec_())
-def TaurusPanelMain():
- '''A launcher for TaurusPanel.'''
- # NOTE: DON'T PUT TEST CODE HERE.
- # THIS IS CALLED FROM THE LAUNCHER SCRIPT (<taurus>/scripts/tauruspanel)
+@click.command('panel')
+@click.option('--tango-host', 'tango_host',
+ default=None,
+ help="Tango Host name (the system's default if not given)")
+@click.option('-d', '--dev', default=None,
+ help='pre-selected device')
+@click.option('-t', '--trend', is_flag=True,
+ help='Create a temporal trend widget')
+def panel_cmd(tango_host, dev, trend):
+ """
+ Show a TaurusPanel (a Taurus application inspired in Jive and Atk Panel)
+ """
from taurus.qt.qtgui.application import TaurusApplication
- from taurus.core.util import argparse
import sys
- parser = argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [devname]")
- parser.set_description("Taurus Application inspired in Jive and Atk Panel")
-
- app = TaurusApplication(cmd_line_parser=parser, app_name="tauruspanel",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
+ app = TaurusApplication(cmd_line_parser=None, app_name="tauruspanel")
w = TaurusDevPanel()
- if options.tango_host is None:
- options.tango_host = taurus.Authority().getNormalName()
- w.setTangoHost(options.tango_host)
+ if tango_host is None:
+ from taurus import Factory
+ tango_host = Factory('tango').getAuthority().getFullName()
+ w.setTangoHost(tango_host)
+
+ if dev is not None:
+ w.setDevice(dev)
+
+ if trend is True:
+ # TODO: Allow to select TaurusTrend back-end
+ try:
+ from taurus.qt.qtgui.qwt5 import TaurusTrend
+ w.info('Using qwt5 back-end')
+ except:
+ try:
+ from taurus.qt.qtgui.tpg import TaurusTrend
+ w.info('Using tpg back-end')
+ except:
+ TaurusTrend = None
+ w.warning('TaurusTrend widget is not available')
- if len(args) == 1:
- w.setDevice(args[0])
+ if TaurusTrend is not None:
+ plot = TaurusTrend()
+ w.createPanel(plot, 'TaurusTrend', permanent=False)
w.show()
sys.exit(app.exec_())
-###############################################################################
-
-if __name__ == "__main__":
- TaurusDevicePanelMain()
diff --git a/lib/taurus/qt/qtgui/panel/taurusform.py b/lib/taurus/qt/qtgui/panel/taurusform.py
index 13572f4a..3fa02aaf 100644
--- a/lib/taurus/qt/qtgui/panel/taurusform.py
+++ b/lib/taurus/qt/qtgui/panel/taurusform.py
@@ -28,6 +28,7 @@
from __future__ import print_function
from __future__ import absolute_import
+import click
from datetime import datetime
from functools import partial
@@ -865,21 +866,22 @@ class TaurusAttrForm(TaurusWidget):
def _updateAttrWidgets(self):
'''Populates the form with an item for each of the attributes shown
'''
- dev = self.getModelObj()
- if dev is None or dev.state != TaurusDevState.Ready:
+ try:
+ dev = self.getModelObj()
+ attrlist = sorted(dev.attribute_list_query(), key=self._sortKey)
+ for f in self.getViewFilters():
+ attrlist = list(filter(f, attrlist))
+ attrnames = []
+ devname = self.getModelName()
+ for a in attrlist:
+ # ugly hack . But setUseParentModel does not work well
+ attrnames.append("%s/%s" % (devname, a.name))
+ self.debug('Filling with attribute list: %s'
+ % ("; ".join(attrnames)))
+ self._form.setModel(attrnames)
+ except:
self.debug('Cannot connect to device')
self._form.setModel([])
- return
- attrlist = sorted(dev.attribute_list_query(), key=self._sortKey)
- for f in self.getViewFilters():
- attrlist = list(filter(f, attrlist))
- attrnames = []
- devname = self.getModelName()
- for a in attrlist:
- # ugly hack . But setUseParentModel does not work well
- attrnames.append("%s/%s" % (devname, a.name))
- self.debug('Filling with attribute list: %s' % ("; ".join(attrnames)))
- self._form.setModel(attrnames)
def setViewFilters(self, filterlist):
'''sets the filters to be applied when displaying the attributes
@@ -948,7 +950,7 @@ def test1():
models = None
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
if models is None:
models = ['sys/tg_test/1/state',
'sys/tg_test/1/float_scalar',
@@ -980,7 +982,7 @@ def test2():
model = 'bl97/pc/dummy-01'
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
dialog = TaurusAttrForm()
dialog.setModel(model)
dialog.show()
@@ -999,7 +1001,7 @@ def test3():
model = 'bl97/pc/dummy-01'
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
dialog = TaurusCommandsForm()
dialog.setModel(model)
dialog.show()
@@ -1014,7 +1016,7 @@ def test4():
from taurus.qt.qtgui.display import TaurusLabel
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
from taurus.qt.qtgui.panel import TaurusValue
@@ -1045,33 +1047,23 @@ def test4():
sys.exit(app.exec_())
-def taurusFormMain():
- '''A launcher for TaurusForm.'''
- # NOTE: DON'T PUT TEST CODE HERE.
- # THIS IS CALLED FROM THE LAUNCHER SCRIPT (<taurus>/scripts/taurusform)
- # USE test1() instead.
+@click.command('form')
+@click.option('--window-name', 'window_name',
+ default='Taurus Form',
+ help='Name of the window')
+@click.option('--config', 'config_file', type=click.File('rb'),
+ help='configuration file for initialization')
+@click.argument('models', nargs=-1)
+def form_cmd(window_name, config_file, models):
+ """Shows a Taurus form populated with the given model names"""
from taurus.qt.qtgui.application import TaurusApplication
- from taurus.core.util import argparse
import sys
- import os
-
- parser = argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [model1 [model2 ...]]")
- parser.set_description("the taurus form panel application")
- parser.add_option("--window-name", dest="window_name",
- default="TaurusForm", help="Name of the window")
- parser.add_option("--config", "--config-file", dest="config_file", default=None,
- help="use the given config file for initialization")
- app = TaurusApplication(cmd_line_parser=parser,
- app_name="taurusform",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
-
+ app = TaurusApplication(cmd_line_parser=None)
dialog = TaurusForm()
dialog.setModifiableByUser(True)
dialog.setModelInConfig(True)
- dialog.setWindowTitle(options.window_name)
+
+ dialog.setWindowTitle(window_name)
# Make sure the window size and position are restored
dialog.registerConfigProperty(dialog.saveGeometry, dialog.restoreGeometry,
@@ -1099,16 +1091,14 @@ def taurusFormMain():
getattr(tauruscustomsettings, 'T_FORM_CUSTOM_WIDGET_MAP', {}))
# set a model list from the command line or launch the chooser
- if options.config_file is not None:
- dialog.loadConfigFile(options.config_file)
- elif len(args) > 0:
- models = args
+ if config_file is not None:
+ dialog.loadConfigFile(config_file)
+ elif len(models) > 0:
dialog.setModel(models)
else:
dialog.chooseModels()
dialog.show()
-
sys.exit(app.exec_())
@@ -1117,7 +1107,7 @@ def main():
# test2()
# test3()
# test4()
- taurusFormMain()
+ form_cmd()
if __name__ == "__main__":
main()
diff --git a/lib/taurus/qt/qtgui/panel/taurusmodelchooser.py b/lib/taurus/qt/qtgui/panel/taurusmodelchooser.py
index e505715e..552a168b 100644
--- a/lib/taurus/qt/qtgui/panel/taurusmodelchooser.py
+++ b/lib/taurus/qt/qtgui/panel/taurusmodelchooser.py
@@ -29,24 +29,124 @@ AttributeChooser.py: widget for choosing (a list of) attributes from a tango DB
from __future__ import print_function
from __future__ import absolute_import
+from builtins import bytes, str
+
import sys
-from taurus.external.qt import Qt
+import pkg_resources
+
+import taurus
+from taurus.external.qt import Qt, QtCore
+from taurus.external.qt.compat import PY_OBJECT
import taurus.core
from taurus.qt.qtgui.container import TaurusWidget
from taurus.qt.qtgui.tree import TaurusDbTreeWidget
from taurus.core.util.containers import CaselessList
from .taurusmodellist import TaurusModelList
+__all__ = ["TaurusModelSelectorTree", "TaurusModelChooser",
+ "TaurusModelSelector", "TaurusModelSelectorItem"]
+
+
+class TaurusModelSelector(Qt.QTabWidget):
+ """TaurusModelSelector is a QTabWidget container for
+ TaurusModelSelectorItem.
+ """
+ # TODO add action to add new TaurusModelSelectorItem
+ # TODO add mechanism to allow manual plugin activation
+ # (instead of relying on installation)
+ modelsAdded = Qt.pyqtSignal(PY_OBJECT)
+
+ def __init__(self, parent=None):
+ Qt.QTabWidget.__init__(self, parent=parent)
+
+ self.currentChanged.connect(self.__setTabItemModel)
+ # ---------------------------------------------------------------------
+ # Note: this is an experimental feature
+ # It may be removed or changed in future releases
+ # Discover the taurus.modelselector plugins
+ ep_name = 'taurus.qt.qtgui.panel.TaurusModelSelector.items'
+ for ep in pkg_resources.iter_entry_points(ep_name):
+ try:
+ ms_class = ep.load()
+ ms_item = ms_class(parent=self)
+ self.__addItem(ms_item, ep.name)
-__all__ = ["TaurusModelSelectorTree", "TaurusModelChooser"]
-
+ except Exception as e:
+ err = 'Invalid TaurusModelSelectorItem plugin: {}\n{}'.format(
+ ep.module_name, e)
+ taurus.warning(err)
+ # ---------------------------------------------------------------------
+
+ def __setTabItemModel(self):
+ w = self.currentWidget()
+ c = self.cursor()
+ try:
+ if not w.model:
+ self.setCursor(QtCore.Qt.WaitCursor)
+ w.setModel(w.default_model)
+ except Exception as e:
+ taurus.warning('Problem setting up selector: %r', e)
+ finally:
+ self.setCursor(c)
+
+ def __addItem(self, widget, name, model=None):
+ if model is not None:
+ widget.default_model = model
+
+ widget.modelsAdded.connect(self.modelsAdded)
+ self.addTab(widget, name)
+
+
+class TaurusModelSelectorItem(TaurusWidget):
+ """Base class for ModelSelectorItem.
+ It defines the minimal API to be defined in the specialization
+ """
+ modelsAdded = Qt.pyqtSignal(PY_OBJECT)
+ _dragEnabled = True
+ # TODO add action for setModel
+
+ def __init__(self, parent=None, **kwargs):
+ TaurusWidget.__init__(self, parent)
+ self._default_model = None
-class TaurusModelSelectorTree(TaurusWidget):
+ def getSelectedModels(self):
+ raise NotImplementedError(('getSelectedModels must be implemented'
+ + ' in TaurusModelSelectorItem subclass'))
+
+ def getModelMimeData(self):
+ """ Reimplemented from TaurusBaseComponent
+ """
+ models = self.getSelectedModels()
+ md = Qt.QMimeData()
+ md.setText(", ".join(models))
+ models_bytes = [bytes(m, encoding='utf-8') for m in models]
+ md.setData(taurus.qt.qtcore.mimetypes.TAURUS_MODEL_LIST_MIME_TYPE,
+ b"\r\n".join(models_bytes))
+ return md
+
+ def _get_default_model(self):
+ """
+ Reimplement to return a default model to initialize the widget
+ """
+ raise NotImplementedError(('default_model must be implemented'
+ + ' in TaurusModelSelectorItem subclass'))
+
+ def _set_default_model(self, model):
+ """
+ Set default model to initialize the widget
+ """
+ self._default_model = model
+
+ # Reimplement this property
+ default_model = property(fget=_get_default_model, fset=_set_default_model)
+
+
+class TaurusModelSelectorTree(TaurusModelSelectorItem):
addModels = Qt.pyqtSignal('QStringList')
def __init__(self, parent=None, selectables=None, buttonsPos=None, designMode=None):
- TaurusWidget.__init__(self, parent)
+ TaurusModelSelectorItem.__init__(self, parent)
if selectables is None:
selectables = [taurus.core.taurusbasetypes.TaurusElementType.Attribute, taurus.core.taurusbasetypes.TaurusElementType.Member,
taurus.core.taurusbasetypes.TaurusElementType.Device]
@@ -138,6 +238,34 @@ class TaurusModelSelectorTree(TaurusWidget):
return ret
+class TangoModelSelectorItem(TaurusModelSelectorTree):
+ """A taurus model selector item for Tango models
+ """
+ # TODO: Tango-centric (move to Taurus-Tango plugin)
+ def __init__(self, parent=None, selectables=None,
+ buttonsPos=Qt.Qt.RightToolBarArea, designMode=None):
+ TaurusModelSelectorTree.__init__(
+ self, parent=parent, selectables=selectables,
+ buttonsPos=buttonsPos, designMode=designMode)
+
+ def onAddSelected(self):
+ """
+ Reimplemented from TaurusModelSelectorTree to emit modelsAdded
+ signal instead of addModels
+ """
+ self.modelsAdded.emit(self.getSelectedModels())
+
+ def _get_default_model(self):
+ """Reimplemented from TaurusModelSelectorItem"""
+ if self._default_model is None:
+ f = taurus.Factory('tango')
+ self._default_model = f.getAuthority().getFullName()
+ return self._default_model
+
+ default_model = property(fget=_get_default_model,
+ fset=TaurusModelSelectorTree._set_default_model)
+
+
class TaurusModelChooser(TaurusWidget):
'''A widget that allows the user to select a list of models from a tree representing
devices and attributes from a Tango server.
diff --git a/lib/taurus/qt/qtgui/panel/taurusmodellist.py b/lib/taurus/qt/qtgui/panel/taurusmodellist.py
index fef186b5..f9cf6b89 100644
--- a/lib/taurus/qt/qtgui/panel/taurusmodellist.py
+++ b/lib/taurus/qt/qtgui/panel/taurusmodellist.py
@@ -27,6 +27,7 @@
itemsmodel Model and view for new CurveItem configuration
"""
from builtins import object
+from builtins import bytes
#raise UnimplementedError('Under Construction!')
import copy
@@ -62,6 +63,16 @@ class TaurusModelItem(object):
if display is not None:
self.display = display
+ def __deepcopy__(self, memo):
+ cls = self.__class__
+ result = cls.__new__(cls)
+ memo[id(self)] = result
+ result.icon = Qt.QIcon(self.icon)
+ result.ok = copy.deepcopy(self.ok, memo)
+ result._src = copy.deepcopy(self._src, memo)
+ result.display = copy.deepcopy(self.display, memo)
+ return result
+
def __repr__(self):
ret = "TaurusModelItem('%s')" % (self.display)
return ret
@@ -236,11 +247,12 @@ class TaurusModelModel(Qt.QAbstractListModel):
if row == -1 and parent.isValid():
row = parent.row()
if data.hasFormat(TAURUS_ATTR_MIME_TYPE):
- items = [str(data.data(TAURUS_ATTR_MIME_TYPE))]
+ items = [bytes(data.data(TAURUS_ATTR_MIME_TYPE)).decode("utf-8")]
elif data.hasFormat(TAURUS_MODEL_MIME_TYPE):
- items = [str(data.data(TAURUS_MODEL_MIME_TYPE))]
+ items = [bytes(data.data(TAURUS_MODEL_MIME_TYPE)).decode("utf-8")]
elif data.hasFormat(TAURUS_MODEL_LIST_MIME_TYPE):
- items = str(data.data(TAURUS_MODEL_LIST_MIME_TYPE)).split()
+ items = bytes(
+ data.data(TAURUS_MODEL_LIST_MIME_TYPE)).decode("utf-8").split()
elif data.hasText():
items = [str(data.text())]
else:
@@ -442,7 +454,7 @@ class TaurusModelList(Qt.QListView):
if __name__ == "__main__":
from taurus.qt.qtgui.application import TaurusApplication
import sys
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w = TaurusModelList()
w.addModels(["item%i" % i for i in range(3)] +
[TaurusModelItem(src='src1', display='d1')] + [('src2', 'd2')])
diff --git a/lib/taurus/qt/qtgui/panel/taurusvalue.py b/lib/taurus/qt/qtgui/panel/taurusvalue.py
index 81532828..2ef054ae 100644
--- a/lib/taurus/qt/qtgui/panel/taurusvalue.py
+++ b/lib/taurus/qt/qtgui/panel/taurusvalue.py
@@ -204,6 +204,15 @@ class CenteredLed(TaurusLed):
DefaultAlignment = Qt.Qt.AlignHCenter | Qt.Qt.AlignVCenter
+class UnitLessLineEdit(TaurusValueLineEdit):
+ """A customised TaurusValueLineEdit that always shows the magnitude"""
+ def setModel(self, model):
+ if model is None or model == '':
+ return TaurusValueLineEdit.setModel(self, None)
+ return TaurusValueLineEdit.setModel(self, model + "#wvalue.magnitude")
+
+
+
class DefaultUnitsWidget(TaurusLabel):
FORMAT = "{}"
@@ -380,7 +389,7 @@ class TaurusValue(Qt.QWidget, TaurusBaseWidget):
itself.
'''
if followCompact and self.isCompact():
- return self._readWidget.readWidget
+ return getattr(self._readWidget, 'readWidget', self._readWidget)
return self._readWidget
def writeWidget(self, followCompact=False):
@@ -587,22 +596,24 @@ class TaurusValue(Qt.QWidget, TaurusBaseWidget):
modelobj = self.getModelObj()
if modelobj is None:
if returnAll:
- return [TaurusValueLineEdit]
+ return [UnitLessLineEdit]
else:
- return TaurusValueLineEdit
+ return UnitLessLineEdit
modelType = modelobj.getType()
if modelobj.data_format == DataFormat._0D:
if modelType == DataType.Boolean:
result = [DefaultTaurusValueCheckBox, TaurusValueLineEdit]
else:
- result = [TaurusValueLineEdit,
+ result = [UnitLessLineEdit,
TaurusValueSpinBox, TaurusWheelEdit]
elif modelobj.data_format == DataFormat._1D:
+ result = [TaurusValuesTableButton_W, TaurusValueLineEdit]
if modelType in (DataType.Float, DataType.Integer):
- result = [TaurusArrayEditorButton,
- TaurusValuesTableButton_W, TaurusValueLineEdit]
- else:
- result = [TaurusValuesTableButton_W, TaurusValueLineEdit]
+ try:
+ import taurus.qt.qtgui.qwt5
+ result.insert(0, TaurusArrayEditorButton)
+ except:
+ pass
elif modelobj.data_format == DataFormat._2D:
result = [TaurusValuesTableButton_W]
else:
@@ -1389,7 +1400,7 @@ if __name__ == "__main__":
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = Qt.QMainWindow()
# ly=Qt.QVBoxLayout(form)
# container=Qt.QWidget()
diff --git a/lib/taurus/qt/qtgui/panel/test/test_taurusvalue.py b/lib/taurus/qt/qtgui/panel/test/test_taurusvalue.py
index 7ec66e6e..d973560e 100644
--- a/lib/taurus/qt/qtgui/panel/test/test_taurusvalue.py
+++ b/lib/taurus/qt/qtgui/panel/test/test_taurusvalue.py
@@ -36,9 +36,7 @@ DEV_NAME = TangoSchemeTestLauncher.DEV_NAME
@insertTest(helper_name="texts",
model="tango:" + DEV_NAME + "/double_scalar",
- expected=("double_scalar", "1.23", "0.00 mm", "mm"),
- # expected=("double_scalar", "1.23", "0.0", "mm"),
- # TODO: change taurusvalue's line edit to hide units
+ expected=("double_scalar", "1.23", "0.00", "mm")
)
class TaurusValueTest(TangoSchemeTestLauncher, BaseWidgetTestCase,
unittest.TestCase):
diff --git a/lib/taurus/qt/qtgui/panel/ui/TaurusDevPanel.ui b/lib/taurus/qt/qtgui/panel/ui/TaurusDevPanel.ui
index a155f1ba..22b7a03b 100644
--- a/lib/taurus/qt/qtgui/panel/ui/TaurusDevPanel.ui
+++ b/lib/taurus/qt/qtgui/panel/ui/TaurusDevPanel.ui
@@ -32,7 +32,7 @@
<item>
<widget class="TaurusAttrForm" name="taurusAttrForm" native="true">
<property name="useParentModel" stdset="0">
- <bool>true</bool>
+ <bool>false</bool>
</property>
</widget>
</item>
@@ -54,7 +54,7 @@
<item>
<widget class="TaurusCommandsForm" name="taurusCommandsForm" native="true">
<property name="useParentModel" stdset="0">
- <bool>true</bool>
+ <bool>false</bool>
</property>
</widget>
</item>
diff --git a/lib/taurus/qt/qtgui/plot/__init__.py b/lib/taurus/qt/qtgui/plot/__init__.py
index 1d4326cb..1d4326cb 100755..100644
--- a/lib/taurus/qt/qtgui/plot/__init__.py
+++ b/lib/taurus/qt/qtgui/plot/__init__.py
diff --git a/lib/taurus/qt/qtgui/qwt5/arrayedit.py b/lib/taurus/qt/qtgui/qwt5/arrayedit.py
index f3c36dfc..58069d12 100644
--- a/lib/taurus/qt/qtgui/qwt5/arrayedit.py
+++ b/lib/taurus/qt/qtgui/qwt5/arrayedit.py
@@ -537,7 +537,7 @@ if __name__ == "__main__":
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = ArrayEditor()
#x = numpy.arange(100)-20
#y = -(x-50)**2+50**2
diff --git a/lib/taurus/qt/qtgui/qwt5/cli.py b/lib/taurus/qt/qtgui/qwt5/cli.py
new file mode 100644
index 00000000..6f1818ad
--- /dev/null
+++ b/lib/taurus/qt/qtgui/qwt5/cli.py
@@ -0,0 +1,103 @@
+#############################################################################
+##
+# This file is part of Taurus
+##
+# http://taurus-scada.org
+##
+# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
+##
+# Taurus 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 3 of the License, or
+# (at your option) any later version.
+##
+# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
+##
+#############################################################################
+
+import click
+from .taurustrend import TaurusTrend
+
+
+@click.group('qwt5')
+def qwt5():
+ """Qwt5 related commands"""
+ pass
+
+
+@qwt5.command('plot')
+@click.argument('models', nargs=-1)
+@click.option('--config', 'config_file', type=click.File('rb'),
+ help='configuration file for initialization')
+@click.option("-x", "--x-axis-mode", "x_axis_mode",
+ type=click.Choice(['t', 'n']),
+ default='n',
+ show_default=True,
+ help=('X axis mode. "t" implies using a Date axis'
+ + '"n" uses the regular axis')
+ )
+@click.option("--demo", is_flag=True, help="show a demo of the widget")
+@click.option('--window-name', 'window_name',
+ default='TaurusPlot (qwt5)',
+ help='Name of the window')
+def plot_cmd(models, config_file, x_axis_mode, demo, window_name):
+ """Shows a plot for the given models"""
+ from .taurusplot import plot_main
+ return plot_main(models=models,
+ config_file=config_file,
+ x_axis_mode=x_axis_mode,
+ demo=demo,
+ window_name=window_name
+ )
+
+
+@qwt5.command('trend')
+@click.argument('models', nargs=-1)
+@click.option("-x", "--x-axis-mode", "x_axis_mode",
+ type=click.Choice(['t', 'n']),
+ default='n',
+ show_default=True,
+ help=('X axis mode. "t" implies using a Date axis'
+ + '"n" uses the regular axis')
+ )
+@click.option('-a', '--use-archiving', 'use_archiving',
+ is_flag=True,
+ default=False,
+ help='enable automatic archiving queries')
+@click.option('-b', '--buffer', 'max_buffer_size', type=int,
+ default=TaurusTrend.DEFAULT_MAX_BUFFER_SIZE,
+ show_default=True,
+ help='maximum number of values per curve to be plotted')
+@click.option('-r', '--forced-read', 'forced_read_period', type=int,
+ default=-1,
+ metavar="MILLISECONDS",
+ help="force re-reading of the attributes every MILLISECONDS ms")
+@click.option('--config', 'config_file', type=click.File('rb'),
+ help='configuration file for initialization')
+@click.option("--demo", is_flag=True, help="show a demo of the widget")
+@click.option('--window-name', 'window_name',
+ default='TaurusPlot (qwt5)',
+ help='Name of the window')
+def trend_cmd(models, x_axis_mode, use_archiving, max_buffer_size,
+ forced_read_period, config_file, demo, window_name):
+ """Shows a trend for the given models"""
+ from .taurustrend import trend_main
+ return trend_main(models=models,
+ config_file=config_file,
+ x_axis_mode=x_axis_mode,
+ use_archiving=use_archiving,
+ max_buffer_size=max_buffer_size,
+ forced_read_period=forced_read_period,
+ demo=demo,
+ window_name=window_name
+ )
+
+
+if __name__ == '__main__':
+ qwt5()
diff --git a/lib/taurus/qt/qtgui/qwt5/curveprops.py b/lib/taurus/qt/qtgui/qwt5/curveprops.py
index e5a4054f..a6dd35aa 100755..100644
--- a/lib/taurus/qt/qtgui/qwt5/curveprops.py
+++ b/lib/taurus/qt/qtgui/qwt5/curveprops.py
@@ -31,6 +31,7 @@ curveprops: Model and view for curve properties
from __future__ import absolute_import
from builtins import str
+from builtins import bytes
from builtins import object
import copy
@@ -294,11 +295,12 @@ class CurvesTableModel(Qt.QAbstractTableModel):
else:
column = parent.columnCount()
if data.hasFormat(TAURUS_ATTR_MIME_TYPE):
- self.setData(self.index(row, column),
- value=str(data.data(TAURUS_ATTR_MIME_TYPE)))
+ model = bytes(data.data(TAURUS_ATTR_MIME_TYPE)).decode('utf-8')
+ self.setData(self.index(row, column), value=model)
return True
elif data.hasFormat(TAURUS_MODEL_LIST_MIME_TYPE):
- models = str(data.data(TAURUS_MODEL_LIST_MIME_TYPE)).split()
+ d = bytes(data.data(TAURUS_MODEL_LIST_MIME_TYPE))
+ models = d.decode('utf-8').split()
if len(models) == 1:
self.setData(self.index(row, column), value=models[0])
return True
@@ -617,7 +619,7 @@ class CurvePropertiesView(Qt.QAbstractItemView):
def main():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
curves = [CurveConf(xsrc='', ysrc='tango://host:1000/a/b/c/d', properties=None, title="tangocurve", vis=Qwt5.QwtPlot.yLeft),
CurveConf(xsrc='=[1,2,3]', ysrc='=#2.x**2',
diff --git a/lib/taurus/qt/qtgui/qwt5/curvesAppearanceChooserDlg.py b/lib/taurus/qt/qtgui/qwt5/curvesAppearanceChooserDlg.py
index 724a058f..039d73e2 100644
--- a/lib/taurus/qt/qtgui/qwt5/curvesAppearanceChooserDlg.py
+++ b/lib/taurus/qt/qtgui/qwt5/curvesAppearanceChooserDlg.py
@@ -34,7 +34,7 @@ from __future__ import print_function
from builtins import object
import copy
-from taurus.external.qt import Qt, Qwt5
+from taurus.external.qt import Qt, Qwt5, compat
from taurus.core.util.containers import CaselessDict
from taurus.qt.qtgui.util.ui import UILoadable
@@ -106,7 +106,7 @@ class CurvesAppearanceChooser(Qt.QWidget):
NAME_ROLE = Qt.Qt.UserRole
controlChanged = Qt.pyqtSignal()
- curveAppearanceChanged = Qt.pyqtSignal(object, list)
+ curveAppearanceChanged = Qt.pyqtSignal(compat.PY_OBJECT, list)
CurveTitleEdited = Qt.pyqtSignal('QString', 'QString')
def __init__(self, parent=None, curvePropDict={}, showButtons=False, autoApply=False, designMode=False):
diff --git a/lib/taurus/qt/qtgui/qwt5/monitor.py b/lib/taurus/qt/qtgui/qwt5/monitor.py
index deab6d7f..be6a8108 100644
--- a/lib/taurus/qt/qtgui/qwt5/monitor.py
+++ b/lib/taurus/qt/qtgui/qwt5/monitor.py
@@ -88,7 +88,7 @@ if __name__ == "__main__":
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
args = sys.argv[1:]
diff --git a/lib/taurus/qt/qtgui/qwt5/taurusplot.py b/lib/taurus/qt/qtgui/qwt5/taurusplot.py
index 7680c93f..d562e634 100644
--- a/lib/taurus/qt/qtgui/qwt5/taurusplot.py
+++ b/lib/taurus/qt/qtgui/qwt5/taurusplot.py
@@ -52,7 +52,7 @@ from taurus.core.taurusbasetypes import DataFormat
# TODO: Tango-centric
from taurus.core.util.containers import LoopList, CaselessDict, CaselessList
from taurus.core.util.safeeval import SafeEvaluator
-from taurus.qt.qtcore.util.signal import baseSignal
+from taurus.qt.qtcore.util import baseSignal
from taurus.qt.qtcore.mimetypes import TAURUS_MODEL_LIST_MIME_TYPE, TAURUS_ATTR_MIME_TYPE
from taurus.qt.qtgui.base import TaurusBaseComponent, TaurusBaseWidget
from taurus.qt.qtgui.qwt5 import TaurusPlotConfigDialog, FancyScaleDraw,\
@@ -2513,8 +2513,8 @@ class TaurusPlot(Qwt5.QwtPlot, TaurusBaseWidget):
)
if not ofile:
return
- if not isinstance(ofile, file):
- ofile = open(ofile, 'w')
+ if isinstance(ofile, string_types):
+ ofile = open(ofile, 'wb')
configdict = self.createConfig(curvenames=curvenames)
self.info("Saving current settings in '%s'" % ofile.name)
pickle.dump(configdict, ofile)
@@ -2534,8 +2534,8 @@ class TaurusPlot(Qwt5.QwtPlot, TaurusBaseWidget):
'TaurusPlot Curve Properties File (*.pck)')
if not ifile:
return
- if not isinstance(ifile, file):
- ifile = open(ifile, 'r')
+ if isinstance(ifile, string_types):
+ ifile = open(ifile, 'rb')
configdict = pickle.load(ifile)
self.applyConfig(configdict)
return ifile.name
@@ -3709,79 +3709,37 @@ class TaurusPlot(Qwt5.QwtPlot, TaurusBaseWidget):
"bool", isOptimizationEnabled, setOptimizationEnabled, resetOptimizationEnabled)
-def main():
+def plot_main(models=(), config_file=None, x_axis_mode='n', demo=False,
+ window_name='TaurusPlot (qwt)'):
import sys
- import taurus.qt.qtgui.application
- import taurus.core.util.argparse
-
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [<model1> [<model2>] ...]")
- parser.set_description("a taurus application for plotting 1D data sets")
- parser.add_option("-x", "--x-axis-mode", dest="x_axis_mode", default='e', metavar="t|n",
- help="interprete X values as either timestamps (t) or numbers (n). Accepted values: t|n (e is also accepted as a synonim of n)")
- parser.add_option("--config", "--config-file", dest="config_file", default=None,
- help="use the given config file for initialization")
- parser.add_option("--import-ascii", dest="import_ascii", default=None,
- help="import the given ascii file into the plot")
- parser.add_option("--export", "--export-file", dest="export_file", default=None,
- help="use the given file to as output instead of showing the plot")
- parser.add_option("--window-name", dest="window_name",
- default="TaurusPlot", help="Name of the window")
-
- app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser,
- app_name="taurusplot",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
- if options.x_axis_mode.lower() not in ['t', 'e', 'n']:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- models = args
+ from taurus.qt.qtgui.application import TaurusApplication
+
+ app = TaurusApplication(cmd_line_parser=None, app_name="taurusplot(qwt)")
+
w = TaurusPlot()
- w.setWindowTitle(options.window_name)
- w.setXIsTime(options.x_axis_mode.lower() == 't')
- if options.config_file is not None:
- w.loadConfig(options.config_file)
+ w.setWindowTitle(window_name)
+
+ w.setXIsTime(x_axis_mode.lower() == 't')
+
+ if demo:
+ models = list(models)
+ models.extend(['eval:rand(100)', 'eval:0.5*sqrt(arange(100))'])
- if options.import_ascii is not None:
- w.importAscii([options.import_ascii], xcol=0)
+ if config_file is not None:
+ w.loadConfigFile(config_file)
if models:
- w.setModel(models)
-
- if options.export_file is not None:
- curves = dict.fromkeys(w.trendSets, 0)
-
- def exportIfAllCurves(curve, trend=w, counters=curves):
- curve = str(curve)
- print('*' * 10 + ' %s: Event received for %s ' % (datetime.now().isoformat(), curve) + '*' * 10)
- if curve in counters:
- counters[curve] += 1
- if all(counters.values()):
- trend.exportPdf(options.export_file)
- print('*' * 10 + ' %s: Exported to : %s ' % (datetime.now().isoformat(), options.export_file) + '*' * 10)
- trend.close()
- return
- if not curves:
- w.close()
- else:
- for ts in w.trendSets.values():
- ts.dataChanged.connect(exportIfAllCurves)
- sys.exit(app.exec_()) # exit without showing the widget
+ w.setModel(list(models))
- # show the widget
w.show()
+
# if no models are passed, show the data import dialog
- if (len(models) == 0
- and options.config_file is None
- and options.import_ascii is None
- ):
+ if not models and config_file is None:
w.showDataImportDlg()
sys.exit(app.exec_())
if __name__ == "__main__":
- main()
+ plot_main()
diff --git a/lib/taurus/qt/qtgui/qwt5/taurusplotconf.py b/lib/taurus/qt/qtgui/qwt5/taurusplotconf.py
index d6a8e509..cb15f5d1 100644
--- a/lib/taurus/qt/qtgui/qwt5/taurusplotconf.py
+++ b/lib/taurus/qt/qtgui/qwt5/taurusplotconf.py
@@ -209,7 +209,7 @@ class demo(Qt.QDialog):
def main1():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = demo()
form.show()
sys.exit(app.exec_())
@@ -218,7 +218,7 @@ def main1():
def main2():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
curves = [curveprops.CurveConf(xsrc='', ysrc='tango://host:1000/a/b/c/d', properties=None, title="tangocurve", vis=Qwt5.QwtPlot.yLeft),
curveprops.CurveConf(
diff --git a/lib/taurus/qt/qtgui/qwt5/taurustrend.py b/lib/taurus/qt/qtgui/qwt5/taurustrend.py
index df069d4d..26ab5d1d 100644
--- a/lib/taurus/qt/qtgui/qwt5/taurustrend.py
+++ b/lib/taurus/qt/qtgui/qwt5/taurustrend.py
@@ -1020,7 +1020,12 @@ class TaurusTrend(TaurusPlot):
self._startingTime) # Set a range of 1 min
else:
self.setAxisScale(axis, 0, 10) # Set a range of 10 events
- self.axisWidget(axis).scaleDivChanged.disconnect(self.rescheduleReplot) # disconnects the previous axis
+ w = self.axisWidget(axis)
+ try:
+ # disconnect the previous axis
+ w.scaleDivChanged.disconnect(self.rescheduleReplot)
+ except TypeError:
+ pass # ignore exception if signal was not previously connected
# enable/disable the archiving action
self._useArchivingAction.setEnabled(enable)
# call the parent class method
@@ -1869,8 +1874,8 @@ class TaurusTrend(TaurusPlot):
def test():
import sys
- import taurus.qt.qtgui.application
- app = taurus.qt.qtgui.application.TaurusApplication()
+ from taurus.qt.qtgui.application import TaurusApplication
+ app = TaurusApplication(cmd_line_parser=None)
w = Qt.QWidget()
w.setLayout(Qt.QVBoxLayout())
s = Qt.QSplitter()
@@ -1885,89 +1890,57 @@ def test():
sys.exit(app.exec_())
-def main():
+def trend_main(models=(), config_file=None, x_axis_mode='n',
+ use_archiving=False,
+ max_buffer_size=None,
+ forced_read_period=-1,
+ demo=False,
+ window_name='TaurusTrend (qwt5)'):
import sys
- import taurus.qt.qtgui.application
- import taurus.core.util.argparse
-
- parser = taurus.core.util.argparse.get_taurus_parser()
- parser.set_usage("%prog [options] [<model1> [<model2>] ...]")
- parser.set_description("a taurus application for plotting trends")
- parser.add_option("-x", "--x-axis-mode", dest="x_axis_mode", default='t', metavar="t|e",
- help="interprete X values as either timestamps (t) or event numbers (e). Accepted values: t|e")
- parser.add_option("-b", "--buffer", dest="max_buffer_size", default=TaurusTrend.DEFAULT_MAX_BUFFER_SIZE,
- help="maximum number of values per curve to be plotted (default = %i) (when reached, the oldest values will be discarded)" % TaurusTrend.DEFAULT_MAX_BUFFER_SIZE)
- parser.add_option("--config", "--config-file", dest="config_file", default=None,
- help="use the given config file for initialization")
- parser.add_option("--export", "--export-file", dest="export_file", default=None,
- help="use the given file to as output instead of showing the plot")
- parser.add_option("-r", "--forced-read", dest="forced_read_period", type="int", default=-1, metavar="MILLISECONDS",
- help="force Taurustrend to re-read the attributes every MILLISECONDS ms")
- parser.add_option("-a", "--use-archiving",
- action="store_true", dest="use_archiving", default=False)
- parser.add_option("--window-name", dest="window_name",
- default="TaurusTrend", help="Name of the window")
-
- app = taurus.qt.qtgui.application.TaurusApplication(cmd_line_parser=parser,
- app_name="taurustrend",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
- if options.x_axis_mode.lower() not in ['t', 'e']:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- models = args
+ from taurus.qt.qtgui.application import TaurusApplication
+
+ app = TaurusApplication(cmd_line_parser=None, app_name="taurustrend(qwt5)")
w = TaurusTrend()
- w.setWindowTitle(options.window_name)
+
+ w.setWindowTitle(window_name)
+
+ # demo option
+ if demo:
+ models = list(models)
+ models.extend(['eval:rand()', 'eval:1+rand(2)'])
# xistime option
- w.setXIsTime(options.x_axis_mode.lower() == 't')
+ w.setXIsTime(x_axis_mode.lower() == 't')
+
# max buffer size option
- w.setMaxDataBufferSize(int(options.max_buffer_size))
+ if max_buffer_size is not None:
+ w.setMaxDataBufferSize(max_buffer_size)
+
# configuration file option
- if options.config_file is not None:
- w.loadConfig(options.config_file)
+ if config_file is not None:
+ w.loadConfig(config_file)
+
# set models
if models:
- w.setModel(models)
- # export option
- if options.export_file is not None:
- curves = dict.fromkeys(w.trendSets, 0)
-
- def exportIfAllCurves(curve, trend=w, counters=curves):
- curve = str(curve)
- print('*' * 10 + ' %s: Event received for %s ' % (datetime.now().isoformat(), curve) + '*' * 10)
- if curve in counters:
- counters[curve] += 1
- if all(counters.values()):
- trend.exportPdf(options.export_file)
- print('*' * 10 + ' %s: Exported to : %s ' % (datetime.now().isoformat(), options.export_file) + '*' * 10)
- trend.close()
- return
- if not curves:
- w.close()
- else:
- for ts in w.trendSets.values():
- ts.dataChanged.connect(exportIfAllCurves)
- sys.exit(app.exec_()) # exit without showing the widget
+ w.setModel(list(models))
# period option
- if options.forced_read_period > 0:
- w.setForcedReadingPeriod(options.forced_read_period)
+ if forced_read_period > 0:
+ w.setForcedReadingPeriod(forced_read_period)
# archiving option
- w.setUseArchiving(options.use_archiving)
+ w.setUseArchiving(use_archiving)
# show the widget
w.show()
# if no models are passed, show the data import dialog
- if len(models) == 0 and options.config_file is None:
+ if not models and config_file is None:
w.showDataImportDlg()
sys.exit(app.exec_())
+
if __name__ == "__main__":
- main()
+ trend_main()
diff --git a/lib/taurus/qt/qtgui/resource/taurus_resource_utils.py b/lib/taurus/qt/qtgui/resource/taurus_resource_utils.py
index b2fbee6a..d9fa73d0 100644
--- a/lib/taurus/qt/qtgui/resource/taurus_resource_utils.py
+++ b/lib/taurus/qt/qtgui/resource/taurus_resource_utils.py
@@ -166,7 +166,7 @@ if __name__ == '__main__':
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
diff --git a/lib/taurus/qt/qtgui/table/qlogtable.py b/lib/taurus/qt/qtgui/table/qlogtable.py
index 3c61cb8d..f0de1be3 100644
--- a/lib/taurus/qt/qtgui/table/qlogtable.py
+++ b/lib/taurus/qt/qtgui/table/qlogtable.py
@@ -36,6 +36,7 @@ import logging.handlers
import datetime
import threading
import socket
+import click
import taurus
from taurus.core.util.log import Logger
@@ -597,5 +598,42 @@ def main():
app.exec_()
w.stop_logging()
+
+@click.command('qlogmon')
+@click.option('--port', 'port', type=int,
+ default=logging.handlers.DEFAULT_TCP_LOGGING_PORT,
+ show_default=True,
+ help='port where log server is running')
+@click.option('--log-name', 'log_name', default=None,
+ help='filter specific log object')
+@click.option('--log-level', 'log_level',
+ type=click.Choice(['critical', 'error', 'warning', 'info',
+ 'debug', 'trace']),
+ default='debug', show_default=True,
+ help='filter specific log level')
+def qlogmon_cmd(port, log_name, log_level):
+ """Show the Taurus Remote Log Monitor"""
+ import taurus
+ host = socket.gethostname()
+ level = getattr(taurus, log_level.capitalize(), taurus.Trace)
+
+ from taurus.qt.qtgui.application import TaurusApplication
+ app = TaurusApplication(cmd_line_parser=None,
+ app_name="Taurus remote logger")
+ w = QLoggingWidget(perspective="Remote")
+ w.setMinimumSize(1024, 600)
+
+ filterbar = w.getFilterBar()
+ filterbar.setLogLevel(level)
+ if log_name is not None:
+ filterbar.setFilterText(log_name)
+ w.getPerspectiveBar().setEnabled(False)
+ w.getQModel().connect_logging(host, port)
+ w.show()
+ app.exec_()
+ w.getQModel().disconnect_logging()
+
+
if __name__ == '__main__':
main()
+ # qlogmon_cmd
diff --git a/lib/taurus/qt/qtgui/table/taurusdevicepropertytable.py b/lib/taurus/qt/qtgui/table/taurusdevicepropertytable.py
index 74f5565b..c256fcca 100755..100644
--- a/lib/taurus/qt/qtgui/table/taurusdevicepropertytable.py
+++ b/lib/taurus/qt/qtgui/table/taurusdevicepropertytable.py
@@ -436,7 +436,8 @@ class Delegate(QtGui.QItemDelegate):
if __name__ == '__main__':
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(app_name="TaurusDevice property table")
+ app = TaurusApplication(app_name="TaurusDevice property table",
+ cmd_line_parser=None)
widget = TaurusPropTable()
args = sys.argv
if len(args) == 1:
diff --git a/lib/taurus/qt/qtgui/table/taurusgrid.py b/lib/taurus/qt/qtgui/table/taurusgrid.py
index a061968d..b9570a6c 100644
--- a/lib/taurus/qt/qtgui/table/taurusgrid.py
+++ b/lib/taurus/qt/qtgui/table/taurusgrid.py
@@ -299,7 +299,7 @@ class TaurusGrid(QtGui.QFrame, TaurusBaseWidget):
'labels': self._show_attr_labels,
'units': self._show_attr_units, 'others': self._show_others
}
- f = open(filename, 'w')
+ f = open(filename, 'wb')
pickle.dump(d, f)
f.close()
@@ -308,7 +308,7 @@ class TaurusGrid(QtGui.QFrame, TaurusBaseWidget):
if not isinstance(filename, dict):
manual = False
import pickle
- f = open(filename)
+ f = open(filename, 'rb')
d = pickle.load(f)
f.close()
else:
@@ -1060,7 +1060,7 @@ if __name__ == '__main__':
print('\t/usr/bin/python taurusgrid.py "model=lt.*/VC.*/.*/((C*)|(P*)|(I*))" cols=IP,CCG,PNV rows=LT01,LT02 others=False rowframe=True colframe=False')
exit()
- app = TaurusApplication(sys.argv[0:1])
+ app = TaurusApplication(sys.argv[0:1], cmd_line_parser=None)
gui = TaurusGrid()
try: # first try if argument is a file to be opened
diff --git a/lib/taurus/qt/qtgui/table/taurusvaluestable.py b/lib/taurus/qt/qtgui/table/taurusvaluestable.py
index 567ea37c..567ea37c 100755..100644
--- a/lib/taurus/qt/qtgui/table/taurusvaluestable.py
+++ b/lib/taurus/qt/qtgui/table/taurusvaluestable.py
diff --git a/lib/taurus/qt/qtgui/taurusgui/__init__.py b/lib/taurus/qt/qtgui/taurusgui/__init__.py
index 021658dd..efd300cd 100644
--- a/lib/taurus/qt/qtgui/taurusgui/__init__.py
+++ b/lib/taurus/qt/qtgui/taurusgui/__init__.py
@@ -35,7 +35,7 @@ The "new GUI wizard" and XML configuration files
------------------------------------------------
Note that the configuration files can either be written by hand or by
-launching the "new GUI" wizard with `taurusgui --new-gui`, which will create
+launching the "new GUI" wizard with `taurus newgui`, which will create
a new directory containing configuration, resource and launcher files.
The new GUI wizard stores all the options in xml format in a file called
@@ -51,7 +51,6 @@ prevail).
"""
from __future__ import absolute_import
-from . import utils
from .paneldescriptionwizard import *
from .taurusgui import *
from .appsettingswizard import *
diff --git a/lib/taurus/qt/qtgui/taurusgui/appsettingswizard.py b/lib/taurus/qt/qtgui/taurusgui/appsettingswizard.py
index 066b6899..f3402909 100644
--- a/lib/taurus/qt/qtgui/taurusgui/appsettingswizard.py
+++ b/lib/taurus/qt/qtgui/taurusgui/appsettingswizard.py
@@ -45,12 +45,11 @@ import datetime
import glob
from lxml import etree
-from taurus import tauruscustomsettings
+from taurus import tauruscustomsettings, warning
from taurus.external.qt import Qt, compat
import taurus.qt.qtgui.panel
import taurus.qt.qtgui.taurusgui.paneldescriptionwizard
import taurus.qt.qtgui.input
-from taurus.core.tango.tangovalidator import TangoDeviceNameValidator
from taurus.core.util.enumeration import Enumeration
from taurus.qt.qtgui.util import ExternalAppAction
@@ -726,6 +725,12 @@ class MacroServerInfoPage(BasePage):
def _getMacroServerName(self):
if (self._macroGroupBox.isChecked()) and len(self._confWidget.macroServerComboBox.currentText()):
+ try: # TODO: tango-centric
+ from taurus.core.tango.tangovalidator import (
+ TangoDeviceNameValidator)
+ except ImportError:
+ warning('Cannot import tango (needed for sardana integration)')
+ return None
ms_name = str(self._confWidget.macroServerComboBox.currentText())
complete_name, _, _ = TangoDeviceNameValidator().getNames(ms_name)
return complete_name
@@ -735,6 +740,12 @@ class MacroServerInfoPage(BasePage):
def _getDoorName(self):
if (self._macroGroupBox.isChecked()) and len(self._confWidget.macroServerComboBox.currentText()):
door_name = str(self._confWidget.doorComboBox.currentText())
+ try: # TODO: tango-centric
+ from taurus.core.tango.tangovalidator import (
+ TangoDeviceNameValidator)
+ except ImportError:
+ warning('Cannot import tango (needed for sardana integration)')
+ return None
complete_name, _, _ = TangoDeviceNameValidator().getNames(
door_name)
return complete_name
@@ -861,7 +872,8 @@ class PanelsPage(BasePage):
name = AppSettingsWizard.getValueFromNode(
child, "name", default=None)
if name:
- self._panels.append((name, etree.tostring(child)))
+ self._panels.append(
+ (name, etree.tostring(child, encoding='unicode')))
def _addPanel(self):
paneldesc, ok = taurus.qt.qtgui.taurusgui.paneldescriptionwizard.PanelDescriptionWizard.getDialog(
@@ -1057,7 +1069,7 @@ class ExternalAppEditor(Qt.QDialog):
icon = etree.SubElement(root, "icon")
icon.text = self._getIcon()
- return etree.tostring(root)
+ return etree.tostring(root, encoding='unicode')
@staticmethod
def getDialog():
@@ -1131,7 +1143,9 @@ class ExternalAppPage(BasePage):
name = AppSettingsWizard.getValueFromNode(
child, "command", default=None)
if name:
- self._externalApps.append((name, etree.tostring(child)))
+ self._externalApps.append(
+ (name, etree.tostring(child, encoding='unicode'))
+ )
def _addApplication(self):
name, xml, ok = ExternalAppEditor.getDialog()
@@ -1673,7 +1687,8 @@ class AppSettingsWizard(Qt.QWizard):
monitor = etree.SubElement(root, "MONITOR")
monitor.text = self.__getitem__("monitor")
- return etree.tostring(root, pretty_print=True), copy.copy(self._substitutions)
+ return (etree.tostring(root, pretty_print=True, encoding='unicode'),
+ copy.copy(self._substitutions))
def substitutionName(self, src, mod_dir):
name = os.path.basename(src)
diff --git a/lib/taurus/qt/qtgui/taurusgui/conf/gui_noconf.py b/lib/taurus/qt/qtgui/taurusgui/conf/gui_noconf.py
index 21bca2a5..87e0e94b 100755..100644
--- a/lib/taurus/qt/qtgui/taurusgui/conf/gui_noconf.py
+++ b/lib/taurus/qt/qtgui/taurusgui/conf/gui_noconf.py
@@ -32,7 +32,7 @@ if __name__ == '__main__':
from taurus.qt.qtgui.taurusgui import TaurusGui
from taurus.external.qt import Qt
# if app_name name not given, it uses the file name
- app = TaurusApplication(app_name='MyGui')
+ app = TaurusApplication(app_name='MyGui', cmd_line_parser=None)
gui = TaurusGui()
panel = Qt.QWidget()
gui.createPanel(panel, 'Foo')
diff --git a/lib/taurus/qt/qtgui/taurusgui/conf/gui_selfconf.py b/lib/taurus/qt/qtgui/taurusgui/conf/gui_selfconf.py
index d1b705f3..c2256413 100755..100644
--- a/lib/taurus/qt/qtgui/taurusgui/conf/gui_selfconf.py
+++ b/lib/taurus/qt/qtgui/taurusgui/conf/gui_selfconf.py
@@ -34,7 +34,7 @@ if __name__ == '__main__':
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.taurusgui import TaurusGui
from taurus.external.qt import Qt
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
gui = TaurusGui(confname=__file__)
panel = Qt.QWidget()
gui.createPanel(panel, 'Foo')
diff --git a/lib/taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/tgconf_macrogui.ini b/lib/taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/tgconf_macrogui.ini
deleted file mode 100644
index 44905da4..00000000
--- a/lib/taurus/qt/qtgui/taurusgui/conf/tgconf_macrogui/tgconf_macrogui.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-[Perspectives]
-Default\MainWindow\State=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x1\0\0\0\x3\0\0\x3R\0\0\x2\xa6\xfc\x1\0\0\0\x2\xfb\0\0\0\x10\0l\0o\0g\0g\0\x65\0r\0\x44\0W\0\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfc\0\0\0\0\0\0\x3R\0\0\x2\x1d\0\xff\xff\xff\xfc\x2\0\0\0\x2\xfc\0\0\0\x36\0\0\x1\xd3\0\0\x1N\0\xff\xff\xff\xfc\x1\0\0\0\x2\xfb\0\0\0\f\0M\0\x61\0\x63\0r\0o\0s\x1\0\0\0\0\0\0\x1\x86\0\0\0\xe8\x1\0\0\x5\xfc\0\0\x1\x89\0\0\x1\xc9\0\0\x1\x32\0\xff\xff\xff\xfc\x2\0\0\0\x2\xfb\0\0\0\x10\0\x31\0\x44\0 \0S\0\x63\0\x61\0n\0s\x1\0\0\0\x36\0\0\x1\x12\0\0\0\xe4\x1\0\0\x5\xfb\0\0\0 \0M\0\x61\0\x63\0r\0o\0\x44\0\x65\0s\0\x63\0r\0i\0p\0t\0i\0o\0n\x1\0\0\x1K\0\0\0\xbe\0\0\0_\x1\0\0\x5\xfc\0\0\x2\f\0\0\0\xd0\0\0\0|\x1\0\0\x1c\xfa\0\0\0\0\x1\0\0\0\x3\xfb\0\0\0\x14\0\x44\0o\0o\0r\0O\0u\0t\0p\0u\0t\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfb\0\0\0\x12\0\x44\0o\0o\0r\0\x44\0\x65\0\x62\0u\0g\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfb\0\0\0\x14\0\x44\0o\0o\0r\0R\0\x65\0s\0u\0l\0t\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\0\0\x3R\0\0\0\0\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x2\0\0\0\x1\0\0\0\x1\0\0\0\x18\0j\0o\0r\0g\0s\0T\0o\0o\0l\0\x42\0\x61\0r\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x2\0\0\0\x3\0\0\0&\0p\0\x65\0r\0s\0p\0\x65\0\x63\0t\0i\0v\0\x65\0s\0T\0o\0o\0l\0\x42\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x1a\0P\0\x61\0n\0\x65\0l\0s\0T\0o\0o\0l\0\x62\0\x61\0r\x1\0\0\0\xb2\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0*\0\x45\0x\0t\0\x65\0r\0n\0\x61\0l\0 \0\x41\0p\0p\0l\0i\0\x63\0\x61\0t\0i\0o\0n\0s\x1\0\0\0\xd8\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
-Default\MainWindow\Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\xf2\0\0\0\xbc\0\0\x4\x91\0\0\x3\xc6\0\0\0\xf6\0\0\0\xd3\0\0\x4\x8d\0\0\x3\xc2\0\0\0\0\0\0)
-Default\TaurusConfig=@ByteArray((dp1\nS'__orderedConfigNames__'\np2\n(lp3\nS'modifiableByUser'\np4\naS'ModelInConfig'\np5\naS'permanentCustomPanels'\np6\naS'Macros'\np7\naS'MacroDescription'\np8\naS'1D Scans'\np9\naS'_extApp[pymca]'\np10\naS'_extApp[Spock]'\np11\nasS'__itemConfigurations__'\np12\n(dp13\ng7\n(dp14\ng2\n(lp15\ng4\nag5\nasS'widget'\np16\n(dp17\ng2\n(lp18\ng4\nag5\naS'aaaaa'\np19\nasg12\n(dp20\ng4\nI00\nsg19\n(dp21\ng2\n(lp22\ng4\nag5\naS'favourites'\np23\naS''\nasg12\n(dp24\ng4\nI00\nsS''\n(dp25\ng2\n(lp26\nsg12\n(dp27\nsS'ConfigVersion'\np28\nS'__UNVERSIONED__'\np29\nsS'__pickable__'\np30\nI01\nssg23\nS'<list/>'\np31\nsg5\nI00\nssg28\ng29\nsg30\nI01\nssg5\nI00\nssg28\ng29\nsg30\nI01\nssg30\nI01\nsg12\n(dp32\ng4\nI00\nsg5\nI00\nssg28\ng29\nsS'widgetClassName'\np33\nS'TaurusMacroExecutorWidget'\np34\nssg4\nI00\nsg8\n(dp35\ng2\n(lp36\ng4\nag5\nasg16\n(dp37\ng2\n(lp38\ng4\nag5\nasg12\n(dp39\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg30\nI01\nssg30\nI01\nsg12\n(dp40\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg33\nS'TaurusMacroDescriptionViewer'\np41\nssg9\n(dp42\ng2\n(lp43\ng4\nag5\nasg16\n(dp44\nS'CurveProp'\np45\n(dp46\nsS'TrendSets'\np47\nccopy_reg\n_reconstructor\np48\n(ctaurus.core.util.containers\nCaselessDict\np49\nc__builtin__\ndict\np50\n(dtRp51\nsS'Axes'\np52\n(dp53\nS'xIsTime'\np54\nI00\nsS'y1Max'\np55\nNsS'y1Min'\np56\nNsS'xMode'\np57\ncsip\n_unpickle_enum\np58\n(S'PyQt4.Qwt5.Qwt'\np59\nS'Type'\nI0\ntRp60\nsS'xMax'\np61\nNsS'y2Min'\np62\nNsS'y2Mode'\np63\ng58\n(g59\nS'Type'\nI0\ntRp64\nsS'y1Mode'\np65\ng58\n(g59\nS'Type'\nI0\ntRp66\nsS'y2Max'\np67\nNsS'xDyn'\np68\nI00\nsS'xMin'\np69\nNssS'Misc'\np70\n(dp71\nS'canvasBackground'\np72\ncsip\n_unpickle_type\np73\n(S'PyQt4.QtGui'\np74\nS'QColor'\n(I224\nI223\nI222\nI255\nttRp75\nsS'defaultCurvesTitle'\np76\nS'<label><[trend_index]>'\np77\nsS'plotTitle'\np78\nV\nsS'orderedCurveNames'\np79\n(lp80\nssS'RawData'\np81\ng48\n(g49\ng50\n(dtRp82\nsg28\nS'ttc-1'\np83\nssg30\nI01\nsg12\n(dp84\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg33\nS'TaurusTrend'\np85\nssg10\n(dp86\ng2\n(lp87\nS'cmdArgs'\np88\nasg12\n(dp89\ng88\n(lp90\nS'pymca'\np91\nassg28\ng29\nsg30\nI01\nssg6\n(lp92\nsg5\nI00\nsg11\n(dp93\ng2\n(lp94\ng88\nasg12\n(dp95\ng88\n(lp96\nS'xterm'\np97\naS'spock'\np98\nassg28\ng29\nsg30\nI01\nsssg28\ng29\nsg30\nI01\ns.)
-
-[MainWindow]
-State=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\x1\0\0\0\x3\0\0\x3R\0\0\x2\xa6\xfc\x1\0\0\0\x2\xfb\0\0\0\x10\0l\0o\0g\0g\0\x65\0r\0\x44\0W\0\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfc\0\0\0\0\0\0\x3R\0\0\x2\x1d\0\xff\xff\xff\xfc\x2\0\0\0\x2\xfc\0\0\0\x36\0\0\x1\xd3\0\0\x1N\0\xff\xff\xff\xfc\x1\0\0\0\x2\xfb\0\0\0\f\0M\0\x61\0\x63\0r\0o\0s\x1\0\0\0\0\0\0\x1\x86\0\0\0\xe8\x1\0\0\x5\xfc\0\0\x1\x89\0\0\x1\xc9\0\0\x1\x32\0\xff\xff\xff\xfc\x2\0\0\0\x2\xfb\0\0\0\x10\0\x31\0\x44\0 \0S\0\x63\0\x61\0n\0s\x1\0\0\0\x36\0\0\x1\x12\0\0\0\xe4\x1\0\0\x5\xfb\0\0\0 \0M\0\x61\0\x63\0r\0o\0\x44\0\x65\0s\0\x63\0r\0i\0p\0t\0i\0o\0n\x1\0\0\x1K\0\0\0\xbe\0\0\0_\x1\0\0\x5\xfc\0\0\x2\f\0\0\0\xd0\0\0\0|\x1\0\0\x1c\xfa\0\0\0\0\x1\0\0\0\x3\xfb\0\0\0\x14\0\x44\0o\0o\0r\0O\0u\0t\0p\0u\0t\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfb\0\0\0\x12\0\x44\0o\0o\0r\0\x44\0\x65\0\x62\0u\0g\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\xfb\0\0\0\x14\0\x44\0o\0o\0r\0R\0\x65\0s\0u\0l\0t\x1\0\0\0\0\xff\xff\xff\xff\0\0\0M\x1\0\0\x5\0\0\x3R\0\0\0\0\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\x2\0\0\0\x1\0\0\0\x1\0\0\0\x18\0j\0o\0r\0g\0s\0T\0o\0o\0l\0\x42\0\x61\0r\x3\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x2\0\0\0\x3\0\0\0&\0p\0\x65\0r\0s\0p\0\x65\0\x63\0t\0i\0v\0\x65\0s\0T\0o\0o\0l\0\x42\0\x61\0r\x1\0\0\0\0\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0\x1a\0P\0\x61\0n\0\x65\0l\0s\0T\0o\0o\0l\0\x62\0\x61\0r\x1\0\0\0\xb2\xff\xff\xff\xff\0\0\0\0\0\0\0\0\0\0\0*\0\x45\0x\0t\0\x65\0r\0n\0\x61\0l\0 \0\x41\0p\0p\0l\0i\0\x63\0\x61\0t\0i\0o\0n\0s\x1\0\0\0\xd8\xff\xff\xff\xff\0\0\0\0\0\0\0\0)
-Geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x1\0\0\0\0\0\xf2\0\0\0\xbc\0\0\x4\x91\0\0\x3\xc6\0\0\0\xf6\0\0\0\xd3\0\0\x4\x8d\0\0\x3\xc2\0\0\0\0\0\0)
-
-[General]
-TaurusConfig=@ByteArray((dp1\nS'__orderedConfigNames__'\np2\n(lp3\nS'modifiableByUser'\np4\naS'ModelInConfig'\np5\naS'permanentCustomPanels'\np6\naS'Macros'\np7\naS'MacroDescription'\np8\naS'1D Scans'\np9\naS'_extApp[pymca]'\np10\naS'_extApp[Spock]'\np11\nasS'__itemConfigurations__'\np12\n(dp13\ng7\n(dp14\ng2\n(lp15\ng4\nag5\nasS'widget'\np16\n(dp17\ng2\n(lp18\ng4\nag5\naS'aaaaa'\np19\nasg12\n(dp20\ng4\nI00\nsg19\n(dp21\ng2\n(lp22\ng4\nag5\naS'favourites'\np23\naS''\nasg12\n(dp24\ng4\nI00\nsS''\n(dp25\ng2\n(lp26\nsg12\n(dp27\nsS'ConfigVersion'\np28\nS'__UNVERSIONED__'\np29\nsS'__pickable__'\np30\nI01\nssg23\nS'<list/>'\np31\nsg5\nI00\nssg28\ng29\nsg30\nI01\nssg5\nI00\nssg28\ng29\nsg30\nI01\nssg30\nI01\nsg12\n(dp32\ng4\nI00\nsg5\nI00\nssg28\ng29\nsS'widgetClassName'\np33\nS'TaurusMacroExecutorWidget'\np34\nssg4\nI00\nsg8\n(dp35\ng2\n(lp36\ng4\nag5\nasg16\n(dp37\ng2\n(lp38\ng4\nag5\nasg12\n(dp39\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg30\nI01\nssg30\nI01\nsg12\n(dp40\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg33\nS'TaurusMacroDescriptionViewer'\np41\nssg9\n(dp42\ng2\n(lp43\ng4\nag5\nasg16\n(dp44\nS'CurveProp'\np45\n(dp46\nsS'TrendSets'\np47\nccopy_reg\n_reconstructor\np48\n(ctaurus.core.util.containers\nCaselessDict\np49\nc__builtin__\ndict\np50\n(dtRp51\nsS'Axes'\np52\n(dp53\nS'xIsTime'\np54\nI00\nsS'y1Max'\np55\nNsS'y1Min'\np56\nNsS'xMode'\np57\ncsip\n_unpickle_enum\np58\n(S'PyQt4.Qwt5.Qwt'\np59\nS'Type'\nI0\ntRp60\nsS'xMax'\np61\nNsS'y2Min'\np62\nNsS'y2Mode'\np63\ng58\n(g59\nS'Type'\nI0\ntRp64\nsS'y1Mode'\np65\ng58\n(g59\nS'Type'\nI0\ntRp66\nsS'y2Max'\np67\nNsS'xDyn'\np68\nI00\nsS'xMin'\np69\nNssS'Misc'\np70\n(dp71\nS'canvasBackground'\np72\ncsip\n_unpickle_type\np73\n(S'PyQt4.QtGui'\np74\nS'QColor'\n(I224\nI223\nI222\nI255\nttRp75\nsS'defaultCurvesTitle'\np76\nS'<label><[trend_index]>'\np77\nsS'plotTitle'\np78\nV\nsS'orderedCurveNames'\np79\n(lp80\nssS'RawData'\np81\ng48\n(g49\ng50\n(dtRp82\nsg28\nS'ttc-1'\np83\nssg30\nI01\nsg12\n(dp84\ng4\nI00\nsg5\nI00\nssg28\ng29\nsg33\nS'TaurusTrend'\np85\nssg10\n(dp86\ng2\n(lp87\nS'cmdArgs'\np88\nasg12\n(dp89\ng88\n(lp90\nS'pymca'\np91\nassg28\ng29\nsg30\nI01\nssg6\n(lp92\nsg5\nI00\nsg11\n(dp93\ng2\n(lp94\ng88\nasg12\n(dp95\ng88\n(lp96\nS'xterm'\np97\naS'spock'\np98\nassg28\ng29\nsg30\nI01\nsssg28\ng29\nsg30\nI01\ns.)
diff --git a/lib/taurus/qt/qtgui/taurusgui/paneldescriptionwizard.py b/lib/taurus/qt/qtgui/taurusgui/paneldescriptionwizard.py
index a4fa08ca..0acf0029 100644
--- a/lib/taurus/qt/qtgui/taurusgui/paneldescriptionwizard.py
+++ b/lib/taurus/qt/qtgui/taurusgui/paneldescriptionwizard.py
@@ -35,7 +35,6 @@ import weakref
from taurus.qt.qtgui.taurusgui.utils import PanelDescription
from taurus.qt.qtgui.icon import getCachedPixmap
from taurus.qt.qtgui.input import GraphicalChoiceWidget
-from taurus.qt.qtgui.panel import TaurusModelChooser
from taurus.qt.qtgui.base import TaurusBaseComponent, TaurusBaseWidget
from taurus.qt.qtcore.communication import SharedDataManager
from taurus.qt.qtcore.mimetypes import TAURUS_MODEL_LIST_MIME_TYPE
@@ -429,6 +428,7 @@ class AdvSettingsPage(Qt.QWizardPage):
self.commLV.setItemDelegate(self.itemDelegate)
def showModelChooser(self):
+ from taurus.qt.qtgui.panel import TaurusModelChooser
models, ok = TaurusModelChooser.modelChooserDlg(
parent=self, asMimeData=True)
if not ok:
@@ -652,7 +652,7 @@ class PanelDescriptionWizard(Qt.QWizard, TaurusBaseWidget):
def test():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
form = PanelDescriptionWizard()
def kk(d):
@@ -667,14 +667,14 @@ def test():
def test2():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
print(ExpertWidgetChooserDlg.getDialog())
sys.exit()
def main():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication(sys.argv)
+ app = TaurusApplication(sys.argv, cmd_line_parser=None)
from taurus.qt.qtgui.container import TaurusMainWindow
form = Qt.QMainWindow()
diff --git a/lib/taurus/qt/qtgui/taurusgui/res/init.template b/lib/taurus/qt/qtgui/taurusgui/res/init.template
index 08f2543d..b14a87b6 100644
--- a/lib/taurus/qt/qtgui/taurusgui/res/init.template
+++ b/lib/taurus/qt/qtgui/taurusgui/res/init.template
@@ -2,9 +2,17 @@
This file was autogenerated by taurusgui --new-gui.
"""
-from config import *
+from __future__ import absolute_import
+import click
+from .config import *
-def run():
- from taurus.qt.qtgui.taurusgui.taurusgui import main
- main(confname="tgconf_{name}")
+@click.command("{name}")
+@click.pass_context
+@click.option('--safe-mode', 'safe_mode', is_flag=True, default=False,
+ help=('launch in safe mode (it prevents potentially problematic '
+ 'configs from being loaded)')
+ )
+def run(ctx, safe_mode):
+ from taurus.qt.qtgui.taurusgui.taurusgui import gui_cmd
+ ctx.invoke(gui_cmd, confname="tgconf_{name}", safe_mode=safe_mode)
diff --git a/lib/taurus/qt/qtgui/taurusgui/res/setup.template b/lib/taurus/qt/qtgui/taurusgui/res/setup.template
index 00eba818..0b011fa3 100644
--- a/lib/taurus/qt/qtgui/taurusgui/res/setup.template
+++ b/lib/taurus/qt/qtgui/taurusgui/res/setup.template
@@ -13,11 +13,12 @@ classifiers = [
'Intended Audience :: End Users/Desktop',
'Topic :: Scientific/Engineering',
'Environment :: X11 Applications :: Qt',
- 'Programming Language :: Python :: 2.7'
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3.5'
]
_entry_points = {{
- "gui_scripts": ["{name}=tgconf_{name}:run"]
+ "console_scripts": ["{name}=tgconf_{name}:run"]
}}
setup(
diff --git a/lib/taurus/qt/qtgui/taurusgui/taurusgui.py b/lib/taurus/qt/qtgui/taurusgui/taurusgui.py
index 7228bc60..f46e5c86 100644
--- a/lib/taurus/qt/qtgui/taurusgui/taurusgui.py
+++ b/lib/taurus/qt/qtgui/taurusgui/taurusgui.py
@@ -25,10 +25,13 @@
"""This package provides the TaurusGui class"""
+from __future__ import absolute_import
+
from builtins import str
import os
import sys
import copy
+import click
import weakref
import inspect
@@ -46,8 +49,6 @@ from taurus.qt.qtgui.container import TaurusMainWindow
from taurus.qt.qtgui.taurusgui.utils import (ExternalApp, PanelDescription,
ToolBarDescription,
AppletDescription)
-from taurus.qt.qtgui.taurusgui.appsettingswizard import ExternalAppEditor
-from taurus.qt.qtgui.panel import QDoubleListDlg
from taurus.qt.qtgui.util.ui import UILoadable
from taurus.qt.qtgui.taurusgui.utils import ExternalAppAction
@@ -214,7 +215,7 @@ class DockWidgetPanel(Qt.QDockWidget, TaurusBaseWidget):
class TaurusGui(TaurusMainWindow):
- '''
+ """
This is main class for constructing the dynamic GUIs. TaurusGui is a
specialised TaurusMainWindow which is able to handle "panels" and load
configuration files.
@@ -246,7 +247,7 @@ class TaurusGui(TaurusMainWindow):
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.taurusgui import TaurusGui
from taurus.external.qt import Qt
- app = TaurusApplication(app_name='MyGui')
+ app = TaurusApplication(cmd_line_parser=None, app_name='MyGui')
gui = TaurusGui()
panel = Qt.QWidget()
gui.createPanel(panel, 'Foo')
@@ -265,14 +266,14 @@ class TaurusGui(TaurusMainWindow):
from taurus.qt.qtgui.application import TaurusApplication
from taurus.qt.qtgui.taurusgui import TaurusGui
from taurus.external.qt import Qt
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
gui = TaurusGui(confname=__file__)
panel = Qt.QWidget()
gui.createPanel(panel, 'Foo') # <-- programmatic!
gui.show()
app.exec_()
- '''
+ """
SelectedInstrument = Qt.pyqtSignal('QString')
doorNameChanged = Qt.pyqtSignal('QString')
@@ -281,7 +282,15 @@ class TaurusGui(TaurusMainWindow):
IMPLICIT_ASSOCIATION = '__[IMPLICIT]__'
- def __init__(self, parent=None, confname=None, configRecursionDepth=None):
+ #: Whether to show user actions related to shared data connections
+ PANELS_MENU_ENABLED = True
+ #: Whether to show the applets toolbar
+ APPLETS_TOOLBAR_ENABLED = True
+ #: wether to add the Quick access Toolbar (empty by default)
+ QUICK_ACCESS_TOOLBAR_ENABLED = True
+
+ def __init__(self, parent=None, confname=None, configRecursionDepth=None,
+ settingsname=None):
TaurusMainWindow.__init__(self, parent, False, True)
if configRecursionDepth is not None:
@@ -312,13 +321,34 @@ class TaurusGui(TaurusMainWindow):
# Create a global SharedDataManager
Qt.qApp.SDM = SharedDataManager(self)
- self.__initPanelsMenu()
- self.__initQuickAccessToolBar()
- self.__initJorgBar()
+ # Initialize menus & toolbars
+ if self.PANELS_MENU_ENABLED:
+ self.__initPanelsMenu()
+ self.__initPanelsToolBar()
+ if self.QUICK_ACCESS_TOOLBAR_ENABLED:
+ self.__initQuickAccessToolBar()
+ if self.APPLETS_TOOLBAR_ENABLED:
+ self.__initJorgBar()
+
self.__initSharedDataConnections()
- self.__initToolsMenu()
- self.__initViewMenu()
- self.__initPanelsToolBar()
+
+ if self.TOOLS_MENU_ENABLED:
+ self.__initToolsMenu()
+
+ # Create lockview actions
+ self._lockviewAction = Qt.QAction(Qt.QIcon.fromTheme(
+ "system-lock-screen"), "Lock View", self)
+ self._lockviewAction.setCheckable(True)
+ self._lockviewAction.toggled.connect(self.setLockView)
+ self._lockviewAction.setChecked(not self.isModifiableByUser())
+
+ if self.VIEW_MENU_ENABLED:
+ self.__initViewMenu()
+
+ if settingsname:
+ self.resetQSettings()
+ _s = Qt.QSettings(settingsname, Qt.QSettings.IniFormat)
+ self.setQSettings(_s)
self.loadConfiguration(confname)
@@ -370,7 +400,11 @@ class TaurusGui(TaurusMainWindow):
def __initPanelsMenu(self):
# Panels menu
self.__panelsMenu = Qt.QMenu('Panels', self)
- self.menuBar().insertMenu(self.helpMenu.menuAction(), self.__panelsMenu)
+ try: # insert the panels menu before the help menu
+ self.menuBar().insertMenu(self.helpMenu.menuAction(),
+ self.__panelsMenu)
+ except AttributeError: # Or just add it if help menu is not shown
+ self.menuBar().addMenu(self.__panelsMenu)
self.hideAllPanelsAction = self.__panelsMenu.addAction(
Qt.QIcon('actions:hide.svg'), "Hide all panels", self.hideAllPanels)
self.showAllPanelsAction = self.__panelsMenu.addAction(
@@ -400,11 +434,6 @@ class TaurusGui(TaurusMainWindow):
self.viewMenu.addSeparator()
# view locking
self.viewMenu.addSeparator()
- self._lockviewAction = Qt.QAction(Qt.QIcon.fromTheme(
- "system-lock-screen"), "Lock View", self)
- self._lockviewAction.setCheckable(True)
- self._lockviewAction.toggled.connect(self.setLockView)
- self._lockviewAction.setChecked(not self.isModifiableByUser())
self.viewMenu.addAction(self._lockviewAction)
def __initPanelsToolBar(self):
@@ -412,15 +441,18 @@ class TaurusGui(TaurusMainWindow):
self.panelsToolBar = self.addToolBar("Panels")
self.panelsToolBar.setObjectName("PanelsToolbar")
self.panelsToolBar.addAction(self.newPanelAction)
- self.viewToolBarsMenu.addAction(self.panelsToolBar.toggleViewAction())
+ if self.VIEW_MENU_ENABLED:
+ self.viewToolBarsMenu.addAction(self.panelsToolBar.toggleViewAction())
def __initQuickAccessToolBar(self):
self.quickAccessToolBar = self.addToolBar("Quick Access")
self.quickAccessToolBar.setObjectName("quickAccessToolbar")
self.quickAccessToolBar.setToolButtonStyle(
Qt.Qt.ToolButtonTextBesideIcon)
- self.viewToolBarsMenu.addAction(
- self.quickAccessToolBar.toggleViewAction())
+ if self.VIEW_MENU_ENABLED:
+ self.viewToolBarsMenu.addAction(
+ self.quickAccessToolBar.toggleViewAction()
+ )
def __initJorgBar(self):
# Fancy Stuff ToolBar (aka Jorg's Bar ;) )
@@ -473,6 +505,7 @@ class TaurusGui(TaurusMainWindow):
def createExternalApp(self):
'''Add a new external application on execution time'''
+ from .appsettingswizard import ExternalAppEditor
app_editor = ExternalAppEditor(self)
name, xml, ok = app_editor.getDialog()
if name in self._external_app_names:
@@ -734,6 +767,7 @@ class TaurusGui(TaurusMainWindow):
temp = [n for n, p in self.__panels.items() if (
p.isCustom() and not p.isPermanent())]
if len(temp) > 0 or showAlways:
+ from taurus.qt.qtgui.panel import QDoubleListDlg
dlg = QDoubleListDlg(winTitle='Stored panels',
mainLabel='Select which of the panels should be stored',
label1='Temporary (to be discarded)', label2='Permanent (to be stored)',
@@ -762,6 +796,7 @@ class TaurusGui(TaurusMainWindow):
# be made permanent
#permanet_ext_app = list(self._external_app_names)
if len(self.__external_app) > 0 or showAlways:
+ from taurus.qt.qtgui.panel import QDoubleListDlg
msg = 'Select which of the external applications should be stored'
dlg = QDoubleListDlg(winTitle='Stored external applications',
mainLabel=msg,
@@ -850,8 +885,10 @@ class TaurusGui(TaurusMainWindow):
synopticpanel = self.createPanel(synoptic, name, permanent=True,
icon=Qt.QIcon.fromTheme(
'image-x-generic'))
- toggleSynopticAction = synopticpanel.toggleViewAction()
- self.quickAccessToolBar.addAction(toggleSynopticAction)
+
+ if self.QUICK_ACCESS_TOOLBAR_ENABLED:
+ toggleSynopticAction = synopticpanel.toggleViewAction()
+ self.quickAccessToolBar.addAction(toggleSynopticAction)
def createConsole(self, kernels):
msg = ('createConsole() and the "CONSOLE" configuration key are ' +
@@ -1000,20 +1037,47 @@ class TaurusGui(TaurusMainWindow):
self, 'Initialization error', msg, Qt.QMessageBox.Abort)
sys.exit()
- # Get the xml root node from the xml configuration file
- XML_CONFIG = getattr(conf, 'XML_CONFIG', None)
- if XML_CONFIG is None:
+ xmlroot = self._loadXmlConfig(conf)
+
+ self._loadAppName(conf, confname, xmlroot)
+ self._loadOrgName(conf, xmlroot)
+ self._loadCustomLogo(conf, xmlroot)
+ Qt.QApplication.instance().basicConfig()
+ self._loadOrgLogo(conf, xmlroot)
+
+ self._loadSingleInstance(conf, xmlroot)
+
+ self._loadExtraCatalogWidgets(conf, xmlroot)
+ self._loadManualUri(conf, xmlroot)
+ POOLINSTRUMENTS = self._loadSardanaOptions(conf, xmlroot)
+ self._loadSynoptic(conf, xmlroot)
+ # TODO: remove deprecated _loadConsole
+ self._loadConsole(conf, xmlroot)
+
+ self._loadCustomPanels(conf, xmlroot, POOLINSTRUMENTS)
+ self._loadCustomToolBars(conf, xmlroot)
+ self._loadCustomApplets(conf, xmlroot)
+ self._loadExternalApps(conf, xmlroot)
+ self._loadIniFile(conf, xmlroot)
+
+ def _loadXmlConfig(self, conf):
+ """
+ Get the xml root node from the xml configuration file
+ """
+
+ xml_config = getattr(conf, 'XML_CONFIG', None)
+ if xml_config is None:
self._xmlConfigFileName = None
else:
self._xmlConfigFileName = os.path.join(
- self._confDirectory, XML_CONFIG)
+ self._confDirectory, xml_config)
# default fallback (in case of I/O or parse errors)
xmlroot = etree.fromstring('<root></root>')
- if XML_CONFIG is not None:
+ if xml_config is not None:
try:
# If a relative name was given, the conf directory will be used
# as base path
- xmlfname = os.path.join(self._confDirectory, XML_CONFIG)
+ xmlfname = os.path.join(self._confDirectory, xml_config)
xmlFile = open(xmlfname, 'r')
xmlstring = xmlFile.read()
xmlFile.close()
@@ -1026,162 +1090,204 @@ class TaurusGui(TaurusMainWindow):
msg, repr(e)), Qt.QMessageBox.Abort | Qt.QMessageBox.Ignore)
if result == Qt.QMessageBox.Abort:
sys.exit()
+ return xmlroot
- # General Qt application settings and jorgs bar logos
- APPNAME = getattr(conf, 'GUI_NAME', self.__getVarFromXML(
+ def _loadAppName(self, conf, confname, xmlroot):
+ appname = getattr(conf, 'GUI_NAME', self.__getVarFromXML(
xmlroot, "GUI_NAME", confname))
- ORGNAME = getattr(conf, 'ORGANIZATION', self.__getVarFromXML(
+ Qt.qApp.setApplicationName(appname)
+ self.setWindowTitle(appname)
+
+ def _loadOrgName(self, conf, xmlroot):
+ orgname = getattr(conf, 'ORGANIZATION', self.__getVarFromXML(
xmlroot, "ORGANIZATION", str(Qt.qApp.organizationName()) or 'Taurus'))
- CUSTOMLOGO = getattr(conf, 'CUSTOM_LOGO', getattr(
+ Qt.qApp.setOrganizationName(orgname)
+
+ def _loadCustomLogo(self, conf, xmlroot):
+ custom_logo = getattr(conf, 'CUSTOM_LOGO', getattr(
conf, 'LOGO', self.__getVarFromXML(xmlroot, "CUSTOM_LOGO", 'logos:taurus.png')))
- if Qt.QFile.exists(CUSTOMLOGO):
- customIcon = Qt.QIcon(CUSTOMLOGO)
+ if Qt.QFile.exists(custom_logo):
+ custom_icon = Qt.QIcon(custom_logo)
else:
- customIcon = Qt.QIcon(os.path.join(
- self._confDirectory, CUSTOMLOGO))
- Qt.qApp.setApplicationName(APPNAME)
- Qt.qApp.setOrganizationName(ORGNAME)
- Qt.QApplication.instance().basicConfig()
-
- logo = getattr(tauruscustomsettings, 'ORGANIZATION_LOGO',
+ custom_icon = Qt.QIcon(os.path.join(
+ self._confDirectory, custom_logo))
+ self.setWindowIcon(custom_icon)
+ if self.APPLETS_TOOLBAR_ENABLED:
+ self.jorgsBar.addAction(custom_icon, Qt.qApp.applicationName())
+
+ def _loadOrgLogo(self, conf, xmlroot):
+ logo = getattr(tauruscustomsettings,
+ "ORGANIZATION_LOGO",
"logos:taurus.png")
- ORGANIZATIONLOGO = getattr(conf, 'ORGANIZATION_LOGO',
- self.__getVarFromXML(xmlroot,
- "ORGANIZATION_LOGO",
- logo))
- ##
- if Qt.QFile.exists(ORGANIZATIONLOGO):
- organizationIcon = Qt.QIcon(ORGANIZATIONLOGO)
+ org_logo = getattr(conf,
+ "ORGANIZATION_LOGO",
+ self.__getVarFromXML(xmlroot,
+ "ORGANIZATION_LOGO",
+ logo))
+ if Qt.QFile.exists(org_logo):
+ org_icon = Qt.QIcon(org_logo)
else:
- organizationIcon = Qt.QIcon(os.path.join(
- self._confDirectory, ORGANIZATIONLOGO))
-
- # if required, enforce that only one instance of this GUI can be run
- SINGLEINSTANCE = getattr(conf, 'SINGLE_INSTANCE', (self.__getVarFromXML(
+ org_icon = Qt.QIcon(os.path.join(
+ self._confDirectory, org_logo))
+ if self.APPLETS_TOOLBAR_ENABLED:
+ self.jorgsBar.addAction(org_icon, Qt.qApp.organizationName())
+
+ def _loadSingleInstance(self, conf, xmlroot):
+ """
+ if required, enforce that only one instance of this GUI can be run
+ """
+ single_inst = getattr(conf, 'SINGLE_INSTANCE', (self.__getVarFromXML(
xmlroot, "SINGLE_INSTANCE", 'True').lower() == 'true'))
- if SINGLEINSTANCE:
+ if single_inst:
if not self.checkSingleInstance():
- msg = 'Only one istance of %s is allowed to run the same time' % (
- APPNAME)
+ msg = 'Only one instance of %s is allowed to run the same time' % (
+ Qt.qApp.applicationName())
self.error(msg)
Qt.QMessageBox.critical(
self, 'Multiple copies', msg, Qt.QMessageBox.Abort)
sys.exit(1)
- # some initialization
- self.resetQSettings()
- self.setWindowTitle(APPNAME)
- self.setWindowIcon(customIcon)
- self.jorgsBar.addAction(organizationIcon, ORGNAME)
- self.jorgsBar.addAction(customIcon, APPNAME)
-
- # get custom widget catalog entries
+ def _loadExtraCatalogWidgets(self, conf, xmlroot):
+ """
+ get custom widget catalog entries
+ """
# @todo: support also loading from xml
- EXTRA_CATALOG_WIDGETS = getattr(conf, 'EXTRA_CATALOG_WIDGETS', [])
+ extra_catalog_widgets = getattr(conf, 'EXTRA_CATALOG_WIDGETS', [])
self._extraCatalogWidgets = []
- for classname, pixmapname in EXTRA_CATALOG_WIDGETS:
+ for class_name, pix_map_name in extra_catalog_widgets:
# If a relative file name is given, the conf directory will be used
# as base path
- if pixmapname and not Qt.QFile.exists(pixmapname):
- pixmapname = os.path.join(self._confDirectory, pixmapname)
- self._extraCatalogWidgets.append((classname, pixmapname))
-
- # manual panel
- MANUAL_URI = getattr(conf, 'MANUAL_URI',
+ if pix_map_name and not Qt.QFile.exists(pix_map_name):
+ pix_map_name = os.path.join(self._confDirectory, pix_map_name)
+ self._extraCatalogWidgets.append((class_name, pix_map_name))
+
+ def _loadManualUri(self, conf, xmlroot):
+ """
+ manual panel
+ """
+ manual_uri = getattr(conf, 'MANUAL_URI',
self.__getVarFromXML(xmlroot, "MANUAL_URI",
taurus.Release.url))
- self.setHelpManualURI(MANUAL_URI)
+ self.setHelpManualURI(manual_uri)
- self.createPanel(self.helpManualBrowser, 'Manual', permanent=True,
- icon=Qt.QIcon.fromTheme('help-browser'))
+ if self.HELP_MENU_ENABLED:
+ self.createPanel(self.helpManualBrowser, 'Manual', permanent=True,
+ icon=Qt.QIcon.fromTheme('help-browser'))
- # configure the macro infrastructure
- MACROSERVER_NAME = getattr(conf, 'MACROSERVER_NAME', self.__getVarFromXML(
- xmlroot, "MACROSERVER_NAME", None))
- MACRO_PANELS = getattr(conf, 'MACRO_PANELS', self.__getVarFromXML(
- xmlroot, "MACRO_PANELS", True))
+ ### SARDANA MACRO STUFF ON
+ def _loadSardanaOptions(self, conf, xmlroot):
+ """configure macro infrastructure"""
+ ms = self._loadMacroServerName(conf, xmlroot)
+ mp = self._loadMacroPanels(conf, xmlroot)
# macro infrastructure will only be created if MACROSERVER_NAME is set
- if MACRO_PANELS and MACROSERVER_NAME is not None:
+ if ms is not None and mp is True:
from sardana.taurus.qt.qtgui.macrolistener import MacroBroker
self.__macroBroker = MacroBroker(self)
- if MACROSERVER_NAME:
- self.macroserverNameChanged.emit(MACROSERVER_NAME)
+ self._loadDoorName(conf, xmlroot)
+ self._loadMacroEditorsPath(conf, xmlroot)
+ pool_instruments = self._loadInstrumentsFromPool(conf, xmlroot, ms)
+ return pool_instruments
+
+ def _loadMacroServerName(self, conf, xmlroot):
+ macro_server_name = getattr(conf, "MACROSERVER_NAME", self.__getVarFromXML(
+ xmlroot, "MACROSERVER_NAME", None))
+ if macro_server_name:
+ self.macroserverNameChanged.emit(macro_server_name)
+ return macro_server_name
- DOOR_NAME = getattr(conf, 'DOOR_NAME',
+ def _loadMacroPanels(self, conf, xmlroot):
+ macro_panels = getattr(conf, "MACRO_PANELS", self.__getVarFromXML(
+ xmlroot, "MACRO_PANELS", True))
+ return macro_panels
+
+ def _loadDoorName(self, conf, xmlroot):
+ door_name = getattr(conf, "DOOR_NAME",
self.__getVarFromXML(xmlroot, "DOOR_NAME", ''))
- if DOOR_NAME:
- self.doorNameChanged.emit(DOOR_NAME)
-
- MACROEDITORS_PATH = getattr(conf, 'MACROEDITORS_PATH', self.__getVarFromXML(
- xmlroot, "MACROEDITORS_PATH", ''))
- if MACROEDITORS_PATH:
- from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.macroparameterseditor import ParamEditorManager
- ParamEditorManager().parsePaths(MACROEDITORS_PATH)
+ if door_name:
+ self.doorNameChanged.emit(door_name)
+
+ def _loadMacroEditorsPath(self, conf, xmlroot):
+ macro_editors_path = getattr(conf, "MACROEDITORS_PATH", self.__getVarFromXML(
+ xmlroot, "MACROEDITORS_PATH", ""))
+ if macro_editors_path:
+ from sardana.taurus.qt.qtgui.extra_macroexecutor.macroparameterseditor.macroparameterseditor import \
+ ParamEditorManager
+ ParamEditorManager().parsePaths(macro_editors_path)
ParamEditorManager().browsePaths()
+ def _loadInstrumentsFromPool(self, conf, xmlroot, macro_server_name):
+ """
+ Get panel descriptions from pool if required
+ """
+ instruments_from_pool = getattr(conf, "INSTRUMENTS_FROM_POOL", (self.__getVarFromXML(
+ xmlroot, "INSTRUMENTS_FROM_POOL", "False").lower() == "true"))
+ if instruments_from_pool:
+ try:
+ self.splashScreen().showMessage("Gathering Instrument info from Pool")
+ except AttributeError:
+ pass
+ pool_instruments = self.createInstrumentsFromPool(
+ macro_server_name) # auto create instruments from pool
+ else:
+ pool_instruments = []
+ return pool_instruments
+ ### SARDANA MACRO STUFF OFF
+
+ def _loadSynoptic(self, conf, xmlroot):
# Synoptics
- SYNOPTIC = getattr(conf, 'SYNOPTIC', None)
- if isinstance(SYNOPTIC, string_types): # old config file style
+ synoptic = getattr(conf, 'SYNOPTIC', None)
+ if isinstance(synoptic, string_types): # old config file style
self.warning(
- 'Deprecated usage of SYNOPTIC keyword (now it expects a list of paths). Please update your configuration file to: "SYNOPTIC=[\'%s\']".' % SYNOPTIC)
- SYNOPTIC = [SYNOPTIC]
- if SYNOPTIC is None: # we look in the xml config file if not present in the python config
- SYNOPTIC = []
+ 'Deprecated usage of synoptic keyword (now it expects a list of paths). Please update your configuration file to: "synoptic=[\'%s\']".' % synoptic)
+ synoptic = [synoptic]
+ if synoptic is None: # we look in the xml config file if not present in the python config
+ synoptic = []
node = xmlroot.find("SYNOPTIC")
if (node is not None) and (node.text is not None):
for child in node:
s = child.get("str")
# we do not append empty strings
if s is not None and len(s):
- SYNOPTIC.append(s)
- for s in SYNOPTIC:
+ synoptic.append(s)
+ for s in synoptic:
self.createMainSynoptic(s)
- # Get panel descriptions from pool if required
- INSTRUMENTS_FROM_POOL = getattr(conf, 'INSTRUMENTS_FROM_POOL', (self.__getVarFromXML(
- xmlroot, "INSTRUMENTS_FROM_POOL", 'False').lower() == 'true'))
- if INSTRUMENTS_FROM_POOL:
- try:
- self.splashScreen().showMessage("Gathering Instrument info from Pool")
- except AttributeError:
- pass
- POOLINSTRUMENTS = self.createInstrumentsFromPool(
- MACROSERVER_NAME) # auto create instruments from pool
- else:
- POOLINSTRUMENTS = []
-
- #######################################################################
- # Deprecated CONSOLE command (if you need a IPython Console, just add a
- # Panel with a `silx.gui.console.IPythonWidget`
- # TODO: remove this block when deprecation grace time is due
- CONSOLE = getattr(conf, 'CONSOLE', self.__getVarFromXML(
+ def _loadConsole(self, conf, xmlroot):
+ """
+ Deprecated CONSOLE command (if you need a IPython Console, just add a
+ Panel with a `silx.gui.console.IPythonWidget`
+ """
+ # TODO: remove this method when making deprecation efective
+ console = getattr(conf, 'CONSOLE', self.__getVarFromXML(
xmlroot, "CONSOLE", []))
- if CONSOLE:
+ if console:
self.createConsole([])
- #######################################################################
- # get custom panel descriptions from the python config file
- CUSTOM_PANELS = [obj for name, obj in inspect.getmembers(
+ def _loadCustomPanels(self, conf, xmlroot, poolinstruments=None):
+ """
+ get custom panel descriptions from the python config file, xml config and
+ create panels based on the panel descriptions
+ """
+ custom_panels = [obj for name, obj in inspect.getmembers(
conf) if isinstance(obj, PanelDescription)]
- # add custom panel descriptions from xml config
- panelDescriptions = xmlroot.find("PanelDescriptions")
- if (panelDescriptions is not None):
- for child in panelDescriptions:
- if (child.tag == "PanelDescription"):
- pd = PanelDescription.fromXml(etree.tostring(child))
+ panel_descriptions = xmlroot.find("PanelDescriptions")
+ if panel_descriptions is not None:
+ for child in panel_descriptions:
+ if child.tag == "PanelDescription":
+ child_str = etree.tostring(child, encoding='unicode')
+ pd = PanelDescription.fromXml(child_str)
if pd is not None:
- CUSTOM_PANELS.append(pd)
+ custom_panels.append(pd)
- # create panels based on the panel descriptions gathered before
- for p in CUSTOM_PANELS + POOLINSTRUMENTS:
+ for p in custom_panels + poolinstruments:
try:
try:
self.splashScreen().showMessage("Creating panel %s" % p.name)
except AttributeError:
pass
w = p.getWidget(sdm=Qt.qApp.SDM, setModel=False)
- if hasattr(w, 'setCustomWidgetMap'):
+ if hasattr(w, "setCustomWidgetMap"):
w.setCustomWidgetMap(self.getCustomWidgetMap())
if p.model is not None:
w.setModel(p.model)
@@ -1189,35 +1295,38 @@ class TaurusGui(TaurusMainWindow):
instrumentkey = self.IMPLICIT_ASSOCIATION
# the pool instruments may change when the pool config changes,
# so we do not store their config
- registerconfig = p not in POOLINSTRUMENTS
+ registerconfig = p not in poolinstruments
# create a panel
self.createPanel(w, p.name, floating=p.floating, registerconfig=registerconfig,
instrumentkey=instrumentkey, permanent=True)
except Exception as e:
- msg = 'Cannot create panel %s' % getattr(
- p, 'name', '__Unknown__')
+ msg = "Cannot create panel %s" % getattr(
+ p, "name", "__Unknown__")
self.error(msg)
self.traceback(level=taurus.Info)
- result = Qt.QMessageBox.critical(self, 'Initialization error', '%s\n\n%s' % (
+ result = Qt.QMessageBox.critical(self, "Initialization error", "%s\n\n%s" % (
msg, repr(e)), Qt.QMessageBox.Abort | Qt.QMessageBox.Ignore)
if result == Qt.QMessageBox.Abort:
sys.exit()
- # get custom toolbars descriptions from the python config file
- CUSTOM_TOOLBARS = [obj for name, obj in inspect.getmembers(
+ def _loadCustomToolBars(self, conf, xmlroot):
+ """
+ get custom toolbars descriptions from the python config file, xml config and
+ create toolbars based on the descriptions
+ """
+ custom_toolbars = [obj for name, obj in inspect.getmembers(
conf) if isinstance(obj, ToolBarDescription)]
- # add custom toolbar descriptions from xml config
- toolBarDescriptions = xmlroot.find("ToolBarDescriptions")
- if (toolBarDescriptions is not None):
- for child in toolBarDescriptions:
- if (child.tag == "ToolBarDescription"):
- d = ToolBarDescription.fromXml(etree.tostring(child))
+ tool_bar_descriptions = xmlroot.find("ToolBarDescriptions")
+ if tool_bar_descriptions is not None:
+ for child in tool_bar_descriptions:
+ if child.tag == "ToolBarDescription":
+ child_str = etree.tostring(child, encoding='unicode')
+ d = ToolBarDescription.fromXml(child_str)
if d is not None:
- CUSTOM_TOOLBARS.append(d)
+ custom_toolbars.append(d)
- # create toolbars based on the descriptions gathered before
- for d in CUSTOM_TOOLBARS:
+ for d in custom_toolbars:
try:
try:
self.splashScreen().showMessage("Creating Toolbar %s" % d.name)
@@ -1236,38 +1345,41 @@ class TaurusGui(TaurusMainWindow):
self.registerConfigDelegate(w, d.name)
except Exception as e:
- msg = 'Cannot add toolbar %s' % getattr(
- d, 'name', '__Unknown__')
+ msg = "Cannot add toolbar %s" % getattr(
+ d, "name", "__Unknown__")
self.error(msg)
self.traceback(level=taurus.Info)
- result = Qt.QMessageBox.critical(self, 'Initialization error', '%s\n\n%s' % (
+ result = Qt.QMessageBox.critical(self, "Initialization error", "%s\n\n%s" % (
msg, repr(e)), Qt.QMessageBox.Abort | Qt.QMessageBox.Ignore)
if result == Qt.QMessageBox.Abort:
sys.exit()
- CUSTOM_APPLETS = []
+ def _loadCustomApplets(self, conf, xmlroot):
+ """
+ get custom applet descriptions from the python config file, xml config and
+ create applet based on the descriptions
+ """
+ custom_applets = []
# for backwards compatibility
MONITOR = getattr(
- conf, 'MONITOR', self.__getVarFromXML(xmlroot, "MONITOR", []))
+ conf, "MONITOR", self.__getVarFromXML(xmlroot, "MONITOR", []))
if MONITOR:
- CUSTOM_APPLETS.append(AppletDescription(
- 'monitor', classname='TaurusMonitorTiny', model=MONITOR))
+ custom_applets.append(AppletDescription(
+ "monitor", classname="TaurusMonitorTiny", model=MONITOR))
- # get custom applet descriptions from the python config file
- CUSTOM_APPLETS += [obj for name, obj in inspect.getmembers(
+ custom_applets += [obj for name, obj in inspect.getmembers(
conf) if isinstance(obj, AppletDescription)]
- # add applet descriptions from xml config
- appletDescriptions = xmlroot.find("AppletDescriptions")
- if (appletDescriptions is not None):
- for child in appletDescriptions:
- if (child.tag == "AppletDescription"):
- d = AppletDescription.fromXml(etree.tostring(child))
+ applet_descriptions = xmlroot.find("AppletDescriptions")
+ if applet_descriptions is not None:
+ for child in applet_descriptions:
+ if child.tag == "AppletDescription":
+ child_str = etree.tostring(child, encoding='unicode')
+ d = AppletDescription.fromXml(child_str)
if d is not None:
- CUSTOM_APPLETS.append(d)
+ custom_applets.append(d)
- # create applet based on the descriptions gathered before
- for d in CUSTOM_APPLETS:
+ for d in custom_applets:
try:
try:
self.splashScreen().showMessage("Creating applet %s" % d.name)
@@ -1282,38 +1394,45 @@ class TaurusGui(TaurusMainWindow):
if isinstance(w, BaseConfigurableClass):
self.registerConfigDelegate(w, d.name)
except Exception as e:
- msg = 'Cannot add applet %s' % getattr(
- d, 'name', '__Unknown__')
+ msg = "Cannot add applet %s" % getattr(
+ d, "name", "__Unknown__")
self.error(msg)
self.traceback(level=taurus.Info)
- result = Qt.QMessageBox.critical(self, 'Initialization error', '%s\n\n%s' % (
+ result = Qt.QMessageBox.critical(self, "Initialization error", "%s\n\n%s" % (
msg, repr(e)), Qt.QMessageBox.Abort | Qt.QMessageBox.Ignore)
if result == Qt.QMessageBox.Abort:
sys.exit()
- # add external applications from both the python and the xml config
- # files
- EXTERNAL_APPS = [obj for name, obj in inspect.getmembers(
+ def _loadExternalApps(self, conf, xmlroot):
+ """
+ add external applications from both the python and the xml config files
+ """
+ external_apps = [obj for name, obj in inspect.getmembers(
conf) if isinstance(obj, ExternalApp)]
- externalAppsNode = xmlroot.find("ExternalApps")
- if (externalAppsNode is not None):
- for child in externalAppsNode:
- if (child.tag == "ExternalApp"):
- ea = ExternalApp.fromXml(etree.tostring(child))
+ ext_apps_node = xmlroot.find("ExternalApps")
+ if ext_apps_node is not None:
+ for child in ext_apps_node:
+ if child.tag == "ExternalApp":
+ child_str = etree.tostring(child, encoding='unicode')
+ ea = ExternalApp.fromXml(child_str)
if ea is not None:
- EXTERNAL_APPS.append(ea)
+ external_apps.append(ea)
- for a in EXTERNAL_APPS:
+ for a in external_apps:
self._external_app_names.append(str(a.getAction().text()))
self.addExternalAppLauncher(a.getAction())
- # get the "factory settings" filename. By default, it is called
- # "default.ini" and resides in the configuration dir
- INIFILE = getattr(conf, 'INIFILE', self.__getVarFromXML(
+ def _loadIniFile(self, conf, xmlroot):
+ """
+ get the "factory settings" filename. By default, it is called
+ "default.ini" and resides in the configuration dir
+ """
+
+ ini_file = getattr(conf, 'INIFILE', self.__getVarFromXML(
xmlroot, "INIFILE", "default.ini"))
# if a relative name is given, the conf dir is used as the root path
- iniFileName = os.path.join(self._confDirectory, INIFILE)
+ ini_file_name = os.path.join(self._confDirectory, ini_file)
# read the settings (or the factory settings if the regular file is not
# found)
@@ -1324,7 +1443,7 @@ class TaurusGui(TaurusMainWindow):
self.splashScreen().showMessage(msg)
except AttributeError:
pass
- self.loadSettings(factorySettingsFileName=iniFileName)
+ self.loadSettings(factorySettingsFileName=ini_file_name)
def setLockView(self, locked):
self.setModifiableByUser(not locked)
@@ -1337,14 +1456,21 @@ class TaurusGui(TaurusMainWindow):
for panel in self.__panels.values():
panel.toggleViewAction().setEnabled(modifiable)
panel.setFeatures(dwfeat)
- for action in (self.newPanelAction, self.showAllPanelsAction,
- self.hideAllPanelsAction,
- self.addExternalApplicationAction,
- self.removeExternalApplicationAction,
- ):
- action.setEnabled(modifiable)
+
+ if self.PANELS_MENU_ENABLED:
+ for action in (self.newPanelAction, self.showAllPanelsAction,
+ self.hideAllPanelsAction,
+ ):
+ action.setEnabled(modifiable)
+
+ if self.TOOLS_MENU_ENABLED:
+ for action in (self.addExternalApplicationAction,
+ self.removeExternalApplicationAction,
+ ):
+ action.setEnabled(modifiable)
self._lockviewAction.setChecked(not modifiable)
+
TaurusMainWindow.setModifiableByUser(self, modifiable)
def onShortMessage(self, msg):
@@ -1529,6 +1655,7 @@ class TaurusGui(TaurusMainWindow):
xmlroot, "PanelDescriptions")
# Get all custom panels
+ from taurus.qt.qtgui.panel import QDoubleListDlg
dlg = QDoubleListDlg(winTitle='Export Panels to XML',
mainLabel='Select which of the custom panels you want to export as xml configuration',
label1='Not Exported', label2='Exported',
@@ -1547,7 +1674,7 @@ class TaurusGui(TaurusMainWindow):
self.registerConfigDelegate(panel, name)
panelxml = PanelDescription.fromPanel(panel).toXml()
panelDescriptionsNode.append(etree.fromstring(panelxml))
- xml = etree.tostring(xmlroot, pretty_print=True)
+ xml = etree.tostring(xmlroot, pretty_print=True, encoding='unicode')
# write to file
while True:
@@ -1605,52 +1732,34 @@ class TaurusGui(TaurusMainWindow):
self.info(nfo)
-#------------------------------------------------------------------------------
-def main(confname=None):
+@click.command('gui')
+@click.argument('confname', nargs=1, required=True)
+@click.option('--safe-mode', 'safe_mode', is_flag=True, default=False,
+ help=('launch in safe mode (it prevents potentially problematic '
+ + 'configs from being loaded)')
+ )
+@click.option('--ini', type=click.Path(exists=True),
+ metavar="INIFILE",
+ help=('settings file (.ini) to be loaded (defaults to '
+ + '<user_config_dir>/<appname>.ini)'),
+ default=None
+ )
+def gui_cmd(confname, safe_mode, ini):
+ """Launch a TaurusGUI using the given CONF"""
import sys
import taurus
- from taurus.core.util import argparse
from taurus.qt.qtgui.application import TaurusApplication
taurus.info('Starting execution of TaurusGui')
- parser = argparse.get_taurus_parser()
- parser.set_usage("%prog [options] confname")
- parser.set_description("The taurus GUI application")
- parser.add_option("", "--config-dir", dest="config_dir", default=None,
- help="use the given configuration directory for initialization")
- parser.add_option("", "--new-gui", action="store_true", dest="new_gui", default=None,
- help="launch a wizard for creating a new TaurusGUI application")
- parser.add_option("", "--fail-proof", action="store_true", dest="fail_proof", default=None,
- help="launch in fail proof mode (it prevents potentially problematic configs from being loaded)")
-
- app = TaurusApplication(cmd_line_parser=parser, app_name="taurusgui",
- app_version=taurus.Release.version)
- args = app.get_command_line_args()
- options = app.get_command_line_options()
-
- if options.new_gui: # launch app settings wizard instead of taurusgui
- from taurus.qt.qtgui.taurusgui import AppSettingsWizard
- wizard = AppSettingsWizard()
- wizard.show()
- sys.exit(app.exec_())
-
- if confname is None:
- confname = options.config_dir
-
- if confname is None:
- if len(args) == 1: # for backwards compat, we allow to specify the confname without the "--config-dir" parameter
- confname = args[0]
- else:
- parser.print_help(sys.stderr)
- sys.exit(1)
+ app = TaurusApplication(cmd_line_parser=None, app_name="taurusgui")
- if options.fail_proof:
+ if safe_mode:
configRecursionDepth = 0
else:
configRecursionDepth = None
- gui = TaurusGui(None, confname=confname,
+ gui = TaurusGui(None, confname=confname, settingsname=ini,
configRecursionDepth=configRecursionDepth)
gui.show()
@@ -1660,6 +1769,27 @@ def main(confname=None):
sys.exit(ret)
+@click.command('newgui')
+# @click.option('--stub', 'stub_name',
+# metavar="NAME",
+# default=None,
+# help='Create an empty stub of gui with the given NAME'
+# )
+def newgui_cmd():
+ """Create a new TaurusGui"""
+ import sys
+ from taurus.qt.qtgui.application import TaurusApplication
+
+ app = TaurusApplication(cmd_line_parser=None, app_name="newgui")
+
+ # if stub_name is not None:
+ # pass # TODO
+
+ from taurus.qt.qtgui.taurusgui import AppSettingsWizard
+ wizard = AppSettingsWizard()
+ wizard.show()
+ sys.exit(app.exec_())
+
+
if __name__ == "__main__":
- main()
- # xmlTest()
+ gui_cmd()
diff --git a/lib/taurus/qt/qtgui/taurusgui/utils.py b/lib/taurus/qt/qtgui/taurusgui/utils.py
index 6812fd31..b224027c 100644
--- a/lib/taurus/qt/qtgui/taurusgui/utils.py
+++ b/lib/taurus/qt/qtgui/taurusgui/utils.py
@@ -264,7 +264,7 @@ class TaurusGuiComponentDescription(object):
model = etree.SubElement(root, "model")
model.text = self._model
- return etree.tostring(root, pretty_print=True)
+ return etree.tostring(root, pretty_print=True, encoding='unicode')
@staticmethod
def fromXml(xmlstring):
diff --git a/lib/taurus/qt/qtgui/test/base.py b/lib/taurus/qt/qtgui/test/base.py
index 678e2762..7e8b4645 100644
--- a/lib/taurus/qt/qtgui/test/base.py
+++ b/lib/taurus/qt/qtgui/test/base.py
@@ -64,10 +64,9 @@ class BaseWidgetTestCase(object):
from taurus.core.util.log import _DEPRECATION_COUNT
self._depCounter = _DEPRECATION_COUNT
self._depCounter.clear()
-
app = TaurusApplication.instance()
if app is None:
- app = TaurusApplication([])
+ app = TaurusApplication([], cmd_line_parser=None)
self._app = app
if self._klass is not None:
diff --git a/lib/taurus/qt/qtgui/util/qdraganddropdebug.py b/lib/taurus/qt/qtgui/util/qdraganddropdebug.py
index 5d3d9ce7..90a462c5 100644
--- a/lib/taurus/qt/qtgui/util/qdraganddropdebug.py
+++ b/lib/taurus/qt/qtgui/util/qdraganddropdebug.py
@@ -59,7 +59,7 @@ if __name__ == '__main__':
import sys
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w = DropDebugger()
w.show()
sys.exit(app.exec_())
diff --git a/lib/taurus/qt/qtgui/util/tauruswidgettree.py b/lib/taurus/qt/qtgui/util/tauruswidgettree.py
index 77948d8a..57517dd9 100644
--- a/lib/taurus/qt/qtgui/util/tauruswidgettree.py
+++ b/lib/taurus/qt/qtgui/util/tauruswidgettree.py
@@ -221,7 +221,7 @@ def build_gui():
def main():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication()
+ app = TaurusApplication(cmd_line_parser=None)
w = build_gui()
tree = TreeQObjectWidget(qobject_root=w)
diff --git a/lib/taurus/qt/qtgui/util/ui.py b/lib/taurus/qt/qtgui/util/ui.py
index b4bc93a2..31489759 100644
--- a/lib/taurus/qt/qtgui/util/ui.py
+++ b/lib/taurus/qt/qtgui/util/ui.py
@@ -176,7 +176,7 @@ def UILoadable(klass=None, with_ui=None):
def main():
from taurus.qt.qtgui.application import TaurusApplication
- app = TaurusApplication([])
+ app = TaurusApplication([], cmd_line_parser=None)
@UILoadable(with_ui="ui")
class A(Qt.QWidget):
diff --git a/lib/taurus/qt/qtgui/util/validator.py b/lib/taurus/qt/qtgui/util/validator.py
index 92f875eb..92f875eb 100755..100644
--- a/lib/taurus/qt/qtgui/util/validator.py
+++ b/lib/taurus/qt/qtgui/util/validator.py
diff --git a/lib/taurus/tauruscustomsettings.py b/lib/taurus/tauruscustomsettings.py
index 17e9d093..e5fa03ae 100755..100644
--- a/lib/taurus/tauruscustomsettings.py
+++ b/lib/taurus/tauruscustomsettings.py
@@ -84,7 +84,7 @@ EXTRA_SCHEME_MODULES = []
#: Consider using the API for modifying this on a per-widget or per-class
#: basis at runtime, or using the related `--default-formatter` parameter
#: from TaurusApplication, e.g.:
-#: $ taurusform MODEL --default-formatter='{:2.3f}'
+#: $ taurus form MODEL --default-formatter='{:2.3f}'
#: The formatter can be a python format string or the name of a formatter
#: callable, e.g.
#: DEFAULT_FORMATTER = '{0}'
@@ -136,6 +136,13 @@ QT_THEME_NAME = 'Tango'
#: setting QT_THEME_FORCE_ON_LINUX=True overrides this.
QT_THEME_FORCE_ON_LINUX = True
+#: Full Qt designer path (including filename. Default is None, meaning:
+#: - linux: look for the system designer following Qt.QLibraryInfo.BinariesPath
+#: - windows: look for the system designer following
+#: Qt.QLibraryInfo.BinariesPath. If this fails, taurus tries to locate binary
+#: manually
+QT_DESIGNER_PATH = None
+
#: Custom organization logo. Set the absolute path to an image file to be used as your
#: organization logo. Qt registered paths can also be used.
#: If not set, it defaults to 'logos:taurus.png"
diff --git a/lib/taurus/test/moduleexplorer.py b/lib/taurus/test/moduleexplorer.py
index c1474282..40547b16 100644
--- a/lib/taurus/test/moduleexplorer.py
+++ b/lib/taurus/test/moduleexplorer.py
@@ -57,23 +57,32 @@ class ModuleExplorer(object):
def _getlocalmembernames(self, module, predicate=None):
ret = []
- modulepath, tail = os.path.split(inspect.getabsfile(module))
+ modulepath, _ = os.path.split(inspect.getabsfile(module))
for n, v in inspect.getmembers(module, predicate):
if inspect.isbuiltin(v):
continue # ignore builtin functions
try:
- memberpath, tail = os.path.split(inspect.getabsfile(v))
+ memberpath, _ = os.path.split(inspect.getabsfile(v))
except TypeError:
continue # ignore builtin modules
if memberpath == modulepath:
ret.append(n)
return ret
- def _getSubmodulesFromPath(self, modulepath):
+ def _getSubpackagesFromPath(self, modulepath):
g = glob.glob(os.path.join(modulepath, '*', '__init__.py'))
ret = [re.findall(r".+\/(.*)\/__init__.py", s)[0] for s in g]
return ret
+ def _getSubmodulesFromPath(self, modulepath, module):
+ _imp = [n for n, m in inspect.getmembers(module, inspect.ismodule)]
+ ret = []
+ for s in glob.glob(os.path.join(modulepath, '*.py')):
+ f = os.path.split(s)[1][:-3]
+ if not f.startswith('_') and f not in _imp:
+ ret.append(f)
+ return ret
+
def _isclass_with_init(self, obj):
return inspect.isclass(obj) and hasattr(obj, '__init__')
@@ -111,14 +120,21 @@ class ModuleExplorer(object):
externalmembernames=[],
submodules={},
warnings=warnings)
- modulepath, tail = os.path.split(inspect.getabsfile(module))
- submodulenames = sorted(self._getSubmodulesFromPath(modulepath))
+ if module.__name__ == module.__package__:
+ modulepath, _ = os.path.split(inspect.getabsfile(module))
+ else:
+ modulepath = inspect.getabsfile(module)
+
+ submodulenames = sorted(
+ self._getSubpackagesFromPath(modulepath)
+ + self._getSubmodulesFromPath(modulepath, module)
+ )
localclassnames = sorted(
- [n for n, _ in inspect.getmembers(module, self._isclass_with_init)]
+ self._getlocalmembernames(module, self._isclass_with_init)
)
localfunctionnames = sorted(
- [n for n, _ in inspect.getmembers(module, inspect.isfunction)]
+ self._getlocalmembernames(module, inspect.isfunction)
)
localenumerationnames = sorted([]) # @todo
externalmembernames = sorted([]) # @todo
diff --git a/lib/taurus/test/skip.py b/lib/taurus/test/skip.py
index fefe68c0..88da2d34 100644
--- a/lib/taurus/test/skip.py
+++ b/lib/taurus/test/skip.py
@@ -59,7 +59,7 @@ def skipUnlessGui():
'''
Logger.deprecated(dep='skipUnlessGui', rel='4.0',
- alt='taurustestsuite --exclude-pattern')
+ alt='taurus testsuite --exclude-pattern')
return unittest.skipUnless(GUI_TESTS_ENABLED, 'requires GUI')
diff --git a/lib/taurus/test/test_import.py b/lib/taurus/test/test_import.py
index 2c92951f..2db3cd20 100644
--- a/lib/taurus/test/test_import.py
+++ b/lib/taurus/test/test_import.py
@@ -49,7 +49,10 @@ class TaurusImportTestCase(unittest.TestCase):
on module importing
"""
exclude_patterns = [r'taurus\.qt\.qtgui\.extra_.*',
- r'taurus\.qt\.qtgui\.qwt5']
+ r'taurus\.qt\.qtgui\.qwt5',
+ r'taurus\.external\.qt\.QtUiTools',
+ r'taurus\.external\.qt\.Qwt5',
+ ]
try:
import PyTango
@@ -64,7 +67,7 @@ class TaurusImportTestCase(unittest.TestCase):
exclude_patterns=exclude_patterns)
msg = None
if wrn:
- msg = '\n%s' % '\n'.join(zip(*wrn)[1])
+ msg = '\n%s' % '\n'.join(list(zip(*wrn))[1])
self.assertEqual(len(wrn), 0, msg=msg)
diff --git a/lib/taurus/test/testsuite.py b/lib/taurus/test/testsuite.py
index 488bf259..2bf5878e 100644
--- a/lib/taurus/test/testsuite.py
+++ b/lib/taurus/test/testsuite.py
@@ -37,6 +37,7 @@ import os
import sys
import re
import unittest
+import click
import taurus
from taurus.external.qt import PYQT4
@@ -101,38 +102,28 @@ def run(disableLogger=True, exclude_pattern='(?!)'):
return runner.run(suite)
-def main():
- import taurus.test.skip
- import argparse
- from taurus import Release
- parser = argparse.ArgumentParser(description='Main test suite for Taurus')
- parser.add_argument('--skip-gui-tests', dest='skip_gui',
- action='store_true', default=False,
- help='Do not perform tests requiring GUI')
- # TODO: Define the default exclude patterns as a tauruscustomsettings
- # variable.
- help = """regexp pattern matching test ids to be excluded.
+@click.command('testsuite')
+@click.option(
+ '--gui-tests/--skip-gui-tests', 'gui_tests',
+ default=True, show_default=True,
+ help='Perform tests requiring GUI'
+)
+@click.option(
+ '-e', '--exclude-pattern', 'exclude_pattern',
+ default='(?!)',
+ help="""regexp pattern matching test ids to be excluded.
(e.g. 'taurus\.core\..*' would exclude taurus.core tests)
"""
- parser.add_argument('-e', '--exclude-pattern',
- dest='exclude_pattern',
- default='(?!)',
- help=help)
- parser.add_argument('--version', action='store_true', default=False,
- help="show program's version number and exit")
- args = parser.parse_args()
-
- if args.version:
- print(Release.version)
- sys.exit(0)
-
- if args.skip_gui:
- import taurus.test.skip
- taurus.test.skip.GUI_TESTS_ENABLED = False
+)
+def testsuite_cmd(gui_tests, exclude_pattern):
+ """Launch the main test suite for Taurus'"""
+ import taurus.test.skip
+
+ taurus.test.skip.GUI_TESTS_ENABLED = gui_tests
if not taurus.test.skip.GUI_TESTS_ENABLED:
- exclude_pattern = '(taurus\.qt\..*)|(%s)' % args.exclude_pattern
+ exclude_pattern = '(taurus\.qt\..*)|(%s)' % exclude_pattern
else:
- exclude_pattern = args.exclude_pattern
+ exclude_pattern = exclude_pattern
ret = run(exclude_pattern=exclude_pattern)
@@ -145,4 +136,4 @@ def main():
if __name__ == '__main__':
- main()
+ testsuite_cmd()
diff --git a/scripts/taurusdoc b/scripts/taurusdoc
index 6ec28152..101ccfad 100755
--- a/scripts/taurusdoc
+++ b/scripts/taurusdoc
@@ -28,15 +28,14 @@ This script is designed to provide taurus developers with a fast way to test
sphinx documentation from source code files or RST files.
"""
+from __future__ import print_function
+
import sys
import os
import shutil
-import optparse
+import argparse
from sphinx.application import Sphinx
-from sphinx.util.console import darkred, nocolor, color_terminal
-
-import taurus.core
def abspath(*path):
@@ -45,12 +44,13 @@ def abspath(*path):
taurusdoc_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(taurusdoc_dir, *path)
+
sys.path.append(abspath('..', 'doc'))
try:
import auto_rst4api
except ImportError:
- print "taurusdoc can only be executed from a source distribution of taurus"
+ print("taurusdoc can only be run from a source distribution of taurus")
sys.exit(1)
__INDEX = """
@@ -69,17 +69,17 @@ Any modifications will be lost.
class RstCreator(auto_rst4api.Auto_rst4API_Creator):
def documentClass(self, module, classname, docparentpath):
- '''Documents a single class
+ """Documents a single class
:param module: (module) python module where class resides
:param classname: (str) class name
:docparentpath: (str) path to the directory in which the documentation
files will be written
- '''
+ """
ofname = os.path.join(docparentpath, "_%s.rst" % classname)
if self.verbose:
- print 'creating "%s" ...' % ofname,
+ print('creating "%s" ...' % ofname, )
info = dict(modulename=module.__name__,
basemodulename=module.__name__.split('.')[-1],
modulepath=module.__path__,
@@ -92,135 +92,133 @@ class RstCreator(auto_rst4api.Auto_rst4API_Creator):
warnings=[])
if not os.path.exists(ofname) or self.overwrite_old:
text = self.classtemplate.render(info=info, classname=classname)
- f = open(ofname, "w")
- f.write('\n'.join((self.AUTOGEN_SIGNATURE, self.AUTOGEN_MESSAGE, text)))
- f.close()
+ with open(ofname, "w") as f:
+ f.write('\n'.join((self.AUTOGEN_SIGNATURE,
+ self.AUTOGEN_MESSAGE,
+ text))
+ )
if self.verbose:
- print ' ok.'
+ print(' ok.')
else:
if self.verbose:
- print ' skipping (file already exists)'
+ print(' skipping (file already exists)')
def main():
- version = "taurusdoc %s" % (taurus.Release.version)
- usage = "usage: %prog [options]"
- description = "a tool to help developers preview the documentation "\
+ description = "a tool to help developers preview the documentation " \
"generated by their code"
- parser = optparse.OptionParser(
- usage=usage, version=version, description=description)
-
- parser.add_option("-v", "--verbose", dest="verbose", action="store_true",
- help="display a lot of information [default]", default=True)
- parser.add_option("-q", "--quiet", dest="verbose", action="store_false",
- help="be really silent")
- parser.add_option("--build-dir", dest="build_dir",
- help="build directory [default=./build]")
- parser.add_option("-a", "--all-files", dest="all_files", default=True, action="store_true",
- help="generate from scratch [default]")
- parser.add_option("--cache", dest="all_files", action="store_false",
- help="use previously generated files")
-
- # o_group = optparse.OptionGroup(parser, "output options",
- # "options regarding the ouput")
-
- parser.add_option("--format", dest="builder", default="html",
- help="output format [default=html]")
-
- parser.add_option("--prefix", dest="prefix",
- help="output directory")
-
- # i_group = optparse.OptionGroup(parser, "input options",
- # "provide one and **only** one of these!")
-
- parser.add_option("--class", dest="klass", default=None,
- help="full class name to generate doc for (ex.: taurus.qt.qtgui.display.TaurusLabel")
- parser.add_option("--package", dest="package", default=None,
- help="full package name to generate doc for (ex.: taurus.qt.qtgui.display)")
- parser.add_option("--file", dest="filename", default=None,
- help="RST file")
-
- options, args = parser.parse_args()
-
- if not options.klass and not options.package and not options.filename:
+ parser = argparse.ArgumentParser(description=description)
+
+ parser.add_argument("-v", "--verbose", dest="verbose",
+ action="store_true",
+ help="display a lot of information [default]",
+ default=True)
+ parser.add_argument("-q", "--quiet", dest="verbose", action="store_false",
+ help="be really silent")
+ parser.add_argument("--build-dir", dest="build_dir",
+ help="build directory [default=./build]")
+ parser.add_argument("-a", "--all-files", dest="all_files", default=True,
+ action="store_true",
+ help="generate from scratch [default]")
+ parser.add_argument("--cache", dest="all_files", action="store_false",
+ help="use previously generated files")
+ parser.add_argument("--format", dest="builder", default="html",
+ help="output format [default=html]")
+ parser.add_argument("--prefix", dest="prefix",
+ help="output directory")
+ parser.add_argument("--class", dest="klass", default=None,
+ help=("full class name to generate doc for "
+ + "(ex.: taurus.qt.qtgui.display.TaurusLabel"))
+ parser.add_argument("--package", dest="package", default=None,
+ help=("full package name to generate doc for "
+ + "(ex.: taurus.qt.qtgui.display)"))
+ parser.add_argument("--file", dest="filename", default=None,
+ help="RST file")
+
+ args = parser.parse_args()
+
+ if not args.klass and not args.package and not args.filename:
parser.error("must give one of --class or --package or --file")
- if int(bool(options.klass)) + int(bool(options.package)) + int(bool(options.filename)) > 1:
+ if int(bool(args.klass)) + int(bool(args.package)) + int(
+ bool(args.filename)) > 1:
parser.error(
"options --class and --package and --file are mutually exclusive")
fromlist = []
- if options.klass:
- package_name, class_name = options.klass.rsplit(".", 1)
+ if args.klass:
+ package_name, class_name = args.klass.rsplit(".", 1)
if package_name.find(".") >= 0:
fromlist.append(package_name.split(".", 1)[0])
mod = __import__(package_name, fromlist=fromlist)
- elif options.package:
- package_name = options.package
+ elif args.package:
+ package_name = args.package
mod = __import__(package_name, fromlist=fromlist)
else:
- filename = options.filename
+ filename = args.filename
- if options.build_dir is None:
- options.build_dir = os.path.join(
+ if args.build_dir is None:
+ args.build_dir = os.path.join(
os.path.abspath(os.path.curdir), "build")
# clean build dir
- if options.all_files:
- if os.path.isdir(options.build_dir):
- shutil.rmtree(options.build_dir)
+ if args.all_files:
+ if os.path.isdir(args.build_dir):
+ shutil.rmtree(args.build_dir)
- if not os.path.isdir(options.build_dir):
- os.makedirs(options.build_dir)
+ if not os.path.isdir(args.build_dir):
+ os.makedirs(args.build_dir)
- if options.prefix is None:
- options.prefix = os.path.join(
+ if args.prefix is None:
+ args.prefix = os.path.join(
os.path.abspath(os.path.curdir), "sphinx")
- if not os.path.isdir(options.prefix):
- os.makedirs(options.prefix)
+ if not os.path.isdir(args.prefix):
+ os.makedirs(args.prefix)
doc_dir = abspath("..", "doc")
- if options.verbose:
+ if args.verbose:
out = sys.stdout
else:
import StringIO
out = StringIO.StringIO()
- if not options.filename:
- rstCreator = RstCreator(exclude_patterns=['.*\.ui'], templatespath=doc_dir,
- overwrite_old=True, verbose=options.verbose,
+ if not args.filename:
+ rstCreator = RstCreator(exclude_patterns=['.*\.ui'],
+ templatespath=doc_dir,
+ overwrite_old=True,
+ verbose=args.verbose,
classtemplate='api_class_simple.rst')
- rstCreator.cleanAutogenerated(options.build_dir)
+ rstCreator.cleanAutogenerated(args.build_dir)
# create index.rst
- index_rst = os.path.join(options.build_dir, 'index.rst')
- f = file(index_rst, "w")
- if options.klass:
- r = rstCreator.documentClass(mod, class_name, options.build_dir)
- txt = __INDEX.format(name="_%s" % class_name)
- elif options.package:
- r = rstCreator.documentModule(package_name, options.build_dir)
- txt = __INDEX.format(name=package_name.rsplit(".", 1)[-1])
- else:
- shutil.copy(options.filename, options.build_dir)
- txt = __INDEX.format(name=os.path.basename(options.filename))
- f.write(txt)
- f.close()
+ index_rst = os.path.join(args.build_dir, 'index.rst')
+ with open(index_rst, "w") as f:
+ if args.klass:
+ rstCreator.documentClass(mod, class_name, args.build_dir)
+ txt = __INDEX.format(name="_%s" % class_name)
+ elif args.package:
+ rstCreator.documentModule(package_name, args.build_dir)
+ txt = __INDEX.format(name=package_name.rsplit(".", 1)[-1])
+ else:
+ shutil.copy(args.filename, args.build_dir)
+ txt = __INDEX.format(name=os.path.basename(args.filename))
+ f.write(txt)
# directory where conf.py resides
config_dir = os.path.join(doc_dir, 'source')
- doctree_dir = os.path.join(options.build_dir, 'doctrees')
+ doctree_dir = os.path.join(args.build_dir, 'doctrees')
- app = Sphinx(options.build_dir, config_dir, options.prefix,
- doctree_dir, options.builder,
+ app = Sphinx(args.build_dir, config_dir, args.prefix,
+ doctree_dir, args.builder,
confoverrides=None, status=out, warning=sys.stderr,
freshenv=False, warningiserror=False, tags=None)
app.build()
+
if __name__ == "__main__":
main()
diff --git a/scripts/taurusremotelogmonitor b/scripts/taurusremotelogmonitor
deleted file mode 100755
index 0a88c78d..00000000
--- a/scripts/taurusremotelogmonitor
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python
-
-#############################################################################
-##
-# This file is part of Taurus, a Tango User Interface Library
-##
-# http://www.tango-controls.org/static/taurus/latest/doc/html/index.html
-##
-# Copyright 2011 CELLS / ALBA Synchrotron, Bellaterra, Spain
-##
-# Taurus 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 3 of the License, or
-# (at your option) any later version.
-##
-# Taurus 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 Taurus. If not, see <http://www.gnu.org/licenses/>.
-##
-#############################################################################
-
-import optparse
-import logging.handlers
-import socket
-
-import taurus
-from taurus.qt.qtgui.application import TaurusApplication
-from taurus.qt.qtgui.table import QLoggingWidget
-
-
-def main():
- import taurus
- dft_port = logging.handlers.DEFAULT_TCP_LOGGING_PORT
- host = socket.gethostname()
-
- help_gui = "gui mode [default]"
- help_con = "console mode"
- help_port = "port where log server is running [default: %d]" % dft_port
- help_name = "filter specific log object [default: None, meaning don't " \
- "filter]"
- help_level = "filter specific log level." \
- "Allowed values are (case insensitive): critical, "\
- "error, warning/warn, info, debug, trace [default: debug]."
-
- parser = optparse.OptionParser()
- parser.set_description("Table that displays the taurus logging messages")
- parser.add_option("-g", "--gui", dest="gui", default=True,
- action="store_true", help=help_gui)
- parser.add_option("-c", "--console", dest="gui",
- action="store_false", help=help_con)
- parser.add_option("--log-port", dest="log_port", default=dft_port,
- type="int", help=help_port)
- parser.add_option("--log-name", dest="log_name", default=None,
- type="string", help=help_name)
- parser.add_option("--log-level", dest="log_level", default="debug",
- type="string", help=help_level)
-
- app = TaurusApplication(app_name="Taurus remote logger",
- app_version="1.0",
- org_domain="Taurus", org_name="Taurus community",
- cmd_line_parser=parser)
-
- options = app.get_command_line_options()
-
- port, name = options.log_port, options.log_name
- level_str = options.log_level.capitalize()
- gui = options.gui
-
- level = taurus.Trace
- if hasattr(taurus, level_str):
- level = getattr(taurus, level_str)
-
- if gui:
- w = QLoggingWidget(perspective="Remote")
- w.setMinimumSize(1024, 600)
-
- filterbar = w.getFilterBar()
- filterbar.setLogLevel(level)
- if name is not None:
- filterbar.setFilterText(name)
- w.getPerspectiveBar().setEnabled(False)
- w.getQModel().connect_logging(host, port)
- w.show()
- app.exec_()
- w.getQModel().disconnect_logging()
- else:
- import taurus.core.util.remotelogmonitor
- taurus.core.util.remotelogmonitor.log(host=host, port=port, name=name,
- level=level)
-if __name__ == '__main__':
- main()
diff --git a/setup.py b/setup.py
index 65be1f17..31b6f86c 100644
--- a/setup.py
+++ b/setup.py
@@ -61,6 +61,7 @@ install_requires = [
'numpy>=1.1',
'pint>=0.8',
'future',
+ 'click',
]
#Workaround for old setuptools
@@ -92,25 +93,34 @@ extras_require = {
}
console_scripts = [
- 'taurustestsuite = taurus.test.testsuite:main',
- 'taurusconfigbrowser = taurus.qt.qtgui.panel.taurusconfigeditor:main',
- 'taurusplot = taurus.qt.qtgui.qwt5.taurusplot:main',
- 'taurustrend = taurus.qt.qtgui.qwt5.taurustrend:main',
- 'taurusform = taurus.qt.qtgui.panel.taurusform:taurusFormMain',
- 'tauruspanel = taurus.qt.qtgui.panel.taurusdevicepanel:TaurusPanelMain',
- 'taurusdevicepanel = taurus.qt.qtgui.panel.taurusdevicepanel:TaurusDevicePanelMain',
- 'taurusgui = taurus.qt.qtgui.taurusgui.taurusgui:main',
- 'taurusdesigner = taurus.qt.qtdesigner.taurusdesigner:main',
- 'tauruscurve = taurus.qt.qtgui.extra_guiqwt.plot:taurusCurveDlgMain',
- 'taurustrend1d = taurus.qt.qtgui.extra_guiqwt.plot:taurusTrendDlgMain',
- 'taurusimage = taurus.qt.qtgui.extra_guiqwt.plot:taurusImageDlgMain',
- 'taurustrend2d = taurus.qt.qtgui.extra_guiqwt.taurustrend2d:taurusTrend2DMain',
- 'taurusiconcatalog = taurus.qt.qtgui.icon.catalog:main',
- 'taurusdemo = taurus.qt.qtgui.panel.taurusdemo:main',
- # TODO: taurusdoc,
+ 'taurus = taurus.cli:main',
]
-entry_points = {'console_scripts': console_scripts,
+taurus_subcommands = [
+ 'testsuite = taurus.test.testsuite:testsuite_cmd',
+ 'config = taurus.qt.qtgui.panel.taurusconfigeditor:config_cmd',
+ 'qwt5 = taurus.qt.qtgui.qwt5.cli:qwt5',
+ 'device = taurus.qt.qtgui.panel.taurusdevicepanel:device_cmd',
+ 'panel = taurus.qt.qtgui.panel.taurusdevicepanel:panel_cmd',
+ 'gui = taurus.qt.qtgui.taurusgui.taurusgui:gui_cmd',
+ 'newgui = taurus.qt.qtgui.taurusgui.taurusgui:newgui_cmd',
+ 'designer = taurus.qt.qtdesigner.taurusdesigner:designer_cmd',
+ 'guiqwt = taurus.qt.qtgui.extra_guiqwt.cli:guiqwt',
+ 'icons = taurus.qt.qtgui.icon.catalog:icons_cmd',
+ 'form = taurus.qt.qtgui.panel.taurusform:form_cmd',
+ 'demo = taurus.qt.qtgui.panel.taurusdemo:demo_cmd',
+ 'logmon = taurus.core.util.remotelogmonitor:logmon_cmd',
+ 'qlogmon = taurus.qt.qtgui.table.qlogtable:qlogmon_cmd',
+]
+
+model_selectors = [
+ 'Tango = taurus.qt.qtgui.panel.taurusmodelchooser:TangoModelSelectorItem',
+]
+
+entry_points = {
+ 'console_scripts': console_scripts,
+ 'taurus.cli.subcommands': taurus_subcommands,
+ 'taurus.qt.qtgui.panel.TaurusModelSelector.items': model_selectors,
}
classifiers = [