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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
|
"""Common utility functions and classes. This includes error/warning
messages etc.
"""
# Author: Prabhu Ramachandran <prabhu_r@users.sf.net>
# Copyright (c) 2005-2020, Enthought, Inc.
# License: BSD Style.
# Standard library imports.
import logging
import os
import sys
import traceback
# Enthought library imports.
from apptools.persistence.state_pickler import create_instance
from traits.etsconfig.api import ETSConfig
if (ETSConfig.toolkit == 'null') or os.environ.get('CI'):
pyface = None
else:
from pyface import api as pyface
# Setup a logger for this module.
logger = logging.getLogger(__name__)
######################################################################
# Utility functions.
######################################################################
def debug(msg):
"""Handle a debug message.
"""
logger.debug(msg)
def warning(msg, parent=None):
"""Handle a warning message.
"""
logger.warn(msg)
if pyface is not None:
pyface.warning(parent, msg)
def error(msg, parent=None):
"""Handle an error message.
"""
logger.error(msg)
if pyface is not None:
pyface.error(parent, msg)
def exception(msg='Exception', parent=None):
"""This function handles any exception derived from Exception and
prints out an error. The optional `parent` argument is passed
along to the dialog box. The optional `msg` is printed and sent
to the logger. So you could send extra information here.
"""
try:
type, value, tb = sys.exc_info()
info = traceback.extract_tb(tb)
filename, lineno, function, text = info[-1] # last line only
exc_msg = "%s\nIn %s:%d\n%s: %s (in %s)" %\
(msg, filename, lineno, type.__name__, str(value),
function)
# Log and display the message.
logger.exception(msg)
if pyface is not None:
pyface.error(parent, exc_msg, title='Exception')
finally:
type = value = tb = None # clean up
def process_ui_events():
"""Process GUI events.
This function merely abstracts the function so nothing is done when
no UI is running.
"""
if pyface is not None:
pyface.GUI.process_events()
def get_engine(obj):
"""Try and return the engine given an object in the mayavi
pipeline. This basically walks up the parent's of the object till
the engine is found.
"""
from mayavi.core.engine import Engine
while obj is not None:
if isinstance(obj, Engine):
return obj
else:
obj = obj.parent
return None
def get_output(obj):
"""Given an object, extracts the output object, hiding differences
between old and new pipeline."""
if obj.is_a('vtkDataSet'):
return obj
else:
return obj.output
def get_object_path(object, parent, path='engine'):
"""Given a mayavi object on the tree view, this should find its
"path" with respect to the parent object that contains it.
"""
def _get_child_trait(obj):
if hasattr(obj, 'scenes'):
return 'scenes'
elif hasattr(obj, 'children'):
return 'children'
return ''
def _finder(obj, to_find, path):
if obj is to_find:
return path
else:
child_t = _get_child_trait(obj)
if child_t == '':
return ''
for i, o in enumerate(getattr(obj, child_t)):
pth = _finder(o, to_find, '%s.%s[%d]'%(path, child_t, i))
if len(pth) > 0:
return pth
return ''
return _finder(parent, object, path)
def handle_children_state(children, kids):
"""Given a list of children (as `children`) of a particular object
and their states in the `kids` argument, this function sets up the
children by removing unnecessary ones, fixing existing ones and
adding new children if necessary (depending on the state).
"""
# Make a copy of the list so adding/removing does not trigger events
# each time.
m_children = list(children)
n_child, n_kid = len(m_children), len(kids)
# Remove extra children we have.
for i in range(n_child - n_kid):
m_children.pop()
# Now check existing children deleting existing ones and
# creating new ones if needed.
for i in range(n_child):
child, kid = m_children[i], kids[i]
md = kid.__metadata__
if (child.__module__ != md['module']) \
or (child.__class__.__name__ != md['class_name']):
m_children[i] = create_instance(kid)
# Add any extra kids.
for i in range(n_kid - n_child):
child = create_instance(kids[n_child + i])
m_children.append(child)
# Now set the children in one shot.
children[:] = m_children
|