source: orange/Orange/OrangeCanvas/gui/utils.py @ 11311:13976e39b13f

Revision 11311:13976e39b13f, 7.0 KB checked in by Ales Erjavec <ales.erjavec@…>, 14 months ago (diff)

Fixed 'is_dwm_compositing_enabled' function check.

Line 
1"""
2Helper utilities
3
4"""
5import os
6import sys
7import traceback
8
9from contextlib import contextmanager
10
11from PyQt4.QtGui import (
12    QWidget, QMessageBox, QGradient, QLinearGradient, QRadialGradient, QBrush,
13    QPainter, QStyleOption, QStyle
14)
15
16import sip
17
18QWIDGETSIZE_MAX = ((1 << 24) - 1)
19
20
21@contextmanager
22def updates_disabled(widget):
23    """Disable QWidget updates (using QWidget.setUpdatesEnabled)
24    """
25    old_state = widget.updatesEnabled()
26    widget.setUpdatesEnabled(False)
27    try:
28        yield
29    finally:
30        widget.setUpdatesEnabled(old_state)
31
32
33@contextmanager
34def signals_disabled(qobject):
35    """Disables signals on an instance of QObject.
36    """
37    old_state = qobject.signalsBlocked()
38    qobject.blockSignals(True)
39    try:
40        yield
41    finally:
42        qobject.blockSignals(old_state)
43
44
45@contextmanager
46def disabled(qobject):
47    """Disables a disablable QObject instance.
48    """
49    if not (hasattr(qobject, "setEnabled") and hasattr(qobject, "isEnabled")):
50        raise TypeError("%r does not have 'enabled' property" % qobject)
51
52    old_state = qobject.isEnabled()
53    qobject.setEnabled(False)
54    try:
55        yield
56    finally:
57        qobject.setEnabled(old_state)
58
59
60def StyledWidget_paintEvent(self, event):
61    """A default styled QWidget subclass  paintEvent function.
62    """
63    opt = QStyleOption()
64    opt.init(self)
65    painter = QPainter(self)
66    self.style().drawPrimitive(QStyle.PE_Widget, opt, painter, self)
67
68
69class StyledWidget(QWidget):
70    """
71    """
72    paintEvent = StyledWidget_paintEvent
73
74
75def is_transparency_supported():
76    """Is window transparency supported by the current windowing system.
77
78    """
79    if sys.platform == "win32":
80        return is_dwm_compositing_enabled()
81    elif sys.platform == "cygwin":
82        return False
83    elif sys.platform == "darwin":
84        if has_x11():
85            return is_x11_compositing_enabled()
86        else:
87            # Quartz compositor
88            return True
89    elif sys.platform.startswith("linux"):
90        # TODO: wayland??
91        return is_x11_compositing_enabled()
92    elif sys.platform.startswith("freebsd"):
93        return is_x11_compositing_enabled()
94    elif has_x11():
95        return is_x11_compositing_enabled()
96    else:
97        return False
98
99
100def has_x11():
101    """
102    Is Qt build against X11 server.
103    """
104    try:
105        from PyQt4.QtGui import QX11Info
106        return True
107    except ImportError:
108        return False
109
110
111def is_x11_compositing_enabled():
112    """Is X11 compositing manager running.
113    """
114    try:
115        from PyQt4.QtGui import QX11Info
116    except ImportError:
117        return False
118
119    return QX11Info.isCompositingManagerRunning()
120
121
122def is_dwm_compositing_enabled():
123    """Is Desktop Window Manager compositing (Aero) enabled.
124    """
125    import ctypes
126
127    enabled = ctypes.c_bool()
128    try:
129        DwmIsCompositionEnabled = ctypes.windll.dwmapi.DwmIsCompositionEnabled
130    except (AttributeError, WindowsError):
131        # dwmapi or DwmIsCompositionEnabled is not present
132        return False
133
134    rval = DwmIsCompositionEnabled(ctypes.byref(enabled))
135
136    return rval == 0 and enabled.value
137
138
139def gradient_darker(grad, factor):
140    """Return a copy of the QGradient darkened by factor.
141
142    .. note:: Only QLinearGradeint and QRadialGradient are supported.
143
144    """
145    if type(grad) is QGradient:
146        if grad.type() == QGradient.LinearGradient:
147            grad = sip.cast(grad, QLinearGradient)
148        elif grad.type() == QGradient.RadialGradient:
149            grad = sip.cast(grad, QRadialGradient)
150
151    if isinstance(grad, QLinearGradient):
152        new_grad = QLinearGradient(grad.start(), grad.finalStop())
153    elif isinstance(grad, QRadialGradient):
154        new_grad = QRadialGradient(grad.center(), grad.radius(),
155                                   grad.focalPoint())
156    else:
157        raise TypeError
158
159    new_grad.setCoordinateMode(grad.coordinateMode())
160
161    for pos, color in grad.stops():
162        new_grad.setColorAt(pos, color.darker(factor))
163
164    return new_grad
165
166
167def brush_darker(brush, factor):
168    """Return a copy of the brush darkened by factor.
169    """
170    grad = brush.gradient()
171    if grad:
172        return QBrush(gradient_darker(grad, factor))
173    else:
174        brush = QBrush(brush)
175        brush.setColor(brush.color().darker(factor))
176        return brush
177
178
179def message_critical(text, title=None, informative_text=None, details=None,
180                     buttons=None, default_button=None, exc_info=False,
181                     parent=None):
182    """Show a critical message.
183    """
184    if not text:
185        text = "An unexpected error occurred."
186
187    if title is None:
188        title = "Error"
189
190    return message(QMessageBox.Critical, text, title, informative_text,
191                   details, buttons, default_button, exc_info, parent)
192
193
194def message_warning(text, title=None, informative_text=None, details=None,
195                    buttons=None, default_button=None, exc_info=False,
196                    parent=None):
197    """Show a warning message.
198    """
199    if not text:
200        import random
201        text_candidates = ["Death could come at any moment.",
202                           "Murphy lurks about. Remember to save frequently."
203                           ]
204        text = random.choice(text_candidates)
205
206    if title is not None:
207        title = "Warning"
208
209    return message(QMessageBox.Warning, text, title, informative_text,
210                   details, buttons, default_button, exc_info, parent)
211
212
213def message_information(text, title=None, informative_text=None, details=None,
214                        buttons=None, default_button=None, exc_info=False,
215                        parent=None):
216    """Show an information message box.
217    """
218    if title is None:
219        title = "Information"
220    if not text:
221        text = "I am not a number."
222
223    return message(QMessageBox.Information, text, title, informative_text,
224                   details, buttons, default_button, exc_info, parent)
225
226
227def message_question(text, title, informative_text=None, details=None,
228                     buttons=None, default_button=None, exc_info=False,
229                     parent=None):
230    """Show an message box asking the user to select some
231    predefined course of action (set by buttons argument).
232
233    """
234    return message(QMessageBox.Question, text, title, informative_text,
235                   details, buttons, default_button, exc_info, parent)
236
237
238def message(icon, text, title=None, informative_text=None, details=None,
239            buttons=None, default_button=None, exc_info=False, parent=None):
240    """Show a message helper function.
241    """
242    if title is None:
243        title = "Message"
244    if not text:
245        text = "I am neither a postman nor a doctor."
246
247    if buttons is None:
248        buttons = QMessageBox.Ok
249
250    if details is None and exc_info:
251        details = traceback.format_exc(limit=20)
252
253    mbox = QMessageBox(icon, title, text, buttons, parent)
254
255    if informative_text:
256        mbox.setInformativeText(informative_text)
257
258    if details:
259        mbox.setDetailedText(details)
260
261    if default_button is not None:
262        mbox.setDefaultButton(default_button)
263
264    return mbox.exec_()
Note: See TracBrowser for help on using the repository browser.