summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/silx.egg-info/PKG-INFO2
-rw-r--r--src/silx.egg-info/SOURCES.txt2
-rw-r--r--src/silx.egg-info/requires.txt3
-rw-r--r--src/silx/_version.py2
-rw-r--r--src/silx/gui/_glutils/gl.py20
-rw-r--r--src/silx/gui/_glutils/test/__init__.py23
-rw-r--r--src/silx/gui/_glutils/test/test_gl.py36
-rw-r--r--src/silx/gui/plot/MaskToolsWidget.py10
-rw-r--r--src/silx/gui/plot/ScatterMaskToolsWidget.py8
-rw-r--r--src/silx/gui/plot/_BaseMaskToolsWidget.py4
-rw-r--r--src/silx/gui/plot/actions/io.py12
-rwxr-xr-xsrc/silx/gui/plot/backends/BackendMatplotlib.py3
-rw-r--r--src/silx/gui/plot/backends/glutils/GLPlotCurve.py4
-rw-r--r--src/silx/gui/plot3d/actions/io.py6
-rw-r--r--src/silx/io/dictdump.py11
15 files changed, 116 insertions, 30 deletions
diff --git a/src/silx.egg-info/PKG-INFO b/src/silx.egg-info/PKG-INFO
index f953bc6..905be0f 100644
--- a/src/silx.egg-info/PKG-INFO
+++ b/src/silx.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: silx
-Version: 1.1.0
+Version: 1.1.2
Summary: Software library for X-ray data analysis
Home-page: http://www.silx.org/
Author: data analysis unit
diff --git a/src/silx.egg-info/SOURCES.txt b/src/silx.egg-info/SOURCES.txt
index 6d81290..55da403 100644
--- a/src/silx.egg-info/SOURCES.txt
+++ b/src/silx.egg-info/SOURCES.txt
@@ -454,6 +454,8 @@ src/silx/gui/_glutils/__init__.py
src/silx/gui/_glutils/font.py
src/silx/gui/_glutils/gl.py
src/silx/gui/_glutils/utils.py
+src/silx/gui/_glutils/test/__init__.py
+src/silx/gui/_glutils/test/test_gl.py
src/silx/gui/data/ArrayTableModel.py
src/silx/gui/data/ArrayTableWidget.py
src/silx/gui/data/DataViewer.py
diff --git a/src/silx.egg-info/requires.txt b/src/silx.egg-info/requires.txt
index 11d2418..5a2c2e0 100644
--- a/src/silx.egg-info/requires.txt
+++ b/src/silx.egg-info/requires.txt
@@ -1,4 +1,4 @@
-numpy>=1.12.0
+numpy>=1.21.3
setuptools
h5py
fabio>=0.9
@@ -18,3 +18,4 @@ Pillow
[test]
pytest
pytest-xvfb
+pytest-mock
diff --git a/src/silx/_version.py b/src/silx/_version.py
index 511e823..5688237 100644
--- a/src/silx/_version.py
+++ b/src/silx/_version.py
@@ -70,7 +70,7 @@ PRERELEASE_NORMALIZED_NAME = {"dev": "a",
MAJOR = 1
MINOR = 1
-MICRO = 0
+MICRO = 2
RELEV = "final" # <16
SERIAL = 0 # <16
diff --git a/src/silx/gui/_glutils/gl.py b/src/silx/gui/_glutils/gl.py
index d33cf49..fb0a3fa 100644
--- a/src/silx/gui/_glutils/gl.py
+++ b/src/silx/gui/_glutils/gl.py
@@ -63,13 +63,29 @@ except NameError:
GLchar = c_char
+def getVersion() -> tuple:
+ """Returns the GL version as tuple of integers.
+
+ Raises:
+ ValueError: If the version returned by the driver is not supported
+ """
+ try:
+ desc = glGetString(GL_VERSION)
+ if isinstance(desc, bytes):
+ desc = desc.decode("ascii")
+ version = desc.split(" ", 1)[0]
+ return tuple([int(i) for i in version.split('.')])
+ except Exception as e:
+ raise ValueError("GL version not properly formatted") from e
+
+
def testGL() -> bool:
"""Test if required OpenGL version and extensions are available.
This MUST be run with an active OpenGL context.
"""
- version = glGetString(GL_VERSION).split()[0] # get version number
- major, minor = int(version[0]), int(version[2])
+ version = getVersion()
+ major, minor = version[0], version[1]
if major < 2 or (major == 2 and minor < 1):
_logger.error("OpenGL version >=2.1 required, running with %s" % version)
return False
diff --git a/src/silx/gui/_glutils/test/__init__.py b/src/silx/gui/_glutils/test/__init__.py
new file mode 100644
index 0000000..5ad4c28
--- /dev/null
+++ b/src/silx/gui/_glutils/test/__init__.py
@@ -0,0 +1,23 @@
+# /*##########################################################################
+#
+# Copyright (c) 2015-2022 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
diff --git a/src/silx/gui/_glutils/test/test_gl.py b/src/silx/gui/_glutils/test/test_gl.py
new file mode 100644
index 0000000..be9332b
--- /dev/null
+++ b/src/silx/gui/_glutils/test/test_gl.py
@@ -0,0 +1,36 @@
+# /*##########################################################################
+#
+# Copyright (c) 2015-2022 European Synchrotron Radiation Facility
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+# ###########################################################################*/
+
+from .. import gl
+
+
+def test_version_bytes(mocker):
+ mocker.patch('silx.gui._glutils.gl.glGetString', return_value=b"3.0 Mock")
+ assert gl.getVersion() == (3, 0)
+
+
+def test_version_str(mocker):
+ """In case glGetString returns str"""
+ mocker.patch('silx.gui._glutils.gl.glGetString', return_value="3.0 Mock")
+ assert gl.getVersion() == (3, 0)
diff --git a/src/silx/gui/plot/MaskToolsWidget.py b/src/silx/gui/plot/MaskToolsWidget.py
index 46b532c..327cdd6 100644
--- a/src/silx/gui/plot/MaskToolsWidget.py
+++ b/src/silx/gui/plot/MaskToolsWidget.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2017-2021 European Synchrotron Radiation Facility
+# Copyright (c) 2017-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -416,7 +416,7 @@ class MaskToolsWidget(BaseMaskToolsWidget):
if self.isMaskInteractionActivated():
# Disable drawing tool
- self.browseAction.trigger()
+ self.plot.resetInteractiveMode()
if self.isItemMaskUpdated(): # No "after-care"
self._data = numpy.zeros((0, 0), dtype=numpy.uint8)
@@ -712,7 +712,7 @@ class MaskToolsWidget(BaseMaskToolsWidget):
"""Open Save mask dialog"""
dialog = qt.QFileDialog(self)
dialog.setWindowTitle("Save Mask")
- dialog.setOption(dialog.DontUseNativeDialog)
+ dialog.setOption(qt.QFileDialog.DontUseNativeDialog)
dialog.setModal(1)
hdf5Filter = 'HDF5 (%s)' % _HDF5_EXT_STR
filters = [
@@ -733,9 +733,9 @@ class MaskToolsWidget(BaseMaskToolsWidget):
# disable overwrite confirmation for HDF5,
# because we append the data to existing files
if filt_ == hdf5Filter:
- dialog.setOption(dialog.DontConfirmOverwrite)
+ dialog.setOption(qt.QFileDialog.DontConfirmOverwrite)
else:
- dialog.setOption(dialog.DontConfirmOverwrite, False)
+ dialog.setOption(qt.QFileDialog.DontConfirmOverwrite, False)
dialog.filterSelected.connect(onFilterSelection)
if not dialog.exec():
diff --git a/src/silx/gui/plot/ScatterMaskToolsWidget.py b/src/silx/gui/plot/ScatterMaskToolsWidget.py
index 3f8c28b..5c82fcf 100644
--- a/src/silx/gui/plot/ScatterMaskToolsWidget.py
+++ b/src/silx/gui/plot/ScatterMaskToolsWidget.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2018-2021 European Synchrotron Radiation Facility
+# Copyright (c) 2018-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -287,8 +287,10 @@ class ScatterMaskToolsWidget(BaseMaskToolsWidget):
self.plot.sigActiveScatterChanged.disconnect(self._activeScatterChanged)
except (RuntimeError, TypeError):
_logger.info(sys.exc_info()[1])
- if not self.browseAction.isChecked():
- self.browseAction.trigger() # Disable drawing tool
+
+ if self.isMaskInteractionActivated():
+ # Disable drawing tool
+ self.plot.resetInteractiveMode()
if self.getSelectionMask(copy=False) is not None:
self.plot.sigActiveScatterChanged.connect(
diff --git a/src/silx/gui/plot/_BaseMaskToolsWidget.py b/src/silx/gui/plot/_BaseMaskToolsWidget.py
index dda75e1..1673137 100644
--- a/src/silx/gui/plot/_BaseMaskToolsWidget.py
+++ b/src/silx/gui/plot/_BaseMaskToolsWidget.py
@@ -918,8 +918,8 @@ class BaseMaskToolsWidget(qt.QWidget):
if (event.type() == qt.QEvent.EnabledChange and
not self.isEnabled() and
self.drawActionGroup.checkedAction()):
- # Disable drawing tool by setting interaction to zoom
- self.browseAction.trigger()
+ # Disable drawing tool by reseting interaction to pan or zoom
+ self.plot.resetInteractiveMode()
def save(self, filename, kind):
"""Save current mask in a file
diff --git a/src/silx/gui/plot/actions/io.py b/src/silx/gui/plot/actions/io.py
index 6cdd4d0..1ed9649 100644
--- a/src/silx/gui/plot/actions/io.py
+++ b/src/silx/gui/plot/actions/io.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2004-2021 European Synchrotron Radiation Facility
+# Copyright (c) 2004-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -628,21 +628,21 @@ class SaveAction(PlotAction):
# Create and run File dialog
dialog = qt.QFileDialog(self.plot)
- dialog.setOption(dialog.DontUseNativeDialog)
+ dialog.setOption(qt.QFileDialog.DontUseNativeDialog)
dialog.setWindowTitle("Output File Selection")
dialog.setModal(1)
dialog.setNameFilters(list(filters.keys()))
- dialog.setFileMode(dialog.AnyFile)
- dialog.setAcceptMode(dialog.AcceptSave)
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
def onFilterSelection(filt_):
# disable overwrite confirmation for NXdata types,
# because we append the data to existing files
if filt_ in self._appendFilters:
- dialog.setOption(dialog.DontConfirmOverwrite)
+ dialog.setOption(qt.QFileDialog.DontConfirmOverwrite)
else:
- dialog.setOption(dialog.DontConfirmOverwrite, False)
+ dialog.setOption(qt.QFileDialog.DontConfirmOverwrite, False)
dialog.filterSelected.connect(onFilterSelection)
diff --git a/src/silx/gui/plot/backends/BackendMatplotlib.py b/src/silx/gui/plot/backends/BackendMatplotlib.py
index 8610ed1..1b31582 100755
--- a/src/silx/gui/plot/backends/BackendMatplotlib.py
+++ b/src/silx/gui/plot/backends/BackendMatplotlib.py
@@ -1485,6 +1485,9 @@ class BackendMatplotlibQt(BackendMatplotlib, FigureCanvasQTAgg):
This is directly called by matplotlib for widget resize.
"""
+ if self.size().isEmpty():
+ return # Skip rendering of 0-sized canvas
+
self.updateZOrder()
# Starting with mpl 2.1.0, toggling autoscale raises a ValueError
diff --git a/src/silx/gui/plot/backends/glutils/GLPlotCurve.py b/src/silx/gui/plot/backends/glutils/GLPlotCurve.py
index 65bb6f0..4825479 100644
--- a/src/silx/gui/plot/backends/glutils/GLPlotCurve.py
+++ b/src/silx/gui/plot/backends/glutils/GLPlotCurve.py
@@ -854,8 +854,8 @@ class Points2D(object):
@classmethod
def init(cls):
"""OpenGL context initialization"""
- version = gl.glGetString(gl.GL_VERSION)
- majorVersion = int(version[0])
+ version = gl.getVersion()
+ majorVersion = version[0]
assert majorVersion >= 2
gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE) # OpenGL 2
gl.glEnable(gl.GL_POINT_SPRITE) # OpenGL 2
diff --git a/src/silx/gui/plot3d/actions/io.py b/src/silx/gui/plot3d/actions/io.py
index f8a1d86..47b0ce5 100644
--- a/src/silx/gui/plot3d/actions/io.py
+++ b/src/silx/gui/plot3d/actions/io.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2016-2021 European Synchrotron Radiation Facility
+# Copyright (c) 2016-2022 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -226,8 +226,8 @@ class VideoAction(Plot3DAction):
dialog.setModal(True)
dialog.setNameFilters([self.PNG_SERIE_FILTER,
self.MNG_FILTER])
- dialog.setFileMode(dialog.AnyFile)
- dialog.setAcceptMode(dialog.AcceptSave)
+ dialog.setFileMode(qt.QFileDialog.AnyFile)
+ dialog.setAcceptMode(qt.QFileDialog.AcceptSave)
if not dialog.exec():
return
diff --git a/src/silx/io/dictdump.py b/src/silx/io/dictdump.py
index d1bf8c4..094a51f 100644
--- a/src/silx/io/dictdump.py
+++ b/src/silx/io/dictdump.py
@@ -32,9 +32,12 @@ import numpy
import os.path
import h5py
try:
- import pint
+ from pint import Quantity as PintQuantity
except ImportError:
- pint = None
+ try:
+ from pint.quantity import Quantity as PintQuantity
+ except ImportError:
+ PintQuantity = None
from .configdict import ConfigDict
from .utils import is_group
@@ -67,7 +70,7 @@ def _prepare_hdf5_write_value(array_like):
``numpy.array()`` (`str`, `list`, `numpy.ndarray`…)
:return: ``numpy.ndarray`` ready to be written as an HDF5 dataset
"""
- if pint is not None and isinstance(array_like, pint.quantity.Quantity):
+ if PintQuantity is not None and isinstance(array_like, PintQuantity):
return numpy.array(array_like.magnitude)
array = numpy.asarray(array_like)
if numpy.issubdtype(array.dtype, numpy.bytes_):
@@ -470,7 +473,7 @@ def nexus_to_h5_dict(
add_nx_class=add_nx_class,
has_nx_class=key_has_nx_class)
- elif pint is not None and isinstance(value, pint.quantity.Quantity):
+ elif PintQuantity is not None and isinstance(value, PintQuantity):
copy[key] = value.magnitude
copy[(key, "units")] = f"{value.units:~C}"