You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
7.7 KiB

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