1from __future__ import absolute_import, division, print_function
2
3from matplotlib import pyplot as plt
4from matplotlib._pylab_helpers import Gcf
5import matplotlib
6import copy
7
8import pytest
9try:
10    # mock in python 3.3+
11    from unittest import mock
12except ImportError:
13    import mock
14
15with matplotlib.rc_context(rc={'backend': 'Qt4Agg'}):
16    qt_compat = pytest.importorskip('matplotlib.backends.qt_compat')
17from matplotlib.backends.backend_qt4 import (
18    MODIFIER_KEYS, SUPER, ALT, CTRL, SHIFT)  # noqa
19
20QtCore = qt_compat.QtCore
21_, ControlModifier, ControlKey = MODIFIER_KEYS[CTRL]
22_, AltModifier, AltKey = MODIFIER_KEYS[ALT]
23_, SuperModifier, SuperKey = MODIFIER_KEYS[SUPER]
24_, ShiftModifier, ShiftKey = MODIFIER_KEYS[SHIFT]
25
26try:
27    py_qt_ver = int(QtCore.PYQT_VERSION_STR.split('.')[0])
28except AttributeError:
29    py_qt_ver = QtCore.__version_info__[0]
30
31if py_qt_ver != 4:
32    pytestmark = pytest.mark.skipif(reason='Qt4 is not available')
33
34
35@pytest.mark.backend('Qt4Agg')
36def test_fig_close():
37    # save the state of Gcf.figs
38    init_figs = copy.copy(Gcf.figs)
39
40    # make a figure using pyplot interface
41    fig = plt.figure()
42
43    # simulate user clicking the close button by reaching in
44    # and calling close on the underlying Qt object
45    fig.canvas.manager.window.close()
46
47    # assert that we have removed the reference to the FigureManager
48    # that got added by plt.figure()
49    assert init_figs == Gcf.figs
50
51
52@pytest.mark.parametrize(
53    'qt_key, qt_mods, answer',
54    [
55        (QtCore.Qt.Key_A, ShiftModifier, 'A'),
56        (QtCore.Qt.Key_A, QtCore.Qt.NoModifier, 'a'),
57        (QtCore.Qt.Key_A, ControlModifier, 'ctrl+a'),
58        (QtCore.Qt.Key_Aacute, ShiftModifier,
59         '\N{LATIN CAPITAL LETTER A WITH ACUTE}'),
60        (QtCore.Qt.Key_Aacute, QtCore.Qt.NoModifier,
61         '\N{LATIN SMALL LETTER A WITH ACUTE}'),
62        (ControlKey, AltModifier, 'alt+control'),
63        (AltKey, ControlModifier, 'ctrl+alt'),
64        (QtCore.Qt.Key_Aacute, (ControlModifier | AltModifier | SuperModifier),
65         'ctrl+alt+super+\N{LATIN SMALL LETTER A WITH ACUTE}'),
66        (QtCore.Qt.Key_Backspace, QtCore.Qt.NoModifier, 'backspace'),
67        (QtCore.Qt.Key_Backspace, ControlModifier, 'ctrl+backspace'),
68        (QtCore.Qt.Key_Play, QtCore.Qt.NoModifier, None),
69    ],
70    ids=[
71        'shift',
72        'lower',
73        'control',
74        'unicode_upper',
75        'unicode_lower',
76        'alt_control',
77        'control_alt',
78        'modifier_order',
79        'backspace',
80        'backspace_mod',
81        'non_unicode_key',
82    ]
83)
84@pytest.mark.backend('Qt4Agg')
85def test_correct_key(qt_key, qt_mods, answer):
86    """
87    Make a figure
88    Send a key_press_event event (using non-public, qt4 backend specific api)
89    Catch the event
90    Assert sent and caught keys are the same
91    """
92    qt_canvas = plt.figure().canvas
93
94    event = mock.Mock()
95    event.isAutoRepeat.return_value = False
96    event.key.return_value = qt_key
97    event.modifiers.return_value = qt_mods
98
99    def receive(event):
100        assert event.key == answer
101
102    qt_canvas.mpl_connect('key_press_event', receive)
103    qt_canvas.keyPressEvent(event)
104