setup.cfg: require python >= 3.6
[git-cola.git] / qtpy / compat.py
blob949d8854d19304ebbd862530338f5da66764515b
1 # -*- coding: utf-8 -*-
3 # Copyright © 2009- The Spyder Development Team
4 # Licensed under the terms of the MIT License
6 """
7 Compatibility functions
8 """
10 from __future__ import print_function
11 import sys
13 from . import PYQT4
14 from .QtWidgets import QFileDialog
15 from .py3compat import Callable, is_text_string, to_text_string, TEXT_TYPES
18 # =============================================================================
19 # QVariant conversion utilities
20 # =============================================================================
21 PYQT_API_1 = False
22 if PYQT4:
23 import sip
24 try:
25 PYQT_API_1 = sip.getapi('QVariant') == 1 # PyQt API #1
26 except AttributeError:
27 # PyQt <v4.6
28 PYQT_API_1 = True
30 def to_qvariant(pyobj=None):
31 """Convert Python object to QVariant
32 This is a transitional function from PyQt API #1 (QVariant exist)
33 to PyQt API #2 and Pyside (QVariant does not exist)"""
34 if PYQT_API_1:
35 # PyQt API #1
36 from PyQt4.QtCore import QVariant
37 return QVariant(pyobj)
38 else:
39 # PyQt API #2
40 return pyobj
42 def from_qvariant(qobj=None, convfunc=None):
43 """Convert QVariant object to Python object
44 This is a transitional function from PyQt API #1 (QVariant exist)
45 to PyQt API #2 and Pyside (QVariant does not exist)"""
46 if PYQT_API_1:
47 # PyQt API #1
48 assert isinstance(convfunc, Callable)
49 if convfunc in TEXT_TYPES or convfunc is to_text_string:
50 return convfunc(qobj.toString())
51 elif convfunc is bool:
52 return qobj.toBool()
53 elif convfunc is int:
54 return qobj.toInt()[0]
55 elif convfunc is float:
56 return qobj.toDouble()[0]
57 else:
58 return convfunc(qobj)
59 else:
60 # PyQt API #2
61 return qobj
62 else:
63 def to_qvariant(obj=None): # analysis:ignore
64 """Convert Python object to QVariant
65 This is a transitional function from PyQt API#1 (QVariant exist)
66 to PyQt API#2 and Pyside (QVariant does not exist)"""
67 return obj
69 def from_qvariant(qobj=None, pytype=None): # analysis:ignore
70 """Convert QVariant object to Python object
71 This is a transitional function from PyQt API #1 (QVariant exist)
72 to PyQt API #2 and Pyside (QVariant does not exist)"""
73 return qobj
76 # =============================================================================
77 # Wrappers around QFileDialog static methods
78 # =============================================================================
79 def getexistingdirectory(parent=None, caption='', basedir='',
80 options=QFileDialog.ShowDirsOnly):
81 """Wrapper around QtGui.QFileDialog.getExistingDirectory static method
82 Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0"""
83 # Calling QFileDialog static method
84 if sys.platform == "win32":
85 # On Windows platforms: redirect standard outputs
86 _temp1, _temp2 = sys.stdout, sys.stderr
87 sys.stdout, sys.stderr = None, None
88 try:
89 result = QFileDialog.getExistingDirectory(parent, caption, basedir,
90 options)
91 finally:
92 if sys.platform == "win32":
93 # On Windows platforms: restore standard outputs
94 sys.stdout, sys.stderr = _temp1, _temp2
95 if not is_text_string(result):
96 # PyQt API #1
97 result = to_text_string(result)
98 return result
101 def _qfiledialog_wrapper(attr, parent=None, caption='', basedir='',
102 filters='', selectedfilter='', options=None):
103 if options is None:
104 options = QFileDialog.Options(0)
105 try:
106 # PyQt <v4.6 (API #1)
107 from .QtCore import QString
108 except ImportError:
109 # PySide or PyQt >=v4.6
110 QString = None # analysis:ignore
111 tuple_returned = True
112 try:
113 # PyQt >=v4.6
114 func = getattr(QFileDialog, attr+'AndFilter')
115 except AttributeError:
116 # PySide or PyQt <v4.6
117 func = getattr(QFileDialog, attr)
118 if QString is not None:
119 selectedfilter = QString()
120 tuple_returned = False
122 # Calling QFileDialog static method
123 if sys.platform == "win32":
124 # On Windows platforms: redirect standard outputs
125 _temp1, _temp2 = sys.stdout, sys.stderr
126 sys.stdout, sys.stderr = None, None
127 try:
128 result = func(parent, caption, basedir,
129 filters, selectedfilter, options)
130 except TypeError:
131 # The selectedfilter option (`initialFilter` in Qt) has only been
132 # introduced in Jan. 2010 for PyQt v4.7, that's why we handle here
133 # the TypeError exception which will be raised with PyQt v4.6
134 # (see Issue 960 for more details)
135 result = func(parent, caption, basedir, filters, options)
136 finally:
137 if sys.platform == "win32":
138 # On Windows platforms: restore standard outputs
139 sys.stdout, sys.stderr = _temp1, _temp2
141 # Processing output
142 if tuple_returned:
143 # PySide or PyQt >=v4.6
144 output, selectedfilter = result
145 else:
146 # PyQt <v4.6 (API #1)
147 output = result
148 if QString is not None:
149 # PyQt API #1: conversions needed from QString/QStringList
150 selectedfilter = to_text_string(selectedfilter)
151 if isinstance(output, QString):
152 # Single filename
153 output = to_text_string(output)
154 else:
155 # List of filenames
156 output = [to_text_string(fname) for fname in output]
158 # Always returns the tuple (output, selectedfilter)
159 return output, selectedfilter
162 def getopenfilename(parent=None, caption='', basedir='', filters='',
163 selectedfilter='', options=None):
164 """Wrapper around QtGui.QFileDialog.getOpenFileName static method
165 Returns a tuple (filename, selectedfilter) -- when dialog box is canceled,
166 returns a tuple of empty strings
167 Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0"""
168 return _qfiledialog_wrapper('getOpenFileName', parent=parent,
169 caption=caption, basedir=basedir,
170 filters=filters, selectedfilter=selectedfilter,
171 options=options)
174 def getopenfilenames(parent=None, caption='', basedir='', filters='',
175 selectedfilter='', options=None):
176 """Wrapper around QtGui.QFileDialog.getOpenFileNames static method
177 Returns a tuple (filenames, selectedfilter) -- when dialog box is canceled,
178 returns a tuple (empty list, empty string)
179 Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0"""
180 return _qfiledialog_wrapper('getOpenFileNames', parent=parent,
181 caption=caption, basedir=basedir,
182 filters=filters, selectedfilter=selectedfilter,
183 options=options)
186 def getsavefilename(parent=None, caption='', basedir='', filters='',
187 selectedfilter='', options=None):
188 """Wrapper around QtGui.QFileDialog.getSaveFileName static method
189 Returns a tuple (filename, selectedfilter) -- when dialog box is canceled,
190 returns a tuple of empty strings
191 Compatible with PyQt >=v4.4 (API #1 and #2) and PySide >=v1.0"""
192 return _qfiledialog_wrapper('getSaveFileName', parent=parent,
193 caption=caption, basedir=basedir,
194 filters=filters, selectedfilter=selectedfilter,
195 options=options)