1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
from __future__ import absolute_import, division, print_function
from qtpy.QtCore import Qt
from qtpy import QtWidgets
from glue.utils.qt import QMessageBoxPatched as QMessageBox, set_cursor_cm
__all__ = ['data_wizard', 'GlueDataDialog']
def data_wizard():
""" QT Dialog to load a file into a new data object
Returns:
A list of new data objects. Returns an empty list if
selection is canceled.
"""
def report_error(error, factory, curfile):
import traceback
retry = QMessageBox.Retry
cancel = QMessageBox.Cancel
buttons = retry | cancel
detail = traceback.format_exc()
msg = "\n".join(["Could not load %s (wrong load method?)" % curfile,
"File load method: %s" % factory.label])
detail = "\n\n".join(["Error message: %s" % error, detail])
mb = QMessageBox(QMessageBox.Critical, "Data Load Error", msg)
mb.setDetailedText(detail)
mb.setDefaultButton(cancel)
mb.setStandardButtons(buttons)
ok = mb.exec_()
return ok == retry
while True:
gdd = GlueDataDialog()
try:
result = gdd.load_data()
break
except Exception as e:
decision = report_error(e, gdd.factory(), gdd._curfile)
if not decision:
return []
return result
class GlueDataDialog(object):
def __init__(self, parent=None):
self._fd = QtWidgets.QFileDialog(parent)
from glue.config import data_factory
self.filters = [(f, self._filter(f))
for f in data_factory.members if not f.deprecated]
self.setNameFilter()
self._fd.setFileMode(QtWidgets.QFileDialog.ExistingFiles)
self._curfile = ''
try:
self._fd.setOption(
QtWidgets.QFileDialog.Option.HideNameFilterDetails, True)
except AttributeError: # HideNameFilterDetails not present
pass
def factory(self):
fltr = self._fd.selectedNameFilter()
for k, v in self.filters:
if v.startswith(fltr):
return k
def setNameFilter(self):
fltr = ";;".join([flt for fac, flt in self.filters])
self._fd.setNameFilter(fltr)
def _filter(self, factory):
return "%s (*)" % factory.label
def paths(self):
"""
Return all selected paths, as a list of unicode strings
"""
return self._fd.selectedFiles()
def _get_paths_and_factory(self):
"""Show dialog to get a file path and data factory
:rtype: tuple of (list-of-strings, func)
giving the path and data factory.
returns ([], None) if user cancels dialog
"""
result = self._fd.exec_()
if result == QtWidgets.QDialog.Rejected:
return [], None
# path = list(map(str, self.paths())) # cast out of unicode
path = list(self.paths())
factory = self.factory()
return path, factory
def load_data(self):
"""Highest level method to interactively load a data set.
:rtype: A list of constructed data objects
"""
from glue.core.data_factories import data_label, load_data
paths, fac = self._get_paths_and_factory()
result = []
with set_cursor_cm(Qt.WaitCursor):
for path in paths:
self._curfile = path
d = load_data(path, factory=fac.function)
if not isinstance(d, list):
d.label = data_label(path)
d = [d]
result.extend(d)
return result
|